diff --git a/libntfs/attrib.c b/libntfs/attrib.c index 0ac4bd8f..1b9f89e5 100644 --- a/libntfs/attrib.c +++ b/libntfs/attrib.c @@ -3131,12 +3131,10 @@ add_attr_record: (val && (ntfs_attr_pwrite(na, 0, size, val) != size))) { err = errno; ntfs_log_trace("Failed to initialize just added attribute.\n"); - if (ntfs_attr_rm(na)) { + if (ntfs_attr_rm(na)) ntfs_log_trace("Failed to remove just added attribute. " "Probably leaving inconsistent " "metadata.\n"); - ntfs_attr_close(na); - } goto err_out; } ntfs_attr_close(na); @@ -3168,7 +3166,8 @@ err_out: * @na: opened ntfs attribute to delete * * Remove attribute and all it's extents from ntfs inode. If attribute was non - * resident also free all clusters allocated by attribute. + * resident also free all clusters allocated by attribute. This function always + * closes @na upon exit (both on success and failure). * * Return 0 on success or -1 on error with errno set to the error code. */ @@ -3188,8 +3187,10 @@ int ntfs_attr_rm(ntfs_attr *na) /* Free cluster allocation. */ if (NAttrNonResident(na)) { - if (ntfs_attr_map_whole_runlist(na)) + if (ntfs_attr_map_whole_runlist(na)) { + ntfs_attr_close(na); return -1; + } if (ntfs_cluster_free(na->ni->vol, na, 0, -1) < 0) { ntfs_log_trace("Failed to free cluster allocation. " "Leaving inconsistent metadata.\n"); @@ -3199,8 +3200,10 @@ int ntfs_attr_rm(ntfs_attr *na) /* Search for attribute extents and remove them all. */ ctx = ntfs_attr_get_search_ctx(na->ni, NULL); - if (!ctx) + if (!ctx) { + ntfs_attr_close(na); return -1; + } while (!ntfs_attr_lookup(na->type, na->name, na->name_len, CASE_SENSITIVE, 0, NULL, 0, ctx)) { if (ntfs_attr_record_rm(ctx)) { diff --git a/libntfs/dir.c b/libntfs/dir.c index c6b562f1..2ef06ab6 100644 --- a/libntfs/dir.c +++ b/libntfs/dir.c @@ -1359,12 +1359,10 @@ err_out: ntfs_log_perror("Failed to open SD (0x50) attribute of " " inode 0x%llx. Run chkdsk.\n", (unsigned long long)ni->mft_no); - else if (ntfs_attr_rm(na)) { + else if (ntfs_attr_rm(na)) ntfs_log_perror("Failed to remove SD (0x50) attribute " "of inode 0x%llx. Run chkdsk.\n", (unsigned long long)ni->mft_no); - ntfs_attr_close(na); - } } if (rollback_data) { ntfs_attr *na; diff --git a/ntfsprogs/ntfsmount.c b/ntfsprogs/ntfsmount.c index b25bb6b9..17eccb41 100644 --- a/ntfsprogs/ntfsmount.c +++ b/ntfsprogs/ntfsmount.c @@ -981,10 +981,8 @@ static int ntfs_fuse_rm_stream(const char *path, ntfschar *stream_name, res = -errno; goto exit; } - if (ntfs_attr_rm(na)) { + if (ntfs_attr_rm(na)) res = -errno; - ntfs_attr_close(na); - } exit: if (ntfs_inode_close(ni)) ntfs_log_perror("Failed to close inode"); @@ -1322,7 +1320,6 @@ static int ntfs_fuse_removexattr(const char *path, const char *name) ntfschar *lename = NULL; int res = 0, lename_len; - if (ctx->streams != NF_STREAMS_INTERFACE_XATTR) return -EOPNOTSUPP; if (strncmp(name, nf_ns_xattr_preffix, nf_ns_xattr_preffix_len) || @@ -1347,8 +1344,7 @@ static int ntfs_fuse_removexattr(const char *path, const char *name) ntfs_fuse_mark_free_space_outdated(); if (ntfs_attr_rm(na)) res = -errno; - else - na = NULL; + na = NULL; exit: if (na) ntfs_attr_close(na);