summaryrefslogtreecommitdiffstats
path: root/fs/ufs/inode.c
Commit message (Collapse)AuthorAgeFilesLines
* ufs_inode_get{frag,block}(): get rid of 'phys' argumentAl Viro2015-07-061-15/+8Star
| | | | | | | | | | | | | | | | Just pass NULL as locked_page in case of first block in the indirect chain. Old calling conventions aside, a reason for having 'phys' was that ufs_inode_getfrag() used to be able to do _two_ allocations - indirect block and extending/reallocating a tail. We needed locked_page for the latter (it's a data), but we also needed to figure out that indirect block is metadata. So we used to pass non-NULL locked_page in all cases *and* used NULL phys as indication of being asked to allocate an indirect. With tail unpacking taken into a separate function we don't need those convolutions anymore. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_getfrag_block(): tidy up a bitAl Viro2015-07-061-33/+15Star
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_inode_getblock(): failure to read an indirect block is -EIOAl Viro2015-07-061-2/+3
| | | | | | ... and not "write to beginning of the disk", TYVM... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_getfrag_block(): turn following indirects into a loopAl Viro2015-07-061-24/+8Star
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_inode_getfrag(): pass index instead of 'fragment'Al Viro2015-07-061-33/+17Star
| | | | | | same story as with ufs_inode_getblock() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_inode_getfrag(): split extending the partial blocks offAl Viro2015-07-061-63/+65
| | | | | | ufs_extend_tail() is handling that now. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_inode_getblock(): pass indirect block number and full indexAl Viro2015-07-061-46/+16Star
| | | | | | | ... instead of messing with buffer_head. We can bloody well do sb_bread() in there. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_inode_getblock(): pass index instead of 'fragment'Al Viro2015-07-061-19/+13Star
| | | | | | | | | | | | | The value passed to ufs_inode_getblock() as the 3rd argument had lower bits ignored; the upper bits were shifted down and used and they actually make sense - those are _lower_ bits of index in indirect block (i.e. they form the index within a fragment within an indirect block). Pass those as argument. Upper bits of index (i.e. the number of fragment within indirect block) will join them shortly. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_inode_get{frag,block}(): leave sb_getblk() to callerAl Viro2015-07-061-33/+55
| | | | | | just return the damn block number Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_getfrag_block(): get rid of macro junglesAl Viro2015-07-061-29/+22Star
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_inode_get{frag,block}(): consolidate success exitsAl Viro2015-07-061-28/+22Star
| | | | | | | | | | These calling conventions are rudiments of pre-2.3 times; they really need to be sanitized. This is the first step; next will be _always_ returning a block number, instead of this "return a pointer to buffer_head, except when we get to the actual data" crap. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs: use the branch depth in ufs_getfrag_block()Al Viro2015-07-061-6/+4Star
| | | | | | we'd already calculated it... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs: move calculation of offsets into ufs_getfrag_block()Al Viro2015-07-061-8/+9
| | | | | | | | | ... and massage ufs_frag_map() to take those instead of fragment number. As it is, we duplicate the damn thing on the write side, open-coded and bloody hard to follow. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_inode_get{frag,block}(): get rid of retriesAl Viro2015-07-061-35/+8Star
| | | | | | | | | We are holding ->truncate_mutex, so nobody else can alter our block pointers. Rechecks/retries were needed back when we only held BKL there, and had to cope with write_begin/writepage and writepage/truncate races. Can't happen anymore... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* __ufs_truncate_blocks(): avoid excessive dirtying of indirect blocksAl Viro2015-07-061-3/+1Star
| | | | | | | | | | | | | | There's a case when an indirect block gets dirtied for no good reason - when there's a hole starting in the middle of area covered by it and spanning past its end, and truncate() is done precisely to the beginning of the hole. The block is obviously not modified at all - all removals happen beyond it. However, existing code ends up dirtying it just in case. It's trivial to fix and while it's not a real bug by any stretch of imagination, it makes the damn thing harder to follow. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* free_full_branch(): don't bother modifying the block we are going to freeAl Viro2015-07-061-12/+2Star
| | | | | | | Note that it's already made unreachable from the inode, so we don't have to worry about ufs_frag_map() walking into something already freed. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* move marking inode dirty to the end of __ufs_truncate_blocks()Al Viro2015-07-061-6/+1Star
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* free_full_branch(): saner calling conventionsAl Viro2015-07-061-49/+51
| | | | | | | Have caller fetch the block number *and* remove it from wherever it was. Pass the block number instead. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_trunc_branch(): kill recursionAl Viro2015-07-061-26/+26
| | | | | | turn recursion into a pair of loops Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_trunc_branch(): massage towards killing recursionAl Viro2015-07-061-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | We always have 0 < depth2 <= depth in there, so if (--depth) { if (--depth2) A B } else { C // not using depth2 } D // not using depth2 is equivalent to if (--depth2) A with s/depth/depth - 1/ if (--depth) B else C D Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* split ufs_truncate_branch() into full- and partial-branch variantsAl Viro2015-07-061-16/+58
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs: unify the logics for collecting adjacent data blocks to freeAl Viro2015-07-061-34/+22Star
| | | | | | open-coded in several places... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_trunc_branch(): separate the calls with non-NULL offsetsAl Viro2015-07-061-4/+7
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_trunc_branch(): never call with offsets != NULL && depth2 == 0Al Viro2015-07-061-3/+6
| | | | | | | | | | For calls in __ufs_truncate_blocks() it's just a matter of not incrementing offsets[0] and not making that call - immediately following loop will be executed one extra time and we'll be just fine. For recursive call in ufs_trunc_branch() itself, just assing NULL to offsets if we would be about to make such call. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* __ufs_trunc_blocks(): turn the part after switch into a loopAl Viro2015-07-061-25/+10Star
| | | | | | | ... and turn the switch into if (), since all cases with depth != 1 have just become identical. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* __ufs_truncate_blocks(): unify freeing the full branchesAl Viro2015-07-061-15/+14Star
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* unify ufs_trunc_..indirect()Al Viro2015-07-061-138/+60Star
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_trunc_..indirect(): more massage towards unifyingAl Viro2015-07-061-17/+26
| | | | | | | | | | | | Instead of manually checking that the array contains only zeroes, find the position of the last non-zero (in __ufs_truncate(), where we can conveniently do that) and use that to tell if there's any non-zero in the array tail passed to ufs_trunc_...indirect(). The goal of all that clumsiness is to get fold these functions together. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_trunc_...indirect(): pass the array of indices instead of offsetsAl Viro2015-07-061-28/+22Star
| | | | | | | | rather than bitslicing the offset just formed as sum of shifted indices, pass the array of those indices itself. NULL is used as equivalent of "all zeroes" (== free the entire branch). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* __ufs_truncate(); find cutoff distances into branches by offsets[] arrayAl Viro2015-07-061-2/+6
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_trunc_dindirect(): pass the number of blocks to keepAl Viro2015-07-061-31/+26Star
| | | | | | same as the previous two. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_trunc_indirect(): pass the index of the first pointer to freeAl Viro2015-07-061-33/+23Star
| | | | | | | ... instead of file offset. Same cleanups as in the tindirect conversion in previous commit. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs_trunc_tindirect(): pass the number of blocks to keepAl Viro2015-07-061-17/+11Star
| | | | | | | | | | | | | | IOW, the distance of cutoff from the begining of the branch (in blocks). That (and the fact that block just prior to cutoff is guaranteed to be present) allows to tell whether to free triple indirect block just by looking at the offset. While we are at it, using u64 for index in the block is wrong - those should be unsigned int. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs: beginning of __ufs_truncate_block() massageAl Viro2015-07-061-4/+12
| | | | | | | | | Use ufs_block_to_path() to find the cutoff path in the block pointers' tree. For now just use the information about the depth (to bypass the fully preserved subtrees); subsequent commits will use the information about actual path. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs: the offsets ufs_block_to_path() puts into array are not sector_tAl Viro2015-07-061-3/+3
| | | | | | | | type makes no sense - those are indices in block number arrays, not block numbers. And no, UFS is not likely to grow indirect blocks with 4Gpointers in them... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs: move truncate code into inode.cAl Viro2015-07-061-12/+468
| | | | | | | | | It is closely tied to block pointers handling there, can benefit from existing helpers, etc. - no point keeping them apart. Trimmed the trailing whitespaces in inode.c at the same time. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs: don't use lock_ufs() for block pointers tree protectionAl Viro2015-07-061-45/+93
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * stores to block pointers are under per-inode seqlock (meta_lock) and mutex (truncate_mutex) * fetches of block pointers are either under truncate_mutex, or wrapped into seqretry loop on meta_lock * all changes of ->i_size are under truncate_mutex and i_mutex * all changes of ->i_lastfrag are under truncate_mutex It's similar to what ext2 is doing; the main difference is that unlike ext2 we can't rely upon the atomicity of stores into block pointers - on UFS2 they are 64bit. So we can't cut the corner when switching a pointer from NULL to non-NULL as we could in ext2_splice_branch() and need to use meta_lock on all modifications. We use seqlock where ext2 uses rwlock; ext2 could probably also benefit from such change... Another non-trivial difference is that with UFS we *cannot* have reader grab truncate_mutex in case of race - it has to keep retrying. That might be possible to change, but not until we lift tail unpacking several levels up in call chain. After that commit we do *NOT* hold fs-wide serialization on accesses to block pointers anymore. Moreover, lock_ufs() can become a normal mutex now - it's only used on statfs, remount and sync_fs and none of those uses are recursive. As the matter of fact, *now* it can be collapsed with ->s_lock, and be eventually replaced with saner per-cylinder-group spinlocks, but that's a separate story. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs: free excessive blocks upon ->write_begin() failure/short copyAl Viro2015-07-061-2/+16
| | | | | | | | | | Broken in "[PATCH] ufs: truncate should allocate block for last byte"; all way back in 2006. ufs_setattr() hadn't been the only user of vmtruncate() and eliminating ->truncate() method required corrections in a bunch of places. Eventually those places had migrated into ->write_begin() failure exit and ->write_end() after short copy... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs: switch ufs_evict_inode() to trimmed-down variant of ufs_truncate()Al Viro2015-07-061-7/+2Star
| | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs: kill more lock_ufs() callsAl Viro2015-07-061-11/+2Star
| | | | | | | | | a) move it inside ufs_truncate() b) ufs_free_inode() doesn't need it - it's serialized on ->s_lock c) ufs_write_inode() doesn't need it either (and can be called without it anyway). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* Merge branch 'for-linus' into for-nextAl Viro2015-06-171-1/+4
|\
| * fs/ufs: revert "ufs: fix deadlocks introduced by sb mutex merge"Fabian Frederick2015-06-141-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This reverts commit 9ef7db7f38d0 ("ufs: fix deadlocks introduced by sb mutex merge") That patch tried to solve commit 0244756edc4b98c ("ufs: sb mutex merge + mutex_destroy") which is itself partially reverted due to multiple deadlocks. Signed-off-by: Fabian Frederick <fabf@skynet.be> Suggested-by: Jan Kara <jack@suse.cz> Cc: Ian Campbell <ian.campbell@citrix.com> Cc: Evgeniy Dushistov <dushistov@mail.ru> Cc: Alexey Khoroshilov <khoroshilov@ispras.ru> Cc: Roger Pau Monne <roger.pau@citrix.com> Cc: Ian Jackson <Ian.Jackson@eu.citrix.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
* | ufs: switch to simple_follow_link()Al Viro2015-05-111-2/+3
|/ | | | Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* ufs: fix deadlocks introduced by sb mutex mergeAlexey Khoroshilov2014-09-071-5/+2Star
| | | | | | | | | | | | | | | | | Commit 0244756edc4b ("ufs: sb mutex merge + mutex_destroy") introduces deadlocks in ufs_new_inode() and ufs_free_inode(). Most callers of that functions acqure the mutex by themselves and ufs_{new,free}_inode() do that via lock_ufs(), i.e we have an unavoidable double lock. The patch proposes to resolve the issue by making sure that ufs_{new,free}_inode() are not called with the mutex held. Found by Linux Driver Verification project (linuxtesting.org). Cc: stable@vger.kernel.org # 3.16 Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* fs/ufs/inode.c: kernel-doc warning fixesFabian Frederick2014-08-091-16/+16
| | | | | | | Signed-off-by: Fabian Frederick <fabf@skynet.be> Cc: Evgeniy Dushistov <dushistov@mail.ru> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* mm + fs: store shadow entries in page cacheJohannes Weiner2014-04-041-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Reclaim will be leaving shadow entries in the page cache radix tree upon evicting the real page. As those pages are found from the LRU, an iput() can lead to the inode being freed concurrently. At this point, reclaim must no longer install shadow pages because the inode freeing code needs to ensure the page tree is really empty. Add an address_space flag, AS_EXITING, that the inode freeing code sets under the tree lock before doing the final truncate. Reclaim will check for this flag before installing shadow pages. Signed-off-by: Johannes Weiner <hannes@cmpxchg.org> Reviewed-by: Rik van Riel <riel@redhat.com> Reviewed-by: Minchan Kim <minchan@kernel.org> Cc: Andrea Arcangeli <aarcange@redhat.com> Cc: Bob Liu <bob.liu@oracle.com> Cc: Christoph Hellwig <hch@infradead.org> Cc: Dave Chinner <david@fromorbit.com> Cc: Greg Thelen <gthelen@google.com> Cc: Hugh Dickins <hughd@google.com> Cc: Jan Kara <jack@suse.cz> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Luigi Semenzato <semenzato@google.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Metin Doslu <metin@citusdata.com> Cc: Michel Lespinasse <walken@google.com> Cc: Ozgun Erdogan <ozgun@citusdata.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Roman Gushchin <klamm@yandex-team.ru> Cc: Ryan Mallon <rmallon@gmail.com> Cc: Tejun Heo <tj@kernel.org> Cc: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* truncate: drop 'oldsize' truncate_pagecache() parameterKirill A. Shutemov2013-09-131-1/+1
| | | | | | | | | | truncate_pagecache() doesn't care about old size since commit cedabed49b39 ("vfs: Fix vmtruncate() regression"). Let's drop it. Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Cc: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
* ufs: drop vmtruncateMarco Stornelli2012-12-201-5/+10
| | | | | | | Removed vmtruncate Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
* userns: Convert the ufs filesystem to use kuid/kgid where appropriateEric W. Biederman2012-09-211-8/+8
| | | | | | Cc: Evgeniy Dushistov <dushistov@mail.ru> Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
* vfs: Rename end_writeback() to clear_inode()Jan Kara2012-05-061-1/+1
| | | | | | | | | After we moved inode_sync_wait() from end_writeback() it doesn't make sense to call the function end_writeback() anymore. Rename it to clear_inode() which well says what the function really does - set I_CLEAR flag. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>