]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/ceph/xattr.c
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi...
[karo-tx-linux.git] / fs / ceph / xattr.c
index 87b85f3403d4d8411c1328599a6a6760d9d59c4f..9b6b2b6dd164c5fd047f691a68aac03fd8de69d5 100644 (file)
@@ -33,6 +33,90 @@ struct ceph_vxattr {
        bool (*exists_cb)(struct ceph_inode_info *ci);
 };
 
+/* layouts */
+
+static bool ceph_vxattrcb_layout_exists(struct ceph_inode_info *ci)
+{
+       size_t s;
+       char *p = (char *)&ci->i_layout;
+
+       for (s = 0; s < sizeof(ci->i_layout); s++, p++)
+               if (*p)
+                       return true;
+       return false;
+}
+
+static size_t ceph_vxattrcb_layout(struct ceph_inode_info *ci, char *val,
+                                       size_t size)
+{
+       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);
+       const char *pool_name;
+
+       dout("ceph_vxattrcb_layout %p\n", &ci->vfs_inode);
+       down_read(&osdc->map_sem);
+       pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, pool);
+       if (pool_name)
+               ret = snprintf(val, size,
+               "stripe_unit=%lld stripe_count=%lld object_size=%lld pool=%s",
+               (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),
+               pool_name);
+       else
+               ret = snprintf(val, size,
+               "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);
+
+       up_read(&osdc->map_sem);
+       return 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));
+}
+
+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));
+}
+
+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));
+}
+
+static size_t ceph_vxattrcb_layout_pool(struct ceph_inode_info *ci,
+                                       char *val, size_t size)
+{
+       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);
+       const char *pool_name;
+
+       down_read(&osdc->map_sem);
+       pool_name = ceph_pg_pool_name_by_id(osdc->osdmap, pool);
+       if (pool_name)
+               ret = snprintf(val, size, "%s", pool_name);
+       else
+               ret = snprintf(val, size, "%lld", (unsigned long long)pool);
+       up_read(&osdc->map_sem);
+       return ret;
+}
+
 /* directories */
 
 static size_t ceph_vxattrcb_dir_entries(struct ceph_inode_info *ci, char *val,
@@ -84,7 +168,10 @@ static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val,
                        (long)ci->i_rctime.tv_nsec);
 }
 
+
 #define CEPH_XATTR_NAME(_type, _name)  XATTR_CEPH_PREFIX #_type "." #_name
+#define CEPH_XATTR_NAME2(_type, _name, _name2) \
+       XATTR_CEPH_PREFIX #_type "." #_name "." #_name2
 
 #define XATTR_NAME_CEPH(_type, _name)                                  \
        {                                                               \
@@ -95,8 +182,29 @@ static size_t ceph_vxattrcb_dir_rctime(struct ceph_inode_info *ci, char *val,
                .hidden = false,                                \
                .exists_cb = NULL,                      \
        }
+#define XATTR_LAYOUT_FIELD(_type, _name, _field)                       \
+       {                                                               \
+               .name = CEPH_XATTR_NAME2(_type, _name, _field), \
+               .name_size = sizeof (CEPH_XATTR_NAME2(_type, _name, _field)), \
+               .getxattr_cb = ceph_vxattrcb_ ## _name ## _ ## _field, \
+               .readonly = false,                              \
+               .hidden = true,                 \
+               .exists_cb = ceph_vxattrcb_layout_exists,       \
+       }
 
 static struct ceph_vxattr ceph_dir_vxattrs[] = {
+       {
+               .name = "ceph.dir.layout",
+               .name_size = sizeof("ceph.dir.layout"),
+               .getxattr_cb = ceph_vxattrcb_layout,
+               .readonly = false,
+               .hidden = false,
+               .exists_cb = ceph_vxattrcb_layout_exists,
+       },
+       XATTR_LAYOUT_FIELD(dir, layout, stripe_unit),
+       XATTR_LAYOUT_FIELD(dir, layout, stripe_count),
+       XATTR_LAYOUT_FIELD(dir, layout, object_size),
+       XATTR_LAYOUT_FIELD(dir, layout, pool),
        XATTR_NAME_CEPH(dir, entries),
        XATTR_NAME_CEPH(dir, files),
        XATTR_NAME_CEPH(dir, subdirs),
@@ -105,28 +213,26 @@ static struct ceph_vxattr ceph_dir_vxattrs[] = {
        XATTR_NAME_CEPH(dir, rsubdirs),
        XATTR_NAME_CEPH(dir, rbytes),
        XATTR_NAME_CEPH(dir, rctime),
-       { 0 }   /* Required table terminator */
+       { .name = NULL, 0 }     /* Required table terminator */
 };
 static size_t ceph_dir_vxattrs_name_size;      /* total size of all names */
 
 /* files */
 
-static size_t ceph_vxattrcb_file_layout(struct ceph_inode_info *ci, char *val,
-                                  size_t size)
-{
-       int ret;
-
-       ret = snprintf(val, size,
-               "chunk_bytes=%lld\nstripe_count=%lld\nobject_size=%lld\n",
-               (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));
-       return ret;
-}
-
 static struct ceph_vxattr ceph_file_vxattrs[] = {
-       XATTR_NAME_CEPH(file, layout),
-       { 0 }   /* Required table terminator */
+       {
+               .name = "ceph.file.layout",
+               .name_size = sizeof("ceph.file.layout"),
+               .getxattr_cb = ceph_vxattrcb_layout,
+               .readonly = false,
+               .hidden = false,
+               .exists_cb = ceph_vxattrcb_layout_exists,
+       },
+       XATTR_LAYOUT_FIELD(file, layout, stripe_unit),
+       XATTR_LAYOUT_FIELD(file, layout, stripe_count),
+       XATTR_LAYOUT_FIELD(file, layout, object_size),
+       XATTR_LAYOUT_FIELD(file, layout, pool),
+       { .name = NULL, 0 }     /* Required table terminator */
 };
 static size_t ceph_file_vxattrs_name_size;     /* total size of all names */
 
@@ -657,23 +763,30 @@ list_xattr:
        vir_namelen = ceph_vxattrs_name_size(vxattrs);
 
        /* adding 1 byte per each variable due to the null termination */
-       namelen = vir_namelen + ci->i_xattrs.names_size + ci->i_xattrs.count;
+       namelen = ci->i_xattrs.names_size + ci->i_xattrs.count;
        err = -ERANGE;
-       if (size && namelen > size)
+       if (size && vir_namelen + namelen > size)
                goto out;
 
-       err = namelen;
+       err = namelen + vir_namelen;
        if (size == 0)
                goto out;
 
        names = __copy_xattr_names(ci, names);
 
        /* virtual xattr names, too */
-       if (vxattrs)
+       err = namelen;
+       if (vxattrs) {
                for (i = 0; vxattrs[i].name; i++) {
-                       len = sprintf(names, "%s", vxattrs[i].name);
-                       names += len + 1;
+                       if (!vxattrs[i].hidden &&
+                           !(vxattrs[i].exists_cb &&
+                             !vxattrs[i].exists_cb(ci))) {
+                               len = sprintf(names, "%s", vxattrs[i].name);
+                               names += len + 1;
+                               err += len + 1;
+                       }
                }
+       }
 
 out:
        spin_unlock(&ci->i_ceph_lock);