1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-26 21:57:41 +03:00

Add name_hash into the share mode entry struct (as yet only use for renames to identify a specific path).

This commit is contained in:
Jeremy Allison 2011-01-25 14:01:52 -08:00
parent 76418e23bc
commit b97f1ce68a
6 changed files with 66 additions and 11 deletions

View File

@ -3068,6 +3068,8 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
bool rename_share_filename(struct messaging_context *msg_ctx,
struct share_mode_lock *lck,
const char *servicepath,
uint32_t orig_name_hash,
uint32_t new_name_hash,
const struct smb_filename *smb_fname);
void get_file_infos(struct file_id id,
bool *delete_on_close,

View File

@ -685,6 +685,7 @@ struct share_mode_entry {
unsigned long share_file_id;
uint32 uid; /* uid of file opener. */
uint16 flags; /* See SHARE_MODE_XX above. */
uint32_t name_hash; /* Jenkins hash of full pathname. */
};
/* oplock break message definition - linearization of share_mode_entry.
@ -704,7 +705,8 @@ Offset Data length.
58 unsigned long file_id 4 bytes
62 uint32 uid 4 bytes
66 uint16 flags 2 bytes
68
68 uint32 name_hash 4 bytes
72
*/
@ -722,12 +724,13 @@ Offset Data length.
#define OP_BREAK_MSG_FILE_ID_OFFSET 58
#define OP_BREAK_MSG_UID_OFFSET 62
#define OP_BREAK_MSG_FLAGS_OFFSET 66
#define OP_BREAK_MSG_NAME_HASH_OFFSET 68
#ifdef CLUSTER_SUPPORT
#define OP_BREAK_MSG_VNN_OFFSET 68
#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 72
#define OP_BREAK_MSG_VNN_OFFSET 72
#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 76
#else
#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 68
#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 72
#endif
struct share_mode_lock {

View File

@ -155,7 +155,8 @@ static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry,
*/
static void create_share_mode_entry(struct share_mode_entry *out,
const struct smb_share_mode_entry *in)
const struct smb_share_mode_entry *in,
uint32_t name_hash)
{
memset(out, '\0', sizeof(struct share_mode_entry));
@ -170,6 +171,7 @@ static void create_share_mode_entry(struct share_mode_entry *out,
out->id.extid = in->extid;
out->uid = (uint32)geteuid();
out->flags = 0;
out->name_hash = name_hash;
}
/*
@ -261,6 +263,26 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
return list_num;
}
static uint32_t smb_name_hash(const char *sharepath, const char *filename, int *err)
{
TDB_DATA key;
char *fullpath = NULL;
int ret;
uint32_t name_hash;
*err = 0;
ret = asprintf(&fullpath, "%s/%s", sharepath, filename);
if (ret == -1 || fullpath == NULL) {
*err = 1;
return 0;
}
key.dptr = (uint8_t *)fullpath;
key.dsize = strlen(fullpath);
name_hash = tdb_jenkins_hash(&key);
free(fullpath);
return name_hash;
}
/*
* Create an entry in the Samba share mode db.
*/
@ -281,6 +303,12 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
struct share_mode_entry *shares = NULL;
uint8 *new_data_p = NULL;
size_t new_data_size = 0;
int err = 0;
uint32_t name_hash = smb_name_hash(sharepath, filename, &err);
if (err) {
return -1;
}
db_data = tdb_fetch(db_ctx->smb_tdb, locking_key);
if (!db_data.dptr) {
@ -299,7 +327,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
ld->u.s.delete_on_close = 0;
ld->u.s.delete_token_size = 0;
shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct locking_data));
create_share_mode_entry(shares, new_entry);
create_share_mode_entry(shares, new_entry, name_hash);
memcpy(db_data.dptr + sizeof(struct locking_data) + sizeof(struct share_mode_entry),
sharepath,
@ -338,7 +366,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
shares = (struct share_mode_entry *)(new_data_p + sizeof(struct locking_data) +
(orig_num_share_modes * sizeof(struct share_mode_entry)));
create_share_mode_entry(shares, new_entry);
create_share_mode_entry(shares, new_entry, name_hash);
ld = (struct locking_data *)new_data_p;
ld->u.s.num_share_mode_entries++;
@ -521,7 +549,7 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx,
}
if (share_mode_entry_equal(set_entry, share)) {
create_share_mode_entry(share, new_entry);
create_share_mode_entry(share, new_entry, share->name_hash);
found_entry = 1;
break;
}

View File

@ -492,7 +492,7 @@ char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
return talloc_asprintf(ctx, "share_mode_entry[%d]: %s "
"pid = %s, share_access = 0x%x, private_options = 0x%x, "
"access_mask = 0x%x, mid = 0x%llx, type= 0x%x, gen_id = %lu, "
"uid = %u, flags = %u, file_id %s",
"uid = %u, flags = %u, file_id %s, name_hash = 0x%x",
num,
e->op_type == UNUSED_SHARE_MODE_ENTRY ? "UNUSED" : "",
procid_str_static(&e->pid),
@ -500,7 +500,8 @@ char *share_mode_str(TALLOC_CTX *ctx, int num, const struct share_mode_entry *e)
e->access_mask, (unsigned long long)e->op_mid,
e->op_type, e->share_file_id,
(unsigned int)e->uid, (unsigned int)e->flags,
file_id_string_tos(&e->id));
file_id_string_tos(&e->id),
(unsigned int)e->name_hash);
}
/*******************************************************************
@ -953,6 +954,8 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx,
bool rename_share_filename(struct messaging_context *msg_ctx,
struct share_mode_lock *lck,
const char *servicepath,
uint32_t orig_name_hash,
uint32_t new_name_hash,
const struct smb_filename *smb_fname_dst)
{
size_t sp_len;
@ -1018,6 +1021,15 @@ bool rename_share_filename(struct messaging_context *msg_ctx,
if (!is_valid_share_mode_entry(se)) {
continue;
}
/* If this is a hardlink to the inode
with a different name, skip this. */
if (se->name_hash != orig_name_hash) {
continue;
}
se->name_hash = new_name_hash;
/* But not to ourselves... */
if (procid_is_me(&se->pid)) {
continue;
@ -1125,6 +1137,7 @@ static void fill_share_mode_entry(struct share_mode_entry *e,
e->share_file_id = fsp->fh->gen_id;
e->uid = (uint32)uid;
e->flags = fsp->posix_open ? SHARE_MODE_FLAG_POSIX_OPEN : 0;
e->name_hash = fsp->name_hash;
}
static void fill_deferred_open_entry(struct share_mode_entry *e,

View File

@ -873,6 +873,7 @@ void share_mode_entry_to_message(char *msg, const struct share_mode_entry *e)
SIVAL(msg,OP_BREAK_MSG_FILE_ID_OFFSET,e->share_file_id);
SIVAL(msg,OP_BREAK_MSG_UID_OFFSET,e->uid);
SSVAL(msg,OP_BREAK_MSG_FLAGS_OFFSET,e->flags);
SIVAL(msg,OP_BREAK_MSG_NAME_HASH_OFFSET,e->name_hash);
#ifdef CLUSTER_SUPPORT
SIVAL(msg,OP_BREAK_MSG_VNN_OFFSET,e->pid.vnn);
#endif
@ -896,6 +897,7 @@ void message_to_share_mode_entry(struct share_mode_entry *e, char *msg)
e->share_file_id = (unsigned long)IVAL(msg,OP_BREAK_MSG_FILE_ID_OFFSET);
e->uid = (uint32)IVAL(msg,OP_BREAK_MSG_UID_OFFSET);
e->flags = (uint16)SVAL(msg,OP_BREAK_MSG_FLAGS_OFFSET);
e->name_hash = IVAL(msg,OP_BREAK_MSG_NAME_HASH_OFFSET);
#ifdef CLUSTER_SUPPORT
e->pid.vnn = IVAL(msg,OP_BREAK_MSG_VNN_OFFSET);
#endif

View File

@ -5804,11 +5804,13 @@ static bool resolve_wildcards(TALLOC_CTX *ctx,
static void rename_open_files(connection_struct *conn,
struct share_mode_lock *lck,
uint32_t orig_name_hash,
const struct smb_filename *smb_fname_dst)
{
files_struct *fsp;
bool did_rename = False;
NTSTATUS status;
uint32_t new_name_hash;
for(fsp = file_find_di_first(conn->sconn, lck->id); fsp;
fsp = file_find_di_next(fsp)) {
@ -5819,6 +5821,9 @@ static void rename_open_files(connection_struct *conn,
if (!strequal(fsp->conn->connectpath, conn->connectpath)) {
continue;
}
if (fsp->name_hash != orig_name_hash) {
continue;
}
DEBUG(10, ("rename_open_files: renaming file fnum %d "
"(file_id %s) from %s -> %s\n", fsp->fnum,
file_id_string_tos(&fsp->file_id), fsp_str_dbg(fsp),
@ -5827,6 +5832,7 @@ static void rename_open_files(connection_struct *conn,
status = fsp_set_smb_fname(fsp, smb_fname_dst);
if (NT_STATUS_IS_OK(status)) {
did_rename = True;
new_name_hash = fsp->name_hash;
}
}
@ -5838,6 +5844,7 @@ static void rename_open_files(connection_struct *conn,
/* Send messages to all smbd's (not ourself) that the name has changed. */
rename_share_filename(conn->sconn->msg_ctx, lck, conn->connectpath,
orig_name_hash, new_name_hash,
smb_fname_dst);
}
@ -6147,7 +6154,7 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
notify_rename(conn, fsp->is_directory, fsp->fsp_name,
smb_fname_dst);
rename_open_files(conn, lck, smb_fname_dst);
rename_open_files(conn, lck, fsp->name_hash, smb_fname_dst);
/*
* A rename acts as a new file create w.r.t. allowing an initial delete