r14933: fix the handling of notify filters to be much closer to the behaviour
authorAndrew Tridgell <tridge@samba.org>
Thu, 6 Apr 2006 01:56:04 +0000 (01:56 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:00:19 +0000 (14:00 -0500)
of w2k3. The behaviour is particularly tricky for rename.
(This used to be commit 4d3b8d95498a328ffc08ecb62d9531b6bfe4e2b5)

source4/ntvfs/posix/pvfs_mkdir.c
source4/ntvfs/posix/pvfs_open.c
source4/ntvfs/posix/pvfs_read.c
source4/ntvfs/posix/pvfs_rename.c
source4/ntvfs/posix/pvfs_setfileinfo.c
source4/ntvfs/posix/pvfs_write.c
source4/ntvfs/posix/vfs_posix.c

index cd83c9de43f86c1685cd64723460ec5e82794fbc..338fc7df0ba2aacbcbf5b42031cefe8a2088d7cf 100644 (file)
@@ -85,7 +85,7 @@ static NTSTATUS pvfs_t2mkdir(struct pvfs_state *pvfs,
 
        notify_trigger(pvfs->notify_context, 
                       NOTIFY_ACTION_ADDED, 
-                      FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME,
+                      FILE_NOTIFY_CHANGE_DIR_NAME,
                       name->full_name);
 
        return NT_STATUS_OK;
@@ -142,7 +142,7 @@ NTSTATUS pvfs_mkdir(struct ntvfs_module_context *ntvfs,
 
        notify_trigger(pvfs->notify_context, 
                       NOTIFY_ACTION_ADDED, 
-                      FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME,
+                      FILE_NOTIFY_CHANGE_DIR_NAME,
                       name->full_name);
 
        return NT_STATUS_OK;
@@ -184,7 +184,7 @@ NTSTATUS pvfs_rmdir(struct ntvfs_module_context *ntvfs,
 
        notify_trigger(pvfs->notify_context, 
                       NOTIFY_ACTION_REMOVED, 
-                      FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME,
+                      FILE_NOTIFY_CHANGE_DIR_NAME,
                       name->full_name);
 
        return NT_STATUS_OK;
index 264234a09bd3c8e35148c08ffb151d3f78dff1c0..5afb538db76481d193fa7b2919c87cb95967cab4 100644 (file)
@@ -380,8 +380,8 @@ static NTSTATUS pvfs_open_directory(struct pvfs_state *pvfs,
                create_action = NTCREATEX_ACTION_CREATED;
 
                notify_trigger(pvfs->notify_context, 
-                              NOTIFY_ACTION_REMOVED, 
-                              FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME,
+                              NOTIFY_ACTION_ADDED, 
+                              FILE_NOTIFY_CHANGE_DIR_NAME,
                               name->full_name);
        } else {
                create_action = NTCREATEX_ACTION_EXISTED;
index f30c4d6e38b0b8d22f225a7e46c4b8a22b8b2c59..411fbd9c27c63bbe12e762283d2f477e52bc9828 100644 (file)
@@ -90,10 +90,5 @@ NTSTATUS pvfs_read(struct ntvfs_module_context *ntvfs,
        rd->readx.out.remaining = 0xFFFF;
        rd->readx.out.compaction_mode = 0; 
 
-       notify_trigger(pvfs->notify_context, 
-                      NOTIFY_ACTION_MODIFIED, 
-                      FILE_NOTIFY_CHANGE_LAST_ACCESS,
-                      f->handle->name->full_name);
-
        return NT_STATUS_OK;
 }
index 824581cdafa121a75d0cdb749a49a0cc63382149..c3442884cff1f97812eb9601b6e7ae00172e5891 100644 (file)
 /*
   do a file rename, and send any notify triggers
 */
-NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, const char *name1, const char *name2)
+NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, const struct pvfs_filename *name1, 
+                       const char *name2)
 {
        const char *r1, *r2;
+       uint32_t mask;
 
-       if (rename(name1, name2) == -1) {
+       if (rename(name1->full_name, name2) == -1) {
                return pvfs_map_errno(pvfs, errno);
        }
 
+       if (name1->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) {
+               mask = FILE_NOTIFY_CHANGE_DIR_NAME;
+       } else {
+               mask = FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_CREATION;
+       }
        /* 
           renames to the same directory cause a OLD_NAME->NEW_NAME notify.
           renames to a different directory are considered a remove/add 
        */
-       r1 = strrchr_m(name1, '/');
+       r1 = strrchr_m(name1->full_name, '/');
        r2 = strrchr_m(name2, '/');
 
-       if ((r1-name1) != (r2-name2) ||
-           strncmp(name1, name2, r1-name1) != 0) {
+       if ((r1-name1->full_name) != (r2-name2) ||
+           strncmp(name1->full_name, name2, r1-name1->full_name) != 0) {
                notify_trigger(pvfs->notify_context, 
                               NOTIFY_ACTION_REMOVED, 
-                              FILE_NOTIFY_CHANGE_FILE_NAME,
-                              name1);
+                              mask,
+                              name1->full_name);
                notify_trigger(pvfs->notify_context, 
                               NOTIFY_ACTION_ADDED, 
-                              FILE_NOTIFY_CHANGE_FILE_NAME,
+                              mask,
                               name2);
        } else {
                notify_trigger(pvfs->notify_context, 
                               NOTIFY_ACTION_OLD_NAME, 
-                              FILE_NOTIFY_CHANGE_FILE_NAME,
-                              name1);
+                              mask,
+                              name1->full_name);
                notify_trigger(pvfs->notify_context, 
                               NOTIFY_ACTION_NEW_NAME, 
-                              FILE_NOTIFY_CHANGE_FILE_NAME,
+                              mask,
                               name2);
        }
        
@@ -217,7 +224,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs,
                return NT_STATUS_NO_MEMORY;
        }
 
-       status = pvfs_do_rename(pvfs, name1->full_name, fname2);
+       status = pvfs_do_rename(pvfs, name1, fname2);
 
        if (NT_STATUS_IS_OK(status)) {
                status = odb_rename(lck, fname2);
@@ -338,7 +345,7 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs,
                return status;
        }
 
-       status = pvfs_do_rename(pvfs, name1->full_name, name2->full_name);
+       status = pvfs_do_rename(pvfs, name1, name2->full_name);
        if (NT_STATUS_IS_OK(status)) {
                status = odb_rename(lck, name2->full_name);
        }
@@ -411,7 +418,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
        case RENAME_FLAG_RENAME:
                status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE);
                NT_STATUS_NOT_OK_RETURN(status);
-               status = pvfs_do_rename(pvfs, name1->full_name, name2->full_name);
+               status = pvfs_do_rename(pvfs, name1, name2->full_name);
                NT_STATUS_NOT_OK_RETURN(status);
                break;
 
index 9f5153eb4bd0c8740837482c5786d197a854ba4f..b00624c0e9540d57de834020db0052be3d1c9aa6 100644 (file)
@@ -147,7 +147,7 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
                return status;
        }
 
-       status = pvfs_do_rename(pvfs, name->full_name, name2->full_name);
+       status = pvfs_do_rename(pvfs, name, name2->full_name);
        if (NT_STATUS_IS_OK(status)) {
                name->full_name = talloc_steal(name, name2->full_name);
                name->original_name = talloc_steal(name, name2->original_name);
@@ -292,7 +292,6 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
        case RAW_SFILEINFO_STANDARD:
                if (!null_time(info->setattre.in.create_time)) {
                        unix_to_nt_time(&newstats.dos.create_time, info->setattre.in.create_time);
-                       change_mask |= FILE_NOTIFY_CHANGE_CREATION;
                }
                if (!null_time(info->setattre.in.access_time)) {
                        unix_to_nt_time(&newstats.dos.access_time, info->setattre.in.access_time);
@@ -311,7 +310,6 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
        case RAW_SFILEINFO_BASIC_INFORMATION:
                if (!null_nttime(info->basic_info.in.create_time)) {
                        newstats.dos.create_time = info->basic_info.in.create_time;
-                       change_mask |= FILE_NOTIFY_CHANGE_CREATION;
                }
                if (!null_nttime(info->basic_info.in.access_time)) {
                        newstats.dos.access_time = info->basic_info.in.access_time;
@@ -408,6 +406,9 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
 
        /* possibly change the file timestamps */
        ZERO_STRUCT(unix_times);
+       if (newstats.dos.create_time != h->name->dos.create_time) {
+               change_mask |= FILE_NOTIFY_CHANGE_CREATION;
+       }
        if (newstats.dos.access_time != h->name->dos.access_time) {
                unix_times.actime = nt_time_to_unix(newstats.dos.access_time);
                change_mask |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
@@ -494,7 +495,6 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
        case RAW_SFILEINFO_STANDARD:
                if (!null_time(info->setattre.in.create_time)) {
                        unix_to_nt_time(&newstats.dos.create_time, info->setattre.in.create_time);
-                       change_mask |= FILE_NOTIFY_CHANGE_CREATION;
                }
                if (!null_time(info->setattre.in.access_time)) {
                        unix_to_nt_time(&newstats.dos.access_time, info->setattre.in.access_time);
@@ -513,7 +513,6 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
        case RAW_SFILEINFO_BASIC_INFORMATION:
                if (!null_nttime(info->basic_info.in.create_time)) {
                        newstats.dos.create_time = info->basic_info.in.create_time;
-                       change_mask |= FILE_NOTIFY_CHANGE_CREATION;
                }
                if (!null_nttime(info->basic_info.in.access_time)) {
                        newstats.dos.access_time = info->basic_info.in.access_time;
@@ -585,11 +584,16 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
 
        /* possibly change the file timestamps */
        ZERO_STRUCT(unix_times);
+       if (newstats.dos.create_time != name->dos.create_time) {
+               change_mask |= FILE_NOTIFY_CHANGE_CREATION;
+       }
        if (newstats.dos.access_time != name->dos.access_time) {
                unix_times.actime = nt_time_to_unix(newstats.dos.access_time);
+               change_mask |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
        }
        if (newstats.dos.write_time != name->dos.write_time) {
                unix_times.modtime = nt_time_to_unix(newstats.dos.write_time);
+               change_mask |= FILE_NOTIFY_CHANGE_LAST_WRITE;
        }
        if (unix_times.actime != 0 || unix_times.modtime != 0) {
                if (utime(name->full_name, &unix_times) == -1) {
@@ -604,6 +608,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
                if (chmod(name->full_name, mode) == -1) {
                        return pvfs_map_errno(pvfs, errno);
                }
+               change_mask |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
        }
 
        *name = newstats;
index 15e352617619bba00b77f9e9a0246a594811342b..298c95e90b0955fbb96891515728dab20fb49386 100644 (file)
@@ -85,10 +85,5 @@ NTSTATUS pvfs_write(struct ntvfs_module_context *ntvfs,
        wr->writex.out.nwritten = ret;
        wr->writex.out.remaining = 0; /* should fill this in? */
 
-       notify_trigger(pvfs->notify_context, 
-                      NOTIFY_ACTION_MODIFIED, 
-                      FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE,
-                      f->handle->name->full_name);
-       
        return NT_STATUS_OK;
 }
index c279350e2f06753d4836efa4eb0ffb6a4f3c17c7..c0c1d6501c70825fe51f6ae6ace91a8b674c14da 100644 (file)
@@ -111,7 +111,7 @@ static int pvfs_state_destructor(void *ptr)
        struct pvfs_search_state *s, *sn;
 
        /* 
-        * make sure we cleanup files and searches before anythingelse
+        * make sure we cleanup files and searches before anything else
         * because there destructors need to acess the pvfs_state struct
         */
        for (f=pvfs->files.list; f; f=fn) {