aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2005-08-29 19:01:43 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-08-29 19:01:43 -0400
commitda61396d24e37258817e42537c482e962b4742f7 (patch)
tree4293a5d557b8f9fed8a2bac93f1e5c939c7b65c3 /fs
parent2f058256cb64e346f4fb4499ff4e0f1c2791a4b4 (diff)
parent8f3d17fb7bcb7c255197d11469fb5e9695c9d2f4 (diff)
Merge upstream kernel into libata 'passthru' branch
Diffstat (limited to 'fs')
-rw-r--r--fs/adfs/adfs.h4
-rw-r--r--fs/afs/mntpt.c8
-rw-r--r--fs/autofs/symlink.c5
-rw-r--r--fs/autofs4/symlink.c4
-rw-r--r--fs/befs/linuxvfs.c10
-rw-r--r--fs/cifs/CHANGES6
-rw-r--r--fs/cifs/cifsfs.h4
-rw-r--r--fs/cifs/cifssmb.c3
-rw-r--r--fs/cifs/file.c2
-rw-r--r--fs/cifs/link.c6
-rw-r--r--fs/cifs/misc.c1
-rw-r--r--fs/devfs/base.c4
-rw-r--r--fs/ext2/symlink.c4
-rw-r--r--fs/ext3/symlink.c4
-rw-r--r--fs/freevxfs/vxfs_immed.c6
-rw-r--r--fs/hppfs/hppfs_kern.c30
-rw-r--r--fs/inotify.c4
-rw-r--r--fs/ioprio.c2
-rw-r--r--fs/jffs2/symlink.c16
-rw-r--r--fs/jfs/inode.c4
-rw-r--r--fs/jfs/jfs_logmgr.c36
-rw-r--r--fs/jfs/jfs_logmgr.h2
-rw-r--r--fs/jfs/jfs_txnmgr.c12
-rw-r--r--fs/jfs/super.c4
-rw-r--r--fs/jfs/symlink.c4
-rw-r--r--fs/namei.c43
-rw-r--r--fs/nfs/dir.c28
-rw-r--r--fs/nfs/file.c5
-rw-r--r--fs/nfs/inode.c197
-rw-r--r--fs/nfs/nfs3acl.c4
-rw-r--r--fs/nfs/nfs3proc.c4
-rw-r--r--fs/nfs/nfs4proc.c10
-rw-r--r--fs/nfs/proc.c2
-rw-r--r--fs/nfs/read.c8
-rw-r--r--fs/nfs/symlink.c37
-rw-r--r--fs/nfs_common/nfsacl.c1
-rw-r--r--fs/nfsd/nfssvc.c1
-rw-r--r--fs/ntfs/ChangeLog3
-rw-r--r--fs/ntfs/aops.c1
-rw-r--r--fs/ntfs/mft.c2
-rw-r--r--fs/proc/base.c8
-rw-r--r--fs/proc/generic.c4
-rw-r--r--fs/reiserfs/inode.c2
-rw-r--r--fs/reiserfs/namei.c3
-rw-r--r--fs/smbfs/symlink.c6
-rw-r--r--fs/sysfs/inode.c4
-rw-r--r--fs/sysfs/symlink.c6
-rw-r--r--fs/sysv/symlink.c4
-rw-r--r--fs/ufs/symlink.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c10
50 files changed, 343 insertions, 239 deletions
diff --git a/fs/adfs/adfs.h b/fs/adfs/adfs.h
index 63f5df9afb7..fd528433de4 100644
--- a/fs/adfs/adfs.h
+++ b/fs/adfs/adfs.h
@@ -97,7 +97,7 @@ extern int adfs_dir_update(struct super_block *sb, struct object_info *obj);
extern struct inode_operations adfs_file_inode_operations;
extern struct file_operations adfs_file_operations;
-extern inline __u32 signed_asl(__u32 val, signed int shift)
+static inline __u32 signed_asl(__u32 val, signed int shift)
{
if (shift >= 0)
val <<= shift;
@@ -112,7 +112,7 @@ extern inline __u32 signed_asl(__u32 val, signed int shift)
*
* The root directory ID should always be looked up in the map [3.4]
*/
-extern inline int
+static inline int
__adfs_block_map(struct super_block *sb, unsigned int object_id,
unsigned int block)
{
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index bfc28abe1cb..31ee06590de 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -30,7 +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);
-static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd);
+static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd);
struct file_operations afs_mntpt_file_operations = {
.open = afs_mntpt_open,
@@ -233,7 +233,7 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
/*
* follow a link from a mountpoint directory, thus causing it to be mounted
*/
-static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct vfsmount *newmnt;
struct dentry *old_dentry;
@@ -249,7 +249,7 @@ static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
newmnt = afs_mntpt_do_automount(dentry);
if (IS_ERR(newmnt)) {
path_release(nd);
- return PTR_ERR(newmnt);
+ return (void *)newmnt;
}
old_dentry = nd->dentry;
@@ -267,7 +267,7 @@ static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
}
kleave(" = %d", err);
- return err;
+ return ERR_PTR(err);
} /* end afs_mntpt_follow_link() */
/*****************************************************************************/
diff --git a/fs/autofs/symlink.c b/fs/autofs/symlink.c
index f028396f138..52e8772b066 100644
--- a/fs/autofs/symlink.c
+++ b/fs/autofs/symlink.c
@@ -12,11 +12,12 @@
#include "autofs_i.h"
-static int autofs_follow_link(struct dentry *dentry, struct nameidata *nd)
+/* Nothing to release.. */
+static void *autofs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
char *s=((struct autofs_symlink *)dentry->d_inode->u.generic_ip)->data;
nd_set_link(nd, s);
- return 0;
+ return NULL;
}
struct inode_operations autofs_symlink_inode_operations = {
diff --git a/fs/autofs4/symlink.c b/fs/autofs4/symlink.c
index c265a66edf0..2ea2c98fd84 100644
--- a/fs/autofs4/symlink.c
+++ b/fs/autofs4/symlink.c
@@ -12,11 +12,11 @@
#include "autofs_i.h"
-static int autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct autofs_info *ino = autofs4_dentry_ino(dentry);
nd_set_link(nd, (char *)ino->u.symlink);
- return 0;
+ return NULL;
}
struct inode_operations autofs4_symlink_inode_operations = {
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index de5bb280a82..e0a6025f1d0 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -41,8 +41,8 @@ static struct inode *befs_alloc_inode(struct super_block *sb);
static void befs_destroy_inode(struct inode *inode);
static int befs_init_inodecache(void);
static void befs_destroy_inodecache(void);
-static int befs_follow_link(struct dentry *, struct nameidata *);
-static void befs_put_link(struct dentry *, struct nameidata *);
+static void *befs_follow_link(struct dentry *, struct nameidata *);
+static void befs_put_link(struct dentry *, struct nameidata *, void *);
static int befs_utf2nls(struct super_block *sb, const char *in, int in_len,
char **out, int *out_len);
static int befs_nls2utf(struct super_block *sb, const char *in, int in_len,
@@ -461,7 +461,7 @@ befs_destroy_inodecache(void)
* The data stream become link name. Unless the LONG_SYMLINK
* flag is set.
*/
-static int
+static void *
befs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
@@ -487,10 +487,10 @@ befs_follow_link(struct dentry *dentry, struct nameidata *nd)
}
nd_set_link(nd, link);
- return 0;
+ return NULL;
}
-static void befs_put_link(struct dentry *dentry, struct nameidata *nd)
+static void befs_put_link(struct dentry *dentry, struct nameidata *nd, void *p)
{
befs_inode_info *befs_ino = BEFS_I(dentry->d_inode);
if (befs_ino->i_flags & BEFS_LONG_SYMLINK) {
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index dab4774ee7b..3196d4c4eed 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,9 @@
+Version 1.35
+------------
+Add writepage performance improvements. Fix path name conversions
+for long filenames on mounts which were done with "mapchars" mount option
+specified.
+
Version 1.34
------------
Fix error mapping of the TOO_MANY_LINKS (hardlinks) case.
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 78af5850c55..1fd21f66f24 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -83,8 +83,8 @@ extern int cifs_dir_notify(struct file *, unsigned long arg);
extern struct dentry_operations cifs_dentry_ops;
/* Functions related to symlinks */
-extern int cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
-extern void cifs_put_link(struct dentry *direntry, struct nameidata *nd);
+extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
+extern void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *);
extern int cifs_readlink(struct dentry *direntry, char __user *buffer,
int buflen);
extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 3c628bf667a..0db0b313d71 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2602,6 +2602,9 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
if(name_len < PATH_MAX) {
memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
byte_count += name_len;
+ /* 14 byte parm len above enough for 2 byte null terminator */
+ pSMB->ResumeFileName[name_len] = 0;
+ pSMB->ResumeFileName[name_len+1] = 0;
} else {
rc = -EINVAL;
goto FNext2_err_exit;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 30ab70ce554..3497125189d 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -643,7 +643,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
netfid, length,
pfLock->fl_start, numUnlock, numLock, lockType,
wait_flag);
- if (rc == 0 && (pfLock->fl_flags & FL_POSIX))
+ if (pfLock->fl_flags & FL_POSIX)
posix_lock_file_wait(file, pfLock);
FreeXid(xid);
return rc;
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index bde0fabfece..ab925ef4f86 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -92,7 +92,7 @@ cifs_hl_exit:
return rc;
}
-int
+void *
cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
{
struct inode *inode = direntry->d_inode;
@@ -148,7 +148,7 @@ out:
out_no_free:
FreeXid(xid);
nd_set_link(nd, target_path);
- return 0;
+ return NULL; /* No cookie */
}
int
@@ -330,7 +330,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
return rc;
}
-void cifs_put_link(struct dentry *direntry, struct nameidata *nd)
+void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
{
char *p = nd_get_link(nd);
if (!IS_ERR(p))
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 072b4ee8c53..20ae4153f79 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -611,6 +611,7 @@ cifsConvertToUCS(__le16 * target, const char *source, int maxlen,
src_char = source[i];
switch (src_char) {
case 0:
+ target[j] = 0;
goto ctoUCS_out;
case ':':
target[j] = cpu_to_le16(UNI_COLON);
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
index 1ecfe1f184d..8b679b67e5e 100644
--- a/fs/devfs/base.c
+++ b/fs/devfs/base.c
@@ -2491,11 +2491,11 @@ static int devfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
return 0;
} /* End Function devfs_mknod */
-static int devfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *devfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct devfs_entry *p = get_devfs_entry_from_vfs_inode(dentry->d_inode);
nd_set_link(nd, p ? p->u.symlink.linkname : ERR_PTR(-ENODEV));
- return 0;
+ return NULL;
} /* End Function devfs_follow_link */
static struct inode_operations devfs_iops = {
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c
index 9f7bac01d55..1e67d87cfa9 100644
--- a/fs/ext2/symlink.c
+++ b/fs/ext2/symlink.c
@@ -21,11 +21,11 @@
#include "xattr.h"
#include <linux/namei.h>
-static int ext2_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *ext2_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct ext2_inode_info *ei = EXT2_I(dentry->d_inode);
nd_set_link(nd, (char *)ei->i_data);
- return 0;
+ return NULL;
}
struct inode_operations ext2_symlink_inode_operations = {
diff --git a/fs/ext3/symlink.c b/fs/ext3/symlink.c
index 8c3e72818fb..4f79122cde6 100644
--- a/fs/ext3/symlink.c
+++ b/fs/ext3/symlink.c
@@ -23,11 +23,11 @@
#include <linux/namei.h>
#include "xattr.h"
-static int ext3_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void * ext3_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct ext3_inode_info *ei = EXT3_I(dentry->d_inode);
nd_set_link(nd, (char*)ei->i_data);
- return 0;
+ return NULL;
}
struct inode_operations ext3_symlink_inode_operations = {
diff --git a/fs/freevxfs/vxfs_immed.c b/fs/freevxfs/vxfs_immed.c
index ac677ab262b..d0401dc68d4 100644
--- a/fs/freevxfs/vxfs_immed.c
+++ b/fs/freevxfs/vxfs_immed.c
@@ -38,7 +38,7 @@
#include "vxfs_inode.h"
-static int vxfs_immed_follow_link(struct dentry *, struct nameidata *);
+static void * vxfs_immed_follow_link(struct dentry *, struct nameidata *);
static int vxfs_immed_readpage(struct file *, struct page *);
@@ -72,12 +72,12 @@ struct address_space_operations vxfs_immed_aops = {
* Returns:
* Zero on success, else a negative error code.
*/
-static int
+static void *
vxfs_immed_follow_link(struct dentry *dp, struct nameidata *np)
{
struct vxfs_inode_info *vip = VXFS_INO(dp->d_inode);
nd_set_link(np, vip->vii_immed.vi_immed);
- return 0;
+ return NULL;
}
/**
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
index ff150fedb98..52930915bad 100644
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs_kern.c
@@ -38,7 +38,7 @@ struct hppfs_inode_info {
static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
{
- return(list_entry(inode, struct hppfs_inode_info, vfs_inode));
+ return container_of(inode, struct hppfs_inode_info, vfs_inode);
}
#define HPPFS_SUPER_MAGIC 0xb00000ee
@@ -662,42 +662,36 @@ static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
{
struct file *proc_file;
struct dentry *proc_dentry;
- int (*readlink)(struct dentry *, char *, int);
- int err, n;
+ int ret;
proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
proc_file = dentry_open(dget(proc_dentry), NULL, O_RDONLY);
- err = PTR_ERR(proc_dentry);
- if(IS_ERR(proc_dentry))
- return(err);
+ if (IS_ERR(proc_file))
+ return PTR_ERR(proc_file);
- readlink = proc_dentry->d_inode->i_op->readlink;
- n = (*readlink)(proc_dentry, buffer, buflen);
+ ret = proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer, buflen);
fput(proc_file);
- return(n);
+ return ret;
}
-static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void* hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct file *proc_file;
struct dentry *proc_dentry;
- int (*follow_link)(struct dentry *, struct nameidata *);
- int err, n;
+ void *ret;
proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
proc_file = dentry_open(dget(proc_dentry), NULL, O_RDONLY);
- err = PTR_ERR(proc_dentry);
- if(IS_ERR(proc_dentry))
- return(err);
+ if (IS_ERR(proc_file))
+ return proc_file;
- follow_link = proc_dentry->d_inode->i_op->follow_link;
- n = (*follow_link)(proc_dentry, nd);
+ ret = proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd);
fput(proc_file);
- return(n);
+ return ret;
}
static struct inode_operations hppfs_dir_iops = {
diff --git a/fs/inotify.c b/fs/inotify.c
index 27ebcac5e07..2e4e2a57708 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -353,7 +353,7 @@ static int inotify_dev_get_wd(struct inotify_device *dev,
do {
if (unlikely(!idr_pre_get(&dev->idr, GFP_KERNEL)))
return -ENOSPC;
- ret = idr_get_new_above(&dev->idr, watch, dev->last_wd, &watch->wd);
+ ret = idr_get_new_above(&dev->idr, watch, dev->last_wd+1, &watch->wd);
} while (ret == -EAGAIN);
return ret;
@@ -402,7 +402,7 @@ static struct inotify_watch *create_watch(struct inotify_device *dev,
return ERR_PTR(ret);
}
- dev->last_wd = ret;
+ dev->last_wd = watch->wd;
watch->mask = mask;
atomic_set(&watch->count, 0);
INIT_LIST_HEAD(&watch->d_list);
diff --git a/fs/ioprio.c b/fs/ioprio.c
index 97e1f088ba0..d1c1f2b2c9d 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -62,6 +62,8 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
break;
case IOPRIO_CLASS_IDLE:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
break;
default:
return -EINVAL;
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index 65ab6b001dc..82ef484f5e1 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.c
@@ -18,7 +18,7 @@
#include <linux/namei.h>
#include "nodelist.h"
-static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd);
+static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd);
struct inode_operations jffs2_symlink_inode_operations =
{
@@ -27,9 +27,10 @@ struct inode_operations jffs2_symlink_inode_operations =
.setattr = jffs2_setattr
};
-static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
+static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
+ char *p = (char *)f->dents;
/*
* We don't acquire the f->sem mutex here since the only data we
@@ -45,19 +46,20 @@ static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
* nd_set_link() call.
*/
- if (!f->dents) {
+ if (!p) {
printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n");
- return -EIO;
+ p = ERR_PTR(-EIO);
+ } else {
+ D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents));
}
- D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents));
- nd_set_link(nd, (char *)f->dents);
+ nd_set_link(nd, p);
/*
* We unlock the f->sem mutex but VFS will use the f->dents string. This is safe
* since the only way that may cause f->dents to be changed is iput() operation.
* But VFS will not use f->dents after iput() has been called.
*/
- return 0;
+ return NULL;
}
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 2137138c59b..767c7ecb429 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -128,6 +128,10 @@ void jfs_delete_inode(struct inode *inode)
{
jfs_info("In jfs_delete_inode, inode = 0x%p", inode);
+ if (is_bad_inode(inode) ||
+ (JFS_IP(inode)->fileset != cpu_to_le32(FILESYSTEM_I)))
+ return;
+
if (test_cflag(COMMIT_Freewmap, inode))
jfs_free_zero_link(inode);
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index 22815e88e7c..d27bac6acaa 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -191,7 +191,7 @@ static int lbmIOWait(struct lbuf * bp, int flag);
static bio_end_io_t lbmIODone;
static void lbmStartIO(struct lbuf * bp);
static void lmGCwrite(struct jfs_log * log, int cant_block);
-static int lmLogSync(struct jfs_log * log, int nosyncwait);
+static int lmLogSync(struct jfs_log * log, int hard_sync);
@@ -915,19 +915,17 @@ static void lmPostGC(struct lbuf * bp)
* if new sync address is available
* (normally the case if sync() is executed by back-ground
* process).
- * if not, explicitly run jfs_blogsync() to initiate
- * getting of new sync address.
* calculate new value of i_nextsync which determines when
* this code is called again.
*
* PARAMETERS: log - log structure
- * nosyncwait - 1 if called asynchronously
+ * hard_sync - 1 to force all metadata to be written
*
* RETURN: 0
*
* serialization: LOG_LOCK() held on entry/exit
*/
-static int lmLogSync(struct jfs_log * log, int nosyncwait)
+static int lmLogSync(struct jfs_log * log, int hard_sync)
{
int logsize;
int written; /* written since last syncpt */
@@ -941,11 +939,18 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait)
unsigned long flags;
/* push dirty metapages out to disk */
- list_for_each_entry(sbi, &log->sb_list, log_list) {
- filemap_flush(sbi->ipbmap->i_mapping);
- filemap_flush(sbi->ipimap->i_mapping);
- filemap_flush(sbi->direct_inode->i_mapping);
- }
+ if (hard_sync)
+ list_for_each_entry(sbi, &log->sb_list, log_list) {
+ filemap_fdatawrite(sbi->ipbmap->i_mapping);
+ filemap_fdatawrite(sbi->ipimap->i_mapping);
+ filemap_fdatawrite(sbi->direct_inode->i_mapping);
+ }
+ else
+ list_for_each_entry(sbi, &log->sb_list, log_list) {
+ filemap_flush(sbi->ipbmap->i_mapping);
+ filemap_flush(sbi->ipimap->i_mapping);
+ filemap_flush(sbi->direct_inode->i_mapping);
+ }
/*
* forward syncpt
@@ -1021,10 +1026,6 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait)
/* next syncpt trigger = written + more */
log->nextsync = written + more;
- /* return if lmLogSync() from outside of transaction, e.g., sync() */
- if (nosyncwait)
- return lsn;
-
/* if number of bytes written from last sync point is more
* than 1/4 of the log size, stop new transactions from
* starting until all current transactions are completed
@@ -1049,11 +1050,12 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait)
*
* FUNCTION: write log SYNCPT record for specified log
*
- * PARAMETERS: log - log structure
+ * PARAMETERS: log - log structure
+ * hard_sync - set to 1 to force metadata to be written
*/
-void jfs_syncpt(struct jfs_log *log)
+void jfs_syncpt(struct jfs_log *log, int hard_sync)
{ LOG_LOCK(log);
- lmLogSync(log, 1);
+ lmLogSync(log, hard_sync);
LOG_UNLOCK(log);
}
diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h
index 747114cd38b..e4978b5b65e 100644
--- a/fs/jfs/jfs_logmgr.h
+++ b/fs/jfs/jfs_logmgr.h
@@ -510,6 +510,6 @@ extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize);
extern int lmGroupCommit(struct jfs_log *, struct tblock *);
extern int jfsIOWait(void *);
extern void jfs_flush_journal(struct jfs_log * log, int wait);
-extern void jfs_syncpt(struct jfs_log *log);
+extern void jfs_syncpt(struct jfs_log *log, int hard_sync);
#endif /* _H_JFS_LOGMGR */
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 121c981ff45..c7a92f9deb2 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -552,6 +552,11 @@ void txEnd(tid_t tid)
* synchronize with logsync barrier
*/
if (test_bit(log_SYNCBARRIER, &log->flag)) {
+ TXN_UNLOCK();
+
+ /* write dirty metadata & forward log syncpt */
+ jfs_syncpt(log, 1);
+
jfs_info("log barrier off: 0x%x", log->lsn);
/* enable new transactions start */
@@ -560,11 +565,6 @@ void txEnd(tid_t tid)
/* wakeup all waitors for logsync barrier */
TXN_WAKEUP(&log->syncwait);
- TXN_UNLOCK();
-
- /* forward log syncpt */
- jfs_syncpt(log);
-
goto wakeup;
}
}
@@ -657,7 +657,9 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
/* only anonymous txn.
* Remove from anon_list
*/
+ TXN_LOCK();
list_del_init(&jfs_ip->anon_inode_list);
+ TXN_UNLOCK();
}
jfs_ip->atlhead = tlck->next;
} else {
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index ee32211288c..9ff89720f93 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -114,6 +114,8 @@ static void jfs_destroy_inode(struct inode *inode)
{
struct jfs_inode_info *ji = JFS_IP(inode);
+ BUG_ON(!list_empty(&ji->anon_inode_list));
+
spin_lock_irq(&ji->ag_lock);
if (ji->active_ag != -1) {
struct bmap *bmap = JFS_SBI(inode->i_sb)->bmap;
@@ -531,7 +533,7 @@ static int jfs_sync_fs(struct super_block *sb, int wait)
/* log == NULL indicates read-only mount */
if (log) {
jfs_flush_journal(log, wait);
- jfs_syncpt(log);
+ jfs_syncpt(log, 0);
}
return 0;
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlin