Skip to content

Commit

Permalink
GFS2: Merge two nearly identical xattr functions
Browse files Browse the repository at this point in the history
There were two functions in the xattr code which were nearly
identical, the only difference being that one was copy data into
the unstuffed xattrs and the other was copying data out from it.

This patch merges the two functions such that the code which deal
with iteration over the unstuffed xattrs is no longer duplicated.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
  • Loading branch information
Steven Whitehouse committed Sep 24, 2012
1 parent 979570e commit 1f98169
Showing 1 changed file with 30 additions and 64 deletions.
94 changes: 30 additions & 64 deletions fs/gfs2/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -448,17 +448,18 @@ ssize_t gfs2_listxattr(struct dentry *dentry, char *buffer, size_t size)
}

/**
* ea_get_unstuffed - actually copies the unstuffed data into the
* request buffer
* ea_iter_unstuffed - copies the unstuffed xattr data to/from the
* request buffer
* @ip: The GFS2 inode
* @ea: The extended attribute header structure
* @data: The data to be copied
* @din: The data to be copied in
* @dout: The data to be copied out (one of din,dout will be NULL)
*
* Returns: errno
*/

static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
char *data)
static int gfs2_iter_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
const char *din, char *dout)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head **bh;
Expand All @@ -467,6 +468,8 @@ static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
__be64 *dataptrs = GFS2_EA2DATAPTRS(ea);
unsigned int x;
int error = 0;
unsigned char *pos;
unsigned cp_size;

bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS);
if (!bh)
Expand Down Expand Up @@ -497,12 +500,21 @@ static int ea_get_unstuffed(struct gfs2_inode *ip, struct gfs2_ea_header *ea,
goto out;
}

memcpy(data, bh[x]->b_data + sizeof(struct gfs2_meta_header),
(sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize);
pos = bh[x]->b_data + sizeof(struct gfs2_meta_header);
cp_size = (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize;

amount -= sdp->sd_jbsize;
data += sdp->sd_jbsize;
if (dout) {
memcpy(dout, pos, cp_size);
dout += sdp->sd_jbsize;
}

if (din) {
gfs2_trans_add_bh(ip->i_gl, bh[x], 1);
memcpy(pos, din, cp_size);
din += sdp->sd_jbsize;
}

amount -= sdp->sd_jbsize;
brelse(bh[x]);
}

Expand All @@ -523,7 +535,7 @@ static int gfs2_ea_get_copy(struct gfs2_inode *ip, struct gfs2_ea_location *el,
memcpy(data, GFS2_EA2DATA(el->el_ea), len);
return len;
}
ret = ea_get_unstuffed(ip, el->el_ea, data);
ret = gfs2_iter_unstuffed(ip, el->el_ea, NULL, data);
if (ret < 0)
return ret;
return len;
Expand Down Expand Up @@ -1220,69 +1232,23 @@ static int gfs2_xattr_set(struct dentry *dentry, const char *name,
size, flags, type);
}


static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
struct gfs2_ea_header *ea, char *data)
{
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
struct buffer_head **bh;
unsigned int amount = GFS2_EA_DATA_LEN(ea);
unsigned int nptrs = DIV_ROUND_UP(amount, sdp->sd_jbsize);
__be64 *dataptrs = GFS2_EA2DATAPTRS(ea);
unsigned int x;
int error;

bh = kcalloc(nptrs, sizeof(struct buffer_head *), GFP_NOFS);
if (!bh)
return -ENOMEM;

error = gfs2_trans_begin(sdp, nptrs + RES_DINODE, 0);
if (error)
goto out;

for (x = 0; x < nptrs; x++) {
error = gfs2_meta_read(ip->i_gl, be64_to_cpu(*dataptrs), 0,
bh + x);
if (error) {
while (x--)
brelse(bh[x]);
goto fail;
}
dataptrs++;
}

for (x = 0; x < nptrs; x++) {
error = gfs2_meta_wait(sdp, bh[x]);
if (error) {
for (; x < nptrs; x++)
brelse(bh[x]);
goto fail;
}
if (gfs2_metatype_check(sdp, bh[x], GFS2_METATYPE_ED)) {
for (; x < nptrs; x++)
brelse(bh[x]);
error = -EIO;
goto fail;
}

gfs2_trans_add_bh(ip->i_gl, bh[x], 1);

memcpy(bh[x]->b_data + sizeof(struct gfs2_meta_header), data,
(sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize);

amount -= sdp->sd_jbsize;
data += sdp->sd_jbsize;

brelse(bh[x]);
}
int ret;

out:
kfree(bh);
return error;
ret = gfs2_trans_begin(sdp, nptrs + RES_DINODE, 0);
if (ret)
return ret;

fail:
ret = gfs2_iter_unstuffed(ip, ea, data, NULL);
gfs2_trans_end(sdp);
kfree(bh);
return error;

return ret;
}

int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
Expand Down

0 comments on commit 1f98169

Please sign in to comment.