aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/buffer.c23
-rw-r--r--fs/ceph/buffer.h20
-rw-r--r--fs/ceph/inode.c11
-rw-r--r--fs/ceph/messenger.c2
-rw-r--r--fs/ceph/xattr.c8
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
5struct ceph_buffer *ceph_buffer_new(gfp_t gfp) 5struct 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
19void ceph_buffer_release(struct kref *kref) 32void 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
23struct ceph_buffer *ceph_buffer_new(gfp_t gfp); 23extern struct ceph_buffer *ceph_buffer_new(size_t len, gfp_t gfp);
24int ceph_buffer_alloc(struct ceph_buffer *b, int len, gfp_t gfp); 24extern void ceph_buffer_release(struct kref *kref);
25 25
26static inline struct ceph_buffer *ceph_buffer_get(struct ceph_buffer *b) 26static 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
32void ceph_buffer_release(struct kref *kref);
33
34static inline void ceph_buffer_put(struct ceph_buffer *b) 32static 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
40static 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
717out: 719out:
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 }