* [PATCH v2 1/3] xfs: factor prid related codes into xfs_get_initial_prid()
2013-12-18 0:22 [PATCH v2 0/3] xfs: add O_TMPFILE support Zhi Yong Wu
@ 2013-12-18 0:22 ` Zhi Yong Wu
2013-12-18 0:22 ` [PATCH v2 2/3] xfs: add O_TMPFILE support Zhi Yong Wu
` (3 subsequent siblings)
4 siblings, 0 replies; 14+ messages in thread
From: Zhi Yong Wu @ 2013-12-18 0:22 UTC (permalink / raw)
To: xfs; +Cc: Zhi Yong Wu
From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
It will be reused by the O_TMPFILE creation function.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
---
fs/xfs/xfs_inode.c | 6 +-----
fs/xfs/xfs_inode.h | 10 ++++++++++
fs/xfs/xfs_symlink.c | 5 +----
3 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 001aa89..c79b875 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -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"
@@ -1169,10 +1168,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.
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 9e6efccb..6c58349 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -20,6 +20,7 @@
#include "xfs_inode_buf.h"
#include "xfs_inode_fork.h"
+#include "xfs_dinode.h"
/*
* Kernel only inode definitions
@@ -192,6 +193,15 @@ xfs_set_projid(struct xfs_inode *ip,
ip->i_d.di_projid_lo = (__uint16_t) (projid & 0xffff);
}
+static inline prid_t
+xfs_get_initial_prid(struct xfs_inode *dp)
+{
+ if (dp->i_d.di_flags & XFS_DIFLAG_PROJINHERIT)
+ return xfs_get_projid(dp);
+
+ return XFS_PROJID_DEFAULT;
+}
+
/*
* In-core inode flags.
*/
diff --git a/fs/xfs/xfs_symlink.c b/fs/xfs/xfs_symlink.c
index 14e58f2..13140c7 100644
--- a/fs/xfs/xfs_symlink.c
+++ b/fs/xfs/xfs_symlink.c
@@ -208,10 +208,7 @@ xfs_symlink(
return XFS_ERROR(ENAMETOOLONG);
udqp = gdqp = NULL;
- 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.
--
1.7.6.5
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v2 2/3] xfs: add O_TMPFILE support
2013-12-18 0:22 [PATCH v2 0/3] xfs: add O_TMPFILE support Zhi Yong Wu
2013-12-18 0:22 ` [PATCH v2 1/3] xfs: factor prid related codes into xfs_get_initial_prid() Zhi Yong Wu
@ 2013-12-18 0:22 ` Zhi Yong Wu
2013-12-24 0:55 ` Dave Chinner
2013-12-18 0:22 ` [PATCH v2 3/3] xfs: allow linkat() on O_TMPFILE files Zhi Yong Wu
` (2 subsequent siblings)
4 siblings, 1 reply; 14+ messages in thread
From: Zhi Yong Wu @ 2013-12-18 0:22 UTC (permalink / raw)
To: xfs; +Cc: Zhi Yong Wu
From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
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>
---
fs/xfs/xfs_inode.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++
fs/xfs/xfs_inode.h | 2 +
fs/xfs/xfs_iops.c | 16 +++++++
fs/xfs/xfs_shared.h | 4 +-
fs/xfs/xfs_trans_resv.c | 36 +++++++++++++++-
fs/xfs/xfs_trans_resv.h | 2 +
6 files changed, 164 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index c79b875..ac133ea 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1333,6 +1333,113 @@ xfs_create(
}
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,
xfs_inode_t *sip,
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 6c58349..3a97820 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -333,6 +333,8 @@ int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name,
struct xfs_inode **ipp, struct xfs_name *ci_name);
int xfs_create(struct xfs_inode *dp, struct xfs_name *name,
umode_t mode, xfs_dev_t rdev, struct xfs_inode **ipp);
+int xfs_create_tmpfile(struct xfs_inode *dp, struct dentry *dentry,
+ umode_t mode);
int xfs_remove(struct xfs_inode *dp, struct xfs_name *name,
struct xfs_inode *ip);
int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip,
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 27e0e54..5ea7f85 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -39,6 +39,7 @@
#include "xfs_da_btree.h"
#include "xfs_dir2_priv.h"
#include "xfs_dinode.h"
+#include "xfs_trans_space.h"
#include <linux/capability.h>
#include <linux/xattr.h>
@@ -1050,6 +1051,19 @@ xfs_vn_fiemap(
return 0;
}
+STATIC int
+xfs_vn_tmpfile(
+ struct inode *dir,
+ struct dentry *dentry,
+ umode_t mode)
+{
+ int error;
+
+ error = xfs_create_tmpfile(XFS_I(dir), dentry, mode);
+
+ return -error;
+}
+
static const struct inode_operations xfs_inode_operations = {
.get_acl = xfs_get_acl,
.getattr = xfs_vn_getattr,
@@ -1086,6 +1100,7 @@ static const struct inode_operations xfs_dir_inode_operations = {
.removexattr = generic_removexattr,
.listxattr = xfs_vn_listxattr,
.update_time = xfs_vn_update_time,
+ .tmpfile = xfs_vn_tmpfile,
};
static const struct inode_operations xfs_dir_ci_inode_operations = {
@@ -1112,6 +1127,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
.removexattr = generic_removexattr,
.listxattr = xfs_vn_listxattr,
.update_time = xfs_vn_update_time,
+ .tmpfile = xfs_vn_tmpfile,
};
static const struct inode_operations xfs_symlink_inode_operations = {
diff --git a/fs/xfs/xfs_shared.h b/fs/xfs/xfs_shared.h
index 8c5035a1..4484e51 100644
--- a/fs/xfs/xfs_shared.h
+++ b/fs/xfs/xfs_shared.h
@@ -104,7 +104,8 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
#define XFS_TRANS_SB_COUNT 41
#define XFS_TRANS_CHECKPOINT 42
#define XFS_TRANS_ICREATE 43
-#define XFS_TRANS_TYPE_MAX 43
+#define XFS_TRANS_CREATE_TMPFILE 44
+#define XFS_TRANS_TYPE_MAX 44
/* new transaction types need to be reflected in xfs_logprint(8) */
#define XFS_TRANS_TYPES \
@@ -112,6 +113,7 @@ extern const struct xfs_buf_ops xfs_symlink_buf_ops;
{ XFS_TRANS_SETATTR_SIZE, "SETATTR_SIZE" }, \
{ XFS_TRANS_INACTIVE, "INACTIVE" }, \
{ XFS_TRANS_CREATE, "CREATE" }, \
+ { XFS_TRANS_CREATE_TMPFILE, "CREATE_TMPFILE" }, \
{ XFS_TRANS_CREATE_TRUNC, "CREATE_TRUNC" }, \
{ XFS_TRANS_TRUNCATE_FILE, "TRUNCATE_FILE" }, \
{ XFS_TRANS_REMOVE, "REMOVE" }, \
diff --git a/fs/xfs/xfs_trans_resv.c b/fs/xfs/xfs_trans_resv.c
index 2fd59c0..bd3b4b7 100644
--- a/fs/xfs/xfs_trans_resv.c
+++ b/fs/xfs/xfs_trans_resv.c
@@ -229,6 +229,18 @@ xfs_calc_link_reservation(
}
/*
+ * For adding an inode to unlinked list we can modify:
+ * the agi hash list: sector size
+ * the unlinked inode: inode size
+ */
+STATIC uint
+xfs_calc_iunlink_add_reservation(xfs_mount_t *mp)
+{
+ return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
+ xfs_calc_inode_res(mp, 1);
+}
+
+/*
* For removing a directory entry we can modify:
* the parent directory inode: inode size
* the removed inode: inode size
@@ -245,10 +257,11 @@ xfs_calc_remove_reservation(
struct xfs_mount *mp)
{
return XFS_DQUOT_LOGRES(mp) +
- MAX((xfs_calc_inode_res(mp, 2) +
+ xfs_calc_iunlink_add_reservation(mp) +
+ MAX((xfs_calc_inode_res(mp, 1) +
xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
XFS_FSB_TO_B(mp, 1))),
- (xfs_calc_buf_res(5, mp->m_sb.sb_sectsize) +
+ (xfs_calc_buf_res(4, mp->m_sb.sb_sectsize) +
xfs_calc_buf_res(XFS_ALLOCFREE_LOG_COUNT(mp, 2),
XFS_FSB_TO_B(mp, 1))));
}
@@ -343,6 +356,20 @@ xfs_calc_create_reservation(
}
+STATIC uint
+xfs_calc_create_tmpfile_reservation(
+ struct xfs_mount *mp)
+{
+ uint res = XFS_DQUOT_LOGRES(mp);
+
+ if (xfs_sb_version_hascrc(&mp->m_sb))
+ res += xfs_calc_icreate_resv_alloc(mp);
+ else
+ res += xfs_calc_create_resv_alloc(mp);
+
+ return res + xfs_calc_iunlink_add_reservation(mp);
+}
+
/*
* Making a new directory is the same as creating a new file.
*/
@@ -729,6 +756,11 @@ xfs_trans_resv_calc(
resp->tr_create.tr_logcount = XFS_CREATE_LOG_COUNT;
resp->tr_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+ resp->tr_create_tmpfile.tr_logres =
+ xfs_calc_create_tmpfile_reservation(mp);
+ resp->tr_create_tmpfile.tr_logcount = XFS_CREATE_TMPFILE_LOG_COUNT;
+ resp->tr_create_tmpfile.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
resp->tr_mkdir.tr_logres = xfs_calc_mkdir_reservation(mp);
resp->tr_mkdir.tr_logcount = XFS_MKDIR_LOG_COUNT;
resp->tr_mkdir.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
diff --git a/fs/xfs/xfs_trans_resv.h b/fs/xfs/xfs_trans_resv.h
index de7de9a..285621d 100644
--- a/fs/xfs/xfs_trans_resv.h
+++ b/fs/xfs/xfs_trans_resv.h
@@ -38,6 +38,7 @@ struct xfs_trans_resv {
struct xfs_trans_res tr_remove; /* unlink trans */
struct xfs_trans_res tr_symlink; /* symlink trans */
struct xfs_trans_res tr_create; /* create trans */
+ struct xfs_trans_res tr_create_tmpfile; /* create O_TMPFILE trans */
struct xfs_trans_res tr_mkdir; /* mkdir trans */
struct xfs_trans_res tr_ifree; /* inode free trans */
struct xfs_trans_res tr_ichange; /* inode update trans */
@@ -100,6 +101,7 @@ struct xfs_trans_resv {
#define XFS_ITRUNCATE_LOG_COUNT 2
#define XFS_INACTIVE_LOG_COUNT 2
#define XFS_CREATE_LOG_COUNT 2
+#define XFS_CREATE_TMPFILE_LOG_COUNT 2
#define XFS_MKDIR_LOG_COUNT 3
#define XFS_SYMLINK_LOG_COUNT 3
#define XFS_REMOVE_LOG_COUNT 2
--
1.7.6.5
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v2 2/3] xfs: add O_TMPFILE support
2013-12-18 0:22 ` [PATCH v2 2/3] xfs: add O_TMPFILE support Zhi Yong Wu
@ 2013-12-24 0:55 ` Dave Chinner
2013-12-24 1:58 ` Zhi Yong Wu
0 siblings, 1 reply; 14+ messages in thread
From: Dave Chinner @ 2013-12-24 0:55 UTC (permalink / raw)
To: Zhi Yong Wu; +Cc: Zhi Yong Wu, xfs
On Wed, Dec 18, 2013 at 08:22:40AM +0800, Zhi Yong Wu wrote:
> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>
> 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().
There's minor stuff I could ask you to change, but I think this is
good enough for initial support of O_TMPFILE.
Reviewed-by: Dave Chinner <dchinner@redhat.com>
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 2/3] xfs: add O_TMPFILE support
2013-12-24 0:55 ` Dave Chinner
@ 2013-12-24 1:58 ` Zhi Yong Wu
0 siblings, 0 replies; 14+ messages in thread
From: Zhi Yong Wu @ 2013-12-24 1:58 UTC (permalink / raw)
To: Dave Chinner, Christoph Hellwig; +Cc: Zhi Yong Wu, xfstests
On Tue, Dec 24, 2013 at 8:55 AM, Dave Chinner <david@fromorbit.com> wrote:
> On Wed, Dec 18, 2013 at 08:22:40AM +0800, Zhi Yong Wu wrote:
>> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>>
>> 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().
>
> There's minor stuff I could ask you to change, but I think this is
> good enough for initial support of O_TMPFILE.
>
> Reviewed-by: Dave Chinner <dchinner@redhat.com>
Great, thanks a lot for your amazing Chrismas gift. Dave and
Christoph, Merry Chrismas!
>
> --
> Dave Chinner
> david@fromorbit.com
--
Regards,
Zhi Yong Wu
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 3/3] xfs: allow linkat() on O_TMPFILE files
2013-12-18 0:22 [PATCH v2 0/3] xfs: add O_TMPFILE support Zhi Yong Wu
2013-12-18 0:22 ` [PATCH v2 1/3] xfs: factor prid related codes into xfs_get_initial_prid() Zhi Yong Wu
2013-12-18 0:22 ` [PATCH v2 2/3] xfs: add O_TMPFILE support Zhi Yong Wu
@ 2013-12-18 0:22 ` Zhi Yong Wu
2013-12-24 0:55 ` Dave Chinner
2013-12-23 1:45 ` [PATCH v2 0/3] xfs: add O_TMPFILE support Zhi Yong Wu
2013-12-26 8:51 ` Christoph Hellwig
4 siblings, 1 reply; 14+ messages in thread
From: Zhi Yong Wu @ 2013-12-18 0:22 UTC (permalink / raw)
To: xfs; +Cc: Zhi Yong Wu
From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
The VFS allows an anonymous temporary file to be named at a later
time via a linkat() syscall. The inodes for O_TMPFILE files are
are marked with a special flag I_LINKABLE and have a zero link count.
To support this in XFS, xfs_link() detects if this flag I_LINKABLE
is set and behaves appropriately when detected. So in this case,
its transaciton reservation takes into account the additional
overhead of removing the inode from the unlinked list. Then the
inode is removed from the unlinked list and the directory entry
is added. Finally its link count is bumped accordingly.
Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
---
fs/xfs/xfs_inode.c | 10 +++++++++-
fs/xfs/xfs_trans_resv.c | 19 +++++++++++++++++--
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index ac133ea..b08b5a8 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -61,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
*/
@@ -1118,7 +1120,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) &&
@@ -1504,6 +1506,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)
diff --git a/fs/xfs/xfs_trans_resv.c b/fs/xfs/xfs_trans_resv.c
index bd3b4b7..76f9a02 100644
--- a/fs/xfs/xfs_trans_resv.c
+++ b/fs/xfs/xfs_trans_resv.c
@@ -204,6 +204,20 @@ xfs_calc_rename_reservation(
}
/*
+ * For removing an inode from unlinked list at first, we can modify:
+ * the agi hash list and counters: sector size
+ * the on disk inode before ours in the agi hash list: inode cluster size
+ */
+STATIC uint
+xfs_calc_iunlink_remove_reservation(
+ struct xfs_mount *mp)
+{
+ return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
+ MAX((__uint16_t)XFS_FSB_TO_B(mp, 1),
+ (__uint16_t)XFS_INODE_CLUSTER_SIZE(mp));
+}
+
+/*
* For creating a link to an inode:
* the parent directory inode: inode size
* the linked inode: inode size
@@ -220,6 +234,7 @@ xfs_calc_link_reservation(
struct xfs_mount *mp)
{
return XFS_DQUOT_LOGRES(mp) +
+ xfs_calc_iunlink_remove_reservation(mp) +
MAX((xfs_calc_inode_res(mp, 2) +
xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp),
XFS_FSB_TO_B(mp, 1))),
@@ -410,9 +425,9 @@ xfs_calc_ifree_reservation(
{
return XFS_DQUOT_LOGRES(mp) +
xfs_calc_inode_res(mp, 1) +
- xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) +
- max_t(uint, XFS_FSB_TO_B(mp, 1), XFS_INODE_CLUSTER_SIZE(mp)) +
+ xfs_calc_iunlink_remove_reservation(mp) +
xfs_calc_buf_res(1, 0) +
xfs_calc_buf_res(2 + XFS_IALLOC_BLOCKS(mp) +
mp->m_in_maxlevels, 0) +
--
1.7.6.5
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v2 3/3] xfs: allow linkat() on O_TMPFILE files
2013-12-18 0:22 ` [PATCH v2 3/3] xfs: allow linkat() on O_TMPFILE files Zhi Yong Wu
@ 2013-12-24 0:55 ` Dave Chinner
0 siblings, 0 replies; 14+ messages in thread
From: Dave Chinner @ 2013-12-24 0:55 UTC (permalink / raw)
To: Zhi Yong Wu; +Cc: Zhi Yong Wu, xfs
On Wed, Dec 18, 2013 at 08:22:41AM +0800, Zhi Yong Wu wrote:
> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>
> The VFS allows an anonymous temporary file to be named at a later
> time via a linkat() syscall. The inodes for O_TMPFILE files are
> are marked with a special flag I_LINKABLE and have a zero link count.
>
> To support this in XFS, xfs_link() detects if this flag I_LINKABLE
> is set and behaves appropriately when detected. So in this case,
> its transaciton reservation takes into account the additional
> overhead of removing the inode from the unlinked list. Then the
> inode is removed from the unlinked list and the directory entry
> is added. Finally its link count is bumped accordingly.
>
> Signed-off-by: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
Looks good.
Reviewed-by: Dave Chinner <dchinner@redhat.com>
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 0/3] xfs: add O_TMPFILE support
2013-12-18 0:22 [PATCH v2 0/3] xfs: add O_TMPFILE support Zhi Yong Wu
` (2 preceding siblings ...)
2013-12-18 0:22 ` [PATCH v2 3/3] xfs: allow linkat() on O_TMPFILE files Zhi Yong Wu
@ 2013-12-23 1:45 ` Zhi Yong Wu
2013-12-26 8:51 ` Christoph Hellwig
4 siblings, 0 replies; 14+ messages in thread
From: Zhi Yong Wu @ 2013-12-23 1:45 UTC (permalink / raw)
To: xfstests; +Cc: Zhi Yong Wu
ping?
On Wed, Dec 18, 2013 at 8:22 AM, Zhi Yong Wu <zwu.kernel@gmail.com> wrote:
> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>
> HI, folks
>
> It's time to post the latest revision out, welcome to any constructive comment, thanks.
>
> If anyone is interested in playing with it, you can get this patchset from my dev git on github:
> git://github.com/wuzhy/kernel.git xfs_tmpfile
>
> The patchset was tested against the code snippet from Andy Lutomirski and other test cases:
> http://lwn.net/Articles/562296/
> If you have any other better test cases, please let me know, thanks.
>
> #include <stdio.h>
> #include <err.h>
> #include <fcntl.h>
> #include <unistd.h>
> #include <string.h>
>
> #define __O_TMPFILE 020000000
> #define O_DIRECTORY 0200000
> #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
> #define AT_EMPTY_PATH 0x1000
>
> int main(int argc, char **argv)
> {
> char buf[128];
>
> if (argc != 3)
> errx(1, "Usage: flinktest PATH linkat|proc");
>
> int fd = open(".", O_TMPFILE | O_RDWR, 0600);
> if (fd == -1)
> err(1, "O_TMPFILE");
> else
> printf("fd #: %d\n", fd);
>
> write(fd, "test", 4);
>
> if (!strcmp(argv[2], "linkat")) {
> if (linkat(fd, "", AT_FDCWD, argv[1], AT_EMPTY_PATH) != 0)
> err(1, "linkat");
> } else if (!strcmp(argv[2], "proc")) {
> sprintf(buf, "/proc/self/fd/%d", fd);
> if (linkat(AT_FDCWD, buf, AT_FDCWD, argv[1], AT_SYMLINK_FOLLOW) != 0)
> err(1, "linkat");
> } else {
> errx(1, "invalid mode");
> }
>
> return 0;
> }
>
> Changelog from v1:
> - Fixed one chunk of the comments from Christoph Hellwig and Jeff Liu.
>
> v1:
> - Addressed the comments from Dave Chinner and Christoph Hellwig.
>
> Zhi Yong Wu (3):
> xfs: factor prid related codes into xfs_get_initial_prid()
> xfs: add O_TMPFILE support
> xfs: allow linkat() on O_TMPFILE files
>
> fs/xfs/xfs_inode.c | 123 ++++++++++++++++++++++++++++++++++++++++++++--
> fs/xfs/xfs_inode.h | 12 +++++
> fs/xfs/xfs_iops.c | 16 ++++++
> fs/xfs/xfs_shared.h | 4 +-
> fs/xfs/xfs_symlink.c | 5 +--
> fs/xfs/xfs_trans_resv.c | 55 +++++++++++++++++++--
> fs/xfs/xfs_trans_resv.h | 2 +
> 7 files changed, 202 insertions(+), 15 deletions(-)
>
> --
> 1.7.6.5
>
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
--
Regards,
Zhi Yong Wu
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 0/3] xfs: add O_TMPFILE support
2013-12-18 0:22 [PATCH v2 0/3] xfs: add O_TMPFILE support Zhi Yong Wu
` (3 preceding siblings ...)
2013-12-23 1:45 ` [PATCH v2 0/3] xfs: add O_TMPFILE support Zhi Yong Wu
@ 2013-12-26 8:51 ` Christoph Hellwig
2013-12-28 10:04 ` Zhi Yong Wu
2014-01-07 20:49 ` Ben Myers
4 siblings, 2 replies; 14+ messages in thread
From: Christoph Hellwig @ 2013-12-26 8:51 UTC (permalink / raw)
To: Zhi Yong Wu; +Cc: linux-api, Zhi Yong Wu, xfs
Both patches looks good to me,
Reviewed-by: Christoph Hellwig <hch@lst.de>
But now we need to make sure we can exercise it, which will need
support for tmpfile and flink commands in xfs_io.
And tests that use those commands in xfstests. At a minimum I'd
suggest:
- test creating read-only/read-write/executable files
- check how permission bits actually work for O_TMPFILE and
enforce that (unfortunately I can't find any documentation for that)
- check that creating non-regular files is properly rejected
- check that flink works on O_TMPFILE files, but doesn't work on
on other files
For an additional XFS-specific test I'd recommend:
- creating a tmpfile, use src/godown to force the filesystem down and
check that repair recoveres the unlinked inode list
- creating a tmpfile, flinking it, use src/godown to force the
filesystem down and check that repair does not have to recover
the unlink inode list.
On Wed, Dec 18, 2013 at 08:22:38AM +0800, Zhi Yong Wu wrote:
> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>
> HI, folks
>
> It's time to post the latest revision out, welcome to any constructive comment, thanks.
>
> If anyone is interested in playing with it, you can get this patchset from my dev git on github:
> git://github.com/wuzhy/kernel.git xfs_tmpfile
>
> The patchset was tested against the code snippet from Andy Lutomirski and other test cases:
> http://lwn.net/Articles/562296/
> If you have any other better test cases, please let me know, thanks.
>
> #include <stdio.h>
> #include <err.h>
> #include <fcntl.h>
> #include <unistd.h>
> #include <string.h>
>
> #define __O_TMPFILE 020000000
> #define O_DIRECTORY 0200000
> #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
> #define AT_EMPTY_PATH 0x1000
>
> int main(int argc, char **argv)
> {
> char buf[128];
>
> if (argc != 3)
> errx(1, "Usage: flinktest PATH linkat|proc");
>
> int fd = open(".", O_TMPFILE | O_RDWR, 0600);
> if (fd == -1)
> err(1, "O_TMPFILE");
> else
> printf("fd #: %d\n", fd);
>
> write(fd, "test", 4);
>
> if (!strcmp(argv[2], "linkat")) {
> if (linkat(fd, "", AT_FDCWD, argv[1], AT_EMPTY_PATH) != 0)
> err(1, "linkat");
> } else if (!strcmp(argv[2], "proc")) {
> sprintf(buf, "/proc/self/fd/%d", fd);
> if (linkat(AT_FDCWD, buf, AT_FDCWD, argv[1], AT_SYMLINK_FOLLOW) != 0)
> err(1, "linkat");
> } else {
> errx(1, "invalid mode");
> }
>
> return 0;
> }
>
> Changelog from v1:
> - Fixed one chunk of the comments from Christoph Hellwig and Jeff Liu.
>
> v1:
> - Addressed the comments from Dave Chinner and Christoph Hellwig.
>
> Zhi Yong Wu (3):
> xfs: factor prid related codes into xfs_get_initial_prid()
> xfs: add O_TMPFILE support
> xfs: allow linkat() on O_TMPFILE files
>
> fs/xfs/xfs_inode.c | 123 ++++++++++++++++++++++++++++++++++++++++++++--
> fs/xfs/xfs_inode.h | 12 +++++
> fs/xfs/xfs_iops.c | 16 ++++++
> fs/xfs/xfs_shared.h | 4 +-
> fs/xfs/xfs_symlink.c | 5 +--
> fs/xfs/xfs_trans_resv.c | 55 +++++++++++++++++++--
> fs/xfs/xfs_trans_resv.h | 2 +
> 7 files changed, 202 insertions(+), 15 deletions(-)
>
> --
> 1.7.6.5
>
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
---end quoted text---
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 0/3] xfs: add O_TMPFILE support
@ 2013-12-28 10:04 ` Zhi Yong Wu
0 siblings, 0 replies; 14+ messages in thread
From: Zhi Yong Wu @ 2013-12-28 10:04 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: linux-api, Zhi Yong Wu, xfstests
On Thu, Dec 26, 2013 at 4:51 PM, Christoph Hellwig <hch@infradead.org> wrote:
> Both patches looks good to me,
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
Indeed thanks for your review. ok, i will place them to my TODO list.
>
> But now we need to make sure we can exercise it, which will need
> support for tmpfile and flink commands in xfs_io.
>
> And tests that use those commands in xfstests. At a minimum I'd
> suggest:
>
> - test creating read-only/read-write/executable files
> - check how permission bits actually work for O_TMPFILE and
> enforce that (unfortunately I can't find any documentation for that)
> - check that creating non-regular files is properly rejected
> - check that flink works on O_TMPFILE files, but doesn't work on
> on other files
>
> For an additional XFS-specific test I'd recommend:
>
> - creating a tmpfile, use src/godown to force the filesystem down and
> check that repair recoveres the unlinked inode list
> - creating a tmpfile, flinking it, use src/godown to force the
> filesystem down and check that repair does not have to recover
> the unlink inode list.
>
> On Wed, Dec 18, 2013 at 08:22:38AM +0800, Zhi Yong Wu wrote:
>> From: Zhi Yong Wu <wuzhy@linux.vnet.ibm.com>
>>
>> HI, folks
>>
>> It's time to post the latest revision out, welcome to any constructive comment, thanks.
>>
>> If anyone is interested in playing with it, you can get this patchset from my dev git on github:
>> git://github.com/wuzhy/kernel.git xfs_tmpfile
>>
>> The patchset was tested against the code snippet from Andy Lutomirski and other test cases:
>> http://lwn.net/Articles/562296/
>> If you have any other better test cases, please let me know, thanks.
>>
>> #include <stdio.h>
>> #include <err.h>
>> #include <fcntl.h>
>> #include <unistd.h>
>> #include <string.h>
>>
>> #define __O_TMPFILE 020000000
>> #define O_DIRECTORY 0200000
>> #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
>> #define AT_EMPTY_PATH 0x1000
>>
>> int main(int argc, char **argv)
>> {
>> char buf[128];
>>
>> if (argc != 3)
>> errx(1, "Usage: flinktest PATH linkat|proc");
>>
>> int fd = open(".", O_TMPFILE | O_RDWR, 0600);
>> if (fd == -1)
>> err(1, "O_TMPFILE");
>> else
>> printf("fd #: %d\n", fd);
>>
>> write(fd, "test", 4);
>>
>> if (!strcmp(argv[2], "linkat")) {
>> if (linkat(fd, "", AT_FDCWD, argv[1], AT_EMPTY_PATH) != 0)
>> err(1, "linkat");
>> } else if (!strcmp(argv[2], "proc")) {
>> sprintf(buf, "/proc/self/fd/%d", fd);
>> if (linkat(AT_FDCWD, buf, AT_FDCWD, argv[1], AT_SYMLINK_FOLLOW) != 0)
>> err(1, "linkat");
>> } else {
>> errx(1, "invalid mode");
>> }
>>
>> return 0;
>> }
>>
>> Changelog from v1:
>> - Fixed one chunk of the comments from Christoph Hellwig and Jeff Liu.
>>
>> v1:
>> - Addressed the comments from Dave Chinner and Christoph Hellwig.
>>
>> Zhi Yong Wu (3):
>> xfs: factor prid related codes into xfs_get_initial_prid()
>> xfs: add O_TMPFILE support
>> xfs: allow linkat() on O_TMPFILE files
>>
>> fs/xfs/xfs_inode.c | 123 ++++++++++++++++++++++++++++++++++++++++++++--
>> fs/xfs/xfs_inode.h | 12 +++++
>> fs/xfs/xfs_iops.c | 16 ++++++
>> fs/xfs/xfs_shared.h | 4 +-
>> fs/xfs/xfs_symlink.c | 5 +--
>> fs/xfs/xfs_trans_resv.c | 55 +++++++++++++++++++--
>> fs/xfs/xfs_trans_resv.h | 2 +
>> 7 files changed, 202 insertions(+), 15 deletions(-)
>>
>> --
>> 1.7.6.5
>>
>> _______________________________________________
>> xfs mailing list
>> xfs@oss.sgi.com
>> http://oss.sgi.com/mailman/listinfo/xfs
> ---end quoted text---
--
Regards,
Zhi Yong Wu
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 0/3] xfs: add O_TMPFILE support
@ 2013-12-28 10:04 ` Zhi Yong Wu
0 siblings, 0 replies; 14+ messages in thread
From: Zhi Yong Wu @ 2013-12-28 10:04 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: xfstests, Zhi Yong Wu, linux-api-u79uwXL29TY76Z2rM5mHXA
On Thu, Dec 26, 2013 at 4:51 PM, Christoph Hellwig <hch-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org> wrote:
> Both patches looks good to me,
>
> Reviewed-by: Christoph Hellwig <hch-jcswGhMUV9g@public.gmane.org>
Indeed thanks for your review. ok, i will place them to my TODO list.
>
> But now we need to make sure we can exercise it, which will need
> support for tmpfile and flink commands in xfs_io.
>
> And tests that use those commands in xfstests. At a minimum I'd
> suggest:
>
> - test creating read-only/read-write/executable files
> - check how permission bits actually work for O_TMPFILE and
> enforce that (unfortunately I can't find any documentation for that)
> - check that creating non-regular files is properly rejected
> - check that flink works on O_TMPFILE files, but doesn't work on
> on other files
>
> For an additional XFS-specific test I'd recommend:
>
> - creating a tmpfile, use src/godown to force the filesystem down and
> check that repair recoveres the unlinked inode list
> - creating a tmpfile, flinking it, use src/godown to force the
> filesystem down and check that repair does not have to recover
> the unlink inode list.
>
> On Wed, Dec 18, 2013 at 08:22:38AM +0800, Zhi Yong Wu wrote:
>> From: Zhi Yong Wu <wuzhy-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>
>>
>> HI, folks
>>
>> It's time to post the latest revision out, welcome to any constructive comment, thanks.
>>
>> If anyone is interested in playing with it, you can get this patchset from my dev git on github:
>> git://github.com/wuzhy/kernel.git xfs_tmpfile
>>
>> The patchset was tested against the code snippet from Andy Lutomirski and other test cases:
>> http://lwn.net/Articles/562296/
>> If you have any other better test cases, please let me know, thanks.
>>
>> #include <stdio.h>
>> #include <err.h>
>> #include <fcntl.h>
>> #include <unistd.h>
>> #include <string.h>
>>
>> #define __O_TMPFILE 020000000
>> #define O_DIRECTORY 0200000
>> #define O_TMPFILE (__O_TMPFILE | O_DIRECTORY)
>> #define AT_EMPTY_PATH 0x1000
>>
>> int main(int argc, char **argv)
>> {
>> char buf[128];
>>
>> if (argc != 3)
>> errx(1, "Usage: flinktest PATH linkat|proc");
>>
>> int fd = open(".", O_TMPFILE | O_RDWR, 0600);
>> if (fd == -1)
>> err(1, "O_TMPFILE");
>> else
>> printf("fd #: %d\n", fd);
>>
>> write(fd, "test", 4);
>>
>> if (!strcmp(argv[2], "linkat")) {
>> if (linkat(fd, "", AT_FDCWD, argv[1], AT_EMPTY_PATH) != 0)
>> err(1, "linkat");
>> } else if (!strcmp(argv[2], "proc")) {
>> sprintf(buf, "/proc/self/fd/%d", fd);
>> if (linkat(AT_FDCWD, buf, AT_FDCWD, argv[1], AT_SYMLINK_FOLLOW) != 0)
>> err(1, "linkat");
>> } else {
>> errx(1, "invalid mode");
>> }
>>
>> return 0;
>> }
>>
>> Changelog from v1:
>> - Fixed one chunk of the comments from Christoph Hellwig and Jeff Liu.
>>
>> v1:
>> - Addressed the comments from Dave Chinner and Christoph Hellwig.
>>
>> Zhi Yong Wu (3):
>> xfs: factor prid related codes into xfs_get_initial_prid()
>> xfs: add O_TMPFILE support
>> xfs: allow linkat() on O_TMPFILE files
>>
>> fs/xfs/xfs_inode.c | 123 ++++++++++++++++++++++++++++++++++++++++++++--
>> fs/xfs/xfs_inode.h | 12 +++++
>> fs/xfs/xfs_iops.c | 16 ++++++
>> fs/xfs/xfs_shared.h | 4 +-
>> fs/xfs/xfs_symlink.c | 5 +--
>> fs/xfs/xfs_trans_resv.c | 55 +++++++++++++++++++--
>> fs/xfs/xfs_trans_resv.h | 2 +
>> 7 files changed, 202 insertions(+), 15 deletions(-)
>>
>> --
>> 1.7.6.5
>>
>> _______________________________________________
>> xfs mailing list
>> xfs-VZNHf3L845pBDgjK7y7TUQ@public.gmane.org
>> http://oss.sgi.com/mailman/listinfo/xfs
> ---end quoted text---
--
Regards,
Zhi Yong Wu
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 0/3] xfs: add O_TMPFILE support
2013-12-26 8:51 ` Christoph Hellwig
2013-12-28 10:04 ` Zhi Yong Wu
@ 2014-01-07 20:49 ` Ben Myers
2014-01-07 20:51 ` Christoph Hellwig
1 sibling, 1 reply; 14+ messages in thread
From: Ben Myers @ 2014-01-07 20:49 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Zhi Yong Wu, linux-api, Zhi Yong Wu, xfs
Hey Christoph,
On Thu, Dec 26, 2013 at 12:51:34AM -0800, Christoph Hellwig wrote:
> Both patches looks good to me,
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
>
> But now we need to make sure we can exercise it, which will need
> support for tmpfile and flink commands in xfs_io.
Are you suggesting that we hold off on this until such time as the tests are
completed?
Thanks,
Ben
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 14+ messages in thread