diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-29 10:52:37 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-04-29 10:52:37 -0700 |
| commit | 1e098dec61ba342c8cebbfdf0fcdcd9ce54f7fa1 (patch) | |
| tree | a43e38e0d085550eaeb6e4052ff3ab122038800a | |
| parent | 56c455b38dba47ae9cb48d71b2a106d769d1a694 (diff) | |
| parent | 788ee1605c2e9feed39c3a749fb3e47c6e15c1b9 (diff) | |
| download | linux-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.rst | 11 | ||||
| -rw-r--r-- | fs/ntfs3/attrib.c | 17 | ||||
| -rw-r--r-- | fs/ntfs3/bitmap.c | 25 | ||||
| -rw-r--r-- | fs/ntfs3/file.c | 50 | ||||
| -rw-r--r-- | fs/ntfs3/frecord.c | 46 | ||||
| -rw-r--r-- | fs/ntfs3/fslog.c | 83 | ||||
| -rw-r--r-- | fs/ntfs3/fsntfs.c | 84 | ||||
| -rw-r--r-- | fs/ntfs3/index.c | 81 | ||||
| -rw-r--r-- | fs/ntfs3/inode.c | 134 | ||||
| -rw-r--r-- | fs/ntfs3/lznt.c | 10 | ||||
| -rw-r--r-- | fs/ntfs3/namei.c | 19 | ||||
| -rw-r--r-- | fs/ntfs3/ntfs.h | 3 | ||||
| -rw-r--r-- | fs/ntfs3/ntfs_fs.h | 19 | ||||
| -rw-r--r-- | fs/ntfs3/record.c | 15 | ||||
| -rw-r--r-- | fs/ntfs3/run.c | 6 | ||||
| -rw-r--r-- | fs/ntfs3/super.c | 312 | ||||
| -rw-r--r-- | fs/ntfs3/xattr.c | 70 |
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 |
