diff options
Diffstat (limited to 'fs/gfs2')
| -rw-r--r-- | fs/gfs2/file.c | 38 | ||||
| -rw-r--r-- | fs/gfs2/meta_io.c | 2 | ||||
| -rw-r--r-- | fs/gfs2/ops_inode.c | 6 | ||||
| -rw-r--r-- | fs/gfs2/xattr.c | 21 |
4 files changed, 52 insertions, 15 deletions
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 4eb308aa3234..a6abbae8a278 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
| @@ -569,6 +569,40 @@ static int gfs2_fsync(struct file *file, struct dentry *dentry, int datasync) | |||
| 569 | return ret; | 569 | return ret; |
| 570 | } | 570 | } |
| 571 | 571 | ||
| 572 | /** | ||
| 573 | * gfs2_file_aio_write - Perform a write to a file | ||
| 574 | * @iocb: The io context | ||
| 575 | * @iov: The data to write | ||
| 576 | * @nr_segs: Number of @iov segments | ||
| 577 | * @pos: The file position | ||
| 578 | * | ||
| 579 | * We have to do a lock/unlock here to refresh the inode size for | ||
| 580 | * O_APPEND writes, otherwise we can land up writing at the wrong | ||
| 581 | * offset. There is still a race, but provided the app is using its | ||
| 582 | * own file locking, this will make O_APPEND work as expected. | ||
| 583 | * | ||
| 584 | */ | ||
| 585 | |||
| 586 | static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | ||
| 587 | unsigned long nr_segs, loff_t pos) | ||
| 588 | { | ||
| 589 | struct file *file = iocb->ki_filp; | ||
| 590 | |||
| 591 | if (file->f_flags & O_APPEND) { | ||
| 592 | struct dentry *dentry = file->f_dentry; | ||
| 593 | struct gfs2_inode *ip = GFS2_I(dentry->d_inode); | ||
| 594 | struct gfs2_holder gh; | ||
| 595 | int ret; | ||
| 596 | |||
| 597 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh); | ||
| 598 | if (ret) | ||
| 599 | return ret; | ||
| 600 | gfs2_glock_dq_uninit(&gh); | ||
| 601 | } | ||
| 602 | |||
| 603 | return generic_file_aio_write(iocb, iov, nr_segs, pos); | ||
| 604 | } | ||
| 605 | |||
| 572 | #ifdef CONFIG_GFS2_FS_LOCKING_DLM | 606 | #ifdef CONFIG_GFS2_FS_LOCKING_DLM |
| 573 | 607 | ||
| 574 | /** | 608 | /** |
| @@ -711,7 +745,7 @@ const struct file_operations gfs2_file_fops = { | |||
| 711 | .read = do_sync_read, | 745 | .read = do_sync_read, |
| 712 | .aio_read = generic_file_aio_read, | 746 | .aio_read = generic_file_aio_read, |
| 713 | .write = do_sync_write, | 747 | .write = do_sync_write, |
| 714 | .aio_write = generic_file_aio_write, | 748 | .aio_write = gfs2_file_aio_write, |
| 715 | .unlocked_ioctl = gfs2_ioctl, | 749 | .unlocked_ioctl = gfs2_ioctl, |
| 716 | .mmap = gfs2_mmap, | 750 | .mmap = gfs2_mmap, |
| 717 | .open = gfs2_open, | 751 | .open = gfs2_open, |
| @@ -741,7 +775,7 @@ const struct file_operations gfs2_file_fops_nolock = { | |||
| 741 | .read = do_sync_read, | 775 | .read = do_sync_read, |
| 742 | .aio_read = generic_file_aio_read, | 776 | .aio_read = generic_file_aio_read, |
| 743 | .write = do_sync_write, | 777 | .write = do_sync_write, |
| 744 | .aio_write = generic_file_aio_write, | 778 | .aio_write = gfs2_file_aio_write, |
| 745 | .unlocked_ioctl = gfs2_ioctl, | 779 | .unlocked_ioctl = gfs2_ioctl, |
| 746 | .mmap = gfs2_mmap, | 780 | .mmap = gfs2_mmap, |
| 747 | .open = gfs2_open, | 781 | .open = gfs2_open, |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index cb8d7a93d5ec..6f68a5f18eb8 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
| @@ -121,7 +121,7 @@ struct inode *gfs2_aspace_get(struct gfs2_sbd *sdp) | |||
| 121 | if (aspace) { | 121 | if (aspace) { |
| 122 | mapping_set_gfp_mask(aspace->i_mapping, GFP_NOFS); | 122 | mapping_set_gfp_mask(aspace->i_mapping, GFP_NOFS); |
| 123 | aspace->i_mapping->a_ops = &aspace_aops; | 123 | aspace->i_mapping->a_ops = &aspace_aops; |
| 124 | aspace->i_size = ~0ULL; | 124 | aspace->i_size = MAX_LFS_FILESIZE; |
| 125 | ip = GFS2_I(aspace); | 125 | ip = GFS2_I(aspace); |
| 126 | clear_bit(GIF_USER, &ip->i_flags); | 126 | clear_bit(GIF_USER, &ip->i_flags); |
| 127 | insert_inode_hash(aspace); | 127 | insert_inode_hash(aspace); |
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c index 247436c10deb..78f73ca1ef3e 100644 --- a/fs/gfs2/ops_inode.c +++ b/fs/gfs2/ops_inode.c | |||
| @@ -748,7 +748,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
| 748 | struct gfs2_rgrpd *nrgd; | 748 | struct gfs2_rgrpd *nrgd; |
| 749 | unsigned int num_gh; | 749 | unsigned int num_gh; |
| 750 | int dir_rename = 0; | 750 | int dir_rename = 0; |
| 751 | int alloc_required; | 751 | int alloc_required = 0; |
| 752 | unsigned int x; | 752 | unsigned int x; |
| 753 | int error; | 753 | int error; |
| 754 | 754 | ||
| @@ -867,7 +867,9 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, | |||
| 867 | goto out_gunlock; | 867 | goto out_gunlock; |
| 868 | } | 868 | } |
| 869 | 869 | ||
| 870 | alloc_required = error = gfs2_diradd_alloc_required(ndir, &ndentry->d_name); | 870 | if (nip == NULL) |
| 871 | alloc_required = gfs2_diradd_alloc_required(ndir, &ndentry->d_name); | ||
| 872 | error = alloc_required; | ||
| 871 | if (error < 0) | 873 | if (error < 0) |
| 872 | goto out_gunlock; | 874 | goto out_gunlock; |
| 873 | error = 0; | 875 | error = 0; |
diff --git a/fs/gfs2/xattr.c b/fs/gfs2/xattr.c index 8a04108e0c22..c2ebdf2c01d4 100644 --- a/fs/gfs2/xattr.c +++ b/fs/gfs2/xattr.c | |||
| @@ -1296,6 +1296,7 @@ fail: | |||
| 1296 | 1296 | ||
| 1297 | int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) | 1297 | int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) |
| 1298 | { | 1298 | { |
| 1299 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
| 1299 | struct gfs2_ea_location el; | 1300 | struct gfs2_ea_location el; |
| 1300 | struct buffer_head *dibh; | 1301 | struct buffer_head *dibh; |
| 1301 | int error; | 1302 | int error; |
| @@ -1305,16 +1306,17 @@ int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) | |||
| 1305 | return error; | 1306 | return error; |
| 1306 | 1307 | ||
| 1307 | if (GFS2_EA_IS_STUFFED(el.el_ea)) { | 1308 | if (GFS2_EA_IS_STUFFED(el.el_ea)) { |
| 1308 | error = gfs2_trans_begin(GFS2_SB(&ip->i_inode), RES_DINODE + RES_EATTR, 0); | 1309 | error = gfs2_trans_begin(sdp, RES_DINODE + RES_EATTR, 0); |
| 1309 | if (error) | 1310 | if (error == 0) { |
| 1310 | return error; | 1311 | gfs2_trans_add_bh(ip->i_gl, el.el_bh, 1); |
| 1311 | 1312 | memcpy(GFS2_EA2DATA(el.el_ea), data, | |
| 1312 | gfs2_trans_add_bh(ip->i_gl, el.el_bh, 1); | 1313 | GFS2_EA_DATA_LEN(el.el_ea)); |
| 1313 | memcpy(GFS2_EA2DATA(el.el_ea), data, | 1314 | } |
| 1314 | GFS2_EA_DATA_LEN(el.el_ea)); | 1315 | } else { |
| 1315 | } else | ||
| 1316 | error = ea_acl_chmod_unstuffed(ip, el.el_ea, data); | 1316 | error = ea_acl_chmod_unstuffed(ip, el.el_ea, data); |
| 1317 | } | ||
| 1317 | 1318 | ||
| 1319 | brelse(el.el_bh); | ||
| 1318 | if (error) | 1320 | if (error) |
| 1319 | return error; | 1321 | return error; |
| 1320 | 1322 | ||
| @@ -1327,8 +1329,7 @@ int gfs2_xattr_acl_chmod(struct gfs2_inode *ip, struct iattr *attr, char *data) | |||
| 1327 | brelse(dibh); | 1329 | brelse(dibh); |
| 1328 | } | 1330 | } |
| 1329 | 1331 | ||
| 1330 | gfs2_trans_end(GFS2_SB(&ip->i_inode)); | 1332 | gfs2_trans_end(sdp); |
| 1331 | |||
| 1332 | return error; | 1333 | return error; |
| 1333 | } | 1334 | } |
| 1334 | 1335 | ||
