forked from Minki/linux
0b61f8a407
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>
137 lines
4.1 KiB
C
137 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);
|
|
}
|