mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 07:12:09 +00:00
Merge branch 'xfs-O_TMPFILE-support' into for-next
Conflicts: fs/xfs/xfs_trans_resv.c - fix for XFS_INODE_CLUSTER_SIZE macro removal
This commit is contained in:
commit
fe986f9d88
7 changed files with 201 additions and 15 deletions
|
@ -42,7 +42,6 @@
|
|||
#include "xfs_bmap_util.h"
|
||||
#include "xfs_error.h"
|
||||
#include "xfs_quota.h"
|
||||
#include "xfs_dinode.h"
|
||||
#include "xfs_filestream.h"
|
||||
#include "xfs_cksum.h"
|
||||
#include "xfs_trace.h"
|
||||
|
@ -62,6 +61,8 @@ kmem_zone_t *xfs_inode_zone;
|
|||
|
||||
STATIC int xfs_iflush_int(xfs_inode_t *, xfs_buf_t *);
|
||||
|
||||
STATIC int xfs_iunlink_remove(xfs_trans_t *, xfs_inode_t *);
|
||||
|
||||
/*
|
||||
* helper function to extract extent size hint from inode
|
||||
*/
|
||||
|
@ -1115,7 +1116,7 @@ xfs_bumplink(
|
|||
{
|
||||
xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
|
||||
|
||||
ASSERT(ip->i_d.di_nlink > 0);
|
||||
ASSERT(ip->i_d.di_nlink > 0 || (VFS_I(ip)->i_state & I_LINKABLE));
|
||||
ip->i_d.di_nlink++;
|
||||
inc_nlink(VFS_I(ip));
|
||||
if ((ip->i_d.di_version == 1) &&
|
||||
|
@ -1165,10 +1166,7 @@ xfs_create(
|
|||
if (XFS_FORCED_SHUTDOWN(mp))
|
||||
return XFS_ERROR(EIO);
|
||||
|
||||
if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
|
||||
prid = xfs_get_projid(dp);
|
||||
else
|
||||
prid = XFS_PROJID_DEFAULT;
|
||||
prid = xfs_get_initial_prid(dp);
|
||||
|
||||
/*
|
||||
* Make sure that we have allocated dquot(s) on disk.
|
||||
|
@ -1332,6 +1330,113 @@ xfs_create(
|
|||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
xfs_create_tmpfile(
|
||||
struct xfs_inode *dp,
|
||||
struct dentry *dentry,
|
||||
umode_t mode)
|
||||
{
|
||||
struct xfs_mount *mp = dp->i_mount;
|
||||
struct xfs_inode *ip = NULL;
|
||||
struct xfs_trans *tp = NULL;
|
||||
int error;
|
||||
uint cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
|
||||
prid_t prid;
|
||||
struct xfs_dquot *udqp = NULL;
|
||||
struct xfs_dquot *gdqp = NULL;
|
||||
struct xfs_dquot *pdqp = NULL;
|
||||
struct xfs_trans_res *tres;
|
||||
uint resblks;
|
||||
|
||||
if (XFS_FORCED_SHUTDOWN(mp))
|
||||
return XFS_ERROR(EIO);
|
||||
|
||||
prid = xfs_get_initial_prid(dp);
|
||||
|
||||
/*
|
||||
* Make sure that we have allocated dquot(s) on disk.
|
||||
*/
|
||||
error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(current_fsuid()),
|
||||
xfs_kgid_to_gid(current_fsgid()), prid,
|
||||
XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
|
||||
&udqp, &gdqp, &pdqp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
resblks = XFS_IALLOC_SPACE_RES(mp);
|
||||
tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE_TMPFILE);
|
||||
|
||||
tres = &M_RES(mp)->tr_create_tmpfile;
|
||||
error = xfs_trans_reserve(tp, tres, resblks, 0);
|
||||
if (error == ENOSPC) {
|
||||
/* No space at all so try a "no-allocation" reservation */
|
||||
resblks = 0;
|
||||
error = xfs_trans_reserve(tp, tres, 0, 0);
|
||||
}
|
||||
if (error) {
|
||||
cancel_flags = 0;
|
||||
goto out_trans_cancel;
|
||||
}
|
||||
|
||||
error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp,
|
||||
pdqp, resblks, 1, 0);
|
||||
if (error)
|
||||
goto out_trans_cancel;
|
||||
|
||||
error = xfs_dir_ialloc(&tp, dp, mode, 1, 0,
|
||||
prid, resblks > 0, &ip, NULL);
|
||||
if (error) {
|
||||
if (error == ENOSPC)
|
||||
goto out_trans_cancel;
|
||||
goto out_trans_abort;
|
||||
}
|
||||
|
||||
if (mp->m_flags & XFS_MOUNT_WSYNC)
|
||||
xfs_trans_set_sync(tp);
|
||||
|
||||
/*
|
||||
* Attach the dquot(s) to the inodes and modify them incore.
|
||||
* These ids of the inode couldn't have changed since the new
|
||||
* inode has been locked ever since it was created.
|
||||
*/
|
||||
xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
|
||||
|
||||
ip->i_d.di_nlink--;
|
||||
d_tmpfile(dentry, VFS_I(ip));
|
||||
error = xfs_iunlink(tp, ip);
|
||||
if (error)
|
||||
goto out_trans_abort;
|
||||
|
||||
error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
|
||||
if (error)
|
||||
goto out_release_inode;
|
||||
|
||||
xfs_qm_dqrele(udqp);
|
||||
xfs_qm_dqrele(gdqp);
|
||||
xfs_qm_dqrele(pdqp);
|
||||
|
||||
return 0;
|
||||
|
||||
out_trans_abort:
|
||||
cancel_flags |= XFS_TRANS_ABORT;
|
||||
out_trans_cancel:
|
||||
xfs_trans_cancel(tp, cancel_flags);
|
||||
out_release_inode:
|
||||
/*
|
||||
* Wait until after the current transaction is aborted to
|
||||
* release the inode. This prevents recursive transactions
|
||||
* and deadlocks from xfs_inactive.
|
||||
*/
|
||||
if (ip)
|
||||
IRELE(ip);
|
||||
|
||||
xfs_qm_dqrele(udqp);
|
||||
xfs_qm_dqrele(gdqp);
|
||||
xfs_qm_dqrele(pdqp);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
xfs_link(
|
||||
xfs_inode_t *tdp,
|
||||
|
@ -1397,6 +1502,12 @@ xfs_link(
|
|||
|
||||
xfs_bmap_init(&free_list, &first_block);
|
||||
|
||||
if (sip->i_d.di_nlink == 0) {
|
||||
error = xfs_iunlink_remove(tp, sip);
|
||||
if (error)
|
||||
goto abort_return;
|
||||
}
|
||||
|
||||
error = xfs_dir_createname(tp, tdp, target_name, sip->i_ino,
|
||||
&first_block, &free_list, resblks);
|
||||
if (error)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue