Commit 3dbecf0a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'xfs-for-linus-v3.12-rc4' of git://oss.sgi.com/xfs/xfs

Pull xfs bugfixes from Ben Myers:
 "There are lockdep annotations for project quotas, a fix for dirent
  dtype support on v4 filesystems, a fix for a memory leak in recovery,
  and a fix for the build error that resulted from it.  D'oh"

* tag 'xfs-for-linus-v3.12-rc4' of git://oss.sgi.com/xfs/xfs:
  xfs: Use kmem_free() instead of free()
  xfs: fix memory leak in xlog_recover_add_to_trans
  xfs: dirent dtype presence is dependent on directory magic numbers
  xfs: lockdep needs to know about 3 dquot-deep nesting
parents ab354062 b2a42f78
...@@ -1158,7 +1158,7 @@ xfs_dir2_sf_to_block( ...@@ -1158,7 +1158,7 @@ xfs_dir2_sf_to_block(
/* /*
* Create entry for . * Create entry for .
*/ */
dep = xfs_dir3_data_dot_entry_p(hdr); dep = xfs_dir3_data_dot_entry_p(mp, hdr);
dep->inumber = cpu_to_be64(dp->i_ino); dep->inumber = cpu_to_be64(dp->i_ino);
dep->namelen = 1; dep->namelen = 1;
dep->name[0] = '.'; dep->name[0] = '.';
...@@ -1172,7 +1172,7 @@ xfs_dir2_sf_to_block( ...@@ -1172,7 +1172,7 @@ xfs_dir2_sf_to_block(
/* /*
* Create entry for .. * Create entry for ..
*/ */
dep = xfs_dir3_data_dotdot_entry_p(hdr); dep = xfs_dir3_data_dotdot_entry_p(mp, hdr);
dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp)); dep->inumber = cpu_to_be64(xfs_dir2_sf_get_parent_ino(sfp));
dep->namelen = 2; dep->namelen = 2;
dep->name[0] = dep->name[1] = '.'; dep->name[0] = dep->name[1] = '.';
...@@ -1183,7 +1183,7 @@ xfs_dir2_sf_to_block( ...@@ -1183,7 +1183,7 @@ xfs_dir2_sf_to_block(
blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot); blp[1].hashval = cpu_to_be32(xfs_dir_hash_dotdot);
blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp, blp[1].address = cpu_to_be32(xfs_dir2_byte_to_dataptr(mp,
(char *)dep - (char *)hdr)); (char *)dep - (char *)hdr));
offset = xfs_dir3_data_first_offset(hdr); offset = xfs_dir3_data_first_offset(mp);
/* /*
* Loop over existing entries, stuff them in. * Loop over existing entries, stuff them in.
*/ */
......
...@@ -497,69 +497,58 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr) ...@@ -497,69 +497,58 @@ xfs_dir3_data_unused_p(struct xfs_dir2_data_hdr *hdr)
/* /*
* Offsets of . and .. in data space (always block 0) * Offsets of . and .. in data space (always block 0)
* *
* The macros are used for shortform directories as they have no headers to read
* the magic number out of. Shortform directories need to know the size of the
* data block header because the sfe embeds the block offset of the entry into
* it so that it doesn't change when format conversion occurs. Bad Things Happen
* if we don't follow this rule.
*
* XXX: there is scope for significant optimisation of the logic here. Right * XXX: there is scope for significant optimisation of the logic here. Right
* now we are checking for "dir3 format" over and over again. Ideally we should * now we are checking for "dir3 format" over and over again. Ideally we should
* only do it once for each operation. * only do it once for each operation.
*/ */
#define XFS_DIR3_DATA_DOT_OFFSET(mp) \
xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&(mp)->m_sb))
#define XFS_DIR3_DATA_DOTDOT_OFFSET(mp) \
(XFS_DIR3_DATA_DOT_OFFSET(mp) + xfs_dir3_data_entsize(mp, 1))
#define XFS_DIR3_DATA_FIRST_OFFSET(mp) \
(XFS_DIR3_DATA_DOTDOT_OFFSET(mp) + xfs_dir3_data_entsize(mp, 2))
static inline xfs_dir2_data_aoff_t static inline xfs_dir2_data_aoff_t
xfs_dir3_data_dot_offset(struct xfs_dir2_data_hdr *hdr) xfs_dir3_data_dot_offset(struct xfs_mount *mp)
{ {
return xfs_dir3_data_entry_offset(hdr); return xfs_dir3_data_hdr_size(xfs_sb_version_hascrc(&mp->m_sb));
} }
static inline xfs_dir2_data_aoff_t static inline xfs_dir2_data_aoff_t
xfs_dir3_data_dotdot_offset(struct xfs_dir2_data_hdr *hdr) xfs_dir3_data_dotdot_offset(struct xfs_mount *mp)
{ {
bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || return xfs_dir3_data_dot_offset(mp) +
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC); xfs_dir3_data_entsize(mp, 1);
return xfs_dir3_data_dot_offset(hdr) +
__xfs_dir3_data_entsize(dir3, 1);
} }
static inline xfs_dir2_data_aoff_t static inline xfs_dir2_data_aoff_t
xfs_dir3_data_first_offset(struct xfs_dir2_data_hdr *hdr) xfs_dir3_data_first_offset(struct xfs_mount *mp)
{ {
bool dir3 = hdr->magic == cpu_to_be32(XFS_DIR3_DATA_MAGIC) || return xfs_dir3_data_dotdot_offset(mp) +
hdr->magic == cpu_to_be32(XFS_DIR3_BLOCK_MAGIC); xfs_dir3_data_entsize(mp, 2);
return xfs_dir3_data_dotdot_offset(hdr) +
__xfs_dir3_data_entsize(dir3, 2);
} }
/* /*
* location of . and .. in data space (always block 0) * location of . and .. in data space (always block 0)
*/ */
static inline struct xfs_dir2_data_entry * static inline struct xfs_dir2_data_entry *
xfs_dir3_data_dot_entry_p(struct xfs_dir2_data_hdr *hdr) xfs_dir3_data_dot_entry_p(
struct xfs_mount *mp,
struct xfs_dir2_data_hdr *hdr)
{ {
return (struct xfs_dir2_data_entry *) return (struct xfs_dir2_data_entry *)
((char *)hdr + xfs_dir3_data_dot_offset(hdr)); ((char *)hdr + xfs_dir3_data_dot_offset(mp));
} }
static inline struct xfs_dir2_data_entry * static inline struct xfs_dir2_data_entry *
xfs_dir3_data_dotdot_entry_p(struct xfs_dir2_data_hdr *hdr) xfs_dir3_data_dotdot_entry_p(
struct xfs_mount *mp,
struct xfs_dir2_data_hdr *hdr)
{ {
return (struct xfs_dir2_data_entry *) return (struct xfs_dir2_data_entry *)
((char *)hdr + xfs_dir3_data_dotdot_offset(hdr)); ((char *)hdr + xfs_dir3_data_dotdot_offset(mp));
} }
static inline struct xfs_dir2_data_entry * static inline struct xfs_dir2_data_entry *
xfs_dir3_data_first_entry_p(struct xfs_dir2_data_hdr *hdr) xfs_dir3_data_first_entry_p(
struct xfs_mount *mp,
struct xfs_dir2_data_hdr *hdr)
{ {
return (struct xfs_dir2_data_entry *) return (struct xfs_dir2_data_entry *)
((char *)hdr + xfs_dir3_data_first_offset(hdr)); ((char *)hdr + xfs_dir3_data_first_offset(mp));
} }
/* /*
......
...@@ -119,9 +119,9 @@ xfs_dir2_sf_getdents( ...@@ -119,9 +119,9 @@ xfs_dir2_sf_getdents(
* mp->m_dirdatablk. * mp->m_dirdatablk.
*/ */
dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, dot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
XFS_DIR3_DATA_DOT_OFFSET(mp)); xfs_dir3_data_dot_offset(mp));
dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk, dotdot_offset = xfs_dir2_db_off_to_dataptr(mp, mp->m_dirdatablk,
XFS_DIR3_DATA_DOTDOT_OFFSET(mp)); xfs_dir3_data_dotdot_offset(mp));
/* /*
* Put . entry unless we're starting past it. * Put . entry unless we're starting past it.
......
...@@ -557,7 +557,7 @@ xfs_dir2_sf_addname_hard( ...@@ -557,7 +557,7 @@ xfs_dir2_sf_addname_hard(
* to insert the new entry. * to insert the new entry.
* If it's going to end up at the end then oldsfep will point there. * If it's going to end up at the end then oldsfep will point there.
*/ */
for (offset = XFS_DIR3_DATA_FIRST_OFFSET(mp), for (offset = xfs_dir3_data_first_offset(mp),
oldsfep = xfs_dir2_sf_firstentry(oldsfp), oldsfep = xfs_dir2_sf_firstentry(oldsfp),
add_datasize = xfs_dir3_data_entsize(mp, args->namelen), add_datasize = xfs_dir3_data_entsize(mp, args->namelen),
eof = (char *)oldsfep == &buf[old_isize]; eof = (char *)oldsfep == &buf[old_isize];
...@@ -640,7 +640,7 @@ xfs_dir2_sf_addname_pick( ...@@ -640,7 +640,7 @@ xfs_dir2_sf_addname_pick(
sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
size = xfs_dir3_data_entsize(mp, args->namelen); size = xfs_dir3_data_entsize(mp, args->namelen);
offset = XFS_DIR3_DATA_FIRST_OFFSET(mp); offset = xfs_dir3_data_first_offset(mp);
sfep = xfs_dir2_sf_firstentry(sfp); sfep = xfs_dir2_sf_firstentry(sfp);
holefit = 0; holefit = 0;
/* /*
...@@ -713,7 +713,7 @@ xfs_dir2_sf_check( ...@@ -713,7 +713,7 @@ xfs_dir2_sf_check(
mp = dp->i_mount; mp = dp->i_mount;
sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data; sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
offset = XFS_DIR3_DATA_FIRST_OFFSET(mp); offset = xfs_dir3_data_first_offset(mp);
ino = xfs_dir2_sf_get_parent_ino(sfp); ino = xfs_dir2_sf_get_parent_ino(sfp);
i8count = ino > XFS_DIR2_MAX_SHORT_INUM; i8count = ino > XFS_DIR2_MAX_SHORT_INUM;
......
...@@ -64,7 +64,8 @@ int xfs_dqerror_mod = 33; ...@@ -64,7 +64,8 @@ int xfs_dqerror_mod = 33;
struct kmem_zone *xfs_qm_dqtrxzone; struct kmem_zone *xfs_qm_dqtrxzone;
static struct kmem_zone *xfs_qm_dqzone; static struct kmem_zone *xfs_qm_dqzone;
static struct lock_class_key xfs_dquot_other_class; static struct lock_class_key xfs_dquot_group_class;
static struct lock_class_key xfs_dquot_project_class;
/* /*
* This is called to free all the memory associated with a dquot * This is called to free all the memory associated with a dquot
...@@ -703,8 +704,20 @@ xfs_qm_dqread( ...@@ -703,8 +704,20 @@ xfs_qm_dqread(
* Make sure group quotas have a different lock class than user * Make sure group quotas have a different lock class than user
* quotas. * quotas.
*/ */
if (!(type & XFS_DQ_USER)) switch (type) {
lockdep_set_class(&dqp->q_qlock, &xfs_dquot_other_class); case XFS_DQ_USER:
/* uses the default lock class */
break;
case XFS_DQ_GROUP:
lockdep_set_class(&dqp->q_qlock, &xfs_dquot_group_class);
break;
case XFS_DQ_PROJ:
lockdep_set_class(&dqp->q_qlock, &xfs_dquot_project_class);
break;
default:
ASSERT(0);
break;
}
XFS_STATS_INC(xs_qm_dquot); XFS_STATS_INC(xs_qm_dquot);
......
...@@ -1585,6 +1585,7 @@ xlog_recover_add_to_trans( ...@@ -1585,6 +1585,7 @@ xlog_recover_add_to_trans(
"bad number of regions (%d) in inode log format", "bad number of regions (%d) in inode log format",
in_f->ilf_size); in_f->ilf_size);
ASSERT(0); ASSERT(0);
kmem_free(ptr);
return XFS_ERROR(EIO); return XFS_ERROR(EIO);
} }
......
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