aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
authorZhi Yong Wu <wuzhy@linux.vnet.ibm.com>2013-12-17 19:22:40 -0500
committerBen Myers <bpm@sgi.com>2014-01-06 14:50:06 -0500
commit99b6436bc29e4f10e4388c27a3e4810191cc4788 (patch)
treea9dc0d6a5b4cec023772eff4b9fbac0ead093135 /fs/xfs/xfs_inode.c
parent163467d3753e77e1d77da75727975cc3803a1dbc (diff)
xfs: add O_TMPFILE support
Add two functions xfs_create_tmpfile() and xfs_vn_tmpfile() to support O_TMPFILE file creation. In contrast to xfs_create(), xfs_create_tmpfile() has a different log reservation to the regular file creation because there is no directory modification, and doesn't check if an entry can be added to the directory, but the reservation quotas is required appropriately, and finally its inode is added to the unlinked list. xfs_vn_tmpfile() add one O_TMPFILE method to VFS interface and directly invoke xfs_create_tmpfile(). Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index c79b875f0354..ac133ea91c4b 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1333,6 +1333,113 @@ xfs_create(
1333} 1333}
1334 1334
1335int 1335int
1336xfs_create_tmpfile(
1337 struct xfs_inode *dp,
1338 struct dentry *dentry,
1339 umode_t mode)
1340{
1341 struct xfs_mount *mp = dp->i_mount;
1342 struct xfs_inode *ip = NULL;
1343 struct xfs_trans *tp = NULL;
1344 int error;
1345 uint cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
1346 prid_t prid;
1347 struct xfs_dquot *udqp = NULL;
1348 struct xfs_dquot *gdqp = NULL;
1349 struct xfs_dquot *pdqp = NULL;
1350 struct xfs_trans_res *tres;
1351 uint resblks;
1352
1353 if (XFS_FORCED_SHUTDOWN(mp))
1354 return XFS_ERROR(EIO);
1355
1356 prid = xfs_get_initial_prid(dp);
1357
1358 /*
1359 * Make sure that we have allocated dquot(s) on disk.
1360 */
1361 error = xfs_qm_vop_dqalloc(dp, xfs_kuid_to_uid(current_fsuid()),
1362 xfs_kgid_to_gid(current_fsgid()), prid,
1363 XFS_QMOPT_QUOTALL | XFS_QMOPT_INHERIT,
1364 &udqp, &gdqp, &pdqp);
1365 if (error)
1366 return error;
1367
1368 resblks = XFS_IALLOC_SPACE_RES(mp);
1369 tp = xfs_trans_alloc(mp, XFS_TRANS_CREATE_TMPFILE);
1370
1371 tres = &M_RES(mp)->tr_create_tmpfile;
1372 error = xfs_trans_reserve(tp, tres, resblks, 0);
1373 if (error == ENOSPC) {
1374 /* No space at all so try a "no-allocation" reservation */
1375 resblks = 0;
1376 error = xfs_trans_reserve(tp, tres, 0, 0);
1377 }
1378 if (error) {
1379 cancel_flags = 0;
1380 goto out_trans_cancel;
1381 }
1382
1383 error = xfs_trans_reserve_quota(tp, mp, udqp, gdqp,
1384 pdqp, resblks, 1, 0);
1385 if (error)
1386 goto out_trans_cancel;
1387
1388 error = xfs_dir_ialloc(&tp, dp, mode, 1, 0,
1389 prid, resblks > 0, &ip, NULL);
1390 if (error) {
1391 if (error == ENOSPC)
1392 goto out_trans_cancel;
1393 goto out_trans_abort;
1394 }
1395
1396 if (mp->m_flags & XFS_MOUNT_WSYNC)
1397 xfs_trans_set_sync(tp);
1398
1399 /*
1400 * Attach the dquot(s) to the inodes and modify them incore.
1401 * These ids of the inode couldn't have changed since the new
1402 * inode has been locked ever since it was created.
1403 */
1404 xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
1405
1406 ip->i_d.di_nlink--;
1407 d_tmpfile(dentry, VFS_I(ip));
1408 error = xfs_iunlink(tp, ip);
1409 if (error)
1410 goto out_trans_abort;
1411
1412 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
1413 if (error)
1414 goto out_release_inode;
1415
1416 xfs_qm_dqrele(udqp);
1417 xfs_qm_dqrele(gdqp);
1418 xfs_qm_dqrele(pdqp);
1419
1420 return 0;
1421
1422 out_trans_abort:
1423 cancel_flags |= XFS_TRANS_ABORT;
1424 out_trans_cancel:
1425 xfs_trans_cancel(tp, cancel_flags);
1426 out_release_inode:
1427 /*
1428 * Wait until after the current transaction is aborted to
1429 * release the inode. This prevents recursive transactions
1430 * and deadlocks from xfs_inactive.
1431 */
1432 if (ip)
1433 IRELE(ip);
1434
1435 xfs_qm_dqrele(udqp);
1436 xfs_qm_dqrele(gdqp);
1437 xfs_qm_dqrele(pdqp);
1438
1439 return error;
1440}
1441
1442int
1336xfs_link( 1443xfs_link(
1337 xfs_inode_t *tdp, 1444 xfs_inode_t *tdp,
1338 xfs_inode_t *sip, 1445 xfs_inode_t *sip,