Fixes for 3.15-rc5:
- 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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAABAgAGBQJTa+0vAAoJEK3oKUf0dfodQGkQAI4IzVYr4K02Rj7UcbZaGlUM R9OAATojaQ8/hPDshzrhyLK7/KvF2tJvH9PhP6zj3bko3fmhofJ5/mB6LYIsQtt+ 3rNd/jij9Icmq4+ouZPRDl00nJdnCZjJcfYys6N/tXwLNIvwKP04vjB4QoC1rxVv j6L85yUkMpPohA0Wbf+PKrTVJDrtTOe+YpczciYgGKHr0YF27Bdy6iYSU3KvTvd+ wuqXvGAc9ARZDsrVHt8t6eh9OKRRk1RAV5vdwGwucBrVlnxGaspvia/85JyU3Kv0 F2EQ3fWcGQs5ydQjpvSZlEIttDqBDn/LiuncNctXIUvHpr+MQ73XMVrNLoNY1m6d wQqXFQXT4e/vzJTXyQz/jYgzGl5t9Lvf/1Z5lFHliqhaBm1aNMhdjfCZhEpehoaQ 09JSVj8ZKLHZt3yRgwkZdOmM0bl4thJmY1Wf5O2EPMrk3NE3nZKiNG+W2U/sSFti i12M4uVgInmeHoDIWFNL9kXp3fs+gr6HF5BNQOulm0ywzG3U1ozWGyKsnRmpPFQr 995voVKZKDP410wzp98UKpjXalmonYuTFLNUDEEjr2UKUWq6fRpvDdSeBSRirGxP kdwfpgCZHDJlZEY7d4lv4Pv6L84KgYYHQpmbaFcPEAmJmlMZ4web1KqHl8TDy1hT Z+STYvTImpXV9sP5TZYT =79c6 -----END PGP SIGNATURE----- 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
This commit is contained in:
Коммит
afcf0a2d92
|
@ -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 @@ restart:
|
|||
|
||||
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 @@ restart:
|
|||
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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче