diff options
Diffstat (limited to 'fs/ceph')
-rw-r--r-- | fs/ceph/buffer.c | 23 | ||||
-rw-r--r-- | fs/ceph/buffer.h | 20 | ||||
-rw-r--r-- | fs/ceph/inode.c | 11 | ||||
-rw-r--r-- | fs/ceph/messenger.c | 2 | ||||
-rw-r--r-- | fs/ceph/xattr.c | 8 |
5 files changed, 35 insertions, 29 deletions
diff --git a/fs/ceph/buffer.c b/fs/ceph/buffer.c index 847c5da9a0db..2576bd452cb8 100644 --- a/fs/ceph/buffer.c +++ b/fs/ceph/buffer.c | |||
@@ -2,23 +2,38 @@ | |||
2 | #include "ceph_debug.h" | 2 | #include "ceph_debug.h" |
3 | #include "buffer.h" | 3 | #include "buffer.h" |
4 | 4 | ||
5 | struct ceph_buffer *ceph_buffer_new(gfp_t gfp) | 5 | struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp) |
6 | { | 6 | { |
7 | struct ceph_buffer *b; | 7 | struct ceph_buffer *b; |
8 | 8 | ||
9 | b = kmalloc(sizeof(*b), gfp); | 9 | b = kmalloc(sizeof(*b), gfp); |
10 | if (!b) | 10 | if (!b) |
11 | return NULL; | 11 | return NULL; |
12 | |||
13 | b->vec.iov_base = kmalloc(len, gfp | __GFP_NOWARN); | ||
14 | if (b->vec.iov_base) { | ||
15 | b->is_vmalloc = false; | ||
16 | } else { | ||
17 | b->vec.iov_base = __vmalloc(len, gfp, PAGE_KERNEL); | ||
18 | if (!b->vec.iov_base) { | ||
19 | kfree(b); | ||
20 | return NULL; | ||
21 | } | ||
22 | b->is_vmalloc = true; | ||
23 | } | ||
24 | |||
12 | kref_init(&b->kref); | 25 | kref_init(&b->kref); |
13 | b->vec.iov_base = NULL; | 26 | b->alloc_len = len; |
14 | b->vec.iov_len = 0; | 27 | b->vec.iov_len = len; |
15 | b->alloc_len = 0; | 28 | dout("buffer_new %p\n", b); |
16 | return b; | 29 | return b; |
17 | } | 30 | } |
18 | 31 | ||
19 | void ceph_buffer_release(struct kref *kref) | 32 | void ceph_buffer_release(struct kref *kref) |
20 | { | 33 | { |
21 | struct ceph_buffer *b = container_of(kref, struct ceph_buffer, kref); | 34 | struct ceph_buffer *b = container_of(kref, struct ceph_buffer, kref); |
35 | |||
36 | dout("buffer_release %p\n", b); | ||
22 | if (b->vec.iov_base) { | 37 | if (b->vec.iov_base) { |
23 | if (b->is_vmalloc) | 38 | if (b->is_vmalloc) |
24 | vfree(b->vec.iov_base); | 39 | vfree(b->vec.iov_base); |
diff --git a/fs/ceph/buffer.h b/fs/ceph/buffer.h index 3f541a13094f..47b9514c5bbd 100644 --- a/fs/ceph/buffer.h +++ b/fs/ceph/buffer.h | |||
@@ -20,8 +20,8 @@ struct ceph_buffer { | |||
20 | bool is_vmalloc; | 20 | bool is_vmalloc; |
21 | }; | 21 | }; |
22 | 22 | ||
23 | struct ceph_buffer *ceph_buffer_new(gfp_t gfp); | 23 | extern struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp); |
24 | int ceph_buffer_alloc(struct ceph_buffer *b, int len, gfp_t gfp); | 24 | extern void ceph_buffer_release(struct kref *kref); |
25 | 25 | ||
26 | static inline struct ceph_buffer *ceph_buffer_get(struct ceph_buffer *b) | 26 | static inline struct ceph_buffer *ceph_buffer_get(struct ceph_buffer *b) |
27 | { | 27 | { |
@@ -29,23 +29,9 @@ static inline struct ceph_buffer *ceph_buffer_get(struct ceph_buffer *b) | |||
29 | return b; | 29 | return b; |
30 | } | 30 | } |
31 | 31 | ||
32 | void ceph_buffer_release(struct kref *kref); | ||
33 | |||
34 | static inline void ceph_buffer_put(struct ceph_buffer *b) | 32 | static inline void ceph_buffer_put(struct ceph_buffer *b) |
35 | { | 33 | { |
36 | if (b) | 34 | kref_put(&b->kref, ceph_buffer_release); |
37 | kref_put(&b->kref, ceph_buffer_release); | ||
38 | } | ||
39 | |||
40 | static inline struct ceph_buffer *ceph_buffer_new_alloc(int len, gfp_t gfp) | ||
41 | { | ||
42 | struct ceph_buffer *b = ceph_buffer_new(gfp); | ||
43 | |||
44 | if (b && ceph_buffer_alloc(b, len, gfp) < 0) { | ||
45 | ceph_buffer_put(b); | ||
46 | b = NULL; | ||
47 | } | ||
48 | return b; | ||
49 | } | 35 | } |
50 | 36 | ||
51 | #endif | 37 | #endif |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 074ee42bd344..db684686f48a 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -383,8 +383,10 @@ void ceph_destroy_inode(struct inode *inode) | |||
383 | } | 383 | } |
384 | 384 | ||
385 | __ceph_destroy_xattrs(ci); | 385 | __ceph_destroy_xattrs(ci); |
386 | ceph_buffer_put(ci->i_xattrs.blob); | 386 | if (ci->i_xattrs.blob) |
387 | ceph_buffer_put(ci->i_xattrs.prealloc_blob); | 387 | ceph_buffer_put(ci->i_xattrs.blob); |
388 | if (ci->i_xattrs.prealloc_blob) | ||
389 | ceph_buffer_put(ci->i_xattrs.prealloc_blob); | ||
388 | 390 | ||
389 | kmem_cache_free(ceph_inode_cachep, ci); | 391 | kmem_cache_free(ceph_inode_cachep, ci); |
390 | } | 392 | } |
@@ -526,7 +528,7 @@ static int fill_inode(struct inode *inode, | |||
526 | * bytes are the xattr count). | 528 | * bytes are the xattr count). |
527 | */ | 529 | */ |
528 | if (iinfo->xattr_len > 4) { | 530 | if (iinfo->xattr_len > 4) { |
529 | xattr_blob = ceph_buffer_new_alloc(iinfo->xattr_len, GFP_NOFS); | 531 | xattr_blob = ceph_buffer_new(iinfo->xattr_len, GFP_NOFS); |
530 | if (!xattr_blob) | 532 | if (!xattr_blob) |
531 | pr_err("fill_inode ENOMEM xattr blob %d bytes\n", | 533 | pr_err("fill_inode ENOMEM xattr blob %d bytes\n", |
532 | iinfo->xattr_len); | 534 | iinfo->xattr_len); |
@@ -715,7 +717,8 @@ no_change: | |||
715 | err = 0; | 717 | err = 0; |
716 | 718 | ||
717 | out: | 719 | out: |
718 | ceph_buffer_put(xattr_blob); | 720 | if (xattr_blob) |
721 | ceph_buffer_put(xattr_blob); | ||
719 | return err; | 722 | return err; |
720 | } | 723 | } |
721 | 724 | ||
diff --git a/fs/ceph/messenger.c b/fs/ceph/messenger.c index 45cec31fdf5e..bf762107b3d5 100644 --- a/fs/ceph/messenger.c +++ b/fs/ceph/messenger.c | |||
@@ -2047,7 +2047,7 @@ int ceph_alloc_middle(struct ceph_connection *con, struct ceph_msg *msg) | |||
2047 | BUG_ON(!middle_len); | 2047 | BUG_ON(!middle_len); |
2048 | BUG_ON(msg->middle); | 2048 | BUG_ON(msg->middle); |
2049 | 2049 | ||
2050 | msg->middle = ceph_buffer_new_alloc(middle_len, GFP_NOFS); | 2050 | msg->middle = ceph_buffer_new(middle_len, GFP_NOFS); |
2051 | if (!msg->middle) | 2051 | if (!msg->middle) |
2052 | return -ENOMEM; | 2052 | return -ENOMEM; |
2053 | return 0; | 2053 | return 0; |
diff --git a/fs/ceph/xattr.c b/fs/ceph/xattr.c index 04769a3ab832..37d6ce645691 100644 --- a/fs/ceph/xattr.c +++ b/fs/ceph/xattr.c | |||
@@ -482,7 +482,8 @@ void __ceph_build_xattrs_blob(struct ceph_inode_info *ci) | |||
482 | ci->i_xattrs.prealloc_blob->vec.iov_len = | 482 | ci->i_xattrs.prealloc_blob->vec.iov_len = |
483 | dest - ci->i_xattrs.prealloc_blob->vec.iov_base; | 483 | dest - ci->i_xattrs.prealloc_blob->vec.iov_base; |
484 | 484 | ||
485 | ceph_buffer_put(ci->i_xattrs.blob); | 485 | if (ci->i_xattrs.blob) |
486 | ceph_buffer_put(ci->i_xattrs.blob); | ||
486 | ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; | 487 | ci->i_xattrs.blob = ci->i_xattrs.prealloc_blob; |
487 | ci->i_xattrs.prealloc_blob = NULL; | 488 | ci->i_xattrs.prealloc_blob = NULL; |
488 | ci->i_xattrs.dirty = false; | 489 | ci->i_xattrs.dirty = false; |
@@ -745,11 +746,12 @@ retry: | |||
745 | 746 | ||
746 | spin_unlock(&inode->i_lock); | 747 | spin_unlock(&inode->i_lock); |
747 | dout(" preaallocating new blob size=%d\n", required_blob_size); | 748 | dout(" preaallocating new blob size=%d\n", required_blob_size); |
748 | blob = ceph_buffer_new_alloc(required_blob_size, GFP_NOFS); | 749 | blob = ceph_buffer_new(required_blob_size, GFP_NOFS); |
749 | if (!blob) | 750 | if (!blob) |
750 | goto out; | 751 | goto out; |
751 | spin_lock(&inode->i_lock); | 752 | spin_lock(&inode->i_lock); |
752 | ceph_buffer_put(ci->i_xattrs.prealloc_blob); | 753 | if (ci->i_xattrs.prealloc_blob) |
754 | ceph_buffer_put(ci->i_xattrs.prealloc_blob); | ||
753 | ci->i_xattrs.prealloc_blob = blob; | 755 | ci->i_xattrs.prealloc_blob = blob; |
754 | goto retry; | 756 | goto retry; |
755 | } | 757 | } |