diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/bio-integrity.c | 13 | ||||
| -rw-r--r-- | fs/bio.c | 15 | ||||
| -rw-r--r-- | fs/cifs/cifsacl.c | 28 | ||||
| -rw-r--r-- | fs/cifs/cifsglob.h | 9 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 3 | ||||
| -rw-r--r-- | fs/cifs/cifssmb.c | 15 | ||||
| -rw-r--r-- | fs/cifs/file.c | 31 | ||||
| -rw-r--r-- | fs/cifs/inode.c | 13 | ||||
| -rw-r--r-- | fs/cifs/smb1ops.c | 8 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.c | 5 | ||||
| -rw-r--r-- | fs/cifs/smb2proto.h | 3 | ||||
| -rw-r--r-- | fs/cifs/xattr.c | 15 | ||||
| -rw-r--r-- | fs/file.c | 2 | ||||
| -rw-r--r-- | fs/lockd/svclock.c | 8 | ||||
| -rw-r--r-- | fs/nfs/dir.c | 5 | ||||
| -rw-r--r-- | fs/nfsd/nfs4acl.c | 9 | ||||
| -rw-r--r-- | fs/ocfs2/alloc.c | 2 | ||||
| -rw-r--r-- | fs/ocfs2/file.c | 52 | ||||
| -rw-r--r-- | fs/ocfs2/namei.c | 17 | ||||
| -rw-r--r-- | fs/proc/vmcore.c | 26 |
20 files changed, 204 insertions, 75 deletions
diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c index 0bad24ddc2e7..0129b78a6908 100644 --- a/fs/bio-integrity.c +++ b/fs/bio-integrity.c | |||
| @@ -114,6 +114,14 @@ void bio_integrity_free(struct bio *bio) | |||
| 114 | } | 114 | } |
| 115 | EXPORT_SYMBOL(bio_integrity_free); | 115 | EXPORT_SYMBOL(bio_integrity_free); |
| 116 | 116 | ||
| 117 | static inline unsigned int bip_integrity_vecs(struct bio_integrity_payload *bip) | ||
| 118 | { | ||
| 119 | if (bip->bip_slab == BIO_POOL_NONE) | ||
| 120 | return BIP_INLINE_VECS; | ||
| 121 | |||
| 122 | return bvec_nr_vecs(bip->bip_slab); | ||
| 123 | } | ||
| 124 | |||
| 117 | /** | 125 | /** |
| 118 | * bio_integrity_add_page - Attach integrity metadata | 126 | * bio_integrity_add_page - Attach integrity metadata |
| 119 | * @bio: bio to update | 127 | * @bio: bio to update |
| @@ -129,7 +137,7 @@ int bio_integrity_add_page(struct bio *bio, struct page *page, | |||
| 129 | struct bio_integrity_payload *bip = bio->bi_integrity; | 137 | struct bio_integrity_payload *bip = bio->bi_integrity; |
| 130 | struct bio_vec *iv; | 138 | struct bio_vec *iv; |
| 131 | 139 | ||
| 132 | if (bip->bip_vcnt >= bvec_nr_vecs(bip->bip_slab)) { | 140 | if (bip->bip_vcnt >= bip_integrity_vecs(bip)) { |
| 133 | printk(KERN_ERR "%s: bip_vec full\n", __func__); | 141 | printk(KERN_ERR "%s: bip_vec full\n", __func__); |
| 134 | return 0; | 142 | return 0; |
| 135 | } | 143 | } |
| @@ -226,7 +234,8 @@ unsigned int bio_integrity_tag_size(struct bio *bio) | |||
| 226 | } | 234 | } |
| 227 | EXPORT_SYMBOL(bio_integrity_tag_size); | 235 | EXPORT_SYMBOL(bio_integrity_tag_size); |
| 228 | 236 | ||
| 229 | int bio_integrity_tag(struct bio *bio, void *tag_buf, unsigned int len, int set) | 237 | static int bio_integrity_tag(struct bio *bio, void *tag_buf, unsigned int len, |
| 238 | int set) | ||
| 230 | { | 239 | { |
| 231 | struct bio_integrity_payload *bip = bio->bi_integrity; | 240 | struct bio_integrity_payload *bip = bio->bi_integrity; |
| 232 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); | 241 | struct blk_integrity *bi = bdev_get_integrity(bio->bi_bdev); |
| @@ -611,7 +611,6 @@ EXPORT_SYMBOL(bio_clone_fast); | |||
| 611 | struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask, | 611 | struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask, |
| 612 | struct bio_set *bs) | 612 | struct bio_set *bs) |
| 613 | { | 613 | { |
| 614 | unsigned nr_iovecs = 0; | ||
| 615 | struct bvec_iter iter; | 614 | struct bvec_iter iter; |
| 616 | struct bio_vec bv; | 615 | struct bio_vec bv; |
| 617 | struct bio *bio; | 616 | struct bio *bio; |
| @@ -638,10 +637,7 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask, | |||
| 638 | * __bio_clone_fast() anyways. | 637 | * __bio_clone_fast() anyways. |
| 639 | */ | 638 | */ |
| 640 | 639 | ||
| 641 | bio_for_each_segment(bv, bio_src, iter) | 640 | bio = bio_alloc_bioset(gfp_mask, bio_segments(bio_src), bs); |
| 642 | nr_iovecs++; | ||
| 643 | |||
| 644 | bio = bio_alloc_bioset(gfp_mask, nr_iovecs, bs); | ||
| 645 | if (!bio) | 641 | if (!bio) |
| 646 | return NULL; | 642 | return NULL; |
| 647 | 643 | ||
| @@ -650,9 +646,18 @@ struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask, | |||
| 650 | bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector; | 646 | bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector; |
| 651 | bio->bi_iter.bi_size = bio_src->bi_iter.bi_size; | 647 | bio->bi_iter.bi_size = bio_src->bi_iter.bi_size; |
| 652 | 648 | ||
| 649 | if (bio->bi_rw & REQ_DISCARD) | ||
| 650 | goto integrity_clone; | ||
| 651 | |||
| 652 | if (bio->bi_rw & REQ_WRITE_SAME) { | ||
| 653 | bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0]; | ||
| 654 | goto integrity_clone; | ||
| 655 | } | ||
| 656 | |||
| 653 | bio_for_each_segment(bv, bio_src, iter) | 657 | bio_for_each_segment(bv, bio_src, iter) |
| 654 | bio->bi_io_vec[bio->bi_vcnt++] = bv; | 658 | bio->bi_io_vec[bio->bi_vcnt++] = bv; |
| 655 | 659 | ||
| 660 | integrity_clone: | ||
| 656 | if (bio_integrity(bio_src)) { | 661 | if (bio_integrity(bio_src)) { |
| 657 | int ret; | 662 | int ret; |
| 658 | 663 | ||
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 8f9b4f710d4a..c819b0bd491a 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
| @@ -1043,15 +1043,30 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, | |||
| 1043 | __u32 secdesclen = 0; | 1043 | __u32 secdesclen = 0; |
| 1044 | struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ | 1044 | struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ |
| 1045 | struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ | 1045 | struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ |
| 1046 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
| 1047 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); | ||
| 1048 | struct cifs_tcon *tcon; | ||
| 1049 | |||
| 1050 | if (IS_ERR(tlink)) | ||
| 1051 | return PTR_ERR(tlink); | ||
| 1052 | tcon = tlink_tcon(tlink); | ||
| 1046 | 1053 | ||
| 1047 | cifs_dbg(NOISY, "set ACL from mode for %s\n", path); | 1054 | cifs_dbg(NOISY, "set ACL from mode for %s\n", path); |
| 1048 | 1055 | ||
| 1049 | /* Get the security descriptor */ | 1056 | /* Get the security descriptor */ |
| 1050 | pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen); | 1057 | |
| 1058 | if (tcon->ses->server->ops->get_acl == NULL) { | ||
| 1059 | cifs_put_tlink(tlink); | ||
| 1060 | return -EOPNOTSUPP; | ||
| 1061 | } | ||
| 1062 | |||
| 1063 | pntsd = tcon->ses->server->ops->get_acl(cifs_sb, inode, path, | ||
| 1064 | &secdesclen); | ||
| 1051 | if (IS_ERR(pntsd)) { | 1065 | if (IS_ERR(pntsd)) { |
| 1052 | rc = PTR_ERR(pntsd); | 1066 | rc = PTR_ERR(pntsd); |
| 1053 | cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc); | 1067 | cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc); |
| 1054 | goto out; | 1068 | cifs_put_tlink(tlink); |
| 1069 | return rc; | ||
| 1055 | } | 1070 | } |
| 1056 | 1071 | ||
| 1057 | /* | 1072 | /* |
| @@ -1064,6 +1079,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, | |||
| 1064 | pnntsd = kmalloc(secdesclen, GFP_KERNEL); | 1079 | pnntsd = kmalloc(secdesclen, GFP_KERNEL); |
| 1065 | if (!pnntsd) { | 1080 | if (!pnntsd) { |
| 1066 | kfree(pntsd); | 1081 | kfree(pntsd); |
| 1082 | cifs_put_tlink(tlink); | ||
| 1067 | return -ENOMEM; | 1083 | return -ENOMEM; |
| 1068 | } | 1084 | } |
| 1069 | 1085 | ||
| @@ -1072,14 +1088,18 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, | |||
| 1072 | 1088 | ||
| 1073 | cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); | 1089 | cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); |
| 1074 | 1090 | ||
| 1091 | if (tcon->ses->server->ops->set_acl == NULL) | ||
| 1092 | rc = -EOPNOTSUPP; | ||
| 1093 | |||
| 1075 | if (!rc) { | 1094 | if (!rc) { |
| 1076 | /* Set the security descriptor */ | 1095 | /* Set the security descriptor */ |
| 1077 | rc = set_cifs_acl(pnntsd, secdesclen, inode, path, aclflag); | 1096 | rc = tcon->ses->server->ops->set_acl(pnntsd, secdesclen, inode, |
| 1097 | path, aclflag); | ||
| 1078 | cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc); | 1098 | cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc); |
| 1079 | } | 1099 | } |
| 1100 | cifs_put_tlink(tlink); | ||
| 1080 | 1101 | ||
| 1081 | kfree(pnntsd); | 1102 | kfree(pnntsd); |
| 1082 | kfree(pntsd); | 1103 | kfree(pntsd); |
| 1083 | out: | ||
| 1084 | return rc; | 1104 | return rc; |
| 1085 | } | 1105 | } |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index a245d1809ed8..86dc28c7aa5c 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -323,7 +323,8 @@ struct smb_version_operations { | |||
| 323 | /* async read from the server */ | 323 | /* async read from the server */ |
| 324 | int (*async_readv)(struct cifs_readdata *); | 324 | int (*async_readv)(struct cifs_readdata *); |
| 325 | /* async write to the server */ | 325 | /* async write to the server */ |
| 326 | int (*async_writev)(struct cifs_writedata *); | 326 | int (*async_writev)(struct cifs_writedata *, |
| 327 | void (*release)(struct kref *)); | ||
| 327 | /* sync read from the server */ | 328 | /* sync read from the server */ |
| 328 | int (*sync_read)(const unsigned int, struct cifsFileInfo *, | 329 | int (*sync_read)(const unsigned int, struct cifsFileInfo *, |
| 329 | struct cifs_io_parms *, unsigned int *, char **, | 330 | struct cifs_io_parms *, unsigned int *, char **, |
| @@ -395,6 +396,10 @@ struct smb_version_operations { | |||
| 395 | int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *, | 396 | int (*set_EA)(const unsigned int, struct cifs_tcon *, const char *, |
| 396 | const char *, const void *, const __u16, | 397 | const char *, const void *, const __u16, |
| 397 | const struct nls_table *, int); | 398 | const struct nls_table *, int); |
| 399 | struct cifs_ntsd * (*get_acl)(struct cifs_sb_info *, struct inode *, | ||
| 400 | const char *, u32 *); | ||
| 401 | int (*set_acl)(struct cifs_ntsd *, __u32, struct inode *, const char *, | ||
| 402 | int); | ||
| 398 | }; | 403 | }; |
| 399 | 404 | ||
| 400 | struct smb_version_values { | 405 | struct smb_version_values { |
| @@ -1064,7 +1069,7 @@ struct cifs_writedata { | |||
| 1064 | unsigned int pagesz; | 1069 | unsigned int pagesz; |
| 1065 | unsigned int tailsz; | 1070 | unsigned int tailsz; |
| 1066 | unsigned int nr_pages; | 1071 | unsigned int nr_pages; |
| 1067 | struct page *pages[1]; | 1072 | struct page *pages[]; |
| 1068 | }; | 1073 | }; |
| 1069 | 1074 | ||
| 1070 | /* | 1075 | /* |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 79e6e9a93a8c..d00e09dfc452 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -488,7 +488,8 @@ void cifs_readdata_release(struct kref *refcount); | |||
| 488 | int cifs_async_readv(struct cifs_readdata *rdata); | 488 | int cifs_async_readv(struct cifs_readdata *rdata); |
| 489 | int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid); | 489 | int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid); |
| 490 | 490 | ||
| 491 | int cifs_async_writev(struct cifs_writedata *wdata); | 491 | int cifs_async_writev(struct cifs_writedata *wdata, |
| 492 | void (*release)(struct kref *kref)); | ||
| 492 | void cifs_writev_complete(struct work_struct *work); | 493 | void cifs_writev_complete(struct work_struct *work); |
| 493 | struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages, | 494 | struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages, |
| 494 | work_func_t complete); | 495 | work_func_t complete); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 4d881c35eeca..f3264bd7a83d 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -1910,7 +1910,7 @@ cifs_writev_requeue(struct cifs_writedata *wdata) | |||
| 1910 | 1910 | ||
| 1911 | do { | 1911 | do { |
| 1912 | server = tlink_tcon(wdata->cfile->tlink)->ses->server; | 1912 | server = tlink_tcon(wdata->cfile->tlink)->ses->server; |
| 1913 | rc = server->ops->async_writev(wdata); | 1913 | rc = server->ops->async_writev(wdata, cifs_writedata_release); |
| 1914 | } while (rc == -EAGAIN); | 1914 | } while (rc == -EAGAIN); |
| 1915 | 1915 | ||
| 1916 | for (i = 0; i < wdata->nr_pages; i++) { | 1916 | for (i = 0; i < wdata->nr_pages; i++) { |
| @@ -1962,15 +1962,9 @@ cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete) | |||
| 1962 | { | 1962 | { |
| 1963 | struct cifs_writedata *wdata; | 1963 | struct cifs_writedata *wdata; |
| 1964 | 1964 | ||
| 1965 | /* this would overflow */ | ||
| 1966 | if (nr_pages == 0) { | ||
| 1967 | cifs_dbg(VFS, "%s: called with nr_pages == 0!\n", __func__); | ||
| 1968 | return NULL; | ||
| 1969 | } | ||
| 1970 | |||
| 1971 | /* writedata + number of page pointers */ | 1965 | /* writedata + number of page pointers */ |
| 1972 | wdata = kzalloc(sizeof(*wdata) + | 1966 | wdata = kzalloc(sizeof(*wdata) + |
| 1973 | sizeof(struct page *) * (nr_pages - 1), GFP_NOFS); | 1967 | sizeof(struct page *) * nr_pages, GFP_NOFS); |
| 1974 | if (wdata != NULL) { | 1968 | if (wdata != NULL) { |
| 1975 | kref_init(&wdata->refcount); | 1969 | kref_init(&wdata->refcount); |
| 1976 | INIT_LIST_HEAD(&wdata->list); | 1970 | INIT_LIST_HEAD(&wdata->list); |
| @@ -2031,7 +2025,8 @@ cifs_writev_callback(struct mid_q_entry *mid) | |||
| 2031 | 2025 | ||
| 2032 | /* cifs_async_writev - send an async write, and set up mid to handle result */ | 2026 | /* cifs_async_writev - send an async write, and set up mid to handle result */ |
| 2033 | int | 2027 | int |
| 2034 | cifs_async_writev(struct cifs_writedata *wdata) | 2028 | cifs_async_writev(struct cifs_writedata *wdata, |
| 2029 | void (*release)(struct kref *kref)) | ||
| 2035 | { | 2030 | { |
| 2036 | int rc = -EACCES; | 2031 | int rc = -EACCES; |
| 2037 | WRITE_REQ *smb = NULL; | 2032 | WRITE_REQ *smb = NULL; |
| @@ -2105,7 +2100,7 @@ cifs_async_writev(struct cifs_writedata *wdata) | |||
| 2105 | if (rc == 0) | 2100 | if (rc == 0) |
| 2106 | cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); | 2101 | cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); |
| 2107 | else | 2102 | else |
| 2108 | kref_put(&wdata->refcount, cifs_writedata_release); | 2103 | kref_put(&wdata->refcount, release); |
| 2109 | 2104 | ||
| 2110 | async_writev_out: | 2105 | async_writev_out: |
| 2111 | cifs_small_buf_release(smb); | 2106 | cifs_small_buf_release(smb); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index a7eda8ebfacc..755584684f6c 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -2043,7 +2043,8 @@ retry: | |||
| 2043 | } | 2043 | } |
| 2044 | wdata->pid = wdata->cfile->pid; | 2044 | wdata->pid = wdata->cfile->pid; |
| 2045 | server = tlink_tcon(wdata->cfile->tlink)->ses->server; | 2045 | server = tlink_tcon(wdata->cfile->tlink)->ses->server; |
| 2046 | rc = server->ops->async_writev(wdata); | 2046 | rc = server->ops->async_writev(wdata, |
| 2047 | cifs_writedata_release); | ||
| 2047 | } while (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN); | 2048 | } while (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN); |
| 2048 | 2049 | ||
| 2049 | for (i = 0; i < nr_pages; ++i) | 2050 | for (i = 0; i < nr_pages; ++i) |
| @@ -2331,9 +2332,20 @@ size_t get_numpages(const size_t wsize, const size_t len, size_t *cur_len) | |||
| 2331 | } | 2332 | } |
| 2332 | 2333 | ||
| 2333 | static void | 2334 | static void |
| 2334 | cifs_uncached_writev_complete(struct work_struct *work) | 2335 | cifs_uncached_writedata_release(struct kref *refcount) |
| 2335 | { | 2336 | { |
| 2336 | int i; | 2337 | int i; |
| 2338 | struct cifs_writedata *wdata = container_of(refcount, | ||
| 2339 | struct cifs_writedata, refcount); | ||
| 2340 | |||
| 2341 | for (i = 0; i < wdata->nr_pages; i++) | ||
| 2342 | put_page(wdata->pages[i]); | ||
| 2343 | cifs_writedata_release(refcount); | ||
| 2344 | } | ||
| 2345 | |||
| 2346 | static void | ||
| 2347 | cifs_uncached_writev_complete(struct work_struct *work) | ||
| 2348 | { | ||
| 2337 | struct cifs_writedata *wdata = container_of(work, | 2349 | struct cifs_writedata *wdata = container_of(work, |
| 2338 | struct cifs_writedata, work); | 2350 | struct cifs_writedata, work); |
| 2339 | struct inode *inode = wdata->cfile->dentry->d_inode; | 2351 | struct inode *inode = wdata->cfile->dentry->d_inode; |
| @@ -2347,12 +2359,7 @@ cifs_uncached_writev_complete(struct work_struct *work) | |||
| 2347 | 2359 | ||
| 2348 | complete(&wdata->done); | 2360 | complete(&wdata->done); |
| 2349 | 2361 | ||
| 2350 | if (wdata->result != -EAGAIN) { | 2362 | kref_put(&wdata->refcount, cifs_uncached_writedata_release); |
| 2351 | for (i = 0; i < wdata->nr_pages; i++) | ||
| 2352 | put_page(wdata->pages[i]); | ||
| 2353 | } | ||
| 2354 | |||
| 2355 | kref_put(&wdata->refcount, cifs_writedata_release); | ||
| 2356 | } | 2363 | } |
| 2357 | 2364 | ||
| 2358 | /* attempt to send write to server, retry on any -EAGAIN errors */ | 2365 | /* attempt to send write to server, retry on any -EAGAIN errors */ |
| @@ -2370,7 +2377,8 @@ cifs_uncached_retry_writev(struct cifs_writedata *wdata) | |||
| 2370 | if (rc != 0) | 2377 | if (rc != 0) |
| 2371 | continue; | 2378 | continue; |
| 2372 | } | 2379 | } |
| 2373 | rc = server->ops->async_writev(wdata); | 2380 | rc = server->ops->async_writev(wdata, |
| 2381 | cifs_uncached_writedata_release); | ||
| 2374 | } while (rc == -EAGAIN); | 2382 | } while (rc == -EAGAIN); |
| 2375 | 2383 | ||
| 2376 | return rc; | 2384 | return rc; |
| @@ -2454,7 +2462,8 @@ cifs_iovec_write(struct file *file, const struct iovec *iov, | |||
| 2454 | wdata->tailsz = cur_len - ((nr_pages - 1) * PAGE_SIZE); | 2462 | wdata->tailsz = cur_len - ((nr_pages - 1) * PAGE_SIZE); |
| 2455 | rc = cifs_uncached_retry_writev(wdata); | 2463 | rc = cifs_uncached_retry_writev(wdata); |
| 2456 | if (rc) { | 2464 | if (rc) { |
| 2457 | kref_put(&wdata->refcount, cifs_writedata_release); | 2465 | kref_put(&wdata->refcount, |
| 2466 | cifs_uncached_writedata_release); | ||
| 2458 | break; | 2467 | break; |
| 2459 | } | 2468 | } |
| 2460 | 2469 | ||
| @@ -2496,7 +2505,7 @@ restart_loop: | |||
| 2496 | } | 2505 | } |
| 2497 | } | 2506 | } |
| 2498 | list_del_init(&wdata->list); | 2507 | list_del_init(&wdata->list); |
| 2499 | kref_put(&wdata->refcount, cifs_writedata_release); | 2508 | kref_put(&wdata->refcount, cifs_uncached_writedata_release); |
| 2500 | } | 2509 | } |
| 2501 | 2510 | ||
| 2502 | if (total_written > 0) | 2511 | if (total_written > 0) |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 9cb9679d7357..be58b8fcdb3c 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
| @@ -527,10 +527,15 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, | |||
| 527 | return PTR_ERR(tlink); | 527 | return PTR_ERR(tlink); |
| 528 | tcon = tlink_tcon(tlink); | 528 | tcon = tlink_tcon(tlink); |
| 529 | 529 | ||
| 530 | rc = CIFSSMBQAllEAs(xid, tcon, path, "SETFILEBITS", | 530 | if (tcon->ses->server->ops->query_all_EAs == NULL) { |
| 531 | ea_value, 4 /* size of buf */, cifs_sb->local_nls, | 531 | cifs_put_tlink(tlink); |
| 532 | cifs_sb->mnt_cifs_flags & | 532 | return -EOPNOTSUPP; |
| 533 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 533 | } |
| 534 | |||
| 535 | rc = tcon->ses->server->ops->query_all_EAs(xid, tcon, path, | ||
| 536 | "SETFILEBITS", ea_value, 4 /* size of buf */, | ||
| 537 | cifs_sb->local_nls, | ||
| 538 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
| 534 | cifs_put_tlink(tlink); | 539 | cifs_put_tlink(tlink); |
| 535 | if (rc < 0) | 540 | if (rc < 0) |
| 536 | return (int)rc; | 541 | return (int)rc; |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index 9ac5bfc9cc56..bfd66d84831e 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
| @@ -1067,6 +1067,14 @@ struct smb_version_operations smb1_operations = { | |||
| 1067 | .query_mf_symlink = cifs_query_mf_symlink, | 1067 | .query_mf_symlink = cifs_query_mf_symlink, |
| 1068 | .create_mf_symlink = cifs_create_mf_symlink, | 1068 | .create_mf_symlink = cifs_create_mf_symlink, |
| 1069 | .is_read_op = cifs_is_read_op, | 1069 | .is_read_op = cifs_is_read_op, |
| 1070 | #ifdef CONFIG_CIFS_XATTR | ||
| 1071 | .query_all_EAs = CIFSSMBQAllEAs, | ||
| 1072 | .set_EA = CIFSSMBSetEA, | ||
| 1073 | #endif /* CIFS_XATTR */ | ||
| 1074 | #ifdef CONFIG_CIFS_ACL | ||
| 1075 | .get_acl = get_cifs_acl, | ||
| 1076 | .set_acl = set_cifs_acl, | ||
| 1077 | #endif /* CIFS_ACL */ | ||
| 1070 | }; | 1078 | }; |
| 1071 | 1079 | ||
| 1072 | struct smb_version_values smb1_values = { | 1080 | struct smb_version_values smb1_values = { |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 2013234b73ad..a3f7a9c3cc69 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
| @@ -1890,7 +1890,8 @@ smb2_writev_callback(struct mid_q_entry *mid) | |||
| 1890 | 1890 | ||
| 1891 | /* smb2_async_writev - send an async write, and set up mid to handle result */ | 1891 | /* smb2_async_writev - send an async write, and set up mid to handle result */ |
| 1892 | int | 1892 | int |
| 1893 | smb2_async_writev(struct cifs_writedata *wdata) | 1893 | smb2_async_writev(struct cifs_writedata *wdata, |
| 1894 | void (*release)(struct kref *kref)) | ||
| 1894 | { | 1895 | { |
| 1895 | int rc = -EACCES; | 1896 | int rc = -EACCES; |
| 1896 | struct smb2_write_req *req = NULL; | 1897 | struct smb2_write_req *req = NULL; |
| @@ -1938,7 +1939,7 @@ smb2_async_writev(struct cifs_writedata *wdata) | |||
| 1938 | smb2_writev_callback, wdata, 0); | 1939 | smb2_writev_callback, wdata, 0); |
| 1939 | 1940 | ||
| 1940 | if (rc) { | 1941 | if (rc) { |
| 1941 | kref_put(&wdata->refcount, cifs_writedata_release); | 1942 | kref_put(&wdata->refcount, release); |
| 1942 | cifs_stats_fail_inc(tcon, SMB2_WRITE_HE); | 1943 | cifs_stats_fail_inc(tcon, SMB2_WRITE_HE); |
| 1943 | } | 1944 | } |
| 1944 | 1945 | ||
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 93adc64666f3..0ce48db20a65 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
| @@ -123,7 +123,8 @@ extern int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon, | |||
| 123 | extern int smb2_async_readv(struct cifs_readdata *rdata); | 123 | extern int smb2_async_readv(struct cifs_readdata *rdata); |
| 124 | extern int SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, | 124 | extern int SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, |
| 125 | unsigned int *nbytes, char **buf, int *buf_type); | 125 | unsigned int *nbytes, char **buf, int *buf_type); |
| 126 | extern int smb2_async_writev(struct cifs_writedata *wdata); | 126 | extern int smb2_async_writev(struct cifs_writedata *wdata, |
| 127 | void (*release)(struct kref *kref)); | ||
| 127 | extern int SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, | 128 | extern int SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms, |
| 128 | unsigned int *nbytes, struct kvec *iov, int n_vec); | 129 | unsigned int *nbytes, struct kvec *iov, int n_vec); |
| 129 | extern int SMB2_echo(struct TCP_Server_Info *server); | 130 | extern int SMB2_echo(struct TCP_Server_Info *server); |
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 95c43bb20335..5ac836a86b18 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
| @@ -176,8 +176,12 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name, | |||
| 176 | rc = -ENOMEM; | 176 | rc = -ENOMEM; |
| 177 | } else { | 177 | } else { |
| 178 | memcpy(pacl, ea_value, value_size); | 178 | memcpy(pacl, ea_value, value_size); |
| 179 | rc = set_cifs_acl(pacl, value_size, | 179 | if (pTcon->ses->server->ops->set_acl) |
| 180 | direntry->d_inode, full_path, CIFS_ACL_DACL); | 180 | rc = pTcon->ses->server->ops->set_acl(pacl, |
| 181 | value_size, direntry->d_inode, | ||
| 182 | full_path, CIFS_ACL_DACL); | ||
| 183 | else | ||
| 184 | rc = -EOPNOTSUPP; | ||
| 181 | if (rc == 0) /* force revalidate of the inode */ | 185 | if (rc == 0) /* force revalidate of the inode */ |
| 182 | CIFS_I(direntry->d_inode)->time = 0; | 186 | CIFS_I(direntry->d_inode)->time = 0; |
| 183 | kfree(pacl); | 187 | kfree(pacl); |
| @@ -323,8 +327,11 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, | |||
| 323 | u32 acllen; | 327 | u32 acllen; |
| 324 | struct cifs_ntsd *pacl; | 328 | struct cifs_ntsd *pacl; |
| 325 | 329 | ||
| 326 | pacl = get_cifs_acl(cifs_sb, direntry->d_inode, | 330 | if (pTcon->ses->server->ops->get_acl == NULL) |
| 327 | full_path, &acllen); | 331 | goto get_ea_exit; /* rc already EOPNOTSUPP */ |
| 332 | |||
| 333 | pacl = pTcon->ses->server->ops->get_acl(cifs_sb, | ||
| 334 | direntry->d_inode, full_path, &acllen); | ||
| 328 | if (IS_ERR(pacl)) { | 335 | if (IS_ERR(pacl)) { |
| 329 | rc = PTR_ERR(pacl); | 336 | rc = PTR_ERR(pacl); |
| 330 | cifs_dbg(VFS, "%s: error %zd getting sec desc\n", | 337 | cifs_dbg(VFS, "%s: error %zd getting sec desc\n", |
| @@ -34,7 +34,7 @@ static void *alloc_fdmem(size_t size) | |||
| 34 | * vmalloc() if the allocation size will be considered "large" by the VM. | 34 | * vmalloc() if the allocation size will be considered "large" by the VM. |
| 35 | */ | 35 | */ |
| 36 | if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { | 36 | if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER)) { |
| 37 | void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN); | 37 | void *data = kmalloc(size, GFP_KERNEL|__GFP_NOWARN|__GFP_NORETRY); |
| 38 | if (data != NULL) | 38 | if (data != NULL) |
| 39 | return data; | 39 | return data; |
| 40 | } | 40 | } |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index e066a3902973..ab798a88ec1d 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
| @@ -779,6 +779,7 @@ nlmsvc_grant_blocked(struct nlm_block *block) | |||
| 779 | struct nlm_file *file = block->b_file; | 779 | struct nlm_file *file = block->b_file; |
| 780 | struct nlm_lock *lock = &block->b_call->a_args.lock; | 780 | struct nlm_lock *lock = &block->b_call->a_args.lock; |
| 781 | int error; | 781 | int error; |
| 782 | loff_t fl_start, fl_end; | ||
| 782 | 783 | ||
| 783 | dprintk("lockd: grant blocked lock %p\n", block); | 784 | dprintk("lockd: grant blocked lock %p\n", block); |
| 784 | 785 | ||
| @@ -796,9 +797,16 @@ nlmsvc_grant_blocked(struct nlm_block *block) | |||
| 796 | } | 797 | } |
| 797 | 798 | ||
| 798 | /* Try the lock operation again */ | 799 | /* Try the lock operation again */ |
| 800 | /* vfs_lock_file() can mangle fl_start and fl_end, but we need | ||
| 801 | * them unchanged for the GRANT_MSG | ||
| 802 | */ | ||
| 799 | lock->fl.fl_flags |= FL_SLEEP; | 803 | lock->fl.fl_flags |= FL_SLEEP; |
| 804 | fl_start = lock->fl.fl_start; | ||
| 805 | fl_end = lock->fl.fl_end; | ||
| 800 | error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); | 806 | error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); |
| 801 | lock->fl.fl_flags &= ~FL_SLEEP; | 807 | lock->fl.fl_flags &= ~FL_SLEEP; |
| 808 | lock->fl.fl_start = fl_start; | ||
| 809 | lock->fl.fl_end = fl_end; | ||
| 802 | 810 | ||
| 803 | switch (error) { | 811 | switch (error) { |
| 804 | case 0: | 812 | case 0: |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index be38b573495a..4a48fe4b84b6 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -1846,6 +1846,11 @@ int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) | |||
| 1846 | GFP_KERNEL)) { | 1846 | GFP_KERNEL)) { |
| 1847 | SetPageUptodate(page); | 1847 | SetPageUptodate(page); |
| 1848 | unlock_page(page); | 1848 | unlock_page(page); |
| 1849 | /* | ||
| 1850 | * add_to_page_cache_lru() grabs an extra page refcount. | ||
| 1851 | * Drop it here to avoid leaking this page later. | ||
| 1852 | */ | ||
| 1853 | page_cache_release(page); | ||
| 1849 | } else | 1854 | } else |
| 1850 | __free_page(page); | 1855 | __free_page(page); |
| 1851 | 1856 | ||
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index d3a587144222..d190e33d0ec2 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
| @@ -151,17 +151,15 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, | |||
| 151 | pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); | 151 | pacl = posix_acl_from_mode(inode->i_mode, GFP_KERNEL); |
| 152 | if (IS_ERR(pacl)) | 152 | if (IS_ERR(pacl)) |
| 153 | return PTR_ERR(pacl); | 153 | return PTR_ERR(pacl); |
| 154 | /* allocate for worst case: one (deny, allow) pair each: */ | ||
| 155 | size += 2 * pacl->a_count; | ||
| 156 | } | 154 | } |
| 155 | /* allocate for worst case: one (deny, allow) pair each: */ | ||
| 156 | size += 2 * pacl->a_count; | ||
| 157 | 157 | ||
| 158 | if (S_ISDIR(inode->i_mode)) { | 158 | if (S_ISDIR(inode->i_mode)) { |
| 159 | flags = NFS4_ACL_DIR; | 159 | flags = NFS4_ACL_DIR; |
| 160 | dpacl = get_acl(inode, ACL_TYPE_DEFAULT); | 160 | dpacl = get_acl(inode, ACL_TYPE_DEFAULT); |
| 161 | if (dpacl) | 161 | if (dpacl) |
| 162 | size += 2 * dpacl->a_count; | 162 | size += 2 * dpacl->a_count; |
| 163 | } else { | ||
| 164 | dpacl = NULL; | ||
| 165 | } | 163 | } |
| 166 | 164 | ||
| 167 | *acl = nfs4_acl_new(size); | 165 | *acl = nfs4_acl_new(size); |
| @@ -170,8 +168,7 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, | |||
| 170 | goto out; | 168 | goto out; |
| 171 | } | 169 | } |
| 172 | 170 | ||
| 173 | if (pacl) | 171 | _posix_to_nfsv4_one(pacl, *acl, flags & ~NFS4_ACL_TYPE_DEFAULT); |
| 174 | _posix_to_nfsv4_one(pacl, *acl, flags & ~NFS4_ACL_TYPE_DEFAULT); | ||
| 175 | 172 | ||
| 176 | if (dpacl) | 173 | if (dpacl) |
| 177 | _posix_to_nfsv4_one(dpacl, *acl, flags | NFS4_ACL_TYPE_DEFAULT); | 174 | _posix_to_nfsv4_one(dpacl, *acl, flags | NFS4_ACL_TYPE_DEFAULT); |
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index aada5801567a..e2edff38be52 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
| @@ -7158,7 +7158,7 @@ int ocfs2_truncate_inline(struct inode *inode, struct buffer_head *di_bh, | |||
| 7158 | if (end > i_size_read(inode)) | 7158 | if (end > i_size_read(inode)) |
| 7159 | end = i_size_read(inode); | 7159 | end = i_size_read(inode); |
| 7160 | 7160 | ||
| 7161 | BUG_ON(start >= end); | 7161 | BUG_ON(start > end); |
| 7162 | 7162 | ||
| 7163 | if (!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) || | 7163 | if (!(OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) || |
| 7164 | !(le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) || | 7164 | !(le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) || |
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index d77d71ead8d1..8450262bcf2a 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
| @@ -185,6 +185,9 @@ static int ocfs2_sync_file(struct file *file, loff_t start, loff_t end, | |||
| 185 | file->f_path.dentry->d_name.name, | 185 | file->f_path.dentry->d_name.name, |
| 186 | (unsigned long long)datasync); | 186 | (unsigned long long)datasync); |
| 187 | 187 | ||
| 188 | if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) | ||
| 189 | return -EROFS; | ||
| 190 | |||
| 188 | err = filemap_write_and_wait_range(inode->i_mapping, start, end); | 191 | err = filemap_write_and_wait_range(inode->i_mapping, start, end); |
| 189 | if (err) | 192 | if (err) |
| 190 | return err; | 193 | return err; |
| @@ -474,11 +477,6 @@ static int ocfs2_truncate_file(struct inode *inode, | |||
| 474 | goto bail; | 477 | goto bail; |
| 475 | } | 478 | } |
| 476 | 479 | ||
| 477 | /* lets handle the simple truncate cases before doing any more | ||
| 478 | * cluster locking. */ | ||
| 479 | if (new_i_size == le64_to_cpu(fe->i_size)) | ||
| 480 | goto bail; | ||
| 481 | |||
| 482 | down_write(&OCFS2_I(inode)->ip_alloc_sem); | 480 | down_write(&OCFS2_I(inode)->ip_alloc_sem); |
| 483 | 481 | ||
| 484 | ocfs2_resv_discard(&osb->osb_la_resmap, | 482 | ocfs2_resv_discard(&osb->osb_la_resmap, |
| @@ -718,7 +716,8 @@ leave: | |||
| 718 | * While a write will already be ordering the data, a truncate will not. | 716 | * While a write will already be ordering the data, a truncate will not. |
| 719 | * Thus, we need to explicitly order the zeroed pages. | 717 | * Thus, we need to explicitly order the zeroed pages. |
| 720 | */ | 718 | */ |
| 721 | static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode) | 719 | static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode, |
| 720 | struct buffer_head *di_bh) | ||
| 722 | { | 721 | { |
| 723 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 722 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
| 724 | handle_t *handle = NULL; | 723 | handle_t *handle = NULL; |
| @@ -735,7 +734,14 @@ static handle_t *ocfs2_zero_start_ordered_transaction(struct inode *inode) | |||
| 735 | } | 734 | } |
| 736 | 735 | ||
| 737 | ret = ocfs2_jbd2_file_inode(handle, inode); | 736 | ret = ocfs2_jbd2_file_inode(handle, inode); |
| 738 | if (ret < 0) | 737 | if (ret < 0) { |
| 738 | mlog_errno(ret); | ||
| 739 | goto out; | ||
| 740 | } | ||
| 741 | |||
| 742 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh, | ||
| 743 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
| 744 | if (ret) | ||
| 739 | mlog_errno(ret); | 745 | mlog_errno(ret); |
| 740 | 746 | ||
| 741 | out: | 747 | out: |
| @@ -751,7 +757,7 @@ out: | |||
| 751 | * to be too fragile to do exactly what we need without us having to | 757 | * to be too fragile to do exactly what we need without us having to |
| 752 | * worry about recursive locking in ->write_begin() and ->write_end(). */ | 758 | * worry about recursive locking in ->write_begin() and ->write_end(). */ |
| 753 | static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | 759 | static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, |
| 754 | u64 abs_to) | 760 | u64 abs_to, struct buffer_head *di_bh) |
| 755 | { | 761 | { |
| 756 | struct address_space *mapping = inode->i_mapping; | 762 | struct address_space *mapping = inode->i_mapping; |
| 757 | struct page *page; | 763 | struct page *page; |
| @@ -759,6 +765,7 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | |||
| 759 | handle_t *handle = NULL; | 765 | handle_t *handle = NULL; |
| 760 | int ret = 0; | 766 | int ret = 0; |
| 761 | unsigned zero_from, zero_to, block_start, block_end; | 767 | unsigned zero_from, zero_to, block_start, block_end; |
| 768 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | ||
| 762 | 769 | ||
| 763 | BUG_ON(abs_from >= abs_to); | 770 | BUG_ON(abs_from >= abs_to); |
| 764 | BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT)); | 771 | BUG_ON(abs_to > (((u64)index + 1) << PAGE_CACHE_SHIFT)); |
| @@ -801,7 +808,8 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | |||
| 801 | } | 808 | } |
| 802 | 809 | ||
| 803 | if (!handle) { | 810 | if (!handle) { |
| 804 | handle = ocfs2_zero_start_ordered_transaction(inode); | 811 | handle = ocfs2_zero_start_ordered_transaction(inode, |
| 812 | di_bh); | ||
| 805 | if (IS_ERR(handle)) { | 813 | if (IS_ERR(handle)) { |
| 806 | ret = PTR_ERR(handle); | 814 | ret = PTR_ERR(handle); |
| 807 | handle = NULL; | 815 | handle = NULL; |
| @@ -818,8 +826,22 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from, | |||
| 818 | ret = 0; | 826 | ret = 0; |
| 819 | } | 827 | } |
| 820 | 828 | ||
| 821 | if (handle) | 829 | if (handle) { |
| 830 | /* | ||
| 831 | * fs-writeback will release the dirty pages without page lock | ||
| 832 | * whose offset are over inode size, the release happens at | ||
| 833 | * block_write_full_page_endio(). | ||
| 834 | */ | ||
| 835 | i_size_write(inode, abs_to); | ||
| 836 | inode->i_blocks = ocfs2_inode_sector_count(inode); | ||
| 837 | di->i_size = cpu_to_le64((u64)i_size_read(inode)); | ||
| 838 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | ||
| 839 | di->i_mtime = di->i_ctime = cpu_to_le64(inode->i_mtime.tv_sec); | ||
| 840 | di->i_ctime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec); | ||
| 841 | di->i_mtime_nsec = di->i_ctime_nsec; | ||
| 842 | ocfs2_journal_dirty(handle, di_bh); | ||
| 822 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | 843 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
| 844 | } | ||
| 823 | 845 | ||
| 824 | out_unlock: | 846 | out_unlock: |
| 825 | unlock_page(page); | 847 | unlock_page(page); |
| @@ -915,7 +937,7 @@ out: | |||
| 915 | * has made sure that the entire range needs zeroing. | 937 | * has made sure that the entire range needs zeroing. |
| 916 | */ | 938 | */ |
| 917 | static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start, | 939 | static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start, |
| 918 | u64 range_end) | 940 | u64 range_end, struct buffer_head *di_bh) |
| 919 | { | 941 | { |
| 920 | int rc = 0; | 942 | int rc = 0; |
| 921 | u64 next_pos; | 943 | u64 next_pos; |
| @@ -931,7 +953,7 @@ static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start, | |||
| 931 | next_pos = (zero_pos & PAGE_CACHE_MASK) + PAGE_CACHE_SIZE; | 953 | next_pos = (zero_pos & PAGE_CACHE_MASK) + PAGE_CACHE_SIZE; |
| 932 | if (next_pos > range_end) | 954 | if (next_pos > range_end) |
| 933 | next_pos = range_end; | 955 | next_pos = range_end; |
| 934 | rc = ocfs2_write_zero_page(inode, zero_pos, next_pos); | 956 | rc = ocfs2_write_zero_page(inode, zero_pos, next_pos, di_bh); |
| 935 | if (rc < 0) { | 957 | if (rc < 0) { |
| 936 | mlog_errno(rc); | 958 | mlog_errno(rc); |
| 937 | break; | 959 | break; |
| @@ -977,7 +999,7 @@ int ocfs2_zero_extend(struct inode *inode, struct buffer_head *di_bh, | |||
| 977 | range_end = zero_to_size; | 999 | range_end = zero_to_size; |
| 978 | 1000 | ||
| 979 | ret = ocfs2_zero_extend_range(inode, range_start, | 1001 | ret = ocfs2_zero_extend_range(inode, range_start, |
| 980 | range_end); | 1002 | range_end, di_bh); |
| 981 | if (ret) { | 1003 | if (ret) { |
| 982 | mlog_errno(ret); | 1004 | mlog_errno(ret); |
| 983 | break; | 1005 | break; |
| @@ -1145,14 +1167,14 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr) | |||
| 1145 | goto bail_unlock_rw; | 1167 | goto bail_unlock_rw; |
| 1146 | } | 1168 | } |
| 1147 | 1169 | ||
| 1148 | if (size_change && attr->ia_size != i_size_read(inode)) { | 1170 | if (size_change) { |
| 1149 | status = inode_newsize_ok(inode, attr->ia_size); | 1171 | status = inode_newsize_ok(inode, attr->ia_size); |
| 1150 | if (status) | 1172 | if (status) |
| 1151 | goto bail_unlock; | 1173 | goto bail_unlock; |
| 1152 | 1174 | ||
| 1153 | inode_dio_wait(inode); | 1175 | inode_dio_wait(inode); |
| 1154 | 1176 | ||
| 1155 | if (i_size_read(inode) > attr->ia_size) { | 1177 | if (i_size_read(inode) >= attr->ia_size) { |
| 1156 | if (ocfs2_should_order_data(inode)) { | 1178 | if (ocfs2_should_order_data(inode)) { |
| 1157 | status = ocfs2_begin_ordered_truncate(inode, | 1179 | status = ocfs2_begin_ordered_truncate(inode, |
| 1158 | attr->ia_size); | 1180 | attr->ia_size); |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index f4d609be9400..3683643f3f0e 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
| @@ -664,6 +664,7 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
| 664 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | 664 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
| 665 | struct ocfs2_dir_lookup_result lookup = { NULL, }; | 665 | struct ocfs2_dir_lookup_result lookup = { NULL, }; |
| 666 | sigset_t oldset; | 666 | sigset_t oldset; |
| 667 | u64 old_de_ino; | ||
| 667 | 668 | ||
| 668 | trace_ocfs2_link((unsigned long long)OCFS2_I(inode)->ip_blkno, | 669 | trace_ocfs2_link((unsigned long long)OCFS2_I(inode)->ip_blkno, |
| 669 | old_dentry->d_name.len, old_dentry->d_name.name, | 670 | old_dentry->d_name.len, old_dentry->d_name.name, |
| @@ -686,6 +687,22 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
| 686 | goto out; | 687 | goto out; |
| 687 | } | 688 | } |
| 688 | 689 | ||
| 690 | err = ocfs2_lookup_ino_from_name(dir, old_dentry->d_name.name, | ||
| 691 | old_dentry->d_name.len, &old_de_ino); | ||
| 692 | if (err) { | ||
| 693 | err = -ENOENT; | ||
| 694 | goto out; | ||
| 695 | } | ||
| 696 | |||
| 697 | /* | ||
| 698 | * Check whether another node removed the source inode while we | ||
| 699 | * were in the vfs. | ||
| 700 | */ | ||
| 701 | if (old_de_ino != OCFS2_I(inode)->ip_blkno) { | ||
| 702 | err = -ENOENT; | ||
| 703 | goto out; | ||
| 704 | } | ||
| 705 | |||
| 689 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, | 706 | err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, |
| 690 | dentry->d_name.len); | 707 | dentry->d_name.len); |
| 691 | if (err) | 708 | if (err) |
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c index 2ca7ba047f04..88d4585b30f1 100644 --- a/fs/proc/vmcore.c +++ b/fs/proc/vmcore.c | |||
| @@ -468,17 +468,24 @@ static int __init update_note_header_size_elf64(const Elf64_Ehdr *ehdr_ptr) | |||
| 468 | return rc; | 468 | return rc; |
| 469 | } | 469 | } |
| 470 | nhdr_ptr = notes_section; | 470 | nhdr_ptr = notes_section; |
| 471 | while (real_sz < max_sz) { | 471 | while (nhdr_ptr->n_namesz != 0) { |
| 472 | if (nhdr_ptr->n_namesz == 0) | ||
| 473 | break; | ||
| 474 | sz = sizeof(Elf64_Nhdr) + | 472 | sz = sizeof(Elf64_Nhdr) + |
| 475 | ((nhdr_ptr->n_namesz + 3) & ~3) + | 473 | ((nhdr_ptr->n_namesz + 3) & ~3) + |
| 476 | ((nhdr_ptr->n_descsz + 3) & ~3); | 474 | ((nhdr_ptr->n_descsz + 3) & ~3); |
| 475 | if ((real_sz + sz) > max_sz) { | ||
| 476 | pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", | ||
| 477 | nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); | ||
| 478 | break; | ||
| 479 | } | ||
| 477 | real_sz += sz; | 480 | real_sz += sz; |
| 478 | nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz); | 481 | nhdr_ptr = (Elf64_Nhdr*)((char*)nhdr_ptr + sz); |
| 479 | } | 482 | } |
| 480 | kfree(notes_section); | 483 | kfree(notes_section); |
| 481 | phdr_ptr->p_memsz = real_sz; | 484 | phdr_ptr->p_memsz = real_sz; |
| 485 | if (real_sz == 0) { | ||
| 486 | pr_warn("Warning: Zero PT_NOTE entries found\n"); | ||
| 487 | return -EINVAL; | ||
| 488 | } | ||
| 482 | } | 489 | } |
| 483 | 490 | ||
| 484 | return 0; | 491 | return 0; |
| @@ -648,17 +655,24 @@ static int __init update_note_header_size_elf32(const Elf32_Ehdr *ehdr_ptr) | |||
| 648 | return rc; | 655 | return rc; |
| 649 | } | 656 | } |
| 650 | nhdr_ptr = notes_section; | 657 | nhdr_ptr = notes_section; |
| 651 | while (real_sz < max_sz) { | 658 | while (nhdr_ptr->n_namesz != 0) { |
| 652 | if (nhdr_ptr->n_namesz == 0) | ||
| 653 | break; | ||
| 654 | sz = sizeof(Elf32_Nhdr) + | 659 | sz = sizeof(Elf32_Nhdr) + |
| 655 | ((nhdr_ptr->n_namesz + 3) & ~3) + | 660 | ((nhdr_ptr->n_namesz + 3) & ~3) + |
| 656 | ((nhdr_ptr->n_descsz + 3) & ~3); | 661 | ((nhdr_ptr->n_descsz + 3) & ~3); |
| 662 | if ((real_sz + sz) > max_sz) { | ||
| 663 | pr_warn("Warning: Exceeded p_memsz, dropping PT_NOTE entry n_namesz=0x%x, n_descsz=0x%x\n", | ||
| 664 | nhdr_ptr->n_namesz, nhdr_ptr->n_descsz); | ||
| 665 | break; | ||
| 666 | } | ||
| 657 | real_sz += sz; | 667 | real_sz += sz; |
| 658 | nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz); | 668 | nhdr_ptr = (Elf32_Nhdr*)((char*)nhdr_ptr + sz); |
| 659 | } | 669 | } |
| 660 | kfree(notes_section); | 670 | kfree(notes_section); |
| 661 | phdr_ptr->p_memsz = real_sz; | 671 | phdr_ptr->p_memsz = real_sz; |
| 672 | if (real_sz == 0) { | ||
| 673 | pr_warn("Warning: Zero PT_NOTE entries found\n"); | ||
| 674 | return -EINVAL; | ||
| 675 | } | ||
| 662 | } | 676 | } |
| 663 | 677 | ||
| 664 | return 0; | 678 | return 0; |
