r3747: - added some of the infrastructure needed for streams support in pvfs
authorAndrew Tridgell <tridge@samba.org>
Mon, 15 Nov 2004 06:57:26 +0000 (06:57 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:05:50 +0000 (13:05 -0500)
  (the IDL, and the load/save meta-data logic)

- changed pvfs_resolve_name() to default to non-wildcard, needing
  PVFS_RESOLVE_WILDCARD to enable wildcards. Most callers don't want
  wildcards, so defaulting this way makes more sense.

- fixed deletion of EAs
(This used to be commit e7afd4403cc1b7e0928776929f8988aa6f15640b)

15 files changed:
source4/include/structs.h
source4/librpc/idl/xattr.idl
source4/ntvfs/posix/config.mk
source4/ntvfs/posix/pvfs_mkdir.c
source4/ntvfs/posix/pvfs_open.c
source4/ntvfs/posix/pvfs_qfileinfo.c
source4/ntvfs/posix/pvfs_rename.c
source4/ntvfs/posix/pvfs_resolve.c
source4/ntvfs/posix/pvfs_search.c
source4/ntvfs/posix/pvfs_setfileinfo.c
source4/ntvfs/posix/pvfs_streams.c [new file with mode: 0644]
source4/ntvfs/posix/pvfs_unlink.c
source4/ntvfs/posix/pvfs_xattr.c
source4/ntvfs/posix/vfs_posix.c
source4/ntvfs/posix/vfs_posix.h

index 424b7a0e7a5ffb79efebc46a596a29c0689bf768..229c4890723fdfbb709f65ca0e951e7872a85128 100644 (file)
@@ -110,6 +110,7 @@ struct net_context;
 struct file_info;
 
 struct xattr_DosEAs;
+struct xattr_DosStreams;
 
 struct test_join;
 
index 0fc965c82586550d9bf8d6fc337e1ca93f0c32c9..be587ffb883270de5c311e638f9a97fe03ebb014 100644 (file)
@@ -47,4 +47,23 @@ interface xattr
                uint16 num_eas;
                [size_is(num_eas)] xattr_EA *eas;
        } xattr_DosEAs;
+
+       /* we store stream information in this xattr structure. Then
+          the streams themselves are stored in
+          user.DosStream.STREAMNAME or in external files, according
+          to the flags */
+       const string XATTR_DOSSTREAMS_NAME = "user.DosStreams";
+
+       const int XATTR_STREAM_FLAG_INTERNAL = 0x00000001;
+
+       typedef struct {
+               utf8string name;
+               uint64     size;
+               uint32     flags;
+       } xattr_DosStream;
+
+       typedef [public] struct {
+               uint32 num_streams;
+               [size_is(num_streams)] xattr_DosStream *streams;
+       } xattr_DosStreams;
 }
index 74e991d9bdd2dfea939088b2900864d61be80f07..1d33d8b38131538c9368220302959bca63b59c51 100644 (file)
@@ -27,6 +27,7 @@ ADD_OBJ_FILES = \
                ntvfs/posix/pvfs_seek.o \
                ntvfs/posix/pvfs_ioctl.o \
                ntvfs/posix/pvfs_xattr.o \
+               ntvfs/posix/pvfs_streams.o \
                ntvfs/common/opendb.o \
                ntvfs/common/brlock.o
 # End MODULE ntvfs_posix
index 3b5204c934243e490647b1533d33d71a242e2ae7..1bc0fa569e7ffe1709fc08baf8add908aa2ba0c1 100644 (file)
@@ -39,8 +39,7 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs,
        }
 
        /* resolve the cifs name to a posix name */
-       status = pvfs_resolve_name(pvfs, req, md->mkdir.in.path, 
-                                  PVFS_RESOLVE_NO_WILDCARD, &name);
+       status = pvfs_resolve_name(pvfs, req, md->mkdir.in.path, 0, &name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -69,8 +68,7 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs,
        struct pvfs_filename *name;
 
        /* resolve the cifs name to a posix name */
-       status = pvfs_resolve_name(pvfs, req, rd->in.path, 
-                                  PVFS_RESOLVE_NO_WILDCARD, &name);
+       status = pvfs_resolve_name(pvfs, req, rd->in.path, 0, &name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
index 9bb34876793415a9e22203ec948516b0a1b86a08..4f089a8c0772f8bb72b080d818d4aaa58f6a67d3 100644 (file)
@@ -103,6 +103,10 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
        NTSTATUS status;
        uint32_t create_action;
 
+       if (name->stream_name) {
+               return NT_STATUS_OBJECT_NAME_INVALID;
+       }
+
        /* if the client says it must be a directory, and it isn't,
           then fail */
        if (name->exists && !(name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
@@ -180,8 +184,7 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
                if (mkdir(name->full_name, mode) == -1) {
                        return pvfs_map_errno(pvfs,errno);
                }
-               status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
-                                          PVFS_RESOLVE_NO_WILDCARD, &name);
+               status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -684,8 +687,7 @@ static NTSTATUS pvfs_open_t2open(struct ntvfs_module_context *ntvfs,
        struct pvfs_filename *name;
        NTSTATUS status;
 
-       status = pvfs_resolve_name(pvfs, req, io->t2open.in.fname,
-                                  PVFS_RESOLVE_NO_WILDCARD, &name);
+       status = pvfs_resolve_name(pvfs, req, io->t2open.in.fname, 0, &name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -735,8 +737,8 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
        }
 
        /* resolve the cifs name to a posix name */
-       status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
-                                  PVFS_RESOLVE_NO_WILDCARD, &name);
+       status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 
+                                  PVFS_RESOLVE_STREAMS, &name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -826,8 +828,7 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
                }
 
                /* try re-resolving the name */
-               status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname,
-                                          PVFS_RESOLVE_NO_WILDCARD, &name);
+               status = pvfs_resolve_name(pvfs, req, io->ntcreatex.in.fname, 0, &name);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
index c8134939a3a3d959928e608a07019a49fd34d99f..3eaa7865e8878b34be5125affe153cbfb650b005 100644 (file)
@@ -219,8 +219,7 @@ NTSTATUS pvfs_qpathinfo(struct ntvfs_module_context *ntvfs,
        NTSTATUS status;
 
        /* resolve the cifs name to a posix name */
-       status = pvfs_resolve_name(pvfs, req, info->generic.in.fname, 
-                                  PVFS_RESOLVE_NO_WILDCARD, &name);
+       status = pvfs_resolve_name(pvfs, req, info->generic.in.fname, 0, &name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
index aae17f327c47a45e3b8ba65f26b433e04279f945..efaf63ba9d344c758c121423add4ee917d0a2640 100644 (file)
@@ -250,12 +250,14 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs,
        struct pvfs_filename *name1, *name2;
 
        /* resolve the cifs name to a posix name */
-       status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern1, 0, &name1);
+       status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern1, 
+                                  PVFS_RESOLVE_WILDCARD, &name1);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern2, 0, &name2);
+       status = pvfs_resolve_name(pvfs, req, ren->rename.in.pattern2, 
+                                  PVFS_RESOLVE_WILDCARD, &name2);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -325,10 +327,6 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
                return status;
        }
 
-       if (name1->has_wildcard || name2->has_wildcard) {
-               return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
-       }
-
        if (!name1->exists) {
                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
index 354cdd4bb444316e416a42f91d375193aae4b414..576b0d9db4ea47f81cd26768666254f30562dcf5 100644 (file)
@@ -253,7 +253,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
                case '<':
                case '?':
                case '"':
-                       if (flags & PVFS_RESOLVE_NO_WILDCARD) {
+                       if (!(flags & PVFS_RESOLVE_WILDCARD)) {
                                return NT_STATUS_OBJECT_NAME_INVALID;
                        }
                        name->has_wildcard = True;
@@ -341,7 +341,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx, const char **fname, uint_t
                }
        }
        if (err_count) {
-               if (!(flags & PVFS_RESOLVE_NO_WILDCARD)) err_count--;
+               if (flags & PVFS_RESOLVE_WILDCARD) err_count--;
 
                if (err_count==1) {
                        return NT_STATUS_OBJECT_NAME_INVALID;
index 831b799716f7704a48a1f794cf7d6dda4ae2fdb4..f805f201f60456b25f854fa649a14bbc02fca61f 100644 (file)
@@ -300,7 +300,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs,
        pattern       = io->search_first.in.pattern;
 
        /* resolve the cifs name to a posix name */
-       status = pvfs_resolve_name(pvfs, req, pattern, 0, &name);
+       status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -436,7 +436,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs,
        max_count     = io->t2ffirst.in.max_count;
 
        /* resolve the cifs name to a posix name */
-       status = pvfs_resolve_name(pvfs, req, pattern, 0, &name);
+       status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
index b9ed592bf4f3f02c4b55a58be148f9ec1cbcee14..7ba64979c3ecef2e538e2d507858c729325e567d 100644 (file)
@@ -70,7 +70,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
        }
 
        /* resolve the new name */
-       status = pvfs_resolve_name(pvfs, name, new_name, PVFS_RESOLVE_NO_WILDCARD, &name2);
+       status = pvfs_resolve_name(pvfs, name, new_name, 0, &name2);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -144,6 +144,17 @@ static NTSTATUS pvfs_setfileinfo_ea_set(struct pvfs_state *pvfs,
        ealist->num_eas++;
        
 save:
+       /* pull out any null EAs */
+       for (i=0;i<ealist->num_eas;i++) {
+               if (ealist->eas[i].value.length == 0) {
+                       memmove(&ealist->eas[i],
+                               &ealist->eas[i+1],
+                               (ealist->num_eas-(i+1)) * sizeof(ealist->eas[i]));
+                       ealist->num_eas--;
+                       i--;
+               }
+       }
+
        status = pvfs_doseas_save(pvfs, name, fd, ealist);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -348,8 +359,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
        struct utimbuf unix_times;
 
        /* resolve the cifs name to a posix name */
-       status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, 
-                                  PVFS_RESOLVE_NO_WILDCARD, &name);
+       status = pvfs_resolve_name(pvfs, req, info->generic.file.fname, 0, &name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
diff --git a/source4/ntvfs/posix/pvfs_streams.c b/source4/ntvfs/posix/pvfs_streams.c
new file mode 100644 (file)
index 0000000..b71ff64
--- /dev/null
@@ -0,0 +1,27 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   POSIX NTVFS backend - alternate data streams
+
+   Copyright (C) Andrew Tridgell 2004
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "system/filesys.h"
+#include "vfs_posix.h"
+#include "librpc/gen_ndr/ndr_xattr.h"
+
index ab8f1abf62232ef5fa7abde6d632839c2bff3cf7..8dc9f60ad8160f6d6c45cc2c91488069babde55e 100644 (file)
@@ -85,7 +85,8 @@ NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
        uint_t ofs;
 
        /* resolve the cifs name to a posix name */
-       status = pvfs_resolve_name(pvfs, req, unl->in.pattern, 0, &name);
+       status = pvfs_resolve_name(pvfs, req, unl->in.pattern, 
+                                  PVFS_RESOLVE_WILDCARD, &name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
index d5a7d17a31e6bfff170e6a09dcacccc1dd487395..269a2cc86369c90d78786b20ee277bd72c503272 100644 (file)
@@ -276,3 +276,40 @@ NTSTATUS pvfs_doseas_save(struct pvfs_state *pvfs, struct pvfs_filename *name, i
        return pvfs_xattr_ndr_save(pvfs, name->full_name, fd, XATTR_DOSEAS_NAME, eas, 
                                   (ndr_push_flags_fn_t)ndr_push_xattr_DosEAs);
 }
+
+
+/*
+  load the set of streams from extended attributes
+*/
+NTSTATUS pvfs_streams_load(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
+                          struct xattr_DosStreams *streams)
+{
+       NTSTATUS status;
+       ZERO_STRUCTP(streams);
+       if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) {
+               return NT_STATUS_OK;
+       }
+       status = pvfs_xattr_ndr_load(pvfs, streams, name->full_name, fd, 
+                                    XATTR_DOSSTREAMS_NAME,
+                                    streams, 
+                                    (ndr_pull_flags_fn_t)ndr_pull_xattr_DosStreams);
+       if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+               return NT_STATUS_OK;
+       }
+       return status;
+}
+
+/*
+  save the set of streams into filesystem xattr
+*/
+NTSTATUS pvfs_streams_save(struct pvfs_state *pvfs, struct pvfs_filename *name, int fd,
+                          struct xattr_DosStreams *streams)
+{
+       if (!(pvfs->flags & PVFS_FLAG_XATTR_ENABLE)) {
+               return NT_STATUS_OK;
+       }
+       return pvfs_xattr_ndr_save(pvfs, name->full_name, fd, 
+                                  XATTR_DOSSTREAMS_NAME, 
+                                  streams, 
+                                  (ndr_push_flags_fn_t)ndr_push_xattr_DosStreams);
+}
index e5712e3e7d9d1475028c1378f87a5abcf0f07460..2b4eef04ba3b3165908cd0117c67e92db4de7238 100644 (file)
@@ -161,8 +161,7 @@ static NTSTATUS pvfs_chkpath(struct ntvfs_module_context *ntvfs,
        NTSTATUS status;
 
        /* resolve the cifs name to a posix name */
-       status = pvfs_resolve_name(pvfs, req, cp->in.path, 
-                                  PVFS_RESOLVE_NO_WILDCARD, &name);
+       status = pvfs_resolve_name(pvfs, req, cp->in.path, 0, &name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
index 46cc38c1f8abe657d73cc1216f760478970be433..645d293a6d4acea50a12b47cbf81dea763b961a0 100644 (file)
@@ -169,7 +169,7 @@ struct pvfs_mangle_context {
 
 
 /* flags to pvfs_resolve_name() */
-#define PVFS_RESOLVE_NO_WILDCARD (1<<0)
+#define PVFS_RESOLVE_WILDCARD    (1<<0)
 #define PVFS_RESOLVE_STREAMS     (1<<1)
 
 /* flags in pvfs->flags */