1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-27 22:50:26 +03:00

s3: Add extid to the dev/inode pair

This extends the file_id struct to add an additional generic uint64_t
field: extid.  For backwards compatibility with dev/inodes stored in
xattr_tdbs and acl_tdbs, the ext id is ignored for these databases.
This patch should cause no functional change on systems that don't use
SMB_VFS_FILE_ID_CREATE to set the extid.

Existing code that uses the smb_share_mode library will need to be
updated to be compatibile with the new extid.
This commit is contained in:
Tim Prouty 2009-02-15 23:45:28 -08:00
parent 6fbebb5369
commit e4675ce8db
14 changed files with 122 additions and 63 deletions

View File

@ -49,6 +49,7 @@ struct file_id {
other than a dev_t for the device */
uint64_t devid;
uint64_t inode;
uint64_t extid; /* Support systems that use an extended id (e.g. snapshots). */
};
struct byte_range_lock {

View File

@ -512,7 +512,8 @@ struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_S
bool file_id_equal(const struct file_id *id1, const struct file_id *id2);
const char *file_id_string_tos(const struct file_id *id);
void push_file_id_16(char *buf, const struct file_id *id);
void pull_file_id_16(char *buf, struct file_id *id);
void push_file_id_24(char *buf, const struct file_id *id);
void pull_file_id_24(char *buf, struct file_id *id);
/* The following definitions come from lib/gencache.c */

View File

@ -758,18 +758,19 @@ Offset Data length.
16 uint32 private_options 4
20 uint32 time sec 4
24 uint32 time usec 4
28 SMB_DEV_T dev 8 bytes.
36 SMB_INO_T inode 8 bytes
44 unsigned long file_id 4 bytes
48 uint32 uid 4 bytes
52 uint16 flags 2 bytes
54
28 uint64 dev 8 bytes
36 uint64 inode 8 bytes
44 uint64 extid 8 bytes
52 unsigned long file_id 4 bytes
56 uint32 uid 4 bytes
60 uint16 flags 2 bytes
62
*/
#ifdef CLUSTER_SUPPORT
#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 58
#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 66
#else
#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 54
#define MSG_SMB_SHARE_MODE_ENTRY_SIZE 62
#endif
struct share_mode_lock {
@ -1631,37 +1632,40 @@ struct inform_level2_message {
/* kernel_oplock_message definition.
struct kernel_oplock_message {
SMB_DEV_T dev;
SMB_INO_T inode;
uint64_t dev;
uint64_t inode;
unit64_t extid;
unsigned long file_id;
};
Offset Data length.
0 SMB_DEV_T dev 8 bytes.
8 SMB_INO_T inode 8 bytes
16 unsigned long file_id 4 bytes
20
0 uint64_t dev 8 bytes
8 uint64_t inode 8 bytes
16 uint64_t extid 8 bytes
24 unsigned long file_id 4 bytes
28
*/
#define MSG_SMB_KERNEL_BREAK_SIZE 20
#define MSG_SMB_KERNEL_BREAK_SIZE 28
/* file_renamed_message definition.
struct file_renamed_message {
SMB_DEV_T dev;
SMB_INO_T inode;
uint64_t dev;
uint64_t inode;
char names[1]; A variable area containing sharepath and filename.
};
Offset Data length.
0 SMB_DEV_T dev 8 bytes.
8 SMB_INO_T inode 8 bytes
16 char [] name zero terminated namelen bytes
minimum length == 18.
0 uint64_t dev 8 bytes
8 uint64_t inode 8 bytes
16 unit64_t extid 8 bytes
24 char [] name zero terminated namelen bytes
minimum length == 24.
*/
#define MSG_FILE_RENAMED_MIN_SIZE 16
#define MSG_FILE_RENAMED_MIN_SIZE 24
/*
* On the wire return values for oplock types.

View File

@ -46,6 +46,7 @@ struct smbdb_ctx;
struct smb_share_mode_entry {
uint64_t dev;
uint64_t ino;
uint64_t extid;
uint32_t share_access;
uint32_t access_mask;
struct timeval open_time;
@ -66,11 +67,13 @@ int smb_share_mode_db_close(struct smbdb_ctx *db_ctx);
int smb_lock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino);
uint64_t ino,
uint64_t extid);
int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino);
uint64_t ino,
uint64_t extid);
/*
* Share mode database accessor functions.
@ -79,23 +82,27 @@ int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx,
int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
uint64_t extid,
struct smb_share_mode_entry **pp_list,
unsigned char *p_delete_on_close);
int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
uint64_t extid,
const struct smb_share_mode_entry *set_entry,
const char *path);
int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
uint64_t extid,
const struct smb_share_mode_entry *set_entry);
int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
uint64_t extid,
const struct smb_share_mode_entry *set_entry,
const struct smb_share_mode_entry *new_entry);

View File

@ -34,7 +34,8 @@ struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_S
*/
bool file_id_equal(const struct file_id *id1, const struct file_id *id2)
{
return id1->inode == id2->inode && id1->devid == id2->devid;
return id1->inode == id2->inode && id1->devid == id2->devid &&
id1->extid == id2->extid;
}
/*
@ -42,15 +43,17 @@ bool file_id_equal(const struct file_id *id1, const struct file_id *id2)
*/
const char *file_id_string_tos(const struct file_id *id)
{
char *result = talloc_asprintf(talloc_tos(), "%llx:%llx",
char *result = talloc_asprintf(talloc_tos(), "%llx:%llx:%llx",
(unsigned long long)id->devid,
(unsigned long long)id->inode);
(unsigned long long)id->inode,
(unsigned long long)id->extid);
SMB_ASSERT(result != NULL);
return result;
}
/*
push a 16 byte version of a file id into a buffer
push a 16 byte version of a file id into a buffer. This ignores the extid
and is needed when dev/inodes are stored in persistent storage (tdbs).
*/
void push_file_id_16(char *buf, const struct file_id *id)
{
@ -61,13 +64,28 @@ void push_file_id_16(char *buf, const struct file_id *id)
}
/*
pul a 16 byte version of a file id from a buffer
push a 24 byte version of a file id into a buffer
*/
void pull_file_id_16(char *buf, struct file_id *id)
void push_file_id_24(char *buf, const struct file_id *id)
{
SIVAL(buf, 0, id->devid&0xFFFFFFFF);
SIVAL(buf, 4, id->devid>>32);
SIVAL(buf, 8, id->inode&0xFFFFFFFF);
SIVAL(buf, 12, id->inode>>32);
SIVAL(buf, 16, id->extid&0xFFFFFFFF);
SIVAL(buf, 20, id->extid>>32);
}
/*
pull a 24 byte version of a file id from a buffer
*/
void pull_file_id_24(char *buf, struct file_id *id)
{
ZERO_STRUCTP(id);
id->devid = IVAL(buf, 0);
id->devid |= ((uint64_t)IVAL(buf,4))<<32;
id->inode = IVAL(buf, 8);
id->inode |= ((uint64_t)IVAL(buf,12))<<32;
id->extid = IVAL(buf, 16);
id->extid |= ((uint64_t)IVAL(buf,20))<<32;
}

View File

@ -38,7 +38,8 @@ struct smbdb_ctx {
#endif
int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, uint64_t dev,
uint64_t ino, const struct smb_share_mode_entry *new_entry,
uint64_t ino, uint64_t extid,
const struct smb_share_mode_entry *new_entry,
const char *sharepath, const char *filename);
static bool sharemodes_procid_equal(const struct server_id *p1, const struct server_id *p2)
@ -83,6 +84,7 @@ struct smbdb_ctx *smb_share_mode_db_open(const char *db_path)
struct locking_key {
SMB_DEV_T dev;
SMB_INO_T inode;
uint64_t extid;
};
int smb_share_mode_db_close(struct smbdb_ctx *db_ctx)
@ -93,13 +95,14 @@ int smb_share_mode_db_close(struct smbdb_ctx *db_ctx)
}
static TDB_DATA get_locking_key(struct locking_key *lk, uint64_t dev,
uint64_t ino)
uint64_t ino, uint64_t extid)
{
TDB_DATA ld;
memset(lk, '\0', sizeof(*lk));
lk->dev = (SMB_DEV_T)dev;
lk->inode = (SMB_INO_T)ino;
lk->extid = extid;
ld.dptr = (uint8 *)lk;
ld.dsize = sizeof(*lk);
return ld;
@ -111,19 +114,22 @@ static TDB_DATA get_locking_key(struct locking_key *lk, uint64_t dev,
int smb_lock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino)
uint64_t ino,
uint64_t extid)
{
struct locking_key lk;
return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino));
return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino,
extid));
}
int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino)
uint64_t ino,
uint64_t extid)
{
struct locking_key lk;
return tdb_chainunlock(db_ctx->smb_tdb,
get_locking_key(&lk, dev, ino));
get_locking_key(&lk, dev, ino, extid));
}
/*
@ -140,7 +146,8 @@ static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry,
e_entry->share_access == (uint32_t)entry->share_access &&
e_entry->access_mask == (uint32_t)entry->access_mask &&
e_entry->dev == entry->id.devid &&
e_entry->ino == entry->id.inode);
e_entry->ino == entry->id.inode &&
e_entry->extid == entry->id.extid);
}
/*
@ -160,6 +167,7 @@ static void create_share_mode_entry(struct share_mode_entry *out,
out->access_mask = in->access_mask;
out->id.devid = in->dev;
out->id.inode = in->ino;
out->id.extid = in->extid;
out->uid = (uint32)geteuid();
out->flags = 0;
}
@ -172,6 +180,7 @@ static void create_share_mode_entry(struct share_mode_entry *out,
int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
uint64_t extid,
struct smb_share_mode_entry **pp_list,
unsigned char *p_delete_on_close)
{
@ -187,7 +196,8 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
*pp_list = NULL;
*p_delete_on_close = 0;
db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino));
db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(&lk, dev, ino,
extid));
if (!db_data.dptr) {
return 0;
}
@ -229,6 +239,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
/* Copy into the external list. */
sme->dev = share->id.devid;
sme->ino = share->id.inode;
sme->extid = share->id.extid;
sme->share_access = (uint32_t)share->share_access;
sme->access_mask = (uint32_t)share->access_mask;
sme->open_time.tv_sec = share->time.tv_sec;
@ -257,13 +268,14 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx,
int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
uint64_t extid,
const struct smb_share_mode_entry *new_entry,
const char *sharepath, /* Must be absolute utf8 path. */
const char *filename) /* Must be relative utf8 path. */
{
TDB_DATA db_data;
struct locking_key lk;
TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
TDB_DATA locking_key = get_locking_key(&lk, dev, ino, extid);
int orig_num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;
@ -360,24 +372,26 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx,
int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
uint64_t extid,
const struct smb_share_mode_entry *new_entry,
const char *filename) /* Must be absolute utf8 path. */
{
if (*filename != '/') {
abort();
}
return smb_create_share_mode_entry_ex(db_ctx, dev, ino, new_entry,
return smb_create_share_mode_entry_ex(db_ctx, dev, ino, extid, new_entry,
"/", &filename[1]);
}
int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
uint64_t extid,
const struct smb_share_mode_entry *del_entry)
{
TDB_DATA db_data;
struct locking_key lk;
TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
TDB_DATA locking_key = get_locking_key(&lk, dev, ino, extid);
int orig_num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;
@ -475,12 +489,13 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx,
int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx,
uint64_t dev,
uint64_t ino,
uint64_t extid,
const struct smb_share_mode_entry *set_entry,
const struct smb_share_mode_entry *new_entry)
{
TDB_DATA db_data;
struct locking_key lk;
TDB_DATA locking_key = get_locking_key(&lk, dev, ino);
TDB_DATA locking_key = get_locking_key(&lk, dev, ino, extid);
int num_share_modes = 0;
struct locking_data *ld = NULL; /* internal samba db state. */
struct share_mode_entry *shares = NULL;

View File

@ -923,12 +923,12 @@ bool rename_share_filename(struct messaging_context *msg_ctx,
return False;
}
push_file_id_16(frm, &lck->id);
push_file_id_24(frm, &lck->id);
DEBUG(10,("rename_share_filename: msg_len = %u\n", (unsigned int)msg_len ));
safe_strcpy(&frm[16], lck->servicepath, sp_len);
safe_strcpy(&frm[16 + sp_len + 1], lck->filename, fn_len);
safe_strcpy(&frm[24], lck->servicepath, sp_len);
safe_strcpy(&frm[24 + sp_len + 1], lck->filename, fn_len);
/* Send the messages. */
for (i=0; i<lck->num_share_modes; i++) {

View File

@ -94,6 +94,8 @@ static struct db_record *acl_tdb_lock(TALLOC_CTX *mem_ctx,
const struct file_id *id)
{
uint8 id_buf[16];
/* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, id);
return db->fetch_locked(db,
mem_ctx,
@ -200,6 +202,7 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
}
id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
/* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, &id);
if (db->fetch(db,
@ -285,6 +288,7 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle,
}
id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
/* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, &id);
rec = db->fetch_locked(db, talloc_tos(),
make_tdb_data(id_buf,
@ -325,6 +329,8 @@ static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle,
}
id = vfs_file_id_from_sbuf(handle->conn, &sbuf);
/* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, &id);
rec = db->fetch_locked(db, talloc_tos(),

View File

@ -1053,6 +1053,7 @@ static struct file_id vfswrap_file_id_create(struct vfs_handle_struct *handle,
key.devid = sbuf->st_dev;
key.inode = sbuf->st_ino;
/* key.extid is unused by default. */
return key;
}

View File

@ -100,6 +100,7 @@ static NTSTATUS xattr_tdb_load_attrs(TALLOC_CTX *mem_ctx,
NTSTATUS status;
TDB_DATA data;
/* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, id);
if (db_ctx->fetch(db_ctx, mem_ctx,
@ -122,6 +123,8 @@ static struct db_record *xattr_tdb_lock_attrs(TALLOC_CTX *mem_ctx,
const struct file_id *id)
{
uint8 id_buf[16];
/* For backwards compatibility only store the dev/inode. */
push_file_id_16((char *)id_buf, id);
return db_ctx->fetch_locked(db_ctx, mem_ctx,
make_tdb_data(id_buf, sizeof(id_buf)));

View File

@ -66,7 +66,8 @@ struct fsp_singleton_cache fsp_fi_cache = {
.fsp = NULL,
.id = {
.devid = 0,
.inode = 0
.inode = 0,
.extid = 0
}
};
unsigned long file_gen_counter = 0;

View File

@ -1856,6 +1856,8 @@ static void call_nt_transact_ioctl(connection_struct *conn,
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
/* For backwards compatibility only store the dev/inode. */
push_file_id_16(pdata, &fsp->file_id);
memcpy(pdata+16,create_volume_objectid(conn,objid),16);
push_file_id_16(pdata+32, &fsp->file_id);

View File

@ -2597,8 +2597,8 @@ void msg_file_was_renamed(struct messaging_context *msg,
}
/* Unpack the message. */
pull_file_id_16(frm, &id);
sharepath = &frm[16];
pull_file_id_24(frm, &id);
sharepath = &frm[24];
newname = sharepath + strlen(sharepath) + 1;
sp_len = strlen(sharepath);

View File

@ -40,8 +40,8 @@ void break_kernel_oplock(struct messaging_context *msg_ctx, files_struct *fsp)
uint8_t msg[MSG_SMB_KERNEL_BREAK_SIZE];
/* Put the kernel break info into the message. */
push_file_id_16((char *)msg, &fsp->file_id);
SIVAL(msg,16,fsp->fh->gen_id);
push_file_id_24((char *)msg, &fsp->file_id);
SIVAL(msg,24,fsp->fh->gen_id);
/* Don't need to be root here as we're only ever
sending to ourselves. */
@ -583,8 +583,8 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx,
}
/* Pull the data from the message. */
pull_file_id_16((char *)data->data, &id);
file_id = (unsigned long)IVAL(data->data, 16);
pull_file_id_24((char *)data->data, &id);
file_id = (unsigned long)IVAL(data->data, 24);
DEBUG(10, ("Got kernel oplock break message from pid %d: %s/%u\n",
(int)procid_to_pid(&src), file_id_string_tos(&id),
@ -865,12 +865,12 @@ void share_mode_entry_to_message(char *msg, const struct share_mode_entry *e)
SIVAL(msg,16,e->private_options);
SIVAL(msg,20,(uint32)e->time.tv_sec);
SIVAL(msg,24,(uint32)e->time.tv_usec);
push_file_id_16(msg+28, &e->id);
SIVAL(msg,44,e->share_file_id);
SIVAL(msg,48,e->uid);
SSVAL(msg,52,e->flags);
push_file_id_24(msg+28, &e->id);
SIVAL(msg,52,e->share_file_id);
SIVAL(msg,56,e->uid);
SSVAL(msg,60,e->flags);
#ifdef CLUSTER_SUPPORT
SIVAL(msg,54,e->pid.vnn);
SIVAL(msg,62,e->pid.vnn);
#endif
}
@ -888,12 +888,12 @@ void message_to_share_mode_entry(struct share_mode_entry *e, char *msg)
e->private_options = IVAL(msg,16);
e->time.tv_sec = (time_t)IVAL(msg,20);
e->time.tv_usec = (int)IVAL(msg,24);
pull_file_id_16(msg+28, &e->id);
e->share_file_id = (unsigned long)IVAL(msg,44);
e->uid = (uint32)IVAL(msg,48);
e->flags = (uint16)SVAL(msg,52);
pull_file_id_24(msg+28, &e->id);
e->share_file_id = (unsigned long)IVAL(msg,52);
e->uid = (uint32)IVAL(msg,56);
e->flags = (uint16)SVAL(msg,60);
#ifdef CLUSTER_SUPPORT
e->pid.vnn = IVAL(msg,54);
e->pid.vnn = IVAL(msg,62);
#endif
}