linux-stable/fs/xfs/libxfs/xfs_log_rlimit.c
Dave Chinner 0b61f8a407 xfs: convert to SPDX license tags
Remove the verbose license text from XFS files and replace them
with SPDX tags. This does not change the license of any of the code,
merely refers to the common, up-to-date license files in LICENSES/

This change was mostly scripted. fs/xfs/Makefile and
fs/xfs/libxfs/xfs_fs.h were modified by hand, the rest were detected
and modified by the following command:

for f in `git grep -l "GNU General" fs/xfs/` ; do
	echo $f
	cat $f | awk -f hdr.awk > $f.new
	mv -f $f.new $f
done

And the hdr.awk script that did the modification (including
detecting the difference between GPL-2.0 and GPL-2.0+ licenses)
is as follows:

$ cat hdr.awk
BEGIN {
	hdr = 1.0
	tag = "GPL-2.0"
	str = ""
}

/^ \* This program is free software/ {
	hdr = 2.0;
	next
}

/any later version./ {
	tag = "GPL-2.0+"
	next
}

/^ \*\// {
	if (hdr > 0.0) {
		print "// SPDX-License-Identifier: " tag
		print str
		print $0
		str=""
		hdr = 0.0
		next
	}
	print $0
	next
}

/^ \* / {
	if (hdr > 1.0)
		next
	if (hdr > 0.0) {
		if (str != "")
			str = str "\n"
		str = str $0
		next
	}
	print $0
	next
}

/^ \*/ {
	if (hdr > 0.0)
		next
	print $0
	next
}

// {
	if (hdr > 0.0) {
		if (str != "")
			str = str "\n"
		str = str $0
		next
	}
	print $0
}

END { }
$

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
2018-06-06 14:17:53 -07:00

136 lines
4.1 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2013 Jie Liu.
* All Rights Reserved.
*/
#include "xfs.h"
#include "xfs_fs.h"
#include "xfs_shared.h"
#include "xfs_format.h"
#include "xfs_log_format.h"
#include "xfs_trans_resv.h"
#include "xfs_mount.h"
#include "xfs_da_format.h"
#include "xfs_trans_space.h"
#include "xfs_inode.h"
#include "xfs_da_btree.h"
#include "xfs_attr_leaf.h"
#include "xfs_bmap_btree.h"
/*
* Calculate the maximum length in bytes that would be required for a local
* attribute value as large attributes out of line are not logged.
*/
STATIC int
xfs_log_calc_max_attrsetm_res(
struct xfs_mount *mp)
{
int size;
int nblks;
size = xfs_attr_leaf_entsize_local_max(mp->m_attr_geo->blksize) -
MAXNAMELEN - 1;
nblks = XFS_DAENTER_SPACE_RES(mp, XFS_ATTR_FORK);
nblks += XFS_B_TO_FSB(mp, size);
nblks += XFS_NEXTENTADD_SPACE_RES(mp, size, XFS_ATTR_FORK);
return M_RES(mp)->tr_attrsetm.tr_logres +
M_RES(mp)->tr_attrsetrt.tr_logres * nblks;
}
/*
* Iterate over the log space reservation table to figure out and return
* the maximum one in terms of the pre-calculated values which were done
* at mount time.
*/
void
xfs_log_get_max_trans_res(
struct xfs_mount *mp,
struct xfs_trans_res *max_resp)
{
struct xfs_trans_res *resp;
struct xfs_trans_res *end_resp;
int log_space = 0;
int attr_space;
attr_space = xfs_log_calc_max_attrsetm_res(mp);
resp = (struct xfs_trans_res *)M_RES(mp);
end_resp = (struct xfs_trans_res *)(M_RES(mp) + 1);
for (; resp < end_resp; resp++) {
int tmp = resp->tr_logcount > 1 ?
resp->tr_logres * resp->tr_logcount :
resp->tr_logres;
if (log_space < tmp) {
log_space = tmp;
*max_resp = *resp; /* struct copy */
}
}
if (attr_space > log_space) {
*max_resp = M_RES(mp)->tr_attrsetm; /* struct copy */
max_resp->tr_logres = attr_space;
}
}
/*
* Calculate the minimum valid log size for the given superblock configuration.
* Used to calculate the minimum log size at mkfs time, and to determine if
* the log is large enough or not at mount time. Returns the minimum size in
* filesystem block size units.
*/
int
xfs_log_calc_minimum_size(
struct xfs_mount *mp)
{
struct xfs_trans_res tres = {0};
int max_logres;
int min_logblks = 0;
int lsunit = 0;
xfs_log_get_max_trans_res(mp, &tres);
max_logres = xfs_log_calc_unit_res(mp, tres.tr_logres);
if (tres.tr_logcount > 1)
max_logres *= tres.tr_logcount;
if (xfs_sb_version_haslogv2(&mp->m_sb) && mp->m_sb.sb_logsunit > 1)
lsunit = BTOBB(mp->m_sb.sb_logsunit);
/*
* Two factors should be taken into account for calculating the minimum
* log space.
* 1) The fundamental limitation is that no single transaction can be
* larger than half size of the log.
*
* From mkfs.xfs, this is considered by the XFS_MIN_LOG_FACTOR
* define, which is set to 3. That means we can definitely fit
* maximally sized 2 transactions in the log. We'll use this same
* value here.
*
* 2) If the lsunit option is specified, a transaction requires 2 LSU
* for the reservation because there are two log writes that can
* require padding - the transaction data and the commit record which
* are written separately and both can require padding to the LSU.
* Consider that we can have an active CIL reservation holding 2*LSU,
* but the CIL is not over a push threshold, in this case, if we
* don't have enough log space for at one new transaction, which
* includes another 2*LSU in the reservation, we will run into dead
* loop situation in log space grant procedure. i.e.
* xlog_grant_head_wait().
*
* Hence the log size needs to be able to contain two maximally sized
* and padded transactions, which is (2 * (2 * LSU + maxlres)).
*
* Also, the log size should be a multiple of the log stripe unit, round
* it up to lsunit boundary if lsunit is specified.
*/
if (lsunit) {
min_logblks = roundup_64(BTOBB(max_logres), lsunit) +
2 * lsunit;
} else
min_logblks = BTOBB(max_logres) + 2 * BBSIZE;
min_logblks *= XFS_MIN_LOG_FACTOR;
return XFS_BB_TO_FSB(mp, min_logblks);
}