Merge branch 'xfs-misc-fixes-for-3.19-2' into for-next
Conflicts: fs/xfs/xfs_iops.c
This commit is contained in:
commit
6044e4386c
24 changed files with 270 additions and 385 deletions
|
@ -5447,13 +5447,11 @@ xfs_bmse_merge(
|
|||
struct xfs_btree_cur *cur,
|
||||
int *logflags) /* output */
|
||||
{
|
||||
struct xfs_ifork *ifp;
|
||||
struct xfs_bmbt_irec got;
|
||||
struct xfs_bmbt_irec left;
|
||||
xfs_filblks_t blockcount;
|
||||
int error, i;
|
||||
|
||||
ifp = XFS_IFORK_PTR(ip, whichfork);
|
||||
xfs_bmbt_get_all(gotp, &got);
|
||||
xfs_bmbt_get_all(leftp, &left);
|
||||
blockcount = left.br_blockcount + got.br_blockcount;
|
||||
|
@ -5486,32 +5484,25 @@ xfs_bmse_merge(
|
|||
error = xfs_bmbt_lookup_eq(cur, got.br_startoff, got.br_startblock,
|
||||
got.br_blockcount, &i);
|
||||
if (error)
|
||||
goto out_error;
|
||||
XFS_WANT_CORRUPTED_GOTO(i == 1, out_error);
|
||||
return error;
|
||||
XFS_WANT_CORRUPTED_RETURN(i == 1);
|
||||
|
||||
error = xfs_btree_delete(cur, &i);
|
||||
if (error)
|
||||
goto out_error;
|
||||
XFS_WANT_CORRUPTED_GOTO(i == 1, out_error);
|
||||
return error;
|
||||
XFS_WANT_CORRUPTED_RETURN(i == 1);
|
||||
|
||||
/* lookup and update size of the previous extent */
|
||||
error = xfs_bmbt_lookup_eq(cur, left.br_startoff, left.br_startblock,
|
||||
left.br_blockcount, &i);
|
||||
if (error)
|
||||
goto out_error;
|
||||
XFS_WANT_CORRUPTED_GOTO(i == 1, out_error);
|
||||
return error;
|
||||
XFS_WANT_CORRUPTED_RETURN(i == 1);
|
||||
|
||||
left.br_blockcount = blockcount;
|
||||
|
||||
error = xfs_bmbt_update(cur, left.br_startoff, left.br_startblock,
|
||||
left.br_blockcount, left.br_state);
|
||||
if (error)
|
||||
goto out_error;
|
||||
|
||||
return 0;
|
||||
|
||||
out_error:
|
||||
return error;
|
||||
return xfs_bmbt_update(cur, left.br_startoff, left.br_startblock,
|
||||
left.br_blockcount, left.br_state);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -5541,35 +5532,29 @@ xfs_bmse_shift_one(
|
|||
startoff = got.br_startoff - offset_shift_fsb;
|
||||
|
||||
/* delalloc extents should be prevented by caller */
|
||||
XFS_WANT_CORRUPTED_GOTO(!isnullstartblock(got.br_startblock),
|
||||
out_error);
|
||||
XFS_WANT_CORRUPTED_RETURN(!isnullstartblock(got.br_startblock));
|
||||
|
||||
/*
|
||||
* If this is the first extent in the file, make sure there's enough
|
||||
* room at the start of the file and jump right to the shift as there's
|
||||
* no left extent to merge.
|
||||
* Check for merge if we've got an extent to the left, otherwise make
|
||||
* sure there's enough room at the start of the file for the shift.
|
||||
*/
|
||||
if (*current_ext == 0) {
|
||||
if (got.br_startoff < offset_shift_fsb)
|
||||
if (*current_ext) {
|
||||
/* grab the left extent and check for a large enough hole */
|
||||
leftp = xfs_iext_get_ext(ifp, *current_ext - 1);
|
||||
xfs_bmbt_get_all(leftp, &left);
|
||||
|
||||
if (startoff < left.br_startoff + left.br_blockcount)
|
||||
return -EINVAL;
|
||||
goto shift_extent;
|
||||
}
|
||||
|
||||
/* grab the left extent and check for a large enough hole */
|
||||
leftp = xfs_iext_get_ext(ifp, *current_ext - 1);
|
||||
xfs_bmbt_get_all(leftp, &left);
|
||||
|
||||
if (startoff < left.br_startoff + left.br_blockcount)
|
||||
/* check whether to merge the extent or shift it down */
|
||||
if (xfs_bmse_can_merge(&left, &got, offset_shift_fsb)) {
|
||||
return xfs_bmse_merge(ip, whichfork, offset_shift_fsb,
|
||||
*current_ext, gotp, leftp, cur,
|
||||
logflags);
|
||||
}
|
||||
} else if (got.br_startoff < offset_shift_fsb)
|
||||
return -EINVAL;
|
||||
|
||||
/* check whether to merge the extent or shift it down */
|
||||
if (!xfs_bmse_can_merge(&left, &got, offset_shift_fsb))
|
||||
goto shift_extent;
|
||||
|
||||
return xfs_bmse_merge(ip, whichfork, offset_shift_fsb, *current_ext,
|
||||
gotp, leftp, cur, logflags);
|
||||
|
||||
shift_extent:
|
||||
/*
|
||||
* Increment the extent index for the next iteration, update the start
|
||||
* offset of the in-core extent and update the btree if applicable.
|
||||
|
@ -5586,14 +5571,11 @@ xfs_bmse_shift_one(
|
|||
got.br_blockcount, &i);
|
||||
if (error)
|
||||
return error;
|
||||
XFS_WANT_CORRUPTED_GOTO(i == 1, out_error);
|
||||
XFS_WANT_CORRUPTED_RETURN(i == 1);
|
||||
|
||||
got.br_startoff = startoff;
|
||||
return xfs_bmbt_update(cur, got.br_startoff, got.br_startblock,
|
||||
got.br_blockcount, got.br_state);
|
||||
|
||||
out_error:
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -512,7 +512,6 @@ xfs_da3_root_split(
|
|||
struct xfs_buf *bp;
|
||||
struct xfs_inode *dp;
|
||||
struct xfs_trans *tp;
|
||||
struct xfs_mount *mp;
|
||||
struct xfs_dir2_leaf *leaf;
|
||||
xfs_dablk_t blkno;
|
||||
int level;
|
||||
|
@ -532,7 +531,6 @@ xfs_da3_root_split(
|
|||
|
||||
dp = args->dp;
|
||||
tp = args->trans;
|
||||
mp = state->mp;
|
||||
error = xfs_da_get_buf(tp, dp, blkno, -1, &bp, args->whichfork);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -2340,14 +2338,12 @@ xfs_da_shrink_inode(
|
|||
xfs_inode_t *dp;
|
||||
int done, error, w, count;
|
||||
xfs_trans_t *tp;
|
||||
xfs_mount_t *mp;
|
||||
|
||||
trace_xfs_da_shrink_inode(args);
|
||||
|
||||
dp = args->dp;
|
||||
w = args->whichfork;
|
||||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
count = args->geo->fsbcount;
|
||||
for (;;) {
|
||||
/*
|
||||
|
|
|
@ -34,6 +34,22 @@
|
|||
|
||||
struct xfs_name xfs_name_dotdot = { (unsigned char *)"..", 2, XFS_DIR3_FT_DIR };
|
||||
|
||||
/*
|
||||
* @mode, if set, indicates that the type field needs to be set up.
|
||||
* This uses the transformation from file mode to DT_* as defined in linux/fs.h
|
||||
* for file type specification. This will be propagated into the directory
|
||||
* structure if appropriate for the given operation and filesystem config.
|
||||
*/
|
||||
const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = {
|
||||
[0] = XFS_DIR3_FT_UNKNOWN,
|
||||
[S_IFREG >> S_SHIFT] = XFS_DIR3_FT_REG_FILE,
|
||||
[S_IFDIR >> S_SHIFT] = XFS_DIR3_FT_DIR,
|
||||
[S_IFCHR >> S_SHIFT] = XFS_DIR3_FT_CHRDEV,
|
||||
[S_IFBLK >> S_SHIFT] = XFS_DIR3_FT_BLKDEV,
|
||||
[S_IFIFO >> S_SHIFT] = XFS_DIR3_FT_FIFO,
|
||||
[S_IFSOCK >> S_SHIFT] = XFS_DIR3_FT_SOCK,
|
||||
[S_IFLNK >> S_SHIFT] = XFS_DIR3_FT_SYMLINK,
|
||||
};
|
||||
|
||||
/*
|
||||
* ASCII case-insensitive (ie. A-Z) support for directories that was
|
||||
|
|
|
@ -31,6 +31,12 @@ struct xfs_dir2_data_unused;
|
|||
|
||||
extern struct xfs_name xfs_name_dotdot;
|
||||
|
||||
/*
|
||||
* directory filetype conversion tables.
|
||||
*/
|
||||
#define S_SHIFT 12
|
||||
extern const unsigned char xfs_mode_to_ftype[];
|
||||
|
||||
/*
|
||||
* directory operations vector for encode/decode routines
|
||||
*/
|
||||
|
@ -177,4 +183,138 @@ extern const struct xfs_buf_ops xfs_dir3_leaf1_buf_ops;
|
|||
extern const struct xfs_buf_ops xfs_dir3_free_buf_ops;
|
||||
extern const struct xfs_buf_ops xfs_dir3_data_buf_ops;
|
||||
|
||||
/*
|
||||
* Directory offset/block conversion functions.
|
||||
*
|
||||
* DB blocks here are logical directory block numbers, not filesystem blocks.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Convert dataptr to byte in file space
|
||||
*/
|
||||
static inline xfs_dir2_off_t
|
||||
xfs_dir2_dataptr_to_byte(xfs_dir2_dataptr_t dp)
|
||||
{
|
||||
return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in file space to dataptr. It had better be aligned.
|
||||
*/
|
||||
static inline xfs_dir2_dataptr_t
|
||||
xfs_dir2_byte_to_dataptr(xfs_dir2_off_t by)
|
||||
{
|
||||
return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in space to (DB) block
|
||||
*/
|
||||
static inline xfs_dir2_db_t
|
||||
xfs_dir2_byte_to_db(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
|
||||
{
|
||||
return (xfs_dir2_db_t)(by >> geo->blklog);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert dataptr to a block number
|
||||
*/
|
||||
static inline xfs_dir2_db_t
|
||||
xfs_dir2_dataptr_to_db(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
|
||||
{
|
||||
return xfs_dir2_byte_to_db(geo, xfs_dir2_dataptr_to_byte(dp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in space to offset in a block
|
||||
*/
|
||||
static inline xfs_dir2_data_aoff_t
|
||||
xfs_dir2_byte_to_off(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
|
||||
{
|
||||
return (xfs_dir2_data_aoff_t)(by & (geo->blksize - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert dataptr to a byte offset in a block
|
||||
*/
|
||||
static inline xfs_dir2_data_aoff_t
|
||||
xfs_dir2_dataptr_to_off(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
|
||||
{
|
||||
return xfs_dir2_byte_to_off(geo, xfs_dir2_dataptr_to_byte(dp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block and offset to byte in space
|
||||
*/
|
||||
static inline xfs_dir2_off_t
|
||||
xfs_dir2_db_off_to_byte(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
|
||||
xfs_dir2_data_aoff_t o)
|
||||
{
|
||||
return ((xfs_dir2_off_t)db << geo->blklog) + o;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block (DB) to block (dablk)
|
||||
*/
|
||||
static inline xfs_dablk_t
|
||||
xfs_dir2_db_to_da(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
|
||||
{
|
||||
return (xfs_dablk_t)(db << (geo->blklog - geo->fsblog));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in space to (DA) block
|
||||
*/
|
||||
static inline xfs_dablk_t
|
||||
xfs_dir2_byte_to_da(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
|
||||
{
|
||||
return xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, by));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block and offset to dataptr
|
||||
*/
|
||||
static inline xfs_dir2_dataptr_t
|
||||
xfs_dir2_db_off_to_dataptr(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
|
||||
xfs_dir2_data_aoff_t o)
|
||||
{
|
||||
return xfs_dir2_byte_to_dataptr(xfs_dir2_db_off_to_byte(geo, db, o));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block (dablk) to block (DB)
|
||||
*/
|
||||
static inline xfs_dir2_db_t
|
||||
xfs_dir2_da_to_db(struct xfs_da_geometry *geo, xfs_dablk_t da)
|
||||
{
|
||||
return (xfs_dir2_db_t)(da >> (geo->blklog - geo->fsblog));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block (dablk) to byte offset in space
|
||||
*/
|
||||
static inline xfs_dir2_off_t
|
||||
xfs_dir2_da_to_byte(struct xfs_da_geometry *geo, xfs_dablk_t da)
|
||||
{
|
||||
return xfs_dir2_db_off_to_byte(geo, xfs_dir2_da_to_db(geo, da), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Directory tail pointer accessor functions. Based on block geometry.
|
||||
*/
|
||||
static inline struct xfs_dir2_block_tail *
|
||||
xfs_dir2_block_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_data_hdr *hdr)
|
||||
{
|
||||
return ((struct xfs_dir2_block_tail *)
|
||||
((char *)hdr + geo->blksize)) - 1;
|
||||
}
|
||||
|
||||
static inline struct xfs_dir2_leaf_tail *
|
||||
xfs_dir2_leaf_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_leaf *lp)
|
||||
{
|
||||
return (struct xfs_dir2_leaf_tail *)
|
||||
((char *)lp + geo->blksize -
|
||||
sizeof(struct xfs_dir2_leaf_tail));
|
||||
}
|
||||
|
||||
#endif /* __XFS_DIR2_H__ */
|
||||
|
|
|
@ -350,7 +350,6 @@ xfs_dir2_block_addname(
|
|||
int low; /* low index for binary srch */
|
||||
int lowstale; /* low stale index */
|
||||
int mid=0; /* midpoint for binary srch */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int needlog; /* need to log header */
|
||||
int needscan; /* need to rescan freespace */
|
||||
__be16 *tagp; /* pointer to tag value */
|
||||
|
@ -360,7 +359,6 @@ xfs_dir2_block_addname(
|
|||
|
||||
dp = args->dp;
|
||||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
|
||||
/* Read the (one and only) directory block into bp. */
|
||||
error = xfs_dir3_block_read(tp, dp, &bp);
|
||||
|
@ -615,7 +613,6 @@ xfs_dir2_block_lookup(
|
|||
xfs_inode_t *dp; /* incore inode */
|
||||
int ent; /* entry index */
|
||||
int error; /* error return value */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
|
||||
trace_xfs_dir2_block_lookup(args);
|
||||
|
||||
|
@ -626,7 +623,6 @@ xfs_dir2_block_lookup(
|
|||
if ((error = xfs_dir2_block_lookup_int(args, &bp, &ent)))
|
||||
return error;
|
||||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
hdr = bp->b_addr;
|
||||
xfs_dir3_data_check(dp, bp);
|
||||
btp = xfs_dir2_block_tail_p(args->geo, hdr);
|
||||
|
@ -767,7 +763,6 @@ xfs_dir2_block_removename(
|
|||
xfs_inode_t *dp; /* incore inode */
|
||||
int ent; /* block leaf entry index */
|
||||
int error; /* error return value */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int needlog; /* need to log block header */
|
||||
int needscan; /* need to fixup bestfree */
|
||||
xfs_dir2_sf_hdr_t sfh; /* shortform header */
|
||||
|
@ -785,7 +780,6 @@ xfs_dir2_block_removename(
|
|||
}
|
||||
dp = args->dp;
|
||||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
hdr = bp->b_addr;
|
||||
btp = xfs_dir2_block_tail_p(args->geo, hdr);
|
||||
blp = xfs_dir2_block_leaf_p(btp);
|
||||
|
@ -849,7 +843,6 @@ xfs_dir2_block_replace(
|
|||
xfs_inode_t *dp; /* incore inode */
|
||||
int ent; /* leaf entry index */
|
||||
int error; /* error return value */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
|
||||
trace_xfs_dir2_block_replace(args);
|
||||
|
||||
|
@ -861,7 +854,6 @@ xfs_dir2_block_replace(
|
|||
return error;
|
||||
}
|
||||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
hdr = bp->b_addr;
|
||||
btp = xfs_dir2_block_tail_p(args->geo, hdr);
|
||||
blp = xfs_dir2_block_leaf_p(btp);
|
||||
|
|
|
@ -382,7 +382,6 @@ xfs_dir2_block_to_leaf(
|
|||
xfs_dir2_db_t ldb; /* leaf block's bno */
|
||||
xfs_dir2_leaf_t *leaf; /* leaf structure */
|
||||
xfs_dir2_leaf_tail_t *ltp; /* leaf's tail */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int needlog; /* need to log block header */
|
||||
int needscan; /* need to rescan bestfree */
|
||||
xfs_trans_t *tp; /* transaction pointer */
|
||||
|
@ -393,7 +392,6 @@ xfs_dir2_block_to_leaf(
|
|||
trace_xfs_dir2_block_to_leaf(args);
|
||||
|
||||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
tp = args->trans;
|
||||
/*
|
||||
* Add the leaf block to the inode.
|
||||
|
@ -624,7 +622,6 @@ xfs_dir2_leaf_addname(
|
|||
int lfloghigh; /* high leaf logging index */
|
||||
int lowstale; /* index of prev stale leaf */
|
||||
xfs_dir2_leaf_tail_t *ltp; /* leaf tail pointer */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int needbytes; /* leaf block bytes needed */
|
||||
int needlog; /* need to log data header */
|
||||
int needscan; /* need to rescan data free */
|
||||
|
@ -639,7 +636,6 @@ xfs_dir2_leaf_addname(
|
|||
|
||||
dp = args->dp;
|
||||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
|
||||
error = xfs_dir3_leaf_read(tp, dp, args->geo->leafblk, -1, &lbp);
|
||||
if (error)
|
||||
|
@ -1354,11 +1350,9 @@ xfs_dir2_leaf_removename(
|
|||
xfs_dir2_leaf_t *leaf; /* leaf structure */
|
||||
xfs_dir2_leaf_entry_t *lep; /* leaf entry */
|
||||
xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int needlog; /* need to log data header */
|
||||
int needscan; /* need to rescan data frees */
|
||||
xfs_dir2_data_off_t oldbest; /* old value of best free */
|
||||
xfs_trans_t *tp; /* transaction pointer */
|
||||
struct xfs_dir2_data_free *bf; /* bestfree table */
|
||||
struct xfs_dir2_leaf_entry *ents;
|
||||
struct xfs_dir3_icleaf_hdr leafhdr;
|
||||
|
@ -1372,8 +1366,6 @@ xfs_dir2_leaf_removename(
|
|||
return error;
|
||||
}
|
||||
dp = args->dp;
|
||||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
leaf = lbp->b_addr;
|
||||
hdr = dbp->b_addr;
|
||||
xfs_dir3_data_check(dp, dbp);
|
||||
|
@ -1605,11 +1597,9 @@ xfs_dir2_leaf_trim_data(
|
|||
int error; /* error return value */
|
||||
xfs_dir2_leaf_t *leaf; /* leaf structure */
|
||||
xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
xfs_trans_t *tp; /* transaction pointer */
|
||||
|
||||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
tp = args->trans;
|
||||
/*
|
||||
* Read the offending data block. We need its buffer.
|
||||
|
|
|
@ -295,7 +295,6 @@ xfs_dir2_leaf_to_node(
|
|||
int i; /* leaf freespace index */
|
||||
xfs_dir2_leaf_t *leaf; /* leaf structure */
|
||||
xfs_dir2_leaf_tail_t *ltp; /* leaf tail structure */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int n; /* count of live freespc ents */
|
||||
xfs_dir2_data_off_t off; /* freespace entry value */
|
||||
__be16 *to; /* pointer to freespace entry */
|
||||
|
@ -305,7 +304,6 @@ xfs_dir2_leaf_to_node(
|
|||
trace_xfs_dir2_leaf_to_node(args);
|
||||
|
||||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
tp = args->trans;
|
||||
/*
|
||||
* Add a freespace block to the directory.
|
||||
|
@ -385,16 +383,12 @@ xfs_dir2_leafn_add(
|
|||
int lfloghigh; /* high leaf entry logging */
|
||||
int lfloglow; /* low leaf entry logging */
|
||||
int lowstale; /* previous stale entry */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
xfs_trans_t *tp; /* transaction pointer */
|
||||
struct xfs_dir3_icleaf_hdr leafhdr;
|
||||
struct xfs_dir2_leaf_entry *ents;
|
||||
|
||||
trace_xfs_dir2_leafn_add(args, index);
|
||||
|
||||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
tp = args->trans;
|
||||
leaf = bp->b_addr;
|
||||
dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
ents = dp->d_ops->leaf_ents_p(leaf);
|
||||
|
@ -1168,7 +1162,6 @@ xfs_dir2_leafn_remove(
|
|||
xfs_dir2_leaf_entry_t *lep; /* leaf entry */
|
||||
int longest; /* longest data free entry */
|
||||
int off; /* data block entry offset */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
int needlog; /* need to log data header */
|
||||
int needscan; /* need to rescan data frees */
|
||||
xfs_trans_t *tp; /* transaction pointer */
|
||||
|
@ -1180,7 +1173,6 @@ xfs_dir2_leafn_remove(
|
|||
|
||||
dp = args->dp;
|
||||
tp = args->trans;
|
||||
mp = dp->i_mount;
|
||||
leaf = bp->b_addr;
|
||||
dp->d_ops->leaf_hdr_from_disk(&leafhdr, leaf);
|
||||
ents = dp->d_ops->leaf_ents_p(leaf);
|
||||
|
@ -1321,7 +1313,6 @@ xfs_dir2_leafn_split(
|
|||
xfs_da_args_t *args; /* operation arguments */
|
||||
xfs_dablk_t blkno; /* new leaf block number */
|
||||
int error; /* error return value */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
struct xfs_inode *dp;
|
||||
|
||||
/*
|
||||
|
@ -1329,7 +1320,6 @@ xfs_dir2_leafn_split(
|
|||
*/
|
||||
args = state->args;
|
||||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
ASSERT(oldblk->magic == XFS_DIR2_LEAFN_MAGIC);
|
||||
error = xfs_da_grow_inode(args, &blkno);
|
||||
if (error) {
|
||||
|
@ -2229,12 +2219,10 @@ xfs_dir2_node_trim_free(
|
|||
xfs_inode_t *dp; /* incore directory inode */
|
||||
int error; /* error return code */
|
||||
xfs_dir2_free_t *free; /* freespace structure */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
xfs_trans_t *tp; /* transaction pointer */
|
||||
struct xfs_dir3_icfree_hdr freehdr;
|
||||
|
||||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
tp = args->trans;
|
||||
/*
|
||||
* Read the freespace block.
|
||||
|
|
|
@ -20,140 +20,6 @@
|
|||
|
||||
struct dir_context;
|
||||
|
||||
/*
|
||||
* Directory offset/block conversion functions.
|
||||
*
|
||||
* DB blocks here are logical directory block numbers, not filesystem blocks.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Convert dataptr to byte in file space
|
||||
*/
|
||||
static inline xfs_dir2_off_t
|
||||
xfs_dir2_dataptr_to_byte(xfs_dir2_dataptr_t dp)
|
||||
{
|
||||
return (xfs_dir2_off_t)dp << XFS_DIR2_DATA_ALIGN_LOG;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in file space to dataptr. It had better be aligned.
|
||||
*/
|
||||
static inline xfs_dir2_dataptr_t
|
||||
xfs_dir2_byte_to_dataptr(xfs_dir2_off_t by)
|
||||
{
|
||||
return (xfs_dir2_dataptr_t)(by >> XFS_DIR2_DATA_ALIGN_LOG);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in space to (DB) block
|
||||
*/
|
||||
static inline xfs_dir2_db_t
|
||||
xfs_dir2_byte_to_db(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
|
||||
{
|
||||
return (xfs_dir2_db_t)(by >> geo->blklog);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert dataptr to a block number
|
||||
*/
|
||||
static inline xfs_dir2_db_t
|
||||
xfs_dir2_dataptr_to_db(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
|
||||
{
|
||||
return xfs_dir2_byte_to_db(geo, xfs_dir2_dataptr_to_byte(dp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in space to offset in a block
|
||||
*/
|
||||
static inline xfs_dir2_data_aoff_t
|
||||
xfs_dir2_byte_to_off(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
|
||||
{
|
||||
return (xfs_dir2_data_aoff_t)(by & (geo->blksize - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert dataptr to a byte offset in a block
|
||||
*/
|
||||
static inline xfs_dir2_data_aoff_t
|
||||
xfs_dir2_dataptr_to_off(struct xfs_da_geometry *geo, xfs_dir2_dataptr_t dp)
|
||||
{
|
||||
return xfs_dir2_byte_to_off(geo, xfs_dir2_dataptr_to_byte(dp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block and offset to byte in space
|
||||
*/
|
||||
static inline xfs_dir2_off_t
|
||||
xfs_dir2_db_off_to_byte(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
|
||||
xfs_dir2_data_aoff_t o)
|
||||
{
|
||||
return ((xfs_dir2_off_t)db << geo->blklog) + o;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block (DB) to block (dablk)
|
||||
*/
|
||||
static inline xfs_dablk_t
|
||||
xfs_dir2_db_to_da(struct xfs_da_geometry *geo, xfs_dir2_db_t db)
|
||||
{
|
||||
return (xfs_dablk_t)(db << (geo->blklog - geo->fsblog));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert byte in space to (DA) block
|
||||
*/
|
||||
static inline xfs_dablk_t
|
||||
xfs_dir2_byte_to_da(struct xfs_da_geometry *geo, xfs_dir2_off_t by)
|
||||
{
|
||||
return xfs_dir2_db_to_da(geo, xfs_dir2_byte_to_db(geo, by));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block and offset to dataptr
|
||||
*/
|
||||
static inline xfs_dir2_dataptr_t
|
||||
xfs_dir2_db_off_to_dataptr(struct xfs_da_geometry *geo, xfs_dir2_db_t db,
|
||||
xfs_dir2_data_aoff_t o)
|
||||
{
|
||||
return xfs_dir2_byte_to_dataptr(xfs_dir2_db_off_to_byte(geo, db, o));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block (dablk) to block (DB)
|
||||
*/
|
||||
static inline xfs_dir2_db_t
|
||||
xfs_dir2_da_to_db(struct xfs_da_geometry *geo, xfs_dablk_t da)
|
||||
{
|
||||
return (xfs_dir2_db_t)(da >> (geo->blklog - geo->fsblog));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert block (dablk) to byte offset in space
|
||||
*/
|
||||
static inline xfs_dir2_off_t
|
||||
xfs_dir2_da_to_byte(struct xfs_da_geometry *geo, xfs_dablk_t da)
|
||||
{
|
||||
return xfs_dir2_db_off_to_byte(geo, xfs_dir2_da_to_db(geo, da), 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Directory tail pointer accessor functions. Based on block geometry.
|
||||
*/
|
||||
static inline struct xfs_dir2_block_tail *
|
||||
xfs_dir2_block_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_data_hdr *hdr)
|
||||
{
|
||||
return ((struct xfs_dir2_block_tail *)
|
||||
((char *)hdr + geo->blksize)) - 1;
|
||||
}
|
||||
|
||||
static inline struct xfs_dir2_leaf_tail *
|
||||
xfs_dir2_leaf_tail_p(struct xfs_da_geometry *geo, struct xfs_dir2_leaf *lp)
|
||||
{
|
||||
return (struct xfs_dir2_leaf_tail *)
|
||||
((char *)lp + geo->blksize -
|
||||
sizeof(struct xfs_dir2_leaf_tail));
|
||||
}
|
||||
|
||||
/* xfs_dir2.c */
|
||||
extern int xfs_dir_ino_validate(struct xfs_mount *mp, xfs_ino_t ino);
|
||||
extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
|
||||
|
@ -161,12 +27,6 @@ extern int xfs_dir2_grow_inode(struct xfs_da_args *args, int space,
|
|||
extern int xfs_dir_cilookup_result(struct xfs_da_args *args,
|
||||
const unsigned char *name, int len);
|
||||
|
||||
#define S_SHIFT 12
|
||||
extern const unsigned char xfs_mode_to_ftype[];
|
||||
|
||||
extern unsigned char xfs_dir3_get_dtype(struct xfs_mount *mp,
|
||||
__uint8_t filetype);
|
||||
|
||||
|
||||
/* xfs_dir2_block.c */
|
||||
extern int xfs_dir3_block_read(struct xfs_trans *tp, struct xfs_inode *dp,
|
||||
|
|
|
@ -452,13 +452,11 @@ xfs_dir2_sf_addname_hard(
|
|||
xfs_dir2_sf_hdr_t *oldsfp; /* original shortform dir */
|
||||
xfs_dir2_sf_entry_t *sfep; /* entry in new dir */
|
||||
xfs_dir2_sf_hdr_t *sfp; /* new shortform dir */
|
||||
struct xfs_mount *mp;
|
||||
|
||||
/*
|
||||
* Copy the old directory to the stack buffer.
|
||||
*/
|
||||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
|
||||
sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
|
||||
old_isize = (int)dp->i_d.di_size;
|
||||
|
@ -539,7 +537,6 @@ xfs_dir2_sf_addname_pick(
|
|||
xfs_inode_t *dp; /* incore directory inode */
|
||||
int holefit; /* found hole it will fit in */
|
||||
int i; /* entry number */
|
||||
xfs_mount_t *mp; /* filesystem mount point */
|
||||
xfs_dir2_data_aoff_t offset; /* data block offset */
|
||||
xfs_dir2_sf_entry_t *sfep; /* shortform entry */
|
||||
xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
|
||||
|
@ -547,7 +544,6 @@ xfs_dir2_sf_addname_pick(
|
|||
int used; /* data bytes used */
|
||||
|
||||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
|
||||
sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
|
||||
size = dp->d_ops->data_entsize(args->namelen);
|
||||
|
@ -613,10 +609,8 @@ xfs_dir2_sf_check(
|
|||
int offset; /* data offset */
|
||||
xfs_dir2_sf_entry_t *sfep; /* shortform dir entry */
|
||||
xfs_dir2_sf_hdr_t *sfp; /* shortform structure */
|
||||
struct xfs_mount *mp;
|
||||
|
||||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
|
||||
sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
|
||||
offset = dp->d_ops->data_first_offset;
|
||||
|
@ -1013,12 +1007,10 @@ xfs_dir2_sf_toino4(
|
|||
int oldsize; /* old inode size */
|
||||
xfs_dir2_sf_entry_t *sfep; /* new sf entry */
|
||||
xfs_dir2_sf_hdr_t *sfp; /* new sf directory */
|
||||
struct xfs_mount *mp;
|
||||
|
||||
trace_xfs_dir2_sf_toino4(args);
|
||||
|
||||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
|
||||
/*
|
||||
* Copy the old directory to the buffer.
|
||||
|
@ -1091,12 +1083,10 @@ xfs_dir2_sf_toino8(
|
|||
int oldsize; /* old inode size */
|
||||
xfs_dir2_sf_entry_t *sfep; /* new sf entry */
|
||||
xfs_dir2_sf_hdr_t *sfp; /* new sf directory */
|
||||
struct xfs_mount *mp;
|
||||
|
||||
trace_xfs_dir2_sf_toino8(args);
|
||||
|
||||
dp = args->dp;
|
||||
mp = dp->i_mount;
|
||||
|
||||
/*
|
||||
* Copy the old directory to the buffer.
|
||||
|
|
|
@ -45,12 +45,12 @@
|
|||
*/
|
||||
static inline int
|
||||
xfs_ialloc_cluster_alignment(
|
||||
xfs_alloc_arg_t *args)
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
if (xfs_sb_version_hasalign(&args->mp->m_sb) &&
|
||||
args->mp->m_sb.sb_inoalignmt >=
|
||||
XFS_B_TO_FSBT(args->mp, args->mp->m_inode_cluster_size))
|
||||
return args->mp->m_sb.sb_inoalignmt;
|
||||
if (xfs_sb_version_hasalign(&mp->m_sb) &&
|
||||
mp->m_sb.sb_inoalignmt >=
|
||||
XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
|
||||
return mp->m_sb.sb_inoalignmt;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -409,7 +409,7 @@ xfs_ialloc_ag_alloc(
|
|||
* but not to use them in the actual exact allocation.
|
||||
*/
|
||||
args.alignment = 1;
|
||||
args.minalignslop = xfs_ialloc_cluster_alignment(&args) - 1;
|
||||
args.minalignslop = xfs_ialloc_cluster_alignment(args.mp) - 1;
|
||||
|
||||
/* Allow space for the inode btree to split. */
|
||||
args.minleft = args.mp->m_in_maxlevels - 1;
|
||||
|
@ -445,7 +445,7 @@ xfs_ialloc_ag_alloc(
|
|||
args.alignment = args.mp->m_dalign;
|
||||
isaligned = 1;
|
||||
} else
|
||||
args.alignment = xfs_ialloc_cluster_alignment(&args);
|
||||
args.alignment = xfs_ialloc_cluster_alignment(args.mp);
|
||||
/*
|
||||
* Need to figure out where to allocate the inode blocks.
|
||||
* Ideally they should be spaced out through the a.g.
|
||||
|
@ -474,7 +474,7 @@ xfs_ialloc_ag_alloc(
|
|||
args.type = XFS_ALLOCTYPE_NEAR_BNO;
|
||||
args.agbno = be32_to_cpu(agi->agi_root);
|
||||
args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
|
||||
args.alignment = xfs_ialloc_cluster_alignment(&args);
|
||||
args.alignment = xfs_ialloc_cluster_alignment(args.mp);
|
||||
if ((error = xfs_alloc_vextent(&args)))
|
||||
return error;
|
||||
}
|
||||
|
@ -629,10 +629,24 @@ xfs_ialloc_ag_select(
|
|||
}
|
||||
|
||||
/*
|
||||
* Is there enough free space for the file plus a block of
|
||||
* inodes? (if we need to allocate some)?
|
||||
* Check that there is enough free space for the file plus a
|
||||
* chunk of inodes if we need to allocate some. If this is the
|
||||
* first pass across the AGs, take into account the potential
|
||||
* space needed for alignment of inode chunks when checking the
|
||||
* longest contiguous free space in the AG - this prevents us
|
||||
* from getting ENOSPC because we have free space larger than
|
||||
* m_ialloc_blks but alignment constraints prevent us from using
|
||||
* it.
|
||||
*
|
||||
* If we can't find an AG with space for full alignment slack to
|
||||
* be taken into account, we must be near ENOSPC in all AGs.
|
||||
* Hence we don't include alignment for the second pass and so
|
||||
* if we fail allocation due to alignment issues then it is most
|
||||
* likely a real ENOSPC condition.
|
||||
*/
|
||||
ineed = mp->m_ialloc_blks;
|
||||
if (flags && ineed > 1)
|
||||
ineed += xfs_ialloc_cluster_alignment(mp);
|
||||
longest = pag->pagf_longest;
|
||||
if (!longest)
|
||||
longest = pag->pagf_flcount > 0;
|
||||
|
|
|
@ -1041,7 +1041,7 @@ xfs_buf_ioend_work(
|
|||
struct work_struct *work)
|
||||
{
|
||||
struct xfs_buf *bp =
|
||||
container_of(work, xfs_buf_t, b_iodone_work);
|
||||
container_of(work, xfs_buf_t, b_ioend_work);
|
||||
|
||||
xfs_buf_ioend(bp);
|
||||
}
|
||||
|
@ -1050,8 +1050,8 @@ void
|
|||
xfs_buf_ioend_async(
|
||||
struct xfs_buf *bp)
|
||||
{
|
||||
INIT_WORK(&bp->b_iodone_work, xfs_buf_ioend_work);
|
||||
queue_work(bp->b_target->bt_mount->m_buf_workqueue, &bp->b_iodone_work);
|
||||
INIT_WORK(&bp->b_ioend_work, xfs_buf_ioend_work);
|
||||
queue_work(bp->b_ioend_wq, &bp->b_ioend_work);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1220,6 +1220,13 @@ _xfs_buf_ioapply(
|
|||
*/
|
||||
bp->b_error = 0;
|
||||
|
||||
/*
|
||||
* Initialize the I/O completion workqueue if we haven't yet or the
|
||||
* submitter has not opted to specify a custom one.
|
||||
*/
|
||||
if (!bp->b_ioend_wq)
|
||||
bp->b_ioend_wq = bp->b_target->bt_mount->m_buf_workqueue;
|
||||
|
||||
if (bp->b_flags & XBF_WRITE) {
|
||||
if (bp->b_flags & XBF_SYNCIO)
|
||||
rw = WRITE_SYNC;
|
||||
|
|
|
@ -164,7 +164,8 @@ typedef struct xfs_buf {
|
|||
struct xfs_perag *b_pag; /* contains rbtree root */
|
||||
xfs_buftarg_t *b_target; /* buffer target (device) */
|
||||
void *b_addr; /* virtual address of buffer */
|
||||
struct work_struct b_iodone_work;
|
||||
struct work_struct b_ioend_work;
|
||||
struct workqueue_struct *b_ioend_wq; /* I/O completion wq */
|
||||
xfs_buf_iodone_t b_iodone; /* I/O completion function */
|
||||
struct completion b_iowait; /* queue for I/O waiters */
|
||||
void *b_fspriv;
|
||||
|
|
|
@ -41,7 +41,7 @@ static unsigned char xfs_dir3_filetype_table[] = {
|
|||
DT_FIFO, DT_SOCK, DT_LNK, DT_WHT,
|
||||
};
|
||||
|
||||
unsigned char
|
||||
static unsigned char
|
||||
xfs_dir3_get_dtype(
|
||||
struct xfs_mount *mp,
|
||||
__uint8_t filetype)
|
||||
|
@ -54,22 +54,6 @@ xfs_dir3_get_dtype(
|
|||
|
||||
return xfs_dir3_filetype_table[filetype];
|
||||
}
|
||||
/*
|
||||
* @mode, if set, indicates that the type field needs to be set up.
|
||||
* This uses the transformation from file mode to DT_* as defined in linux/fs.h
|
||||
* for file type specification. This will be propagated into the directory
|
||||
* structure if appropriate for the given operation and filesystem config.
|
||||
*/
|
||||
const unsigned char xfs_mode_to_ftype[S_IFMT >> S_SHIFT] = {
|
||||
[0] = XFS_DIR3_FT_UNKNOWN,
|
||||
[S_IFREG >> S_SHIFT] = XFS_DIR3_FT_REG_FILE,
|
||||
[S_IFDIR >> S_SHIFT] = XFS_DIR3_FT_DIR,
|
||||
[S_IFCHR >> S_SHIFT] = XFS_DIR3_FT_CHRDEV,
|
||||
[S_IFBLK >> S_SHIFT] = XFS_DIR3_FT_BLKDEV,
|
||||
[S_IFIFO >> S_SHIFT] = XFS_DIR3_FT_FIFO,
|
||||
[S_IFSOCK >> S_SHIFT] = XFS_DIR3_FT_SOCK,
|
||||
[S_IFLNK >> S_SHIFT] = XFS_DIR3_FT_SYMLINK,
|
||||
};
|
||||
|
||||
STATIC int
|
||||
xfs_dir2_sf_getdents(
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "xfs_trans_resv.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_format.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_export.h"
|
||||
#include "xfs_inode.h"
|
||||
|
|
|
@ -63,6 +63,7 @@ xfs_inode_alloc(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
XFS_STATS_INC(vn_active);
|
||||
ASSERT(atomic_read(&ip->i_pincount) == 0);
|
||||
ASSERT(!spin_is_locked(&ip->i_flags_lock));
|
||||
ASSERT(!xfs_isiflocked(ip));
|
||||
|
@ -128,6 +129,7 @@ xfs_inode_free(
|
|||
/* asserts to verify all state is correct here */
|
||||
ASSERT(atomic_read(&ip->i_pincount) == 0);
|
||||
ASSERT(!xfs_isiflocked(ip));
|
||||
XFS_STATS_DEC(vn_active);
|
||||
|
||||
call_rcu(&VFS_I(ip)->i_rcu, xfs_inode_free_callback);
|
||||
}
|
||||
|
|
|
@ -2483,9 +2483,7 @@ xfs_remove(
|
|||
xfs_fsblock_t first_block;
|
||||
int cancel_flags;
|
||||
int committed;
|
||||
int link_zero;
|
||||
uint resblks;
|
||||
uint log_count;
|
||||
|
||||
trace_xfs_remove(dp, name);
|
||||
|
||||
|
@ -2500,13 +2498,10 @@ xfs_remove(
|
|||
if (error)
|
||||
goto std_return;
|
||||
|
||||
if (is_dir) {
|
||||
if (is_dir)
|
||||
tp = xfs_trans_alloc(mp, XFS_TRANS_RMDIR);
|
||||
log_count = XFS_DEFAULT_LOG_COUNT;
|
||||
} else {
|
||||
else
|
||||
tp = xfs_trans_alloc(mp, XFS_TRANS_REMOVE);
|
||||
log_count = XFS_REMOVE_LOG_COUNT;
|
||||
}
|
||||
cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
|
||||
|
||||
/*
|
||||
|
@ -2574,9 +2569,6 @@ xfs_remove(
|
|||
if (error)
|
||||
goto out_trans_cancel;
|
||||
|
||||
/* Determine if this is the last link while the inode is locked */
|
||||
link_zero = (ip->i_d.di_nlink == 0);
|
||||
|
||||
xfs_bmap_init(&free_list, &first_block);
|
||||
error = xfs_dir_removename(tp, dp, name, ip->i_ino,
|
||||
&first_block, &free_list, resblks);
|
||||
|
|
|
@ -49,7 +49,6 @@ xfs_iomap_eof_align_last_fsb(
|
|||
xfs_extlen_t extsize,
|
||||
xfs_fileoff_t *last_fsb)
|
||||
{
|
||||
xfs_fileoff_t new_last_fsb = 0;
|
||||
xfs_extlen_t align = 0;
|
||||
int eof, error;
|
||||
|
||||
|
@ -67,8 +66,8 @@ xfs_iomap_eof_align_last_fsb(
|
|||
else if (mp->m_dalign)
|
||||
align = mp->m_dalign;
|
||||
|
||||
if (align && XFS_ISIZE(ip) >= XFS_FSB_TO_B(mp, align))
|
||||
new_last_fsb = roundup_64(*last_fsb, align);
|
||||
if (align && XFS_ISIZE(ip) < XFS_FSB_TO_B(mp, align))
|
||||
align = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -76,14 +75,14 @@ xfs_iomap_eof_align_last_fsb(
|
|||
* (when file on a real-time subvolume or has di_extsize hint).
|
||||
*/
|
||||
if (extsize) {
|
||||
if (new_last_fsb)
|
||||
align = roundup_64(new_last_fsb, extsize);
|
||||
if (align)
|
||||
align = roundup_64(align, extsize);
|
||||
else
|
||||
align = extsize;
|
||||
new_last_fsb = roundup_64(*last_fsb, align);
|
||||
}
|
||||
|
||||
if (new_last_fsb) {
|
||||
if (align) {
|
||||
xfs_fileoff_t new_last_fsb = roundup_64(*last_fsb, align);
|
||||
error = xfs_bmap_eof(ip, new_last_fsb, XFS_DATA_FORK, &eof);
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -261,7 +260,6 @@ xfs_iomap_eof_want_preallocate(
|
|||
{
|
||||
xfs_fileoff_t start_fsb;
|
||||
xfs_filblks_t count_fsb;
|
||||
xfs_fsblock_t firstblock;
|
||||
int n, error, imaps;
|
||||
int found_delalloc = 0;
|
||||
|
||||
|
@ -286,7 +284,6 @@ xfs_iomap_eof_want_preallocate(
|
|||
count_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
|
||||
while (count_fsb > 0) {
|
||||
imaps = nimaps;
|
||||
firstblock = NULLFSBLOCK;
|
||||
error = xfs_bmapi_read(ip, start_fsb, count_fsb, imap, &imaps,
|
||||
0);
|
||||
if (error)
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "xfs_icache.h"
|
||||
#include "xfs_symlink.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_dir2_priv.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_trans_space.h"
|
||||
|
||||
#include <linux/capability.h>
|
||||
|
|
|
@ -348,7 +348,6 @@ xfs_bulkstat(
|
|||
int *done) /* 1 if there are more stats to get */
|
||||
{
|
||||
xfs_buf_t *agbp; /* agi header buffer */
|
||||
xfs_agi_t *agi; /* agi header data */
|
||||
xfs_agino_t agino; /* inode # in allocation group */
|
||||
xfs_agnumber_t agno; /* allocation group number */
|
||||
xfs_btree_cur_t *cur; /* btree cursor for ialloc btree */
|
||||
|
@ -399,7 +398,6 @@ xfs_bulkstat(
|
|||
error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp);
|
||||
if (error)
|
||||
break;
|
||||
agi = XFS_BUF_TO_AGI(agbp);
|
||||
/*
|
||||
* Allocate and initialize a btree cursor for ialloc btree.
|
||||
*/
|
||||
|
|
|
@ -1806,6 +1806,8 @@ xlog_sync(
|
|||
XFS_BUF_ZEROFLAGS(bp);
|
||||
XFS_BUF_ASYNC(bp);
|
||||
bp->b_flags |= XBF_SYNCIO;
|
||||
/* use high priority completion wq */
|
||||
bp->b_ioend_wq = log->l_mp->m_log_workqueue;
|
||||
|
||||
if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) {
|
||||
bp->b_flags |= XBF_FUA;
|
||||
|
@ -1854,6 +1856,8 @@ xlog_sync(
|
|||
bp->b_flags |= XBF_SYNCIO;
|
||||
if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
|
||||
bp->b_flags |= XBF_FUA;
|
||||
/* use high priority completion wq */
|
||||
bp->b_ioend_wq = log->l_mp->m_log_workqueue;
|
||||
|
||||
ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
|
||||
ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "xfs_sb.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_format.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_inode.h"
|
||||
#include "xfs_trans.h"
|
||||
#include "xfs_log.h"
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "xfs_sb.h"
|
||||
#include "xfs_mount.h"
|
||||
#include "xfs_da_format.h"
|
||||
#include "xfs_da_btree.h"
|
||||
#include "xfs_inode.h"
|
||||
#include "xfs_dir2.h"
|
||||
#include "xfs_ialloc.h"
|
||||
|
|
|
@ -839,8 +839,7 @@ xfs_init_mount_workqueues(
|
|||
struct xfs_mount *mp)
|
||||
{
|
||||
mp->m_buf_workqueue = alloc_workqueue("xfs-buf/%s",
|
||||
WQ_MEM_RECLAIM|WQ_HIGHPRI|WQ_FREEZABLE, 1,
|
||||
mp->m_fsname);
|
||||
WQ_MEM_RECLAIM|WQ_FREEZABLE, 1, mp->m_fsname);
|
||||
if (!mp->m_buf_workqueue)
|
||||
goto out;
|
||||
|
||||
|
@ -865,7 +864,7 @@ xfs_init_mount_workqueues(
|
|||
goto out_destroy_cil;
|
||||
|
||||
mp->m_log_workqueue = alloc_workqueue("xfs-log/%s",
|
||||
WQ_FREEZABLE, 0, mp->m_fsname);
|
||||
WQ_FREEZABLE|WQ_HIGHPRI, 0, mp->m_fsname);
|
||||
if (!mp->m_log_workqueue)
|
||||
goto out_destroy_reclaim;
|
||||
|
||||
|
@ -1005,7 +1004,6 @@ xfs_fs_evict_inode(
|
|||
clear_inode(inode);
|
||||
XFS_STATS_INC(vn_rele);
|
||||
XFS_STATS_INC(vn_remove);
|
||||
XFS_STATS_DEC(vn_active);
|
||||
|
||||
xfs_inactive(ip);
|
||||
}
|
||||
|
|
|
@ -227,13 +227,6 @@ xfs_trans_getsb(xfs_trans_t *tp,
|
|||
return bp;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
xfs_buftarg_t *xfs_error_target;
|
||||
int xfs_do_error;
|
||||
int xfs_req_num;
|
||||
int xfs_error_mod = 33;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Get and lock the buffer for the caller if it is not already
|
||||
* locked within the given transaction. If it has not yet been
|
||||
|
@ -255,46 +248,11 @@ xfs_trans_read_buf_map(
|
|||
struct xfs_buf **bpp,
|
||||
const struct xfs_buf_ops *ops)
|
||||
{
|
||||
xfs_buf_t *bp;
|
||||
xfs_buf_log_item_t *bip;
|
||||
struct xfs_buf *bp = NULL;
|
||||
struct xfs_buf_log_item *bip;
|
||||
int error;
|
||||
|
||||
*bpp = NULL;
|
||||
if (!tp) {
|
||||
bp = xfs_buf_read_map(target, map, nmaps, flags, ops);
|
||||
if (!bp)
|
||||
return (flags & XBF_TRYLOCK) ?
|
||||
-EAGAIN : -ENOMEM;
|
||||
|
||||
if (bp->b_error) {
|
||||
error = bp->b_error;
|
||||
xfs_buf_ioerror_alert(bp, __func__);
|
||||
XFS_BUF_UNDONE(bp);
|
||||
xfs_buf_stale(bp);
|
||||
xfs_buf_relse(bp);
|
||||
|
||||
/* bad CRC means corrupted metadata */
|
||||
if (error == -EFSBADCRC)
|
||||
error = -EFSCORRUPTED;
|
||||
return error;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (xfs_do_error) {
|
||||
if (xfs_error_target == target) {
|
||||
if (((xfs_req_num++) % xfs_error_mod) == 0) {
|
||||
xfs_buf_relse(bp);
|
||||
xfs_debug(mp, "Returning error!");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (XFS_FORCED_SHUTDOWN(mp))
|
||||
goto shutdown_abort;
|
||||
*bpp = bp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we find the buffer in the cache with this transaction
|
||||
* pointer in its b_fsprivate2 field, then we know we already
|
||||
|
@ -303,49 +261,24 @@ xfs_trans_read_buf_map(
|
|||
* If the buffer is not yet read in, then we read it in, increment
|
||||
* the lock recursion count, and return it to the caller.
|
||||
*/
|
||||
bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
|
||||
if (bp != NULL) {
|
||||
if (tp)
|
||||
bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
|
||||
if (bp) {
|
||||
ASSERT(xfs_buf_islocked(bp));
|
||||
ASSERT(bp->b_transp == tp);
|
||||
ASSERT(bp->b_fspriv != NULL);
|
||||
ASSERT(!bp->b_error);
|
||||
if (!(XFS_BUF_ISDONE(bp))) {
|
||||
trace_xfs_trans_read_buf_io(bp, _RET_IP_);
|
||||
ASSERT(!XFS_BUF_ISASYNC(bp));
|
||||
ASSERT(bp->b_iodone == NULL);
|
||||
XFS_BUF_READ(bp);
|
||||
bp->b_ops = ops;
|
||||
ASSERT(bp->b_flags & XBF_DONE);
|
||||
|
||||
error = xfs_buf_submit_wait(bp);
|
||||
if (error) {
|
||||
if (!XFS_FORCED_SHUTDOWN(mp))
|
||||
xfs_buf_ioerror_alert(bp, __func__);
|
||||
xfs_buf_relse(bp);
|
||||
/*
|
||||
* We can gracefully recover from most read
|
||||
* errors. Ones we can't are those that happen
|
||||
* after the transaction's already dirty.
|
||||
*/
|
||||
if (tp->t_flags & XFS_TRANS_DIRTY)
|
||||
xfs_force_shutdown(tp->t_mountp,
|
||||
SHUTDOWN_META_IO_ERROR);
|
||||
/* bad CRC means corrupted metadata */
|
||||
if (error == -EFSBADCRC)
|
||||
error = -EFSCORRUPTED;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* We never locked this buf ourselves, so we shouldn't
|
||||
* brelse it either. Just get out.
|
||||
*/
|
||||
if (XFS_FORCED_SHUTDOWN(mp)) {
|
||||
trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
|
||||
*bpp = NULL;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
bip = bp->b_fspriv;
|
||||
bip->bli_recur++;
|
||||
|
||||
|
@ -356,17 +289,29 @@ xfs_trans_read_buf_map(
|
|||
}
|
||||
|
||||
bp = xfs_buf_read_map(target, map, nmaps, flags, ops);
|
||||
if (bp == NULL) {
|
||||
*bpp = NULL;
|
||||
return (flags & XBF_TRYLOCK) ?
|
||||
0 : -ENOMEM;
|
||||
if (!bp) {
|
||||
if (!(flags & XBF_TRYLOCK))
|
||||
return -ENOMEM;
|
||||
return tp ? 0 : -EAGAIN;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we've had a read error, then the contents of the buffer are
|
||||
* invalid and should not be used. To ensure that a followup read tries
|
||||
* to pull the buffer from disk again, we clear the XBF_DONE flag and
|
||||
* mark the buffer stale. This ensures that anyone who has a current
|
||||
* reference to the buffer will interpret it's contents correctly and
|
||||
* future cache lookups will also treat it as an empty, uninitialised
|
||||
* buffer.
|
||||
*/
|
||||
if (bp->b_error) {
|
||||
error = bp->b_error;
|
||||
if (!XFS_FORCED_SHUTDOWN(mp))
|
||||
xfs_buf_ioerror_alert(bp, __func__);
|
||||
bp->b_flags &= ~XBF_DONE;
|
||||
xfs_buf_stale(bp);
|
||||
XFS_BUF_DONE(bp);
|
||||
xfs_buf_ioerror_alert(bp, __func__);
|
||||
if (tp->t_flags & XFS_TRANS_DIRTY)
|
||||
|
||||
if (tp && (tp->t_flags & XFS_TRANS_DIRTY))
|
||||
xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR);
|
||||
xfs_buf_relse(bp);
|
||||
|
||||
|
@ -375,33 +320,19 @@ xfs_trans_read_buf_map(
|
|||
error = -EFSCORRUPTED;
|
||||
return error;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (xfs_do_error && !(tp->t_flags & XFS_TRANS_DIRTY)) {
|
||||
if (xfs_error_target == target) {
|
||||
if (((xfs_req_num++) % xfs_error_mod) == 0) {
|
||||
xfs_force_shutdown(tp->t_mountp,
|
||||
SHUTDOWN_META_IO_ERROR);
|
||||
xfs_buf_relse(bp);
|
||||
xfs_debug(mp, "Returning trans error!");
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
|
||||
if (XFS_FORCED_SHUTDOWN(mp)) {
|
||||
xfs_buf_relse(bp);
|
||||
trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
|
||||
return -EIO;
|
||||
}
|
||||
#endif
|
||||
if (XFS_FORCED_SHUTDOWN(mp))
|
||||
goto shutdown_abort;
|
||||
|
||||
_xfs_trans_bjoin(tp, bp, 1);
|
||||
if (tp)
|
||||
_xfs_trans_bjoin(tp, bp, 1);
|
||||
trace_xfs_trans_read_buf(bp->b_fspriv);
|
||||
|
||||
*bpp = bp;
|
||||
return 0;
|
||||
|
||||
shutdown_abort:
|
||||
trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
|
||||
xfs_buf_relse(bp);
|
||||
*bpp = NULL;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue