osd_req->r_callback = rbd_osd_req_callback;
        osd_req->r_priv = obj_request;
 
-       osd_req->r_base_oloc.pool = ceph_file_layout_pg_pool(rbd_dev->layout);
+       osd_req->r_base_oloc.pool = rbd_dev->layout.pool_id;
        if (ceph_oid_aprintf(&osd_req->r_base_oid, GFP_NOIO, "%s",
                             obj_request->object_name))
                goto fail;
        osd_req->r_callback = rbd_osd_req_callback;
        osd_req->r_priv = obj_request;
 
-       osd_req->r_base_oloc.pool = ceph_file_layout_pg_pool(rbd_dev->layout);
+       osd_req->r_base_oloc.pool = rbd_dev->layout.pool_id;
        if (ceph_oid_aprintf(&osd_req->r_base_oid, GFP_NOIO, "%s",
                             obj_request->object_name))
                goto fail;
 
        /* Initialize the layout used for all rbd requests */
 
-       rbd_dev->layout.fl_stripe_unit = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER);
-       rbd_dev->layout.fl_stripe_count = cpu_to_le32(1);
-       rbd_dev->layout.fl_object_size = cpu_to_le32(1 << RBD_MAX_OBJ_ORDER);
-       rbd_dev->layout.fl_pg_pool = cpu_to_le32((u32) spec->pool_id);
+       rbd_dev->layout.stripe_unit = 1 << RBD_MAX_OBJ_ORDER;
+       rbd_dev->layout.stripe_count = 1;
+       rbd_dev->layout.object_size = 1 << RBD_MAX_OBJ_ORDER;
+       rbd_dev->layout.pool_id = spec->pool_id;
 
        /*
         * If this is a mapping rbd_dev (as opposed to a parent one),
 
        rbd_assert(rbd_image_format_valid(rbd_dev->image_format));
 
-       rbd_dev->header_oloc.pool = ceph_file_layout_pg_pool(rbd_dev->layout);
+       rbd_dev->header_oloc.pool = rbd_dev->layout.pool_id;
        if (rbd_dev->image_format == 1)
                ret = ceph_oid_aprintf(&rbd_dev->header_oid, GFP_KERNEL, "%s%s",
                                       spec->image_name, RBD_SUFFIX);
 
        POOL_WRITE      = 2,
 };
 
-static int __ceph_pool_perm_get(struct ceph_inode_info *ci, u32 pool)
+static int __ceph_pool_perm_get(struct ceph_inode_info *ci, s64 pool)
 {
        struct ceph_fs_client *fsc = ceph_inode_to_client(&ci->vfs_inode);
        struct ceph_mds_client *mdsc = fsc->mdsc;
        if (*p)
                goto out;
 
-       dout("__ceph_pool_perm_get pool %u no perm cached\n", pool);
+       dout("__ceph_pool_perm_get pool %lld no perm cached\n", pool);
 
        down_write(&mdsc->pool_perm_rwsem);
        parent = NULL;
 out:
        if (!err)
                err = have;
-       dout("__ceph_pool_perm_get pool %u result = %d\n", pool, err);
+       dout("__ceph_pool_perm_get pool %lld result = %d\n", pool, err);
        return err;
 }
 
 int ceph_pool_perm_check(struct ceph_inode_info *ci, int need)
 {
-       u32 pool;
+       s64 pool;
        int ret, flags;
 
        /* does not support pool namespace yet */
 
        spin_lock(&ci->i_ceph_lock);
        flags = ci->i_ceph_flags;
-       pool = ceph_file_layout_pg_pool(ci->i_layout);
+       pool = ci->i_layout.pool_id;
        spin_unlock(&ci->i_ceph_lock);
 check:
        if (flags & CEPH_I_POOL_PERM) {
                if ((need & CEPH_CAP_FILE_RD) && !(flags & CEPH_I_POOL_RD)) {
-                       dout("ceph_pool_perm_check pool %u no read perm\n",
+                       dout("ceph_pool_perm_check pool %lld no read perm\n",
                             pool);
                        return -EPERM;
                }
                if ((need & CEPH_CAP_FILE_WR) && !(flags & CEPH_I_POOL_WR)) {
-                       dout("ceph_pool_perm_check pool %u no write perm\n",
+                       dout("ceph_pool_perm_check pool %lld no write perm\n",
                             pool);
                        return -EPERM;
                }
                flags |= CEPH_I_POOL_WR;
 
        spin_lock(&ci->i_ceph_lock);
-       if (pool == ceph_file_layout_pg_pool(ci->i_layout)) {
+       if (pool == ci->i_layout.pool_id) {
                ci->i_ceph_flags = flags;
         } else {
-               pool = ceph_file_layout_pg_pool(ci->i_layout);
+               pool = ci->i_layout.pool_id;
                flags = ci->i_ceph_flags;
        }
        spin_unlock(&ci->i_ceph_lock);
 
 
        if (newcaps & (CEPH_CAP_ANY_FILE_RD | CEPH_CAP_ANY_FILE_WR)) {
                /* file layout may have changed */
-               ci->i_layout = grant->layout;
+               s64 old_pool = ci->i_layout.pool_id;
+               ceph_file_layout_from_legacy(&ci->i_layout, &grant->layout);
                ci->i_pool_ns_len = pool_ns_len;
+               if (ci->i_layout.pool_id != old_pool)
+                       ci->i_ceph_flags &= ~CEPH_I_POOL_PERM;
 
                /* size/truncate_seq? */
                queue_trunc = ceph_fill_file_size(inode, issued,
 
 {
        int ret = 0;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       s32 stripe_unit = ceph_file_layout_su(ci->i_layout);
-       s32 stripe_count = ceph_file_layout_stripe_count(ci->i_layout);
-       s32 object_size = ceph_file_layout_object_size(ci->i_layout);
+       s32 stripe_unit = ci->i_layout.stripe_unit;
+       s32 stripe_count = ci->i_layout.stripe_count;
+       s32 object_size = ci->i_layout.object_size;
        u64 object_set_size = object_size * stripe_count;
        u64 nearly, t;
 
 
 
        if (new_version ||
            (new_issued & (CEPH_CAP_ANY_FILE_RD | CEPH_CAP_ANY_FILE_WR))) {
-               if (ci->i_layout.fl_pg_pool != info->layout.fl_pg_pool)
-                       ci->i_ceph_flags &= ~CEPH_I_POOL_PERM;
-               ci->i_layout = info->layout;
+               s64 old_pool = ci->i_layout.pool_id;
+               ceph_file_layout_from_legacy(&ci->i_layout, &info->layout);
                ci->i_pool_ns_len = iinfo->pool_ns_len;
+               if (ci->i_layout.pool_id != old_pool)
+                       ci->i_ceph_flags &= ~CEPH_I_POOL_PERM;
 
                queue_trunc = ceph_fill_file_size(inode, issued,
                                        le32_to_cpu(info->truncate_seq),
 
 
        err = ceph_do_getattr(file_inode(file), CEPH_STAT_CAP_LAYOUT, false);
        if (!err) {
-               l.stripe_unit = ceph_file_layout_su(ci->i_layout);
-               l.stripe_count = ceph_file_layout_stripe_count(ci->i_layout);
-               l.object_size = ceph_file_layout_object_size(ci->i_layout);
-               l.data_pool = le32_to_cpu(ci->i_layout.fl_pg_pool);
+               l.stripe_unit = ci->i_layout.stripe_unit;
+               l.stripe_count = ci->i_layout.stripe_count;
+               l.object_size = ci->i_layout.object_size;
+               l.data_pool = ci->i_layout.pool_id;
                l.preferred_osd = (s32)-1;
                if (copy_to_user(arg, &l, sizeof(l)))
                        return -EFAULT;
        if (l.stripe_count)
                nl.stripe_count = l.stripe_count;
        else
-               nl.stripe_count = ceph_file_layout_stripe_count(ci->i_layout);
+               nl.stripe_count = ci->i_layout.stripe_count;
        if (l.stripe_unit)
                nl.stripe_unit = l.stripe_unit;
        else
-               nl.stripe_unit = ceph_file_layout_su(ci->i_layout);
+               nl.stripe_unit = ci->i_layout.stripe_unit;
        if (l.object_size)
                nl.object_size = l.object_size;
        else
-               nl.object_size = ceph_file_layout_object_size(ci->i_layout);
+               nl.object_size = ci->i_layout.object_size;
        if (l.data_pool)
                nl.data_pool = l.data_pool;
        else
-               nl.data_pool = ceph_file_layout_pg_pool(ci->i_layout);
+               nl.data_pool = ci->i_layout.pool_id;
 
        /* this is obsolete, and always -1 */
        nl.preferred_osd = le64_to_cpu(-1);
                return -EIO;
        }
        dl.file_offset -= dl.object_offset;
-       dl.object_size = ceph_file_layout_object_size(ci->i_layout);
-       dl.block_size = ceph_file_layout_su(ci->i_layout);
+       dl.object_size = ci->i_layout.object_size;
+       dl.block_size = ci->i_layout.stripe_unit;
 
        /* block_offset = object_offset % block_size */
        tmp = dl.object_offset;
        snprintf(dl.object_name, sizeof(dl.object_name), "%llx.%08llx",
                 ceph_ino(inode), dl.object_no);
 
-       oloc.pool = ceph_file_layout_pg_pool(ci->i_layout);
+       oloc.pool = ci->i_layout.pool_id;
        ceph_oid_printf(&oid, "%s", dl.object_name);
 
        r = ceph_object_locator_to_pg(osdc->osdmap, &oid, &oloc, &pgid);
 
 
 struct ceph_pool_perm {
        struct rb_node node;
-       u32 pool;
        int perm;
+       s64 pool;
 };
 
 /*
 
        int ret;
        struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb);
        struct ceph_osd_client *osdc = &fsc->client->osdc;
-       s64 pool = ceph_file_layout_pg_pool(ci->i_layout);
+       s64 pool = ci->i_layout.pool_id;
        const char *pool_name;
        char buf[128];
 
        if (pool_name) {
                size_t len = strlen(pool_name);
                ret = snprintf(buf, sizeof(buf),
-               "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=",
-               (unsigned long long)ceph_file_layout_su(ci->i_layout),
-               (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout),
-               (unsigned long long)ceph_file_layout_object_size(ci->i_layout));
+               "stripe_unit=%u stripe_count=%u object_size=%u pool=",
+               ci->i_layout.stripe_unit, ci->i_layout.stripe_count,
+               ci->i_layout.object_size);
                if (!size) {
                        ret += len;
                } else if (ret + len > size) {
                }
        } else {
                ret = snprintf(buf, sizeof(buf),
-               "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=%lld",
-               (unsigned long long)ceph_file_layout_su(ci->i_layout),
-               (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout),
-               (unsigned long long)ceph_file_layout_object_size(ci->i_layout),
-               (unsigned long long)pool);
+               "stripe_unit=%u stripe_count=%u object_size=%u pool=%lld",
+               ci->i_layout.stripe_unit, ci->i_layout.stripe_count,
+               ci->i_layout.object_size, (unsigned long long)pool);
                if (size) {
                        if (ret <= size)
                                memcpy(val, buf, ret);
 static size_t ceph_vxattrcb_layout_stripe_unit(struct ceph_inode_info *ci,
                                               char *val, size_t size)
 {
-       return snprintf(val, size, "%lld",
-                       (unsigned long long)ceph_file_layout_su(ci->i_layout));
+       return snprintf(val, size, "%u", ci->i_layout.stripe_unit);
 }
 
 static size_t ceph_vxattrcb_layout_stripe_count(struct ceph_inode_info *ci,
                                                char *val, size_t size)
 {
-       return snprintf(val, size, "%lld",
-              (unsigned long long)ceph_file_layout_stripe_count(ci->i_layout));
+       return snprintf(val, size, "%u", ci->i_layout.stripe_count);
 }
 
 static size_t ceph_vxattrcb_layout_object_size(struct ceph_inode_info *ci,
                                               char *val, size_t size)
 {
-       return snprintf(val, size, "%lld",
-              (unsigned long long)ceph_file_layout_object_size(ci->i_layout));
+       return snprintf(val, size, "%u", ci->i_layout.object_size);
 }
 
 static size_t ceph_vxattrcb_layout_pool(struct ceph_inode_info *ci,
        int ret;
        struct ceph_fs_client *fsc = ceph_sb_to_client(ci->vfs_inode.i_sb);
        struct ceph_osd_client *osdc = &fsc->client->osdc;
-       s64 pool = ceph_file_layout_pg_pool(ci->i_layout);
+       s64 pool = ci->i_layout.pool_id;
        const char *pool_name;
 
        down_read(&osdc->lock);
 
 #define CEPH_MAX_MON   31
 
 /*
- * ceph_file_layout - describe data layout for a file/inode
+ * legacy ceph_file_layoute
  */
-struct ceph_file_layout {
+struct ceph_file_layout_legacy {
        /* file -> object mapping */
        __le32 fl_stripe_unit;     /* stripe unit, in bytes.  must be multiple
                                      of page size. */
        __le32 fl_pg_pool;      /* namespace, crush ruleset, rep level */
 } __attribute__ ((packed));
 
-#define ceph_file_layout_su(l) ((__s32)le32_to_cpu((l).fl_stripe_unit))
-#define ceph_file_layout_stripe_count(l) \
-       ((__s32)le32_to_cpu((l).fl_stripe_count))
-#define ceph_file_layout_object_size(l) ((__s32)le32_to_cpu((l).fl_object_size))
-#define ceph_file_layout_cas_hash(l) ((__s32)le32_to_cpu((l).fl_cas_hash))
-#define ceph_file_layout_object_su(l) \
-       ((__s32)le32_to_cpu((l).fl_object_stripe_unit))
-#define ceph_file_layout_pg_pool(l) \
-       ((__s32)le32_to_cpu((l).fl_pg_pool))
-
-static inline unsigned ceph_file_layout_stripe_width(struct ceph_file_layout *l)
-{
-       return le32_to_cpu(l->fl_stripe_unit) *
-               le32_to_cpu(l->fl_stripe_count);
-}
-
-/* "period" == bytes before i start on a new set of objects */
-static inline unsigned ceph_file_layout_period(struct ceph_file_layout *l)
-{
-       return le32_to_cpu(l->fl_object_size) *
-               le32_to_cpu(l->fl_stripe_count);
-}
+/*
+ * ceph_file_layout - describe data layout for a file/inode
+ */
+struct ceph_file_layout {
+       /* file -> object mapping */
+       u32 stripe_unit;   /* stripe unit, in bytes */
+       u32 stripe_count;  /* over this many objects */
+       u32 object_size;   /* until objects are this big */
+       s64 pool_id;        /* rados pool id */
+};
+
+extern int ceph_file_layout_is_valid(const struct ceph_file_layout *layout);
+extern void ceph_file_layout_from_legacy(struct ceph_file_layout *fl,
+                               struct ceph_file_layout_legacy *legacy);
+extern void ceph_file_layout_to_legacy(struct ceph_file_layout *fl,
+                               struct ceph_file_layout_legacy *legacy);
 
 #define CEPH_MIN_STRIPE_UNIT 65536
 
-int ceph_file_layout_is_valid(const struct ceph_file_layout *layout);
-
 struct ceph_dir_layout {
        __u8   dl_dir_hash;   /* see ceph_hash.h for ids */
        __u8   dl_unused1;
                __le32 flags;
        } __attribute__ ((packed)) setxattr;
        struct {
-               struct ceph_file_layout layout;
+               struct ceph_file_layout_legacy layout;
        } __attribute__ ((packed)) setlayout;
        struct {
                __u8 rule; /* currently fcntl or flock */
        __le64 version;                /* inode version */
        __le64 xattr_version;          /* version for xattr blob */
        struct ceph_mds_reply_cap cap; /* caps issued for this inode */
-       struct ceph_file_layout layout;
+       struct ceph_file_layout_legacy layout;
        struct ceph_timespec ctime, mtime, atime;
        __le32 time_warp_seq;
        __le64 size, max_size, truncate_size;
        __le64 size, max_size, truncate_size;
        __le32 truncate_seq;
        struct ceph_timespec mtime, atime, ctime;
-       struct ceph_file_layout layout;
+       struct ceph_file_layout_legacy layout;
        __le32 time_warp_seq;
 } __attribute__ ((packed));
 
 
  */
 int ceph_file_layout_is_valid(const struct ceph_file_layout *layout)
 {
-       __u32 su = le32_to_cpu(layout->fl_stripe_unit);
-       __u32 sc = le32_to_cpu(layout->fl_stripe_count);
-       __u32 os = le32_to_cpu(layout->fl_object_size);
+       __u32 su = layout->stripe_unit;
+       __u32 sc = layout->stripe_count;
+       __u32 os = layout->object_size;
 
        /* stripe unit, object size must be non-zero, 64k increment */
        if (!su || (su & (CEPH_MIN_STRIPE_UNIT-1)))
        return 1;
 }
 
+void ceph_file_layout_from_legacy(struct ceph_file_layout *fl,
+                                 struct ceph_file_layout_legacy *legacy)
+{
+       fl->stripe_unit = le32_to_cpu(legacy->fl_stripe_unit);
+       fl->stripe_count = le32_to_cpu(legacy->fl_stripe_count);
+       fl->object_size = le32_to_cpu(legacy->fl_object_size);
+       fl->pool_id = le32_to_cpu(legacy->fl_pg_pool);
+       if (fl->pool_id == 0)
+               fl->pool_id = -1;
+}
+EXPORT_SYMBOL(ceph_file_layout_from_legacy);
+
+void ceph_file_layout_to_legacy(struct ceph_file_layout *fl,
+                               struct ceph_file_layout_legacy *legacy)
+{
+       legacy->fl_stripe_unit = cpu_to_le32(fl->stripe_unit);
+       legacy->fl_stripe_count = cpu_to_le32(fl->stripe_count);
+       legacy->fl_object_size = cpu_to_le32(fl->object_size);
+       if (fl->pool_id >= 0)
+               legacy->fl_pg_pool = cpu_to_le32(fl->pool_id);
+       else
+               legacy->fl_pg_pool = 0;
+}
+EXPORT_SYMBOL(ceph_file_layout_to_legacy);
 
 int ceph_flags_to_mode(int flags)
 {
 
        if (opcode == CEPH_OSD_OP_CREATE || opcode == CEPH_OSD_OP_DELETE) {
                osd_req_op_init(req, which, opcode, 0);
        } else {
-               u32 object_size = le32_to_cpu(layout->fl_object_size);
+               u32 object_size = layout->object_size;
                u32 object_base = off - objoff;
                if (!(truncate_seq == 1 && truncate_size == -1ULL)) {
                        if (truncate_size <= object_base) {
        }
 
        req->r_flags = flags;
-       req->r_base_oloc.pool = ceph_file_layout_pg_pool(*layout);
+       req->r_base_oloc.pool = layout->pool_id;
        ceph_oid_printf(&req->r_base_oid, "%llx.%08llx", vino.ino, objnum);
 
        req->r_snapid = vino.snap;
 
                                   u64 *ono,
                                   u64 *oxoff, u64 *oxlen)
 {
-       u32 osize = le32_to_cpu(layout->fl_object_size);
-       u32 su = le32_to_cpu(layout->fl_stripe_unit);
-       u32 sc = le32_to_cpu(layout->fl_stripe_count);
+       u32 osize = layout->object_size;
+       u32 su = layout->stripe_unit;
+       u32 sc = layout->stripe_count;
        u32 bl, stripeno, stripepos, objsetno;
        u32 su_per_object;
        u64 t, su_offset;