Skip to content

Commit

Permalink
Merge tag 'xfs-for-linus-3.15-rc5' of git://oss.sgi.com/xfs/xfs
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Linus Torvalds committed May 9, 2014
2 parents f322e26 + 8275cdd commit afcf0a2
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 50 deletions.
24 changes: 23 additions & 1 deletion fs/xfs/xfs_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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;
}

/*
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
21 changes: 11 additions & 10 deletions fs/xfs/xfs_attr_leaf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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)));
}
Expand Down Expand Up @@ -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)));
}
Expand Down
1 change: 1 addition & 0 deletions fs/xfs/xfs_attr_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
8 changes: 5 additions & 3 deletions fs/xfs/xfs_attr_remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions fs/xfs/xfs_da_btree.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
55 changes: 29 additions & 26 deletions fs/xfs/xfs_iops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -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);
Expand All @@ -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,
Expand Down Expand Up @@ -353,6 +373,7 @@ xfs_vn_symlink(

out_cleanup_inode:
xfs_cleanup_inode(dir, inode, dentry);
iput(inode);
out:
return -error;
}
Expand Down Expand Up @@ -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 = {
Expand Down
10 changes: 6 additions & 4 deletions fs/xfs/xfs_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
2 changes: 0 additions & 2 deletions fs/xfs/xfs_mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/*
Expand Down
4 changes: 0 additions & 4 deletions fs/xfs/xfs_sb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit afcf0a2

Please sign in to comment.