Skip to content

Commit

Permalink
ocfs2: Add a missing journal credit in ocfs2_link_credits() -v2
Browse files Browse the repository at this point in the history
With indexed_dir enabled, ocfs2 maintains a list of dirblocks having
space.

The credit calculation in ocfs2_link_credits() did not correctly account
for adding an entry that exactly fills a dirblock that triggers removing
that dirblock by changing the pointer in the previous block in the list.
The credit calculation did not account for that previous block.

To expose, do:

mkfs.ocfs2 -b 512 -M local /dev/sdX
mount /dev/sdX /ocfs2
mkdir /ocfs2/linkdir
touch /ocfs2/linkdir/file1
for i in `seq 1 29` ; do link /ocfs2/linkdir/file1
/ocfs2/linkdir/linklinklinklinklinklink$i; done
rm -f /ocfs2/linkdir/linklinklinklinklinklink10
sleep 8
link /ocfs2/linkdir/file1
/ocfs2/linkdir/linklinklinklinklinklinkaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Note:
The link names have been crafted for a 512 byte blocksize. Reproducing
with a larger blocksize will require longer (or more) links. The sleep
is important. We want jbd2 to commit the transaction so that the missing
block does not piggy back on account of the previous transaction.

Signed-off-by: XiaoweiHu <xiaowei.hu at oracle.com>
Reviewed-by: WengangWang <wen.gang.wang at oracle.com>
Reviewed-by: Sunil.Mushran <sunil.mushran at oracle.com>
Signed-off-by: Joel Becker <jlbec@evilplan.org>
  • Loading branch information
Xiaowei.Hu authored and Joel Becker committed Nov 17, 2011
1 parent e41d33a commit 0393afe
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions fs/ocfs2/journal.h
Original file line number Diff line number Diff line change
Expand Up @@ -441,10 +441,11 @@ static inline int ocfs2_mknod_credits(struct super_block *sb, int is_dir,
#define OCFS2_SIMPLE_DIR_EXTEND_CREDITS (2)

/* file update (nlink, etc) + directory mtime/ctime + dir entry block + quota
* update on dir + index leaf + dx root update for free list */
* update on dir + index leaf + dx root update for free list +
* previous dirblock update in the free list */
static inline int ocfs2_link_credits(struct super_block *sb)
{
return 2*OCFS2_INODE_UPDATE_CREDITS + 3 +
return 2*OCFS2_INODE_UPDATE_CREDITS + 4 +
ocfs2_quota_trans_credits(sb);
}

Expand Down

0 comments on commit 0393afe

Please sign in to comment.