]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
afs: Implement client support for the YFSVL.GetCellName RPC op
authorDavid Howells <dhowells@redhat.com>
Wed, 29 Apr 2020 16:26:41 +0000 (17:26 +0100)
committerDavid Howells <dhowells@redhat.com>
Thu, 4 Jun 2020 14:37:57 +0000 (15:37 +0100)
Implement client support for the YFSVL.GetCellName RPC operation by which
YFS permits the canonical cell name to be queried from a VL server.

Signed-off-by: David Howells <dhowells@redhat.com>
fs/afs/afs.h
fs/afs/afs_vl.h
fs/afs/internal.h
fs/afs/protocol_yfs.h
fs/afs/vlclient.c
include/trace/events/afs.h

index f8e34406243e3aa95d7eda37237e26060a8d3650..432cb4b23961424776b05d56f40962eb9bc2356b 100644 (file)
@@ -10,7 +10,7 @@
 
 #include <linux/in.h>
 
-#define AFS_MAXCELLNAME                64      /* Maximum length of a cell name */
+#define AFS_MAXCELLNAME                256     /* Maximum length of a cell name */
 #define AFS_MAXVOLNAME         64      /* Maximum length of a volume name */
 #define AFS_MAXNSERVERS                8       /* Maximum servers in a basic volume record */
 #define AFS_NMAXNSERVERS       13      /* Maximum servers in a N/U-class volume record */
index e9b8029920ec831937f1da385090416f10d070e9..9c65ffb8a523bd90debe526c7eda4872a0336d98 100644 (file)
@@ -22,6 +22,7 @@ enum AFSVL_Operations {
        VLGETENTRYBYNAMEU       = 527,  /* AFS Get VLDB entry by name (UUID-variant) */
        VLGETADDRSU             = 533,  /* AFS Get addrs for fileserver */
        YVLGETENDPOINTS         = 64002, /* YFS Get endpoints for file/volume server */
+       YVLGETCELLNAME          = 64014, /* YFS Get actual cell name */
        VLGETCAPABILITIES       = 65537, /* AFS Get server capabilities */
 };
 
index dce03e068cabe62d5be51ae1a9526c8309cad411..3606cfa5083212814feaa2106368d270e7e7f8d2 100644 (file)
@@ -116,6 +116,7 @@ struct afs_call {
                long                    ret0;   /* Value to reply with instead of 0 */
                struct afs_addr_list    *ret_alist;
                struct afs_vldb_entry   *ret_vldb;
+               char                    *ret_str;
        };
        struct afs_operation    *op;
        unsigned int            server_index;
@@ -1373,6 +1374,7 @@ extern struct afs_addr_list *afs_vl_get_addrs_u(struct afs_vl_cursor *, const uu
 extern struct afs_call *afs_vl_get_capabilities(struct afs_net *, struct afs_addr_cursor *,
                                                struct key *, struct afs_vlserver *, unsigned int);
 extern struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *, const uuid_t *);
+extern char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *);
 
 /*
  * vl_probe.c
index 32be9c698348c4e0b12a0a53be2727ecfb28aa29..b5bd03b1d3c7f0d271671a134f1cafb697825f42 100644 (file)
@@ -8,7 +8,7 @@
 #define YFS_FS_SERVICE 2500
 #define YFS_CM_SERVICE 2501
 
-#define YFSCBMAX 1024
+#define YFSCBMAX       1024
 
 enum YFS_CM_Operations {
        YFSCBProbe              = 206,  /* probe client */
index d0c85623ce8fc229be04d3442d18873b06c4c297..fd82850cd4244efa5e4daa77d496d7952eca43b4 100644 (file)
@@ -645,3 +645,114 @@ struct afs_addr_list *afs_yfsvl_get_endpoints(struct afs_vl_cursor *vc,
        afs_make_call(&vc->ac, call, GFP_KERNEL);
        return (struct afs_addr_list *)afs_wait_for_call_to_complete(call, &vc->ac);
 }
+
+/*
+ * Deliver reply data to a YFSVL.GetCellName operation.
+ */
+static int afs_deliver_yfsvl_get_cell_name(struct afs_call *call)
+{
+       char *cell_name;
+       u32 namesz, paddedsz;
+       int ret;
+
+       _enter("{%u,%zu/%u}",
+              call->unmarshall, iov_iter_count(call->iter), call->count);
+
+       switch (call->unmarshall) {
+       case 0:
+               afs_extract_to_tmp(call);
+               call->unmarshall++;
+
+               /* Fall through - and extract the cell name length */
+       case 1:
+               ret = afs_extract_data(call, true);
+               if (ret < 0)
+                       return ret;
+
+               namesz = ntohl(call->tmp);
+               if (namesz > AFS_MAXCELLNAME)
+                       return afs_protocol_error(call, afs_eproto_cellname_len);
+               paddedsz = (namesz + 3) & ~3;
+               call->count = namesz;
+               call->count2 = paddedsz - namesz;
+
+               cell_name = kmalloc(namesz + 1, GFP_KERNEL);
+               if (!cell_name)
+                       return -ENOMEM;
+               cell_name[namesz] = 0;
+               call->ret_str = cell_name;
+
+               afs_extract_begin(call, cell_name, namesz);
+               call->unmarshall++;
+
+               /* Fall through - and extract cell name */
+       case 2:
+               ret = afs_extract_data(call, true);
+               if (ret < 0)
+                       return ret;
+
+               afs_extract_discard(call, call->count2);
+               call->unmarshall++;
+
+               /* Fall through - and extract padding */
+       case 3:
+               ret = afs_extract_data(call, false);
+               if (ret < 0)
+                       return ret;
+
+               call->unmarshall++;
+               break;
+       }
+
+       _leave(" = 0 [done]");
+       return 0;
+}
+
+static void afs_destroy_yfsvl_get_cell_name(struct afs_call *call)
+{
+       kfree(call->ret_str);
+       afs_flat_call_destructor(call);
+}
+
+/*
+ * VL.GetCapabilities operation type
+ */
+static const struct afs_call_type afs_YFSVLGetCellName = {
+       .name           = "YFSVL.GetCellName",
+       .op             = afs_YFSVL_GetCellName,
+       .deliver        = afs_deliver_yfsvl_get_cell_name,
+       .destructor     = afs_destroy_yfsvl_get_cell_name,
+};
+
+/*
+ * Probe a volume server for the capabilities that it supports.  This can
+ * return up to 196 words.
+ *
+ * We use this to probe for service upgrade to determine what the server at the
+ * other end supports.
+ */
+char *afs_yfsvl_get_cell_name(struct afs_vl_cursor *vc)
+{
+       struct afs_call *call;
+       struct afs_net *net = vc->cell->net;
+       __be32 *bp;
+
+       _enter("");
+
+       call = afs_alloc_flat_call(net, &afs_YFSVLGetCellName, 1 * 4, 0);
+       if (!call)
+               return ERR_PTR(-ENOMEM);
+
+       call->key = vc->key;
+       call->ret_str = NULL;
+       call->max_lifespan = AFS_VL_MAX_LIFESPAN;
+
+       /* marshall the parameters */
+       bp = call->request;
+       *bp++ = htonl(YVLGETCELLNAME);
+
+       /* Can't take a ref on server */
+       trace_afs_make_vl_call(call);
+       afs_make_call(&vc->ac, call, GFP_KERNEL);
+       return (char *)afs_wait_for_call_to_complete(call, &vc->ac);
+}
index f4d66919fb2214e5941e114d98b886c519d7a040..f320b3ad54da88b69d47e650adc0dec20874e067 100644 (file)
@@ -111,6 +111,7 @@ enum afs_vl_operation {
        afs_VL_GetEntryByNameU  = 527,          /* AFS Get Vol Entry By Name operation ID */
        afs_VL_GetAddrsU        = 533,          /* AFS Get FS server addresses */
        afs_YFSVL_GetEndpoints  = 64002,        /* YFS Get FS & Vol server addresses */
+       afs_YFSVL_GetCellName   = 64014,        /* YFS Get actual cell name */
        afs_VL_GetCapabilities  = 65537,        /* AFS Get VL server capabilities */
 };
 
@@ -143,6 +144,7 @@ enum afs_eproto_cause {
        afs_eproto_bad_status,
        afs_eproto_cb_count,
        afs_eproto_cb_fid_count,
+       afs_eproto_cellname_len,
        afs_eproto_file_type,
        afs_eproto_ibulkst_cb_count,
        afs_eproto_ibulkst_count,
@@ -316,6 +318,7 @@ enum afs_cb_break_reason {
        EM(afs_VL_GetEntryByNameU,              "VL.GetEntryByNameU") \
        EM(afs_VL_GetAddrsU,                    "VL.GetAddrsU") \
        EM(afs_YFSVL_GetEndpoints,              "YFSVL.GetEndpoints") \
+       EM(afs_YFSVL_GetCellName,               "YFSVL.GetCellName") \
        E_(afs_VL_GetCapabilities,              "VL.GetCapabilities")
 
 #define afs_edit_dir_ops                                 \
@@ -345,6 +348,7 @@ enum afs_cb_break_reason {
        EM(afs_eproto_bad_status,       "BadStatus") \
        EM(afs_eproto_cb_count,         "CbCount") \
        EM(afs_eproto_cb_fid_count,     "CbFidCount") \
+       EM(afs_eproto_cellname_len,     "CellNameLen") \
        EM(afs_eproto_file_type,        "FileTYpe") \
        EM(afs_eproto_ibulkst_cb_count, "IBS.CbCount") \
        EM(afs_eproto_ibulkst_count,    "IBS.FidCount") \