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:
parent
76418e23bc
commit
b97f1ce68a
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user