Commit afcf0a2d authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'xfs-for-linus-3.15-rc5' of git://oss.sgi.com/xfs/xfs

Pull xfs fixes from Dave Chinner:
 "The main fix is adding support for default ACLs on O_TMPFILE opened
  inodes to bring XFS into line with other filesystems.  Metadata CRCs
  are now also considered well enough tested to be fully supported, so
  we're removing the shouty warnings issued at mount time for
  filesystems with that format.  And there's transaction block
  reservation overrun fix.

  Summary:
   - fix a remote attribute size calculation bug that leads to a
     transaction overrun
   - add default ACLs to O_TMPFILE files
   - Remove the EXPERIMENTAL tag from filesystems with metadata CRC
     support"

* tag 'xfs-for-linus-3.15-rc5' of git://oss.sgi.com/xfs/xfs:
  xfs: remote attribute overwrite causes transaction overrun
  xfs: initialize default acls for ->tmpfile()
  xfs: fully support v5 format filesystems
parents f322e262 8275cdd0
......@@ -213,7 +213,7 @@ xfs_attr_calc_size(
* Out of line attribute, cannot double split, but
* make room for the attribute value itself.
*/
uint dblocks = XFS_B_TO_FSB(mp, valuelen);
uint dblocks = xfs_attr3_rmt_blocks(mp, valuelen);
nblks += dblocks;
nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK);
}
......@@ -698,11 +698,22 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
trace_xfs_attr_leaf_replace(args);
/* save the attribute state for later removal*/
args->op_flags |= XFS_DA_OP_RENAME; /* an atomic rename */
args->blkno2 = args->blkno; /* set 2nd entry info*/
args->index2 = args->index;
args->rmtblkno2 = args->rmtblkno;
args->rmtblkcnt2 = args->rmtblkcnt;
args->rmtvaluelen2 = args->rmtvaluelen;
/*
* clear the remote attr state now that it is saved so that the
* values reflect the state of the attribute we are about to
* add, not the attribute we just found and will remove later.
*/
args->rmtblkno = 0;
args->rmtblkcnt = 0;
args->rmtvaluelen = 0;
}
/*
......@@ -794,6 +805,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args)
args->blkno = args->blkno2;
args->rmtblkno = args->rmtblkno2;
args->rmtblkcnt = args->rmtblkcnt2;
args->rmtvaluelen = args->rmtvaluelen2;
if (args->rmtblkno) {
error = xfs_attr_rmtval_remove(args);
if (error)
......@@ -999,13 +1011,22 @@ xfs_attr_node_addname(xfs_da_args_t *args)
trace_xfs_attr_node_replace(args);
/* save the attribute state for later removal*/
args->op_flags |= XFS_DA_OP_RENAME; /* atomic rename op */
args->blkno2 = args->blkno; /* set 2nd entry info*/
args->index2 = args->index;
args->rmtblkno2 = args->rmtblkno;
args->rmtblkcnt2 = args->rmtblkcnt;
args->rmtvaluelen2 = args->rmtvaluelen;
/*
* clear the remote attr state now that it is saved so that the
* values reflect the state of the attribute we are about to
* add, not the attribute we just found and will remove later.
*/
args->rmtblkno = 0;
args->rmtblkcnt = 0;
args->rmtvaluelen = 0;
}
retval = xfs_attr3_leaf_add(blk->bp, state->args);
......@@ -1133,6 +1154,7 @@ xfs_attr_node_addname(xfs_da_args_t *args)
args->blkno = args->blkno2;
args->rmtblkno = args->rmtblkno2;
args->rmtblkcnt = args->rmtblkcnt2;
args->rmtvaluelen = args->rmtvaluelen2;
if (args->rmtblkno) {
error = xfs_attr_rmtval_remove(args);
if (error)
......
......@@ -1229,6 +1229,7 @@ xfs_attr3_leaf_add_work(
name_rmt->valueblk = 0;
args->rmtblkno = 1;
args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen);
args->rmtvaluelen = args->valuelen;
}
xfs_trans_log_buf(args->trans, bp,
XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index),
......@@ -2167,11 +2168,11 @@ xfs_attr3_leaf_lookup_int(
if (!xfs_attr_namesp_match(args->flags, entry->flags))
continue;
args->index = probe;
args->valuelen = be32_to_cpu(name_rmt->valuelen);
args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
args->rmtblkcnt = xfs_attr3_rmt_blocks(
args->dp->i_mount,
args->valuelen);
args->rmtvaluelen);
return XFS_ERROR(EEXIST);
}
}
......@@ -2220,19 +2221,19 @@ xfs_attr3_leaf_getvalue(
name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
ASSERT(name_rmt->namelen == args->namelen);
ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0);
valuelen = be32_to_cpu(name_rmt->valuelen);
args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount,
valuelen);
args->rmtvaluelen);
if (args->flags & ATTR_KERNOVAL) {
args->valuelen = valuelen;
args->valuelen = args->rmtvaluelen;
return 0;
}
if (args->valuelen < valuelen) {
args->valuelen = valuelen;
if (args->valuelen < args->rmtvaluelen) {
args->valuelen = args->rmtvaluelen;
return XFS_ERROR(ERANGE);
}
args->valuelen = valuelen;
args->valuelen = args->rmtvaluelen;
}
return 0;
}
......@@ -2519,7 +2520,7 @@ xfs_attr3_leaf_clearflag(
ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0);
name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
name_rmt->valuelen = cpu_to_be32(args->valuelen);
name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen);
xfs_trans_log_buf(args->trans, bp,
XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt)));
}
......@@ -2677,7 +2678,7 @@ xfs_attr3_leaf_flipflags(
ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0);
name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index);
name_rmt->valueblk = cpu_to_be32(args->rmtblkno);
name_rmt->valuelen = cpu_to_be32(args->valuelen);
name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen);
xfs_trans_log_buf(args->trans, bp1,
XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt)));
}
......
......@@ -447,6 +447,7 @@ xfs_attr3_leaf_list_int(
args.dp = context->dp;
args.whichfork = XFS_ATTR_FORK;
args.valuelen = valuelen;
args.rmtvaluelen = valuelen;
args.value = kmem_alloc(valuelen, KM_SLEEP | KM_NOFS);
args.rmtblkno = be32_to_cpu(name_rmt->valueblk);
args.rmtblkcnt = xfs_attr3_rmt_blocks(
......
......@@ -337,7 +337,7 @@ xfs_attr_rmtval_get(
struct xfs_buf *bp;
xfs_dablk_t lblkno = args->rmtblkno;
__uint8_t *dst = args->value;
int valuelen = args->valuelen;
int valuelen;
int nmap;
int error;
int blkcnt = args->rmtblkcnt;
......@@ -347,7 +347,9 @@ xfs_attr_rmtval_get(
trace_xfs_attr_rmtval_get(args);
ASSERT(!(args->flags & ATTR_KERNOVAL));
ASSERT(args->rmtvaluelen == args->valuelen);
valuelen = args->rmtvaluelen;
while (valuelen > 0) {
nmap = ATTR_RMTVALUE_MAPSIZE;
error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno,
......@@ -415,7 +417,7 @@ xfs_attr_rmtval_set(
* attributes have headers, we can't just do a straight byte to FSB
* conversion and have to take the header space into account.
*/
blkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen);
blkcnt = xfs_attr3_rmt_blocks(mp, args->rmtvaluelen);
error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff,
XFS_ATTR_FORK);
if (error)
......@@ -480,7 +482,7 @@ xfs_attr_rmtval_set(
*/
lblkno = args->rmtblkno;
blkcnt = args->rmtblkcnt;
valuelen = args->valuelen;
valuelen = args->rmtvaluelen;
while (valuelen > 0) {
struct xfs_buf *bp;
xfs_daddr_t dblkno;
......
......@@ -60,10 +60,12 @@ typedef struct xfs_da_args {
int index; /* index of attr of interest in blk */
xfs_dablk_t rmtblkno; /* remote attr value starting blkno */
int rmtblkcnt; /* remote attr value block count */
int rmtvaluelen; /* remote attr value length in bytes */
xfs_dablk_t blkno2; /* blkno of 2nd attr leaf of interest */
int index2; /* index of 2nd attr in blk */
xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */
int rmtblkcnt2; /* remote attr value block count */
int rmtvaluelen2; /* remote attr value length in bytes */
int op_flags; /* operation flags */
enum xfs_dacmp cmpresult; /* name compare result for lookups */
} xfs_da_args_t;
......
......@@ -124,15 +124,15 @@ xfs_cleanup_inode(
xfs_dentry_to_name(&teardown, dentry, 0);
xfs_remove(XFS_I(dir), &teardown, XFS_I(inode));
iput(inode);
}
STATIC int
xfs_vn_mknod(
xfs_generic_create(
struct inode *dir,
struct dentry *dentry,
umode_t mode,
dev_t rdev)
dev_t rdev,
bool tmpfile) /* unnamed file */
{
struct inode *inode;
struct xfs_inode *ip = NULL;
......@@ -156,8 +156,12 @@ xfs_vn_mknod(
if (error)
return error;
xfs_dentry_to_name(&name, dentry, mode);
error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip);
if (!tmpfile) {
xfs_dentry_to_name(&name, dentry, mode);
error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip);
} else {
error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip);
}
if (unlikely(error))
goto out_free_acl;
......@@ -180,7 +184,11 @@ xfs_vn_mknod(
}
#endif
d_instantiate(dentry, inode);
if (tmpfile)
d_tmpfile(dentry, inode);
else
d_instantiate(dentry, inode);
out_free_acl:
if (default_acl)
posix_acl_release(default_acl);
......@@ -189,10 +197,22 @@ xfs_vn_mknod(
return -error;
out_cleanup_inode:
xfs_cleanup_inode(dir, inode, dentry);
if (!tmpfile)
xfs_cleanup_inode(dir, inode, dentry);
iput(inode);
goto out_free_acl;
}
STATIC int
xfs_vn_mknod(
struct inode *dir,
struct dentry *dentry,
umode_t mode,
dev_t rdev)
{
return xfs_generic_create(dir, dentry, mode, rdev, false);
}
STATIC int
xfs_vn_create(
struct inode *dir,
......@@ -353,6 +373,7 @@ xfs_vn_symlink(
out_cleanup_inode:
xfs_cleanup_inode(dir, inode, dentry);
iput(inode);
out:
return -error;
}
......@@ -1053,25 +1074,7 @@ xfs_vn_tmpfile(
struct dentry *dentry,
umode_t mode)
{
int error;
struct xfs_inode *ip;
struct inode *inode;
error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip);
if (unlikely(error))
return -error;
inode = VFS_I(ip);
error = xfs_init_security(inode, dir, &dentry->d_name);
if (unlikely(error)) {
iput(inode);
return -error;
}
d_tmpfile(dentry, inode);
return 0;
return xfs_generic_create(dir, dentry, mode, 0, true);
}
static const struct inode_operations xfs_inode_operations = {
......
......@@ -616,11 +616,13 @@ xfs_log_mount(
int error = 0;
int min_logfsbs;
if (!(mp->m_flags & XFS_MOUNT_NORECOVERY))
xfs_notice(mp, "Mounting Filesystem");
else {
if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
xfs_notice(mp, "Mounting V%d Filesystem",
XFS_SB_VERSION_NUM(&mp->m_sb));
} else {
xfs_notice(mp,
"Mounting filesystem in no-recovery mode. Filesystem will be inconsistent.");
"Mounting V%d filesystem in no-recovery mode. Filesystem will be inconsistent.",
XFS_SB_VERSION_NUM(&mp->m_sb));
ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
}
......
......@@ -743,8 +743,6 @@ xfs_mountfs(
new_size *= mp->m_sb.sb_inodesize / XFS_DINODE_MIN_SIZE;
if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size))
mp->m_inode_cluster_size = new_size;
xfs_info(mp, "Using inode cluster size of %d bytes",
mp->m_inode_cluster_size);
}
/*
......
......@@ -201,10 +201,6 @@ xfs_mount_validate_sb(
* write validation, we don't need to check feature masks.
*/
if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) {
xfs_alert(mp,
"Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled!\n"
"Use of these features in this kernel is at your own risk!");
if (xfs_sb_has_compat_feature(sbp,
XFS_SB_FEAT_COMPAT_UNKNOWN)) {
xfs_warn(mp,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment