Avoided double copy of dir when closing a file in an open dir
parent
91a3909048
commit
758a99ea87
|
@ -177,6 +177,7 @@ extern ntfs_inode *ntfs_inode_allocate(ntfs_volume *vol);
|
|||
extern ntfs_inode *ntfs_inode_open(ntfs_volume *vol, const MFT_REF mref);
|
||||
|
||||
extern int ntfs_inode_close(ntfs_inode *ni);
|
||||
extern int ntfs_inode_close_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni);
|
||||
|
||||
extern ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni,
|
||||
const MFT_REF mref);
|
||||
|
|
|
@ -2068,8 +2068,10 @@ static int set_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
|
|||
longname, longlen,
|
||||
FILE_NAME_WIN32_AND_DOS) >= 0))
|
||||
res = 0;
|
||||
ntfs_inode_close(ni);
|
||||
ntfs_inode_close(dir_ni);
|
||||
if (ntfs_inode_close_in_dir(ni,dir_ni) && !res)
|
||||
res = -1;
|
||||
if (ntfs_inode_close(dir_ni) && !res)
|
||||
res = -1;
|
||||
}
|
||||
} else
|
||||
if (!ntfs_link_i(ni, dir_ni, shortname, shortlen,
|
||||
|
@ -2088,13 +2090,17 @@ static int set_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
|
|||
longname, longlen,
|
||||
FILE_NAME_WIN32))
|
||||
res = 0;
|
||||
ntfs_inode_close(ni);
|
||||
if (ntfs_inode_close_in_dir(ni,
|
||||
dir_ni)
|
||||
&& !res)
|
||||
res = -1;
|
||||
}
|
||||
ntfs_inode_close(dir_ni);
|
||||
if (ntfs_inode_close(dir_ni) && !res)
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ntfs_inode_close(ni);
|
||||
ntfs_inode_close_in_dir(ni,dir_ni);
|
||||
ntfs_inode_close(dir_ni);
|
||||
}
|
||||
return (res);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* Copyright (c) 2002-2008 Szabolcs Szakacsits
|
||||
* Copyright (c) 2004-2007 Yura Pakhuchiy
|
||||
* Copyright (c) 2004-2005 Richard Russon
|
||||
* Copyright (c) 2009 Jean-Pierre Andre
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as published
|
||||
|
@ -595,7 +596,7 @@ static int ntfs_inode_sync_standard_information(ntfs_inode *ni)
|
|||
*
|
||||
* Return 0 on success or -1 on error with errno set to the error code.
|
||||
*/
|
||||
static int ntfs_inode_sync_file_name(ntfs_inode *ni)
|
||||
static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni)
|
||||
{
|
||||
ntfs_attr_search_ctx *ctx = NULL;
|
||||
ntfs_index_context *ictx;
|
||||
|
@ -625,7 +626,10 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni)
|
|||
*/
|
||||
index_ni = ni;
|
||||
} else
|
||||
index_ni = ntfs_inode_open(ni->vol,
|
||||
if (dir_ni)
|
||||
index_ni = dir_ni;
|
||||
else
|
||||
index_ni = ntfs_inode_open(ni->vol,
|
||||
le64_to_cpu(fn->parent_directory));
|
||||
if (!index_ni) {
|
||||
if (!err)
|
||||
|
@ -640,7 +644,8 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni)
|
|||
err = errno;
|
||||
ntfs_log_perror("Failed to get index ctx, inode %lld",
|
||||
(long long)index_ni->mft_no);
|
||||
if (ni != index_ni && ntfs_inode_close(index_ni) && !err)
|
||||
if ((ni != index_ni) && !dir_ni
|
||||
&& ntfs_inode_close(index_ni) && !err)
|
||||
err = errno;
|
||||
continue;
|
||||
}
|
||||
|
@ -678,7 +683,8 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni)
|
|||
}
|
||||
ntfs_index_entry_mark_dirty(ictx);
|
||||
ntfs_index_ctx_put(ictx);
|
||||
if ((ni != index_ni) && ntfs_inode_close(index_ni) && !err)
|
||||
if ((ni != index_ni) && !dir_ni
|
||||
&& ntfs_inode_close(index_ni) && !err)
|
||||
err = errno;
|
||||
}
|
||||
/* Check for real error occurred. */
|
||||
|
@ -720,11 +726,10 @@ err_out:
|
|||
* EBUSY - Inode and/or one of its extents is busy, try again later.
|
||||
* EIO - I/O error while writing the inode (or one of its extents).
|
||||
*/
|
||||
int ntfs_inode_sync(ntfs_inode *ni)
|
||||
static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
|
||||
{
|
||||
int ret = 0;
|
||||
int err = 0;
|
||||
|
||||
if (!ni) {
|
||||
errno = EINVAL;
|
||||
ntfs_log_error("Failed to sync NULL inode\n");
|
||||
|
@ -746,7 +751,7 @@ int ntfs_inode_sync(ntfs_inode *ni)
|
|||
/* Update FILE_NAME's in the index. */
|
||||
if ((ni->mrec->flags & MFT_RECORD_IN_USE) && ni->nr_extents != -1 &&
|
||||
NInoFileNameTestAndClearDirty(ni) &&
|
||||
ntfs_inode_sync_file_name(ni)) {
|
||||
ntfs_inode_sync_file_name(ni, dir_ni)) {
|
||||
if (!err || errno == EIO) {
|
||||
err = errno;
|
||||
if (err != EIO)
|
||||
|
@ -849,6 +854,28 @@ sync_inode:
|
|||
return ret;
|
||||
}
|
||||
|
||||
int ntfs_inode_sync(ntfs_inode *ni)
|
||||
{
|
||||
return (ntfs_inode_sync_in_dir(ni, (ntfs_inode*)NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
* Close an inode with an open parent inode
|
||||
*/
|
||||
|
||||
int ntfs_inode_close_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = ntfs_inode_sync_in_dir(ni, dir_ni);
|
||||
if (res) {
|
||||
if (errno != EIO)
|
||||
errno = EBUSY;
|
||||
} else
|
||||
res = ntfs_inode_close(ni);
|
||||
return (res);
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_inode_add_attrlist - add attribute list to inode and fill it
|
||||
* @ni: opened ntfs inode to which add attribute list
|
||||
|
|
|
@ -1504,16 +1504,12 @@ static int ntfs_fuse_create(const char *org_path, mode_t typemode, dev_t dev,
|
|||
fi->fh |= CLOSE_ENCRYPTED;
|
||||
NInoSetDirty(ni);
|
||||
/*
|
||||
* closing ni will necessitate to open dir_ni to
|
||||
* synchronize the index.
|
||||
* Better avoid a dangerous double opening.
|
||||
* closing ni requires access to dir_ni to
|
||||
* synchronize the index, avoid double opening.
|
||||
*/
|
||||
if (ntfs_inode_close_in_dir(ni, dir_ni))
|
||||
set_fuse_error(&res);
|
||||
ntfs_fuse_update_times(dir_ni, NTFS_UPDATE_MCTIME);
|
||||
if (ntfs_inode_close(dir_ni))
|
||||
set_fuse_error(&res);
|
||||
dir_ni = (ntfs_inode*)NULL;
|
||||
if (ntfs_inode_close(ni))
|
||||
set_fuse_error(&res);
|
||||
} else
|
||||
res = -errno;
|
||||
#if POSIXACLS
|
||||
|
|
Loading…
Reference in New Issue