Commit 88dcb911 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy/jfs-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy/jfs-2.6:
  JFS: add uid, gid, and umask mount options
  JFS: Take logsync lock before testing mp->lsn
  JFS: kzalloc conversion
  JFS: Add missing file from fa3241d2
  JFS: Use the kthread_ API
  JFS: Fix regression.  fsck complains if symlinks do not have INLINEEA attribute
  JFS: ext2 inode attributes for jfs
  JFS: semaphore to mutex conversion.
  JFS: make buddy table static
  JFS: Add back directory i_size calculations for legacy partitions
parents c7cace64 c5111f50
...@@ -8,7 +8,8 @@ jfs-y := super.o file.o inode.o namei.o jfs_mount.o jfs_umount.o \ ...@@ -8,7 +8,8 @@ jfs-y := super.o file.o inode.o namei.o jfs_mount.o jfs_umount.o \
jfs_xtree.o jfs_imap.o jfs_debug.o jfs_dmap.o \ jfs_xtree.o jfs_imap.o jfs_debug.o jfs_dmap.o \
jfs_unicode.o jfs_dtree.o jfs_inode.o \ jfs_unicode.o jfs_dtree.o jfs_inode.o \
jfs_extent.o symlink.o jfs_metapage.o \ jfs_extent.o symlink.o jfs_metapage.o \
jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o resize.o xattr.o jfs_logmgr.o jfs_txnmgr.o jfs_uniupr.o \
resize.o xattr.o ioctl.o
jfs-$(CONFIG_JFS_POSIX_ACL) += acl.o jfs-$(CONFIG_JFS_POSIX_ACL) += acl.o
......
...@@ -183,6 +183,9 @@ int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) ...@@ -183,6 +183,9 @@ int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir)
posix_acl_release(acl); posix_acl_release(acl);
} else } else
inode->i_mode &= ~current->fs->umask; inode->i_mode &= ~current->fs->umask;
JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) |
inode->i_mode;
return rc; return rc;
} }
...@@ -207,12 +210,12 @@ static int jfs_acl_chmod(struct inode *inode) ...@@ -207,12 +210,12 @@ static int jfs_acl_chmod(struct inode *inode)
rc = posix_acl_chmod_masq(clone, inode->i_mode); rc = posix_acl_chmod_masq(clone, inode->i_mode);
if (!rc) { if (!rc) {
tid_t tid = txBegin(inode->i_sb, 0); tid_t tid = txBegin(inode->i_sb, 0);
down(&JFS_IP(inode)->commit_sem); mutex_lock(&JFS_IP(inode)->commit_mutex);
rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, clone); rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS, clone);
if (!rc) if (!rc)
rc = txCommit(tid, 1, &inode, 0); rc = txCommit(tid, 1, &inode, 0);
txEnd(tid); txEnd(tid);
up(&JFS_IP(inode)->commit_sem); mutex_unlock(&JFS_IP(inode)->commit_mutex);
} }
posix_acl_release(clone); posix_acl_release(clone);
......
...@@ -113,4 +113,5 @@ struct file_operations jfs_file_operations = { ...@@ -113,4 +113,5 @@ struct file_operations jfs_file_operations = {
.sendfile = generic_file_sendfile, .sendfile = generic_file_sendfile,
.fsync = jfs_fsync, .fsync = jfs_fsync,
.release = jfs_release, .release = jfs_release,
.ioctl = jfs_ioctl,
}; };
...@@ -55,6 +55,7 @@ void jfs_read_inode(struct inode *inode) ...@@ -55,6 +55,7 @@ void jfs_read_inode(struct inode *inode)
inode->i_op = &jfs_file_inode_operations; inode->i_op = &jfs_file_inode_operations;
init_special_inode(inode, inode->i_mode, inode->i_rdev); init_special_inode(inode, inode->i_mode, inode->i_rdev);
} }
jfs_set_inode_flags(inode);
} }
/* /*
...@@ -89,16 +90,16 @@ int jfs_commit_inode(struct inode *inode, int wait) ...@@ -89,16 +90,16 @@ int jfs_commit_inode(struct inode *inode, int wait)
} }
tid = txBegin(inode->i_sb, COMMIT_INODE); tid = txBegin(inode->i_sb, COMMIT_INODE);
down(&JFS_IP(inode)->commit_sem); mutex_lock(&JFS_IP(inode)->commit_mutex);
/* /*
* Retest inode state after taking commit_sem * Retest inode state after taking commit_mutex
*/ */
if (inode->i_nlink && test_cflag(COMMIT_Dirty, inode)) if (inode->i_nlink && test_cflag(COMMIT_Dirty, inode))
rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0); rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
txEnd(tid); txEnd(tid);
up(&JFS_IP(inode)->commit_sem); mutex_unlock(&JFS_IP(inode)->commit_mutex);
return rc; return rc;
} }
...@@ -335,18 +336,18 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length) ...@@ -335,18 +336,18 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length)
tid = txBegin(ip->i_sb, 0); tid = txBegin(ip->i_sb, 0);
/* /*
* The commit_sem cannot be taken before txBegin. * The commit_mutex cannot be taken before txBegin.
* txBegin may block and there is a chance the inode * txBegin may block and there is a chance the inode
* could be marked dirty and need to be committed * could be marked dirty and need to be committed
* before txBegin unblocks * before txBegin unblocks
*/ */
down(&JFS_IP(ip)->commit_sem); mutex_lock(&JFS_IP(ip)->commit_mutex);
newsize = xtTruncate(tid, ip, length, newsize = xtTruncate(tid, ip, length,
COMMIT_TRUNCATE | COMMIT_PWMAP); COMMIT_TRUNCATE | COMMIT_PWMAP);
if (newsize < 0) { if (newsize < 0) {
txEnd(tid); txEnd(tid);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
break; break;
} }
...@@ -355,7 +356,7 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length) ...@@ -355,7 +356,7 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length)
txCommit(tid, 1, &ip, 0); txCommit(tid, 1, &ip, 0);
txEnd(tid); txEnd(tid);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
} while (newsize > length); /* Truncate isn't always atomic */ } while (newsize > length); /* Truncate isn't always atomic */
} }
......
/*
* linux/fs/jfs/ioctl.c
*
* Copyright (C) 2006 Herbert Poetzl
* adapted from Remy Card's ext2/ioctl.c
*/
#include <linux/fs.h>
#include <linux/ext2_fs.h>
#include <linux/ctype.h>
#include <linux/capability.h>
#include <linux/time.h>
#include <asm/current.h>
#include <asm/uaccess.h>
#include "jfs_incore.h"
#include "jfs_dinode.h"
#include "jfs_inode.h"
static struct {
long jfs_flag;
long ext2_flag;
} jfs_map[] = {
{JFS_NOATIME_FL, EXT2_NOATIME_FL},
{JFS_DIRSYNC_FL, EXT2_DIRSYNC_FL},
{JFS_SYNC_FL, EXT2_SYNC_FL},
{JFS_SECRM_FL, EXT2_SECRM_FL},
{JFS_UNRM_FL, EXT2_UNRM_FL},
{JFS_APPEND_FL, EXT2_APPEND_FL},
{JFS_IMMUTABLE_FL, EXT2_IMMUTABLE_FL},
{0, 0},
};
static long jfs_map_ext2(unsigned long flags, int from)
{
int index=0;
long mapped=0;
while (jfs_map[index].jfs_flag) {
if (from) {
if (jfs_map[index].ext2_flag & flags)
mapped |= jfs_map[index].jfs_flag;
} else {
if (jfs_map[index].jfs_flag & flags)
mapped |= jfs_map[index].ext2_flag;
}
index++;
}
return mapped;
}
int jfs_ioctl(struct inode * inode, struct file * filp, unsigned int cmd,
unsigned long arg)
{
struct jfs_inode_info *jfs_inode = JFS_IP(inode);
unsigned int flags;
switch (cmd) {
case JFS_IOC_GETFLAGS:
flags = jfs_inode->mode2 & JFS_FL_USER_VISIBLE;
flags = jfs_map_ext2(flags, 0);
return put_user(flags, (int __user *) arg);
case JFS_IOC_SETFLAGS: {
unsigned int oldflags;
if (IS_RDONLY(inode))
return -EROFS;
if ((current->fsuid != inode->i_uid) && !capable(CAP_FOWNER))
return -EACCES;
if (get_user(flags, (int __user *) arg))
return -EFAULT;
flags = jfs_map_ext2(flags, 1);
if (!S_ISDIR(inode->i_mode))
flags &= ~JFS_DIRSYNC_FL;
oldflags = jfs_inode->mode2;
/*
* The IMMUTABLE and APPEND_ONLY flags can only be changed by
* the relevant capability.
*/
if ((oldflags & JFS_IMMUTABLE_FL) ||
((flags ^ oldflags) &
(JFS_APPEND_FL | JFS_IMMUTABLE_FL))) {
if (!capable(CAP_LINUX_IMMUTABLE))
return -EPERM;
}
flags = flags & JFS_FL_USER_MODIFIABLE;
flags |= oldflags & ~JFS_FL_USER_MODIFIABLE;
jfs_inode->mode2 = flags;
jfs_set_inode_flags(inode);
inode->i_ctime = CURRENT_TIME_SEC;
mark_inode_dirty(inode);
return 0;
}
default:
return -ENOTTY;
}
}
...@@ -139,13 +139,36 @@ struct dinode { ...@@ -139,13 +139,36 @@ struct dinode {
/* more extended mode bits: attributes for OS/2 */ /* more extended mode bits: attributes for OS/2 */
#define IREADONLY 0x02000000 /* no write access to file */ #define IREADONLY 0x02000000 /* no write access to file */
#define IARCHIVE 0x40000000 /* file archive bit */
#define ISYSTEM 0x08000000 /* system file */
#define IHIDDEN 0x04000000 /* hidden file */ #define IHIDDEN 0x04000000 /* hidden file */
#define IRASH 0x4E000000 /* mask for changeable attributes */ #define ISYSTEM 0x08000000 /* system file */
#define INEWNAME 0x80000000 /* non-8.3 filename format */
#define IDIRECTORY 0x20000000 /* directory (shadow of real bit) */ #define IDIRECTORY 0x20000000 /* directory (shadow of real bit) */
#define IARCHIVE 0x40000000 /* file archive bit */
#define INEWNAME 0x80000000 /* non-8.3 filename format */
#define IRASH 0x4E000000 /* mask for changeable attributes */
#define ATTRSHIFT 25 /* bits to shift to move attribute #define ATTRSHIFT 25 /* bits to shift to move attribute
specification to mode position */ specification to mode position */
/* extended attributes for Linux */
#define JFS_NOATIME_FL 0x00080000 /* do not update atime */
#define JFS_DIRSYNC_FL 0x00100000 /* dirsync behaviour */
#define JFS_SYNC_FL 0x00200000 /* Synchronous updates */
#define JFS_SECRM_FL 0x00400000 /* Secure deletion */
#define JFS_UNRM_FL 0x00800000 /* allow for undelete */
#define JFS_APPEND_FL 0x01000000 /* writes to file may only append */
#define JFS_IMMUTABLE_FL 0x02000000 /* Immutable file */
#define JFS_FL_USER_VISIBLE 0x03F80000
#define JFS_FL_USER_MODIFIABLE 0x03F80000
#define JFS_FL_INHERIT 0x03C80000
/* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */
#define JFS_IOC_GETFLAGS _IOR('f', 1, long)
#define JFS_IOC_SETFLAGS _IOW('f', 2, long)
#endif /*_H_JFS_DINODE */ #endif /*_H_JFS_DINODE */
...@@ -64,9 +64,9 @@ ...@@ -64,9 +64,9 @@
* to the persistent bitmaps in dmaps) is guarded by (busy) buffers. * to the persistent bitmaps in dmaps) is guarded by (busy) buffers.
*/ */
#define BMAP_LOCK_INIT(bmp) init_MUTEX(&bmp->db_bmaplock) #define BMAP_LOCK_INIT(bmp) mutex_init(&bmp->db_bmaplock)
#define BMAP_LOCK(bmp) down(&bmp->db_bmaplock) #define BMAP_LOCK(bmp) mutex_lock(&bmp->db_bmaplock)
#define BMAP_UNLOCK(bmp) up(&bmp->db_bmaplock) #define BMAP_UNLOCK(bmp) mutex_unlock(&bmp->db_bmaplock)
/* /*
* forward references * forward references
...@@ -125,7 +125,7 @@ static int dbGetL2AGSize(s64 nblocks); ...@@ -125,7 +125,7 @@ static int dbGetL2AGSize(s64 nblocks);
* into the table, with the table elements yielding the maximum * into the table, with the table elements yielding the maximum
* binary buddy of free bits within the character. * binary buddy of free bits within the character.
*/ */
static s8 budtab[256] = { static const s8 budtab[256] = {
3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
......
...@@ -243,7 +243,7 @@ struct dbmap { ...@@ -243,7 +243,7 @@ struct dbmap {
struct bmap { struct bmap {
struct dbmap db_bmap; /* on-disk aggregate map descriptor */ struct dbmap db_bmap; /* on-disk aggregate map descriptor */
struct inode *db_ipbmap; /* ptr to aggregate map incore inode */ struct inode *db_ipbmap; /* ptr to aggregate map incore inode */
struct semaphore db_bmaplock; /* aggregate map lock */ struct mutex db_bmaplock; /* aggregate map lock */
atomic_t db_active[MAXAG]; /* count of active, open files in AG */ atomic_t db_active[MAXAG]; /* count of active, open files in AG */
u32 *db_DBmap; u32 *db_DBmap;
}; };
......
...@@ -1005,6 +1005,9 @@ static int dtSplitUp(tid_t tid, ...@@ -1005,6 +1005,9 @@ static int dtSplitUp(tid_t tid,
DT_PUTPAGE(smp); DT_PUTPAGE(smp);
if (!DO_INDEX(ip))
ip->i_size = xlen << sbi->l2bsize;
goto freeKeyName; goto freeKeyName;
} }
...@@ -1055,7 +1058,9 @@ static int dtSplitUp(tid_t tid, ...@@ -1055,7 +1058,9 @@ static int dtSplitUp(tid_t tid,
xaddr = addressPXD(pxd) + xlen; xaddr = addressPXD(pxd) + xlen;
dbFree(ip, xaddr, (s64) n); dbFree(ip, xaddr, (s64) n);
} }
} } else if (!DO_INDEX(ip))
ip->i_size = lengthPXD(pxd) << sbi->l2bsize;
extendOut: extendOut:
DT_PUTPAGE(smp); DT_PUTPAGE(smp);
...@@ -1098,6 +1103,9 @@ static int dtSplitUp(tid_t tid, ...@@ -1098,6 +1103,9 @@ static int dtSplitUp(tid_t tid,
goto splitOut; goto splitOut;
} }
if (!DO_INDEX(ip))
ip->i_size += PSIZE;
/* /*
* propagate up the router entry for the leaf page just split * propagate up the router entry for the leaf page just split
* *
...@@ -2424,6 +2432,9 @@ static int dtDeleteUp(tid_t tid, struct inode *ip, ...@@ -2424,6 +2432,9 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
break; break;
} }
if (!DO_INDEX(ip))
ip->i_size -= PSIZE;
return 0; return 0;
} }
......
...@@ -94,7 +94,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) ...@@ -94,7 +94,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
txBeginAnon(ip->i_sb); txBeginAnon(ip->i_sb);
/* Avoid race with jfs_commit_inode() */ /* Avoid race with jfs_commit_inode() */
down(&JFS_IP(ip)->commit_sem); mutex_lock(&JFS_IP(ip)->commit_mutex);
/* validate extent length */ /* validate extent length */
if (xlen > MAXXLEN) if (xlen > MAXXLEN)
...@@ -136,14 +136,14 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) ...@@ -136,14 +136,14 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
*/ */
nxlen = xlen; nxlen = xlen;
if ((rc = extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) { if ((rc = extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) {
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
return (rc); return (rc);
} }
/* Allocate blocks to quota. */ /* Allocate blocks to quota. */
if (DQUOT_ALLOC_BLOCK(ip, nxlen)) { if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {
dbFree(ip, nxaddr, (s64) nxlen); dbFree(ip, nxaddr, (s64) nxlen);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
return -EDQUOT; return -EDQUOT;
} }
...@@ -165,7 +165,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) ...@@ -165,7 +165,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
if (rc) { if (rc) {
dbFree(ip, nxaddr, nxlen); dbFree(ip, nxaddr, nxlen);
DQUOT_FREE_BLOCK(ip, nxlen); DQUOT_FREE_BLOCK(ip, nxlen);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
return (rc); return (rc);
} }
...@@ -177,7 +177,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) ...@@ -177,7 +177,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
mark_inode_dirty(ip); mark_inode_dirty(ip);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
/* /*
* COMMIT_SyncList flags an anonymous tlock on page that is on * COMMIT_SyncList flags an anonymous tlock on page that is on
* sync list. * sync list.
...@@ -222,7 +222,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr) ...@@ -222,7 +222,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
/* This blocks if we are low on resources */ /* This blocks if we are low on resources */
txBeginAnon(ip->i_sb); txBeginAnon(ip->i_sb);
down(&JFS_IP(ip)->commit_sem); mutex_lock(&JFS_IP(ip)->commit_mutex);
/* validate extent length */ /* validate extent length */
if (nxlen > MAXXLEN) if (nxlen > MAXXLEN)
nxlen = MAXXLEN; nxlen = MAXXLEN;
...@@ -258,7 +258,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr) ...@@ -258,7 +258,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
/* Allocat blocks to quota. */ /* Allocat blocks to quota. */
if (DQUOT_ALLOC_BLOCK(ip, nxlen)) { if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {
dbFree(ip, nxaddr, (s64) nxlen); dbFree(ip, nxaddr, (s64) nxlen);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
return -EDQUOT; return -EDQUOT;
} }
...@@ -338,7 +338,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr) ...@@ -338,7 +338,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
mark_inode_dirty(ip); mark_inode_dirty(ip);
exit: exit:
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
return (rc); return (rc);
} }
#endif /* _NOTYET */ #endif /* _NOTYET */
...@@ -439,12 +439,12 @@ int extRecord(struct inode *ip, xad_t * xp) ...@@ -439,12 +439,12 @@ int extRecord(struct inode *ip, xad_t * xp)
txBeginAnon(ip->i_sb); txBeginAnon(ip->i_sb);
down(&JFS_IP(ip)->commit_sem); mutex_lock(&JFS_IP(ip)->commit_mutex);
/* update the extent */ /* update the extent */
rc = xtUpdate(0, ip, xp); rc = xtUpdate(0, ip, xp);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
return rc; return rc;
} }
......
...@@ -66,14 +66,14 @@ static HLIST_HEAD(aggregate_hash); ...@@ -66,14 +66,14 @@ static HLIST_HEAD(aggregate_hash);
* imap locks * imap locks
*/ */
/* iag free list lock */ /* iag free list lock */
#define IAGFREE_LOCK_INIT(imap) init_MUTEX(&imap->im_freelock) #define IAGFREE_LOCK_INIT(imap) mutex_init(&imap->im_freelock)
#define IAGFREE_LOCK(imap) down(&imap->im_freelock) #define IAGFREE_LOCK(imap) mutex_lock(&imap->im_freelock)
#define IAGFREE_UNLOCK(imap) up(&imap->im_freelock) #define IAGFREE_UNLOCK(imap) mutex_unlock(&imap->im_freelock)
/* per ag iag list locks */ /* per ag iag list locks */
#define AG_LOCK_INIT(imap,index) init_MUTEX(&(imap->im_aglock[index])) #define AG_LOCK_INIT(imap,index) mutex_init(&(imap->im_aglock[index]))
#define AG_LOCK(imap,agno) down(&imap->im_aglock[agno]) #define AG_LOCK(imap,agno) mutex_lock(&imap->im_aglock[agno])
#define AG_UNLOCK(imap,agno) up(&imap->im_aglock[agno]) #define AG_UNLOCK(imap,agno) mutex_unlock(&imap->im_aglock[agno])
/* /*
* forward references * forward references
...@@ -1261,7 +1261,7 @@ int diFree(struct inode *ip) ...@@ -1261,7 +1261,7 @@ int diFree(struct inode *ip)
* to be freed by the transaction; * to be freed by the transaction;
*/ */
tid = txBegin(ipimap->i_sb, COMMIT_FORCE); tid = txBegin(ipimap->i_sb, COMMIT_FORCE);
down(&JFS_IP(ipimap)->commit_sem); mutex_lock(&JFS_IP(ipimap)->commit_mutex);
/* acquire tlock of the iag page of the freed ixad /* acquire tlock of the iag page of the freed ixad
* to force the page NOHOMEOK (even though no data is * to force the page NOHOMEOK (even though no data is
...@@ -1294,7 +1294,7 @@ int diFree(struct inode *ip) ...@@ -1294,7 +1294,7 @@ int diFree(struct inode *ip)
rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE); rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
txEnd(tid); txEnd(tid);
up(&JFS_IP(ipimap)->commit_sem); mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
/* unlock the AG inode map information */ /* unlock the AG inode map information */
AG_UNLOCK(imap, agno); AG_UNLOCK(imap, agno);
...@@ -2554,13 +2554,13 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) ...@@ -2554,13 +2554,13 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
* addressing structure pointing to the new iag page; * addressing structure pointing to the new iag page;
*/ */
tid = txBegin(sb, COMMIT_FORCE); tid = txBegin(sb, COMMIT_FORCE);
down(&JFS_IP(ipimap)->commit_sem); mutex_lock(&JFS_IP(ipimap)->commit_mutex);
/* update the inode map addressing structure to point to it */ /* update the inode map addressing structure to point to it */
if ((rc = if ((rc =
xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) { xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
txEnd(tid); txEnd(tid);
up(&JFS_IP(ipimap)->commit_sem); mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
/* Free the blocks allocated for the iag since it was /* Free the blocks allocated for the iag since it was
* not successfully added to the inode map * not successfully added to the inode map
*/ */
...@@ -2626,7 +2626,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) ...@@ -2626,7 +2626,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE); rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
txEnd(tid); txEnd(tid);
up(&JFS_IP(ipimap)->commit_sem); mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
duplicateIXtree(sb, blkno, xlen, &xaddr); duplicateIXtree(sb, blkno, xlen, &xaddr);
...@@ -3074,14 +3074,40 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno, ...@@ -3074,14 +3074,40 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno,
static int copy_from_dinode(struct dinode * dip, struct inode *ip) static int copy_from_dinode(struct dinode * dip, struct inode *ip)
{ {
struct jfs_inode_info *jfs_ip = JFS_IP(ip); struct jfs_inode_info *jfs_ip = JFS_IP(ip);
struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
jfs_ip->fileset = le32_to_cpu(dip->di_fileset); jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
jfs_ip->mode2 = le32_to_cpu(dip->di_mode); jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff; ip->i_mode = le32_to_cpu(dip->di_mode) & 0xffff;
if (sbi->umask != -1) {
ip->i_mode = (ip->i_mode & ~0777) | (0777 & ~sbi->umask);
/* For directories, add x permission if r is allowed by umask */
if (S_ISDIR(ip->i_mode)) {
if (ip->i_mode & 0400)
ip->i_mode |= 0100;
if (ip->i_mode & 0040)
ip->i_mode |= 0010;
if (ip->i_mode & 0004)
ip->i_mode |= 0001;
}
}
ip->i_nlink = le32_to_cpu(dip->di_nlink); ip->i_nlink = le32_to_cpu(dip->di_nlink);
ip->i_uid = le32_to_cpu(dip->di_uid);
ip->i_gid = le32_to_cpu(dip->di_gid); jfs_ip->saved_uid = le32_to_cpu(dip->di_uid);
if (sbi->uid == -1)
ip->i_uid = jfs_ip->saved_uid;
else {
ip->i_uid = sbi->uid;
}
jfs_ip->saved_gid = le32_to_cpu(dip->di_gid);
if (sbi->gid == -1)
ip->i_gid = jfs_ip->saved_gid;
else {
ip->i_gid = sbi->gid;
}
ip->i_size = le64_to_cpu(dip->di_size); ip->i_size = le64_to_cpu(dip->di_size);
ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec); ip->i_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec);
ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec); ip->i_atime.tv_nsec = le32_to_cpu(dip->di_atime.tv_nsec);
...@@ -3132,21 +3158,33 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip) ...@@ -3132,21 +3158,33 @@ static int copy_from_dinode(struct dinode * dip, struct inode *ip)
static void copy_to_dinode(struct dinode * dip, struct inode *ip) static void copy_to_dinode(struct dinode * dip, struct inode *ip)
{ {
struct jfs_inode_info *jfs_ip = JFS_IP(ip); struct jfs_inode_info *jfs_ip = JFS_IP(ip);
struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
dip->di_fileset = cpu_to_le32(jfs_ip->fileset); dip->di_fileset = cpu_to_le32(jfs_ip->fileset);
dip->di_inostamp = cpu_to_le32(JFS_SBI(ip->i_sb)->inostamp); dip->di_inostamp = cpu_to_le32(sbi->inostamp);
dip->di_number = cpu_to_le32(ip->i_ino); dip->di_number = cpu_to_le32(ip->i_ino);
dip->di_gen = cpu_to_le32(ip->i_generation); dip->di_gen = cpu_to_le32(ip->i_generation);
dip->di_size = cpu_to_le64(ip->i_size); dip->di_size = cpu_to_le64(ip->i_size);
dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks)); dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
dip->di_nlink = cpu_to_le32(ip->i_nlink); dip->di_nlink = cpu_to_le32(ip->i_nlink);
dip->di_uid = cpu_to_le32(ip->i_uid); if (sbi->uid == -1)
dip->di_gid = cpu_to_le32(ip->i_gid); dip->di_uid = cpu_to_le32(ip->i_uid);
else
dip->di_uid = cpu_to_le32(jfs_ip->saved_uid);
if (sbi->gid == -1)
dip->di_gid = cpu_to_le32(ip->i_gid);
else
dip->di_gid = cpu_to_le32(jfs_ip->saved_gid);
/* /*
* mode2 is only needed for storing the higher order bits. * mode2 is only needed for storing the higher order bits.
* Trust i_mode for the lower order ones * Trust i_mode for the lower order ones
*/ */
dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) | ip->i_mode); if (sbi->umask == -1)
dip->di_mode = cpu_to_le32((jfs_ip->mode2 & 0xffff0000) |
ip->i_mode);
else /* Leave the original permissions alone */
dip->di_mode = cpu_to_le32(jfs_ip->mode2);
dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime.tv_sec); dip->di_atime.tv_sec = cpu_to_le32(ip->i_atime.tv_sec);
dip->di_atime.tv_nsec = cpu_to_le32(ip->i_atime.tv_nsec); dip->di_atime.tv_nsec = cpu_to_le32(ip->i_atime.tv_nsec);
dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime.tv_sec); dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime.tv_sec);
......
...@@ -140,8 +140,8 @@ struct dinomap { ...@@ -140,8 +140,8 @@ struct dinomap {
struct inomap { struct inomap {
struct dinomap im_imap; /* 4096: inode allocation control */ struct dinomap im_imap; /* 4096: inode allocation control */
struct inode *im_ipimap; /* 4: ptr to inode for imap */ struct inode *im_ipimap; /* 4: ptr to inode for imap */
struct semaphore im_freelock; /* 4: iag free list lock */ struct mutex im_freelock; /* 4: iag free list lock */
struct semaphore im_aglock[MAXAG]; /* 512: per AG locks */ struct mutex im_aglock[MAXAG]; /* 512: per AG locks */
u32 *im_DBGdimap; u32 *im_DBGdimap;
atomic_t im_numinos; /* num of backed inodes */ atomic_t im_numinos; /* num of backed inodes */
atomic_t im_numfree; /* num of free backed inodes */ atomic_t im_numfree; /* num of free backed inodes */
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#ifndef _H_JFS_INCORE #ifndef _H_JFS_INCORE
#define _H_JFS_INCORE #define _H_JFS_INCORE
#include <linux/mutex.h>
#include <linux/rwsem.h> #include <linux/rwsem.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/bitops.h> #include <linux/bitops.h>
...@@ -37,6 +38,8 @@ ...@@ -37,6 +38,8 @@
struct jfs_inode_info { struct jfs_inode_info {
int fileset; /* fileset number (always 16)*/ int fileset; /* fileset number (always 16)*/
uint mode2; /* jfs-specific mode */ uint mode2; /* jfs-specific mode */
uint saved_uid; /* saved for uid mount option */
uint saved_gid; /* saved for gid mount option */
pxd_t ixpxd; /* inode extent descriptor */ pxd_t ixpxd; /* inode extent descriptor */
dxd_t acl; /* dxd describing acl */ dxd_t acl; /* dxd describing acl */
dxd_t ea; /* dxd describing ea */ dxd_t ea; /* dxd describing ea */
...@@ -62,12 +65,12 @@ struct jfs_inode_info { ...@@ -62,12 +65,12 @@ struct jfs_inode_info {
*/ */
struct rw_semaphore rdwrlock; struct rw_semaphore rdwrlock;
/* /*
* commit_sem serializes transaction processing on an inode. * commit_mutex serializes transaction processing on an inode.
* It must be taken after beginning a transaction (txBegin), since * It must be taken after beginning a transaction (txBegin), since
* dirty inodes may be committed while a new transaction on the * dirty inodes may be committed while a new transaction on the
* inode is blocked in txBegin or TxBeginAnon * inode is blocked in txBegin or TxBeginAnon
*/ */
struct semaphore commit_sem; struct mutex commit_mutex;
/* xattr_sem allows us to access the xattrs without taking i_mutex */ /* xattr_sem allows us to access the xattrs without taking i_mutex */
struct rw_semaphore xattr_sem; struct rw_semaphore xattr_sem;
lid_t xtlid; /* lid of xtree lock on directory */ lid_t xtlid; /* lid of xtree lock on directory */
...@@ -169,6 +172,9 @@ struct jfs_sb_info { ...@@ -169,6 +172,9 @@ struct jfs_sb_info {
uint state; /* mount/recovery state */ uint state; /* mount/recovery state */
unsigned long flag; /* mount time flags */ unsigned long flag; /* mount time flags */
uint p_state; /* state prior to going no integrity */ uint p_state; /* state prior to going no integrity */
uint uid; /* uid to override on-disk uid */
uint gid; /* gid to override on-disk gid */
uint umask; /* umask to override on-disk umask */
}; };
/* jfs_sb_info commit_state */ /* jfs_sb_info commit_state */
......
...@@ -25,6 +25,26 @@ ...@@ -25,6 +25,26 @@
#include "jfs_dinode.h" #include "jfs_dinode.h"
#include "jfs_debug.h" #include "jfs_debug.h"
void jfs_set_inode_flags(struct inode *inode)
{
unsigned int flags = JFS_IP(inode)->mode2;
inode->i_flags &= ~(S_IMMUTABLE | S_APPEND |
S_NOATIME | S_DIRSYNC | S_SYNC);
if (flags & JFS_IMMUTABLE_FL)
inode->i_flags |= S_IMMUTABLE;
if (flags & JFS_APPEND_FL)
inode->i_flags |= S_APPEND;
if (flags & JFS_NOATIME_FL)
inode->i_flags |= S_NOATIME;
if (flags & JFS_DIRSYNC_FL)
inode->i_flags |= S_DIRSYNC;
if (flags & JFS_SYNC_FL)
inode->i_flags |= S_SYNC;
}
/* /*
* NAME: ialloc() * NAME: ialloc()
* *
...@@ -62,6 +82,13 @@ struct inode *ialloc(struct inode *parent, umode_t mode) ...@@ -62,6 +82,13 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
} else } else
inode->i_gid = current->fsgid; inode->i_gid = current->fsgid;
/*
* New inodes need to save sane values on disk when
* uid & gid mount options are used
*/
jfs_inode->saved_uid = inode->i_uid;
jfs_inode->saved_gid = inode->i_gid;
/* /*
* Allocate inode to quota. * Allocate inode to quota.
*/ */
...@@ -74,10 +101,20 @@ struct inode *ialloc(struct inode *parent, umode_t mode) ...@@ -74,10 +101,20 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
} }
inode->i_mode = mode; inode->i_mode = mode;
if (S_ISDIR(mode)) /* inherit flags from parent */
jfs_inode->mode2 = IDIRECTORY | mode; jfs_inode->mode2 = JFS_IP(parent)->mode2 & JFS_FL_INHERIT;
else
jfs_inode->mode2 = INLINEEA | ISPARSE | mode; if (S_ISDIR(mode)) {
jfs_inode->mode2 |= IDIRECTORY;
jfs_inode->mode2 &= ~JFS_DIRSYNC_FL;
}
else {
jfs_inode->mode2 |= INLINEEA | ISPARSE;
if (S_ISLNK(mode))
jfs_inode->mode2 &= ~(JFS_IMMUTABLE_FL|JFS_APPEND_FL);
}
jfs_inode->mode2 |= mode;
inode->i_blksize = sb->s_blocksize; inode->i_blksize = sb->s_blocksize;
inode->i_blocks = 0; inode->i_blocks = 0;
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
...@@ -98,6 +135,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode) ...@@ -98,6 +135,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
jfs_inode->atlhead = 0; jfs_inode->atlhead = 0;
jfs_inode->atltail = 0; jfs_inode->atltail = 0;
jfs_inode->xtlid = 0; jfs_inode->xtlid = 0;
jfs_set_inode_flags(inode);
jfs_info("ialloc returns inode = 0x%p\n", inode); jfs_info("ialloc returns inode = 0x%p\n", inode);
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
extern struct inode *ialloc(struct inode *, umode_t); extern struct inode *ialloc(struct inode *, umode_t);
extern int jfs_fsync(struct file *, struct dentry *, int); extern int jfs_fsync(struct file *, struct dentry *, int);
extern int jfs_ioctl(struct inode *, struct file *,
unsigned int, unsigned long);
extern void jfs_read_inode(struct inode *); extern void jfs_read_inode(struct inode *);
extern int jfs_commit_inode(struct inode *, int); extern int jfs_commit_inode(struct inode *, int);
extern int jfs_write_inode(struct inode*, int); extern int jfs_write_inode(struct inode*, int);
...@@ -29,6 +31,7 @@ extern void jfs_truncate(struct inode *); ...@@ -29,6 +31,7 @@ extern void jfs_truncate(struct inode *);
extern void jfs_truncate_nolock(struct inode *, loff_t); extern void jfs_truncate_nolock(struct inode *, loff_t);
extern void jfs_free_zero_link(struct inode *); extern void jfs_free_zero_link(struct inode *);
extern struct dentry *jfs_get_parent(struct dentry *dentry); extern struct dentry *jfs_get_parent(struct dentry *dentry);
extern void jfs_set_inode_flags(struct inode *);
extern struct address_space_operations jfs_aops; extern struct address_space_operations jfs_aops;
extern struct inode_operations jfs_dir_inode_operations; extern struct inode_operations jfs_dir_inode_operations;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#define _H_JFS_LOCK #define _H_JFS_LOCK
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/sched.h> #include <linux/sched.h>
/* /*
......
...@@ -64,6 +64,7 @@ ...@@ -64,6 +64,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/kthread.h>
#include <linux/buffer_head.h> /* for sync_blockdev() */ #include <linux/buffer_head.h> /* for sync_blockdev() */
#include <linux/bio.h> #include <linux/bio.h>
#include <linux/suspend.h> #include <linux/suspend.h>
...@@ -81,15 +82,14 @@ ...@@ -81,15 +82,14 @@
*/ */
static struct lbuf *log_redrive_list; static struct lbuf *log_redrive_list;
static DEFINE_SPINLOCK(log_redrive_lock); static DEFINE_SPINLOCK(log_redrive_lock);
DECLARE_WAIT_QUEUE_HEAD(jfs_IO_thread_wait);
/* /*
* log read/write serialization (per log) * log read/write serialization (per log)
*/ */
#define LOG_LOCK_INIT(log) init_MUTEX(&(log)->loglock) #define LOG_LOCK_INIT(log) mutex_init(&(log)->loglock)
#define LOG_LOCK(log) down(&((log)->loglock)) #define LOG_LOCK(log) mutex_lock(&((log)->loglock))
#define LOG_UNLOCK(log) up(&((log)->loglock)) #define LOG_UNLOCK(log) mutex_unlock(&((log)->loglock))
/* /*
...@@ -1105,11 +1105,10 @@ int lmLogOpen(struct super_block *sb) ...@@ -1105,11 +1105,10 @@ int lmLogOpen(struct super_block *sb)
} }
} }
if (!(log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL))) { if (!(log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL))) {
up(&jfs_log_sem); up(&jfs_log_sem);
return -ENOMEM; return -ENOMEM;
} }
memset(log, 0, sizeof(struct jfs_log));
INIT_LIST_HEAD(&log->sb_list); INIT_LIST_HEAD(&log->sb_list);
init_waitqueue_head(&log->syncwait); init_waitqueue_head(&log->syncwait);
...@@ -1181,9 +1180,8 @@ static int open_inline_log(struct super_block *sb) ...@@ -1181,9 +1180,8 @@ static int open_inline_log(struct super_block *sb)
struct jfs_log *log; struct jfs_log *log;
int rc; int rc;
if (!(log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL))) if (!(log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
memset(log, 0, sizeof(struct jfs_log));
INIT_LIST_HEAD(&log->sb_list); INIT_LIST_HEAD(&log->sb_list);
init_waitqueue_head(&log->syncwait); init_waitqueue_head(&log->syncwait);
...@@ -1216,12 +1214,11 @@ static int open_dummy_log(struct super_block *sb) ...@@ -1216,12 +1214,11 @@ static int open_dummy_log(struct super_block *sb)
down(&jfs_log_sem); down(&jfs_log_sem);
if (!dummy_log) { if (!dummy_log) {
dummy_log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL); dummy_log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL);
if (!dummy_log) { if (!dummy_log) {
up(&jfs_log_sem); up(&jfs_log_sem);
return -ENOMEM; return -ENOMEM;
} }
memset(dummy_log, 0, sizeof(struct jfs_log));
INIT_LIST_HEAD(&dummy_log->sb_list); INIT_LIST_HEAD(&dummy_log->sb_list);
init_waitqueue_head(&dummy_log->syncwait); init_waitqueue_head(&dummy_log->syncwait);
dummy_log->no_integrity = 1; dummy_log->no_integrity = 1;
...@@ -1980,7 +1977,7 @@ static inline void lbmRedrive(struct lbuf *bp) ...@@ -1980,7 +1977,7 @@ static inline void lbmRedrive(struct lbuf *bp)
log_redrive_list = bp; log_redrive_list = bp;
spin_unlock_irqrestore(&log_redrive_lock, flags); spin_unlock_irqrestore(&log_redrive_lock, flags);
wake_up(&jfs_IO_thread_wait); wake_up_process(jfsIOthread);
} }
...@@ -2347,13 +2344,7 @@ int jfsIOWait(void *arg) ...@@ -2347,13 +2344,7 @@ int jfsIOWait(void *arg)
{ {
struct lbuf *bp; struct lbuf *bp;
daemonize("jfsIO");
complete(&jfsIOwait);
do { do {
DECLARE_WAITQUEUE(wq, current);
spin_lock_irq(&log_redrive_lock); spin_lock_irq(&log_redrive_lock);
while ((bp = log_redrive_list) != 0) { while ((bp = log_redrive_list) != 0) {
log_redrive_list = bp->l_redrive_next; log_redrive_list = bp->l_redrive_next;
...@@ -2362,21 +2353,19 @@ int jfsIOWait(void *arg) ...@@ -2362,21 +2353,19 @@ int jfsIOWait(void *arg)
lbmStartIO(bp); lbmStartIO(bp);
spin_lock_irq(&log_redrive_lock); spin_lock_irq(&log_redrive_lock);
} }
spin_unlock_irq(&log_redrive_lock);
if (freezing(current)) { if (freezing(current)) {
spin_unlock_irq(&log_redrive_lock);
refrigerator(); refrigerator();
} else { } else {
add_wait_queue(&jfs_IO_thread_wait, &wq);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
spin_unlock_irq(&log_redrive_lock);
schedule(); schedule();
current->state = TASK_RUNNING; current->state = TASK_RUNNING;
remove_wait_queue(&jfs_IO_thread_wait, &wq);
} }
} while (!jfs_stop_threads); } while (!kthread_should_stop());
jfs_info("jfsIOWait being killed!"); jfs_info("jfsIOWait being killed!");
complete_and_exit(&jfsIOwait, 0); return 0;
} }
/* /*
......
...@@ -389,7 +389,7 @@ struct jfs_log { ...@@ -389,7 +389,7 @@ struct jfs_log {
int eor; /* 4: eor of last record in eol page */ int eor; /* 4: eor of last record in eol page */
struct lbuf *bp; /* 4: current log page buffer */ struct lbuf *bp; /* 4: current log page buffer */
struct semaphore loglock; /* 4: log write serialization lock */ struct mutex loglock; /* 4: log write serialization lock */
/* syncpt */ /* syncpt */
int nextsync; /* 4: bytes to write before next syncpt */ int nextsync; /* 4: bytes to write before next syncpt */
......
...@@ -104,10 +104,9 @@ static inline int insert_metapage(struct page *page, struct metapage *mp) ...@@ -104,10 +104,9 @@ static inline int insert_metapage(struct page *page, struct metapage *mp)
if (PagePrivate(page)) if (PagePrivate(page))
a = mp_anchor(page); a = mp_anchor(page);
else { else {
a = kmalloc(sizeof(struct meta_anchor), GFP_NOFS); a = kzalloc(sizeof(struct meta_anchor), GFP_NOFS);
if (!a) if (!a)
return -ENOMEM; return -ENOMEM;
memset(a, 0, sizeof(struct meta_anchor));
set_page_private(page, (unsigned long)a); set_page_private(page, (unsigned long)a);
SetPagePrivate(page); SetPagePrivate(page);
kmap(page); kmap(page);
......
...@@ -113,12 +113,9 @@ extern int jfs_mount(struct super_block *); ...@@ -113,12 +113,9 @@ extern int jfs_mount(struct super_block *);
extern int jfs_mount_rw(struct super_block *, int); extern int jfs_mount_rw(struct super_block *, int);
extern int jfs_umount(struct super_block *); extern int jfs_umount(struct super_block *);
extern int jfs_umount_rw(struct super_block *); extern int jfs_umount_rw(struct super_block *);
extern int jfs_stop_threads;
extern struct completion jfsIOwait;
extern wait_queue_head_t jfs_IO_thread_wait;
extern wait_queue_head_t jfs_commit_thread_wait;
extern wait_queue_head_t jfs_sync_thread_wait;
extern int jfs_extendfs(struct super_block *, s64, int); extern int jfs_extendfs(struct super_block *, s64, int);
extern struct task_struct *jfsIOthread;
extern struct task_struct *jfsSyncThread;
#endif /*_H_JFS_SUPERBLOCK */ #endif /*_H_JFS_SUPERBLOCK */
...@@ -49,6 +49,7 @@ ...@@ -49,6 +49,7 @@
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/kthread.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_inode.h" #include "jfs_inode.h"
#include "jfs_filsys.h" #include "jfs_filsys.h"
...@@ -121,8 +122,7 @@ static DEFINE_SPINLOCK(jfsTxnLock); ...@@ -121,8 +122,7 @@ static DEFINE_SPINLOCK(jfsTxnLock);
#define LAZY_LOCK(flags) spin_lock_irqsave(&TxAnchor.LazyLock, flags) #define LAZY_LOCK(flags) spin_lock_irqsave(&TxAnchor.LazyLock, flags)
#define LAZY_UNLOCK(flags) spin_unlock_irqrestore(&TxAnchor.LazyLock, flags) #define LAZY_UNLOCK(flags) spin_unlock_irqrestore(&TxAnchor.LazyLock, flags)
DECLARE_WAIT_QUEUE_HEAD(jfs_sync_thread_wait); static DECLARE_WAIT_QUEUE_HEAD(jfs_commit_thread_wait);
DECLARE_WAIT_QUEUE_HEAD(jfs_commit_thread_wait);
static int jfs_commit_thread_waking; static int jfs_commit_thread_waking;
/* /*
...@@ -207,7 +207,7 @@ static lid_t txLockAlloc(void) ...@@ -207,7 +207,7 @@ static lid_t txLockAlloc(void)
if ((++TxAnchor.tlocksInUse > TxLockHWM) && (jfs_tlocks_low == 0)) { if ((++TxAnchor.tlocksInUse > TxLockHWM) && (jfs_tlocks_low == 0)) {
jfs_info("txLockAlloc tlocks low"); jfs_info("txLockAlloc tlocks low");
jfs_tlocks_low = 1; jfs_tlocks_low = 1;
wake_up(&jfs_sync_thread_wait); wake_up_process(jfsSyncThread);
} }
return lid; return lid;
...@@ -2743,10 +2743,6 @@ int jfs_lazycommit(void *arg) ...@@ -2743,10 +2743,6 @@ int jfs_lazycommit(void *arg)
unsigned long flags; unsigned long flags;
struct jfs_sb_info *sbi; struct jfs_sb_info *sbi;
daemonize("jfsCommit");
complete(&jfsIOwait);
do { do {
LAZY_LOCK(flags); LAZY_LOCK(flags);
jfs_commit_thread_waking = 0; /* OK to wake another thread */ jfs_commit_thread_waking = 0; /* OK to wake another thread */
...@@ -2806,13 +2802,13 @@ int jfs_lazycommit(void *arg) ...@@ -2806,13 +2802,13 @@ int jfs_lazycommit(void *arg)
current->state = TASK_RUNNING; current->state = TASK_RUNNING;
remove_wait_queue(&jfs_commit_thread_wait, &wq); remove_wait_queue(&jfs_commit_thread_wait, &wq);
} }
} while (!jfs_stop_threads); } while (!kthread_should_stop());
if (!list_empty(&TxAnchor.unlock_queue)) if (!list_empty(&TxAnchor.unlock_queue))
jfs_err("jfs_lazycommit being killed w/pending transactions!"); jfs_err("jfs_lazycommit being killed w/pending transactions!");
else else
jfs_info("jfs_lazycommit being killed\n"); jfs_info("jfs_lazycommit being killed\n");
complete_and_exit(&jfsIOwait, 0); return 0;
} }
void txLazyUnlock(struct tblock * tblk) void txLazyUnlock(struct tblock * tblk)
...@@ -2876,10 +2872,10 @@ void txQuiesce(struct super_block *sb) ...@@ -2876,10 +2872,10 @@ void txQuiesce(struct super_block *sb)
*/ */
TXN_UNLOCK(); TXN_UNLOCK();
tid = txBegin(ip->i_sb, COMMIT_INODE | COMMIT_FORCE); tid = txBegin(ip->i_sb, COMMIT_INODE | COMMIT_FORCE);
down(&jfs_ip->commit_sem); mutex_lock(&jfs_ip->commit_mutex);
txCommit(tid, 1, &ip, 0); txCommit(tid, 1, &ip, 0);
txEnd(tid); txEnd(tid);
up(&jfs_ip->commit_sem); mutex_unlock(&jfs_ip->commit_mutex);
/* /*
* Just to be safe. I don't know how * Just to be safe. I don't know how
* long we can run without blocking * long we can run without blocking
...@@ -2932,10 +2928,6 @@ int jfs_sync(void *arg) ...@@ -2932,10 +2928,6 @@ int jfs_sync(void *arg)
int rc; int rc;
tid_t tid; tid_t tid;
daemonize("jfsSync");
complete(&jfsIOwait);
do { do {
/* /*
* write each inode on the anonymous inode list * write each inode on the anonymous inode list
...@@ -2952,7 +2944,7 @@ int jfs_sync(void *arg) ...@@ -2952,7 +2944,7 @@ int jfs_sync(void *arg)
* Inode is being freed * Inode is being freed
*/ */
list_del_init(&jfs_ip->anon_inode_list); list_del_init(&jfs_ip->anon_inode_list);
} else if (! down_trylock(&jfs_ip->commit_sem)) { } else if (! !mutex_trylock(&jfs_ip->commit_mutex)) {
/* /*
* inode will be removed from anonymous list * inode will be removed from anonymous list
* when it is committed * when it is committed
...@@ -2961,7 +2953,7 @@ int jfs_sync(void *arg) ...@@ -2961,7 +2953,7 @@ int jfs_sync(void *arg)
tid = txBegin(ip->i_sb, COMMIT_INODE); tid = txBegin(ip->i_sb, COMMIT_INODE);
rc = txCommit(tid, 1, &ip, 0); rc = txCommit(tid, 1, &ip, 0);
txEnd(tid); txEnd(tid);
up(&jfs_ip->commit_sem); mutex_unlock(&jfs_ip->commit_mutex);
iput(ip); iput(ip);
/* /*
...@@ -2971,7 +2963,7 @@ int jfs_sync(void *arg) ...@@ -2971,7 +2963,7 @@ int jfs_sync(void *arg)
cond_resched(); cond_resched();
TXN_LOCK(); TXN_LOCK();
} else { } else {
/* We can't get the commit semaphore. It may /* We can't get the commit mutex. It may
* be held by a thread waiting for tlock's * be held by a thread waiting for tlock's
* so let's not block here. Save it to * so let's not block here. Save it to
* put back on the anon_list. * put back on the anon_list.
...@@ -2996,19 +2988,15 @@ int jfs_sync(void *arg) ...@@ -2996,19 +2988,15 @@ int jfs_sync(void *arg)
TXN_UNLOCK(); TXN_UNLOCK();
refrigerator(); refrigerator();
} else { } else {
DECLARE_WAITQUEUE(wq, current);
add_wait_queue(&jfs_sync_thread_wait, &wq);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
TXN_UNLOCK(); TXN_UNLOCK();
schedule(); schedule();
current->state = TASK_RUNNING; current->state = TASK_RUNNING;
remove_wait_queue(&jfs_sync_thread_wait, &wq);
} }
} while (!jfs_stop_threads); } while (!kthread_should_stop());
jfs_info("jfs_sync being killed"); jfs_info("jfs_sync being killed");
complete_and_exit(&jfsIOwait, 0); return 0;
} }
#if defined(CONFIG_PROC_FS) && defined(CONFIG_JFS_DEBUG) #if defined(CONFIG_PROC_FS) && defined(CONFIG_JFS_DEBUG)
......
...@@ -104,8 +104,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, ...@@ -104,8 +104,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
tid = txBegin(dip->i_sb, 0); tid = txBegin(dip->i_sb, 0);
down(&JFS_IP(dip)->commit_sem); mutex_lock(&JFS_IP(dip)->commit_mutex);
down(&JFS_IP(ip)->commit_sem); mutex_lock(&JFS_IP(ip)->commit_mutex);
rc = jfs_init_acl(tid, ip, dip); rc = jfs_init_acl(tid, ip, dip);
if (rc) if (rc)
...@@ -165,8 +165,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, ...@@ -165,8 +165,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
out3: out3:
txEnd(tid); txEnd(tid);
up(&JFS_IP(dip)->commit_sem); mutex_unlock(&JFS_IP(dip)->commit_mutex);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
if (rc) { if (rc) {
free_ea_wmap(ip); free_ea_wmap(ip);
ip->i_nlink = 0; ip->i_nlink = 0;
...@@ -238,8 +238,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) ...@@ -238,8 +238,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
tid = txBegin(dip->i_sb, 0); tid = txBegin(dip->i_sb, 0);
down(&JFS_IP(dip)->commit_sem); mutex_lock(&JFS_IP(dip)->commit_mutex);
down(&JFS_IP(ip)->commit_sem); mutex_lock(&JFS_IP(ip)->commit_mutex);
rc = jfs_init_acl(tid, ip, dip); rc = jfs_init_acl(tid, ip, dip);
if (rc) if (rc)
...@@ -300,8 +300,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) ...@@ -300,8 +300,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
out3: out3:
txEnd(tid); txEnd(tid);
up(&JFS_IP(dip)->commit_sem); mutex_unlock(&JFS_IP(dip)->commit_mutex);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
if (rc) { if (rc) {
free_ea_wmap(ip); free_ea_wmap(ip);
ip->i_nlink = 0; ip->i_nlink = 0;
...@@ -365,8 +365,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) ...@@ -365,8 +365,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
tid = txBegin(dip->i_sb, 0); tid = txBegin(dip->i_sb, 0);
down(&JFS_IP(dip)->commit_sem); mutex_lock(&JFS_IP(dip)->commit_mutex);
down(&JFS_IP(ip)->commit_sem); mutex_lock(&JFS_IP(ip)->commit_mutex);
iplist[0] = dip; iplist[0] = dip;
iplist[1] = ip; iplist[1] = ip;
...@@ -384,8 +384,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) ...@@ -384,8 +384,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
if (rc == -EIO) if (rc == -EIO)
txAbort(tid, 1); txAbort(tid, 1);
txEnd(tid); txEnd(tid);
up(&JFS_IP(dip)->commit_sem); mutex_unlock(&JFS_IP(dip)->commit_mutex);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
goto out2; goto out2;
} }
...@@ -422,8 +422,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) ...@@ -422,8 +422,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
txEnd(tid); txEnd(tid);
up(&JFS_IP(dip)->commit_sem); mutex_unlock(&JFS_IP(dip)->commit_mutex);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
/* /*
* Truncating the directory index table is not guaranteed. It * Truncating the directory index table is not guaranteed. It
...@@ -488,8 +488,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) ...@@ -488,8 +488,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
tid = txBegin(dip->i_sb, 0); tid = txBegin(dip->i_sb, 0);
down(&JFS_IP(dip)->commit_sem); mutex_lock(&JFS_IP(dip)->commit_mutex);
down(&JFS_IP(ip)->commit_sem); mutex_lock(&JFS_IP(ip)->commit_mutex);
iplist[0] = dip; iplist[0] = dip;
iplist[1] = ip; iplist[1] = ip;
...@@ -503,8 +503,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) ...@@ -503,8 +503,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
if (rc == -EIO) if (rc == -EIO)
txAbort(tid, 1); /* Marks FS Dirty */ txAbort(tid, 1); /* Marks FS Dirty */
txEnd(tid); txEnd(tid);
up(&JFS_IP(dip)->commit_sem); mutex_unlock(&JFS_IP(dip)->commit_mutex);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
IWRITE_UNLOCK(ip); IWRITE_UNLOCK(ip);
goto out1; goto out1;
} }
...@@ -527,8 +527,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) ...@@ -527,8 +527,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
if ((new_size = commitZeroLink(tid, ip)) < 0) { if ((new_size = commitZeroLink(tid, ip)) < 0) {
txAbort(tid, 1); /* Marks FS Dirty */ txAbort(tid, 1); /* Marks FS Dirty */
txEnd(tid); txEnd(tid);
up(&JFS_IP(dip)->commit_sem); mutex_unlock(&JFS_IP(dip)->commit_mutex);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
IWRITE_UNLOCK(ip); IWRITE_UNLOCK(ip);
rc = new_size; rc = new_size;
goto out1; goto out1;
...@@ -556,13 +556,13 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) ...@@ -556,13 +556,13 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
txEnd(tid); txEnd(tid);
up(&JFS_IP(dip)->commit_sem); mutex_unlock(&JFS_IP(dip)->commit_mutex);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
while (new_size && (rc == 0)) { while (new_size && (rc == 0)) {
tid = txBegin(dip->i_sb, 0); tid = txBegin(dip->i_sb, 0);
down(&JFS_IP(ip)->commit_sem); mutex_lock(&JFS_IP(ip)->commit_mutex);
new_size = xtTruncate_pmap(tid, ip, new_size); new_size = xtTruncate_pmap(tid, ip, new_size);
if (new_size < 0) { if (new_size < 0) {
txAbort(tid, 1); /* Marks FS Dirty */ txAbort(tid, 1); /* Marks FS Dirty */
...@@ -570,7 +570,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) ...@@ -570,7 +570,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
} else } else
rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC); rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC);
txEnd(tid); txEnd(tid);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
} }
if (ip->i_nlink == 0) if (ip->i_nlink == 0)
...@@ -805,8 +805,8 @@ static int jfs_link(struct dentry *old_dentry, ...@@ -805,8 +805,8 @@ static int jfs_link(struct dentry *old_dentry,
tid = txBegin(ip->i_sb, 0); tid = txBegin(ip->i_sb, 0);
down(&JFS_IP(dir)->commit_sem); mutex_lock(&JFS_IP(dir)->commit_mutex);
down(&JFS_IP(ip)->commit_sem); mutex_lock(&JFS_IP(ip)->commit_mutex);
/* /*
* scan parent directory for entry/freespace * scan parent directory for entry/freespace
...@@ -847,8 +847,8 @@ static int jfs_link(struct dentry *old_dentry, ...@@ -847,8 +847,8 @@ static int jfs_link(struct dentry *old_dentry,
out: out:
txEnd(tid); txEnd(tid);
up(&JFS_IP(dir)->commit_sem); mutex_unlock(&JFS_IP(dir)->commit_mutex);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
jfs_info("jfs_link: rc:%d", rc); jfs_info("jfs_link: rc:%d", rc);
return rc; return rc;
...@@ -916,8 +916,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, ...@@ -916,8 +916,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
tid = txBegin(dip->i_sb, 0); tid = txBegin(dip->i_sb, 0);
down(&JFS_IP(dip)->commit_sem); mutex_lock(&JFS_IP(dip)->commit_mutex);
down(&JFS_IP(ip)->commit_sem); mutex_lock(&JFS_IP(ip)->commit_mutex);
rc = jfs_init_security(tid, ip, dip); rc = jfs_init_security(tid, ip, dip);
if (rc) if (rc)
...@@ -1037,8 +1037,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, ...@@ -1037,8 +1037,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
out3: out3:
txEnd(tid); txEnd(tid);
up(&JFS_IP(dip)->commit_sem); mutex_unlock(&JFS_IP(dip)->commit_mutex);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
if (rc) { if (rc) {
free_ea_wmap(ip); free_ea_wmap(ip);
ip->i_nlink = 0; ip->i_nlink = 0;
...@@ -1141,13 +1141,13 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1141,13 +1141,13 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
*/ */
tid = txBegin(new_dir->i_sb, 0); tid = txBegin(new_dir->i_sb, 0);
down(&JFS_IP(new_dir)->commit_sem); mutex_lock(&JFS_IP(new_dir)->commit_mutex);
down(&JFS_IP(old_ip)->commit_sem); mutex_lock(&JFS_IP(old_ip)->commit_mutex);
if (old_dir != new_dir) if (old_dir != new_dir)
down(&JFS_IP(old_dir)->commit_sem); mutex_lock(&JFS_IP(old_dir)->commit_mutex);
if (new_ip) { if (new_ip) {
down(&JFS_IP(new_ip)->commit_sem); mutex_lock(&JFS_IP(new_ip)->commit_mutex);
/* /*
* Change existing directory entry to new inode number * Change existing directory entry to new inode number
*/ */
...@@ -1160,10 +1160,10 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1160,10 +1160,10 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (S_ISDIR(new_ip->i_mode)) { if (S_ISDIR(new_ip->i_mode)) {
new_ip->i_nlink--; new_ip->i_nlink--;
if (new_ip->i_nlink) { if (new_ip->i_nlink) {
up(&JFS_IP(new_dir)->commit_sem); mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
up(&JFS_IP(old_ip)->commit_sem); mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
if (old_dir != new_dir) if (old_dir != new_dir)
up(&JFS_IP(old_dir)->commit_sem); mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
if (!S_ISDIR(old_ip->i_mode) && new_ip) if (!S_ISDIR(old_ip->i_mode) && new_ip)
IWRITE_UNLOCK(new_ip); IWRITE_UNLOCK(new_ip);
jfs_error(new_ip->i_sb, jfs_error(new_ip->i_sb,
...@@ -1282,16 +1282,16 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1282,16 +1282,16 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
out4: out4:
txEnd(tid); txEnd(tid);
up(&JFS_IP(new_dir)->commit_sem); mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
up(&JFS_IP(old_ip)->commit_sem); mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
if (old_dir != new_dir) if (old_dir != new_dir)
up(&JFS_IP(old_dir)->commit_sem); mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
if (new_ip) if (new_ip)
up(&JFS_IP(new_ip)->commit_sem); mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
while (new_size && (rc == 0)) { while (new_size && (rc == 0)) {
tid = txBegin(new_ip->i_sb, 0); tid = txBegin(new_ip->i_sb, 0);
down(&JFS_IP(new_ip)->commit_sem); mutex_lock(&JFS_IP(new_ip)->commit_mutex);
new_size = xtTruncate_pmap(tid, new_ip, new_size); new_size = xtTruncate_pmap(tid, new_ip, new_size);
if (new_size < 0) { if (new_size < 0) {
txAbort(tid, 1); txAbort(tid, 1);
...@@ -1299,7 +1299,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1299,7 +1299,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
} else } else
rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC); rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
txEnd(tid); txEnd(tid);
up(&JFS_IP(new_ip)->commit_sem); mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
} }
if (new_ip && (new_ip->i_nlink == 0)) if (new_ip && (new_ip->i_nlink == 0))
set_cflag(COMMIT_Nolink, new_ip); set_cflag(COMMIT_Nolink, new_ip);
...@@ -1361,8 +1361,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, ...@@ -1361,8 +1361,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
tid = txBegin(dir->i_sb, 0); tid = txBegin(dir->i_sb, 0);
down(&JFS_IP(dir)->commit_sem); mutex_lock(&JFS_IP(dir)->commit_mutex);
down(&JFS_IP(ip)->commit_sem); mutex_lock(&JFS_IP(ip)->commit_mutex);
rc = jfs_init_acl(tid, ip, dir); rc = jfs_init_acl(tid, ip, dir);
if (rc) if (rc)
...@@ -1407,8 +1407,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry, ...@@ -1407,8 +1407,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
out3: out3:
txEnd(tid); txEnd(tid);
up(&JFS_IP(ip)->commit_sem); mutex_unlock(&JFS_IP(ip)->commit_mutex);
up(&JFS_IP(dir)->commit_sem); mutex_unlock(&JFS_IP(dir)->commit_mutex);
if (rc) { if (rc) {
free_ea_wmap(ip); free_ea_wmap(ip);
ip->i_nlink = 0; ip->i_nlink = 0;
...@@ -1523,6 +1523,7 @@ struct file_operations jfs_dir_operations = { ...@@ -1523,6 +1523,7 @@ struct file_operations jfs_dir_operations = {
.read = generic_read_dir, .read = generic_read_dir,
.readdir = jfs_readdir, .readdir = jfs_readdir,
.fsync = jfs_fsync, .fsync = jfs_fsync,
.ioctl = jfs_ioctl,
}; };
static int jfs_ci_hash(struct dentry *dir, struct qstr *this) static int jfs_ci_hash(struct dentry *dir, struct qstr *this)
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/vfs.h> #include <linux/vfs.h>
#include <linux/mount.h> #include <linux/mount.h>
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/kthread.h>
#include <linux/posix_acl.h> #include <linux/posix_acl.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
...@@ -54,11 +55,9 @@ static int commit_threads = 0; ...@@ -54,11 +55,9 @@ static int commit_threads = 0;
module_param(commit_threads, int, 0); module_param(commit_threads, int, 0);
MODULE_PARM_DESC(commit_threads, "Number of commit threads"); MODULE_PARM_DESC(commit_threads, "Number of commit threads");
int jfs_stop_threads; static struct task_struct *jfsCommitThread[MAX_COMMIT_THREADS];
static pid_t jfsIOthread; struct task_struct *jfsIOthread;
static pid_t jfsCommitThread[MAX_COMMIT_THREADS]; struct task_struct *jfsSyncThread;
static pid_t jfsSyncThread;
DECLARE_COMPLETION(jfsIOwait);
#ifdef CONFIG_JFS_DEBUG #ifdef CONFIG_JFS_DEBUG
int jfsloglevel = JFS_LOGLEVEL_WARN; int jfsloglevel = JFS_LOGLEVEL_WARN;
...@@ -195,7 +194,7 @@ static void jfs_put_super(struct super_block *sb) ...@@ -195,7 +194,7 @@ static void jfs_put_super(struct super_block *sb)
enum { enum {
Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize, Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota, Opt_resize_nosize, Opt_errors, Opt_ignore, Opt_err, Opt_quota,
Opt_usrquota, Opt_grpquota Opt_usrquota, Opt_grpquota, Opt_uid, Opt_gid, Opt_umask
}; };
static match_table_t tokens = { static match_table_t tokens = {
...@@ -209,6 +208,9 @@ static match_table_t tokens = { ...@@ -209,6 +208,9 @@ static match_table_t tokens = {
{Opt_ignore, "quota"}, {Opt_ignore, "quota"},
{Opt_usrquota, "usrquota"}, {Opt_usrquota, "usrquota"},
{Opt_grpquota, "grpquota"}, {Opt_grpquota, "grpquota"},
{Opt_uid, "uid=%u"},
{Opt_gid, "gid=%u"},
{Opt_umask, "umask=%u"},
{Opt_err, NULL} {Opt_err, NULL}
}; };
...@@ -313,7 +315,29 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize, ...@@ -313,7 +315,29 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
"JFS: quota operations not supported\n"); "JFS: quota operations not supported\n");
break; break;
#endif #endif
case Opt_uid:
{
char *uid = args[0].from;
sbi->uid = simple_strtoul(uid, &uid, 0);
break;
}
case Opt_gid:
{
char *gid = args[0].from;
sbi->gid = simple_strtoul(gid, &gid, 0);
break;
}
case Opt_umask:
{
char *umask = args[0].from;
sbi->umask = simple_strtoul(umask, &umask, 8);
if (sbi->umask & ~0777) {
printk(KERN_ERR
"JFS: Invalid value of umask\n");
goto cleanup;
}
break;
}
default: default:
printk("jfs: Unrecognized mount option \"%s\" " printk("jfs: Unrecognized mount option \"%s\" "
" or missing value\n", p); " or missing value\n", p);
...@@ -396,12 +420,12 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -396,12 +420,12 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
if (!new_valid_dev(sb->s_bdev->bd_dev)) if (!new_valid_dev(sb->s_bdev->bd_dev))
return -EOVERFLOW; return -EOVERFLOW;
sbi = kmalloc(sizeof (struct jfs_sb_info), GFP_KERNEL); sbi = kzalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
if (!sbi) if (!sbi)
return -ENOSPC; return -ENOSPC;
memset(sbi, 0, sizeof (struct jfs_sb_info));
sb->s_fs_info = sbi; sb->s_fs_info = sbi;
sbi->sb = sb; sbi->sb = sb;
sbi->uid = sbi->gid = sbi->umask = -1;
/* initialize the mount flag and determine the default error handler */ /* initialize the mount flag and determine the default error handler */
flag = JFS_ERR_REMOUNT_RO; flag = JFS_ERR_REMOUNT_RO;
...@@ -564,10 +588,14 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs) ...@@ -564,10 +588,14 @@ static int jfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
{ {
struct jfs_sb_info *sbi = JFS_SBI(vfs->mnt_sb); struct jfs_sb_info *sbi = JFS_SBI(vfs->mnt_sb);
if (sbi->uid != -1)
seq_printf(seq, ",uid=%d", sbi->uid);
if (sbi->gid != -1)
seq_printf(seq, ",gid=%d", sbi->gid);
if (sbi->umask != -1)
seq_printf(seq, ",umask=%03o", sbi->umask);
if (sbi->flag & JFS_NOINTEGRITY) if (sbi->flag & JFS_NOINTEGRITY)
seq_puts(seq, ",nointegrity"); seq_puts(seq, ",nointegrity");
else
seq_puts(seq, ",integrity");
#if defined(CONFIG_QUOTA) #if defined(CONFIG_QUOTA)
if (sbi->flag & JFS_USRQUOTA) if (sbi->flag & JFS_USRQUOTA)
...@@ -617,7 +645,7 @@ static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags) ...@@ -617,7 +645,7 @@ static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
memset(jfs_ip, 0, sizeof(struct jfs_inode_info)); memset(jfs_ip, 0, sizeof(struct jfs_inode_info));
INIT_LIST_HEAD(&jfs_ip->anon_inode_list); INIT_LIST_HEAD(&jfs_ip->anon_inode_list);
init_rwsem(&jfs_ip->rdwrlock); init_rwsem(&jfs_ip->rdwrlock);
init_MUTEX(&jfs_ip->commit_sem); mutex_init(&jfs_ip->commit_mutex);
init_rwsem(&jfs_ip->xattr_sem); init_rwsem(&jfs_ip->xattr_sem);
spin_lock_init(&jfs_ip->ag_lock); spin_lock_init(&jfs_ip->ag_lock);
jfs_ip->active_ag = -1; jfs_ip->active_ag = -1;
...@@ -661,12 +689,12 @@ static int __init init_jfs_fs(void) ...@@ -661,12 +689,12 @@ static int __init init_jfs_fs(void)
/* /*
* I/O completion thread (endio) * I/O completion thread (endio)
*/ */
jfsIOthread = kernel_thread(jfsIOWait, NULL, CLONE_KERNEL); jfsIOthread = kthread_run(jfsIOWait, NULL, "jfsIO");
if (jfsIOthread < 0) { if (IS_ERR(jfsIOthread)) {
jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsIOthread); rc = PTR_ERR(jfsIOthread);
jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
goto end_txmngr; goto end_txmngr;
} }
wait_for_completion(&jfsIOwait); /* Wait until thread starts */
if (commit_threads < 1) if (commit_threads < 1)
commit_threads = num_online_cpus(); commit_threads = num_online_cpus();
...@@ -674,24 +702,21 @@ static int __init init_jfs_fs(void) ...@@ -674,24 +702,21 @@ static int __init init_jfs_fs(void)
commit_threads = MAX_COMMIT_THREADS; commit_threads = MAX_COMMIT_THREADS;
for (i = 0; i < commit_threads; i++) { for (i = 0; i < commit_threads; i++) {
jfsCommitThread[i] = kernel_thread(jfs_lazycommit, NULL, jfsCommitThread[i] = kthread_run(jfs_lazycommit, NULL, "jfsCommit");
CLONE_KERNEL); if (IS_ERR(jfsCommitThread[i])) {
if (jfsCommitThread[i] < 0) { rc = PTR_ERR(jfsCommitThread[i]);
jfs_err("init_jfs_fs: fork failed w/rc = %d", jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
jfsCommitThread[i]);
commit_threads = i; commit_threads = i;
goto kill_committask; goto kill_committask;
} }
/* Wait until thread starts */
wait_for_completion(&jfsIOwait);
} }
jfsSyncThread = kernel_thread(jfs_sync, NULL, CLONE_KERNEL); jfsSyncThread = kthread_run(jfs_sync, NULL, "jfsSync");
if (jfsSyncThread < 0) { if (IS_ERR(jfsSyncThread)) {
jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsSyncThread); rc = PTR_ERR(jfsSyncThread);
jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
goto kill_committask; goto kill_committask;
} }
wait_for_completion(&jfsIOwait); /* Wait until thread starts */
#ifdef PROC_FS_JFS #ifdef PROC_FS_JFS
jfs_proc_init(); jfs_proc_init();
...@@ -700,13 +725,9 @@ static int __init init_jfs_fs(void) ...@@ -700,13 +725,9 @@ static int __init init_jfs_fs(void)
return register_filesystem(&jfs_fs_type); return register_filesystem(&jfs_fs_type);
kill_committask: kill_committask:
jfs_stop_threads = 1;
wake_up_all(&jfs_commit_thread_wait);
for (i = 0; i < commit_threads; i++) for (i = 0; i < commit_threads; i++)
wait_for_completion(&jfsIOwait); kthread_stop(jfsCommitThread[i]);
kthread_stop(jfsIOthread);
wake_up(&jfs_IO_thread_wait);
wait_for_completion(&jfsIOwait); /* Wait for thread exit */
end_txmngr: end_txmngr:
txExit(); txExit();
free_metapage: free_metapage:
...@@ -722,16 +743,13 @@ static void __exit exit_jfs_fs(void) ...@@ -722,16 +743,13 @@ static void __exit exit_jfs_fs(void)
jfs_info("exit_jfs_fs called"); jfs_info("exit_jfs_fs called");
jfs_stop_threads = 1;
txExit(); txExit();
metapage_exit(); metapage_exit();
wake_up(&jfs_IO_thread_wait);
wait_for_completion(&jfsIOwait); /* Wait until IO thread exits */ kthread_stop(jfsIOthread);
wake_up_all(&jfs_commit_thread_wait);
for (i = 0; i < commit_threads; i++) for (i = 0; i < commit_threads; i++)
wait_for_completion(&jfsIOwait); kthread_stop(jfsCommitThread[i]);
wake_up(&jfs_sync_thread_wait); kthread_stop(jfsSyncThread);
wait_for_completion(&jfsIOwait); /* Wait until Sync thread exits */
#ifdef PROC_FS_JFS #ifdef PROC_FS_JFS
jfs_proc_clean(); jfs_proc_clean();
#endif #endif
......
...@@ -934,13 +934,13 @@ int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, ...@@ -934,13 +934,13 @@ int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
} }
tid = txBegin(inode->i_sb, 0); tid = txBegin(inode->i_sb, 0);
down(&ji->commit_sem); mutex_lock(&ji->commit_mutex);
rc = __jfs_setxattr(tid, dentry->d_inode, name, value, value_len, rc = __jfs_setxattr(tid, dentry->d_inode, name, value, value_len,
flags); flags);
if (!rc) if (!rc)
rc = txCommit(tid, 1, &inode, 0); rc = txCommit(tid, 1, &inode, 0);
txEnd(tid); txEnd(tid);
up(&ji->commit_sem); mutex_unlock(&ji->commit_mutex);
return rc; return rc;
} }
...@@ -1093,12 +1093,12 @@ int jfs_removexattr(struct dentry *dentry, const char *name) ...@@ -1093,12 +1093,12 @@ int jfs_removexattr(struct dentry *dentry, const char *name)
return rc; return rc;
tid = txBegin(inode->i_sb, 0); tid = txBegin(inode->i_sb, 0);
down(&ji->commit_sem); mutex_lock(&ji->commit_mutex);
rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE); rc = __jfs_setxattr(tid, dentry->d_inode, name, NULL, 0, XATTR_REPLACE);
if (!rc) if (!rc)
rc = txCommit(tid, 1, &inode, 0); rc = txCommit(tid, 1, &inode, 0);
txEnd(tid); txEnd(tid);
up(&ji->commit_sem); mutex_unlock(&ji->commit_mutex);
return rc; return rc;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment