aboutsummaryrefslogtreecommitdiff
path: root/fs/ntfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ntfs')
-rw-r--r--fs/ntfs/aops.c2
-rw-r--r--fs/ntfs/attrib.c1
-rw-r--r--fs/ntfs/compress.c2
-rw-r--r--fs/ntfs/debug.c58
-rw-r--r--fs/ntfs/debug.h7
-rw-r--r--fs/ntfs/dir.c84
-rw-r--r--fs/ntfs/file.c30
-rw-r--r--fs/ntfs/inode.c22
-rw-r--r--fs/ntfs/inode.h4
-rw-r--r--fs/ntfs/super.c97
-rw-r--r--fs/ntfs/sysctl.c6
-rw-r--r--fs/ntfs/volume.h5
12 files changed, 155 insertions, 163 deletions
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index fa9c05f97af..d267ea6aa1a 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -1372,7 +1372,7 @@ retry_writepage:
* The page may have dirty, unmapped buffers. Make them
* freeable here, so the page does not leak.
*/
- block_invalidatepage(page, 0);
+ block_invalidatepage(page, 0, PAGE_CACHE_SIZE);
unlock_page(page);
ntfs_debug("Write outside i_size - truncated?");
return 0;
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index a27e3fecefa..250ed5b20c8 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1748,7 +1748,6 @@ int ntfs_attr_make_non_resident(ntfs_inode *ni, const u32 data_size)
if (page) {
set_page_dirty(page);
unlock_page(page);
- mark_page_accessed(page);
page_cache_release(page);
}
ntfs_debug("Done.");
diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c
index ee4144ce5d7..f82498c35e7 100644
--- a/fs/ntfs/compress.c
+++ b/fs/ntfs/compress.c
@@ -58,7 +58,7 @@ typedef enum {
/**
* ntfs_compression_buffer - one buffer for the decompression engine
*/
-static u8 *ntfs_compression_buffer = NULL;
+static u8 *ntfs_compression_buffer;
/**
* ntfs_cb_lock - spinlock which protects ntfs_compression_buffer
diff --git a/fs/ntfs/debug.c b/fs/ntfs/debug.c
index 807150e2c2b..dd6103cc93c 100644
--- a/fs/ntfs/debug.c
+++ b/fs/ntfs/debug.c
@@ -18,16 +18,9 @@
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include "debug.h"
-/*
- * A static buffer to hold the error string being displayed and a spinlock
- * to protect concurrent accesses to it.
- */
-static char err_buf[1024];
-static DEFINE_SPINLOCK(err_buf_lock);
-
/**
* __ntfs_warning - output a warning to the syslog
* @function: name of function outputting the warning
@@ -50,6 +43,7 @@ static DEFINE_SPINLOCK(err_buf_lock);
void __ntfs_warning(const char *function, const struct super_block *sb,
const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
int flen = 0;
@@ -59,17 +53,15 @@ void __ntfs_warning(const char *function, const struct super_block *sb,
#endif
if (function)
flen = strlen(function);
- spin_lock(&err_buf_lock);
va_start(args, fmt);
- vsnprintf(err_buf, sizeof(err_buf), fmt, args);
- va_end(args);
+ vaf.fmt = fmt;
+ vaf.va = &args;
if (sb)
- printk(KERN_ERR "NTFS-fs warning (device %s): %s(): %s\n",
- sb->s_id, flen ? function : "", err_buf);
+ pr_warn("(device %s): %s(): %pV\n",
+ sb->s_id, flen ? function : "", &vaf);
else
- printk(KERN_ERR "NTFS-fs warning: %s(): %s\n",
- flen ? function : "", err_buf);
- spin_unlock(&err_buf_lock);
+ pr_warn("%s(): %pV\n", flen ? function : "", &vaf);
+ va_end(args);
}
/**
@@ -94,6 +86,7 @@ void __ntfs_warning(const char *function, const struct super_block *sb,
void __ntfs_error(const char *function, const struct super_block *sb,
const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
int flen = 0;
@@ -103,17 +96,15 @@ void __ntfs_error(const char *function, const struct super_block *sb,
#endif
if (function)
flen = strlen(function);
- spin_lock(&err_buf_lock);
va_start(args, fmt);
- vsnprintf(err_buf, sizeof(err_buf), fmt, args);
- va_end(args);
+ vaf.fmt = fmt;
+ vaf.va = &args;
if (sb)
- printk(KERN_ERR "NTFS-fs error (device %s): %s(): %s\n",
- sb->s_id, flen ? function : "", err_buf);
+ pr_err("(device %s): %s(): %pV\n",
+ sb->s_id, flen ? function : "", &vaf);
else
- printk(KERN_ERR "NTFS-fs error: %s(): %s\n",
- flen ? function : "", err_buf);
- spin_unlock(&err_buf_lock);
+ pr_err("%s(): %pV\n", flen ? function : "", &vaf);
+ va_end(args);
}
#ifdef DEBUG
@@ -124,6 +115,7 @@ int debug_msgs = 0;
void __ntfs_debug (const char *file, int line, const char *function,
const char *fmt, ...)
{
+ struct va_format vaf;
va_list args;
int flen = 0;
@@ -131,13 +123,11 @@ void __ntfs_debug (const char *file, int line, const char *function,
return;
if (function)
flen = strlen(function);
- spin_lock(&err_buf_lock);
va_start(args, fmt);
- vsnprintf(err_buf, sizeof(err_buf), fmt, args);
+ vaf.fmt = fmt;
+ vaf.va = &args;
+ pr_debug("(%s, %d): %s(): %pV", file, line, flen ? function : "", &vaf);
va_end(args);
- printk(KERN_DEBUG "NTFS-fs DEBUG (%s, %d): %s(): %s\n", file, line,
- flen ? function : "", err_buf);
- spin_unlock(&err_buf_lock);
}
/* Dump a runlist. Caller has to provide synchronisation for @rl. */
@@ -149,12 +139,12 @@ void ntfs_debug_dump_runlist(const runlist_element *rl)
if (!debug_msgs)
return;
- printk(KERN_DEBUG "NTFS-fs DEBUG: Dumping runlist (values in hex):\n");
+ pr_debug("Dumping runlist (values in hex):\n");
if (!rl) {
- printk(KERN_DEBUG "Run list not present.\n");
+ pr_debug("Run list not present.\n");
return;
}
- printk(KERN_DEBUG "VCN LCN Run length\n");
+ pr_debug("VCN LCN Run length\n");
for (i = 0; ; i++) {
LCN lcn = (rl + i)->lcn;
@@ -163,13 +153,13 @@ void ntfs_debug_dump_runlist(const runlist_element *rl)
if (index > -LCN_ENOENT - 1)
index = 3;
- printk(KERN_DEBUG "%-16Lx %s %-16Lx%s\n",
+ pr_debug("%-16Lx %s %-16Lx%s\n",
(long long)(rl + i)->vcn, lcn_str[index],
(long long)(rl + i)->length,
(rl + i)->length ? "" :
" (runlist end)");
} else
- printk(KERN_DEBUG "%-16Lx %-16Lx %-16Lx%s\n",
+ pr_debug("%-16Lx %-16Lx %-16Lx%s\n",
(long long)(rl + i)->vcn,
(long long)(rl + i)->lcn,
(long long)(rl + i)->length,
diff --git a/fs/ntfs/debug.h b/fs/ntfs/debug.h
index 53c27eaf230..61bf091e32a 100644
--- a/fs/ntfs/debug.h
+++ b/fs/ntfs/debug.h
@@ -48,7 +48,12 @@ extern void ntfs_debug_dump_runlist(const runlist_element *rl);
#else /* !DEBUG */
-#define ntfs_debug(f, a...) do {} while (0)
+#define ntfs_debug(fmt, ...) \
+do { \
+ if (0) \
+ no_printk(fmt, ##__VA_ARGS__); \
+} while (0)
+
#define ntfs_debug_dump_runlist(rl) do {} while (0)
#endif /* !DEBUG */
diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c
index 99e36107ff6..9e38dafa3bc 100644
--- a/fs/ntfs/dir.c
+++ b/fs/ntfs/dir.c
@@ -1004,13 +1004,11 @@ dir_err_out:
/**
* ntfs_filldir - ntfs specific filldir method
* @vol: current ntfs volume
- * @fpos: position in the directory
* @ndir: ntfs inode of current directory
* @ia_page: page in which the index allocation buffer @ie is in resides
* @ie: current index entry
* @name: buffer to use for the converted name
- * @dirent: vfs filldir callback context
- * @filldir: vfs filldir callback
+ * @actor: what to feed the entries to
*
* Convert the Unicode @name to the loaded NLS and pass it to the @filldir
* callback.
@@ -1024,12 +1022,12 @@ dir_err_out:
* retake the lock if we are returning a non-zero value as ntfs_readdir()
* would need to drop the lock immediately anyway.
*/
-static inline int ntfs_filldir(ntfs_volume *vol, loff_t fpos,
+static inline int ntfs_filldir(ntfs_volume *vol,
ntfs_inode *ndir, struct page *ia_page, INDEX_ENTRY *ie,
- u8 *name, void *dirent, filldir_t filldir)
+ u8 *name, struct dir_context *actor)
{
unsigned long mref;
- int name_len, rc;
+ int name_len;
unsigned dt_type;
FILE_NAME_TYPE_FLAGS name_type;
@@ -1068,13 +1066,14 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t fpos,
if (ia_page)
unlock_page(ia_page);
ntfs_debug("Calling filldir for %s with len %i, fpos 0x%llx, inode "
- "0x%lx, DT_%s.", name, name_len, fpos, mref,
+ "0x%lx, DT_%s.", name, name_len, actor->pos, mref,
dt_type == DT_DIR ? "DIR" : "REG");
- rc = filldir(dirent, name, name_len, fpos, mref, dt_type);
+ if (!dir_emit(actor, name, name_len, mref, dt_type))
+ return 1;
/* Relock the page but not if we are aborting ->readdir. */
- if (!rc && ia_page)
+ if (ia_page)
lock_page(ia_page);
- return rc;
+ return 0;
}
/*
@@ -1097,11 +1096,11 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t fpos,
* removes them again after the write is complete after which it
* unlocks the page.
*/
-static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+static int ntfs_readdir(struct file *file, struct dir_context *actor)
{
s64 ia_pos, ia_start, prev_ia_pos, bmp_pos;
- loff_t fpos, i_size;
- struct inode *bmp_vi, *vdir = filp->f_path.dentry->d_inode;
+ loff_t i_size;
+ struct inode *bmp_vi, *vdir = file_inode(file);
struct super_block *sb = vdir->i_sb;
ntfs_inode *ndir = NTFS_I(vdir);
ntfs_volume *vol = NTFS_SB(sb);
@@ -1116,33 +1115,16 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
u8 *kaddr, *bmp, *index_end;
ntfs_attr_search_ctx *ctx;
- fpos = filp->f_pos;
ntfs_debug("Entering for inode 0x%lx, fpos 0x%llx.",
- vdir->i_ino, fpos);
+ vdir->i_ino, actor->pos);
rc = err = 0;
/* Are we at end of dir yet? */
i_size = i_size_read(vdir);
- if (fpos >= i_size + vol->mft_record_size)
- goto done;
+ if (actor->pos >= i_size + vol->mft_record_size)
+ return 0;
/* Emulate . and .. for all directories. */
- if (!fpos) {
- ntfs_debug("Calling filldir for . with len 1, fpos 0x0, "
- "inode 0x%lx, DT_DIR.", vdir->i_ino);
- rc = filldir(dirent, ".", 1, fpos, vdir->i_ino, DT_DIR);
- if (rc)
- goto done;
- fpos++;
- }
- if (fpos == 1) {
- ntfs_debug("Calling filldir for .. with len 2, fpos 0x1, "
- "inode 0x%lx, DT_DIR.",
- (unsigned long)parent_ino(filp->f_path.dentry));
- rc = filldir(dirent, "..", 2, fpos,
- parent_ino(filp->f_path.dentry), DT_DIR);
- if (rc)
- goto done;
- fpos++;
- }
+ if (!dir_emit_dots(file, actor))
+ return 0;
m = NULL;
ctx = NULL;
/*
@@ -1155,7 +1137,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
goto err_out;
}
/* Are we jumping straight into the index allocation attribute? */
- if (fpos >= vol->mft_record_size)
+ if (actor->pos >= vol->mft_record_size)
goto skip_index_root;
/* Get hold of the mft record for the directory. */
m = map_mft_record(ndir);
@@ -1170,7 +1152,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
goto err_out;
}
/* Get the offset into the index root attribute. */
- ir_pos = (s64)fpos;
+ ir_pos = (s64)actor->pos;
/* Find the index root attribute in the mft record. */
err = ntfs_attr_lookup(AT_INDEX_ROOT, I30, 4, CASE_SENSITIVE, 0, NULL,
0, ctx);
@@ -1226,10 +1208,9 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (ir_pos > (u8*)ie - (u8*)ir)
continue;
/* Advance the position even if going to skip the entry. */
- fpos = (u8*)ie - (u8*)ir;
+ actor->pos = (u8*)ie - (u8*)ir;
/* Submit the name to the filldir callback. */
- rc = ntfs_filldir(vol, fpos, ndir, NULL, ie, name, dirent,
- filldir);
+ rc = ntfs_filldir(vol, ndir, NULL, ie, name, actor);
if (rc) {
kfree(ir);
goto abort;
@@ -1242,12 +1223,12 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
if (!NInoIndexAllocPresent(ndir))
goto EOD;
/* Advance fpos to the beginning of the index allocation. */
- fpos = vol->mft_record_size;
+ actor->pos = vol->mft_record_size;
skip_index_root:
kaddr = NULL;
prev_ia_pos = -1LL;
/* Get the offset into the index allocation attribute. */
- ia_pos = (s64)fpos - vol->mft_record_size;
+ ia_pos = (s64)actor->pos - vol->mft_record_size;
ia_mapping = vdir->i_mapping;
ntfs_debug("Inode 0x%lx, getting index bitmap.", vdir->i_ino);
bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4);
@@ -1409,7 +1390,7 @@ find_next_index_buffer:
if (ia_pos - ia_start > (u8*)ie - (u8*)ia)
continue;
/* Advance the position even if going to skip the entry. */
- fpos = (u8*)ie - (u8*)ia +
+ actor->pos = (u8*)ie - (u8*)ia +
(sle64_to_cpu(ia->index_block_vcn) <<
ndir->itype.index.vcn_size_bits) +
vol->mft_record_size;
@@ -1419,8 +1400,7 @@ find_next_index_buffer:
* before returning, unless a non-zero value is returned in
* which case the page is left unlocked.
*/
- rc = ntfs_filldir(vol, fpos, ndir, ia_page, ie, name, dirent,
- filldir);
+ rc = ntfs_filldir(vol, ndir, ia_page, ie, name, actor);
if (rc) {
/* @ia_page is already unlocked in this case. */
ntfs_unmap_page(ia_page);
@@ -1439,18 +1419,9 @@ unm_EOD:
iput(bmp_vi);
EOD:
/* We are finished, set fpos to EOD. */
- fpos = i_size + vol->mft_record_size;
+ actor->pos = i_size + vol->mft_record_size;
abort:
kfree(name);
-done:
-#ifdef DEBUG
- if (!rc)
- ntfs_debug("EOD, fpos 0x%llx, returning 0.", fpos);
- else
- ntfs_debug("filldir returned %i, fpos 0x%llx, returning 0.",
- rc, fpos);
-#endif
- filp->f_pos = fpos;
return 0;
err_out:
if (bmp_page) {
@@ -1471,7 +1442,6 @@ iput_err_out:
if (!err)
err = -EIO;
ntfs_debug("Failed. Returning error code %i.", -err);
- filp->f_pos = fpos;
return err;
}
@@ -1571,7 +1541,7 @@ static int ntfs_dir_fsync(struct file *filp, loff_t start, loff_t end,
const struct file_operations ntfs_dir_ops = {
.llseek = generic_file_llseek, /* Seek inside directory. */
.read = generic_read_dir, /* Return -EISDIR. */
- .readdir = ntfs_readdir, /* Read directory contents. */
+ .iterate = ntfs_readdir, /* Read directory contents. */
#ifdef NTFS_RW
.fsync = ntfs_dir_fsync, /* Sync a directory to disk. */
/*.aio_fsync = ,*/ /* Sync all outstanding async
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 7389d2d5e51..5c9e2c81cb1 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -27,6 +27,7 @@
#include <linux/swap.h>
#include <linux/uio.h>
#include <linux/writeback.h>
+#include <linux/aio.h>
#include <asm/page.h>
#include <asm/uaccess.h>
@@ -1762,6 +1763,16 @@ err_out:
return err;
}
+static void ntfs_write_failed(struct address_space *mapping, loff_t to)
+{
+ struct inode *inode = mapping->host;
+
+ if (to > inode->i_size) {
+ truncate_pagecache(inode, inode->i_size);
+ ntfs_truncate_vfs(inode);
+ }
+}
+
/**
* ntfs_file_buffered_write -
*
@@ -2022,8 +2033,9 @@ static ssize_t ntfs_file_buffered_write(struct kiocb *iocb,
* allocated space, which is not a disaster.
*/
i_size = i_size_read(vi);
- if (pos + bytes > i_size)
- vmtruncate(vi, i_size);
+ if (pos + bytes > i_size) {
+ ntfs_write_failed(mapping, pos + bytes);
+ }
break;
}
}
@@ -2048,7 +2060,6 @@ static ssize_t ntfs_file_buffered_write(struct kiocb *iocb,
}
do {
unlock_page(pages[--do_pages]);
- mark_page_accessed(pages[do_pages]);
page_cache_release(pages[do_pages]);
} while (do_pages);
if (unlikely(status))
@@ -2079,12 +2090,8 @@ static ssize_t ntfs_file_aio_write_nolock(struct kiocb *iocb,
size_t count; /* after file limit checks */
ssize_t written, err;
- count = 0;
- err = generic_segment_checks(iov, &nr_segs, &count, VERIFY_READ);
- if (err)
- return err;
+ count = iov_length(iov, nr_segs);
pos = *ppos;
- vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
/* We can write back this queue in page reclaim. */
current->backing_dev_info = mapping->backing_dev_info;
written = 0;
@@ -2123,7 +2130,7 @@ static ssize_t ntfs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
ret = ntfs_file_aio_write_nolock(iocb, iov, nr_segs, &iocb->ki_pos);
mutex_unlock(&inode->i_mutex);
if (ret > 0) {
- int err = generic_write_sync(file, pos, ret);
+ int err = generic_write_sync(file, iocb->ki_pos - ret, ret);
if (err < 0)
ret = err;
}
@@ -2192,8 +2199,8 @@ static int ntfs_file_fsync(struct file *filp, loff_t start, loff_t end,
const struct file_operations ntfs_file_ops = {
.llseek = generic_file_llseek, /* Seek inside file. */
- .read = do_sync_read, /* Read from file. */
- .aio_read = generic_file_aio_read, /* Async read from file. */
+ .read = new_sync_read, /* Read from file. */
+ .read_iter = generic_file_read_iter, /* Async read from file. */
#ifdef NTFS_RW
.write = do_sync_write, /* Write to file. */
.aio_write = ntfs_file_aio_write, /* Async write to file. */
@@ -2226,7 +2233,6 @@ const struct file_operations ntfs_file_ops = {
const struct inode_operations ntfs_file_inode_ops = {
#ifdef NTFS_RW
- .truncate = ntfs_truncate_vfs,
.setattr = ntfs_setattr,
#endif /* NTFS_RW */
};
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index c6dbd3db6ca..f47af5e6e23 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -28,6 +28,7 @@
#include <linux/quotaops.h>
#include <linux/slab.h>
#include <linux/log2.h>
+#include <linux/aio.h>
#include "aops.h"
#include "attrib.h"
@@ -54,7 +55,7 @@
*
* Return 1 if the attributes match and 0 if not.
*
- * NOTE: This function runs with the inode->i_lock spin lock held so it is not
+ * NOTE: This function runs with the inode_hash_lock spin lock held so it is not
* allowed to sleep.
*/
int ntfs_test_inode(struct inode *vi, ntfs_attr *na)
@@ -1703,8 +1704,6 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)
iput(bvi);
skip_large_index_stuff:
/* Setup the operations for this index inode. */
- vi->i_op = NULL;
- vi->i_fop = NULL;
vi->i_mapping->a_ops = &ntfs_mst_aops;
vi->i_blocks = ni->allocated_size >> 9;
/*
@@ -2124,7 +2123,8 @@ int ntfs_read_inode_mount(struct inode *vi)
* ntfs_read_inode() will have set up the default ones.
*/
/* Set uid and gid to root. */
- vi->i_uid = vi->i_gid = 0;
+ vi->i_uid = GLOBAL_ROOT_UID;
+ vi->i_gid = GLOBAL_ROOT_GID;
/* Regular file. No access for anyone. */
vi->i_mode = S_IFREG;
/* No VFS initiated operations allowed for $MFT. */
@@ -2257,7 +2257,7 @@ void ntfs_evict_big_inode(struct inode *vi)
{
ntfs_inode *ni = NTFS_I(vi);
- truncate_inode_pages(&vi->i_data, 0);
+ truncate_inode_pages_final(&vi->i_data);
clear_inode(vi);
#ifdef NTFS_RW
@@ -2312,8 +2312,8 @@ int ntfs_show_options(struct seq_file *sf, struct dentry *root)
ntfs_volume *vol = NTFS_SB(root->d_sb);
int i;
- seq_printf(sf, ",uid=%i", vol->uid);
- seq_printf(sf, ",gid=%i", vol->gid);
+ seq_printf(sf, ",uid=%i", from_kuid_munged(&init_user_ns, vol->uid));
+ seq_printf(sf, ",gid=%i", from_kgid_munged(&init_user_ns, vol->gid));
if (vol->fmask == vol->dmask)
seq_printf(sf, ",umask=0%o", vol->fmask);
else {
@@ -2865,9 +2865,11 @@ conv_err_out:
*
* See ntfs_truncate() description above for details.
*/
+#ifdef NTFS_RW
void ntfs_truncate_vfs(struct inode *vi) {
ntfs_truncate(vi);
}
+#endif
/**
* ntfs_setattr - called from notify_change() when an attribute is being changed
@@ -2913,8 +2915,10 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
NInoCompressed(ni) ?
"compressed" : "encrypted");
err = -EOPNOTSUPP;
- } else
- err = vmtruncate(vi, attr->ia_size);
+ } else {
+ truncate_setsize(vi, attr->ia_size);
+ ntfs_truncate_vfs(vi);
+ }
if (err || ia_valid == ATTR_SIZE)
goto out;
} else {
diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h
index db29695f845..76b6cfb579d 100644
--- a/fs/ntfs/inode.h
+++ b/fs/ntfs/inode.h
@@ -316,6 +316,10 @@ static inline void ntfs_commit_inode(struct inode *vi)
return;
}
+#else
+
+static inline void ntfs_truncate_vfs(struct inode *vi) {}
+
#endif /* NTFS_RW */
#endif /* _LINUX_NTFS_INODE_H */
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index b341492542c..6c3296e546c 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -19,6 +19,7 @@
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/stddef.h>
#include <linux/init.h>
@@ -49,8 +50,8 @@
static unsigned long ntfs_nr_compression_users;
/* A global default upcase table and a corresponding reference count. */
-static ntfschar *default_upcase = NULL;
-static unsigned long ntfs_nr_upcase_users = 0;
+static ntfschar *default_upcase;
+static unsigned long ntfs_nr_upcase_users;
/* Error constants/strings used in inode.c::ntfs_show_options(). */
typedef enum {
@@ -102,8 +103,8 @@ static bool parse_options(ntfs_volume *vol, char *opt)
char *p, *v, *ov;
static char *utf8 = "utf8";
int errors = 0, sloppy = 0;
- uid_t uid = (uid_t)-1;
- gid_t gid = (gid_t)-1;
+ kuid_t uid = INVALID_UID;
+ kgid_t gid = INVALID_GID;
umode_t fmask = (umode_t)-1, dmask = (umode_t)-1;
int mft_zone_multiplier = -1, on_errors = -1;
int show_sys_files = -1, case_sensitive = -1, disable_sparse = -1;
@@ -128,6 +129,30 @@ static bool parse_options(ntfs_volume *vol, char *opt)
if (*v) \
goto needs_val; \
}
+#define NTFS_GETOPT_UID(option, variable) \
+ if (!strcmp(p, option)) { \
+ uid_t uid_value; \
+ if (!v || !*v) \
+ goto needs_arg; \
+ uid_value = simple_strtoul(ov = v, &v, 0); \
+ if (*v) \
+ goto needs_val; \
+ variable = make_kuid(current_user_ns(), uid_value); \
+ if (!uid_valid(variable)) \
+ goto needs_val; \
+ }
+#define NTFS_GETOPT_GID(option, variable) \
+ if (!strcmp(p, option)) { \
+ gid_t gid_value; \
+ if (!v || !*v) \
+ goto needs_arg; \
+ gid_value = simple_strtoul(ov = v, &v, 0); \
+ if (*v) \
+ goto needs_val; \
+ variable = make_kgid(current_user_ns(), gid_value); \
+ if (!gid_valid(variable)) \
+ goto needs_val; \
+ }
#define NTFS_GETOPT_OCTAL(option, variable) \
if (!strcmp(p, option)) { \
if (!v || !*v) \
@@ -165,8 +190,8 @@ static bool parse_options(ntfs_volume *vol, char *opt)
while ((p = strsep(&opt, ","))) {
if ((v = strchr(p, '=')))
*v++ = 0;
- NTFS_GETOPT("uid", uid)
- else NTFS_GETOPT("gid", gid)
+ NTFS_GETOPT_UID("uid", uid)
+ else NTFS_GETOPT_GID("gid", gid)
else NTFS_GETOPT_OCTAL("umask", fmask = dmask)
else NTFS_GETOPT_OCTAL("fmask", fmask)
else NTFS_GETOPT_OCTAL("dmask", dmask)
@@ -283,9 +308,9 @@ no_mount_options:
vol->on_errors = on_errors;
if (!vol->on_errors || vol->on_errors == ON_ERRORS_RECOVER)
vol->on_errors |= ON_ERRORS_CONTINUE;
- if (uid != (uid_t)-1)
+ if (uid_valid(uid))
vol->uid = uid;
- if (gid != (gid_t)-1)
+ if (gid_valid(gid))
vol->gid = gid;
if (fmask != (umode_t)-1)
vol->fmask = fmask;
@@ -444,6 +469,8 @@ static int ntfs_remount(struct super_block *sb, int *flags, char *opt)
ntfs_debug("Entering with remount options string: %s", opt);
+ sync_filesystem(sb);
+
#ifndef NTFS_RW
/* For read-only compiled driver, enforce read-only flag. */
*flags |= MS_RDONLY;
@@ -1023,7 +1050,8 @@ static bool load_and_init_mft_mirror(ntfs_volume *vol)
* ntfs_read_inode() will have set up the default ones.
*/
/* Set uid and gid to root. */
- tmp_ino->i_uid = tmp_ino->i_gid = 0;
+ tmp_ino->i_uid = GLOBAL_ROOT_UID;
+ tmp_ino->i_gid = GLOBAL_ROOT_GID;
/* Regular file. No access for anyone. */
tmp_ino->i_mode = S_IFREG;
/* No VFS initiated operations allowed for $MFTMirr. */
@@ -1869,7 +1897,7 @@ get_ctx_vol_failed:
vol->minor_ver = vi->minor_ver;
ntfs_attr_put_search_ctx(ctx);
unmap_mft_record(NTFS_I(vol->vol_ino));
- printk(KERN_INFO "NTFS volume version %i.%i.\n", vol->major_ver,
+ pr_info("volume version %i.%i.\n", vol->major_ver,
vol->minor_ver);
if (vol->major_ver < 3 && NVolSparseEnabled(vol)) {
ntfs_warning(vol->sb, "Disabling sparse support due to NTFS "
@@ -2660,31 +2688,14 @@ static const struct super_operations ntfs_sops = {
.alloc_inode = ntfs_alloc_big_inode, /* VFS: Allocate new inode. */
.destroy_inode = ntfs_destroy_big_inode, /* VFS: Deallocate inode. */
#ifdef NTFS_RW
- //.dirty_inode = NULL, /* VFS: Called from
- // __mark_inode_dirty(). */
.write_inode = ntfs_write_inode, /* VFS: Write dirty inode to
disk. */
- //.drop_inode = NULL, /* VFS: Called just after the
- // inode reference count has
- // been decreased to zero.
- // NOTE: The inode lock is
- // held. See fs/inode.c::
- // generic_drop_inode(). */
- //.delete_inode = NULL, /* VFS: Delete inode from disk.
- // Called when i_count becomes
- // 0 and i_nlink is also 0. */
- //.write_super = NULL, /* Flush dirty super block to
- // disk. */
- //.sync_fs = NULL, /* ? */
- //.write_super_lockfs = NULL, /* ? */
- //.unlockfs = NULL, /* ? */
#endif /* NTFS_RW */
.put_super = ntfs_put_super, /* Syscall: umount. */
.statfs = ntfs_statfs, /* Syscall: statfs */
.remount_fs = ntfs_remount, /* Syscall: mount -o remount. */
.evict_inode = ntfs_evict_big_inode, /* VFS: Called when an inode is
removed from memory. */
- //.umount_begin = NULL, /* Forced umount. */
.show_options = ntfs_show_options, /* Show mount options in
proc. */
};
@@ -3071,6 +3082,7 @@ static struct file_system_type ntfs_fs_type = {
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
+MODULE_ALIAS_FS("ntfs");
/* Stable names for the slab caches. */
static const char ntfs_index_ctx_cache_name[] = "ntfs_index_ctx_cache";
@@ -3084,7 +3096,7 @@ static int __init init_ntfs_fs(void)
int err = 0;
/* This may be ugly but it results in pretty output so who cares. (-8 */
- printk(KERN_INFO "NTFS driver " NTFS_VERSION " [Flags: R/"
+ pr_info("driver " NTFS_VERSION " [Flags: R/"
#ifdef NTFS_RW
"W"
#else
@@ -3104,16 +3116,15 @@ static int __init init_ntfs_fs(void)
sizeof(ntfs_index_context), 0 /* offset */,
SLAB_HWCACHE_ALIGN, NULL /* ctor */);
if (!ntfs_index_ctx_cache) {
- printk(KERN_CRIT "NTFS: Failed to create %s!\n",
- ntfs_index_ctx_cache_name);
+ pr_crit("Failed to create %s!\n", ntfs_index_ctx_cache_name);
goto ictx_err_out;
}
ntfs_attr_ctx_cache = kmem_cache_create(ntfs_attr_ctx_cache_name,
sizeof(ntfs_attr_search_ctx), 0 /* offset */,
SLAB_HWCACHE_ALIGN, NULL /* ctor */);
if (!ntfs_attr_ctx_cache) {
- printk(KERN_CRIT "NTFS: Failed to create %s!\n",
- ntfs_attr_ctx_cache_name);
+ pr_crit("NTFS: Failed to create %s!\n",
+ ntfs_attr_ctx_cache_name);
goto actx_err_out;
}
@@ -3121,8 +3132,7 @@ static int __init init_ntfs_fs(void)
(NTFS_MAX_NAME_LEN+1) * sizeof(ntfschar), 0,
SLAB_HWCACHE_ALIGN, NULL);
if (!ntfs_name_cache) {
- printk(KERN_CRIT "NTFS: Failed to create %s!\n",
- ntfs_name_cache_name);
+ pr_crit("Failed to create %s!\n", ntfs_name_cache_name);
goto name_err_out;
}
@@ -3130,8 +3140,7 @@ static int __init init_ntfs_fs(void)
sizeof(ntfs_inode), 0,
SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL);
if (!ntfs_inode_cache) {
- printk(KERN_CRIT "NTFS: Failed to create %s!\n",
- ntfs_inode_cache_name);
+ pr_crit("Failed to create %s!\n", ntfs_inode_cache_name);
goto inode_err_out;
}
@@ -3140,15 +3149,14 @@ static int __init init_ntfs_fs(void)
SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD,
ntfs_big_inode_init_once);
if (!ntfs_big_inode_cache) {
- printk(KERN_CRIT "NTFS: Failed to create %s!\n",
- ntfs_big_inode_cache_name);
+ pr_crit("Failed to create %s!\n", ntfs_big_inode_cache_name);
goto big_inode_err_out;
}
/* Register the ntfs sysctls. */
err = ntfs_sysctl(1);
if (err) {
- printk(KERN_CRIT "NTFS: Failed to register NTFS sysctls!\n");
+ pr_crit("Failed to register NTFS sysctls!\n");
goto sysctl_err_out;
}
@@ -3157,7 +3165,7 @@ static int __init init_ntfs_fs(void)
ntfs_debug("NTFS driver registered successfully.");
return 0; /* Success! */
}
- printk(KERN_CRIT "NTFS: Failed to register NTFS filesystem driver!\n");
+ pr_crit("Failed to register NTFS filesystem driver!\n");
/* Unregister the ntfs sysctls. */
ntfs_sysctl(0);
@@ -3173,8 +3181,7 @@ actx_err_out:
kmem_cache_destroy(ntfs_index_ctx_cache);
ictx_err_out:
if (!err) {
- printk(KERN_CRIT "NTFS: Aborting NTFS filesystem driver "
- "registration...\n");
+ pr_crit("Aborting NTFS filesystem driver registration...\n");
err = -ENOMEM;
}
return err;
@@ -3185,6 +3192,12 @@ static void __exit exit_ntfs_fs(void)
ntfs_debug("Unregistering NTFS driver.");
unregister_filesystem(&ntfs_fs_type);
+
+ /*
+ * Make sure all delayed rcu free inodes are flushed before we
+ * destroy cache.
+ */
+ rcu_barrier();
kmem_cache_destroy(ntfs_big_inode_cache);
kmem_cache_destroy(ntfs_inode_cache);
kmem_cache_destroy(ntfs_name_cache);
diff --git a/fs/ntfs/sysctl.c b/fs/ntfs/sysctl.c
index 79a89184cb5..a503156ec15 100644
--- a/fs/ntfs/sysctl.c
+++ b/fs/ntfs/sysctl.c
@@ -34,7 +34,7 @@
#include "debug.h"
/* Definition of the ntfs sysctl. */
-static ctl_table ntfs_sysctls[] = {
+static struct ctl_table ntfs_sysctls[] = {
{
.procname = "ntfs-debug",
.data = &debug_msgs, /* Data pointer and size. */
@@ -46,7 +46,7 @@ static ctl_table ntfs_sysctls[] = {
};
/* Define the parent directory /proc/sys/fs. */
-static ctl_table sysctls_root[] = {
+static struct ctl_table sysctls_root[] = {
{
.procname = "fs",
.mode = 0555,
@@ -56,7 +56,7 @@ static ctl_table sysctls_root[] = {
};
/* Storage for the sysctls header. */
-static struct ctl_table_header *sysctls_root_table = NULL;
+static struct ctl_table_header *sysctls_root_table;
/**
* ntfs_sysctl - add or remove the debug sysctl
diff --git a/fs/ntfs/volume.h b/fs/ntfs/volume.h
index 15e3ba8d521..4f579b02bc7 100644
--- a/fs/ntfs/volume.h
+++ b/fs/ntfs/volume.h
@@ -25,6 +25,7 @@
#define _LINUX_NTFS_VOLUME_H
#include <linux/rwsem.h>
+#include <linux/uidgid.h>
#include "types.h"
#include "layout.h"
@@ -46,8 +47,8 @@ typedef struct {
sized blocks on the device. */
/* Configuration provided by user at mount time. */
unsigned long flags; /* Miscellaneous flags, see below. */
- uid_t uid; /* uid that files will be mounted as. */
- gid_t gid; /* gid that files will be mounted as. */
+ kuid_t uid; /* uid that files will be mounted as. */
+ kgid_t gid; /* gid that files will be mounted as. */
umode_t fmask; /* The mask for file permissions. */
umode_t dmask; /* The mask for directory
permissions. */