Ejemplo n.º 1
0
void trigger_write_time_update_immediate(struct files_struct *fsp)
{
	struct smb_file_time ft;

	if (fsp->posix_open) {
		/* Don't use delayed writes on POSIX files. */
		return;
	}

        if (fsp->write_time_forced) {
		/*
		 * No point - "sticky" write times
		 * in effect.
		 */
                return;
        }

	TALLOC_FREE(fsp->update_write_time_event);
	DEBUG(5, ("Update write time immediate on %s\n",
		  fsp_str_dbg(fsp)));

	/* After an immediate update, reset the trigger. */
	fsp->update_write_time_triggered = true;
        fsp->update_write_time_on_close = false;

	ZERO_STRUCT(ft);
	ft.mtime = timespec_current();

	/* Update the time in the open file db. */
	(void)set_write_time(fsp->file_id, ft.mtime);

	/* Now set on disk - takes care of notify. */
	(void)smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
}
Ejemplo n.º 2
0
static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
{
	struct smb_file_time ft;
	NTSTATUS status;
	struct share_mode_lock *lck = NULL;

	ZERO_STRUCT(ft);

	if (!fsp->update_write_time_on_close) {
		return NT_STATUS_OK;
	}

	if (null_timespec(fsp->close_write_time)) {
		fsp->close_write_time = timespec_current();
	}

	/* Ensure we have a valid stat struct for the source. */
	status = vfs_stat_fsp(fsp);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	if (!VALID_STAT(fsp->fsp_name->st)) {
		/* if it doesn't seem to be a real file */
		return NT_STATUS_OK;
	}

	/* On close if we're changing the real file time we
	 * must update it in the open file db too. */
	(void)set_write_time(fsp->file_id, fsp->close_write_time);

	lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, NULL);
	if (lck) {
		/* Close write times overwrite sticky write times
		   so we must replace any sticky write time here. */
		if (!null_timespec(lck->changed_write_time)) {
			(void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
		}
		TALLOC_FREE(lck);
	}

	ft.mtime = fsp->close_write_time;
	/* We must use NULL for the fsp handle here, as smb_set_file_time()
	   checks the fsp access_mask, which may not include FILE_WRITE_ATTRIBUTES.
	   As this is a close based update, we are not directly changing the
	   file attributes from a client call, but indirectly from a write. */
	status = smb_set_file_time(fsp->conn, NULL, fsp->fsp_name, &ft, false);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10,("update_write_time_on_close: smb_set_file_time "
			"on file %s returned %s\n",
			fsp_str_dbg(fsp),
			nt_errstr(status)));
		return status;
	}

	return status;
}
Ejemplo n.º 3
0
static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
{
    struct smb_file_time ft;
    NTSTATUS status;
    struct share_mode_lock *lck = NULL;

    ZERO_STRUCT(ft);

    if (!fsp->update_write_time_on_close) {
        return NT_STATUS_OK;
    }

    if (null_timespec(fsp->close_write_time)) {
        fsp->close_write_time = timespec_current();
    }

    /* Ensure we have a valid stat struct for the source. */
    status = vfs_stat_fsp(fsp);
    if (!NT_STATUS_IS_OK(status)) {
        return status;
    }

    if (!VALID_STAT(fsp->fsp_name->st)) {
        /* if it doesn't seem to be a real file */
        return NT_STATUS_OK;
    }

    /* On close if we're changing the real file time we
     * must update it in the open file db too. */
    (void)set_write_time(fsp->file_id, fsp->close_write_time);

    lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, NULL);
    if (lck) {
        /* Close write times overwrite sticky write times
           so we must replace any sticky write time here. */
        if (!null_timespec(lck->changed_write_time)) {
            (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
        }
        TALLOC_FREE(lck);
    }

    ft.mtime = fsp->close_write_time;
    status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
    if (!NT_STATUS_IS_OK(status)) {
        return status;
    }

    return status;
}
Ejemplo n.º 4
0
void update_write_time_handler(struct event_context *ctx,
				      struct timed_event *te,
				      struct timeval now,
				      void *private_data)
{
	files_struct *fsp = (files_struct *)private_data;

	DEBUG(5, ("Update write time on %s\n", fsp_str_dbg(fsp)));

	/* change the write time in the open file db. */
	(void)set_write_time(fsp->file_id, timespec_current());

	/* And notify. */
        notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
                     FILE_NOTIFY_CHANGE_LAST_WRITE, fsp->fsp_name->base_name);

	/* Remove the timed event handler. */
	TALLOC_FREE(fsp->update_write_time_event);
}
Ejemplo n.º 5
0
static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
{
	struct smb_file_time ft;
	NTSTATUS status;
	struct share_mode_lock *lck = NULL;

	ZERO_STRUCT(ft);

	if (!fsp->update_write_time_on_close) {
		return NT_STATUS_OK;
	}

	if (null_timespec(fsp->close_write_time)) {
		fsp->close_write_time = timespec_current();
	}

	/* Ensure we have a valid stat struct for the source. */
	status = vfs_stat_fsp(fsp);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	if (!VALID_STAT(fsp->fsp_name->st)) {
		/* if it doesn't seem to be a real file */
		return NT_STATUS_OK;
	}

	/*
	 * get_existing_share_mode_lock() isn't really the right
	 * call here, as we're being called after
	 * close_remove_share_mode() inside close_normal_file()
	 * so it's quite normal to not have an existing share
	 * mode here. However, get_share_mode_lock() doesn't
	 * work because that will create a new share mode if
	 * one doesn't exist - so stick with this call (just
	 * ignore any error we get if the share mode doesn't
	 * exist.
	 */

	lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
	if (lck) {
		/* On close if we're changing the real file time we
		 * must update it in the open file db too. */
		(void)set_write_time(fsp->file_id, fsp->close_write_time);

		/* Close write times overwrite sticky write times
		   so we must replace any sticky write time here. */
		if (!null_timespec(lck->data->changed_write_time)) {
			(void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
		}
		TALLOC_FREE(lck);
	}

	ft.mtime = fsp->close_write_time;
	/* As this is a close based update, we are not directly changing the
	   file attributes from a client call, but indirectly from a write. */
	status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10,("update_write_time_on_close: smb_set_file_time "
			"on file %s returned %s\n",
			fsp_str_dbg(fsp),
			nt_errstr(status)));
		return status;
	}

	return status;
}