s3: Modifications to generic notify structures to allow implementation of OneFS notify.
authorSteven Danneman <steven.danneman@isilon.com>
Fri, 20 Feb 2009 21:23:53 +0000 (13:23 -0800)
committerMichael Adam <obnox@samba.org>
Tue, 28 Jul 2009 13:12:44 +0000 (15:12 +0200)
The OneFS kernel based change notify system takes an fd of the directory
to watch in it's initialization syscall.  Since we already have this
directory open, this commit plumbs that fd down to the VFS layer via the
notify_entry struct.

We also need to know if the watch is taken out on a snapshot directory.
The full file_id struct is also passed down to make this determination.
The file_id marshalling wrappers are hand written here, but should
eventually be auto-generated by moving the struct file_id into the idl.

source/librpc/gen_ndr/ndr_notify.c
source/librpc/gen_ndr/notify.h
source/librpc/idl/notify.idl
source/librpc/ndr/ndr_basic.c
source/smbd/notify.c

index 00ba8bc29329107c6c0c5e9e0ac91a657109a40b..d4ac42e96146ee7c1ffc4ca56e7bb78afa995a56 100644 (file)
@@ -10,6 +10,8 @@ _PUBLIC_ enum ndr_err_code ndr_push_notify_entry(struct ndr_push *ndr, int ndr_f
                NDR_CHECK(ndr_push_server_id(ndr, NDR_SCALARS, &r->server));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->filter));
                NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->subdir_filter));
+               NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->dir_fd));
+               NDR_CHECK(ndr_push_file_id(ndr, NDR_SCALARS, &r->dir_id));
                {
                        uint32_t _flags_save_string = ndr->flags;
                        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM);
@@ -21,6 +23,7 @@ _PUBLIC_ enum ndr_err_code ndr_push_notify_entry(struct ndr_push *ndr, int ndr_f
        }
        if (ndr_flags & NDR_BUFFERS) {
                NDR_CHECK(ndr_push_server_id(ndr, NDR_BUFFERS, &r->server));
+               NDR_CHECK(ndr_push_file_id(ndr, NDR_BUFFERS, &r->dir_id));
        }
        return NDR_ERR_SUCCESS;
 }
@@ -32,6 +35,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull_notify_entry(struct ndr_pull *ndr, int ndr_f
                NDR_CHECK(ndr_pull_server_id(ndr, NDR_SCALARS, &r->server));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->filter));
                NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->subdir_filter));
+               NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->dir_fd));
+               NDR_CHECK(ndr_pull_file_id(ndr, NDR_SCALARS, &r->dir_id));
                {
                        uint32_t _flags_save_string = ndr->flags;
                        ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM);
@@ -43,6 +48,7 @@ _PUBLIC_ enum ndr_err_code ndr_pull_notify_entry(struct ndr_pull *ndr, int ndr_f
        }
        if (ndr_flags & NDR_BUFFERS) {
                NDR_CHECK(ndr_pull_server_id(ndr, NDR_BUFFERS, &r->server));
+               NDR_CHECK(ndr_pull_file_id(ndr, NDR_BUFFERS, &r->dir_id));
        }
        return NDR_ERR_SUCCESS;
 }
@@ -54,6 +60,8 @@ _PUBLIC_ void ndr_print_notify_entry(struct ndr_print *ndr, const char *name, co
        ndr_print_server_id(ndr, "server", &r->server);
        ndr_print_uint32(ndr, "filter", r->filter);
        ndr_print_uint32(ndr, "subdir_filter", r->subdir_filter);
+       ndr_print_uint32(ndr, "dir_fd", r->dir_fd);
+       ndr_print_file_id(ndr, "dir_id", &r->dir_id);
        ndr_print_string(ndr, "path", r->path);
        ndr_print_uint32(ndr, "path_len", r->path_len);
        ndr_print_pointer(ndr, "private_data", r->private_data);
index c809702e5d509e555b4eec66d8656e4af79dfe15..a5ec4a46e6e7a335bc999249e8d8f6773c1ebcda 100644 (file)
@@ -9,6 +9,8 @@ struct notify_entry {
        struct server_id server;
        uint32_t filter;
        uint32_t subdir_filter;
+       uint32_t dir_fd;
+       struct file_id dir_id;
        const char * path;/* [flag(LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM)] */
        uint32_t path_len;
        void* private_data;
index c4e633c254fe2890555ea96ca71c3e34d5c527b6..550783b5cd3a99b46b8cf6787a8533afb8bab346 100644 (file)
@@ -18,6 +18,8 @@ interface notify
                server_id server;
                uint32 filter; /* filter to apply in this directory */
                uint32 subdir_filter; /* filter to apply in child directories */
+               uint32 dir_fd;   /* fd of open directory */
+               file_id dir_id;  /* file_id of open directory */
                utf8string path;
                uint32 path_len; /* saves some computation on search */
                pointer private_data;
index c8fa70b1851d042d86bc4cb2a5120ccdc25be518..f81ac7b384f84fc8b846fddaa711abca45bb0733 100644 (file)
@@ -857,3 +857,38 @@ _PUBLIC_ void ndr_print_sockaddr_storage(struct ndr_print *ndr, const char *name
        char addr[INET6_ADDRSTRLEN];
        ndr->print(ndr, "%-25s: %s", name, print_sockaddr(addr, sizeof(addr), ss));
 }
+
+enum ndr_err_code ndr_push_file_id(struct ndr_push *ndr, int ndr_flags, const struct file_id *r)
+{
+       if (ndr_flags & NDR_SCALARS) {
+               NDR_CHECK(ndr_push_align(ndr, 4));
+               NDR_CHECK(ndr_push_udlong(ndr, NDR_SCALARS,
+                                         (uint64_t)r->devid));
+               NDR_CHECK(ndr_push_udlong(ndr, NDR_SCALARS,
+                                         (uint64_t)r->inode));
+       }
+       if (ndr_flags & NDR_BUFFERS) {
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_pull_file_id(struct ndr_pull *ndr, int ndr_flags, struct file_id *r)
+{
+       if (ndr_flags & NDR_SCALARS) {
+               NDR_CHECK(ndr_pull_align(ndr, 4));
+               NDR_CHECK(ndr_pull_udlong(ndr, NDR_SCALARS, &r->devid));
+               NDR_CHECK(ndr_pull_udlong(ndr, NDR_SCALARS, &r->inode));
+       }
+       if (ndr_flags & NDR_BUFFERS) {
+       }
+       return NDR_ERR_SUCCESS;
+}
+
+void ndr_print_file_id(struct ndr_print *ndr, const char *name, const struct file_id *r)
+{
+       ndr_print_struct(ndr, name, "file_id");
+       ndr->depth++;
+       ndr_print_udlong(ndr, "devid", (uint64_t)r->devid);
+       ndr_print_udlong(ndr, "inode", (uint64_t)r->inode);
+       ndr->depth--;
+}
index d1cd8dfe6971e5b45adf5bad2e3b2603a893adc1..7be103b5b834435ca13dc5536bae61530486a405 100644 (file)
@@ -237,6 +237,8 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter,
 
        ZERO_STRUCT(e);
        e.path = fullpath;
+       e.dir_fd = fsp->fh->fd;
+       e.dir_id = fsp->file_id;
        e.filter = filter;
        e.subdir_filter = 0;
        if (recursive) {