diff options
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/addr.c | 5 | ||||
-rw-r--r-- | fs/ceph/caps.c | 5 | ||||
-rw-r--r-- | fs/ceph/inode.c | 7 | ||||
-rw-r--r-- | fs/ceph/locks.c | 3 | ||||
-rw-r--r-- | fs/ceph/snap.c | 4 | ||||
-rw-r--r-- | fs/ceph/super.h | 2 | ||||
-rw-r--r-- | fs/ceph/xattr.c | 19 |
7 files changed, 30 insertions, 15 deletions
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index e078cc55b989..b3c8b886bf64 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
@@ -913,8 +913,9 @@ get_more_pages: | |||
913 | if (page_offset(page) >= ceph_wbc.i_size) { | 913 | if (page_offset(page) >= ceph_wbc.i_size) { |
914 | dout("%p page eof %llu\n", | 914 | dout("%p page eof %llu\n", |
915 | page, ceph_wbc.i_size); | 915 | page, ceph_wbc.i_size); |
916 | if (ceph_wbc.size_stable || | 916 | if ((ceph_wbc.size_stable || |
917 | page_offset(page) >= i_size_read(inode)) | 917 | page_offset(page) >= i_size_read(inode)) && |
918 | clear_page_dirty_for_io(page)) | ||
918 | mapping->a_ops->invalidatepage(page, | 919 | mapping->a_ops->invalidatepage(page, |
919 | 0, PAGE_SIZE); | 920 | 0, PAGE_SIZE); |
920 | unlock_page(page); | 921 | unlock_page(page); |
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index d98dcd976c80..ce0f5658720a 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -1301,6 +1301,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1301 | { | 1301 | { |
1302 | struct ceph_inode_info *ci = cap->ci; | 1302 | struct ceph_inode_info *ci = cap->ci; |
1303 | struct inode *inode = &ci->vfs_inode; | 1303 | struct inode *inode = &ci->vfs_inode; |
1304 | struct ceph_buffer *old_blob = NULL; | ||
1304 | struct cap_msg_args arg; | 1305 | struct cap_msg_args arg; |
1305 | int held, revoking; | 1306 | int held, revoking; |
1306 | int wake = 0; | 1307 | int wake = 0; |
@@ -1365,7 +1366,7 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1365 | ci->i_requested_max_size = arg.max_size; | 1366 | ci->i_requested_max_size = arg.max_size; |
1366 | 1367 | ||
1367 | if (flushing & CEPH_CAP_XATTR_EXCL) { | 1368 | if (flushing & CEPH_CAP_XATTR_EXCL) { |
1368 | __ceph_build_xattrs_blob(ci); | 1369 | old_blob = __ceph_build_xattrs_blob(ci); |
1369 | arg.xattr_version = ci->i_xattrs.version; | 1370 | arg.xattr_version = ci->i_xattrs.version; |
1370 | arg.xattr_buf = ci->i_xattrs.blob; | 1371 | arg.xattr_buf = ci->i_xattrs.blob; |
1371 | } else { | 1372 | } else { |
@@ -1409,6 +1410,8 @@ static int __send_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, | |||
1409 | 1410 | ||
1410 | spin_unlock(&ci->i_ceph_lock); | 1411 | spin_unlock(&ci->i_ceph_lock); |
1411 | 1412 | ||
1413 | ceph_buffer_put(old_blob); | ||
1414 | |||
1412 | ret = send_cap_msg(&arg); | 1415 | ret = send_cap_msg(&arg); |
1413 | if (ret < 0) { | 1416 | if (ret < 0) { |
1414 | dout("error sending cap msg, must requeue %p\n", inode); | 1417 | dout("error sending cap msg, must requeue %p\n", inode); |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 791f84a13bb8..18500edefc56 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -736,6 +736,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page, | |||
736 | int issued, new_issued, info_caps; | 736 | int issued, new_issued, info_caps; |
737 | struct timespec64 mtime, atime, ctime; | 737 | struct timespec64 mtime, atime, ctime; |
738 | struct ceph_buffer *xattr_blob = NULL; | 738 | struct ceph_buffer *xattr_blob = NULL; |
739 | struct ceph_buffer *old_blob = NULL; | ||
739 | struct ceph_string *pool_ns = NULL; | 740 | struct ceph_string *pool_ns = NULL; |
740 | struct ceph_cap *new_cap = NULL; | 741 | struct ceph_cap *new_cap = NULL; |
741 | int err = 0; | 742 | int err = 0; |
@@ -881,7 +882,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page, | |||
881 | if ((ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL)) && | 882 | if ((ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL)) && |
882 | le64_to_cpu(info->xattr_version) > ci->i_xattrs.version) { | 883 | le64_to_cpu(info->xattr_version) > ci->i_xattrs.version) { |
883 | if (ci->i_xattrs.blob) | 884 | if (ci->i_xattrs.blob) |
884 | ceph_buffer_put(ci->i_xattrs.blob); | 885 | old_blob = ci->i_xattrs.blob; |
885 | ci->i_xattrs.blob = xattr_blob; | 886 | ci->i_xattrs.blob = xattr_blob; |
886 | if (xattr_blob) | 887 | if (xattr_blob) |
887 | memcpy(ci->i_xattrs.blob->vec.iov_base, | 888 | memcpy(ci->i_xattrs.blob->vec.iov_base, |
@@ -1022,8 +1023,8 @@ static int fill_inode(struct inode *inode, struct page *locked_page, | |||
1022 | out: | 1023 | out: |
1023 | if (new_cap) | 1024 | if (new_cap) |
1024 | ceph_put_cap(mdsc, new_cap); | 1025 | ceph_put_cap(mdsc, new_cap); |
1025 | if (xattr_blob) | 1026 | ceph_buffer_put(old_blob); |
1026 | ceph_buffer_put(xattr_blob); | 1027 | ceph_buffer_put(xattr_blob); |
1027 | ceph_put_string(pool_ns); | 1028 | ceph_put_string(pool_ns); |
1028 | return err; | 1029 | return err; |
1029 | } | 1030 | } |
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index ac9b53b89365..5083e238ad15 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
@@ -111,8 +111,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct inode *inode, | |||
111 | req->r_wait_for_completion = ceph_lock_wait_for_completion; | 111 | req->r_wait_for_completion = ceph_lock_wait_for_completion; |
112 | 112 | ||
113 | err = ceph_mdsc_do_request(mdsc, inode, req); | 113 | err = ceph_mdsc_do_request(mdsc, inode, req); |
114 | 114 | if (!err && operation == CEPH_MDS_OP_GETFILELOCK) { | |
115 | if (operation == CEPH_MDS_OP_GETFILELOCK) { | ||
116 | fl->fl_pid = -le64_to_cpu(req->r_reply_info.filelock_reply->pid); | 115 | fl->fl_pid = -le64_to_cpu(req->r_reply_info.filelock_reply->pid); |
117 | if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type) | 116 | if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type) |
118 | fl->fl_type = F_RDLCK; | 117 | fl->fl_type = F_RDLCK; |
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index 4c6494eb02b5..ccfcc66aaf44 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c | |||
@@ -465,6 +465,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
465 | struct inode *inode = &ci->vfs_inode; | 465 | struct inode *inode = &ci->vfs_inode; |
466 | struct ceph_cap_snap *capsnap; | 466 | struct ceph_cap_snap *capsnap; |
467 | struct ceph_snap_context *old_snapc, *new_snapc; | 467 | struct ceph_snap_context *old_snapc, *new_snapc; |
468 | struct ceph_buffer *old_blob = NULL; | ||
468 | int used, dirty; | 469 | int used, dirty; |
469 | 470 | ||
470 | capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS); | 471 | capsnap = kzalloc(sizeof(*capsnap), GFP_NOFS); |
@@ -541,7 +542,7 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci) | |||
541 | capsnap->gid = inode->i_gid; | 542 | capsnap->gid = inode->i_gid; |
542 | 543 | ||
543 | if (dirty & CEPH_CAP_XATTR_EXCL) { | 544 | if (dirty & CEPH_CAP_XATTR_EXCL) { |
544 | __ceph_build_xattrs_blob(ci); | 545 | old_blob = __ceph_build_xattrs_blob(ci); |
545 | capsnap->xattr_blob = | 546 | capsnap->xattr_blob = |
546 | ceph_buffer_get(ci->i_xattrs.blob); | 547 | ceph_buffer_get(ci->i_xattrs.blob); |
547 | capsnap->xattr_version = ci->i_xattrs.version; | 548 | capsnap->xattr_version = ci->i_xattrs.version; |
@@ -584,6 +585,7 @@ update_snapc: | |||
584 | } | 585 | } |
585 | spin_unlock(&ci->i_ceph_lock); | 586 | spin_unlock(&ci->i_ceph_lock); |
586 | 587 | ||
588 | ceph_buffer_put(old_blob); | ||
587 | kfree(capsnap); | 589 | kfree(capsnap); |
588 | ceph_put_snap_context(old_snapc); | 590 | ceph_put_snap_context(old_snapc); |
589 | } | 591 | } |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index d2352fd95dbc..6b9f1ee7de85 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -926,7 +926,7 @@ extern int ceph_getattr(const struct path *path, struct kstat *stat, | |||
926 | int __ceph_setxattr(struct inode *, const char *, const void *, size_t, int); | 926 | int __ceph_setxattr(struct inode *, const char *, const void *, size_t, int); |
927 | ssize_t __ceph_getxattr(struct inode *, const char *, void *, size_t); | 927 | ssize_t __ceph_getxattr(struct inode *, const char *, void *, size_t); |
928 | extern ssize_t ceph_listxattr(struct dentry *, char *, size_t); | 928 | extern ssize_t ceph_listxattr(struct dentry *, char *, size_t); |
929 | extern void __ceph_build_xattrs_blob(struct ceph_inode_info *ci); | 929 | extern struct ceph_buffer *__ceph_build_xattrs_blob(struct ceph_inode_info *ci); |
930 | extern void __ceph_destroy_xattrs(struct ceph_inode_info *ci); | 930 | extern void __ceph_destroy_xattrs(struct ceph_inode_info *ci); |
931 | extern const struct xattr_handler *ceph_xattr_handlers[]; | 931 | extern const struct xattr_handler *ceph_xattr_handlers[]; |
932 | 932 | ||
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 37b458a9af3a..939eab7aa219 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -754,12 +754,15 @@ static int __get_required_blob_size(struct ceph_inode_info *ci, int name_size, | |||
754 | 754 | ||
755 | /* | 755 | /* |
756 | * If there are dirty xattrs, reencode xattrs into the prealloc_blob | 756 | * If there are dirty xattrs, reencode xattrs into the prealloc_blob |
757 | * and swap into place. | 757 | * and swap into place. It returns the old i_xattrs.blob (or NULL) so |
758 | * that it can be freed by the caller as the i_ceph_lock is likely to be | ||
759 | * held. | ||
758 | */ | 760 | */ |
759 | void __ceph_build_xattrs_blob(struct ceph_inode_info *ci) | 761 | struct ceph_buffer *__ceph_build_xattrs_blob(struct ceph_inode_info *ci) |
760 | { | 762 | { |
761 | struct rb_node *p; | 763 | struct rb_node *p; |
762 | struct ceph_inode_xattr *xattr = NULL; | 764 | struct ceph_inode_xattr *xattr = NULL; |
765 | struct ceph_buffer *old_blob = NULL; | ||
763 | void *dest; | 766 | void *dest; |
764 | 767 | ||
765 | dout("__build_xattrs_blob %p\n", &ci->vfs_inode); | 768 | dout("__build_xattrs_blob %p\n", &ci->vfs_inode); |
@@ -790,12 +793,14 @@ void __ceph_build_xattrs_blob(struct ceph_inode_info *ci) | |||
790 | dest - ci->i_xattrs.prealloc_blob->vec.iov_base; | 793 | dest - ci->i_xattrs.prealloc_blob->vec.iov_base; |
791 | 794 | ||
792 | if (ci->i_xattrs.blob) | 795 | if (ci->i_xattrs.blob) |
793 | ceph_buffer_put(ci->i_xattrs.blob); | 796 | old_blob = ci->i_xattrs.blob; |
794 | ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; | 797 | ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; |
795 | ci->i_xattrs.prealloc_blob = NULL; | 798 | ci->i_xattrs.prealloc_blob = NULL; |
796 | ci->i_xattrs.dirty = false; | 799 | ci->i_xattrs.dirty = false; |
797 | ci->i_xattrs.version++; | 800 | ci->i_xattrs.version++; |
798 | } | 801 | } |
802 | |||
803 | return old_blob; | ||
799 | } | 804 | } |
800 | 805 | ||
801 | static inline int __get_request_mask(struct inode *in) { | 806 | static inline int __get_request_mask(struct inode *in) { |
@@ -1036,6 +1041,7 @@ int __ceph_setxattr(struct inode *inode, const char *name, | |||
1036 | struct ceph_inode_info *ci = ceph_inode(inode); | 1041 | struct ceph_inode_info *ci = ceph_inode(inode); |
1037 | struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; | 1042 | struct ceph_mds_client *mdsc = ceph_sb_to_client(inode->i_sb)->mdsc; |
1038 | struct ceph_cap_flush *prealloc_cf = NULL; | 1043 | struct ceph_cap_flush *prealloc_cf = NULL; |
1044 | struct ceph_buffer *old_blob = NULL; | ||
1039 | int issued; | 1045 | int issued; |
1040 | int err; | 1046 | int err; |
1041 | int dirty = 0; | 1047 | int dirty = 0; |
@@ -1109,13 +1115,15 @@ retry: | |||
1109 | struct ceph_buffer *blob; | 1115 | struct ceph_buffer *blob; |
1110 | 1116 | ||
1111 | spin_unlock(&ci->i_ceph_lock); | 1117 | spin_unlock(&ci->i_ceph_lock); |
1112 | dout(" preaallocating new blob size=%d\n", required_blob_size); | 1118 | ceph_buffer_put(old_blob); /* Shouldn't be required */ |
1119 | dout(" pre-allocating new blob size=%d\n", required_blob_size); | ||
1113 | blob = ceph_buffer_new(required_blob_size, GFP_NOFS); | 1120 | blob = ceph_buffer_new(required_blob_size, GFP_NOFS); |
1114 | if (!blob) | 1121 | if (!blob) |
1115 | goto do_sync_unlocked; | 1122 | goto do_sync_unlocked; |
1116 | spin_lock(&ci->i_ceph_lock); | 1123 | spin_lock(&ci->i_ceph_lock); |
1124 | /* prealloc_blob can't be released while holding i_ceph_lock */ | ||
1117 | if (ci->i_xattrs.prealloc_blob) | 1125 | if (ci->i_xattrs.prealloc_blob) |
1118 | ceph_buffer_put(ci->i_xattrs.prealloc_blob); | 1126 | old_blob = ci->i_xattrs.prealloc_blob; |
1119 | ci->i_xattrs.prealloc_blob = blob; | 1127 | ci->i_xattrs.prealloc_blob = blob; |
1120 | goto retry; | 1128 | goto retry; |
1121 | } | 1129 | } |
@@ -1131,6 +1139,7 @@ retry: | |||
1131 | } | 1139 | } |
1132 | 1140 | ||
1133 | spin_unlock(&ci->i_ceph_lock); | 1141 | spin_unlock(&ci->i_ceph_lock); |
1142 | ceph_buffer_put(old_blob); | ||
1134 | if (lock_snap_rwsem) | 1143 | if (lock_snap_rwsem) |
1135 | up_read(&mdsc->snap_rwsem); | 1144 | up_read(&mdsc->snap_rwsem); |
1136 | if (dirty) | 1145 | if (dirty) |