summaryrefslogtreecommitdiff
path: root/source3/locking
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2008-03-12 15:32:47 +0100
committerStefan Metzmacher <metze@samba.org>2008-04-07 12:29:25 +0200
commit2ccf50256e31bd7b9da0f7a7c223bebca5bca062 (patch)
treecce0d5430e82941b8195e6952fd2704241f4ddfa /source3/locking
parent4f715d110279098bb62cb3f5b0831f1a8868068a (diff)
downloadsamba-2ccf50256e31bd7b9da0f7a7c223bebca5bca062.tar.gz
samba-2ccf50256e31bd7b9da0f7a7c223bebca5bca062.tar.bz2
samba-2ccf50256e31bd7b9da0f7a7c223bebca5bca062.zip
locking: store the write time in the locking.tdb
This is needed to implement the strange write time update logic later. We need to store 2 time timestamps to distinguish between the time the file system had before the first client opened the file and a forced timestamp update. metze (This used to be commit 6aaa2ce0eeb46f6735ec984a2e7aadde7a7f456d)
Diffstat (limited to 'source3/locking')
-rw-r--r--source3/locking/locking.c96
1 files changed, 82 insertions, 14 deletions
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 782e10fb7c..8d8c0347a5 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -503,12 +503,20 @@ static bool parse_share_modes(TDB_DATA dbuf, struct share_mode_lock *lck)
data = (struct locking_data *)dbuf.dptr;
lck->delete_on_close = data->u.s.delete_on_close;
+ lck->old_write_time = data->u.s.old_write_time;
+ lck->changed_write_time = data->u.s.changed_write_time;
lck->num_share_modes = data->u.s.num_share_mode_entries;
- DEBUG(10, ("parse_share_modes: delete_on_close: %d, "
- "num_share_modes: %d\n",
- lck->delete_on_close,
- lck->num_share_modes));
+ DEBUG(10, ("parse_share_modes: delete_on_close: %d, owrt: %s, "
+ "cwrt: %s, tok: %u, num_share_modes: %d\n",
+ lck->delete_on_close,
+ timestring(debug_ctx(),
+ convert_timespec_to_time_t(lck->old_write_time)),
+ timestring(debug_ctx(),
+ convert_timespec_to_time_t(
+ lck->changed_write_time)),
+ (unsigned int)data->u.s.delete_token_size,
+ lck->num_share_modes));
if ((lck->num_share_modes < 0) || (lck->num_share_modes > 1000000)) {
DEBUG(0, ("invalid number of share modes: %d\n",
@@ -659,11 +667,20 @@ static TDB_DATA unparse_share_modes(struct share_mode_lock *lck)
ZERO_STRUCTP(data);
data->u.s.num_share_mode_entries = lck->num_share_modes;
data->u.s.delete_on_close = lck->delete_on_close;
+ data->u.s.old_write_time = lck->old_write_time;
+ data->u.s.changed_write_time = lck->changed_write_time;
data->u.s.delete_token_size = delete_token_size;
- DEBUG(10, ("unparse_share_modes: del: %d, tok = %u, num: %d\n",
- data->u.s.delete_on_close,
- (unsigned int)data->u.s.delete_token_size,
- data->u.s.num_share_mode_entries));
+
+ DEBUG(10,("unparse_share_modes: del: %d, owrt: %s cwrt: %s, tok: %u, "
+ "num: %d\n", data->u.s.delete_on_close,
+ timestring(debug_ctx(),
+ convert_timespec_to_time_t(lck->old_write_time)),
+ timestring(debug_ctx(),
+ convert_timespec_to_time_t(
+ lck->changed_write_time)),
+ (unsigned int)data->u.s.delete_token_size,
+ data->u.s.num_share_mode_entries));
+
memcpy(result.dptr + sizeof(*data), lck->share_modes,
sizeof(struct share_mode_entry)*lck->num_share_modes);
offset = sizeof(*data) +
@@ -739,7 +756,8 @@ static bool fill_share_mode_lock(struct share_mode_lock *lck,
struct file_id id,
const char *servicepath,
const char *fname,
- TDB_DATA share_mode_data)
+ TDB_DATA share_mode_data,
+ const struct timespec *old_write_time)
{
/* Ensure we set every field here as the destructor must be
valid even if parse_share_modes fails. */
@@ -751,13 +769,16 @@ static bool fill_share_mode_lock(struct share_mode_lock *lck,
lck->share_modes = NULL;
lck->delete_token = NULL;
lck->delete_on_close = False;
+ ZERO_STRUCT(lck->old_write_time);
+ ZERO_STRUCT(lck->changed_write_time);
lck->fresh = False;
lck->modified = False;
lck->fresh = (share_mode_data.dptr == NULL);
if (lck->fresh) {
- if (fname == NULL || servicepath == NULL) {
+ if (fname == NULL || servicepath == NULL
+ || old_write_time == NULL) {
return False;
}
lck->filename = talloc_strdup(lck, fname);
@@ -766,6 +787,7 @@ static bool fill_share_mode_lock(struct share_mode_lock *lck,
DEBUG(0, ("talloc failed\n"));
return False;
}
+ lck->old_write_time = *old_write_time;
} else {
if (!parse_share_modes(share_mode_data, lck)) {
DEBUG(0, ("Could not parse share modes\n"));
@@ -779,7 +801,8 @@ static bool fill_share_mode_lock(struct share_mode_lock *lck,
struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
const struct file_id id,
const char *servicepath,
- const char *fname)
+ const char *fname,
+ const struct timespec *old_write_time)
{
struct share_mode_lock *lck;
struct file_id tmp;
@@ -797,7 +820,7 @@ struct share_mode_lock *get_share_mode_lock(TALLOC_CTX *mem_ctx,
}
if (!fill_share_mode_lock(lck, id, servicepath, fname,
- lck->record->value)) {
+ lck->record->value, old_write_time)) {
DEBUG(3, ("fill_share_mode_lock failed\n"));
TALLOC_FREE(lck);
return NULL;
@@ -829,7 +852,7 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
return NULL;
}
- if (!fill_share_mode_lock(lck, id, servicepath, fname, data)) {
+ if (!fill_share_mode_lock(lck, id, servicepath, fname, data, NULL)) {
DEBUG(3, ("fill_share_mode_lock failed\n"));
TALLOC_FREE(lck);
return NULL;
@@ -917,6 +940,26 @@ bool rename_share_filename(struct messaging_context *msg_ctx,
return True;
}
+struct timespec get_write_time(struct file_id id)
+{
+ struct timespec result;
+ struct share_mode_lock *lck;
+
+ ZERO_STRUCT(result);
+
+ if (!(lck = fetch_share_mode_unlocked(talloc_tos(), id, NULL, NULL))) {
+ return result;
+ }
+ result = lck->changed_write_time;
+
+ if (null_timespec(result)) {
+ result = lck->old_write_time;
+ }
+
+ TALLOC_FREE(lck);
+ return result;
+}
+
bool get_delete_on_close_flag(struct file_id id)
{
bool result;
@@ -1321,7 +1364,8 @@ bool set_delete_on_close(files_struct *fsp, bool delete_on_close, UNIX_USER_TOKE
return True;
}
- lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL);
+ lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
+ NULL);
if (lck == NULL) {
return False;
}
@@ -1361,6 +1405,30 @@ bool set_allow_initial_delete_on_close(struct share_mode_lock *lck, files_struct
return True;
}
+bool set_write_time(struct file_id fileid, struct timespec write_time,
+ bool overwrite)
+{
+ struct share_mode_lock *lck;
+
+ DEBUG(5,("set_write_time: %s overwrite=%d id=%s\n",
+ timestring(debug_ctx(),
+ convert_timespec_to_time_t(write_time)),
+ overwrite, file_id_string_tos(&fileid)));
+
+ lck = get_share_mode_lock(NULL, fileid, NULL, NULL, NULL);
+ if (lck == NULL) {
+ return False;
+ }
+
+ if (overwrite || null_timespec(lck->changed_write_time)) {
+ lck->modified = True;
+ lck->changed_write_time = write_time;
+ }
+
+ TALLOC_FREE(lck);
+ return True;
+}
+
struct forall_state {
void (*fn)(const struct share_mode_entry *entry,
const char *sharepath,