Merge branch 'xfs-4.10-misc-fixes-3' into for-next

This commit is contained in:
Dave Chinner 2016-12-07 17:42:30 +11:00
commit a444d72e60
28 changed files with 306 additions and 301 deletions

View File

@ -2455,12 +2455,15 @@ xfs_agf_verify(
be32_to_cpu(agf->agf_flcount) <= XFS_AGFL_SIZE(mp)))
return false;
if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS ||
if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 ||
be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 ||
be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) > XFS_BTREE_MAXLEVELS ||
be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) > XFS_BTREE_MAXLEVELS)
return false;
if (xfs_sb_version_hasrmapbt(&mp->m_sb) &&
be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS)
(be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) < 1 ||
be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) > XFS_BTREE_MAXLEVELS))
return false;
/*
@ -2477,7 +2480,8 @@ xfs_agf_verify(
return false;
if (xfs_sb_version_hasreflink(&mp->m_sb) &&
be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS)
(be32_to_cpu(agf->agf_refcount_level) < 1 ||
be32_to_cpu(agf->agf_refcount_level) > XFS_BTREE_MAXLEVELS))
return false;
return true;;

View File

@ -428,6 +428,10 @@ xfs_allocbt_init_cursor(
cur->bc_btnum = btnum;
cur->bc_blocklog = mp->m_sb.sb_blocklog;
cur->bc_ops = &xfs_allocbt_ops;
if (btnum == XFS_BTNUM_BNO)
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtb_2);
else
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_abtc_2);
if (btnum == XFS_BTNUM_CNT) {
cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);

View File

@ -77,7 +77,7 @@ int xfs_attr3_leaf_add(struct xfs_buf *leaf_buffer,
struct xfs_da_args *args);
int xfs_attr3_leaf_remove(struct xfs_buf *leaf_buffer,
struct xfs_da_args *args);
int xfs_attr3_leaf_list_int(struct xfs_buf *bp,
void xfs_attr3_leaf_list_int(struct xfs_buf *bp,
struct xfs_attr_list_context *context);
/*

View File

@ -518,7 +518,7 @@ void
xfs_bmap_trace_exlist(
xfs_inode_t *ip, /* incore inode pointer */
xfs_extnum_t cnt, /* count of entries in the list */
int whichfork, /* data or attr fork */
int whichfork, /* data or attr or cow fork */
unsigned long caller_ip)
{
xfs_extnum_t idx; /* extent record index */
@ -527,11 +527,13 @@ xfs_bmap_trace_exlist(
if (whichfork == XFS_ATTR_FORK)
state |= BMAP_ATTRFORK;
else if (whichfork == XFS_COW_FORK)
state |= BMAP_COWFORK;
ifp = XFS_IFORK_PTR(ip, whichfork);
ASSERT(cnt == xfs_iext_count(ifp));
for (idx = 0; idx < cnt; idx++)
trace_xfs_extlist(ip, idx, whichfork, caller_ip);
trace_xfs_extlist(ip, idx, state, caller_ip);
}
/*
@ -1151,6 +1153,10 @@ xfs_bmap_add_attrfork(
goto trans_cancel;
if (XFS_IFORK_Q(ip))
goto trans_cancel;
if (ip->i_d.di_anextents != 0) {
error = -EFSCORRUPTED;
goto trans_cancel;
}
if (ip->i_d.di_aformat != XFS_DINODE_FMT_EXTENTS) {
/*
* For inodes coming from pre-6.2 filesystems.
@ -1158,7 +1164,6 @@ xfs_bmap_add_attrfork(
ASSERT(ip->i_d.di_aformat == 0);
ip->i_d.di_aformat = XFS_DINODE_FMT_EXTENTS;
}
ASSERT(ip->i_d.di_anextents == 0);
xfs_trans_ijoin(tp, ip, 0);
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
@ -1375,8 +1380,9 @@ xfs_bmap_read_extents(
return error;
block = XFS_BUF_TO_BLOCK(bp);
}
if (i != XFS_IFORK_NEXTENTS(ip, whichfork))
return -EFSCORRUPTED;
ASSERT(i == xfs_iext_count(ifp));
ASSERT(i == XFS_IFORK_NEXTENTS(ip, whichfork));
XFS_BMAP_TRACE_EXLIST(ip, i, whichfork);
return 0;
error0:

View File

@ -803,6 +803,7 @@ xfs_bmbt_init_cursor(
cur->bc_nlevels = be16_to_cpu(ifp->if_broot->bb_level) + 1;
cur->bc_btnum = XFS_BTNUM_BMAP;
cur->bc_blocklog = mp->m_sb.sb_blocklog;
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_bmbt_2);
cur->bc_ops = &xfs_bmbt_ops;
cur->bc_flags = XFS_BTREE_LONG_PTRS | XFS_BTREE_ROOT_IN_INODE;

View File

@ -1769,8 +1769,28 @@ xfs_btree_lookup_get_block(
if (error)
return error;
/* Check the inode owner since the verifiers don't. */
if (xfs_sb_version_hascrc(&cur->bc_mp->m_sb) &&
(cur->bc_flags & XFS_BTREE_LONG_PTRS) &&
be64_to_cpu((*blkp)->bb_u.l.bb_owner) !=
cur->bc_private.b.ip->i_ino)
goto out_bad;
/* Did we get the level we were looking for? */
if (be16_to_cpu((*blkp)->bb_level) != level)
goto out_bad;
/* Check that internal nodes have at least one record. */
if (level != 0 && be16_to_cpu((*blkp)->bb_numrecs) == 0)
goto out_bad;
xfs_btree_setbuf(cur, level, bp);
return 0;
out_bad:
*blkp = NULL;
xfs_trans_brelse(cur->bc_tp, bp);
return -EFSCORRUPTED;
}
/*

View File

@ -96,46 +96,10 @@ union xfs_btree_rec {
/*
* Generic stats interface
*/
#define __XFS_BTREE_STATS_INC(mp, type, stat) \
XFS_STATS_INC(mp, xs_ ## type ## _2_ ## stat)
#define XFS_BTREE_STATS_INC(cur, stat) \
do { \
struct xfs_mount *__mp = cur->bc_mp; \
switch (cur->bc_btnum) { \
case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(__mp, abtb, stat); break; \
case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(__mp, abtc, stat); break; \
case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(__mp, bmbt, stat); break; \
case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(__mp, ibt, stat); break; \
case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(__mp, fibt, stat); break; \
case XFS_BTNUM_RMAP: __XFS_BTREE_STATS_INC(__mp, rmap, stat); break; \
case XFS_BTNUM_REFC: __XFS_BTREE_STATS_INC(__mp, refcbt, stat); break; \
case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
} \
} while (0)
#define __XFS_BTREE_STATS_ADD(mp, type, stat, val) \
XFS_STATS_ADD(mp, xs_ ## type ## _2_ ## stat, val)
#define XFS_BTREE_STATS_ADD(cur, stat, val) \
do { \
struct xfs_mount *__mp = cur->bc_mp; \
switch (cur->bc_btnum) { \
case XFS_BTNUM_BNO: \
__XFS_BTREE_STATS_ADD(__mp, abtb, stat, val); break; \
case XFS_BTNUM_CNT: \
__XFS_BTREE_STATS_ADD(__mp, abtc, stat, val); break; \
case XFS_BTNUM_BMAP: \
__XFS_BTREE_STATS_ADD(__mp, bmbt, stat, val); break; \
case XFS_BTNUM_INO: \
__XFS_BTREE_STATS_ADD(__mp, ibt, stat, val); break; \
case XFS_BTNUM_FINO: \
__XFS_BTREE_STATS_ADD(__mp, fibt, stat, val); break; \
case XFS_BTNUM_RMAP: \
__XFS_BTREE_STATS_ADD(__mp, rmap, stat, val); break; \
case XFS_BTNUM_REFC: \
__XFS_BTREE_STATS_ADD(__mp, refcbt, stat, val); break; \
case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break; \
} \
} while (0)
XFS_STATS_INC_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat)
#define XFS_BTREE_STATS_ADD(cur, stat, val) \
XFS_STATS_ADD_OFF((cur)->bc_mp, (cur)->bc_statoff + __XBTS_ ## stat, val)
#define XFS_BTREE_MAXLEVELS 9 /* max of all btrees */
@ -253,6 +217,7 @@ typedef struct xfs_btree_cur
__uint8_t bc_nlevels; /* number of levels in the tree */
__uint8_t bc_blocklog; /* log2(blocksize) of btree blocks */
xfs_btnum_t bc_btnum; /* identifies which btree type */
int bc_statoff; /* offset of btre stats array */
union {
struct { /* needed for BNO, CNT, INO */
struct xfs_buf *agbp; /* agf/agi buffer pointer */

View File

@ -6,10 +6,11 @@
/*
* Calculate the intermediate checksum for a buffer that has the CRC field
* inside it. The offset of the 32bit crc fields is passed as the
* cksum_offset parameter.
* cksum_offset parameter. We do not modify the buffer during verification,
* hence we have to split the CRC calculation across the cksum_offset.
*/
static inline __uint32_t
xfs_start_cksum(char *buffer, size_t length, unsigned long cksum_offset)
xfs_start_cksum_safe(char *buffer, size_t length, unsigned long cksum_offset)
{
__uint32_t zero = 0;
__uint32_t crc;
@ -25,6 +26,20 @@ xfs_start_cksum(char *buffer, size_t length, unsigned long cksum_offset)
length - (cksum_offset + sizeof(__be32)));
}
/*
* Fast CRC method where the buffer is modified. Callers must have exclusive
* access to the buffer while the calculation takes place.
*/
static inline __uint32_t
xfs_start_cksum_update(char *buffer, size_t length, unsigned long cksum_offset)
{
/* zero the CRC field */
*(__le32 *)(buffer + cksum_offset) = 0;
/* single pass CRC calculation for the entire buffer */
return crc32c(XFS_CRC_SEED, buffer, length);
}
/*
* Convert the intermediate checksum to the final ondisk format.
*
@ -40,11 +55,14 @@ xfs_end_cksum(__uint32_t crc)
/*
* Helper to generate the checksum for a buffer.
*
* This modifies the buffer temporarily - callers must have exclusive
* access to the buffer while the calculation takes place.
*/
static inline void
xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset)
{
__uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset);
__uint32_t crc = xfs_start_cksum_update(buffer, length, cksum_offset);
*(__le32 *)(buffer + cksum_offset) = xfs_end_cksum(crc);
}
@ -55,7 +73,7 @@ xfs_update_cksum(char *buffer, size_t length, unsigned long cksum_offset)
static inline int
xfs_verify_cksum(char *buffer, size_t length, unsigned long cksum_offset)
{
__uint32_t crc = xfs_start_cksum(buffer, length, cksum_offset);
__uint32_t crc = xfs_start_cksum_safe(buffer, length, cksum_offset);
return *(__le32 *)(buffer + cksum_offset) == xfs_end_cksum(crc);
}

View File

@ -329,7 +329,7 @@ xfs_dir3_data_read(
err = xfs_da_read_buf(tp, dp, bno, mapped_bno, bpp,
XFS_DATA_FORK, &xfs_dir3_data_buf_ops);
if (!err && tp)
if (!err && tp && *bpp)
xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_DIR_DATA_BUF);
return err;
}

View File

@ -2451,8 +2451,6 @@ xfs_ialloc_log_agi(
ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
#endif
xfs_trans_buf_set_type(tp, bp, XFS_BLFT_AGI_BUF);
/*
* Compute byte offsets for the first and last fields in the first
* region and log the agi buffer. This only logs up through
@ -2513,8 +2511,15 @@ xfs_agi_verify(
if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)))
return false;
if (be32_to_cpu(agi->agi_level) > XFS_BTREE_MAXLEVELS)
if (be32_to_cpu(agi->agi_level) < 1 ||
be32_to_cpu(agi->agi_level) > XFS_BTREE_MAXLEVELS)
return false;
if (xfs_sb_version_hasfinobt(&mp->m_sb) &&
(be32_to_cpu(agi->agi_free_level) < 1 ||
be32_to_cpu(agi->agi_free_level) > XFS_BTREE_MAXLEVELS))
return false;
/*
* during growfs operations, the perag is not fully initialised,
* so we can't use it for any useful checking. growfs ensures we can't
@ -2593,6 +2598,8 @@ xfs_read_agi(
XFS_FSS_TO_BB(mp, 1), 0, bpp, &xfs_agi_buf_ops);
if (error)
return error;
if (tp)
xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_AGI_BUF);
xfs_buf_set_ref(*bpp, XFS_AGI_REF);
return 0;

View File

@ -365,9 +365,11 @@ xfs_inobt_init_cursor(
if (btnum == XFS_BTNUM_INO) {
cur->bc_nlevels = be32_to_cpu(agi->agi_level);
cur->bc_ops = &xfs_inobt_ops;
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_ibt_2);
} else {
cur->bc_nlevels = be32_to_cpu(agi->agi_free_level);
cur->bc_ops = &xfs_finobt_ops;
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_fibt_2);
}
cur->bc_blocklog = mp->m_sb.sb_blocklog;

View File

@ -392,6 +392,14 @@ xfs_dinode_verify(
if (dip->di_magic != cpu_to_be16(XFS_DINODE_MAGIC))
return false;
/* don't allow invalid i_size */
if (be64_to_cpu(dip->di_size) & (1ULL << 63))
return false;
/* No zero-length symlinks. */
if (S_ISLNK(be16_to_cpu(dip->di_mode)) && dip->di_size == 0)
return false;
/* only version 3 or greater inodes are extensively verified here */
if (dip->di_version < 3)
return true;
@ -436,7 +444,7 @@ xfs_dinode_calc_crc(
return;
ASSERT(xfs_sb_version_hascrc(&mp->m_sb));
crc = xfs_start_cksum((char *)dip, mp->m_sb.sb_inodesize,
crc = xfs_start_cksum_update((char *)dip, mp->m_sb.sb_inodesize,
XFS_DINODE_CRC_OFF);
dip->di_crc = xfs_end_cksum(crc);
}

View File

@ -354,6 +354,7 @@ xfs_refcountbt_init_cursor(
cur->bc_btnum = XFS_BTNUM_REFC;
cur->bc_blocklog = mp->m_sb.sb_blocklog;
cur->bc_ops = &xfs_refcountbt_ops;
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2);
cur->bc_nlevels = be32_to_cpu(agf->agf_refcount_level);

View File

@ -484,6 +484,7 @@ xfs_rmapbt_init_cursor(
cur->bc_blocklog = mp->m_sb.sb_blocklog;
cur->bc_ops = &xfs_rmapbt_ops;
cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]);
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_rmap_2);
cur->bc_private.a.agbp = agbp;
cur->bc_private.a.agno = agno;

View File

@ -112,8 +112,8 @@ typedef struct attrlist_cursor_kern {
*========================================================================*/
/* Return 0 on success, or -errno; other state communicated via *context */
typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, int,
/* void; state communicated via *context */
typedef void (*put_listent_func_t)(struct xfs_attr_list_context *, int,
unsigned char *, int, int);
typedef struct xfs_attr_list_context {

View File

@ -74,7 +74,6 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
xfs_attr_sf_entry_t *sfe;
xfs_inode_t *dp;
int sbsize, nsbuf, count, i;
int error;
ASSERT(context != NULL);
dp = context->dp;
@ -102,13 +101,11 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
(XFS_ISRESET_CURSOR(cursor) &&
(dp->i_afp->if_bytes + sf->hdr.count * 16) < context->bufsize)) {
for (i = 0, sfe = &sf->list[0]; i < sf->hdr.count; i++) {
error = context->put_listent(context,
sfe->flags,
sfe->nameval,
(int)sfe->namelen,
(int)sfe->valuelen);
if (error)
return error;
context->put_listent(context,
sfe->flags,
sfe->nameval,
(int)sfe->namelen,
(int)sfe->valuelen);
/*
* Either search callback finished early or
* didn't fit it all in the buffer after all.
@ -193,15 +190,11 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
cursor->hashval = sbp->hash;
cursor->offset = 0;
}
error = context->put_listent(context,
sbp->flags,
sbp->name,
sbp->namelen,
sbp->valuelen);
if (error) {
kmem_free(sbuf);
return error;
}
context->put_listent(context,
sbp->flags,
sbp->name,
sbp->namelen,
sbp->valuelen);
if (context->seen_enough)
break;
cursor->offset++;
@ -335,11 +328,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
*/
for (;;) {
leaf = bp->b_addr;
error = xfs_attr3_leaf_list_int(bp, context);
if (error) {
xfs_trans_brelse(NULL, bp);
return error;
}
xfs_attr3_leaf_list_int(bp, context);
xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
if (context->seen_enough || leafhdr.forw == 0)
break;
@ -356,7 +345,7 @@ xfs_attr_node_list(xfs_attr_list_context_t *context)
/*
* Copy out attribute list entries for attr_list(), for leaf attribute lists.
*/
int
void
xfs_attr3_leaf_list_int(
struct xfs_buf *bp,
struct xfs_attr_list_context *context)
@ -366,7 +355,6 @@ xfs_attr3_leaf_list_int(
struct xfs_attr3_icleaf_hdr ichdr;
struct xfs_attr_leaf_entry *entries;
struct xfs_attr_leaf_entry *entry;
int retval;
int i;
struct xfs_mount *mp = context->dp->i_mount;
@ -399,7 +387,7 @@ xfs_attr3_leaf_list_int(
}
if (i == ichdr.count) {
trace_xfs_attr_list_notfound(context);
return 0;
return;
}
} else {
entry = &entries[0];
@ -410,7 +398,6 @@ xfs_attr3_leaf_list_int(
/*
* We have found our place, start copying out the new attributes.
*/
retval = 0;
for (; i < ichdr.count; entry++, i++) {
char *name;
int namelen, valuelen;
@ -439,16 +426,14 @@ xfs_attr3_leaf_list_int(
valuelen = be32_to_cpu(name_rmt->valuelen);
}
retval = context->put_listent(context, entry->flags,
context->put_listent(context, entry->flags,
name, namelen, valuelen);
if (retval)
break;
if (context->seen_enough)
break;
cursor->offset++;
}
trace_xfs_attr_list_leaf_end(context);
return retval;
return;
}
/*
@ -467,9 +452,9 @@ xfs_attr_leaf_list(xfs_attr_list_context_t *context)
if (error)
return error;
error = xfs_attr3_leaf_list_int(bp, context);
xfs_attr3_leaf_list_int(bp, context);
xfs_trans_brelse(NULL, bp);
return error;
return 0;
}
int
@ -513,7 +498,7 @@ xfs_attr_list_int(
* Take care to check values and protect against them changing later,
* we may be reading them directly out of a user buffer.
*/
STATIC int
STATIC void
xfs_attr_put_listent(
xfs_attr_list_context_t *context,
int flags,
@ -536,10 +521,10 @@ xfs_attr_put_listent(
*/
if (((context->flags & ATTR_SECURE) == 0) !=
((flags & XFS_ATTR_SECURE) == 0))
return 0;
return;
if (((context->flags & ATTR_ROOT) == 0) !=
((flags & XFS_ATTR_ROOT) == 0))
return 0;
return;
arraytop = sizeof(*alist) +
context->count * sizeof(alist->al_offset[0]);
@ -548,7 +533,7 @@ xfs_attr_put_listent(
trace_xfs_attr_list_full(context);
alist->al_more = 1;
context->seen_enough = 1;
return 0;
return;
}
aep = (attrlist_ent_t *)&context->alist[context->firstu];
@ -558,7 +543,7 @@ xfs_attr_put_listent(
alist->al_offset[context->count++] = context->firstu;
alist->al_count = context->count;
trace_xfs_attr_list_add(context);
return 0;
return;
}
/*

View File

@ -219,7 +219,6 @@ _xfs_buf_alloc(
init_completion(&bp->b_iowait);
INIT_LIST_HEAD(&bp->b_lru);
INIT_LIST_HEAD(&bp->b_list);
RB_CLEAR_NODE(&bp->b_rbnode);
sema_init(&bp->b_sema, 0); /* held, no waiters */
spin_lock_init(&bp->b_lock);
XB_SET_OWNER(bp);
@ -473,6 +472,62 @@ _xfs_buf_map_pages(
/*
* Finding and Reading Buffers
*/
static int
_xfs_buf_obj_cmp(
struct rhashtable_compare_arg *arg,
const void *obj)
{
const struct xfs_buf_map *map = arg->key;
const struct xfs_buf *bp = obj;
/*
* The key hashing in the lookup path depends on the key being the
* first element of the compare_arg, make sure to assert this.
*/
BUILD_BUG_ON(offsetof(struct xfs_buf_map, bm_bn) != 0);
if (bp->b_bn != map->bm_bn)
return 1;
if (unlikely(bp->b_length != map->bm_len)) {
/*
* found a block number match. If the range doesn't
* match, the only way this is allowed is if the buffer
* in the cache is stale and the transaction that made
* it stale has not yet committed. i.e. we are
* reallocating a busy extent. Skip this buffer and
* continue searching for an exact match.
*/
ASSERT(bp->b_flags & XBF_STALE);
return 1;
}
return 0;
}
static const struct rhashtable_params xfs_buf_hash_params = {
.min_size = 32, /* empty AGs have minimal footprint */
.nelem_hint = 16,
.key_len = sizeof(xfs_daddr_t),
.key_offset = offsetof(struct xfs_buf, b_bn),
.head_offset = offsetof(struct xfs_buf, b_rhash_head),
.automatic_shrinking = true,
.obj_cmpfn = _xfs_buf_obj_cmp,
};
int
xfs_buf_hash_init(
struct xfs_perag *pag)
{
spin_lock_init(&pag->pag_buf_lock);
return rhashtable_init(&pag->pag_buf_hash, &xfs_buf_hash_params);
}
void
xfs_buf_hash_destroy(
struct xfs_perag *pag)
{
rhashtable_destroy(&pag->pag_buf_hash);
}
/*
* Look up, and creates if absent, a lockable buffer for
@ -488,27 +543,24 @@ _xfs_buf_find(
xfs_buf_t *new_bp)
{
struct xfs_perag *pag;
struct rb_node **rbp;
struct rb_node *parent;
xfs_buf_t *bp;
xfs_daddr_t blkno = map[0].bm_bn;
struct xfs_buf_map cmap = { .bm_bn = map[0].bm_bn };
xfs_daddr_t eofs;
int numblks = 0;
int i;
for (i = 0; i < nmaps; i++)
numblks += map[i].bm_len;
cmap.bm_len += map[i].bm_len;
/* Check for IOs smaller than the sector size / not sector aligned */
ASSERT(!(BBTOB(numblks) < btp->bt_meta_sectorsize));
ASSERT(!(BBTOB(blkno) & (xfs_off_t)btp->bt_meta_sectormask));
ASSERT(!(BBTOB(cmap.bm_len) < btp->bt_meta_sectorsize));
ASSERT(!(BBTOB(cmap.bm_bn) & (xfs_off_t)btp->bt_meta_sectormask));
/*
* Corrupted block numbers can get through to here, unfortunately, so we
* have to check that the buffer falls within the filesystem bounds.
*/
eofs = XFS_FSB_TO_BB(btp->bt_mount, btp->bt_mount->m_sb.sb_dblocks);
if (blkno < 0 || blkno >= eofs) {
if (cmap.bm_bn < 0 || cmap.bm_bn >= eofs) {
/*
* XXX (dgc): we should really be returning -EFSCORRUPTED here,
* but none of the higher level infrastructure supports
@ -516,53 +568,29 @@ _xfs_buf_find(
*/
xfs_alert(btp->bt_mount,
"%s: Block out of range: block 0x%llx, EOFS 0x%llx ",
__func__, blkno, eofs);
__func__, cmap.bm_bn, eofs);
WARN_ON(1);
return NULL;
}
/* get tree root */
pag = xfs_perag_get(btp->bt_mount,
xfs_daddr_to_agno(btp->bt_mount, blkno));
xfs_daddr_to_agno(btp->bt_mount, cmap.bm_bn));
/* walk tree */
spin_lock(&pag->pag_buf_lock);
rbp = &pag->pag_buf_tree.rb_node;
parent = NULL;
bp = NULL;
while (*rbp) {
parent = *rbp;
bp = rb_entry(parent, struct xfs_buf, b_rbnode);
if (blkno < bp->b_bn)
rbp = &(*rbp)->rb_left;
else if (blkno > bp->b_bn)
rbp = &(*rbp)->rb_right;
else {
/*
* found a block number match. If the range doesn't
* match, the only way this is allowed is if the buffer
* in the cache is stale and the transaction that made
* it stale has not yet committed. i.e. we are
* reallocating a busy extent. Skip this buffer and
* continue searching to the right for an exact match.
*/
if (bp->b_length != numblks) {
ASSERT(bp->b_flags & XBF_STALE);
rbp = &(*rbp)->rb_right;
continue;
}
atomic_inc(&bp->b_hold);
goto found;
}
bp = rhashtable_lookup_fast(&pag->pag_buf_hash, &cmap,
xfs_buf_hash_params);
if (bp) {
atomic_inc(&bp->b_hold);
goto found;
}
/* No match found */
if (new_bp) {
rb_link_node(&new_bp->b_rbnode, parent, rbp);
rb_insert_color(&new_bp->b_rbnode, &pag->pag_buf_tree);
/* the buffer keeps the perag reference until it is freed */
new_bp->b_pag = pag;
rhashtable_insert_fast(&pag->pag_buf_hash,
&new_bp->b_rhash_head,
xfs_buf_hash_params);
spin_unlock(&pag->pag_buf_lock);
} else {
XFS_STATS_INC(btp->bt_mount, xb_miss_locked);
@ -930,7 +958,6 @@ xfs_buf_rele(
if (!pag) {
ASSERT(list_empty(&bp->b_lru));
ASSERT(RB_EMPTY_NODE(&bp->b_rbnode));
if (atomic_dec_and_test(&bp->b_hold)) {
xfs_buf_ioacct_dec(bp);
xfs_buf_free(bp);
@ -938,8 +965,6 @@ xfs_buf_rele(
return;
}
ASSERT(!RB_EMPTY_NODE(&bp->b_rbnode));
ASSERT(atomic_read(&bp->b_hold) > 0);
release = atomic_dec_and_lock(&bp->b_hold, &pag->pag_buf_lock);
@ -983,7 +1008,8 @@ xfs_buf_rele(
}
ASSERT(!(bp->b_flags & _XBF_DELWRI_Q));
rb_erase(&bp->b_rbnode, &pag->pag_buf_tree);
rhashtable_remove_fast(&pag->pag_buf_hash, &bp->b_rhash_head,
xfs_buf_hash_params);
spin_unlock(&pag->pag_buf_lock);
xfs_perag_put(pag);
freebuf = true;

View File

@ -151,7 +151,7 @@ typedef struct xfs_buf {
* which is the only bit that is touched if we hit the semaphore
* fast-path on locking.
*/
struct rb_node b_rbnode; /* rbtree node */
struct rhash_head b_rhash_head; /* pag buffer hash node */
xfs_daddr_t b_bn; /* block number of buffer */
int b_length; /* size of buffer in BBs */
atomic_t b_hold; /* reference count */

View File

@ -883,7 +883,6 @@ xfs_file_clone_range(
len, false);
}
#define XFS_MAX_DEDUPE_LEN (16 * 1024 * 1024)
STATIC ssize_t
xfs_file_dedupe_range(
struct file *src_file,
@ -894,14 +893,6 @@ xfs_file_dedupe_range(
{
int error;
/*
* Limit the total length we will dedupe for each operation.
* This is intended to bound the total time spent in this
* ioctl to something sane.
*/
if (len > XFS_MAX_DEDUPE_LEN)
len = XFS_MAX_DEDUPE_LEN;
error = xfs_reflink_remap_range(src_file, loff, dst_file, dst_loff,
len, true);
if (error)

View File

@ -2032,7 +2032,6 @@ xfs_iunlink(
agi->agi_unlinked[bucket_index] = cpu_to_be32(agino);
offset = offsetof(xfs_agi_t, agi_unlinked) +
(sizeof(xfs_agino_t) * bucket_index);
xfs_trans_buf_set_type(tp, agibp, XFS_BLFT_AGI_BUF);
xfs_trans_log_buf(tp, agibp, offset,
(offset + sizeof(xfs_agino_t) - 1));
return 0;
@ -2124,7 +2123,6 @@ xfs_iunlink_remove(
agi->agi_unlinked[bucket_index] = cpu_to_be32(next_agino);
offset = offsetof(xfs_agi_t, agi_unlinked) +
(sizeof(xfs_agino_t) * bucket_index);
xfs_trans_buf_set_type(tp, agibp, XFS_BLFT_AGI_BUF);
xfs_trans_log_buf(tp, agibp, offset,
(offset + sizeof(xfs_agino_t) - 1));
} else {

View File

@ -78,6 +78,7 @@ typedef __u32 xfs_nlink_t;
#include <linux/freezer.h>
#include <linux/list_sort.h>
#include <linux/ratelimit.h>
#include <linux/rhashtable.h>
#include <asm/page.h>
#include <asm/div64.h>

View File

@ -1668,7 +1668,7 @@ xlog_cksum(
__uint32_t crc;
/* first generate the crc for the record header ... */
crc = xfs_start_cksum((char *)rhead,
crc = xfs_start_cksum_update((char *)rhead,
sizeof(struct xlog_rec_header),
offsetof(struct xlog_rec_header, h_crc));

View File

@ -5113,19 +5113,21 @@ xlog_recover_process(
struct list_head *buffer_list)
{
int error;
__le32 old_crc = rhead->h_crc;
__le32 crc;
crc = xlog_cksum(log, rhead, dp, be32_to_cpu(rhead->h_len));
/*
* Nothing else to do if this is a CRC verification pass. Just return
* if this a record with a non-zero crc. Unfortunately, mkfs always
* sets h_crc to 0 so we must consider this valid even on v5 supers.
* sets old_crc to 0 so we must consider this valid even on v5 supers.
* Otherwise, return EFSBADCRC on failure so the callers up the stack
* know precisely what failed.
*/
if (pass == XLOG_RECOVER_CRCPASS) {
if (rhead->h_crc && crc != rhead->h_crc)
if (old_crc && crc != old_crc)
return -EFSBADCRC;
return 0;
}
@ -5136,11 +5138,11 @@ xlog_recover_process(
* zero CRC check prevents warnings from being emitted when upgrading
* the kernel from one that does not add CRCs by default.
*/
if (crc != rhead->h_crc) {
if (rhead->h_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
if (crc != old_crc) {
if (old_crc || xfs_sb_version_hascrc(&log->l_mp->m_sb)) {
xfs_alert(log->l_mp,
"log record CRC mismatch: found 0x%x, expected 0x%x.",
le32_to_cpu(rhead->h_crc),
le32_to_cpu(old_crc),
le32_to_cpu(crc));
xfs_hex_dump(dp, 32);
}

View File

@ -157,6 +157,7 @@ xfs_free_perag(
spin_unlock(&mp->m_perag_lock);
ASSERT(pag);
ASSERT(atomic_read(&pag->pag_ref) == 0);
xfs_buf_hash_destroy(pag);
call_rcu(&pag->rcu_head, __xfs_free_perag);
}
}
@ -212,8 +213,8 @@ xfs_initialize_perag(
spin_lock_init(&pag->pag_ici_lock);
mutex_init(&pag->pag_ici_reclaim_lock);
INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
spin_lock_init(&pag->pag_buf_lock);
pag->pag_buf_tree = RB_ROOT;
if (xfs_buf_hash_init(pag))
goto out_unwind;
if (radix_tree_preload(GFP_NOFS))
goto out_unwind;
@ -239,9 +240,11 @@ xfs_initialize_perag(
return 0;
out_unwind:
xfs_buf_hash_destroy(pag);
kmem_free(pag);
for (; index > first_initialised; index--) {
pag = radix_tree_delete(&mp->m_perag_tree, index);
xfs_buf_hash_destroy(pag);
kmem_free(pag);
}
return error;

View File

@ -393,8 +393,8 @@ typedef struct xfs_perag {
unsigned long pag_ici_reclaim_cursor; /* reclaim restart point */
/* buffer cache index */
spinlock_t pag_buf_lock; /* lock for pag_buf_tree */
struct rb_root pag_buf_tree; /* ordered tree of active buffers */
spinlock_t pag_buf_lock; /* lock for pag_buf_hash */
struct rhashtable pag_buf_hash;
/* for rcu-safe freeing */
struct rcu_head rcu_head;
@ -424,6 +424,9 @@ xfs_perag_resv(
}
}
int xfs_buf_hash_init(xfs_perag_t *pag);
void xfs_buf_hash_destroy(xfs_perag_t *pag);
extern void xfs_uuid_table_free(void);
extern int xfs_log_sbcount(xfs_mount_t *);
extern __uint64_t xfs_default_resblks(xfs_mount_t *mp);

View File

@ -80,9 +80,9 @@ int xfs_stats_format(struct xfsstats __percpu *stats, char *buf)
}
/* extra precision counters */
for_each_possible_cpu(i) {
xs_xstrat_bytes += per_cpu_ptr(stats, i)->xs_xstrat_bytes;
xs_write_bytes += per_cpu_ptr(stats, i)->xs_write_bytes;
xs_read_bytes += per_cpu_ptr(stats, i)->xs_read_bytes;
xs_xstrat_bytes += per_cpu_ptr(stats, i)->s.xs_xstrat_bytes;
xs_write_bytes += per_cpu_ptr(stats, i)->s.xs_write_bytes;
xs_read_bytes += per_cpu_ptr(stats, i)->s.xs_read_bytes;
}
len += snprintf(buf + len, PATH_MAX-len, "xpc %Lu %Lu %Lu\n",
@ -106,9 +106,9 @@ void xfs_stats_clearall(struct xfsstats __percpu *stats)
for_each_possible_cpu(c) {
preempt_disable();
/* save vn_active, it's a universal truth! */
vn_active = per_cpu_ptr(stats, c)->vn_active;
vn_active = per_cpu_ptr(stats, c)->s.vn_active;
memset(per_cpu_ptr(stats, c), 0, sizeof(*stats));
per_cpu_ptr(stats, c)->vn_active = vn_active;
per_cpu_ptr(stats, c)->s.vn_active = vn_active;
preempt_enable();
}
}

View File

@ -21,10 +21,38 @@
#include <linux/percpu.h>
/*
* The btree stats arrays have fixed offsets for the different stats. We
* store the base index in the btree cursor via XFS_STATS_CALC_INDEX() and
* that allows us to use fixed offsets into the stats array for each btree
* stat. These index offsets are defined in the order they will be emitted
* in the stats files, so it is possible to add new btree stat types by
* appending to the enum list below.
*/
enum {
__XBTS_lookup = 0,
__XBTS_compare = 1,
__XBTS_insrec = 2,
__XBTS_delrec = 3,
__XBTS_newroot = 4,
__XBTS_killroot = 5,
__XBTS_increment = 6,
__XBTS_decrement = 7,
__XBTS_lshift = 8,
__XBTS_rshift = 9,
__XBTS_split = 10,
__XBTS_join = 11,
__XBTS_alloc = 12,
__XBTS_free = 13,
__XBTS_moves = 14,
__XBTS_MAX = 15,
};
/*
* XFS global statistics
*/
struct xfsstats {
struct __xfsstats {
# define XFSSTAT_END_EXTENT_ALLOC 4
__uint32_t xs_allocx;
__uint32_t xs_allocb;
@ -117,118 +145,20 @@ struct xfsstats {
__uint32_t xb_page_found;
__uint32_t xb_get_read;
/* Version 2 btree counters */
#define XFSSTAT_END_ABTB_V2 (XFSSTAT_END_BUF+15)
__uint32_t xs_abtb_2_lookup;
__uint32_t xs_abtb_2_compare;
__uint32_t xs_abtb_2_insrec;
__uint32_t xs_abtb_2_delrec;
__uint32_t xs_abtb_2_newroot;
__uint32_t xs_abtb_2_killroot;
__uint32_t xs_abtb_2_increment;
__uint32_t xs_abtb_2_decrement;
__uint32_t xs_abtb_2_lshift;
__uint32_t xs_abtb_2_rshift;
__uint32_t xs_abtb_2_split;
__uint32_t xs_abtb_2_join;
__uint32_t xs_abtb_2_alloc;
__uint32_t xs_abtb_2_free;
__uint32_t xs_abtb_2_moves;
#define XFSSTAT_END_ABTC_V2 (XFSSTAT_END_ABTB_V2+15)
__uint32_t xs_abtc_2_lookup;
__uint32_t xs_abtc_2_compare;
__uint32_t xs_abtc_2_insrec;
__uint32_t xs_abtc_2_delrec;
__uint32_t xs_abtc_2_newroot;
__uint32_t xs_abtc_2_killroot;
__uint32_t xs_abtc_2_increment;
__uint32_t xs_abtc_2_decrement;
__uint32_t xs_abtc_2_lshift;
__uint32_t xs_abtc_2_rshift;
__uint32_t xs_abtc_2_split;
__uint32_t xs_abtc_2_join;
__uint32_t xs_abtc_2_alloc;
__uint32_t xs_abtc_2_free;
__uint32_t xs_abtc_2_moves;
#define XFSSTAT_END_BMBT_V2 (XFSSTAT_END_ABTC_V2+15)
__uint32_t xs_bmbt_2_lookup;
__uint32_t xs_bmbt_2_compare;
__uint32_t xs_bmbt_2_insrec;
__uint32_t xs_bmbt_2_delrec;
__uint32_t xs_bmbt_2_newroot;
__uint32_t xs_bmbt_2_killroot;
__uint32_t xs_bmbt_2_increment;
__uint32_t xs_bmbt_2_decrement;
__uint32_t xs_bmbt_2_lshift;
__uint32_t xs_bmbt_2_rshift;
__uint32_t xs_bmbt_2_split;
__uint32_t xs_bmbt_2_join;
__uint32_t xs_bmbt_2_alloc;
__uint32_t xs_bmbt_2_free;
__uint32_t xs_bmbt_2_moves;
#define XFSSTAT_END_IBT_V2 (XFSSTAT_END_BMBT_V2+15)
__uint32_t xs_ibt_2_lookup;
__uint32_t xs_ibt_2_compare;
__uint32_t xs_ibt_2_insrec;
__uint32_t xs_ibt_2_delrec;
__uint32_t xs_ibt_2_newroot;
__uint32_t xs_ibt_2_killroot;
__uint32_t xs_ibt_2_increment;
__uint32_t xs_ibt_2_decrement;
__uint32_t xs_ibt_2_lshift;
__uint32_t xs_ibt_2_rshift;
__uint32_t xs_ibt_2_split;
__uint32_t xs_ibt_2_join;
__uint32_t xs_ibt_2_alloc;
__uint32_t xs_ibt_2_free;
__uint32_t xs_ibt_2_moves;
#define XFSSTAT_END_FIBT_V2 (XFSSTAT_END_IBT_V2+15)
__uint32_t xs_fibt_2_lookup;
__uint32_t xs_fibt_2_compare;
__uint32_t xs_fibt_2_insrec;
__uint32_t xs_fibt_2_delrec;
__uint32_t xs_fibt_2_newroot;
__uint32_t xs_fibt_2_killroot;
__uint32_t xs_fibt_2_increment;
__uint32_t xs_fibt_2_decrement;
__uint32_t xs_fibt_2_lshift;
__uint32_t xs_fibt_2_rshift;
__uint32_t xs_fibt_2_split;
__uint32_t xs_fibt_2_join;
__uint32_t xs_fibt_2_alloc;
__uint32_t xs_fibt_2_free;
__uint32_t xs_fibt_2_moves;
#define XFSSTAT_END_RMAP_V2 (XFSSTAT_END_FIBT_V2+15)
__uint32_t xs_rmap_2_lookup;
__uint32_t xs_rmap_2_compare;
__uint32_t xs_rmap_2_insrec;
__uint32_t xs_rmap_2_delrec;
__uint32_t xs_rmap_2_newroot;
__uint32_t xs_rmap_2_killroot;
__uint32_t xs_rmap_2_increment;
__uint32_t xs_rmap_2_decrement;
__uint32_t xs_rmap_2_lshift;
__uint32_t xs_rmap_2_rshift;
__uint32_t xs_rmap_2_split;
__uint32_t xs_rmap_2_join;
__uint32_t xs_rmap_2_alloc;
__uint32_t xs_rmap_2_free;
__uint32_t xs_rmap_2_moves;
#define XFSSTAT_END_REFCOUNT (XFSSTAT_END_RMAP_V2 + 15)
__uint32_t xs_refcbt_2_lookup;
__uint32_t xs_refcbt_2_compare;
__uint32_t xs_refcbt_2_insrec;
__uint32_t xs_refcbt_2_delrec;
__uint32_t xs_refcbt_2_newroot;
__uint32_t xs_refcbt_2_killroot;
__uint32_t xs_refcbt_2_increment;
__uint32_t xs_refcbt_2_decrement;
__uint32_t xs_refcbt_2_lshift;
__uint32_t xs_refcbt_2_rshift;
__uint32_t xs_refcbt_2_split;
__uint32_t xs_refcbt_2_join;
__uint32_t xs_refcbt_2_alloc;
__uint32_t xs_refcbt_2_free;
__uint32_t xs_refcbt_2_moves;
#define XFSSTAT_END_ABTB_V2 (XFSSTAT_END_BUF + __XBTS_MAX)
__uint32_t xs_abtb_2[__XBTS_MAX];
#define XFSSTAT_END_ABTC_V2 (XFSSTAT_END_ABTB_V2 + __XBTS_MAX)
__uint32_t xs_abtc_2[__XBTS_MAX];
#define XFSSTAT_END_BMBT_V2 (XFSSTAT_END_ABTC_V2 + __XBTS_MAX)
__uint32_t xs_bmbt_2[__XBTS_MAX];
#define XFSSTAT_END_IBT_V2 (XFSSTAT_END_BMBT_V2 + __XBTS_MAX)
__uint32_t xs_ibt_2[__XBTS_MAX];
#define XFSSTAT_END_FIBT_V2 (XFSSTAT_END_IBT_V2 + __XBTS_MAX)
__uint32_t xs_fibt_2[__XBTS_MAX];
#define XFSSTAT_END_RMAP_V2 (XFSSTAT_END_FIBT_V2 + __XBTS_MAX)
__uint32_t xs_rmap_2[__XBTS_MAX];
#define XFSSTAT_END_REFCOUNT (XFSSTAT_END_RMAP_V2 + __XBTS_MAX)
__uint32_t xs_refcbt_2[__XBTS_MAX];
#define XFSSTAT_END_XQMSTAT (XFSSTAT_END_REFCOUNT + 6)
__uint32_t xs_qm_dqreclaims;
__uint32_t xs_qm_dqreclaim_misses;
@ -245,26 +175,58 @@ struct xfsstats {
__uint64_t xs_read_bytes;
};
struct xfsstats {
union {
struct __xfsstats s;
uint32_t a[XFSSTAT_END_XQMSTAT];
};
};
/*
* simple wrapper for getting the array index of s struct member offset
*/
#define XFS_STATS_CALC_INDEX(member) \
(offsetof(struct __xfsstats, member) / (int)sizeof(__uint32_t))
int xfs_stats_format(struct xfsstats __percpu *stats, char *buf);
void xfs_stats_clearall(struct xfsstats __percpu *stats);
extern struct xstats xfsstats;
#define XFS_STATS_INC(mp, v) \
do { \
per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v++; \
per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v++; \
per_cpu_ptr(xfsstats.xs_stats, current_cpu())->s.v++; \
per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->s.v++; \
} while (0)
#define XFS_STATS_DEC(mp, v) \
do { \
per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v--; \
per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v--; \
per_cpu_ptr(xfsstats.xs_stats, current_cpu())->s.v--; \
per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->s.v--; \
} while (0)
#define XFS_STATS_ADD(mp, v, inc) \
do { \
per_cpu_ptr(xfsstats.xs_stats, current_cpu())->v += (inc); \
per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->v += (inc); \
per_cpu_ptr(xfsstats.xs_stats, current_cpu())->s.v += (inc); \
per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->s.v += (inc); \
} while (0)
#define XFS_STATS_INC_OFF(mp, off) \
do { \
per_cpu_ptr(xfsstats.xs_stats, current_cpu())->a[off]++; \
per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->a[off]++; \
} while (0)
#define XFS_STATS_DEC_OFF(mp, off) \
do { \
per_cpu_ptr(xfsstats.xs_stats, current_cpu())->a[off]; \
per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->a[off]; \
} while (0)
#define XFS_STATS_ADD_OFF(mp, off, inc) \
do { \
per_cpu_ptr(xfsstats.xs_stats, current_cpu())->a[off] += (inc); \
per_cpu_ptr(mp->m_stats.xs_stats, current_cpu())->a[off] += (inc); \
} while (0)
#if defined(CONFIG_PROC_FS)

View File

@ -130,7 +130,7 @@ const struct xattr_handler *xfs_xattr_handlers[] = {
NULL
};
static int
static void
__xfs_xattr_put_listent(
struct xfs_attr_list_context *context,
char *prefix,
@ -148,7 +148,7 @@ __xfs_xattr_put_listent(
if (arraytop > context->firstu) {
context->count = -1; /* insufficient space */
context->seen_enough = 1;
return 0;
return;
}
offset = (char *)context->alist + context->count;
strncpy(offset, prefix, prefix_len);
@ -159,10 +159,10 @@ __xfs_xattr_put_listent(
compute_size:
context->count += prefix_len + namelen + 1;
return 0;
return;
}
static int
static void
xfs_xattr_put_listent(
struct xfs_attr_list_context *context,
int flags,
@ -180,23 +180,19 @@ xfs_xattr_put_listent(
if (namelen == SGI_ACL_FILE_SIZE &&
strncmp(name, SGI_ACL_FILE,
SGI_ACL_FILE_SIZE) == 0) {
int ret = __xfs_xattr_put_listent(
__xfs_xattr_put_listent(
context, XATTR_SYSTEM_PREFIX,
XATTR_SYSTEM_PREFIX_LEN,
XATTR_POSIX_ACL_ACCESS,
strlen(XATTR_POSIX_ACL_ACCESS));
if (ret)
return ret;
} else if (namelen == SGI_ACL_DEFAULT_SIZE &&
strncmp(name, SGI_ACL_DEFAULT,
SGI_ACL_DEFAULT_SIZE) == 0) {
int ret = __xfs_xattr_put_listent(
__xfs_xattr_put_listent(
context, XATTR_SYSTEM_PREFIX,
XATTR_SYSTEM_PREFIX_LEN,
XATTR_POSIX_ACL_DEFAULT,
strlen(XATTR_POSIX_ACL_DEFAULT));
if (ret)
return ret;
}
#endif
@ -205,7 +201,7 @@ xfs_xattr_put_listent(
* see them.
*/
if (!capable(CAP_SYS_ADMIN))
return 0;
return;
prefix = XATTR_TRUSTED_PREFIX;
prefix_len = XATTR_TRUSTED_PREFIX_LEN;
@ -217,8 +213,9 @@ xfs_xattr_put_listent(
prefix_len = XATTR_USER_PREFIX_LEN;
}
return __xfs_xattr_put_listent(context, prefix, prefix_len, name,
namelen);
__xfs_xattr_put_listent(context, prefix, prefix_len, name,
namelen);
return;
}
ssize_t