]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/ceph/xattr.c
Merge branch 'mailbox-for-linus' of git://git.linaro.org/landing-teams/working/fujits...
[karo-tx-linux.git] / fs / ceph / xattr.c
index a87510f89ade074f802f5f3497e1de0db8b83599..678b0d2bbbc4d6d8eaaa4ee64a310b212aeda655 100644 (file)
@@ -1,4 +1,5 @@
 #include <linux/ceph/ceph_debug.h>
+#include <linux/ceph/pagelist.h>
 
 #include "super.h"
 #include "mds_client.h"
@@ -284,8 +285,7 @@ static size_t ceph_vxattrs_name_size(struct ceph_vxattr *vxattrs)
                return ceph_dir_vxattrs_name_size;
        if (vxattrs == ceph_file_vxattrs)
                return ceph_file_vxattrs_name_size;
-       BUG();
-
+       BUG_ON(vxattrs);
        return 0;
 }
 
@@ -851,35 +851,25 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name,
        struct ceph_inode_info *ci = ceph_inode(inode);
        struct ceph_mds_request *req;
        struct ceph_mds_client *mdsc = fsc->mdsc;
+       struct ceph_pagelist *pagelist = NULL;
        int err;
-       int i, nr_pages;
-       struct page **pages = NULL;
-       void *kaddr;
-
-       /* copy value into some pages */
-       nr_pages = calc_pages_for(0, size);
-       if (nr_pages) {
-               pages = kmalloc(sizeof(pages[0])*nr_pages, GFP_NOFS);
-               if (!pages)
+
+       if (value) {
+               /* copy value into pagelist */
+               pagelist = kmalloc(sizeof(*pagelist), GFP_NOFS);
+               if (!pagelist)
                        return -ENOMEM;
-               err = -ENOMEM;
-               for (i = 0; i < nr_pages; i++) {
-                       pages[i] = __page_cache_alloc(GFP_NOFS);
-                       if (!pages[i]) {
-                               nr_pages = i;
-                               goto out;
-                       }
-                       kaddr = kmap(pages[i]);
-                       memcpy(kaddr, value + i*PAGE_CACHE_SIZE,
-                              min(PAGE_CACHE_SIZE, size-i*PAGE_CACHE_SIZE));
-               }
+
+               ceph_pagelist_init(pagelist);
+               err = ceph_pagelist_append(pagelist, value, size);
+               if (err)
+                       goto out;
+       } else {
+               flags |= CEPH_XATTR_REMOVE;
        }
 
        dout("setxattr value=%.*s\n", (int)size, value);
 
-       if (!value)
-               flags |= CEPH_XATTR_REMOVE;
-
        /* do request */
        req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_SETXATTR,
                                       USE_AUTH_MDS);
@@ -894,9 +884,8 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name,
        req->r_args.setxattr.flags = cpu_to_le32(flags);
        req->r_path2 = kstrdup(name, GFP_NOFS);
 
-       req->r_pages = pages;
-       req->r_num_pages = nr_pages;
-       req->r_data_len = size;
+       req->r_pagelist = pagelist;
+       pagelist = NULL;
 
        dout("xattr.ver (before): %lld\n", ci->i_xattrs.version);
        err = ceph_mdsc_do_request(mdsc, NULL, req);
@@ -904,11 +893,8 @@ static int ceph_sync_setxattr(struct dentry *dentry, const char *name,
        dout("xattr.ver (after): %lld\n", ci->i_xattrs.version);
 
 out:
-       if (pages) {
-               for (i = 0; i < nr_pages; i++)
-                       __free_page(pages[i]);
-               kfree(pages);
-       }
+       if (pagelist)
+               ceph_pagelist_release(pagelist);
        return err;
 }