aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteve French <cifs.adm@hostme.bitkeeper.com>2004-07-10 21:07:02 -0700
committerSteve French <cifs.adm@hostme.bitkeeper.com>2004-07-10 21:07:02 -0700
commit5d456f60c995e32970f7e32dd3365e63c3fdc64b (patch)
treed5e632b7d04dbc62ed1600bb0036fae61c4ea3d3 /fs
parent8540342d7331064ac1da8d967ecaa59e896db026 (diff)
parent8319ca6ae5f27bc30724728c3400e3eda249d250 (diff)
downloadhistory-5d456f60c995e32970f7e32dd3365e63c3fdc64b.tar.gz
Merge bk://linux.bkbits.net/linux-2.5
into hostme.bitkeeper.com:/repos/c/cifs/linux-2.5cifs
Diffstat (limited to 'fs')
-rw-r--r--fs/Kconfig46
-rw-r--r--fs/afs/cmservice.c4
-rw-r--r--fs/afs/internal.h2
-rw-r--r--fs/afs/mntpt.c12
-rw-r--r--fs/afs/super.c2
-rw-r--r--fs/buffer.c31
-rw-r--r--fs/dquot.c59
-rw-r--r--fs/inode.c12
-rw-r--r--fs/jffs/inode-v23.c28
-rw-r--r--fs/jffs/intrep.c62
-rw-r--r--fs/jffs/jffs_fm.c54
-rw-r--r--fs/jffs2/os-linux.h5
-rw-r--r--fs/jffs2/wbuf.c8
-rw-r--r--fs/jffs2/write.c4
-rw-r--r--fs/jffs2/writev.c4
-rw-r--r--fs/jfs/jfs_dtree.c38
-rw-r--r--fs/jfs/jfs_imap.c6
-rw-r--r--fs/jfs/jfs_metapage.c6
-rw-r--r--fs/jfs/jfs_mount.c2
-rw-r--r--fs/jfs/jfs_txnmgr.c10
-rw-r--r--fs/jfs/jfs_uniupr.c2
-rw-r--r--fs/jfs/jfs_xtree.c30
-rw-r--r--fs/jfs/namei.c4
-rw-r--r--fs/jfs/super.c8
-rw-r--r--fs/jfs/xattr.c6
-rw-r--r--fs/mpage.c35
-rw-r--r--fs/namei.c10
-rw-r--r--fs/namespace.c215
-rw-r--r--fs/nfsd/vfs.c10
-rw-r--r--fs/read_write.c10
-rw-r--r--fs/smbfs/file.c2
-rw-r--r--fs/smbfs/proc.c12
-rw-r--r--fs/super.c3
-rw-r--r--fs/udf/super.c8
34 files changed, 458 insertions, 292 deletions
diff --git a/fs/Kconfig b/fs/Kconfig
index 55d99d885c03ee..fe7868a8e0f30a 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -7,47 +7,14 @@ menu "File systems"
config EXT2_FS
tristate "Second extended fs support"
help
- This is the de facto standard Linux file system (method to organize
- files on a storage device) for hard disks.
-
- You want to say Y here, unless you intend to use Linux exclusively
- from inside a DOS partition using the UMSDOS file system. The
- advantage of the latter is that you can get away without
- repartitioning your hard drive (which often implies backing
- everything up and restoring afterwards); the disadvantage is that
- Linux becomes susceptible to DOS viruses and that UMSDOS is somewhat
- slower than ext2fs. Even if you want to run Linux in this fashion,
- it might be a good idea to have ext2fs around: it enables you to
- read more floppy disks and facilitates the transition to a *real*
- Linux partition later. Another (rare) case which doesn't require
- ext2fs is a diskless Linux box which mounts all files over the
- network using NFS (in this case it's sufficient to say Y to "NFS
- file system support" below). Saying Y here will enlarge your kernel
- by about 44 KB.
-
- The Ext2fs-Undeletion mini-HOWTO, available from
- <http://www.tldp.org/docs.html#howto>, gives information about
- how to retrieve deleted files on ext2fs file systems.
-
- To change the behavior of ext2 file systems, you can use the tune2fs
- utility ("man tune2fs"). To modify attributes of files and
- directories on ext2 file systems, use chattr ("man chattr").
-
- Ext2fs partitions can be read from within DOS using the ext2tool
- command line tool package (available from
- <ftp://ibiblio.org/pub/Linux/system/filesystems/ext2/>) and from
- within Windows NT using the ext2nt command line tool package from
- <ftp://ibiblio.org/pub/Linux/utils/dos/>. Explore2fs is a
- graphical explorer for ext2fs partitions which runs on Windows 95
- and Windows NT and includes experimental write support; it is
- available from
- <http://jnewbigin-pc.it.swin.edu.au/Linux/Explore2fs.htm>.
+ Ext2 is a standard Linux file system for hard disks.
To compile this file system support as a module, choose M here: the
module will be called ext2. Be aware however that the file system
of your root partition (the one containing the directory /) cannot
- be compiled as a module, and so this could be dangerous. Most
- everyone wants to say Y here.
+ be compiled as a module, and so this could be dangerous.
+
+ If unsure, say Y.
config EXT2_FS_XATTR
bool "Ext2 extended attributes"
@@ -575,6 +542,11 @@ config UDF_FS
If unsure, say N.
+config UDF_NLS
+ bool
+ default y
+ depends on (UDF_FS=m && NLS) || (UDF_FS=y && NLS=y)
+
endmenu
menu "DOS/FAT/NT Filesystems"
diff --git a/fs/afs/cmservice.c b/fs/afs/cmservice.c
index 289489da3ca242..1f968366e6517c 100644
--- a/fs/afs/cmservice.c
+++ b/fs/afs/cmservice.c
@@ -307,10 +307,8 @@ int afscm_start(void)
if (ret < 0)
goto kill;
-#ifdef AFS_AUTOMOUNT_SUPPORT
afs_kafstimod_add_timer(&afs_mntpt_expiry_timer,
afs_mntpt_expiry_timeout * HZ);
-#endif
}
afscm_usage++;
@@ -392,9 +390,7 @@ void afscm_stop(void)
}
spin_unlock(&kafscmd_attention_lock);
-#ifdef AFS_AUTOMOUNT_SUPPORT
afs_kafstimod_del_timer(&afs_mntpt_expiry_timer);
-#endif
}
up_write(&afscm_sem);
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 11ef8c5568b2be..f09860b45c1a30 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -107,11 +107,9 @@ extern struct cachefs_netfs afs_cache_netfs;
*/
extern struct inode_operations afs_mntpt_inode_operations;
extern struct file_operations afs_mntpt_file_operations;
-#ifdef AFS_AUTOMOUNT_SUPPORT
extern struct afs_timer afs_mntpt_expiry_timer;
extern struct afs_timer_ops afs_mntpt_expiry_timer_ops;
extern unsigned long afs_mntpt_expiry_timeout;
-#endif
extern int afs_mntpt_check_symlink(struct afs_vnode *vnode);
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index 3a36a3ca5e3965..aab380e7e6dba2 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -30,10 +30,7 @@ static struct dentry *afs_mntpt_lookup(struct inode *dir,
struct dentry *dentry,
struct nameidata *nd);
static int afs_mntpt_open(struct inode *inode, struct file *file);
-
-#ifdef AFS_AUTOMOUNT_SUPPORT
static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd);
-#endif
struct file_operations afs_mntpt_file_operations = {
.open = afs_mntpt_open,
@@ -41,14 +38,11 @@ struct file_operations afs_mntpt_file_operations = {
struct inode_operations afs_mntpt_inode_operations = {
.lookup = afs_mntpt_lookup,
-#ifdef AFS_AUTOMOUNT_SUPPORT
.follow_link = afs_mntpt_follow_link,
-#endif
.readlink = page_readlink,
.getattr = afs_inode_getattr,
};
-#ifdef AFS_AUTOMOUNT_SUPPORT
static LIST_HEAD(afs_vfsmounts);
static void afs_mntpt_expiry_timed_out(struct afs_timer *timer);
@@ -60,7 +54,6 @@ struct afs_timer_ops afs_mntpt_expiry_timer_ops = {
struct afs_timer afs_mntpt_expiry_timer;
unsigned long afs_mntpt_expiry_timeout = 20;
-#endif
/*****************************************************************************/
/*
@@ -156,7 +149,6 @@ static int afs_mntpt_open(struct inode *inode, struct file *file)
return -EREMOTE;
} /* end afs_mntpt_open() */
-#ifdef AFS_AUTOMOUNT_SUPPORT
/*****************************************************************************/
/*
* create a vfsmount to be automounted
@@ -168,6 +160,7 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
struct page *page = NULL;
size_t size;
char *buf, *devname = NULL, *options = NULL;
+ filler_t *filler;
int ret;
kenter("{%s}", mntpt->d_name.name);
@@ -189,7 +182,7 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
goto error;
/* read the contents of the AFS special symlink */
- filler_t *filler = mntpt->d_inode->i_mapping->a_ops->readpage;
+ filler = mntpt->d_inode->i_mapping->a_ops->readpage;
page = read_cache_page(mntpt->d_inode->i_mapping, 0, filler, NULL);
if (IS_ERR(page)) {
@@ -288,4 +281,3 @@ static void afs_mntpt_expiry_timed_out(struct afs_timer *timer)
kleave("");
} /* end afs_mntpt_expiry_timed_out() */
-#endif
diff --git a/fs/afs/super.c b/fs/afs/super.c
index bdf830191f6242..d6fa8e5999df9a 100644
--- a/fs/afs/super.c
+++ b/fs/afs/super.c
@@ -78,9 +78,7 @@ int __init afs_fs_init(void)
_enter("");
-#ifdef AFS_AUTOMOUNT_SUPPORT
afs_timer_init(&afs_mntpt_expiry_timer, &afs_mntpt_expiry_timer_ops);
-#endif
/* create ourselves an inode cache */
atomic_set(&afs_count_active_inodes, 0);
diff --git a/fs/buffer.c b/fs/buffer.c
index 9d34cf52696b1b..c70e72ef5c6274 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -1588,10 +1588,9 @@ __bread(struct block_device *bdev, sector_t block, int size)
EXPORT_SYMBOL(__bread);
/*
- * invalidate_bh_lrus() is called rarely - at unmount. Because it is only for
- * unmount it only needs to ensure that all buffers from the target device are
- * invalidated on return and it doesn't need to worry about new buffers from
- * that device being added - the unmount code has to prevent that.
+ * invalidate_bh_lrus() is called rarely - but not only at unmount.
+ * This doesn't race because it runs in each cpu either in irq
+ * or with preempt disabled.
*/
static void invalidate_bh_lru(void *arg)
{
@@ -1807,10 +1806,10 @@ EXPORT_SYMBOL(unmap_underlying_metadata);
* state inside lock_buffer().
*
* If block_write_full_page() is called for regular writeback
- * (called_for_sync() is false) then it will redirty a page which has a locked
- * buffer. This only can happen if someone has written the buffer directly,
- * with submit_bh(). At the address_space level PageWriteback prevents this
- * contention from occurring.
+ * (wbc->sync_mode == WB_SYNC_NONE) then it will redirty a page which has a
+ * locked buffer. This only can happen if someone has written the buffer
+ * directly, with submit_bh(). At the address_space level PageWriteback
+ * prevents this contention from occurring.
*/
static int __block_write_full_page(struct inode *inode, struct page *page,
get_block_t *get_block, struct writeback_control *wbc)
@@ -1899,14 +1898,14 @@ static int __block_write_full_page(struct inode *inode, struct page *page,
}
} while ((bh = bh->b_this_page) != head);
+ /*
+ * The page and its buffers are protected by PageWriteback(), so we can
+ * drop the bh refcounts early.
+ */
BUG_ON(PageWriteback(page));
- set_page_writeback(page); /* Keeps try_to_free_buffers() away */
+ set_page_writeback(page);
unlock_page(page);
- /*
- * The page may come unlocked any time after the *first* submit_bh()
- * call. Be careful with its buffers.
- */
do {
struct buffer_head *next = bh->b_this_page;
if (buffer_async_write(bh)) {
@@ -1936,6 +1935,10 @@ done:
if (uptodate)
SetPageUptodate(page);
end_page_writeback(page);
+ /*
+ * The page and buffer_heads can be released at any time from
+ * here on.
+ */
wbc->pages_skipped++; /* We didn't write this page */
}
return err;
@@ -2723,7 +2726,7 @@ int block_write_full_page(struct page *page, get_block_t *get_block,
/*
* The page straddles i_size. It must be zeroed out on each and every
- * writepage invocation because it may be mmapped. "A file is mapped
+ * writepage invokation because it may be mmapped. "A file is mapped
* in multiples of the page size. For a file that is not a multiple of
* the page size, the remaining memory is zeroed when mapped, and
* writes to that region are not written out to the file."
diff --git a/fs/dquot.c b/fs/dquot.c
index 748beac66e02c2..35c84acdcc8003 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -96,9 +96,11 @@
*
* Any operation working on dquots via inode pointers must hold dqptr_sem. If
* operation is just reading pointers from inode (or not using them at all) the
- * read lock is enough. If pointers are altered function must hold write lock.
- * If operation is holding reference to dquot in other way (e.g. quotactl ops)
- * it must be guarded by dqonoff_sem.
+ * read lock is enough. If pointers are altered function must hold write lock
+ * (these locking rules also apply for S_NOQUOTA flag in the inode - note that
+ * for altering the flag i_sem is also needed). If operation is holding
+ * reference to dquot in other way (e.g. quotactl ops) it must be guarded by
+ * dqonoff_sem.
* This locking assures that:
* a) update/access to dquot pointers in inode is serialized
* b) everyone is guarded against invalidate_dquots()
@@ -112,7 +114,7 @@
* operations on dquots don't hold dq_lock as they copy data under dq_data_lock
* spinlock to internal buffers before writing.
*
- * Lock ordering (including some related VFS locks) is the following:
+ * Lock ordering (including related VFS locks) is following:
* i_sem > dqonoff_sem > iprune_sem > journal_lock > dqptr_sem >
* > dquot->dq_lock > dqio_sem
* i_sem on quota files is special (it's below dqio_sem)
@@ -204,9 +206,12 @@ struct dqstats dqstats;
static void dqput(struct dquot *dquot);
-static inline int const hashfn(struct super_block *sb, unsigned int id, int type)
+static inline unsigned int
+hashfn(const struct super_block *sb, unsigned int id, int type)
{
- unsigned long tmp = (((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type);
+ unsigned long tmp;
+
+ tmp = (((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type);
return (tmp + (tmp >> dq_hash_bits)) & dq_hash_mask;
}
@@ -686,16 +691,8 @@ static inline int dqput_blocks(struct dquot *dquot)
int remove_inode_dquot_ref(struct inode *inode, int type, struct list_head *tofree_head)
{
struct dquot *dquot = inode->i_dquot[type];
- int cnt;
inode->i_dquot[type] = NODQUOT;
- /* any other quota in use? */
- for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
- if (inode->i_dquot[cnt] != NODQUOT)
- goto put_it;
- }
- inode->i_flags &= ~S_QUOTA;
-put_it:
if (dquot != NODQUOT) {
if (dqput_blocks(dquot)) {
#ifdef __DQUOT_PARANOIA
@@ -956,8 +953,6 @@ int dquot_initialize(struct inode *inode, int type)
break;
}
inode->i_dquot[cnt] = dqget(inode->i_sb, id, cnt);
- if (inode->i_dquot[cnt])
- inode->i_flags |= S_QUOTA;
}
}
out_err:
@@ -974,7 +969,6 @@ int dquot_drop(struct inode *inode)
int cnt;
down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
- inode->i_flags &= ~S_QUOTA;
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
if (inode->i_dquot[cnt] != NODQUOT) {
dqput(inode->i_dquot[cnt]);
@@ -1367,7 +1361,7 @@ static int vfs_quota_on_file(struct file *f, int type, int format_id)
struct quota_info *dqopt = sb_dqopt(sb);
struct dquot *to_drop[MAXQUOTAS];
int error, cnt;
- unsigned int oldflags;
+ unsigned int oldflags = -1;
if (!fmt)
return -ESRCH;
@@ -1379,22 +1373,26 @@ static int vfs_quota_on_file(struct file *f, int type, int format_id)
if (!S_ISREG(inode->i_mode))
goto out_fmt;
+ down(&inode->i_sem);
down(&dqopt->dqonoff_sem);
if (sb_has_quota_enabled(sb, type)) {
+ up(&inode->i_sem);
error = -EBUSY;
goto out_lock;
}
- oldflags = inode->i_flags;
- dqopt->files[type] = f;
- error = -EINVAL;
- if (!fmt->qf_ops->check_quota_file(sb, type))
- goto out_file_init;
/* We don't want quota and atime on quota files (deadlocks possible)
* We also need to set GFP mask differently because we cannot recurse
* into filesystem when allocating page for quota inode */
down_write(&dqopt->dqptr_sem);
+ oldflags = inode->i_flags & (S_NOATIME | S_NOQUOTA);
inode->i_flags |= S_NOQUOTA | S_NOATIME;
+ up_write(&dqopt->dqptr_sem);
+ up(&inode->i_sem);
+ dqopt->files[type] = f;
+ error = -EINVAL;
+ if (!fmt->qf_ops->check_quota_file(sb, type))
+ goto out_file_init;
/*
* We write to quota files deep within filesystem code. We don't want
* the VFS to reenter filesystem code when it tries to allocate a
@@ -1404,11 +1402,11 @@ static int vfs_quota_on_file(struct file *f, int type, int format_id)
mapping_set_gfp_mask(inode->i_mapping,
mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS);
+ down_write(&dqopt->dqptr_sem);
for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
to_drop[cnt] = inode->i_dquot[cnt];
inode->i_dquot[cnt] = NODQUOT;
}
- inode->i_flags &= ~S_QUOTA;
up_write(&dqopt->dqptr_sem);
/* We must put dquots outside of dqptr_sem because we may need to
* start transaction for dquot_release() */
@@ -1434,11 +1432,20 @@ static int vfs_quota_on_file(struct file *f, int type, int format_id)
return 0;
out_file_init:
- inode->i_flags = oldflags;
dqopt->files[type] = NULL;
out_lock:
- up_write(&dqopt->dqptr_sem);
up(&dqopt->dqonoff_sem);
+ if (oldflags != -1) {
+ down(&inode->i_sem);
+ down_write(&dqopt->dqptr_sem);
+ /* Reset the NOATIME flag back. I know it could change in the
+ * mean time but playing with NOATIME flags on a quota file is
+ * never a good idea */
+ inode->i_flags &= ~(S_NOATIME | S_NOQUOTA);
+ inode->i_flags |= oldflags;
+ up_write(&dqopt->dqptr_sem);
+ up(&inode->i_sem);
+ }
out_fmt:
put_quota_format(fmt);
diff --git a/fs/inode.c b/fs/inode.c
index 5cd72ced8c9e5e..ec0945963c930a 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1235,26 +1235,26 @@ void remove_dquot_ref(struct super_block *sb, int type, struct list_head *tofree
if (!sb->dq_op)
return; /* nothing to do */
spin_lock(&inode_lock); /* This lock is for inodes code */
- /* We don't have to lock against quota code - test IS_QUOTAINIT is just for speedup... */
-
+
+ /* We hold dqptr_sem so we are safe against the quota code */
list_for_each(act_head, &inode_in_use) {
inode = list_entry(act_head, struct inode, i_list);
- if (inode->i_sb == sb && IS_QUOTAINIT(inode))
+ if (inode->i_sb == sb && !IS_NOQUOTA(inode))
remove_inode_dquot_ref(inode, type, tofree_head);
}
list_for_each(act_head, &inode_unused) {
inode = list_entry(act_head, struct inode, i_list);
- if (inode->i_sb == sb && IS_QUOTAINIT(inode))
+ if (inode->i_sb == sb && !IS_NOQUOTA(inode))
remove_inode_dquot_ref(inode, type, tofree_head);
}
list_for_each(act_head, &sb->s_dirty) {
inode = list_entry(act_head, struct inode, i_list);
- if (IS_QUOTAINIT(inode))
+ if (!IS_NOQUOTA(inode))
remove_inode_dquot_ref(inode, type, tofree_head);
}
list_for_each(act_head, &sb->s_io) {
inode = list_entry(act_head, struct inode, i_list);
- if (IS_QUOTAINIT(inode))
+ if (!IS_NOQUOTA(inode))
remove_inode_dquot_ref(inode, type, tofree_head);
}
spin_unlock(&inode_lock);
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 4d34ba69c3066a..1173626cadfdbf 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -315,7 +315,7 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
}
/* Write this node to the flash. */
- if ((res = jffs_write_node(c, new_node, &raw_inode, f->name, 0, recoverable, f)) < 0) {
+ if ((res = jffs_write_node(c, new_node, &raw_inode, f->name, NULL, recoverable, f)) < 0) {
D(printk("jffs_notify_change(): The write failed!\n"));
jffs_free_node(new_node);
D3(printk (KERN_NOTICE "n_c(): up biglock\n"));
@@ -323,7 +323,7 @@ jffs_setattr(struct dentry *dentry, struct iattr *iattr)
goto out;
}
- jffs_insert_node(c, f, &raw_inode, 0, new_node);
+ jffs_insert_node(c, f, &raw_inode, NULL, new_node);
mark_inode_dirty(inode);
D3(printk (KERN_NOTICE "n_c(): up biglock\n"));
@@ -879,14 +879,14 @@ jffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
/* Write the new node to the flash. */
if ((result = jffs_write_node(c, node, &raw_inode,
- dentry->d_name.name, 0, 0, NULL)) < 0) {
+ dentry->d_name.name, NULL, 0, NULL)) < 0) {
D(printk("jffs_mkdir(): jffs_write_node() failed.\n"));
jffs_free_node(node);
goto jffs_mkdir_end;
}
/* Insert the new node into the file system. */
- if ((result = jffs_insert_node(c, 0, &raw_inode, dentry->d_name.name,
+ if ((result = jffs_insert_node(c, NULL, &raw_inode, dentry->d_name.name,
node)) < 0) {
goto jffs_mkdir_end;
}
@@ -959,7 +959,7 @@ jffs_remove(struct inode *dir, struct dentry *dentry, int type)
struct jffs_file *dir_f; /* The file-to-remove's parent. */
struct jffs_file *del_f; /* The file to remove. */
struct jffs_node *del_node;
- struct inode *inode = 0;
+ struct inode *inode = NULL;
int result = 0;
D1({
@@ -1041,7 +1041,7 @@ jffs_remove(struct inode *dir, struct dentry *dentry, int type)
raw_inode.deleted = 1;
/* Write the new node to the flash memory. */
- if (jffs_write_node(c, del_node, &raw_inode, 0, 0, 1, del_f) < 0) {
+ if (jffs_write_node(c, del_node, &raw_inode, NULL, NULL, 1, del_f) < 0) {
jffs_free_node(del_node);
result = -EIO;
goto jffs_remove_end;
@@ -1049,7 +1049,7 @@ jffs_remove(struct inode *dir, struct dentry *dentry, int type)
/* Update the file. This operation will make the file disappear
from the in-memory file system structures. */
- jffs_insert_node(c, del_f, &raw_inode, 0, del_node);
+ jffs_insert_node(c, del_f, &raw_inode, NULL, del_node);
dir->i_ctime = dir->i_mtime = CURRENT_TIME;
mark_inode_dirty(dir);
@@ -1070,7 +1070,7 @@ jffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
{
struct jffs_raw_inode raw_inode;
struct jffs_file *dir_f;
- struct jffs_node *node = 0;
+ struct jffs_node *node = NULL;
struct jffs_control *c;
struct inode *inode;
int result = 0;
@@ -1127,7 +1127,7 @@ jffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
}
/* Insert the new node into the file system. */
- if ((err = jffs_insert_node(c, 0, &raw_inode, dentry->d_name.name,
+ if ((err = jffs_insert_node(c, NULL, &raw_inode, dentry->d_name.name,
node)) < 0) {
result = err;
goto jffs_mknod_end;
@@ -1237,7 +1237,7 @@ jffs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
}
/* Insert the new node into the file system. */
- if ((err = jffs_insert_node(c, 0, &raw_inode, dentry->d_name.name,
+ if ((err = jffs_insert_node(c, NULL, &raw_inode, dentry->d_name.name,
node)) < 0) {
goto jffs_symlink_end;
}
@@ -1333,14 +1333,14 @@ jffs_create(struct inode *dir, struct dentry *dentry, int mode,
/* Write the new node to the flash. */
if ((err = jffs_write_node(c, node, &raw_inode,
- dentry->d_name.name, 0, 0, NULL)) < 0) {
+ dentry->d_name.name, NULL, 0, NULL)) < 0) {
D(printk("jffs_create(): jffs_write_node() failed.\n"));
jffs_free_node(node);
goto jffs_create_end;
}
/* Insert the new node into the file system. */
- if ((err = jffs_insert_node(c, 0, &raw_inode, dentry->d_name.name,
+ if ((err = jffs_insert_node(c, NULL, &raw_inode, dentry->d_name.name,
node)) < 0) {
goto jffs_create_end;
}
@@ -1501,7 +1501,7 @@ jffs_file_write(struct file *filp, const char *buf, size_t count,
pos += err;
/* Insert the new node into the file system. */
- if ((err = jffs_insert_node(c, f, &raw_inode, 0, node)) < 0) {
+ if ((err = jffs_insert_node(c, f, &raw_inode, NULL, node)) < 0) {
goto out;
}
@@ -1750,7 +1750,7 @@ jffs_delete_inode(struct inode *inode)
lock_kernel();
inode->i_size = 0;
inode->i_blocks = 0;
- inode->u.generic_ip = 0;
+ inode->u.generic_ip = NULL;
clear_inode(inode);
if (inode->i_nlink == 0) {
c = (struct jffs_control *) inode->i_sb->s_fs_info;
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c
index 816f07676539c1..273a3c9cc5b0f0 100644
--- a/fs/jffs/intrep.c
+++ b/fs/jffs/intrep.c
@@ -209,7 +209,7 @@ flash_safe_write(struct mtd_info *mtd, loff_t to,
static int
-flash_safe_writev(struct mtd_info *mtd, const struct iovec *vecs,
+flash_safe_writev(struct mtd_info *mtd, const struct kvec *vecs,
unsigned long iovec_cnt, loff_t to)
{
size_t retlen, retlen_a;
@@ -409,7 +409,7 @@ jffs_create_file(struct jffs_control *c,
if (!(f = (struct jffs_file *)kmalloc(sizeof(struct jffs_file),
GFP_KERNEL))) {
D(printk("jffs_create_file(): Failed!\n"));
- return 0;
+ return NULL;
}
no_jffs_file++;
memset(f, 0, sizeof(struct jffs_file));
@@ -438,8 +438,8 @@ jffs_create_control(struct super_block *sb)
goto fail_control;
}
DJM(no_jffs_control++);
- c->root = 0;
- c->gc_task = 0;
+ c->root = NULL;
+ c->gc_task = NULL;
c->hash_len = JFFS_HASH_SIZE;
s = sizeof(struct list_head) * c->hash_len;
if (!(c->hash = (struct list_head *)kmalloc(s, GFP_KERNEL))) {
@@ -752,7 +752,7 @@ jffs_scan_flash(struct jffs_control *c)
{
char name[JFFS_MAX_NAME_LEN + 2];
struct jffs_raw_inode raw_inode;
- struct jffs_node *node = 0;
+ struct jffs_node *node = NULL;
struct jffs_fmcontrol *fmc = c->fmc;
__u32 checksum;
__u8 tmp_accurate;
@@ -904,7 +904,7 @@ jffs_scan_flash(struct jffs_control *c)
D1(printk("Dirty space: Starting 0x%x for 0x%x bytes\n",
(unsigned int) start, (unsigned int) (pos - start)));
jffs_fmalloced(fmc, (__u32) start,
- (__u32) (pos - start), 0);
+ (__u32) (pos - start), NULL);
}else{
/* "Flipping bits" detected. This means that our scan for them
did not catch this offset. See check_partly_erased_sectors() for
@@ -964,7 +964,7 @@ jffs_scan_flash(struct jffs_control *c)
D1(printk("Dirty space: Starting 0x%x for 0x%x bytes\n",
(unsigned int) start, (unsigned int) (pos - start)));
jffs_fmalloced(fmc, (__u32) start,
- (__u32) (pos - start), 0);
+ (__u32) (pos - start), NULL);
}
}
@@ -986,7 +986,7 @@ jffs_scan_flash(struct jffs_control *c)
D1(printk("jffs_scan_flash(): 0x00 ended at "
"pos 0x%lx.\n", (long)pos));
jffs_fmalloced(fmc, (__u32) start,
- (__u32) (pos - start), 0);
+ (__u32) (pos - start), NULL);
continue;
case JFFS_MAGIC_BITMASK:
@@ -1020,7 +1020,7 @@ jffs_scan_flash(struct jffs_control *c)
which really does contain crap. */
jffs_fmalloced(fmc, (__u32) start,
(__u32) (pos - start),
- 0);
+ NULL);
continue;
}/* switch */
@@ -1067,7 +1067,7 @@ jffs_scan_flash(struct jffs_control *c)
checksum, raw_inode.chksum));
pos += sizeof(struct jffs_raw_inode);
jffs_fmalloced(fmc, (__u32) start,
- (__u32) (pos - start), 0);
+ (__u32) (pos - start), NULL);
/* Reuse this unused struct jffs_node. */
continue;
}
@@ -1121,7 +1121,7 @@ jffs_scan_flash(struct jffs_control *c)
"raw_inode.nchksum = %u\n",
checksum, raw_inode.nchksum));
jffs_fmalloced(fmc, (__u32) start,
- (__u32) (pos - start), 0);
+ (__u32) (pos - start), NULL);
/* Reuse this unused struct jffs_node. */
continue;
}
@@ -1139,7 +1139,7 @@ jffs_scan_flash(struct jffs_control *c)
if (jffs_checksum_flash(fmc->mtd, pos, raw_inode.dsize, &checksum)) {
printk("jffs_checksum_flash() failed to calculate a checksum\n");
jffs_fmalloced(fmc, (__u32) start,
- (__u32) (pos - start), 0);
+ (__u32) (pos - start), NULL);
/* Reuse this unused struct jffs_node. */
continue;
}
@@ -1152,7 +1152,7 @@ jffs_scan_flash(struct jffs_control *c)
"raw_inode.dchksum = %u\n",
checksum, raw_inode.dchksum));
jffs_fmalloced(fmc, (__u32) start,
- (__u32) (pos - start), 0);
+ (__u32) (pos - start), NULL);
/* Reuse this unused struct jffs_node. */
continue;
}
@@ -1194,7 +1194,7 @@ jffs_scan_flash(struct jffs_control *c)
return -ENOMEM;
}
- if ((err = jffs_insert_node(c, 0, &raw_inode,
+ if ((err = jffs_insert_node(c, NULL, &raw_inode,
name, node)) < 0) {
printk("JFFS: Failed to handle raw inode. "
"(err = %d)\n", err);
@@ -1224,11 +1224,11 @@ jffs_scan_flash(struct jffs_control *c)
node->data_size = 0;
}
D3(jffs_print_node(node));
- node = 0; /* Don't free the node! */
+ node = NULL; /* Don't free the node! */
}
else {
jffs_fmalloced(fmc, (__u32) start,
- (__u32) (pos - start), 0);
+ (__u32) (pos - start), NULL);
D3(printk("jffs_scan_flash(): Just found an obsolete "
"raw_inode. Continuing the scan...\n"));
/* Reuse this unused struct jffs_node. */
@@ -1312,8 +1312,8 @@ jffs_insert_node(struct jffs_control *c, struct jffs_file *f,
/* This is the first node. */
f->version_head = node;
f->version_tail = node;
- node->version_prev = 0;
- node->version_next = 0;
+ node->version_prev = NULL;
+ node->version_next = NULL;
f->highest_version = node->version;
update_name = 1;
f->mode = raw_inode->mode;
@@ -1328,7 +1328,7 @@ jffs_insert_node(struct jffs_control *c, struct jffs_file *f,
/* Insert at the end of the list. I.e. this node is the
newest one so far. */
node->version_prev = f->version_tail;
- node->version_next = 0;
+ node->version_next = NULL;
f->version_tail->version_next = node;
f->version_tail = node;
f->highest_version = node->version;
@@ -1343,7 +1343,7 @@ jffs_insert_node(struct jffs_control *c, struct jffs_file *f,
}
else if (f->version_head->version > node->version) {
/* Insert at the bottom of the list. */
- node->version_prev = 0;
+ node->version_prev = NULL;
node->version_next = f->version_head;
f->version_head->version_prev = node;
f->version_head = node;
@@ -1556,9 +1556,9 @@ jffs_insert_file_into_tree(struct jffs_file *f)
if (!(parent = jffs_find_file(f->c, f->pino))) {
if (f->pino == 0) {
f->c->root = f;
- f->parent = 0;
- f->sibling_prev = 0;
- f->sibling_next = 0;
+ f->parent = NULL;
+ f->sibling_prev = NULL;
+ f->sibling_next = NULL;
return 0;
}
else {
@@ -1573,7 +1573,7 @@ jffs_insert_file_into_tree(struct jffs_file *f)
if (f->sibling_next) {
f->sibling_next->sibling_prev = f;
}
- f->sibling_prev = 0;
+ f->sibling_prev = NULL;
parent->children = f;
return 0;
}
@@ -1740,7 +1740,7 @@ jffs_write_node(struct jffs_control *c, struct jffs_node *node,
{
struct jffs_fmcontrol *fmc = c->fmc;
struct jffs_fm *fm;
- struct iovec node_iovec[4];
+ struct kvec node_iovec[4];
unsigned long iovec_cnt;
__u32 pos;
@@ -2311,7 +2311,7 @@ jffs_insert_data(struct jffs_file *f, struct jffs_node *node)
retry:
if (node->data_offset == f->size) {
/* A simple append. This is the most common operation. */
- node->range_next = 0;
+ node->range_next = NULL;
node->range_prev = f->range_tail;
if (node->range_prev) {
node->range_prev->range_next = node;
@@ -2389,10 +2389,10 @@ jffs_insert_data(struct jffs_file *f, struct jffs_node *node)
virtual_node->removed_size = 0;
virtual_node->fm_offset = 0;
virtual_node->name_size = 0;
- virtual_node->fm = 0; /* This is a virtual data holder. */
- virtual_node->version_prev = 0;
- virtual_node->version_next = 0;
- virtual_node->range_next = 0;
+ virtual_node->fm = NULL; /* This is a virtual data holder. */
+ virtual_node->version_prev = NULL;
+ virtual_node->version_next = NULL;
+ virtual_node->range_next = NULL;
/* Are there any data at all in the file yet? */
if (f->range_head) {
@@ -2407,7 +2407,7 @@ jffs_insert_data(struct jffs_file *f, struct jffs_node *node)
else {
virtual_node->data_offset = 0;
virtual_node->data_size = node->data_offset;
- virtual_node->range_prev = 0;
+ virtual_node->range_prev = NULL;
f->range_head = virtual_node;
}
diff --git a/fs/jffs/jffs_fm.c b/fs/jffs/jffs_fm.c
index 71cda0ca0d1dd7..1597328f01cefc 100644
--- a/fs/jffs/jffs_fm.c
+++ b/fs/jffs/jffs_fm.c
@@ -77,10 +77,10 @@ jffs_build_begin(struct jffs_control *c, int unit)
fmc->min_free_size = fmc->sector_size << 2;
fmc->mtd = mtd;
fmc->c = c;
- fmc->head = 0;
- fmc->tail = 0;
- fmc->head_extra = 0;
- fmc->tail_extra = 0;
+ fmc->head = NULL;
+ fmc->tail = NULL;
+ fmc->head_extra = NULL;
+ fmc->tail_extra = NULL;
init_MUTEX(&fmc->biglock);
return fmc;
}
@@ -102,8 +102,8 @@ jffs_build_end(struct jffs_fmcontrol *fmc)
fmc->head->prev = fmc->tail_extra;
fmc->head = fmc->head_extra;
}
- fmc->head_extra = 0; /* These two instructions should be omitted. */
- fmc->tail_extra = 0;
+ fmc->head_extra = NULL; /* These two instructions should be omitted. */
+ fmc->tail_extra = NULL;
D3(jffs_print_fmcontrol(fmc));
}
@@ -205,7 +205,7 @@ jffs_fmalloc(struct jffs_fmcontrol *fmc, __u32 size, struct jffs_node *node,
D2(printk("jffs_fmalloc(): fmc = 0x%p, size = %d, "
"node = 0x%p\n", fmc, size, node));
- *result = 0;
+ *result = NULL;
if (!(fm = jffs_alloc_fm())) {
D(printk("jffs_fmalloc(): kmalloc() failed! (fm)\n"));
@@ -234,7 +234,7 @@ jffs_fmalloc(struct jffs_fmcontrol *fmc, __u32 size, struct jffs_node *node,
}
DJM(no_jffs_node_ref++);
fm->nodes->node = node;
- fm->nodes->next = 0;
+ fm->nodes->next = NULL;
if (fmc->tail) {
fm->offset = fmc->tail->offset + fmc->tail->size;
if (fm->offset == fmc->flash_size) {
@@ -264,7 +264,7 @@ jffs_fmalloc(struct jffs_fmcontrol *fmc, __u32 size, struct jffs_node *node,
else {
fm->offset = fmc->tail->offset + fmc->tail->size;
fm->size = free_chunk_size1;
- fm->nodes = 0;
+ fm->nodes = NULL;
fmc->free_size -= fm->size;
fmc->dirty_size += fm->size; /* Changed by simonk. This seemingly fixes a
bug that caused infinite garbage collection.
@@ -273,9 +273,9 @@ jffs_fmalloc(struct jffs_fmcontrol *fmc, __u32 size, struct jffs_node *node,
*/
}
- fm->next = 0;
+ fm->next = NULL;
if (!fmc->head) {
- fm->prev = 0;
+ fm->prev = NULL;
fmc->head = fm;
fmc->tail = fm;
}
@@ -309,13 +309,13 @@ jffs_fmfree(struct jffs_fmcontrol *fmc, struct jffs_fm *fm, struct jffs_node *no
ASSERT(if (!fmc || !fm || !fm->nodes) {
printk(KERN_ERR "jffs_fmfree(): fmc: 0x%p, fm: 0x%p, "
"fm->nodes: 0x%p\n",
- fmc, fm, (fm ? fm->nodes : 0));
+ fmc, fm, (fm ? fm->nodes : NULL));
return -1;
});
/* Find the reference to the node that is going to be removed
and remove it. */
- for (ref = fm->nodes, prev = 0; ref; ref = ref->next) {
+ for (ref = fm->nodes, prev = NULL; ref; ref = ref->next) {
if (ref->node == node) {
if (prev) {
prev->next = ref->next;
@@ -368,13 +368,13 @@ jffs_fmalloced(struct jffs_fmcontrol *fmc, __u32 offset, __u32 size,
if (!(fm = jffs_alloc_fm())) {
D(printk("jffs_fmalloced(0x%p, %u, %u, 0x%p): failed!\n",
fmc, offset, size, node));
- return 0;
+ return NULL;
}
fm->offset = offset;
fm->size = size;
- fm->prev = 0;
- fm->next = 0;
- fm->nodes = 0;
+ fm->prev = NULL;
+ fm->next = NULL;
+ fm->nodes = NULL;
if (node) {
/* `node' exists and it should be associated with the
jffs_fm structure `fm'. */
@@ -383,11 +383,11 @@ jffs_fmalloced(struct jffs_fmcontrol *fmc, __u32 offset, __u32 size,
GFP_KERNEL))) {
D(printk("jffs_fmalloced(): !fm->nodes\n"));
jffs_free_fm(fm);
- return 0;
+ return NULL;
}
DJM(no_jffs_node_ref++);
fm->nodes->node = node;
- fm->nodes->next = 0;
+ fm->nodes->next = NULL;
fmc->used_size += size;
fmc->free_size -= size;
}
@@ -454,7 +454,7 @@ jffs_fmfree_partly(struct jffs_fmcontrol *fmc, struct jffs_fm *fm, __u32 size)
if (fm->nodes) {
kfree(fm->nodes);
DJM(no_jffs_node_ref--);
- fm->nodes = 0;
+ fm->nodes = NULL;
}
fmc->used_size -= fm->size;
if (fm == fmc->tail) {
@@ -476,12 +476,12 @@ jffs_cut_node(struct jffs_fmcontrol *fmc, __u32 size)
__u32 pos = 0;
if (size == 0) {
- return 0;
+ return NULL;
}
ASSERT(if (!fmc) {
printk(KERN_ERR "jffs_cut_node(): fmc == NULL\n");
- return 0;
+ return NULL;
});
fm = fmc->head;
@@ -495,7 +495,7 @@ jffs_cut_node(struct jffs_fmcontrol *fmc, __u32 size)
break;
}
else {
- fm = 0;
+ fm = NULL;
break;
}
}
@@ -524,7 +524,7 @@ jffs_sync_erase(struct jffs_fmcontrol *fmc, int erased_size)
erased_size -= fm->size;
del = fm;
fm = fm->next;
- fm->prev = 0;
+ fm->prev = NULL;
fmc->head = fm;
jffs_free_fm(del);
}
@@ -543,17 +543,17 @@ jffs_get_oldest_node(struct jffs_fmcontrol *fmc)
{
struct jffs_fm *fm;
struct jffs_node_ref *nref;
- struct jffs_node *node = 0;
+ struct jffs_node *node = NULL;
ASSERT(if (!fmc) {
printk(KERN_ERR "jffs_get_oldest_node(): fmc == NULL\n");
- return 0;
+ return NULL;
});
for (fm = fmc->head; fm && !fm->nodes; fm = fm->next);
if (!fm) {
- return 0;
+ return NULL;
}
/* The oldest node is the last one in the reference list. This list
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index 91401c1c9dca70..11f3a5a35dfe28 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -132,8 +132,9 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
#define jffs2_wbuf_dirty(c) (!!(c)->wbuf_len)
struct kstatfs;
+struct kvec;
/* wbuf.c */
-int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino);
+int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino);
int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, const u_char *buf);
int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, u_char *buf);
int jffs2_check_oob_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,int mode);
@@ -185,7 +186,7 @@ int jffs2_remount_fs (struct super_block *, int *, char *);
int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
/* writev.c */
-int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs,
+int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen);
/* super.c */
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index ecfb155cb82bd9..956f98d8dd3599 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -544,9 +544,9 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c)
#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) )
#define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) )
-int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino)
+int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino)
{
- struct iovec outvecs[3];
+ struct kvec outvecs[3];
uint32_t totlen = 0;
uint32_t split_ofs = 0;
uint32_t old_totlen;
@@ -751,11 +751,11 @@ alldone:
/*
* This is the entry for flash write.
- * Check, if we work on NAND FLASH, if so build an iovec and write it via vritev
+ * Check, if we work on NAND FLASH, if so build an kvec and write it via vritev
*/
int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, const u_char *buf)
{
- struct iovec vecs[1];
+ struct kvec vecs[1];
if (jffs2_can_mark_obsolete(c))
return c->mtd->write(c->mtd, ofs, len, retlen, buf);
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index f28d9d5bcd36a9..11c76104521582 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -92,7 +92,7 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
struct jffs2_raw_node_ref *raw;
struct jffs2_full_dnode *fn;
size_t retlen;
- struct iovec vecs[2];
+ struct kvec vecs[2];
int ret;
int retried = 0;
unsigned long cnt = 2;
@@ -233,7 +233,7 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
struct jffs2_raw_node_ref *raw;
struct jffs2_full_dirent *fd;
size_t retlen;
- struct iovec vecs[2];
+ struct kvec vecs[2];
int retried = 0;
int ret;
diff --git a/fs/jffs2/writev.c b/fs/jffs2/writev.c
index 80cd3820373f74..c88bf7336e5091 100644
--- a/fs/jffs2/writev.c
+++ b/fs/jffs2/writev.c
@@ -18,7 +18,7 @@
/* This ought to be in core MTD code. All registered MTD devices
without writev should have this put in place. Bug the MTD
maintainer */
-static inline int mtd_fake_writev(struct mtd_info *mtd, const struct iovec *vecs,
+static inline int mtd_fake_writev(struct mtd_info *mtd, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen)
{
unsigned long i;
@@ -39,7 +39,7 @@ static inline int mtd_fake_writev(struct mtd_info *mtd, const struct iovec *vecs
return ret;
}
-int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs,
+int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct kvec *vecs,
unsigned long count, loff_t to, size_t *retlen)
{
if (c->mtd->writev)
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index dc749c2e6fa87c..71e797774c088e 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -259,19 +259,19 @@ static struct dir_table_slot *find_index(struct inode *ip, u32 index,
jfs_warn("find_entry called with index = %d", index);
maxWarnings--;
}
- return 0;
+ return NULL;
}
if (index >= jfs_ip->next_index) {
jfs_warn("find_entry called with index >= next_index");
- return 0;
+ return NULL;
}
if (jfs_ip->next_index <= (MAX_INLINE_DIRTABLE_ENTRY + 1)) {
/*
* Inline directory table
*/
- *mp = 0;
+ *mp = NULL;
slot = &jfs_ip->i_dirtable[index - 2];
} else {
offset = (index - 2) * sizeof(struct dir_table_slot);
@@ -281,7 +281,7 @@ static struct dir_table_slot *find_index(struct inode *ip, u32 index,
if (*mp && (*lblock != blkno)) {
release_metapage(*mp);
- *mp = 0;
+ *mp = NULL;
}
if (*mp == 0) {
*lblock = blkno;
@@ -289,7 +289,7 @@ static struct dir_table_slot *find_index(struct inode *ip, u32 index,
}
if (*mp == 0) {
jfs_err("free_index: error reading directory table");
- return 0;
+ return NULL;
}
slot =
@@ -490,7 +490,7 @@ static void free_index(tid_t tid, struct inode *ip, u32 index, u32 next)
{
struct dir_table_slot *dirtab_slot;
s64 lblock;
- struct metapage *mp = 0;
+ struct metapage *mp = NULL;
dirtab_slot = find_index(ip, index, &mp, &lblock);
@@ -543,7 +543,7 @@ static int read_index(struct inode *ip, u32 index,
struct dir_table_slot * dirtab_slot)
{
s64 lblock;
- struct metapage *mp = 0;
+ struct metapage *mp = NULL;
struct dir_table_slot *slot;
slot = find_index(ip, index, &mp, &lblock);
@@ -850,7 +850,7 @@ int dtInsert(tid_t tid, struct inode *ip,
data.leaf.ip = ip;
} else {
n = NDTLEAF_LEGACY(name->namlen);
- data.leaf.ip = 0; /* signifies legacy directory format */
+ data.leaf.ip = NULL; /* signifies legacy directory format */
}
data.leaf.ino = cpu_to_le32(*fsn);
@@ -940,7 +940,7 @@ static int dtSplitUp(tid_t tid,
int xlen, xsize;
struct pxdlist pxdlist;
pxd_t *pxd;
- struct component_name key = { 0, 0 };
+ struct component_name key = { 0, NULL };
ddata_t *data = split->data;
int n;
struct dt_lock *dtlck;
@@ -1550,7 +1550,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) {
s64 lblock;
- mp = 0;
+ mp = NULL;
stbl = DT_GETSTBL(rp);
for (n = 0; n < rp->header.nextindex; n++) {
ldtentry = (struct ldtentry *) & rp->slot[stbl[n]];
@@ -1676,7 +1676,7 @@ static int dtExtendPage(tid_t tid,
if (DO_INDEX(ip)) {
s64 lblock;
- mp = 0;
+ mp = NULL;
stbl = DT_GETSTBL(sp);
for (n = 0; n < sp->header.nextindex; n++) {
ldtentry =
@@ -1970,7 +1970,7 @@ static int dtSplitRoot(tid_t tid,
*/
if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) {
s64 lblock;
- struct metapage *mp = 0;
+ struct metapage *mp = NULL;
struct ldtentry *ldtentry;
stbl = DT_GETSTBL(rp);
@@ -2181,7 +2181,7 @@ int dtDelete(tid_t tid,
if (DO_INDEX(ip) && index < p->header.nextindex) {
s64 lblock;
- imp = 0;
+ imp = NULL;
stbl = DT_GETSTBL(p);
for (i = index; i < p->header.nextindex; i++) {
ldtentry =
@@ -3873,8 +3873,8 @@ static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key,
ddata_t * data, struct dt_lock ** dtlock)
{
struct dtslot *h, *t;
- struct ldtentry *lh = 0;
- struct idtentry *ih = 0;
+ struct ldtentry *lh = NULL;
+ struct idtentry *ih = NULL;
int hsi, fsi, klen, len, nextindex;
wchar_t *kname, *name;
s8 *stbl;
@@ -3883,7 +3883,7 @@ static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key,
struct lv *lv;
int xsi, n;
s64 bn = 0;
- struct metapage *mp = 0;
+ struct metapage *mp = NULL;
klen = key->namlen;
kname = key->name;
@@ -3999,7 +3999,7 @@ static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key,
* Need to update slot number for entries that moved
* in the stbl
*/
- mp = 0;
+ mp = NULL;
for (n = index + 1; n <= nextindex; n++) {
lh = (struct ldtentry *) & (p->slot[stbl[n]]);
modify_index(data->leaf.tid, data->leaf.ip,
@@ -4035,8 +4035,8 @@ static void dtMoveEntry(dtpage_t * sp, int si, dtpage_t * dp,
int dsi; /* dst slot index */
s8 *sstbl, *dstbl; /* sorted entry table */
int snamlen, len;
- struct ldtentry *slh, *dlh = 0;
- struct idtentry *sih, *dih = 0;
+ struct ldtentry *slh, *dlh = NULL;
+ struct idtentry *sih, *dih = NULL;
struct dtslot *h, *s, *d;
struct dt_lock *sdtlck = *sdtlock, *ddtlck = *ddtlock;
struct lv *slv, *dlv;
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 865334f6c8afce..86246f4db7a6fd 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -2061,7 +2061,7 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
{
int extno, bitno, agno, sword, rc;
struct metapage *amp = NULL, *bmp = NULL;
- struct iag *aiagp = 0, *biagp = 0;
+ struct iag *aiagp = NULL, *biagp = NULL;
u32 mask;
/* check if this is the last free inode within the iag.
@@ -2207,7 +2207,7 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
{
int agno, iagno, fwd, back, freei = 0, sword, rc;
- struct iag *aiagp = 0, *biagp = 0, *ciagp = 0;
+ struct iag *aiagp = NULL, *biagp = NULL, *ciagp = NULL;
struct metapage *amp, *bmp, *cmp, *dmp;
struct inode *ipimap;
s64 blkno, hint;
@@ -2910,7 +2910,7 @@ int diExtendFS(struct inode *ipimap, struct inode *ipbmap)
{
int rc, rcx = 0;
struct inomap *imap = JFS_IP(ipimap)->i_imap;
- struct iag *iagp = 0, *hiagp = 0;
+ struct iag *iagp = NULL, *hiagp = NULL;
struct bmap *mp = JFS_SBI(ipbmap->i_sb)->bmap;
struct metapage *bp, *hbp;
int i, n, head;
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 8c94bb015c845f..dd6578b7d3b260 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -320,7 +320,7 @@ again:
atomic_set(&mp->nohomeok,0);
mp->mapping = mapping;
mp->index = lblock;
- mp->page = 0;
+ mp->page = NULL;
mp->logical_size = size;
add_to_hash(mp, hash_ptr);
spin_unlock(&meta_lock);
@@ -465,7 +465,7 @@ void release_metapage(struct metapage * mp)
set_bit(META_stale, &mp->flag);
spin_unlock(&meta_lock);
kunmap(mp->page);
- mp->data = 0;
+ mp->data = NULL;
if (test_bit(META_dirty, &mp->flag))
__write_metapage(mp);
if (test_bit(META_sync, &mp->flag)) {
@@ -491,7 +491,7 @@ void release_metapage(struct metapage * mp)
*/
log = mp->log;
LOGSYNC_LOCK(log);
- mp->log = 0;
+ mp->log = NULL;
mp->lsn = 0;
mp->clsn = 0;
log->count--;
diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c
index 3de7db13d2574b..fad757e9ea5348 100644
--- a/fs/jfs/jfs_mount.c
+++ b/fs/jfs/jfs_mount.c
@@ -166,7 +166,7 @@ int jfs_mount(struct super_block *sb)
}
} else
/* Secondary aggregate inode table is not valid */
- sbi->ipaimap2 = 0;
+ sbi->ipaimap2 = NULL;
/*
* mount (the only/single) fileset
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 7e08dd5025ada2..f4bd79b705f6ff 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -330,9 +330,9 @@ int txInit(void)
void txExit(void)
{
vfree(TxLock);
- TxLock = 0;
+ TxLock = NULL;
vfree(TxBlock);
- TxBlock = 0;
+ TxBlock = NULL;
}
@@ -1554,7 +1554,7 @@ static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
hold_metapage(mp, 0);
atomic_dec(&mp->nohomeok);
discard_metapage(mp);
- tlck->mp = 0;
+ tlck->mp = NULL;
return 0;
}
@@ -2270,7 +2270,7 @@ static void txUpdateMap(struct tblock * tblk)
struct pxd_lock pxdlock;
int maptype;
int k, nlock;
- struct metapage *mp = 0;
+ struct metapage *mp = NULL;
ipimap = JFS_SBI(tblk->sb)->ipimap;
@@ -2358,7 +2358,7 @@ static void txUpdateMap(struct tblock * tblk)
assert(atomic_read(&mp->nohomeok) == 1);
atomic_dec(&mp->nohomeok);
discard_metapage(mp);
- tlck->mp = 0;
+ tlck->mp = NULL;
}
}
/*
diff --git a/fs/jfs/jfs_uniupr.c b/fs/jfs/jfs_uniupr.c
index af63d97bb1af52..4ab185d26308b9 100644
--- a/fs/jfs/jfs_uniupr.c
+++ b/fs/jfs/jfs_uniupr.c
@@ -130,5 +130,5 @@ UNICASERANGE UniUpperRange[] = {
{ 0x0490, 0x04cc, UniCaseRangeU0490 },
{ 0x1e00, 0x1ffc, UniCaseRangeU1e00 },
{ 0xff40, 0xff5a, UniCaseRangeUff40 },
- { 0, 0, 0 }
+ { 0 }
};
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
index fab2bbcfe09b49..5aa647326887e3 100644
--- a/fs/jfs/jfs_xtree.c
+++ b/fs/jfs/jfs_xtree.c
@@ -1222,7 +1222,7 @@ xtSplitPage(tid_t tid, struct inode *ip,
struct pxdlist *pxdlist;
pxd_t *pxd;
struct tlock *tlck;
- struct xtlock *sxtlck = 0, *rxtlck = 0;
+ struct xtlock *sxtlck = NULL, *rxtlck = NULL;
smp = split->mp;
sp = XT_PAGE(ip, smp);
@@ -1603,7 +1603,7 @@ int xtExtend(tid_t tid, /* transaction id */
xad_t *xad;
s64 xaddr;
struct tlock *tlck;
- struct xtlock *xtlck = 0;
+ struct xtlock *xtlck = NULL;
int rootsplit = 0;
jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);
@@ -1957,7 +1957,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
int nxlen, xlen, lxlen, rxlen;
s64 nxaddr, xaddr;
struct tlock *tlck;
- struct xtlock *xtlck = 0;
+ struct xtlock *xtlck = NULL;
int rootsplit = 0, newpage = 0;
/* there must exist extent to be tailgated */
@@ -3416,9 +3416,9 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
int xlen, len, freexlen;
struct btstack btstack;
struct btframe *parent;
- struct tblock *tblk = 0;
- struct tlock *tlck = 0;
- struct xtlock *xtlck = 0;
+ struct tblock *tblk = NULL;
+ struct tlock *tlck = NULL;
+ struct xtlock *xtlck = NULL;
struct xdlistlock xadlock; /* maplock for COMMIT_WMAP */
struct pxd_lock *pxdlock; /* maplock for COMMIT_WMAP */
s64 nfreed;
@@ -3614,7 +3614,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
pxdlock->flag = mlckFREEPXD;
PXDaddress(&pxdlock->pxd, xaddr);
PXDlength(&pxdlock->pxd, freexlen);
- txFreeMap(ip, pxdlock, 0, COMMIT_WMAP);
+ txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
/* reset map lock */
xadlock.flag = mlckFREEXADLIST;
@@ -3642,8 +3642,8 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
xadlock.count =
le16_to_cpu(p->header.nextindex) -
nextindex;
- txFreeMap(ip, (struct maplock *) & xadlock, 0,
- COMMIT_WMAP);
+ txFreeMap(ip, (struct maplock *) & xadlock,
+ NULL, COMMIT_WMAP);
}
p->header.nextindex = cpu_to_le16(nextindex);
}
@@ -3672,7 +3672,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
xadlock.xdlist = &p->xad[XTENTRYSTART];
xadlock.count =
le16_to_cpu(p->header.nextindex) - XTENTRYSTART;
- txFreeMap(ip, (struct maplock *) & xadlock, 0, COMMIT_WMAP);
+ txFreeMap(ip, (struct maplock *) & xadlock, NULL, COMMIT_WMAP);
}
if (p->header.flag & BT_ROOT) {
@@ -3747,8 +3747,8 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
xadlock.count =
le16_to_cpu(p->header.nextindex) -
index - 1;
- txFreeMap(ip, (struct maplock *) & xadlock, 0,
- COMMIT_WMAP);
+ txFreeMap(ip, (struct maplock *) & xadlock,
+ NULL, COMMIT_WMAP);
}
BT_MARK_DIRTY(mp, ip);
@@ -3819,7 +3819,7 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
xadlock.count =
le16_to_cpu(p->header.nextindex) -
XTENTRYSTART;
- txFreeMap(ip, (struct maplock *) & xadlock, 0,
+ txFreeMap(ip, (struct maplock *) & xadlock, NULL,
COMMIT_WMAP);
}
BT_MARK_DIRTY(mp, ip);
@@ -3956,11 +3956,11 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
struct btframe *parent;
int rc;
struct tblock *tblk;
- struct tlock *tlck = 0;
+ struct tlock *tlck = NULL;
xad_t *xad;
int xlen;
s64 xoff;
- struct xtlock *xtlck = 0;
+ struct xtlock *xtlck = NULL;
/* save object truncation type */
tblk = tid_to_tblock(tid);
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 998410cccaa03e..871371d5a1aa32 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -702,7 +702,7 @@ int freeZeroLink(struct inode *ip)
pxdlock->flag = mlckFREEPXD;
PXDaddress(&pxdlock->pxd, xaddr);
PXDlength(&pxdlock->pxd, xlen);
- txFreeMap(ip, pxdlock, 0, COMMIT_WMAP);
+ txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
}
/*
@@ -722,7 +722,7 @@ int freeZeroLink(struct inode *ip)
pxdlock->flag = mlckFREEPXD;
PXDaddress(&pxdlock->pxd, xaddr);
PXDlength(&pxdlock->pxd, xlen);
- txFreeMap(ip, pxdlock, 0, COMMIT_WMAP);
+ txFreeMap(ip, pxdlock, NULL, COMMIT_WMAP);
}
/*
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index d359c26195cfbf..18fdb77086a0ee 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -422,7 +422,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
goto out_kfree;
}
if (sb->s_flags & MS_RDONLY)
- sbi->log = 0;
+ sbi->log = NULL;
else {
rc = jfs_mount_rw(sb, 0);
if (rc) {
@@ -600,7 +600,7 @@ static int __init init_jfs_fs(void)
/*
* I/O completion thread (endio)
*/
- jfsIOthread = kernel_thread(jfsIOWait, 0, CLONE_KERNEL);
+ jfsIOthread = kernel_thread(jfsIOWait, NULL, CLONE_KERNEL);
if (jfsIOthread < 0) {
jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsIOthread);
goto end_txmngr;
@@ -613,7 +613,7 @@ static int __init init_jfs_fs(void)
commit_threads = MAX_COMMIT_THREADS;
for (i = 0; i < commit_threads; i++) {
- jfsCommitThread[i] = kernel_thread(jfs_lazycommit, 0,
+ jfsCommitThread[i] = kernel_thread(jfs_lazycommit, NULL,
CLONE_KERNEL);
if (jfsCommitThread[i] < 0) {
jfs_err("init_jfs_fs: fork failed w/rc = %d",
@@ -625,7 +625,7 @@ static int __init init_jfs_fs(void)
wait_for_completion(&jfsIOwait);
}
- jfsSyncThread = kernel_thread(jfs_sync, 0, CLONE_KERNEL);
+ jfsSyncThread = kernel_thread(jfs_sync, NULL, CLONE_KERNEL);
if (jfsSyncThread < 0) {
jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsSyncThread);
goto kill_committask;
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index c786348cdb00fa..cf3fba6e5d7811 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -592,7 +592,7 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size)
if (new_size == 0) {
ea_release(inode, ea_buf);
- ea_buf = 0;
+ ea_buf = NULL;
} else if (ea_buf->flag & EA_INLINE) {
assert(new_size <= sizeof (ji->i_inline_ea));
ji->mode2 &= ~INLINEEA;
@@ -633,7 +633,7 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size)
}
ji->ea = ea_buf->new_ea;
} else {
- txEA(tid, inode, &ji->ea, 0);
+ txEA(tid, inode, &ji->ea, NULL);
if (ji->ea.flag & DXD_INLINE)
ji->mode2 |= INLINEEA;
ji->ea.flag = 0;
@@ -1039,5 +1039,5 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
int jfs_removexattr(struct dentry *dentry, const char *name)
{
- return __jfs_setxattr(dentry->d_inode, name, 0, 0, XATTR_REPLACE);
+ return __jfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE);
}
diff --git a/fs/mpage.c b/fs/mpage.c
index a22fc8f0ba9b05..79fdc78455b979 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -404,6 +404,7 @@ mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
struct block_device *boundary_bdev = NULL;
int length;
struct buffer_head map_bh;
+ loff_t i_size = i_size_read(inode);
if (page_has_buffers(page)) {
struct buffer_head *head = page_buffers(page);
@@ -460,7 +461,7 @@ mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
*/
BUG_ON(!PageUptodate(page));
block_in_file = page->index << (PAGE_CACHE_SHIFT - blkbits);
- last_block = (i_size_read(inode) - 1) >> blkbits;
+ last_block = (i_size - 1) >> blkbits;
map_bh.b_page = page;
for (page_block = 0; page_block < blocks_per_page; ) {
@@ -489,9 +490,18 @@ mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
first_unmapped = page_block;
- end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT;
+page_is_mapped:
+ end_index = i_size >> PAGE_CACHE_SHIFT;
if (page->index >= end_index) {
- unsigned offset = i_size_read(inode) & (PAGE_CACHE_SIZE - 1);
+ /*
+ * The page straddles i_size. It must be zeroed out on each
+ * and every writepage invokation because it may be mmapped.
+ * "A file is mapped in multiples of the page size. For a file
+ * that is not a multiple of the page size, the remaining memory
+ * is zeroed when mapped, and writes to that region are not
+ * written out to the file."
+ */
+ unsigned offset = i_size & (PAGE_CACHE_SIZE - 1);
char *kaddr;
if (page->index > end_index || !offset)
@@ -502,8 +512,6 @@ mpage_writepage(struct bio *bio, struct page *page, get_block_t get_block,
kunmap_atomic(kaddr, KM_USER0);
}
-page_is_mapped:
-
/*
* This page will go to BIO. Do we need to send this BIO off first?
*/
@@ -519,6 +527,17 @@ alloc_new:
}
/*
+ * Must try to add the page before marking the buffer clean or
+ * the confused fail path above (OOM) will be very confused when
+ * it finds all bh marked clean (i.e. it will not write anything)
+ */
+ length = first_unmapped << blkbits;
+ if (bio_add_page(bio, page, length, 0) < length) {
+ bio = mpage_bio_submit(WRITE, bio);
+ goto alloc_new;
+ }
+
+ /*
* OK, we have our BIO, so we can now mark the buffers clean. Make
* sure to only clean buffers which we know we'll be writing.
*/
@@ -538,12 +557,6 @@ alloc_new:
try_to_free_buffers(page);
}
- length = first_unmapped << blkbits;
- if (bio_add_page(bio, page, length, 0) < length) {
- bio = mpage_bio_submit(WRITE, bio);
- goto alloc_new;
- }
-
BUG_ON(PageWriteback(page));
set_page_writeback(page);
unlock_page(page);
diff --git a/fs/namei.c b/fs/namei.c
index 3db4da5a2116ed..bbadcf782e92f7 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -279,6 +279,16 @@ void path_release(struct nameidata *nd)
}
/*
+ * umount() mustn't call path_release()/mntput() as that would clear
+ * mnt_expiry_mark
+ */
+void path_release_on_umount(struct nameidata *nd)
+{
+ dput(nd->dentry);
+ _mntput(nd->mnt);
+}
+
+/*
* Internal lookup() using the new generic dcache.
* SMP-safe
*/
diff --git a/fs/namespace.c b/fs/namespace.c
index f3ab6910fdf130..759527b1efe2ce 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -60,6 +60,7 @@ struct vfsmount *alloc_vfsmnt(const char *name)
INIT_LIST_HEAD(&mnt->mnt_child);
INIT_LIST_HEAD(&mnt->mnt_mounts);
INIT_LIST_HEAD(&mnt->mnt_list);
+ INIT_LIST_HEAD(&mnt->mnt_fslink);
if (name) {
int size = strlen(name)+1;
char *newname = kmalloc(size, GFP_KERNEL);
@@ -106,13 +107,9 @@ struct vfsmount *lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)
EXPORT_SYMBOL(lookup_mnt);
-static int check_mnt(struct vfsmount *mnt)
+static inline int check_mnt(struct vfsmount *mnt)
{
- spin_lock(&vfsmount_lock);
- while (mnt->mnt_parent != mnt)
- mnt = mnt->mnt_parent;
- spin_unlock(&vfsmount_lock);
- return mnt == current->namespace->root;
+ return mnt->mnt_namespace == current->namespace;
}
static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
@@ -164,6 +161,14 @@ clone_mnt(struct vfsmount *old, struct dentry *root)
mnt->mnt_root = dget(root);
mnt->mnt_mountpoint = mnt->mnt_root;
mnt->mnt_parent = mnt;
+ mnt->mnt_namespace = old->mnt_namespace;
+
+ /* stick the duplicate mount on the same expiry list
+ * as the original if that was on one */
+ spin_lock(&vfsmount_lock);
+ if (!list_empty(&old->mnt_fslink))
+ list_add(&mnt->mnt_fslink, &old->mnt_fslink);
+ spin_unlock(&vfsmount_lock);
}
return mnt;
}
@@ -346,6 +351,7 @@ void umount_tree(struct vfsmount *mnt)
while (!list_empty(&kill)) {
mnt = list_entry(kill.next, struct vfsmount, mnt_list);
list_del_init(&mnt->mnt_list);
+ list_del_init(&mnt->mnt_fslink);
if (mnt->mnt_parent == mnt) {
spin_unlock(&vfsmount_lock);
} else {
@@ -369,6 +375,24 @@ static int do_umount(struct vfsmount *mnt, int flags)
return retval;
/*
+ * Allow userspace to request a mountpoint be expired rather than
+ * unmounting unconditionally. Unmount only happens if:
+ * (1) the mark is already set (the mark is cleared by mntput())
+ * (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount]
+ */
+ if (flags & MNT_EXPIRE) {
+ if (mnt == current->fs->rootmnt ||
+ flags & (MNT_FORCE | MNT_DETACH))
+ return -EINVAL;
+
+ if (atomic_read(&mnt->mnt_count) != 2)
+ return -EBUSY;
+
+ if (!xchg(&mnt->mnt_expiry_mark, 1))
+ return -EAGAIN;
+ }
+
+ /*
* If we may have to abort operations to get out of this
* mount, and they will themselves hold resources we must
* allow the fs to do things. In the Unix tradition of
@@ -461,7 +485,7 @@ asmlinkage long sys_umount(char __user * name, int flags)
retval = do_umount(nd.mnt, flags);
dput_and_out:
- path_release(&nd);
+ path_release_on_umount(&nd);
out:
return retval;
}
@@ -618,6 +642,11 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
}
if (mnt) {
+ /* stop bind mounts from expiring */
+ spin_lock(&vfsmount_lock);
+ list_del_init(&mnt->mnt_fslink);
+ spin_unlock(&vfsmount_lock);
+
err = graft_tree(mnt, nd);
if (err) {
spin_lock(&vfsmount_lock);
@@ -638,7 +667,8 @@ static int do_loopback(struct nameidata *nd, char *old_name, int recurse)
* on it - tough luck.
*/
-static int do_remount(struct nameidata *nd,int flags,int mnt_flags,void *data)
+static int do_remount(struct nameidata *nd, int flags, int mnt_flags,
+ void *data)
{
int err;
struct super_block * sb = nd->mnt->mnt_sb;
@@ -710,6 +740,10 @@ static int do_move_mount(struct nameidata *nd, char *old_name)
detach_mnt(old_nd.mnt, &parent_nd);
attach_mnt(old_nd.mnt, nd);
+
+ /* if the mount is moved, it should no longer be expire
+ * automatically */
+ list_del_init(&old_nd.mnt->mnt_fslink);
out2:
spin_unlock(&vfsmount_lock);
out1:
@@ -722,11 +756,14 @@ out:
return err;
}
-static int do_add_mount(struct nameidata *nd, char *type, int flags,
+/*
+ * create a new mount for userspace and request it to be added into the
+ * namespace's tree
+ */
+static int do_new_mount(struct nameidata *nd, char *type, int flags,
int mnt_flags, char *name, void *data)
{
struct vfsmount *mnt;
- int err;
if (!type || !memchr(type, 0, PAGE_SIZE))
return -EINVAL;
@@ -736,9 +773,20 @@ static int do_add_mount(struct nameidata *nd, char *type, int flags,
return -EPERM;
mnt = do_kern_mount(type, flags, name, data);
- err = PTR_ERR(mnt);
if (IS_ERR(mnt))
- goto out;
+ return PTR_ERR(mnt);
+
+ return do_add_mount(mnt, nd, mnt_flags, NULL);
+}
+
+/*
+ * add a mount into a namespace's mount tree
+ * - provide the option of adding the new mount to an expiration list
+ */
+int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
+ int mnt_flags, struct list_head *fslist)
+{
+ int err;
down_write(&current->namespace->sem);
/* Something was mounted here while we slept */
@@ -750,22 +798,143 @@ static int do_add_mount(struct nameidata *nd, char *type, int flags,
/* Refuse the same filesystem on the same mount point */
err = -EBUSY;
- if (nd->mnt->mnt_sb == mnt->mnt_sb && nd->mnt->mnt_root == nd->dentry)
+ if (nd->mnt->mnt_sb == newmnt->mnt_sb &&
+ nd->mnt->mnt_root == nd->dentry)
goto unlock;
err = -EINVAL;
- if (S_ISLNK(mnt->mnt_root->d_inode->i_mode))
+ if (S_ISLNK(newmnt->mnt_root->d_inode->i_mode))
goto unlock;
- mnt->mnt_flags = mnt_flags;
- err = graft_tree(mnt, nd);
+ newmnt->mnt_flags = mnt_flags;
+ err = graft_tree(newmnt, nd);
+
+ if (err == 0 && fslist) {
+ /* add to the specified expiration list */
+ spin_lock(&vfsmount_lock);
+ list_add_tail(&newmnt->mnt_fslink, fslist);
+ spin_unlock(&vfsmount_lock);
+ }
+
unlock:
up_write(&current->namespace->sem);
- mntput(mnt);
-out:
+ mntput(newmnt);
return err;
}
+EXPORT_SYMBOL_GPL(do_add_mount);
+
+/*
+ * process a list of expirable mountpoints with the intent of discarding any
+ * mountpoints that aren't in use and haven't been touched since last we came
+ * here
+ */
+void mark_mounts_for_expiry(struct list_head *mounts)
+{
+ struct namespace *namespace;
+ struct list_head graveyard, *_p, *_n;
+ struct vfsmount *mnt;
+
+ if (list_empty(mounts))
+ return;
+
+ INIT_LIST_HEAD(&graveyard);
+
+ spin_lock(&vfsmount_lock);
+
+ /* extract from the expiration list every vfsmount that matches the
+ * following criteria:
+ * - only referenced by its parent vfsmount
+ * - still marked for expiry (marked on the last call here; marks are
+ * cleared by mntput())
+ */
+ list_for_each_safe(_p, _n, mounts) {
+ mnt = list_entry(_p, struct vfsmount, mnt_fslink);
+
+ if (!xchg(&mnt->mnt_expiry_mark, 1) ||
+ atomic_read(&mnt->mnt_count) != 1)
+ continue;
+
+ mntget(mnt);
+ list_move(&mnt->mnt_fslink, &graveyard);
+ }
+
+ /*
+ * go through the vfsmounts we've just consigned to the graveyard to
+ * - check that they're still dead
+ * - delete the vfsmount from the appropriate namespace under lock
+ * - dispose of the corpse
+ */
+ while (!list_empty(&graveyard)) {
+ mnt = list_entry(graveyard.next, struct vfsmount, mnt_fslink);
+ list_del_init(&mnt->mnt_fslink);
+
+ /* don't do anything if the namespace is dead - all the
+ * vfsmounts from it are going away anyway */
+ namespace = mnt->mnt_namespace;
+ if (!namespace || atomic_read(&namespace->count) <= 0)
+ continue;
+ get_namespace(namespace);
+
+ spin_unlock(&vfsmount_lock);
+ down_write(&namespace->sem);
+ spin_lock(&vfsmount_lock);
+
+ /* check that it is still dead: the count should now be 2 - as
+ * contributed by the vfsmount parent and the mntget above */
+ if (atomic_read(&mnt->mnt_count) == 2) {
+ struct vfsmount *xdmnt;
+ struct dentry *xdentry;
+
+ /* delete from the namespace */
+ list_del_init(&mnt->mnt_list);
+ list_del_init(&mnt->mnt_child);
+ list_del_init(&mnt->mnt_hash);
+ mnt->mnt_mountpoint->d_mounted--;
+
+ xdentry = mnt->mnt_mountpoint;
+ mnt->mnt_mountpoint = mnt->mnt_root;
+ xdmnt = mnt->mnt_parent;
+ mnt->mnt_parent = mnt;
+
+ spin_unlock(&vfsmount_lock);
+
+ mntput(xdmnt);
+ dput(xdentry);
+
+ /* now lay it to rest if this was the last ref on the
+ * superblock */
+ if (atomic_read(&mnt->mnt_sb->s_active) == 1) {
+ /* last instance - try to be smart */
+ lock_kernel();
+ DQUOT_OFF(mnt->mnt_sb);
+ acct_auto_close(mnt->mnt_sb);
+ unlock_kernel();
+ }
+
+ mntput(mnt);
+ }
+ else {
+ /* someone brought it back to life whilst we didn't
+ * have any locks held so return it to the expiration
+ * list */
+ list_add_tail(&mnt->mnt_fslink, mounts);
+ spin_unlock(&vfsmount_lock);
+ }
+
+ up_write(&namespace->sem);
+
+ mntput(mnt);
+ put_namespace(namespace);
+
+ spin_lock(&vfsmount_lock);
+ }
+
+ spin_unlock(&vfsmount_lock);
+}
+
+EXPORT_SYMBOL_GPL(mark_mounts_for_expiry);
+
int copy_mount_options (const void __user *data, unsigned long *where)
{
int i;
@@ -860,7 +1029,7 @@ long do_mount(char * dev_name, char * dir_name, char *type_page,
else if (flags & MS_MOVE)
retval = do_move_mount(&nd, dev_name);
else
- retval = do_add_mount(&nd, type_page, flags, mnt_flags,
+ retval = do_new_mount(&nd, type_page, flags, mnt_flags,
dev_name, data_page);
dput_out:
path_release(&nd);
@@ -1185,6 +1354,7 @@ static void __init init_mount_tree(void)
init_rwsem(&namespace->sem);
list_add(&mnt->mnt_list, &namespace->list);
namespace->root = mnt;
+ mnt->mnt_namespace = namespace;
init_task.namespace = namespace;
read_lock(&tasklist_lock);
@@ -1252,8 +1422,15 @@ void __init mnt_init(unsigned long mempages)
void __put_namespace(struct namespace *namespace)
{
+ struct vfsmount *mnt;
+
down_write(&namespace->sem);
spin_lock(&vfsmount_lock);
+
+ list_for_each_entry(mnt, &namespace->list, mnt_list) {
+ mnt->mnt_namespace = NULL;
+ }
+
umount_tree(namespace->root);
spin_unlock(&vfsmount_lock);
up_write(&namespace->sem);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 3c57bc31f5213c..f7ac90d1596167 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1477,10 +1477,12 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
err = nfsd_open(rqstp, fhp, S_IFDIR, MAY_READ, &file);
if (err)
goto out;
- if (offset > ~(u32) 0)
- goto out_close;
- file.f_pos = offset;
+ offset = vfs_llseek(&file, offset, 0);
+ if (offset < 0) {
+ err = nfserrno((int)offset);
+ goto out_close;
+ }
/*
* Read the directory entries. This silly loop is necessary because
@@ -1496,7 +1498,7 @@ nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t *offsetp,
err = nfserrno(err);
else
err = cdp->err;
- *offsetp = file.f_pos;
+ *offsetp = vfs_llseek(&file, 0, 1);
if (err == nfserr_eof || err == nfserr_toosmall)
err = nfs_ok; /* can still be found in ->err */
diff --git a/fs/read_write.c b/fs/read_write.c
index f765a22b49cb50..481332642515c0 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -76,14 +76,12 @@ loff_t remote_llseek(struct file *file, loff_t offset, int origin)
unlock_kernel();
return retval;
}
-
EXPORT_SYMBOL(remote_llseek);
loff_t no_llseek(struct file *file, loff_t offset, int origin)
{
return -ESPIPE;
}
-
EXPORT_SYMBOL(no_llseek);
loff_t default_llseek(struct file *file, loff_t offset, int origin)
@@ -109,10 +107,9 @@ loff_t default_llseek(struct file *file, loff_t offset, int origin)
unlock_kernel();
return retval;
}
-
EXPORT_SYMBOL(default_llseek);
-static inline loff_t llseek(struct file *file, loff_t offset, int origin)
+loff_t vfs_llseek(struct file *file, loff_t offset, int origin)
{
loff_t (*fn)(struct file *, loff_t, int);
@@ -121,6 +118,7 @@ static inline loff_t llseek(struct file *file, loff_t offset, int origin)
fn = file->f_op->llseek;
return fn(file, offset, origin);
}
+EXPORT_SYMBOL(vfs_llseek);
asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
{
@@ -135,7 +133,7 @@ asmlinkage off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin)
retval = -EINVAL;
if (origin <= 2) {
- loff_t res = llseek(file, offset, origin);
+ loff_t res = vfs_llseek(file, offset, origin);
retval = res;
if (res != (loff_t)retval)
retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */
@@ -165,7 +163,7 @@ asmlinkage long sys_llseek(unsigned int fd, unsigned long offset_high,
if (origin > 2)
goto out_putf;
- offset = llseek(file, ((loff_t) offset_high << 32) | offset_low,
+ offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low,
origin);
retval = (int)offset;
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index 12fc56cac3a90d..b28f42e3bf08db 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -271,7 +271,7 @@ smb_file_sendfile(struct file *file, loff_t *ppos,
status = smb_revalidate_inode(dentry);
if (status) {
- PARANOIA("%s/%s validation failed, error=%zd\n",
+ PARANOIA("%s/%s validation failed, error=%Zd\n",
DENTRY_PATH(dentry), status);
goto out;
}
diff --git a/fs/smbfs/proc.c b/fs/smbfs/proc.c
index da0f1642689a85..8096d74922eca2 100644
--- a/fs/smbfs/proc.c
+++ b/fs/smbfs/proc.c
@@ -2309,16 +2309,14 @@ smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
*/
mask = param + 12;
- mask_len = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dir, &star);
- if (mask_len < 0) {
- result = mask_len;
+ result = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dir, &star);
+ if (result <= 0)
goto out_free;
- }
- mask_len--; /* mask_len is strlen, not #bytes */
+ mask_len = result - 1; /* mask_len is strlen, not #bytes */
+ result = 0;
first = 1;
VERBOSE("starting mask_len=%d, mask=%s\n", mask_len, mask);
- result = 0;
entries_seen = 2;
ff_eos = 0;
@@ -2464,8 +2462,6 @@ smb_proc_readdir_long(struct file *filp, void *dirent, filldir_t filldir,
/*
* Update the mask string for the next message.
*/
- if (mask_len < 0)
- mask_len = 0;
if (mask_len > 255)
mask_len = 255;
if (mask_len)
diff --git a/fs/super.c b/fs/super.c
index ca60ada578b55e..38c23bf558d498 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -793,6 +793,7 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data)
mnt->mnt_root = dget(sb->s_root);
mnt->mnt_mountpoint = sb->s_root;
mnt->mnt_parent = mnt;
+ mnt->mnt_namespace = current->namespace;
up_write(&sb->s_umount);
put_filesystem(type);
return mnt;
@@ -809,6 +810,8 @@ out:
return (struct vfsmount *)sb;
}
+EXPORT_SYMBOL_GPL(do_kern_mount);
+
struct vfsmount *kern_mount(struct file_system_type *type)
{
return do_kern_mount(type->name, 0, type->name, NULL);
diff --git a/fs/udf/super.c b/fs/udf/super.c
index bbad84970ebbf6..54e1ecffa07a89 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -417,7 +417,7 @@ udf_parse_options(char *options, struct udf_options *uopt)
case Opt_utf8:
uopt->flags |= (1 << UDF_FLAG_UTF8);
break;
-#if defined(CONFIG_NLS) || defined(CONFIG_NLS_MODULE)
+#ifdef CONFIG_UDF_NLS
case Opt_iocharset:
uopt->nls_map = load_nls(args[0].from);
uopt->flags |= (1 << UDF_FLAG_NLS_MAP);
@@ -1518,7 +1518,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
"utf8 cannot be combined with iocharset\n");
goto error_out;
}
-#if defined(CONFIG_NLS) || defined(CONFIG_NLS_MODULE)
+#ifdef CONFIG_UDF_NLS
if ((uopt.flags & (1 << UDF_FLAG_NLS_MAP)) && !uopt.nls_map)
{
uopt.nls_map = load_nls_default();
@@ -1668,7 +1668,7 @@ error_out:
udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
}
}
-#if defined(CONFIG_NLS) || defined(CONFIG_NLS_MODULE)
+#ifdef CONFIG_UDF_NLS
if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
unload_nls(UDF_SB(sb)->s_nls_map);
#endif
@@ -1746,7 +1746,7 @@ udf_put_super(struct super_block *sb)
udf_release_data(UDF_SB_TYPESPAR(sb, UDF_SB_PARTITION(sb)).s_spar_map[i]);
}
}
-#if defined(CONFIG_NLS) || defined(CONFIG_NLS_MODULE)
+#ifdef CONFIG_UDF_NLS
if (UDF_QUERY_FLAG(sb, UDF_FLAG_NLS_MAP))
unload_nls(UDF_SB(sb)->s_nls_map);
#endif