diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/btrfs/qgroup.c | 8 | ||||
| -rw-r--r-- | fs/cifs/file.c | 2 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.h | 4 | ||||
| -rw-r--r-- | fs/ecryptfs/file.c | 10 | ||||
| -rw-r--r-- | fs/ecryptfs/inode.c | 5 | ||||
| -rw-r--r-- | fs/ecryptfs/main.c | 1 | ||||
| -rw-r--r-- | fs/ext3/inode.c | 17 | ||||
| -rw-r--r-- | fs/fuse/control.c | 4 | ||||
| -rw-r--r-- | fs/fuse/cuse.c | 4 | ||||
| -rw-r--r-- | fs/fuse/dev.c | 1 | ||||
| -rw-r--r-- | fs/fuse/inode.c | 12 | ||||
| -rw-r--r-- | fs/gfs2/file.c | 31 | ||||
| -rw-r--r-- | fs/gfs2/inode.c | 8 | ||||
| -rw-r--r-- | fs/gfs2/rgrp.c | 66 | ||||
| -rw-r--r-- | fs/nfs/file.c | 4 | ||||
| -rw-r--r-- | fs/nfs/inode.c | 2 | ||||
| -rw-r--r-- | fs/nfs/nfs3proc.c | 2 | ||||
| -rw-r--r-- | fs/nfs/nfs4file.c | 4 | ||||
| -rw-r--r-- | fs/nfs/nfs4proc.c | 55 | ||||
| -rw-r--r-- | fs/nfs/nfs4xdr.c | 17 | ||||
| -rw-r--r-- | fs/nfs/super.c | 2 | ||||
| -rw-r--r-- | fs/stat.c | 2 | ||||
| -rw-r--r-- | fs/udf/file.c | 35 |
23 files changed, 177 insertions, 119 deletions
diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c index 38b42e7bc91d..b65015581744 100644 --- a/fs/btrfs/qgroup.c +++ b/fs/btrfs/qgroup.c | |||
| @@ -1371,10 +1371,8 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, | |||
| 1371 | 1371 | ||
| 1372 | if (srcid) { | 1372 | if (srcid) { |
| 1373 | srcgroup = find_qgroup_rb(fs_info, srcid); | 1373 | srcgroup = find_qgroup_rb(fs_info, srcid); |
| 1374 | if (!srcgroup) { | 1374 | if (!srcgroup) |
| 1375 | ret = -EINVAL; | ||
| 1376 | goto unlock; | 1375 | goto unlock; |
| 1377 | } | ||
| 1378 | dstgroup->rfer = srcgroup->rfer - level_size; | 1376 | dstgroup->rfer = srcgroup->rfer - level_size; |
| 1379 | dstgroup->rfer_cmpr = srcgroup->rfer_cmpr - level_size; | 1377 | dstgroup->rfer_cmpr = srcgroup->rfer_cmpr - level_size; |
| 1380 | srcgroup->excl = level_size; | 1378 | srcgroup->excl = level_size; |
| @@ -1383,10 +1381,8 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, | |||
| 1383 | qgroup_dirty(fs_info, srcgroup); | 1381 | qgroup_dirty(fs_info, srcgroup); |
| 1384 | } | 1382 | } |
| 1385 | 1383 | ||
| 1386 | if (!inherit) { | 1384 | if (!inherit) |
| 1387 | ret = -EINVAL; | ||
| 1388 | goto unlock; | 1385 | goto unlock; |
| 1389 | } | ||
| 1390 | 1386 | ||
| 1391 | i_qgroups = (u64 *)(inherit + 1); | 1387 | i_qgroups = (u64 *)(inherit + 1); |
| 1392 | for (i = 0; i < inherit->num_qgroups; ++i) { | 1388 | for (i = 0; i < inherit->num_qgroups; ++i) { |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 9154192b0683..71e9ad9f5961 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -917,7 +917,7 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
| 917 | if (!buf) { | 917 | if (!buf) { |
| 918 | mutex_unlock(&cinode->lock_mutex); | 918 | mutex_unlock(&cinode->lock_mutex); |
| 919 | free_xid(xid); | 919 | free_xid(xid); |
| 920 | return rc; | 920 | return -ENOMEM; |
| 921 | } | 921 | } |
| 922 | 922 | ||
| 923 | for (i = 0; i < 2; i++) { | 923 | for (i = 0; i < 2; i++) { |
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index c5fbfac5d576..15dc8eea8273 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
| @@ -96,7 +96,7 @@ | |||
| 96 | * | 96 | * |
| 97 | */ | 97 | */ |
| 98 | 98 | ||
| 99 | #define SMB2_HEADER_STRUCTURE_SIZE __constant_le16_to_cpu(64) | 99 | #define SMB2_HEADER_STRUCTURE_SIZE __constant_cpu_to_le16(64) |
| 100 | 100 | ||
| 101 | struct smb2_hdr { | 101 | struct smb2_hdr { |
| 102 | __be32 smb2_buf_length; /* big endian on wire */ | 102 | __be32 smb2_buf_length; /* big endian on wire */ |
| @@ -140,7 +140,7 @@ struct smb2_pdu { | |||
| 140 | * | 140 | * |
| 141 | */ | 141 | */ |
| 142 | 142 | ||
| 143 | #define SMB2_ERROR_STRUCTURE_SIZE2 __constant_le16_to_cpu(9) | 143 | #define SMB2_ERROR_STRUCTURE_SIZE2 __constant_cpu_to_le16(9) |
| 144 | 144 | ||
| 145 | struct smb2_err_rsp { | 145 | struct smb2_err_rsp { |
| 146 | struct smb2_hdr hdr; | 146 | struct smb2_hdr hdr; |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 44ce5c6a541d..d45ba4568128 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
| @@ -275,8 +275,14 @@ out: | |||
| 275 | 275 | ||
| 276 | static int ecryptfs_flush(struct file *file, fl_owner_t td) | 276 | static int ecryptfs_flush(struct file *file, fl_owner_t td) |
| 277 | { | 277 | { |
| 278 | return file->f_mode & FMODE_WRITE | 278 | struct file *lower_file = ecryptfs_file_to_lower(file); |
| 279 | ? filemap_write_and_wait(file->f_mapping) : 0; | 279 | |
| 280 | if (lower_file->f_op && lower_file->f_op->flush) { | ||
| 281 | filemap_write_and_wait(file->f_mapping); | ||
| 282 | return lower_file->f_op->flush(lower_file, td); | ||
| 283 | } | ||
| 284 | |||
| 285 | return 0; | ||
| 280 | } | 286 | } |
| 281 | 287 | ||
| 282 | static int ecryptfs_release(struct inode *inode, struct file *file) | 288 | static int ecryptfs_release(struct inode *inode, struct file *file) |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 534b129ea676..cc7709e7c508 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
| @@ -619,6 +619,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 619 | struct dentry *lower_old_dir_dentry; | 619 | struct dentry *lower_old_dir_dentry; |
| 620 | struct dentry *lower_new_dir_dentry; | 620 | struct dentry *lower_new_dir_dentry; |
| 621 | struct dentry *trap = NULL; | 621 | struct dentry *trap = NULL; |
| 622 | struct inode *target_inode; | ||
| 622 | 623 | ||
| 623 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); | 624 | lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); |
| 624 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); | 625 | lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); |
| @@ -626,6 +627,7 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 626 | dget(lower_new_dentry); | 627 | dget(lower_new_dentry); |
| 627 | lower_old_dir_dentry = dget_parent(lower_old_dentry); | 628 | lower_old_dir_dentry = dget_parent(lower_old_dentry); |
| 628 | lower_new_dir_dentry = dget_parent(lower_new_dentry); | 629 | lower_new_dir_dentry = dget_parent(lower_new_dentry); |
| 630 | target_inode = new_dentry->d_inode; | ||
| 629 | trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); | 631 | trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); |
| 630 | /* source should not be ancestor of target */ | 632 | /* source should not be ancestor of target */ |
| 631 | if (trap == lower_old_dentry) { | 633 | if (trap == lower_old_dentry) { |
| @@ -641,6 +643,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 641 | lower_new_dir_dentry->d_inode, lower_new_dentry); | 643 | lower_new_dir_dentry->d_inode, lower_new_dentry); |
| 642 | if (rc) | 644 | if (rc) |
| 643 | goto out_lock; | 645 | goto out_lock; |
| 646 | if (target_inode) | ||
| 647 | fsstack_copy_attr_all(target_inode, | ||
| 648 | ecryptfs_inode_to_lower(target_inode)); | ||
| 644 | fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode); | 649 | fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode); |
| 645 | if (new_dir != old_dir) | 650 | if (new_dir != old_dir) |
| 646 | fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); | 651 | fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode); |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 2768138eefee..9b627c15010a 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
| @@ -162,6 +162,7 @@ void ecryptfs_put_lower_file(struct inode *inode) | |||
| 162 | inode_info = ecryptfs_inode_to_private(inode); | 162 | inode_info = ecryptfs_inode_to_private(inode); |
| 163 | if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count, | 163 | if (atomic_dec_and_mutex_lock(&inode_info->lower_file_count, |
| 164 | &inode_info->lower_file_mutex)) { | 164 | &inode_info->lower_file_mutex)) { |
| 165 | filemap_write_and_wait(inode->i_mapping); | ||
| 165 | fput(inode_info->lower_file); | 166 | fput(inode_info->lower_file); |
| 166 | inode_info->lower_file = NULL; | 167 | inode_info->lower_file = NULL; |
| 167 | mutex_unlock(&inode_info->lower_file_mutex); | 168 | mutex_unlock(&inode_info->lower_file_mutex); |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index a07597307fd1..ff574b4e345e 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
| @@ -3072,6 +3072,8 @@ static int ext3_do_update_inode(handle_t *handle, | |||
| 3072 | struct ext3_inode_info *ei = EXT3_I(inode); | 3072 | struct ext3_inode_info *ei = EXT3_I(inode); |
| 3073 | struct buffer_head *bh = iloc->bh; | 3073 | struct buffer_head *bh = iloc->bh; |
| 3074 | int err = 0, rc, block; | 3074 | int err = 0, rc, block; |
| 3075 | int need_datasync = 0; | ||
| 3076 | __le32 disksize; | ||
| 3075 | uid_t i_uid; | 3077 | uid_t i_uid; |
| 3076 | gid_t i_gid; | 3078 | gid_t i_gid; |
| 3077 | 3079 | ||
| @@ -3113,7 +3115,11 @@ again: | |||
| 3113 | raw_inode->i_gid_high = 0; | 3115 | raw_inode->i_gid_high = 0; |
| 3114 | } | 3116 | } |
| 3115 | raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); | 3117 | raw_inode->i_links_count = cpu_to_le16(inode->i_nlink); |
| 3116 | raw_inode->i_size = cpu_to_le32(ei->i_disksize); | 3118 | disksize = cpu_to_le32(ei->i_disksize); |
| 3119 | if (disksize != raw_inode->i_size) { | ||
| 3120 | need_datasync = 1; | ||
| 3121 | raw_inode->i_size = disksize; | ||
| 3122 | } | ||
| 3117 | raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); | 3123 | raw_inode->i_atime = cpu_to_le32(inode->i_atime.tv_sec); |
| 3118 | raw_inode->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec); | 3124 | raw_inode->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec); |
| 3119 | raw_inode->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec); | 3125 | raw_inode->i_mtime = cpu_to_le32(inode->i_mtime.tv_sec); |
| @@ -3129,8 +3135,11 @@ again: | |||
| 3129 | if (!S_ISREG(inode->i_mode)) { | 3135 | if (!S_ISREG(inode->i_mode)) { |
| 3130 | raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl); | 3136 | raw_inode->i_dir_acl = cpu_to_le32(ei->i_dir_acl); |
| 3131 | } else { | 3137 | } else { |
| 3132 | raw_inode->i_size_high = | 3138 | disksize = cpu_to_le32(ei->i_disksize >> 32); |
| 3133 | cpu_to_le32(ei->i_disksize >> 32); | 3139 | if (disksize != raw_inode->i_size_high) { |
| 3140 | raw_inode->i_size_high = disksize; | ||
| 3141 | need_datasync = 1; | ||
| 3142 | } | ||
| 3134 | if (ei->i_disksize > 0x7fffffffULL) { | 3143 | if (ei->i_disksize > 0x7fffffffULL) { |
| 3135 | struct super_block *sb = inode->i_sb; | 3144 | struct super_block *sb = inode->i_sb; |
| 3136 | if (!EXT3_HAS_RO_COMPAT_FEATURE(sb, | 3145 | if (!EXT3_HAS_RO_COMPAT_FEATURE(sb, |
| @@ -3183,6 +3192,8 @@ again: | |||
| 3183 | ext3_clear_inode_state(inode, EXT3_STATE_NEW); | 3192 | ext3_clear_inode_state(inode, EXT3_STATE_NEW); |
| 3184 | 3193 | ||
| 3185 | atomic_set(&ei->i_sync_tid, handle->h_transaction->t_tid); | 3194 | atomic_set(&ei->i_sync_tid, handle->h_transaction->t_tid); |
| 3195 | if (need_datasync) | ||
| 3196 | atomic_set(&ei->i_datasync_tid, handle->h_transaction->t_tid); | ||
| 3186 | out_brelse: | 3197 | out_brelse: |
| 3187 | brelse (bh); | 3198 | brelse (bh); |
| 3188 | ext3_std_error(inode->i_sb, err); | 3199 | ext3_std_error(inode->i_sb, err); |
diff --git a/fs/fuse/control.c b/fs/fuse/control.c index 03ff5b1eba93..75a20c092dd4 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c | |||
| @@ -117,7 +117,7 @@ static ssize_t fuse_conn_max_background_write(struct file *file, | |||
| 117 | const char __user *buf, | 117 | const char __user *buf, |
| 118 | size_t count, loff_t *ppos) | 118 | size_t count, loff_t *ppos) |
| 119 | { | 119 | { |
| 120 | unsigned val; | 120 | unsigned uninitialized_var(val); |
| 121 | ssize_t ret; | 121 | ssize_t ret; |
| 122 | 122 | ||
| 123 | ret = fuse_conn_limit_write(file, buf, count, ppos, &val, | 123 | ret = fuse_conn_limit_write(file, buf, count, ppos, &val, |
| @@ -154,7 +154,7 @@ static ssize_t fuse_conn_congestion_threshold_write(struct file *file, | |||
| 154 | const char __user *buf, | 154 | const char __user *buf, |
| 155 | size_t count, loff_t *ppos) | 155 | size_t count, loff_t *ppos) |
| 156 | { | 156 | { |
| 157 | unsigned val; | 157 | unsigned uninitialized_var(val); |
| 158 | ssize_t ret; | 158 | ssize_t ret; |
| 159 | 159 | ||
| 160 | ret = fuse_conn_limit_write(file, buf, count, ppos, &val, | 160 | ret = fuse_conn_limit_write(file, buf, count, ppos, &val, |
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index 3426521f3205..ee8d55042298 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c | |||
| @@ -396,7 +396,7 @@ err_device: | |||
| 396 | err_region: | 396 | err_region: |
| 397 | unregister_chrdev_region(devt, 1); | 397 | unregister_chrdev_region(devt, 1); |
| 398 | err: | 398 | err: |
| 399 | fc->conn_error = 1; | 399 | fuse_conn_kill(fc); |
| 400 | goto out; | 400 | goto out; |
| 401 | } | 401 | } |
| 402 | 402 | ||
| @@ -532,8 +532,6 @@ static int cuse_channel_release(struct inode *inode, struct file *file) | |||
| 532 | cdev_del(cc->cdev); | 532 | cdev_del(cc->cdev); |
| 533 | } | 533 | } |
| 534 | 534 | ||
| 535 | /* kill connection and shutdown channel */ | ||
| 536 | fuse_conn_kill(&cc->fc); | ||
| 537 | rc = fuse_dev_release(inode, file); /* puts the base reference */ | 535 | rc = fuse_dev_release(inode, file); /* puts the base reference */ |
| 538 | 536 | ||
| 539 | return rc; | 537 | return rc; |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 7df2b5e8fbe1..f4246cfc8d87 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
| @@ -1576,6 +1576,7 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, | |||
| 1576 | req->pages[req->num_pages] = page; | 1576 | req->pages[req->num_pages] = page; |
| 1577 | req->num_pages++; | 1577 | req->num_pages++; |
| 1578 | 1578 | ||
| 1579 | offset = 0; | ||
| 1579 | num -= this_num; | 1580 | num -= this_num; |
| 1580 | total_len += this_num; | 1581 | total_len += this_num; |
| 1581 | index++; | 1582 | index++; |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index ce0a2838ccd0..fca222dabe3c 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
| @@ -367,11 +367,6 @@ void fuse_conn_kill(struct fuse_conn *fc) | |||
| 367 | wake_up_all(&fc->waitq); | 367 | wake_up_all(&fc->waitq); |
| 368 | wake_up_all(&fc->blocked_waitq); | 368 | wake_up_all(&fc->blocked_waitq); |
| 369 | wake_up_all(&fc->reserved_req_waitq); | 369 | wake_up_all(&fc->reserved_req_waitq); |
| 370 | mutex_lock(&fuse_mutex); | ||
| 371 | list_del(&fc->entry); | ||
| 372 | fuse_ctl_remove_conn(fc); | ||
| 373 | mutex_unlock(&fuse_mutex); | ||
| 374 | fuse_bdi_destroy(fc); | ||
| 375 | } | 370 | } |
| 376 | EXPORT_SYMBOL_GPL(fuse_conn_kill); | 371 | EXPORT_SYMBOL_GPL(fuse_conn_kill); |
| 377 | 372 | ||
| @@ -380,7 +375,14 @@ static void fuse_put_super(struct super_block *sb) | |||
| 380 | struct fuse_conn *fc = get_fuse_conn_super(sb); | 375 | struct fuse_conn *fc = get_fuse_conn_super(sb); |
| 381 | 376 | ||
| 382 | fuse_send_destroy(fc); | 377 | fuse_send_destroy(fc); |
| 378 | |||
| 383 | fuse_conn_kill(fc); | 379 | fuse_conn_kill(fc); |
| 380 | mutex_lock(&fuse_mutex); | ||
| 381 | list_del(&fc->entry); | ||
| 382 | fuse_ctl_remove_conn(fc); | ||
| 383 | mutex_unlock(&fuse_mutex); | ||
| 384 | fuse_bdi_destroy(fc); | ||
| 385 | |||
| 384 | fuse_conn_put(fc); | 386 | fuse_conn_put(fc); |
| 385 | } | 387 | } |
| 386 | 388 | ||
diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index d1d791ef38de..382000ffac1f 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c | |||
| @@ -323,6 +323,29 @@ static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
| 323 | } | 323 | } |
| 324 | 324 | ||
| 325 | /** | 325 | /** |
| 326 | * gfs2_size_hint - Give a hint to the size of a write request | ||
| 327 | * @file: The struct file | ||
| 328 | * @offset: The file offset of the write | ||
| 329 | * @size: The length of the write | ||
| 330 | * | ||
| 331 | * When we are about to do a write, this function records the total | ||
| 332 | * write size in order to provide a suitable hint to the lower layers | ||
| 333 | * about how many blocks will be required. | ||
| 334 | * | ||
| 335 | */ | ||
| 336 | |||
| 337 | static void gfs2_size_hint(struct file *filep, loff_t offset, size_t size) | ||
| 338 | { | ||
| 339 | struct inode *inode = filep->f_dentry->d_inode; | ||
| 340 | struct gfs2_sbd *sdp = GFS2_SB(inode); | ||
| 341 | struct gfs2_inode *ip = GFS2_I(inode); | ||
| 342 | size_t blks = (size + sdp->sd_sb.sb_bsize - 1) >> sdp->sd_sb.sb_bsize_shift; | ||
| 343 | int hint = min_t(size_t, INT_MAX, blks); | ||
| 344 | |||
| 345 | atomic_set(&ip->i_res->rs_sizehint, hint); | ||
| 346 | } | ||
| 347 | |||
| 348 | /** | ||
| 326 | * gfs2_allocate_page_backing - Use bmap to allocate blocks | 349 | * gfs2_allocate_page_backing - Use bmap to allocate blocks |
| 327 | * @page: The (locked) page to allocate backing for | 350 | * @page: The (locked) page to allocate backing for |
| 328 | * | 351 | * |
| @@ -382,8 +405,7 @@ static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) | |||
| 382 | if (ret) | 405 | if (ret) |
| 383 | return ret; | 406 | return ret; |
| 384 | 407 | ||
| 385 | atomic_set(&ip->i_res->rs_sizehint, | 408 | gfs2_size_hint(vma->vm_file, pos, PAGE_CACHE_SIZE); |
| 386 | PAGE_CACHE_SIZE >> sdp->sd_sb.sb_bsize_shift); | ||
| 387 | 409 | ||
| 388 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 410 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
| 389 | ret = gfs2_glock_nq(&gh); | 411 | ret = gfs2_glock_nq(&gh); |
| @@ -663,7 +685,8 @@ static ssize_t gfs2_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
| 663 | if (ret) | 685 | if (ret) |
| 664 | return ret; | 686 | return ret; |
| 665 | 687 | ||
| 666 | atomic_set(&ip->i_res->rs_sizehint, writesize >> sdp->sd_sb.sb_bsize_shift); | 688 | gfs2_size_hint(file, pos, writesize); |
| 689 | |||
| 667 | if (file->f_flags & O_APPEND) { | 690 | if (file->f_flags & O_APPEND) { |
| 668 | struct gfs2_holder gh; | 691 | struct gfs2_holder gh; |
| 669 | 692 | ||
| @@ -789,7 +812,7 @@ static long gfs2_fallocate(struct file *file, int mode, loff_t offset, | |||
| 789 | if (unlikely(error)) | 812 | if (unlikely(error)) |
| 790 | goto out_uninit; | 813 | goto out_uninit; |
| 791 | 814 | ||
| 792 | atomic_set(&ip->i_res->rs_sizehint, len >> sdp->sd_sb.sb_bsize_shift); | 815 | gfs2_size_hint(file, offset, len); |
| 793 | 816 | ||
| 794 | while (len > 0) { | 817 | while (len > 0) { |
| 795 | if (len < bytes) | 818 | if (len < bytes) |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 4ce22e547308..753af3d86bbc 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
| @@ -1722,7 +1722,9 @@ static int gfs2_setxattr(struct dentry *dentry, const char *name, | |||
| 1722 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 1722 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
| 1723 | ret = gfs2_glock_nq(&gh); | 1723 | ret = gfs2_glock_nq(&gh); |
| 1724 | if (ret == 0) { | 1724 | if (ret == 0) { |
| 1725 | ret = generic_setxattr(dentry, name, data, size, flags); | 1725 | ret = gfs2_rs_alloc(ip); |
| 1726 | if (ret == 0) | ||
| 1727 | ret = generic_setxattr(dentry, name, data, size, flags); | ||
| 1726 | gfs2_glock_dq(&gh); | 1728 | gfs2_glock_dq(&gh); |
| 1727 | } | 1729 | } |
| 1728 | gfs2_holder_uninit(&gh); | 1730 | gfs2_holder_uninit(&gh); |
| @@ -1757,7 +1759,9 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name) | |||
| 1757 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 1759 | gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
| 1758 | ret = gfs2_glock_nq(&gh); | 1760 | ret = gfs2_glock_nq(&gh); |
| 1759 | if (ret == 0) { | 1761 | if (ret == 0) { |
| 1760 | ret = generic_removexattr(dentry, name); | 1762 | ret = gfs2_rs_alloc(ip); |
| 1763 | if (ret == 0) | ||
| 1764 | ret = generic_removexattr(dentry, name); | ||
| 1761 | gfs2_glock_dq(&gh); | 1765 | gfs2_glock_dq(&gh); |
| 1762 | } | 1766 | } |
| 1763 | gfs2_holder_uninit(&gh); | 1767 | gfs2_holder_uninit(&gh); |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 4d34887a601d..c9ed814eeb6f 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
| @@ -1961,7 +1961,7 @@ static void gfs2_rgrp_error(struct gfs2_rgrpd *rgd) | |||
| 1961 | * @dinode: 1 if this block is a dinode block, otherwise data block | 1961 | * @dinode: 1 if this block is a dinode block, otherwise data block |
| 1962 | * @nblocks: desired extent length | 1962 | * @nblocks: desired extent length |
| 1963 | * | 1963 | * |
| 1964 | * Lay claim to previously allocated block reservation blocks. | 1964 | * Lay claim to previously reserved blocks. |
| 1965 | * Returns: Starting block number of the blocks claimed. | 1965 | * Returns: Starting block number of the blocks claimed. |
| 1966 | * Sets *nblocks to the actual extent length allocated. | 1966 | * Sets *nblocks to the actual extent length allocated. |
| 1967 | */ | 1967 | */ |
| @@ -1970,19 +1970,17 @@ static u64 claim_reserved_blks(struct gfs2_inode *ip, bool dinode, | |||
| 1970 | { | 1970 | { |
| 1971 | struct gfs2_blkreserv *rs = ip->i_res; | 1971 | struct gfs2_blkreserv *rs = ip->i_res; |
| 1972 | struct gfs2_rgrpd *rgd = rs->rs_rgd; | 1972 | struct gfs2_rgrpd *rgd = rs->rs_rgd; |
| 1973 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | ||
| 1974 | struct gfs2_bitmap *bi; | 1973 | struct gfs2_bitmap *bi; |
| 1975 | u64 start_block = gfs2_rs_startblk(rs); | 1974 | u64 start_block = gfs2_rs_startblk(rs); |
| 1976 | const unsigned int elen = *nblocks; | 1975 | const unsigned int elen = *nblocks; |
| 1977 | 1976 | ||
| 1978 | /*BUG_ON(!gfs2_glock_is_locked_by_me(ip->i_gl));*/ | ||
| 1979 | gfs2_assert_withdraw(sdp, rgd); | ||
| 1980 | /*BUG_ON(!gfs2_glock_is_locked_by_me(rgd->rd_gl));*/ | ||
| 1981 | bi = rs->rs_bi; | 1977 | bi = rs->rs_bi; |
| 1982 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | 1978 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); |
| 1983 | 1979 | ||
| 1984 | for (*nblocks = 0; *nblocks < elen && rs->rs_free; (*nblocks)++) { | 1980 | for (*nblocks = 0; *nblocks < elen && rs->rs_free; (*nblocks)++) { |
| 1985 | /* Make sure the bitmap hasn't changed */ | 1981 | if (gfs2_testbit(rgd, bi->bi_bh->b_data + bi->bi_offset, |
| 1982 | bi->bi_len, rs->rs_biblk) != GFS2_BLKST_FREE) | ||
| 1983 | break; | ||
| 1986 | gfs2_setbit(rgd, bi->bi_clone, bi, rs->rs_biblk, | 1984 | gfs2_setbit(rgd, bi->bi_clone, bi, rs->rs_biblk, |
| 1987 | dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); | 1985 | dinode ? GFS2_BLKST_DINODE : GFS2_BLKST_USED); |
| 1988 | rs->rs_biblk++; | 1986 | rs->rs_biblk++; |
| @@ -1991,20 +1989,12 @@ static u64 claim_reserved_blks(struct gfs2_inode *ip, bool dinode, | |||
| 1991 | BUG_ON(!rgd->rd_reserved); | 1989 | BUG_ON(!rgd->rd_reserved); |
| 1992 | rgd->rd_reserved--; | 1990 | rgd->rd_reserved--; |
| 1993 | dinode = false; | 1991 | dinode = false; |
| 1994 | trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM); | ||
| 1995 | } | 1992 | } |
| 1996 | 1993 | ||
| 1997 | if (!rs->rs_free) { | 1994 | trace_gfs2_rs(ip, rs, TRACE_RS_CLAIM); |
| 1998 | struct gfs2_rgrpd *rgd = ip->i_res->rs_rgd; | 1995 | if (!rs->rs_free || *nblocks != elen) |
| 1999 | |||
| 2000 | gfs2_rs_deltree(rs); | 1996 | gfs2_rs_deltree(rs); |
| 2001 | /* -nblocks because we haven't returned to do the math yet. | 1997 | |
| 2002 | I'm doing the math backwards to prevent negative numbers, | ||
| 2003 | but think of it as: | ||
| 2004 | if (unclaimed_blocks(rgd) - *nblocks >= RGRP_RSRV_MINBLKS */ | ||
| 2005 | if (unclaimed_blocks(rgd) >= RGRP_RSRV_MINBLKS + *nblocks) | ||
| 2006 | rg_mblk_search(rgd, ip); | ||
| 2007 | } | ||
| 2008 | return start_block; | 1998 | return start_block; |
| 2009 | } | 1999 | } |
| 2010 | 2000 | ||
| @@ -2037,34 +2027,34 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks, | |||
| 2037 | if (ip->i_res->rs_requested == 0) | 2027 | if (ip->i_res->rs_requested == 0) |
| 2038 | return -ECANCELED; | 2028 | return -ECANCELED; |
| 2039 | 2029 | ||
| 2040 | /* Check if we have a multi-block reservation, and if so, claim the | 2030 | /* If we have a reservation, claim blocks from it. */ |
| 2041 | next free block from it. */ | ||
| 2042 | if (gfs2_rs_active(ip->i_res)) { | 2031 | if (gfs2_rs_active(ip->i_res)) { |
| 2043 | BUG_ON(!ip->i_res->rs_free); | 2032 | BUG_ON(!ip->i_res->rs_free); |
| 2044 | rgd = ip->i_res->rs_rgd; | 2033 | rgd = ip->i_res->rs_rgd; |
| 2045 | block = claim_reserved_blks(ip, dinode, nblocks); | 2034 | block = claim_reserved_blks(ip, dinode, nblocks); |
| 2046 | } else { | 2035 | if (*nblocks) |
| 2047 | rgd = ip->i_rgd; | 2036 | goto found_blocks; |
| 2037 | } | ||
| 2048 | 2038 | ||
| 2049 | if (!dinode && rgrp_contains_block(rgd, ip->i_goal)) | 2039 | rgd = ip->i_rgd; |
| 2050 | goal = ip->i_goal - rgd->rd_data0; | ||
| 2051 | else | ||
| 2052 | goal = rgd->rd_last_alloc; | ||
| 2053 | |||
| 2054 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi); | ||
| 2055 | |||
| 2056 | /* Since all blocks are reserved in advance, this shouldn't | ||
| 2057 | happen */ | ||
| 2058 | if (blk == BFITNOENT) { | ||
| 2059 | printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", | ||
| 2060 | *nblocks); | ||
| 2061 | printk(KERN_WARNING "FULL=%d\n", | ||
| 2062 | test_bit(GBF_FULL, &rgd->rd_bits->bi_flags)); | ||
| 2063 | goto rgrp_error; | ||
| 2064 | } | ||
| 2065 | 2040 | ||
| 2066 | block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks); | 2041 | if (!dinode && rgrp_contains_block(rgd, ip->i_goal)) |
| 2042 | goal = ip->i_goal - rgd->rd_data0; | ||
| 2043 | else | ||
| 2044 | goal = rgd->rd_last_alloc; | ||
| 2045 | |||
| 2046 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, &bi); | ||
| 2047 | |||
| 2048 | /* Since all blocks are reserved in advance, this shouldn't happen */ | ||
| 2049 | if (blk == BFITNOENT) { | ||
| 2050 | printk(KERN_WARNING "BFITNOENT, nblocks=%u\n", *nblocks); | ||
| 2051 | printk(KERN_WARNING "FULL=%d\n", | ||
| 2052 | test_bit(GBF_FULL, &rgd->rd_bits->bi_flags)); | ||
| 2053 | goto rgrp_error; | ||
| 2067 | } | 2054 | } |
| 2055 | |||
| 2056 | block = gfs2_alloc_extent(rgd, bi, blk, dinode, nblocks); | ||
| 2057 | found_blocks: | ||
| 2068 | ndata = *nblocks; | 2058 | ndata = *nblocks; |
| 2069 | if (dinode) | 2059 | if (dinode) |
| 2070 | ndata--; | 2060 | ndata--; |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 75d6d0a3d32e..6a7fcab7ecb3 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
| @@ -287,10 +287,12 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
| 287 | struct inode *inode = file->f_path.dentry->d_inode; | 287 | struct inode *inode = file->f_path.dentry->d_inode; |
| 288 | 288 | ||
| 289 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); | 289 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); |
| 290 | if (ret != 0) | ||
| 291 | goto out; | ||
| 290 | mutex_lock(&inode->i_mutex); | 292 | mutex_lock(&inode->i_mutex); |
| 291 | ret = nfs_file_fsync_commit(file, start, end, datasync); | 293 | ret = nfs_file_fsync_commit(file, start, end, datasync); |
| 292 | mutex_unlock(&inode->i_mutex); | 294 | mutex_unlock(&inode->i_mutex); |
| 293 | 295 | out: | |
| 294 | return ret; | 296 | return ret; |
| 295 | } | 297 | } |
| 296 | 298 | ||
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index c6e895f0fbf3..9b47610338f5 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
| @@ -154,7 +154,7 @@ static void nfs_zap_caches_locked(struct inode *inode) | |||
| 154 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); | 154 | nfsi->attrtimeo = NFS_MINATTRTIMEO(inode); |
| 155 | nfsi->attrtimeo_timestamp = jiffies; | 155 | nfsi->attrtimeo_timestamp = jiffies; |
| 156 | 156 | ||
| 157 | memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); | 157 | memset(NFS_I(inode)->cookieverf, 0, sizeof(NFS_I(inode)->cookieverf)); |
| 158 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) | 158 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) |
| 159 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; | 159 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; |
| 160 | else | 160 | else |
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c index d6b3b5f2d779..69322096c325 100644 --- a/fs/nfs/nfs3proc.c +++ b/fs/nfs/nfs3proc.c | |||
| @@ -643,7 +643,7 @@ nfs3_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
| 643 | u64 cookie, struct page **pages, unsigned int count, int plus) | 643 | u64 cookie, struct page **pages, unsigned int count, int plus) |
| 644 | { | 644 | { |
| 645 | struct inode *dir = dentry->d_inode; | 645 | struct inode *dir = dentry->d_inode; |
| 646 | __be32 *verf = NFS_COOKIEVERF(dir); | 646 | __be32 *verf = NFS_I(dir)->cookieverf; |
| 647 | struct nfs3_readdirargs arg = { | 647 | struct nfs3_readdirargs arg = { |
| 648 | .fh = NFS_FH(dir), | 648 | .fh = NFS_FH(dir), |
| 649 | .cookie = cookie, | 649 | .cookie = cookie, |
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index acb65e7887f8..eb5eb8eef4d3 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c | |||
| @@ -96,13 +96,15 @@ nfs4_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
| 96 | struct inode *inode = file->f_path.dentry->d_inode; | 96 | struct inode *inode = file->f_path.dentry->d_inode; |
| 97 | 97 | ||
| 98 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); | 98 | ret = filemap_write_and_wait_range(inode->i_mapping, start, end); |
| 99 | if (ret != 0) | ||
| 100 | goto out; | ||
| 99 | mutex_lock(&inode->i_mutex); | 101 | mutex_lock(&inode->i_mutex); |
| 100 | ret = nfs_file_fsync_commit(file, start, end, datasync); | 102 | ret = nfs_file_fsync_commit(file, start, end, datasync); |
| 101 | if (!ret && !datasync) | 103 | if (!ret && !datasync) |
| 102 | /* application has asked for meta-data sync */ | 104 | /* application has asked for meta-data sync */ |
| 103 | ret = pnfs_layoutcommit_inode(inode, true); | 105 | ret = pnfs_layoutcommit_inode(inode, true); |
| 104 | mutex_unlock(&inode->i_mutex); | 106 | mutex_unlock(&inode->i_mutex); |
| 105 | 107 | out: | |
| 106 | return ret; | 108 | return ret; |
| 107 | } | 109 | } |
| 108 | 110 | ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 635274140b18..1e50326d00dd 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -3215,11 +3215,11 @@ static int _nfs4_proc_readdir(struct dentry *dentry, struct rpc_cred *cred, | |||
| 3215 | dentry->d_parent->d_name.name, | 3215 | dentry->d_parent->d_name.name, |
| 3216 | dentry->d_name.name, | 3216 | dentry->d_name.name, |
| 3217 | (unsigned long long)cookie); | 3217 | (unsigned long long)cookie); |
| 3218 | nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); | 3218 | nfs4_setup_readdir(cookie, NFS_I(dir)->cookieverf, dentry, &args); |
| 3219 | res.pgbase = args.pgbase; | 3219 | res.pgbase = args.pgbase; |
| 3220 | status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0); | 3220 | status = nfs4_call_sync(NFS_SERVER(dir)->client, NFS_SERVER(dir), &msg, &args.seq_args, &res.seq_res, 0); |
| 3221 | if (status >= 0) { | 3221 | if (status >= 0) { |
| 3222 | memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); | 3222 | memcpy(NFS_I(dir)->cookieverf, res.verifier.data, NFS4_VERIFIER_SIZE); |
| 3223 | status += args.pgbase; | 3223 | status += args.pgbase; |
| 3224 | } | 3224 | } |
| 3225 | 3225 | ||
| @@ -3653,11 +3653,11 @@ static inline int nfs4_server_supports_acls(struct nfs_server *server) | |||
| 3653 | && (server->acl_bitmask & ACL4_SUPPORT_DENY_ACL); | 3653 | && (server->acl_bitmask & ACL4_SUPPORT_DENY_ACL); |
| 3654 | } | 3654 | } |
| 3655 | 3655 | ||
| 3656 | /* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_CACHE_SIZE, and that | 3656 | /* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_SIZE, and that |
| 3657 | * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_CACHE_SIZE) bytes on | 3657 | * it's OK to put sizeof(void) * (XATTR_SIZE_MAX/PAGE_SIZE) bytes on |
| 3658 | * the stack. | 3658 | * the stack. |
| 3659 | */ | 3659 | */ |
| 3660 | #define NFS4ACL_MAXPAGES (XATTR_SIZE_MAX >> PAGE_CACHE_SHIFT) | 3660 | #define NFS4ACL_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE) |
| 3661 | 3661 | ||
| 3662 | static int buf_to_pages_noslab(const void *buf, size_t buflen, | 3662 | static int buf_to_pages_noslab(const void *buf, size_t buflen, |
| 3663 | struct page **pages, unsigned int *pgbase) | 3663 | struct page **pages, unsigned int *pgbase) |
| @@ -3668,7 +3668,7 @@ static int buf_to_pages_noslab(const void *buf, size_t buflen, | |||
| 3668 | spages = pages; | 3668 | spages = pages; |
| 3669 | 3669 | ||
| 3670 | do { | 3670 | do { |
| 3671 | len = min_t(size_t, PAGE_CACHE_SIZE, buflen); | 3671 | len = min_t(size_t, PAGE_SIZE, buflen); |
| 3672 | newpage = alloc_page(GFP_KERNEL); | 3672 | newpage = alloc_page(GFP_KERNEL); |
| 3673 | 3673 | ||
| 3674 | if (newpage == NULL) | 3674 | if (newpage == NULL) |
| @@ -3739,7 +3739,7 @@ static void nfs4_write_cached_acl(struct inode *inode, struct page **pages, size | |||
| 3739 | struct nfs4_cached_acl *acl; | 3739 | struct nfs4_cached_acl *acl; |
| 3740 | size_t buflen = sizeof(*acl) + acl_len; | 3740 | size_t buflen = sizeof(*acl) + acl_len; |
| 3741 | 3741 | ||
| 3742 | if (pages && buflen <= PAGE_SIZE) { | 3742 | if (buflen <= PAGE_SIZE) { |
| 3743 | acl = kmalloc(buflen, GFP_KERNEL); | 3743 | acl = kmalloc(buflen, GFP_KERNEL); |
| 3744 | if (acl == NULL) | 3744 | if (acl == NULL) |
| 3745 | goto out; | 3745 | goto out; |
| @@ -3782,17 +3782,15 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu | |||
| 3782 | .rpc_argp = &args, | 3782 | .rpc_argp = &args, |
| 3783 | .rpc_resp = &res, | 3783 | .rpc_resp = &res, |
| 3784 | }; | 3784 | }; |
| 3785 | int ret = -ENOMEM, npages, i; | 3785 | unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); |
| 3786 | size_t acl_len = 0; | 3786 | int ret = -ENOMEM, i; |
| 3787 | 3787 | ||
| 3788 | npages = (buflen + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
| 3789 | /* As long as we're doing a round trip to the server anyway, | 3788 | /* As long as we're doing a round trip to the server anyway, |
| 3790 | * let's be prepared for a page of acl data. */ | 3789 | * let's be prepared for a page of acl data. */ |
| 3791 | if (npages == 0) | 3790 | if (npages == 0) |
| 3792 | npages = 1; | 3791 | npages = 1; |
| 3793 | 3792 | if (npages > ARRAY_SIZE(pages)) | |
| 3794 | /* Add an extra page to handle the bitmap returned */ | 3793 | return -ERANGE; |
| 3795 | npages++; | ||
| 3796 | 3794 | ||
| 3797 | for (i = 0; i < npages; i++) { | 3795 | for (i = 0; i < npages; i++) { |
| 3798 | pages[i] = alloc_page(GFP_KERNEL); | 3796 | pages[i] = alloc_page(GFP_KERNEL); |
| @@ -3808,11 +3806,6 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu | |||
| 3808 | args.acl_len = npages * PAGE_SIZE; | 3806 | args.acl_len = npages * PAGE_SIZE; |
| 3809 | args.acl_pgbase = 0; | 3807 | args.acl_pgbase = 0; |
| 3810 | 3808 | ||
| 3811 | /* Let decode_getfacl know not to fail if the ACL data is larger than | ||
| 3812 | * the page we send as a guess */ | ||
| 3813 | if (buf == NULL) | ||
| 3814 | res.acl_flags |= NFS4_ACL_LEN_REQUEST; | ||
| 3815 | |||
| 3816 | dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", | 3809 | dprintk("%s buf %p buflen %zu npages %d args.acl_len %zu\n", |
| 3817 | __func__, buf, buflen, npages, args.acl_len); | 3810 | __func__, buf, buflen, npages, args.acl_len); |
| 3818 | ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), | 3811 | ret = nfs4_call_sync(NFS_SERVER(inode)->client, NFS_SERVER(inode), |
| @@ -3820,20 +3813,19 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu | |||
| 3820 | if (ret) | 3813 | if (ret) |
| 3821 | goto out_free; | 3814 | goto out_free; |
| 3822 | 3815 | ||
| 3823 | acl_len = res.acl_len; | 3816 | /* Handle the case where the passed-in buffer is too short */ |
| 3824 | if (acl_len > args.acl_len) | 3817 | if (res.acl_flags & NFS4_ACL_TRUNC) { |
| 3825 | nfs4_write_cached_acl(inode, NULL, 0, acl_len); | 3818 | /* Did the user only issue a request for the acl length? */ |
| 3826 | else | 3819 | if (buf == NULL) |
| 3827 | nfs4_write_cached_acl(inode, pages, res.acl_data_offset, | 3820 | goto out_ok; |
| 3828 | acl_len); | ||
| 3829 | if (buf) { | ||
| 3830 | ret = -ERANGE; | 3821 | ret = -ERANGE; |
| 3831 | if (acl_len > buflen) | 3822 | goto out_free; |
| 3832 | goto out_free; | ||
| 3833 | _copy_from_pages(buf, pages, res.acl_data_offset, | ||
| 3834 | acl_len); | ||
| 3835 | } | 3823 | } |
| 3836 | ret = acl_len; | 3824 | nfs4_write_cached_acl(inode, pages, res.acl_data_offset, res.acl_len); |
| 3825 | if (buf) | ||
| 3826 | _copy_from_pages(buf, pages, res.acl_data_offset, res.acl_len); | ||
| 3827 | out_ok: | ||
| 3828 | ret = res.acl_len; | ||
| 3837 | out_free: | 3829 | out_free: |
| 3838 | for (i = 0; i < npages; i++) | 3830 | for (i = 0; i < npages; i++) |
| 3839 | if (pages[i]) | 3831 | if (pages[i]) |
| @@ -3891,10 +3883,13 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl | |||
| 3891 | .rpc_argp = &arg, | 3883 | .rpc_argp = &arg, |
| 3892 | .rpc_resp = &res, | 3884 | .rpc_resp = &res, |
| 3893 | }; | 3885 | }; |
| 3886 | unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE); | ||
| 3894 | int ret, i; | 3887 | int ret, i; |
| 3895 | 3888 | ||
| 3896 | if (!nfs4_server_supports_acls(server)) | 3889 | if (!nfs4_server_supports_acls(server)) |
| 3897 | return -EOPNOTSUPP; | 3890 | return -EOPNOTSUPP; |
| 3891 | if (npages > ARRAY_SIZE(pages)) | ||
| 3892 | return -ERANGE; | ||
| 3898 | i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase); | 3893 | i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase); |
| 3899 | if (i < 0) | 3894 | if (i < 0) |
| 3900 | return i; | 3895 | return i; |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 1bfbd67c556d..8dba6bd48557 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
| @@ -5072,18 +5072,14 @@ static int decode_getacl(struct xdr_stream *xdr, struct rpc_rqst *req, | |||
| 5072 | * are stored with the acl data to handle the problem of | 5072 | * are stored with the acl data to handle the problem of |
| 5073 | * variable length bitmaps.*/ | 5073 | * variable length bitmaps.*/ |
| 5074 | res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; | 5074 | res->acl_data_offset = xdr_stream_pos(xdr) - pg_offset; |
| 5075 | |||
| 5076 | /* We ignore &savep and don't do consistency checks on | ||
| 5077 | * the attr length. Let userspace figure it out.... */ | ||
| 5078 | res->acl_len = attrlen; | 5075 | res->acl_len = attrlen; |
| 5079 | if (attrlen > (xdr->nwords << 2)) { | 5076 | |
| 5080 | if (res->acl_flags & NFS4_ACL_LEN_REQUEST) { | 5077 | /* Check for receive buffer overflow */ |
| 5081 | /* getxattr interface called with a NULL buf */ | 5078 | if (res->acl_len > (xdr->nwords << 2) || |
| 5082 | goto out; | 5079 | res->acl_len + res->acl_data_offset > xdr->buf->page_len) { |
| 5083 | } | 5080 | res->acl_flags |= NFS4_ACL_TRUNC; |
| 5084 | dprintk("NFS: acl reply: attrlen %u > page_len %u\n", | 5081 | dprintk("NFS: acl reply: attrlen %u > page_len %u\n", |
| 5085 | attrlen, xdr->nwords << 2); | 5082 | attrlen, xdr->nwords << 2); |
| 5086 | return -EINVAL; | ||
| 5087 | } | 5083 | } |
| 5088 | } else | 5084 | } else |
| 5089 | status = -EOPNOTSUPP; | 5085 | status = -EOPNOTSUPP; |
| @@ -6229,7 +6225,8 @@ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr, | |||
| 6229 | status = decode_open(xdr, res); | 6225 | status = decode_open(xdr, res); |
| 6230 | if (status) | 6226 | if (status) |
| 6231 | goto out; | 6227 | goto out; |
| 6232 | if (decode_getfh(xdr, &res->fh) != 0) | 6228 | status = decode_getfh(xdr, &res->fh); |
| 6229 | if (status) | ||
| 6233 | goto out; | 6230 | goto out; |
| 6234 | decode_getfattr(xdr, res->f_attr, res->server); | 6231 | decode_getfattr(xdr, res->f_attr, res->server); |
| 6235 | out: | 6232 | out: |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 239aff7338eb..b8eda700584b 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
| @@ -1867,6 +1867,7 @@ static int nfs23_validate_mount_data(void *options, | |||
| 1867 | 1867 | ||
| 1868 | memcpy(sap, &data->addr, sizeof(data->addr)); | 1868 | memcpy(sap, &data->addr, sizeof(data->addr)); |
| 1869 | args->nfs_server.addrlen = sizeof(data->addr); | 1869 | args->nfs_server.addrlen = sizeof(data->addr); |
| 1870 | args->nfs_server.port = ntohs(data->addr.sin_port); | ||
| 1870 | if (!nfs_verify_server_address(sap)) | 1871 | if (!nfs_verify_server_address(sap)) |
| 1871 | goto out_no_address; | 1872 | goto out_no_address; |
| 1872 | 1873 | ||
| @@ -2564,6 +2565,7 @@ static int nfs4_validate_mount_data(void *options, | |||
| 2564 | return -EFAULT; | 2565 | return -EFAULT; |
| 2565 | if (!nfs_verify_server_address(sap)) | 2566 | if (!nfs_verify_server_address(sap)) |
| 2566 | goto out_no_address; | 2567 | goto out_no_address; |
| 2568 | args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port); | ||
| 2567 | 2569 | ||
| 2568 | if (data->auth_flavourlen) { | 2570 | if (data->auth_flavourlen) { |
| 2569 | if (data->auth_flavourlen > 1) | 2571 | if (data->auth_flavourlen > 1) |
| @@ -58,7 +58,7 @@ EXPORT_SYMBOL(vfs_getattr); | |||
| 58 | int vfs_fstat(unsigned int fd, struct kstat *stat) | 58 | int vfs_fstat(unsigned int fd, struct kstat *stat) |
| 59 | { | 59 | { |
| 60 | int fput_needed; | 60 | int fput_needed; |
| 61 | struct file *f = fget_light(fd, &fput_needed); | 61 | struct file *f = fget_raw_light(fd, &fput_needed); |
| 62 | int error = -EBADF; | 62 | int error = -EBADF; |
| 63 | 63 | ||
| 64 | if (f) { | 64 | if (f) { |
diff --git a/fs/udf/file.c b/fs/udf/file.c index 7f3f7ba3df6e..d1c6093fd3d3 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
| @@ -39,20 +39,24 @@ | |||
| 39 | #include "udf_i.h" | 39 | #include "udf_i.h" |
| 40 | #include "udf_sb.h" | 40 | #include "udf_sb.h" |
| 41 | 41 | ||
| 42 | static int udf_adinicb_readpage(struct file *file, struct page *page) | 42 | static void __udf_adinicb_readpage(struct page *page) |
| 43 | { | 43 | { |
| 44 | struct inode *inode = page->mapping->host; | 44 | struct inode *inode = page->mapping->host; |
| 45 | char *kaddr; | 45 | char *kaddr; |
| 46 | struct udf_inode_info *iinfo = UDF_I(inode); | 46 | struct udf_inode_info *iinfo = UDF_I(inode); |
| 47 | 47 | ||
| 48 | BUG_ON(!PageLocked(page)); | ||
| 49 | |||
| 50 | kaddr = kmap(page); | 48 | kaddr = kmap(page); |
| 51 | memset(kaddr, 0, PAGE_CACHE_SIZE); | ||
| 52 | memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size); | 49 | memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size); |
| 50 | memset(kaddr + inode->i_size, 0, PAGE_CACHE_SIZE - inode->i_size); | ||
| 53 | flush_dcache_page(page); | 51 | flush_dcache_page(page); |
| 54 | SetPageUptodate(page); | 52 | SetPageUptodate(page); |
| 55 | kunmap(page); | 53 | kunmap(page); |
| 54 | } | ||
| 55 | |||
| 56 | static int udf_adinicb_readpage(struct file *file, struct page *page) | ||
| 57 | { | ||
| 58 | BUG_ON(!PageLocked(page)); | ||
| 59 | __udf_adinicb_readpage(page); | ||
| 56 | unlock_page(page); | 60 | unlock_page(page); |
| 57 | 61 | ||
| 58 | return 0; | 62 | return 0; |
| @@ -77,6 +81,25 @@ static int udf_adinicb_writepage(struct page *page, | |||
| 77 | return 0; | 81 | return 0; |
| 78 | } | 82 | } |
| 79 | 83 | ||
| 84 | static int udf_adinicb_write_begin(struct file *file, | ||
| 85 | struct address_space *mapping, loff_t pos, | ||
| 86 | unsigned len, unsigned flags, struct page **pagep, | ||
| 87 | void **fsdata) | ||
| 88 | { | ||
| 89 | struct page *page; | ||
| 90 | |||
| 91 | if (WARN_ON_ONCE(pos >= PAGE_CACHE_SIZE)) | ||
| 92 | return -EIO; | ||
| 93 | page = grab_cache_page_write_begin(mapping, 0, flags); | ||
| 94 | if (!page) | ||
| 95 | return -ENOMEM; | ||
| 96 | *pagep = page; | ||
| 97 | |||
| 98 | if (!PageUptodate(page) && len != PAGE_CACHE_SIZE) | ||
| 99 | __udf_adinicb_readpage(page); | ||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | |||
| 80 | static int udf_adinicb_write_end(struct file *file, | 103 | static int udf_adinicb_write_end(struct file *file, |
| 81 | struct address_space *mapping, | 104 | struct address_space *mapping, |
| 82 | loff_t pos, unsigned len, unsigned copied, | 105 | loff_t pos, unsigned len, unsigned copied, |
| @@ -98,8 +121,8 @@ static int udf_adinicb_write_end(struct file *file, | |||
| 98 | const struct address_space_operations udf_adinicb_aops = { | 121 | const struct address_space_operations udf_adinicb_aops = { |
| 99 | .readpage = udf_adinicb_readpage, | 122 | .readpage = udf_adinicb_readpage, |
| 100 | .writepage = udf_adinicb_writepage, | 123 | .writepage = udf_adinicb_writepage, |
| 101 | .write_begin = simple_write_begin, | 124 | .write_begin = udf_adinicb_write_begin, |
| 102 | .write_end = udf_adinicb_write_end, | 125 | .write_end = udf_adinicb_write_end, |
| 103 | }; | 126 | }; |
| 104 | 127 | ||
| 105 | static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | 128 | static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, |
