/* a fsp to use when chaining */
static files_struct *chain_fsp = NULL;
-/* a fsp to use to save when breaking an oplock. */
-static files_struct *oplock_save_chain_fsp = NULL;
static int files_used;
/* A singleton cache to speed up searching by dev/inode. */
static struct fsp_singleton_cache {
files_struct *fsp;
- SMB_DEV_T dev;
- SMB_INO_T inode;
+ struct file_id id;
} fsp_fi_cache;
/****************************************************************************
Find first available file slot.
****************************************************************************/
-files_struct *file_new(connection_struct *conn)
+NTSTATUS file_new(connection_struct *conn, files_struct **result)
{
int i;
static int first_file;
/* TODO: We have to unconditionally return a DOS error here,
* W2k3 even returns ERRDOS/ERRnofids for ntcreate&x with
* NTSTATUS negotiated */
- set_saved_ntstatus(NT_STATUS_TOO_MANY_OPENED_FILES);
- return NULL;
+ return NT_STATUS_TOO_MANY_OPENED_FILES;
}
fsp = SMB_MALLOC_P(files_struct);
if (!fsp) {
- set_saved_ntstatus(NT_STATUS_NO_MEMORY);
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
ZERO_STRUCTP(fsp);
fsp->fh = SMB_MALLOC_P(struct fd_handle);
if (!fsp->fh) {
SAFE_FREE(fsp);
- set_saved_ntstatus(NT_STATUS_NO_MEMORY);
- return NULL;
+ return NT_STATUS_NO_MEMORY;
}
ZERO_STRUCTP(fsp->fh);
fsp->fh->fd = -1;
fsp->conn = conn;
- fsp->file_id = get_gen_count();
+ fsp->fh->gen_id = get_gen_count();
GetTimeOfDay(&fsp->open_time);
first_file = (i+1) % real_max_open_files;
if (fsp_fi_cache.fsp == NULL) {
ZERO_STRUCT(fsp_fi_cache);
}
-
- return fsp;
+
+ *result = fsp;
+ return NT_STATUS_OK;
}
/****************************************************************************
files_struct *fsp;
for (fsp=Files;fsp;fsp=fsp->next,count++) {
- DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, fileid = %lu, dev = %x, inode = %.0f\n",
- count, fsp->fnum, fsp->fsp_name, fsp->fh->fd, (unsigned long)fsp->file_id,
- (unsigned int)fsp->dev, (double)fsp->inode ));
+ DEBUG(10,("Files[%d], fnum = %d, name %s, fd = %d, gen = %lu, fileid=%s\n",
+ count, fsp->fnum, fsp->fsp_name, fsp->fh->fd, (unsigned long)fsp->fh->gen_id,
+ file_id_static_string(&fsp->file_id)));
}
}
Find a fsp given a device, inode and file_id.
****************************************************************************/
-files_struct *file_find_dif(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id)
+files_struct *file_find_dif(struct file_id id, unsigned long gen_id)
{
int count=0;
files_struct *fsp;
for (fsp=Files;fsp;fsp=fsp->next,count++) {
/* We can have a fsp->fh->fd == -1 here as it could be a stat open. */
- if (fsp->dev == dev &&
- fsp->inode == inode &&
- fsp->file_id == file_id ) {
+ if (file_id_equal(&fsp->file_id, &id) &&
+ fsp->fh->gen_id == gen_id ) {
if (count > 10) {
DLIST_PROMOTE(Files, fsp);
}
if ((fsp->fh->fd == -1) &&
(fsp->oplock_type != NO_OPLOCK) &&
(fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
- DEBUG(0,("file_find_dif: file %s dev = %x, inode = %.0f, file_id = %u \
-oplock_type = %u is a stat open with oplock type !\n", fsp->fsp_name, (unsigned int)fsp->dev,
- (double)fsp->inode, (unsigned int)fsp->file_id,
- (unsigned int)fsp->oplock_type ));
+ DEBUG(0,("file_find_dif: file %s file_id = %s, gen = %u \
+oplock_type = %u is a stat open with oplock type !\n", fsp->fsp_name,
+ file_id_static_string(&fsp->file_id),
+ (unsigned int)fsp->fh->gen_id,
+ (unsigned int)fsp->oplock_type ));
smb_panic("file_find_dif\n");
}
return fsp;
calls.
****************************************************************************/
-files_struct *file_find_di_first(SMB_DEV_T dev, SMB_INO_T inode)
+files_struct *file_find_di_first(struct file_id id)
{
files_struct *fsp;
- if (fsp_fi_cache.dev == dev && fsp_fi_cache.inode == inode) {
+ if (file_id_equal(&fsp_fi_cache.id, &id)) {
/* Positive or negative cache hit. */
return fsp_fi_cache.fsp;
}
- fsp_fi_cache.dev = dev;
- fsp_fi_cache.inode = inode;
+ fsp_fi_cache.id = id;
for (fsp=Files;fsp;fsp=fsp->next) {
if ( fsp->fh->fd != -1 &&
- fsp->dev == dev &&
- fsp->inode == inode ) {
+ file_id_equal(&fsp->file_id, &id)) {
/* Setup positive cache. */
fsp_fi_cache.fsp = fsp;
return fsp;
for (fsp = start_fsp->next;fsp;fsp=fsp->next) {
if ( fsp->fh->fd != -1 &&
- fsp->dev == start_fsp->dev &&
- fsp->inode == start_fsp->inode )
+ file_id_equal(&fsp->file_id, &start_fsp->file_id)) {
return fsp;
+ }
}
return NULL;
Record the owner of that modtime.
****************************************************************************/
-void fsp_set_pending_modtime(files_struct *tfsp, time_t pmod)
+void fsp_set_pending_modtime(files_struct *tfsp, const struct timespec mod)
{
files_struct *fsp;
- if (null_mtime(pmod)) {
+ if (null_timespec(mod)) {
return;
}
for (fsp = Files;fsp;fsp=fsp->next) {
- if ( fsp->fh->fd != -1 &&
- fsp->dev == tfsp->dev &&
- fsp->inode == tfsp->inode ) {
- fsp->pending_modtime = pmod;
+ if ( fsp->fh->fd != -1 && file_id_equal(&fsp->file_id, &tfsp->file_id)) {
+ fsp->pending_modtime = mod;
fsp->pending_modtime_owner = False;
}
}
fsp->fh->ref_count--;
}
+ if (fsp->notify) {
+ notify_remove(fsp->conn->notify_ctx, fsp);
+ TALLOC_FREE(fsp->notify);
+ }
+
bitmap_clear(file_bmap, fsp->fnum - FILE_HANDLE_OFFSET);
files_used--;
}
/****************************************************************************
- Get a fsp from a packet given the offset of a 16 bit fnum.
+ Get an fsp from a 16 bit fnum.
****************************************************************************/
-files_struct *file_fsp(char *buf, int where)
+files_struct *file_fnum(uint16 fnum)
{
- int fnum, count=0;
files_struct *fsp;
-
- if (chain_fsp)
- return chain_fsp;
-
- if (!buf)
- return NULL;
- fnum = SVAL(buf, where);
+ int count=0;
for (fsp=Files;fsp;fsp=fsp->next, count++) {
if (fsp->fnum == fnum) {
- chain_fsp = fsp;
if (count > 10) {
DLIST_PROMOTE(Files, fsp);
}
}
/****************************************************************************
- Reset the chained fsp - done at the start of a packet reply.
+ Get an fsp from a packet given the offset of a 16 bit fnum.
****************************************************************************/
-void file_chain_reset(void)
+files_struct *file_fsp(char *buf, int where)
{
- chain_fsp = NULL;
-}
+ files_struct *fsp;
-/****************************************************************************
- Save the chained fsp - done when about to do an oplock break.
-****************************************************************************/
+ if (chain_fsp) {
+ return chain_fsp;
+ }
-void file_chain_save(void)
-{
- oplock_save_chain_fsp = chain_fsp;
+ if (!buf) {
+ return NULL;
+ }
+
+ fsp = file_fnum(SVAL(buf, where));
+ if (fsp) {
+ chain_fsp = fsp;
+ }
+ return fsp;
}
/****************************************************************************
- Restore the chained fsp - done after an oplock break.
+ Reset the chained fsp - done at the start of a packet reply.
****************************************************************************/
-void file_chain_restore(void)
+void file_chain_reset(void)
{
- chain_fsp = oplock_save_chain_fsp;
+ chain_fsp = NULL;
}
/****************************************************************************
Duplicate the file handle part for a DOS or FCB open.
****************************************************************************/
-files_struct *dup_file_fsp(files_struct *fsp,
+NTSTATUS dup_file_fsp(files_struct *fsp,
uint32 access_mask,
uint32 share_access,
- uint32 create_options)
+ uint32 create_options,
+ files_struct **result)
{
- files_struct *dup_fsp = file_new(fsp->conn);
+ NTSTATUS status;
+ files_struct *dup_fsp;
- if (!dup_fsp) {
- return NULL;
+ status = file_new(fsp->conn, &dup_fsp);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
SAFE_FREE(dup_fsp->fh);
dup_fsp->fh = fsp->fh;
dup_fsp->fh->ref_count++;
- dup_fsp->dev = fsp->dev;
- dup_fsp->inode = fsp->inode;
+ dup_fsp->file_id = fsp->file_id;
dup_fsp->initial_allocation_size = fsp->initial_allocation_size;
dup_fsp->mode = fsp->mode;
dup_fsp->file_pid = fsp->file_pid;
dup_fsp->modified = fsp->modified;
dup_fsp->is_directory = fsp->is_directory;
dup_fsp->is_stat = fsp->is_stat;
- dup_fsp->aio_write_behind = fsp->aio_write_behind;
string_set(&dup_fsp->fsp_name,fsp->fsp_name);
- return dup_fsp;
+ *result = dup_fsp;
+ return NT_STATUS_OK;
}