mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-28 23:24:50 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes
* git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes: GFS2: Use MAX_LFS_FILESIZE for meta inode size GFS2: Fix gfs2_xattr_acl_chmod() GFS2: Fix locking bug in rename GFS2: Ensure uptodate inode size when using O_APPEND
This commit is contained in:
commit
79ecb043ea
4 changed files with 52 additions and 15 deletions
|
@ -569,6 +569,40 @@ static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gfs2_file_aio_write - Perform a write to a file
|
||||||
|
* @iocb: The io context
|
||||||
|
* @iov: The data to write
|
||||||
|
* @nr_segs: Number of @iov segments
|
||||||
|
* @pos: The file position
|
||||||
|
*
|
||||||
|
* We have to do a lock/unlock here to refresh the inode size for
|
||||||
|
* O_APPEND writes, otherwise we can land up writing at the wrong
|
||||||
|
* offset. There is still a race, but provided the app is using its
|
||||||
|
* own file locking, this will make O_APPEND work as expected.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
|
||||||
|
unsigned long nr_segs, loff_t pos)
|
||||||
|
{
|
||||||
|
struct file *file = iocb->ki_filp;
|
||||||
|
|
||||||
|
if (file->f_flags & O_APPEND) {
|
||||||
|
struct dentry *dentry = file->f_dentry;
|
||||||
|
struct gfs2_inode *ip = GFS2_I(dentry->d_inode);
|
||||||
|
struct gfs2_holder gh;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
gfs2_glock_dq_uninit(&gh);
|
||||||
|
}
|
||||||
|
|
||||||
|
return generic_file_aio_write(iocb, iov, nr_segs, pos);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_GFS2_FS_LOCKING_DLM
|
#ifdef CONFIG_GFS2_FS_LOCKING_DLM
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -711,7 +745,7 @@ const struct file_operations gfs2_file_fops = {
|
||||||
.read = do_sync_read,
|
.read = do_sync_read,
|
||||||
.aio_read = generic_file_aio_read,
|
.aio_read = generic_file_aio_read,
|
||||||
.write = do_sync_write,
|
.write = do_sync_write,
|
||||||
.aio_write = generic_file_aio_write,
|
.aio_write = gfs2_file_aio_write,
|
||||||
.unlocked_ioctl = gfs2_ioctl,
|
.unlocked_ioctl = gfs2_ioctl,
|
||||||
.mmap = gfs2_mmap,
|
.mmap = gfs2_mmap,
|
||||||
.open = gfs2_open,
|
.open = gfs2_open,
|
||||||
|
@ -741,7 +775,7 @@ const struct file_operations gfs2_file_fops_nolock = {
|
||||||
.read = do_sync_read,
|
.read = do_sync_read,
|
||||||
.aio_read = generic_file_aio_read,
|
.aio_read = generic_file_aio_read,
|
||||||
.write = do_sync_write,
|
.write = do_sync_write,
|
||||||
.aio_write = generic_file_aio_write,
|
.aio_write = gfs2_file_aio_write,
|
||||||
.unlocked_ioctl = gfs2_ioctl,
|
.unlocked_ioctl = gfs2_ioctl,
|
||||||
.mmap = gfs2_mmap,
|
.mmap = gfs2_mmap,
|
||||||
.open = gfs2_open,
|
.open = gfs2_open,
|
||||||
|
|
|
@ -121,7 +121,7 @@ struct inode *gfs2_aspace_get(struct gfs2_sbd *sdp)
|
||||||
if (aspace) {
|
if (aspace) {
|
||||||
mapping_set_gfp_mask(aspace->i_mapping, GFP_NOFS);
|
mapping_set_gfp_mask(aspace->i_mapping, GFP_NOFS);
|
||||||
aspace->i_mapping->a_ops = &aspace_aops;
|
aspace->i_mapping->a_ops = &aspace_aops;
|
||||||
aspace->i_size = ~0ULL;
|
aspace->i_size = MAX_LFS_FILESIZE;
|
||||||
ip = GFS2_I(aspace);
|
ip = GFS2_I(aspace);
|
||||||
clear_bit(GIF_USER, &ip->i_flags);
|
clear_bit(GIF_USER, &ip->i_flags);
|
||||||
insert_inode_hash(aspace);
|
insert_inode_hash(aspace);
|
||||||
|
|
|
@ -748,7 +748,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
||||||
struct gfs2_rgrpd *nrgd;
|
struct gfs2_rgrpd *nrgd;
|
||||||
unsigned int num_gh;
|
unsigned int num_gh;
|
||||||
int dir_rename = 0;
|
int dir_rename = 0;
|
||||||
int alloc_required;
|
int alloc_required = 0;
|
||||||
unsigned int x;
|
unsigned int x;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -867,7 +867,9 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry,
|
||||||
goto out_gunlock;
|
goto out_gunlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
alloc_required = error = gfs2_diradd_alloc_required(ndir, &ndentry->d_name);
|
if (nip == NULL)
|
||||||
|
alloc_required = gfs2_diradd_alloc_required(ndir, &ndentry->d_name);
|
||||||
|
error = alloc_required;
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
goto out_gunlock;
|
goto out_gunlock;
|
||||||
error = 0;
|
error = 0;
|
||||||
|
|
|
@ -1296,6 +1296,7 @@ static int ea_acl_chmod_unstuffed(struct gfs2_inode *ip,
|
||||||
|
|
||||||
int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
|
int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
|
||||||
{
|
{
|
||||||
|
struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode);
|
||||||
struct gfs2_ea_location el;
|
struct gfs2_ea_location el;
|
||||||
struct buffer_head *dibh;
|
struct buffer_head *dibh;
|
||||||
int error;
|
int error;
|
||||||
|
@ -1305,16 +1306,17 @@ int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
if (GFS2_EA_IS_STUFFED(el.el_ea)) {
|
if (GFS2_EA_IS_STUFFED(el.el_ea)) {
|
||||||
error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0);
|
error = gfs2_trans_begin(sdp, RES_DINODE + RES_EATTR, 0);
|
||||||
if (error)
|
if (error == 0) {
|
||||||
return error;
|
gfs2_trans_add_bh(ip->i_gl, el.el_bh, 1);
|
||||||
|
memcpy(GFS2_EA2DATA(el.el_ea), data,
|
||||||
gfs2_trans_add_bh(ip->i_gl, el.el_bh, 1);
|
GFS2_EA_DATA_LEN(el.el_ea));
|
||||||
memcpy(GFS2_EA2DATA(el.el_ea), data,
|
}
|
||||||
GFS2_EA_DATA_LEN(el.el_ea));
|
} else {
|
||||||
} else
|
|
||||||
error = ea_acl_chmod_unstuffed(ip, el.el_ea, data);
|
error = ea_acl_chmod_unstuffed(ip, el.el_ea, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
brelse(el.el_bh);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
@ -1327,8 +1329,7 @@ int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data)
|
||||||
brelse(dibh);
|
brelse(dibh);
|
||||||
}
|
}
|
||||||
|
|
||||||
gfs2_trans_end(GFS2_SB(&ip->i_inode));
|
gfs2_trans_end(sdp);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue