Skip to content

Commit fe0142d

Browse files
committed
Merge tag 'xfs-4.20-merge-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pul xfs updates from Dave Chinner: "There's not a huge amount of change in this cycle - Darrick has been out of action for a couple of months (hence me sending the last few pull requests), so we decided a quiet cycle mainly focussed on bug fixes was a good idea. Darrick will take the helm again at the end of this merge window. FYI, I may be sending another update later in the cycle - there's a pending rework of the clone/dedupe_file_range code that fixes numerous bugs that is spread amongst the VFS, XFS and ocfs2 code. It has been reviewed and tested, Al and I just need to work out the details of the merge, so it may come from him rather than me. Summary: - only support filesystems with unwritten extents - add definition for statfs XFS magic number - remove unused parameters around reflink code - more debug for dangling delalloc extents - cancel COW extents on extent swap targets - fix quota stats output and clean up the code - refactor some of the attribute code in preparation for parent pointers - fix several buffer handling bugs" * tag 'xfs-4.20-merge-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (21 commits) xfs: cancel COW blocks before swapext xfs: clear ail delwri queued bufs on unmount of shutdown fs xfs: use offsetof() in place of offset macros for __xfsstats xfs: Fix xqmstats offsets in /proc/fs/xfs/xqmstat xfs: fix use-after-free race in xfs_buf_rele xfs: Add attibute remove and helper functions xfs: Add attibute set and helper functions xfs: Add helper function xfs_attr_try_sf_addname xfs: Move fs/xfs/xfs_attr.h to fs/xfs/libxfs/xfs_attr.h xfs: issue log message on user force shutdown xfs: fix buffer state management in xrep_findroot_block xfs: always assign buffer verifiers when one is provided xfs: xrep_findroot_block should reject root blocks with siblings xfs: add a define for statfs magic to uapi xfs: print dangling delalloc extents xfs: fix fork selection in xfs_find_trim_cow_extent xfs: remove the unused trimmed argument from xfs_reflink_trim_around_shared xfs: remove the unused shared argument to xfs_reflink_reserve_cow xfs: handle zeroing in xfs_file_iomap_begin_delay xfs: remove suport for filesystems without unwritten extent flag ...
2 parents bfd93a8 + 96987ee commit fe0142d

25 files changed

+608
-383
lines changed

fs/xfs/libxfs/xfs_attr.c

Lines changed: 136 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,128 @@ xfs_attr_calc_size(
191191
return nblks;
192192
}
193193

194+
STATIC int
195+
xfs_attr_try_sf_addname(
196+
struct xfs_inode *dp,
197+
struct xfs_da_args *args)
198+
{
199+
200+
struct xfs_mount *mp = dp->i_mount;
201+
int error, error2;
202+
203+
error = xfs_attr_shortform_addname(args);
204+
if (error == -ENOSPC)
205+
return error;
206+
207+
/*
208+
* Commit the shortform mods, and we're done.
209+
* NOTE: this is also the error path (EEXIST, etc).
210+
*/
211+
if (!error && (args->flags & ATTR_KERNOTIME) == 0)
212+
xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
213+
214+
if (mp->m_flags & XFS_MOUNT_WSYNC)
215+
xfs_trans_set_sync(args->trans);
216+
217+
error2 = xfs_trans_commit(args->trans);
218+
args->trans = NULL;
219+
return error ? error : error2;
220+
}
221+
222+
/*
223+
* Set the attribute specified in @args.
224+
*/
225+
int
226+
xfs_attr_set_args(
227+
struct xfs_da_args *args,
228+
struct xfs_buf **leaf_bp)
229+
{
230+
struct xfs_inode *dp = args->dp;
231+
int error;
232+
233+
/*
234+
* If the attribute list is non-existent or a shortform list,
235+
* upgrade it to a single-leaf-block attribute list.
236+
*/
237+
if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL ||
238+
(dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
239+
dp->i_d.di_anextents == 0)) {
240+
241+
/*
242+
* Build initial attribute list (if required).
243+
*/
244+
if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS)
245+
xfs_attr_shortform_create(args);
246+
247+
/*
248+
* Try to add the attr to the attribute list in the inode.
249+
*/
250+
error = xfs_attr_try_sf_addname(dp, args);
251+
if (error != -ENOSPC)
252+
return error;
253+
254+
/*
255+
* It won't fit in the shortform, transform to a leaf block.
256+
* GROT: another possible req'mt for a double-split btree op.
257+
*/
258+
error = xfs_attr_shortform_to_leaf(args, leaf_bp);
259+
if (error)
260+
return error;
261+
262+
/*
263+
* Prevent the leaf buffer from being unlocked so that a
264+
* concurrent AIL push cannot grab the half-baked leaf
265+
* buffer and run into problems with the write verifier.
266+
*/
267+
xfs_trans_bhold(args->trans, *leaf_bp);
268+
269+
error = xfs_defer_finish(&args->trans);
270+
if (error)
271+
return error;
272+
273+
/*
274+
* Commit the leaf transformation. We'll need another
275+
* (linked) transaction to add the new attribute to the
276+
* leaf.
277+
*/
278+
error = xfs_trans_roll_inode(&args->trans, dp);
279+
if (error)
280+
return error;
281+
xfs_trans_bjoin(args->trans, *leaf_bp);
282+
*leaf_bp = NULL;
283+
}
284+
285+
if (xfs_bmap_one_block(dp, XFS_ATTR_FORK))
286+
error = xfs_attr_leaf_addname(args);
287+
else
288+
error = xfs_attr_node_addname(args);
289+
return error;
290+
}
291+
292+
/*
293+
* Remove the attribute specified in @args.
294+
*/
295+
int
296+
xfs_attr_remove_args(
297+
struct xfs_da_args *args)
298+
{
299+
struct xfs_inode *dp = args->dp;
300+
int error;
301+
302+
if (!xfs_inode_hasattr(dp)) {
303+
error = -ENOATTR;
304+
} else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
305+
ASSERT(dp->i_afp->if_flags & XFS_IFINLINE);
306+
error = xfs_attr_shortform_remove(args);
307+
} else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
308+
error = xfs_attr_leaf_removename(args);
309+
} else {
310+
error = xfs_attr_node_removename(args);
311+
}
312+
313+
return error;
314+
}
315+
194316
int
195317
xfs_attr_set(
196318
struct xfs_inode *dp,
@@ -204,7 +326,7 @@ xfs_attr_set(
204326
struct xfs_da_args args;
205327
struct xfs_trans_res tres;
206328
int rsvd = (flags & ATTR_ROOT) != 0;
207-
int error, err2, local;
329+
int error, local;
208330

209331
XFS_STATS_INC(mp, xs_attr_set);
210332

@@ -255,93 +377,17 @@ xfs_attr_set(
255377
error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0,
256378
rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
257379
XFS_QMOPT_RES_REGBLKS);
258-
if (error) {
259-
xfs_iunlock(dp, XFS_ILOCK_EXCL);
260-
xfs_trans_cancel(args.trans);
261-
return error;
262-
}
380+
if (error)
381+
goto out_trans_cancel;
263382

264383
xfs_trans_ijoin(args.trans, dp, 0);
265-
266-
/*
267-
* If the attribute list is non-existent or a shortform list,
268-
* upgrade it to a single-leaf-block attribute list.
269-
*/
270-
if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL ||
271-
(dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS &&
272-
dp->i_d.di_anextents == 0)) {
273-
274-
/*
275-
* Build initial attribute list (if required).
276-
*/
277-
if (dp->i_d.di_aformat == XFS_DINODE_FMT_EXTENTS)
278-
xfs_attr_shortform_create(&args);
279-
280-
/*
281-
* Try to add the attr to the attribute list in
282-
* the inode.
283-
*/
284-
error = xfs_attr_shortform_addname(&args);
285-
if (error != -ENOSPC) {
286-
/*
287-
* Commit the shortform mods, and we're done.
288-
* NOTE: this is also the error path (EEXIST, etc).
289-
*/
290-
ASSERT(args.trans != NULL);
291-
292-
/*
293-
* If this is a synchronous mount, make sure that
294-
* the transaction goes to disk before returning
295-
* to the user.
296-
*/
297-
if (mp->m_flags & XFS_MOUNT_WSYNC)
298-
xfs_trans_set_sync(args.trans);
299-
300-
if (!error && (flags & ATTR_KERNOTIME) == 0) {
301-
xfs_trans_ichgtime(args.trans, dp,
302-
XFS_ICHGTIME_CHG);
303-
}
304-
err2 = xfs_trans_commit(args.trans);
305-
xfs_iunlock(dp, XFS_ILOCK_EXCL);
306-
307-
return error ? error : err2;
308-
}
309-
310-
/*
311-
* It won't fit in the shortform, transform to a leaf block.
312-
* GROT: another possible req'mt for a double-split btree op.
313-
*/
314-
error = xfs_attr_shortform_to_leaf(&args, &leaf_bp);
315-
if (error)
316-
goto out;
317-
/*
318-
* Prevent the leaf buffer from being unlocked so that a
319-
* concurrent AIL push cannot grab the half-baked leaf
320-
* buffer and run into problems with the write verifier.
321-
*/
322-
xfs_trans_bhold(args.trans, leaf_bp);
323-
error = xfs_defer_finish(&args.trans);
324-
if (error)
325-
goto out;
326-
327-
/*
328-
* Commit the leaf transformation. We'll need another (linked)
329-
* transaction to add the new attribute to the leaf, which
330-
* means that we have to hold & join the leaf buffer here too.
331-
*/
332-
error = xfs_trans_roll_inode(&args.trans, dp);
333-
if (error)
334-
goto out;
335-
xfs_trans_bjoin(args.trans, leaf_bp);
336-
leaf_bp = NULL;
337-
}
338-
339-
if (xfs_bmap_one_block(dp, XFS_ATTR_FORK))
340-
error = xfs_attr_leaf_addname(&args);
341-
else
342-
error = xfs_attr_node_addname(&args);
384+
error = xfs_attr_set_args(&args, &leaf_bp);
343385
if (error)
344-
goto out;
386+
goto out_release_leaf;
387+
if (!args.trans) {
388+
/* shortform attribute has already been committed */
389+
goto out_unlock;
390+
}
345391

346392
/*
347393
* If this is a synchronous mount, make sure that the
@@ -358,17 +404,17 @@ xfs_attr_set(
358404
*/
359405
xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
360406
error = xfs_trans_commit(args.trans);
407+
out_unlock:
361408
xfs_iunlock(dp, XFS_ILOCK_EXCL);
362-
363409
return error;
364410

365-
out:
411+
out_release_leaf:
366412
if (leaf_bp)
367413
xfs_trans_brelse(args.trans, leaf_bp);
414+
out_trans_cancel:
368415
if (args.trans)
369416
xfs_trans_cancel(args.trans);
370-
xfs_iunlock(dp, XFS_ILOCK_EXCL);
371-
return error;
417+
goto out_unlock;
372418
}
373419

374420
/*
@@ -423,17 +469,7 @@ xfs_attr_remove(
423469
*/
424470
xfs_trans_ijoin(args.trans, dp, 0);
425471

426-
if (!xfs_inode_hasattr(dp)) {
427-
error = -ENOATTR;
428-
} else if (dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL) {
429-
ASSERT(dp->i_afp->if_flags & XFS_IFINLINE);
430-
error = xfs_attr_shortform_remove(&args);
431-
} else if (xfs_bmap_one_block(dp, XFS_ATTR_FORK)) {
432-
error = xfs_attr_leaf_removename(&args);
433-
} else {
434-
error = xfs_attr_node_removename(&args);
435-
}
436-
472+
error = xfs_attr_remove_args(&args);
437473
if (error)
438474
goto out;
439475

fs/xfs/xfs_attr.h renamed to fs/xfs/libxfs/xfs_attr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ int xfs_attr_get(struct xfs_inode *ip, const unsigned char *name,
140140
unsigned char *value, int *valuelenp, int flags);
141141
int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name,
142142
unsigned char *value, int valuelen, int flags);
143+
int xfs_attr_set_args(struct xfs_da_args *args, struct xfs_buf **leaf_bp);
143144
int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name, int flags);
145+
int xfs_attr_remove_args(struct xfs_da_args *args);
144146
int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
145147
int flags, struct attrlist_cursor_kern *cursor);
146148

0 commit comments

Comments
 (0)