diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-17 12:57:48 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-07-17 12:57:48 -0700 |
commit | bf3aa9de7ba57c2c7b5ea70c1ad3a6670cd6fcb0 (patch) | |
tree | 791228dc4eb6d90e2c27295930449b06f6952ad3 /fs/xfs/xfs_symlink.c | |
parent | 0260b0a7445c62a08938fa66fad256e5d0779817 (diff) | |
parent | 2bf6e353542d233486195953dc9c346331f82dcb (diff) |
Merge tag 'xfs-6.11-merge-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
Pull xfs updates from Chandan Babu:
"Major changes in this release are limited to enabling FITRIM on
realtime devices and Byte-based grant head log reservation tracking.
The remaining changes are limited to fixes and cleanups included in
this pull request.
Core:
- Enable FITRIM on the realtime device
- Introduce byte-based grant head log reservation tracking instead of
physical log location tracking.
This allows grant head to track a full 64 bit bytes space and hence
overcome the limit of 4GB indexing that has been present until now
Fixes:
- xfs_flush_unmap_range() and xfs_prepare_shift() should consider RT
extents in the flush unmap range
- Implement bounds check when traversing log operations during log
replay
- Prevent out of bounds access when traversing a directory data block
- Prevent incorrect ENOSPC when concurrently performing file creation
and file writes
- Fix rtalloc rotoring when delalloc is in use
Cleanups:
- Clean up I/O path inode locking helpers and the page fault handler
- xfs: hoist inode operations to libxfs in anticipation of the
metadata inode directory feature, which maintains a directory tree
of metadata inodes. This will be necessary for further enhancements
to the realtime feature, subvolume support
- Clean up some warts in the extent freeing log intent code
- Clean up the refcount and rmap intent code before adding support
for realtime devices
- Provide the correct email address for sysfs ABI documentation"
* tag 'xfs-6.11-merge-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (80 commits)
xfs: fix rtalloc rotoring when delalloc is in use
xfs: get rid of xfs_ag_resv_rmapbt_alloc
xfs: skip flushing log items during push
xfs: grant heads track byte counts, not LSNs
xfs: pass the full grant head to accounting functions
xfs: track log space pinned by the AIL
xfs: collapse xlog_state_set_callback in caller
xfs: l_last_sync_lsn is really AIL state
xfs: ensure log tail is always up to date
xfs: background AIL push should target physical space
xfs: AIL doesn't need manual pushing
xfs: move and rename xfs_trans_committed_bulk
xfs: fix the contact address for the sysfs ABI documentation
xfs: Avoid races with cnt_btree lastrec updates
xfs: move xfs_refcount_update_defer_add to xfs_refcount_item.c
xfs: simplify usage of the rcur local variable in xfs_refcount_finish_one
xfs: don't bother calling xfs_refcount_finish_one_cleanup in xfs_refcount_finish_one
xfs: reuse xfs_refcount_update_cancel_item
xfs: add a ci_entry helper
xfs: remove xfs_trans_set_refcount_flags
...
Diffstat (limited to 'fs/xfs/xfs_symlink.c')
-rw-r--r-- | fs/xfs/xfs_symlink.c | 70 |
1 files changed, 28 insertions, 42 deletions
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c index 17aee806ec2e..77f19e2f66e0 100644 --- a/fs/xfs/xfs_symlink.c +++ b/fs/xfs/xfs_symlink.c @@ -90,19 +90,25 @@ xfs_symlink( struct xfs_inode **ipp) { struct xfs_mount *mp = dp->i_mount; + struct xfs_icreate_args args = { + .idmap = idmap, + .pip = dp, + .mode = S_IFLNK | (mode & ~S_IFMT), + }; + struct xfs_dir_update du = { + .dp = dp, + .name = link_name, + }; struct xfs_trans *tp = NULL; - struct xfs_inode *ip = NULL; int error = 0; int pathlen; bool unlock_dp_on_error = false; xfs_filblks_t fs_blocks; - prid_t prid; - struct xfs_dquot *udqp = NULL; - struct xfs_dquot *gdqp = NULL; - struct xfs_dquot *pdqp = NULL; + struct xfs_dquot *udqp; + struct xfs_dquot *gdqp; + struct xfs_dquot *pdqp; uint resblks; xfs_ino_t ino; - struct xfs_parent_args *ppargs; *ipp = NULL; @@ -119,15 +125,8 @@ xfs_symlink( return -ENAMETOOLONG; ASSERT(pathlen > 0); - prid = xfs_get_initial_prid(dp); - - /* - * Make sure that we have allocated dquot(s) on disk. - */ - error = xfs_qm_vop_dqalloc(dp, mapped_fsuid(idmap, &init_user_ns), - mapped_fsgid(idmap, &init_user_ns), prid, - XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT, - &udqp, &gdqp, &pdqp); + /* Make sure that we have allocated dquot(s) on disk. */ + error = xfs_icreate_dqalloc(&args, &udqp, &gdqp, &pdqp); if (error) return error; @@ -143,7 +142,7 @@ xfs_symlink( fs_blocks = xfs_symlink_blocks(mp, pathlen); resblks = xfs_symlink_space_res(mp, link_name->len, fs_blocks); - error = xfs_parent_start(mp, &ppargs); + error = xfs_parent_start(mp, &du.ppargs); if (error) goto out_release_dquots; @@ -168,9 +167,7 @@ xfs_symlink( */ error = xfs_dialloc(&tp, dp->i_ino, S_IFLNK, &ino); if (!error) - error = xfs_init_new_inode(idmap, tp, dp, ino, - S_IFLNK | (mode & ~S_IFMT), 1, 0, prid, - xfs_has_parent(mp), &ip); + error = xfs_icreate(tp, ino, &args, &du.ip); if (error) goto out_trans_cancel; @@ -186,33 +183,22 @@ xfs_symlink( /* * Also attach the dquot(s) to it, if applicable. */ - xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); + xfs_qm_vop_create_dqattach(tp, du.ip, udqp, gdqp, pdqp); resblks -= XFS_IALLOC_SPACE_RES(mp); - error = xfs_symlink_write_target(tp, ip, ip->i_ino, target_path, + error = xfs_symlink_write_target(tp, du.ip, du.ip->i_ino, target_path, pathlen, fs_blocks, resblks); if (error) goto out_trans_cancel; resblks -= fs_blocks; - i_size_write(VFS_I(ip), ip->i_disk_size); + i_size_write(VFS_I(du.ip), du.ip->i_disk_size); /* * Create the directory entry for the symlink. */ - error = xfs_dir_createname(tp, dp, link_name, ip->i_ino, resblks); + error = xfs_dir_create_child(tp, resblks, &du); if (error) goto out_trans_cancel; - xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); - xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE); - - /* Add parent pointer for the new symlink. */ - if (ppargs) { - error = xfs_parent_addname(tp, ppargs, dp, link_name, ip); - if (error) - goto out_trans_cancel; - } - - xfs_dir_update_hook(dp, ip, 1, link_name); /* * If this is a synchronous mount, make sure that the @@ -230,10 +216,10 @@ xfs_symlink( xfs_qm_dqrele(gdqp); xfs_qm_dqrele(pdqp); - *ipp = ip; - xfs_iunlock(ip, XFS_ILOCK_EXCL); + *ipp = du.ip; + xfs_iunlock(du.ip, XFS_ILOCK_EXCL); xfs_iunlock(dp, XFS_ILOCK_EXCL); - xfs_parent_finish(mp, ppargs); + xfs_parent_finish(mp, du.ppargs); return 0; out_trans_cancel: @@ -244,13 +230,13 @@ out_release_inode: * setup of the inode and release the inode. This prevents recursive * transactions and deadlocks from xfs_inactive. */ - if (ip) { - xfs_iunlock(ip, XFS_ILOCK_EXCL); - xfs_finish_inode_setup(ip); - xfs_irele(ip); + if (du.ip) { + xfs_iunlock(du.ip, XFS_ILOCK_EXCL); + xfs_finish_inode_setup(du.ip); + xfs_irele(du.ip); } out_parent: - xfs_parent_finish(mp, ppargs); + xfs_parent_finish(mp, du.ppargs); out_release_dquots: xfs_qm_dqrele(udqp); xfs_qm_dqrele(gdqp); |