summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-04-29 10:52:37 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2023-04-29 10:52:37 -0700
commit1e098dec61ba342c8cebbfdf0fcdcd9ce54f7fa1 (patch)
treea43e38e0d085550eaeb6e4052ff3ab122038800a
parent56c455b38dba47ae9cb48d71b2a106d769d1a694 (diff)
parent788ee1605c2e9feed39c3a749fb3e47c6e15c1b9 (diff)
downloadlinux-1e098dec61ba342c8cebbfdf0fcdcd9ce54f7fa1.tar.gz
linux-1e098dec61ba342c8cebbfdf0fcdcd9ce54f7fa1.tar.bz2
linux-1e098dec61ba342c8cebbfdf0fcdcd9ce54f7fa1.zip
Merge tag 'ntfs3_for_6.4' of https://github.com/Paragon-Software-Group/linux-ntfs3
Pull ntfs3 updates from Konstantin Komarov: "New code: - add missed "nocase" in ntfs_show_options - extend information on failures/errors - small optimizations Fixes: - some logic errors - some dead code was removed - code is refactored and reformatted according to the new version of clang-format Code removal: - 'noacsrules' option. Currently, this option does not work properly, and its use leads to unstable results. If we figure out how to implement it without errors, we will add it later - writepage" * tag 'ntfs3_for_6.4' of https://github.com/Paragon-Software-Group/linux-ntfs3: (30 commits) fs/ntfs3: Fix root inode checking fs/ntfs3: Print details about mount fails fs/ntfs3: Add missed "nocase" in ntfs_show_options fs/ntfs3: Code formatting and refactoring fs/ntfs3: Changed ntfs_get_acl() to use dentry fs/ntfs3: Remove field sbi->used.bitmap.set_tail fs/ntfs3: Undo critial modificatins to keep directory consistency fs/ntfs3: Undo endian changes fs/ntfs3: Optimization in ntfs_set_state() fs/ntfs3: Fix ntfs_create_inode() fs/ntfs3: Remove noacsrules fs/ntfs3: Use bh_read to simplify code fs/ntfs3: Fix a possible null-pointer dereference in ni_clear() fs/ntfs3: Refactoring of various minor issues fs/ntfs3: Restore overflow checking for attr size in mi_enum_attr fs/ntfs3: Check for extremely large size of $AttrDef fs/ntfs3: Improved checking of attribute's name length fs/ntfs3: Add null pointer checks fs/ntfs3: fix spelling mistake "attibute" -> "attribute" fs/ntfs3: Add length check in indx_get_root ...
-rw-r--r--Documentation/filesystems/ntfs3.rst11
-rw-r--r--fs/ntfs3/attrib.c17
-rw-r--r--fs/ntfs3/bitmap.c25
-rw-r--r--fs/ntfs3/file.c50
-rw-r--r--fs/ntfs3/frecord.c46
-rw-r--r--fs/ntfs3/fslog.c83
-rw-r--r--fs/ntfs3/fsntfs.c84
-rw-r--r--fs/ntfs3/index.c81
-rw-r--r--fs/ntfs3/inode.c134
-rw-r--r--fs/ntfs3/lznt.c10
-rw-r--r--fs/ntfs3/namei.c19
-rw-r--r--fs/ntfs3/ntfs.h3
-rw-r--r--fs/ntfs3/ntfs_fs.h19
-rw-r--r--fs/ntfs3/record.c15
-rw-r--r--fs/ntfs3/run.c6
-rw-r--r--fs/ntfs3/super.c312
-rw-r--r--fs/ntfs3/xattr.c70
17 files changed, 528 insertions, 457 deletions
diff --git a/Documentation/filesystems/ntfs3.rst b/Documentation/filesystems/ntfs3.rst
index 5aa102bd72c2..f0cf05cad2ba 100644
--- a/Documentation/filesystems/ntfs3.rst
+++ b/Documentation/filesystems/ntfs3.rst
@@ -61,17 +61,6 @@ this table marked with no it means default is without **no**.
directories, fmask applies only to files and dmask only to directories.
* - fmask=
- * - noacsrules
- - "No access rules" mount option sets access rights for files/folders to
- 777 and owner/group to root. This mount option absorbs all other
- permissions.
-
- - Permissions change for files/folders will be reported as successful,
- but they will remain 777.
-
- - Owner/group change will be reported as successful, butthey will stay
- as root.
-
* - nohidden
- Files with the Windows-specific HIDDEN (FILE_ATTRIBUTE_HIDDEN) attribute
will not be shown under Linux.
diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
index 5e6bafb10f42..0b8bc66377db 100644
--- a/fs/ntfs3/attrib.c
+++ b/fs/ntfs3/attrib.c
@@ -405,8 +405,8 @@ int attr_set_size(struct ntfs_inode *ni, enum ATTR_TYPE type,
int err = 0;
struct ntfs_sb_info *sbi = ni->mi.sbi;
u8 cluster_bits = sbi->cluster_bits;
- bool is_mft =
- ni->mi.rno == MFT_REC_MFT && type == ATTR_DATA && !name_len;
+ bool is_mft = ni->mi.rno == MFT_REC_MFT && type == ATTR_DATA &&
+ !name_len;
u64 old_valid, old_size, old_alloc, new_alloc, new_alloc_tmp;
struct ATTRIB *attr = NULL, *attr_b;
struct ATTR_LIST_ENTRY *le, *le_b;
@@ -531,11 +531,10 @@ add_alloc_in_same_attr_seg:
pre_alloc = 0;
if (type == ATTR_DATA && !name_len &&
sbi->options->prealloc) {
- pre_alloc =
- bytes_to_cluster(
- sbi,
- get_pre_allocated(new_size)) -
- new_alen;
+ pre_alloc = bytes_to_cluster(
+ sbi, get_pre_allocated(
+ new_size)) -
+ new_alen;
}
/* Get the last LCN to allocate from. */
@@ -573,8 +572,8 @@ add_alloc_in_same_attr_seg:
err = attr_allocate_clusters(
sbi, run, vcn, lcn, to_allocate, &pre_alloc,
is_mft ? ALLOCATE_MFT : ALLOCATE_DEF, &alen,
- is_mft ? 0
- : (sbi->record_size -
+ is_mft ? 0 :
+ (sbi->record_size -
le32_to_cpu(rec->used) + 8) /
3 +
1,
diff --git a/fs/ntfs3/bitmap.c b/fs/ntfs3/bitmap.c
index 723fb64e6531..9a6c6a09d70c 100644
--- a/fs/ntfs3/bitmap.c
+++ b/fs/ntfs3/bitmap.c
@@ -40,9 +40,9 @@ static struct kmem_cache *ntfs_enode_cachep;
int __init ntfs3_init_bitmap(void)
{
- ntfs_enode_cachep =
- kmem_cache_create("ntfs3_enode_cache", sizeof(struct e_node), 0,
- SLAB_RECLAIM_ACCOUNT, NULL);
+ ntfs_enode_cachep = kmem_cache_create("ntfs3_enode_cache",
+ sizeof(struct e_node), 0,
+ SLAB_RECLAIM_ACCOUNT, NULL);
return ntfs_enode_cachep ? 0 : -ENOMEM;
}
@@ -286,9 +286,9 @@ static void wnd_add_free_ext(struct wnd_bitmap *wnd, size_t bit, size_t len,
if (wnd->uptodated != 1) {
/* Check bits before 'bit'. */
ib = wnd->zone_bit == wnd->zone_end ||
- bit < wnd->zone_end
- ? 0
- : wnd->zone_end;
+ bit < wnd->zone_end ?
+ 0 :
+ wnd->zone_end;
while (bit > ib && wnd_is_free_hlp(wnd, bit - 1, 1)) {
bit -= 1;
@@ -297,9 +297,9 @@ static void wnd_add_free_ext(struct wnd_bitmap *wnd, size_t bit, size_t len,
/* Check bits after 'end_in'. */
ib = wnd->zone_bit == wnd->zone_end ||
- end_in > wnd->zone_bit
- ? wnd->nbits
- : wnd->zone_bit;
+ end_in > wnd->zone_bit ?
+ wnd->nbits :
+ wnd->zone_bit;
while (end_in < ib && wnd_is_free_hlp(wnd, end_in, 1)) {
end_in += 1;
@@ -417,8 +417,8 @@ static void wnd_remove_free_ext(struct wnd_bitmap *wnd, size_t bit, size_t len)
return;
n3 = rb_first(&wnd->count_tree);
wnd->extent_max =
- n3 ? rb_entry(n3, struct e_node, count.node)->count.key
- : 0;
+ n3 ? rb_entry(n3, struct e_node, count.node)->count.key :
+ 0;
return;
}
@@ -658,7 +658,8 @@ int wnd_init(struct wnd_bitmap *wnd, struct super_block *sb, size_t nbits)
if (!wnd->bits_last)
wnd->bits_last = wbits;
- wnd->free_bits = kcalloc(wnd->nwnd, sizeof(u16), GFP_NOFS | __GFP_NOWARN);
+ wnd->free_bits =
+ kcalloc(wnd->nwnd, sizeof(u16), GFP_NOFS | __GFP_NOWARN);
if (!wnd->free_bits)
return -ENOMEM;
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c
index e9bdc1ff08c9..9a3d55c367d9 100644
--- a/fs/ntfs3/file.c
+++ b/fs/ntfs3/file.c
@@ -22,20 +22,21 @@ static int ntfs_ioctl_fitrim(struct ntfs_sb_info *sbi, unsigned long arg)
{
struct fstrim_range __user *user_range;
struct fstrim_range range;
+ struct block_device *dev;
int err;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- if (!bdev_max_discard_sectors(sbi->sb->s_bdev))
+ dev = sbi->sb->s_bdev;
+ if (!bdev_max_discard_sectors(dev))
return -EOPNOTSUPP;
user_range = (struct fstrim_range __user *)arg;
if (copy_from_user(&range, user_range, sizeof(range)))
return -EFAULT;
- range.minlen = max_t(u32, range.minlen,
- bdev_discard_granularity(sbi->sb->s_bdev));
+ range.minlen = max_t(u32, range.minlen, bdev_discard_granularity(dev));
err = ntfs_trim_fs(sbi, &range);
if (err < 0)
@@ -190,8 +191,8 @@ static int ntfs_zero_range(struct inode *inode, u64 vbo, u64 vbo_to)
for (; idx < idx_end; idx += 1, from = 0) {
page_off = (loff_t)idx << PAGE_SHIFT;
- to = (page_off + PAGE_SIZE) > vbo_to ? (vbo_to - page_off)
- : PAGE_SIZE;
+ to = (page_off + PAGE_SIZE) > vbo_to ? (vbo_to - page_off) :
+ PAGE_SIZE;
iblock = page_off >> inode->i_blkbits;
page = find_or_create_page(mapping, idx,
@@ -223,16 +224,10 @@ static int ntfs_zero_range(struct inode *inode, u64 vbo, u64 vbo_to)
set_buffer_uptodate(bh);
if (!buffer_uptodate(bh)) {
- lock_buffer(bh);
- bh->b_end_io = end_buffer_read_sync;
- get_bh(bh);
- submit_bh(REQ_OP_READ, bh);
-
- wait_on_buffer(bh);
- if (!buffer_uptodate(bh)) {
+ err = bh_read(bh, 0);
+ if (err < 0) {
unlock_page(page);
put_page(page);
- err = -EIO;
goto out;
}
}
@@ -570,13 +565,14 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
ni_unlock(ni);
} else {
/* Check new size. */
+ u8 cluster_bits = sbi->cluster_bits;
/* generic/213: expected -ENOSPC instead of -EFBIG. */
if (!is_supported_holes) {
loff_t to_alloc = new_size - inode_get_bytes(inode);
if (to_alloc > 0 &&
- (to_alloc >> sbi->cluster_bits) >
+ (to_alloc >> cluster_bits) >
wnd_zeroes(&sbi->used.bitmap)) {
err = -ENOSPC;
goto out;
@@ -597,7 +593,7 @@ static long ntfs_fallocate(struct file *file, int mode, loff_t vbo, loff_t len)
}
if (is_supported_holes) {
- CLST vcn = vbo >> sbi->cluster_bits;
+ CLST vcn = vbo >> cluster_bits;
CLST cend = bytes_to_cluster(sbi, end);
CLST cend_v = bytes_to_cluster(sbi, ni->i_valid);
CLST lcn, clen;
@@ -660,22 +656,12 @@ out:
int ntfs3_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
struct iattr *attr)
{
- struct super_block *sb = dentry->d_sb;
- struct ntfs_sb_info *sbi = sb->s_fs_info;
struct inode *inode = d_inode(dentry);
struct ntfs_inode *ni = ntfs_i(inode);
u32 ia_valid = attr->ia_valid;
umode_t mode = inode->i_mode;
int err;
- if (sbi->options->noacsrules) {
- /* "No access rules" - Force any changes of time etc. */
- attr->ia_valid |= ATTR_FORCE;
- /* and disable for editing some attributes. */
- attr->ia_valid &= ~(ATTR_UID | ATTR_GID | ATTR_MODE);
- ia_valid = attr->ia_valid;
- }
-
err = setattr_prepare(idmap, dentry, attr);
if (err)
goto out;
@@ -719,7 +705,7 @@ int ntfs3_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
}
if (ia_valid & (ATTR_UID | ATTR_GID | ATTR_MODE))
- ntfs_save_wsl_perm(inode);
+ ntfs_save_wsl_perm(inode, NULL);
mark_inode_dirty(inode);
out:
return err;
@@ -1065,8 +1051,8 @@ static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
if (ret)
goto out;
- ret = is_compressed(ni) ? ntfs_compress_write(iocb, from)
- : __generic_file_write_iter(iocb, from);
+ ret = is_compressed(ni) ? ntfs_compress_write(iocb, from) :
+ __generic_file_write_iter(iocb, from);
out:
inode_unlock(inode);
@@ -1118,8 +1104,9 @@ static int ntfs_file_release(struct inode *inode, struct file *file)
int err = 0;
/* If we are last writer on the inode, drop the block reservation. */
- if (sbi->options->prealloc && ((file->f_mode & FMODE_WRITE) &&
- atomic_read(&inode->i_writecount) == 1)) {
+ if (sbi->options->prealloc &&
+ ((file->f_mode & FMODE_WRITE) &&
+ atomic_read(&inode->i_writecount) == 1)) {
ni_lock(ni);
down_write(&ni->file.run_lock);
@@ -1159,8 +1146,7 @@ const struct inode_operations ntfs_file_inode_operations = {
.getattr = ntfs_getattr,
.setattr = ntfs3_setattr,
.listxattr = ntfs_listxattr,
- .permission = ntfs_permission,
- .get_inode_acl = ntfs_get_acl,
+ .get_acl = ntfs_get_acl,
.set_acl = ntfs_set_acl,
.fiemap = ntfs_fiemap,
};
diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c
index f1df52dfab74..2bfcf1a989c9 100644
--- a/fs/ntfs3/frecord.c
+++ b/fs/ntfs3/frecord.c
@@ -76,8 +76,8 @@ struct ATTR_STD_INFO *ni_std(struct ntfs_inode *ni)
const struct ATTRIB *attr;
attr = mi_find_attr(&ni->mi, NULL, ATTR_STD, NULL, 0, NULL);
- return attr ? resident_data_ex(attr, sizeof(struct ATTR_STD_INFO))
- : NULL;
+ return attr ? resident_data_ex(attr, sizeof(struct ATTR_STD_INFO)) :
+ NULL;
}
/*
@@ -91,8 +91,8 @@ struct ATTR_STD_INFO5 *ni_std5(struct ntfs_inode *ni)
attr = mi_find_attr(&ni->mi, NULL, ATTR_STD, NULL, 0, NULL);
- return attr ? resident_data_ex(attr, sizeof(struct ATTR_STD_INFO5))
- : NULL;
+ return attr ? resident_data_ex(attr, sizeof(struct ATTR_STD_INFO5)) :
+ NULL;
}
/*
@@ -102,7 +102,7 @@ void ni_clear(struct ntfs_inode *ni)
{
struct rb_node *node;
- if (!ni->vfs_inode.i_nlink && is_rec_inuse(ni->mi.mrec))
+ if (!ni->vfs_inode.i_nlink && ni->mi.mrec && is_rec_inuse(ni->mi.mrec))
ni_delete_all(ni);
al_destroy(ni);
@@ -1439,8 +1439,8 @@ int ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type,
int err;
CLST plen;
struct ATTRIB *attr;
- bool is_ext =
- (flags & (ATTR_FLAG_SPARSED | ATTR_FLAG_COMPRESSED)) && !svcn;
+ bool is_ext = (flags & (ATTR_FLAG_SPARSED | ATTR_FLAG_COMPRESSED)) &&
+ !svcn;
u32 name_size = ALIGN(name_len * sizeof(short), 8);
u32 name_off = is_ext ? SIZEOF_NONRESIDENT_EX : SIZEOF_NONRESIDENT;
u32 run_off = name_off + name_size;
@@ -1645,7 +1645,7 @@ struct ATTR_FILE_NAME *ni_fname_name(struct ntfs_inode *ni,
{
struct ATTRIB *attr = NULL;
struct ATTR_FILE_NAME *fname;
- struct le_str *fns;
+ struct le_str *fns;
if (le)
*le = NULL;
@@ -1756,9 +1756,9 @@ int ni_new_attr_flags(struct ntfs_inode *ni, enum FILE_ATTRIBUTE new_fa)
}
/* Resize nonresident empty attribute in-place only. */
- new_asize = (new_aflags & (ATTR_FLAG_COMPRESSED | ATTR_FLAG_SPARSED))
- ? (SIZEOF_NONRESIDENT_EX + 8)
- : (SIZEOF_NONRESIDENT + 8);
+ new_asize = (new_aflags & (ATTR_FLAG_COMPRESSED | ATTR_FLAG_SPARSED)) ?
+ (SIZEOF_NONRESIDENT_EX + 8) :
+ (SIZEOF_NONRESIDENT + 8);
if (!mi_resize_attr(mi, attr, new_asize - le32_to_cpu(attr->size)))
return -EOPNOTSUPP;
@@ -2965,14 +2965,14 @@ bool ni_remove_name_undo(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
{
struct ntfs_sb_info *sbi = ni->mi.sbi;
struct ATTRIB *attr;
- u16 de_key_size = de2 ? le16_to_cpu(de2->key_size) : 0;
+ u16 de_key_size;
switch (undo_step) {
case 4:
+ de_key_size = le16_to_cpu(de2->key_size);
if (ni_insert_resident(ni, de_key_size, ATTR_NAME, NULL, 0,
- &attr, NULL, NULL)) {
+ &attr, NULL, NULL))
return false;
- }
memcpy(Add2Ptr(attr, SIZEOF_RESIDENT), de2 + 1, de_key_size);
mi_get_ref(&ni->mi, &de2->ref);
@@ -2981,19 +2981,16 @@ bool ni_remove_name_undo(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
de2->flags = 0;
de2->res = 0;
- if (indx_insert_entry(&dir_ni->dir, dir_ni, de2, sbi, NULL,
- 1)) {
+ if (indx_insert_entry(&dir_ni->dir, dir_ni, de2, sbi, NULL, 1))
return false;
- }
fallthrough;
case 2:
de_key_size = le16_to_cpu(de->key_size);
if (ni_insert_resident(ni, de_key_size, ATTR_NAME, NULL, 0,
- &attr, NULL, NULL)) {
+ &attr, NULL, NULL))
return false;
- }
memcpy(Add2Ptr(attr, SIZEOF_RESIDENT), de + 1, de_key_size);
mi_get_ref(&ni->mi, &de->ref);
@@ -3162,9 +3159,9 @@ static bool ni_update_parent(struct ntfs_inode *ni, struct NTFS_DUP_INFO *dup,
u64 data_size = le64_to_cpu(attr->nres.data_size);
__le64 valid_le;
- dup->alloc_size = is_attr_ext(attr)
- ? attr->nres.total_size
- : attr->nres.alloc_size;
+ dup->alloc_size = is_attr_ext(attr) ?
+ attr->nres.total_size :
+ attr->nres.alloc_size;
dup->data_size = attr->nres.data_size;
if (new_valid > data_size)
@@ -3258,6 +3255,9 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint)
return 0;
}
+ if (!ni->mi.mrec)
+ goto out;
+
if (is_rec_inuse(ni->mi.mrec) &&
!(sbi->flags & NTFS_FLAGS_LOG_REPLAYING) && inode->i_nlink) {
bool modified = false;
@@ -3360,7 +3360,7 @@ out:
ni_unlock(ni);
if (err) {
- ntfs_err(sb, "%s r=%lx failed, %d.", hint, inode->i_ino, err);
+ ntfs_inode_err(inode, "%s failed, %d.", hint, err);
ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
return err;
}
diff --git a/fs/ntfs3/fslog.c b/fs/ntfs3/fslog.c
index c6eb371a3695..57762c5fe68b 100644
--- a/fs/ntfs3/fslog.c
+++ b/fs/ntfs3/fslog.c
@@ -827,10 +827,10 @@ static inline struct RESTART_TABLE *extend_rsttbl(struct RESTART_TABLE *tbl,
memcpy(rt + 1, tbl + 1, esize * used);
- rt->free_goal = free_goal == ~0u
- ? cpu_to_le32(~0u)
- : cpu_to_le32(sizeof(struct RESTART_TABLE) +
- free_goal * esize);
+ rt->free_goal = free_goal == ~0u ?
+ cpu_to_le32(~0u) :
+ cpu_to_le32(sizeof(struct RESTART_TABLE) +
+ free_goal * esize);
if (tbl->first_free) {
rt->first_free = tbl->first_free;
@@ -1089,9 +1089,9 @@ static inline u64 base_lsn(struct ntfs_log *log,
(lsn < (lsn_to_vbo(log, h_lsn) & ~log->page_mask) ? 1 : 0))
<< log->file_data_bits) +
((((is_log_record_end(hdr) &&
- h_lsn <= le64_to_cpu(hdr->record_hdr.last_end_lsn))
- ? le16_to_cpu(hdr->record_hdr.next_record_off)
- : log->page_size) +
+ h_lsn <= le64_to_cpu(hdr->record_hdr.last_end_lsn)) ?
+ le16_to_cpu(hdr->record_hdr.next_record_off) :
+ log->page_size) +
lsn) >>
3);
@@ -1298,9 +1298,9 @@ static void log_init_pg_hdr(struct ntfs_log *log, u32 sys_page_size,
if (!log->clst_per_page)
log->clst_per_page = 1;
- log->first_page = major_ver >= 2
- ? 0x22 * page_size
- : ((sys_page_size << 1) + (page_size << 1));
+ log->first_page = major_ver >= 2 ?
+ 0x22 * page_size :
+ ((sys_page_size << 1) + (page_size << 1));
log->major_ver = major_ver;
log->minor_ver = minor_ver;
}
@@ -1512,20 +1512,19 @@ static u32 current_log_avail(struct ntfs_log *log)
* have to compute the free range.
* If there is no oldest lsn then start at the first page of the file.
*/
- oldest_off = (log->l_flags & NTFSLOG_NO_OLDEST_LSN)
- ? log->first_page
- : (log->oldest_lsn_off & ~log->sys_page_mask);
+ oldest_off = (log->l_flags & NTFSLOG_NO_OLDEST_LSN) ?
+ log->first_page :
+ (log->oldest_lsn_off & ~log->sys_page_mask);
/*
* We will use the next log page offset to compute the next free page.
* If we are going to reuse this page go to the next page.
* If we are at the first page then use the end of the file.
*/
- next_free_off = (log->l_flags & NTFSLOG_REUSE_TAIL)
- ? log->next_page + log->page_size
- : log->next_page == log->first_page
- ? log->l_size
- : log->next_page;
+ next_free_off = (log->l_flags & NTFSLOG_REUSE_TAIL) ?
+ log->next_page + log->page_size :
+ log->next_page == log->first_page ? log->l_size :
+ log->next_page;
/* If the two offsets are the same then there is no available space. */
if (oldest_off == next_free_off)
@@ -1535,9 +1534,9 @@ static u32 current_log_avail(struct ntfs_log *log)
* this range from the total available pages.
*/
free_bytes =
- oldest_off < next_free_off
- ? log->total_avail_pages - (next_free_off - oldest_off)
- : oldest_off - next_free_off;
+ oldest_off < next_free_off ?
+ log->total_avail_pages - (next_free_off - oldest_off) :
+ oldest_off - next_free_off;
free_bytes >>= log->page_bits;
return free_bytes * log->reserved;
@@ -1671,8 +1670,8 @@ next_tail:
}
best_lsn1 = first_tail ? base_lsn(log, first_tail, first_file_off) : 0;
- best_lsn2 =
- second_tail ? base_lsn(log, second_tail, second_file_off) : 0;
+ best_lsn2 = second_tail ? base_lsn(log, second_tail, second_file_off) :
+ 0;
if (first_tail && second_tail) {
if (best_lsn1 > best_lsn2) {
@@ -1767,8 +1766,8 @@ tail_read:
page_cnt = page_pos = 1;
- curpage_off = seq_base == log->seq_num ? min(log->next_page, page_off)
- : log->next_page;
+ curpage_off = seq_base == log->seq_num ? min(log->next_page, page_off) :
+ log->next_page;
wrapped_file =
curpage_off == log->first_page &&
@@ -1826,9 +1825,9 @@ use_cur_page:
le64_to_cpu(cur_page->record_hdr.last_end_lsn) &&
((lsn_cur >> log->file_data_bits) +
((curpage_off <
- (lsn_to_vbo(log, lsn_cur) & ~log->page_mask))
- ? 1
- : 0)) != expected_seq) {
+ (lsn_to_vbo(log, lsn_cur) & ~log->page_mask)) ?
+ 1 :
+ 0)) != expected_seq) {
goto check_tail;
}
@@ -2575,7 +2574,7 @@ static int read_next_log_rec(struct ntfs_log *log, struct lcb *lcb, u64 *lsn)
return find_log_rec(log, *lsn, lcb);
}
-static inline bool check_index_header(const struct INDEX_HDR *hdr, size_t bytes)
+bool check_index_header(const struct INDEX_HDR *hdr, size_t bytes)
{
__le16 mask;
u32 min_de, de_off, used, total;
@@ -2642,9 +2641,10 @@ static inline bool check_index_root(const struct ATTRIB *attr,
{
bool ret;
const struct INDEX_ROOT *root = resident_data(attr);
- u8 index_bits = le32_to_cpu(root->index_block_size) >= sbi->cluster_size
- ? sbi->cluster_bits
- : SECTOR_SHIFT;
+ u8 index_bits = le32_to_cpu(root->index_block_size) >=
+ sbi->cluster_size ?
+ sbi->cluster_bits :
+ SECTOR_SHIFT;
u8 block_clst = root->index_block_clst;
if (le32_to_cpu(attr->res.data_size) < sizeof(struct INDEX_ROOT) ||
@@ -3683,7 +3683,8 @@ move_data:
if (a_dirty) {
attr = oa->attr;
- err = ntfs_sb_write_run(sbi, oa->run1, vbo, buffer_le, bytes, 0);
+ err = ntfs_sb_write_run(sbi, oa->run1, vbo, buffer_le, bytes,
+ 0);
if (err)
goto out;
}
@@ -3768,11 +3769,10 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
if (!log)
return -ENOMEM;
- memset(&rst_info, 0, sizeof(struct restart_info));
-
log->ni = ni;
log->l_size = l_size;
log->one_page_buf = kmalloc(page_size, GFP_NOFS);
+
if (!log->one_page_buf) {
err = -ENOMEM;
goto out;
@@ -3783,6 +3783,7 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
log->page_bits = blksize_bits(page_size);
/* Look for a restart area on the disk. */
+ memset(&rst_info, 0, sizeof(struct restart_info));
err = log_read_rst(log, l_size, true, &rst_info);
if (err)
goto out;
@@ -3859,10 +3860,10 @@ check_restart_area:
log->init_ra = !!rst_info.vbo;
/* If we have a valid page then grab a pointer to the restart area. */
- ra2 = rst_info.valid_page
- ? Add2Ptr(rst_info.r_page,
- le16_to_cpu(rst_info.r_page->ra_off))
- : NULL;
+ ra2 = rst_info.valid_page ?
+ Add2Ptr(rst_info.r_page,
+ le16_to_cpu(rst_info.r_page->ra_off)) :
+ NULL;
if (rst_info.chkdsk_was_run ||
(ra2 && ra2->client_idx[1] == LFS_NO_CLIENT_LE)) {
@@ -4256,6 +4257,10 @@ check_attribute_names:
rec_len -= t32;
attr_names = kmemdup(Add2Ptr(lrh, t32), rec_len, GFP_NOFS);
+ if (!attr_names) {
+ err = -ENOMEM;
+ goto out;
+ }
lcb_put(lcb);
lcb = NULL;
diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c
index 567563771bf8..28cc421102e5 100644
--- a/fs/ntfs3/fsntfs.c
+++ b/fs/ntfs3/fsntfs.c
@@ -172,8 +172,8 @@ int ntfs_fix_post_read(struct NTFS_RECORD_HEADER *rhdr, size_t bytes,
u16 sample, fo, fn;
fo = le16_to_cpu(rhdr->fix_off);
- fn = simple ? ((bytes >> SECTOR_SHIFT) + 1)
- : le16_to_cpu(rhdr->fix_num);
+ fn = simple ? ((bytes >> SECTOR_SHIFT) + 1) :
+ le16_to_cpu(rhdr->fix_num);
/* Check errors. */
if ((fo & 1) || fo + fn * sizeof(short) > SECTOR_SIZE || !fn-- ||
@@ -223,7 +223,7 @@ int ntfs_extend_init(struct ntfs_sb_info *sbi)
inode = ntfs_iget5(sb, &ref, &NAME_EXTEND);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
- ntfs_err(sb, "Failed to load $Extend.");
+ ntfs_err(sb, "Failed to load $Extend (%d).", err);
inode = NULL;
goto out;
}
@@ -282,7 +282,7 @@ int ntfs_loadlog_and_replay(struct ntfs_inode *ni, struct ntfs_sb_info *sbi)
/* Check for 4GB. */
if (ni->vfs_inode.i_size >= 0x100000000ull) {
- ntfs_err(sb, "\x24LogFile is too big");
+ ntfs_err(sb, "\x24LogFile is large than 4G.");
err = -EINVAL;
goto out;
}
@@ -646,13 +646,13 @@ next:
NULL, 0, NULL, NULL))
goto next;
- __clear_bit_le(ir - MFT_REC_RESERVED,
+ __clear_bit(ir - MFT_REC_RESERVED,
&sbi->mft.reserved_bitmap);
}
}
/* Scan 5 bits for zero. Bit 0 == MFT_REC_RESERVED */
- zbit = find_next_zero_bit_le(&sbi->mft.reserved_bitmap,
+ zbit = find_next_zero_bit(&sbi->mft.reserved_bitmap,
MFT_REC_FREE, MFT_REC_RESERVED);
if (zbit >= MFT_REC_FREE) {
sbi->mft.next_reserved = MFT_REC_FREE;
@@ -720,7 +720,7 @@ found:
if (*rno >= MFT_REC_FREE)
wnd_set_used(wnd, *rno, 1);
else if (*rno >= MFT_REC_RESERVED && sbi->mft.reserved_bitmap_inited)
- __set_bit_le(*rno - MFT_REC_RESERVED, &sbi->mft.reserved_bitmap);
+ __set_bit(*rno - MFT_REC_RESERVED, &sbi->mft.reserved_bitmap);
out:
if (!mft)
@@ -748,7 +748,7 @@ void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno, bool is_mft)
else
wnd_set_free(wnd, rno, 1);
} else if (rno >= MFT_REC_RESERVED && sbi->mft.reserved_bitmap_inited) {
- __clear_bit_le(rno - MFT_REC_RESERVED, &sbi->mft.reserved_bitmap);
+ __clear_bit(rno - MFT_REC_RESERVED, &sbi->mft.reserved_bitmap);
}
if (rno < wnd_zone_bit(wnd))
@@ -846,18 +846,16 @@ void ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait)
{
int err;
struct super_block *sb = sbi->sb;
- u32 blocksize;
+ u32 blocksize, bytes;
sector_t block1, block2;
- u32 bytes;
- if (!sb)
+ /*
+ * sb can be NULL here. In this case sbi->flags should be 0 too.
+ */
+ if (!sb || !(sbi->flags & NTFS_FLAGS_MFTMIRR))
return;
blocksize = sb->s_blocksize;
-
- if (!(sbi->flags & NTFS_FLAGS_MFTMIRR))
- return;
-
bytes = sbi->mft.recs_mirr << sbi->record_bits;
block1 = sbi->mft.lbo >> sb->s_blocksize_bits;
block2 = sbi->mft.lbo2 >> sb->s_blocksize_bits;
@@ -925,6 +923,7 @@ int ntfs_set_state(struct ntfs_sb_info *sbi, enum NTFS_DIRTY_FLAGS dirty)
struct VOLUME_INFO *info;
struct mft_inode *mi;
struct ntfs_inode *ni;
+ __le16 info_flags;
/*
* Do not change state if fs was real_dirty.
@@ -957,6 +956,8 @@ int ntfs_set_state(struct ntfs_sb_info *sbi, enum NTFS_DIRTY_FLAGS dirty)
goto out;
}
+ info_flags = info->flags;
+
switch (dirty) {
case NTFS_DIRTY_ERROR:
ntfs_notice(sbi->sb, "Mark volume as dirty due to NTFS errors");
@@ -970,8 +971,10 @@ int ntfs_set_state(struct ntfs_sb_info *sbi, enum NTFS_DIRTY_FLAGS dirty)
break;
}
/* Cache current volume flags. */
- sbi->volume.flags = info->flags;
- mi->dirty = true;
+ if (info_flags != info->flags) {
+ sbi->volume.flags = info->flags;
+ mi->dirty = true;
+ }
err = 0;
out:
@@ -1683,6 +1686,7 @@ struct ntfs_inode *ntfs_new_inode(struct ntfs_sb_info *sbi, CLST rno, bool dir)
out:
if (err) {
+ make_bad_inode(inode);
iput(inode);
ni = ERR_PTR(err);
}
@@ -1859,7 +1863,7 @@ int ntfs_security_init(struct ntfs_sb_info *sbi)
inode = ntfs_iget5(sb, &ref, &NAME_SECURE);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
- ntfs_err(sb, "Failed to load $Secure.");
+ ntfs_err(sb, "Failed to load $Secure (%d).", err);
inode = NULL;
goto out;
}
@@ -1870,41 +1874,43 @@ int ntfs_security_init(struct ntfs_sb_info *sbi)
attr = ni_find_attr(ni, NULL, &le, ATTR_ROOT, SDH_NAME,
ARRAY_SIZE(SDH_NAME), NULL, NULL);
- if (!attr) {
- err = -EINVAL;
- goto out;
- }
-
- root_sdh = resident_data_ex(attr, sizeof(struct INDEX_ROOT));
- if (root_sdh->type != ATTR_ZERO ||
+ if (!attr ||
+ !(root_sdh = resident_data_ex(attr, sizeof(struct INDEX_ROOT))) ||
+ root_sdh->type != ATTR_ZERO ||
root_sdh->rule != NTFS_COLLATION_TYPE_SECURITY_HASH ||
- offsetof(struct INDEX_ROOT, ihdr) + root_sdh->ihdr.used > attr->res.data_size) {
+ offsetof(struct INDEX_ROOT, ihdr) +
+ le32_to_cpu(root_sdh->ihdr.used) >
+ le32_to_cpu(attr->res.data_size)) {
+ ntfs_err(sb, "$Secure::$SDH is corrupted.");
err = -EINVAL;
goto out;
}
err = indx_init(indx_sdh, sbi, attr, INDEX_MUTEX_SDH);
- if (err)
+ if (err) {
+ ntfs_err(sb, "Failed to initialize $Secure::$SDH (%d).", err);
goto out;
+ }
attr = ni_find_attr(ni, attr, &le, ATTR_ROOT, SII_NAME,
ARRAY_SIZE(SII_NAME), NULL, NULL);
- if (!attr) {
- err = -EINVAL;
- goto out;
- }
-
- root_sii = resident_data_ex(attr, sizeof(struct INDEX_ROOT));
- if (root_sii->type != ATTR_ZERO ||
+ if (!attr ||
+ !(root_sii = resident_data_ex(attr, sizeof(struct INDEX_ROOT))) ||
+ root_sii->type != ATTR_ZERO ||
root_sii->rule != NTFS_COLLATION_TYPE_UINT ||
- offsetof(struct INDEX_ROOT, ihdr) + root_sii->ihdr.used > attr->res.data_size) {
+ offsetof(struct INDEX_ROOT, ihdr) +
+ le32_to_cpu(root_sii->ihdr.used) >
+ le32_to_cpu(attr->res.data_size)) {
+ ntfs_err(sb, "$Secure::$SII is corrupted.");
err = -EINVAL;
goto out;
}
err = indx_init(indx_sii, sbi, attr, INDEX_MUTEX_SII);
- if (err)
+ if (err) {
+ ntfs_err(sb, "Failed to initialize $Secure::$SII (%d).", err);
goto out;
+ }
fnd_sii = fnd_get();
if (!fnd_sii) {
@@ -2594,8 +2600,10 @@ static inline bool is_reserved_name(struct ntfs_sb_info *sbi,
if (len == 4 || (len > 4 && le16_to_cpu(name[4]) == '.')) {
port_digit = le16_to_cpu(name[3]);
if (port_digit >= '1' && port_digit <= '9')
- if (!ntfs_cmp_names(name, 3, COM_NAME, 3, upcase, false) ||
- !ntfs_cmp_names(name, 3, LPT_NAME, 3, upcase, false))
+ if (!ntfs_cmp_names(name, 3, COM_NAME, 3, upcase,
+ false) ||
+ !ntfs_cmp_names(name, 3, LPT_NAME, 3, upcase,
+ false))
return true;
}
diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c
index 51ab75954640..0a48d2d67219 100644
--- a/fs/ntfs3/index.c
+++ b/fs/ntfs3/index.c
@@ -431,8 +431,9 @@ next_run:
if (vbo + blocksize > data_size)
nbits = 8 * (data_size - vbo);
- ok = nbits > from ? (*fn)((ulong *)bh->b_data, from, nbits, ret)
- : false;
+ ok = nbits > from ?
+ (*fn)((ulong *)bh->b_data, from, nbits, ret) :
+ false;
put_bh(bh);
if (ok) {
@@ -725,9 +726,13