From jacekt at dug.com Tue Jul 2 07:19:55 2019 From: jacekt at dug.com (Jacek Tomaka) Date: Tue, 2 Jul 2019 15:19:55 +0800 Subject: [lustre-devel] Kernel panic - not syncing: LBUG: llite_mmap.c:71:our_vma() Message-ID: Hello, I was wondering if you would be interested in the following failed assertion: 2019-07-02T01:45:11-05:00 nanny1926 kernel: LustreError: 251884:0:(llite_mmap.c:71:our_vma()) ASSERTION( !down_write_trylock(&mm->mmap_sem) ) failed: 2019-07-02T01:45:11-05:00 nanny1926 kernel: LustreError: 251884:0:(llite_mmap.c:71:our_vma()) LBUG 2019-07-02T01:45:11-05:00 nanny1926 kernel: Pid: 251884, comm: java 2019-07-02T01:45:11-05:00 nanny1926 kernel: #012Call Trace: 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] libcfs_call_trace+0x4e/0x60 [libcfs] 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] lbug_with_loc+0x4c/0xb0 [libcfs] 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] our_vma+0x16b/0x170 [lustre] 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] vvp_io_rw_lock+0x409/0x6e0 [lustre] 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] ? lov_io_iter_init+0x302/0x8b0 [lov] 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] vvp_io_write_lock+0x59/0xf0 [lustre] 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] cl_io_lock+0x5c/0x3d0 [obdclass] 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] cl_io_loop+0x11b/0xc90 [obdclass] 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] ll_file_io_generic+0x498/0xc40 [lustre] 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] ll_file_aio_write+0x12d/0x1f0 [lustre] 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] ll_file_write+0xce/0x1e0 [lustre] 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] vfs_write+0xbd/0x1e0 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] ? __audit_syscall_entry+0xb4/0x110 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] SyS_write+0x7f/0xe0 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] tracesys+0xdd/0xe2 2019-07-02T01:45:11-05:00 nanny1926 kernel: 2019-07-02T01:45:11-05:00 nanny1926 kernel: Kernel panic - not syncing: LBUG Is there any other place where you would want it reported? -- Jacek Tomaka Geophysical Software Developer DownUnder GeoSolutions 76 Kings Park Road West Perth 6005 WA, Australia tel +61 8 9287 4143 jacekt at dug.com www.dug.com From adilger at whamcloud.com Tue Jul 2 07:45:24 2019 From: adilger at whamcloud.com (Andreas Dilger) Date: Tue, 2 Jul 2019 07:45:24 +0000 Subject: [lustre-devel] Kernel panic - not syncing: LBUG: llite_mmap.c:71:our_vma() In-Reply-To: References: Message-ID: The best place to report Lustre bugs is at https://jira.whamcloud.com/ Please include the Lustre version number you are running, and any details you can provide about what kind of IO the Java application was doing at the time, if this is even possible for Java :-). It looks like it is doing AIO? Also, is this repeatable, or a one-time event? Cheers, Andreas > On Jul 2, 2019, at 01:20, Jacek Tomaka wrote: > > Hello, > I was wondering if you would be interested in the following failed assertion: > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: LustreError: > 251884:0:(llite_mmap.c:71:our_vma()) ASSERTION( > !down_write_trylock(&mm->mmap_sem) ) failed: > 2019-07-02T01:45:11-05:00 nanny1926 kernel: LustreError: > 251884:0:(llite_mmap.c:71:our_vma()) LBUG > 2019-07-02T01:45:11-05:00 nanny1926 kernel: Pid: 251884, comm: java > 2019-07-02T01:45:11-05:00 nanny1926 kernel: #012Call Trace: > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > libcfs_call_trace+0x4e/0x60 [libcfs] > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > lbug_with_loc+0x4c/0xb0 [libcfs] > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > our_vma+0x16b/0x170 [lustre] > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > vvp_io_rw_lock+0x409/0x6e0 [lustre] > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] ? > lov_io_iter_init+0x302/0x8b0 [lov] > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > vvp_io_write_lock+0x59/0xf0 [lustre] > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > cl_io_lock+0x5c/0x3d0 [obdclass] > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > cl_io_loop+0x11b/0xc90 [obdclass] > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > ll_file_io_generic+0x498/0xc40 [lustre] > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > ll_file_aio_write+0x12d/0x1f0 [lustre] > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > ll_file_write+0xce/0x1e0 [lustre] > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > vfs_write+0xbd/0x1e0 > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] ? > __audit_syscall_entry+0xb4/0x110 > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > SyS_write+0x7f/0xe0 > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > tracesys+0xdd/0xe2 > 2019-07-02T01:45:11-05:00 nanny1926 kernel: > 2019-07-02T01:45:11-05:00 nanny1926 kernel: Kernel panic - not syncing: LBUG > > Is there any other place where you would want it reported? > > -- > Jacek Tomaka > Geophysical Software Developer > > > > > DownUnder GeoSolutions > > 76 Kings Park Road > West Perth 6005 WA, Australia > tel +61 8 9287 4143 > jacekt at dug.com > www.dug.com > _______________________________________________ > lustre-devel mailing list > lustre-devel at lists.lustre.org > http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org From jacekt at dug.com Fri Jul 5 01:07:42 2019 From: jacekt at dug.com (Jacek Tomaka) Date: Fri, 5 Jul 2019 09:07:42 +0800 Subject: [lustre-devel] Kernel panic - not syncing: LBUG: llite_mmap.c:71:our_vma() In-Reply-To: References: Message-ID: Hi Andreas, Linux version 3.10.0-693.5.2.el7.x86_64 (builder at kbuilder.dev.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC) ) #1 SMP Fri Oct 20 20: 32:50 UTC 2017 Lustre: Lustre: Build Version: 2.10.1 Intel(R) Xeon Phi(TM) CPU 7210 @ 1.30GHz It is reading in up to 256 threads. And writing 16 files in up to 16 threads. It is reproducible (but does not fail every time) on this particular machine, which might just be a particular network timing. I will try to reproduce it on another machine and get back to you if successful. Any ideas why this lock would have failed? A quick analysis shows that the only place where our_vma is called is lustre/llite/vvp_io.c:453, and it only acquires read lock: vvp_mmap_locks: 452 down_read(&mm->mmap_sem); 453 while((vma = our_vma(mm, addr, count)) != NULL) { 454 struct dentry *de = file_dentry(vma->vm_file); 455 struct inode *inode = de->d_inode; 456 int flags = CEF_MUST; whereas our_vma has this: 70 /* mmap_sem must have been held by caller. */ 71 LASSERT(!down_write_trylock(&mm->mmap_sem)); So i guess if there are multiple threads in vvp_mmap_locks and more than one happen to acquire read_lock, or one of them acquires write lock then the other would fail, no? I will put these details into JIRA. Jacek Tomaka On Tue, Jul 2, 2019 at 3:45 PM Andreas Dilger wrote: > The best place to report Lustre bugs is at https://jira.whamcloud.com/ > > Please include the Lustre version number you are running, and any details > you can provide about what kind of IO the Java application was doing at the > time, if this is even possible for Java :-). It looks like it is doing > AIO? Also, is this repeatable, or a one-time event? > > Cheers, Andreas > > > On Jul 2, 2019, at 01:20, Jacek Tomaka wrote: > > > > Hello, > > I was wondering if you would be interested in the following failed > assertion: > > > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: LustreError: > > 251884:0:(llite_mmap.c:71:our_vma()) ASSERTION( > > !down_write_trylock(&mm->mmap_sem) ) failed: > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: LustreError: > > 251884:0:(llite_mmap.c:71:our_vma()) LBUG > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: Pid: 251884, comm: java > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: #012Call Trace: > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > > libcfs_call_trace+0x4e/0x60 [libcfs] > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > > lbug_with_loc+0x4c/0xb0 [libcfs] > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > > our_vma+0x16b/0x170 [lustre] > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > > vvp_io_rw_lock+0x409/0x6e0 [lustre] > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] ? > > lov_io_iter_init+0x302/0x8b0 [lov] > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > > vvp_io_write_lock+0x59/0xf0 [lustre] > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > > cl_io_lock+0x5c/0x3d0 [obdclass] > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > > cl_io_loop+0x11b/0xc90 [obdclass] > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > > ll_file_io_generic+0x498/0xc40 [lustre] > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > > ll_file_aio_write+0x12d/0x1f0 [lustre] > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > > ll_file_write+0xce/0x1e0 [lustre] > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > > vfs_write+0xbd/0x1e0 > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] ? > > __audit_syscall_entry+0xb4/0x110 > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > > SyS_write+0x7f/0xe0 > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] > > tracesys+0xdd/0xe2 > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: > > 2019-07-02T01:45:11-05:00 nanny1926 kernel: Kernel panic - not syncing: > LBUG > > > > Is there any other place where you would want it reported? > > > > -- > > Jacek Tomaka > > Geophysical Software Developer > > > > > > > > > > DownUnder GeoSolutions > > > > 76 Kings Park Road > > West Perth 6005 WA, Australia > > tel +61 8 9287 4143 > > jacekt at dug.com > > www.dug.com > > _______________________________________________ > > lustre-devel mailing list > > lustre-devel at lists.lustre.org > > http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org > -- *Jacek Tomaka* Geophysical Software Developer *DownUnder GeoSolutions* 76 Kings Park Road West Perth 6005 WA, Australia *tel *+61 8 9287 4143 <+61%208%209287%204143> jacekt at dug.com *www.dug.com * -------------- next part -------------- An HTML attachment was scrubbed... URL: From jacekt at dug.com Fri Jul 5 01:13:59 2019 From: jacekt at dug.com (Jacek Tomaka) Date: Fri, 5 Jul 2019 09:13:59 +0800 Subject: [lustre-devel] Kernel panic - not syncing: LBUG: llite_mmap.c:71:our_vma() In-Reply-To: References: Message-ID: https://jira.whamcloud.com/browse/LU-12508 Regards. Jacek Tomaka On Fri, Jul 5, 2019 at 9:07 AM Jacek Tomaka wrote: > > Hi Andreas, > Linux version 3.10.0-693.5.2.el7.x86_64 (builder at kbuilder.dev.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC) ) #1 SMP Fri Oct 20 20: > 32:50 UTC 2017 > Lustre: Lustre: Build Version: 2.10.1 > Intel(R) Xeon Phi(TM) CPU 7210 @ 1.30GHz > > It is reading in up to 256 threads. And writing 16 files in up to 16 threads. > > It is reproducible (but does not fail every time) on this particular machine, which might just be a particular network timing. > I will try to reproduce it on another machine and get back to you if successful. > > Any ideas why this lock would have failed? > A quick analysis shows that the only place where our_vma is called is lustre/llite/vvp_io.c:453, and it only acquires read lock: > vvp_mmap_locks: > 452 down_read(&mm->mmap_sem); > 453 while((vma = our_vma(mm, addr, count)) != NULL) { > 454 struct dentry *de = file_dentry(vma->vm_file); > 455 struct inode *inode = de->d_inode; > 456 int flags = CEF_MUST; > > whereas our_vma has this: > 70 /* mmap_sem must have been held by caller. */ > 71 LASSERT(!down_write_trylock(&mm->mmap_sem)); > > So i guess if there are multiple threads in vvp_mmap_locks and more than one happen to acquire read_lock, or one of them acquires write lock then the other would fail, no? > I will put these details into JIRA. > Jacek Tomaka > > On Tue, Jul 2, 2019 at 3:45 PM Andreas Dilger wrote: >> >> The best place to report Lustre bugs is at https://jira.whamcloud.com/ >> >> Please include the Lustre version number you are running, and any details you can provide about what kind of IO the Java application was doing at the time, if this is even possible for Java :-). It looks like it is doing AIO? Also, is this repeatable, or a one-time event? >> >> Cheers, Andreas >> >> > On Jul 2, 2019, at 01:20, Jacek Tomaka wrote: >> > >> > Hello, >> > I was wondering if you would be interested in the following failed assertion: >> > >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: LustreError: >> > 251884:0:(llite_mmap.c:71:our_vma()) ASSERTION( >> > !down_write_trylock(&mm->mmap_sem) ) failed: >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: LustreError: >> > 251884:0:(llite_mmap.c:71:our_vma()) LBUG >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: Pid: 251884, comm: java >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: #012Call Trace: >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] >> > libcfs_call_trace+0x4e/0x60 [libcfs] >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] >> > lbug_with_loc+0x4c/0xb0 [libcfs] >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] >> > our_vma+0x16b/0x170 [lustre] >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] >> > vvp_io_rw_lock+0x409/0x6e0 [lustre] >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] ? >> > lov_io_iter_init+0x302/0x8b0 [lov] >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] >> > vvp_io_write_lock+0x59/0xf0 [lustre] >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] >> > cl_io_lock+0x5c/0x3d0 [obdclass] >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] >> > cl_io_loop+0x11b/0xc90 [obdclass] >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] >> > ll_file_io_generic+0x498/0xc40 [lustre] >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] >> > ll_file_aio_write+0x12d/0x1f0 [lustre] >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] >> > ll_file_write+0xce/0x1e0 [lustre] >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] >> > vfs_write+0xbd/0x1e0 >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] ? >> > __audit_syscall_entry+0xb4/0x110 >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] >> > SyS_write+0x7f/0xe0 >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: [] >> > tracesys+0xdd/0xe2 >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: >> > 2019-07-02T01:45:11-05:00 nanny1926 kernel: Kernel panic - not syncing: LBUG >> > >> > Is there any other place where you would want it reported? >> > >> > -- >> > Jacek Tomaka >> > Geophysical Software Developer >> > >> > >> > >> > >> > DownUnder GeoSolutions >> > >> > 76 Kings Park Road >> > West Perth 6005 WA, Australia >> > tel +61 8 9287 4143 >> > jacekt at dug.com >> > www.dug.com >> > _______________________________________________ >> > lustre-devel mailing list >> > lustre-devel at lists.lustre.org >> > http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org > > > > -- > Jacek Tomaka > Geophysical Software Developer > > > > > DownUnder GeoSolutions > > 76 Kings Park Road > West Perth 6005 WA, Australia > tel +61 8 9287 4143 > jacekt at dug.com > www.dug.com -- Jacek Tomaka Geophysical Software Developer DownUnder GeoSolutions 76 Kings Park Road West Perth 6005 WA, Australia tel +61 8 9287 4143 jacekt at dug.com www.dug.com From mahrens at delphix.com Fri Jul 5 18:15:01 2019 From: mahrens at delphix.com (Matthew Ahrens) Date: Fri, 5 Jul 2019 11:15:01 -0700 Subject: [lustre-devel] Request arc buffer, zerocopy In-Reply-To: <1561715412.12733.3@informatik.uni-hamburg.de> References: <1560426887.3392.0@informatik.uni-hamburg.de> <1561554708.16396.0@informatik.uni-hamburg.de> <1561715412.12733.3@informatik.uni-hamburg.de> Message-ID: On Fri, Jun 28, 2019 at 2:50 AM Anna Fuchs < anna.fuchs at informatik.uni-hamburg.de> wrote: > Hello Matt, > > thanks for your reply. > > > > > You can set the block size (of the first and only block) using > > dmu_object_set_blocksize(). FYI, I think that this comment is > > incorrect: > > * If the first block is allocated already, the new size must be > > greater > > * than the current block size. > > > > You can increase or decrease the block size with this routine. > > This is a deeper call of Lustre's osd_grow_blocksize I mentioned > before. If I understand it correctly, they are called in the context of > transactions, right? > It is not possible to change the block size of a ZFS object outside of a transaction. > If so, I can not use it - I need the blocksize to be set in the buffer > preparation stage, before comitting in a transaction. > Lustre's original routine looks simplified as follows: > > osd_bufs_get_write > bs = dn->dn_datablksz > while (len > 0) > if (sz_in_block == bs) /* full block, try > zerocopy */ > abuf = osd_request_arcbuf(dn, bs); > else /* can't use zerocopy, > allocate temp. buffers */ > ... alloc_page ... > here going later on the dmu_write path (pagewise!) > > Currently, in the very first iteration this blocksize (bs) is taken > from the dnode and is e.g. 4K. > When writing a chunk of 16K, I get 4 arcbufs 4K each. For the next > chunk the block size might be grown up to x (recordsize?). > Here I need the blocksize to be set to 16K (or 128K or later some > generic value defined by the Lustre client) before the first arcbuf is > requested, > because the compressed chunk sent from client is logically this size. > At this point I don't have any dmu_tx yet to grow the blocksize saved > in dn->dn_datablksz before the while loop. > So I am not sure how deep to go? This min size is set on dnode creation > by ZFS, how can I "reset" it? > I think that you are saying that you want to be loaned an ARC buffer of the size provided by the client, which may be different from the object's current blocksize. You will later (within a transaction) change the object's blocksize to the size specified by the client, and write the data (using the loaned ARC buffer). You can do exactly that using the routines I mentioned. In your example code above, you are providing the dnode when requesting the arc buf, which leads to the problem you described (needing that dnode's block size to match the size provided by the client before you change the blocksize of the object). However, this is an unnecessary restriction, because arc_loan_compressed_buf() does not need to know the dnode, or its current block size. --matt > > > > > I'd recommend that you hand the compressed data to ZFS similarly to > > how "zfs receive" does (for compressed send streams). It sounds like > > the is the direction you're going, which is great. FYI, here are > > some of the routines you'd want to use (copied from dmu_recv.c): > > > > abuf = arc_loan_compressed_buf( > > > > dmu_objset_spa(drc->drc_os), > > > > drrw->drr_compressed_size, > drrw->drr_logical_size, > > > > drrw->drr_compressiontype); > > > > > > dmu_assign_arcbuf(bonus, drrw->drr_offset, abuf, tx); > > > > (or dmu_assign_arcbuf_dnode()) > > > > > > dmu_return_arcbuf(rrd->write_buf); > > > > Yes, thanks for that. We have two paths how Lustre interacts with ZFS - > requesting arc buffers or dmu_write. > The common dmu_request_arcbuf goes over arc_loan_buf, so we introduced > dmu_request_compressed_arcbuf to go over arc_loan_compressed_buf to > reuse the receive functionality. > We try to make as few changes as possible on Lustre's interface since > we want mix compressed and uncompressed data chunks (and be at the same > time compatible with ZFS' on disk format..) > The dmu_write path will be tricky, though. > > Any comments are welcome. > > Best regards > Anna > > -- > > Anna Fuchs > Universität Hamburg > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From baptiste.gerondeau at linaro.org Tue Jul 16 12:11:19 2019 From: baptiste.gerondeau at linaro.org (Baptiste Gerondeau) Date: Tue, 16 Jul 2019 14:11:19 +0200 Subject: [lustre-devel] Auster and no facet /usr/sbin/lctl Message-ID: Hi, I'm currently in the process of bringing up the "3 node" x86 cluster and running "verbose=true ./auster -f multinode -rsv runtests" (on CentOS 7.6 x86 client & server, installed from repos), I keep getting "MDS: No host defined for facet /usr/sbin/lctl". Auster then prints out some pdsh stuff, "Failures : 0" and exits after 16s obviously without running any tests. Any suggestions? Thanks a lot, PS : My multinode config is attached PPS: I posted to the devel list because it concerned auster, if I need to post it elsewhere please let me know -- Baptiste Gerondeau Engineer - HPC SIG - LDCG - Linaro #irc : BaptisteGer -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- [root at x8602 tests]# cat cfg/multinode.sh FSNAME=master FSTYPE=ldiskfs MOUNT=/mnt/lustre MOUNT2=/mnt/master2 # MDS and MDT configuration MDSCOUNT=1 mds_HOST="x86ohpc" mgs_HOST="x86ohpc" mdt_HOST="x86ohpc" MDSDEV1="/dev/sda2" # OSS and OST configuration OSTCOUNT=1 ost_HOST="x8601" OSTDEV1="/dev/sda2" # Client configuration CLIENTCOUNT=1 RCLIENTS="x8602" export PDSH_SSH_ARGS_APPEND="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/cluster" PDSH="/usr/bin/pdsh -l root -S -Rssh -d -w" SHARED_DIRECTORY=${SHARED_DIRECTORY:-/opt/ohpc/pub} From adilger at whamcloud.com Tue Jul 16 21:09:53 2019 From: adilger at whamcloud.com (Andreas Dilger) Date: Tue, 16 Jul 2019 21:09:53 +0000 Subject: [lustre-devel] Auster and no facet /usr/sbin/lctl In-Reply-To: References: Message-ID: <7AE1C6EF-B45C-4256-A28A-9A5E73C2BBCC@whamcloud.com> On Jul 16, 2019, at 06:11, Baptiste Gerondeau wrote: > > Hi, > > I'm currently in the process of bringing up the "3 node" x86 cluster and running "verbose=true ./auster -f multinode -rsv runtests" (on CentOS 7.6 x86 client & server, installed from repos), I keep getting "MDS: No host defined for facet /usr/sbin/lctl". > > Auster then prints out some pdsh stuff, "Failures : 0" and exits after 16s obviously without running any tests. > > Any suggestions? > Thanks a lot, > > > PS : My multinode config is attached > PPS: I posted to the devel list because it concerned auster, if I need to post it elsewhere please let me know Before running auster, which tries to launch a lot of tests, start with just a plain mount to see if that is working: master.sh: > MOUNT=/mnt/lustre > MOUNT2=/mnt/master2 This is a bit odd for tests, which normally have e.g. /mnt/master and /mnt/master2, but I'm not sure i there will be a problem or not. ### assume modules/utils are built ### modules/utils are installed or you are running out of the build directory ### ssh to the MDS and OSS nodes works without a password ### if you are not using @tcp0 for LNet, /etc/modprobe.d/lnet.conf is correct all# modprobe ptlrpc ### on client and OSS and MDS to start LNet x8602# lctl ping x86ohpc ### should print NID(s) of x860hpc x8602# lctl ping x8601 ### should print NID(s) of x8601 x8602# export NAME=master ### get config from lustre/tests/cfg/master.sh x8602# sh llmount.sh ### should format x86ohpc:/dev/sda2 and x8601:/dev/sda2 x8602# lfs df ### should show master-MDT0000 and master-OST0000 Cheers, Andreas -- Andreas Dilger Principal Lustre Architect Whamcloud From baptiste.gerondeau at linaro.org Thu Jul 18 10:29:17 2019 From: baptiste.gerondeau at linaro.org (Baptiste Gerondeau) Date: Thu, 18 Jul 2019 12:29:17 +0200 Subject: [lustre-devel] Auster and no facet /usr/sbin/lctl In-Reply-To: <7AE1C6EF-B45C-4256-A28A-9A5E73C2BBCC@whamcloud.com> References: <7AE1C6EF-B45C-4256-A28A-9A5E73C2BBCC@whamcloud.com> Message-ID: Thank you very much for your quick help ! I reformatted and remounted everything from scratch and can confirm that mounting works, and that the client can communicate with the MDS (210, OSS is 211 and client 212): [root at x8602 tests]# lnetctl net show net: - net type: lo local NI(s): - nid: 0 at lo status: up - net type: tcp local NI(s): - nid: 10.40.24.212 at tcp status: up interfaces: 0: eno1 [root at x8602 tests]# lnetctl peer show -v peer: - primary nid: 10.40.24.210 at tcp Multi-Rail: True peer ni: - nid: 10.40.24.210 at tcp state: NA max_ni_tx_credits: 8 available_tx_credits: 8 min_tx_credits: 6 tx_q_num_of_buf: 0 available_rtr_credits: 8 min_rtr_credits: 8 refcount: 1 statistics: send_count: 137546 recv_count: 137545 drop_count: 0 - primary nid: 10.40.24.212 at tcp Multi-Rail: True peer ni: - nid: 10.40.24.212 at tcp state: NA max_ni_tx_credits: 8 available_tx_credits: 8 min_tx_credits: -84 tx_q_num_of_buf: 0 available_rtr_credits: 8 min_rtr_credits: 8 refcount: 1 statistics: send_count: 291726 recv_count: 291726 drop_count: 0 - primary nid: 10.40.24.211 at tcp Multi-Rail: True peer ni: - nid: 10.40.24.211 at tcp state: NA max_ni_tx_credits: 8 available_tx_credits: 8 min_tx_credits: 7 tx_q_num_of_buf: 0 available_rtr_credits: 8 min_rtr_credits: 8 refcount: 1 statistics: send_count: 56 recv_count: 56 drop_count: 0 [root at x8602 tests]# lctl which_nid 10.40.24.210 at tcp 10.40.24.210 at tcp [root at x8602 tests]# lfs df -ih UUID Inodes IUsed IFree IUse% Mounted on test-MDT0000_UUID 4.0M 272 4.0M 1% /lustre[MDT:0] test-OST0000_UUID 640.0K 267 639.7K 0% /lustre[OST:0] filesystem_summary: 640.0K 272 639.7K 0% /lustre [root at x8602 tests]# ls -lsah /lustre/ total 12K 4.0K drwxr-xr-x 3 root root 4.0K Jul 18 11:03 . 4.0K dr-xr-xr-x. 19 root root 4.0K Jun 28 11:43 .. 4.0K -rw-r--r-- 1 root root 14 Jul 18 11:03 test.txt I get the same output from auster though: Client: Lustre version: 2.12.0 MDS: No host defined for facet /usr/sbin/lctl OSS: Lustre version: 2.12.0 >From the client I can ssh into the other nodes (and from each node I can ssh into the others). I had tried to debug the scripts behind the above auster output but was unable to track down where it failed... On Tue, 16 Jul 2019 at 23:09, Andreas Dilger wrote: > On Jul 16, 2019, at 06:11, Baptiste Gerondeau < > baptiste.gerondeau at linaro.org> wrote: > > > > Hi, > > > > I'm currently in the process of bringing up the "3 node" x86 cluster and > running "verbose=true ./auster -f multinode -rsv runtests" (on CentOS 7.6 > x86 client & server, installed from repos), I keep getting "MDS: No host > defined for facet /usr/sbin/lctl". > > > > Auster then prints out some pdsh stuff, "Failures : 0" and exits after > 16s obviously without running any tests. > > > > Any suggestions? > > Thanks a lot, > > > > > > PS : My multinode config is attached > > PPS: I posted to the devel list because it concerned auster, if I need > to post it elsewhere please let me know > > Before running auster, which tries to launch a lot of tests, start with > just a plain mount to see if that is working: > > master.sh: > > MOUNT=/mnt/lustre > > MOUNT2=/mnt/master2 > > This is a bit odd for tests, which normally have e.g. /mnt/master and > /mnt/master2, but I'm > not sure i there will be a problem or not. > > ### assume modules/utils are built > ### modules/utils are installed or you are running out of the build > directory > ### ssh to the MDS and OSS nodes works without a password > ### if you are not using @tcp0 for LNet, /etc/modprobe.d/lnet.conf is > correct > > all# modprobe ptlrpc ### on client and OSS and MDS to start LNet > x8602# lctl ping x86ohpc ### should print NID(s) of x860hpc > x8602# lctl ping x8601 ### should print NID(s) of x8601 > x8602# export NAME=master ### get config from > lustre/tests/cfg/master.sh > x8602# sh llmount.sh ### should format x86ohpc:/dev/sda2 and > x8601:/dev/sda2 > x8602# lfs df ### should show master-MDT0000 and > master-OST0000 > > Cheers, Andreas > -- > Andreas Dilger > Principal Lustre Architect > Whamcloud > > > > > > > -- Baptiste Gerondeau Engineer - HPC SIG - LDCG - Linaro #irc : BaptisteGer -------------- next part -------------- An HTML attachment was scrubbed... URL: From adilger at whamcloud.com Thu Jul 18 18:56:49 2019 From: adilger at whamcloud.com (Andreas Dilger) Date: Thu, 18 Jul 2019 18:56:49 +0000 Subject: [lustre-devel] Auster and no facet /usr/sbin/lctl In-Reply-To: References: <7AE1C6EF-B45C-4256-A28A-9A5E73C2BBCC@whamcloud.com> Message-ID: <257DDBDC-58B6-4D0E-904F-B141A4761C4C@whamcloud.com> On Jul 18, 2019, at 04:29, Baptiste Gerondeau wrote: > > Thank you very much for your quick help ! > I reformatted and remounted everything from scratch and can confirm that mounting works, and that the client can communicate with the MDS (210, OSS is 211 and client 212): [snip] > [root at x8602 tests]# lctl which_nid 10.40.24.210 at tcp > 10.40.24.210 at tcp > [root at x8602 tests]# lfs df -ih > UUID Inodes IUsed IFree IUse% Mounted on > test-MDT0000_UUID 4.0M 272 4.0M 1% /lustre[MDT:0] > test-OST0000_UUID 640.0K 267 639.7K 0% /lustre[OST:0] > > filesystem_summary: 640.0K 272 639.7K 0% /lustre > > [root at x8602 tests]# ls -lsah /lustre/ > total 12K > 4.0K drwxr-xr-x 3 root root 4.0K Jul 18 11:03 . > 4.0K dr-xr-xr-x. 19 root root 4.0K Jun 28 11:43 .. > 4.0K -rw-r--r-- 1 root root 14 Jul 18 11:03 test.txt > > I get the same output from auster though: > Client: Lustre version: 2.12.0 > MDS: No host defined for facet /usr/sbin/lctl This looks like some kind of problem with the test configuration file, where an environment variable is not set (e.g. mds_HOST) and it is interpreting the next argument (the lctl command) as the target facet when calling do_facet() or similar? If "llmount.sh" works, then you are also able to run tests directly like: client# cd lustre/tests client# sh sanity.sh I don't use auster myself (it is just a wrapper around lower-level scripts), so I can't really comment where the problem might be. Cheers, Andreas > OSS: Lustre version: 2.12.0 > > From the client I can ssh into the other nodes (and from each node I can ssh into the others). > I had tried to debug the scripts behind the above auster output but was unable to track down where it failed... > > On Tue, 16 Jul 2019 at 23:09, Andreas Dilger wrote: > On Jul 16, 2019, at 06:11, Baptiste Gerondeau wrote: > > > > Hi, > > > > I'm currently in the process of bringing up the "3 node" x86 cluster and running "verbose=true ./auster -f multinode -rsv runtests" (on CentOS 7.6 x86 client & server, installed from repos), I keep getting "MDS: No host defined for facet /usr/sbin/lctl". > > > > Auster then prints out some pdsh stuff, "Failures : 0" and exits after 16s obviously without running any tests. > > > > Any suggestions? > > Thanks a lot, > > > > > > PS : My multinode config is attached > > PPS: I posted to the devel list because it concerned auster, if I need to post it elsewhere please let me know > > Before running auster, which tries to launch a lot of tests, start with just a plain mount to see if that is working: > > master.sh: > > MOUNT=/mnt/lustre > > MOUNT2=/mnt/master2 > > This is a bit odd for tests, which normally have e.g. /mnt/master and /mnt/master2, but I'm > not sure i there will be a problem or not. > > ### assume modules/utils are built > ### modules/utils are installed or you are running out of the build directory > ### ssh to the MDS and OSS nodes works without a password > ### if you are not using @tcp0 for LNet, /etc/modprobe.d/lnet.conf is correct > > all# modprobe ptlrpc ### on client and OSS and MDS to start LNet > x8602# lctl ping x86ohpc ### should print NID(s) of x860hpc > x8602# lctl ping x8601 ### should print NID(s) of x8601 > x8602# export NAME=master ### get config from lustre/tests/cfg/master.sh > x8602# sh llmount.sh ### should format x86ohpc:/dev/sda2 and x8601:/dev/sda2 > x8602# lfs df ### should show master-MDT0000 and master-OST0000 > > Cheers, Andreas > -- > Andreas Dilger > Principal Lustre Architect > Whamcloud > > > > > > > > > -- > Baptiste Gerondeau > Engineer - HPC SIG - LDCG - Linaro > #irc : BaptisteGer Cheers, Andreas -- Andreas Dilger Principal Lustre Architect Whamcloud From degremoa at amazon.com Fri Jul 19 15:02:18 2019 From: degremoa at amazon.com (Degremont, Aurelien) Date: Fri, 19 Jul 2019 15:02:18 +0000 Subject: [lustre-devel] sanity-hsm and libtool Message-ID: Hi! I'm trying to run sanity-hsm.sh tests in my lustre source directory as I'm used to. Since libtool patch was landed, tools like lhsmtool_posix are executed through a wrapper and appear in process list as 'lt-lhsmtool_posix'. Some tests try to find and kill them, relying on command like: "ps -C $HSMTOOL" Even if run through "libtool execute ps -C $HSMTOOL" (as it is in the source right now) this command does not catch the proper process and so fail the test. I'm wondering what the proper way to run the test suite to have it working and how this is working in Maloo? I'm doing: git clone autogen configure make sudo REFORMAT=: ./lustre/tests/sanity-hsm.sh By the way, when hsm helper functions were moved from sanity-hsm.sh to test-framework.sh (f172b1168, for PCC), some of them were just copied and not moved. So there are several duplicates between these 2 files. I think that's not on purpose? Thanks Aurélien -------------- next part -------------- An HTML attachment was scrubbed... URL: From jsimmons at infradead.org Fri Jul 19 15:20:26 2019 From: jsimmons at infradead.org (James Simmons) Date: Fri, 19 Jul 2019 16:20:26 +0100 (BST) Subject: [lustre-devel] sanity-hsm and libtool In-Reply-To: References: Message-ID: > Hi! > >   > > I'm trying to run sanity-hsm.sh tests in my lustre source directory as I'm used to. > > Since libtool patch was landed, tools like lhsmtool_posix are executed through a wrapper and appear in process list as 'lt-lhsmtool_posix'. > > Some tests try to find and kill them, relying on command like: > >   > > "ps -C $HSMTOOL" > >   > > Even if run through "libtool execute ps -C $HSMTOOL" (as it is in the source right now) this command does not catch the proper process and > so fail the test. > >   > > I'm wondering what the proper way to run the test suite to have it working and how this is working in Maloo? > > I'm doing: > >   > > git clone > > autogen > > configure > > make > > sudo REFORMAT=: ./lustre/tests/sanity-hsm.sh > >   > >   > >   > > By the way, when hsm helper functions were moved from sanity-hsm.sh to test-framework.sh (f172b1168, for PCC), some of them were just > copied and not moved. So there are several duplicates between these 2 files. I think that's not on purpose? What version of lustre are you testing with? Their was a patch landed to handle this. LU-11742 test: have libtool execute the test binaries which is lustre commit f9e5224fbb60bb8b44753b7be10cb06108627f89. This has been back ported to 2.12 LTS. Can you see if your lustre tree has this fix. See https://www.gnu.org/software/libtool/manual/html_node/Debugging-executables.html for details about using libtool against the binary wrappers. From degremoa at amazon.com Fri Jul 19 15:44:47 2019 From: degremoa at amazon.com (Degremont, Aurelien) Date: Fri, 19 Jul 2019 15:44:47 +0000 Subject: [lustre-devel] sanity-hsm and libtool In-Reply-To: References: Message-ID: Le 19/07/2019 17:21, « James Simmons » a écrit : > Hi! > > > > I'm trying to run sanity-hsm.sh tests in my lustre source directory as I'm used to. > > Since libtool patch was landed, tools like lhsmtool_posix are executed through a wrapper and appear in process list as 'lt-lhsmtool_posix'. > > Some tests try to find and kill them, relying on command like: > > > > "ps -C $HSMTOOL" > > > > Even if run through "libtool execute ps -C $HSMTOOL" (as it is in the source right now) this command does not catch the proper process and > so fail the test. > > > > I'm wondering what the proper way to run the test suite to have it working and how this is working in Maloo? > > I'm doing: > > > > git clone > > autogen > > configure > > make > > sudo REFORMAT=: ./lustre/tests/sanity-hsm.sh > > > > > > > > By the way, when hsm helper functions were moved from sanity-hsm.sh to test-framework.sh (f172b1168, for PCC), some of them were just > copied and not moved. So there are several duplicates between these 2 files. I think that's not on purpose? What version of lustre are you testing with? Their was a patch landed to handle this. LU-11742 test: have libtool execute the test binaries which is lustre commit f9e5224fbb60bb8b44753b7be10cb06108627f89. This has been back ported to 2.12 LTS. Can you see if your lustre tree has this fix. See https://www.gnu.org/software/libtool/manual/html_node/Debugging-executables.html for details about using libtool against the binary wrappers. I'm running master. That's exactly the patch which is giving me issue. I can run sanity-hsm successfully prior to this patch, not after. Aurélien From quentin.bouget at gmail.com Fri Jul 19 19:52:46 2019 From: quentin.bouget at gmail.com (Quentin BOUGET) Date: Fri, 19 Jul 2019 21:52:46 +0200 Subject: [lustre-devel] sanity-hsm and libtool In-Reply-To: References: Message-ID: Le ven. 19 juil. 2019 à 17:44, Degremont, Aurelien a écrit : > > > Le 19/07/2019 17:21, « James Simmons » a écrit : > > > > Hi! > > > > > > > > I'm trying to run sanity-hsm.sh tests in my lustre source directory > as I'm used to. > > > > Since libtool patch was landed, tools like lhsmtool_posix are > executed through a wrapper and appear in process list as > 'lt-lhsmtool_posix'. > > > > Some tests try to find and kill them, relying on command like: > > > > > > > > "ps -C $HSMTOOL" > > > > > > > > Even if run through "libtool execute ps -C $HSMTOOL" (as it is in > the source right now) this command does not catch the proper process and > > so fail the test. > > > > > > > > I'm wondering what the proper way to run the test suite to have it > working and how this is working in Maloo? > > > > I'm doing: > > > > > > > > git clone > > > > autogen > > > > configure > > > > make > > > > sudo REFORMAT=: ./lustre/tests/sanity-hsm.sh > > > > > > > > > > > > > > > > By the way, when hsm helper functions were moved from sanity-hsm.sh > to test-framework.sh (f172b1168, for PCC), some of them were just > > copied and not moved. So there are several duplicates between these > 2 files. I think that's not on purpose? > > What version of lustre are you testing with? Their was a patch landed > to > handle this. > > LU-11742 test: have libtool execute the test binaries > > which is lustre commit f9e5224fbb60bb8b44753b7be10cb06108627f89. This > has > been back ported to 2.12 LTS. Can you see if your lustre tree has this > fix. > > See > https://www.gnu.org/software/libtool/manual/html_node/Debugging-executables.html > for details about using libtool against the binary wrappers. > > I'm running master. > That's exactly the patch which is giving me issue. > I can run sanity-hsm successfully prior to this patch, not after. > > Aurélien > I concur : I cannot run sanity-hsm on master. Works fine when checking out the commit right before the libtool patch , breaks if the patch is applied. With some testing it appears this is because "libtool execute" does does not use the PATH environment variable when it resolves paths : $> pwd /home/user/lustre-release $> export PATH=lustre/utils:/usr/bin $> which lhsmtool_posix /home/user/lustre-release/lustre/utils/lhsmtool_posix $> libtool execute echo lhsmtool_posix lhsmtool_posix $> libtool execute echo lustre/utils/lhsmtool_posix /home/user/lustre-release/luster/utils/.libs/lhsmtool_posix I suspect this works on Maloo because Maloo does not run tests from the git repo but rather from installed rpms (=> no libtool wrappers). @James, I can see you asked me a follow-up review on the patch that introduces this regressions, and I did not answer, Sorry about that. I will try to keep better track of patches I reviewed at least once... In this spirit, I will try to update my review of this change this weekend. =) Cheers, Quentin -------------- next part -------------- An HTML attachment was scrubbed... URL: From jsimmons at infradead.org Mon Jul 22 01:23:33 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:33 -0400 Subject: [lustre-devel] [PATCH 04/22] ext4: export inode management In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-5-git-send-email-jsimmons@infradead.org> Make ext4_delete_entry() exportable for osd-ldiskfs. Also add exportable ext4_create_inode(). Signed-off-by: James Simmons --- fs/ext4/ext4.h | 6 ++++++ fs/ext4/namei.c | 30 ++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 423ab4d..50f0c50 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2579,6 +2579,12 @@ extern int ext4_dirent_csum_verify(struct inode *inode, struct ext4_dir_entry *dirent); extern int ext4_orphan_add(handle_t *, struct inode *); extern int ext4_orphan_del(handle_t *, struct inode *); +extern struct inode *ext4_create_inode(handle_t *handle, + struct inode *dir, int mode, + uid_t *owner); +extern int ext4_delete_entry(handle_t *handle, struct inode * dir, + struct ext4_dir_entry_2 *de_del, + struct buffer_head *bh); extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash, __u32 start_minor_hash, __u32 *next_hash); extern int ext4_search_dir(struct buffer_head *bh, diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index a52b311..a42a2db 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2459,10 +2459,9 @@ int ext4_generic_delete_entry(handle_t *handle, return -ENOENT; } -static int ext4_delete_entry(handle_t *handle, - struct inode *dir, - struct ext4_dir_entry_2 *de_del, - struct buffer_head *bh) +int ext4_delete_entry(handle_t *handle, struct inode *dir, + struct ext4_dir_entry_2 *de_del, + struct buffer_head *bh) { int err, csum_size = 0; @@ -2499,6 +2498,7 @@ static int ext4_delete_entry(handle_t *handle, ext4_std_error(dir->i_sb, err); return err; } +EXPORT_SYMBOL(ext4_delete_entry); /* * Set directory link count to 1 if nlinks > EXT4_LINK_MAX, or if nlinks == 2 @@ -2545,6 +2545,28 @@ static int ext4_add_nondir(handle_t *handle, return err; } +/* Return locked inode, then the caller can modify the inode's states/flags + * before others finding it. The caller should unlock the inode by itself. + */ +struct inode *ext4_create_inode(handle_t *handle, struct inode *dir, int mode, + uid_t *owner) +{ + struct inode *inode; + + inode = ext4_new_inode(handle, dir, mode, NULL, 0, owner, 0); + if (!IS_ERR(inode)) { + if (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode)) { + inode->i_op = &ext4_special_inode_operations; + } else { + inode->i_op = &ext4_file_inode_operations; + inode->i_fop = &ext4_file_operations; + ext4_set_aops(inode); + } + } + return inode; +} +EXPORT_SYMBOL(ext4_create_inode); + /* * By the time this is called, we already have created * the directory cache entry for the new file, but it -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:36 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:36 -0400 Subject: [lustre-devel] [PATCH 07/22] ext4: update .. for hash indexed directory In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-8-git-send-email-jsimmons@infradead.org> Handle special .. case. Signed-off-by: James Simmons --- fs/ext4/namei.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 91fc7fe..dd64a10 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -2133,6 +2133,73 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname, return retval; } +/* update ".." for hash-indexed directory, split the item "." if necessary */ +static int ext4_update_dotdot(handle_t *handle, struct dentry *dentry, + struct inode *inode) +{ + struct inode *dir = dentry->d_parent->d_inode; + struct buffer_head *dir_block; + struct ext4_dir_entry_2 *de; + int len, journal = 0, err = 0; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + + if (IS_DIRSYNC(dir)) + handle->h_sync = 1; + + dir_block = ext4_bread(handle, dir, 0, 0); + if (IS_ERR(dir_block)) { + err = PTR_ERR(dir_block); + goto out; + } + + de = (struct ext4_dir_entry_2 *)dir_block->b_data; + /* the first item must be "." */ + assert(de->name_len == 1 && de->name[0] == '.'); + len = le16_to_cpu(de->rec_len); + assert(len >= EXT4_DIR_REC_LEN(1)); + if (len > EXT4_DIR_REC_LEN(1)) { + BUFFER_TRACE(dir_block, "get_write_access"); + err = ext4_journal_get_write_access(handle, dir_block); + if (err) + goto out_journal; + + journal = 1; + de->rec_len = cpu_to_le16(EXT4_DIR_REC_LEN(1)); + } + + len -= EXT4_DIR_REC_LEN(1); + assert(len == 0 || len >= EXT4_DIR_REC_LEN(2)); + de = (struct ext4_dir_entry_2 *) + ((char *) de + le16_to_cpu(de->rec_len)); + if (!journal) { + BUFFER_TRACE(dir_block, "get_write_access"); + err = ext4_journal_get_write_access(handle, dir_block); + if (err) + goto out_journal; + } + + de->inode = cpu_to_le32(inode->i_ino); + if (len > 0) + de->rec_len = cpu_to_le16(len); + else + assert(le16_to_cpu(de->rec_len) >= EXT4_DIR_REC_LEN(2)); + de->name_len = 2; + strcpy(de->name, ".."); + ext4_set_de_type(dir->i_sb, de, S_IFDIR); + +out_journal: + if (journal) { + BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata"); + err = ext4_handle_dirty_dirent_node(handle, dir, dir_block); + ext4_mark_inode_dirty(handle, dir); + } + brelse(dir_block); +out: + return err; +} + /* * ext4_add_entry() * @@ -2189,6 +2256,9 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, } if (is_dx(dir)) { + if (dentry->d_name.len == 2 && + memcmp(dentry->d_name.name, "..", 2) == 0) + return ext4_update_dotdot(handle, dentry, inode); retval = ext4_dx_add_entry(handle, &fname, dir, inode); if (!retval || (retval != ERR_BAD_DX_DIR)) goto out; -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:37 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:37 -0400 Subject: [lustre-devel] [PATCH 08/22] ext4: kill off struct dx_root In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-9-git-send-email-jsimmons@infradead.org> Use struct dx_root_info directly. Signed-off-by: James Simmons --- fs/ext4/namei.c | 110 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index dd64a10..4c45570 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -197,23 +197,13 @@ struct dx_entry * dirent the two low bits of the hash version will be zero. Therefore, the * hash version mod 4 should never be 0. Sincerely, the paranoia department. */ - -struct dx_root +struct dx_root_info { - struct fake_dirent dot; - char dot_name[4]; - struct fake_dirent dotdot; - char dotdot_name[4]; - struct dx_root_info - { - __le32 reserved_zero; - u8 hash_version; - u8 info_length; /* 8 */ - u8 indirect_levels; - u8 unused_flags; - } - info; - struct dx_entry entries[0]; + __le32 reserved_zero; + u8 hash_version; + u8 info_length; /* 8 */ + u8 indirect_levels; + u8 unused_flags; }; struct dx_node @@ -514,6 +504,16 @@ static inline int ext4_handle_dirty_dx_node(handle_t *handle, * Future: use high four bits of block for coalesce-on-delete flags * Mask them off for now. */ +struct dx_root_info *dx_get_dx_info(struct ext4_dir_entry_2 *de) +{ + /* get dotdot first */ + de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(1)); + + /* dx root info is after dotdot entry */ + de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(2)); + + return (struct dx_root_info *)de; +} static inline ext4_lblk_t dx_get_block(struct dx_entry *entry) { @@ -738,7 +738,7 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir, { unsigned count, indirect; struct dx_entry *at, *entries, *p, *q, *m; - struct dx_root *root; + struct dx_root_info *info; struct dx_frame *frame = frame_in; struct dx_frame *ret_err = ERR_PTR(ERR_BAD_DX_DIR); u32 hash; @@ -748,17 +748,17 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir, if (IS_ERR(frame->bh)) return (struct dx_frame *) frame->bh; - root = (struct dx_root *) frame->bh->b_data; - if (root->info.hash_version != DX_HASH_TEA && - root->info.hash_version != DX_HASH_HALF_MD4 && - root->info.hash_version != DX_HASH_LEGACY) { + info = dx_get_dx_info((struct ext4_dir_entry_2 *)frame->bh->b_data); + if (info->hash_version != DX_HASH_TEA && + info->hash_version != DX_HASH_HALF_MD4 && + info->hash_version != DX_HASH_LEGACY) { ext4_warning_inode(dir, "Unrecognised inode hash code %u for directory %lu", - root->info.hash_version, dir->i_ino); + info->hash_version, dir->i_ino); goto fail; } if (fname) hinfo = &fname->hinfo; - hinfo->hash_version = root->info.hash_version; + hinfo->hash_version = info->hash_version; if (hinfo->hash_version <= DX_HASH_TEA) hinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned; hinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed; @@ -766,13 +766,13 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir, ext4fs_dirhash(dir, fname_name(fname), fname_len(fname), hinfo); hash = hinfo->hash; - if (root->info.unused_flags & 1) { + if (info->unused_flags & 1) { ext4_warning_inode(dir, "Unimplemented hash flags: %#06x", - root->info.unused_flags); + info->unused_flags); goto fail; } - indirect = root->info.indirect_levels; + indirect = info->indirect_levels; if (indirect >= ext4_dir_htree_level(dir->i_sb)) { ext4_warning(dir->i_sb, "Directory (ino: %lu) htree depth %#06x exceed" @@ -785,14 +785,13 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir, goto fail; } - entries = (struct dx_entry *)(((char *)&root->info) + - root->info.info_length); + entries = (struct dx_entry *)(((char *)info) + info->info_length); if (dx_get_limit(entries) != dx_root_limit(dir, - root->info.info_length)) { + info->info_length)) { ext4_warning_inode(dir, "dx entry: limit %u != root limit %u", dx_get_limit(entries), - dx_root_limit(dir, root->info.info_length)); + dx_root_limit(dir, info->info_length)); goto fail; } @@ -877,7 +876,7 @@ static void dx_release(struct dx_frame *frames) if (frames[0].bh == NULL) return; - info = &((struct dx_root *)frames[0].bh->b_data)->info; + info = dx_get_dx_info((struct ext4_dir_entry_2 *)frames[0].bh->b_data); /* save local copy, "info" may be freed after brelse() */ indirect_levels = info->indirect_levels; for (i = 0; i <= indirect_levels; i++) { @@ -2020,17 +2019,16 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname, struct inode *inode, struct buffer_head *bh) { struct buffer_head *bh2; - struct dx_root *root; struct dx_frame frames[EXT4_HTREE_LEVEL], *frame; struct dx_entry *entries; - struct ext4_dir_entry_2 *de, *de2; + struct ext4_dir_entry_2 *de, *de2, *dot_de, *dotdot_de; struct ext4_dir_entry_tail *t; char *data1, *top; unsigned len; int retval; unsigned blocksize; ext4_lblk_t block; - struct fake_dirent *fde; + struct dx_root_info *dx_info; int csum_size = 0; if (ext4_has_metadata_csum(inode->i_sb)) @@ -2045,18 +2043,19 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname, brelse(bh); return retval; } - root = (struct dx_root *) bh->b_data; + + dot_de = (struct ext4_dir_entry_2 *)bh->b_data; + dotdot_de = ext4_next_entry(dot_de, blocksize); /* The 0th block becomes the root, move the dirents out */ - fde = &root->dotdot; - de = (struct ext4_dir_entry_2 *)((char *)fde + - ext4_rec_len_from_disk(fde->rec_len, blocksize)); - if ((char *) de >= (((char *) root) + blocksize)) { + de = (struct ext4_dir_entry_2 *)((char *)dotdot_de + + ext4_rec_len_from_disk(dotdot_de->rec_len, blocksize)); + if ((char *)de >= (((char *)dot_de) + blocksize)) { EXT4_ERROR_INODE(dir, "invalid rec_len for '..'"); brelse(bh); return -EFSCORRUPTED; } - len = ((char *) root) + (blocksize - csum_size) - (char *) de; + len = ((char *)dot_de) + (blocksize - csum_size) - (char *) de; /* Allocate new block for the 0th block's dirents */ bh2 = ext4_append(handle, dir, &block); @@ -2082,19 +2081,24 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname, } /* Initialize the root; the dot dirents already exist */ - de = (struct ext4_dir_entry_2 *) (&root->dotdot); - de->rec_len = ext4_rec_len_to_disk(blocksize - EXT4_DIR_REC_LEN(2), - blocksize); - memset (&root->info, 0, sizeof(root->info)); - root->info.info_length = sizeof(root->info); - root->info.hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version; - entries = root->entries; + dotdot_de->rec_len = + ext4_rec_len_to_disk(blocksize - le16_to_cpu(dot_de->rec_len), + blocksize); + + /* initialize hashing info */ + dx_info = dx_get_dx_info(dot_de); + memset(dx_info, 0, sizeof(*dx_info)); + dx_info->info_length = sizeof(*dx_info); + dx_info->hash_version = EXT4_SB(dir->i_sb)->s_def_hash_version; + + entries = (void *)dx_info + sizeof(*dx_info); + dx_set_block(entries, 1); dx_set_count(entries, 1); - dx_set_limit(entries, dx_root_limit(dir, sizeof(root->info))); + dx_set_limit(entries, dx_root_limit(dir, sizeof(*dx_info))); /* Initialize as for dx_probe */ - fname->hinfo.hash_version = root->info.hash_version; + fname->hinfo.hash_version = dx_info->hash_version; if (fname->hinfo.hash_version <= DX_HASH_TEA) fname->hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned; fname->hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed; @@ -2443,7 +2447,8 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, goto journal_error; } } else { - struct dx_root *dxroot; + struct dx_root_info *info; + memcpy((char *) entries2, (char *) entries, icount * sizeof(struct dx_entry)); dx_set_limit(entries2, dx_node_limit(dir)); @@ -2451,8 +2456,9 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, /* Set up root */ dx_set_count(entries, 1); dx_set_block(entries + 0, newblock); - dxroot = (struct dx_root *)frames[0].bh->b_data; - dxroot->info.indirect_levels += 1; + info = dx_get_dx_info((struct ext4_dir_entry_2 *) + frames[0].bh->b_data); + info->indirect_levels += 1; dxtrace(printk(KERN_DEBUG "Creating %d level index...\n", dxroot->info.indirect_levels)); -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:42 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:42 -0400 Subject: [lustre-devel] [PATCH 13/22] ext4: Add a proc interface for max_dir_size. In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-14-git-send-email-jsimmons@infradead.org> Signed-off-by: James Simmons --- fs/ext4/sysfs.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c index 1375815..3a71a16 100644 --- a/fs/ext4/sysfs.c +++ b/fs/ext4/sysfs.c @@ -180,6 +180,8 @@ static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf) EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, inode_readahead, ext4_sb_info, s_inode_readahead_blks); EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal); +EXT4_RW_ATTR_SBI_UI(max_dir_size, s_max_dir_size_kb); +EXT4_RW_ATTR_SBI_UI(max_dir_size_kb, s_max_dir_size_kb); EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats); EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan); EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan); @@ -210,6 +212,8 @@ static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf) ATTR_LIST(reserved_clusters), ATTR_LIST(inode_readahead_blks), ATTR_LIST(inode_goal), + ATTR_LIST(max_dir_size), + ATTR_LIST(max_dir_size_kb), ATTR_LIST(mb_stats), ATTR_LIST(mb_max_to_scan), ATTR_LIST(mb_min_to_scan), @@ -350,6 +354,8 @@ static ssize_t ext4_attr_store(struct kobject *kobj, ret = kstrtoul(skip_spaces(buf), 0, &t); if (ret) return ret; + if (strcmp("max_dir_size", a->attr.name) == 0) + t >>= 10; if (a->attr_ptr == ptr_ext4_super_block_offset) *((__le32 *) ptr) = cpu_to_le32(t); else -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:30 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:30 -0400 Subject: [lustre-devel] [PATCH 01/22] ext4: add i_fs_version In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-2-git-send-email-jsimmons@infradead.org> From: James Simmons Add inode version field that osd-ldiskfs uses. Signed-off-by: James Simmons --- fs/ext4/ext4.h | 2 ++ fs/ext4/ialloc.c | 1 + fs/ext4/inode.c | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 1cb6785..8abbcab 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1063,6 +1063,8 @@ struct ext4_inode_info { struct dquot *i_dquot[MAXQUOTAS]; #endif + u64 i_fs_version; + /* Precomputed uuid+inum+igen checksum for seeding inode checksums */ __u32 i_csum_seed; diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 764ff4c..09ae4a4 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -1100,6 +1100,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir, ei->i_dtime = 0; ei->i_block_group = group; ei->i_last_alloc_group = ~0; + ei->i_fs_version = 0; ext4_set_inode_flags(inode); if (IS_DIRSYNC(inode)) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index c7f77c6..6e66175 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4806,14 +4806,14 @@ static inline void ext4_inode_set_iversion_queried(struct inode *inode, u64 val) if (unlikely(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) inode_set_iversion_raw(inode, val); else - inode_set_iversion_queried(inode, val); + EXT4_I(inode)->i_fs_version = val; } static inline u64 ext4_inode_peek_iversion(const struct inode *inode) { if (unlikely(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) return inode_peek_iversion_raw(inode); else - return inode_peek_iversion(inode); + return EXT4_I(inode)->i_fs_version; } struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:31 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:31 -0400 Subject: [lustre-devel] [PATCH 02/22] ext4: use d_find_alias() in ext4_lookup In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-3-git-send-email-jsimmons@infradead.org> From: James Simmons Really old bug that might not even exist anymore? Signed-off-by: James Simmons --- fs/ext4/namei.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index cd01c4a..a616f58 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1664,6 +1664,35 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi } } + /* ".." shouldn't go into dcache to preserve dcache hierarchy + * otherwise we'll get parent being a child of actual child. + * see bug 10458 for details -bzzz + */ + if (inode && (dentry->d_name.name[0] == '.' && + (dentry->d_name.len == 1 || (dentry->d_name.len == 2 && + dentry->d_name.name[1] == '.')))) { + struct dentry *goal = NULL; + + /* first, look for an existing dentry - any one is good */ + goal = d_find_any_alias(inode); + if (!goal) { + spin_lock(&dentry->d_lock); + /* there is no alias, we need to make current dentry: + * a) inaccessible for __d_lookup() + * b) inaccessible for iopen + */ + J_ASSERT(hlist_unhashed(&dentry->d_u.d_alias)); + dentry->d_flags |= DCACHE_NFSFS_RENAMED; + /* this is d_instantiate() ... */ + hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry); + dentry->d_inode = inode; + spin_unlock(&dentry->d_lock); + } + if (goal) + iput(inode); + return goal; + } + #ifdef CONFIG_UNICODE if (!inode && IS_CASEFOLDED(dir)) { /* Eventually we want to call d_add_ci(dentry, NULL) -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:32 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:32 -0400 Subject: [lustre-devel] [PATCH 03/22] ext4: prealloc table optimization In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-4-git-send-email-jsimmons@infradead.org> Optimize prealloc table Signed-off-by: James Simmons --- fs/ext4/ext4.h | 7 +- fs/ext4/inode.c | 3 + fs/ext4/mballoc.c | 221 +++++++++++++++++++++++++++++++++++++++++------------- fs/ext4/namei.c | 4 +- fs/ext4/sysfs.c | 8 +- 5 files changed, 186 insertions(+), 57 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 8abbcab..423ab4d 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1190,6 +1190,8 @@ struct ext4_inode_info { /* Metadata checksum algorithm codes */ #define EXT4_CRC32C_CHKSUM 1 +#define EXT4_MAX_PREALLOC_TABLE 64 + /* * Structure of the super block */ @@ -1447,12 +1449,14 @@ struct ext4_sb_info { /* tunables */ unsigned long s_stripe; - unsigned int s_mb_stream_request; + unsigned long s_mb_small_req; + unsigned long s_mb_large_req; unsigned int s_mb_max_to_scan; unsigned int s_mb_min_to_scan; unsigned int s_mb_stats; unsigned int s_mb_order2_reqs; unsigned int s_mb_group_prealloc; + unsigned long *s_mb_prealloc_table; unsigned int s_max_dir_size_kb; /* where last allocation was done - for stream allocation */ unsigned long s_mb_last_group; @@ -2457,6 +2461,7 @@ extern int ext4_init_inode_table(struct super_block *sb, extern void ext4_end_bitmap_read(struct buffer_head *bh, int uptodate); /* mballoc.c */ +extern const struct file_operations ext4_seq_prealloc_table_fops; extern const struct seq_operations ext4_mb_seq_groups_ops; extern long ext4_mb_stats; extern long ext4_mb_max_to_scan; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 6e66175..c37418a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2796,6 +2796,9 @@ static int ext4_writepages(struct address_space *mapping, ext4_journal_stop(handle); } + if (wbc->nr_to_write < sbi->s_mb_small_req) + wbc->nr_to_write = sbi->s_mb_small_req; + if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) range_whole = 1; diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 99ba720..3be3bef 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2339,6 +2339,101 @@ static void ext4_mb_seq_groups_stop(struct seq_file *seq, void *v) .show = ext4_mb_seq_groups_show, }; +static int ext4_mb_check_and_update_prealloc(struct ext4_sb_info *sbi, + char *str, size_t cnt, + int update) +{ + unsigned long value; + unsigned long prev = 0; + char *cur; + char *next; + char *end; + int num = 0; + + cur = str; + end = str + cnt; + while (cur < end) { + while ((cur < end) && (*cur == ' ')) cur++; + /* Yuck - simple_strtol */ + value = simple_strtol(cur, &next, 0); + if (value == 0) + break; + if (cur == next) + return -EINVAL; + + cur = next; + + if (value > (sbi->s_blocks_per_group - 1 - 1 - sbi->s_itb_per_group)) + return -EINVAL; + + /* they should add values in order */ + if (value <= prev) + return -EINVAL; + + if (update) + sbi->s_mb_prealloc_table[num] = value; + + prev = value; + num++; + } + + if (num > EXT4_MAX_PREALLOC_TABLE - 1) + return -EOVERFLOW; + + if (update) + sbi->s_mb_prealloc_table[num] = 0; + + return 0; +} + +static ssize_t ext4_mb_prealloc_table_proc_write(struct file *file, + const char __user *buf, + size_t cnt, loff_t *pos) +{ + struct ext4_sb_info *sbi = EXT4_SB(PDE_DATA(file_inode(file))); + char str[128]; + int rc; + + if (cnt >= sizeof(str)) + return -EINVAL; + if (copy_from_user(str, buf, cnt)) + return -EFAULT; + + rc = ext4_mb_check_and_update_prealloc(sbi, str, cnt, 0); + if (rc) + return rc; + + rc = ext4_mb_check_and_update_prealloc(sbi, str, cnt, 1); + return rc ? rc : cnt; +} + +static int mb_prealloc_table_seq_show(struct seq_file *m, void *v) +{ + struct ext4_sb_info *sbi = EXT4_SB(m->private); + int i; + + for (i = 0; i < EXT4_MAX_PREALLOC_TABLE && + sbi->s_mb_prealloc_table[i] != 0; i++) + seq_printf(m, "%ld ", sbi->s_mb_prealloc_table[i]); + seq_printf(m, "\n"); + + return 0; +} + +static int mb_prealloc_table_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, mb_prealloc_table_seq_show, PDE_DATA(inode)); +} + +const struct file_operations ext4_seq_prealloc_table_fops = { + .owner = THIS_MODULE, + .open = mb_prealloc_table_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = ext4_mb_prealloc_table_proc_write, +}; + static struct kmem_cache *get_groupinfo_cache(int blocksize_bits) { int cache_index = blocksize_bits - EXT4_MIN_BLOCK_LOG_SIZE; @@ -2567,7 +2662,7 @@ static int ext4_groupinfo_create_slab(size_t size) int ext4_mb_init(struct super_block *sb) { struct ext4_sb_info *sbi = EXT4_SB(sb); - unsigned i, j; + unsigned i, j, k, l; unsigned offset, offset_incr; unsigned max; int ret; @@ -2616,7 +2711,6 @@ int ext4_mb_init(struct super_block *sb) sbi->s_mb_max_to_scan = MB_DEFAULT_MAX_TO_SCAN; sbi->s_mb_min_to_scan = MB_DEFAULT_MIN_TO_SCAN; sbi->s_mb_stats = MB_DEFAULT_STATS; - sbi->s_mb_stream_request = MB_DEFAULT_STREAM_THRESHOLD; sbi->s_mb_order2_reqs = MB_DEFAULT_ORDER2_REQS; /* * The default group preallocation is 512, which for 4k block @@ -2640,9 +2734,28 @@ int ext4_mb_init(struct super_block *sb) * RAID stripe size so that preallocations don't fragment * the stripes. */ - if (sbi->s_stripe > 1) { - sbi->s_mb_group_prealloc = roundup( - sbi->s_mb_group_prealloc, sbi->s_stripe); + /* Allocate table once */ + sbi->s_mb_prealloc_table = kzalloc( + EXT4_MAX_PREALLOC_TABLE * sizeof(unsigned long), GFP_NOFS); + if (!sbi->s_mb_prealloc_table) { + ret = -ENOMEM; + goto out; + } + + if (sbi->s_stripe == 0) { + for (k = 0, l = 4; k <= 9; ++k, l *= 2) + sbi->s_mb_prealloc_table[k] = l; + + sbi->s_mb_small_req = 256; + sbi->s_mb_large_req = 1024; + sbi->s_mb_group_prealloc = 512; + } else { + for (k = 0, l = sbi->s_stripe; k <= 2; ++k, l *= 2) + sbi->s_mb_prealloc_table[k] = l; + + sbi->s_mb_small_req = sbi->s_stripe; + sbi->s_mb_large_req = sbi->s_stripe * 8; + sbi->s_mb_group_prealloc = sbi->s_stripe * 4; } sbi->s_locality_groups = alloc_percpu(struct ext4_locality_group); @@ -2670,6 +2783,7 @@ int ext4_mb_init(struct super_block *sb) free_percpu(sbi->s_locality_groups); sbi->s_locality_groups = NULL; out: + kfree(sbi->s_mb_prealloc_table); kfree(sbi->s_mb_offsets); sbi->s_mb_offsets = NULL; kfree(sbi->s_mb_maxs); @@ -2932,7 +3046,6 @@ void ext4_exit_mballoc(void) int err, len; BUG_ON(ac->ac_status != AC_STATUS_FOUND); - BUG_ON(ac->ac_b_ex.fe_len <= 0); sb = ac->ac_sb; sbi = EXT4_SB(sb); @@ -3062,13 +3175,14 @@ static void ext4_mb_normalize_group_request(struct ext4_allocation_context *ac) struct ext4_allocation_request *ar) { struct ext4_sb_info *sbi = EXT4_SB(ac->ac_sb); - int bsbits, max; + int bsbits, i, wind; ext4_lblk_t end; - loff_t size, start_off; + loff_t size; loff_t orig_size __maybe_unused; ext4_lblk_t start; struct ext4_inode_info *ei = EXT4_I(ac->ac_inode); struct ext4_prealloc_space *pa; + unsigned long value, last_non_zero; /* do normalize only data requests, metadata requests do not need preallocation */ @@ -3097,51 +3211,47 @@ static void ext4_mb_normalize_group_request(struct ext4_allocation_context *ac) size = size << bsbits; if (size < i_size_read(ac->ac_inode)) size = i_size_read(ac->ac_inode); - orig_size = size; + size = (size + ac->ac_sb->s_blocksize - 1) >> bsbits; - /* max size of free chunks */ - max = 2 << bsbits; - -#define NRL_CHECK_SIZE(req, size, max, chunk_size) \ - (req <= (size) || max <= (chunk_size)) - - /* first, try to predict filesize */ - /* XXX: should this table be tunable? */ - start_off = 0; - if (size <= 16 * 1024) { - size = 16 * 1024; - } else if (size <= 32 * 1024) { - size = 32 * 1024; - } else if (size <= 64 * 1024) { - size = 64 * 1024; - } else if (size <= 128 * 1024) { - size = 128 * 1024; - } else if (size <= 256 * 1024) { - size = 256 * 1024; - } else if (size <= 512 * 1024) { - size = 512 * 1024; - } else if (size <= 1024 * 1024) { - size = 1024 * 1024; - } else if (NRL_CHECK_SIZE(size, 4 * 1024 * 1024, max, 2 * 1024)) { - start_off = ((loff_t)ac->ac_o_ex.fe_logical >> - (21 - bsbits)) << 21; - size = 2 * 1024 * 1024; - } else if (NRL_CHECK_SIZE(size, 8 * 1024 * 1024, max, 4 * 1024)) { - start_off = ((loff_t)ac->ac_o_ex.fe_logical >> - (22 - bsbits)) << 22; - size = 4 * 1024 * 1024; - } else if (NRL_CHECK_SIZE(ac->ac_o_ex.fe_len, - (8<<20)>>bsbits, max, 8 * 1024)) { - start_off = ((loff_t)ac->ac_o_ex.fe_logical >> - (23 - bsbits)) << 23; - size = 8 * 1024 * 1024; + start = wind = 0; + value = last_non_zero = 0; + + /* let's choose preallocation window depending on file size */ + for (i = 0; i < EXT4_MAX_PREALLOC_TABLE; i++) { + value = sbi->s_mb_prealloc_table[i]; + if (value == 0) + break; + else + last_non_zero = value; + + if (size <= value) { + wind = value; + break; + } + } + + if (wind == 0) { + if (last_non_zero != 0) { + u64 tstart, tend; + + /* file is quite large, we now preallocate with + * the biggest configured window with regart to + * logical offset + */ + wind = last_non_zero; + tstart = ac->ac_o_ex.fe_logical; + do_div(tstart, wind); + start = tstart * wind; + tend = ac->ac_o_ex.fe_logical + ac->ac_o_ex.fe_len - 1; + do_div(tend, wind); + tend = tend * wind + wind; + size = tend - start; + } } else { - start_off = (loff_t) ac->ac_o_ex.fe_logical << bsbits; - size = (loff_t) EXT4_C2B(EXT4_SB(ac->ac_sb), - ac->ac_o_ex.fe_len) << bsbits; + size = wind; } - size = size >> bsbits; - start = start_off >> bsbits; + + orig_size = size; /* don't cover already allocated blocks in selected range */ if (ar->pleft && start <= ar->lleft) { @@ -3223,7 +3333,6 @@ static void ext4_mb_normalize_group_request(struct ext4_allocation_context *ac) (unsigned long) ac->ac_o_ex.fe_logical); BUG(); } - BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); /* now prepare goal request */ @@ -4191,11 +4300,19 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac) /* don't use group allocation for large files */ size = max(size, isize); - if (size > sbi->s_mb_stream_request) { + if ((ac->ac_o_ex.fe_len >= sbi->s_mb_small_req) || + (size >= sbi->s_mb_large_req)) { ac->ac_flags |= EXT4_MB_STREAM_ALLOC; return; } + /* + * request is so large that we don't care about + * streaming - it overweights any possible seek + */ + if (ac->ac_o_ex.fe_len >= sbi->s_mb_large_req) + return; + BUG_ON(ac->ac_lg != NULL); /* * locality group prealloc space are per cpu. The reason for having diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index a616f58..a52b311 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -752,8 +752,8 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir, if (root->info.hash_version != DX_HASH_TEA && root->info.hash_version != DX_HASH_HALF_MD4 && root->info.hash_version != DX_HASH_LEGACY) { - ext4_warning_inode(dir, "Unrecognised inode hash code %u", - root->info.hash_version); + ext4_warning_inode(dir, "Unrecognised inode hash code %u for directory %lu", + root->info.hash_version, dir->i_ino); goto fail; } if (fname) diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c index 04b4f53..1375815 100644 --- a/fs/ext4/sysfs.c +++ b/fs/ext4/sysfs.c @@ -184,7 +184,8 @@ static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf) EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan); EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan); EXT4_RW_ATTR_SBI_UI(mb_order2_req, s_mb_order2_reqs); -EXT4_RW_ATTR_SBI_UI(mb_stream_req, s_mb_stream_request); +EXT4_RW_ATTR_SBI_UI(mb_small_req, s_mb_small_req); +EXT4_RW_ATTR_SBI_UI(mb_large_req, s_mb_large_req); EXT4_RW_ATTR_SBI_UI(mb_group_prealloc, s_mb_group_prealloc); EXT4_RW_ATTR_SBI_UI(extent_max_zeroout_kb, s_extent_max_zeroout_kb); EXT4_ATTR(trigger_fs_error, 0200, trigger_test_error); @@ -213,7 +214,8 @@ static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf) ATTR_LIST(mb_max_to_scan), ATTR_LIST(mb_min_to_scan), ATTR_LIST(mb_order2_req), - ATTR_LIST(mb_stream_req), + ATTR_LIST(mb_small_req), + ATTR_LIST(mb_large_req), ATTR_LIST(mb_group_prealloc), ATTR_LIST(max_writeback_mb_bump), ATTR_LIST(extent_max_zeroout_kb), @@ -413,6 +415,8 @@ int ext4_register_sysfs(struct super_block *sb) sb); proc_create_seq_data("mb_groups", S_IRUGO, sbi->s_proc, &ext4_mb_seq_groups_ops, sb); + proc_create_data("prealloc_table", S_IRUGO, sbi->s_proc, + &ext4_seq_prealloc_table_fops, sb); } return 0; } -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:38 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:38 -0400 Subject: [lustre-devel] [PATCH 09/22] ext4: fix mballoc pa free mismatch In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-10-git-send-email-jsimmons@infradead.org> Intoduce pa_error so we can find any mballoc pa cleanup problems. Signed-off-by: James Simmons --- fs/ext4/mballoc.c | 45 +++++++++++++++++++++++++++++++++++++++------ fs/ext4/mballoc.h | 2 ++ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 483fc0f..463fba6 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -3863,6 +3863,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, INIT_LIST_HEAD(&pa->pa_group_list); pa->pa_deleted = 0; pa->pa_type = MB_INODE_PA; + pa->pa_error = 0; mb_debug(1, "new inode pa %p: %llu/%u for %u\n", pa, pa->pa_pstart, pa->pa_len, pa->pa_lstart); @@ -3924,6 +3925,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, INIT_LIST_HEAD(&pa->pa_group_list); pa->pa_deleted = 0; pa->pa_type = MB_GROUP_PA; + pa->pa_error = 0; mb_debug(1, "new group pa %p: %llu/%u for %u\n", pa, pa->pa_pstart, pa->pa_len, pa->pa_lstart); @@ -3983,7 +3985,9 @@ static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac) unsigned long long grp_blk_start; int free = 0; + assert_spin_locked(ext4_group_lock_ptr(sb, e4b->bd_group)); BUG_ON(pa->pa_deleted == 0); + BUG_ON(pa->pa_inode == NULL); ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); grp_blk_start = pa->pa_pstart - EXT4_C2B(sbi, bit); BUG_ON(group != e4b->bd_group && pa->pa_len != 0); @@ -4006,12 +4010,19 @@ static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac) mb_free_blocks(pa->pa_inode, e4b, bit, next - bit); bit = next + 1; } - if (free != pa->pa_free) { - ext4_msg(e4b->bd_sb, KERN_CRIT, - "pa %p: logic %lu, phys. %lu, len %lu", - pa, (unsigned long) pa->pa_lstart, - (unsigned long) pa->pa_pstart, - (unsigned long) pa->pa_len); + + /* "free < pa->pa_free" means we maybe double alloc the same blocks, + * otherwise maybe leave some free blocks unavailable, no need to BUG. + */ + if ((free > pa->pa_free && !pa->pa_error) || (free < pa->pa_free)) { + ext4_error(sb, "pa free mismatch: [pa %p] " + "[phy %lu] [logic %lu] [len %u] [free %u] " + "[error %u] [inode %lu] [freed %u]", pa, + (unsigned long)pa->pa_pstart, + (unsigned long)pa->pa_lstart, + (unsigned)pa->pa_len, (unsigned)pa->pa_free, + (unsigned)pa->pa_error, pa->pa_inode->i_ino, + free); ext4_grp_locked_error(sb, group, 0, 0, "free %u, pa_free %u", free, pa->pa_free); /* @@ -4019,6 +4030,8 @@ static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac) * from the bitmap and continue. */ } + /* do not verify if the file system is being umounted */ + BUG_ON(atomic_read(&sb->s_active) > 0 && pa->pa_free != free); atomic_add(free, &sbi->s_mb_discarded); return 0; @@ -4764,6 +4777,26 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, ac->ac_b_ex.fe_len = 0; ar->len = 0; ext4_mb_show_ac(ac); + if (ac->ac_pa) { + struct ext4_prealloc_space *pa = ac->ac_pa; + + /* We can not make sure whether the bitmap has + * been updated or not when fail case. So can + * not revert pa_free back, just mark pa_error + */ + pa->pa_error++; + ext4_error(sb, + "Updating bitmap error: [err %d] " + "[pa %p] [phy %lu] [logic %lu] " + "[len %u] [free %u] [error %u] " + "[inode %lu]", *errp, pa, + (unsigned long)pa->pa_pstart, + (unsigned long)pa->pa_lstart, + (unsigned)pa->pa_len, + (unsigned)pa->pa_free, + (unsigned)pa->pa_error, + pa->pa_inode ? pa->pa_inode->i_ino : 0); + } } ext4_mb_release_context(ac); out: diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h index 8325ad9..e00c3b7 100644 --- a/fs/ext4/mballoc.h +++ b/fs/ext4/mballoc.h @@ -20,6 +20,7 @@ #include #include #include +#include #include "ext4_jbd2.h" #include "ext4.h" @@ -111,6 +112,7 @@ struct ext4_prealloc_space { ext4_grpblk_t pa_len; /* len of preallocated chunk */ ext4_grpblk_t pa_free; /* how many blocks are free */ unsigned short pa_type; /* pa type. inode or group */ + unsigned short pa_error; spinlock_t *pa_obj_lock; struct inode *pa_inode; /* hack, for history only */ }; -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:39 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:39 -0400 Subject: [lustre-devel] [PATCH 10/22] ext4: add data in dentry feature In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-11-git-send-email-jsimmons@infradead.org> Lustre likes to stuff extra data into dentrys. Signed-off-by: James Simmons --- fs/ext4/dir.c | 14 ++-- fs/ext4/ext4.h | 92 +++++++++++++++++++++-- fs/ext4/inline.c | 16 ++-- fs/ext4/namei.c | 217 +++++++++++++++++++++++++++++++++++++++++++------------ fs/ext4/super.c | 4 +- 5 files changed, 278 insertions(+), 65 deletions(-) diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index c7843b1..20e0d32 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -70,11 +70,11 @@ int __ext4_check_dir_entry(const char *function, unsigned int line, const int rlen = ext4_rec_len_from_disk(de->rec_len, dir->i_sb->s_blocksize); - if (unlikely(rlen < EXT4_DIR_REC_LEN(1))) + if (unlikely(rlen < __EXT4_DIR_REC_LEN(1))) error_msg = "rec_len is smaller than minimal"; else if (unlikely(rlen % 4 != 0)) error_msg = "rec_len % 4 != 0"; - else if (unlikely(rlen < EXT4_DIR_REC_LEN(de->name_len))) + else if (unlikely(rlen < __EXT4_DIR_REC_LEN(de->name_len))) error_msg = "rec_len is too small for name_len"; else if (unlikely(((char *) de - buf) + rlen > size)) error_msg = "directory entry overrun"; @@ -219,7 +219,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx) * failure will be detected in the * dirent test below. */ if (ext4_rec_len_from_disk(de->rec_len, - sb->s_blocksize) < EXT4_DIR_REC_LEN(1)) + sb->s_blocksize) < __EXT4_DIR_REC_LEN(1)) break; i += ext4_rec_len_from_disk(de->rec_len, sb->s_blocksize); @@ -441,13 +441,17 @@ int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, struct rb_node **p, *parent = NULL; struct fname *fname, *new_fn; struct dir_private_info *info; + int extra_data = 0; int len; info = dir_file->private_data; p = &info->root.rb_node; /* Create and allocate the fname structure */ - len = sizeof(struct fname) + ent_name->len + 1; + if (dirent->file_type & EXT4_DIRENT_LUFID) + extra_data = ext4_get_dirent_data_len(dirent); + + len = sizeof(struct fname) + ent_name->len + extra_data + 1; new_fn = kzalloc(len, GFP_KERNEL); if (!new_fn) return -ENOMEM; @@ -456,7 +460,7 @@ int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, new_fn->inode = le32_to_cpu(dirent->inode); new_fn->name_len = ent_name->len; new_fn->file_type = dirent->file_type; - memcpy(new_fn->name, ent_name->name, ent_name->len); + memcpy(new_fn->name, ent_name->name, ent_name->len + extra_data); new_fn->name[ent_name->len] = 0; while (*p) { diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index e321286..51b6159 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1069,6 +1069,7 @@ struct ext4_inode_info { __u32 i_csum_seed; kprojid_t i_projid; + void *i_dirdata; }; /* @@ -1112,6 +1113,7 @@ struct ext4_inode_info { #define EXT4_MOUNT_POSIX_ACL 0x08000 /* POSIX 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_DIRDATA 0x40000 /* Data in directory entries */ #define EXT4_MOUNT_QUOTA 0x40000 /* Some quota option set */ #define EXT4_MOUNT_USRQUOTA 0x80000 /* "old" user quota, * enable enforcement for hidden @@ -1805,6 +1807,7 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei) EXT4_FEATURE_INCOMPAT_FLEX_BG| \ EXT4_FEATURE_INCOMPAT_EA_INODE| \ EXT4_FEATURE_INCOMPAT_MMP | \ + EXT4_FEATURE_INCOMPAT_DIRDATA | \ EXT4_FEATURE_INCOMPAT_INLINE_DATA | \ EXT4_FEATURE_INCOMPAT_ENCRYPT | \ EXT4_FEATURE_INCOMPAT_CASEFOLD | \ @@ -1984,6 +1987,43 @@ struct ext4_dir_entry_tail { #define EXT4_FT_SYMLINK 7 #define EXT4_FT_MAX 8 +#define EXT4_FT_MASK 0xf + +#if EXT4_FT_MAX > EXT4_FT_MASK +#error "conflicting EXT4_FT_MAX and EXT4_FT_MASK" +#endif + +/* + * d_type has 4 unused bits, so it can hold four types data. these different + * type of data (e.g. lustre data, high 32 bits of 64-bit inode number) can be + * stored, in flag order, after file-name in ext4 dirent. +*/ +/* + * this flag is added to d_type if ext4 dirent has extra data after + * filename. this data length is variable and length is stored in first byte + * of data. data start after filename NUL byte. + * This is used by Lustre FS. + */ +#define EXT4_DIRENT_LUFID 0x10 + +#define EXT4_LUFID_MAGIC 0xAD200907UL +struct ext4_dentry_param { + __u32 edp_magic; /* EXT4_LUFID_MAGIC */ + char edp_len; /* size of edp_data in bytes */ + char edp_data[0]; /* packed array of data */ +} __packed; + +static inline unsigned char *ext4_dentry_get_data(struct super_block *sb, + struct ext4_dentry_param *p) +{ + if (!ext4_has_feature_dirdata(sb)) + return NULL; + + if (p && p->edp_magic == EXT4_LUFID_MAGIC) + return &p->edp_len; + else + return NULL; +} #define EXT4_FT_DIR_CSUM 0xDE @@ -1994,8 +2034,11 @@ struct ext4_dir_entry_tail { */ #define EXT4_DIR_PAD 4 #define EXT4_DIR_ROUND (EXT4_DIR_PAD - 1) -#define EXT4_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT4_DIR_ROUND) & \ +#define __EXT4_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT4_DIR_ROUND) & \ ~EXT4_DIR_ROUND) +#define EXT4_DIR_REC_LEN(de) (__EXT4_DIR_REC_LEN((de)->name_len +\ + ext4_get_dirent_data_len(de))) + #define EXT4_MAX_REC_LEN ((1<<16)-1) /* @@ -2422,11 +2465,11 @@ extern int ext4_find_dest_de(struct inode *dir, struct inode *inode, struct buffer_head *bh, void *buf, int buf_size, struct ext4_filename *fname, - struct ext4_dir_entry_2 **dest_de); + struct ext4_dir_entry_2 **dest_de, int *dlen); void ext4_insert_dentry(struct inode *inode, struct ext4_dir_entry_2 *de, int buf_size, - struct ext4_filename *fname); + struct ext4_filename *fname, void *data); static inline void ext4_update_dx_flag(struct inode *inode) { if (!ext4_has_feature_dir_index(inode->i_sb)) @@ -2438,11 +2481,18 @@ static inline void ext4_update_dx_flag(struct inode *inode) static inline unsigned char get_dtype(struct super_block *sb, int filetype) { - if (!ext4_has_feature_filetype(sb) || filetype >= EXT4_FT_MAX) + int fl_index = filetype & EXT4_FT_MASK; + + if (!ext4_has_feature_filetype(sb) || fl_index >= EXT4_FT_MAX) return DT_UNKNOWN; - return ext4_filetype_table[filetype]; + if (!test_opt(sb, DIRDATA)) + return ext4_filetype_table[fl_index]; + + return (ext4_filetype_table[fl_index]) | + (filetype & EXT4_DIRENT_LUFID); } + extern int ext4_check_all_de(struct inode *dir, struct buffer_head *bh, void *buf, int buf_size); @@ -2604,6 +2654,8 @@ extern struct inode *ext4_create_inode(handle_t *handle, extern int ext4_delete_entry(handle_t *handle, struct inode * dir, struct ext4_dir_entry_2 *de_del, struct buffer_head *bh); +extern int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir, + struct inode *inode, const void *, const void *); extern int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash, __u32 start_minor_hash, __u32 *next_hash); extern int ext4_search_dir(struct buffer_head *bh, @@ -3339,6 +3391,36 @@ static inline void ext4_clear_io_unwritten_flag(ext4_io_end_t *io_end) extern const struct iomap_ops ext4_iomap_ops; +/* + * Compute the total directory entry data length. + * This includes the filename and an implicit NUL terminator (always present), + * and optional extensions. Each extension has a bit set in the high 4 bits of + * de->file_type, and the extension length is the first byte in each entry. + */ +static inline int ext4_get_dirent_data_len(struct ext4_dir_entry_2 *de) +{ + char *len = de->name + de->name_len + 1 /* NUL terminator */; + int dlen = 0; + u8 extra_data_flags = (de->file_type & ~EXT4_FT_MASK) >> 4; + struct ext4_dir_entry_tail *t = (struct ext4_dir_entry_tail *)de; + + if (!t->det_reserved_zero1 && + le16_to_cpu(t->det_rec_len) == + sizeof(struct ext4_dir_entry_tail) && + !t->det_reserved_zero2 && + t->det_reserved_ft == EXT4_FT_DIR_CSUM) + return 0; + + while (extra_data_flags) { + if (extra_data_flags & 1) { + dlen += *len + (dlen == 0); + len += *len; + } + extra_data_flags >>= 1; + } + return dlen; +} + #endif /* __KERNEL__ */ #define EFSBADCRC EBADMSG /* Bad CRC detected */ diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index f73bc39..7610cfe 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -1023,7 +1023,7 @@ static int ext4_add_dirent_to_inline(handle_t *handle, struct ext4_dir_entry_2 *de; err = ext4_find_dest_de(dir, inode, iloc->bh, inline_start, - inline_size, fname, &de); + inline_size, fname, &de, NULL); if (err) return err; @@ -1031,7 +1031,7 @@ static int ext4_add_dirent_to_inline(handle_t *handle, err = ext4_journal_get_write_access(handle, iloc->bh); if (err) return err; - ext4_insert_dentry(inode, de, inline_size, fname); + ext4_insert_dentry(inode, de, inline_size, fname, NULL); ext4_show_inline_dir(dir, iloc->bh, inline_start, inline_size); @@ -1100,7 +1100,7 @@ static int ext4_update_inline_dir(handle_t *handle, struct inode *dir, int old_size = EXT4_I(dir)->i_inline_size - EXT4_MIN_INLINE_DATA_SIZE; int new_size = get_max_inline_xattr_value_size(dir, iloc); - if (new_size - old_size <= EXT4_DIR_REC_LEN(1)) + if (new_size - old_size <= __EXT4_DIR_REC_LEN(1)) return -ENOSPC; ret = ext4_update_inline_data(handle, dir, @@ -1381,7 +1381,7 @@ int htree_inlinedir_to_tree(struct file *dir_file, fake.name_len = 1; strcpy(fake.name, "."); fake.rec_len = ext4_rec_len_to_disk( - EXT4_DIR_REC_LEN(fake.name_len), + EXT4_DIR_REC_LEN(&fake), inline_size); ext4_set_de_type(inode->i_sb, &fake, S_IFDIR); de = &fake; @@ -1391,7 +1391,7 @@ int htree_inlinedir_to_tree(struct file *dir_file, fake.name_len = 2; strcpy(fake.name, ".."); fake.rec_len = ext4_rec_len_to_disk( - EXT4_DIR_REC_LEN(fake.name_len), + EXT4_DIR_REC_LEN(&fake), inline_size); ext4_set_de_type(inode->i_sb, &fake, S_IFDIR); de = &fake; @@ -1489,8 +1489,8 @@ int ext4_read_inline_dir(struct file *file, * So we will use extra_offset and extra_size to indicate them * during the inline dir iteration. */ - dotdot_offset = EXT4_DIR_REC_LEN(1); - dotdot_size = dotdot_offset + EXT4_DIR_REC_LEN(2); + dotdot_offset = __EXT4_DIR_REC_LEN(1); + dotdot_size = dotdot_offset + __EXT4_DIR_REC_LEN(2); extra_offset = dotdot_size - EXT4_INLINE_DOTDOT_SIZE; extra_size = extra_offset + inline_size; @@ -1525,7 +1525,7 @@ int ext4_read_inline_dir(struct file *file, * failure will be detected in the * dirent test below. */ if (ext4_rec_len_from_disk(de->rec_len, extra_size) - < EXT4_DIR_REC_LEN(1)) + < __EXT4_DIR_REC_LEN(1)) break; i += ext4_rec_len_from_disk(de->rec_len, extra_size); diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 4c45570..9cb86e4 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -243,7 +243,9 @@ struct dx_tail { static unsigned dx_get_limit(struct dx_entry *entries); static void dx_set_count(struct dx_entry *entries, unsigned value); static void dx_set_limit(struct dx_entry *entries, unsigned value); -static unsigned dx_root_limit(struct inode *dir, unsigned infosize); +static unsigned int inline dx_root_limit(struct inode *dir, + struct ext4_dir_entry_2 *dot_de, + unsigned int infosize); static unsigned dx_node_limit(struct inode *dir); static struct dx_frame *dx_probe(struct ext4_filename *fname, struct inode *dir, @@ -384,24 +386,26 @@ static struct dx_countlimit *get_dx_countlimit(struct inode *inode, struct ext4_dir_entry *dirent, int *offset) { + int dot_rec_len, dotdot_rec_len; struct ext4_dir_entry *dp; struct dx_root_info *root; int count_offset; if (le16_to_cpu(dirent->rec_len) == EXT4_BLOCK_SIZE(inode->i_sb)) count_offset = 8; - else if (le16_to_cpu(dirent->rec_len) == 12) { - dp = (struct ext4_dir_entry *)(((void *)dirent) + 12); + else { + dot_rec_len = le16_to_cpu(dirent->rec_len); + dp = (struct ext4_dir_entry *)(((void *)dirent) + dot_rec_len); if (le16_to_cpu(dp->rec_len) != - EXT4_BLOCK_SIZE(inode->i_sb) - 12) + EXT4_BLOCK_SIZE(inode->i_sb) - dot_rec_len) return NULL; - root = (struct dx_root_info *)(((void *)dp + 12)); + dotdot_rec_len = EXT4_DIR_REC_LEN((struct ext4_dir_entry_2 *)dp); + root = (struct dx_root_info *)(((void *)dp + dotdot_rec_len)); if (root->reserved_zero || root->info_length != sizeof(struct dx_root_info)) return NULL; - count_offset = 32; - } else - return NULL; + count_offset = 8 + dot_rec_len + dotdot_rec_len; + } if (offset) *offset = count_offset; @@ -507,10 +511,10 @@ static inline int ext4_handle_dirty_dx_node(handle_t *handle, struct dx_root_info *dx_get_dx_info(struct ext4_dir_entry_2 *de) { /* get dotdot first */ - de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(1)); + de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(de)); /* dx root info is after dotdot entry */ - de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(2)); + de = (struct ext4_dir_entry_2 *)((char *)de + EXT4_DIR_REC_LEN(de)); return (struct dx_root_info *)de; } @@ -555,10 +559,17 @@ static inline void dx_set_limit(struct dx_entry *entries, unsigned value) ((struct dx_countlimit *) entries)->limit = cpu_to_le16(value); } -static inline unsigned dx_root_limit(struct inode *dir, unsigned infosize) +static inline unsigned int dx_root_limit(struct inode *dir, + struct ext4_dir_entry_2 *dot_de, + unsigned int infosize) { - unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(1) - - EXT4_DIR_REC_LEN(2) - infosize; + struct ext4_dir_entry_2 *dotdot_de; + unsigned int entry_space; + + BUG_ON(dot_de->name_len != 1); + dotdot_de = ext4_next_entry(dot_de, dir->i_sb->s_blocksize); + entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(dot_de) - + EXT4_DIR_REC_LEN(dotdot_de) - infosize; if (ext4_has_metadata_csum(dir->i_sb)) entry_space -= sizeof(struct dx_tail); @@ -567,7 +578,7 @@ static inline unsigned dx_root_limit(struct inode *dir, unsigned infosize) static inline unsigned dx_node_limit(struct inode *dir) { - unsigned entry_space = dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0); + unsigned entry_space = dir->i_sb->s_blocksize - __EXT4_DIR_REC_LEN(0); if (ext4_has_metadata_csum(dir->i_sb)) entry_space -= sizeof(struct dx_tail); @@ -679,7 +690,7 @@ static struct stats dx_show_leaf(struct inode *dir, (unsigned) ((char *) de - base)); #endif } - space += EXT4_DIR_REC_LEN(de->name_len); + space += EXT4_DIR_REC_LEN(de); names++; } de = ext4_next_entry(de, size); @@ -787,11 +798,14 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir, entries = (struct dx_entry *)(((char *)info) + info->info_length); - if (dx_get_limit(entries) != dx_root_limit(dir, - info->info_length)) { + if (dx_get_limit(entries) != + dx_root_limit(dir, (struct ext4_dir_entry_2 *)frame->bh->b_data, + info->info_length)) { ext4_warning_inode(dir, "dx entry: limit %u != root limit %u", dx_get_limit(entries), - dx_root_limit(dir, info->info_length)); + dx_root_limit(dir, + (struct ext4_dir_entry_2 *)frame->bh->b_data, + info->info_length)); goto fail; } @@ -986,7 +1000,7 @@ static int htree_dirblock_to_tree(struct file *dir_file, de = (struct ext4_dir_entry_2 *) bh->b_data; top = (struct ext4_dir_entry_2 *) ((char *) de + dir->i_sb->s_blocksize - - EXT4_DIR_REC_LEN(0)); + __EXT4_DIR_REC_LEN(0)); #ifdef CONFIG_FS_ENCRYPTION /* Check if the directory is encrypted */ if (IS_ENCRYPTED(dir)) { @@ -1743,7 +1757,7 @@ struct dentry *ext4_get_parent(struct dentry *child) while (count--) { struct ext4_dir_entry_2 *de = (struct ext4_dir_entry_2 *) (from + (map->offs<<2)); - rec_len = EXT4_DIR_REC_LEN(de->name_len); + rec_len = EXT4_DIR_REC_LEN(de); memcpy (to, de, rec_len); ((struct ext4_dir_entry_2 *) to)->rec_len = ext4_rec_len_to_disk(rec_len, blocksize); @@ -1767,7 +1781,7 @@ static struct ext4_dir_entry_2* dx_pack_dirents(char *base, unsigned blocksize) while ((char*)de < base + blocksize) { next = ext4_next_entry(de, blocksize); if (de->inode && de->name_len) { - rec_len = EXT4_DIR_REC_LEN(de->name_len); + rec_len = EXT4_DIR_REC_LEN(de); if (de > to) memmove(to, de, rec_len); to->rec_len = ext4_rec_len_to_disk(rec_len, blocksize); @@ -1898,14 +1912,16 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode, struct buffer_head *bh, void *buf, int buf_size, struct ext4_filename *fname, - struct ext4_dir_entry_2 **dest_de) + struct ext4_dir_entry_2 **dest_de, int *dlen) { struct ext4_dir_entry_2 *de; - unsigned short reclen = EXT4_DIR_REC_LEN(fname_len(fname)); + unsigned short reclen = __EXT4_DIR_REC_LEN(fname_len(fname)) + + (dlen ? *dlen : 0); int nlen, rlen; unsigned int offset = 0; char *top; + dlen ? *dlen = 0 : 0; /* default set to 0 */ de = (struct ext4_dir_entry_2 *)buf; top = buf + buf_size - reclen; while ((char *) de <= top) { @@ -1914,10 +1930,29 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode, return -EFSCORRUPTED; if (ext4_match(dir, fname, de)) return -EEXIST; - nlen = EXT4_DIR_REC_LEN(de->name_len); + nlen = EXT4_DIR_REC_LEN(de); rlen = ext4_rec_len_from_disk(de->rec_len, buf_size); if ((de->inode ? rlen - nlen : rlen) >= reclen) break; + /* Then for dotdot entries, check for the smaller space + * required for just the entry, no FID + */ + if (fname_len(fname) == 2 && memcmp(fname_name(fname), "..", 2) == 0) { + if ((de->inode ? rlen - nlen : rlen) >= + __EXT4_DIR_REC_LEN(fname_len(fname))) { + /* set dlen=1 to indicate not + * enough space store fid + */ + dlen ? *dlen = 1 : 0; + break; + } + /* The new ".." entry must be written over the + * previous ".." entry, which is the first + * entry traversed by this scan. If it doesn't + * fit, something is badly wrong, so -EIO. + */ + return -EIO; + } de = (struct ext4_dir_entry_2 *)((char *)de + rlen); offset += rlen; } @@ -1931,12 +1966,12 @@ int ext4_find_dest_de(struct inode *dir, struct inode *inode, void ext4_insert_dentry(struct inode *inode, struct ext4_dir_entry_2 *de, int buf_size, - struct ext4_filename *fname) + struct ext4_filename *fname, void *data ) { int nlen, rlen; - nlen = EXT4_DIR_REC_LEN(de->name_len); + nlen = EXT4_DIR_REC_LEN(de); rlen = ext4_rec_len_from_disk(de->rec_len, buf_size); if (de->inode) { struct ext4_dir_entry_2 *de1 = @@ -1950,6 +1985,11 @@ void ext4_insert_dentry(struct inode *inode, ext4_set_de_type(inode->i_sb, de, inode->i_mode); de->name_len = fname_len(fname); memcpy(de->name, fname_name(fname), fname_len(fname)); + if (data) { + de->name[fname_len(fname)] = 0; + memcpy(&de->name[fname_len(fname) + 1], data, *(char *)data); + de->file_type |= EXT4_DIRENT_LUFID; + } } /* @@ -1966,15 +2006,21 @@ static int add_dirent_to_buf(handle_t *handle, struct ext4_filename *fname, struct buffer_head *bh) { unsigned int blocksize = dir->i_sb->s_blocksize; + unsigned char *data; int csum_size = 0; + int dlen = 0; int err; + data = ext4_dentry_get_data(inode->i_sb, + (struct ext4_dentry_param *)EXT4_I(inode)->i_dirdata); if (ext4_has_metadata_csum(inode->i_sb)) csum_size = sizeof(struct ext4_dir_entry_tail); if (!de) { + if (data) + dlen = (*data) + 1; err = ext4_find_dest_de(dir, inode, bh, bh->b_data, - blocksize - csum_size, fname, &de); + blocksize - csum_size, fname, &de, &dlen); if (err) return err; } @@ -1986,7 +2032,10 @@ static int add_dirent_to_buf(handle_t *handle, struct ext4_filename *fname, } /* By now the buffer is marked for journaling */ - ext4_insert_dentry(inode, de, blocksize, fname); + /* If writing the short form of "dotdot", don't add the data section */ + if (dlen == 1) + data = NULL; + ext4_insert_dentry(inode, de, blocksize, fname, data); /* * XXX shouldn't update any times until successful @@ -2095,7 +2144,8 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname, dx_set_block(entries, 1); dx_set_count(entries, 1); - dx_set_limit(entries, dx_root_limit(dir, sizeof(*dx_info))); + dx_set_limit(entries, dx_root_limit(dir, dot_de, + sizeof(*dx_info))); /* Initialize as for dx_probe */ fname->hinfo.hash_version = dx_info->hash_version; @@ -2145,6 +2195,8 @@ static int ext4_update_dotdot(handle_t *handle, struct dentry *dentry, struct buffer_head *dir_block; struct ext4_dir_entry_2 *de; int len, journal = 0, err = 0; + int dlen = 0; + char *data; if (IS_ERR(handle)) return PTR_ERR(handle); @@ -2162,19 +2214,24 @@ static int ext4_update_dotdot(handle_t *handle, struct dentry *dentry, /* the first item must be "." */ assert(de->name_len == 1 && de->name[0] == '.'); len = le16_to_cpu(de->rec_len); - assert(len >= EXT4_DIR_REC_LEN(1)); - if (len > EXT4_DIR_REC_LEN(1)) { + assert(len >= __EXT4_DIR_REC_LEN(1)); + if (len > __EXT4_DIR_REC_LEN(1)) { BUFFER_TRACE(dir_block, "get_write_access"); err = ext4_journal_get_write_access(handle, dir_block); if (err) goto out_journal; journal = 1; - de->rec_len = cpu_to_le16(EXT4_DIR_REC_LEN(1)); + de->rec_len = cpu_to_le16(EXT4_DIR_REC_LEN(de)); } - len -= EXT4_DIR_REC_LEN(1); - assert(len == 0 || len >= EXT4_DIR_REC_LEN(2)); + len -= EXT4_DIR_REC_LEN(de); + data = ext4_dentry_get_data(dir->i_sb, + (struct ext4_dentry_param *)dentry->d_fsdata); + if (data) + dlen = *data + 1; + assert(len == 0 || len >= __EXT4_DIR_REC_LEN(2 + dlen)); + de = (struct ext4_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len)); if (!journal) { @@ -2188,10 +2245,15 @@ static int ext4_update_dotdot(handle_t *handle, struct dentry *dentry, if (len > 0) de->rec_len = cpu_to_le16(len); else - assert(le16_to_cpu(de->rec_len) >= EXT4_DIR_REC_LEN(2)); + assert(le16_to_cpu(de->rec_len) >= __EXT4_DIR_REC_LEN(2)); de->name_len = 2; strcpy(de->name, ".."); - ext4_set_de_type(dir->i_sb, de, S_IFDIR); + if (data && ext4_get_dirent_data_len(de) >= dlen) { + de->name[2] = 0; + memcpy(&de->name[2 + 1], data, *data); + ext4_set_de_type(dir->i_sb, de, S_IFDIR); + de->file_type |= EXT4_DIRENT_LUFID; + } out_journal: if (journal) { @@ -2230,6 +2292,7 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, ext4_lblk_t block, blocks; int csum_size = 0; + EXT4_I(inode)->i_dirdata = dentry->d_fsdata; if (ext4_has_metadata_csum(inode->i_sb)) csum_size = sizeof(struct ext4_dir_entry_tail); @@ -2757,37 +2820,71 @@ static int ext4_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode) return err; } +struct tp_block { + struct inode *inode; + void *data1; + void *data2; +}; + struct ext4_dir_entry_2 *ext4_init_dot_dotdot(struct inode *inode, struct ext4_dir_entry_2 *de, int blocksize, int csum_size, unsigned int parent_ino, int dotdot_real_len) { + void *data1 = NULL, *data2 = NULL; + int dot_reclen = 0; + + if (dotdot_real_len == 10) { + struct tp_block *tpb = (struct tp_block *)inode; + + data1 = tpb->data1; + data2 = tpb->data2; + inode = tpb->inode; + dotdot_real_len = 0; + } de->inode = cpu_to_le32(inode->i_ino); de->name_len = 1; - de->rec_len = ext4_rec_len_to_disk(EXT4_DIR_REC_LEN(de->name_len), - blocksize); strcpy(de->name, "."); ext4_set_de_type(inode->i_sb, de, S_IFDIR); + /* get packed fid data*/ + data1 = ext4_dentry_get_data(inode->i_sb, + (struct ext4_dentry_param *) data1); + if (data1) { + de->name[1] = 0; + memcpy(&de->name[2], data1, *(char *) data1); + de->file_type |= EXT4_DIRENT_LUFID; + } + de->rec_len = cpu_to_le16(EXT4_DIR_REC_LEN(de)); + dot_reclen = cpu_to_le16(de->rec_len); de = ext4_next_entry(de, blocksize); de->inode = cpu_to_le32(parent_ino); de->name_len = 2; + strcpy(de->name, ".."); + ext4_set_de_type(inode->i_sb, de, S_IFDIR); + data2 = ext4_dentry_get_data(inode->i_sb, + (struct ext4_dentry_param *) data2); + if (data2) { + de->name[2] = 0; + memcpy(&de->name[3], data2, *(char *) data2); + de->file_type |= EXT4_DIRENT_LUFID; + } if (!dotdot_real_len) de->rec_len = ext4_rec_len_to_disk(blocksize - - (csum_size + EXT4_DIR_REC_LEN(1)), + (csum_size + dot_reclen), blocksize); else de->rec_len = ext4_rec_len_to_disk( - EXT4_DIR_REC_LEN(de->name_len), blocksize); - strcpy(de->name, ".."); - ext4_set_de_type(inode->i_sb, de, S_IFDIR); + EXT4_DIR_REC_LEN(de), blocksize); return ext4_next_entry(de, blocksize); } static int ext4_init_new_dir(handle_t *handle, struct inode *dir, - struct inode *inode) + struct inode *inode, + const void *data1, const void *data2) { + struct tp_block param; struct buffer_head *dir_block = NULL; struct ext4_dir_entry_2 *de; struct ext4_dir_entry_tail *t; @@ -2812,7 +2909,11 @@ static int ext4_init_new_dir(handle_t *handle, struct inode *dir, if (IS_ERR(dir_block)) return PTR_ERR(dir_block); de = (struct ext4_dir_entry_2 *)dir_block->b_data; - ext4_init_dot_dotdot(inode, de, blocksize, csum_size, dir->i_ino, 0); + param.inode = inode; + param.data1 = (void *)data1; + param.data2 = (void *)data2; + ext4_init_dot_dotdot((struct inode *)(¶m), de, blocksize, + csum_size, dir->i_ino, 10); set_nlink(inode, 2); if (csum_size) { t = EXT4_DIRENT_TAIL(dir_block->b_data, blocksize); @@ -2829,6 +2930,30 @@ static int ext4_init_new_dir(handle_t *handle, struct inode *dir, return err; } +/* Initialize @inode as a subdirectory of @dir, and add the + * "." and ".." entries into the first directory block. + */ +int ext4_add_dot_dotdot(handle_t *handle, struct inode *dir, + struct inode *inode, + const void *data1, const void *data2) +{ + int rc; + + if (IS_ERR(handle)) + return PTR_ERR(handle); + + if (IS_DIRSYNC(dir)) + ext4_handle_sync(handle); + + inode->i_op = &ext4_dir_inode_operations; + inode->i_fop = &ext4_dir_operations; + rc = ext4_init_new_dir(handle, dir, inode, data1, data2); + if (!rc) + rc = ext4_mark_inode_dirty(handle, inode); + return rc; +} +EXPORT_SYMBOL(ext4_add_dot_dotdot); + static int ext4_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) { handle_t *handle; @@ -2855,7 +2980,7 @@ static int ext4_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) inode->i_op = &ext4_dir_inode_operations; inode->i_fop = &ext4_dir_operations; - err = ext4_init_new_dir(handle, dir, inode); + err = ext4_init_new_dir(handle, dir, inode, NULL, NULL); if (err) goto out_clear_inode; err = ext4_mark_inode_dirty(handle, inode); @@ -2906,7 +3031,7 @@ bool ext4_empty_dir(struct inode *inode) } sb = inode->i_sb; - if (inode->i_size < EXT4_DIR_REC_LEN(1) + EXT4_DIR_REC_LEN(2)) { + if (inode->i_size < __EXT4_DIR_REC_LEN(1) + __EXT4_DIR_REC_LEN(2)) { EXT4_ERROR_INODE(inode, "invalid size"); return true; } diff --git a/fs/ext4/super.c b/fs/ext4/super.c index d15c26c..564eb35 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1447,7 +1447,7 @@ enum { Opt_data_err_abort, Opt_data_err_ignore, Opt_test_dummy_encryption, Opt_usrjquota, Opt_grpjquota, Opt_offusrjquota, Opt_offgrpjquota, Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, - Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err, + Opt_noquota, Opt_barrier, Opt_nobarrier, Opt_err, Opt_dirdata, Opt_usrquota, Opt_grpquota, Opt_prjquota, Opt_i_version, Opt_dax, Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_warn_on_error, Opt_nowarn_on_error, Opt_mblk_io_submit, @@ -1474,6 +1474,7 @@ enum { {Opt_err_ro, "errors=remount-ro"}, {Opt_nouid32, "nouid32"}, {Opt_debug, "debug"}, + {Opt_dirdata, "dirdata"}, {Opt_removed, "oldalloc"}, {Opt_removed, "orlov"}, {Opt_user_xattr, "user_xattr"}, @@ -1747,6 +1748,7 @@ static int clear_qf_name(struct super_block *sb, int qtype) {Opt_grpjquota, 0, MOPT_Q}, {Opt_offusrjquota, 0, MOPT_Q}, {Opt_offgrpjquota, 0, MOPT_Q}, + {Opt_dirdata, EXT4_MOUNT_DIRDATA, MOPT_SET}, {Opt_jqfmt_vfsold, QFMT_VFS_OLD, MOPT_QFMT}, {Opt_jqfmt_vfsv0, QFMT_VFS_V0, MOPT_QFMT}, {Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT}, -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:40 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:40 -0400 Subject: [lustre-devel] [PATCH 11/22] ext4: over ride current_time In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-12-git-send-email-jsimmons@infradead.org> return i_ctime if IS_NOCMTIME is true for inode. Signed-off-by: James Simmons --- fs/ext4/ext4.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 51b6159..80601a9 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -661,6 +661,13 @@ enum { #define EXT4_GOING_FLAGS_LOGFLUSH 0x1 /* flush log but not data */ #define EXT4_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */ +static inline struct timespec64 ext4_current_time(struct inode *inode) +{ + if (IS_NOCMTIME(inode)) + return inode->i_ctime; + return current_time(inode); +} +#define current_time(a) ext4_current_time(a) #if defined(__KERNEL__) && defined(CONFIG_COMPAT) /* -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:35 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:35 -0400 Subject: [lustre-devel] [PATCH 06/22] ext4: add extra checks for mballoc In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-7-git-send-email-jsimmons@infradead.org> Handle mballoc corruptions. Signed-off-by: James Simmons --- fs/ext4/ext4.h | 1 + fs/ext4/mballoc.c | 110 +++++++++++++++++++++++++++++++++++++++++++++--------- fs/ext4/mballoc.h | 2 +- 3 files changed, 94 insertions(+), 19 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index eb2d124..e321286 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2957,6 +2957,7 @@ struct ext4_group_info { ext4_grpblk_t bb_fragments; /* nr of freespace fragments */ ext4_grpblk_t bb_largest_free_order;/* order of largest frag in BG */ struct list_head bb_prealloc_list; + unsigned long bb_prealloc_nr; #ifdef DOUBLE_CHECK void *bb_bitmap; #endif diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 3be3bef..483fc0f 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -352,8 +352,8 @@ "ext4_groupinfo_64k", "ext4_groupinfo_128k" }; -static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, - ext4_group_t group); +static int ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, + ext4_group_t group); static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, ext4_group_t group); @@ -708,8 +708,8 @@ static void ext4_mb_mark_free_simple(struct super_block *sb, } static noinline_for_stack -void ext4_mb_generate_buddy(struct super_block *sb, - void *buddy, void *bitmap, ext4_group_t group) +int ext4_mb_generate_buddy(struct super_block *sb, + void *buddy, void *bitmap, ext4_group_t group) { struct ext4_group_info *grp = ext4_get_group_info(sb, group); struct ext4_sb_info *sbi = EXT4_SB(sb); @@ -752,6 +752,7 @@ void ext4_mb_generate_buddy(struct super_block *sb, grp->bb_free = free; ext4_mark_group_bitmap_corrupted(sb, group, EXT4_GROUP_INFO_BBITMAP_CORRUPT); + return -EIO; } mb_set_largest_free_order(sb, grp); @@ -762,6 +763,8 @@ void ext4_mb_generate_buddy(struct super_block *sb, sbi->s_mb_buddies_generated++; sbi->s_mb_generation_time += period; spin_unlock(&sbi->s_bal_lock); + + return 0; } static void mb_regenerate_buddy(struct ext4_buddy *e4b) @@ -882,7 +885,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore, gfp_t gfp) } first_block = page->index * blocks_per_page; - for (i = 0; i < blocks_per_page; i++) { + for (i = 0; i < blocks_per_page && err == 0; i++) { group = (first_block + i) >> 1; if (group >= ngroups) break; @@ -926,7 +929,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore, gfp_t gfp) ext4_lock_group(sb, group); /* init the buddy */ memset(data, 0xff, blocksize); - ext4_mb_generate_buddy(sb, data, incore, group); + err = ext4_mb_generate_buddy(sb, data, incore, group); ext4_unlock_group(sb, group); incore = NULL; } else { @@ -941,7 +944,7 @@ static int ext4_mb_init_cache(struct page *page, char *incore, gfp_t gfp) memcpy(data, bitmap, blocksize); /* mark all preallocated blks used in in-core bitmap */ - ext4_mb_generate_from_pa(sb, data, group); + err = ext4_mb_generate_from_pa(sb, data, group); ext4_mb_generate_from_freelist(sb, data, group); ext4_unlock_group(sb, group); @@ -951,8 +954,8 @@ static int ext4_mb_init_cache(struct page *page, char *incore, gfp_t gfp) incore = data; } } - SetPageUptodate(page); - + if (likely(err == 0)) + SetPageUptodate(page); out: if (bh) { for (i = 0; i < groups_per_page; i++) @@ -2281,7 +2284,8 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v) { struct super_block *sb = PDE_DATA(file_inode(seq->file)); ext4_group_t group = (ext4_group_t) ((unsigned long) v); - int i; + struct ext4_group_desc *gdp; + int free = 0, i; int err, buddy_loaded = 0; struct ext4_buddy e4b; struct ext4_group_info *grinfo; @@ -2295,7 +2299,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v) group--; if (group == 0) - seq_puts(seq, "#group: free frags first [" + seq_puts(seq, "#group: bfree gfree free frags first [" " 2^0 2^1 2^2 2^3 2^4 2^5 2^6 " " 2^7 2^8 2^9 2^10 2^11 2^12 2^13 ]\n"); @@ -2313,13 +2317,19 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v) buddy_loaded = 1; } + gdp = ext4_get_group_desc(sb, group, NULL); + if (gdp) + free = ext4_free_group_clusters(sb, gdp); + memcpy(&sg, ext4_get_group_info(sb, group), i); if (buddy_loaded) ext4_mb_unload_buddy(&e4b); - seq_printf(seq, "#%-5u: %-5u %-5u %-5u [", group, sg.info.bb_free, - sg.info.bb_fragments, sg.info.bb_first_free); + seq_printf(seq, "#%-5lu: %-5u %-5u %-5u %-5u %-5lu [", + (long unsigned int)group, sg.info.bb_free, free, + sg.info.bb_fragments, sg.info.bb_first_free, + sg.info.bb_prealloc_nr); for (i = 0; i <= 13; i++) seq_printf(seq, " %-5u", i <= blocksize_bits + 1 ? sg.info.bb_counters[i] : 0); @@ -3593,6 +3603,42 @@ static void ext4_mb_use_group_pa(struct ext4_allocation_context *ac, } /* + * check free blocks in bitmap match free block in group descriptor + * do this before taking preallocated blocks into account to be able + * to detect on-disk corruptions. The group lock should be hold by the + * caller. + */ +int ext4_mb_check_ondisk_bitmap(struct super_block *sb, void *bitmap, + struct ext4_group_desc *gdp, int group) +{ + unsigned short max = EXT4_CLUSTERS_PER_GROUP(sb); + unsigned short i, first, free = 0; + unsigned short free_in_gdp = ext4_free_group_clusters(sb, gdp); + + if (free_in_gdp == 0 && gdp->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) + return 0; + + i = mb_find_next_zero_bit(bitmap, max, 0); + + while (i < max) { + first = i; + i = mb_find_next_bit(bitmap, max, i); + if (i > max) + i = max; + free += i - first; + if (i < max) + i = mb_find_next_zero_bit(bitmap, max, i); + } + + if (free != free_in_gdp) { + ext4_error(sb, "on-disk bitmap for group %d corrupted: %u blocks free in bitmap, %u - in gd\n", + group, free, free_in_gdp); + return -EIO; + } + return 0; +} + +/* * the function goes through all block freed in the group * but not yet committed and marks them used in in-core bitmap. * buddy must be generated from this bitmap @@ -3622,16 +3668,27 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, * Need to be called with ext4 group lock held */ static noinline_for_stack -void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, - ext4_group_t group) +int ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, + ext4_group_t group) { struct ext4_group_info *grp = ext4_get_group_info(sb, group); struct ext4_prealloc_space *pa; + struct ext4_group_desc *gdp; struct list_head *cur; ext4_group_t groupnr; ext4_grpblk_t start; int preallocated = 0; - int len; + int skip = 0, count = 0; + int err, len; + + gdp = ext4_get_group_desc(sb, group, NULL); + if (!gdp) + return -EIO; + + /* before applying preallocations, check bitmap consistency */ + err = ext4_mb_check_ondisk_bitmap(sb, bitmap, gdp, group); + if (err) + return err; /* all form of preallocation discards first load group, * so the only competing code is preallocation use. @@ -3648,13 +3705,22 @@ void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, &groupnr, &start); len = pa->pa_len; spin_unlock(&pa->pa_lock); - if (unlikely(len == 0)) + if (unlikely(len == 0)) { + skip++; continue; + } BUG_ON(groupnr != group); ext4_set_bits(bitmap, start, len); preallocated += len; + count++; + } + if (count + skip != grp->bb_prealloc_nr) { + ext4_error(sb, "lost preallocations: count %d, bb_prealloc_nr %lu, skip %d\n", + count, grp->bb_prealloc_nr, skip); + return -EIO; } mb_debug(1, "preallocated %u for group %u\n", preallocated, group); + return 0; } static void ext4_mb_pa_callback(struct rcu_head *head) @@ -3718,6 +3784,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, */ ext4_lock_group(sb, grp); list_del(&pa->pa_group_list); + ext4_get_group_info(sb, grp)->bb_prealloc_nr--; ext4_unlock_group(sb, grp); spin_lock(pa->pa_obj_lock); @@ -3812,6 +3879,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, ext4_lock_group(sb, ac->ac_b_ex.fe_group); list_add(&pa->pa_group_list, &grp->bb_prealloc_list); + grp->bb_prealloc_nr++; ext4_unlock_group(sb, ac->ac_b_ex.fe_group); spin_lock(pa->pa_obj_lock); @@ -3873,6 +3941,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, ext4_lock_group(sb, ac->ac_b_ex.fe_group); list_add(&pa->pa_group_list, &grp->bb_prealloc_list); + grp->bb_prealloc_nr++; ext4_unlock_group(sb, ac->ac_b_ex.fe_group); /* @@ -4044,6 +4113,8 @@ static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac) spin_unlock(&pa->pa_lock); + BUG_ON(grp->bb_prealloc_nr == 0); + grp->bb_prealloc_nr--; list_del(&pa->pa_group_list); list_add(&pa->u.pa_tmp_list, &list); } @@ -4174,7 +4245,7 @@ void ext4_discard_preallocations(struct inode *inode) if (err) { ext4_error(sb, "Error %d loading buddy information for %u", err, group); - continue; + return; } bitmap_bh = ext4_read_block_bitmap(sb, group); @@ -4187,6 +4258,8 @@ void ext4_discard_preallocations(struct inode *inode) } ext4_lock_group(sb, group); + BUG_ON(e4b.bd_info->bb_prealloc_nr == 0); + e4b.bd_info->bb_prealloc_nr--; list_del(&pa->pa_group_list); ext4_mb_release_inode_pa(&e4b, bitmap_bh, pa); ext4_unlock_group(sb, group); @@ -4448,6 +4521,7 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac) } ext4_lock_group(sb, group); list_del(&pa->pa_group_list); + ext4_get_group_info(sb, group)->bb_prealloc_nr--; ext4_mb_release_group_pa(&e4b, pa); ext4_unlock_group(sb, group); diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h index 88c98f1..8325ad9 100644 --- a/fs/ext4/mballoc.h +++ b/fs/ext4/mballoc.h @@ -70,7 +70,7 @@ /* * for which requests use 2^N search using buddies */ -#define MB_DEFAULT_ORDER2_REQS 2 +#define MB_DEFAULT_ORDER2_REQS 8 /* * default group prealloc size 512 blocks -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:45 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:45 -0400 Subject: [lustre-devel] [PATCH 16/22] ext4: add warning for directory htree growth In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-17-git-send-email-jsimmons@infradead.org> Signed-off-by: James Simmons --- fs/ext4/ext4.h | 1 + fs/ext4/namei.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- fs/ext4/super.c | 2 ++ fs/ext4/sysfs.c | 2 ++ 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index bf74c7c..5f73e19 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1472,6 +1472,7 @@ struct ext4_sb_info { unsigned int s_mb_group_prealloc; unsigned long *s_mb_prealloc_table; unsigned int s_max_dir_size_kb; + unsigned long s_warning_dir_size; /* where last allocation was done - for stream allocation */ unsigned long s_mb_last_group; unsigned long s_mb_last_start; diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 1b6d22a..9b30cc6 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -757,12 +757,20 @@ struct ext4_dir_lock_data { #define ext4_htree_lock_data(l) ((struct ext4_dir_lock_data *)(l)->lk_private) #define ext4_find_entry(dir, name, dirent, inline) \ ext4_find_entry_locked(dir, name, dirent, inline, NULL) -#define ext4_add_entry(handle, dentry, inode) \ - ext4_add_entry_locked(handle, dentry, inode, NULL) /* NB: ext4_lblk_t is 32 bits so we use high bits to identify invalid blk */ #define EXT4_HTREE_NODE_CHANGED (0xcafeULL << 32) +inline int ext4_add_entry(handle_t *handle, struct dentry *dentry, + struct inode *inode) +{ + int ret = ext4_add_entry_locked(handle, dentry, inode, NULL); + + if (ret == -ENOBUFS) + ret = 0; + return ret; +} + static void ext4_htree_event_cb(void *target, void *event) { u64 *block = (u64 *)target; @@ -2612,6 +2620,55 @@ static int ext4_update_dotdot(handle_t *handle, struct dentry *dentry, return err; } +static unsigned long __ext4_max_dir_size(struct dx_frame *frames, + struct dx_frame *frame, + struct inode *dir) +{ + unsigned long max_dir_size; + + if (EXT4_SB(dir->i_sb)->s_max_dir_size_kb) { + max_dir_size = EXT4_SB(dir->i_sb)->s_max_dir_size_kb << 10; + } else { + max_dir_size = EXT4_BLOCK_SIZE(dir->i_sb); + while (frame >= frames) { + max_dir_size *= dx_get_limit(frame->entries); + if (frame == frames) + break; + frame--; + } + /* use 75% of max dir size in average */ + max_dir_size = max_dir_size / 4 * 3; + } + return max_dir_size; +} + +/* + * With hash tree growing, it is easy to hit ENOSPC, but it is hard + * to predict when it will happen. let's give administrators warning + * when reaching 3/5 and 2/3 of limit + */ +static inline bool dir_size_in_warning_range(struct dx_frame *frames, + struct dx_frame *frame, + struct inode *dir) +{ + struct super_block *sb = dir->i_sb; + unsigned long size1, size2; + + if (unlikely(!EXT4_SB(sb)->s_warning_dir_size)) + EXT4_SB(sb)->s_warning_dir_size = + __ext4_max_dir_size(frames, frame, dir); + + size1 = EXT4_SB(sb)->s_warning_dir_size / 16 * 10; + size1 = size1 & ~(EXT4_BLOCK_SIZE(sb) - 1); + size2 = EXT4_SB(sb)->s_warning_dir_size / 16 * 11; + size2 = size2 & ~(EXT4_BLOCK_SIZE(sb) - 1); + if (in_range(dir->i_size, size1, EXT4_BLOCK_SIZE(sb)) || + in_range(dir->i_size, size2, EXT4_BLOCK_SIZE(sb))) + return true; + + return false; +} + /* * ext4_add_entry() * @@ -2739,6 +2796,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, struct buffer_head *bh; struct super_block *sb = dir->i_sb; struct ext4_dir_entry_2 *de; + bool ret_warn = false; int restart; int err; @@ -2769,6 +2827,11 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, /* Block full, should compress but for now just split */ dxtrace(printk(KERN_DEBUG "using %u of %u node entries\n", dx_get_count(entries), dx_get_limit(entries))); + + if (frame - frames + 1 >= ext4_dir_htree_level(sb) || + EXT4_SB(sb)->s_warning_dir_size) + ret_warn = dir_size_in_warning_range(frames, frame, dir); + /* Need to split index? */ if (dx_get_count(entries) == dx_get_limit(entries)) { ext4_lblk_t newblock; @@ -2935,6 +2998,8 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, */ if (restart && err == 0) goto again; + if (err == 0 && ret_warn) + err = -ENOBUFS; return err; } diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 07242d7..a3179b2 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1901,6 +1901,8 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, sbi->s_li_wait_mult = arg; } else if (token == Opt_max_dir_size_kb) { sbi->s_max_dir_size_kb = arg; + /* reset s_warning_dir_size and make it re-calculated */ + sbi->s_warning_dir_size = 0; } else if (token == Opt_stripe) { sbi->s_stripe = arg; } else if (token == Opt_resuid) { diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c index 3a71a16..575f318 100644 --- a/fs/ext4/sysfs.c +++ b/fs/ext4/sysfs.c @@ -182,6 +182,7 @@ static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf) EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal); EXT4_RW_ATTR_SBI_UI(max_dir_size, s_max_dir_size_kb); EXT4_RW_ATTR_SBI_UI(max_dir_size_kb, s_max_dir_size_kb); +EXT4_RW_ATTR_SBI_UI(warning_dir_size, s_warning_dir_size); EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats); EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan); EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan); @@ -214,6 +215,7 @@ static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf) ATTR_LIST(inode_goal), ATTR_LIST(max_dir_size), ATTR_LIST(max_dir_size_kb), + ATTR_LIST(warning_dir_size), ATTR_LIST(mb_stats), ATTR_LIST(mb_max_to_scan), ATTR_LIST(mb_min_to_scan), -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:49 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:49 -0400 Subject: [lustre-devel] [PATCH 20/22] ext4: use GFP_NOFS in ext4_inode_attach_jinode In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-21-git-send-email-jsimmons@infradead.org> Signed-off-by: James Simmons --- fs/ext4/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index bf00dfc..ca72097 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4422,7 +4422,7 @@ int ext4_inode_attach_jinode(struct inode *inode) if (ei->jinode || !EXT4_SB(inode->i_sb)->s_journal) return 0; - jinode = jbd2_alloc_inode(GFP_KERNEL); + jinode = jbd2_alloc_inode(GFP_NOFS); spin_lock(&inode->i_lock); if (!ei->jinode) { if (!jinode) { -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:51 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:51 -0400 Subject: [lustre-devel] [PATCH 22/22] ext4: export mb stream allocator variables In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-23-git-send-email-jsimmons@infradead.org> Signed-off-by: James Simmons --- fs/ext4/ext4.h | 2 ++ fs/ext4/mballoc.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/sysfs.c | 4 ++++ 3 files changed, 65 insertions(+) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 0ee4606..46f2619 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2620,6 +2620,8 @@ extern int ext4_init_inode_table(struct super_block *sb, /* mballoc.c */ extern const struct file_operations ext4_seq_prealloc_table_fops; extern const struct seq_operations ext4_mb_seq_groups_ops; +extern const struct file_operations ext4_seq_mb_last_group_fops; +extern int ext4_mb_seq_last_start_seq_show(struct seq_file *m, void *v); extern long ext4_mb_stats; extern long ext4_mb_max_to_scan; extern int ext4_mb_init(struct super_block *); diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 82398b0..8270e35 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2459,6 +2459,65 @@ static struct kmem_cache *get_groupinfo_cache(int blocksize_bits) return cachep; } +#define EXT4_MB_MAX_INPUT_STRING_SIZE 32 + +static ssize_t ext4_mb_last_group_write(struct file *file, + const char __user *buf, + size_t cnt, loff_t *pos) +{ + char dummy[EXT4_MB_MAX_INPUT_STRING_SIZE + 1]; + struct super_block *sb = PDE_DATA(file_inode(file)); + struct ext4_sb_info *sbi = EXT4_SB(sb); + unsigned long val; + char *end; + + if (cnt > EXT4_MB_MAX_INPUT_STRING_SIZE) + return -EINVAL; + if (copy_from_user(dummy, buf, cnt)) + return -EFAULT; + dummy[cnt] = '\0'; + val = simple_strtoul(dummy, &end, 0); + if (dummy == end) + return -EINVAL; + if (val >= ext4_get_groups_count(sb)) + return -ERANGE; + spin_lock(&sbi->s_md_lock); + sbi->s_mb_last_group = val; + sbi->s_mb_last_start = 0; + spin_unlock(&sbi->s_md_lock); + return cnt; +} + +static int ext4_mb_seq_last_group_seq_show(struct seq_file *m, void *v) +{ + struct ext4_sb_info *sbi = EXT4_SB(m->private); + + seq_printf(m , "%ld\n", sbi->s_mb_last_group); + return 0; +} + +static int ext4_mb_seq_last_group_open(struct inode *inode, struct file *file) +{ + return single_open(file, ext4_mb_seq_last_group_seq_show, PDE_DATA(inode)); +} + +const struct file_operations ext4_seq_mb_last_group_fops = { + .owner = THIS_MODULE, + .open = ext4_mb_seq_last_group_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, + .write = ext4_mb_last_group_write, +}; + +int ext4_mb_seq_last_start_seq_show(struct seq_file *m, void *v) +{ + struct ext4_sb_info *sbi = EXT4_SB(m->private); + + seq_printf(m , "%ld\n", sbi->s_mb_last_start); + return 0; +} + /* * Allocate the top-level s_group_info array for the specified number * of groups diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c index 575f318..6bcb455 100644 --- a/fs/ext4/sysfs.c +++ b/fs/ext4/sysfs.c @@ -425,6 +425,10 @@ int ext4_register_sysfs(struct super_block *sb) &ext4_mb_seq_groups_ops, sb); proc_create_data("prealloc_table", S_IRUGO, sbi->s_proc, &ext4_seq_prealloc_table_fops, sb); + proc_create_data("mb_last_group", S_IRUGO, sbi->s_proc, + &ext4_seq_mb_last_group_fops, sb); + proc_create_single_data("mb_last_start", S_IRUGO, sbi->s_proc, + ext4_mb_seq_last_start_seq_show, sb); } return 0; } -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:47 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:47 -0400 Subject: [lustre-devel] [PATCH 18/22] ext4: attach jinode in writepages In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-19-git-send-email-jsimmons@infradead.org> Signed-off-by: James Simmons --- fs/ext4/ext4.h | 1 + fs/ext4/inode.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 5f73e19..0ee4606 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -2643,6 +2643,7 @@ extern int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, extern void ext4_process_freed_data(struct super_block *sb, tid_t commit_tid); /* inode.c */ +#define HAVE_LDISKFS_INFO_JINODE int ext4_inode_is_fast_symlink(struct inode *inode); struct buffer_head *ext4_getblk(handle_t *, struct inode *, ext4_lblk_t, int); struct buffer_head *ext4_bread(handle_t *, struct inode *, ext4_lblk_t, int); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 9296611..bf00dfc 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -731,6 +731,9 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, !(flags & EXT4_GET_BLOCKS_ZERO) && !ext4_is_quota_file(inode) && ext4_should_order_data(inode)) { + ret = ext4_inode_attach_jinode(inode); + if (ret) + return ret; if (flags & EXT4_GET_BLOCKS_IO_SUBMIT) ret = ext4_jbd2_inode_add_wait(handle, inode); else @@ -2815,6 +2818,9 @@ static int ext4_writepages(struct address_space *mapping, mpd.last_page = wbc->range_end >> PAGE_SHIFT; } + ret = ext4_inode_attach_jinode(inode); + if (ret) + return ret; mpd.inode = inode; mpd.wbc = wbc; ext4_io_submit_init(&mpd.io_submit, wbc); @@ -4432,6 +4438,7 @@ int ext4_inode_attach_jinode(struct inode *inode) jbd2_free_inode(jinode); return 0; } +EXPORT_SYMBOL(ext4_inode_attach_jinode); /* * ext4_truncate() -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:34 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:34 -0400 Subject: [lustre-devel] [PATCH 05/22] ext4: various misc changes In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-6-git-send-email-jsimmons@infradead.org> Mostly exporting symbols for osd-ldiskfs. Signed-off-by: James Simmons --- fs/ext4/balloc.c | 1 + fs/ext4/ext4.h | 26 +++++++++++++++++++++++++- fs/ext4/ext4_jbd2.c | 4 ++++ fs/ext4/hash.c | 1 + fs/ext4/ialloc.c | 3 ++- fs/ext4/inode.c | 6 ++++++ fs/ext4/namei.c | 13 +++++++------ fs/ext4/super.c | 9 +++------ 8 files changed, 49 insertions(+), 14 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index e5d6ee6..bca75c1 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -294,6 +294,7 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, *bh = sbi->s_group_desc[group_desc]; return desc; } +EXPORT_SYMBOL(ext4_get_group_desc); /* * Return the block number which was discovered to be invalid, or 0 if diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 50f0c50..eb2d124 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1617,6 +1617,8 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei) #define NEXT_ORPHAN(inode) EXT4_I(inode)->i_dtime +#define JOURNAL_START_HAS_3ARGS 1 + /* * Codes for operating systems */ @@ -1839,7 +1841,24 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei) EXTN_FEATURE_FUNCS(2) EXTN_FEATURE_FUNCS(3) -EXTN_FEATURE_FUNCS(4) + +static inline bool ext4_has_unknown_ext4_compat_features(struct super_block *sb) +{ + return ((EXT4_SB(sb)->s_es->s_feature_compat & + cpu_to_le32(~EXT4_FEATURE_COMPAT_SUPP)) != 0); +} + +static inline bool ext4_has_unknown_ext4_ro_compat_features(struct super_block *sb) +{ + return ((EXT4_SB(sb)->s_es->s_feature_ro_compat & + cpu_to_le32(~EXT4_FEATURE_RO_COMPAT_SUPP)) != 0); +} + +static inline bool ext4_has_unknown_ext4_incompat_features(struct super_block *sb) +{ + return ((EXT4_SB(sb)->s_es->s_feature_incompat & + cpu_to_le32(~EXT4_FEATURE_INCOMPAT_SUPP)) != 0); +} static inline bool ext4_has_compat_features(struct super_block *sb) { @@ -3192,6 +3211,11 @@ extern int ext4_check_blockref(const char *, unsigned int, extern int ext4_ext_tree_init(handle_t *handle, struct inode *); extern int ext4_ext_writepage_trans_blocks(struct inode *, int); +extern struct buffer_head *ext4_read_inode_bitmap(struct super_block *sb, + ext4_group_t block_group); +extern struct buffer_head *ext4_append(handle_t *handle, + struct inode *inode, + ext4_lblk_t *block); extern int ext4_ext_index_trans_blocks(struct inode *inode, int extents); extern int ext4_ext_map_blocks(handle_t *handle, struct inode *inode, struct ext4_map_blocks *map, int flags); diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c index 7c70b08..fcec082 100644 --- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c @@ -81,6 +81,7 @@ handle_t *__ext4_journal_start_sb(struct super_block *sb, unsigned int line, return jbd2__journal_start(journal, blocks, rsv_blocks, GFP_NOFS, type, line); } +EXPORT_SYMBOL(__ext4_journal_start_sb); int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) { @@ -108,6 +109,7 @@ int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) __ext4_std_error(sb, where, line, err); return err; } +EXPORT_SYMBOL(__ext4_journal_stop); handle_t *__ext4_journal_start_reserved(handle_t *handle, unsigned int line, int type) @@ -173,6 +175,7 @@ int __ext4_journal_get_write_access(const char *where, unsigned int line, } return err; } +EXPORT_SYMBOL(__ext4_journal_get_write_access); /* * The ext4 forget function must perform a revoke if we are freeing data @@ -313,6 +316,7 @@ int __ext4_handle_dirty_metadata(const char *where, unsigned int line, } return err; } +EXPORT_SYMBOL(__ext4_handle_dirty_metadata); int __ext4_handle_dirty_super(const char *where, unsigned int line, handle_t *handle, struct super_block *sb) diff --git a/fs/ext4/hash.c b/fs/ext4/hash.c index d358bfc..4648a8f 100644 --- a/fs/ext4/hash.c +++ b/fs/ext4/hash.c @@ -300,3 +300,4 @@ int ext4fs_dirhash(const struct inode *dir, const char *name, int len, #endif return __ext4fs_dirhash(name, len, hinfo); } +EXPORT_SYMBOL(ext4fs_dirhash); diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 09ae4a4..68d41e6 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -114,7 +114,7 @@ static int ext4_validate_inode_bitmap(struct super_block *sb, * * Return buffer_head of bitmap on success or NULL. */ -static struct buffer_head * +struct buffer_head * ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group) { struct ext4_group_desc *desc; @@ -211,6 +211,7 @@ static int ext4_validate_inode_bitmap(struct super_block *sb, put_bh(bh); return ERR_PTR(err); } +EXPORT_SYMBOL(ext4_read_inode_bitmap); /* * NOTE! When we get the inode, we're the only people diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index c37418a..5561351 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -741,6 +741,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, } return retval; } +EXPORT_SYMBOL(ext4_map_blocks); /* * Update EXT4_MAP_FLAGS in bh->b_state. For buffer heads attached to pages @@ -1027,6 +1028,7 @@ struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode, put_bh(bh); return ERR_PTR(-EIO); } +EXPORT_SYMBOL(ext4_bread); /* Read a contiguous batch of blocks. */ int ext4_bread_batch(struct inode *inode, ext4_lblk_t block, int bh_count, @@ -4559,6 +4561,7 @@ int ext4_truncate(struct inode *inode) trace_ext4_truncate_exit(inode); return err; } +EXPORT_SYMBOL(ext4_truncate); /* * ext4_get_inode_loc returns with an extra refcount against the inode's @@ -4710,6 +4713,7 @@ int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc) return __ext4_get_inode_loc(inode, iloc, !ext4_test_inode_state(inode, EXT4_STATE_XATTR)); } +EXPORT_SYMBOL(ext4_get_inode_loc); static bool ext4_should_use_dax(struct inode *inode) { @@ -5113,6 +5117,7 @@ struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, iget_failed(inode); return ERR_PTR(ret); } +EXPORT_SYMBOL(__ext4_iget); static int ext4_inode_blocks_set(handle_t *handle, struct ext4_inode *raw_inode, @@ -6050,6 +6055,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) return ext4_mark_iloc_dirty(handle, inode, &iloc); } +EXPORT_SYMBOL(ext4_mark_inode_dirty); /* * ext4_dirty_inode() is called from __mark_inode_dirty() diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index a42a2db..91fc7fe 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -50,9 +50,9 @@ #define NAMEI_RA_BLOCKS 4 #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) -static struct buffer_head *ext4_append(handle_t *handle, - struct inode *inode, - ext4_lblk_t *block) +struct buffer_head *ext4_append(handle_t *handle, + struct inode *inode, + ext4_lblk_t *block) { struct buffer_head *bh; int err; @@ -2511,24 +2511,25 @@ int ext4_delete_entry(handle_t *handle, struct inode *dir, * for checking S_ISDIR(inode) (since the INODE_INDEX feature will not be set * on regular files) and to avoid creating huge/slow non-HTREE directories. */ -static void ext4_inc_count(handle_t *handle, struct inode *inode) +void ext4_inc_count(handle_t *handle, struct inode *inode) { inc_nlink(inode); if (is_dx(inode) && (inode->i_nlink > EXT4_LINK_MAX || inode->i_nlink == 2)) set_nlink(inode, 1); } +EXPORT_SYMBOL(ext4_inc_count); /* * If a directory had nlink == 1, then we should let it be 1. This indicates * directory has >EXT4_LINK_MAX subdirs. */ -static void ext4_dec_count(handle_t *handle, struct inode *inode) +void ext4_dec_count(handle_t *handle, struct inode *inode) { if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2) drop_nlink(inode); } - +EXPORT_SYMBOL(ext4_dec_count); static int ext4_add_nondir(handle_t *handle, struct dentry *dentry, struct inode *inode) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 4079605..d15c26c 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -279,6 +279,7 @@ __u32 ext4_itable_unused_count(struct super_block *sb, (EXT4_DESC_SIZE(sb) >= EXT4_MIN_DESC_SIZE_64BIT ? (__u32)le16_to_cpu(bg->bg_itable_unused_hi) << 16 : 0); } +EXPORT_SYMBOL(ext4_itable_unused_count); void ext4_block_bitmap_set(struct super_block *sb, struct ext4_group_desc *bg, ext4_fsblk_t blk) @@ -658,6 +659,7 @@ void __ext4_std_error(struct super_block *sb, const char *function, save_error_info(sb, function, line); ext4_handle_error(sb); } +EXPORT_SYMBOL(__ext4_std_error); /* * ext4_abort is a much stronger failure handler than ext4_error. The @@ -5101,6 +5103,7 @@ int ext4_force_commit(struct super_block *sb) journal = EXT4_SB(sb)->s_journal; return ext4_journal_force_commit(journal); } +EXPORT_SYMBOL(ext4_force_commit); static int ext4_sync_fs(struct super_block *sb, int wait) { @@ -6115,16 +6118,12 @@ static int __init ext4_init_fs(void) err = init_inodecache(); if (err) goto out1; - register_as_ext3(); - register_as_ext2(); err = register_filesystem(&ext4_fs_type); if (err) goto out; return 0; out: - unregister_as_ext2(); - unregister_as_ext3(); destroy_inodecache(); out1: ext4_exit_mballoc(); @@ -6145,8 +6144,6 @@ static int __init ext4_init_fs(void) static void __exit ext4_exit_fs(void) { ext4_destroy_lazyinit_thread(); - unregister_as_ext2(); - unregister_as_ext3(); unregister_filesystem(&ext4_fs_type); destroy_inodecache(); ext4_exit_mballoc(); -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:41 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:41 -0400 Subject: [lustre-devel] [PATCH 12/22] ext4: add htree lock implementation In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-13-git-send-email-jsimmons@infradead.org> Used for parallel lookup Signed-off-by: James Simmons --- fs/ext4/Makefile | 4 +- fs/ext4/ext4.h | 80 +++++ fs/ext4/htree_lock.c | 891 +++++++++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/htree_lock.h | 187 +++++++++++ fs/ext4/namei.c | 461 +++++++++++++++++++++++--- fs/ext4/super.c | 1 + 6 files changed, 1583 insertions(+), 41 deletions(-) create mode 100644 fs/ext4/htree_lock.c create mode 100644 fs/ext4/htree_lock.h diff --git a/fs/ext4/Makefile b/fs/ext4/Makefile index 8fdfcd3..0d0a28f 100644 --- a/fs/ext4/Makefile +++ b/fs/ext4/Makefile @@ -6,8 +6,8 @@ obj-$(CONFIG_EXT4_FS) += ext4.o ext4-y := balloc.o bitmap.o block_validity.o dir.o ext4_jbd2.o extents.o \ - extents_status.o file.o fsmap.o fsync.o hash.o ialloc.o \ - indirect.o inline.o inode.o ioctl.o mballoc.o migrate.o \ + extents_status.o file.o fsmap.o fsync.o hash.o htree_lock.o \ + ialloc.o indirect.o inline.o inode.o ioctl.o mballoc.o migrate.o \ mmp.o move_extent.o namei.o page-io.o readpage.o resize.o \ super.o symlink.o sysfs.o xattr.o xattr_trusted.o xattr_user.o diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 80601a9..bf74c7c 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -44,6 +44,8 @@ #include +#include "htree_lock.h" + /* * The fourth extended filesystem constants/structures */ @@ -936,6 +938,9 @@ struct ext4_inode_info { __u32 i_dtime; ext4_fsblk_t i_file_acl; + /* following fields for parallel directory operations -bzzz */ + struct semaphore i_append_sem; + /* * i_block_group is the number of the block group which contains * this file's inode. Constant across the lifetime of the inode, @@ -2145,6 +2150,72 @@ struct dx_hash_info */ #define HASH_NB_ALWAYS 1 +/* assume name-hash is protected by upper layer */ +#define EXT4_HTREE_LOCK_HASH 0 + +enum ext4_pdo_lk_types { +#if EXT4_HTREE_LOCK_HASH + EXT4_LK_HASH, +#endif + EXT4_LK_DX, /* index block */ + EXT4_LK_DE, /* directory entry block */ + EXT4_LK_SPIN, /* spinlock */ + EXT4_LK_MAX, +}; + +/* read-only bit */ +#define EXT4_LB_RO(b) (1 << (b)) +/* read + write, high bits for writer */ +#define EXT4_LB_RW(b) ((1 << (b)) | (1 << (EXT4_LK_MAX + (b)))) + +enum ext4_pdo_lock_bits { + /* DX lock bits */ + EXT4_LB_DX_RO = EXT4_LB_RO(EXT4_LK_DX), + EXT4_LB_DX = EXT4_LB_RW(EXT4_LK_DX), + /* DE lock bits */ + EXT4_LB_DE_RO = EXT4_LB_RO(EXT4_LK_DE), + EXT4_LB_DE = EXT4_LB_RW(EXT4_LK_DE), + /* DX spinlock bits */ + EXT4_LB_SPIN_RO = EXT4_LB_RO(EXT4_LK_SPIN), + EXT4_LB_SPIN = EXT4_LB_RW(EXT4_LK_SPIN), + /* accurate searching */ + EXT4_LB_EXACT = EXT4_LB_RO(EXT4_LK_MAX << 1), +}; + +enum ext4_pdo_lock_opc { + /* external */ + EXT4_HLOCK_READDIR = (EXT4_LB_DE_RO | EXT4_LB_DX_RO), + EXT4_HLOCK_LOOKUP = (EXT4_LB_DE_RO | EXT4_LB_SPIN_RO | + EXT4_LB_EXACT), + EXT4_HLOCK_DEL = (EXT4_LB_DE | EXT4_LB_SPIN_RO | + EXT4_LB_EXACT), + EXT4_HLOCK_ADD = (EXT4_LB_DE | EXT4_LB_SPIN_RO), + + /* internal */ + EXT4_HLOCK_LOOKUP_SAFE = (EXT4_LB_DE_RO | EXT4_LB_DX_RO | + EXT4_LB_EXACT), + EXT4_HLOCK_DEL_SAFE = (EXT4_LB_DE | EXT4_LB_DX_RO | EXT4_LB_EXACT), + EXT4_HLOCK_SPLIT = (EXT4_LB_DE | EXT4_LB_DX | EXT4_LB_SPIN), +}; + +extern struct htree_lock_head *ext4_htree_lock_head_alloc(unsigned hbits); +#define ext4_htree_lock_head_free(lhead) htree_lock_head_free(lhead) + +extern struct htree_lock *ext4_htree_lock_alloc(void); +#define ext4_htree_lock_free(lck) htree_lock_free(lck) + +extern void ext4_htree_lock(struct htree_lock *lck, + struct htree_lock_head *lhead, + struct inode *dir, unsigned flags); +#define ext4_htree_unlock(lck) htree_unlock(lck) + +extern struct buffer_head *ext4_find_entry_locked(struct inode *dir, + const struct qstr *d_name, + struct ext4_dir_entry_2 **res_dir, + int *inlined, struct htree_lock *lck); +extern int ext4_add_entry_locked(handle_t *handle, struct dentry *dentry, + struct inode *inode, struct htree_lock *lck); + struct ext4_filename { const struct qstr *usr_fname; struct fscrypt_str disk_name; @@ -2479,8 +2550,17 @@ void ext4_insert_dentry(struct inode *inode, struct ext4_filename *fname, void *data); static inline void ext4_update_dx_flag(struct inode *inode) { + /* Disable it for ldiskfs, because going from a DX directory to + * a non-DX directory while it is in use will completely break + * the htree-locking. + * If we really want to support this operation in the future, + * we need to exclusively lock the directory at here which will + * increase complexity of code + */ +#if 0 if (!ext4_has_feature_dir_index(inode->i_sb)) ext4_clear_inode_flag(inode, EXT4_INODE_INDEX); +#endif } static const unsigned char ext4_filetype_table[] = { DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK diff --git a/fs/ext4/htree_lock.c b/fs/ext4/htree_lock.c new file mode 100644 index 0000000..9c1e8f0 --- /dev/null +++ b/fs/ext4/htree_lock.c @@ -0,0 +1,891 @@ +/* + * fs/ext4/htree_lock.c + * + * Copyright (c) 2011, 2012, Intel Corporation. + * + * Author: Liang Zhen + */ +#include +#include +#include +#include "htree_lock.h" + +enum { + HTREE_LOCK_BIT_EX = (1 << HTREE_LOCK_EX), + HTREE_LOCK_BIT_PW = (1 << HTREE_LOCK_PW), + HTREE_LOCK_BIT_PR = (1 << HTREE_LOCK_PR), + HTREE_LOCK_BIT_CW = (1 << HTREE_LOCK_CW), + HTREE_LOCK_BIT_CR = (1 << HTREE_LOCK_CR), +}; + +enum { + HTREE_LOCK_COMPAT_EX = 0, + HTREE_LOCK_COMPAT_PW = HTREE_LOCK_COMPAT_EX | HTREE_LOCK_BIT_CR, + HTREE_LOCK_COMPAT_PR = HTREE_LOCK_COMPAT_PW | HTREE_LOCK_BIT_PR, + HTREE_LOCK_COMPAT_CW = HTREE_LOCK_COMPAT_PW | HTREE_LOCK_BIT_CW, + HTREE_LOCK_COMPAT_CR = HTREE_LOCK_COMPAT_CW | HTREE_LOCK_BIT_PR | + HTREE_LOCK_BIT_PW, +}; + +static int htree_lock_compat[] = { + [HTREE_LOCK_EX] HTREE_LOCK_COMPAT_EX, + [HTREE_LOCK_PW] HTREE_LOCK_COMPAT_PW, + [HTREE_LOCK_PR] HTREE_LOCK_COMPAT_PR, + [HTREE_LOCK_CW] HTREE_LOCK_COMPAT_CW, + [HTREE_LOCK_CR] HTREE_LOCK_COMPAT_CR, +}; + +/* max allowed htree-lock depth. + * We only need depth=3 for ext4 although user can have higher value. */ +#define HTREE_LOCK_DEP_MAX 16 + +#ifdef HTREE_LOCK_DEBUG + +static char *hl_name[] = { + [HTREE_LOCK_EX] "EX", + [HTREE_LOCK_PW] "PW", + [HTREE_LOCK_PR] "PR", + [HTREE_LOCK_CW] "CW", + [HTREE_LOCK_CR] "CR", +}; + +/* lock stats */ +struct htree_lock_node_stats { + unsigned long long blocked[HTREE_LOCK_MAX]; + unsigned long long granted[HTREE_LOCK_MAX]; + unsigned long long retried[HTREE_LOCK_MAX]; + unsigned long long events; +}; + +struct htree_lock_stats { + struct htree_lock_node_stats nodes[HTREE_LOCK_DEP_MAX]; + unsigned long long granted[HTREE_LOCK_MAX]; + unsigned long long blocked[HTREE_LOCK_MAX]; +}; + +static struct htree_lock_stats hl_stats; + +void htree_lock_stat_reset(void) +{ + memset(&hl_stats, 0, sizeof(hl_stats)); +} + +void htree_lock_stat_print(int depth) +{ + int i; + int j; + + printk(KERN_DEBUG "HTREE LOCK STATS:\n"); + for (i = 0; i < HTREE_LOCK_MAX; i++) { + printk(KERN_DEBUG "[%s]: G [%10llu], B [%10llu]\n", + hl_name[i], hl_stats.granted[i], hl_stats.blocked[i]); + } + for (i = 0; i < depth; i++) { + printk(KERN_DEBUG "HTREE CHILD [%d] STATS:\n", i); + for (j = 0; j < HTREE_LOCK_MAX; j++) { + printk(KERN_DEBUG + "[%s]: G [%10llu], B [%10llu], R [%10llu]\n", + hl_name[j], hl_stats.nodes[i].granted[j], + hl_stats.nodes[i].blocked[j], + hl_stats.nodes[i].retried[j]); + } + } +} + +#define lk_grant_inc(m) do { hl_stats.granted[m]++; } while (0) +#define lk_block_inc(m) do { hl_stats.blocked[m]++; } while (0) +#define ln_grant_inc(d, m) do { hl_stats.nodes[d].granted[m]++; } while (0) +#define ln_block_inc(d, m) do { hl_stats.nodes[d].blocked[m]++; } while (0) +#define ln_retry_inc(d, m) do { hl_stats.nodes[d].retried[m]++; } while (0) +#define ln_event_inc(d) do { hl_stats.nodes[d].events++; } while (0) + +#else /* !DEBUG */ + +void htree_lock_stat_reset(void) {} +void htree_lock_stat_print(int depth) {} + +#define lk_grant_inc(m) do {} while (0) +#define lk_block_inc(m) do {} while (0) +#define ln_grant_inc(d, m) do {} while (0) +#define ln_block_inc(d, m) do {} while (0) +#define ln_retry_inc(d, m) do {} while (0) +#define ln_event_inc(d) do {} while (0) + +#endif /* DEBUG */ + +EXPORT_SYMBOL(htree_lock_stat_reset); +EXPORT_SYMBOL(htree_lock_stat_print); + +#define HTREE_DEP_ROOT (-1) + +#define htree_spin_lock(lhead, dep) \ + bit_spin_lock((dep) + 1, &(lhead)->lh_lock) +#define htree_spin_unlock(lhead, dep) \ + bit_spin_unlock((dep) + 1, &(lhead)->lh_lock) + +#define htree_key_event_ignore(child, ln) \ + (!((child)->lc_events & (1 << (ln)->ln_mode))) + +static int +htree_key_list_empty(struct htree_lock_node *ln) +{ + return list_empty(&ln->ln_major_list) && list_empty(&ln->ln_minor_list); +} + +static void +htree_key_list_del_init(struct htree_lock_node *ln) +{ + struct htree_lock_node *tmp = NULL; + + if (!list_empty(&ln->ln_minor_list)) { + tmp = list_entry(ln->ln_minor_list.next, + struct htree_lock_node, ln_minor_list); + list_del_init(&ln->ln_minor_list); + } + + if (list_empty(&ln->ln_major_list)) + return; + + if (tmp == NULL) { /* not on minor key list */ + list_del_init(&ln->ln_major_list); + } else { + BUG_ON(!list_empty(&tmp->ln_major_list)); + list_replace_init(&ln->ln_major_list, &tmp->ln_major_list); + } +} + +static void +htree_key_list_replace_init(struct htree_lock_node *old, + struct htree_lock_node *new) +{ + if (!list_empty(&old->ln_major_list)) + list_replace_init(&old->ln_major_list, &new->ln_major_list); + + if (!list_empty(&old->ln_minor_list)) + list_replace_init(&old->ln_minor_list, &new->ln_minor_list); +} + +static void +htree_key_event_enqueue(struct htree_lock_child *child, + struct htree_lock_node *ln, int dep, void *event) +{ + struct htree_lock_node *tmp; + + /* NB: ALWAYS called holding lhead::lh_lock(dep) */ + BUG_ON(ln->ln_mode == HTREE_LOCK_NL); + if (event == NULL || htree_key_event_ignore(child, ln)) + return; + + /* shouldn't be a very long list */ + list_for_each_entry(tmp, &ln->ln_alive_list, ln_alive_list) { + if (tmp->ln_mode == HTREE_LOCK_NL) { + ln_event_inc(dep); + if (child->lc_callback != NULL) + child->lc_callback(tmp->ln_ev_target, event); + } + } +} + +static int +htree_node_lock_enqueue(struct htree_lock *newlk, struct htree_lock *curlk, + unsigned dep, int wait, void *event) +{ + struct htree_lock_child *child = &newlk->lk_head->lh_children[dep]; + struct htree_lock_node *newln = &newlk->lk_nodes[dep]; + struct htree_lock_node *curln = &curlk->lk_nodes[dep]; + + /* NB: ALWAYS called holding lhead::lh_lock(dep) */ + /* NB: we only expect PR/PW lock mode at here, only these two modes are + * allowed for htree_node_lock(asserted in htree_node_lock_internal), + * NL is only used for listener, user can't directly require NL mode */ + if ((curln->ln_mode == HTREE_LOCK_NL) || + (curln->ln_mode != HTREE_LOCK_PW && + newln->ln_mode != HTREE_LOCK_PW)) { + /* no conflict, attach it on granted list of @curlk */ + if (curln->ln_mode != HTREE_LOCK_NL) { + list_add(&newln->ln_granted_list, + &curln->ln_granted_list); + } else { + /* replace key owner */ + htree_key_list_replace_init(curln, newln); + } + + list_add(&newln->ln_alive_list, &curln->ln_alive_list); + htree_key_event_enqueue(child, newln, dep, event); + ln_grant_inc(dep, newln->ln_mode); + return 1; /* still hold lh_lock */ + } + + if (!wait) { /* can't grant and don't want to wait */ + ln_retry_inc(dep, newln->ln_mode); + newln->ln_mode = HTREE_LOCK_INVAL; + return -1; /* don't wait and just return -1 */ + } + + newlk->lk_task = current; + set_current_state(TASK_UNINTERRUPTIBLE); + /* conflict, attach it on blocked list of curlk */ + list_add_tail(&newln->ln_blocked_list, &curln->ln_blocked_list); + list_add(&newln->ln_alive_list, &curln->ln_alive_list); + ln_block_inc(dep, newln->ln_mode); + + htree_spin_unlock(newlk->lk_head, dep); + /* wait to be given the lock */ + if (newlk->lk_task != NULL) + schedule(); + /* granted, no doubt, wake up will set me RUNNING */ + if (event == NULL || htree_key_event_ignore(child, newln)) + return 0; /* granted without lh_lock */ + + htree_spin_lock(newlk->lk_head, dep); + htree_key_event_enqueue(child, newln, dep, event); + return 1; /* still hold lh_lock */ +} + +/* + * get PR/PW access to particular tree-node according to @dep and @key, + * it will return -1 if @wait is false and can't immediately grant this lock. + * All listeners(HTREE_LOCK_NL) on @dep and with the same @key will get + * @event if it's not NULL. + * NB: ALWAYS called holding lhead::lh_lock + */ +static int +htree_node_lock_internal(struct htree_lock_head *lhead, struct htree_lock *lck, + htree_lock_mode_t mode, u32 key, unsigned dep, + int wait, void *event) +{ + LIST_HEAD(list); + struct htree_lock *tmp; + struct htree_lock *tmp2; + u16 major; + u16 minor; + u8 reverse; + u8 ma_bits; + u8 mi_bits; + + BUG_ON(mode != HTREE_LOCK_PW && mode != HTREE_LOCK_PR); + BUG_ON(htree_node_is_granted(lck, dep)); + + key = hash_long(key, lhead->lh_hbits); + + mi_bits = lhead->lh_hbits >> 1; + ma_bits = lhead->lh_hbits - mi_bits; + + lck->lk_nodes[dep].ln_major_key = major = key & ((1U << ma_bits) - 1); + lck->lk_nodes[dep].ln_minor_key = minor = key >> ma_bits; + lck->lk_nodes[dep].ln_mode = mode; + + /* + * The major key list is an ordered list, so searches are started + * at the end of the list that is numerically closer to major_key, + * so at most half of the list will be walked (for well-distributed + * keys). The list traversal aborts early if the expected key + * location is passed. + */ + reverse = (major >= (1 << (ma_bits - 1))); + + if (reverse) { + list_for_each_entry_reverse(tmp, + &lhead->lh_children[dep].lc_list, + lk_nodes[dep].ln_major_list) { + if (tmp->lk_nodes[dep].ln_major_key == major) { + goto search_minor; + + } else if (tmp->lk_nodes[dep].ln_major_key < major) { + /* attach _after_ @tmp */ + list_add(&lck->lk_nodes[dep].ln_major_list, + &tmp->lk_nodes[dep].ln_major_list); + goto out_grant_major; + } + } + + list_add(&lck->lk_nodes[dep].ln_major_list, + &lhead->lh_children[dep].lc_list); + goto out_grant_major; + + } else { + list_for_each_entry(tmp, &lhead->lh_children[dep].lc_list, + lk_nodes[dep].ln_major_list) { + if (tmp->lk_nodes[dep].ln_major_key == major) { + goto search_minor; + + } else if (tmp->lk_nodes[dep].ln_major_key > major) { + /* insert _before_ @tmp */ + list_add_tail(&lck->lk_nodes[dep].ln_major_list, + &tmp->lk_nodes[dep].ln_major_list); + goto out_grant_major; + } + } + + list_add_tail(&lck->lk_nodes[dep].ln_major_list, + &lhead->lh_children[dep].lc_list); + goto out_grant_major; + } + + search_minor: + /* + * NB: minor_key list doesn't have a "head", @list is just a + * temporary stub for helping list searching, make sure it's removed + * after searching. + * minor_key list is an ordered list too. + */ + list_add_tail(&list, &tmp->lk_nodes[dep].ln_minor_list); + + reverse = (minor >= (1 << (mi_bits - 1))); + + if (reverse) { + list_for_each_entry_reverse(tmp2, &list, + lk_nodes[dep].ln_minor_list) { + if (tmp2->lk_nodes[dep].ln_minor_key == minor) { + goto out_enqueue; + + } else if (tmp2->lk_nodes[dep].ln_minor_key < minor) { + /* attach _after_ @tmp2 */ + list_add(&lck->lk_nodes[dep].ln_minor_list, + &tmp2->lk_nodes[dep].ln_minor_list); + goto out_grant_minor; + } + } + + list_add(&lck->lk_nodes[dep].ln_minor_list, &list); + + } else { + list_for_each_entry(tmp2, &list, + lk_nodes[dep].ln_minor_list) { + if (tmp2->lk_nodes[dep].ln_minor_key == minor) { + goto out_enqueue; + + } else if (tmp2->lk_nodes[dep].ln_minor_key > minor) { + /* insert _before_ @tmp2 */ + list_add_tail(&lck->lk_nodes[dep].ln_minor_list, + &tmp2->lk_nodes[dep].ln_minor_list); + goto out_grant_minor; + } + } + + list_add_tail(&lck->lk_nodes[dep].ln_minor_list, &list); + } + + out_grant_minor: + if (list.next == &lck->lk_nodes[dep].ln_minor_list) { + /* new lock @lck is the first one on minor_key list, which + * means it has the smallest minor_key and it should + * replace @tmp as minor_key owner */ + list_replace_init(&tmp->lk_nodes[dep].ln_major_list, + &lck->lk_nodes[dep].ln_major_list); + } + /* remove the temporary head */ + list_del(&list); + + out_grant_major: + ln_grant_inc(dep, lck->lk_nodes[dep].ln_mode); + return 1; /* granted with holding lh_lock */ + + out_enqueue: + list_del(&list); /* remove temprary head */ + return htree_node_lock_enqueue(lck, tmp2, dep, wait, event); +} + +/* + * release the key of @lck at level @dep, and grant any blocked locks. + * caller will still listen on @key if @event is not NULL, which means + * caller can see a event (by event_cb) while granting any lock with + * the same key at level @dep. + * NB: ALWAYS called holding lhead::lh_lock + * NB: listener will not block anyone because listening mode is HTREE_LOCK_NL + */ +static void +htree_node_unlock_internal(struct htree_lock_head *lhead, + struct htree_lock *curlk, unsigned dep, void *event) +{ + struct htree_lock_node *curln = &curlk->lk_nodes[dep]; + struct htree_lock *grtlk = NULL; + struct htree_lock_node *grtln; + struct htree_lock *poslk; + struct htree_lock *tmplk; + + if (!htree_node_is_granted(curlk, dep)) + return; + + if (!list_empty(&curln->ln_granted_list)) { + /* there is another granted lock */ + grtlk = list_entry(curln->ln_granted_list.next, + struct htree_lock, + lk_nodes[dep].ln_granted_list); + list_del_init(&curln->ln_granted_list); + } + + if (grtlk == NULL && !list_empty(&curln->ln_blocked_list)) { + /* + * @curlk is the only granted lock, so we confirmed: + * a) curln is key owner (attached on major/minor_list), + * so if there is any blocked lock, it should be attached + * on curln->ln_blocked_list + * b) we always can grant the first blocked lock + */ + grtlk = list_entry(curln->ln_blocked_list.next, + struct htree_lock, + lk_nodes[dep].ln_blocked_list); + BUG_ON(grtlk->lk_task == NULL); + wake_up_process(grtlk->lk_task); + } + + if (event != NULL && + lhead->lh_children[dep].lc_events != HTREE_EVENT_DISABLE) { + curln->ln_ev_target = event; + curln->ln_mode = HTREE_LOCK_NL; /* listen! */ + } else { + curln->ln_mode = HTREE_LOCK_INVAL; + } + + if (grtlk == NULL) { /* I must be the only one locking this key */ + struct htree_lock_node *tmpln; + + BUG_ON(htree_key_list_empty(curln)); + + if (curln->ln_mode == HTREE_LOCK_NL) /* listening */ + return; + + /* not listening */ + if (list_empty(&curln->ln_alive_list)) { /* no more listener */ + htree_key_list_del_init(curln); + return; + } + + tmpln = list_entry(curln->ln_alive_list.next, + struct htree_lock_node, ln_alive_list); + + BUG_ON(tmpln->ln_mode != HTREE_LOCK_NL); + + htree_key_list_replace_init(curln, tmpln); + list_del_init(&curln->ln_alive_list); + + return; + } + + /* have a granted lock */ + grtln = &grtlk->lk_nodes[dep]; + if (!list_empty(&curln->ln_blocked_list)) { + /* only key owner can be on both lists */ + BUG_ON(htree_key_list_empty(curln)); + + if (list_empty(&grtln->ln_blocked_list)) { + list_add(&grtln->ln_blocked_list, + &curln->ln_blocked_list); + } + list_del_init(&curln->ln_blocked_list); + } + /* + * NB: this is the tricky part: + * We have only two modes for child-lock (PR and PW), also, + * only owner of the key (attached on major/minor_list) can be on + * both blocked_list and granted_list, so @grtlk must be one + * of these two cases: + * + * a) @grtlk is taken from granted_list, which means we've granted + * more than one lock so @grtlk has to be PR, the first blocked + * lock must be PW and we can't grant it at all. + * So even @grtlk is not owner of the key (empty blocked_list), + * we don't care because we can't grant any lock. + * b) we just grant a new lock which is taken from head of blocked + * list, and it should be the first granted lock, and it should + * be the first one linked on blocked_list. + * + * Either way, we can get correct result by iterating blocked_list + * of @grtlk, and don't have to bother on how to find out + * owner of current key. + */ + list_for_each_entry_safe(poslk, tmplk, &grtln->ln_blocked_list, + lk_nodes[dep].ln_blocked_list) { + if (grtlk->lk_nodes[dep].ln_mode == HTREE_LOCK_PW || + poslk->lk_nodes[dep].ln_mode == HTREE_LOCK_PW) + break; + /* grant all readers */ + list_del_init(&poslk->lk_nodes[dep].ln_blocked_list); + list_add(&poslk->lk_nodes[dep].ln_granted_list, + &grtln->ln_granted_list); + + BUG_ON(poslk->lk_task == NULL); + wake_up_process(poslk->lk_task); + } + + /* if @curln is the owner of this key, replace it with @grtln */ + if (!htree_key_list_empty(curln)) + htree_key_list_replace_init(curln, grtln); + + if (curln->ln_mode == HTREE_LOCK_INVAL) + list_del_init(&curln->ln_alive_list); +} + +/* + * it's just wrapper of htree_node_lock_internal, it returns 1 on granted + * and 0 only if @wait is false and can't grant it immediately + */ +int +htree_node_lock_try(struct htree_lock *lck, htree_lock_mode_t mode, + u32 key, unsigned dep, int wait, void *event) +{ + struct htree_lock_head *lhead = lck->lk_head; + int rc; + + BUG_ON(dep >= lck->lk_depth); + BUG_ON(lck->lk_mode == HTREE_LOCK_INVAL); + + htree_spin_lock(lhead, dep); + rc = htree_node_lock_internal(lhead, lck, mode, key, dep, wait, event); + if (rc != 0) + htree_spin_unlock(lhead, dep); + return rc >= 0; +} +EXPORT_SYMBOL(htree_node_lock_try); + +/* it's wrapper of htree_node_unlock_internal */ +void +htree_node_unlock(struct htree_lock *lck, unsigned dep, void *event) +{ + struct htree_lock_head *lhead = lck->lk_head; + + BUG_ON(dep >= lck->lk_depth); + BUG_ON(lck->lk_mode == HTREE_LOCK_INVAL); + + htree_spin_lock(lhead, dep); + htree_node_unlock_internal(lhead, lck, dep, event); + htree_spin_unlock(lhead, dep); +} +EXPORT_SYMBOL(htree_node_unlock); + +/* stop listening on child-lock level @dep */ +void +htree_node_stop_listen(struct htree_lock *lck, unsigned dep) +{ + struct htree_lock_node *ln = &lck->lk_nodes[dep]; + struct htree_lock_node *tmp; + + BUG_ON(htree_node_is_granted(lck, dep)); + BUG_ON(!list_empty(&ln->ln_blocked_list)); + BUG_ON(!list_empty(&ln->ln_granted_list)); + + if (!htree_node_is_listening(lck, dep)) + return; + + htree_spin_lock(lck->lk_head, dep); + ln->ln_mode = HTREE_LOCK_INVAL; + ln->ln_ev_target = NULL; + + if (htree_key_list_empty(ln)) { /* not owner */ + list_del_init(&ln->ln_alive_list); + goto out; + } + + /* I'm the owner... */ + if (list_empty(&ln->ln_alive_list)) { /* no more listener */ + htree_key_list_del_init(ln); + goto out; + } + + tmp = list_entry(ln->ln_alive_list.next, + struct htree_lock_node, ln_alive_list); + + BUG_ON(tmp->ln_mode != HTREE_LOCK_NL); + htree_key_list_replace_init(ln, tmp); + list_del_init(&ln->ln_alive_list); + out: + htree_spin_unlock(lck->lk_head, dep); +} +EXPORT_SYMBOL(htree_node_stop_listen); + +/* release all child-locks if we have any */ +static void +htree_node_release_all(struct htree_lock *lck) +{ + int i; + + for (i = 0; i < lck->lk_depth; i++) { + if (htree_node_is_granted(lck, i)) + htree_node_unlock(lck, i, NULL); + else if (htree_node_is_listening(lck, i)) + htree_node_stop_listen(lck, i); + } +} + +/* + * obtain htree lock, it could be blocked inside if there's conflict + * with any granted or blocked lock and @wait is true. + * NB: ALWAYS called holding lhead::lh_lock + */ +static int +htree_lock_internal(struct htree_lock *lck, int wait) +{ + struct htree_lock_head *lhead = lck->lk_head; + int granted = 0; + int blocked = 0; + int i; + + for (i = 0; i < HTREE_LOCK_MAX; i++) { + if (lhead->lh_ngranted[i] != 0) + granted |= 1 << i; + if (lhead->lh_nblocked[i] != 0) + blocked |= 1 << i; + } + if ((htree_lock_compat[lck->lk_mode] & granted) != granted || + (htree_lock_compat[lck->lk_mode] & blocked) != blocked) { + /* will block current lock even it just conflicts with any + * other blocked lock, so lock like EX wouldn't starve */ + if (!wait) + return -1; + lhead->lh_nblocked[lck->lk_mode]++; + lk_block_inc(lck->lk_mode); + + lck->lk_task = current; + list_add_tail(&lck->lk_blocked_list, &lhead->lh_blocked_list); + +retry: + set_current_state(TASK_UNINTERRUPTIBLE); + htree_spin_unlock(lhead, HTREE_DEP_ROOT); + /* wait to be given the lock */ + if (lck->lk_task != NULL) + schedule(); + /* granted, no doubt. wake up will set me RUNNING. + * Since thread would be waken up accidentally, + * so we need check lock whether granted or not again. */ + if (!list_empty(&lck->lk_blocked_list)) { + htree_spin_lock(lhead, HTREE_DEP_ROOT); + if (list_empty(&lck->lk_blocked_list)) { + htree_spin_unlock(lhead, HTREE_DEP_ROOT); + return 0; + } + goto retry; + } + return 0; /* without lh_lock */ + } + lhead->lh_ngranted[lck->lk_mode]++; + lk_grant_inc(lck->lk_mode); + return 1; +} + +/* release htree lock. NB: ALWAYS called holding lhead::lh_lock */ +static void +htree_unlock_internal(struct htree_lock *lck) +{ + struct htree_lock_head *lhead = lck->lk_head; + struct htree_lock *tmp; + struct htree_lock *tmp2; + int granted = 0; + int i; + + BUG_ON(lhead->lh_ngranted[lck->lk_mode] == 0); + + lhead->lh_ngranted[lck->lk_mode]--; + lck->lk_mode = HTREE_LOCK_INVAL; + + for (i = 0; i < HTREE_LOCK_MAX; i++) { + if (lhead->lh_ngranted[i] != 0) + granted |= 1 << i; + } + list_for_each_entry_safe(tmp, tmp2, + &lhead->lh_blocked_list, lk_blocked_list) { + /* conflict with any granted lock? */ + if ((htree_lock_compat[tmp->lk_mode] & granted) != granted) + break; + + list_del_init(&tmp->lk_blocked_list); + + BUG_ON(lhead->lh_nblocked[tmp->lk_mode] == 0); + + lhead->lh_nblocked[tmp->lk_mode]--; + lhead->lh_ngranted[tmp->lk_mode]++; + granted |= 1 << tmp->lk_mode; + + BUG_ON(tmp->lk_task == NULL); + wake_up_process(tmp->lk_task); + } +} + +/* it's wrapper of htree_lock_internal and exported interface. + * It always return 1 with granted lock if @wait is true, it can return 0 + * if @wait is false and locking request can't be granted immediately */ +int +htree_lock_try(struct htree_lock *lck, struct htree_lock_head *lhead, + htree_lock_mode_t mode, int wait) +{ + int rc; + + BUG_ON(lck->lk_depth > lhead->lh_depth); + BUG_ON(lck->lk_head != NULL); + BUG_ON(lck->lk_task != NULL); + + lck->lk_head = lhead; + lck->lk_mode = mode; + + htree_spin_lock(lhead, HTREE_DEP_ROOT); + rc = htree_lock_internal(lck, wait); + if (rc != 0) + htree_spin_unlock(lhead, HTREE_DEP_ROOT); + return rc >= 0; +} +EXPORT_SYMBOL(htree_lock_try); + +/* it's wrapper of htree_unlock_internal and exported interface. + * It will release all htree_node_locks and htree_lock */ +void +htree_unlock(struct htree_lock *lck) +{ + BUG_ON(lck->lk_head == NULL); + BUG_ON(lck->lk_mode == HTREE_LOCK_INVAL); + + htree_node_release_all(lck); + + htree_spin_lock(lck->lk_head, HTREE_DEP_ROOT); + htree_unlock_internal(lck); + htree_spin_unlock(lck->lk_head, HTREE_DEP_ROOT); + lck->lk_head = NULL; + lck->lk_task = NULL; +} +EXPORT_SYMBOL(htree_unlock); + +/* change lock mode */ +void +htree_change_mode(struct htree_lock *lck, htree_lock_mode_t mode) +{ + BUG_ON(lck->lk_mode == HTREE_LOCK_INVAL); + lck->lk_mode = mode; +} +EXPORT_SYMBOL(htree_change_mode); + +/* release htree lock, and lock it again with new mode. + * This function will first release all htree_node_locks and htree_lock, + * then try to gain htree_lock with new @mode. + * It always return 1 with granted lock if @wait is true, it can return 0 + * if @wait is false and locking request can't be granted immediately */ +int +htree_change_lock_try(struct htree_lock *lck, htree_lock_mode_t mode, int wait) +{ + struct htree_lock_head *lhead = lck->lk_head; + int rc; + + BUG_ON(lhead == NULL); + BUG_ON(lck->lk_mode == mode); + BUG_ON(lck->lk_mode == HTREE_LOCK_INVAL || mode == HTREE_LOCK_INVAL); + + htree_node_release_all(lck); + + htree_spin_lock(lhead, HTREE_DEP_ROOT); + htree_unlock_internal(lck); + lck->lk_mode = mode; + rc = htree_lock_internal(lck, wait); + if (rc != 0) + htree_spin_unlock(lhead, HTREE_DEP_ROOT); + return rc >= 0; +} +EXPORT_SYMBOL(htree_change_lock_try); + +/* create a htree_lock head with @depth levels (number of child-locks), + * it is a per resoruce structure */ +struct htree_lock_head * +htree_lock_head_alloc(unsigned depth, unsigned hbits, unsigned priv) +{ + struct htree_lock_head *lhead; + int i; + + if (depth > HTREE_LOCK_DEP_MAX) { + printk(KERN_ERR "%d is larger than max htree_lock depth %d\n", + depth, HTREE_LOCK_DEP_MAX); + return NULL; + } + + lhead = kzalloc(offsetof(struct htree_lock_head, + lh_children[depth]) + priv, GFP_NOFS); + if (lhead == NULL) + return NULL; + + if (hbits < HTREE_HBITS_MIN) + lhead->lh_hbits = HTREE_HBITS_MIN; + else if (hbits > HTREE_HBITS_MAX) + lhead->lh_hbits = HTREE_HBITS_MAX; + + lhead->lh_lock = 0; + lhead->lh_depth = depth; + INIT_LIST_HEAD(&lhead->lh_blocked_list); + if (priv > 0) { + lhead->lh_private = (void *)lhead + + offsetof(struct htree_lock_head, lh_children[depth]); + } + + for (i = 0; i < depth; i++) { + INIT_LIST_HEAD(&lhead->lh_children[i].lc_list); + lhead->lh_children[i].lc_events = HTREE_EVENT_DISABLE; + } + return lhead; +} +EXPORT_SYMBOL(htree_lock_head_alloc); + +/* free the htree_lock head */ +void +htree_lock_head_free(struct htree_lock_head *lhead) +{ + int i; + + BUG_ON(!list_empty(&lhead->lh_blocked_list)); + for (i = 0; i < lhead->lh_depth; i++) + BUG_ON(!list_empty(&lhead->lh_children[i].lc_list)); + kfree(lhead); +} +EXPORT_SYMBOL(htree_lock_head_free); + +/* register event callback for @events of child-lock at level @dep */ +void +htree_lock_event_attach(struct htree_lock_head *lhead, unsigned dep, + unsigned events, htree_event_cb_t callback) +{ + BUG_ON(lhead->lh_depth <= dep); + lhead->lh_children[dep].lc_events = events; + lhead->lh_children[dep].lc_callback = callback; +} +EXPORT_SYMBOL(htree_lock_event_attach); + +/* allocate a htree_lock, which is per-thread structure, @pbytes is some + * extra-bytes as private data for caller */ +struct htree_lock * +htree_lock_alloc(unsigned depth, unsigned pbytes) +{ + struct htree_lock *lck; + int i = offsetof(struct htree_lock, lk_nodes[depth]); + + if (depth > HTREE_LOCK_DEP_MAX) { + printk(KERN_ERR "%d is larger than max htree_lock depth %d\n", + depth, HTREE_LOCK_DEP_MAX); + return NULL; + } + lck = kzalloc(i + pbytes, GFP_NOFS); + if (lck == NULL) + return NULL; + + if (pbytes != 0) + lck->lk_private = (void *)lck + i; + lck->lk_mode = HTREE_LOCK_INVAL; + lck->lk_depth = depth; + INIT_LIST_HEAD(&lck->lk_blocked_list); + + for (i = 0; i < depth; i++) { + struct htree_lock_node *node = &lck->lk_nodes[i]; + + node->ln_mode = HTREE_LOCK_INVAL; + INIT_LIST_HEAD(&node->ln_major_list); + INIT_LIST_HEAD(&node->ln_minor_list); + INIT_LIST_HEAD(&node->ln_alive_list); + INIT_LIST_HEAD(&node->ln_blocked_list); + INIT_LIST_HEAD(&node->ln_granted_list); + } + + return lck; +} +EXPORT_SYMBOL(htree_lock_alloc); + +/* free htree_lock node */ +void +htree_lock_free(struct htree_lock *lck) +{ + BUG_ON(lck->lk_mode != HTREE_LOCK_INVAL); + kfree(lck); +} +EXPORT_SYMBOL(htree_lock_free); diff --git a/fs/ext4/htree_lock.h b/fs/ext4/htree_lock.h new file mode 100644 index 0000000..9dc7788 --- /dev/null +++ b/fs/ext4/htree_lock.h @@ -0,0 +1,187 @@ +/* + * include/linux/htree_lock.h + * + * Copyright (c) 2011, 2012, Intel Corporation. + * + * Author: Liang Zhen + */ + +/* + * htree lock + * + * htree_lock is an advanced lock, it can support five lock modes (concept is + * taken from DLM) and it's a sleeping lock. + * + * most common use case is: + * - create a htree_lock_head for data + * - each thread (contender) creates it's own htree_lock + * - contender needs to call htree_lock(lock_node, mode) to protect data and + * call htree_unlock to release lock + * + * Also, there is advanced use-case which is more complex, user can have + * PW/PR lock on particular key, it's mostly used while user holding shared + * lock on the htree (CW, CR) + * + * htree_lock(lock_node, HTREE_LOCK_CR); lock the htree with CR + * htree_node_lock(lock_node, HTREE_LOCK_PR, key...); lock @key with PR + * ... + * htree_node_unlock(lock_node);; unlock the key + * + * Another tip is, we can have N-levels of this kind of keys, all we need to + * do is specifying N-levels while creating htree_lock_head, then we can + * lock/unlock a specific level by: + * htree_node_lock(lock_node, mode1, key1, level1...); + * do something; + * htree_node_lock(lock_node, mode1, key2, level2...); + * do something; + * htree_node_unlock(lock_node, level2); + * htree_node_unlock(lock_node, level1); + * + * NB: for multi-level, should be careful about locking order to avoid deadlock + */ + +#ifndef _LINUX_HTREE_LOCK_H +#define _LINUX_HTREE_LOCK_H + +#include +#include +#include + +/* + * Lock Modes + * more details can be found here: + * http://en.wikipedia.org/wiki/Distributed_lock_manager + */ +typedef enum { + HTREE_LOCK_EX = 0, /* exclusive lock: incompatible with all others */ + HTREE_LOCK_PW, /* protected write: allows only CR users */ + HTREE_LOCK_PR, /* protected read: allow PR, CR users */ + HTREE_LOCK_CW, /* concurrent write: allow CR, CW users */ + HTREE_LOCK_CR, /* concurrent read: allow all but EX users */ + HTREE_LOCK_MAX, /* number of lock modes */ +} htree_lock_mode_t; + +#define HTREE_LOCK_NL HTREE_LOCK_MAX +#define HTREE_LOCK_INVAL 0xdead10c + +enum { + HTREE_HBITS_MIN = 2, + HTREE_HBITS_DEF = 14, + HTREE_HBITS_MAX = 32, +}; + +enum { + HTREE_EVENT_DISABLE = (0), + HTREE_EVENT_RD = (1 << HTREE_LOCK_PR), + HTREE_EVENT_WR = (1 << HTREE_LOCK_PW), + HTREE_EVENT_RDWR = (HTREE_EVENT_RD | HTREE_EVENT_WR), +}; + +struct htree_lock; + +typedef void (*htree_event_cb_t)(void *target, void *event); + +struct htree_lock_child { + struct list_head lc_list; /* granted list */ + htree_event_cb_t lc_callback; /* event callback */ + unsigned lc_events; /* event types */ +}; + +struct htree_lock_head { + unsigned long lh_lock; /* bits lock */ + /* blocked lock list (htree_lock) */ + struct list_head lh_blocked_list; + /* # key levels */ + u16 lh_depth; + /* hash bits for key and limit number of locks */ + u16 lh_hbits; + /* counters for blocked locks */ + u16 lh_nblocked[HTREE_LOCK_MAX]; + /* counters for granted locks */ + u16 lh_ngranted[HTREE_LOCK_MAX]; + /* private data */ + void *lh_private; + /* array of children locks */ + struct htree_lock_child lh_children[0]; +}; + +/* htree_lock_node_t is child-lock for a specific key (ln_value) */ +struct htree_lock_node { + htree_lock_mode_t ln_mode; + /* major hash key */ + u16 ln_major_key; + /* minor hash key */ + u16 ln_minor_key; + struct list_head ln_major_list; + struct list_head ln_minor_list; + /* alive list, all locks (granted, blocked, listening) are on it */ + struct list_head ln_alive_list; + /* blocked list */ + struct list_head ln_blocked_list; + /* granted list */ + struct list_head ln_granted_list; + void *ln_ev_target; +}; + +struct htree_lock { + struct task_struct *lk_task; + struct htree_lock_head *lk_head; + void *lk_private; + unsigned lk_depth; + htree_lock_mode_t lk_mode; + struct list_head lk_blocked_list; + struct htree_lock_node lk_nodes[0]; +}; + +/* create a lock head, which stands for a resource */ +struct htree_lock_head *htree_lock_head_alloc(unsigned depth, + unsigned hbits, unsigned priv); +/* free a lock head */ +void htree_lock_head_free(struct htree_lock_head *lhead); +/* register event callback for child lock at level @depth */ +void htree_lock_event_attach(struct htree_lock_head *lhead, unsigned depth, + unsigned events, htree_event_cb_t callback); +/* create a lock handle, which stands for a thread */ +struct htree_lock *htree_lock_alloc(unsigned depth, unsigned pbytes); +/* free a lock handle */ +void htree_lock_free(struct htree_lock *lck); +/* lock htree, when @wait is true, 0 is returned if the lock can't + * be granted immediately */ +int htree_lock_try(struct htree_lock *lck, struct htree_lock_head *lhead, + htree_lock_mode_t mode, int wait); +/* unlock htree */ +void htree_unlock(struct htree_lock *lck); +/* unlock and relock htree with @new_mode */ +int htree_change_lock_try(struct htree_lock *lck, + htree_lock_mode_t new_mode, int wait); +void htree_change_mode(struct htree_lock *lck, htree_lock_mode_t mode); +/* require child lock (key) of htree at level @dep, @event will be sent to all + * listeners on this @key while lock being granted */ +int htree_node_lock_try(struct htree_lock *lck, htree_lock_mode_t mode, + u32 key, unsigned dep, int wait, void *event); +/* release child lock at level @dep, this lock will listen on it's key + * if @event isn't NULL, event_cb will be called against @lck while granting + * any other lock at level @dep with the same key */ +void htree_node_unlock(struct htree_lock *lck, unsigned dep, void *event); +/* stop listening on child lock at level @dep */ +void htree_node_stop_listen(struct htree_lock *lck, unsigned dep); +/* for debug */ +void htree_lock_stat_print(int depth); +void htree_lock_stat_reset(void); + +#define htree_lock(lck, lh, mode) htree_lock_try(lck, lh, mode, 1) +#define htree_change_lock(lck, mode) htree_change_lock_try(lck, mode, 1) + +#define htree_lock_mode(lck) ((lck)->lk_mode) + +#define htree_node_lock(lck, mode, key, dep) \ + htree_node_lock_try(lck, mode, key, dep, 1, NULL) +/* this is only safe in thread context of lock owner */ +#define htree_node_is_granted(lck, dep) \ + ((lck)->lk_nodes[dep].ln_mode != HTREE_LOCK_INVAL && \ + (lck)->lk_nodes[dep].ln_mode != HTREE_LOCK_NL) +/* this is only safe in thread context of lock owner */ +#define htree_node_is_listening(lck, dep) \ + ((lck)->lk_nodes[dep].ln_mode == HTREE_LOCK_NL) + +#endif diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 9cb86e4..0153c4d 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -54,6 +54,7 @@ struct buffer_head *ext4_append(handle_t *handle, struct inode *inode, ext4_lblk_t *block) { + struct ext4_inode_info *ei = EXT4_I(inode); struct buffer_head *bh; int err; @@ -62,15 +63,24 @@ struct buffer_head *ext4_append(handle_t *handle, EXT4_SB(inode->i_sb)->s_max_dir_size_kb))) return ERR_PTR(-ENOSPC); + /* with parallel dir operations all appends + * have to be serialized -bzzz + */ + down(&ei->i_append_sem); + *block = inode->i_size >> inode->i_sb->s_blocksize_bits; bh = ext4_bread(handle, inode, *block, EXT4_GET_BLOCKS_CREATE); - if (IS_ERR(bh)) + if (IS_ERR(bh)) { + up(&ei->i_append_sem); return bh; + } + inode->i_size += inode->i_sb->s_blocksize; EXT4_I(inode)->i_disksize = inode->i_size; BUFFER_TRACE(bh, "get_write_access"); err = ext4_journal_get_write_access(handle, bh); + up(&ei->i_append_sem); if (err) { brelse(bh); ext4_std_error(inode->i_sb, err); @@ -250,7 +260,8 @@ static unsigned int inline dx_root_limit(struct inode *dir, static struct dx_frame *dx_probe(struct ext4_filename *fname, struct inode *dir, struct dx_hash_info *hinfo, - struct dx_frame *frame); + struct dx_frame *frame, + struct htree_lock *lck); static void dx_release(struct dx_frame *frames); static int dx_make_map(struct inode *dir, struct ext4_dir_entry_2 *de, unsigned blocksize, struct dx_hash_info *hinfo, @@ -264,12 +275,13 @@ static void dx_insert_block(struct dx_frame *frame, static int ext4_htree_next_block(struct inode *dir, __u32 hash, struct dx_frame *frame, struct dx_frame *frames, - __u32 *start_hash); + __u32 *start_hash, struct htree_lock *lck); static struct buffer_head * ext4_dx_find_entry(struct inode *dir, struct ext4_filename *fname, - struct ext4_dir_entry_2 **res_dir); + struct ext4_dir_entry_2 **res_dir, struct htree_lock *lck); static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, - struct inode *dir, struct inode *inode); + struct inode *dir, struct inode *inode, + struct htree_lock *lck); /* checksumming functions */ void initialize_dirent_tail(struct ext4_dir_entry_tail *t, @@ -734,6 +746,226 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir, } #endif /* DX_DEBUG */ +/* private data for htree_lock */ +struct ext4_dir_lock_data { + unsigned int ld_flags; /* bits-map for lock types */ + unsigned int ld_count; /* # entries of the last DX block */ + struct dx_entry ld_at_entry; /* copy of leaf dx_entry */ + struct dx_entry *ld_at; /* position of leaf dx_entry */ +}; + +#define ext4_htree_lock_data(l) ((struct ext4_dir_lock_data *)(l)->lk_private) +#define ext4_find_entry(dir, name, dirent, inline) \ + ext4_find_entry_locked(dir, name, dirent, inline, NULL) +#define ext4_add_entry(handle, dentry, inode) \ + ext4_add_entry_locked(handle, dentry, inode, NULL) + +/* NB: ext4_lblk_t is 32 bits so we use high bits to identify invalid blk */ +#define EXT4_HTREE_NODE_CHANGED (0xcafeULL << 32) + +static void ext4_htree_event_cb(void *target, void *event) +{ + u64 *block = (u64 *)target; + + if (*block == dx_get_block((struct dx_entry *)event)) + *block = EXT4_HTREE_NODE_CHANGED; +} + +struct htree_lock_head *ext4_htree_lock_head_alloc(unsigned hbits) +{ + struct htree_lock_head *lhead; + + lhead = htree_lock_head_alloc(EXT4_LK_MAX, hbits, 0); + if (lhead) { + htree_lock_event_attach(lhead, EXT4_LK_SPIN, HTREE_EVENT_WR, + ext4_htree_event_cb); + } + return lhead; +} +EXPORT_SYMBOL(ext4_htree_lock_head_alloc); + +struct htree_lock *ext4_htree_lock_alloc(void) +{ + return htree_lock_alloc(EXT4_LK_MAX, + sizeof(struct ext4_dir_lock_data)); +} +EXPORT_SYMBOL(ext4_htree_lock_alloc); + +static htree_lock_mode_t ext4_htree_mode(unsigned flags) +{ + switch (flags) { + default: /* 0 or unknown flags require EX lock */ + return HTREE_LOCK_EX; + case EXT4_HLOCK_READDIR: + return HTREE_LOCK_PR; + case EXT4_HLOCK_LOOKUP: + return HTREE_LOCK_CR; + case EXT4_HLOCK_DEL: + case EXT4_HLOCK_ADD: + return HTREE_LOCK_CW; + } +} + +/* return PR for read-only operations, otherwise return EX */ +static inline htree_lock_mode_t ext4_htree_safe_mode(unsigned flags) +{ + int writer = (flags & EXT4_LB_DE) == EXT4_LB_DE; + + /* 0 requires EX lock */ + return (flags == 0 || writer) ? HTREE_LOCK_EX : HTREE_LOCK_PR; +} + +static int ext4_htree_safe_locked(struct htree_lock *lck) +{ + int writer; + + if (!lck || lck->lk_mode == HTREE_LOCK_EX) + return 1; + + writer = (ext4_htree_lock_data(lck)->ld_flags & EXT4_LB_DE) == + EXT4_LB_DE; + if (writer) /* all readers & writers are excluded? */ + return lck->lk_mode == HTREE_LOCK_EX; + + /* all writers are excluded? */ + return lck->lk_mode == HTREE_LOCK_PR || + lck->lk_mode == HTREE_LOCK_PW || + lck->lk_mode == HTREE_LOCK_EX; +} + +/* relock htree_lock with EX mode if it's change operation, otherwise + * relock it with PR mode. It's noop if PDO is disabled. + */ +static void ext4_htree_safe_relock(struct htree_lock *lck) +{ + if (!ext4_htree_safe_locked(lck)) { + unsigned int flags = ext4_htree_lock_data(lck)->ld_flags; + + htree_change_lock(lck, ext4_htree_safe_mode(flags)); + } +} + +void ext4_htree_lock(struct htree_lock *lck, struct htree_lock_head *lhead, + struct inode *dir, unsigned flags) +{ + htree_lock_mode_t mode = is_dx(dir) ? ext4_htree_mode(flags) : + ext4_htree_safe_mode(flags); + + ext4_htree_lock_data(lck)->ld_flags = flags; + htree_lock(lck, lhead, mode); + if (!is_dx(dir)) + ext4_htree_safe_relock(lck); /* make sure it's safe locked */ +} +EXPORT_SYMBOL(ext4_htree_lock); + +static int ext4_htree_node_lock(struct htree_lock *lck, struct dx_entry *at, + unsigned int lmask, int wait, void *ev) +{ + u32 key = (at == NULL) ? 0 : dx_get_block(at); + u32 mode; + + /* NOOP if htree is well protected or caller doesn't require the lock */ + if (ext4_htree_safe_locked(lck) || + !(ext4_htree_lock_data(lck)->ld_flags & lmask)) + return 1; + + mode = (ext4_htree_lock_data(lck)->ld_flags & lmask) == lmask ? + HTREE_LOCK_PW : HTREE_LOCK_PR; + while (1) { + if (htree_node_lock_try(lck, mode, key, ffz(~lmask), wait, ev)) + return 1; + if (!(lmask & EXT4_LB_SPIN)) /* not a spinlock */ + return 0; + cpu_relax(); /* spin until granted */ + } +} + +static int ext4_htree_node_locked(struct htree_lock *lck, unsigned lmask) +{ + return ext4_htree_safe_locked(lck) || + htree_node_is_granted(lck, ffz(~lmask)); +} + +static void ext4_htree_node_unlock(struct htree_lock *lck, + unsigned int lmask, void *buf) +{ + /* NB: it's safe to call mutiple times or even it's not locked */ + if (!ext4_htree_safe_locked(lck) && + htree_node_is_granted(lck, ffz(~lmask))) + htree_node_unlock(lck, ffz(~lmask), buf); +} + +#define ext4_htree_dx_lock(lck, key) \ + ext4_htree_node_lock(lck, key, EXT4_LB_DX, 1, NULL) +#define ext4_htree_dx_lock_try(lck, key) \ + ext4_htree_node_lock(lck, key, EXT4_LB_DX, 0, NULL) +#define ext4_htree_dx_unlock(lck) \ + ext4_htree_node_unlock(lck, EXT4_LB_DX, NULL) +#define ext4_htree_dx_locked(lck) \ + ext4_htree_node_locked(lck, EXT4_LB_DX) + +static void ext4_htree_dx_need_lock(struct htree_lock *lck) +{ + struct ext4_dir_lock_data *ld; + + if (ext4_htree_safe_locked(lck)) + return; + + ld = ext4_htree_lock_data(lck); + switch (ld->ld_flags) { + default: + return; + case EXT4_HLOCK_LOOKUP: + ld->ld_flags = EXT4_HLOCK_LOOKUP_SAFE; + return; + case EXT4_HLOCK_DEL: + ld->ld_flags = EXT4_HLOCK_DEL_SAFE; + return; + case EXT4_HLOCK_ADD: + ld->ld_flags = EXT4_HLOCK_SPLIT; + return; + } +} + +#define ext4_htree_de_lock(lck, key) \ + ext4_htree_node_lock(lck, key, EXT4_LB_DE, 1, NULL) +#define ext4_htree_de_unlock(lck) \ + ext4_htree_node_unlock(lck, EXT4_LB_DE, NULL) + +#define ext4_htree_spin_lock(lck, key, event) \ + ext4_htree_node_lock(lck, key, EXT4_LB_SPIN, 0, event) +#define ext4_htree_spin_unlock(lck) \ + ext4_htree_node_unlock(lck, EXT4_LB_SPIN, NULL) +#define ext4_htree_spin_unlock_listen(lck, p) \ + ext4_htree_node_unlock(lck, EXT4_LB_SPIN, p) + +static void ext4_htree_spin_stop_listen(struct htree_lock *lck) +{ + if (!ext4_htree_safe_locked(lck) && + htree_node_is_listening(lck, ffz(~EXT4_LB_SPIN))) + htree_node_stop_listen(lck, ffz(~EXT4_LB_SPIN)); +} + +enum { + DX_HASH_COL_IGNORE, /* ignore collision while probing frames */ + DX_HASH_COL_YES, /* there is collision and it does matter */ + DX_HASH_COL_NO, /* there is no collision */ +}; + +static int dx_probe_hash_collision(struct htree_lock *lck, + struct dx_entry *entries, + struct dx_entry *at, u32 hash) +{ + if (!(lck && ext4_htree_lock_data(lck)->ld_flags & EXT4_LB_EXACT)) { + return DX_HASH_COL_IGNORE; /* don't care about collision */ + } else if (at == entries + dx_get_count(entries) - 1) { + return DX_HASH_COL_IGNORE; /* not in any leaf of this DX */ + } else { /* hash collision? */ + return ((dx_get_hash(at + 1) & ~1) == hash) ? + DX_HASH_COL_YES : DX_HASH_COL_NO; + } +} + /* * Probe for a directory leaf block to search. * @@ -745,10 +977,11 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir, */ static struct dx_frame * dx_probe(struct ext4_filename *fname, struct inode *dir, - struct dx_hash_info *hinfo, struct dx_frame *frame_in) + struct dx_hash_info *hinfo, struct dx_frame *frame_in, + struct htree_lock *lck) { unsigned count, indirect; - struct dx_entry *at, *entries, *p, *q, *m; + struct dx_entry *at, *entries, *p, *q, *m, *dx = NULL; struct dx_root_info *info; struct dx_frame *frame = frame_in; struct dx_frame *ret_err = ERR_PTR(ERR_BAD_DX_DIR); @@ -811,6 +1044,13 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir, dxtrace(printk("Look up %x", hash)); while (1) { + if (indirect == 0) { /* the last index level */ + /* NB: ext4_htree_dx_lock() could be noop if + * DX-lock flag is not set for current operation + */ + ext4_htree_dx_lock(lck, dx); + ext4_htree_spin_lock(lck, dx, NULL); + } count = dx_get_count(entries); if (!count || count > dx_get_limit(entries)) { ext4_warning_inode(dir, @@ -851,8 +1091,75 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir, dx_get_block(at))); frame->entries = entries; frame->at = at; - if (!indirect--) + + if (indirect == 0) { /* the last index level */ + struct ext4_dir_lock_data *ld; + u64 myblock; + + /* By default we only lock DE-block, however, we will + * also lock the last level DX-block if: + * a) there is hash collision + * we will set DX-lock flag (a few lines below) + * and redo to lock DX-block + * see detail in dx_probe_hash_collision() + * b) it's a retry from splitting + * we need to lock the last level DX-block so nobody + * else can split any leaf blocks under the same + * DX-block, see detail in ext4_dx_add_entry() + */ + if (ext4_htree_dx_locked(lck)) { + /* DX-block is locked, just lock DE-block + * and return + */ + ext4_htree_spin_unlock(lck); + if (!ext4_htree_safe_locked(lck)) + ext4_htree_de_lock(lck, frame->at); + return frame; + } + /* it's pdirop and no DX lock */ + if (dx_probe_hash_collision(lck, entries, at, hash) == + DX_HASH_COL_YES) { + /* found hash collision, set DX-lock flag + * and retry to abtain DX-lock + */ + ext4_htree_spin_unlock(lck); + ext4_htree_dx_need_lock(lck); + continue; + } + ld = ext4_htree_lock_data(lck); + /* because I don't lock DX, so @at can't be trusted + * after I release spinlock so I have to save it + */ + ld->ld_at = at; + ld->ld_at_entry = *at; + ld->ld_count = dx_get_count(entries); + + frame->at = &ld->ld_at_entry; + myblock = dx_get_block(at); + + /* NB: ordering locking */ + ext4_htree_spin_unlock_listen(lck, &myblock); + /* other thread can split this DE-block because: + * a) I don't have lock for the DE-block yet + * b) I released spinlock on DX-block + * if it happened I can detect it by listening + * splitting event on this DE-block + */ + ext4_htree_de_lock(lck, frame->at); + ext4_htree_spin_stop_listen(lck); + + if (myblock == EXT4_HTREE_NODE_CHANGED) { + /* someone split this DE-block before + * I locked it, I need to retry and lock + * valid DE-block + */ + ext4_htree_de_unlock(lck); + continue; + } return frame; + } + dx = at; + indirect--; frame++; frame->bh = ext4_read_dirblock(dir, dx_get_block(at), INDEX); if (IS_ERR(frame->bh)) { @@ -921,7 +1228,7 @@ static void dx_release(struct dx_frame *frames) static int ext4_htree_next_block(struct inode *dir, __u32 hash, struct dx_frame *frame, struct dx_frame *frames, - __u32 *start_hash) + u32 *start_hash, struct htree_lock *lck) { struct dx_frame *p; struct buffer_head *bh; @@ -936,12 +1243,23 @@ static int ext4_htree_next_block(struct inode *dir, __u32 hash, * this loop, num_frames indicates the number of interior * nodes need to be read. */ + ext4_htree_de_unlock(lck); while (1) { - if (++(p->at) < p->entries + dx_get_count(p->entries)) - break; + if (num_frames > 0 || ext4_htree_dx_locked(lck)) { + /* num_frames > 0 : + * DX block + * ext4_htree_dx_locked: + * frame->at is reliable pointer returned by dx_probe, + * otherwise dx_probe already knew no collision + */ + if (++(p->at) < p->entries + dx_get_count(p->entries)) + break; + } if (p == frames) return 0; num_frames++; + if (num_frames == 1) + ext4_htree_dx_unlock(lck); p--; } @@ -964,6 +1282,14 @@ static int ext4_htree_next_block(struct inode *dir, __u32 hash, * block so no check is necessary */ while (num_frames--) { + if (num_frames == 0) { + /* it's not always necessary, we just don't want to + * detect hash collision again + */ + ext4_htree_dx_need_lock(lck); + ext4_htree_dx_lock(lck, p->at); + } + bh = ext4_read_dirblock(dir, dx_get_block(p->at), INDEX); if (IS_ERR(bh)) return PTR_ERR(bh); @@ -972,10 +1298,10 @@ static int ext4_htree_next_block(struct inode *dir, __u32 hash, p->bh = bh; p->at = p->entries = ((struct dx_node *) bh->b_data)->entries; } + ext4_htree_de_lock(lck, p->at); return 1; } - /* * This function fills a red-black tree with information from a * directory block. It returns the number directory entries loaded @@ -1119,7 +1445,8 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash, } hinfo.hash = start_hash; hinfo.minor_hash = 0; - frame = dx_probe(NULL, dir, &hinfo, frames); + /* assume it's PR locked */ + frame = dx_probe(NULL, dir, &hinfo, frames, NULL); if (IS_ERR(frame)) return PTR_ERR(frame); @@ -1162,7 +1489,7 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash, count += ret; hashval = ~0; ret = ext4_htree_next_block(dir, HASH_NB_ALWAYS, - frame, frames, &hashval); + frame, frames, &hashval, NULL); *next_hash = hashval; if (ret < 0) { err = ret; @@ -1400,7 +1727,7 @@ static int is_dx_internal_node(struct inode *dir, ext4_lblk_t block, static struct buffer_head *__ext4_find_entry(struct inode *dir, struct ext4_filename *fname, struct ext4_dir_entry_2 **res_dir, - int *inlined) + int *inlined, struct htree_lock *lck) { struct super_block *sb; struct buffer_head *bh_use[NAMEI_RA_SIZE]; @@ -1442,7 +1769,7 @@ static struct buffer_head *__ext4_find_entry(struct inode *dir, goto restart; } if (is_dx(dir)) { - ret = ext4_dx_find_entry(dir, fname, res_dir); + ret = ext4_dx_find_entry(dir, fname, res_dir, lck); /* * On success, or if the error was file not found, * return. Otherwise, fall back to doing a search the @@ -1452,6 +1779,7 @@ static struct buffer_head *__ext4_find_entry(struct inode *dir, goto cleanup_and_exit; dxtrace(printk(KERN_DEBUG "ext4_find_entry: dx failed, " "falling back\n")); + ext4_htree_safe_relock(lck); ret = NULL; } nblocks = dir->i_size >> EXT4_BLOCK_SIZE_BITS(sb); @@ -1540,10 +1868,10 @@ static struct buffer_head *__ext4_find_entry(struct inode *dir, return ret; } -static struct buffer_head *ext4_find_entry(struct inode *dir, +struct buffer_head *ext4_find_entry_locked(struct inode *dir, const struct qstr *d_name, struct ext4_dir_entry_2 **res_dir, - int *inlined) + int *inlined, struct htree_lock *lck) { int err; struct ext4_filename fname; @@ -1555,11 +1883,12 @@ static struct buffer_head *ext4_find_entry(struct inode *dir, if (err) return ERR_PTR(err); - bh = __ext4_find_entry(dir, &fname, res_dir, inlined); + bh = __ext4_find_entry(dir, &fname, res_dir, inlined, lck); ext4_fname_free_filename(&fname); return bh; } +EXPORT_SYMBOL(ext4_find_entry_locked); static struct buffer_head *ext4_lookup_entry(struct inode *dir, struct dentry *dentry, @@ -1575,7 +1904,7 @@ static struct buffer_head *ext4_lookup_entry(struct inode *dir, if (err) return ERR_PTR(err); - bh = __ext4_find_entry(dir, &fname, res_dir, NULL); + bh = __ext4_find_entry(dir, &fname, res_dir, NULL, NULL); ext4_fname_free_filename(&fname); return bh; @@ -1583,7 +1912,8 @@ static struct buffer_head *ext4_lookup_entry(struct inode *dir, static struct buffer_head * ext4_dx_find_entry(struct inode *dir, struct ext4_filename *fname, - struct ext4_dir_entry_2 **res_dir) + struct ext4_dir_entry_2 **res_dir, + struct htree_lock *lck) { struct super_block * sb = dir->i_sb; struct dx_frame frames[EXT4_HTREE_LEVEL], *frame; @@ -1594,7 +1924,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, #ifdef CONFIG_FS_ENCRYPTION *res_dir = NULL; #endif - frame = dx_probe(fname, dir, NULL, frames); + frame = dx_probe(fname, dir, NULL, frames, lck); if (IS_ERR(frame)) return (struct buffer_head *) frame; do { @@ -1616,7 +1946,7 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, /* Check to see if we should continue to search */ retval = ext4_htree_next_block(dir, fname->hinfo.hash, frame, - frames, NULL); + frames, NULL, lck); if (retval < 0) { ext4_warning_inode(dir, "error %d reading directory index block", @@ -1799,8 +2129,9 @@ static struct ext4_dir_entry_2* dx_pack_dirents(char *base, unsigned blocksize) * Returns pointer to de in block into which the new entry will be inserted. */ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, - struct buffer_head **bh,struct dx_frame *frame, - struct dx_hash_info *hinfo) + struct buffer_head **bh, struct dx_frame *frames, + struct dx_frame *frame, struct dx_hash_info *hinfo, + struct htree_lock *lck) { unsigned blocksize = dir->i_sb->s_blocksize; unsigned count, continued; @@ -1862,8 +2193,15 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, hash2, split, count-split)); /* Fancy dance to stay within two buffers */ - de2 = dx_move_dirents(data1, data2, map + split, count - split, - blocksize); + if (hinfo->hash < hash2) { + de2 = dx_move_dirents(data1, data2, map + split, + count - split, blocksize); + } else { + /* make sure we will add entry to the same block which + * we have already locked + */ + de2 = dx_move_dirents(data1, data2, map, split, blocksize); + } de = dx_pack_dirents(data1, blocksize); de->rec_len = ext4_rec_len_to_disk(data1 + (blocksize - csum_size) - (char *) de, @@ -1884,12 +2222,20 @@ static struct ext4_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, dxtrace(dx_show_leaf(dir, hinfo, (struct ext4_dir_entry_2 *) data2, blocksize, 1)); - /* Which block gets the new entry? */ - if (hinfo->hash >= hash2) { - swap(*bh, bh2); - de = de2; + ext4_htree_spin_lock(lck, frame > frames ? (frame - 1)->at : NULL, + frame->at); /* notify block is being split */ + if (hinfo->hash < hash2) { + dx_insert_block(frame, hash2 + continued, newblock); + } else { + /* switch block number */ + dx_insert_block(frame, hash2 + continued, + dx_get_block(frame->at)); + dx_set_block(frame->at, newblock); + (frame->at)++; } - dx_insert_block(frame, hash2 + continued, newblock); + ext4_htree_spin_unlock(lck); + ext4_htree_dx_unlock(lck); + err = ext4_handle_dirty_dirent_node(handle, dir, bh2); if (err) goto journal_error; @@ -2167,7 +2513,7 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname, if (retval) goto out_frames; - de = do_split(handle,dir, &bh2, frame, &fname->hinfo); + de = do_split(handle, dir, &bh2, frames, frame, &fname->hinfo, NULL); if (IS_ERR(de)) { retval = PTR_ERR(de); goto out_frames; @@ -2276,8 +2622,8 @@ static int ext4_update_dotdot(handle_t *handle, struct dentry *dentry, * may not sleep between calling this and putting something into * the entry, as someone else might have used it while you slept. */ -static int ext4_add_entry(handle_t *handle, struct dentry *dentry, - struct inode *inode) +int ext4_add_entry_locked(handle_t *handle, struct dentry *dentry, + struct inode *inode, struct htree_lock *lck) { struct inode *dir = d_inode(dentry->d_parent); struct buffer_head *bh = NULL; @@ -2326,9 +2672,10 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, if (dentry->d_name.len == 2 && memcmp(dentry->d_name.name, "..", 2) == 0) return ext4_update_dotdot(handle, dentry, inode); - retval = ext4_dx_add_entry(handle, &fname, dir, inode); + retval = ext4_dx_add_entry(handle, &fname, dir, inode, lck); if (!retval || (retval != ERR_BAD_DX_DIR)) goto out; + ext4_htree_safe_relock(lck); ext4_clear_inode_flag(dir, EXT4_INODE_INDEX); dx_fallback++; ext4_mark_inode_dirty(handle, dir); @@ -2378,12 +2725,14 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry, ext4_set_inode_state(inode, EXT4_STATE_NEWENTRY); return retval; } +EXPORT_SYMBOL(ext4_add_entry_locked); /* * Returns 0 for success, or a negative error value */ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, - struct inode *dir, struct inode *inode) + struct inode *dir, struct inode *inode, + struct htree_lock *lck) { struct dx_frame frames[EXT4_HTREE_LEVEL], *frame; struct dx_entry *entries, *at; @@ -2395,7 +2744,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, again: restart = 0; - frame = dx_probe(fname, dir, NULL, frames); + frame = dx_probe(fname, dir, NULL, frames, lck); if (IS_ERR(frame)) return PTR_ERR(frame); entries = frame->entries; @@ -2430,6 +2779,12 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, struct dx_node *node2; struct buffer_head *bh2; + if (!ext4_htree_safe_locked(lck)) { /* retry with EX lock */ + ext4_htree_safe_relock(lck); + restart = 1; + goto cleanup; + } + while (frame > frames) { if (dx_get_count((frame - 1)->entries) < dx_get_limit((frame - 1)->entries)) { @@ -2533,8 +2888,34 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, restart = 1; goto journal_error; } + } else if (!ext4_htree_dx_locked(lck)) { + struct ext4_dir_lock_data *ld = ext4_htree_lock_data(lck); + + /* not well protected, require DX lock */ + ext4_htree_dx_need_lock(lck); + at = frame > frames ? (frame - 1)->at : NULL; + + /* NB: no risk of deadlock because it's just a try. + * + * NB: we check ld_count for twice, the first time before + * having DX lock, the second time after holding DX lock. + * + * NB: We never free blocks for directory so far, which + * means value returned by dx_get_count() should equal to + * ld->ld_count if nobody split any DE-block under @at, + * and ld->ld_at still points to valid dx_entry. + */ + if ((ld->ld_count != dx_get_count(entries)) || + !ext4_htree_dx_lock_try(lck, at) || + (ld->ld_count != dx_get_count(entries))) { + restart = 1; + goto cleanup; + } + /* OK, I've got DX lock and nothing changed */ + frame->at = ld->ld_at; } - de = do_split(handle, dir, &bh, frame, &fname->hinfo); + + de = do_split(handle, dir, &bh, frames, frame, &fname->hinfo, lck); if (IS_ERR(de)) { err = PTR_ERR(de); goto cleanup; @@ -2545,6 +2926,8 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, journal_error: ext4_std_error(dir->i_sb, err); /* this is a no-op if err == 0 */ cleanup: + ext4_htree_dx_unlock(lck); + ext4_htree_de_unlock(lck); brelse(bh); dx_release(frames); /* @restart is true means htree-path has been changed, we need to diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 564eb35..07242d7 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1077,6 +1077,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) return NULL; inode_set_iversion(&ei->vfs_inode, 1); + sema_init(&ei->i_append_sem, 1); spin_lock_init(&ei->i_raw_lock); INIT_LIST_HEAD(&ei->i_prealloc_list); spin_lock_init(&ei->i_prealloc_lock); -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:48 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:48 -0400 Subject: [lustre-devel] [PATCH 19/22] ext4: don't check before replay In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-20-git-send-email-jsimmons@infradead.org> When ldiskfs run in failover mode whith read-only disk. Part of allocation updates are lost and ldiskfs may fail while mounting this is due to inconsistent state of group-descriptor. Group-descriptor check is added after journal replay. Signed-off-by: James Simmons --- fs/ext4/super.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index a3179b2..b818acb 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4255,11 +4255,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) } } sbi->s_gdb_count = db_count; - if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { - ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); - ret = -EFSCORRUPTED; - goto failed_mount2; - } timer_setup(&sbi->s_err_report, print_daily_error_info, 0); @@ -4401,6 +4396,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; no_journal: + if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { + ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); + ret = -EFSCORRUPTED; + goto failed_mount_wq; + } + if (!test_opt(sb, NO_MBCACHE)) { sbi->s_ea_block_cache = ext4_xattr_create_cache(); if (!sbi->s_ea_block_cache) { -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:50 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:50 -0400 Subject: [lustre-devel] [PATCH 21/22] ext4: export ext4_orphan_add In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-22-git-send-email-jsimmons@infradead.org> Signed-off-by: James Simmons --- fs/ext4/namei.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 9b30cc6..6cb3f63 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3615,6 +3615,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) ext4_std_error(sb, err); return err; } +EXPORT_SYMBOL(ext4_orphan_add); /* * ext4_orphan_del() removes an unlinked or truncated inode from the list -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:29 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:29 -0400 Subject: [lustre-devel] [PATCH 00/22] [RFC] ldiskfs patches against 5.2-rc2+ Message-ID: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> From: James Simmons With the work of Shaun Tancheff from Cray to bring the ldiskfs patches in sync with the kernel in Neil's kernel source tree it was a easy port from OpenSFS to the kernel proper. This is just to start the discussion on how to move forward main streaming what Lustre has done with ext4. So let the flames begin!!!! James Simmons (22): ext4: add i_fs_version ext4: use d_find_alias() in ext4_lookup ext4: prealloc table optimization ext4: export inode management ext4: various misc changes ext4: add extra checks for mballoc ext4: update .. for hash indexed directory ext4: kill off struct dx_root ext4: fix mballoc pa free mismatch ext4: add data in dentry feature ext4: over ride current_time ext4: add htree lock implementation ext4: Add a proc interface for max_dir_size. ext4: remove inode_lock handling ext4: remove bitmap corruption warnings ext4: add warning for directory htree growth ext4: optimize ext4_journal_callback_add ext4: attach jinode in writepages ext4: don't check before replay ext4: use GFP_NOFS in ext4_inode_attach_jinode ext4: export ext4_orphan_add ext4: export mb stream allocator variables fs/ext4/Makefile | 4 +- fs/ext4/balloc.c | 11 +- fs/ext4/dir.c | 14 +- fs/ext4/ext4.h | 225 +++++++++++- fs/ext4/ext4_jbd2.c | 4 + fs/ext4/ext4_jbd2.h | 2 +- fs/ext4/hash.c | 1 + fs/ext4/htree_lock.c | 891 ++++++++++++++++++++++++++++++++++++++++++++++ fs/ext4/htree_lock.h | 187 ++++++++++ fs/ext4/ialloc.c | 10 +- fs/ext4/inline.c | 16 +- fs/ext4/inode.c | 24 +- fs/ext4/mballoc.c | 479 +++++++++++++++++++------ fs/ext4/mballoc.h | 4 +- fs/ext4/namei.c | 978 +++++++++++++++++++++++++++++++++++++++++++-------- fs/ext4/super.c | 27 +- fs/ext4/sysfs.c | 20 +- 17 files changed, 2601 insertions(+), 296 deletions(-) create mode 100644 fs/ext4/htree_lock.c create mode 100644 fs/ext4/htree_lock.h -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:44 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:44 -0400 Subject: [lustre-devel] [PATCH 15/22] ext4: remove bitmap corruption warnings In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-16-git-send-email-jsimmons@infradead.org> Since we could skip corrupt block groups, this patch use ext4_warning() intead of ext4_error() to make FS not mount RO in default. Signed-off-by: James Simmons --- fs/ext4/balloc.c | 10 ++++----- fs/ext4/ialloc.c | 6 ++--- fs/ext4/mballoc.c | 66 +++++++++++++++++++++++-------------------------------- 3 files changed, 35 insertions(+), 47 deletions(-) diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index bca75c1..aff3981 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c @@ -374,7 +374,7 @@ static int ext4_validate_block_bitmap(struct super_block *sb, if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group, desc, bh))) { ext4_unlock_group(sb, block_group); - ext4_error(sb, "bg %u: bad block bitmap checksum", block_group); + ext4_warning(sb, "bg %u: bad block bitmap checksum", block_group); ext4_mark_group_bitmap_corrupted(sb, block_group, EXT4_GROUP_INFO_BBITMAP_CORRUPT); return -EFSBADCRC; @@ -382,8 +382,8 @@ static int ext4_validate_block_bitmap(struct super_block *sb, blk = ext4_valid_block_bitmap(sb, desc, block_group, bh); if (unlikely(blk != 0)) { ext4_unlock_group(sb, block_group); - ext4_error(sb, "bg %u: block %llu: invalid block bitmap", - block_group, blk); + ext4_warning(sb, "bg %u: block %llu: invalid block bitmap", + block_group, blk); ext4_mark_group_bitmap_corrupted(sb, block_group, EXT4_GROUP_INFO_BBITMAP_CORRUPT); return -EFSCORRUPTED; @@ -459,8 +459,8 @@ struct buffer_head * ext4_unlock_group(sb, block_group); unlock_buffer(bh); if (err) { - ext4_error(sb, "Failed to init block bitmap for group " - "%u: %d", block_group, err); + ext4_warning(sb, "Failed to init block bitmap for group " + "%u: %d", block_group, err); goto out; } goto verify; diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 68d41e6..a72fe63 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -96,8 +96,8 @@ static int ext4_validate_inode_bitmap(struct super_block *sb, if (!ext4_inode_bitmap_csum_verify(sb, block_group, desc, bh, EXT4_INODES_PER_GROUP(sb) / 8)) { ext4_unlock_group(sb, block_group); - ext4_error(sb, "Corrupt inode bitmap - block_group = %u, " - "inode_bitmap = %llu", block_group, blk); + ext4_warning(sb, "Corrupt inode bitmap - block_group = %u, " + "inode_bitmap = %llu", block_group, blk); ext4_mark_group_bitmap_corrupted(sb, block_group, EXT4_GROUP_INFO_IBITMAP_CORRUPT); return -EFSBADCRC; @@ -346,7 +346,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) if (!fatal) fatal = err; } else { - ext4_error(sb, "bit already cleared for inode %lu", ino); + ext4_warning(sb, "bit already cleared for inode %lu", ino); ext4_mark_group_bitmap_corrupted(sb, block_group, EXT4_GROUP_INFO_IBITMAP_CORRUPT); } diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 463fba6..82398b0 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -741,10 +741,15 @@ int ext4_mb_generate_buddy(struct super_block *sb, grp->bb_fragments = fragments; if (free != grp->bb_free) { - ext4_grp_locked_error(sb, group, 0, 0, - "block bitmap and bg descriptor " - "inconsistent: %u vs %u free clusters", - free, grp->bb_free); + struct ext4_group_desc *gdp; + + gdp = ext4_get_group_desc(sb, group, NULL); + ext4_warning(sb, "group %lu: block bitmap and bg descriptor " + "inconsistent: %u vs %u free clusters " + "%u in gd, %lu pa's", + (long unsigned int)group, free, grp->bb_free, + ext4_free_group_clusters(sb, gdp), + grp->bb_prealloc_nr); /* * If we intend to continue, we consider group descriptor * corrupt and update bb_free using bitmap value @@ -1106,7 +1111,7 @@ int ext4_mb_init_group(struct super_block *sb, ext4_group_t group, gfp_t gfp) int block; int pnum; int poff; - struct page *page; + struct page *page = NULL; int ret; struct ext4_group_info *grp; struct ext4_sb_info *sbi = EXT4_SB(sb); @@ -1132,7 +1137,7 @@ int ext4_mb_init_group(struct super_block *sb, ext4_group_t group, gfp_t gfp) */ ret = ext4_mb_init_group(sb, group, gfp); if (ret) - return ret; + goto err; } /* @@ -1235,6 +1240,7 @@ int ext4_mb_init_group(struct super_block *sb, ext4_group_t group, gfp_t gfp) put_page(e4b->bd_buddy_page); e4b->bd_buddy = NULL; e4b->bd_bitmap = NULL; + ext4_warning(sb, "Error loading buddy information for %u", group); return ret; } @@ -3631,8 +3637,10 @@ int ext4_mb_check_ondisk_bitmap(struct super_block *sb, void *bitmap, } if (free != free_in_gdp) { - ext4_error(sb, "on-disk bitmap for group %d corrupted: %u blocks free in bitmap, %u - in gd\n", - group, free, free_in_gdp); + ext4_warning(sb, "on-disk bitmap for group %d corrupted: %u blocks free in bitmap, %u - in gd\n", + group, free, free_in_gdp); + ext4_mark_group_bitmap_corrupted(sb, group, + EXT4_GROUP_INFO_BBITMAP_CORRUPT); return -EIO; } return 0; @@ -4015,14 +4023,6 @@ static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac) * otherwise maybe leave some free blocks unavailable, no need to BUG. */ if ((free > pa->pa_free && !pa->pa_error) || (free < pa->pa_free)) { - ext4_error(sb, "pa free mismatch: [pa %p] " - "[phy %lu] [logic %lu] [len %u] [free %u] " - "[error %u] [inode %lu] [freed %u]", pa, - (unsigned long)pa->pa_pstart, - (unsigned long)pa->pa_lstart, - (unsigned)pa->pa_len, (unsigned)pa->pa_free, - (unsigned)pa->pa_error, pa->pa_inode->i_ino, - free); ext4_grp_locked_error(sb, group, 0, 0, "free %u, pa_free %u", free, pa->pa_free); /* @@ -4086,15 +4086,11 @@ static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac) bitmap_bh = ext4_read_block_bitmap(sb, group); if (IS_ERR(bitmap_bh)) { err = PTR_ERR(bitmap_bh); - ext4_error(sb, "Error %d reading block bitmap for %u", - err, group); return 0; } err = ext4_mb_load_buddy(sb, group, &e4b); if (err) { - ext4_warning(sb, "Error %d loading buddy information for %u", - err, group); put_bh(bitmap_bh); return 0; } @@ -4255,17 +4251,12 @@ void ext4_discard_preallocations(struct inode *inode) err = ext4_mb_load_buddy_gfp(sb, group, &e4b, GFP_NOFS|__GFP_NOFAIL); - if (err) { - ext4_error(sb, "Error %d loading buddy information for %u", - err, group); + if (err) return; - } bitmap_bh = ext4_read_block_bitmap(sb, group); if (IS_ERR(bitmap_bh)) { err = PTR_ERR(bitmap_bh); - ext4_error(sb, "Error %d reading block bitmap for %u", - err, group); ext4_mb_unload_buddy(&e4b); continue; } @@ -4527,11 +4518,8 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac) group = ext4_get_group_number(sb, pa->pa_pstart); err = ext4_mb_load_buddy_gfp(sb, group, &e4b, GFP_NOFS|__GFP_NOFAIL); - if (err) { - ext4_error(sb, "Error %d loading buddy information for %u", - err, group); + if (err) continue; - } ext4_lock_group(sb, group); list_del(&pa->pa_group_list); ext4_get_group_info(sb, group)->bb_prealloc_nr--; @@ -4785,7 +4773,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, * not revert pa_free back, just mark pa_error */ pa->pa_error++; - ext4_error(sb, + ext4_warning(sb, "Updating bitmap error: [err %d] " "[pa %p] [phy %lu] [logic %lu] " "[len %u] [free %u] [error %u] " @@ -4796,6 +4784,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, (unsigned)pa->pa_free, (unsigned)pa->pa_error, pa->pa_inode ? pa->pa_inode->i_ino : 0); + ext4_mark_group_bitmap_corrupted(sb, 0, 0); } } ext4_mb_release_context(ac); @@ -5081,7 +5070,7 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, err = ext4_mb_load_buddy_gfp(sb, block_group, &e4b, GFP_NOFS|__GFP_NOFAIL); if (err) - goto error_return; + goto error_brelse; /* * We need to make sure we don't reuse the freed block until after the @@ -5171,8 +5160,9 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, goto do_more; } error_return: - brelse(bitmap_bh); ext4_std_error(sb, err); +error_brelse: + brelse(bitmap_bh); return; } @@ -5272,7 +5262,7 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, err = ext4_mb_load_buddy(sb, block_group, &e4b); if (err) - goto error_return; + goto error_brelse; /* * need to update group_info->bb_free and bitmap @@ -5310,8 +5300,9 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, err = ret; error_return: - brelse(bitmap_bh); ext4_std_error(sb, err); +error_brelse: + brelse(bitmap_bh); return err; } @@ -5386,11 +5377,8 @@ static int ext4_trim_extent(struct super_block *sb, int start, int count, trace_ext4_trim_all_free(sb, group, start, max); ret = ext4_mb_load_buddy(sb, group, &e4b); - if (ret) { - ext4_warning(sb, "Error %d loading buddy information for %u", - ret, group); + if (ret) return ret; - } bitmap = e4b.bd_bitmap; ext4_lock_group(sb, group); -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:43 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:43 -0400 Subject: [lustre-devel] [PATCH 14/22] ext4: remove inode_lock handling In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-15-git-send-email-jsimmons@infradead.org> There will cause a deadlock if invoke ext4_truncate with i_mutex locked in lustre. Since lustre has own lock to provide protect so we don't need this check at all. Signed-off-by: James Simmons --- fs/ext4/inode.c | 2 -- fs/ext4/namei.c | 4 ---- 2 files changed, 6 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 5561351..9296611 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4474,8 +4474,6 @@ int ext4_truncate(struct inode *inode) * or it's a completely new inode. In those cases we might not * have i_mutex locked because it's not necessary. */ - if (!(inode->i_state & (I_NEW|I_FREEING))) - WARN_ON(!inode_is_locked(inode)); trace_ext4_truncate_enter(inode); if (!ext4_can_truncate(inode)) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 0153c4d..1b6d22a 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3485,8 +3485,6 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) if (!sbi->s_journal || is_bad_inode(inode)) return 0; - WARN_ON_ONCE(!(inode->i_state & (I_NEW | I_FREEING)) && - !inode_is_locked(inode)); /* * Exit early if inode already is on orphan list. This is a big speedup * since we don't have to contend on the global s_orphan_lock. @@ -3569,8 +3567,6 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) if (!sbi->s_journal && !(sbi->s_mount_state & EXT4_ORPHAN_FS)) return 0; - WARN_ON_ONCE(!(inode->i_state & (I_NEW | I_FREEING)) && - !inode_is_locked(inode)); /* Do this quick check before taking global s_orphan_lock. */ if (list_empty(&ei->i_orphan)) return 0; -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:23:46 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:23:46 -0400 Subject: [lustre-devel] [PATCH 17/22] ext4: optimize ext4_journal_callback_add In-Reply-To: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563758631-29550-18-git-send-email-jsimmons@infradead.org> Change list_add_tail to list_add. It gives advantages to ldiskfs in tgt_cb_last_committed. In the beginning of list will be placed thandles with the highest transaction numbers. So at the first iterations we will have the highest transno. It will save from extra call of ptlrpc_commit_replies. Signed-off-by: James Simmons --- fs/ext4/ext4_jbd2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h index 75a5309..5ebf8ee 100644 --- a/fs/ext4/ext4_jbd2.h +++ b/fs/ext4/ext4_jbd2.h @@ -169,7 +169,7 @@ static inline void _ext4_journal_callback_add(handle_t *handle, struct ext4_journal_cb_entry *jce) { /* Add the jce to transaction's private list */ - list_add_tail(&jce->jce_list, &handle->h_transaction->t_private_list); + list_add(&jce->jce_list, &handle->h_transaction->t_private_list); } static inline void ext4_journal_callback_add(handle_t *handle, -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:52:07 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:52:07 -0400 Subject: [lustre-devel] [PATCH 00/11] lustre: cleanup most check patch issues Message-ID: <1563760338-806-1-git-send-email-jsimmons@infradead.org> Another run at fs/lustre to reduce the check patch issue to a small number that are mostly over 80 characters per line issues. This makes Lustre appear to be real Linux kernel code :-) No code changes in this patch series. This is again the main lustre branch of Neil Brown's kernel tree. James Simmons (11): lustre: ptlrpc: checkpatch cleanup lustre: llite: checkpatch cleanup lustre: fid: checkpatch cleanup lustre: mgc: checkpatch cleanup lustre: lmv: checkpatch cleanup lustre: mdc: checkpatch cleanup lustre: osc: checkpatch cleanup lustre: lov: checkpatch cleanup lustre: obdclass: checkpatch cleanup lustre: ldlm: checkpatch cleanup lustre: internal headers checkpatch cleanup fs/lustre/fid/fid_request.c | 1 - fs/lustre/fid/lproc_fid.c | 3 +- fs/lustre/fld/fld_internal.h | 5 +-- fs/lustre/include/cl_object.h | 13 +++---- fs/lustre/include/lprocfs_status.h | 11 +++--- fs/lustre/include/lu_object.h | 26 +++++++------- fs/lustre/include/lustre_acl.h | 4 +-- fs/lustre/include/lustre_dlm.h | 53 +++++++++++++++++----------- fs/lustre/include/seq_range.h | 8 ++--- fs/lustre/ldlm/ldlm_extent.c | 1 - fs/lustre/ldlm/ldlm_flock.c | 15 ++++---- fs/lustre/ldlm/ldlm_internal.h | 5 +-- fs/lustre/ldlm/ldlm_lib.c | 4 +-- fs/lustre/ldlm/ldlm_lock.c | 8 ++--- fs/lustre/ldlm/ldlm_lockd.c | 22 +++++++----- fs/lustre/ldlm/ldlm_pool.c | 3 +- fs/lustre/ldlm/ldlm_request.c | 18 +++++----- fs/lustre/llite/dir.c | 18 +++++----- fs/lustre/llite/file.c | 24 ++++++------- fs/lustre/llite/llite_internal.h | 8 +++-- fs/lustre/llite/llite_lib.c | 26 +++++++------- fs/lustre/llite/llite_nfs.c | 3 +- fs/lustre/llite/lproc_llite.c | 8 +++-- fs/lustre/llite/namei.c | 15 +++++--- fs/lustre/llite/rw26.c | 3 +- fs/lustre/llite/statahead.c | 23 ++++++++----- fs/lustre/llite/super25.c | 3 +- fs/lustre/llite/vvp_dev.c | 3 +- fs/lustre/llite/vvp_io.c | 2 +- fs/lustre/lmv/lmv_intent.c | 9 +++-- fs/lustre/lmv/lmv_obd.c | 22 +++++++----- fs/lustre/lov/lov_io.c | 2 +- fs/lustre/lov/lov_lock.c | 4 +-- fs/lustre/lov/lov_merge.c | 6 ++-- fs/lustre/lov/lov_obd.c | 6 ++-- fs/lustre/lov/lov_object.c | 6 ++-- fs/lustre/lov/lov_pool.c | 24 +++++++++---- fs/lustre/lov/lov_request.c | 3 +- fs/lustre/mdc/mdc_changelog.c | 15 +++++--- fs/lustre/mdc/mdc_lib.c | 15 +++++--- fs/lustre/mdc/mdc_locks.c | 2 +- fs/lustre/mdc/mdc_request.c | 16 +++++---- fs/lustre/mgc/mgc_request.c | 17 +++++---- fs/lustre/obdclass/cl_io.c | 16 ++++++--- fs/lustre/obdclass/cl_lock.c | 8 +++-- fs/lustre/obdclass/cl_object.c | 12 +++---- fs/lustre/obdclass/cl_page.c | 9 ++--- fs/lustre/obdclass/class_obd.c | 3 +- fs/lustre/obdclass/genops.c | 9 +++-- fs/lustre/obdclass/llog.c | 3 +- fs/lustre/obdclass/llog_obd.c | 8 ++--- fs/lustre/obdclass/llog_swab.c | 6 ++-- fs/lustre/obdclass/lprocfs_status.c | 4 +-- fs/lustre/obdclass/lu_object.c | 3 +- fs/lustre/obdclass/obd_config.c | 12 ++++--- fs/lustre/obdclass/obd_mount.c | 3 +- fs/lustre/obdecho/debug.c | 12 ++++--- fs/lustre/osc/lproc_osc.c | 7 ++-- fs/lustre/osc/osc_cache.c | 15 +++----- fs/lustre/osc/osc_internal.h | 6 ++-- fs/lustre/osc/osc_lock.c | 6 ++-- fs/lustre/osc/osc_object.c | 6 ++-- fs/lustre/osc/osc_page.c | 3 +- fs/lustre/osc/osc_quota.c | 20 ++++++----- fs/lustre/osc/osc_request.c | 38 +++++++++----------- fs/lustre/ptlrpc/client.c | 67 ++++++++++++++++++++++------------- fs/lustre/ptlrpc/connection.c | 2 +- fs/lustre/ptlrpc/events.c | 5 +-- fs/lustre/ptlrpc/import.c | 69 +++++++++++++++++++++---------------- fs/lustre/ptlrpc/layout.c | 19 +++++----- fs/lustre/ptlrpc/llog_client.c | 3 +- fs/lustre/ptlrpc/lproc_ptlrpc.c | 21 +++++++---- fs/lustre/ptlrpc/niobuf.c | 12 ++++--- fs/lustre/ptlrpc/nrs.c | 2 +- fs/lustre/ptlrpc/pack_generic.c | 6 ++-- fs/lustre/ptlrpc/pinger.c | 6 ++-- fs/lustre/ptlrpc/ptlrpc_internal.h | 5 ++- fs/lustre/ptlrpc/ptlrpc_module.c | 6 ++-- fs/lustre/ptlrpc/ptlrpcd.c | 3 +- fs/lustre/ptlrpc/recover.c | 3 +- fs/lustre/ptlrpc/sec.c | 21 ++++++----- fs/lustre/ptlrpc/sec_config.c | 15 +++++--- fs/lustre/ptlrpc/sec_lproc.c | 3 +- fs/lustre/ptlrpc/service.c | 40 ++++++++++++--------- 84 files changed, 588 insertions(+), 412 deletions(-) -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:52:08 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:52:08 -0400 Subject: [lustre-devel] [PATCH 01/11] lustre: ptlrpc: checkpatch cleanup In-Reply-To: <1563760338-806-1-git-send-email-jsimmons@infradead.org> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563760338-806-2-git-send-email-jsimmons@infradead.org> Many checkpatch errors exist in the ptlrpc layer. This address a good chuck of them. Other are left since future patches will cleanup those areas. Others will need more code rework so this patch handles the simple cases. This is a good step forward toward proper kernel code style compliance. Signed-off-by: James Simmons --- fs/lustre/ptlrpc/client.c | 67 +++++++++++++++++++++++------------- fs/lustre/ptlrpc/connection.c | 2 +- fs/lustre/ptlrpc/events.c | 5 +-- fs/lustre/ptlrpc/import.c | 69 +++++++++++++++++++++----------------- fs/lustre/ptlrpc/layout.c | 19 ++++++----- fs/lustre/ptlrpc/llog_client.c | 3 +- fs/lustre/ptlrpc/lproc_ptlrpc.c | 21 ++++++++---- fs/lustre/ptlrpc/niobuf.c | 12 ++++--- fs/lustre/ptlrpc/nrs.c | 2 +- fs/lustre/ptlrpc/pack_generic.c | 6 ++-- fs/lustre/ptlrpc/pinger.c | 6 ++-- fs/lustre/ptlrpc/ptlrpc_internal.h | 5 ++- fs/lustre/ptlrpc/ptlrpc_module.c | 6 ++-- fs/lustre/ptlrpc/ptlrpcd.c | 3 +- fs/lustre/ptlrpc/recover.c | 3 +- fs/lustre/ptlrpc/sec.c | 21 +++++++----- fs/lustre/ptlrpc/sec_config.c | 15 ++++++--- fs/lustre/ptlrpc/sec_lproc.c | 3 +- fs/lustre/ptlrpc/service.c | 40 +++++++++++++--------- 19 files changed, 188 insertions(+), 120 deletions(-) diff --git a/fs/lustre/ptlrpc/client.c b/fs/lustre/ptlrpc/client.c index da1ccd8..364c61f 100644 --- a/fs/lustre/ptlrpc/client.c +++ b/fs/lustre/ptlrpc/client.c @@ -204,7 +204,8 @@ struct ptlrpc_bulk_desc *ptlrpc_prep_bulk_imp(struct ptlrpc_request *req, EXPORT_SYMBOL(ptlrpc_prep_bulk_imp); void __ptlrpc_prep_bulk_page(struct ptlrpc_bulk_desc *desc, - struct page *page, int pageoffset, int len, int pin) + struct page *page, int pageoffset, int len, + int pin) { struct bio_vec *kiov; @@ -342,9 +343,11 @@ static void ptlrpc_at_adj_service(struct ptlrpc_request *req, */ oldse = at_measured(&at->iat_service_estimate[idx], serv_est); if (oldse != 0) - CDEBUG(D_ADAPTTO, "The RPC service estimate for %s ptl %d has changed from %d to %d\n", - req->rq_import->imp_obd->obd_name, req->rq_request_portal, - oldse, at_get(&at->iat_service_estimate[idx])); + CDEBUG(D_ADAPTTO, + "The RPC service estimate for %s ptl %d has changed from %d to %d\n", + req->rq_import->imp_obd->obd_name, + req->rq_request_portal, oldse, + at_get(&at->iat_service_estimate[idx])); } /* Expected network latency per remote node (secs) */ @@ -386,10 +389,10 @@ void ptlrpc_at_adj_net_latency(struct ptlrpc_request *req, oldnl = at_measured(&at->iat_net_latency, nl); if (oldnl != 0) - CDEBUG(D_ADAPTTO, "The network latency for %s (nid %s) has changed from %d to %d\n", + CDEBUG(D_ADAPTTO, + "The network latency for %s (nid %s) has changed from %d to %d\n", req->rq_import->imp_obd->obd_name, - obd_uuid2str( - &req->rq_import->imp_connection->c_remote_uuid), + obd_uuid2str(&req->rq_import->imp_connection->c_remote_uuid), oldnl, at_get(&at->iat_net_latency)); } @@ -513,7 +516,8 @@ void ptlrpc_free_rq_pool(struct ptlrpc_request_pool *pool) struct ptlrpc_request *req; while ((req = list_first_entry_or_null(&pool->prp_req_list, - struct ptlrpc_request, rq_list))) { + struct ptlrpc_request, + rq_list))) { list_del(&req->rq_list); LASSERT(req->rq_reqbuf); LASSERT(req->rq_reqbuf_len == pool->prp_rq_size); @@ -665,7 +669,8 @@ void ptlrpc_add_unreplied(struct ptlrpc_request *req) LASSERT(list_empty(&req->rq_unreplied_list)); /* unreplied list is sorted by xid in ascending order */ - list_for_each_entry_reverse(iter, &imp->imp_unreplied_list, rq_unreplied_list) { + list_for_each_entry_reverse(iter, &imp->imp_unreplied_list, + rq_unreplied_list) { LASSERT(req->rq_xid != iter->rq_xid); if (req->rq_xid < iter->rq_xid) continue; @@ -1136,7 +1141,9 @@ static int ptlrpc_import_delay_req(struct obd_import *imp, D_HA : D_ERROR, req, "IMP_CLOSED "); *status = -EIO; } else if (ptlrpc_send_limit_expired(req)) { - /* probably doesn't need to be a D_ERROR after initial testing */ + /* probably doesn't need to be a D_ERROR after initial + * testing + */ DEBUG_REQ(D_HA, req, "send limit expired "); *status = -ETIMEDOUT; } else if (req->rq_send_state == LUSTRE_IMP_CONNECTING && @@ -1230,7 +1237,8 @@ static int ptlrpc_check_status(struct ptlrpc_request *req) /* -EAGAIN is normal when using POSIX flocks */ if (ptlrpc_console_allow(req) && !(opc == LDLM_ENQUEUE && err == -EAGAIN)) - LCONSOLE_ERROR_MSG(0x011, "%s: operation %s to node %s failed: rc = %d\n", + LCONSOLE_ERROR_MSG(0x011, + "%s: operation %s to node %s failed: rc = %d\n", imp->imp_obd->obd_name, ll_opcode2str(opc), libcfs_nid2str(nid), err); @@ -1306,7 +1314,8 @@ static int after_reply(struct ptlrpc_request *req) if (req->rq_reply_truncated) { if (ptlrpc_no_resend(req)) { - DEBUG_REQ(D_ERROR, req, "reply buffer overflow, expected: %d, actual size: %d", + DEBUG_REQ(D_ERROR, req, + "reply buffer overflow, expected: %d, actual size: %d", req->rq_nob_received, req->rq_repbuf_len); return -EOVERFLOW; } @@ -1520,7 +1529,8 @@ static int ptlrpc_send_new_req(struct ptlrpc_request *req) req->rq_waiting = 1; spin_unlock(&req->rq_lock); - DEBUG_REQ(D_HA, req, "req from PID %d waiting for recovery: (%s != %s)", + DEBUG_REQ(D_HA, req, + "req from PID %d waiting for recovery: (%s != %s)", lustre_msg_get_status(req->rq_reqmsg), ptlrpc_import_state_name(req->rq_send_state), ptlrpc_import_state_name(imp->imp_state)); @@ -1574,7 +1584,8 @@ static int ptlrpc_send_new_req(struct ptlrpc_request *req) return 0; } - CDEBUG(D_RPCTRACE, "Sending RPC pname:cluuid:pid:xid:nid:opc %s:%s:%d:%llu:%s:%d\n", + CDEBUG(D_RPCTRACE, + "Sending RPC pname:cluuid:pid:xid:nid:opc %s:%s:%d:%llu:%s:%d\n", current->comm, imp->imp_obd->obd_uuid.uuid, lustre_msg_get_status(req->rq_reqmsg), req->rq_xid, @@ -1837,7 +1848,9 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set) spin_unlock(&req->rq_lock); if (req->rq_timedout || req->rq_resend) { - /* This is re-sending anyway, let's mark req as resend. */ + /* This is re-sending anyway, + * let's mark req as resend. + */ spin_lock(&req->rq_lock); req->rq_resend = 1; spin_unlock(&req->rq_lock); @@ -2158,10 +2171,9 @@ void ptlrpc_expired_set(struct ptlrpc_request_set *set) static void ptlrpc_interrupted_set(struct ptlrpc_request_set *set) { struct ptlrpc_request *req; - CDEBUG(D_RPCTRACE, "INTERRUPTED SET %p\n", set); + CDEBUG(D_RPCTRACE, "INTERRUPTED SET %p\n", set); list_for_each_entry(req, &set->set_requests, rq_set_chain) { - if (req->rq_phase != RQ_PHASE_RPC && req->rq_phase != RQ_PHASE_UNREG_RPC) continue; @@ -2260,8 +2272,9 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set) } else if (rc < 0) { rc = -EINTR; ptlrpc_interrupted_set(set); - } else + } else { rc = 0; + } } else { /* * At least one request is in flight, so no @@ -2283,8 +2296,9 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set) */ if (l_fatal_signal_pending(current)) ptlrpc_interrupted_set(set); - } else + } else { rc = 0; + } } LASSERT(rc == 0 || rc == -EINTR || rc == -ETIMEDOUT); @@ -2299,7 +2313,8 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set) * the error cases -eeb. */ if (rc == 0 && atomic_read(&set->set_remaining) == 0) { - list_for_each_entry(req, &set->set_requests, rq_set_chain) { + list_for_each_entry(req, &set->set_requests, + rq_set_chain) { spin_lock(&req->rq_lock); req->rq_invalid_rqset = 1; spin_unlock(&req->rq_lock); @@ -2513,7 +2528,7 @@ static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async) return 0; /* - * We have to wait_event_idle_timeout() whatever the result, to give liblustre + * We have to wait_event_idle_timeout() whatever the result, to get * a chance to run reply_in_callback(), and to make sure we've * unlinked before returning a req to the pool. */ @@ -2528,6 +2543,7 @@ static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async) * timeout lets us CWARN for visibility of sluggish NALs */ int cnt = 0; + while (cnt < LONG_UNLINK && (rc = wait_event_idle_timeout(*wq, !ptlrpc_client_recv_or_unlink(request), @@ -2716,6 +2732,7 @@ void ptlrpc_retain_replayable_request(struct ptlrpc_request *req, struct obd_import *imp) { struct ptlrpc_request *iter; + assert_spin_locked(&imp->imp_lock); if (req->rq_transno == 0) { @@ -2742,7 +2759,8 @@ void ptlrpc_retain_replayable_request(struct ptlrpc_request *req, LASSERT(imp->imp_replayable); /* Balanced in ptlrpc_free_committed, usually. */ ptlrpc_request_addref(req); - list_for_each_entry_reverse(iter, &imp->imp_replay_list, rq_replay_list) { + list_for_each_entry_reverse(iter, &imp->imp_replay_list, + rq_replay_list) { /* * We may have duplicate transnos if we create and then * open a file, or for closes retained if to match creating @@ -3110,7 +3128,8 @@ void ptlrpc_set_bulk_mbits(struct ptlrpc_request *req) * 'resend for the -EINPROGRESS resend'. To make it simple, * we opt to generate mbits for all resend cases. */ - if (OCD_HAS_FLAG(&bd->bd_import->imp_connect_data, BULK_MBITS)) { + if (OCD_HAS_FLAG(&bd->bd_import->imp_connect_data, + BULK_MBITS)) { req->rq_mbits = ptlrpc_next_xid(); } else { /* old version transfers rq_xid to peer as matchbits */ @@ -3188,7 +3207,7 @@ u64 ptlrpc_sample_next_xid(void) * have delay before it really runs by ptlrpcd thread. */ struct ptlrpc_work_async_args { - int (*cb)(const struct lu_env *, void *); + int (*cb)(const struct lu_env *env, void *cbdata); void *cbdata; }; diff --git a/fs/lustre/ptlrpc/connection.c b/fs/lustre/ptlrpc/connection.c index ca9b4ca..5466755 100644 --- a/fs/lustre/ptlrpc/connection.c +++ b/fs/lustre/ptlrpc/connection.c @@ -105,7 +105,7 @@ struct ptlrpc_connection * */ conn2 = rhashtable_lookup_get_insert_fast(&conn_hash, &conn->c_hash, conn_hash_params); - if (conn2 != NULL) { + if (conn2) { /* insertion failed */ kfree(conn); if (IS_ERR(conn2)) diff --git a/fs/lustre/ptlrpc/events.c b/fs/lustre/ptlrpc/events.c index 0c16a2c..fc3c7f0 100644 --- a/fs/lustre/ptlrpc/events.c +++ b/fs/lustre/ptlrpc/events.c @@ -254,13 +254,14 @@ static void ptlrpc_req_add_history(struct ptlrpc_service_part *svcpt, struct ptlrpc_request *req) { u64 sec = req->rq_arrival_time.tv_sec; - u32 usec = req->rq_arrival_time.tv_nsec / NSEC_PER_USEC / 16; /* usec / 16 */ u64 new_seq; + u32 usec; + /* usec /16 */ + usec = req->rq_arrival_time.tv_nsec / NSEC_PER_USEC / 16; /* set sequence ID for request and add it to history list, * it must be called with hold svcpt::scp_lock */ - new_seq = (sec << REQS_SEC_SHIFT) | (usec << REQS_USEC_SHIFT) | (svcpt->scp_cpt < 0 ? 0 : svcpt->scp_cpt); diff --git a/fs/lustre/ptlrpc/import.c b/fs/lustre/ptlrpc/import.c index 18823d5..d49707a 100644 --- a/fs/lustre/ptlrpc/import.c +++ b/fs/lustre/ptlrpc/import.c @@ -105,7 +105,6 @@ static void __import_set_state(struct obd_import *imp, static int ptlrpc_connect_interpret(const struct lu_env *env, struct ptlrpc_request *request, void *data, int rc); -int ptlrpc_import_recovery_state_machine(struct obd_import *imp); /* Only this function is allowed to change the import state when it is * CLOSED. I would rather refcount the import and free it after @@ -170,10 +169,12 @@ int ptlrpc_set_import_discon(struct obd_import *imp, u32 conn_cnt) if (imp->imp_replayable) { LCONSOLE_WARN("%s: Connection to %.*s (at %s) was lost; in progress operations using this service will wait for recovery to complete\n", - imp->imp_obd->obd_name, target_len, target_start, + imp->imp_obd->obd_name, + target_len, target_start, libcfs_nid2str(imp->imp_connection->c_peer.nid)); } else { - LCONSOLE_ERROR_MSG(0x166, "%s: Connection to %.*s (at %s) was lost; in progress operations using this service will fail\n", + LCONSOLE_ERROR_MSG(0x166, + "%s: Connection to %.*s (at %s) was lost; in progress operations using this service will fail\n", imp->imp_obd->obd_name, target_len, target_start, libcfs_nid2str(imp->imp_connection->c_peer.nid)); @@ -317,8 +318,9 @@ void ptlrpc_invalidate_import(struct obd_import *imp) spin_lock(&imp->imp_lock); if (atomic_read(&imp->imp_inflight) == 0) { - int count = atomic_read(&imp->imp_unregistering); + int count; + count = atomic_read(&imp->imp_unregistering); /* We know that "unregistering" rpcs only can * survive in sending or delaying lists (they * maybe waiting for long reply unlink in @@ -326,7 +328,8 @@ void ptlrpc_invalidate_import(struct obd_import *imp) * is no inflight and unregistering != 0, this * is bug. */ - LASSERTF(count == 0, "Some RPCs are still unregistering: %d\n", + LASSERTF(count == 0, + "Some RPCs are still unregistering: %d\n", count); /* Let's save one loop as soon as inflight have @@ -348,8 +351,7 @@ void ptlrpc_invalidate_import(struct obd_import *imp) CERROR("%s: Unregistering RPCs found (%d). Network is sluggish? Waiting them to error out.\n", cli_tgt, - atomic_read(&imp-> - imp_unregistering)); + atomic_read(&imp->imp_unregistering)); } spin_unlock(&imp->imp_lock); } @@ -405,7 +407,8 @@ void ptlrpc_fail_import(struct obd_import *imp, u32 conn_cnt) if (ptlrpc_set_import_discon(imp, conn_cnt)) { if (!imp->imp_replayable) { - CDEBUG(D_HA, "import %s@%s for %s not replayable, auto-deactivating\n", + CDEBUG(D_HA, + "import %s@%s for %s not replayable, auto-deactivating\n", obd2cli_tgt(imp->imp_obd), imp->imp_connection->c_remote_uuid.uuid, imp->imp_obd->obd_name); @@ -466,7 +469,7 @@ static int import_select_connection(struct obd_import *imp) */ if ((conn->oic_last_attempt == 0) || time_before_eq64(conn->oic_last_attempt, - imp->imp_last_success_conn)) { + imp->imp_last_success_conn)) { imp_conn = conn; tried_all = 0; break; @@ -506,7 +509,8 @@ static int import_select_connection(struct obd_import *imp) at_reset(at, CONNECTION_SWITCH_MAX); } LASSERT(imp_conn->oic_last_attempt); - CDEBUG(D_HA, "%s: tried all connections, increasing latency to %ds\n", + CDEBUG(D_HA, + "%s: tried all connections, increasing latency to %ds\n", imp->imp_obd->obd_name, at_get(at)); } @@ -526,7 +530,8 @@ static int import_select_connection(struct obd_import *imp) deuuidify(obd2cli_tgt(imp->imp_obd), NULL, &target_start, &target_len); - CDEBUG(D_HA, "%s: Connection changing to %.*s (at %s)\n", + CDEBUG(D_HA, + "%s: Connection changing to %.*s (at %s)\n", imp->imp_obd->obd_name, target_len, target_start, libcfs_nid2str(imp_conn->oic_conn->c_peer.nid)); @@ -819,9 +824,8 @@ static int ptlrpc_connect_set_flags(struct obd_import *imp, ocd->ocd_cksum_types, cksum_types_supported_client()); return -EPROTO; - } else { - cli->cl_supp_cksum_types = ocd->ocd_cksum_types; } + cli->cl_supp_cksum_types = ocd->ocd_cksum_types; } else { /* * The server does not support OBD_CONNECT_CKSUM. @@ -862,7 +866,8 @@ static int ptlrpc_connect_set_flags(struct obd_import *imp, * disable lru_resize, etc. */ if (old_connect_flags != exp_connect_flags(exp) || init_connect) { - CDEBUG(D_HA, "%s: Resetting ns_connect_flags to server flags: %#llx\n", + CDEBUG(D_HA, + "%s: Resetting ns_connect_flags to server flags: %#llx\n", imp->imp_obd->obd_name, ocd->ocd_connect_flags); imp->imp_obd->obd_namespace->ns_connect_flags = ocd->ocd_connect_flags; @@ -1113,20 +1118,18 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, * with server again */ if ((msg_flags & MSG_CONNECT_RECOVERING)) { - CDEBUG(level, "%s@%s changed server handle from %#llx to %#llx but is still in recovery\n", + CDEBUG(level, + "%s@%s changed server handle from %#llx to %#llx but is still in recovery\n", obd2cli_tgt(imp->imp_obd), imp->imp_connection->c_remote_uuid.uuid, imp->imp_remote_handle.cookie, - lustre_msg_get_handle( - request->rq_repmsg)->cookie); + lustre_msg_get_handle(request->rq_repmsg)->cookie); } else { LCONSOLE_WARN("Evicted from %s (at %s) after server handle changed from %#llx to %#llx\n", obd2cli_tgt(imp->imp_obd), - imp->imp_connection-> \ - c_remote_uuid.uuid, + imp->imp_connection->c_remote_uuid.uuid, imp->imp_remote_handle.cookie, - lustre_msg_get_handle( - request->rq_repmsg)->cookie); + lustre_msg_get_handle(request->rq_repmsg)->cookie); } imp->imp_remote_handle = @@ -1145,7 +1148,8 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, } if (imp->imp_invalid) { - CDEBUG(D_HA, "%s: reconnected but import is invalid; marking evicted\n", + CDEBUG(D_HA, + "%s: reconnected but import is invalid; marking evicted\n", imp->imp_obd->obd_name); IMPORT_SET_STATE(imp, LUSTRE_IMP_EVICTED); } else if (msg_flags & MSG_CONNECT_RECOVERING) { @@ -1169,7 +1173,8 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, imp->imp_replay_cursor = &imp->imp_committed_list; IMPORT_SET_STATE(imp, LUSTRE_IMP_REPLAY); } else { - DEBUG_REQ(D_HA, request, "%s: evicting (reconnect/recover flags not set: %x)", + DEBUG_REQ(D_HA, request, + "%s: evicting (reconnect/recover flags not set: %x)", imp->imp_obd->obd_name, msg_flags); imp->imp_remote_handle = *lustre_msg_get_handle(request->rq_repmsg); @@ -1191,7 +1196,8 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, ptlrpc_prepare_replay(imp); rc = ptlrpc_import_recovery_state_machine(imp); if (rc == -ENOTCONN) { - CDEBUG(D_HA, "evicted/aborted by %s@%s during recovery; invalidating and reconnecting\n", + CDEBUG(D_HA, + "evicted/aborted by %s@%s during recovery; invalidating and reconnecting\n", obd2cli_tgt(imp->imp_obd), imp->imp_connection->c_remote_uuid.uuid); ptlrpc_connect_import(imp); @@ -1236,7 +1242,8 @@ static int ptlrpc_connect_interpret(const struct lu_env *env, * connection from liblustre clients, so we * should never see this from VFS context */ - LCONSOLE_ERROR_MSG(0x16a, "Server %s version (%d.%d.%d.%d) refused connection from this client with an incompatible version (%s). Client must be recompiled\n", + LCONSOLE_ERROR_MSG(0x16a, + "Server %s version (%d.%d.%d.%d) refused connection from this client with an incompatible version (%s). Client must be recompiled\n", obd2cli_tgt(imp->imp_obd), OBD_OCD_VERSION_MAJOR(ocd->ocd_version), OBD_OCD_VERSION_MINOR(ocd->ocd_version), @@ -1278,7 +1285,8 @@ static int completed_replay_interpret(const struct lu_env *env, "%s: version recovery fails, reconnecting\n", req->rq_import->imp_obd->obd_name); } else { - CDEBUG(D_HA, "%s: LAST_REPLAY message error: %d, reconnecting\n", + CDEBUG(D_HA, + "%s: LAST_REPLAY message error: %d, reconnecting\n", req->rq_import->imp_obd->obd_name, req->rq_status); } @@ -1383,7 +1391,8 @@ int ptlrpc_import_recovery_state_machine(struct obd_import *imp) /* Don't care about MGC eviction */ if (strcmp(imp->imp_obd->obd_type->typ_name, LUSTRE_MGC_NAME) != 0) { - LCONSOLE_ERROR_MSG(0x167, "%s: This client was evicted by %.*s; in progress operations using this service will fail.\n", + LCONSOLE_ERROR_MSG(0x167, + "%s: This client was evicted by %.*s; in progress operations using this service will fail.\n", imp->imp_obd->obd_name, target_len, target_start); } @@ -1638,9 +1647,9 @@ int at_measured(struct adaptive_timeout *at, unsigned int val) at->at_current = max(at->at_current, at_min); if (at->at_current != old) - CDEBUG(D_OTHER, "AT %p change: old=%u new=%u delta=%d (val=%u) hist %u %u %u %u\n", - at, - old, at->at_current, at->at_current - old, val, + CDEBUG(D_OTHER, + "AT %p change: old=%u new=%u delta=%d (val=%u) hist %u %u %u %u\n", + at, old, at->at_current, at->at_current - old, val, at->at_hist[0], at->at_hist[1], at->at_hist[2], at->at_hist[3]); diff --git a/fs/lustre/ptlrpc/layout.c b/fs/lustre/ptlrpc/layout.c index 3bebfd7..da315f7 100644 --- a/fs/lustre/ptlrpc/layout.c +++ b/fs/lustre/ptlrpc/layout.c @@ -775,8 +775,8 @@ struct req_msg_field { * but the actual size must be a whole multiple of @rmf_size. */ const int rmf_size; - void (*rmf_swabber)(void *); - void (*rmf_dumper)(void *); + void (*rmf_swabber)(void *value); + void (*rmf_dumper)(void *value); int rmf_offset[ARRAY_SIZE(req_formats)][RCL_NR]; }; @@ -1053,7 +1053,8 @@ struct req_msg_field RMF_LAYOUT_INTENT = */ struct req_msg_field RMF_OST_BODY = DEFINE_MSGF("ost_body", 0, - sizeof(struct ost_body), lustre_swab_ost_body, dump_ost_body); + sizeof(struct ost_body), lustre_swab_ost_body, + dump_ost_body); EXPORT_SYMBOL(RMF_OST_BODY); struct req_msg_field RMF_OBD_IOOBJ = @@ -1868,7 +1869,8 @@ u32 __req_capsule_offset(const struct req_capsule *pill, i < n; i++, p += field->rmf_size) { if (dump) { - CDEBUG(D_RPCTRACE, "Dump of %sarray field %s, element %d follows\n", + CDEBUG(D_RPCTRACE, + "Dump of %sarray field %s, element %d follows\n", do_swab ? "unswabbed " : "", field->rmf_name, i); field->rmf_dumper(p); } @@ -1876,7 +1878,8 @@ u32 __req_capsule_offset(const struct req_capsule *pill, continue; swabber(p); if (dump) { - CDEBUG(D_RPCTRACE, "Dump of swabbed array field %s, element %d follows\n", + CDEBUG(D_RPCTRACE, + "Dump of swabbed array field %s, element %d follows\n", field->rmf_name, i); field->rmf_dumper(value); } @@ -2145,8 +2148,7 @@ u32 req_capsule_fmt_size(u32 magic, const struct req_format *fmt, for (; i < fmt->rf_fields[loc].nr; ++i) if (fmt->rf_fields[loc].d[i]->rmf_size != -1) - size += cfs_size_round(fmt->rf_fields[loc].d[i]-> - rmf_size); + size += cfs_size_round(fmt->rf_fields[loc].d[i]->rmf_size); return size; } @@ -2185,8 +2187,9 @@ void req_capsule_extend(struct req_capsule *pill, const struct req_format *fmt) for (i = 0; i < RCL_NR; ++i) { LASSERT(fmt->rf_fields[i].nr >= old->rf_fields[i].nr); for (j = 0; j < old->rf_fields[i].nr - 1; ++j) { - const struct req_msg_field *ofield = FMT_FIELD(old, i, j); + const struct req_msg_field *ofield; + ofield = FMT_FIELD(old, i, j); /* "opaque" fields can be transmogrified */ if (!ofield->rmf_swabber && (ofield->rmf_flags & ~RMF_F_NO_SIZE_CHECK) == 0 && diff --git a/fs/lustre/ptlrpc/llog_client.c b/fs/lustre/ptlrpc/llog_client.c index 8ca6959..e5ff080 100644 --- a/fs/lustre/ptlrpc/llog_client.c +++ b/fs/lustre/ptlrpc/llog_client.c @@ -278,7 +278,8 @@ static int llog_client_read_header(const struct lu_env *env, int rc; LLOG_CLIENT_ENTRY(handle->lgh_ctxt, imp); - req = ptlrpc_request_alloc_pack(imp, &RQF_LLOG_ORIGIN_HANDLE_READ_HEADER, + req = ptlrpc_request_alloc_pack(imp, + &RQF_LLOG_ORIGIN_HANDLE_READ_HEADER, LUSTRE_LOG_VERSION, LLOG_ORIGIN_HANDLE_READ_HEADER); if (!req) { diff --git a/fs/lustre/ptlrpc/lproc_ptlrpc.c b/fs/lustre/ptlrpc/lproc_ptlrpc.c index 0d56704..bc5dc3f 100644 --- a/fs/lustre/ptlrpc/lproc_ptlrpc.c +++ b/fs/lustre/ptlrpc/lproc_ptlrpc.c @@ -282,7 +282,8 @@ static const char *ll_eopcode2str(u32 opcode) const char __user *buffer, size_t count, loff_t *off) { - struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private; + struct seq_file *m = file->private_data; + struct ptlrpc_service *svc = m->private; int bufpages; int val; int rc; @@ -628,7 +629,8 @@ static ssize_t ptlrpc_lprocfs_nrs_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { - struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private; + struct seq_file *m = file->private_data; + struct ptlrpc_service *svc = m->private; enum ptlrpc_nrs_queue_type queue = PTLRPC_NRS_QUEUE_BOTH; char *cmd; char *cmd_copy = NULL; @@ -1180,7 +1182,8 @@ void ptlrpc_lprocfs_unregister_obd(struct obd_device *obd) int lprocfs_wr_ping(struct file *file, const char __user *buffer, size_t count, loff_t *off) { - struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + struct seq_file *m = file->private_data; + struct obd_device *obd = m->private; struct ptlrpc_request *req; int rc; @@ -1211,7 +1214,8 @@ int lprocfs_wr_ping(struct file *file, const char __user *buffer, int lprocfs_wr_import(struct file *file, const char __user *buffer, size_t count, loff_t *off) { - struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + struct seq_file *m = file->private_data; + struct obd_device *obd = m->private; struct obd_import *imp = obd->u.cli.cl_import; char *kbuf = NULL; char *uuid; @@ -1253,12 +1257,14 @@ int lprocfs_wr_import(struct file *file, const char __user *buffer, if (*endptr) { CERROR("config: wrong instance # %s\n", ptr); } else if (inst != imp->imp_connect_data.ocd_instance) { - CDEBUG(D_INFO, "IR: %s is connecting to an obsoleted target(%u/%u), reconnecting...\n", + CDEBUG(D_INFO, + "IR: %s is connecting to an obsoleted target(%u/%u), reconnecting...\n", imp->imp_obd->obd_name, imp->imp_connect_data.ocd_instance, inst); do_reconn = 1; } else { - CDEBUG(D_INFO, "IR: %s has already been connecting to new target(%u)\n", + CDEBUG(D_INFO, + "IR: %s has already been connecting to new target(%u)\n", imp->imp_obd->obd_name, inst); } } @@ -1292,7 +1298,8 @@ int lprocfs_rd_pinger_recov(struct seq_file *m, void *n) int lprocfs_wr_pinger_recov(struct file *file, const char __user *buffer, size_t count, loff_t *off) { - struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + struct seq_file *m = file->private_data; + struct obd_device *obd = m->private; struct client_obd *cli = &obd->u.cli; struct obd_import *imp = cli->cl_import; int rc, val; diff --git a/fs/lustre/ptlrpc/niobuf.c b/fs/lustre/ptlrpc/niobuf.c index c279fb1..033d628 100644 --- a/fs/lustre/ptlrpc/niobuf.c +++ b/fs/lustre/ptlrpc/niobuf.c @@ -220,7 +220,8 @@ static int ptlrpc_register_bulk(struct ptlrpc_request *req) total_md - desc->bd_md_count); spin_unlock(&desc->bd_lock); - CDEBUG(D_NET, "Setup %u bulk %s buffers: %u pages %u bytes, mbits x%#llx-%#llx, portal %u\n", + CDEBUG(D_NET, + "Setup %u bulk %s buffers: %u pages %u bytes, mbits x%#llx-%#llx, portal %u\n", desc->bd_md_count, ptlrpc_is_bulk_op_get(desc->bd_type) ? "get-source" : "put-sink", desc->bd_iov_count, desc->bd_nob, @@ -335,7 +336,8 @@ static void ptlrpc_at_set_reply(struct ptlrpc_request *req, int flags) if (req->rq_reqmsg && !(lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT)) { - CDEBUG(D_ADAPTTO, "No early reply support: flags=%#x req_flags=%#x magic=%x/%x len=%d\n", + CDEBUG(D_ADAPTTO, + "No early reply support: flags=%#x req_flags=%#x magic=%x/%x len=%d\n", flags, lustre_msg_get_flags(req->rq_reqmsg), lustre_msg_get_magic(req->rq_reqmsg), lustre_msg_get_magic(req->rq_repmsg), req->rq_replen); @@ -542,7 +544,8 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) spin_unlock(&imp->imp_lock); lustre_msg_set_last_xid(request->rq_reqmsg, min_xid); - DEBUG_REQ(D_RPCTRACE, request, "Allocating new xid for resend on EINPROGRESS"); + DEBUG_REQ(D_RPCTRACE, request, + "Allocating new xid for resend on EINPROGRESS"); } if (request->rq_bulk) { @@ -667,7 +670,8 @@ int ptl_send_rpc(struct ptlrpc_request *request, int noreply) goto cleanup_me; } - CDEBUG(D_NET, "Setup reply buffer: %u bytes, xid %llu, portal %u\n", + CDEBUG(D_NET, + "Setup reply buffer: %u bytes, xid %llu, portal %u\n", request->rq_repbuf_len, request->rq_xid, request->rq_reply_portal); } diff --git a/fs/lustre/ptlrpc/nrs.c b/fs/lustre/ptlrpc/nrs.c index a56b7b3..953a0b8 100644 --- a/fs/lustre/ptlrpc/nrs.c +++ b/fs/lustre/ptlrpc/nrs.c @@ -79,7 +79,7 @@ static int nrs_policy_ctl_locked(struct ptlrpc_nrs_policy *policy, return policy->pol_desc->pd_ops->op_policy_ctl ? policy->pol_desc->pd_ops->op_policy_ctl(policy, opc, arg) : - -ENOSYS; + -ENXIO; } static void __nrs_policy_stop(struct ptlrpc_nrs_policy *policy) diff --git a/fs/lustre/ptlrpc/pack_generic.c b/fs/lustre/ptlrpc/pack_generic.c index 2cbb855..6d61cc7 100644 --- a/fs/lustre/ptlrpc/pack_generic.c +++ b/fs/lustre/ptlrpc/pack_generic.c @@ -1799,7 +1799,8 @@ void lustre_swab_mgs_nidtbl_entry(struct mgs_nidtbl_entry *entry) __swab32s(&entry->mne_length); /* mne_nid_(count|type) must be one byte size because we're gonna - * access it w/o swapping. */ + * access it w/o swapping: + */ BUILD_BUG_ON(sizeof(entry->mne_nid_count) != sizeof(u8)); BUILD_BUG_ON(sizeof(entry->mne_nid_type) != sizeof(u8)); @@ -2175,7 +2176,8 @@ static void dump_obdo(struct obdo *oa) CDEBUG(D_RPCTRACE, "obdo: o_valid = %08x\n", valid); if (valid & OBD_MD_FLID) - CDEBUG(D_RPCTRACE, "obdo: id = " DOSTID "\n", POSTID(&oa->o_oi)); + CDEBUG(D_RPCTRACE, "obdo: id = " DOSTID "\n", + POSTID(&oa->o_oi)); if (valid & OBD_MD_FLFID) CDEBUG(D_RPCTRACE, "obdo: o_parent_seq = %#llx\n", oa->o_parent_seq); diff --git a/fs/lustre/ptlrpc/pinger.c b/fs/lustre/ptlrpc/pinger.c index b3297b5..6a437f4 100644 --- a/fs/lustre/ptlrpc/pinger.c +++ b/fs/lustre/ptlrpc/pinger.c @@ -190,7 +190,8 @@ static void ptlrpc_pinger_process_import(struct obd_import *imp, spin_unlock(&imp->imp_lock); - CDEBUG(level == LUSTRE_IMP_FULL ? D_INFO : D_HA, "%s->%s: level %s/%u force %u force_next %u deactive %u pingable %u suppress %u\n", + CDEBUG(level == LUSTRE_IMP_FULL ? D_INFO : D_HA, + "%s->%s: level %s/%u force %u force_next %u deactive %u pingable %u suppress %u\n", imp->imp_obd->obd_uuid.uuid, obd2cli_tgt(imp->imp_obd), ptlrpc_import_state_name(level), level, force, force_next, imp->imp_deactive, imp->imp_pingable, suppress); @@ -203,7 +204,8 @@ static void ptlrpc_pinger_process_import(struct obd_import *imp, } else if (level != LUSTRE_IMP_FULL || imp->imp_obd->obd_no_recov || imp_is_deactive(imp)) { - CDEBUG(D_HA, "%s->%s: not pinging (in recovery or recovery disabled: %s)\n", + CDEBUG(D_HA, + "%s->%s: not pinging (in recovery or recovery disabled: %s)\n", imp->imp_obd->obd_uuid.uuid, obd2cli_tgt(imp->imp_obd), ptlrpc_import_state_name(level)); if (force) { diff --git a/fs/lustre/ptlrpc/ptlrpc_internal.h b/fs/lustre/ptlrpc/ptlrpc_internal.h index 5383b68..201ccdd 100644 --- a/fs/lustre/ptlrpc/ptlrpc_internal.h +++ b/fs/lustre/ptlrpc/ptlrpc_internal.h @@ -224,8 +224,8 @@ struct ptlrpc_nrs_policy *nrs_request_policy(struct ptlrpc_nrs_request *nrq) * a separating space character. */ #define LPROCFS_NRS_WR_QUANTUM_MAX_CMD \ - sizeof(NRS_LPROCFS_QUANTUM_NAME_REG __stringify(LPROCFS_NRS_QUANTUM_MAX) " " \ - NRS_LPROCFS_QUANTUM_NAME_HP __stringify(LPROCFS_NRS_QUANTUM_MAX)) + sizeof(NRS_LPROCFS_QUANTUM_NAME_REG __stringify(LPROCFS_NRS_QUANTUM_MAX) " " \ + NRS_LPROCFS_QUANTUM_NAME_HP __stringify(LPROCFS_NRS_QUANTUM_MAX)) /* ptlrpc/nrs_fifo.c */ extern struct ptlrpc_nrs_pol_conf nrs_conf_fifo; @@ -301,7 +301,6 @@ static inline int tgt_mod_init(void) static inline void tgt_mod_exit(void) { - return; } static inline void ptlrpc_reqset_put(struct ptlrpc_request_set *set) diff --git a/fs/lustre/ptlrpc/ptlrpc_module.c b/fs/lustre/ptlrpc/ptlrpc_module.c index 5c32b657..f73ba41 100644 --- a/fs/lustre/ptlrpc/ptlrpc_module.c +++ b/fs/lustre/ptlrpc/ptlrpc_module.c @@ -46,7 +46,7 @@ #endif DEFINE_MUTEX(ptlrpc_startup); -static int ptlrpc_active = 0; +static int ptlrpc_active; int ptlrpc_inc_ref(void) { @@ -58,7 +58,7 @@ int ptlrpc_inc_ref(void) rc = ptlrpc_init_portals(); if (!rc) { - rc= ptlrpc_start_pinger(); + rc = ptlrpc_start_pinger(); if (rc) ptlrpc_exit_portals(); } @@ -160,7 +160,7 @@ static int __init ptlrpc_init(void) req_layout_fini(); /* Fall through */ default: - ; + break; } return rc; diff --git a/fs/lustre/ptlrpc/ptlrpcd.c b/fs/lustre/ptlrpc/ptlrpcd.c index f0ac296..92b477d 100644 --- a/fs/lustre/ptlrpc/ptlrpcd.c +++ b/fs/lustre/ptlrpc/ptlrpcd.c @@ -362,7 +362,8 @@ static int ptlrpcd_check(struct lu_env *env, struct ptlrpcd_ctl *pc) if (atomic_read(&ps->set_new_count)) { rc = ptlrpcd_steal_rqset(set, ps); if (rc > 0) - CDEBUG(D_RPCTRACE, "transfer %d async RPCs [%d->%d]\n", + CDEBUG(D_RPCTRACE, + "transfer %d async RPCs [%d->%d]\n", rc, partner->pc_index, pc->pc_index); } diff --git a/fs/lustre/ptlrpc/recover.c b/fs/lustre/ptlrpc/recover.c index af672ab..5548049 100644 --- a/fs/lustre/ptlrpc/recover.c +++ b/fs/lustre/ptlrpc/recover.c @@ -232,7 +232,8 @@ void ptlrpc_request_handle_notconn(struct ptlrpc_request *failed_req) if (ptlrpc_set_import_discon(imp, lustre_msg_get_conn_cnt(failed_req->rq_reqmsg))) { if (!imp->imp_replayable) { - CDEBUG(D_HA, "import %s@%s for %s not replayable, auto-deactivating\n", + CDEBUG(D_HA, + "import %s@%s for %s not replayable, auto-deactivating\n", obd2cli_tgt(imp->imp_obd), imp->imp_connection->c_remote_uuid.uuid, imp->imp_obd->obd_name); diff --git a/fs/lustre/ptlrpc/sec.c b/fs/lustre/ptlrpc/sec.c index 1cf0e9b..a0d6732 100644 --- a/fs/lustre/ptlrpc/sec.c +++ b/fs/lustre/ptlrpc/sec.c @@ -427,7 +427,8 @@ int sptlrpc_req_ctx_switch(struct ptlrpc_request *req, LASSERT(req->rq_reqlen); LASSERT(req->rq_replen); - CDEBUG(D_SEC, "req %p: switch ctx %p(%u->%s) -> %p(%u->%s), switch sec %p(%s) -> %p(%s)\n", + CDEBUG(D_SEC, + "req %p: switch ctx %p(%u->%s) -> %p(%u->%s), switch sec %p(%s) -> %p(%s)\n", req, oldctx, oldctx->cc_vcred.vc_uid, sec2target_str(oldctx->cc_sec), newctx, newctx->cc_vcred.vc_uid, sec2target_str(newctx->cc_sec), @@ -515,7 +516,8 @@ static int sptlrpc_req_replace_dead_ctx(struct ptlrpc_request *req) newctx, newctx->cc_flags); schedule_timeout_interruptible(HZ); - } else if (unlikely(!test_bit(PTLRPC_CTX_UPTODATE_BIT, &newctx->cc_flags))) { + } else if (unlikely(!test_bit(PTLRPC_CTX_UPTODATE_BIT, + &newctx->cc_flags))) { /* * new ctx not up to date yet */ @@ -1819,7 +1821,8 @@ int sptlrpc_target_export_check(struct obd_export *exp, req->rq_svc_ctx, &flavor); } else { - CDEBUG(D_SEC, "exp %p (%x|%x|%x): is current flavor, install rvs ctx\n", + CDEBUG(D_SEC, + "exp %p (%x|%x|%x): is current flavor, install rvs ctx\n", exp, exp->exp_flvr.sf_rpc, exp->exp_flvr_old[0].sf_rpc, exp->exp_flvr_old[1].sf_rpc); @@ -1833,8 +1836,9 @@ int sptlrpc_target_export_check(struct obd_export *exp, if (exp->exp_flvr_expire[0]) { if (exp->exp_flvr_expire[0] >= ktime_get_real_seconds()) { if (flavor_allowed(&exp->exp_flvr_old[0], req)) { - CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the middle one (%lld)\n", exp, - exp->exp_flvr.sf_rpc, + CDEBUG(D_SEC, + "exp %p (%x|%x|%x): match the middle one (%lld)\n", + exp, exp->exp_flvr.sf_rpc, exp->exp_flvr_old[0].sf_rpc, exp->exp_flvr_old[1].sf_rpc, (s64)(exp->exp_flvr_expire[0] - @@ -1846,8 +1850,8 @@ int sptlrpc_target_export_check(struct obd_export *exp, CDEBUG(D_SEC, "mark middle expired\n"); exp->exp_flvr_expire[0] = 0; } - CDEBUG(D_SEC, "exp %p (%x|%x|%x): %x not match middle\n", exp, - exp->exp_flvr.sf_rpc, + CDEBUG(D_SEC, "exp %p (%x|%x|%x): %x not match middle\n", + exp, exp->exp_flvr.sf_rpc, exp->exp_flvr_old[0].sf_rpc, exp->exp_flvr_old[1].sf_rpc, req->rq_flvr.sf_rpc); } @@ -1858,7 +1862,8 @@ int sptlrpc_target_export_check(struct obd_export *exp, if (exp->exp_flvr_changed == 0 && exp->exp_flvr_expire[1]) { if (exp->exp_flvr_expire[1] >= ktime_get_real_seconds()) { if (flavor_allowed(&exp->exp_flvr_old[1], req)) { - CDEBUG(D_SEC, "exp %p (%x|%x|%x): match the oldest one (%lld)\n", + CDEBUG(D_SEC, + "exp %p (%x|%x|%x): match the oldest one (%lld)\n", exp, exp->exp_flvr.sf_rpc, exp->exp_flvr_old[0].sf_rpc, diff --git a/fs/lustre/ptlrpc/sec_config.c b/fs/lustre/ptlrpc/sec_config.c index 35ebd56..d3c949d 100644 --- a/fs/lustre/ptlrpc/sec_config.c +++ b/fs/lustre/ptlrpc/sec_config.c @@ -416,11 +416,16 @@ struct sptlrpc_conf_tgt { struct sptlrpc_conf { struct list_head sc_list; char sc_fsname[MTI_NAME_MAXLEN]; - unsigned int sc_modified; /* modified during updating */ - unsigned int sc_updated:1, /* updated copy from MGS */ - sc_local:1; /* local copy from target */ - struct sptlrpc_rule_set sc_rset; /* fs general rules */ - struct list_head sc_tgts; /* target-specific rules */ + /* modified during updating */ + unsigned int sc_modified; + unsigned int sc_updated:1, /* updated copy from + * MGS + */ + sc_local:1; /* local copy from target */ + /* fs general rules */ + struct sptlrpc_rule_set sc_rset; + /* target-specific rules */ + struct list_head sc_tgts; }; static struct mutex sptlrpc_conf_lock; diff --git a/fs/lustre/ptlrpc/sec_lproc.c b/fs/lustre/ptlrpc/sec_lproc.c index 2bb75eb..df7c667 100644 --- a/fs/lustre/ptlrpc/sec_lproc.c +++ b/fs/lustre/ptlrpc/sec_lproc.c @@ -160,7 +160,8 @@ int sptlrpc_lprocfs_cliobd_attach(struct obd_device *dev) void sptlrpc_lproc_init(void) { - sptlrpc_debugfs_dir = debugfs_create_dir("sptlrpc", debugfs_lustre_root); + sptlrpc_debugfs_dir = debugfs_create_dir("sptlrpc", + debugfs_lustre_root); ldebugfs_add_vars(sptlrpc_debugfs_dir, sptlrpc_lprocfs_vars, NULL); } diff --git a/fs/lustre/ptlrpc/service.c b/fs/lustre/ptlrpc/service.c index 5a7e9fa..a40e964 100644 --- a/fs/lustre/ptlrpc/service.c +++ b/fs/lustre/ptlrpc/service.c @@ -445,7 +445,8 @@ static void ptlrpc_at_timer(struct timer_list *t) svc->srv_nthrs_cpt_init = init; if (nthrs * svc->srv_ncpts > tc->tc_nthrs_max) { - CDEBUG(D_OTHER, "%s: This service may have more threads (%d) than the given soft limit (%d)\n", + CDEBUG(D_OTHER, + "%s: This service may have more threads (%d) than the given soft limit (%d)\n", svc->srv_name, nthrs * svc->srv_ncpts, tc->tc_nthrs_max); } @@ -1042,7 +1043,8 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) return 0; if (olddl < 0) { - DEBUG_REQ(D_WARNING, req, "Already past deadline (%+lds), not sending early reply. Consider increasing at_early_margin (%d)?", + DEBUG_REQ(D_WARNING, req, + "Already past deadline (%+lds), not sending early reply. Consider increasing at_early_margin (%d)?", olddl, at_early_margin); /* Return an error so we're not re-added to the timed list. */ @@ -1050,7 +1052,8 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) } if (!(lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT)) { - DEBUG_REQ(D_INFO, req, "Wanted to ask client for more time, but no AT support"); + DEBUG_REQ(D_INFO, req, + "Wanted to ask client for more time, but no AT support"); return -ENOSYS; } @@ -1098,7 +1101,8 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) LASSERT(atomic_read(&req->rq_refcount)); /** if it is last refcount then early reply isn't needed */ if (atomic_read(&req->rq_refcount) == 1) { - DEBUG_REQ(D_ADAPTTO, reqcopy, "Normal reply already sent out, abort sending early reply\n"); + DEBUG_REQ(D_ADAPTTO, reqcopy, + "Normal reply already sent out, abort sending early reply\n"); rc = -EINVAL; goto out; } @@ -1223,7 +1227,8 @@ static void ptlrpc_at_check_timed(struct ptlrpc_service_part *svcpt) spin_unlock(&svcpt->scp_at_lock); - CDEBUG(D_ADAPTTO, "timeout in %+ds, asking for %d secs on %d early replies\n", + CDEBUG(D_ADAPTTO, + "timeout in %+ds, asking for %d secs on %d early replies\n", first, at_extra, counter); if (first < 0) { /* We're already past request deadlines before we even get a @@ -1566,7 +1571,8 @@ static bool ptlrpc_server_normal_pending(struct ptlrpc_service_part *svcpt, if (rc == 0) { rc = sptlrpc_target_export_check(req->rq_export, req); if (rc) - DEBUG_REQ(D_ERROR, req, "DROPPING req with illegal security flavor,"); + DEBUG_REQ(D_ERROR, req, + "DROPPING req with illegal security flavor,"); } if (rc) @@ -1684,7 +1690,8 @@ static bool ptlrpc_server_normal_pending(struct ptlrpc_service_part *svcpt, * The deadline is increased if we send an early reply. */ if (ktime_get_real_seconds() > request->rq_deadline) { - DEBUG_REQ(D_ERROR, request, "Dropping timed-out request from %s: deadline %lld:%llds ago\n", + DEBUG_REQ(D_ERROR, request, + "Dropping timed-out request from %s: deadline %lld:%llds ago\n", libcfs_id2str(request->rq_peer), request->rq_deadline - request->rq_arrival_time.tv_sec, @@ -1692,7 +1699,8 @@ static bool ptlrpc_server_normal_pending(struct ptlrpc_service_part *svcpt, goto put_conn; } - CDEBUG(D_RPCTRACE, "Handling RPC pname:cluuid+ref:pid:xid:nid:opc %s:%s+%d:%d:x%llu:%s:%d\n", + CDEBUG(D_RPCTRACE, + "Handling RPC pname:cluuid+ref:pid:xid:nid:opc %s:%s+%d:%d:x%llu:%s:%d\n", current->comm, (request->rq_export ? (char *)request->rq_export->exp_client_uuid.uuid : "0"), @@ -1722,8 +1730,7 @@ static bool ptlrpc_server_normal_pending(struct ptlrpc_service_part *svcpt, put_conn: if (unlikely(ktime_get_real_seconds() > request->rq_deadline)) { DEBUG_REQ(D_WARNING, request, - "Request took longer than estimated (%lld:%llds); " - "client may timeout.", + "Request took longer than estimated (%lld:%llds); client may timeout.", (s64)request->rq_deadline - request->rq_arrival_time.tv_sec, (s64)ktime_get_real_seconds() - request->rq_deadline); @@ -1736,7 +1743,8 @@ static bool ptlrpc_server_normal_pending(struct ptlrpc_service_part *svcpt, arrived = timespec64_sub(work_end, request->rq_arrival_time); arrived_usecs = arrived.tv_sec * USEC_PER_SEC + arrived.tv_nsec / NSEC_PER_USEC; - CDEBUG(D_RPCTRACE, "Handled RPC pname:cluuid+ref:pid:xid:nid:opc %s:%s+%d:%d:x%llu:%s:%d Request processed in %ldus (%ldus total) trans %llu rc %d/%d\n", + CDEBUG(D_RPCTRACE, + "Handled RPC pname:cluuid+ref:pid:xid:nid:opc %s:%s+%d:%d:x%llu:%s:%d Request processed in %ldus (%ldus total) trans %llu rc %d/%d\n", current->comm, (request->rq_export ? (char *)request->rq_export->exp_client_uuid.uuid : "0"), @@ -1841,9 +1849,9 @@ static bool ptlrpc_server_normal_pending(struct ptlrpc_service_part *svcpt, /* If we see this, we should already have seen the warning * in mds_steal_ack_locks() */ - CDEBUG(D_HA, "All locks stolen from rs %p x%lld.t%lld o%d NID %s\n", - rs, - rs->rs_xid, rs->rs_transno, rs->rs_opc, + CDEBUG(D_HA, + "All locks stolen from rs %p x%lld.t%lld o%d NID %s\n", + rs, rs->rs_xid, rs->rs_transno, rs->rs_opc, libcfs_nid2str(exp->exp_connection->c_peer.nid)); } @@ -1995,7 +2003,7 @@ static __attribute__((__noinline__)) int false) || ptlrpc_rqbd_pending(svcpt) || ptlrpc_at_check(svcpt)); - else if (0 == wait_event_idle_exclusive_lifo_timeout( + else if (wait_event_idle_exclusive_lifo_timeout( svcpt->scp_waitq, ptlrpc_thread_stopping(thread) || ptlrpc_server_request_incoming(svcpt) || @@ -2003,7 +2011,7 @@ static __attribute__((__noinline__)) int false) || ptlrpc_rqbd_pending(svcpt) || ptlrpc_at_check(svcpt), - svcpt->scp_rqbd_timeout)) + svcpt->scp_rqbd_timeout) == 0) svcpt->scp_rqbd_timeout = 0; if (ptlrpc_thread_stopping(thread)) -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:52:12 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:52:12 -0400 Subject: [lustre-devel] [PATCH 05/11] lustre: lmv: checkpatch cleanup In-Reply-To: <1563760338-806-1-git-send-email-jsimmons@infradead.org> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563760338-806-6-git-send-email-jsimmons@infradead.org> Many checkpatch errors exist in the lmv layer. This address a good chuck of them. Other are left since future patches will cleanup those areas. Others will need more code rework so this patch handles the simple cases. This is a good step forward toward proper kernel code style compliance. Signed-off-by: James Simmons --- fs/lustre/lmv/lmv_intent.c | 9 ++++++--- fs/lustre/lmv/lmv_obd.c | 22 ++++++++++++++-------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/fs/lustre/lmv/lmv_intent.c b/fs/lustre/lmv/lmv_intent.c index 8892426..818bb72 100644 --- a/fs/lustre/lmv/lmv_intent.c +++ b/fs/lustre/lmv/lmv_intent.c @@ -222,7 +222,8 @@ int lmv_revalidate_slaves(struct obd_export *exp, &RMF_MDT_BODY); if (!body) { if (it.it_lock_mode && lockh) { - ldlm_lock_decref(lockh, it.it_lock_mode); + ldlm_lock_decref(lockh, + it.it_lock_mode); it.it_lock_mode = 0; } @@ -309,7 +310,8 @@ static int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data, return rc; } - CDEBUG(D_INODE, "OPEN_INTENT with fid1=" DFID ", fid2=" DFID ", name='%s' -> mds #%u\n", + CDEBUG(D_INODE, + "OPEN_INTENT with fid1=" DFID ", fid2=" DFID ", name='%s' -> mds #%u\n", PFID(&op_data->op_fid1), PFID(&op_data->op_fid2), op_data->op_name, tgt->ltd_idx); @@ -387,7 +389,8 @@ static int lmv_intent_lookup(struct obd_export *exp, if (!fid_is_sane(&op_data->op_fid2)) fid_zero(&op_data->op_fid2); - CDEBUG(D_INODE, "LOOKUP_INTENT with fid1=" DFID ", fid2=" DFID ", name='%s' -> mds #%u lsm=%p lsm_magic=%x\n", + CDEBUG(D_INODE, + "LOOKUP_INTENT with fid1=" DFID ", fid2=" DFID ", name='%s' -> mds #%u lsm=%p lsm_magic=%x\n", PFID(&op_data->op_fid1), PFID(&op_data->op_fid2), op_data->op_name ? op_data->op_name : "", tgt->ltd_idx, lsm, !lsm ? -1 : lsm->lsm_md_magic); diff --git a/fs/lustre/lmv/lmv_obd.c b/fs/lustre/lmv/lmv_obd.c index 64ebaf3..1c43022 100644 --- a/fs/lustre/lmv/lmv_obd.c +++ b/fs/lustre/lmv/lmv_obd.c @@ -1630,7 +1630,8 @@ static int lmv_create(struct obd_export *exp, struct md_op_data *op_data, if (rc == 0) { if (!*request) return rc; - CDEBUG(D_INODE, "Created - " DFID "\n", PFID(&op_data->op_fid2)); + CDEBUG(D_INODE, "Created - " DFID "\n", + PFID(&op_data->op_fid2)); } return rc; } @@ -1749,8 +1750,8 @@ static int lmv_early_cancel(struct obd_export *exp, struct lmv_tgt_desc *tgt, } /* - * llite passes fid of an target inode in op_data->op_fid1 and id of directory in - * op_data->op_fid2 + * llite passes fid of an target inode in op_data->op_fid1 and id of + * directory in op_data->op_fid2 */ static int lmv_link(struct obd_export *exp, struct md_op_data *op_data, struct ptlrpc_request **request) @@ -1823,7 +1824,8 @@ static int lmv_rename(struct obd_export *exp, struct md_op_data *op_data, op_data->op_cap = current_cap(); if (op_data->op_cli_flags & CLI_MIGRATE) { - LASSERTF(fid_is_sane(&op_data->op_fid3), "invalid FID " DFID "\n", + LASSERTF(fid_is_sane(&op_data->op_fid3), + "invalid FID " DFID "\n", PFID(&op_data->op_fid3)); if (op_data->op_mea1) { @@ -2302,8 +2304,10 @@ static int lmv_read_page(struct obd_export *exp, struct md_op_data *op_data, struct lmv_obd *lmv = &obd->u.lmv; struct lmv_tgt_desc *tgt; - if (unlikely(lsm)) - return lmv_read_striped_page(exp, op_data, cb_op, offset, ppage); + if (unlikely(lsm)) { + return lmv_read_striped_page(exp, op_data, cb_op, + offset, ppage); + } tgt = lmv_find_target(lmv, &op_data->op_fid1); if (IS_ERR(tgt)) @@ -2647,7 +2651,8 @@ static int lmv_unpack_md_v1(struct obd_export *exp, struct lmv_stripe_md *lsm, if (cplen >= sizeof(lsm->lsm_md_pool_name)) return -E2BIG; - CDEBUG(D_INFO, "unpack lsm count %d, master %d hash_type %d layout_version %d\n", + CDEBUG(D_INFO, + "unpack lsm count %d, master %d hash_type %d layout_version %d\n", lsm->lsm_md_stripe_count, lsm->lsm_md_master_mdt_index, lsm->lsm_md_hash_type, lsm->lsm_md_layout_version); @@ -3016,7 +3021,8 @@ static int lmv_merge_attr(struct obd_export *exp, for (i = 0; i < lsm->lsm_md_stripe_count; i++) { struct inode *inode = lsm->lsm_md_oinfo[i].lmo_root; - CDEBUG(D_INFO, "" DFID " size %llu, blocks %llu nlink %u, atime %lld ctime %lld, mtime %lld.\n", + CDEBUG(D_INFO, + "" DFID " size %llu, blocks %llu nlink %u, atime %lld ctime %lld, mtime %lld.\n", PFID(&lsm->lsm_md_oinfo[i].lmo_fid), i_size_read(inode), (unsigned long long)inode->i_blocks, inode->i_nlink, inode->i_atime.tv_sec, -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:52:15 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:52:15 -0400 Subject: [lustre-devel] [PATCH 08/11] lustre: lov: checkpatch cleanup In-Reply-To: <1563760338-806-1-git-send-email-jsimmons@infradead.org> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563760338-806-9-git-send-email-jsimmons@infradead.org> Many checkpatch errors exist in the lov layer. This address a good chuck of them. Other are left since future patches will cleanup those areas. Others will need more code rework so this patch handles the simple cases. This is a good step forward toward proper kernel code style compliance. Signed-off-by: James Simmons --- fs/lustre/lov/lov_io.c | 2 +- fs/lustre/lov/lov_lock.c | 4 ++-- fs/lustre/lov/lov_merge.c | 6 ++++-- fs/lustre/lov/lov_obd.c | 6 ++++-- fs/lustre/lov/lov_object.c | 6 +++--- fs/lustre/lov/lov_pool.c | 24 +++++++++++++++++------- fs/lustre/lov/lov_request.c | 3 ++- 7 files changed, 33 insertions(+), 18 deletions(-) diff --git a/fs/lustre/lov/lov_io.c b/fs/lustre/lov/lov_io.c index 64982be..8214493 100644 --- a/fs/lustre/lov/lov_io.c +++ b/fs/lustre/lov/lov_io.c @@ -406,7 +406,7 @@ static int lov_io_iter_init(const struct lu_env *env, * it's handled in lov_io_setattr_iter_init() */ if (io->ci_type == CIT_WRITE || cl_io_is_mkwrite(io)) { - io->ci_need_write_intent = 1; + io->ci_need_write_intent = 1; rc = -ENODATA; break; } diff --git a/fs/lustre/lov/lov_lock.c b/fs/lustre/lov/lov_lock.c index 039c902..5520199 100644 --- a/fs/lustre/lov/lov_lock.c +++ b/fs/lustre/lov/lov_lock.c @@ -283,8 +283,8 @@ static void lov_lock_cancel(const struct lu_env *env, cl_lock_cancel(subenv->lse_env, sublock); } else { CL_LOCK_DEBUG(D_ERROR, env, slice->cls_lock, - "lov_lock_cancel fails with %ld.\n", - PTR_ERR(subenv)); + "%s fails with %ld.\n", + __func__, PTR_ERR(subenv)); } } } diff --git a/fs/lustre/lov/lov_merge.c b/fs/lustre/lov/lov_merge.c index ab0ba12..a8c23fe 100644 --- a/fs/lustre/lov/lov_merge.c +++ b/fs/lustre/lov/lov_merge.c @@ -57,7 +57,8 @@ int lov_merge_lvb_kms(struct lov_stripe_md *lsm, int index, assert_spin_locked(&lsm->lsm_lock); LASSERT(lsm->lsm_lock_owner == current->pid); - CDEBUG(D_INODE, "MDT ID " DOSTID " initial value: s=%llu m=%llu a=%llu c=%llu b=%llu\n", + CDEBUG(D_INODE, + "MDT ID " DOSTID " initial value: s=%llu m=%llu a=%llu c=%llu b=%llu\n", POSTID(&lsm->lsm_oi), lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime, lvb->lvb_ctime, lvb->lvb_blocks); @@ -90,7 +91,8 @@ int lov_merge_lvb_kms(struct lov_stripe_md *lsm, int index, if (loi->loi_lvb.lvb_ctime > current_ctime) current_ctime = loi->loi_lvb.lvb_ctime; - CDEBUG(D_INODE, "MDT ID " DOSTID " on OST[%u]: s=%llu m=%llu a=%llu c=%llu b=%llu\n", + CDEBUG(D_INODE, + "MDT ID " DOSTID " on OST[%u]: s=%llu m=%llu a=%llu c=%llu b=%llu\n", POSTID(&lsm->lsm_oi), loi->loi_ost_idx, loi->loi_lvb.lvb_size, loi->loi_lvb.lvb_mtime, loi->loi_lvb.lvb_atime, loi->loi_lvb.lvb_ctime, diff --git a/fs/lustre/lov/lov_obd.c b/fs/lustre/lov/lov_obd.c index 652ed6a..1d96f28 100644 --- a/fs/lustre/lov/lov_obd.c +++ b/fs/lustre/lov/lov_obd.c @@ -104,7 +104,8 @@ void lov_tgts_putref(struct obd_device *obd) mutex_unlock(&lov->lov_lock); while (!list_empty(&kill)) { - tgt = list_first_entry(&kill, struct lov_tgt_desc, ltd_kill); + tgt = list_first_entry(&kill, struct lov_tgt_desc, + ltd_kill); list_del(&tgt->ltd_kill); /* Disconnect */ __lov_del_obd(obd, tgt); @@ -171,7 +172,8 @@ int lov_connect_obd(struct obd_device *obd, u32 index, int activate, } if (imp->imp_invalid) { - CDEBUG(D_CONFIG, "not connecting OSC %s; administratively disabled\n", + CDEBUG(D_CONFIG, + "not connecting OSC %s; administratively disabled\n", obd_uuid2str(tgt_uuid)); return 0; } diff --git a/fs/lustre/lov/lov_object.c b/fs/lustre/lov/lov_object.c index 261f7b7..caeff89 100644 --- a/fs/lustre/lov/lov_object.c +++ b/fs/lustre/lov/lov_object.c @@ -216,8 +216,8 @@ static int lov_init_raid0(const struct lu_env *env, struct lov_device *dev, r0->lo_nr = lse->lsme_stripe_count; LASSERT(r0->lo_nr <= lov_targets_nr(dev)); - r0->lo_sub = kzalloc(r0->lo_nr * sizeof(r0->lo_sub[0]), - GFP_NOFS); + r0->lo_sub = kcalloc(r0->lo_nr, sizeof(r0->lo_sub[0]), + GFP_KERNEL); if (!r0->lo_sub) return -ENOMEM; @@ -1568,7 +1568,7 @@ static int lov_object_fiemap(const struct lu_env *env, struct cl_object *obj, goto finish; if (fs.fs_finish_stripe) break; - } /* for each stripe */ + } /* for each stripe */ } /* for covering layout component */ /* diff --git a/fs/lustre/lov/lov_pool.c b/fs/lustre/lov/lov_pool.c index 833fac9..78a7dd2 100644 --- a/fs/lustre/lov/lov_pool.c +++ b/fs/lustre/lov/lov_pool.c @@ -50,13 +50,16 @@ static u32 pool_hashfh(const void *data, u32 len, u32 seed) { const char *pool_name = data; - return hashlen_hash(hashlen_string((void*)(unsigned long)seed, pool_name)); + + return hashlen_hash(hashlen_string((void *)(unsigned long)seed, + pool_name)); } static int pool_cmpfn(struct rhashtable_compare_arg *arg, const void *obj) { const struct pool_desc *pool = obj; const char *pool_name = arg->key; + return strcmp(pool_name, pool->pool_name); } @@ -338,6 +341,7 @@ int lov_ost_pool_free(struct ost_pool *op) pools_hash_exit(void *vpool, void *data) { struct pool_desc *pool = vpool; + lov_pool_putref(pool); } @@ -391,7 +395,8 @@ int lov_pool_new(struct obd_device *obd, char *poolname) /* Add to hash table only when it is fully ready. */ rc = rhashtable_lookup_insert_fast(&lov->lov_pools_hash_body, - &new_pool->pool_hash, pools_hash_params); + &new_pool->pool_hash, + pools_hash_params); if (rc) { if (rc != -EEXIST) /* @@ -428,11 +433,14 @@ int lov_pool_del(struct obd_device *obd, char *poolname) /* lookup and kill hash reference */ rcu_read_lock(); - pool = rhashtable_lookup(&lov->lov_pools_hash_body, poolname, pools_hash_params); - if (pool) + pool = rhashtable_lookup(&lov->lov_pools_hash_body, poolname, + pools_hash_params); + if (pool) { if (rhashtable_remove_fast(&lov->lov_pools_hash_body, - &pool->pool_hash, pools_hash_params) != 0) + &pool->pool_hash, + pools_hash_params) != 0) pool = NULL; + } rcu_read_unlock(); if (!pool) return -ENOENT; @@ -462,7 +470,8 @@ int lov_pool_add(struct obd_device *obd, char *poolname, char *ostname) lov = &obd->u.lov; rcu_read_lock(); - pool = rhashtable_lookup(&lov->lov_pools_hash_body, poolname, pools_hash_params); + pool = rhashtable_lookup(&lov->lov_pools_hash_body, poolname, + pools_hash_params); if (pool && !atomic_inc_not_zero(&pool->pool_refcount)) pool = NULL; rcu_read_unlock(); @@ -511,7 +520,8 @@ int lov_pool_remove(struct obd_device *obd, char *poolname, char *ostname) lov = &obd->u.lov; rcu_read_lock(); - pool = rhashtable_lookup(&lov->lov_pools_hash_body, poolname, pools_hash_params); + pool = rhashtable_lookup(&lov->lov_pools_hash_body, poolname, + pools_hash_params); if (pool && !atomic_inc_not_zero(&pool->pool_refcount)) pool = NULL; rcu_read_unlock(); diff --git a/fs/lustre/lov/lov_request.c b/fs/lustre/lov/lov_request.c index 7f591ba..057d6ca 100644 --- a/fs/lustre/lov/lov_request.c +++ b/fs/lustre/lov/lov_request.c @@ -315,7 +315,8 @@ int lov_prep_statfs_set(struct obd_device *obd, struct obd_info *oinfo, * administrator */ if (!lov->lov_tgts[i]->ltd_exp) { - CDEBUG(D_HA, "lov idx %d administratively disabled\n", i); + CDEBUG(D_HA, + "lov idx %d administratively disabled\n", i); continue; } -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:52:09 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:52:09 -0400 Subject: [lustre-devel] [PATCH 02/11] lustre: llite: checkpatch cleanup In-Reply-To: <1563760338-806-1-git-send-email-jsimmons@infradead.org> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563760338-806-3-git-send-email-jsimmons@infradead.org> Many checkpatch errors exist in the llite layer. This address a good chuck of them. Other are left since future patches will cleanup those areas. Others will need more code rework so this patch handles the simple cases. This is a good step forward toward proper kernel code style compliance. Signed-off-by: James Simmons --- fs/lustre/llite/dir.c | 18 ++++++++---------- fs/lustre/llite/file.c | 24 ++++++++++++------------ fs/lustre/llite/llite_internal.h | 8 +++++--- fs/lustre/llite/llite_lib.c | 26 ++++++++++++++------------ fs/lustre/llite/llite_nfs.c | 3 ++- fs/lustre/llite/lproc_llite.c | 8 +++++--- fs/lustre/llite/namei.c | 15 ++++++++++----- fs/lustre/llite/rw26.c | 3 ++- fs/lustre/llite/statahead.c | 23 +++++++++++++++-------- fs/lustre/llite/super25.c | 3 ++- fs/lustre/llite/vvp_dev.c | 3 ++- fs/lustre/llite/vvp_io.c | 2 +- 12 files changed, 78 insertions(+), 58 deletions(-) diff --git a/fs/lustre/llite/dir.c b/fs/lustre/llite/dir.c index 1fbfc3a..ba53c1e 100644 --- a/fs/lustre/llite/dir.c +++ b/fs/lustre/llite/dir.c @@ -423,7 +423,8 @@ static int ll_dir_setdirstripe(struct dentry *dparent, struct lmv_user_md *lump, if (unlikely(lump->lum_magic != LMV_USER_MAGIC)) return -EINVAL; - CDEBUG(D_VFSTRACE, "VFS Op:inode=" DFID "(%p) name %s stripe_offset %d, stripe_count: %u\n", + CDEBUG(D_VFSTRACE, + "VFS Op:inode=" DFID "(%p) name %s stripe_offset %d, stripe_count: %u\n", PFID(ll_inode2fid(parent)), parent, dirname, (int)lump->lum_stripe_offset, lump->lum_stripe_count); @@ -517,24 +518,20 @@ int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump, } case LOV_USER_MAGIC_V3: { if (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_V3)) - lustre_swab_lov_user_md_v3( - (struct lov_user_md_v3 *)lump); + lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lump); lum_size = sizeof(struct lov_user_md_v3); break; } case LOV_USER_MAGIC_COMP_V1: { if (lump->lmm_magic != cpu_to_le32(LOV_USER_MAGIC_COMP_V1)) - lustre_swab_lov_comp_md_v1( - (struct lov_comp_md_v1 *)lump); - lum_size = le32_to_cpu( - ((struct lov_comp_md_v1 *)lump)->lcm_size); + lustre_swab_lov_comp_md_v1((struct lov_comp_md_v1 *)lump); + lum_size = le32_to_cpu(((struct lov_comp_md_v1 *)lump)->lcm_size); break; } case LMV_USER_MAGIC: { if (lump->lmm_magic != cpu_to_le32(LMV_USER_MAGIC)) - lustre_swab_lmv_user_md( - (struct lmv_user_md *)lump); + lustre_swab_lmv_user_md((struct lmv_user_md *)lump); lum_size = sizeof(struct lmv_user_md); break; } @@ -877,7 +874,8 @@ static int ll_ioc_copy_end(struct super_block *sb, struct hsm_copy *copy) */ if ((copy->hc_hai.hai_action == HSMA_ARCHIVE) && (copy->hc_data_version != data_version)) { - CDEBUG(D_HSM, "File data version mismatched. File content was changed during archiving. " DFID ", start:%#llx current:%#llx\n", + CDEBUG(D_HSM, + "File data version mismatched. File content was changed during archiving. " DFID ", start:%#llx current:%#llx\n", PFID(©->hc_hai.hai_fid), copy->hc_data_version, data_version); /* File was changed, send error to cdt. Do not ask for diff --git a/fs/lustre/llite/file.c b/fs/lustre/llite/file.c index fd53a3a..faf4fb8 100644 --- a/fs/lustre/llite/file.c +++ b/fs/lustre/llite/file.c @@ -587,7 +587,7 @@ int ll_file_open(struct inode *inode, struct file *file) } else { LASSERT(*och_usecount == 0); if (!it->it_disposition) { - struct ll_dentry_data *ldd = ll_d2d(file->f_path.dentry); + struct ll_dentry_data *ldd; /* We cannot just request lock handle now, new ELC code * means that one of other OPEN locks for this file @@ -611,6 +611,7 @@ int ll_file_open(struct inode *inode, struct file *file) * lookup path only, since ll_iget_for_nfs always calls * ll_d_init(). */ + ldd = ll_d2d(file->f_path.dentry); if (ldd && ldd->lld_nfs_dentry) { ldd->lld_nfs_dentry = 0; it->it_flags |= MDS_OPEN_LOCK; @@ -1460,15 +1461,13 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename, if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) { lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm); if (S_ISREG(body->mbo_mode)) - lustre_swab_lov_user_md_objects( - ((struct lov_user_md_v1 *)lmm)->lmm_objects, - stripe_count); + lustre_swab_lov_user_md_objects(((struct lov_user_md_v1 *)lmm)->lmm_objects, + stripe_count); } else if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)) { lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm); if (S_ISREG(body->mbo_mode)) - lustre_swab_lov_user_md_objects( - ((struct lov_user_md_v3 *)lmm)->lmm_objects, - stripe_count); + lustre_swab_lov_user_md_objects(((struct lov_user_md_v3 *)lmm)->lmm_objects, + stripe_count); } else if (lmm->lmm_magic == cpu_to_le32(LOV_MAGIC_COMP_V1)) { lustre_swab_lov_comp_md_v1((struct lov_comp_md_v1 *)lmm); } @@ -2237,7 +2236,7 @@ int ll_ioctl_fsgetxattr(struct inode *inode, unsigned int cmd, fsxattr.fsx_xflags |= FS_XFLAG_PROJINHERIT; fsxattr.fsx_projid = ll_i2info(inode)->lli_projid; if (copy_to_user((struct fsxattr __user *)arg, - &fsxattr, sizeof(fsxattr))) + &fsxattr, sizeof(fsxattr))) return -EFAULT; return 0; @@ -2344,9 +2343,9 @@ int ll_ioctl_fssetxattr(struct inode *inode, unsigned int cmd, return 0; case LL_IOC_LOV_SETSTRIPE: case LL_IOC_LOV_SETSTRIPE_NEW: - return ll_lov_setstripe(inode, file, (void __user *) arg); + return ll_lov_setstripe(inode, file, (void __user *)arg); case LL_IOC_LOV_SETEA: - return ll_lov_setea(inode, file, (void __user *) arg); + return ll_lov_setea(inode, file, (void __user *)arg); case LL_IOC_LOV_SWAP_LAYOUTS: { struct file *file2; struct lustre_swap_layouts lsl; @@ -2959,7 +2958,8 @@ int ll_fsync(struct file *file, loff_t start, loff_t end, int datasync) if (IS_ERR(op_data)) return PTR_ERR(op_data); - CDEBUG(D_DLMTRACE, "inode=" DFID ", pid=%u, flags=%#llx, mode=%u, start=%llu, end=%llu\n", + CDEBUG(D_DLMTRACE, + "inode=" DFID ", pid=%u, flags=%#llx, mode=%u, start=%llu, end=%llu\n", PFID(ll_inode2fid(inode)), flock.l_flock.pid, flags, einfo.ei_mode, flock.l_flock.start, flock.l_flock.end); @@ -3167,7 +3167,7 @@ int ll_migrate(struct inode *parent, struct file *file, int mdtidx, static int ll_file_noflock(struct file *file, int cmd, struct file_lock *file_lock) { - return -ENOSYS; + return -EINVAL; } /** diff --git a/fs/lustre/llite/llite_internal.h b/fs/lustre/llite/llite_internal.h index 9da59b1..b8f4e0e 100644 --- a/fs/lustre/llite/llite_internal.h +++ b/fs/lustre/llite/llite_internal.h @@ -267,7 +267,7 @@ static inline bool obd_connect_has_secctx(struct obd_connect_data *data) return data->ocd_connect_flags & OBD_CONNECT_FLAGS2 && data->ocd_connect_flags2 & OBD_CONNECT2_FILE_SECCTX; #else - return false; + return false; #endif } @@ -1079,6 +1079,7 @@ enum ras_update_flags { LL_RAS_HIT = 0x1, LL_RAS_MMAP = 0x2 }; + void ll_ra_count_put(struct ll_sb_info *sbi, unsigned long len); void ll_ra_stats_inc(struct inode *inode, enum ra_stat which); @@ -1096,7 +1097,7 @@ enum ras_update_flags { #define LL_SA_RUNNING_DEF 16 #define LL_SA_CACHE_BIT 5 -#define LL_SA_CACHE_SIZE (1 << LL_SA_CACHE_BIT) +#define LL_SA_CACHE_SIZE BIT(LL_SA_CACHE_BIT) #define LL_SA_CACHE_MASK (LL_SA_CACHE_SIZE - 1) /* per inode struct, for dir only */ @@ -1256,7 +1257,8 @@ static inline void ll_set_lock_data(struct obd_export *exp, struct inode *inode, */ if (it->it_remote_lock_mode) { handle.cookie = it->it_remote_lock_handle; - CDEBUG(D_DLMTRACE, "setting l_data to inode " DFID "%p for remote lock %#llx\n", + CDEBUG(D_DLMTRACE, + "setting l_data to inode " DFID "%p for remote lock %#llx\n", PFID(ll_inode2fid(inode)), inode, handle.cookie); md_set_lock_data(exp, &handle, inode, NULL); diff --git a/fs/lustre/llite/llite_lib.c b/fs/lustre/llite/llite_lib.c index 4e98eb4..4e09f0f 100644 --- a/fs/lustre/llite/llite_lib.c +++ b/fs/lustre/llite/llite_lib.c @@ -93,7 +93,7 @@ static struct ll_sb_info *ll_init_sbi(void) } sbi->ll_ra_info.ra_max_pages_per_file = min(pages / 32, - SBI_DEFAULT_READAHEAD_MAX); + SBI_DEFAULT_READAHEAD_MAX); sbi->ll_ra_info.ra_max_pages = sbi->ll_ra_info.ra_max_pages_per_file; sbi->ll_ra_info.ra_max_read_ahead_whole_pages = SBI_DEFAULT_READAHEAD_WHOLE_MAX; @@ -110,10 +110,11 @@ static struct ll_sb_info *ll_init_sbi(void) sbi->ll_flags |= LL_SBI_LAZYSTATFS; for (i = 0; i <= LL_PROCESS_HIST_MAX; i++) { - spin_lock_init(&sbi->ll_rw_extents_info.pp_extents[i]. - pp_r_hist.oh_lock); - spin_lock_init(&sbi->ll_rw_extents_info.pp_extents[i]. - pp_w_hist.oh_lock); + struct per_process_info *pp_ext; + + pp_ext = &sbi->ll_rw_extents_info.pp_extents[i]; + spin_lock_init(&pp_ext->pp_r_hist.oh_lock); + spin_lock_init(&pp_ext->pp_w_hist.oh_lock); } /* metadata statahead is enabled by default */ @@ -353,9 +354,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) if (data->ocd_ibits_known & MDS_INODELOCK_XATTR) { if (!(data->ocd_connect_flags & OBD_CONNECT_MAX_EASIZE)) { - LCONSOLE_INFO( - "%s: disabling xattr cache due to unknown maximum xattr size.\n", - dt); + LCONSOLE_INFO("%s: disabling xattr cache due to unknown maximum xattr size.\n", + dt); } else if (!sbi->ll_xattr_cache_set) { /* If xattr_cache is already set (no matter 0 or 1) * during processing llog, it won't be enabled here. @@ -377,7 +377,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt) data->ocd_connect_flags = OBD_CONNECT_GRANT | OBD_CONNECT_VERSION | OBD_CONNECT_REQPORTAL | OBD_CONNECT_BRW_SIZE | OBD_CONNECT_CANCELSET | OBD_CONNECT_FID | - OBD_CONNECT_SRVLOCK | OBD_CONNECT_TRUNCLOCK| + OBD_CONNECT_SRVLOCK | + OBD_CONNECT_TRUNCLOCK | OBD_CONNECT_AT | OBD_CONNECT_OSS_CAPA | OBD_CONNECT_VBR | OBD_CONNECT_FULL20 | OBD_CONNECT_64BITHASH | OBD_CONNECT_MAXBYTES | @@ -2063,7 +2064,7 @@ int ll_iocontrol(struct inode *inode, struct file *file, return rc; } default: - return -ENOSYS; + return -EINVAL; } return 0; @@ -2235,8 +2236,9 @@ int ll_prep_inode(struct inode **inode, struct ptlrpc_request *req, goto out; } - *inode = ll_iget(sb, cl_fid_build_ino(&md.body->mbo_fid1, - sbi->ll_flags & LL_SBI_32BIT_API), + *inode = ll_iget(sb, + cl_fid_build_ino(&md.body->mbo_fid1, + sbi->ll_flags & LL_SBI_32BIT_API), &md); if (IS_ERR(*inode)) { #ifdef CONFIG_FS_POSIX_ACL diff --git a/fs/lustre/llite/llite_nfs.c b/fs/lustre/llite/llite_nfs.c index 9129f47..64bff0a 100644 --- a/fs/lustre/llite/llite_nfs.c +++ b/fs/lustre/llite/llite_nfs.c @@ -218,7 +218,8 @@ static int ll_nfs_get_name_filldir(struct dir_context *ctx, const char *name, /* It is hack to access lde_fid for comparison with lgd_fid. * So the input 'name' must be part of the 'lu_dirent'. */ - struct lu_dirent *lde = container_of((void*)name, struct lu_dirent, lde_name); + struct lu_dirent *lde = container_of((void *)name, struct lu_dirent, + lde_name); struct ll_getname_data *lgd = container_of(ctx, struct ll_getname_data, ctx); struct lu_fid fid; diff --git a/fs/lustre/llite/lproc_llite.c b/fs/lustre/llite/lproc_llite.c index 7cb1c28..99e8a82 100644 --- a/fs/lustre/llite/lproc_llite.c +++ b/fs/lustre/llite/lproc_llite.c @@ -501,7 +501,8 @@ static ssize_t ll_max_cached_mb_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { - struct super_block *sb = ((struct seq_file *)file->private_data)->private; + struct seq_file *m = file->private_data; + struct super_block *sb = m->private; struct ll_sb_info *sbi = ll_s2sbi(sb); struct cl_client_cache *cache = sbi->ll_cache; struct lu_env *env; @@ -1094,7 +1095,8 @@ static ssize_t ll_unstable_stats_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { - struct super_block *sb = ((struct seq_file *)file->private_data)->private; + struct seq_file *m = file->private_data; + struct super_block *sb = m->private; struct ll_sb_info *sbi = ll_s2sbi(sb); char kernbuf[128]; bool val; @@ -1320,7 +1322,7 @@ void ll_stats_ops_tally(struct ll_sb_info *sbi, int op, int count) } EXPORT_SYMBOL(ll_stats_ops_tally); -static const char *ra_stat_string[] = { +static const char *const ra_stat_string[] = { [RA_STAT_HIT] = "hits", [RA_STAT_MISS] = "misses", [RA_STAT_DISTANT_READPAGE] = "readpage not consecutive", diff --git a/fs/lustre/llite/namei.c b/fs/lustre/llite/namei.c index a87c8a2..caa759f 100644 --- a/fs/lustre/llite/namei.c +++ b/fs/lustre/llite/namei.c @@ -263,13 +263,16 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, PFID(ll_inode2fid(inode)), rc); } - if (bits & MDS_INODELOCK_UPDATE) - set_bit(LLIF_UPDATE_ATIME, &ll_i2info(inode)->lli_flags); + if (bits & MDS_INODELOCK_UPDATE) { + set_bit(LLIF_UPDATE_ATIME, + &ll_i2info(inode)->lli_flags); + } if ((bits & MDS_INODELOCK_UPDATE) && S_ISDIR(inode->i_mode)) { struct ll_inode_info *lli = ll_i2info(inode); - CDEBUG(D_INODE, "invalidating inode " DFID " lli = %p, pfid = " DFID "\n", + CDEBUG(D_INODE, + "invalidating inode " DFID " lli = %p, pfid = " DFID "\n", PFID(ll_inode2fid(inode)), lli, PFID(&lli->lli_pfid)); @@ -563,7 +566,8 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry, } } - if (it->it_op & IT_OPEN && it->it_flags & FMODE_WRITE && sb_rdonly(dentry->d_sb)) + if (it->it_op & IT_OPEN && it->it_flags & FMODE_WRITE && + sb_rdonly(dentry->d_sb)) return ERR_PTR(-EROFS); if (it->it_op & IT_CREAT) @@ -714,7 +718,8 @@ static int ll_atomic_open(struct inode *dir, struct dentry *dentry, struct dentry *de; int rc = 0; - CDEBUG(D_VFSTRACE, "VFS Op:name=%pd, dir=" DFID "(%p),file %p,open_flags %x,mode %x\n", + CDEBUG(D_VFSTRACE, + "VFS Op:name=%pd, dir=" DFID "(%p),file %p,open_flags %x,mode %x\n", dentry, PFID(ll_inode2fid(dir)), dir, file, open_flags, mode); /* Only negative dentries enter here */ diff --git a/fs/lustre/llite/rw26.c b/fs/lustre/llite/rw26.c index e4ce3b6..805ba32 100644 --- a/fs/lustre/llite/rw26.c +++ b/fs/lustre/llite/rw26.c @@ -306,7 +306,8 @@ static ssize_t ll_direct_IO(struct kiocb *iocb, struct iov_iter *iter) if ((file_offset & ~PAGE_MASK) || (count & ~PAGE_MASK)) return -EINVAL; - CDEBUG(D_VFSTRACE, "VFS Op:inode=" DFID "(%p), size=%zd (max %lu), offset=%lld=%llx, pages %zd (max %lu)\n", + CDEBUG(D_VFSTRACE, + "VFS Op:inode=" DFID "(%p), size=%zd (max %lu), offset=%lld=%llx, pages %zd (max %lu)\n", PFID(ll_inode2fid(inode)), inode, count, MAX_DIO_SIZE, file_offset, file_offset, count >> PAGE_SHIFT, MAX_DIO_SIZE >> PAGE_SHIFT); diff --git a/fs/lustre/llite/statahead.c b/fs/lustre/llite/statahead.c index 53bab47..797ad06 100644 --- a/fs/lustre/llite/statahead.c +++ b/fs/lustre/llite/statahead.c @@ -265,8 +265,8 @@ static void sa_free(struct ll_statahead_info *sai, struct sa_entry *entry) } /* called by scanner after use, sa_entry will be killed */ -static void -sa_put(struct ll_statahead_info *sai, struct sa_entry *entry, struct ll_inode_info *lli) +static void sa_put(struct ll_statahead_info *sai, struct sa_entry *entry, + struct ll_inode_info *lli) { struct sa_entry *tmp, *next; @@ -326,7 +326,8 @@ static void sa_free(struct ll_statahead_info *sai, struct sa_entry *entry) * LU-9210: ll_statahead_interpet must be able to see this before * we wake it up */ - smp_store_release(&entry->se_state, ret < 0 ? SA_ENTRY_INVA : SA_ENTRY_SUCC); + smp_store_release(&entry->se_state, + ret < 0 ? SA_ENTRY_INVA : SA_ENTRY_SUCC); return (index == sai->sai_index_wait); } @@ -590,7 +591,8 @@ static void sa_instantiate(struct ll_statahead_info *sai, child = entry->se_inode; if (child) { /* revalidate; unlinked and re-created with the same name */ - if (unlikely(!lu_fid_eq(&minfo->mi_data.op_fid2, &body->mbo_fid1))) { + if (unlikely(!lu_fid_eq(&minfo->mi_data.op_fid2, + &body->mbo_fid1))) { entry->se_inode = NULL; iput(child); child = NULL; @@ -701,6 +703,7 @@ static int ll_statahead_interpret(struct ptlrpc_request *req, wake_up(&sai->sai_waitq); } else { int first = 0; + entry->se_minfo = minfo; entry->se_req = ptlrpc_request_addref(req); /* @@ -881,7 +884,9 @@ static int ll_agl_thread(void *arg) struct inode *dir = d_inode(parent); struct ll_inode_info *plli = ll_i2info(dir); struct ll_inode_info *clli; - /* We already own this reference, so it is safe to take it without a lock. */ + /* We already own this reference, so it is safe to take it without + * a lock. + */ struct ll_statahead_info *sai = plli->lli_sai; CDEBUG(D_READA, "agl thread started: sai %p, parent %pd\n", @@ -1113,7 +1118,9 @@ static int ll_statahead_thread(void *arg) sa_handle_callback(sai); set_current_state(TASK_IDLE); - /* ensure we see the NULL stored by ll_deauthorize_statahead() */ + /* ensure we see the NULL stored by + * ll_deauthorize_statahead() + */ if (!sa_has_callback(sai) && smp_load_acquire(&sai->sai_task)) schedule(); @@ -1408,8 +1415,8 @@ static int revalidate_statahead_dentry(struct inode *dir, spin_lock(&lli->lli_sa_lock); sai->sai_index_wait = entry->se_index; spin_unlock(&lli->lli_sa_lock); - if (0 == wait_event_idle_timeout(sai->sai_waitq, - sa_ready(entry), 30 * HZ)) { + if (wait_event_idle_timeout(sai->sai_waitq, + sa_ready(entry), 30 * HZ) == 0) { /* * entry may not be ready, so it may be used by inflight * statahead RPC, don't free it. diff --git a/fs/lustre/llite/super25.c b/fs/lustre/llite/super25.c index a25d03c..2b65e2f 100644 --- a/fs/lustre/llite/super25.c +++ b/fs/lustre/llite/super25.c @@ -89,7 +89,8 @@ struct super_operations lustre_super_operations = { * * @data: Mount options (e.g. -o flock,abort_recov) */ -static int lustre_fill_super(struct super_block *sb, void *lmd2_data, int silent) +static int lustre_fill_super(struct super_block *sb, void *lmd2_data, + int silent) { struct lustre_mount_data *lmd; struct lustre_sb_info *lsi; diff --git a/fs/lustre/llite/vvp_dev.c b/fs/lustre/llite/vvp_dev.c index 568943d..4c5a29d 100644 --- a/fs/lustre/llite/vvp_dev.c +++ b/fs/lustre/llite/vvp_dev.c @@ -451,7 +451,8 @@ static struct page *vvp_pgcache_current(struct vvp_seq_private *priv) } inode = vvp_object_inode(priv->vsp_clob); - nr = find_get_pages_contig(inode->i_mapping, priv->vsp_id.vpi_index, 1, &vmpage); + nr = find_get_pages_contig(inode->i_mapping, + priv->vsp_id.vpi_index, 1, &vmpage); if (nr > 0) { priv->vsp_id.vpi_index = vmpage->index; return vmpage; diff --git a/fs/lustre/llite/vvp_io.c b/fs/lustre/llite/vvp_io.c index 225a858..b2160d6 100644 --- a/fs/lustre/llite/vvp_io.c +++ b/fs/lustre/llite/vvp_io.c @@ -641,7 +641,7 @@ static int vvp_io_setattr_time(const struct lu_env *env, struct cl_object *obj = io->ci_obj; struct cl_attr *attr = vvp_env_thread_attr(env); int result; - unsigned valid = CAT_CTIME; + unsigned int valid = CAT_CTIME; cl_object_attr_lock(obj); attr->cat_ctime = io->u.ci_setattr.sa_attr.lvb_ctime; -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:52:11 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:52:11 -0400 Subject: [lustre-devel] [PATCH 04/11] lustre: mgc: checkpatch cleanup In-Reply-To: <1563760338-806-1-git-send-email-jsimmons@infradead.org> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563760338-806-5-git-send-email-jsimmons@infradead.org> Many checkpatch errors exist in the mgc layer. This address a good chuck of them. Other are left since future patches will cleanup those areas. Others will need more code rework so this patch handles the simple cases. This is a good step forward toward proper kernel code style compliance. Signed-off-by: James Simmons --- fs/lustre/mgc/mgc_request.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/fs/lustre/mgc/mgc_request.c b/fs/lustre/mgc/mgc_request.c index 5ce49e7..fa0be5c 100644 --- a/fs/lustre/mgc/mgc_request.c +++ b/fs/lustre/mgc/mgc_request.c @@ -96,7 +96,8 @@ int mgc_fsname2resid(char *fsname, struct ldlm_res_id *res_id, int type) } EXPORT_SYMBOL(mgc_fsname2resid); -static int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id, int type) +static int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id, + int type) { char *name_end; int len; @@ -474,7 +475,7 @@ int lprocfs_mgc_rd_ir_state(struct seq_file *m, void *data) seq_printf(m, "imperative_recovery: %s\n", OCD_HAS_FLAG(ocd, IMP_RECOV) ? "ENABLED" : "DISABLED"); - seq_printf(m, "client_state:\n"); + seq_puts(m, "client_state:\n"); spin_lock(&config_list_lock); list_for_each_entry(cld, &config_llog_list, cld_list_chain) { @@ -821,7 +822,8 @@ static int mgc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, */ if (!lock->l_conn_export || !lock->l_conn_export->exp_obd->u.cli.cl_conn_count) { - CDEBUG(D_MGC, "log %.8s: disconnecting, won't requeue\n", + CDEBUG(D_MGC, + "log %.8s: disconnecting, won't requeue\n", cld->cld_logname); config_log_put(cld); break; @@ -874,7 +876,8 @@ static int mgc_set_mgs_param(struct obd_export *exp, req->rq_delay_limit = MGC_SEND_PARAM_LIMIT; rc = ptlrpc_queue_wait(req); if (!rc) { - rep_msp = req_capsule_server_get(&req->rq_pill, &RMF_MGS_SEND_PARAM); + rep_msp = req_capsule_server_get(&req->rq_pill, + &RMF_MGS_SEND_PARAM); memcpy(msp, rep_msp, sizeof(*rep_msp)); } @@ -1733,7 +1736,7 @@ static int mgc_process_config(struct obd_device *obd, u32 len, void *buf) case LCFG_LOV_DEL_OBD: /* Unregister has no meaning at the moment. */ CERROR("lov_del_obd unimplemented\n"); - rc = -ENOSYS; + rc = -ENXIO; break; case LCFG_SPTLRPC_CONF: { rc = sptlrpc_process_config(lcfg); @@ -1765,8 +1768,8 @@ static int mgc_process_config(struct obd_device *obd, u32 len, void *buf) rc = mgc_process_log(obd, cld); if (rc == 0 && cld->cld_recover) { - if (OCD_HAS_FLAG(&obd->u.cli.cl_import-> - imp_connect_data, IMP_RECOV)) { + if (OCD_HAS_FLAG(&obd->u.cli.cl_import->imp_connect_data, + IMP_RECOV)) { rc = mgc_process_log(obd, cld->cld_recover); } else { struct config_llog_data *cir; -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:52:10 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:52:10 -0400 Subject: [lustre-devel] [PATCH 03/11] lustre: fid: checkpatch cleanup In-Reply-To: <1563760338-806-1-git-send-email-jsimmons@infradead.org> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563760338-806-4-git-send-email-jsimmons@infradead.org> Various checkpatch errors exist in the fid /fld layer. This work address all of those issues making this layer checkpatch error free. Signed-off-by: James Simmons --- fs/lustre/fid/fid_request.c | 1 - fs/lustre/fid/lproc_fid.c | 3 ++- fs/lustre/fld/fld_internal.h | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/fs/lustre/fid/fid_request.c b/fs/lustre/fid/fid_request.c index 45dd275..cdf5402 100644 --- a/fs/lustre/fid/fid_request.c +++ b/fs/lustre/fid/fid_request.c @@ -267,7 +267,6 @@ int seq_client_alloc_fid(const struct lu_env *env, */ void seq_client_flush(struct lu_client_seq *seq) { - LASSERT(seq); spin_lock(&seq->lcs_lock); diff --git a/fs/lustre/fid/lproc_fid.c b/fs/lustre/fid/lproc_fid.c index d7d23b4..94869d4 100644 --- a/fs/lustre/fid/lproc_fid.c +++ b/fs/lustre/fid/lproc_fid.c @@ -131,7 +131,8 @@ if (seq->lcs_update) rc = -EBUSY; else - seq_printf(m, "[%#llx - %#llx]:%x:%s\n", PRANGE(&seq->lcs_space)); + seq_printf(m, "[%#llx - %#llx]:%x:%s\n", + PRANGE(&seq->lcs_space)); spin_unlock(&seq->lcs_lock); return rc; diff --git a/fs/lustre/fld/fld_internal.h b/fs/lustre/fld/fld_internal.h index e2eda59..465c6ccf 100644 --- a/fs/lustre/fld/fld_internal.h +++ b/fs/lustre/fld/fld_internal.h @@ -70,8 +70,9 @@ struct fld_stats { struct lu_fld_hash { const char *fh_name; - int (*fh_hash_func)(struct lu_client_fld *, u64); - struct lu_fld_target *(*fh_scan_func)(struct lu_client_fld *, u64); + int (*fh_hash_func)(struct lu_client_fld *fld, u64 seq); + struct lu_fld_target *(*fh_scan_func)(struct lu_client_fld *fld, + u64 seq); }; struct fld_cache_entry { -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:52:14 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:52:14 -0400 Subject: [lustre-devel] [PATCH 07/11] lustre: osc: checkpatch cleanup In-Reply-To: <1563760338-806-1-git-send-email-jsimmons@infradead.org> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563760338-806-8-git-send-email-jsimmons@infradead.org> Many checkpatch errors exist in the osc layer. This address a good chuck of them. Other are left since future patches will cleanup those areas. Others will need more code rework so this patch handles the simple cases. This is a good step forward toward proper kernel code style compliance. Signed-off-by: James Simmons --- fs/lustre/osc/lproc_osc.c | 7 ++++--- fs/lustre/osc/osc_cache.c | 15 +++++---------- fs/lustre/osc/osc_internal.h | 6 ++++-- fs/lustre/osc/osc_lock.c | 6 ++++-- fs/lustre/osc/osc_object.c | 6 ++++-- fs/lustre/osc/osc_page.c | 3 ++- fs/lustre/osc/osc_quota.c | 20 ++++++++++++-------- fs/lustre/osc/osc_request.c | 38 ++++++++++++++++---------------------- 8 files changed, 51 insertions(+), 50 deletions(-) diff --git a/fs/lustre/osc/lproc_osc.c b/fs/lustre/osc/lproc_osc.c index 299a69f..eb724f4 100644 --- a/fs/lustre/osc/lproc_osc.c +++ b/fs/lustre/osc/lproc_osc.c @@ -197,7 +197,8 @@ static ssize_t osc_cached_mb_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { - struct obd_device *dev = ((struct seq_file *)file->private_data)->private; + struct seq_file *m = file->private_data; + struct obd_device *dev = m->private; struct client_obd *cli = &dev->u.cli; long pages_number, rc; char kernbuf[128]; @@ -251,7 +252,6 @@ static ssize_t cur_dirty_bytes_show(struct kobject *kobj, struct client_obd *cli = &dev->u.cli; return sprintf(buf, "%lu\n", cli->cl_dirty_pages << PAGE_SHIFT); - } LUSTRE_RO_ATTR(cur_dirty_bytes); @@ -405,7 +405,8 @@ static ssize_t osc_checksum_type_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { - struct obd_device *obd = ((struct seq_file *)file->private_data)->private; + struct seq_file *m = file->private_data; + struct obd_device *obd = m->private; DECLARE_CKSUM_NAME; char kernbuf[10]; int i; diff --git a/fs/lustre/osc/osc_cache.c b/fs/lustre/osc/osc_cache.c index f8fddbf..46d578e 100644 --- a/fs/lustre/osc/osc_cache.c +++ b/fs/lustre/osc/osc_cache.c @@ -393,13 +393,6 @@ static void osc_extent_free(struct kref *kref) LDLM_LOCK_PUT(ext->oe_dlmlock); ext->oe_dlmlock = NULL; } -#if 0 - // When cl_object_put drop the need for 'env', - // this code can be enabled. - cl_object_put(osc2cl(ext->oe_obj)); - - kmem_cache_free(osc_extent_kmem, ext); -#endif } static struct osc_extent *osc_extent_get(struct osc_extent *ext) @@ -1547,19 +1540,21 @@ static bool osc_enter_cache_try(struct client_obd *cli, struct osc_async_page *oap, int bytes) { + bool rc = false; + OSC_DUMP_GRANT(D_CACHE, cli, "need:%d\n", bytes); if (osc_reserve_grant(cli, bytes) < 0) - return false; + return rc; if (cli->cl_dirty_pages < cli->cl_dirty_max_pages && atomic_long_read(&obd_dirty_pages) + 1 <= obd_max_dirty_pages) { osc_consume_write_grant(cli, &oap->oap_brw_page); - return true; + rc = true; } else { __osc_unreserve_grant(cli, bytes, bytes); - return false; } + return rc; } #define __wait_event_idle_exclusive_timeout_cmd(wq_head, condition, \ diff --git a/fs/lustre/osc/osc_internal.h b/fs/lustre/osc/osc_internal.h index 4033365..95f5b93 100644 --- a/fs/lustre/osc/osc_internal.h +++ b/fs/lustre/osc/osc_internal.h @@ -48,7 +48,8 @@ enum async_flags { * added to an rpc */ ASYNC_URGENT = 0x2, /* page must be put into an RPC - * before return */ + * before return + */ ASYNC_COUNT_STABLE = 0x4, /* ap_refresh_count will not be * called to give the caller a * chance to update or cancel @@ -178,7 +179,8 @@ struct osc_device { static inline struct osc_device *obd2osc_dev(const struct obd_device *d) { - return container_of_safe(d->obd_lu_dev, struct osc_device, od_cl.cd_lu_dev); + return container_of_safe(d->obd_lu_dev, struct osc_device, + od_cl.cd_lu_dev); } extern struct lu_kmem_descr osc_caches[]; diff --git a/fs/lustre/osc/osc_lock.c b/fs/lustre/osc/osc_lock.c index 612305a..65b734ea 100644 --- a/fs/lustre/osc/osc_lock.c +++ b/fs/lustre/osc/osc_lock.c @@ -212,12 +212,14 @@ static void osc_lock_lvb_update(const struct lu_env *env, if (size > dlmlock->l_policy_data.l_extent.end) size = dlmlock->l_policy_data.l_extent.end + 1; if (size >= oinfo->loi_kms) { - LDLM_DEBUG(dlmlock, "lock acquired, setting rss=%llu, kms=%llu", + LDLM_DEBUG(dlmlock, + "lock acquired, setting rss=%llu, kms=%llu", lvb->lvb_size, size); valid |= CAT_KMS; attr->cat_kms = size; } else { - LDLM_DEBUG(dlmlock, "lock acquired, setting rss=%llu; leaving kms=%llu, end=%llu", + LDLM_DEBUG(dlmlock, + "lock acquired, setting rss=%llu; leaving kms=%llu, end=%llu", lvb->lvb_size, oinfo->loi_kms, dlmlock->l_policy_data.l_extent.end); } diff --git a/fs/lustre/osc/osc_object.c b/fs/lustre/osc/osc_object.c index 98a0b6c..7468729 100644 --- a/fs/lustre/osc/osc_object.c +++ b/fs/lustre/osc/osc_object.c @@ -125,7 +125,8 @@ static void osc_object_free(const struct lu_env *env, struct lu_object *obj) int osc_lvb_print(const struct lu_env *env, void *cookie, lu_printer_t p, const struct ost_lvb *lvb) { - return (*p)(env, cookie, "size: %llu mtime: %llu atime: %llu ctime: %llu blocks: %llu", + return (*p)(env, cookie, + "size: %llu mtime: %llu atime: %llu ctime: %llu blocks: %llu", lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime, lvb->lvb_ctime, lvb->lvb_blocks); } @@ -137,7 +138,8 @@ static int osc_object_print(const struct lu_env *env, void *cookie, struct lov_oinfo *oinfo = osc->oo_oinfo; struct osc_async_rc *ar = &oinfo->loi_ar; - (*p)(env, cookie, "id: " DOSTID " idx: %d gen: %d kms_valid: %u kms %llu rc: %d force_sync: %d min_xid: %llu ", + (*p)(env, cookie, + "id: " DOSTID " idx: %d gen: %d kms_valid: %u kms %llu rc: %d force_sync: %d min_xid: %llu ", POSTID(&oinfo->loi_oi), oinfo->loi_ost_idx, oinfo->loi_ost_gen, oinfo->loi_kms_valid, oinfo->loi_kms, ar->ar_rc, ar->ar_force_sync, ar->ar_min_xid); diff --git a/fs/lustre/osc/osc_page.c b/fs/lustre/osc/osc_page.c index ce911b8..8d541df 100644 --- a/fs/lustre/osc/osc_page.c +++ b/fs/lustre/osc/osc_page.c @@ -284,7 +284,8 @@ void osc_page_submit(const struct lu_env *env, struct osc_page *opg, { struct osc_async_page *oap = &opg->ops_oap; - LASSERTF(oap->oap_magic == OAP_MAGIC, "Bad oap magic: oap %p, magic 0x%x\n", + LASSERTF(oap->oap_magic == OAP_MAGIC, + "Bad oap magic: oap %p, magic 0x%x\n", oap, oap->oap_magic); LASSERT(oap->oap_async_flags & ASYNC_READY); LASSERT(oap->oap_async_flags & ASYNC_COUNT_STABLE); diff --git a/fs/lustre/osc/osc_quota.c b/fs/lustre/osc/osc_quota.c index 555f1be..5fa85c6 100644 --- a/fs/lustre/osc/osc_quota.c +++ b/fs/lustre/osc/osc_quota.c @@ -52,8 +52,8 @@ int osc_quota_chkdq(struct client_obd *cli, const unsigned int qid[]) for (type = 0; type < MAXQUOTAS; type++) { struct osc_quota_info *oqi; - oqi = rhashtable_lookup_fast(&cli->cl_quota_hash[type], &qid[type], - quota_hash_params); + oqi = rhashtable_lookup_fast(&cli->cl_quota_hash[type], + &qid[type], quota_hash_params); if (oqi) { /* Must not access oqi here, it could have been * freed by osc_quota_setdq() @@ -73,7 +73,8 @@ int osc_quota_chkdq(struct client_obd *cli, const unsigned int qid[]) static void osc_quota_free(struct rcu_head *head) { - struct osc_quota_info *oqi = container_of(head, struct osc_quota_info, rcu); + struct osc_quota_info *oqi = container_of(head, struct osc_quota_info, + rcu); kmem_cache_free(osc_quota_kmem, oqi); } @@ -123,8 +124,8 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], /* lookup the ID in the per-type hash table */ rcu_read_lock(); - oqi = rhashtable_lookup_fast(&cli->cl_quota_hash[type], &qid[type], - quota_hash_params); + oqi = rhashtable_lookup_fast(&cli->cl_quota_hash[type], + &qid[type], quota_hash_params); if ((flags & fl_quota_flag(type)) != 0) { /* This ID is getting close to its quota limit, let's * switch to sync I/O @@ -140,7 +141,8 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], } rc = rhashtable_lookup_insert_fast(&cli->cl_quota_hash[type], - &oqi->oqi_hash, quota_hash_params); + &oqi->oqi_hash, + quota_hash_params); /* race with others? */ if (rc) { kmem_cache_free(osc_quota_kmem, oqi); @@ -162,7 +164,8 @@ int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], continue; } if (rhashtable_remove_fast(&cli->cl_quota_hash[type], - &oqi->oqi_hash, quota_hash_params) == 0) + &oqi->oqi_hash, + quota_hash_params) == 0) call_rcu(&oqi->rcu, osc_quota_free); rcu_read_unlock(); CDEBUG(D_QUOTA, "%s: setdq to remove for %s %d (%p)\n", @@ -187,7 +190,8 @@ int osc_quota_setup(struct obd_device *obd) int i, type; for (type = 0; type < MAXQUOTAS; type++) { - if (rhashtable_init(&cli->cl_quota_hash[type], "a_hash_params) != 0) + if (rhashtable_init(&cli->cl_quota_hash[type], + "a_hash_params) != 0) break; } diff --git a/fs/lustre/osc/osc_request.c b/fs/lustre/osc/osc_request.c index 9484b9a..a64b8ab 100644 --- a/fs/lustre/osc/osc_request.c +++ b/fs/lustre/osc/osc_request.c @@ -1413,32 +1413,26 @@ static int check_write_checksum(struct obdo *oa, aa->aa_ppga, OST_WRITE, cksum_type); if (cksum_type != cksum_type_unpack(aa->aa_oa->o_flags)) - msg = "the server did not use the checksum type specified in the original request - likely a protocol problem" - ; + msg = "the server did not use the checksum type specified in the original request - likely a protocol problem"; else if (new_cksum == server_cksum) - msg = "changed on the client after we checksummed it - likely false positive due to mmap IO (bug 11742)" - ; + msg = "changed on the client after we checksummed it - likely false positive due to mmap IO (bug 11742)"; else if (new_cksum == client_cksum) msg = "changed in transit before arrival at OST"; else - msg = "changed in transit AND doesn't match the original - likely false positive due to mmap IO (bug 11742)" - ; - - LCONSOLE_ERROR_MSG( - 0x132, - "%s: BAD WRITE CHECKSUM: %s: from %s inode " DFID - " object " DOSTID - " extent [%llu-%llu], original client csum %x (type %x), server csum %x (type %x), client csum now %x\n", - aa->aa_cli->cl_import->imp_obd->obd_name, - msg, libcfs_nid2str(peer->nid), - oa->o_valid & OBD_MD_FLFID ? oa->o_parent_seq : (u64)0, - oa->o_valid & OBD_MD_FLFID ? oa->o_parent_oid : 0, - oa->o_valid & OBD_MD_FLFID ? oa->o_parent_ver : 0, - POSTID(&oa->o_oi), aa->aa_ppga[0]->off, - aa->aa_ppga[aa->aa_page_count - 1]->off + - aa->aa_ppga[aa->aa_page_count - 1]->count - 1, - client_cksum, cksum_type_unpack(aa->aa_oa->o_flags), - server_cksum, cksum_type, new_cksum); + msg = "changed in transit AND doesn't match the original - likely false positive due to mmap IO (bug 11742)"; + + LCONSOLE_ERROR_MSG(0x132, + "%s: BAD WRITE CHECKSUM: %s: from %s inode " DFID " object " DOSTID " extent [%llu-%llu], original client csum %x (type %x), server csum %x (type %x), client csum now %x\n", + aa->aa_cli->cl_import->imp_obd->obd_name, + msg, libcfs_nid2str(peer->nid), + oa->o_valid & OBD_MD_FLFID ? oa->o_parent_seq : (u64)0, + oa->o_valid & OBD_MD_FLFID ? oa->o_parent_oid : 0, + oa->o_valid & OBD_MD_FLFID ? oa->o_parent_ver : 0, + POSTID(&oa->o_oi), aa->aa_ppga[0]->off, + aa->aa_ppga[aa->aa_page_count - 1]->off + + aa->aa_ppga[aa->aa_page_count - 1]->count - 1, + client_cksum, cksum_type_unpack(aa->aa_oa->o_flags), + server_cksum, cksum_type, new_cksum); return 1; } -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:52:17 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:52:17 -0400 Subject: [lustre-devel] [PATCH 10/11] lustre: ldlm: checkpatch cleanup In-Reply-To: <1563760338-806-1-git-send-email-jsimmons@infradead.org> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563760338-806-11-git-send-email-jsimmons@infradead.org> Many checkpatch errors exist in the ldlm layer. This address a good chuck of them. Other are left since future patches will cleanup those areas. Others will need more code rework so this patch handles the simple cases. This is a good step forward toward proper kernel code style compliance. Signed-off-by: James Simmons --- fs/lustre/ldlm/ldlm_extent.c | 1 - fs/lustre/ldlm/ldlm_flock.c | 15 ++++++++------- fs/lustre/ldlm/ldlm_internal.h | 5 +++-- fs/lustre/ldlm/ldlm_lib.c | 4 ++-- fs/lustre/ldlm/ldlm_lock.c | 8 +++----- fs/lustre/ldlm/ldlm_lockd.c | 22 +++++++++++++--------- fs/lustre/ldlm/ldlm_pool.c | 3 ++- fs/lustre/ldlm/ldlm_request.c | 18 ++++++++---------- 8 files changed, 39 insertions(+), 37 deletions(-) diff --git a/fs/lustre/ldlm/ldlm_extent.c b/fs/lustre/ldlm/ldlm_extent.c index 99aef0b..0695f7e 100644 --- a/fs/lustre/ldlm/ldlm_extent.c +++ b/fs/lustre/ldlm/ldlm_extent.c @@ -79,7 +79,6 @@ u64 ldlm_extent_shift_kms(struct ldlm_lock *lock, u64 old_kms) ldlm_set_kms_ignore(lock); list_for_each_entry(lck, &res->lr_granted, l_res_link) { - if (ldlm_is_kms_ignore(lck)) continue; diff --git a/fs/lustre/ldlm/ldlm_flock.c b/fs/lustre/ldlm/ldlm_flock.c index 4316b2b..d2b4f0d 100644 --- a/fs/lustre/ldlm/ldlm_flock.c +++ b/fs/lustre/ldlm/ldlm_flock.c @@ -118,7 +118,7 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req) struct ldlm_lock *new2 = NULL; enum ldlm_mode mode = req->l_req_mode; int added = (mode == LCK_NL); - int splitted = 0; + int split = 0; const struct ldlm_callback_suite null_cbs = { }; CDEBUG(D_DLMTRACE, @@ -146,7 +146,6 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req) * We may have to merge or split existing locks. */ list_for_each_entry_safe_from(lock, tmp, &res->lr_granted, l_res_link) { - if (!ldlm_same_flock_owner(lock, new)) break; @@ -246,7 +245,7 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req) goto reprocess; } - splitted = 1; + split = 1; new2->l_granted_mode = lock->l_granted_mode; new2->l_policy_data.l_flock.pid = @@ -273,7 +272,7 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req) } /* if new2 is created but never used, destroy it*/ - if (splitted == 0 && new2) + if (split == 0 && new2) ldlm_lock_destroy_nolock(new2); /* At this point we're granting the lock request. */ @@ -345,12 +344,14 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req) "client-side enqueue returned a blocked lock, sleeping"); /* Go to sleep until the lock is granted. */ - rc = l_wait_event_abortable(lock->l_waitq, is_granted_or_cancelled(lock)); - + rc = l_wait_event_abortable(lock->l_waitq, + is_granted_or_cancelled(lock)); if (rc) { lock_res_and_lock(lock); - /* client side - set flag to prevent lock from being put on LRU list */ + /* client side - set flag to prevent lock from being put on + * LRU list + */ ldlm_set_cbpending(lock); unlock_res_and_lock(lock); diff --git a/fs/lustre/ldlm/ldlm_internal.h b/fs/lustre/ldlm/ldlm_internal.h index d8dcf8a..05d5b08 100644 --- a/fs/lustre/ldlm/ldlm_internal.h +++ b/fs/lustre/ldlm/ldlm_internal.h @@ -146,6 +146,7 @@ void ldlm_lock_addref_internal_nolock(struct ldlm_lock *lock, void ldlm_lock_decref_internal(struct ldlm_lock *lock, enum ldlm_mode mode); void ldlm_lock_decref_internal_nolock(struct ldlm_lock *lock, enum ldlm_mode mode); +struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock); int ldlm_run_ast_work(struct ldlm_namespace *ns, struct list_head *rpc_list, enum ldlm_desc_ast_t ast_type); int ldlm_lock_remove_from_lru_check(struct ldlm_lock *lock, time_t last_use); @@ -212,8 +213,8 @@ enum ldlm_policy_res { #define LDLM_POOL_SYSFS_SET_int(a, b) { a = b; } #define LDLM_POOL_SYSFS_PRINT_u64(v) sprintf(buf, "%lld\n", v) #define LDLM_POOL_SYSFS_SET_u64(a, b) { a = b; } -#define LDLM_POOL_SYSFS_PRINT_atomic(v) sprintf(buf, "%d\n", atomic_read(&v)) -#define LDLM_POOL_SYSFS_SET_atomic(a, b) atomic_set(&a, b) +#define LDLM_POOL_SYSFS_PRINT_atomic(v) sprintf(buf, "%d\n", atomic_read(&(v))) +#define LDLM_POOL_SYSFS_SET_atomic(a, b) atomic_set(&(a), b) #define LDLM_POOL_SYSFS_READER_SHOW(var, type) \ static ssize_t var##_show(struct kobject *kobj, \ diff --git a/fs/lustre/ldlm/ldlm_lib.c b/fs/lustre/ldlm/ldlm_lib.c index 9c61b33..887507d 100644 --- a/fs/lustre/ldlm/ldlm_lib.c +++ b/fs/lustre/ldlm/ldlm_lib.c @@ -832,9 +832,9 @@ int ldlm_error2errno(enum ldlm_error error) result = -EBADF; break; default: - if (((int)error) < 0) /* cast to signed type */ + if (((int)error) < 0) { /* cast to signed type */ result = error; /* as enum ldlm_error can be unsigned */ - else { + } else { CERROR("Invalid DLM result code: %d\n", error); result = -EPROTO; } diff --git a/fs/lustre/ldlm/ldlm_lock.c b/fs/lustre/ldlm/ldlm_lock.c index 7ec5fc9..2f2b1ab 100644 --- a/fs/lustre/ldlm/ldlm_lock.c +++ b/fs/lustre/ldlm/ldlm_lock.c @@ -874,7 +874,6 @@ static void search_granted_lock(struct list_head *queue, struct ldlm_lock *lock, *mode_end, *policy_end; list_for_each_entry(lock, queue, l_res_link) { - mode_end = list_prev_entry(lock, l_sl_mode); if (lock->l_req_mode != req->l_req_mode) { @@ -1354,8 +1353,7 @@ enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, u64 flags, /* check user's security context */ if (lock->l_conn_export && - sptlrpc_import_check_ctx( - class_exp2cliimp(lock->l_conn_export))) { + sptlrpc_import_check_ctx(class_exp2cliimp(lock->l_conn_export))) { if (!(flags & LDLM_FL_TEST_LOCK)) ldlm_lock_decref_internal(lock, mode); rc = 0; @@ -1443,7 +1441,7 @@ int ldlm_fill_lvb(struct ldlm_lock *lock, struct req_capsule *pill, if (loc == RCL_CLIENT) lvb = req_capsule_client_swab_get(pill, &RMF_DLM_LVB, - lustre_swab_ost_lvb_v1); + lustre_swab_ost_lvb_v1); else lvb = req_capsule_server_sized_swab_get(pill, &RMF_DLM_LVB, size, @@ -1744,7 +1742,7 @@ static int ldlm_work_gl_ast_lock(struct ptlrpc_request_set *rqset, void *opaq) return -ENOENT; gl_work = list_first_entry(arg->list, struct ldlm_glimpse_work, - gl_list); + gl_list); list_del_init(&gl_work->gl_list); lock = gl_work->gl_lock; diff --git a/fs/lustre/ldlm/ldlm_lockd.c b/fs/lustre/ldlm/ldlm_lockd.c index 589b89d..56f042c 100644 --- a/fs/lustre/ldlm/ldlm_lockd.c +++ b/fs/lustre/ldlm/ldlm_lockd.c @@ -210,9 +210,9 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req, if (lock->l_resource->lr_type != LDLM_PLAIN) { ldlm_convert_policy_to_local(req->rq_export, - dlm_req->lock_desc.l_resource.lr_type, - &dlm_req->lock_desc.l_policy_data, - &lock->l_policy_data); + dlm_req->lock_desc.l_resource.lr_type, + &dlm_req->lock_desc.l_policy_data, + &lock->l_policy_data); LDLM_DEBUG(lock, "completion AST, new policy data"); } @@ -222,7 +222,7 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req, sizeof(lock->l_resource->lr_name)) != 0) { unlock_res_and_lock(lock); rc = ldlm_lock_change_resource(ns, lock, - &dlm_req->lock_desc.l_resource.lr_name); + &dlm_req->lock_desc.l_resource.lr_name); if (rc < 0) { LDLM_ERROR(lock, "Failed to allocate resource"); goto out; @@ -286,7 +286,7 @@ static void ldlm_handle_gl_callback(struct ptlrpc_request *req, struct ldlm_request *dlm_req, struct ldlm_lock *lock) { - int rc = -ENOSYS; + int rc = -ENXIO; LDLM_DEBUG(lock, "client glimpse AST callback handler"); @@ -396,8 +396,10 @@ static int ldlm_bl_to_thread(struct ldlm_namespace *ns, struct list_head *cancels, int count, enum ldlm_cancel_flags cancel_flags) { + int rc = 0; + if (cancels && count == 0) - return 0; + return rc; if (cancel_flags & LCF_ASYNC) { struct ldlm_bl_work_item *blwi; @@ -407,7 +409,7 @@ static int ldlm_bl_to_thread(struct ldlm_namespace *ns, return -ENOMEM; init_blwi(blwi, ns, ld, cancels, count, lock, cancel_flags); - return __ldlm_bl_to_thread(blwi, cancel_flags); + rc = __ldlm_bl_to_thread(blwi, cancel_flags); } else { /* if it is synchronous call do minimum mem alloc, as it could * be triggered from kernel shrinker @@ -416,8 +418,9 @@ static int ldlm_bl_to_thread(struct ldlm_namespace *ns, memset(&blwi, 0, sizeof(blwi)); init_blwi(&blwi, ns, ld, cancels, count, lock, cancel_flags); - return __ldlm_bl_to_thread(&blwi, cancel_flags); + rc = __ldlm_bl_to_thread(&blwi, cancel_flags); } + return rc; } int ldlm_bl_to_thread_lock(struct ldlm_namespace *ns, struct ldlm_lock_desc *ld, @@ -446,7 +449,7 @@ static int ldlm_handle_setinfo(struct ptlrpc_request *req) char *key; void *val; int keylen, vallen; - int rc = -ENOSYS; + int rc = -ENXIO; DEBUG_REQ(D_HSM, req, "%s: handle setinfo\n", obd->obd_name); @@ -875,6 +878,7 @@ int ldlm_get_ref(void) void ldlm_put_ref(void) { int rc = 0; + mutex_lock(&ldlm_ref_mutex); if (ldlm_refcount == 1) { rc = ldlm_cleanup(); diff --git a/fs/lustre/ldlm/ldlm_pool.c b/fs/lustre/ldlm/ldlm_pool.c index 1f81795..6714c30 100644 --- a/fs/lustre/ldlm/ldlm_pool.c +++ b/fs/lustre/ldlm/ldlm_pool.c @@ -360,7 +360,8 @@ static int ldlm_pool_recalc(struct ldlm_pool *pl) recalc_interval_sec = ktime_get_real_seconds() - pl->pl_recalc_time; if (recalc_interval_sec > 0) { spin_lock(&pl->pl_lock); - recalc_interval_sec = ktime_get_real_seconds() - pl->pl_recalc_time; + recalc_interval_sec = ktime_get_real_seconds() - + pl->pl_recalc_time; if (recalc_interval_sec > 0) { /* diff --git a/fs/lustre/ldlm/ldlm_request.c b/fs/lustre/ldlm/ldlm_request.c index a614d74..b7dcfda 100644 --- a/fs/lustre/ldlm/ldlm_request.c +++ b/fs/lustre/ldlm/ldlm_request.c @@ -438,7 +438,7 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, PLDLMRES(lock->l_resource)); rc = ldlm_lock_change_resource(ns, lock, - &reply->lock_desc.l_resource.lr_name); + &reply->lock_desc.l_resource.lr_name); if (rc || !lock->l_resource) { rc = -ENOMEM; goto cleanup; @@ -450,9 +450,9 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, !(exp_connect_flags(exp) & OBD_CONNECT_IBITS))) /* We assume lock type cannot change on server*/ ldlm_convert_policy_to_local(exp, - lock->l_resource->lr_type, - &reply->lock_desc.l_policy_data, - &lock->l_policy_data); + lock->l_resource->lr_type, + &reply->lock_desc.l_policy_data, + &lock->l_policy_data); if (type != LDLM_PLAIN) LDLM_DEBUG(lock, "client-side enqueue, new policy data"); @@ -927,8 +927,7 @@ static int ldlm_cli_cancel_req(struct obd_export *exp, if (rc == LUSTRE_ESTALE) { CDEBUG(D_DLMTRACE, "client/server (nid %s) out of sync -- not fatal\n", - libcfs_nid2str(req->rq_import-> - imp_connection->c_peer.nid)); + libcfs_nid2str(req->rq_import->imp_connection->c_peer.nid)); rc = 0; } else if (rc == -ETIMEDOUT && /* check there was no reconnect*/ req->rq_import_generation == imp->imp_generation) { @@ -1290,10 +1289,9 @@ static enum ldlm_policy_res ldlm_cancel_aged_policy(struct ldlm_namespace *ns, LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK; } -typedef enum ldlm_policy_res (*ldlm_cancel_lru_policy_t)( - struct ldlm_namespace *, - struct ldlm_lock *, int, - int, int); +typedef enum ldlm_policy_res (*ldlm_cancel_lru_policy_t)(struct ldlm_namespace *, + struct ldlm_lock *, + int, int, int); static ldlm_cancel_lru_policy_t ldlm_cancel_lru_policy(struct ldlm_namespace *ns, int lru_flags) -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:52:18 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:52:18 -0400 Subject: [lustre-devel] [PATCH 11/11] lustre: internal headers checkpatch cleanup In-Reply-To: <1563760338-806-1-git-send-email-jsimmons@infradead.org> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563760338-806-12-git-send-email-jsimmons@infradead.org> Many checkpatch errors exist in the headers. This address a good chuck of them. Other are left since future patches will cleanup those areas. Others will need more code rework so this patch handles the simple cases. This is a good step forward toward proper kernel code style compliance. Signed-off-by: James Simmons --- fs/lustre/include/cl_object.h | 13 +++++----- fs/lustre/include/lprocfs_status.h | 11 ++++---- fs/lustre/include/lu_object.h | 26 ++++++++++--------- fs/lustre/include/lustre_acl.h | 4 +-- fs/lustre/include/lustre_dlm.h | 53 +++++++++++++++++++++++--------------- fs/lustre/include/seq_range.h | 8 +++--- 6 files changed, 65 insertions(+), 50 deletions(-) diff --git a/fs/lustre/include/cl_object.h b/fs/lustre/include/cl_object.h index 691c2f5..be30ce8 100644 --- a/fs/lustre/include/cl_object.h +++ b/fs/lustre/include/cl_object.h @@ -987,8 +987,9 @@ struct cl_page_operations { /** * Helper macro, dumping detailed information about @page into a log. */ -#define CL_PAGE_DEBUG(mask, env, page, format, ...) \ +#define CL_PAGE_DEBUG(_mask, env, page, format, ...) \ do { \ + typeof(_mask) (mask) = (_mask); \ if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \ LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \ cl_page_print(env, &msgdata, lu_cdebug_printer, page); \ @@ -999,8 +1000,9 @@ struct cl_page_operations { /** * Helper macro, dumping shorter information about @page into a log. */ -#define CL_PAGE_HEADER(mask, env, page, format, ...) \ +#define CL_PAGE_HEADER(_mask, env, page, format, ...) \ do { \ + typeof(_mask) (mask) = (_mask); \ if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \ LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \ cl_page_header_print(env, &msgdata, lu_cdebug_printer, page); \ @@ -1163,9 +1165,6 @@ struct cl_lock_descr { }; #define DDESCR "%s(%d):[%lu, %lu]:%x" -#define PDESCR(descr) \ - cl_lock_mode_name((descr)->cld_mode), (descr)->cld_mode, \ - (descr)->cld_start, (descr)->cld_end, (descr)->cld_enq_flags const char *cl_lock_mode_name(const enum cl_lock_mode mode); @@ -1237,8 +1236,9 @@ struct cl_lock_operations { const struct cl_lock_slice *slice); }; -#define CL_LOCK_DEBUG(mask, env, lock, format, ...) \ +#define CL_LOCK_DEBUG(_mask, env, lock, format, ...) \ do { \ + typeof(_mask) (mask) = (_mask); \ LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \ \ if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \ @@ -1657,6 +1657,7 @@ struct cl_io_lock_link { void (*cill_fini)(const struct lu_env *env, struct cl_io_lock_link *link); }; + #define cill_descr cill_lock.cll_descr /** diff --git a/fs/lustre/include/lprocfs_status.h b/fs/lustre/include/lprocfs_status.h index 8565c28..815ca37 100644 --- a/fs/lustre/include/lprocfs_status.h +++ b/fs/lustre/include/lprocfs_status.h @@ -435,11 +435,11 @@ void lprocfs_stats_unlock(struct lprocfs_stats *stats, lprocfs_counter_sub(stats, idx, 1) s64 lprocfs_read_helper(struct lprocfs_counter *lc, - struct lprocfs_counter_header *header, - enum lprocfs_stats_flags flags, - enum lprocfs_fields_flags field); + struct lprocfs_counter_header *header, + enum lprocfs_stats_flags flags, + enum lprocfs_fields_flags field); u64 lprocfs_stats_collector(struct lprocfs_stats *stats, int idx, - enum lprocfs_fields_flags field); + enum lprocfs_fields_flags field); extern struct lprocfs_stats * lprocfs_alloc_stats(unsigned int num, enum lprocfs_stats_flags flags); @@ -553,7 +553,8 @@ void lprocfs_stats_collect(struct lprocfs_stats *stats, int idx, { \ return lprocfs_wr_##type(file, buffer, count, off); \ } \ - static int name##_##type##_open(struct inode *inode, struct file *file) \ + static int name##_##type##_open(struct inode *inode, \ + struct file *file) \ { \ return single_open(file, NULL, inode->i_private); \ } \ diff --git a/fs/lustre/include/lu_object.h b/fs/lustre/include/lu_object.h index 8137628..05f8d81 100644 --- a/fs/lustre/include/lu_object.h +++ b/fs/lustre/include/lu_object.h @@ -142,10 +142,10 @@ struct lu_device_operations { /** * process config specific for device. */ - int (*ldo_process_config)(const struct lu_env *env, - struct lu_device *, struct lustre_cfg *); - int (*ldo_recovery_complete)(const struct lu_env *, - struct lu_device *); + int (*ldo_process_config)(const struct lu_env *env, struct lu_device *d, + struct lustre_cfg *cfg); + int (*ldo_recovery_complete)(const struct lu_env *env, + struct lu_device *dev); /** * initialize local objects for device. this method called after layer @@ -153,7 +153,7 @@ struct lu_device_operations { * serving user requests. */ - int (*ldo_prepare)(const struct lu_env *, + int (*ldo_prepare)(const struct lu_env *env, struct lu_device *parent, struct lu_device *dev); @@ -347,22 +347,22 @@ struct lu_device_type_operations { * lu_device_type_operations::ldto_device_alloc(). Returns pointer to * the next device in the stack. */ - struct lu_device *(*ldto_device_free)(const struct lu_env *, - struct lu_device *); + struct lu_device *(*ldto_device_free)(const struct lu_env *env, + struct lu_device *dev); /** * Initialize the devices after allocation */ int (*ldto_device_init)(const struct lu_env *env, - struct lu_device *, const char *, - struct lu_device *); + struct lu_device *dev, const char *name, + struct lu_device *next); /** * Finalize device. Dual to * lu_device_type_operations::ldto_device_init(). Returns pointer to * the next device in the stack. */ struct lu_device *(*ldto_device_fini)(const struct lu_env *env, - struct lu_device *); + struct lu_device *dev); /** * Initialize device type. This is called on module load. */ @@ -753,8 +753,9 @@ int lu_cdebug_printer(const struct lu_env *env, /** * Print object description followed by a user-supplied message. */ -#define LU_OBJECT_DEBUG(mask, env, object, format, ...) \ +#define LU_OBJECT_DEBUG(_mask, env, object, format, ...) \ do { \ + typeof(_mask) (mask) = (_mask); \ if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \ LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \ lu_object_print(env, &msgdata, lu_cdebug_printer, object);\ @@ -765,8 +766,9 @@ int lu_cdebug_printer(const struct lu_env *env, /** * Print short object description followed by a user-supplied message. */ -#define LU_OBJECT_HEADER(mask, env, object, format, ...) \ +#define LU_OBJECT_HEADER(_mask, env, object, format, ...) \ do { \ + typeof(_mask) (mask) = (_mask); \ if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \ LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \ lu_object_header_print(env, &msgdata, lu_cdebug_printer,\ diff --git a/fs/lustre/include/lustre_acl.h b/fs/lustre/include/lustre_acl.h index e7575a1..aff77b0 100644 --- a/fs/lustre/include/lustre_acl.h +++ b/fs/lustre/include/lustre_acl.h @@ -40,8 +40,8 @@ #include #define LUSTRE_POSIX_ACL_MAX_ENTRIES 32 -#define LUSTRE_POSIX_ACL_MAX_SIZE_OLD \ - (sizeof(struct posix_acl_xattr_header) + \ +#define LUSTRE_POSIX_ACL_MAX_SIZE_OLD \ + (sizeof(struct posix_acl_xattr_header) + \ LUSTRE_POSIX_ACL_MAX_ENTRIES * sizeof(struct posix_acl_xattr_entry)) #else /* ! CONFIG_FS_POSIX_ACL */ diff --git a/fs/lustre/include/lustre_dlm.h b/fs/lustre/include/lustre_dlm.h index 1bd5119..a1ff852 100644 --- a/fs/lustre/include/lustre_dlm.h +++ b/fs/lustre/include/lustre_dlm.h @@ -165,10 +165,9 @@ static inline int lockmode_compat(enum ldlm_mode exist_mode, #define DLM_MDS_NAMESPACE 2 /* XXX - - do we just separate this by security domains and use a prefix for - multiple namespaces in the same domain? - - -*/ + * - do we just separate this by security domains and use a prefix for + * multiple namespaces in the same domain? + */ /** * Locking rules for LDLM: @@ -444,7 +443,7 @@ struct ldlm_namespace { enum ldlm_appetite ns_appetite; /** Limit of parallel AST RPC count. */ - unsigned ns_max_parallel_ast; + unsigned int ns_max_parallel_ast; /** * Callback to check if a lock is good to be canceled by ELC or @@ -845,8 +844,10 @@ struct ldlm_resource { */ struct ldlm_interval_tree *lr_itree; - /** Type of locks this resource can hold. Only one type per resource. */ - enum ldlm_type lr_type; /* LDLM_{PLAIN,EXTENT,FLOCK,IBITS} */ + /** Type of locks this resource can hold. Only one type per resource. + * LDLM_{PLAIN,EXTENT,FLOCK,IBITS} + */ + enum ldlm_type lr_type; /** * Server-side-only lock value block elements. @@ -944,13 +945,20 @@ struct ldlm_ast_work { * Common ldlm_enqueue parameters */ struct ldlm_enqueue_info { - enum ldlm_type ei_type; /** Type of the lock being enqueued. */ - enum ldlm_mode ei_mode; /** Mode of the lock being enqueued. */ - void *ei_cb_bl; /** blocking lock callback */ - void *ei_cb_cp; /** lock completion callback */ - void *ei_cb_gl; /** lock glimpse callback */ - void *ei_cbdata; /** Data to be passed into callbacks. */ - unsigned int ei_enq_slave:1; /* whether enqueue slave stripes */ + /* Type of the lock being enqueued. */ + enum ldlm_type ei_type; + /* Mode of the lock being enqueued. */ + enum ldlm_mode ei_mode; + /* blocking lock callback */ + void *ei_cb_bl; + /* lock completion callback */ + void *ei_cb_cp; + /* lock glimpse callback */ + void *ei_cb_gl; + /* Data to be passed into callbacks. */ + void *ei_cbdata; + /* whether enqueue slave stripes */ + unsigned int ei_enq_slave:1; }; extern struct obd_ops ldlm_obd_ops; @@ -1027,7 +1035,8 @@ typedef int (*ldlm_processing_policy)(struct ldlm_lock *lock, u64 *flags, * namespace or every resource in a namespace. * @{ */ -int ldlm_resource_iterate(struct ldlm_namespace *, const struct ldlm_res_id *, +int ldlm_resource_iterate(struct ldlm_namespace *ns, + const struct ldlm_res_id *res_id, ldlm_iterator_t iter, void *data); /** @} ldlm_iterator */ @@ -1053,9 +1062,10 @@ struct ldlm_callback_suite { /* ldlm_lock.c */ void ldlm_lock2handle(const struct ldlm_lock *lock, struct lustre_handle *lockh); -struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *, u64 flags); -void ldlm_cancel_callback(struct ldlm_lock *); -int ldlm_lock_remove_from_lru(struct ldlm_lock *); +struct ldlm_lock *__ldlm_handle2lock(const struct lustre_handle *lh, + u64 flags); +void ldlm_cancel_callback(struct ldlm_lock *lock); +int ldlm_lock_remove_from_lru(struct ldlm_lock *lock); int ldlm_lock_set_data(const struct lustre_handle *lockh, void *data); /** @@ -1155,9 +1165,10 @@ void ldlm_lock_decref_and_cancel(const struct lustre_handle *lockh, void ldlm_lock_allow_match(struct ldlm_lock *lock); void ldlm_lock_allow_match_locked(struct ldlm_lock *lock); enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, u64 flags, - const struct ldlm_res_id *, - enum ldlm_type type, union ldlm_policy_data *, - enum ldlm_mode mode, struct lustre_handle *, + const struct ldlm_res_id *res_id, + enum ldlm_type type, + union ldlm_policy_data *policy, + enum ldlm_mode mode, struct lustre_handle *lh, int unref); enum ldlm_mode ldlm_revalidate_lock_handle(const struct lustre_handle *lockh, u64 *bits); diff --git a/fs/lustre/include/seq_range.h b/fs/lustre/include/seq_range.h index dbf73ea..ede0c4b 100644 --- a/fs/lustre/include/seq_range.h +++ b/fs/lustre/include/seq_range.h @@ -191,10 +191,10 @@ static inline int lu_seq_range_compare_loc(const struct lu_seq_range *r1, */ #define DRANGE "[%#16.16llx-%#16.16llx]:%x:%s" -#define PRANGE(range) \ - (range)->lsr_start, \ - (range)->lsr_end, \ - (range)->lsr_index, \ +#define PRANGE(range) \ + (range)->lsr_start, \ + (range)->lsr_end, \ + (range)->lsr_index, \ fld_range_is_mdt(range) ? "mdt" : "ost" #endif -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:52:13 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:52:13 -0400 Subject: [lustre-devel] [PATCH 06/11] lustre: mdc: checkpatch cleanup In-Reply-To: <1563760338-806-1-git-send-email-jsimmons@infradead.org> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563760338-806-7-git-send-email-jsimmons@infradead.org> Many checkpatch errors exist in the mdc layer. This address a good chuck of them. Other are left since future patches will cleanup those areas. Others will need more code rework so this patch handles the simple cases. This is a good step forward toward proper kernel code style compliance. Signed-off-by: James Simmons --- fs/lustre/mdc/mdc_changelog.c | 15 ++++++++++----- fs/lustre/mdc/mdc_lib.c | 15 ++++++++++----- fs/lustre/mdc/mdc_locks.c | 2 +- fs/lustre/mdc/mdc_request.c | 16 ++++++++++------ 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/fs/lustre/mdc/mdc_changelog.c b/fs/lustre/mdc/mdc_changelog.c index 45aef9c..011bcc9 100644 --- a/fs/lustre/mdc/mdc_changelog.c +++ b/fs/lustre/mdc/mdc_changelog.c @@ -112,7 +112,8 @@ enum { * @hdr: Header of the current llog record * @data: chlg_reader_state passed from caller * - * Returns: 0 or LLOG_PROC_* control code on success, negated error on failure. + * Returns: 0 or LLOG_PROC_* control code on success, + * negated error on failure. */ static int chlg_read_cat_process_cb(const struct lu_env *env, struct llog_handle *llh, @@ -276,7 +277,8 @@ static int chlg_load(void *args) * @ppos: File position, updated with the index number of the next * record to read. * - * Returns: number of copied bytes on success, negated error code on failure. + * Returns: number of copied bytes on success, + * negated error code on failure. */ static ssize_t chlg_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) @@ -377,7 +379,8 @@ static int chlg_set_start_offset(struct chlg_reader_state *crs, u64 offset) * @off: Offset to skip, actually a record index, not byte count * @whence: Relative/Absolute interpretation of the offset * - * Returns: the resulting position on success or negated error code on failure. + * Returns: the resulting position on success or + * negated error code on failure. */ static loff_t chlg_llseek(struct file *file, loff_t off, int whence) { @@ -434,7 +437,8 @@ static int chlg_clear(struct chlg_reader_state *crs, u32 reader, u64 record) else ret = obd_set_info_async(NULL, obd->obd_self_export, strlen(KEY_CHANGELOG_CLEAR), - KEY_CHANGELOG_CLEAR, sizeof(cs), &cs, NULL); + KEY_CHANGELOG_CLEAR, sizeof(cs), + &cs, NULL); mutex_unlock(&chlg_registered_dev_lock); return ret; } @@ -451,7 +455,8 @@ static int chlg_clear(struct chlg_reader_state *crs, u32 reader, u64 record) * @count: Number of written bytes * @off: (unused) * - * Returns: number of written bytes on success, negated error code on failure. + * Returns: number of written bytes on success, + * negated error code on failure. */ static ssize_t chlg_write(struct file *file, const char __user *buff, size_t count, loff_t *off) diff --git a/fs/lustre/mdc/mdc_lib.c b/fs/lustre/mdc/mdc_lib.c index 7680346..6aa9dc2 100644 --- a/fs/lustre/mdc/mdc_lib.c +++ b/fs/lustre/mdc/mdc_lib.c @@ -157,7 +157,8 @@ void mdc_create_pack(struct ptlrpc_request *req, struct md_op_data *op_data, char *tmp; u64 flags; - BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != sizeof(struct mdt_rec_create)); + BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != + sizeof(struct mdt_rec_create)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); rec->cr_opcode = REINT_CREATE; @@ -225,7 +226,8 @@ void mdc_open_pack(struct ptlrpc_request *req, struct md_op_data *op_data, char *tmp; u64 cr_flags; - BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != sizeof(struct mdt_rec_create)); + BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != + sizeof(struct mdt_rec_create)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); /* XXX do something about time, uid, gid */ @@ -380,7 +382,8 @@ void mdc_unlink_pack(struct ptlrpc_request *req, struct md_op_data *op_data) { struct mdt_rec_unlink *rec; - BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != sizeof(struct mdt_rec_unlink)); + BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != + sizeof(struct mdt_rec_unlink)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); rec->ul_opcode = op_data->op_cli_flags & CLI_RM_ENTRY ? @@ -403,7 +406,8 @@ void mdc_link_pack(struct ptlrpc_request *req, struct md_op_data *op_data) { struct mdt_rec_link *rec; - BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != sizeof(struct mdt_rec_link)); + BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != + sizeof(struct mdt_rec_link)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); rec->lk_opcode = REINT_LINK; @@ -451,7 +455,8 @@ void mdc_rename_pack(struct ptlrpc_request *req, struct md_op_data *op_data, { struct mdt_rec_rename *rec; - BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != sizeof(struct mdt_rec_rename)); + BUILD_BUG_ON(sizeof(struct mdt_rec_reint) != + sizeof(struct mdt_rec_rename)); rec = req_capsule_client_get(&req->rq_pill, &RMF_REC_REINT); /* XXX do something about time, uid, gid */ diff --git a/fs/lustre/mdc/mdc_locks.c b/fs/lustre/mdc/mdc_locks.c index 430c422..4e6928e 100644 --- a/fs/lustre/mdc/mdc_locks.c +++ b/fs/lustre/mdc/mdc_locks.c @@ -630,7 +630,7 @@ static int mdc_finish_enqueue(struct obd_export *exp, mdc_set_open_replay_data(NULL, NULL, it); } - if ((body->mbo_valid & (OBD_MD_FLDIREA | OBD_MD_FLEASIZE)) != 0) { + if (body->mbo_valid & (OBD_MD_FLDIREA | OBD_MD_FLEASIZE)) { void *eadata; mdc_update_max_ea_from_body(exp, body); diff --git a/fs/lustre/mdc/mdc_request.c b/fs/lustre/mdc/mdc_request.c index 6f933b5..dd90e931 100644 --- a/fs/lustre/mdc/mdc_request.c +++ b/fs/lustre/mdc/mdc_request.c @@ -803,8 +803,8 @@ static int mdc_close(struct obd_export *exp, struct md_op_data *op_data, mod->mod_open_req->rq_replay = 0; spin_unlock(&mod->mod_open_req->rq_lock); } else { - CDEBUG(D_HA, - "couldn't find open req; expecting close error\n"); + CDEBUG(D_HA, + "couldn't find open req; expecting close error\n"); } if (!req) { /* @@ -1019,9 +1019,11 @@ static struct page *mdc_page_locate(struct address_space *mapping, u64 *hash, if (unlikely(*start == 1 && *hash == 0)) *hash = *start; else - LASSERTF(*start <= *hash, "start = %#llx,end = %#llx,hash = %#llx\n", + LASSERTF(*start <= *hash, + "start = %#llx,end = %#llx,hash = %#llx\n", *start, *end, *hash); - CDEBUG(D_VFSTRACE, "offset %lx [%#llx %#llx], hash %#llx\n", + CDEBUG(D_VFSTRACE, + "offset %lx [%#llx %#llx], hash %#llx\n", offset, *start, *end, *hash); if (*hash > *end) { kunmap(page); @@ -1258,7 +1260,8 @@ static int mdc_read_page_remote(void *data, struct page *page0) if (!ret) unlock_page(page); else - CDEBUG(D_VFSTRACE, "page %lu add to page cache failed: rc = %d\n", + CDEBUG(D_VFSTRACE, + "page %lu add to page cache failed: rc = %d\n", offset, ret); put_page(page); } @@ -1325,7 +1328,8 @@ static int mdc_read_page(struct obd_export *exp, struct md_op_data *op_data, page = mdc_page_locate(mapping, &rp_param.rp_off, &start, &end, rp_param.rp_hash64); if (IS_ERR(page)) { - CDEBUG(D_INFO, "%s: dir page locate: " DFID " at %llu: rc %ld\n", + CDEBUG(D_INFO, + "%s: dir page locate: " DFID " at %llu: rc %ld\n", exp->exp_obd->obd_name, PFID(&op_data->op_fid1), rp_param.rp_off, PTR_ERR(page)); rc = PTR_ERR(page); -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 01:52:16 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 21:52:16 -0400 Subject: [lustre-devel] [PATCH 09/11] lustre: obdclass: checkpatch cleanup In-Reply-To: <1563760338-806-1-git-send-email-jsimmons@infradead.org> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563760338-806-10-git-send-email-jsimmons@infradead.org> Many checkpatch errors exist in the obdclass layer. This address a good chuck of them. Other are left since future patches will cleanup those areas. Others will need more code rework so this patch handles the simple cases. This is a good step forward toward proper kernel code style compliance. Signed-off-by: James Simmons --- fs/lustre/obdclass/cl_io.c | 16 +++++++++++----- fs/lustre/obdclass/cl_lock.c | 8 ++++++-- fs/lustre/obdclass/cl_object.c | 12 ++++++------ fs/lustre/obdclass/cl_page.c | 9 +++++---- fs/lustre/obdclass/class_obd.c | 3 ++- fs/lustre/obdclass/genops.c | 9 ++++++--- fs/lustre/obdclass/llog.c | 3 ++- fs/lustre/obdclass/llog_obd.c | 8 ++++---- fs/lustre/obdclass/llog_swab.c | 6 ++++-- fs/lustre/obdclass/lprocfs_status.c | 4 ++-- fs/lustre/obdclass/lu_object.c | 3 ++- fs/lustre/obdclass/obd_config.c | 12 ++++++++---- fs/lustre/obdclass/obd_mount.c | 3 ++- fs/lustre/obdecho/debug.c | 12 ++++++++---- 14 files changed, 68 insertions(+), 40 deletions(-) diff --git a/fs/lustre/obdclass/cl_io.c b/fs/lustre/obdclass/cl_io.c index eef0dd8..1f1579b 100644 --- a/fs/lustre/obdclass/cl_io.c +++ b/fs/lustre/obdclass/cl_io.c @@ -217,11 +217,16 @@ int cl_io_rw_init(const struct lu_env *env, struct cl_io *io, static int cl_lock_descr_cmp(void *priv, struct list_head *a, struct list_head *b) { - const struct cl_io_lock_link *l0 = list_entry(a, struct cl_io_lock_link, cill_linkage); - const struct cl_io_lock_link *l1 = list_entry(b, struct cl_io_lock_link, cill_linkage); + const struct cl_io_lock_link *l0; + const struct cl_io_lock_link *l1; + const struct cl_lock_descr *d0; + const struct cl_lock_descr *d1; - const struct cl_lock_descr *d0 = &l0->cill_descr; - const struct cl_lock_descr *d1 = &l1->cill_descr; + l0 = list_entry(a, struct cl_io_lock_link, cill_linkage); + l1 = list_entry(b, struct cl_io_lock_link, cill_linkage); + + d0 = &l0->cill_descr; + d1 = &l1->cill_descr; return lu_fid_cmp(lu_object_fid(&d0->cld_obj->co_lu), lu_object_fid(&d1->cld_obj->co_lu)); @@ -334,7 +339,8 @@ void cl_io_unlock(const struct lu_env *env, struct cl_io *io) const struct cl_io_slice *scan; LASSERT(cl_io_is_loopable(io)); - LASSERT(CIS_IT_STARTED <= io->ci_state && io->ci_state < CIS_UNLOCKED); + LASSERT(CIS_IT_STARTED <= io->ci_state && + io->ci_state < CIS_UNLOCKED); LINVRNT(cl_io_invariant(io)); set = &io->ci_lockset; diff --git a/fs/lustre/obdclass/cl_lock.c b/fs/lustre/obdclass/cl_lock.c index 797302c..af88383 100644 --- a/fs/lustre/obdclass/cl_lock.c +++ b/fs/lustre/obdclass/cl_lock.c @@ -80,6 +80,7 @@ void cl_lock_slice_add(struct cl_lock *lock, struct cl_lock_slice *slice, void cl_lock_fini(const struct lu_env *env, struct cl_lock *lock) { struct cl_lock_slice *slice; + cl_lock_trace(D_DLMTRACE, env, "destroy lock", lock); while ((slice = list_first_entry_or_null(&lock->cll_layers, @@ -158,7 +159,7 @@ int cl_lock_enqueue(const struct lu_env *env, struct cl_io *io, struct cl_lock *lock, struct cl_sync_io *anchor) { const struct cl_lock_slice *slice; - int rc = -ENOSYS; + int rc = -EBUSY; list_for_each_entry(slice, &lock->cll_layers, cls_linkage) { if (!slice->cls_ops->clo_enqueue) @@ -246,7 +247,10 @@ void cl_lock_descr_print(const struct lu_env *env, void *cookie, const struct lu_fid *fid; fid = lu_object_fid(&descr->cld_obj->co_lu); - (*printer)(env, cookie, DDESCR "@" DFID, PDESCR(descr), PFID(fid)); + (*printer)(env, cookie, DDESCR "@" DFID, + cl_lock_mode_name(descr->cld_mode), descr->cld_mode, + descr->cld_start, descr->cld_end, descr->cld_enq_flags, + PFID(fid)); } EXPORT_SYMBOL(cl_lock_descr_print); diff --git a/fs/lustre/obdclass/cl_object.c b/fs/lustre/obdclass/cl_object.c index 6c084bc..b4ea585 100644 --- a/fs/lustre/obdclass/cl_object.c +++ b/fs/lustre/obdclass/cl_object.c @@ -427,7 +427,7 @@ static int cache_stats_print(const struct cache_stats *cs, seq_printf(m, "%6s", " "); for (i = 0; i < CS_NR; i++) seq_printf(m, "%8s", names[i]); - seq_printf(m, "\n"); + seq_puts(m, "\n"); } seq_printf(m, "%5.5s:", cs->cs_name); @@ -489,10 +489,10 @@ int cl_site_stats_print(const struct cl_site *site, struct seq_file *m) [CPS_FREEING] = "f" }; /* - lookup hit total busy create -pages: ...... ...... ...... ...... ...... [...... ...... ...... ......] -locks: ...... ...... ...... ...... ...... [...... ...... ...... ...... ......] - env: ...... ...... ...... ...... ...... + * lookup hit total busy create + * pages: ...... ...... ...... ...... ...... [..... ..... ..... .....] + * locks: ...... ...... ...... ...... ...... [..... ..... ..... ..... .....] + * env: ...... ...... ...... ...... ...... */ lu_site_stats_print(&site->cs_lu, m); cache_stats_print(&site->cs_pages, m, 1); @@ -722,7 +722,7 @@ unsigned int cl_env_cache_purge(unsigned int nr) for_each_possible_cpu(i) { write_lock(&cl_envs[i].cec_guard); - for (; nr >0 && + for (; nr > 0 && (cle = list_first_entry_or_null( &cl_envs[i].cec_envs, struct cl_env, diff --git a/fs/lustre/obdclass/cl_page.c b/fs/lustre/obdclass/cl_page.c index 349f19e..163f4de 100644 --- a/fs/lustre/obdclass/cl_page.c +++ b/fs/lustre/obdclass/cl_page.c @@ -148,8 +148,8 @@ struct cl_page *cl_page_alloc(const struct lu_env *env, lu_ref_init(&page->cp_reference); cl_object_for_each(o2, o) { if (o2->co_ops->coo_page_init) { - result = o2->co_ops->coo_page_init(env, o2, page, - ind); + result = o2->co_ops->coo_page_init(env, o2, + page, ind); if (result != 0) { __cl_page_delete(env, page); cl_page_free(env, page); @@ -418,8 +418,9 @@ int cl_page_is_owned(const struct cl_page *pg, const struct cl_io *io) * Return: 0 success * * -ve failure, e.g., page was destroyed (and landed in - * cl_page_state::CPS_FREEING instead of cl_page_state::CPS_CACHED). - * or, page was owned by another thread, or in IO. + * cl_page_state::CPS_FREEING instead of + * cl_page_state::CPS_CACHED). or, page was owned by + * another thread, or in IO. * * \see cl_page_disown() * \see cl_page_operations::cpo_own() diff --git a/fs/lustre/obdclass/class_obd.c b/fs/lustre/obdclass/class_obd.c index b8fc740..d8fc0db 100644 --- a/fs/lustre/obdclass/class_obd.c +++ b/fs/lustre/obdclass/class_obd.c @@ -364,7 +364,8 @@ int class_handle_ioctl(unsigned int cmd, unsigned long arg) * Today that information is in the sysfs tree so we can in the * future remove this. */ - BUILD_BUG_ON(OBD_OCD_VERSION(3, 0, 53, 0) <= LUSTRE_VERSION_CODE); + BUILD_BUG_ON(OBD_OCD_VERSION(3, 0, 53, 0) <= + LUSTRE_VERSION_CODE); if (!data->ioc_inlbuf1) { CERROR("No buffer passed in ioctl\n"); diff --git a/fs/lustre/obdclass/genops.c b/fs/lustre/obdclass/genops.c index 2d12717..9a9de35 100644 --- a/fs/lustre/obdclass/genops.c +++ b/fs/lustre/obdclass/genops.c @@ -74,7 +74,8 @@ static struct obd_device *obd_device_alloc(void) static void obd_device_free(struct obd_device *obd) { - LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC, "obd %p obd_magic %08x != %08x\n", + LASSERTF(obd->obd_magic == OBD_DEVICE_MAGIC, + "obd %p obd_magic %08x != %08x\n", obd, obd->obd_magic, OBD_DEVICE_MAGIC); if (obd->obd_namespace) { CERROR("obd %p: namespace %p was not properly cleaned up (obd_force=%d)!\n", @@ -801,7 +802,8 @@ void class_export_put(struct obd_export *exp) static void obd_zombie_exp_cull(struct work_struct *ws) { - struct obd_export *export = container_of(ws, struct obd_export, exp_zombie_work); + struct obd_export *export = container_of(ws, struct obd_export, + exp_zombie_work); class_export_destroy(export); } @@ -998,7 +1000,8 @@ static void init_imp_at(struct imp_at *at) static void obd_zombie_imp_cull(struct work_struct *ws) { - struct obd_import *import = container_of(ws, struct obd_import, imp_zombie_work); + struct obd_import *import = container_of(ws, struct obd_import, + imp_zombie_work); class_import_destroy(import); } diff --git a/fs/lustre/obdclass/llog.c b/fs/lustre/obdclass/llog.c index a34b1a7..e9a6514 100644 --- a/fs/lustre/obdclass/llog.c +++ b/fs/lustre/obdclass/llog.c @@ -327,7 +327,8 @@ static int llog_process_thread(void *arg) rc = 0; goto out; } - CDEBUG(D_OTHER, "Re-read last llog buffer for new records, index %u, last %u\n", + CDEBUG(D_OTHER, + "Re-read last llog buffer for new records, index %u, last %u\n", index, loghandle->lgh_last_idx); /* save offset inside buffer for the re-read */ buf_offset = (char *)rec - (char *)buf; diff --git a/fs/lustre/obdclass/llog_obd.c b/fs/lustre/obdclass/llog_obd.c index a89ec81..f652eed 100644 --- a/fs/lustre/obdclass/llog_obd.c +++ b/fs/lustre/obdclass/llog_obd.c @@ -127,7 +127,7 @@ int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt) rc, ctxt); l_wait_event_abortable(olg->olg_waitq, - llog_group_ctxt_null(olg, idx)); + llog_group_ctxt_null(olg, idx)); return rc; } @@ -165,9 +165,9 @@ int llog_setup(const struct lu_env *env, struct obd_device *obd, ctxt = llog_group_get_ctxt(olg, index); if (ctxt) { /* - * mds_lov_update_desc() might call here multiple - * times. So if the llog is already set up then - * don't to do it again. + * mds_lov_update_desc() might call here + * multiple times. So if the llog is already + * set up then don't to do it again. */ CDEBUG(D_CONFIG, "obd %s ctxt %d already set up\n", obd->obd_name, index); diff --git a/fs/lustre/obdclass/llog_swab.c b/fs/lustre/obdclass/llog_swab.c index 57dadec..49024fd 100644 --- a/fs/lustre/obdclass/llog_swab.c +++ b/fs/lustre/obdclass/llog_swab.c @@ -321,7 +321,8 @@ void print_lustre_cfg(struct lustre_cfg *lcfg) CDEBUG(D_OTHER, "\tlcfg->lcfg_command: %#x\n", lcfg->lcfg_command); CDEBUG(D_OTHER, "\tlcfg->lcfg_num: %#x\n", lcfg->lcfg_num); CDEBUG(D_OTHER, "\tlcfg->lcfg_flags: %#x\n", lcfg->lcfg_flags); - CDEBUG(D_OTHER, "\tlcfg->lcfg_nid: %s\n", libcfs_nid2str(lcfg->lcfg_nid)); + CDEBUG(D_OTHER, "\tlcfg->lcfg_nid: %s\n", + libcfs_nid2str(lcfg->lcfg_nid)); CDEBUG(D_OTHER, "\tlcfg->lcfg_bufcount: %d\n", lcfg->lcfg_bufcount); if (lcfg->lcfg_bufcount < LUSTRE_CFG_MAX_BUFCOUNT) @@ -407,7 +408,8 @@ void lustre_swab_cfg_marker(struct cfg_marker *marker, int swab, int size) } marker->cm_createtime = createtime; marker->cm_canceltime = canceltime; - CDEBUG(D_CONFIG, "Find old cfg_marker(Srv32b,Clt64b) for target %s, converting\n", + CDEBUG(D_CONFIG, + "Find old cfg_marker(Srv32b,Clt64b) for target %s, converting\n", marker->cm_tgtname); } else if (swab) { __swab64s(&marker->cm_createtime); diff --git a/fs/lustre/obdclass/lprocfs_status.c b/fs/lustre/obdclass/lprocfs_status.c index 71bf409..c5f5807 100644 --- a/fs/lustre/obdclass/lprocfs_status.c +++ b/fs/lustre/obdclass/lprocfs_status.c @@ -330,7 +330,6 @@ void ldebugfs_add_vars(struct dentry *parent, struct lprocfs_vars *list, list->fops ?: &lprocfs_generic_fops); list++; } - return; } EXPORT_SYMBOL_GPL(ldebugfs_add_vars); @@ -558,7 +557,8 @@ int lprocfs_rd_conn_uuid(struct seq_file *m, void *data) * @flags: CPU interrupt saved state for IRQ-safe locking * * Returns: cpuid of current thread or number of allocated structs - * negative on error (only for opc LPROCFS_GET_SMP_ID + per-CPU stats) + * negative on error (only for opc LPROCFS_GET_SMP_ID + + * per-CPU stats) */ int lprocfs_stats_lock(struct lprocfs_stats *stats, enum lprocfs_stats_lock_ops opc, diff --git a/fs/lustre/obdclass/lu_object.c b/fs/lustre/obdclass/lu_object.c index 6f778eb..4302482 100644 --- a/fs/lustre/obdclass/lu_object.c +++ b/fs/lustre/obdclass/lu_object.c @@ -498,7 +498,8 @@ struct lu_cdebug_data { .lct_tags = LCT_MD_THREAD | LCT_DT_THREAD | LCT_MG_THREAD | LCT_CL_THREAD | LCT_LOCAL, .lct_init = lu_global_key_init, - .lct_fini = lu_global_key_fini + .lct_fini = lu_global_key_fini, + .lct_owner = THIS_MODULE, }; /** diff --git a/fs/lustre/obdclass/obd_config.c b/fs/lustre/obdclass/obd_config.c index 0cdadea4..73264fd 100644 --- a/fs/lustre/obdclass/obd_config.c +++ b/fs/lustre/obdclass/obd_config.c @@ -509,7 +509,8 @@ static int class_cleanup(struct obd_device *obd, struct lustre_cfg *lcfg) obd->obd_name, err); /* destroy an uuid-export hash body */ - rhashtable_free_and_destroy(&obd->obd_uuid_hash, uuid_export_exit, NULL); + rhashtable_free_and_destroy(&obd->obd_uuid_hash, uuid_export_exit, + NULL); class_decref(obd, "setup", obd); obd->obd_set_up = 0; @@ -831,11 +832,13 @@ int class_process_config(struct lustre_cfg *lcfg) goto out; } case LCFG_ADD_UUID: { - CDEBUG(D_IOCTL, "adding mapping from uuid %s to nid %#llx (%s)\n", + CDEBUG(D_IOCTL, + "adding mapping from uuid %s to nid %#llx (%s)\n", lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid, libcfs_nid2str(lcfg->lcfg_nid)); - err = class_add_uuid(lustre_cfg_string(lcfg, 1), lcfg->lcfg_nid); + err = class_add_uuid(lustre_cfg_string(lcfg, 1), + lcfg->lcfg_nid); goto out; } case LCFG_DEL_UUID: { @@ -893,7 +896,8 @@ int class_process_config(struct lustre_cfg *lcfg) marker = lustre_cfg_buf(lcfg, 1); CDEBUG(D_IOCTL, "marker %d (%#x) %.16s %s\n", marker->cm_step, - marker->cm_flags, marker->cm_tgtname, marker->cm_comment); + marker->cm_flags, marker->cm_tgtname, + marker->cm_comment); err = 0; goto out; } diff --git a/fs/lustre/obdclass/obd_mount.c b/fs/lustre/obdclass/obd_mount.c index 104e64b..de81baa 100644 --- a/fs/lustre/obdclass/obd_mount.c +++ b/fs/lustre/obdclass/obd_mount.c @@ -1187,7 +1187,8 @@ int lmd_parse(char *options, struct lustre_mount_data *lmd) } if (!devname) { - LCONSOLE_ERROR_MSG(0x164, "Can't find the device name (need mount option 'device=...')\n"); + LCONSOLE_ERROR_MSG(0x164, + "Can't find the device name (need mount option 'device=...')\n"); goto invalid; } diff --git a/fs/lustre/obdecho/debug.c b/fs/lustre/obdecho/debug.c index 149aca5..a8f773a 100644 --- a/fs/lustre/obdecho/debug.c +++ b/fs/lustre/obdecho/debug.c @@ -68,24 +68,28 @@ int block_debug_check(char *who, void *addr, int end, u64 off, u64 id) ne_off = le64_to_cpu(off); id = le64_to_cpu(id); if (memcmp(addr, (char *)&ne_off, LPDS)) { - CDEBUG(D_ERROR, "%s: id %#llx offset %llu off: %#llx != %#llx\n", + CDEBUG(D_ERROR, + "%s: id %#llx offset %llu off: %#llx != %#llx\n", who, id, off, *(u64 *)addr, ne_off); err = -EINVAL; } if (memcmp(addr + LPDS, (char *)&id, LPDS)) { - CDEBUG(D_ERROR, "%s: id %#llx offset %llu id: %#llx != %#llx\n", + CDEBUG(D_ERROR, + "%s: id %#llx offset %llu id: %#llx != %#llx\n", who, id, off, *(u64 *)(addr + LPDS), id); err = -EINVAL; } addr += end - LPDS - LPDS; if (memcmp(addr, (char *)&ne_off, LPDS)) { - CDEBUG(D_ERROR, "%s: id %#llx offset %llu end off: %#llx != %#llx\n", + CDEBUG(D_ERROR, + "%s: id %#llx offset %llu end off: %#llx != %#llx\n", who, id, off, *(u64 *)addr, ne_off); err = -EINVAL; } if (memcmp(addr + LPDS, (char *)&id, LPDS)) { - CDEBUG(D_ERROR, "%s: id %#llx offset %llu end id: %#llx != %#llx\n", + CDEBUG(D_ERROR, + "%s: id %#llx offset %llu end id: %#llx != %#llx\n", who, id, off, *(u64 *)(addr + LPDS), id); err = -EINVAL; } -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 02:12:12 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 22:12:12 -0400 Subject: [lustre-devel] [PATCH 00/10] lustre: push patches ready from lustre-testing Message-ID: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> Several patches from lustre-testing have been reviewed and tested. They are ready to land to the main lustre branch. One patch in lustre-testing to remove set_cblist in ptlrpc has been replaced by a patch from John Hammond that removed even more. John L. Hammond (1): lustre: ptlrpc: simplify struct ptlrpc_request_set NeilBrown (9): lustre: ldlm: discard varname in ldlm_pool. lustre: lprocfs: use log2.h macros instead of shift loop. lustre: ptlrpc: make ptlrpc_bulk_frag_ops always const. lustre: mgc: remove llog_process_lock lustre: don't declare extern variables in C files. lnet: socklnd: fix infinite loop in ksocknal_push() lustre: ptlrpc: remove inline on non-inlined functions. lustre: convert rsi_sem to a spinlock. lustre: ptlrpc: make ptlrpc_last_xid an atomic64_t fs/lustre/include/lustre_net.h | 47 +------------------- fs/lustre/include/obd_class.h | 25 +---------- fs/lustre/ldlm/ldlm_internal.h | 2 - fs/lustre/ldlm/ldlm_pool.c | 18 +++----- fs/lustre/ldlm/ldlm_resource.c | 2 - fs/lustre/llite/llite_lib.c | 8 ++-- fs/lustre/llite/lproc_llite.c | 4 +- fs/lustre/lov/lov_obd.c | 85 ++++++++++++------------------------- fs/lustre/mgc/mgc_request.c | 6 +-- fs/lustre/obdclass/lprocfs_status.c | 18 +++----- fs/lustre/ptlrpc/client.c | 82 ++++++++++++++--------------------- fs/lustre/ptlrpc/import.c | 1 - fs/lustre/ptlrpc/ptlrpc_module.c | 5 --- net/lnet/klnds/socklnd/socklnd.c | 2 +- 14 files changed, 82 insertions(+), 223 deletions(-) -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 02:12:14 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 22:12:14 -0400 Subject: [lustre-devel] [PATCH 02/10] lustre: lprocfs: use log2.h macros instead of shift loop. In-Reply-To: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> References: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563761542-3708-3-git-send-email-jsimmons@infradead.org> From: NeilBrown These shift loops seem to be trying to avoid doing a multiplication. The same effect can be achieved more transparently using rounddown_pow_of_two(). Even though there is a multiplication in the C code, the resulting machine code just does a single shift. As rounddown_pow_of_two() is not defined for 0, and as we cannot be positively use the blk_size is non-zero, use blk_size ?: 1. Signed-off-by: NeilBrown WC-bug-id: https://jira.whamcloud.com/browse/LU-4423 Reviewed-on: https://review.whamcloud.com/35274 Reviewed-by: Petros Koutoupis Reviewed-by: Shaun Tancheff Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- fs/lustre/obdclass/lprocfs_status.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/fs/lustre/obdclass/lprocfs_status.c b/fs/lustre/obdclass/lprocfs_status.c index c5f5807..2b4302e 100644 --- a/fs/lustre/obdclass/lprocfs_status.c +++ b/fs/lustre/obdclass/lprocfs_status.c @@ -373,9 +373,7 @@ static ssize_t kbytestotal_show(struct kobject *kobj, struct attribute *attr, u32 blk_size = osfs.os_bsize >> 10; u64 result = osfs.os_blocks; - while (blk_size >>= 1) - result <<= 1; - + result *= rounddown_pow_of_two(blk_size ?: 1); return sprintf(buf, "%llu\n", result); } @@ -396,8 +394,7 @@ static ssize_t kbytesfree_show(struct kobject *kobj, struct attribute *attr, u32 blk_size = osfs.os_bsize >> 10; u64 result = osfs.os_bfree; - while (blk_size >>= 1) - result <<= 1; + result *= rounddown_pow_of_two(blk_size ?: 1); return sprintf(buf, "%llu\n", result); } @@ -419,8 +416,7 @@ static ssize_t kbytesavail_show(struct kobject *kobj, struct attribute *attr, u32 blk_size = osfs.os_bsize >> 10; u64 result = osfs.os_bavail; - while (blk_size >>= 1) - result <<= 1; + result *= rounddown_pow_of_two(blk_size ?: 1); return sprintf(buf, "%llu\n", result); } -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 02:12:17 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 22:12:17 -0400 Subject: [lustre-devel] [PATCH 05/10] lustre: don't declare extern variables in C files. In-Reply-To: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> References: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563761542-3708-6-git-send-email-jsimmons@infradead.org> From: NeilBrown 'extern' declarations should only appear in .h files. All these names are declared in .h files as needed, and these duplicate declarations in .c files can be removed. Signed-off-by: NeilBrown WC-bug-id: https://jira.whamcloud.com/browse/LU-4423 Reviewed-on: https://review.whamcloud.com/35294 Reviewed-by: Andreas Dilger Reviewed-by: Arshad Hussain Reviewed-by: Petros Koutoupis Signed-off-by: James Simmons --- fs/lustre/ldlm/ldlm_resource.c | 2 -- fs/lustre/ptlrpc/import.c | 1 - fs/lustre/ptlrpc/ptlrpc_module.c | 5 ----- 3 files changed, 8 deletions(-) diff --git a/fs/lustre/ldlm/ldlm_resource.c b/fs/lustre/ldlm/ldlm_resource.c index 45b2e97..372a290 100644 --- a/fs/lustre/ldlm/ldlm_resource.c +++ b/fs/lustre/ldlm/ldlm_resource.c @@ -681,8 +681,6 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name, } EXPORT_SYMBOL(ldlm_namespace_new); -extern struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock); - /** * Cancel and destroy all locks on a resource. * diff --git a/fs/lustre/ptlrpc/import.c b/fs/lustre/ptlrpc/import.c index d49707a..67a66a5 100644 --- a/fs/lustre/ptlrpc/import.c +++ b/fs/lustre/ptlrpc/import.c @@ -1572,7 +1572,6 @@ int ptlrpc_disconnect_import(struct obd_import *imp, int noclose) EXPORT_SYMBOL(ptlrpc_disconnect_import); /* Adaptive Timeout utils */ -extern unsigned int at_min, at_max, at_history; /* *Update at_current with the specified value (bounded by at_min and at_max), diff --git a/fs/lustre/ptlrpc/ptlrpc_module.c b/fs/lustre/ptlrpc/ptlrpc_module.c index f73ba41..6888df9 100644 --- a/fs/lustre/ptlrpc/ptlrpc_module.c +++ b/fs/lustre/ptlrpc/ptlrpc_module.c @@ -40,11 +40,6 @@ #include "ptlrpc_internal.h" -extern spinlock_t ptlrpc_last_xid_lock; -#if RS_DEBUG -extern spinlock_t ptlrpc_rs_debug_lock; -#endif - DEFINE_MUTEX(ptlrpc_startup); static int ptlrpc_active; -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 02:12:20 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 22:12:20 -0400 Subject: [lustre-devel] [PATCH 08/10] lustre: convert rsi_sem to a spinlock. In-Reply-To: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> References: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563761542-3708-9-git-send-email-jsimmons@infradead.org> From: NeilBrown This lock is never held over code that sleeps, and is only ever held for short periods of time. So a simple spinlock is best. Signed-off-by: NeilBrown WC-bug-id: https://jira.whamcloud.com/browse/LU-4423 Reviewed-on: https://review.whamcloud.com/35279 Reviewed-by: Andreas Dilger Signed-off-by: James Simmons --- fs/lustre/include/obd_class.h | 3 +-- fs/lustre/llite/llite_lib.c | 6 +++--- fs/lustre/llite/lproc_llite.c | 4 ++-- fs/lustre/obdclass/lprocfs_status.c | 8 ++++---- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/fs/lustre/include/obd_class.h b/fs/lustre/include/obd_class.h index 34a8511..2f02efe 100644 --- a/fs/lustre/include/obd_class.h +++ b/fs/lustre/include/obd_class.h @@ -1689,12 +1689,11 @@ static inline void class_uuid_unparse(class_uuid_t uu, struct obd_uuid *out) void statfs_unpack(struct kstatfs *sfs, struct obd_statfs *osfs); /* root squash info */ -struct rw_semaphore; struct root_squash_info { uid_t rsi_uid; gid_t rsi_gid; struct list_head rsi_nosquash_nids; - struct rw_semaphore rsi_sem; + spinlock_t rsi_lock; /* protects rsi_nosquash_nids */ }; /* linux-module.c */ diff --git a/fs/lustre/llite/llite_lib.c b/fs/lustre/llite/llite_lib.c index 4e09f0f..b933f37 100644 --- a/fs/lustre/llite/llite_lib.c +++ b/fs/lustre/llite/llite_lib.c @@ -131,7 +131,7 @@ static struct ll_sb_info *ll_init_sbi(void) sbi->ll_squash.rsi_uid = 0; sbi->ll_squash.rsi_gid = 0; INIT_LIST_HEAD(&sbi->ll_squash.rsi_nosquash_nids); - init_rwsem(&sbi->ll_squash.rsi_sem); + spin_lock_init(&sbi->ll_squash.rsi_lock); return sbi; } @@ -2578,7 +2578,7 @@ void ll_compute_rootsquash_state(struct ll_sb_info *sbi) int i; /* Update norootsquash flag */ - down_write(&squash->rsi_sem); + spin_lock(&squash->rsi_lock); if (list_empty(&squash->rsi_nosquash_nids)) { spin_lock(&sbi->ll_lock); sbi->ll_flags &= ~LL_SBI_NOROOTSQUASH; @@ -2606,7 +2606,7 @@ void ll_compute_rootsquash_state(struct ll_sb_info *sbi) sbi->ll_flags &= ~LL_SBI_NOROOTSQUASH; spin_unlock(&sbi->ll_lock); } - up_write(&squash->rsi_sem); + spin_unlock(&squash->rsi_lock); } /** diff --git a/fs/lustre/llite/lproc_llite.c b/fs/lustre/llite/lproc_llite.c index 99e8a82..69f4f25 100644 --- a/fs/lustre/llite/lproc_llite.c +++ b/fs/lustre/llite/lproc_llite.c @@ -1157,7 +1157,7 @@ static int ll_nosquash_nids_seq_show(struct seq_file *m, void *v) struct root_squash_info *squash = &sbi->ll_squash; int len; - down_read(&squash->rsi_sem); + spin_lock(&squash->rsi_lock); if (!list_empty(&squash->rsi_nosquash_nids)) { len = cfs_print_nidlist(m->buf + m->count, m->size - m->count, &squash->rsi_nosquash_nids); @@ -1166,7 +1166,7 @@ static int ll_nosquash_nids_seq_show(struct seq_file *m, void *v) } else { seq_puts(m, "NONE\n"); } - up_read(&squash->rsi_sem); + spin_unlock(&squash->rsi_lock); return 0; } diff --git a/fs/lustre/obdclass/lprocfs_status.c b/fs/lustre/obdclass/lprocfs_status.c index 2b4302e..01b8f90 100644 --- a/fs/lustre/obdclass/lprocfs_status.c +++ b/fs/lustre/obdclass/lprocfs_status.c @@ -1747,10 +1747,10 @@ int lprocfs_wr_nosquash_nids(const char __user *buffer, unsigned long count, if ((len == 4 && !strncmp(kernbuf, "NONE", len)) || (len == 5 && !strncmp(kernbuf, "clear", len))) { /* empty string is special case */ - down_write(&squash->rsi_sem); + spin_lock(&squash->rsi_lock); if (!list_empty(&squash->rsi_nosquash_nids)) cfs_free_nidlist(&squash->rsi_nosquash_nids); - up_write(&squash->rsi_sem); + spin_unlock(&squash->rsi_lock); LCONSOLE_INFO("%s: nosquash_nids is cleared\n", name); kfree(kernbuf); return count; @@ -1767,11 +1767,11 @@ int lprocfs_wr_nosquash_nids(const char __user *buffer, unsigned long count, kfree(kernbuf); kernbuf = NULL; - down_write(&squash->rsi_sem); + spin_lock(&squash->rsi_lock); if (!list_empty(&squash->rsi_nosquash_nids)) cfs_free_nidlist(&squash->rsi_nosquash_nids); list_splice(&tmp, &squash->rsi_nosquash_nids); - up_write(&squash->rsi_sem); + spin_unlock(&squash->rsi_lock); return count; -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 02:12:15 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 22:12:15 -0400 Subject: [lustre-devel] [PATCH 03/10] lustre: ptlrpc: make ptlrpc_bulk_frag_ops always const. In-Reply-To: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> References: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563761542-3708-4-git-send-email-jsimmons@infradead.org> From: NeilBrown There is one place where a non-const pointer to this struct exists, and that causes a cast to be required. Make it always const, and discard the cast. Signed-off-by: NeilBrown WC-bug-id: https://jira.whamcloud.com/browse/LU-4423 Reviewed-on: https://review.whamcloud.com/35295 Reviewed-by: Petros Koutoupis Reviewed-by: Shaun Tancheff Reviewed-by: Sebastien Buisson Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- fs/lustre/include/lustre_net.h | 2 +- fs/lustre/ptlrpc/client.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/lustre/include/lustre_net.h b/fs/lustre/include/lustre_net.h index 1cf0f12..83f8aff 100644 --- a/fs/lustre/include/lustre_net.h +++ b/fs/lustre/include/lustre_net.h @@ -1222,7 +1222,7 @@ struct ptlrpc_bulk_desc { struct obd_import *bd_import; /** Back pointer to the request */ struct ptlrpc_request *bd_req; - struct ptlrpc_bulk_frag_ops *bd_frag_ops; + const struct ptlrpc_bulk_frag_ops *bd_frag_ops; wait_queue_head_t bd_waitq; /* server side only WQ */ int bd_iov_count; /* # entries in bd_iov */ int bd_max_iov; /* allocated size of bd_iov */ diff --git a/fs/lustre/ptlrpc/client.c b/fs/lustre/ptlrpc/client.c index 364c61f..ff1fa68 100644 --- a/fs/lustre/ptlrpc/client.c +++ b/fs/lustre/ptlrpc/client.c @@ -150,7 +150,7 @@ struct ptlrpc_bulk_desc *ptlrpc_new_bulk(unsigned int nfrags, desc->bd_portal = portal; desc->bd_type = type; desc->bd_md_count = 0; - desc->bd_frag_ops = (struct ptlrpc_bulk_frag_ops *)ops; + desc->bd_frag_ops = ops; LASSERT(max_brw > 0); desc->bd_md_max_brw = min(max_brw, PTLRPC_BULK_OPS_COUNT); /* -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 02:12:18 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 22:12:18 -0400 Subject: [lustre-devel] [PATCH 06/10] lnet: socklnd: fix infinite loop in ksocknal_push() In-Reply-To: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> References: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563761542-3708-7-git-send-email-jsimmons@infradead.org> From: NeilBrown If the list_for_each_entry() loop in ksocknal_push() ever finds a match, then it will increment 'i', and the outer loop will continue. Once peer_off becomes larger than the number of matches in a given chain, 'peer_ni' will be an invalid pointer, and ksocknal_push_peer() will probably crash when called on it. To abort the outer loop properly, we need to test if "i <= peer_off", which indicates that all patching peers have been found. This bug can easily be reproduced by running lctl --net tcp push Signed-off-by: NeilBrown WC-bug-id: https://jira.whamcloud.com/browse/LU-12101 Reviewed-on: https://review.whamcloud.com/34499 Reviewed-by: James Simmons Reviewed-by: Sonia Sharma Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- net/lnet/klnds/socklnd/socklnd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/lnet/klnds/socklnd/socklnd.c b/net/lnet/klnds/socklnd/socklnd.c index 08feaf7..a422481 100644 --- a/net/lnet/klnds/socklnd/socklnd.c +++ b/net/lnet/klnds/socklnd/socklnd.c @@ -1952,7 +1952,7 @@ static int ksocknal_push(struct lnet_ni *ni, struct lnet_process_id id) } read_unlock(&ksocknal_data.ksnd_global_lock); - if (!i) /* no match */ + if (i <= peer_off) /* no match */ break; rc = 0; -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 02:12:16 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 22:12:16 -0400 Subject: [lustre-devel] [PATCH 04/10] lustre: mgc: remove llog_process_lock In-Reply-To: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> References: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563761542-3708-5-git-send-email-jsimmons@infradead.org> From: NeilBrown This mutex is never used, so remove it. Signed-off-by: NeilBrown WC-bug-id: https://jira.whamcloud.com/browse/LU-4423 Reviewed-on: https://review.whamcloud.com/35293 Reviewed-by: Petros Koutoupis Reviewed-by: Andreas Dilger Signed-off-by: James Simmons --- fs/lustre/mgc/mgc_request.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/fs/lustre/mgc/mgc_request.c b/fs/lustre/mgc/mgc_request.c index fa0be5c..581ffb0 100644 --- a/fs/lustre/mgc/mgc_request.c +++ b/fs/lustre/mgc/mgc_request.c @@ -384,8 +384,6 @@ struct config_llog_data *do_config_log_add(struct obd_device *obd, return ERR_PTR(rc); } -static DEFINE_MUTEX(llog_process_lock); - static inline void config_mark_cld_stop(struct config_llog_data *cld) { if (!cld) @@ -1538,9 +1536,7 @@ static int mgc_process_cfg_log(struct obd_device *mgc, __llog_ctxt_put(env, ctxt); /* - * update settings on existing OBDs. doing it inside - * of llog_process_lock so no device is attaching/detaching - * in parallel. + * update settings on existing OBDs. * the logname must be -sptlrpc */ if (sptlrpc_started) { -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 02:12:22 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 22:12:22 -0400 Subject: [lustre-devel] [PATCH 10/10] lustre: ptlrpc: simplify struct ptlrpc_request_set In-Reply-To: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> References: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563761542-3708-11-git-send-email-jsimmons@infradead.org> From: "John L. Hammond" Remove obd_statfs_rqset(), replacing its only use with obd_statfs(). Collapse lov_statfs_async() and lov_statfs() into a single function, removing the need for lov_statfs_interpret(). Remove the then unused set_wakeup_ptr, set_cblist, set_interpret, and set_arg members of struct ptlrpc_request_set. Remove struct ptlrpc_set_cbdata and ptlrpc_set_add_cb(). On x86_64 this reduces the size of struct ptlrpc_request_set from 152 bytes to 112. Signed-off-by: John L. Hammond WC-bug-id: https://jira.whamcloud.com/browse/LU-10227 Reviewed-on: https://review.whamcloud.com/30060 Reviewed-by: Andreas Dilger Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- fs/lustre/include/lustre_net.h | 24 ------------ fs/lustre/include/obd_class.h | 22 ----------- fs/lustre/llite/llite_lib.c | 2 +- fs/lustre/lov/lov_obd.c | 85 ++++++++++++++---------------------------- fs/lustre/ptlrpc/client.c | 19 ---------- 5 files changed, 28 insertions(+), 124 deletions(-) diff --git a/fs/lustre/include/lustre_net.h b/fs/lustre/include/lustre_net.h index f7bd8ad..fde59df 100644 --- a/fs/lustre/include/lustre_net.h +++ b/fs/lustre/include/lustre_net.h @@ -331,7 +331,6 @@ struct ptlrpc_client { }; struct ptlrpc_request_set; -typedef int (*set_interpreter_func)(struct ptlrpc_request_set *, void *, int); typedef int (*set_producer_func)(struct ptlrpc_request_set *, void *); /** @@ -353,20 +352,9 @@ struct ptlrpc_request_set { atomic_t set_remaining; /** wait queue to wait on for request events */ wait_queue_head_t set_waitq; - wait_queue_head_t *set_wakeup_ptr; /** List of requests in the set */ struct list_head set_requests; /** - * List of completion callbacks to be called when the set is completed - * This is only used if @set_interpret is NULL. - * Links struct ptlrpc_set_cbdata. - */ - struct list_head set_cblist; - /** Completion callback, if only one. */ - set_interpreter_func set_interpret; - /** opaq argument passed to completion @set_interpret callback. */ - void *set_arg; - /** * Lock for @set_new_requests manipulations * locked so that any old caller can communicate requests to * the set holder who can then fold them into the lock-free set @@ -386,18 +374,6 @@ struct ptlrpc_request_set { void *set_producer_arg; }; -/** - * Description of a single ptrlrpc_set callback - */ -struct ptlrpc_set_cbdata { - /** List linkage item */ - struct list_head psc_item; - /** Pointer to interpreting function */ - set_interpreter_func psc_interpret; - /** Opaq argument to pass to the callback */ - void *psc_data; -}; - struct ptlrpc_bulk_desc; struct ptlrpc_service_part; struct ptlrpc_service; diff --git a/fs/lustre/include/obd_class.h b/fs/lustre/include/obd_class.h index 2f02efe..f26ca17 100644 --- a/fs/lustre/include/obd_class.h +++ b/fs/lustre/include/obd_class.h @@ -909,28 +909,6 @@ static inline int obd_statfs_async(struct obd_export *exp, return rc; } -static inline int obd_statfs_rqset(struct obd_export *exp, - struct obd_statfs *osfs, u64 max_age, - u32 flags) -{ - struct ptlrpc_request_set *set = NULL; - struct obd_info oinfo = { - .oi_osfs = osfs, - .oi_flags = flags, - }; - int rc = 0; - - set = ptlrpc_prep_set(); - if (!set) - return -ENOMEM; - - rc = obd_statfs_async(exp, &oinfo, max_age, set); - if (rc == 0) - rc = ptlrpc_set_wait(set); - ptlrpc_set_destroy(set); - return rc; -} - /* * @max_age is the oldest time in jiffies that we accept using a cached data. * If the cache is older than @max_age we will get a new value from the diff --git a/fs/lustre/llite/llite_lib.c b/fs/lustre/llite/llite_lib.c index b933f37..83b63d8 100644 --- a/fs/lustre/llite/llite_lib.c +++ b/fs/lustre/llite/llite_lib.c @@ -1710,7 +1710,7 @@ int ll_statfs_internal(struct ll_sb_info *sbi, struct obd_statfs *osfs, if (sbi->ll_flags & LL_SBI_LAZYSTATFS) flags |= OBD_STATFS_NODELAY; - rc = obd_statfs_rqset(sbi->ll_dt_exp, &obd_osfs, max_age, flags); + rc = obd_statfs(NULL, sbi->ll_dt_exp, &obd_osfs, max_age, flags); if (rc) { CERROR("obd_statfs fails: rc = %d\n", rc); return rc; diff --git a/fs/lustre/lov/lov_obd.c b/fs/lustre/lov/lov_obd.c index 1d96f28..5dbc00e 100644 --- a/fs/lustre/lov/lov_obd.c +++ b/fs/lustre/lov/lov_obd.c @@ -911,78 +911,48 @@ int lov_process_config_base(struct obd_device *obd, struct lustre_cfg *lcfg, return rc; } -static int -lov_statfs_interpret(struct ptlrpc_request_set *rqset, void *data, int rc) -{ - struct lov_request_set *lovset = (struct lov_request_set *)data; - int err; - - if (rc) - atomic_set(&lovset->set_completes, 0); - - err = lov_fini_statfs_set(lovset); - return rc ? rc : err; -} - -static int lov_statfs_async(struct obd_export *exp, struct obd_info *oinfo, - u64 max_age, struct ptlrpc_request_set *rqset) +static int lov_statfs(const struct lu_env *env, struct obd_export *exp, + struct obd_statfs *osfs, u64 max_age, u32 flags) { struct obd_device *obd = class_exp2obd(exp); - struct lov_request_set *set; + struct lov_obd *lov = &obd->u.lov; + struct ptlrpc_request_set *rqset; + struct obd_info oinfo = { + .oi_osfs = osfs, + .oi_flags = flags, + }; + struct lov_request_set *set = NULL; struct lov_request *req; - struct lov_obd *lov; int rc = 0; + int rc2; - LASSERT(oinfo->oi_osfs); + rqset = ptlrpc_prep_set(); + if (!rqset) + return -ENOMEM; - lov = &obd->u.lov; - rc = lov_prep_statfs_set(obd, oinfo, &set); - if (rc) - return rc; + rc = lov_prep_statfs_set(obd, &oinfo, &set); + if (rc < 0) + goto out_rqset; list_for_each_entry(req, &set->set_list, rq_link) { rc = obd_statfs_async(lov->lov_tgts[req->rq_idx]->ltd_exp, &req->rq_oi, max_age, rqset); - if (rc) - break; - } - - if (rc || list_empty(&rqset->set_requests)) { - int err; - - if (rc) - atomic_set(&set->set_completes, 0); - err = lov_fini_statfs_set(set); - return rc ? rc : err; + if (rc < 0) + goto out_set; } - LASSERT(!rqset->set_interpret); - rqset->set_interpret = lov_statfs_interpret; - rqset->set_arg = (void *)set; - return 0; -} + rc = ptlrpc_set_wait(rqset); -static int lov_statfs(const struct lu_env *env, struct obd_export *exp, - struct obd_statfs *osfs, u64 max_age, u32 flags) -{ - struct ptlrpc_request_set *set = NULL; - struct obd_info oinfo = { - .oi_osfs = osfs, - .oi_flags = flags, - }; - int rc = 0; +out_set: + if (rc < 0) + atomic_set(&set->set_completes, 0); - /* for obdclass we forbid using obd_statfs_rqset, but prefer using async - * statfs requests - */ - set = ptlrpc_prep_set(); - if (!set) - return -ENOMEM; - - rc = lov_statfs_async(exp, &oinfo, max_age, set); + rc2 = lov_fini_statfs_set(set); if (rc == 0) - rc = ptlrpc_set_wait(set); - ptlrpc_set_destroy(set); + rc = rc2; + +out_rqset: + ptlrpc_set_destroy(rqset); return rc; } @@ -1341,7 +1311,6 @@ static int lov_quotactl(struct obd_device *obd, struct obd_export *exp, .connect = lov_connect, .disconnect = lov_disconnect, .statfs = lov_statfs, - .statfs_async = lov_statfs_async, .iocontrol = lov_iocontrol, .get_info = lov_get_info, .set_info_async = lov_set_info_async, diff --git a/fs/lustre/ptlrpc/client.c b/fs/lustre/ptlrpc/client.c index 5c0a3ec..f7f3678 100644 --- a/fs/lustre/ptlrpc/client.c +++ b/fs/lustre/ptlrpc/client.c @@ -980,7 +980,6 @@ struct ptlrpc_request_set *ptlrpc_prep_set(void) atomic_set(&set->set_remaining, 0); spin_lock_init(&set->set_new_req_lock); INIT_LIST_HEAD(&set->set_new_requests); - INIT_LIST_HEAD(&set->set_cblist); set->set_max_inflight = UINT_MAX; set->set_producer = NULL; set->set_producer_arg = NULL; @@ -2353,24 +2352,6 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set) rc = req->rq_status; } - if (set->set_interpret) { - int (*interpreter)(struct ptlrpc_request_set *set, void *, int) = - set->set_interpret; - rc = interpreter(set, set->set_arg, rc); - } else { - struct ptlrpc_set_cbdata *cbdata, *n; - int err; - - list_for_each_entry_safe(cbdata, n, - &set->set_cblist, psc_item) { - list_del_init(&cbdata->psc_item); - err = cbdata->psc_interpret(set, cbdata->psc_data, rc); - if (err && !rc) - rc = err; - kfree(cbdata); - } - } - return rc; } EXPORT_SYMBOL(ptlrpc_set_wait); -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 02:12:19 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 22:12:19 -0400 Subject: [lustre-devel] [PATCH 07/10] lustre: ptlrpc: remove inline on non-inlined functions. In-Reply-To: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> References: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563761542-3708-8-git-send-email-jsimmons@infradead.org> From: NeilBrown These three functions are never inlined. The only time they are used, their address is taken, and this forces them to be compiled as stand-alone functions. So having the "inline" declaration is misleading. Move the functions to the place where their address is used, and remove the 'inline' tag. Signed-off-by: NeilBrown WC-bug-id: https://jira.whamcloud.com/browse/LU-4423 Reviewed-on: https://review.whamcloud.com/35296 Reviewed-by: Andreas Dilger Reviewed-by: Sebastien Buisson Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- fs/lustre/include/lustre_net.h | 21 --------------------- fs/lustre/ptlrpc/client.c | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/fs/lustre/include/lustre_net.h b/fs/lustre/include/lustre_net.h index 83f8aff..f7bd8ad 100644 --- a/fs/lustre/include/lustre_net.h +++ b/fs/lustre/include/lustre_net.h @@ -1872,30 +1872,9 @@ int ptlrpc_prep_bulk_frag(struct ptlrpc_bulk_desc *desc, void __ptlrpc_prep_bulk_page(struct ptlrpc_bulk_desc *desc, struct page *page, int pageoffset, int len, int pin); -static inline void ptlrpc_prep_bulk_page_pin(struct ptlrpc_bulk_desc *desc, - struct page *page, int pageoffset, - int len) -{ - __ptlrpc_prep_bulk_page(desc, page, pageoffset, len, 1); -} - -static inline void ptlrpc_prep_bulk_page_nopin(struct ptlrpc_bulk_desc *desc, - struct page *page, int pageoffset, - int len) -{ - __ptlrpc_prep_bulk_page(desc, page, pageoffset, len, 0); -} void ptlrpc_free_bulk(struct ptlrpc_bulk_desc *bulk); -static inline void ptlrpc_release_bulk_page_pin(struct ptlrpc_bulk_desc *desc) -{ - int i; - - for (i = 0; i < desc->bd_iov_count ; i++) - put_page(BD_GET_KIOV(desc, i).bv_page); -} - void ptlrpc_retain_replayable_request(struct ptlrpc_request *req, struct obd_import *imp); u64 ptlrpc_next_xid(void); diff --git a/fs/lustre/ptlrpc/client.c b/fs/lustre/ptlrpc/client.c index ff1fa68..5f3dc3f 100644 --- a/fs/lustre/ptlrpc/client.c +++ b/fs/lustre/ptlrpc/client.c @@ -48,6 +48,28 @@ #include "ptlrpc_internal.h" +static void ptlrpc_prep_bulk_page_pin(struct ptlrpc_bulk_desc *desc, + struct page *page, int pageoffset, + int len) +{ + __ptlrpc_prep_bulk_page(desc, page, pageoffset, len, 1); +} + +static void ptlrpc_prep_bulk_page_nopin(struct ptlrpc_bulk_desc *desc, + struct page *page, int pageoffset, + int len) +{ + __ptlrpc_prep_bulk_page(desc, page, pageoffset, len, 0); +} + +static void ptlrpc_release_bulk_page_pin(struct ptlrpc_bulk_desc *desc) +{ + int i; + + for (i = 0; i < desc->bd_iov_count ; i++) + put_page(BD_GET_KIOV(desc, i).bv_page); +} + const struct ptlrpc_bulk_frag_ops ptlrpc_bulk_kiov_pin_ops = { .add_kiov_frag = ptlrpc_prep_bulk_page_pin, .release_frags = ptlrpc_release_bulk_page_pin, -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 02:12:13 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 22:12:13 -0400 Subject: [lustre-devel] [PATCH 01/10] lustre: ldlm: discard varname in ldlm_pool. In-Reply-To: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> References: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563761542-3708-2-git-send-email-jsimmons@infradead.org> From: NeilBrown This allocated buffer serves no purpose. A constant string is copied into it, it is passed to some function which copies it out again, then the buffer is freed. Instead, we can pass the constant string to that function. Signed-off-by: NeilBrown WC-bug-id: https://jira.whamcloud.com/browse/LU-4423 Reviewed-on: https://review.whamcloud.com/35273 Reviewed-by: Andreas Dilger Reviewed-by: Petros Koutoupis Signed-off-by: James Simmons --- fs/lustre/ldlm/ldlm_internal.h | 2 -- fs/lustre/ldlm/ldlm_pool.c | 18 +++++------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/fs/lustre/ldlm/ldlm_internal.h b/fs/lustre/ldlm/ldlm_internal.h index 05d5b08..a6dee9f 100644 --- a/fs/lustre/ldlm/ldlm_internal.h +++ b/fs/lustre/ldlm/ldlm_internal.h @@ -31,8 +31,6 @@ * Lustre is a trademark of Sun Microsystems, Inc. */ -#define MAX_STRING_SIZE 128 - extern int ldlm_srv_namespace_nr; extern int ldlm_cli_namespace_nr; extern struct mutex ldlm_srv_namespace_lock; diff --git a/fs/lustre/ldlm/ldlm_pool.c b/fs/lustre/ldlm/ldlm_pool.c index 6714c30..3dfbde5 100644 --- a/fs/lustre/ldlm/ldlm_pool.c +++ b/fs/lustre/ldlm/ldlm_pool.c @@ -504,9 +504,9 @@ static ssize_t grant_speed_show(struct kobject *kobj, struct attribute *attr, LDLM_POOL_SYSFS_WRITER_NOLOCK_STORE(lock_volume_factor, atomic); LUSTRE_RW_ATTR(lock_volume_factor); -#define LDLM_POOL_ADD_VAR(name, var, ops) \ +#define LDLM_POOL_ADD_VAR(_name, var, ops) \ do { \ - snprintf(var_name, MAX_STRING_SIZE, #name); \ + pool_vars[0].name = #_name; \ pool_vars[0].data = var; \ pool_vars[0].fops = ops; \ ldebugfs_add_vars(pl->pl_debugfs_entry, pool_vars, NULL);\ @@ -558,25 +558,18 @@ static int ldlm_pool_debugfs_init(struct ldlm_pool *pl) ns_pool); struct dentry *debugfs_ns_parent; struct lprocfs_vars pool_vars[2]; - char *var_name = NULL; int rc = 0; - var_name = kzalloc(MAX_STRING_SIZE + 1, GFP_NOFS); - if (!var_name) - return -ENOMEM; - debugfs_ns_parent = ns->ns_debugfs_entry; if (IS_ERR_OR_NULL(debugfs_ns_parent)) { CERROR("%s: debugfs entry is not initialized\n", ldlm_ns_name(ns)); rc = -EINVAL; - goto out_free_name; + goto out; } pl->pl_debugfs_entry = debugfs_create_dir("pool", debugfs_ns_parent); - var_name[MAX_STRING_SIZE] = '\0'; memset(pool_vars, 0, sizeof(pool_vars)); - pool_vars[0].name = var_name; LDLM_POOL_ADD_VAR(state, pl, &lprocfs_pool_state_fops); @@ -584,7 +577,7 @@ static int ldlm_pool_debugfs_init(struct ldlm_pool *pl) LDLM_POOL_FIRST_STAT, 0); if (!pl->pl_stats) { rc = -ENOMEM; - goto out_free_name; + goto out; } lprocfs_counter_init(pl->pl_stats, LDLM_POOL_GRANTED_STAT, @@ -623,8 +616,7 @@ static int ldlm_pool_debugfs_init(struct ldlm_pool *pl) debugfs_create_file("stats", 0644, pl->pl_debugfs_entry, pl->pl_stats, &lprocfs_stats_seq_fops); -out_free_name: - kfree(var_name); +out: return rc; } -- 1.8.3.1 From jsimmons at infradead.org Mon Jul 22 02:12:21 2019 From: jsimmons at infradead.org (James Simmons) Date: Sun, 21 Jul 2019 22:12:21 -0400 Subject: [lustre-devel] [PATCH 09/10] lustre: ptlrpc: make ptlrpc_last_xid an atomic64_t In-Reply-To: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> References: <1563761542-3708-1-git-send-email-jsimmons@infradead.org> Message-ID: <1563761542-3708-10-git-send-email-jsimmons@infradead.org> From: NeilBrown This variable is treated like an atomic64_t, so change it's type and simplify the code. Signed-off-by: NeilBrown WC-bug-id: https://jira.whamcloud.com/browse/LU-4423 Reviewed-on: https://review.whamcloud.com/35510 Reviewed-by: Shaun Tancheff Reviewed-by: Petros Koutoupis Reviewed-by: Andreas Dilger Signed-off-by: James Simmons --- fs/lustre/ptlrpc/client.c | 39 ++++++++++----------------------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/fs/lustre/ptlrpc/client.c b/fs/lustre/ptlrpc/client.c index 5f3dc3f..5c0a3ec 100644 --- a/fs/lustre/ptlrpc/client.c +++ b/fs/lustre/ptlrpc/client.c @@ -3062,8 +3062,7 @@ void ptlrpc_abort_set(struct ptlrpc_request_set *set) } } -static u64 ptlrpc_last_xid; -static spinlock_t ptlrpc_last_xid_lock; +static atomic64_t ptlrpc_last_xid; /** * Initialize the XID for the node. This is common among all requests on @@ -3084,19 +3083,20 @@ void ptlrpc_abort_set(struct ptlrpc_request_set *set) void ptlrpc_init_xid(void) { time64_t now = ktime_get_real_seconds(); + u64 xid; - spin_lock_init(&ptlrpc_last_xid_lock); if (now < YEAR_2004) { - get_random_bytes(&ptlrpc_last_xid, sizeof(ptlrpc_last_xid)); - ptlrpc_last_xid >>= 2; - ptlrpc_last_xid |= (1ULL << 61); + get_random_bytes(&xid, sizeof(xid)); + xid >>= 2; + xid |= (1ULL << 61); } else { - ptlrpc_last_xid = (u64)now << 20; + xid = (u64)now << 20; } /* Always need to be aligned to a power-of-two for multi-bulk BRW */ BUILD_BUG_ON(((PTLRPC_BULK_OPS_COUNT - 1) & PTLRPC_BULK_OPS_COUNT) != 0); - ptlrpc_last_xid &= PTLRPC_BULK_OPS_MASK; + xid &= PTLRPC_BULK_OPS_MASK; + atomic64_set(&ptlrpc_last_xid, xid); } /** @@ -3113,14 +3113,7 @@ void ptlrpc_init_xid(void) */ u64 ptlrpc_next_xid(void) { - u64 next; - - spin_lock(&ptlrpc_last_xid_lock); - next = ptlrpc_last_xid + PTLRPC_BULK_OPS_COUNT; - ptlrpc_last_xid = next; - spin_unlock(&ptlrpc_last_xid_lock); - - return next; + return atomic64_add_return(PTLRPC_BULK_OPS_COUNT, &ptlrpc_last_xid); } /** @@ -3195,19 +3188,7 @@ void ptlrpc_set_bulk_mbits(struct ptlrpc_request *req) */ u64 ptlrpc_sample_next_xid(void) { -#if BITS_PER_LONG == 32 - /* need to avoid possible word tearing on 32-bit systems */ - u64 next; - - spin_lock(&ptlrpc_last_xid_lock); - next = ptlrpc_last_xid + PTLRPC_BULK_OPS_COUNT; - spin_unlock(&ptlrpc_last_xid_lock); - - return next; -#else - /* No need to lock, since returned value is racy anyways */ - return ptlrpc_last_xid + PTLRPC_BULK_OPS_COUNT; -#endif + return atomic64_read(&ptlrpc_last_xid) + PTLRPC_BULK_OPS_COUNT; } EXPORT_SYMBOL(ptlrpc_sample_next_xid); -- 1.8.3.1 From neilb at suse.com Mon Jul 22 04:13:37 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 14:13:37 +1000 Subject: [lustre-devel] [PATCH 01/22] ext4: add i_fs_version In-Reply-To: <1563758631-29550-2-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-2-git-send-email-jsimmons@infradead.org> Message-ID: <87wogapuz2.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > From: James Simmons > > Add inode version field that osd-ldiskfs uses. We need more words here. What is i_fs_version used for? (I'll probably find out as I keep reading, but I need to know the intention first, or I cannot properly review the patches that make use of it. ) NeilBrown > > Signed-off-by: James Simmons > --- > fs/ext4/ext4.h | 2 ++ > fs/ext4/ialloc.c | 1 + > fs/ext4/inode.c | 4 ++-- > 3 files changed, 5 insertions(+), 2 deletions(-) > > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > index 1cb6785..8abbcab 100644 > --- a/fs/ext4/ext4.h > +++ b/fs/ext4/ext4.h > @@ -1063,6 +1063,8 @@ struct ext4_inode_info { > struct dquot *i_dquot[MAXQUOTAS]; > #endif > > + u64 i_fs_version; > + > /* Precomputed uuid+inum+igen checksum for seeding inode checksums */ > __u32 i_csum_seed; > > diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c > index 764ff4c..09ae4a4 100644 > --- a/fs/ext4/ialloc.c > +++ b/fs/ext4/ialloc.c > @@ -1100,6 +1100,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir, > ei->i_dtime = 0; > ei->i_block_group = group; > ei->i_last_alloc_group = ~0; > + ei->i_fs_version = 0; > > ext4_set_inode_flags(inode); > if (IS_DIRSYNC(inode)) > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > index c7f77c6..6e66175 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -4806,14 +4806,14 @@ static inline void ext4_inode_set_iversion_queried(struct inode *inode, u64 val) > if (unlikely(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) > inode_set_iversion_raw(inode, val); > else > - inode_set_iversion_queried(inode, val); > + EXT4_I(inode)->i_fs_version = val; > } > static inline u64 ext4_inode_peek_iversion(const struct inode *inode) > { > if (unlikely(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) > return inode_peek_iversion_raw(inode); > else > - return inode_peek_iversion(inode); > + return EXT4_I(inode)->i_fs_version; > } > > struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 04:16:47 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 14:16:47 +1000 Subject: [lustre-devel] [PATCH 02/22] ext4: use d_find_alias() in ext4_lookup In-Reply-To: <1563758631-29550-3-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-3-git-send-email-jsimmons@infradead.org> Message-ID: <87tvbeputs.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > From: James Simmons > > Really old bug that might not even exist anymore? If there is a bug, it is somewhere else. ext4_lookup() should never be called on "." or "..". Whatever calls ext4_lookup must filter those out if there are a possibility. NeilBrown > > Signed-off-by: James Simmons > --- > fs/ext4/namei.c | 29 +++++++++++++++++++++++++++++ > 1 file changed, 29 insertions(+) > > diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c > index cd01c4a..a616f58 100644 > --- a/fs/ext4/namei.c > +++ b/fs/ext4/namei.c > @@ -1664,6 +1664,35 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi > } > } > > + /* ".." shouldn't go into dcache to preserve dcache hierarchy > + * otherwise we'll get parent being a child of actual child. > + * see bug 10458 for details -bzzz > + */ > + if (inode && (dentry->d_name.name[0] == '.' && > + (dentry->d_name.len == 1 || (dentry->d_name.len == 2 && > + dentry->d_name.name[1] == '.')))) { > + struct dentry *goal = NULL; > + > + /* first, look for an existing dentry - any one is good */ > + goal = d_find_any_alias(inode); > + if (!goal) { > + spin_lock(&dentry->d_lock); > + /* there is no alias, we need to make current dentry: > + * a) inaccessible for __d_lookup() > + * b) inaccessible for iopen > + */ > + J_ASSERT(hlist_unhashed(&dentry->d_u.d_alias)); > + dentry->d_flags |= DCACHE_NFSFS_RENAMED; > + /* this is d_instantiate() ... */ > + hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry); > + dentry->d_inode = inode; > + spin_unlock(&dentry->d_lock); > + } > + if (goal) > + iput(inode); > + return goal; > + } > + > #ifdef CONFIG_UNICODE > if (!inode && IS_CASEFOLDED(dir)) { > /* Eventually we want to call d_add_ci(dentry, NULL) > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 04:29:59 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 14:29:59 +1000 Subject: [lustre-devel] [PATCH 03/22] ext4: prealloc table optimization In-Reply-To: <1563758631-29550-4-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-4-git-send-email-jsimmons@infradead.org> Message-ID: <87r26ipu7s.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > Optimize prealloc table "Optimize"??? What does that even mean here? I notice that the patch removes a comment: /* XXX: should this table be tunable? */ and at least some of what the patch does is to make that table tunable. There should be a patch which *only* makes that table tunable, with hopefully a suggestion of why this is a good thing, and then anything else need to go in a separate patch (with text telling me why this is an improvement). NeilBrown -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 04:34:02 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 14:34:02 +1000 Subject: [lustre-devel] [PATCH 04/22] ext4: export inode management In-Reply-To: <1563758631-29550-5-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-5-git-send-email-jsimmons@infradead.org> Message-ID: <87o91mpu11.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > Make ext4_delete_entry() exportable for osd-ldiskfs. Also add > exportable ext4_create_inode(). Why can't lustre use vfs_unlink like everyone else? And vfs_mknod()? My hope is that what we land upstream will use generic interfaces only. If there is something that osd needs to do that the generic interfaces cannot support, then we need to look at how to add that to the generic interface. NeilBrown -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 04:37:00 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 14:37:00 +1000 Subject: [lustre-devel] [PATCH 06/22] ext4: add extra checks for mballoc In-Reply-To: <1563758631-29550-7-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-7-git-send-email-jsimmons@infradead.org> Message-ID: <87lfwqptw3.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > Handle mballoc corruptions. "Handle" here mean "return -EIO if corruptions are found" ?? Sounds like a good thing to do. I cannot comment on the code without understand the fs more, but... > diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h > index 88c98f1..8325ad9 100644 > --- a/fs/ext4/mballoc.h > +++ b/fs/ext4/mballoc.h > @@ -70,7 +70,7 @@ > /* > * for which requests use 2^N search using buddies > */ > -#define MB_DEFAULT_ORDER2_REQS 2 > +#define MB_DEFAULT_ORDER2_REQS 8 I don't think this belongs with the reset of the patch. NeilBrown > > /* > * default group prealloc size 512 blocks > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 04:45:49 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 14:45:49 +1000 Subject: [lustre-devel] [PATCH 07/22] ext4: update .. for hash indexed directory In-Reply-To: <1563758631-29550-8-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-8-git-send-email-jsimmons@infradead.org> Message-ID: <87imrupthe.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > Handle special .. case. This seems to be for adding ".." to a directory. That happens at "mkdir". When else would you want to do that? Is this an on-line fsck-repair thing? NeilBrown -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 04:52:37 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 14:52:37 +1000 Subject: [lustre-devel] [PATCH 08/22] ext4: kill off struct dx_root In-Reply-To: <1563758631-29550-9-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-9-git-send-email-jsimmons@infradead.org> Message-ID: <87ftmypt62.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > Use struct dx_root_info directly. This looks like a style change. Instead of a 'struct' that models the start of an on-disk directory block, the location of some fields is done using calculations instead. Why would we want to do that? Might we want dx_root_info to be at a different offset in the directory ?? NeilBrown -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 04:56:32 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 14:56:32 +1000 Subject: [lustre-devel] [PATCH 09/22] ext4: fix mballoc pa free mismatch In-Reply-To: <1563758631-29550-10-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-10-git-send-email-jsimmons@infradead.org> Message-ID: <87d0i2pszj.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > Intoduce pa_error so we can find any mballoc pa cleanup problems. This patch seems to make sense, though > + BUG_ON(atomic_read(&sb->s_active) > 0 && pa->pa_free != free); should probably be a WARN_ON and > +#include seems un-called for. NeilBrown > > Signed-off-by: James Simmons > --- > fs/ext4/mballoc.c | 45 +++++++++++++++++++++++++++++++++++++++------ > fs/ext4/mballoc.h | 2 ++ > 2 files changed, 41 insertions(+), 6 deletions(-) > > diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c > index 483fc0f..463fba6 100644 > --- a/fs/ext4/mballoc.c > +++ b/fs/ext4/mballoc.c > @@ -3863,6 +3863,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, > INIT_LIST_HEAD(&pa->pa_group_list); > pa->pa_deleted = 0; > pa->pa_type = MB_INODE_PA; > + pa->pa_error = 0; > > mb_debug(1, "new inode pa %p: %llu/%u for %u\n", pa, > pa->pa_pstart, pa->pa_len, pa->pa_lstart); > @@ -3924,6 +3925,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, > INIT_LIST_HEAD(&pa->pa_group_list); > pa->pa_deleted = 0; > pa->pa_type = MB_GROUP_PA; > + pa->pa_error = 0; > > mb_debug(1, "new group pa %p: %llu/%u for %u\n", pa, > pa->pa_pstart, pa->pa_len, pa->pa_lstart); > @@ -3983,7 +3985,9 @@ static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac) > unsigned long long grp_blk_start; > int free = 0; > > + assert_spin_locked(ext4_group_lock_ptr(sb, e4b->bd_group)); > BUG_ON(pa->pa_deleted == 0); > + BUG_ON(pa->pa_inode == NULL); > ext4_get_group_no_and_offset(sb, pa->pa_pstart, &group, &bit); > grp_blk_start = pa->pa_pstart - EXT4_C2B(sbi, bit); > BUG_ON(group != e4b->bd_group && pa->pa_len != 0); > @@ -4006,12 +4010,19 @@ static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac) > mb_free_blocks(pa->pa_inode, e4b, bit, next - bit); > bit = next + 1; > } > - if (free != pa->pa_free) { > - ext4_msg(e4b->bd_sb, KERN_CRIT, > - "pa %p: logic %lu, phys. %lu, len %lu", > - pa, (unsigned long) pa->pa_lstart, > - (unsigned long) pa->pa_pstart, > - (unsigned long) pa->pa_len); > + > + /* "free < pa->pa_free" means we maybe double alloc the same blocks, > + * otherwise maybe leave some free blocks unavailable, no need to BUG. > + */ > + if ((free > pa->pa_free && !pa->pa_error) || (free < pa->pa_free)) { > + ext4_error(sb, "pa free mismatch: [pa %p] " > + "[phy %lu] [logic %lu] [len %u] [free %u] " > + "[error %u] [inode %lu] [freed %u]", pa, > + (unsigned long)pa->pa_pstart, > + (unsigned long)pa->pa_lstart, > + (unsigned)pa->pa_len, (unsigned)pa->pa_free, > + (unsigned)pa->pa_error, pa->pa_inode->i_ino, > + free); > ext4_grp_locked_error(sb, group, 0, 0, "free %u, pa_free %u", > free, pa->pa_free); > /* > @@ -4019,6 +4030,8 @@ static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac) > * from the bitmap and continue. > */ > } > + /* do not verify if the file system is being umounted */ > + BUG_ON(atomic_read(&sb->s_active) > 0 && pa->pa_free != free); > atomic_add(free, &sbi->s_mb_discarded); > > return 0; > @@ -4764,6 +4777,26 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, > ac->ac_b_ex.fe_len = 0; > ar->len = 0; > ext4_mb_show_ac(ac); > + if (ac->ac_pa) { > + struct ext4_prealloc_space *pa = ac->ac_pa; > + > + /* We can not make sure whether the bitmap has > + * been updated or not when fail case. So can > + * not revert pa_free back, just mark pa_error > + */ > + pa->pa_error++; > + ext4_error(sb, > + "Updating bitmap error: [err %d] " > + "[pa %p] [phy %lu] [logic %lu] " > + "[len %u] [free %u] [error %u] " > + "[inode %lu]", *errp, pa, > + (unsigned long)pa->pa_pstart, > + (unsigned long)pa->pa_lstart, > + (unsigned)pa->pa_len, > + (unsigned)pa->pa_free, > + (unsigned)pa->pa_error, > + pa->pa_inode ? pa->pa_inode->i_ino : 0); > + } > } > ext4_mb_release_context(ac); > out: > diff --git a/fs/ext4/mballoc.h b/fs/ext4/mballoc.h > index 8325ad9..e00c3b7 100644 > --- a/fs/ext4/mballoc.h > +++ b/fs/ext4/mballoc.h > @@ -20,6 +20,7 @@ > #include > #include > #include > +#include > #include "ext4_jbd2.h" > #include "ext4.h" > > @@ -111,6 +112,7 @@ struct ext4_prealloc_space { > ext4_grpblk_t pa_len; /* len of preallocated chunk */ > ext4_grpblk_t pa_free; /* how many blocks are free */ > unsigned short pa_type; /* pa type. inode or group */ > + unsigned short pa_error; > spinlock_t *pa_obj_lock; > struct inode *pa_inode; /* hack, for history only */ > }; > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 05:06:49 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 15:06:49 +1000 Subject: [lustre-devel] [PATCH 11/22] ext4: over ride current_time In-Reply-To: <1563758631-29550-12-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-12-git-send-email-jsimmons@infradead.org> Message-ID: <87a7d6psie.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > return i_ctime if IS_NOCMTIME is true for inode. So ... this prevents ext4 from ever changing the i_ctime on any file with S_NOCMTIME set - and osd-ldiskfs sets that on all inodes. Presumably osd wants full control of the ctime. That's probably a reasonable goal. I think it should be achieved by adding a mount/sb flag which suppresses all m/ctime updates except those made through utimes(). NeilBrown > > Signed-off-by: James Simmons > --- > fs/ext4/ext4.h | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > index 51b6159..80601a9 100644 > --- a/fs/ext4/ext4.h > +++ b/fs/ext4/ext4.h > @@ -661,6 +661,13 @@ enum { > #define EXT4_GOING_FLAGS_LOGFLUSH 0x1 /* flush log but not data */ > #define EXT4_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */ > > +static inline struct timespec64 ext4_current_time(struct inode *inode) > +{ > + if (IS_NOCMTIME(inode)) > + return inode->i_ctime; > + return current_time(inode); > +} > +#define current_time(a) ext4_current_time(a) > > #if defined(__KERNEL__) && defined(CONFIG_COMPAT) > /* > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 05:10:50 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 15:10:50 +1000 Subject: [lustre-devel] [PATCH 12/22] ext4: add htree lock implementation In-Reply-To: <1563758631-29550-13-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-13-git-send-email-jsimmons@infradead.org> Message-ID: <877e8apsbp.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > Used for parallel lookup This needs more time for review than I have just now ... I suspect the full EX,PW,PR,CW,CR locking is overkill, but I won't know until I read the code (unlikely to happen this year). Also, we need parallel lookups at the VFS level - I do have code for that. NeilBrown -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 05:14:45 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 15:14:45 +1000 Subject: [lustre-devel] [PATCH 13/22] ext4: Add a proc interface for max_dir_size. In-Reply-To: <1563758631-29550-14-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-14-git-send-email-jsimmons@infradead.org> Message-ID: <874l3eps56.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > Signed-off-by: James Simmons > --- > fs/ext4/sysfs.c | 6 ++++++ > 1 file changed, 6 insertions(+) > > diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c > index 1375815..3a71a16 100644 > --- a/fs/ext4/sysfs.c > +++ b/fs/ext4/sysfs.c > @@ -180,6 +180,8 @@ static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf) > EXT4_ATTR_OFFSET(inode_readahead_blks, 0644, inode_readahead, > ext4_sb_info, s_inode_readahead_blks); > EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal); > +EXT4_RW_ATTR_SBI_UI(max_dir_size, s_max_dir_size_kb); > +EXT4_RW_ATTR_SBI_UI(max_dir_size_kb, s_max_dir_size_kb); Why do we need both? > EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats); > EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan); > EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan); > @@ -210,6 +212,8 @@ static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf) > ATTR_LIST(reserved_clusters), > ATTR_LIST(inode_readahead_blks), > ATTR_LIST(inode_goal), > + ATTR_LIST(max_dir_size), > + ATTR_LIST(max_dir_size_kb), > ATTR_LIST(mb_stats), > ATTR_LIST(mb_max_to_scan), > ATTR_LIST(mb_min_to_scan), > @@ -350,6 +354,8 @@ static ssize_t ext4_attr_store(struct kobject *kobj, > ret = kstrtoul(skip_spaces(buf), 0, &t); > if (ret) > return ret; > + if (strcmp("max_dir_size", a->attr.name) == 0) > + t >>= 10; Give that the attrs are read/write, surely we need a <<= 10 in the read path too?? NeilBrown > if (a->attr_ptr == ptr_ext4_super_block_offset) > *((__le32 *) ptr) = cpu_to_le32(t); > else > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 05:16:50 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 15:16:50 +1000 Subject: [lustre-devel] [PATCH 14/22] ext4: remove inode_lock handling In-Reply-To: <1563758631-29550-15-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-15-git-send-email-jsimmons@infradead.org> Message-ID: <871ryips1p.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > There will cause a deadlock if invoke ext4_truncate with i_mutex locked > in lustre. Since lustre has own lock to provide protect so we don't > need this check at all. I guess you mean that if you took i_mutex in lustre, that would cause a deadlock? More evidence needed, and I strongly suspect that this is a bad idea. NeilBrown > > Signed-off-by: James Simmons > --- > fs/ext4/inode.c | 2 -- > fs/ext4/namei.c | 4 ---- > 2 files changed, 6 deletions(-) > > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > index 5561351..9296611 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -4474,8 +4474,6 @@ int ext4_truncate(struct inode *inode) > * or it's a completely new inode. In those cases we might not > * have i_mutex locked because it's not necessary. > */ > - if (!(inode->i_state & (I_NEW|I_FREEING))) > - WARN_ON(!inode_is_locked(inode)); > trace_ext4_truncate_enter(inode); > > if (!ext4_can_truncate(inode)) > diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c > index 0153c4d..1b6d22a 100644 > --- a/fs/ext4/namei.c > +++ b/fs/ext4/namei.c > @@ -3485,8 +3485,6 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) > if (!sbi->s_journal || is_bad_inode(inode)) > return 0; > > - WARN_ON_ONCE(!(inode->i_state & (I_NEW | I_FREEING)) && > - !inode_is_locked(inode)); > /* > * Exit early if inode already is on orphan list. This is a big speedup > * since we don't have to contend on the global s_orphan_lock. > @@ -3569,8 +3567,6 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) > if (!sbi->s_journal && !(sbi->s_mount_state & EXT4_ORPHAN_FS)) > return 0; > > - WARN_ON_ONCE(!(inode->i_state & (I_NEW | I_FREEING)) && > - !inode_is_locked(inode)); > /* Do this quick check before taking global s_orphan_lock. */ > if (list_empty(&ei->i_orphan)) > return 0; > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 05:18:38 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 15:18:38 +1000 Subject: [lustre-devel] [PATCH 15/22] ext4: remove bitmap corruption warnings In-Reply-To: <1563758631-29550-16-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-16-git-send-email-jsimmons@infradead.org> Message-ID: <87y30qode9.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > Since we could skip corrupt block groups, this patch > use ext4_warning() intead of ext4_error() to make FS not > mount RO in default. Does this related to the previous patch: ext4: add extra checks for mballoc ?? If so, it seems like a good idea, but the two patches should be consecutive. The description could read "Now that we skip corrupt ....". NeilBrown > > Signed-off-by: James Simmons > --- > fs/ext4/balloc.c | 10 ++++----- > fs/ext4/ialloc.c | 6 ++--- > fs/ext4/mballoc.c | 66 +++++++++++++++++++++++-------------------------------- > 3 files changed, 35 insertions(+), 47 deletions(-) > > diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c > index bca75c1..aff3981 100644 > --- a/fs/ext4/balloc.c > +++ b/fs/ext4/balloc.c > @@ -374,7 +374,7 @@ static int ext4_validate_block_bitmap(struct super_block *sb, > if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group, > desc, bh))) { > ext4_unlock_group(sb, block_group); > - ext4_error(sb, "bg %u: bad block bitmap checksum", block_group); > + ext4_warning(sb, "bg %u: bad block bitmap checksum", block_group); > ext4_mark_group_bitmap_corrupted(sb, block_group, > EXT4_GROUP_INFO_BBITMAP_CORRUPT); > return -EFSBADCRC; > @@ -382,8 +382,8 @@ static int ext4_validate_block_bitmap(struct super_block *sb, > blk = ext4_valid_block_bitmap(sb, desc, block_group, bh); > if (unlikely(blk != 0)) { > ext4_unlock_group(sb, block_group); > - ext4_error(sb, "bg %u: block %llu: invalid block bitmap", > - block_group, blk); > + ext4_warning(sb, "bg %u: block %llu: invalid block bitmap", > + block_group, blk); > ext4_mark_group_bitmap_corrupted(sb, block_group, > EXT4_GROUP_INFO_BBITMAP_CORRUPT); > return -EFSCORRUPTED; > @@ -459,8 +459,8 @@ struct buffer_head * > ext4_unlock_group(sb, block_group); > unlock_buffer(bh); > if (err) { > - ext4_error(sb, "Failed to init block bitmap for group " > - "%u: %d", block_group, err); > + ext4_warning(sb, "Failed to init block bitmap for group " > + "%u: %d", block_group, err); > goto out; > } > goto verify; > diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c > index 68d41e6..a72fe63 100644 > --- a/fs/ext4/ialloc.c > +++ b/fs/ext4/ialloc.c > @@ -96,8 +96,8 @@ static int ext4_validate_inode_bitmap(struct super_block *sb, > if (!ext4_inode_bitmap_csum_verify(sb, block_group, desc, bh, > EXT4_INODES_PER_GROUP(sb) / 8)) { > ext4_unlock_group(sb, block_group); > - ext4_error(sb, "Corrupt inode bitmap - block_group = %u, " > - "inode_bitmap = %llu", block_group, blk); > + ext4_warning(sb, "Corrupt inode bitmap - block_group = %u, " > + "inode_bitmap = %llu", block_group, blk); > ext4_mark_group_bitmap_corrupted(sb, block_group, > EXT4_GROUP_INFO_IBITMAP_CORRUPT); > return -EFSBADCRC; > @@ -346,7 +346,7 @@ void ext4_free_inode(handle_t *handle, struct inode *inode) > if (!fatal) > fatal = err; > } else { > - ext4_error(sb, "bit already cleared for inode %lu", ino); > + ext4_warning(sb, "bit already cleared for inode %lu", ino); > ext4_mark_group_bitmap_corrupted(sb, block_group, > EXT4_GROUP_INFO_IBITMAP_CORRUPT); > } > diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c > index 463fba6..82398b0 100644 > --- a/fs/ext4/mballoc.c > +++ b/fs/ext4/mballoc.c > @@ -741,10 +741,15 @@ int ext4_mb_generate_buddy(struct super_block *sb, > grp->bb_fragments = fragments; > > if (free != grp->bb_free) { > - ext4_grp_locked_error(sb, group, 0, 0, > - "block bitmap and bg descriptor " > - "inconsistent: %u vs %u free clusters", > - free, grp->bb_free); > + struct ext4_group_desc *gdp; > + > + gdp = ext4_get_group_desc(sb, group, NULL); > + ext4_warning(sb, "group %lu: block bitmap and bg descriptor " > + "inconsistent: %u vs %u free clusters " > + "%u in gd, %lu pa's", > + (long unsigned int)group, free, grp->bb_free, > + ext4_free_group_clusters(sb, gdp), > + grp->bb_prealloc_nr); > /* > * If we intend to continue, we consider group descriptor > * corrupt and update bb_free using bitmap value > @@ -1106,7 +1111,7 @@ int ext4_mb_init_group(struct super_block *sb, ext4_group_t group, gfp_t gfp) > int block; > int pnum; > int poff; > - struct page *page; > + struct page *page = NULL; > int ret; > struct ext4_group_info *grp; > struct ext4_sb_info *sbi = EXT4_SB(sb); > @@ -1132,7 +1137,7 @@ int ext4_mb_init_group(struct super_block *sb, ext4_group_t group, gfp_t gfp) > */ > ret = ext4_mb_init_group(sb, group, gfp); > if (ret) > - return ret; > + goto err; > } > > /* > @@ -1235,6 +1240,7 @@ int ext4_mb_init_group(struct super_block *sb, ext4_group_t group, gfp_t gfp) > put_page(e4b->bd_buddy_page); > e4b->bd_buddy = NULL; > e4b->bd_bitmap = NULL; > + ext4_warning(sb, "Error loading buddy information for %u", group); > return ret; > } > > @@ -3631,8 +3637,10 @@ int ext4_mb_check_ondisk_bitmap(struct super_block *sb, void *bitmap, > } > > if (free != free_in_gdp) { > - ext4_error(sb, "on-disk bitmap for group %d corrupted: %u blocks free in bitmap, %u - in gd\n", > - group, free, free_in_gdp); > + ext4_warning(sb, "on-disk bitmap for group %d corrupted: %u blocks free in bitmap, %u - in gd\n", > + group, free, free_in_gdp); > + ext4_mark_group_bitmap_corrupted(sb, group, > + EXT4_GROUP_INFO_BBITMAP_CORRUPT); > return -EIO; > } > return 0; > @@ -4015,14 +4023,6 @@ static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac) > * otherwise maybe leave some free blocks unavailable, no need to BUG. > */ > if ((free > pa->pa_free && !pa->pa_error) || (free < pa->pa_free)) { > - ext4_error(sb, "pa free mismatch: [pa %p] " > - "[phy %lu] [logic %lu] [len %u] [free %u] " > - "[error %u] [inode %lu] [freed %u]", pa, > - (unsigned long)pa->pa_pstart, > - (unsigned long)pa->pa_lstart, > - (unsigned)pa->pa_len, (unsigned)pa->pa_free, > - (unsigned)pa->pa_error, pa->pa_inode->i_ino, > - free); > ext4_grp_locked_error(sb, group, 0, 0, "free %u, pa_free %u", > free, pa->pa_free); > /* > @@ -4086,15 +4086,11 @@ static int ext4_mb_new_preallocation(struct ext4_allocation_context *ac) > bitmap_bh = ext4_read_block_bitmap(sb, group); > if (IS_ERR(bitmap_bh)) { > err = PTR_ERR(bitmap_bh); > - ext4_error(sb, "Error %d reading block bitmap for %u", > - err, group); > return 0; > } > > err = ext4_mb_load_buddy(sb, group, &e4b); > if (err) { > - ext4_warning(sb, "Error %d loading buddy information for %u", > - err, group); > put_bh(bitmap_bh); > return 0; > } > @@ -4255,17 +4251,12 @@ void ext4_discard_preallocations(struct inode *inode) > > err = ext4_mb_load_buddy_gfp(sb, group, &e4b, > GFP_NOFS|__GFP_NOFAIL); > - if (err) { > - ext4_error(sb, "Error %d loading buddy information for %u", > - err, group); > + if (err) > return; > - } > > bitmap_bh = ext4_read_block_bitmap(sb, group); > if (IS_ERR(bitmap_bh)) { > err = PTR_ERR(bitmap_bh); > - ext4_error(sb, "Error %d reading block bitmap for %u", > - err, group); > ext4_mb_unload_buddy(&e4b); > continue; > } > @@ -4527,11 +4518,8 @@ static void ext4_mb_group_or_file(struct ext4_allocation_context *ac) > group = ext4_get_group_number(sb, pa->pa_pstart); > err = ext4_mb_load_buddy_gfp(sb, group, &e4b, > GFP_NOFS|__GFP_NOFAIL); > - if (err) { > - ext4_error(sb, "Error %d loading buddy information for %u", > - err, group); > + if (err) > continue; > - } > ext4_lock_group(sb, group); > list_del(&pa->pa_group_list); > ext4_get_group_info(sb, group)->bb_prealloc_nr--; > @@ -4785,7 +4773,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, > * not revert pa_free back, just mark pa_error > */ > pa->pa_error++; > - ext4_error(sb, > + ext4_warning(sb, > "Updating bitmap error: [err %d] " > "[pa %p] [phy %lu] [logic %lu] " > "[len %u] [free %u] [error %u] " > @@ -4796,6 +4784,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, > (unsigned)pa->pa_free, > (unsigned)pa->pa_error, > pa->pa_inode ? pa->pa_inode->i_ino : 0); > + ext4_mark_group_bitmap_corrupted(sb, 0, 0); > } > } > ext4_mb_release_context(ac); > @@ -5081,7 +5070,7 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, > err = ext4_mb_load_buddy_gfp(sb, block_group, &e4b, > GFP_NOFS|__GFP_NOFAIL); > if (err) > - goto error_return; > + goto error_brelse; > > /* > * We need to make sure we don't reuse the freed block until after the > @@ -5171,8 +5160,9 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode, > goto do_more; > } > error_return: > - brelse(bitmap_bh); > ext4_std_error(sb, err); > +error_brelse: > + brelse(bitmap_bh); > return; > } > > @@ -5272,7 +5262,7 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, > > err = ext4_mb_load_buddy(sb, block_group, &e4b); > if (err) > - goto error_return; > + goto error_brelse; > > /* > * need to update group_info->bb_free and bitmap > @@ -5310,8 +5300,9 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb, > err = ret; > > error_return: > - brelse(bitmap_bh); > ext4_std_error(sb, err); > +error_brelse: > + brelse(bitmap_bh); > return err; > } > > @@ -5386,11 +5377,8 @@ static int ext4_trim_extent(struct super_block *sb, int start, int count, > trace_ext4_trim_all_free(sb, group, start, max); > > ret = ext4_mb_load_buddy(sb, group, &e4b); > - if (ret) { > - ext4_warning(sb, "Error %d loading buddy information for %u", > - ret, group); > + if (ret) > return ret; > - } > bitmap = e4b.bd_bitmap; > > ext4_lock_group(sb, group); > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 05:24:29 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 15:24:29 +1000 Subject: [lustre-devel] [PATCH 16/22] ext4: add warning for directory htree growth In-Reply-To: <1563758631-29550-17-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-17-git-send-email-jsimmons@infradead.org> Message-ID: <87v9vuod4i.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: You have really out-done yourself with the commit message here !!! I think this allows lustre to generate warnings if any single directory exceeds some particular size ?? Any be default, the max size is 33% larger than the first directory that anything is added to?? I guess lustre just uses one big directory?? I appreciate that this might be useful functionality. I suspect a better interface is needed. NeilBrown > Signed-off-by: James Simmons > --- > fs/ext4/ext4.h | 1 + > fs/ext4/namei.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- > fs/ext4/super.c | 2 ++ > fs/ext4/sysfs.c | 2 ++ > 4 files changed, 72 insertions(+), 2 deletions(-) > > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > index bf74c7c..5f73e19 100644 > --- a/fs/ext4/ext4.h > +++ b/fs/ext4/ext4.h > @@ -1472,6 +1472,7 @@ struct ext4_sb_info { > unsigned int s_mb_group_prealloc; > unsigned long *s_mb_prealloc_table; > unsigned int s_max_dir_size_kb; > + unsigned long s_warning_dir_size; > /* where last allocation was done - for stream allocation */ > unsigned long s_mb_last_group; > unsigned long s_mb_last_start; > diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c > index 1b6d22a..9b30cc6 100644 > --- a/fs/ext4/namei.c > +++ b/fs/ext4/namei.c > @@ -757,12 +757,20 @@ struct ext4_dir_lock_data { > #define ext4_htree_lock_data(l) ((struct ext4_dir_lock_data *)(l)->lk_private) > #define ext4_find_entry(dir, name, dirent, inline) \ > ext4_find_entry_locked(dir, name, dirent, inline, NULL) > -#define ext4_add_entry(handle, dentry, inode) \ > - ext4_add_entry_locked(handle, dentry, inode, NULL) > > /* NB: ext4_lblk_t is 32 bits so we use high bits to identify invalid blk */ > #define EXT4_HTREE_NODE_CHANGED (0xcafeULL << 32) > > +inline int ext4_add_entry(handle_t *handle, struct dentry *dentry, > + struct inode *inode) > +{ > + int ret = ext4_add_entry_locked(handle, dentry, inode, NULL); > + > + if (ret == -ENOBUFS) > + ret = 0; > + return ret; > +} > + > static void ext4_htree_event_cb(void *target, void *event) > { > u64 *block = (u64 *)target; > @@ -2612,6 +2620,55 @@ static int ext4_update_dotdot(handle_t *handle, struct dentry *dentry, > return err; > } > > +static unsigned long __ext4_max_dir_size(struct dx_frame *frames, > + struct dx_frame *frame, > + struct inode *dir) > +{ > + unsigned long max_dir_size; > + > + if (EXT4_SB(dir->i_sb)->s_max_dir_size_kb) { > + max_dir_size = EXT4_SB(dir->i_sb)->s_max_dir_size_kb << 10; > + } else { > + max_dir_size = EXT4_BLOCK_SIZE(dir->i_sb); > + while (frame >= frames) { > + max_dir_size *= dx_get_limit(frame->entries); > + if (frame == frames) > + break; > + frame--; > + } > + /* use 75% of max dir size in average */ > + max_dir_size = max_dir_size / 4 * 3; > + } > + return max_dir_size; > +} > + > +/* > + * With hash tree growing, it is easy to hit ENOSPC, but it is hard > + * to predict when it will happen. let's give administrators warning > + * when reaching 3/5 and 2/3 of limit > + */ > +static inline bool dir_size_in_warning_range(struct dx_frame *frames, > + struct dx_frame *frame, > + struct inode *dir) > +{ > + struct super_block *sb = dir->i_sb; > + unsigned long size1, size2; > + > + if (unlikely(!EXT4_SB(sb)->s_warning_dir_size)) > + EXT4_SB(sb)->s_warning_dir_size = > + __ext4_max_dir_size(frames, frame, dir); > + > + size1 = EXT4_SB(sb)->s_warning_dir_size / 16 * 10; > + size1 = size1 & ~(EXT4_BLOCK_SIZE(sb) - 1); > + size2 = EXT4_SB(sb)->s_warning_dir_size / 16 * 11; > + size2 = size2 & ~(EXT4_BLOCK_SIZE(sb) - 1); > + if (in_range(dir->i_size, size1, EXT4_BLOCK_SIZE(sb)) || > + in_range(dir->i_size, size2, EXT4_BLOCK_SIZE(sb))) > + return true; > + > + return false; > +} > + > /* > * ext4_add_entry() > * > @@ -2739,6 +2796,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, > struct buffer_head *bh; > struct super_block *sb = dir->i_sb; > struct ext4_dir_entry_2 *de; > + bool ret_warn = false; > int restart; > int err; > > @@ -2769,6 +2827,11 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, > /* Block full, should compress but for now just split */ > dxtrace(printk(KERN_DEBUG "using %u of %u node entries\n", > dx_get_count(entries), dx_get_limit(entries))); > + > + if (frame - frames + 1 >= ext4_dir_htree_level(sb) || > + EXT4_SB(sb)->s_warning_dir_size) > + ret_warn = dir_size_in_warning_range(frames, frame, dir); > + > /* Need to split index? */ > if (dx_get_count(entries) == dx_get_limit(entries)) { > ext4_lblk_t newblock; > @@ -2935,6 +2998,8 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname, > */ > if (restart && err == 0) > goto again; > + if (err == 0 && ret_warn) > + err = -ENOBUFS; > return err; > } > > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > index 07242d7..a3179b2 100644 > --- a/fs/ext4/super.c > +++ b/fs/ext4/super.c > @@ -1901,6 +1901,8 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token, > sbi->s_li_wait_mult = arg; > } else if (token == Opt_max_dir_size_kb) { > sbi->s_max_dir_size_kb = arg; > + /* reset s_warning_dir_size and make it re-calculated */ > + sbi->s_warning_dir_size = 0; > } else if (token == Opt_stripe) { > sbi->s_stripe = arg; > } else if (token == Opt_resuid) { > diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c > index 3a71a16..575f318 100644 > --- a/fs/ext4/sysfs.c > +++ b/fs/ext4/sysfs.c > @@ -182,6 +182,7 @@ static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf) > EXT4_RW_ATTR_SBI_UI(inode_goal, s_inode_goal); > EXT4_RW_ATTR_SBI_UI(max_dir_size, s_max_dir_size_kb); > EXT4_RW_ATTR_SBI_UI(max_dir_size_kb, s_max_dir_size_kb); > +EXT4_RW_ATTR_SBI_UI(warning_dir_size, s_warning_dir_size); > EXT4_RW_ATTR_SBI_UI(mb_stats, s_mb_stats); > EXT4_RW_ATTR_SBI_UI(mb_max_to_scan, s_mb_max_to_scan); > EXT4_RW_ATTR_SBI_UI(mb_min_to_scan, s_mb_min_to_scan); > @@ -214,6 +215,7 @@ static ssize_t journal_task_show(struct ext4_sb_info *sbi, char *buf) > ATTR_LIST(inode_goal), > ATTR_LIST(max_dir_size), > ATTR_LIST(max_dir_size_kb), > + ATTR_LIST(warning_dir_size), > ATTR_LIST(mb_stats), > ATTR_LIST(mb_max_to_scan), > ATTR_LIST(mb_min_to_scan), > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 05:27:08 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 15:27:08 +1000 Subject: [lustre-devel] [PATCH 17/22] ext4: optimize ext4_journal_callback_add In-Reply-To: <1563758631-29550-18-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-18-git-send-email-jsimmons@infradead.org> Message-ID: <87sgqyod03.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > Change list_add_tail to list_add. It gives advantages to ldiskfs > in tgt_cb_last_committed. In the beginning of list will be placed > thandles with the highest transaction numbers. So at the first > iterations we will have the highest transno. It will save from > extra call of ptlrpc_commit_replies. If only more commit messages were like this !! Thanks! I suspect it would be better for that thing that needs to see the highest transno first, to find a way to look at the end of the list instead of the beginning. This isn't the sort of change that can land in ext4. NeilBrown > > Signed-off-by: James Simmons > --- > fs/ext4/ext4_jbd2.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h > index 75a5309..5ebf8ee 100644 > --- a/fs/ext4/ext4_jbd2.h > +++ b/fs/ext4/ext4_jbd2.h > @@ -169,7 +169,7 @@ static inline void _ext4_journal_callback_add(handle_t *handle, > struct ext4_journal_cb_entry *jce) > { > /* Add the jce to transaction's private list */ > - list_add_tail(&jce->jce_list, &handle->h_transaction->t_private_list); > + list_add(&jce->jce_list, &handle->h_transaction->t_private_list); > } > > static inline void ext4_journal_callback_add(handle_t *handle, > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 05:29:44 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 15:29:44 +1000 Subject: [lustre-devel] [PATCH 19/22] ext4: don't check before replay In-Reply-To: <1563758631-29550-20-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-20-git-send-email-jsimmons@infradead.org> Message-ID: <87pnm2ocvr.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > When ldiskfs run in failover mode whith read-only disk. > Part of allocation updates are lost and ldiskfs may fail > while mounting this is due to inconsistent state of > group-descriptor. Group-descriptor check is added after > journal replay. I think this needs to be enabled by a mount option or super-block flag. NeilBrown > > Signed-off-by: James Simmons > --- > fs/ext4/super.c | 11 ++++++----- > 1 file changed, 6 insertions(+), 5 deletions(-) > > diff --git a/fs/ext4/super.c b/fs/ext4/super.c > index a3179b2..b818acb 100644 > --- a/fs/ext4/super.c > +++ b/fs/ext4/super.c > @@ -4255,11 +4255,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) > } > } > sbi->s_gdb_count = db_count; > - if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { > - ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); > - ret = -EFSCORRUPTED; > - goto failed_mount2; > - } > > timer_setup(&sbi->s_err_report, print_daily_error_info, 0); > > @@ -4401,6 +4396,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) > sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; > > no_journal: > + if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { > + ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); > + ret = -EFSCORRUPTED; > + goto failed_mount_wq; > + } > + > if (!test_opt(sb, NO_MBCACHE)) { > sbi->s_ea_block_cache = ext4_xattr_create_cache(); > if (!sbi->s_ea_block_cache) { > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 05:30:55 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 15:30:55 +1000 Subject: [lustre-devel] [PATCH 20/22] ext4: use GFP_NOFS in ext4_inode_attach_jinode In-Reply-To: <1563758631-29550-21-git-send-email-jsimmons@infradead.org> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-21-git-send-email-jsimmons@infradead.org> Message-ID: <87muh6octs.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: If you need to call this from a context where GFP_KERNEL is not safe, use memalloc_nofs_{save,restore}(). NeilBrown > Signed-off-by: James Simmons > --- > fs/ext4/inode.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > index bf00dfc..ca72097 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -4422,7 +4422,7 @@ int ext4_inode_attach_jinode(struct inode *inode) > if (ei->jinode || !EXT4_SB(inode->i_sb)->s_journal) > return 0; > > - jinode = jbd2_alloc_inode(GFP_KERNEL); > + jinode = jbd2_alloc_inode(GFP_NOFS); > spin_lock(&inode->i_lock); > if (!ei->jinode) { > if (!jinode) { > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From neilb at suse.com Mon Jul 22 06:46:04 2019 From: neilb at suse.com (NeilBrown) Date: Mon, 22 Jul 2019 16:46:04 +1000 Subject: [lustre-devel] [PATCH 19/22] ext4: don't check before replay In-Reply-To: <506765DD-0068-469E-ADA4-2C71B8B60114@cloudlinux.com> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-20-git-send-email-jsimmons@infradead.org> <87pnm2ocvr.fsf@notabene.neil.brown.name> <506765DD-0068-469E-ADA4-2C71B8B60114@cloudlinux.com> Message-ID: <87wogak1n7.fsf@notabene.neil.brown.name> On Mon, Jul 22 2019, Alexey Lyashkov wrote: > Why? > Purpose of this patch is simple and don’t addressed a failover in general. > Crash can occurred in commit time - when journal _partially_ flushed to the FS. Checking any FS metadata in this time is wrong, because we have no guarantee to be consistence. > But checking an after journal replay is fine, it check have verification no corruption hit and FS is fine. If the corruption can occur in non-ldiskfs usage, and would be fixed by a journal replay, then yes - the patch looks like a good idea. Possibly I misunderstood the source of the corruption... maybe if that could be made clearer in the commit message, that would help. Thanks, NeilBrown > > >> 22 июля 2019 г., в 8:29, NeilBrown написал(а): >> >> On Sun, Jul 21 2019, James Simmons wrote: >> >>> When ldiskfs run in failover mode whith read-only disk. >>> Part of allocation updates are lost and ldiskfs may fail >>> while mounting this is due to inconsistent state of >>> group-descriptor. Group-descriptor check is added after >>> journal replay. >> >> I think this needs to be enabled by a mount option or super-block flag. >> >> NeilBrown >> >> >>> >>> Signed-off-by: James Simmons >>> --- >>> fs/ext4/super.c | 11 ++++++----- >>> 1 file changed, 6 insertions(+), 5 deletions(-) >>> >>> diff --git a/fs/ext4/super.c b/fs/ext4/super.c >>> index a3179b2..b818acb 100644 >>> --- a/fs/ext4/super.c >>> +++ b/fs/ext4/super.c >>> @@ -4255,11 +4255,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) >>> } >>> } >>> sbi->s_gdb_count = db_count; >>> - if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { >>> - ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); >>> - ret = -EFSCORRUPTED; >>> - goto failed_mount2; >>> - } >>> >>> timer_setup(&sbi->s_err_report, print_daily_error_info, 0); >>> >>> @@ -4401,6 +4396,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) >>> sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; >>> >>> no_journal: >>> + if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { >>> + ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); >>> + ret = -EFSCORRUPTED; >>> + goto failed_mount_wq; >>> + } >>> + >>> if (!test_opt(sb, NO_MBCACHE)) { >>> sbi->s_ea_block_cache = ext4_xattr_create_cache(); >>> if (!sbi->s_ea_block_cache) { >>> -- >>> 1.8.3.1 >> _______________________________________________ >> lustre-devel mailing list >> lustre-devel at lists.lustre.org >> http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From green at whamcloud.com Mon Jul 22 06:56:24 2019 From: green at whamcloud.com (Oleg Drokin) Date: Mon, 22 Jul 2019 06:56:24 +0000 Subject: [lustre-devel] [PATCH 19/22] ext4: don't check before replay In-Reply-To: <87wogak1n7.fsf@notabene.neil.brown.name> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-20-git-send-email-jsimmons@infradead.org> <87pnm2ocvr.fsf@notabene.neil.brown.name> <506765DD-0068-469E-ADA4-2C71B8B60114@cloudlinux.com> <87wogak1n7.fsf@notabene.neil.brown.name> Message-ID: <82691452-7473-4CAB-BE70-0C89238D5720@whamcloud.com> > On Jul 22, 2019, at 2:46 AM, NeilBrown wrote: > > On Mon, Jul 22 2019, Alexey Lyashkov wrote: > >> Why? >> Purpose of this patch is simple and don’t addressed a failover in general. >> Crash can occurred in commit time - when journal _partially_ flushed to the FS. Checking any FS metadata in this time is wrong, because we have no guarantee to be consistence. >> But checking an after journal replay is fine, it check have verification no corruption hit and FS is fine. > > If the corruption can occur in non-ldiskfs usage, and would be fixed by > a journal replay, then yes - the patch looks like a good idea. > > Possibly I misunderstood the source of the corruption... maybe if that > could be made clearer in the commit message, that would help. I think the argument is: wtf do we even look at metadata (or anything, really) before journal replay. The patch is actually good because it does move the read after the journal replay though? > >> >> >>> 22 июля 2019 г., в 8:29, NeilBrown написал(а): >>> >>> On Sun, Jul 21 2019, James Simmons wrote: >>> >>>> When ldiskfs run in failover mode whith read-only disk. >>>> Part of allocation updates are lost and ldiskfs may fail >>>> while mounting this is due to inconsistent state of >>>> group-descriptor. Group-descriptor check is added after >>>> journal replay. >>> >>> I think this needs to be enabled by a mount option or super-block flag. >>> >>> NeilBrown >>> >>> >>>> >>>> Signed-off-by: James Simmons >>>> --- >>>> fs/ext4/super.c | 11 ++++++----- >>>> 1 file changed, 6 insertions(+), 5 deletions(-) >>>> >>>> diff --git a/fs/ext4/super.c b/fs/ext4/super.c >>>> index a3179b2..b818acb 100644 >>>> --- a/fs/ext4/super.c >>>> +++ b/fs/ext4/super.c >>>> @@ -4255,11 +4255,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) >>>> } >>>> } >>>> sbi->s_gdb_count = db_count; >>>> - if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { >>>> - ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); >>>> - ret = -EFSCORRUPTED; >>>> - goto failed_mount2; >>>> - } >>>> >>>> timer_setup(&sbi->s_err_report, print_daily_error_info, 0); >>>> >>>> @@ -4401,6 +4396,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) >>>> sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; >>>> >>>> no_journal: >>>> + if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { >>>> + ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); >>>> + ret = -EFSCORRUPTED; >>>> + goto failed_mount_wq; >>>> + } >>>> + >>>> if (!test_opt(sb, NO_MBCACHE)) { >>>> sbi->s_ea_block_cache = ext4_xattr_create_cache(); >>>> if (!sbi->s_ea_block_cache) { >>>> -- >>>> 1.8.3.1 >>> _______________________________________________ >>> lustre-devel mailing list >>> lustre-devel at lists.lustre.org >>> http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org From green at whamcloud.com Mon Jul 22 07:16:06 2019 From: green at whamcloud.com (Oleg Drokin) Date: Mon, 22 Jul 2019 07:16:06 +0000 Subject: [lustre-devel] [PATCH 04/22] ext4: export inode management In-Reply-To: <87o91mpu11.fsf@notabene.neil.brown.name> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-5-git-send-email-jsimmons@infradead.org> <87o91mpu11.fsf@notabene.neil.brown.name> Message-ID: <700E5EAE-5BD9-4F40-95CF-3419F69070D3@whamcloud.com> > On Jul 22, 2019, at 12:34 AM, NeilBrown wrote: > > On Sun, Jul 21 2019, James Simmons wrote: > >> Make ext4_delete_entry() exportable for osd-ldiskfs. Also add >> exportable ext4_create_inode(). > > Why can't lustre use vfs_unlink like everyone else? And vfs_mknod()? > My hope is that what we land upstream will use generic interfaces only. > If there is something that osd needs to do that the generic interfaces > cannot support, then we need to look at how to add that to the generic > interface. That’s probably going to be a tough thing to do. At times we need certain things that are bad from vfs standpoint in general sense, but because we have various outside guarantees from locking and such - we can still do them. nothing precise comes to mind now, but I remember various games with nlink count/moving and resurrecting such files. We also have wider “transaction boundaries”. Where say normal via-vfs transaction is metadata only, we can request certain data (from ext4 perspective, but metadata from Lustre) to be part of a particular transaction. From jsimmons at infradead.org Tue Jul 23 00:07:38 2019 From: jsimmons at infradead.org (James Simmons) Date: Tue, 23 Jul 2019 01:07:38 +0100 (BST) Subject: [lustre-devel] [PATCH 01/22] ext4: add i_fs_version In-Reply-To: <87wogapuz2.fsf@notabene.neil.brown.name> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-2-git-send-email-jsimmons@infradead.org> <87wogapuz2.fsf@notabene.neil.brown.name> Message-ID: > > From: James Simmons > > > > Add inode version field that osd-ldiskfs uses. > > We need more words here. What is i_fs_version used for? > > (I'll probably find out as I keep reading, but I need to know > the intention first, or I cannot properly review the patches > that make use of it. > ) Sadly these patches don't contain much in terms of why they exist. I did some digging and it seems at one time Lustre did use the i_version field directly for it recovery process. It seems ext4 stomps on its i_version independently of lustre so it can't be trusted in use of recovery. > NeilBrown > > > > > > Signed-off-by: James Simmons > > --- > > fs/ext4/ext4.h | 2 ++ > > fs/ext4/ialloc.c | 1 + > > fs/ext4/inode.c | 4 ++-- > > 3 files changed, 5 insertions(+), 2 deletions(-) > > > > diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h > > index 1cb6785..8abbcab 100644 > > --- a/fs/ext4/ext4.h > > +++ b/fs/ext4/ext4.h > > @@ -1063,6 +1063,8 @@ struct ext4_inode_info { > > struct dquot *i_dquot[MAXQUOTAS]; > > #endif > > > > + u64 i_fs_version; > > + > > /* Precomputed uuid+inum+igen checksum for seeding inode checksums */ > > __u32 i_csum_seed; > > > > diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c > > index 764ff4c..09ae4a4 100644 > > --- a/fs/ext4/ialloc.c > > +++ b/fs/ext4/ialloc.c > > @@ -1100,6 +1100,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir, > > ei->i_dtime = 0; > > ei->i_block_group = group; > > ei->i_last_alloc_group = ~0; > > + ei->i_fs_version = 0; > > > > ext4_set_inode_flags(inode); > > if (IS_DIRSYNC(inode)) > > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > > index c7f77c6..6e66175 100644 > > --- a/fs/ext4/inode.c > > +++ b/fs/ext4/inode.c > > @@ -4806,14 +4806,14 @@ static inline void ext4_inode_set_iversion_queried(struct inode *inode, u64 val) > > if (unlikely(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) > > inode_set_iversion_raw(inode, val); > > else > > - inode_set_iversion_queried(inode, val); > > + EXT4_I(inode)->i_fs_version = val; > > } > > static inline u64 ext4_inode_peek_iversion(const struct inode *inode) > > { > > if (unlikely(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) > > return inode_peek_iversion_raw(inode); > > else > > - return inode_peek_iversion(inode); > > + return EXT4_I(inode)->i_fs_version; > > } > > > > struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, > > -- > > 1.8.3.1 > From jsimmons at infradead.org Tue Jul 23 00:23:20 2019 From: jsimmons at infradead.org (James Simmons) Date: Tue, 23 Jul 2019 01:23:20 +0100 (BST) Subject: [lustre-devel] sanity-hsm and libtool In-Reply-To: References: Message-ID: > Le 19/07/2019 17:21, « James Simmons » a écrit : > > >     > Hi! >     > >     >  >     > >     > I'm trying to run sanity-hsm.sh tests in my lustre source directory as I'm used to. >     > >     > Since libtool patch was landed, tools like lhsmtool_posix are executed through a wrapper and appear in process list as > 'lt-lhsmtool_posix'. >     > >     > Some tests try to find and kill them, relying on command like: >     > >     >  >     > >     > "ps -C $HSMTOOL" >     > >     >  >     > >     > Even if run through "libtool execute ps -C $HSMTOOL" (as it is in the source right now) this command does not catch the > proper process and >     > so fail the test. >     > >     >  >     > >     > I'm wondering what the proper way to run the test suite to have it working and how this is working in Maloo? >     > >     > I'm doing: >     > >     >  >     > >     > git clone >     > >     > autogen >     > >     > configure >     > >     > make >     > >     > sudo REFORMAT=: ./lustre/tests/sanity-hsm.sh >     > >     >  >     > >     >  >     > >     >  >     > >     > By the way, when hsm helper functions were moved from sanity-hsm.sh to test-framework.sh (f172b1168, for PCC), some of > them were just >     > copied and not moved. So there are several duplicates between these 2 files. I think that's not on purpose? > >     What version of lustre are you testing with? Their was a patch landed to >     handle this. > >     LU-11742 test: have libtool execute the test binaries > >     which is lustre commit f9e5224fbb60bb8b44753b7be10cb06108627f89. This has >     been back ported to 2.12 LTS. Can you see if your lustre tree has this >     fix. > >     See https://www.gnu.org/software/libtool/manual/html_node/Debugging-executables.html >     for details about using libtool against the binary wrappers. > > I'm running master. > That's exactly the patch which is giving me issue. > I can run sanity-hsm successfully prior to this patch, not after. > > Aurélien > > > I concur : I cannot run sanity-hsm on master. Works fine when checking out the commit right before the libtool patch , breaks if the patch > is applied. > > With some testing it appears this is because "libtool execute" does does not use the PATH environment variable when it resolves paths : > > $> pwd > /home/user/lustre-release > $> export PATH=lustre/utils:/usr/bin > $> which lhsmtool_posix > /home/user/lustre-release/lustre/utils/lhsmtool_posix > $> libtool execute echo lhsmtool_posix > lhsmtool_posix > $> libtool execute echo lustre/utils/lhsmtool_posix > /home/user/lustre-release/luster/utils/.libs/lhsmtool_posix > > I suspect this works on Maloo because Maloo does not run tests from the git repo but rather from installed rpms (=> no libtool wrappers). > > @James, I can see you asked me a follow-up review on the patch that introduces this regressions, and I did not answer, Sorry about that. I > will try to keep better track of patches I reviewed at least once... In this spirit, I will try to update my review of this change this > weekend. =) This is strange since Oleg does his testing in the lustre source tree directly. I would think he would have encounter this issue. I need to looking how libtool does its path searches. From green at whamcloud.com Tue Jul 23 01:40:48 2019 From: green at whamcloud.com (Oleg Drokin) Date: Tue, 23 Jul 2019 01:40:48 +0000 Subject: [lustre-devel] sanity-hsm and libtool In-Reply-To: References: Message-ID: <3BEAD335-B8BA-42EE-940F-B482B3FB3B1C@whamcloud.com> >> I concur : I cannot run sanity-hsm on master. Works fine when checking out the commit right before the libtool patch , breaks if the patch >> is applied. >> >> With some testing it appears this is because "libtool execute" does does not use the PATH environment variable when it resolves paths : >> >> $> pwd >> /home/user/lustre-release >> $> export PATH=lustre/utils:/usr/bin >> $> which lhsmtool_posix >> /home/user/lustre-release/lustre/utils/lhsmtool_posix >> $> libtool execute echo lhsmtool_posix >> lhsmtool_posix >> $> libtool execute echo lustre/utils/lhsmtool_posix >> /home/user/lustre-release/luster/utils/.libs/lhsmtool_posix >> >> I suspect this works on Maloo because Maloo does not run tests from the git repo but rather from installed rpms (=> no libtool wrappers). >> >> @James, I can see you asked me a follow-up review on the patch that introduces this regressions, and I did not answer, Sorry about that. I >> will try to keep better track of patches I reviewed at least once... In this spirit, I will try to update my review of this change this >> weekend. =) > > This is strange since Oleg does his testing in the lustre source tree > directly. I would think he would have encounter this issue. I need > to looking how libtool does its path searches. I build with configure --disable-shared to sidestep this issue. From adilger at whamcloud.com Tue Jul 23 01:56:56 2019 From: adilger at whamcloud.com (Andreas Dilger) Date: Tue, 23 Jul 2019 01:56:56 +0000 Subject: [lustre-devel] [PATCH 20/22] ext4: use GFP_NOFS in ext4_inode_attach_jinode In-Reply-To: <87muh6octs.fsf@notabene.neil.brown.name> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-21-git-send-email-jsimmons@infradead.org>, <87muh6octs.fsf@notabene.neil.brown.name> Message-ID: That interface has only existed for a handful of kernel releases, so was/is not a viable option for earlier kernels. Cheers, Andreas > On Jul 21, 2019, at 23:31, NeilBrown wrote: > > On Sun, Jul 21 2019, James Simmons wrote: > > If you need to call this from a context where GFP_KERNEL is not safe, > use memalloc_nofs_{save,restore}(). > > NeilBrown > > > >> Signed-off-by: James Simmons >> --- >> fs/ext4/inode.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c >> index bf00dfc..ca72097 100644 >> --- a/fs/ext4/inode.c >> +++ b/fs/ext4/inode.c >> @@ -4422,7 +4422,7 @@ int ext4_inode_attach_jinode(struct inode *inode) >> if (ei->jinode || !EXT4_SB(inode->i_sb)->s_journal) >> return 0; >> >> - jinode = jbd2_alloc_inode(GFP_KERNEL); >> + jinode = jbd2_alloc_inode(GFP_NOFS); >> spin_lock(&inode->i_lock); >> if (!ei->jinode) { >> if (!jinode) { >> -- >> 1.8.3.1 From adilger at whamcloud.com Tue Jul 23 01:57:41 2019 From: adilger at whamcloud.com (Andreas Dilger) Date: Tue, 23 Jul 2019 01:57:41 +0000 Subject: [lustre-devel] [PATCH 19/22] ext4: don't check before replay In-Reply-To: <87pnm2ocvr.fsf@notabene.neil.brown.name> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-20-git-send-email-jsimmons@infradead.org>, <87pnm2ocvr.fsf@notabene.neil.brown.name> Message-ID: <3F8B391A-6FFD-4C44-BD87-D12AD8456651@whamcloud.com> Actually, I think this patch would be OK to push upstream. Cheers, Andreas > On Jul 21, 2019, at 23:29, NeilBrown wrote: > >> On Sun, Jul 21 2019, James Simmons wrote: >> >> When ldiskfs run in failover mode whith read-only disk. >> Part of allocation updates are lost and ldiskfs may fail >> while mounting this is due to inconsistent state of >> group-descriptor. Group-descriptor check is added after >> journal replay. > > I think this needs to be enabled by a mount option or super-block flag. > > NeilBrown > > >> >> Signed-off-by: James Simmons >> --- >> fs/ext4/super.c | 11 ++++++----- >> 1 file changed, 6 insertions(+), 5 deletions(-) >> >> diff --git a/fs/ext4/super.c b/fs/ext4/super.c >> index a3179b2..b818acb 100644 >> --- a/fs/ext4/super.c >> +++ b/fs/ext4/super.c >> @@ -4255,11 +4255,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) >> } >> } >> sbi->s_gdb_count = db_count; >> - if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { >> - ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); >> - ret = -EFSCORRUPTED; >> - goto failed_mount2; >> - } >> >> timer_setup(&sbi->s_err_report, print_daily_error_info, 0); >> >> @@ -4401,6 +4396,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) >> sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; >> >> no_journal: >> + if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { >> + ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); >> + ret = -EFSCORRUPTED; >> + goto failed_mount_wq; >> + } >> + >> if (!test_opt(sb, NO_MBCACHE)) { >> sbi->s_ea_block_cache = ext4_xattr_create_cache(); >> if (!sbi->s_ea_block_cache) { >> -- >> 1.8.3.1 From green at whamcloud.com Tue Jul 23 02:01:08 2019 From: green at whamcloud.com (Oleg Drokin) Date: Tue, 23 Jul 2019 02:01:08 +0000 Subject: [lustre-devel] [PATCH 19/22] ext4: don't check before replay In-Reply-To: <3F8B391A-6FFD-4C44-BD87-D12AD8456651@whamcloud.com> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-20-git-send-email-jsimmons@infradead.org> <87pnm2ocvr.fsf@notabene.neil.brown.name> <3F8B391A-6FFD-4C44-BD87-D12AD8456651@whamcloud.com> Message-ID: what I think needs to happen is a better description. Something like: In a crash group descriptors might not be written completely in place that would lead to FS error message on subsequent mount. Move the check to after journal replay to ensure we are dealing with up to date (and hopefully correct) information before declaring the FS as bad. > On Jul 22, 2019, at 9:57 PM, Andreas Dilger wrote: > > Actually, I think this patch would be OK to push upstream. > > Cheers, Andreas > >> On Jul 21, 2019, at 23:29, NeilBrown wrote: >> >>> On Sun, Jul 21 2019, James Simmons wrote: >>> >>> When ldiskfs run in failover mode whith read-only disk. >>> Part of allocation updates are lost and ldiskfs may fail >>> while mounting this is due to inconsistent state of >>> group-descriptor. Group-descriptor check is added after >>> journal replay. >> >> I think this needs to be enabled by a mount option or super-block flag. >> >> NeilBrown >> >> >>> >>> Signed-off-by: James Simmons >>> --- >>> fs/ext4/super.c | 11 ++++++----- >>> 1 file changed, 6 insertions(+), 5 deletions(-) >>> >>> diff --git a/fs/ext4/super.c b/fs/ext4/super.c >>> index a3179b2..b818acb 100644 >>> --- a/fs/ext4/super.c >>> +++ b/fs/ext4/super.c >>> @@ -4255,11 +4255,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) >>> } >>> } >>> sbi->s_gdb_count = db_count; >>> - if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { >>> - ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); >>> - ret = -EFSCORRUPTED; >>> - goto failed_mount2; >>> - } >>> >>> timer_setup(&sbi->s_err_report, print_daily_error_info, 0); >>> >>> @@ -4401,6 +4396,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) >>> sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; >>> >>> no_journal: >>> + if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { >>> + ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); >>> + ret = -EFSCORRUPTED; >>> + goto failed_mount_wq; >>> + } >>> + >>> if (!test_opt(sb, NO_MBCACHE)) { >>> sbi->s_ea_block_cache = ext4_xattr_create_cache(); >>> if (!sbi->s_ea_block_cache) { >>> -- >>> 1.8.3.1 From adilger at whamcloud.com Tue Jul 23 02:01:26 2019 From: adilger at whamcloud.com (Andreas Dilger) Date: Tue, 23 Jul 2019 02:01:26 +0000 Subject: [lustre-devel] [PATCH 17/22] ext4: optimize ext4_journal_callback_add In-Reply-To: <87sgqyod03.fsf@notabene.neil.brown.name> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-18-git-send-email-jsimmons@infradead.org>, <87sgqyod03.fsf@notabene.neil.brown.name> Message-ID: <80826E7E-8D69-44BA-B8CC-03B62EC98D42@whamcloud.com> This might be accommodated by a new API variant that allows the caller to add this commit callback at the head of the list instead of the tail. The main question is whether such an API would be accepted upstream without a user? Cheers, Andreas > On Jul 21, 2019, at 23:27, NeilBrown wrote: > >> On Sun, Jul 21 2019, James Simmons wrote: >> >> Change list_add_tail to list_add. It gives advantages to ldiskfs >> in tgt_cb_last_committed. In the beginning of list will be placed >> thandles with the highest transaction numbers. So at the first >> iterations we will have the highest transno. It will save from >> extra call of ptlrpc_commit_replies. > > If only more commit messages were like this !! Thanks! > > I suspect it would be better for that thing that needs to see the > highest transno first, to find a way to look at the end of the list > instead of the beginning. > > This isn't the sort of change that can land in ext4. > > NeilBrown > > >> >> Signed-off-by: James Simmons >> --- >> fs/ext4/ext4_jbd2.h | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h >> index 75a5309..5ebf8ee 100644 >> --- a/fs/ext4/ext4_jbd2.h >> +++ b/fs/ext4/ext4_jbd2.h >> @@ -169,7 +169,7 @@ static inline void _ext4_journal_callback_add(handle_t *handle, >> struct ext4_journal_cb_entry *jce) >> { >> /* Add the jce to transaction's private list */ >> - list_add_tail(&jce->jce_list, &handle->h_transaction->t_private_list); >> + list_add(&jce->jce_list, &handle->h_transaction->t_private_list); >> } >> >> static inline void ext4_journal_callback_add(handle_t *handle, >> -- >> 1.8.3.1 From adilger at whamcloud.com Tue Jul 23 02:07:27 2019 From: adilger at whamcloud.com (Andreas Dilger) Date: Tue, 23 Jul 2019 02:07:27 +0000 Subject: [lustre-devel] [PATCH 08/22] ext4: kill off struct dx_root In-Reply-To: <87ftmypt62.fsf@notabene.neil.brown.name> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-9-git-send-email-jsimmons@infradead.org>, <87ftmypt62.fsf@notabene.neil.brown.name> Message-ID: This is needed so that we can add extra data to struct ext4_dir_entry (Lustre FID) via the "dirdata" feature, and struct dx_root assumes "." and ".." entries are a fixed size. So there is a reason for the patch, and I think it would be acceptable upstream. Artem @ Cray has an updated version of this patch that was submitted upstream to linux-ext4 and reviewed, but it needs to be refreshed again. Cheers, Andreas > On Jul 21, 2019, at 22:52, NeilBrown wrote: > >> On Sun, Jul 21 2019, James Simmons wrote: >> >> Use struct dx_root_info directly. > > This looks like a style change. > Instead of a 'struct' that models the start of an on-disk directory > block, the location of some fields is done using calculations instead. > > Why would we want to do that? Might we want dx_root_info to be at a > different offset in the directory ?? > > NeilBrown From neilb at suse.com Tue Jul 23 02:54:08 2019 From: neilb at suse.com (NeilBrown) Date: Tue, 23 Jul 2019 12:54:08 +1000 Subject: [lustre-devel] [PATCH 10/11] lustre: ldlm: checkpatch cleanup In-Reply-To: <1563760338-806-11-git-send-email-jsimmons@infradead.org> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> <1563760338-806-11-git-send-email-jsimmons@infradead.org> Message-ID: <87tvbdjwa7.fsf@notabene.neil.brown.name> On Sun, Jul 21 2019, James Simmons wrote: > Many checkpatch errors exist in the ldlm layer. This address > a good chuck of them. Other are left since future patches will > cleanup those areas. Others will need more code rework so this > patch handles the simple cases. This is a good step forward > toward proper kernel code style compliance. > > Signed-off-by: James Simmons > --- > fs/lustre/ldlm/ldlm_extent.c | 1 - > fs/lustre/ldlm/ldlm_flock.c | 15 ++++++++------- > fs/lustre/ldlm/ldlm_internal.h | 5 +++-- > fs/lustre/ldlm/ldlm_lib.c | 4 ++-- > fs/lustre/ldlm/ldlm_lock.c | 8 +++----- > fs/lustre/ldlm/ldlm_lockd.c | 22 +++++++++++++--------- > fs/lustre/ldlm/ldlm_pool.c | 3 ++- > fs/lustre/ldlm/ldlm_request.c | 18 ++++++++---------- > 8 files changed, 39 insertions(+), 37 deletions(-) > > diff --git a/fs/lustre/ldlm/ldlm_extent.c b/fs/lustre/ldlm/ldlm_extent.c > index 99aef0b..0695f7e 100644 > --- a/fs/lustre/ldlm/ldlm_extent.c > +++ b/fs/lustre/ldlm/ldlm_extent.c > @@ -79,7 +79,6 @@ u64 ldlm_extent_shift_kms(struct ldlm_lock *lock, u64 old_kms) > ldlm_set_kms_ignore(lock); > > list_for_each_entry(lck, &res->lr_granted, l_res_link) { > - > if (ldlm_is_kms_ignore(lck)) > continue; > > diff --git a/fs/lustre/ldlm/ldlm_flock.c b/fs/lustre/ldlm/ldlm_flock.c > index 4316b2b..d2b4f0d 100644 > --- a/fs/lustre/ldlm/ldlm_flock.c > +++ b/fs/lustre/ldlm/ldlm_flock.c > @@ -118,7 +118,7 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req) > struct ldlm_lock *new2 = NULL; > enum ldlm_mode mode = req->l_req_mode; > int added = (mode == LCK_NL); > - int splitted = 0; > + int split = 0; > const struct ldlm_callback_suite null_cbs = { }; > > CDEBUG(D_DLMTRACE, > @@ -146,7 +146,6 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req) > * We may have to merge or split existing locks. > */ > list_for_each_entry_safe_from(lock, tmp, &res->lr_granted, l_res_link) { > - > if (!ldlm_same_flock_owner(lock, new)) > break; > > @@ -246,7 +245,7 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req) > goto reprocess; > } > > - splitted = 1; > + split = 1; > > new2->l_granted_mode = lock->l_granted_mode; > new2->l_policy_data.l_flock.pid = > @@ -273,7 +272,7 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req) > } > > /* if new2 is created but never used, destroy it*/ > - if (splitted == 0 && new2) > + if (split == 0 && new2) > ldlm_lock_destroy_nolock(new2); > > /* At this point we're granting the lock request. */ > @@ -345,12 +344,14 @@ static int ldlm_process_flock_lock(struct ldlm_lock *req) > "client-side enqueue returned a blocked lock, sleeping"); > > /* Go to sleep until the lock is granted. */ > - rc = l_wait_event_abortable(lock->l_waitq, is_granted_or_cancelled(lock)); > - > + rc = l_wait_event_abortable(lock->l_waitq, > + is_granted_or_cancelled(lock)); > if (rc) { > lock_res_and_lock(lock); > > - /* client side - set flag to prevent lock from being put on LRU list */ > + /* client side - set flag to prevent lock from being put on > + * LRU list > + */ > ldlm_set_cbpending(lock); > unlock_res_and_lock(lock); > > diff --git a/fs/lustre/ldlm/ldlm_internal.h b/fs/lustre/ldlm/ldlm_internal.h > index d8dcf8a..05d5b08 100644 > --- a/fs/lustre/ldlm/ldlm_internal.h > +++ b/fs/lustre/ldlm/ldlm_internal.h > @@ -146,6 +146,7 @@ void ldlm_lock_addref_internal_nolock(struct ldlm_lock *lock, > void ldlm_lock_decref_internal(struct ldlm_lock *lock, enum ldlm_mode mode); > void ldlm_lock_decref_internal_nolock(struct ldlm_lock *lock, > enum ldlm_mode mode); > +struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock); > int ldlm_run_ast_work(struct ldlm_namespace *ns, struct list_head *rpc_list, > enum ldlm_desc_ast_t ast_type); > int ldlm_lock_remove_from_lru_check(struct ldlm_lock *lock, time_t last_use); > @@ -212,8 +213,8 @@ enum ldlm_policy_res { > #define LDLM_POOL_SYSFS_SET_int(a, b) { a = b; } > #define LDLM_POOL_SYSFS_PRINT_u64(v) sprintf(buf, "%lld\n", v) > #define LDLM_POOL_SYSFS_SET_u64(a, b) { a = b; } > -#define LDLM_POOL_SYSFS_PRINT_atomic(v) sprintf(buf, "%d\n", atomic_read(&v)) > -#define LDLM_POOL_SYSFS_SET_atomic(a, b) atomic_set(&a, b) > +#define LDLM_POOL_SYSFS_PRINT_atomic(v) sprintf(buf, "%d\n", atomic_read(&(v))) > +#define LDLM_POOL_SYSFS_SET_atomic(a, b) atomic_set(&(a), b) > > #define LDLM_POOL_SYSFS_READER_SHOW(var, type) \ > static ssize_t var##_show(struct kobject *kobj, \ > diff --git a/fs/lustre/ldlm/ldlm_lib.c b/fs/lustre/ldlm/ldlm_lib.c > index 9c61b33..887507d 100644 > --- a/fs/lustre/ldlm/ldlm_lib.c > +++ b/fs/lustre/ldlm/ldlm_lib.c > @@ -832,9 +832,9 @@ int ldlm_error2errno(enum ldlm_error error) > result = -EBADF; > break; > default: > - if (((int)error) < 0) /* cast to signed type */ > + if (((int)error) < 0) { /* cast to signed type */ > result = error; /* as enum ldlm_error can be unsigned */ > - else { > + } else { > CERROR("Invalid DLM result code: %d\n", error); > result = -EPROTO; > } > diff --git a/fs/lustre/ldlm/ldlm_lock.c b/fs/lustre/ldlm/ldlm_lock.c > index 7ec5fc9..2f2b1ab 100644 > --- a/fs/lustre/ldlm/ldlm_lock.c > +++ b/fs/lustre/ldlm/ldlm_lock.c > @@ -874,7 +874,6 @@ static void search_granted_lock(struct list_head *queue, > struct ldlm_lock *lock, *mode_end, *policy_end; > > list_for_each_entry(lock, queue, l_res_link) { > - > mode_end = list_prev_entry(lock, l_sl_mode); > > if (lock->l_req_mode != req->l_req_mode) { > @@ -1354,8 +1353,7 @@ enum ldlm_mode ldlm_lock_match(struct ldlm_namespace *ns, u64 flags, > > /* check user's security context */ > if (lock->l_conn_export && > - sptlrpc_import_check_ctx( > - class_exp2cliimp(lock->l_conn_export))) { > + sptlrpc_import_check_ctx(class_exp2cliimp(lock->l_conn_export))) { > if (!(flags & LDLM_FL_TEST_LOCK)) > ldlm_lock_decref_internal(lock, mode); > rc = 0; > @@ -1443,7 +1441,7 @@ int ldlm_fill_lvb(struct ldlm_lock *lock, struct req_capsule *pill, > if (loc == RCL_CLIENT) > lvb = req_capsule_client_swab_get(pill, > &RMF_DLM_LVB, > - lustre_swab_ost_lvb_v1); > + lustre_swab_ost_lvb_v1); > else > lvb = req_capsule_server_sized_swab_get(pill, > &RMF_DLM_LVB, size, > @@ -1744,7 +1742,7 @@ static int ldlm_work_gl_ast_lock(struct ptlrpc_request_set *rqset, void *opaq) > return -ENOENT; > > gl_work = list_first_entry(arg->list, struct ldlm_glimpse_work, > - gl_list); > + gl_list); > list_del_init(&gl_work->gl_list); > > lock = gl_work->gl_lock; > diff --git a/fs/lustre/ldlm/ldlm_lockd.c b/fs/lustre/ldlm/ldlm_lockd.c > index 589b89d..56f042c 100644 > --- a/fs/lustre/ldlm/ldlm_lockd.c > +++ b/fs/lustre/ldlm/ldlm_lockd.c > @@ -210,9 +210,9 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req, > > if (lock->l_resource->lr_type != LDLM_PLAIN) { > ldlm_convert_policy_to_local(req->rq_export, > - dlm_req->lock_desc.l_resource.lr_type, > - &dlm_req->lock_desc.l_policy_data, > - &lock->l_policy_data); > + dlm_req->lock_desc.l_resource.lr_type, > + &dlm_req->lock_desc.l_policy_data, > + &lock->l_policy_data); > LDLM_DEBUG(lock, "completion AST, new policy data"); > } > > @@ -222,7 +222,7 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req, > sizeof(lock->l_resource->lr_name)) != 0) { > unlock_res_and_lock(lock); > rc = ldlm_lock_change_resource(ns, lock, > - &dlm_req->lock_desc.l_resource.lr_name); > + &dlm_req->lock_desc.l_resource.lr_name); > if (rc < 0) { > LDLM_ERROR(lock, "Failed to allocate resource"); > goto out; > @@ -286,7 +286,7 @@ static void ldlm_handle_gl_callback(struct ptlrpc_request *req, > struct ldlm_request *dlm_req, > struct ldlm_lock *lock) > { > - int rc = -ENOSYS; > + int rc = -ENXIO; Is this really a checkpatch warning? Is it safe? Is there a visible behaviour change here, or is the error status only used internally? There seem to be a few others ... maybe checkpatch doesn't like ENOSYS - probably reasonable. Everything else looks OK. Thanks for these! NeilBrown > > LDLM_DEBUG(lock, "client glimpse AST callback handler"); > > @@ -396,8 +396,10 @@ static int ldlm_bl_to_thread(struct ldlm_namespace *ns, > struct list_head *cancels, int count, > enum ldlm_cancel_flags cancel_flags) > { > + int rc = 0; > + > if (cancels && count == 0) > - return 0; > + return rc; > > if (cancel_flags & LCF_ASYNC) { > struct ldlm_bl_work_item *blwi; > @@ -407,7 +409,7 @@ static int ldlm_bl_to_thread(struct ldlm_namespace *ns, > return -ENOMEM; > init_blwi(blwi, ns, ld, cancels, count, lock, cancel_flags); > > - return __ldlm_bl_to_thread(blwi, cancel_flags); > + rc = __ldlm_bl_to_thread(blwi, cancel_flags); > } else { > /* if it is synchronous call do minimum mem alloc, as it could > * be triggered from kernel shrinker > @@ -416,8 +418,9 @@ static int ldlm_bl_to_thread(struct ldlm_namespace *ns, > > memset(&blwi, 0, sizeof(blwi)); > init_blwi(&blwi, ns, ld, cancels, count, lock, cancel_flags); > - return __ldlm_bl_to_thread(&blwi, cancel_flags); > + rc = __ldlm_bl_to_thread(&blwi, cancel_flags); > } > + return rc; > } > > int ldlm_bl_to_thread_lock(struct ldlm_namespace *ns, struct ldlm_lock_desc *ld, > @@ -446,7 +449,7 @@ static int ldlm_handle_setinfo(struct ptlrpc_request *req) > char *key; > void *val; > int keylen, vallen; > - int rc = -ENOSYS; > + int rc = -ENXIO; > > DEBUG_REQ(D_HSM, req, "%s: handle setinfo\n", obd->obd_name); > > @@ -875,6 +878,7 @@ int ldlm_get_ref(void) > void ldlm_put_ref(void) > { > int rc = 0; > + > mutex_lock(&ldlm_ref_mutex); > if (ldlm_refcount == 1) { > rc = ldlm_cleanup(); > diff --git a/fs/lustre/ldlm/ldlm_pool.c b/fs/lustre/ldlm/ldlm_pool.c > index 1f81795..6714c30 100644 > --- a/fs/lustre/ldlm/ldlm_pool.c > +++ b/fs/lustre/ldlm/ldlm_pool.c > @@ -360,7 +360,8 @@ static int ldlm_pool_recalc(struct ldlm_pool *pl) > recalc_interval_sec = ktime_get_real_seconds() - pl->pl_recalc_time; > if (recalc_interval_sec > 0) { > spin_lock(&pl->pl_lock); > - recalc_interval_sec = ktime_get_real_seconds() - pl->pl_recalc_time; > + recalc_interval_sec = ktime_get_real_seconds() - > + pl->pl_recalc_time; > > if (recalc_interval_sec > 0) { > /* > diff --git a/fs/lustre/ldlm/ldlm_request.c b/fs/lustre/ldlm/ldlm_request.c > index a614d74..b7dcfda 100644 > --- a/fs/lustre/ldlm/ldlm_request.c > +++ b/fs/lustre/ldlm/ldlm_request.c > @@ -438,7 +438,7 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, > PLDLMRES(lock->l_resource)); > > rc = ldlm_lock_change_resource(ns, lock, > - &reply->lock_desc.l_resource.lr_name); > + &reply->lock_desc.l_resource.lr_name); > if (rc || !lock->l_resource) { > rc = -ENOMEM; > goto cleanup; > @@ -450,9 +450,9 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, > !(exp_connect_flags(exp) & OBD_CONNECT_IBITS))) > /* We assume lock type cannot change on server*/ > ldlm_convert_policy_to_local(exp, > - lock->l_resource->lr_type, > - &reply->lock_desc.l_policy_data, > - &lock->l_policy_data); > + lock->l_resource->lr_type, > + &reply->lock_desc.l_policy_data, > + &lock->l_policy_data); > if (type != LDLM_PLAIN) > LDLM_DEBUG(lock, > "client-side enqueue, new policy data"); > @@ -927,8 +927,7 @@ static int ldlm_cli_cancel_req(struct obd_export *exp, > if (rc == LUSTRE_ESTALE) { > CDEBUG(D_DLMTRACE, > "client/server (nid %s) out of sync -- not fatal\n", > - libcfs_nid2str(req->rq_import-> > - imp_connection->c_peer.nid)); > + libcfs_nid2str(req->rq_import->imp_connection->c_peer.nid)); > rc = 0; > } else if (rc == -ETIMEDOUT && /* check there was no reconnect*/ > req->rq_import_generation == imp->imp_generation) { > @@ -1290,10 +1289,9 @@ static enum ldlm_policy_res ldlm_cancel_aged_policy(struct ldlm_namespace *ns, > LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK; > } > > -typedef enum ldlm_policy_res (*ldlm_cancel_lru_policy_t)( > - struct ldlm_namespace *, > - struct ldlm_lock *, int, > - int, int); > +typedef enum ldlm_policy_res (*ldlm_cancel_lru_policy_t)(struct ldlm_namespace *, > + struct ldlm_lock *, > + int, int, int); > > static ldlm_cancel_lru_policy_t > ldlm_cancel_lru_policy(struct ldlm_namespace *ns, int lru_flags) > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From baptiste.gerondeau at linaro.org Tue Jul 23 08:33:35 2019 From: baptiste.gerondeau at linaro.org (Baptiste Gerondeau) Date: Tue, 23 Jul 2019 10:33:35 +0200 Subject: [lustre-devel] Auster and no facet /usr/sbin/lctl In-Reply-To: <257DDBDC-58B6-4D0E-904F-B141A4761C4C@whamcloud.com> References: <7AE1C6EF-B45C-4256-A28A-9A5E73C2BBCC@whamcloud.com> <257DDBDC-58B6-4D0E-904F-B141A4761C4C@whamcloud.com> Message-ID: After testing it out on an ARM64 client (hostname : lustrerhel, running RHEL8, compiled from master), it seems it has the same problem. I can *successfully* llmount.sh and llmountcleanup.sh and write and read files from the client. That said, sanity.sh is *not* working for me : it never gets to the tests part, it just stops at 'cat /proc/mounts on OSS'. dmesg says nothing more, and I can't seem to get a more info (an error) from the logs. I have confirmed that I can 'cat /proc/mounts' just fine on all the machines. Client: Lustre version: 2.12.0 MDS: No host defined for facet /usr/sbin/lctl OSS: Lustre version: 2.12.0 CMD: lustrerhel,x8602 PATH=/usr/lib64/lustre/tests:/usr/lib/lustre/tests:/usr/lib64/lustre/tests:/usr/lib64/lustre/tests/mpi:/usr/lib64/lustre/tests/racer:/usr/lib64/lustre/../lustre-iokit/sgpdd-survey:/usr/lib64/lustre/tests:/usr/lib64/lustre/utils/gss:/usr/lib64/lustre/utils:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/sbin::/sbin:/bin:/usr/sbin: NAME=local bash rpc.sh check_config_client /lustre x8602: x8602: executing check_config_client /lustre lustrerhel: CMD: lustrerhel /usr/sbin/lctl get_param -n version 2>/dev/null || lustrerhel: /usr/sbin/lctl lustre_build_version 2>/dev/null || lustrerhel: /usr/sbin/lctl --version 2>/dev/null | cut -d' ' -f2 lustrerhel: CMD: lustrerhel /usr/sbin/lctl get_param -n version 2>/dev/null || lustrerhel: /usr/sbin/lctl lustre_build_version 2>/dev/null || lustrerhel: /usr/sbin/lctl --version 2>/dev/null | cut -d' ' -f2 lustrerhel: CMD: lustrerhel /usr/sbin/lctl get_param -n version 2>/dev/null || lustrerhel: /usr/sbin/lctl lustre_build_version 2>/dev/null || lustrerhel: /usr/sbin/lctl --version 2>/dev/null | cut -d' ' -f2 lustrerhel: CMD: lustrerhel /usr/sbin/lctl get_param -n version 2>/dev/null || lustrerhel: /usr/sbin/lctl lustre_build_version 2>/dev/null || lustrerhel: /usr/sbin/lctl --version 2>/dev/null | cut -d' ' -f2 x8602: Checking config lustre mounted on /lustre lustrerhel: lustrerhel: executing check_config_client /lustre lustrerhel: Checking config lustre mounted on /lustre Checking servers environments [...] CMD: x86ohpc e2label /dev/sda2 2>/dev/null x86ohpc: Warning: Permanently added 'x86ohpc,10.40.24.210' (ECDSA) to the list of known hosts. CMD: x86ohpc cat /proc/mounts x86ohpc: Warning: Permanently added 'x86ohpc,10.40.24.210' (ECDSA) to the list of known hosts. CMD: x8601 e2label /dev/sda2 2>/dev/null CMD: x8601 cat /proc/mounts Thanks a lot for your support, Best regards, On Thu, 18 Jul 2019 at 20:56, Andreas Dilger wrote: > On Jul 18, 2019, at 04:29, Baptiste Gerondeau < > baptiste.gerondeau at linaro.org> wrote: > > > > Thank you very much for your quick help ! > > I reformatted and remounted everything from scratch and can confirm that > mounting works, and that the client can communicate with the MDS (210, OSS > is 211 and client 212): > [snip] > > [root at x8602 tests]# lctl which_nid 10.40.24.210 at tcp > > 10.40.24.210 at tcp > > [root at x8602 tests]# lfs df -ih > > UUID Inodes IUsed IFree IUse% Mounted on > > test-MDT0000_UUID 4.0M 272 4.0M 1% > /lustre[MDT:0] > > test-OST0000_UUID 640.0K 267 639.7K 0% > /lustre[OST:0] > > > > filesystem_summary: 640.0K 272 639.7K 0% /lustre > > > > [root at x8602 tests]# ls -lsah /lustre/ > > total 12K > > 4.0K drwxr-xr-x 3 root root 4.0K Jul 18 11:03 . > > 4.0K dr-xr-xr-x. 19 root root 4.0K Jun 28 11:43 .. > > 4.0K -rw-r--r-- 1 root root 14 Jul 18 11:03 test.txt > > > > I get the same output from auster though: > > Client: Lustre version: 2.12.0 > > MDS: No host defined for facet /usr/sbin/lctl > > This looks like some kind of problem with the test configuration file, > where an environment variable is not set (e.g. mds_HOST) and it is > interpreting the next argument (the lctl command) as the target facet when > calling do_facet() or similar? > > If "llmount.sh" works, then you are also able to run tests directly like: > > client# cd lustre/tests > client# sh sanity.sh > > I don't use auster myself (it is just a wrapper around lower-level > scripts), so I can't really comment where the problem might be. > > Cheers, Andreas > > > OSS: Lustre version: 2.12.0 > > > > From the client I can ssh into the other nodes (and from each node I can > ssh into the others). > > I had tried to debug the scripts behind the above auster output but was > unable to track down where it failed... > > > > On Tue, 16 Jul 2019 at 23:09, Andreas Dilger > wrote: > > On Jul 16, 2019, at 06:11, Baptiste Gerondeau < > baptiste.gerondeau at linaro.org> wrote: > > > > > > Hi, > > > > > > I'm currently in the process of bringing up the "3 node" x86 cluster > and running "verbose=true ./auster -f multinode -rsv runtests" (on CentOS > 7.6 x86 client & server, installed from repos), I keep getting "MDS: No > host defined for facet /usr/sbin/lctl". > > > > > > Auster then prints out some pdsh stuff, "Failures : 0" and exits after > 16s obviously without running any tests. > > > > > > Any suggestions? > > > Thanks a lot, > > > > > > > > > PS : My multinode config is attached > > > PPS: I posted to the devel list because it concerned auster, if I need > to post it elsewhere please let me know > > > > Before running auster, which tries to launch a lot of tests, start with > just a plain mount to see if that is working: > > > > master.sh: > > > MOUNT=/mnt/lustre > > > MOUNT2=/mnt/master2 > > > > This is a bit odd for tests, which normally have e.g. /mnt/master and > /mnt/master2, but I'm > > not sure i there will be a problem or not. > > > > ### assume modules/utils are built > > ### modules/utils are installed or you are running out of the build > directory > > ### ssh to the MDS and OSS nodes works without a password > > ### if you are not using @tcp0 for LNet, /etc/modprobe.d/lnet.conf is > correct > > > > all# modprobe ptlrpc ### on client and OSS and MDS to start > LNet > > x8602# lctl ping x86ohpc ### should print NID(s) of x860hpc > > x8602# lctl ping x8601 ### should print NID(s) of x8601 > > x8602# export NAME=master ### get config from > lustre/tests/cfg/master.sh > > x8602# sh llmount.sh ### should format x86ohpc:/dev/sda2 and > x8601:/dev/sda2 > > x8602# lfs df ### should show master-MDT0000 and > master-OST0000 > > > > Cheers, Andreas > > -- > > Andreas Dilger > > Principal Lustre Architect > > Whamcloud > > > > > > > > > > > > > > > > > > -- > > Baptiste Gerondeau > > Engineer - HPC SIG - LDCG - Linaro > > #irc : BaptisteGer > > Cheers, Andreas > -- > Andreas Dilger > Principal Lustre Architect > Whamcloud > > > > > > > -- Baptiste Gerondeau Engineer - HPC SIG - LDCG - Linaro #irc : BaptisteGer -------------- next part -------------- An HTML attachment was scrubbed... URL: From umka at cloudlinux.com Mon Jul 22 09:51:02 2019 From: umka at cloudlinux.com (Alexey Lyashkov) Date: Mon, 22 Jul 2019 12:51:02 +0300 Subject: [lustre-devel] [PATCH 19/22] ext4: don't check before replay In-Reply-To: <82691452-7473-4CAB-BE70-0C89238D5720@whamcloud.com> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-20-git-send-email-jsimmons@infradead.org> <87pnm2ocvr.fsf@notabene.neil.brown.name> <506765DD-0068-469E-ADA4-2C71B8B60114@cloudlinux.com> <87wogak1n7.fsf@notabene.neil.brown.name> <82691452-7473-4CAB-BE70-0C89238D5720@whamcloud.com> Message-ID: > 22 июля 2019 г., в 9:56, Oleg Drokin написал(а): > > > >> On Jul 22, 2019, at 2:46 AM, NeilBrown wrote: >> >> On Mon, Jul 22 2019, Alexey Lyashkov wrote: >> >>> Why? >>> Purpose of this patch is simple and don’t addressed a failover in general. >>> Crash can occurred in commit time - when journal _partially_ flushed to the FS. Checking any FS metadata in this time is wrong, because we have no guarantee to be consistence. >>> But checking an after journal replay is fine, it check have verification no corruption hit and FS is fine. >> >> If the corruption can occur in non-ldiskfs usage, and would be fixed by >> a journal replay, then yes - the patch looks like a good idea. Yes, bug should fixed by journal replay. BUT this check was run _before_ journal replay and patch move groups check _after_ journal replay done. >> >> Possibly I misunderstood the source of the corruption... maybe if that >> could be made clearer in the commit message, that would help. > > I think the argument is: wtf do we even look at metadata (or anything, really) > before journal replay. > The patch is actually good because it does move the read after the journal replay > though? Oleg, you are right. > > >> >>> >>> >>>> 22 июля 2019 г., в 8:29, NeilBrown написал(а): >>>> >>>> On Sun, Jul 21 2019, James Simmons wrote: >>>> >>>>> When ldiskfs run in failover mode whith read-only disk. >>>>> Part of allocation updates are lost and ldiskfs may fail >>>>> while mounting this is due to inconsistent state of >>>>> group-descriptor. Group-descriptor check is added after >>>>> journal replay. >>>> >>>> I think this needs to be enabled by a mount option or super-block flag. >>>> >>>> NeilBrown >>>> >>>> >>>>> >>>>> Signed-off-by: James Simmons >>>>> --- >>>>> fs/ext4/super.c | 11 ++++++----- >>>>> 1 file changed, 6 insertions(+), 5 deletions(-) >>>>> >>>>> diff --git a/fs/ext4/super.c b/fs/ext4/super.c >>>>> index a3179b2..b818acb 100644 >>>>> --- a/fs/ext4/super.c >>>>> +++ b/fs/ext4/super.c >>>>> @@ -4255,11 +4255,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) >>>>> } >>>>> } >>>>> sbi->s_gdb_count = db_count; >>>>> - if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { >>>>> - ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); >>>>> - ret = -EFSCORRUPTED; >>>>> - goto failed_mount2; >>>>> - } >>>>> >>>>> timer_setup(&sbi->s_err_report, print_daily_error_info, 0); >>>>> >>>>> @@ -4401,6 +4396,12 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) >>>>> sbi->s_journal->j_commit_callback = ext4_journal_commit_callback; >>>>> >>>>> no_journal: >>>>> + if (!ext4_check_descriptors(sb, logical_sb_block, &first_not_zeroed)) { >>>>> + ext4_msg(sb, KERN_ERR, "group descriptors corrupted!"); >>>>> + ret = -EFSCORRUPTED; >>>>> + goto failed_mount_wq; >>>>> + } >>>>> + >>>>> if (!test_opt(sb, NO_MBCACHE)) { >>>>> sbi->s_ea_block_cache = ext4_xattr_create_cache(); >>>>> if (!sbi->s_ea_block_cache) { >>>>> -- >>>>> 1.8.3.1 >>>> _______________________________________________ >>>> lustre-devel mailing list >>>> lustre-devel at lists.lustre.org >>>> http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org > > _______________________________________________ > lustre-devel mailing list > lustre-devel at lists.lustre.org > http://lists.lustre.org/listinfo.cgi/lustre-devel-lustre.org From jsimmons at infradead.org Wed Jul 24 03:37:00 2019 From: jsimmons at infradead.org (James Simmons) Date: Wed, 24 Jul 2019 04:37:00 +0100 (BST) Subject: [lustre-devel] [PATCH 10/11] lustre: ldlm: checkpatch cleanup In-Reply-To: <87tvbdjwa7.fsf@notabene.neil.brown.name> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> <1563760338-806-11-git-send-email-jsimmons@infradead.org> <87tvbdjwa7.fsf@notabene.neil.brown.name> Message-ID: > > @@ -286,7 +286,7 @@ static void ldlm_handle_gl_callback(struct ptlrpc_request *req, > > struct ldlm_request *dlm_req, > > struct ldlm_lock *lock) > > { > > - int rc = -ENOSYS; > > + int rc = -ENXIO; > > Is this really a checkpatch warning? > Is it safe? > Is there a visible behaviour change here, or is the error status only > used internally? > > There seem to be a few others ... maybe checkpatch doesn't like ENOSYS - > probably reasonable. > > Everything else looks OK. > > Thanks for these! >From checkpatch - "ENOSYS means 'invalid syscall nr' and nothing else" So using ENOSYS is no no. We get away with this because people rarely actually handle each error code individually. Only the MDT coordinator really looks to see if the errno code is ENOSYS. > NeilBrown > > > > > > LDLM_DEBUG(lock, "client glimpse AST callback handler"); > > > > @@ -396,8 +396,10 @@ static int ldlm_bl_to_thread(struct ldlm_namespace *ns, > > struct list_head *cancels, int count, > > enum ldlm_cancel_flags cancel_flags) > > { > > + int rc = 0; > > + > > if (cancels && count == 0) > > - return 0; > > + return rc; > > > > if (cancel_flags & LCF_ASYNC) { > > struct ldlm_bl_work_item *blwi; > > @@ -407,7 +409,7 @@ static int ldlm_bl_to_thread(struct ldlm_namespace *ns, > > return -ENOMEM; > > init_blwi(blwi, ns, ld, cancels, count, lock, cancel_flags); > > > > - return __ldlm_bl_to_thread(blwi, cancel_flags); > > + rc = __ldlm_bl_to_thread(blwi, cancel_flags); > > } else { > > /* if it is synchronous call do minimum mem alloc, as it could > > * be triggered from kernel shrinker > > @@ -416,8 +418,9 @@ static int ldlm_bl_to_thread(struct ldlm_namespace *ns, > > > > memset(&blwi, 0, sizeof(blwi)); > > init_blwi(&blwi, ns, ld, cancels, count, lock, cancel_flags); > > - return __ldlm_bl_to_thread(&blwi, cancel_flags); > > + rc = __ldlm_bl_to_thread(&blwi, cancel_flags); > > } > > + return rc; > > } > > > > int ldlm_bl_to_thread_lock(struct ldlm_namespace *ns, struct ldlm_lock_desc *ld, > > @@ -446,7 +449,7 @@ static int ldlm_handle_setinfo(struct ptlrpc_request *req) > > char *key; > > void *val; > > int keylen, vallen; > > - int rc = -ENOSYS; > > + int rc = -ENXIO; > > > > DEBUG_REQ(D_HSM, req, "%s: handle setinfo\n", obd->obd_name); > > > > @@ -875,6 +878,7 @@ int ldlm_get_ref(void) > > void ldlm_put_ref(void) > > { > > int rc = 0; > > + > > mutex_lock(&ldlm_ref_mutex); > > if (ldlm_refcount == 1) { > > rc = ldlm_cleanup(); > > diff --git a/fs/lustre/ldlm/ldlm_pool.c b/fs/lustre/ldlm/ldlm_pool.c > > index 1f81795..6714c30 100644 > > --- a/fs/lustre/ldlm/ldlm_pool.c > > +++ b/fs/lustre/ldlm/ldlm_pool.c > > @@ -360,7 +360,8 @@ static int ldlm_pool_recalc(struct ldlm_pool *pl) > > recalc_interval_sec = ktime_get_real_seconds() - pl->pl_recalc_time; > > if (recalc_interval_sec > 0) { > > spin_lock(&pl->pl_lock); > > - recalc_interval_sec = ktime_get_real_seconds() - pl->pl_recalc_time; > > + recalc_interval_sec = ktime_get_real_seconds() - > > + pl->pl_recalc_time; > > > > if (recalc_interval_sec > 0) { > > /* > > diff --git a/fs/lustre/ldlm/ldlm_request.c b/fs/lustre/ldlm/ldlm_request.c > > index a614d74..b7dcfda 100644 > > --- a/fs/lustre/ldlm/ldlm_request.c > > +++ b/fs/lustre/ldlm/ldlm_request.c > > @@ -438,7 +438,7 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, > > PLDLMRES(lock->l_resource)); > > > > rc = ldlm_lock_change_resource(ns, lock, > > - &reply->lock_desc.l_resource.lr_name); > > + &reply->lock_desc.l_resource.lr_name); > > if (rc || !lock->l_resource) { > > rc = -ENOMEM; > > goto cleanup; > > @@ -450,9 +450,9 @@ int ldlm_cli_enqueue_fini(struct obd_export *exp, struct ptlrpc_request *req, > > !(exp_connect_flags(exp) & OBD_CONNECT_IBITS))) > > /* We assume lock type cannot change on server*/ > > ldlm_convert_policy_to_local(exp, > > - lock->l_resource->lr_type, > > - &reply->lock_desc.l_policy_data, > > - &lock->l_policy_data); > > + lock->l_resource->lr_type, > > + &reply->lock_desc.l_policy_data, > > + &lock->l_policy_data); > > if (type != LDLM_PLAIN) > > LDLM_DEBUG(lock, > > "client-side enqueue, new policy data"); > > @@ -927,8 +927,7 @@ static int ldlm_cli_cancel_req(struct obd_export *exp, > > if (rc == LUSTRE_ESTALE) { > > CDEBUG(D_DLMTRACE, > > "client/server (nid %s) out of sync -- not fatal\n", > > - libcfs_nid2str(req->rq_import-> > > - imp_connection->c_peer.nid)); > > + libcfs_nid2str(req->rq_import->imp_connection->c_peer.nid)); > > rc = 0; > > } else if (rc == -ETIMEDOUT && /* check there was no reconnect*/ > > req->rq_import_generation == imp->imp_generation) { > > @@ -1290,10 +1289,9 @@ static enum ldlm_policy_res ldlm_cancel_aged_policy(struct ldlm_namespace *ns, > > LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK; > > } > > > > -typedef enum ldlm_policy_res (*ldlm_cancel_lru_policy_t)( > > - struct ldlm_namespace *, > > - struct ldlm_lock *, int, > > - int, int); > > +typedef enum ldlm_policy_res (*ldlm_cancel_lru_policy_t)(struct ldlm_namespace *, > > + struct ldlm_lock *, > > + int, int, int); > > > > static ldlm_cancel_lru_policy_t > > ldlm_cancel_lru_policy(struct ldlm_namespace *ns, int lru_flags) > > -- > > 1.8.3.1 > From degremoa at amazon.com Wed Jul 24 07:23:46 2019 From: degremoa at amazon.com (Degremont, Aurelien) Date: Wed, 24 Jul 2019 07:23:46 +0000 Subject: [lustre-devel] [PATCH 10/11] lustre: ldlm: checkpatch cleanup In-Reply-To: References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> <1563760338-806-11-git-send-email-jsimmons@infradead.org> <87tvbdjwa7.fsf@notabene.neil.brown.name> Message-ID: <1BDF7232-853F-4B2D-AC0B-AC49E78F6884@amazon.com> Le 24/07/2019 05:38, « lustre-devel au nom de James Simmons » a écrit : From checkpatch - "ENOSYS means 'invalid syscall nr' and nothing else" So using ENOSYS is no no. We get away with this because people rarely actually handle each error code individually. . As a general comment about this, I think we should improve this in the futur. Some people asked me "what's the error code when this or that happens in Lustre?". And I've got no real answer for that. Indeed people, most of the time, only checks returned code against 0. That does not help when looking at specific Lustre issues. From jsimmons at infradead.org Wed Jul 24 20:45:54 2019 From: jsimmons at infradead.org (James Simmons) Date: Wed, 24 Jul 2019 16:45:54 -0400 Subject: [lustre-devel] [PATCH] lustre: lnet: fix needed headers for lnet headers Message-ID: <1564001154-2944-1-git-send-email-jsimmons@infradead.org> The linux kernel now has a sanity check for the global headers and LNet are missing a few headers to allow them to build properly. Signed-off-by: James Simmons --- include/linux/libcfs/libcfs_fail.h | 1 + include/linux/libcfs/libcfs_private.h | 3 +++ include/uapi/linux/lnet/lnetst.h | 2 ++ 3 files changed, 6 insertions(+) diff --git a/include/linux/libcfs/libcfs_fail.h b/include/linux/libcfs/libcfs_fail.h index 0e73eef..f52a82a 100644 --- a/include/linux/libcfs/libcfs_fail.h +++ b/include/linux/libcfs/libcfs_fail.h @@ -35,6 +35,7 @@ #include #include +#include extern unsigned long cfs_fail_loc; extern unsigned int cfs_fail_val; diff --git a/include/linux/libcfs/libcfs_private.h b/include/linux/libcfs/libcfs_private.h index 515fd63..2e8cff6 100644 --- a/include/linux/libcfs/libcfs_private.h +++ b/include/linux/libcfs/libcfs_private.h @@ -39,6 +39,9 @@ #ifndef __LIBCFS_PRIVATE_H__ #define __LIBCFS_PRIVATE_H__ +#include +#include + #ifndef DEBUG_SUBSYSTEM # define DEBUG_SUBSYSTEM S_UNDEFINED #endif diff --git a/include/uapi/linux/lnet/lnetst.h b/include/uapi/linux/lnet/lnetst.h index 27fcd91..449c5e6 100644 --- a/include/uapi/linux/lnet/lnetst.h +++ b/include/uapi/linux/lnet/lnetst.h @@ -38,6 +38,8 @@ #define __LNET_ST_H__ #include +#include +#include #define LST_FEAT_NONE (0) #define LST_FEAT_BULK_LEN (1 << 0) /* enable variable page size */ -- 1.8.3.1 From jsimmons at infradead.org Thu Jul 25 01:54:04 2019 From: jsimmons at infradead.org (James Simmons) Date: Thu, 25 Jul 2019 02:54:04 +0100 (BST) Subject: [lustre-devel] [PATCH 10/11] lustre: ldlm: checkpatch cleanup In-Reply-To: <1BDF7232-853F-4B2D-AC0B-AC49E78F6884@amazon.com> References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> <1563760338-806-11-git-send-email-jsimmons@infradead.org> <87tvbdjwa7.fsf@notabene.neil.brown.name> <1BDF7232-853F-4B2D-AC0B-AC49E78F6884@amazon.com> Message-ID: > Le 24/07/2019 05:38, « lustre-devel au nom de James Simmons » a écrit : > > From checkpatch - "ENOSYS means 'invalid syscall nr' and nothing else" > So using ENOSYS is no no. We get away with this because people rarely > actually handle each error code individually. > . > > As a general comment about this, I think we should improve this in the futur. Some people asked me "what's the error code when this or that happens in Lustre?". And I've got no real answer for that. > Indeed people, most of the time, only checks returned code against 0. That does not help when looking at specific Lustre issues. perf probe 'lustre_function%return $retval' Does the same thing as lctl set_param debug=+trace except dynamic probes can work on any kernel function without code modification!!! From jsimmons at infradead.org Thu Jul 25 02:43:59 2019 From: jsimmons at infradead.org (James Simmons) Date: Wed, 24 Jul 2019 22:43:59 -0400 Subject: [lustre-devel] [PATCH 0/8] lustre: some old patches from whamcloud tree Message-ID: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> Some old patches missing from the linux lustre client. I suspect these weren't port since they most are likely server side only but I want to make sure. Also we are missing patch: http://review.whamcloud.com/20939 from LU-8319 but I don't know if that is needed anymore with the earlier changes done. Feedback welcomed. Andreas Dilger (1): lustre: seq: make seq_proc_write_common() safer Gregoire Pichon (1): lustre: tests: testcases for multiple modify RPCs feature Jeremy Filizetti (1): lustre: ldlm: Don't check opcode with NULL rq_reqmsg Li Wei (1): lustre: ptlrpc: Fix an rq_no_reply assertion failure Wang Di (1): lustre: fld: retry fld rpc until the import is closed wang di (3): lustre: fld: resend seq lookup RPC if it is on LWP lustre: fld: retry fld rpc even for ESHUTDOWN lustre: fld: fld client lookup should retry fs/lustre/fid/lproc_fid.c | 12 +++++++----- fs/lustre/fld/fld_request.c | 42 ++++++++++++++++++++++++++++++++++++++--- fs/lustre/include/obd_support.h | 2 ++ fs/lustre/ldlm/ldlm_lib.c | 7 +++++++ fs/lustre/ptlrpc/service.c | 10 ++++++++++ 5 files changed, 65 insertions(+), 8 deletions(-) -- 1.8.3.1 From jsimmons at infradead.org Thu Jul 25 02:44:00 2019 From: jsimmons at infradead.org (James Simmons) Date: Wed, 24 Jul 2019 22:44:00 -0400 Subject: [lustre-devel] [PATCH 1/8] lustre: seq: make seq_proc_write_common() safer In-Reply-To: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> References: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> Message-ID: <1564022647-17351-2-git-send-email-jsimmons@infradead.org> From: Andreas Dilger Don't allow seq_proc_write_common() to specify arbitrary ranges, since this can permanently corrupt the sequence controller and/or sequnece server. That would allow duplicate FID allocation, or possibly prevent any new files to be created or servers to be added to the filesystem. Instead, limit the sequence range that can be written via /proc to a subset of the sequence range currently allocated to that node. Add the "clear" keyword to allow dropping the entire local sequence and force a new one to be fetched from the sequence server. WC-bug-id: https://jira.whamcloud.com/browse/LU-3642 Lustre-commit: 05f69f5ee20eeffcc26f643333cedcfb53ba6669 Signed-off-by: Andreas Dilger Reviewed-on: http://review.whamcloud.com/7123 Reviewed-by: Jinshan Xiong Reviewed-by: Alex Zhuravlev Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- fs/lustre/fid/lproc_fid.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/fs/lustre/fid/lproc_fid.c b/fs/lustre/fid/lproc_fid.c index 94869d4..e2e47df 100644 --- a/fs/lustre/fid/lproc_fid.c +++ b/fs/lustre/fid/lproc_fid.c @@ -52,14 +52,18 @@ /* Format: [0x64BIT_INT - 0x64BIT_INT] + 32 bytes just in case */ #define MAX_FID_RANGE_STRLEN (32 + 2 * 2 * sizeof(u64)) /* - * Note: this function is only used for testing, it is no safe for production - * use. + * Reduce the SEQ range allocated to a node to a strict subset of the range + * currently-allocated SEQ range. If the specified range is "clear", then + * drop all allocated sequences and request a new one from the master. + * + * Note: this function should only be used for testing, it is not necessarily + * safe for production use. */ static int ldebugfs_fid_write_common(const char __user *buffer, size_t count, struct lu_seq_range *range) { - struct lu_seq_range tmp; + struct lu_seq_range tmp = { 0, }; int rc; char kernbuf[MAX_FID_RANGE_STRLEN]; @@ -82,8 +86,6 @@ rc = sscanf(kernbuf, "[%llx - %llx]\n", (unsigned long long *)&tmp.lsr_start, (unsigned long long *)&tmp.lsr_end); - if (rc != 2) - return -EINVAL; if (!lu_seq_range_is_sane(&tmp) || lu_seq_range_is_zero(&tmp) || tmp.lsr_start < range->lsr_start || tmp.lsr_end > range->lsr_end) return -EINVAL; -- 1.8.3.1 From jsimmons at infradead.org Thu Jul 25 02:44:06 2019 From: jsimmons at infradead.org (James Simmons) Date: Wed, 24 Jul 2019 22:44:06 -0400 Subject: [lustre-devel] [PATCH 7/8] lustre: tests: testcases for multiple modify RPCs feature In-Reply-To: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> References: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> Message-ID: <1564022647-17351-8-git-send-email-jsimmons@infradead.org> From: Gregoire Pichon This patch creates new testcases in the Auster test suite to test the support of multiple modify RPCs in flight feature. Two new OBD_FAIL codes are added to allow several failure occurences of the reint requests or replies. This is needed because the current fail checks impose the OBD_FAIL_ONCE flag. Added testcases are : - sanity 245 - conf-sanity 90a 90b 90c 90d - replay-single 102a 102b 102c 102d This patch also removes replay-single tests 53a and 53b from the ALWAYS_EXCEPT list. WC-bug-id: https://jira.whamcloud.com/browse/LU-5319 Lustre-commit: c2d27a0f12688c0d029880919f8b002e557b540c Signed-off-by: Gregoire Pichon Reviewed-on: http://review.whamcloud.com/14861 Reviewed-by: Jian Yu Reviewed-by: Andreas Dilger --- fs/lustre/include/obd_support.h | 2 ++ fs/lustre/ldlm/ldlm_lib.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/fs/lustre/include/obd_support.h b/fs/lustre/include/obd_support.h index 3e15cac..7999ac6 100644 --- a/fs/lustre/include/obd_support.h +++ b/fs/lustre/include/obd_support.h @@ -189,6 +189,8 @@ #define OBD_FAIL_MDS_SWAP_LAYOUTS_NET 0x14f #define OBD_FAIL_MDS_HSM_ACTION_NET 0x150 #define OBD_FAIL_MDS_CHANGELOG_INIT 0x151 +#define OBD_FAIL_MDS_REINT_MULTI_NET 0x159 +#define OBD_FAIL_MDS_REINT_MULTI_NET_REP 0x15a /* layout lock */ #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170 diff --git a/fs/lustre/ldlm/ldlm_lib.c b/fs/lustre/ldlm/ldlm_lib.c index 887507d..a3b8df4 100644 --- a/fs/lustre/ldlm/ldlm_lib.c +++ b/fs/lustre/ldlm/ldlm_lib.c @@ -689,6 +689,9 @@ int target_pack_pool_reply(struct ptlrpc_request *req) DEBUG_REQ(D_ERROR, req, "dropping reply"); return -ECOMM; } + if (unlikely(lustre_msg_get_opc(req->rq_reqmsg) == MDS_REINT && + OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_MULTI_NET_REP))) + return -ECOMM; if (unlikely(rc)) { DEBUG_REQ(D_NET, req, "processing error (%d)", rc); -- 1.8.3.1 From jsimmons at infradead.org Thu Jul 25 02:44:04 2019 From: jsimmons at infradead.org (James Simmons) Date: Wed, 24 Jul 2019 22:44:04 -0400 Subject: [lustre-devel] [PATCH 5/8] lustre: fld: retry fld rpc until the import is closed In-Reply-To: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> References: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> Message-ID: <1564022647-17351-6-git-send-email-jsimmons@infradead.org> From: Wang Di Since LWP is not replayable, it should retry RPC until the import is closed, otherwise it would cause unnecessary failure of the application. WC-bug-id: https://jira.whamcloud.com/browse/LU-5312 Lustre-commit: 07d481957c16832c782bb7d0c1fc436bcb148ea6 Signed-off-by: Wang Di Reviewed-on: http://review.whamcloud.com/11039 Reviewed-by: Andreas Dilger Reviewed-by: Fan Yong Reviewed-by: Oleg Drokin --- fs/lustre/fld/fld_request.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/fs/lustre/fld/fld_request.c b/fs/lustre/fld/fld_request.c index ba0ef82..60e7105 100644 --- a/fs/lustre/fld/fld_request.c +++ b/fs/lustre/fld/fld_request.c @@ -367,12 +367,10 @@ int fld_client_rpc(struct obd_export *exp, rc = ptlrpc_queue_wait(req); obd_put_request_slot(&exp->exp_obd->u.cli); if (rc != 0) { - if (rc == -EWOULDBLOCK || rc == -ESHUTDOWN) { - /* For no_delay req(see above), EWOULDBLOCK and - * ESHUTDOWN means the connection is being evicted, - * but this seq lookup should not return error, - * since it would cause unecessary failure of the - * application, instead it should retry here + if (imp->imp_state != LUSTRE_IMP_CLOSED) { + /* Since LWP is not replayable, so it will keep + * trying unless umount happens, otherwise it would + * cause unecessary failure of the application. */ ptlrpc_req_finished(req); goto again; -- 1.8.3.1 From jsimmons at infradead.org Thu Jul 25 02:44:07 2019 From: jsimmons at infradead.org (James Simmons) Date: Wed, 24 Jul 2019 22:44:07 -0400 Subject: [lustre-devel] [PATCH 8/8] lustre: ldlm: Don't check opcode with NULL rq_reqmsg In-Reply-To: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> References: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> Message-ID: <1564022647-17351-9-git-send-email-jsimmons@infradead.org> From: Jeremy Filizetti When GSS is enabled it's possible to have a NULL rq_reqmsg if a bad signature or no context is returned during the unwrap of the request. Don't check the opcode in this case. WC-bug-id: https://jira.whamcloud.com/browse/LU-7508 Lustre-commit: 3f4572caef5f25f4a9b5347b2ccf933fdad9db9c Signed-off-by: Jeremy Filizetti Reviewed-on: http://review.whamcloud.com/17414 Reviewed-by: Andreas Dilger Reviewed-by: Sebastien Buisson Reviewed-by: John L. Hammond --- fs/lustre/ldlm/ldlm_lib.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/lustre/ldlm/ldlm_lib.c b/fs/lustre/ldlm/ldlm_lib.c index a3b8df4..04982b8 100644 --- a/fs/lustre/ldlm/ldlm_lib.c +++ b/fs/lustre/ldlm/ldlm_lib.c @@ -689,8 +689,12 @@ int target_pack_pool_reply(struct ptlrpc_request *req) DEBUG_REQ(D_ERROR, req, "dropping reply"); return -ECOMM; } - if (unlikely(lustre_msg_get_opc(req->rq_reqmsg) == MDS_REINT && - OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_MULTI_NET_REP))) + /* We can have a null rq_reqmsg in the event of bad signature or + * no context when unwrapping + */ + if (req->rq_reqmsg && + unlikely(lustre_msg_get_opc(req->rq_reqmsg) == MDS_REINT && + OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_MULTI_NET_REP))) return -ECOMM; if (unlikely(rc)) { -- 1.8.3.1 From jsimmons at infradead.org Thu Jul 25 02:44:02 2019 From: jsimmons at infradead.org (James Simmons) Date: Wed, 24 Jul 2019 22:44:02 -0400 Subject: [lustre-devel] [PATCH 3/8] lustre: fld: resend seq lookup RPC if it is on LWP In-Reply-To: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> References: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> Message-ID: <1564022647-17351-4-git-send-email-jsimmons@infradead.org> From: wang di Because Light Weight connection might be evicted after restart, then cause inflight RPC fails, to avoid this, we need resend seq lookup RPC. remove "-f" from "stop mdt" in sanity 17m, so umount can keep the the connection, and otherwise the OSP might be evicted. WC-bug-id: https://jira.whamcloud.com/browse/LU-4571 Lustre-commit: cf7f66d87e52293535cde6e8cc7386e6c1bdfa46 Signed-off-by: wang di Reviewed-on: http://review.whamcloud.com/9106 Reviewed-by: Andreas Dilger Reviewed-by: Jinshan Xiong Reviewed-by: Niu Yawei --- fs/lustre/fld/fld_request.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/fs/lustre/fld/fld_request.c b/fs/lustre/fld/fld_request.c index 248fffa..ec45ea6 100644 --- a/fs/lustre/fld/fld_request.c +++ b/fs/lustre/fld/fld_request.c @@ -314,6 +314,7 @@ int fld_client_rpc(struct obd_export *exp, LASSERT(exp); +again: imp = class_exp2cliimp(exp); switch (fld_op) { case FLD_QUERY: @@ -329,8 +330,15 @@ int fld_client_rpc(struct obd_export *exp, op = req_capsule_client_get(&req->rq_pill, &RMF_FLD_OPC); *op = FLD_LOOKUP; - if (imp->imp_connect_flags_orig & OBD_CONNECT_MDS_MDS) + /* For MDS_MDS seq lookup, it will always use LWP connection, + * but LWP will be evicted after restart, so cause the error. + * so we will set no_delay for seq lookup request, once the + * request fails because of the eviction. always retry here + */ + if (imp->imp_connect_flags_orig & OBD_CONNECT_MDS_MDS) { req->rq_allow_replay = 1; + req->rq_no_delay = 1; + } break; case FLD_READ: req = ptlrpc_request_alloc_pack(imp, &RQF_FLD_READ, @@ -358,8 +366,19 @@ int fld_client_rpc(struct obd_export *exp, obd_get_request_slot(&exp->exp_obd->u.cli); rc = ptlrpc_queue_wait(req); obd_put_request_slot(&exp->exp_obd->u.cli); - if (rc) + if (rc != 0) { + if (rc == -EWOULDBLOCK) { + /* For no_delay req(see above), EWOULDBLOCK means the + * connection is being evicted, but this seq lookup + * should not return error, since it would cause + * unecessary failure of the application, instead + * it should retry here + */ + ptlrpc_req_finished(req); + goto again; + } goto out_req; + } if (fld_op == FLD_QUERY) { prange = req_capsule_server_get(&req->rq_pill, &RMF_FLD_MDFLD); -- 1.8.3.1 From jsimmons at infradead.org Thu Jul 25 02:44:01 2019 From: jsimmons at infradead.org (James Simmons) Date: Wed, 24 Jul 2019 22:44:01 -0400 Subject: [lustre-devel] [PATCH 2/8] lustre: ptlrpc: Fix an rq_no_reply assertion failure In-Reply-To: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> References: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> Message-ID: <1564022647-17351-3-git-send-email-jsimmons@infradead.org> From: Li Wei An OSS had an assertion failure: LustreError: 5366:0:(ldlm_lib.c:2689:target_bulk_io()) @@@ timeout on bulk GET after 0+0s req at ffff88083a61b400 x1476486691018500/t0(4300509964) o4->8dda3382-83f8-6445-5eea-828fd59e4a06 at 192.168.1.116@o2ib1:0/0 lens 504/448 e 391470 to 0 dl 1408494729 ref 2 fl Complete:/4/0 rc 0/0 LustreError: 5432:0:(niobuf.c:550:ptlrpc_send_reply()) ASSERTION( req->rq_no_reply == 0 ) failed: Lustre: soaked-OST0000: Bulk IO write error with 8dda3382-83f8-6445-5eea-828fd59e4a06 (at 192.168.1.116 at o2ib1), client will retry: rc -110 LustreError: 5432:0:(niobuf.c:550:ptlrpc_send_reply()) LBUG Pid: 5432, comm: ll_ost_io03_003 Call Trace: [] libcfs_debug_dumpstack+0x55/0x80 [libcfs] [] lbug_with_loc+0x47/0xb0 [libcfs] [] ptlrpc_send_reply+0x4ec/0x7f0 [ptlrpc] [] ? lustre_pack_reply_flags+0xae/0x1f0 [ptlrpc] [] ptlrpc_at_check_timed+0xcd5/0x1370 [ptlrpc] [] ? ptlrpc_wait_event+0xa9/0x2d0 [ptlrpc] [] ptlrpc_main+0x12e8/0x1990 [ptlrpc] [] ? pick_next_task_fair+0xd0/0x130 [] ? schedule+0x176/0x3b0 [] ? ptlrpc_main+0x0/0x1990 [ptlrpc] [] kthread+0x96/0xa0 [] child_rip+0xa/0x20 [] ? kthread+0x0/0xa0 [] ? child_rip+0x0/0x20 The thread in tgt_brw_write() had decided not to reply by setting rq_no_reply, right before another thread tried to send an early reply for the request. WC-bug-id: https://jira.whamcloud.com/browse/LU-5537 Lustre-commit: a8d448e4cd5978c546911f98067232bcdd30b651 Signed-off-by: Li Wei Reviewed-on: http://review.whamcloud.com/11740 Reviewed-by: Andreas Dilger Reviewed-by: Johann Lombardi --- fs/lustre/ptlrpc/service.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/lustre/ptlrpc/service.c b/fs/lustre/ptlrpc/service.c index a40e964..c9ab9c3 100644 --- a/fs/lustre/ptlrpc/service.c +++ b/fs/lustre/ptlrpc/service.c @@ -1098,6 +1098,16 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) reqcopy->rq_reqmsg = reqmsg; memcpy(reqmsg, req->rq_reqmsg, req->rq_reqlen); + /* + * tgt_brw_read() and tgt_brw_write() may have decided not to reply. + * Without this check, we would fail the rq_no_reply assertion in + * ptlrpc_send_reply(). + */ + if (reqcopy->rq_no_reply) { + rc = -ETIMEDOUT; + goto out; + } + LASSERT(atomic_read(&req->rq_refcount)); /** if it is last refcount then early reply isn't needed */ if (atomic_read(&req->rq_refcount) == 1) { -- 1.8.3.1 From jsimmons at infradead.org Thu Jul 25 02:44:05 2019 From: jsimmons at infradead.org (James Simmons) Date: Wed, 24 Jul 2019 22:44:05 -0400 Subject: [lustre-devel] [PATCH 6/8] lustre: fld: fld client lookup should retry In-Reply-To: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> References: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> Message-ID: <1564022647-17351-7-git-send-email-jsimmons@infradead.org> From: wang di If FLD client lookup fails because of the remote target is shutdown (or deactive), it should retry another target, otherwise it will cause the application failure. And FLD client should stop retry if the import has been deactive. WC-bug-id: https://jira.whamcloud.com/browse/LU-6419 Lustre-commit: 3ededde903c92f8485cae0dc9f958f194ff0b140 Signed-off-by: wang di Reviewed-on: http://review.whamcloud.com/14313 Reviewed-by: Lai Siyao Reviewed-by: Fan Yong Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin --- fs/lustre/fld/fld_request.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/fs/lustre/fld/fld_request.c b/fs/lustre/fld/fld_request.c index 60e7105..dfd4ae9 100644 --- a/fs/lustre/fld/fld_request.c +++ b/fs/lustre/fld/fld_request.c @@ -367,7 +367,7 @@ int fld_client_rpc(struct obd_export *exp, rc = ptlrpc_queue_wait(req); obd_put_request_slot(&exp->exp_obd->u.cli); if (rc != 0) { - if (imp->imp_state != LUSTRE_IMP_CLOSED) { + if (imp->imp_state != LUSTRE_IMP_CLOSED && !imp->imp_deactive) { /* Since LWP is not replayable, so it will keep * trying unless umount happens, otherwise it would * cause unecessary failure of the application. @@ -404,6 +404,7 @@ int fld_client_lookup(struct lu_client_fld *fld, u64 seq, u32 *mds, { struct lu_seq_range res = { 0 }; struct lu_fld_target *target; + struct lu_fld_target *origin; int rc; rc = fld_cache_lookup(fld->lcf_cache, seq, &res); @@ -415,7 +416,8 @@ int fld_client_lookup(struct lu_client_fld *fld, u64 seq, u32 *mds, /* Can not find it in the cache */ target = fld_client_get_target(fld, seq); LASSERT(target); - + origin = target; +again: CDEBUG(D_INFO, "%s: Lookup fld entry (seq: %#llx) on target %s (idx %llu)\n", fld->lcf_name, seq, fld_target_name(target), target->ft_idx); @@ -424,6 +426,23 @@ int fld_client_lookup(struct lu_client_fld *fld, u64 seq, u32 *mds, fld_range_set_type(&res, flags); rc = fld_client_rpc(target->ft_exp, &res, FLD_QUERY, NULL); + if (rc == -ESHUTDOWN) { + /* If fld lookup failed because the target has been shutdown, + * then try next target in the list, until trying all targets + * or fld lookup succeeds + */ + spin_lock(&fld->lcf_lock); + if (target->ft_chain.next == fld->lcf_targets.prev) + target = list_entry(fld->lcf_targets.next, + struct lu_fld_target, ft_chain); + else + target = list_entry(target->ft_chain.next, + struct lu_fld_target, + ft_chain); + spin_unlock(&fld->lcf_lock); + if (target != origin) + goto again; + } if (rc == 0) { *mds = res.lsr_index; -- 1.8.3.1 From jsimmons at infradead.org Thu Jul 25 02:44:03 2019 From: jsimmons at infradead.org (James Simmons) Date: Wed, 24 Jul 2019 22:44:03 -0400 Subject: [lustre-devel] [PATCH 4/8] lustre: fld: retry fld rpc even for ESHUTDOWN In-Reply-To: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> References: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> Message-ID: <1564022647-17351-5-git-send-email-jsimmons@infradead.org> From: wang di when LWP is being evicted, because it is not replayable, the request might return ESHUTDOWN or EWOULDBLOCK, instead of failed, which might cause application failure, fld client will retry RPC, until the connection is being setup again or the LWP is being closed. WC-bug-id: https://jira.whamcloud.com/browse/LU-4420 Lustre-commit: d335e310d4bf490509998ddbb1824e38cff20998 Signed-off-by: wang di Reviewed-on: http://review.whamcloud.com/10285 Reviewed-by: Fan Yong Reviewed-by: Johann Lombardi --- fs/lustre/fld/fld_request.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/lustre/fld/fld_request.c b/fs/lustre/fld/fld_request.c index ec45ea6..ba0ef82 100644 --- a/fs/lustre/fld/fld_request.c +++ b/fs/lustre/fld/fld_request.c @@ -367,12 +367,12 @@ int fld_client_rpc(struct obd_export *exp, rc = ptlrpc_queue_wait(req); obd_put_request_slot(&exp->exp_obd->u.cli); if (rc != 0) { - if (rc == -EWOULDBLOCK) { - /* For no_delay req(see above), EWOULDBLOCK means the - * connection is being evicted, but this seq lookup - * should not return error, since it would cause - * unecessary failure of the application, instead - * it should retry here + if (rc == -EWOULDBLOCK || rc == -ESHUTDOWN) { + /* For no_delay req(see above), EWOULDBLOCK and + * ESHUTDOWN means the connection is being evicted, + * but this seq lookup should not return error, + * since it would cause unecessary failure of the + * application, instead it should retry here */ ptlrpc_req_finished(req); goto again; -- 1.8.3.1 From neilb at suse.com Thu Jul 25 04:53:58 2019 From: neilb at suse.com (NeilBrown) Date: Thu, 25 Jul 2019 14:53:58 +1000 Subject: [lustre-devel] [PATCH] lustre: lnet: fix needed headers for lnet headers In-Reply-To: <1564001154-2944-1-git-send-email-jsimmons@infradead.org> References: <1564001154-2944-1-git-send-email-jsimmons@infradead.org> Message-ID: <87k1c6n28p.fsf@notabene.neil.brown.name> On Wed, Jul 24 2019, James Simmons wrote: > The linux kernel now has a sanity check for the global headers and > LNet are missing a few headers to allow them to build properly. Thanks. I've modified the above to: The linux kernel now has a sanity check for the global headers, activated by CONFIG_HEADER_TEST=y and CONFIG_KERNEL_HEADER_TEST=y. Some LNet headers are missing a few headers to allow them to build properly. and applied the patch. NeilBrown > > Signed-off-by: James Simmons > --- > include/linux/libcfs/libcfs_fail.h | 1 + > include/linux/libcfs/libcfs_private.h | 3 +++ > include/uapi/linux/lnet/lnetst.h | 2 ++ > 3 files changed, 6 insertions(+) > > diff --git a/include/linux/libcfs/libcfs_fail.h b/include/linux/libcfs/libcfs_fail.h > index 0e73eef..f52a82a 100644 > --- a/include/linux/libcfs/libcfs_fail.h > +++ b/include/linux/libcfs/libcfs_fail.h > @@ -35,6 +35,7 @@ > > #include > #include > +#include > > extern unsigned long cfs_fail_loc; > extern unsigned int cfs_fail_val; > diff --git a/include/linux/libcfs/libcfs_private.h b/include/linux/libcfs/libcfs_private.h > index 515fd63..2e8cff6 100644 > --- a/include/linux/libcfs/libcfs_private.h > +++ b/include/linux/libcfs/libcfs_private.h > @@ -39,6 +39,9 @@ > #ifndef __LIBCFS_PRIVATE_H__ > #define __LIBCFS_PRIVATE_H__ > > +#include > +#include > + > #ifndef DEBUG_SUBSYSTEM > # define DEBUG_SUBSYSTEM S_UNDEFINED > #endif > diff --git a/include/uapi/linux/lnet/lnetst.h b/include/uapi/linux/lnet/lnetst.h > index 27fcd91..449c5e6 100644 > --- a/include/uapi/linux/lnet/lnetst.h > +++ b/include/uapi/linux/lnet/lnetst.h > @@ -38,6 +38,8 @@ > #define __LNET_ST_H__ > > #include > +#include > +#include > > #define LST_FEAT_NONE (0) > #define LST_FEAT_BULK_LEN (1 << 0) /* enable variable page size */ > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From degremoa at amazon.com Thu Jul 25 08:07:59 2019 From: degremoa at amazon.com (Degremont, Aurelien) Date: Thu, 25 Jul 2019 08:07:59 +0000 Subject: [lustre-devel] [PATCH 10/11] lustre: ldlm: checkpatch cleanup In-Reply-To: References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> <1563760338-806-11-git-send-email-jsimmons@infradead.org> <87tvbdjwa7.fsf@notabene.neil.brown.name> <1BDF7232-853F-4B2D-AC0B-AC49E78F6884@amazon.com> Message-ID: Le 25/07/2019 03:54, « James Simmons » a écrit : > Le 24/07/2019 05:38, « lustre-devel au nom de James Simmons » a écrit : > > From checkpatch - "ENOSYS means 'invalid syscall nr' and nothing else" > So using ENOSYS is no no. We get away with this because people rarely > actually handle each error code individually. > . > > As a general comment about this, I think we should improve this in the futur. Some people asked me "what's the error code when this or that happens in Lustre?". And I've got no real answer for that. > Indeed people, most of the time, only checks returned code against 0. That does not help when looking at specific Lustre issues. perf probe 'lustre_function%return $retval' Does the same thing as lctl set_param debug=+trace except dynamic probes can work on any kernel function without code modification!!! I mean from userspace. When some applications want to adapt its behaviour depending on what is happening in Lustre. From jsimmons at infradead.org Thu Jul 25 18:46:14 2019 From: jsimmons at infradead.org (James Simmons) Date: Thu, 25 Jul 2019 19:46:14 +0100 (BST) Subject: [lustre-devel] [PATCH] lustre: lnet: fix needed headers for lnet headers In-Reply-To: <87k1c6n28p.fsf@notabene.neil.brown.name> References: <1564001154-2944-1-git-send-email-jsimmons@infradead.org> <87k1c6n28p.fsf@notabene.neil.brown.name> Message-ID: > On Wed, Jul 24 2019, James Simmons wrote: > > > The linux kernel now has a sanity check for the global headers and > > LNet are missing a few headers to allow them to build properly. > > Thanks. > I've modified the above to: > > The linux kernel now has a sanity check for the global headers, > activated by CONFIG_HEADER_TEST=y and CONFIG_KERNEL_HEADER_TEST=y. > Some LNet headers are missing a few headers to allow them to build properly. > > and applied the patch. > Acked-by: James Simmons > > --- > > include/linux/libcfs/libcfs_fail.h | 1 + > > include/linux/libcfs/libcfs_private.h | 3 +++ > > include/uapi/linux/lnet/lnetst.h | 2 ++ > > 3 files changed, 6 insertions(+) > > > > diff --git a/include/linux/libcfs/libcfs_fail.h b/include/linux/libcfs/libcfs_fail.h > > index 0e73eef..f52a82a 100644 > > --- a/include/linux/libcfs/libcfs_fail.h > > +++ b/include/linux/libcfs/libcfs_fail.h > > @@ -35,6 +35,7 @@ > > > > #include > > #include > > +#include > > > > extern unsigned long cfs_fail_loc; > > extern unsigned int cfs_fail_val; > > diff --git a/include/linux/libcfs/libcfs_private.h b/include/linux/libcfs/libcfs_private.h > > index 515fd63..2e8cff6 100644 > > --- a/include/linux/libcfs/libcfs_private.h > > +++ b/include/linux/libcfs/libcfs_private.h > > @@ -39,6 +39,9 @@ > > #ifndef __LIBCFS_PRIVATE_H__ > > #define __LIBCFS_PRIVATE_H__ > > > > +#include > > +#include > > + > > #ifndef DEBUG_SUBSYSTEM > > # define DEBUG_SUBSYSTEM S_UNDEFINED > > #endif > > diff --git a/include/uapi/linux/lnet/lnetst.h b/include/uapi/linux/lnet/lnetst.h > > index 27fcd91..449c5e6 100644 > > --- a/include/uapi/linux/lnet/lnetst.h > > +++ b/include/uapi/linux/lnet/lnetst.h > > @@ -38,6 +38,8 @@ > > #define __LNET_ST_H__ > > > > #include > > +#include > > +#include > > > > #define LST_FEAT_NONE (0) > > #define LST_FEAT_BULK_LEN (1 << 0) /* enable variable page size */ > > -- > > 1.8.3.1 > From neilb at suse.com Thu Jul 25 23:55:12 2019 From: neilb at suse.com (NeilBrown) Date: Fri, 26 Jul 2019 09:55:12 +1000 Subject: [lustre-devel] [PATCH 1/8] lustre: seq: make seq_proc_write_common() safer In-Reply-To: <1564022647-17351-2-git-send-email-jsimmons@infradead.org> References: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> <1564022647-17351-2-git-send-email-jsimmons@infradead.org> Message-ID: <87h879mzz3.fsf@notabene.neil.brown.name> On Wed, Jul 24 2019, James Simmons wrote: > From: Andreas Dilger > > Don't allow seq_proc_write_common() to specify arbitrary ranges, > since this can permanently corrupt the sequence controller and/or > sequnece server. That would allow duplicate FID allocation, or > possibly prevent any new files to be created or servers to be added > to the filesystem. > > Instead, limit the sequence range that can be written via /proc to > a subset of the sequence range currently allocated to that node. > Add the "clear" keyword to allow dropping the entire local sequence > and force a new one to be fetched from the sequence server. > > WC-bug-id: https://jira.whamcloud.com/browse/LU-3642 > Lustre-commit: 05f69f5ee20eeffcc26f643333cedcfb53ba6669 > Signed-off-by: Andreas Dilger > Reviewed-on: http://review.whamcloud.com/7123 > Reviewed-by: Jinshan Xiong > Reviewed-by: Alex Zhuravlev > Reviewed-by: James Simmons > Reviewed-by: Oleg Drokin > --- > fs/lustre/fid/lproc_fid.c | 12 +++++++----- > 1 file changed, 7 insertions(+), 5 deletions(-) I already have this is my backport branch. a8ab6db57383 NeilBrown > > diff --git a/fs/lustre/fid/lproc_fid.c b/fs/lustre/fid/lproc_fid.c > index 94869d4..e2e47df 100644 > --- a/fs/lustre/fid/lproc_fid.c > +++ b/fs/lustre/fid/lproc_fid.c > @@ -52,14 +52,18 @@ > /* Format: [0x64BIT_INT - 0x64BIT_INT] + 32 bytes just in case */ > #define MAX_FID_RANGE_STRLEN (32 + 2 * 2 * sizeof(u64)) > /* > - * Note: this function is only used for testing, it is no safe for production > - * use. > + * Reduce the SEQ range allocated to a node to a strict subset of the range > + * currently-allocated SEQ range. If the specified range is "clear", then > + * drop all allocated sequences and request a new one from the master. > + * > + * Note: this function should only be used for testing, it is not necessarily > + * safe for production use. > */ > static int > ldebugfs_fid_write_common(const char __user *buffer, size_t count, > struct lu_seq_range *range) > { > - struct lu_seq_range tmp; > + struct lu_seq_range tmp = { 0, }; > int rc; > char kernbuf[MAX_FID_RANGE_STRLEN]; > > @@ -82,8 +86,6 @@ > rc = sscanf(kernbuf, "[%llx - %llx]\n", > (unsigned long long *)&tmp.lsr_start, > (unsigned long long *)&tmp.lsr_end); > - if (rc != 2) > - return -EINVAL; > if (!lu_seq_range_is_sane(&tmp) || lu_seq_range_is_zero(&tmp) || > tmp.lsr_start < range->lsr_start || tmp.lsr_end > range->lsr_end) > return -EINVAL; > -- > 1.8.3.1 -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 832 bytes Desc: not available URL: From jsimmons at infradead.org Fri Jul 26 03:31:09 2019 From: jsimmons at infradead.org (James Simmons) Date: Fri, 26 Jul 2019 04:31:09 +0100 (BST) Subject: [lustre-devel] [PATCH 1/8] lustre: seq: make seq_proc_write_common() safer In-Reply-To: <87h879mzz3.fsf@notabene.neil.brown.name> References: <1564022647-17351-1-git-send-email-jsimmons@infradead.org> <1564022647-17351-2-git-send-email-jsimmons@infradead.org> <87h879mzz3.fsf@notabene.neil.brown.name> Message-ID: > > From: Andreas Dilger > > > > Don't allow seq_proc_write_common() to specify arbitrary ranges, > > since this can permanently corrupt the sequence controller and/or > > sequnece server. That would allow duplicate FID allocation, or > > possibly prevent any new files to be created or servers to be added > > to the filesystem. > > > > Instead, limit the sequence range that can be written via /proc to > > a subset of the sequence range currently allocated to that node. > > Add the "clear" keyword to allow dropping the entire local sequence > > and force a new one to be fetched from the sequence server. > > > > WC-bug-id: https://jira.whamcloud.com/browse/LU-3642 > > Lustre-commit: 05f69f5ee20eeffcc26f643333cedcfb53ba6669 > > Signed-off-by: Andreas Dilger > > Reviewed-on: http://review.whamcloud.com/7123 > > Reviewed-by: Jinshan Xiong > > Reviewed-by: Alex Zhuravlev > > Reviewed-by: James Simmons > > Reviewed-by: Oleg Drokin > > --- > > fs/lustre/fid/lproc_fid.c | 12 +++++++----- > > 1 file changed, 7 insertions(+), 5 deletions(-) > > I already have this is my backport branch. > a8ab6db57383 I pushed the first batch from your backport branch. I remember remember pushing some patches before for fid / fld that ended up being server only patches. Its not really clear what is server or client in that code. I was hoping for some feedback from Andreas and / or Oleg about this patch collect being server only. > > diff --git a/fs/lustre/fid/lproc_fid.c b/fs/lustre/fid/lproc_fid.c > > index 94869d4..e2e47df 100644 > > --- a/fs/lustre/fid/lproc_fid.c > > +++ b/fs/lustre/fid/lproc_fid.c > > @@ -52,14 +52,18 @@ > > /* Format: [0x64BIT_INT - 0x64BIT_INT] + 32 bytes just in case */ > > #define MAX_FID_RANGE_STRLEN (32 + 2 * 2 * sizeof(u64)) > > /* > > - * Note: this function is only used for testing, it is no safe for production > > - * use. > > + * Reduce the SEQ range allocated to a node to a strict subset of the range > > + * currently-allocated SEQ range. If the specified range is "clear", then > > + * drop all allocated sequences and request a new one from the master. > > + * > > + * Note: this function should only be used for testing, it is not necessarily > > + * safe for production use. > > */ > > static int > > ldebugfs_fid_write_common(const char __user *buffer, size_t count, > > struct lu_seq_range *range) > > { > > - struct lu_seq_range tmp; > > + struct lu_seq_range tmp = { 0, }; > > int rc; > > char kernbuf[MAX_FID_RANGE_STRLEN]; > > > > @@ -82,8 +86,6 @@ > > rc = sscanf(kernbuf, "[%llx - %llx]\n", > > (unsigned long long *)&tmp.lsr_start, > > (unsigned long long *)&tmp.lsr_end); > > - if (rc != 2) > > - return -EINVAL; > > if (!lu_seq_range_is_sane(&tmp) || lu_seq_range_is_zero(&tmp) || > > tmp.lsr_start < range->lsr_start || tmp.lsr_end > range->lsr_end) > > return -EINVAL; > > -- > > 1.8.3.1 > From jsimmons at infradead.org Mon Jul 29 19:40:28 2019 From: jsimmons at infradead.org (James Simmons) Date: Mon, 29 Jul 2019 20:40:28 +0100 (BST) Subject: [lustre-devel] [PATCH 10/11] lustre: ldlm: checkpatch cleanup In-Reply-To: References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> <1563760338-806-11-git-send-email-jsimmons@infradead.org> <87tvbdjwa7.fsf@notabene.neil.brown.name> <1BDF7232-853F-4B2D-AC0B-AC49E78F6884@amazon.com> Message-ID: > Le 25/07/2019 03:54, « James Simmons » a écrit : > > > > Le 24/07/2019 05:38, « lustre-devel au nom de James Simmons » a écrit : > > > > From checkpatch - "ENOSYS means 'invalid syscall nr' and nothing else" > > So using ENOSYS is no no. We get away with this because people rarely > > actually handle each error code individually. > > . > > > > As a general comment about this, I think we should improve this in the futur. Some people asked me "what's the error code when this or that happens in Lustre?". And I've got no real answer for that. > > Indeed people, most of the time, only checks returned code against 0. That does not help when looking at specific Lustre issues. > > perf probe 'lustre_function%return $retval' > > Does the same thing as lctl set_param debug=+trace except dynamic probes > can work on any kernel function without code modification!!! > > I mean from userspace. > When some applications want to adapt its behaviour depending on what is happening in Lustre. Ah I see what you mean. Actually I'm working on such a project. See https://jira.whamcloud.com/browse/LU-10756 I also gave a LUG talk about this work this year. Currently you can do this with sysfs tunables. So if you do a lctl set_param -P on the MGS server on the clients an udev event is created. Normally udev rules are used to managed these changes but you can write applications that responsed to these changes. You just need to use libudev for this type of monitoring. This is planned to be expanded to other areas for Lustre 2.14. One is the import state which a early patch exist for: https://review.whamcloud.com/#/c/31407 For this work the import state change is reported using udev to systemed. The changes seen in this case cover recovery state, evictions, idle etc. Bascially any state covered in enum lustre_imp_state from lustre_import.h. Additionally the sysfs work for LNet will always open new possibilities. We will be able to use udev events to report the network health state and well as network timeouts etc. Those are the areas for 2.14. Any others you can think of ? So this kind of functionality is being added to Lustre. If Amazon is interested in such work I can add you as a reviewer :-) From degremoa at amazon.com Tue Jul 30 16:02:39 2019 From: degremoa at amazon.com (Degremont, Aurelien) Date: Tue, 30 Jul 2019 16:02:39 +0000 Subject: [lustre-devel] [PATCH 10/11] lustre: ldlm: checkpatch cleanup In-Reply-To: References: <1563760338-806-1-git-send-email-jsimmons@infradead.org> <1563760338-806-11-git-send-email-jsimmons@infradead.org> <87tvbdjwa7.fsf@notabene.neil.brown.name> <1BDF7232-853F-4B2D-AC0B-AC49E78F6884@amazon.com> Message-ID: Hi James, I remember your talk(s) at LUG. This event-based work is a good thing but I was thinking at even simpler things. Thinking at syscall returned codes. By example: retcode when mounting a lustre filesystem failed, or retcode when doing I/O or even using lustre CLI tools. This is much more easier to handle that with a 'case' in your app, checking the retcode instead of deploying a more complex event based system. Aurélien Le 29/07/2019 21:41, « James Simmons » a écrit : > Le 25/07/2019 03:54, « James Simmons » a écrit : > > > > Le 24/07/2019 05:38, « lustre-devel au nom de James Simmons » a écrit : > > > > From checkpatch - "ENOSYS means 'invalid syscall nr' and nothing else" > > So using ENOSYS is no no. We get away with this because people rarely > > actually handle each error code individually. > > . > > > > As a general comment about this, I think we should improve this in the futur. Some people asked me "what's the error code when this or that happens in Lustre?". And I've got no real answer for that. > > Indeed people, most of the time, only checks returned code against 0. That does not help when looking at specific Lustre issues. > > perf probe 'lustre_function%return $retval' > > Does the same thing as lctl set_param debug=+trace except dynamic probes > can work on any kernel function without code modification!!! > > I mean from userspace. > When some applications want to adapt its behaviour depending on what is happening in Lustre. Ah I see what you mean. Actually I'm working on such a project. See https://jira.whamcloud.com/browse/LU-10756 I also gave a LUG talk about this work this year. Currently you can do this with sysfs tunables. So if you do a lctl set_param -P on the MGS server on the clients an udev event is created. Normally udev rules are used to managed these changes but you can write applications that responsed to these changes. You just need to use libudev for this type of monitoring. This is planned to be expanded to other areas for Lustre 2.14. One is the import state which a early patch exist for: https://review.whamcloud.com/#/c/31407 For this work the import state change is reported using udev to systemed. The changes seen in this case cover recovery state, evictions, idle etc. Bascially any state covered in enum lustre_imp_state from lustre_import.h. Additionally the sysfs work for LNet will always open new possibilities. We will be able to use udev events to report the network health state and well as network timeouts etc. Those are the areas for 2.14. Any others you can think of ? So this kind of functionality is being added to Lustre. If Amazon is interested in such work I can add you as a reviewer :-) From adilger at whamcloud.com Wed Jul 31 22:03:44 2019 From: adilger at whamcloud.com (Andreas Dilger) Date: Wed, 31 Jul 2019 22:03:44 +0000 Subject: [lustre-devel] [PATCH 01/22] ext4: add i_fs_version In-Reply-To: <87wogapuz2.fsf@notabene.neil.brown.name> References: <1563758631-29550-1-git-send-email-jsimmons@infradead.org> <1563758631-29550-2-git-send-email-jsimmons@infradead.org> <87wogapuz2.fsf@notabene.neil.brown.name> Message-ID: On Jul 21, 2019, at 22:13, NeilBrown wrote: > > On Sun, Jul 21 2019, James Simmons wrote: > >> From: James Simmons >> >> Add inode version field that osd-ldiskfs uses. > > We need more words here. What is i_fs_version used for? > > (I'll probably find out as I keep reading, but I need to know > the intention first, or I cannot properly review the patches > that make use of it. We use the 64-bit i_version field to store the Lustre transno in which the inode was last modified. This maintains the NFS required semantics that the version change when the inode is modified, but the number has a specific meaning so we don't want the ext4 code or VFS to just increment it. When a client modifies an inode, the old version is returned in the RPC reply to the client. The old version number can be used during Lustre recovery (RPC replay using "Version Based Recovery", VBR) after an MDS crash to determine if it is safe to apply this change to the inode, in the case that some clients have been evicted and we don't have a full stream of RPCs to replay. If we could get some way to prevent the kernel from updating the inode->i_version (which is now also a 64-bit value) then we could remove one more patch from our code. In the meantime, the current kernel is not conducive to hijacking inode->i_version so we need to store our own value in the ext4_inode_info and write that to disk instead of the kernel version. Cheers, Andreas > >> >> Signed-off-by: James Simmons >> --- >> fs/ext4/ext4.h | 2 ++ >> fs/ext4/ialloc.c | 1 + >> fs/ext4/inode.c | 4 ++-- >> 3 files changed, 5 insertions(+), 2 deletions(-) >> >> diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h >> index 1cb6785..8abbcab 100644 >> --- a/fs/ext4/ext4.h >> +++ b/fs/ext4/ext4.h >> @@ -1063,6 +1063,8 @@ struct ext4_inode_info { >> struct dquot *i_dquot[MAXQUOTAS]; >> #endif >> >> + u64 i_fs_version; >> + >> /* Precomputed uuid+inum+igen checksum for seeding inode checksums */ >> __u32 i_csum_seed; >> >> diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c >> index 764ff4c..09ae4a4 100644 >> --- a/fs/ext4/ialloc.c >> +++ b/fs/ext4/ialloc.c >> @@ -1100,6 +1100,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir, >> ei->i_dtime = 0; >> ei->i_block_group = group; >> ei->i_last_alloc_group = ~0; >> + ei->i_fs_version = 0; >> >> ext4_set_inode_flags(inode); >> if (IS_DIRSYNC(inode)) >> diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c >> index c7f77c6..6e66175 100644 >> --- a/fs/ext4/inode.c >> +++ b/fs/ext4/inode.c >> @@ -4806,14 +4806,14 @@ static inline void ext4_inode_set_iversion_queried(struct inode *inode, u64 val) >> if (unlikely(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) >> inode_set_iversion_raw(inode, val); >> else >> - inode_set_iversion_queried(inode, val); >> + EXT4_I(inode)->i_fs_version = val; >> } >> static inline u64 ext4_inode_peek_iversion(const struct inode *inode) >> { >> if (unlikely(EXT4_I(inode)->i_flags & EXT4_EA_INODE_FL)) >> return inode_peek_iversion_raw(inode); >> else >> - return inode_peek_iversion(inode); >> + return EXT4_I(inode)->i_fs_version; >> } >> >> struct inode *__ext4_iget(struct super_block *sb, unsigned long ino, >> -- >> 1.8.3.1 Cheers, Andreas -- Andreas Dilger Principal Lustre Architect Whamcloud