]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/shaggy...
authorLinus Torvalds <torvalds@g5.osdl.org>
Mon, 20 Mar 2006 18:32:33 +0000 (10:32 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Mon, 20 Mar 2006 18:32:33 +0000 (10:32 -0800)
* '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 fa3241d24cf1182b0ffb6e4d412c3bc2a2ab7bf6
  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

24 files changed:
fs/jfs/Makefile
fs/jfs/acl.c
fs/jfs/file.c
fs/jfs/inode.c
fs/jfs/ioctl.c [new file with mode: 0644]
fs/jfs/jfs_dinode.h
fs/jfs/jfs_dmap.c
fs/jfs/jfs_dmap.h
fs/jfs/jfs_dtree.c
fs/jfs/jfs_extent.c
fs/jfs/jfs_imap.c
fs/jfs/jfs_imap.h
fs/jfs/jfs_incore.h
fs/jfs/jfs_inode.c
fs/jfs/jfs_inode.h
fs/jfs/jfs_lock.h
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_logmgr.h
fs/jfs/jfs_metapage.c
fs/jfs/jfs_superblock.h
fs/jfs/jfs_txnmgr.c
fs/jfs/namei.c
fs/jfs/super.c
fs/jfs/xattr.c

index 6f1e0e95587a1e9e40e0bff579d75c77aecdd656..3adb6395e42de858ada7adec76b964dfef250e41 100644 (file)
@@ -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_unicode.o jfs_dtree.o jfs_inode.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
 
index 461e4934ca7c280553190f9c7b34cc296a95a23a..e2281300979c7b2c5e09287e28364bb25733c648 100644 (file)
@@ -183,6 +183,9 @@ cleanup:
                posix_acl_release(acl);
        } else
                inode->i_mode &= ~current->fs->umask;
+       
+       JFS_IP(inode)->mode2 = (JFS_IP(inode)->mode2 & 0xffff0000) |
+                              inode->i_mode;
 
        return rc;
 }
@@ -207,12 +210,12 @@ static int jfs_acl_chmod(struct inode *inode)
        rc = posix_acl_chmod_masq(clone, inode->i_mode);
        if (!rc) {
                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);
                if (!rc)
                        rc = txCommit(tid, 1, &inode, 0);
                txEnd(tid);
-               up(&JFS_IP(inode)->commit_sem);
+               mutex_unlock(&JFS_IP(inode)->commit_mutex);
        }
 
        posix_acl_release(clone);
index c2c19c9ed9a40b45d5ff591e2218251a309a4f97..e1ac6e497e2be67829bbc583ea545ae645ebf97d 100644 (file)
@@ -113,4 +113,5 @@ struct file_operations jfs_file_operations = {
        .sendfile       = generic_file_sendfile,
        .fsync          = jfs_fsync,
        .release        = jfs_release,
+       .ioctl          = jfs_ioctl,
 };
index 9f942ca8e4e3369440f408fd6b5650d1095ff5a8..51a5fed90cca46264520cc2183cdd95168a26679 100644 (file)
@@ -55,6 +55,7 @@ void jfs_read_inode(struct inode *inode)
                inode->i_op = &jfs_file_inode_operations;
                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)
        }
 
        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))
                rc = txCommit(tid, 1, &inode, wait ? COMMIT_SYNC : 0);
 
        txEnd(tid);
-       up(&JFS_IP(inode)->commit_sem);
+       mutex_unlock(&JFS_IP(inode)->commit_mutex);
        return rc;
 }
 
@@ -335,18 +336,18 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length)
                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
                 * could be marked dirty and need to be committed
                 * before txBegin unblocks
                 */
-               down(&JFS_IP(ip)->commit_sem);
+               mutex_lock(&JFS_IP(ip)->commit_mutex);
 
                newsize = xtTruncate(tid, ip, length,
                                     COMMIT_TRUNCATE | COMMIT_PWMAP);
                if (newsize < 0) {
                        txEnd(tid);
-                       up(&JFS_IP(ip)->commit_sem);
+                       mutex_unlock(&JFS_IP(ip)->commit_mutex);
                        break;
                }
 
@@ -355,7 +356,7 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length)
 
                txCommit(tid, 1, &ip, 0);
                txEnd(tid);
-               up(&JFS_IP(ip)->commit_sem);
+               mutex_unlock(&JFS_IP(ip)->commit_mutex);
        } while (newsize > length);     /* Truncate isn't always atomic */
 }
 
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c
new file mode 100644 (file)
index 0000000..67b3774
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * 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;
+       }
+}
+
index 580a3258449b56806b917a0fe936dabfde610c3c..9f2572aea5611b00279a771c760c6bbcf2126f7d 100644 (file)
@@ -139,13 +139,36 @@ struct dinode {
 
 /* more extended mode bits: attributes for OS/2 */
 #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 IRASH          0x4E000000      /* mask for changeable attributes */
-#define INEWNAME       0x80000000      /* non-8.3 filename format */
+#define ISYSTEM                0x08000000      /* system file */
+
 #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
                                   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 */
index 79b5404db100a4289e76dc3f28e11b980142e093..c161c98954e08b17afb7e849ef57c7b47bbd1b6f 100644 (file)
@@ -64,9 +64,9 @@
  *     to the persistent bitmaps in dmaps) is guarded by (busy) buffers.
  */
 
-#define BMAP_LOCK_INIT(bmp)    init_MUTEX(&bmp->db_bmaplock)
-#define BMAP_LOCK(bmp)         down(&bmp->db_bmaplock)
-#define BMAP_UNLOCK(bmp)       up(&bmp->db_bmaplock)
+#define BMAP_LOCK_INIT(bmp)    mutex_init(&bmp->db_bmaplock)
+#define BMAP_LOCK(bmp)         mutex_lock(&bmp->db_bmaplock)
+#define BMAP_UNLOCK(bmp)       mutex_unlock(&bmp->db_bmaplock)
 
 /*
  * forward references
@@ -125,7 +125,7 @@ static int dbGetL2AGSize(s64 nblocks);
  * into the table, with the table elements yielding the maximum
  * 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,
        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,
index 32e25884e7e84ca44113192b52bf4691c5c2c6e4..8b14cc8e0228346d703e6bb45509214d0b116be9 100644 (file)
@@ -243,7 +243,7 @@ struct dbmap {
 struct bmap {
        struct dbmap db_bmap;           /* on-disk aggregate map descriptor */
        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 */
        u32 *db_DBmap;
 };
index 404f33eae50792b2d3508507745890c28600dce8..6c3f083198468a686af3ed7c4dcc6bcbaf782dd8 100644 (file)
@@ -1005,6 +1005,9 @@ static int dtSplitUp(tid_t tid,
 
                DT_PUTPAGE(smp);
 
+               if (!DO_INDEX(ip))
+                       ip->i_size = xlen << sbi->l2bsize;
+
                goto freeKeyName;
        }
 
@@ -1055,7 +1058,9 @@ static int dtSplitUp(tid_t tid,
                                xaddr = addressPXD(pxd) + xlen;
                                dbFree(ip, xaddr, (s64) n);
                        }
-               }
+               } else if (!DO_INDEX(ip))
+                       ip->i_size = lengthPXD(pxd) << sbi->l2bsize;
+
 
              extendOut:
                DT_PUTPAGE(smp);
@@ -1098,6 +1103,9 @@ static int dtSplitUp(tid_t tid,
                goto splitOut;
        }
 
+       if (!DO_INDEX(ip))
+               ip->i_size += PSIZE;
+
        /*
         * propagate up the router entry for the leaf page just split
         *
@@ -2424,6 +2432,9 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
                break;
        }
 
+       if (!DO_INDEX(ip))
+               ip->i_size -= PSIZE;
+
        return 0;
 }
 
index 4879603daa1c76756d1ded3cd6ccec62683f3ed7..5549378358bfde82735db184e95b259eba6c5f0f 100644 (file)
@@ -94,7 +94,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
        txBeginAnon(ip->i_sb);
 
        /* Avoid race with jfs_commit_inode() */
-       down(&JFS_IP(ip)->commit_sem);
+       mutex_lock(&JFS_IP(ip)->commit_mutex);
 
        /* validate extent length */
        if (xlen > MAXXLEN)
@@ -136,14 +136,14 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
         */
        nxlen = xlen;
        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);
        }
 
        /* Allocate blocks to quota. */
        if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {
                dbFree(ip, nxaddr, (s64) nxlen);
-               up(&JFS_IP(ip)->commit_sem);
+               mutex_unlock(&JFS_IP(ip)->commit_mutex);
                return -EDQUOT;
        }
 
@@ -165,7 +165,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
        if (rc) {
                dbFree(ip, nxaddr, nxlen);
                DQUOT_FREE_BLOCK(ip, nxlen);
-               up(&JFS_IP(ip)->commit_sem);
+               mutex_unlock(&JFS_IP(ip)->commit_mutex);
                return (rc);
        }
 
@@ -177,7 +177,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
 
        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
         * sync list.
@@ -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 */
        txBeginAnon(ip->i_sb);
 
-       down(&JFS_IP(ip)->commit_sem);
+       mutex_lock(&JFS_IP(ip)->commit_mutex);
        /* validate extent length */
        if (nxlen > MAXXLEN)
                nxlen = MAXXLEN;
@@ -258,7 +258,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
        /* Allocat blocks to quota. */
        if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {
                dbFree(ip, nxaddr, (s64) nxlen);
-               up(&JFS_IP(ip)->commit_sem);
+               mutex_unlock(&JFS_IP(ip)->commit_mutex);
                return -EDQUOT;
        }
 
@@ -338,7 +338,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
 
        mark_inode_dirty(ip);
 exit:
-       up(&JFS_IP(ip)->commit_sem);
+       mutex_unlock(&JFS_IP(ip)->commit_mutex);
        return (rc);
 }
 #endif                 /* _NOTYET */
@@ -439,12 +439,12 @@ int extRecord(struct inode *ip, xad_t * xp)
 
        txBeginAnon(ip->i_sb);
 
-       down(&JFS_IP(ip)->commit_sem);
+       mutex_lock(&JFS_IP(ip)->commit_mutex);
 
        /* update the extent */
        rc = xtUpdate(0, ip, xp);
 
-       up(&JFS_IP(ip)->commit_sem);
+       mutex_unlock(&JFS_IP(ip)->commit_mutex);
        return rc;
 }
 
index 4efa0d0eec39400245420305262ad424e8486103..ccbe60aff83de64edddc27381e020c83240adb1b 100644 (file)
@@ -66,14 +66,14 @@ static HLIST_HEAD(aggregate_hash);
  * imap locks
  */
 /* iag free list lock */
-#define IAGFREE_LOCK_INIT(imap)                init_MUTEX(&imap->im_freelock)
-#define IAGFREE_LOCK(imap)             down(&imap->im_freelock)
-#define IAGFREE_UNLOCK(imap)           up(&imap->im_freelock)
+#define IAGFREE_LOCK_INIT(imap)                mutex_init(&imap->im_freelock)
+#define IAGFREE_LOCK(imap)             mutex_lock(&imap->im_freelock)
+#define IAGFREE_UNLOCK(imap)           mutex_unlock(&imap->im_freelock)
 
 /* per ag iag list locks */
-#define AG_LOCK_INIT(imap,index)       init_MUTEX(&(imap->im_aglock[index]))
-#define AG_LOCK(imap,agno)             down(&imap->im_aglock[agno])
-#define AG_UNLOCK(imap,agno)           up(&imap->im_aglock[agno])
+#define AG_LOCK_INIT(imap,index)       mutex_init(&(imap->im_aglock[index]))
+#define AG_LOCK(imap,agno)             mutex_lock(&imap->im_aglock[agno])
+#define AG_UNLOCK(imap,agno)           mutex_unlock(&imap->im_aglock[agno])
 
 /*
  * forward references
@@ -1261,7 +1261,7 @@ int diFree(struct inode *ip)
         * to be freed by the transaction;  
         */
        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 
         * to force the page NOHOMEOK (even though no data is
@@ -1294,7 +1294,7 @@ int diFree(struct inode *ip)
        rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
 
        txEnd(tid);
-       up(&JFS_IP(ipimap)->commit_sem);
+       mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
 
        /* unlock the AG inode map information */
        AG_UNLOCK(imap, agno);
@@ -2554,13 +2554,13 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
                 * addressing structure pointing to the new iag page;
                 */
                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 */
                if ((rc =
                     xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
                        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
                         * not successfully added to the inode map
                         */
@@ -2626,7 +2626,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
                rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
 
                txEnd(tid);
-               up(&JFS_IP(ipimap)->commit_sem);
+               mutex_unlock(&JFS_IP(ipimap)->commit_mutex);
 
                duplicateIXtree(sb, blkno, xlen, &xaddr);
 
@@ -3074,14 +3074,40 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno,
 static int copy_from_dinode(struct dinode * dip, struct inode *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->mode2 = le32_to_cpu(dip->di_mode);
 
        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_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_atime.tv_sec = le32_to_cpu(dip->di_atime.tv_sec);
        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)
 static void copy_to_dinode(struct dinode * dip, struct inode *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_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_gen = cpu_to_le32(ip->i_generation);
        dip->di_size = cpu_to_le64(ip->i_size);
        dip->di_nblocks = cpu_to_le64(PBLK2LBLK(ip->i_sb, ip->i_blocks));
        dip->di_nlink = cpu_to_le32(ip->i_nlink);
-       dip->di_uid = cpu_to_le32(ip->i_uid);
-       dip->di_gid = cpu_to_le32(ip->i_gid);
+       if (sbi->uid == -1)
+               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.
         * 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_nsec = cpu_to_le32(ip->i_atime.tv_nsec);
        dip->di_ctime.tv_sec = cpu_to_le32(ip->i_ctime.tv_sec);
index 6b59adec036a82d938831df169b78c29e3862fcb..6e24465f0f98d12cba1eb35bbe9b37ae0c8bcbee 100644 (file)
@@ -140,8 +140,8 @@ struct dinomap {
 struct inomap {
        struct dinomap im_imap;         /* 4096: inode allocation control */
        struct inode *im_ipimap;        /* 4: ptr to inode for imap   */
-       struct semaphore im_freelock;   /* 4: iag free list lock      */
-       struct semaphore im_aglock[MAXAG];      /* 512: per AG locks          */
+       struct mutex im_freelock;       /* 4: iag free list lock      */
+       struct mutex im_aglock[MAXAG];  /* 512: per AG locks          */
        u32 *im_DBGdimap;
        atomic_t im_numinos;    /* num of backed inodes */
        atomic_t im_numfree;    /* num of free backed inodes */
index dc21a5bd54d43007e07d368e08d445aee7ffbf2f..54d73716ca8c4dfbed653ae6e0c0df29dcb6da96 100644 (file)
@@ -19,6 +19,7 @@
 #ifndef _H_JFS_INCORE
 #define _H_JFS_INCORE
 
+#include <linux/mutex.h>
 #include <linux/rwsem.h>
 #include <linux/slab.h>
 #include <linux/bitops.h>
@@ -37,6 +38,8 @@
 struct jfs_inode_info {
        int     fileset;        /* fileset number (always 16)*/
        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      */
        dxd_t   acl;            /* dxd describing acl   */
        dxd_t   ea;             /* dxd describing ea    */
@@ -62,12 +65,12 @@ struct jfs_inode_info {
         */
        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
         * dirty inodes may be committed while a new transaction on the
         * 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 */
        struct rw_semaphore xattr_sem;
        lid_t   xtlid;          /* lid of xtree lock on directory */
@@ -169,6 +172,9 @@ struct jfs_sb_info {
        uint            state;          /* mount/recovery state */
        unsigned long   flag;           /* mount time flags */
        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 */
index 2af5efbfd06fa7dd97905c2df0aeeddca1076218..495df402916dbf5d3ff77415aec2085e9f50daf8 100644 (file)
 #include "jfs_dinode.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()
  *
@@ -62,6 +82,13 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
        } else
                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.
         */
@@ -74,10 +101,20 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
        }
 
        inode->i_mode = mode;
-       if (S_ISDIR(mode))
-               jfs_inode->mode2 = IDIRECTORY | mode;
-       else
-               jfs_inode->mode2 = INLINEEA | ISPARSE | mode;
+       /* inherit flags from parent */
+       jfs_inode->mode2 = JFS_IP(parent)->mode2 & JFS_FL_INHERIT;
+
+       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_blocks = 0;
        inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
@@ -98,6 +135,7 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
        jfs_inode->atlhead = 0;
        jfs_inode->atltail = 0;
        jfs_inode->xtlid = 0;
+       jfs_set_inode_flags(inode);
 
        jfs_info("ialloc returns inode = 0x%p\n", inode);
 
index b54bac576cb3b9811d17e6c3d4053e69a14c4e9d..095d471b9f9a186c36b5736d5484626133718dea 100644 (file)
@@ -20,6 +20,8 @@
 
 extern struct inode *ialloc(struct inode *, umode_t);
 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 int jfs_commit_inode(struct inode *, int);
 extern int jfs_write_inode(struct inode*, int);
@@ -29,6 +31,7 @@ extern void jfs_truncate(struct inode *);
 extern void jfs_truncate_nolock(struct inode *, loff_t);
 extern void jfs_free_zero_link(struct inode *);
 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 inode_operations jfs_dir_inode_operations;
index 10ad1d08668562435bdc1f1842634e00105c5ac4..70ac9f7d1e00c22064dcc43ff3d923820ce1048c 100644 (file)
@@ -20,6 +20,7 @@
 #define _H_JFS_LOCK
 
 #include <linux/spinlock.h>
+#include <linux/mutex.h>
 #include <linux/sched.h>
 
 /*
index d27bac6acaa346118b39bb02517987130b5cdcfb..0b348b13b55153772298e410bc4cf29ed849e47b 100644 (file)
@@ -64,6 +64,7 @@
 #include <linux/interrupt.h>
 #include <linux/smp_lock.h>
 #include <linux/completion.h>
+#include <linux/kthread.h>
 #include <linux/buffer_head.h>         /* for sync_blockdev() */
 #include <linux/bio.h>
 #include <linux/suspend.h>
  */
 static struct lbuf *log_redrive_list;
 static DEFINE_SPINLOCK(log_redrive_lock);
-DECLARE_WAIT_QUEUE_HEAD(jfs_IO_thread_wait);
 
 
 /*
  *     log read/write serialization (per log)
  */
-#define LOG_LOCK_INIT(log)     init_MUTEX(&(log)->loglock)
-#define LOG_LOCK(log)          down(&((log)->loglock))
-#define LOG_UNLOCK(log)                up(&((log)->loglock))
+#define LOG_LOCK_INIT(log)     mutex_init(&(log)->loglock)
+#define LOG_LOCK(log)          mutex_lock(&((log)->loglock))
+#define LOG_UNLOCK(log)                mutex_unlock(&((log)->loglock))
 
 
 /*
@@ -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);
                return -ENOMEM;
        }
-       memset(log, 0, sizeof(struct jfs_log));
        INIT_LIST_HEAD(&log->sb_list);
        init_waitqueue_head(&log->syncwait);
 
@@ -1181,9 +1180,8 @@ static int open_inline_log(struct super_block *sb)
        struct jfs_log *log;
        int rc;
 
-       if (!(log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL)))
+       if (!(log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL)))
                return -ENOMEM;
-       memset(log, 0, sizeof(struct jfs_log));
        INIT_LIST_HEAD(&log->sb_list);
        init_waitqueue_head(&log->syncwait);
 
@@ -1216,12 +1214,11 @@ static int open_dummy_log(struct super_block *sb)
 
        down(&jfs_log_sem);
        if (!dummy_log) {
-               dummy_log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL);
+               dummy_log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL);
                if (!dummy_log) {
                        up(&jfs_log_sem);
                        return -ENOMEM;
                }
-               memset(dummy_log, 0, sizeof(struct jfs_log));
                INIT_LIST_HEAD(&dummy_log->sb_list);
                init_waitqueue_head(&dummy_log->syncwait);
                dummy_log->no_integrity = 1;
@@ -1980,7 +1977,7 @@ static inline void lbmRedrive(struct lbuf *bp)
        log_redrive_list = bp;
        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)
 {
        struct lbuf *bp;
 
-       daemonize("jfsIO");
-
-       complete(&jfsIOwait);
-
        do {
-               DECLARE_WAITQUEUE(wq, current);
-
                spin_lock_irq(&log_redrive_lock);
                while ((bp = log_redrive_list) != 0) {
                        log_redrive_list = bp->l_redrive_next;
@@ -2362,21 +2353,19 @@ int jfsIOWait(void *arg)
                        lbmStartIO(bp);
                        spin_lock_irq(&log_redrive_lock);
                }
+               spin_unlock_irq(&log_redrive_lock);
+
                if (freezing(current)) {
-                       spin_unlock_irq(&log_redrive_lock);
                        refrigerator();
                } else {
-                       add_wait_queue(&jfs_IO_thread_wait, &wq);
                        set_current_state(TASK_INTERRUPTIBLE);
-                       spin_unlock_irq(&log_redrive_lock);
                        schedule();
                        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!");
-       complete_and_exit(&jfsIOwait, 0);
+       return 0;
 }
 
 /*
index e4978b5b65ee05000e877209b733dfb1c1355a82..8c6909b80014b6948c0f044cb19062e72fafe25d 100644 (file)
@@ -389,7 +389,7 @@ struct jfs_log {
        int eor;                /* 4: eor of last record in eol page */
        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 */
        int nextsync;           /* 4: bytes to write before next syncpt */
index 8a53981f9f2797061cc6dc1667ea211ac6bce91f..5fbaeaadccd39f03c9eda07e9815add79acf37db 100644 (file)
@@ -104,10 +104,9 @@ static inline int insert_metapage(struct page *page, struct metapage *mp)
        if (PagePrivate(page))
                a = mp_anchor(page);
        else {
-               a = kmalloc(sizeof(struct meta_anchor), GFP_NOFS);
+               a = kzalloc(sizeof(struct meta_anchor), GFP_NOFS);
                if (!a)
                        return -ENOMEM;
-               memset(a, 0, sizeof(struct meta_anchor));
                set_page_private(page, (unsigned long)a);
                SetPagePrivate(page);
                kmap(page);
index fcf781bf31cbf9e399043953fb6857d2c27b93aa..682cf1a68a185ae3a7f22c954a86de1b35c2d339 100644 (file)
@@ -113,12 +113,9 @@ extern int jfs_mount(struct super_block *);
 extern int jfs_mount_rw(struct super_block *, int);
 extern int jfs_umount(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 struct task_struct *jfsIOthread;
+extern struct task_struct *jfsSyncThread;
+
 #endif /*_H_JFS_SUPERBLOCK */
index 2ddb6b892bcf17b80d75b2fb20b8d573fafb30b0..ac3d66948e8ceae440e77d944bd2667f9a9e8e76 100644 (file)
@@ -49,6 +49,7 @@
 #include <linux/suspend.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/kthread.h>
 #include "jfs_incore.h"
 #include "jfs_inode.h"
 #include "jfs_filsys.h"
@@ -121,8 +122,7 @@ static DEFINE_SPINLOCK(jfsTxnLock);
 #define LAZY_LOCK(flags)       spin_lock_irqsave(&TxAnchor.LazyLock, flags)
 #define LAZY_UNLOCK(flags) spin_unlock_irqrestore(&TxAnchor.LazyLock, flags)
 
-DECLARE_WAIT_QUEUE_HEAD(jfs_sync_thread_wait);
-DECLARE_WAIT_QUEUE_HEAD(jfs_commit_thread_wait);
+static DECLARE_WAIT_QUEUE_HEAD(jfs_commit_thread_wait);
 static int jfs_commit_thread_waking;
 
 /*
@@ -207,7 +207,7 @@ static lid_t txLockAlloc(void)
        if ((++TxAnchor.tlocksInUse > TxLockHWM) && (jfs_tlocks_low == 0)) {
                jfs_info("txLockAlloc tlocks low");
                jfs_tlocks_low = 1;
-               wake_up(&jfs_sync_thread_wait);
+               wake_up_process(jfsSyncThread);
        }
 
        return lid;
@@ -2743,10 +2743,6 @@ int jfs_lazycommit(void *arg)
        unsigned long flags;
        struct jfs_sb_info *sbi;
 
-       daemonize("jfsCommit");
-
-       complete(&jfsIOwait);
-
        do {
                LAZY_LOCK(flags);
                jfs_commit_thread_waking = 0;   /* OK to wake another thread */
@@ -2806,13 +2802,13 @@ int jfs_lazycommit(void *arg)
                        current->state = TASK_RUNNING;
                        remove_wait_queue(&jfs_commit_thread_wait, &wq);
                }
-       } while (!jfs_stop_threads);
+       } while (!kthread_should_stop());
 
        if (!list_empty(&TxAnchor.unlock_queue))
                jfs_err("jfs_lazycommit being killed w/pending transactions!");
        else
                jfs_info("jfs_lazycommit being killed\n");
-       complete_and_exit(&jfsIOwait, 0);
+       return 0;
 }
 
 void txLazyUnlock(struct tblock * tblk)
@@ -2876,10 +2872,10 @@ restart:
                 */
                TXN_UNLOCK();
                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);
                txEnd(tid);
-               up(&jfs_ip->commit_sem);
+               mutex_unlock(&jfs_ip->commit_mutex);
                /*
                 * Just to be safe.  I don't know how
                 * long we can run without blocking
@@ -2932,10 +2928,6 @@ int jfs_sync(void *arg)
        int rc;
        tid_t tid;
 
-       daemonize("jfsSync");
-
-       complete(&jfsIOwait);
-
        do {
                /*
                 * write each inode on the anonymous inode list
@@ -2952,7 +2944,7 @@ int jfs_sync(void *arg)
                                 * Inode is being freed
                                 */
                                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
                                 * when it is committed
@@ -2961,7 +2953,7 @@ int jfs_sync(void *arg)
                                tid = txBegin(ip->i_sb, COMMIT_INODE);
                                rc = txCommit(tid, 1, &ip, 0);
                                txEnd(tid);
-                               up(&jfs_ip->commit_sem);
+                               mutex_unlock(&jfs_ip->commit_mutex);
 
                                iput(ip);
                                /*
@@ -2971,7 +2963,7 @@ int jfs_sync(void *arg)
                                cond_resched();
                                TXN_LOCK();
                        } 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
                                 * so let's not block here.  Save it to
                                 * put back on the anon_list.
@@ -2996,19 +2988,15 @@ int jfs_sync(void *arg)
                        TXN_UNLOCK();
                        refrigerator();
                } else {
-                       DECLARE_WAITQUEUE(wq, current);
-
-                       add_wait_queue(&jfs_sync_thread_wait, &wq);
                        set_current_state(TASK_INTERRUPTIBLE);
                        TXN_UNLOCK();
                        schedule();
                        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");
-       complete_and_exit(&jfsIOwait, 0);
+       return 0;
 }
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_JFS_DEBUG)
index 4abbe86043021e931ccdfec7e1932bf15641a22d..309cee575f7db88165c6edf78aeb0ba86b7bcc3f 100644 (file)
@@ -104,8 +104,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
 
        tid = txBegin(dip->i_sb, 0);
 
-       down(&JFS_IP(dip)->commit_sem);
-       down(&JFS_IP(ip)->commit_sem);
+       mutex_lock(&JFS_IP(dip)->commit_mutex);
+       mutex_lock(&JFS_IP(ip)->commit_mutex);
 
        rc = jfs_init_acl(tid, ip, dip);
        if (rc)
@@ -165,8 +165,8 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
 
       out3:
        txEnd(tid);
-       up(&JFS_IP(dip)->commit_sem);
-       up(&JFS_IP(ip)->commit_sem);
+       mutex_unlock(&JFS_IP(dip)->commit_mutex);
+       mutex_unlock(&JFS_IP(ip)->commit_mutex);
        if (rc) {
                free_ea_wmap(ip);
                ip->i_nlink = 0;
@@ -238,8 +238,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
 
        tid = txBegin(dip->i_sb, 0);
 
-       down(&JFS_IP(dip)->commit_sem);
-       down(&JFS_IP(ip)->commit_sem);
+       mutex_lock(&JFS_IP(dip)->commit_mutex);
+       mutex_lock(&JFS_IP(ip)->commit_mutex);
 
        rc = jfs_init_acl(tid, ip, dip);
        if (rc)
@@ -300,8 +300,8 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
 
       out3:
        txEnd(tid);
-       up(&JFS_IP(dip)->commit_sem);
-       up(&JFS_IP(ip)->commit_sem);
+       mutex_unlock(&JFS_IP(dip)->commit_mutex);
+       mutex_unlock(&JFS_IP(ip)->commit_mutex);
        if (rc) {
                free_ea_wmap(ip);
                ip->i_nlink = 0;
@@ -365,8 +365,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
 
        tid = txBegin(dip->i_sb, 0);
 
-       down(&JFS_IP(dip)->commit_sem);
-       down(&JFS_IP(ip)->commit_sem);
+       mutex_lock(&JFS_IP(dip)->commit_mutex);
+       mutex_lock(&JFS_IP(ip)->commit_mutex);
 
        iplist[0] = dip;
        iplist[1] = ip;
@@ -384,8 +384,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
                if (rc == -EIO)
                        txAbort(tid, 1);
                txEnd(tid);
-               up(&JFS_IP(dip)->commit_sem);
-               up(&JFS_IP(ip)->commit_sem);
+               mutex_unlock(&JFS_IP(dip)->commit_mutex);
+               mutex_unlock(&JFS_IP(ip)->commit_mutex);
 
                goto out2;
        }
@@ -422,8 +422,8 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
 
        txEnd(tid);
 
-       up(&JFS_IP(dip)->commit_sem);
-       up(&JFS_IP(ip)->commit_sem);
+       mutex_unlock(&JFS_IP(dip)->commit_mutex);
+       mutex_unlock(&JFS_IP(ip)->commit_mutex);
 
        /*
         * Truncating the directory index table is not guaranteed.  It
@@ -488,8 +488,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
 
        tid = txBegin(dip->i_sb, 0);
 
-       down(&JFS_IP(dip)->commit_sem);
-       down(&JFS_IP(ip)->commit_sem);
+       mutex_lock(&JFS_IP(dip)->commit_mutex);
+       mutex_lock(&JFS_IP(ip)->commit_mutex);
 
        iplist[0] = dip;
        iplist[1] = ip;
@@ -503,8 +503,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
                if (rc == -EIO)
                        txAbort(tid, 1);        /* Marks FS Dirty */
                txEnd(tid);
-               up(&JFS_IP(dip)->commit_sem);
-               up(&JFS_IP(ip)->commit_sem);
+               mutex_unlock(&JFS_IP(dip)->commit_mutex);
+               mutex_unlock(&JFS_IP(ip)->commit_mutex);
                IWRITE_UNLOCK(ip);
                goto out1;
        }
@@ -527,8 +527,8 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
                if ((new_size = commitZeroLink(tid, ip)) < 0) {
                        txAbort(tid, 1);        /* Marks FS Dirty */
                        txEnd(tid);
-                       up(&JFS_IP(dip)->commit_sem);
-                       up(&JFS_IP(ip)->commit_sem);
+                       mutex_unlock(&JFS_IP(dip)->commit_mutex);
+                       mutex_unlock(&JFS_IP(ip)->commit_mutex);
                        IWRITE_UNLOCK(ip);
                        rc = new_size;
                        goto out1;
@@ -556,13 +556,13 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
 
        txEnd(tid);
 
-       up(&JFS_IP(dip)->commit_sem);
-       up(&JFS_IP(ip)->commit_sem);
+       mutex_unlock(&JFS_IP(dip)->commit_mutex);
+       mutex_unlock(&JFS_IP(ip)->commit_mutex);
 
 
        while (new_size && (rc == 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);
                if (new_size < 0) {
                        txAbort(tid, 1);        /* Marks FS Dirty */
@@ -570,7 +570,7 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
                } else
                        rc = txCommit(tid, 2, &iplist[0], COMMIT_SYNC);
                txEnd(tid);
-               up(&JFS_IP(ip)->commit_sem);
+               mutex_unlock(&JFS_IP(ip)->commit_mutex);
        }
 
        if (ip->i_nlink == 0)
@@ -805,8 +805,8 @@ static int jfs_link(struct dentry *old_dentry,
 
        tid = txBegin(ip->i_sb, 0);
 
-       down(&JFS_IP(dir)->commit_sem);
-       down(&JFS_IP(ip)->commit_sem);
+       mutex_lock(&JFS_IP(dir)->commit_mutex);
+       mutex_lock(&JFS_IP(ip)->commit_mutex);
 
        /*
         * scan parent directory for entry/freespace
@@ -847,8 +847,8 @@ static int jfs_link(struct dentry *old_dentry,
       out:
        txEnd(tid);
 
-       up(&JFS_IP(dir)->commit_sem);
-       up(&JFS_IP(ip)->commit_sem);
+       mutex_unlock(&JFS_IP(dir)->commit_mutex);
+       mutex_unlock(&JFS_IP(ip)->commit_mutex);
 
        jfs_info("jfs_link: rc:%d", rc);
        return rc;
@@ -916,8 +916,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
 
        tid = txBegin(dip->i_sb, 0);
 
-       down(&JFS_IP(dip)->commit_sem);
-       down(&JFS_IP(ip)->commit_sem);
+       mutex_lock(&JFS_IP(dip)->commit_mutex);
+       mutex_lock(&JFS_IP(ip)->commit_mutex);
 
        rc = jfs_init_security(tid, ip, dip);
        if (rc)
@@ -1037,8 +1037,8 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
 
       out3:
        txEnd(tid);
-       up(&JFS_IP(dip)->commit_sem);
-       up(&JFS_IP(ip)->commit_sem);
+       mutex_unlock(&JFS_IP(dip)->commit_mutex);
+       mutex_unlock(&JFS_IP(ip)->commit_mutex);
        if (rc) {
                free_ea_wmap(ip);
                ip->i_nlink = 0;
@@ -1141,13 +1141,13 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
         */
        tid = txBegin(new_dir->i_sb, 0);
 
-       down(&JFS_IP(new_dir)->commit_sem);
-       down(&JFS_IP(old_ip)->commit_sem);
+       mutex_lock(&JFS_IP(new_dir)->commit_mutex);
+       mutex_lock(&JFS_IP(old_ip)->commit_mutex);
        if (old_dir != new_dir)
-               down(&JFS_IP(old_dir)->commit_sem);
+               mutex_lock(&JFS_IP(old_dir)->commit_mutex);
 
        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
                 */
@@ -1160,10 +1160,10 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                if (S_ISDIR(new_ip->i_mode)) {
                        new_ip->i_nlink--;
                        if (new_ip->i_nlink) {
-                               up(&JFS_IP(new_dir)->commit_sem);
-                               up(&JFS_IP(old_ip)->commit_sem);
+                               mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
+                               mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
                                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)
                                        IWRITE_UNLOCK(new_ip);
                                jfs_error(new_ip->i_sb,
@@ -1282,16 +1282,16 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
       out4:
        txEnd(tid);
 
-       up(&JFS_IP(new_dir)->commit_sem);
-       up(&JFS_IP(old_ip)->commit_sem);
+       mutex_unlock(&JFS_IP(new_dir)->commit_mutex);
+       mutex_unlock(&JFS_IP(old_ip)->commit_mutex);
        if (old_dir != new_dir)
-               up(&JFS_IP(old_dir)->commit_sem);
+               mutex_unlock(&JFS_IP(old_dir)->commit_mutex);
        if (new_ip)
-               up(&JFS_IP(new_ip)->commit_sem);
+               mutex_unlock(&JFS_IP(new_ip)->commit_mutex);
 
        while (new_size && (rc == 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);
                if (new_size < 0) {
                        txAbort(tid, 1);
@@ -1299,7 +1299,7 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
                } else
                        rc = txCommit(tid, 1, &new_ip, COMMIT_SYNC);
                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))
                set_cflag(COMMIT_Nolink, new_ip);
@@ -1361,8 +1361,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
 
        tid = txBegin(dir->i_sb, 0);
 
-       down(&JFS_IP(dir)->commit_sem);
-       down(&JFS_IP(ip)->commit_sem);
+       mutex_lock(&JFS_IP(dir)->commit_mutex);
+       mutex_lock(&JFS_IP(ip)->commit_mutex);
 
        rc = jfs_init_acl(tid, ip, dir);
        if (rc)
@@ -1407,8 +1407,8 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
 
       out3:
        txEnd(tid);
-       up(&JFS_IP(ip)->commit_sem);
-       up(&JFS_IP(dir)->commit_sem);
+       mutex_unlock(&JFS_IP(ip)->commit_mutex);
+       mutex_unlock(&JFS_IP(dir)->commit_mutex);
        if (rc) {
                free_ea_wmap(ip);
                ip->i_nlink = 0;
@@ -1523,6 +1523,7 @@ struct file_operations jfs_dir_operations = {
        .read           = generic_read_dir,
        .readdir        = jfs_readdir,
        .fsync          = jfs_fsync,
+       .ioctl          = jfs_ioctl,
 };
 
 static int jfs_ci_hash(struct dentry *dir, struct qstr *this)
index 8d31f1336431a916e7947f0381ec439d61705bbb..18f69e6aa719358e793c31745cd1831b4eded107 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/vfs.h>
 #include <linux/mount.h>
 #include <linux/moduleparam.h>
+#include <linux/kthread.h>
 #include <linux/posix_acl.h>
 #include <asm/uaccess.h>
 #include <linux/seq_file.h>
@@ -54,11 +55,9 @@ static int commit_threads = 0;
 module_param(commit_threads, int, 0);
 MODULE_PARM_DESC(commit_threads, "Number of commit threads");
 
-int jfs_stop_threads;
-static pid_t jfsIOthread;
-static pid_t jfsCommitThread[MAX_COMMIT_THREADS];
-static pid_t jfsSyncThread;
-DECLARE_COMPLETION(jfsIOwait);
+static struct task_struct *jfsCommitThread[MAX_COMMIT_THREADS];
+struct task_struct *jfsIOthread;
+struct task_struct *jfsSyncThread;
 
 #ifdef CONFIG_JFS_DEBUG
 int jfsloglevel = JFS_LOGLEVEL_WARN;
@@ -195,7 +194,7 @@ static void jfs_put_super(struct super_block *sb)
 enum {
        Opt_integrity, Opt_nointegrity, Opt_iocharset, Opt_resize,
        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 = {
@@ -209,6 +208,9 @@ static match_table_t tokens = {
        {Opt_ignore, "quota"},
        {Opt_usrquota, "usrquota"},
        {Opt_grpquota, "grpquota"},
+       {Opt_uid, "uid=%u"},
+       {Opt_gid, "gid=%u"},
+       {Opt_umask, "umask=%u"},
        {Opt_err, NULL}
 };
 
@@ -313,7 +315,29 @@ static int parse_options(char *options, struct super_block *sb, s64 *newLVSize,
                               "JFS: quota operations not supported\n");
                        break;
 #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:
                        printk("jfs: Unrecognized mount option \"%s\" "
                                        " or missing value\n", p);
@@ -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))
                return -EOVERFLOW;
 
-       sbi = kmalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
+       sbi = kzalloc(sizeof (struct jfs_sb_info), GFP_KERNEL);
        if (!sbi)
                return -ENOSPC;
-       memset(sbi, 0, sizeof (struct jfs_sb_info));
        sb->s_fs_info = sbi;
        sbi->sb = sb;
+       sbi->uid = sbi->gid = sbi->umask = -1;
 
        /* initialize the mount flag and determine the default error handler */
        flag = JFS_ERR_REMOUNT_RO;
@@ -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);
 
+       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)
                seq_puts(seq, ",nointegrity");
-       else
-               seq_puts(seq, ",integrity");
 
 #if defined(CONFIG_QUOTA)
        if (sbi->flag & JFS_USRQUOTA)
@@ -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));
                INIT_LIST_HEAD(&jfs_ip->anon_inode_list);
                init_rwsem(&jfs_ip->rdwrlock);
-               init_MUTEX(&jfs_ip->commit_sem);
+               mutex_init(&jfs_ip->commit_mutex);
                init_rwsem(&jfs_ip->xattr_sem);
                spin_lock_init(&jfs_ip->ag_lock);
                jfs_ip->active_ag = -1;
@@ -661,12 +689,12 @@ static int __init init_jfs_fs(void)
        /*
         * I/O completion thread (endio)
         */
-       jfsIOthread = kernel_thread(jfsIOWait, NULL, CLONE_KERNEL);
-       if (jfsIOthread < 0) {
-               jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsIOthread);
+       jfsIOthread = kthread_run(jfsIOWait, NULL, "jfsIO");
+       if (IS_ERR(jfsIOthread)) {
+               rc = PTR_ERR(jfsIOthread);
+               jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
                goto end_txmngr;
        }
-       wait_for_completion(&jfsIOwait);        /* Wait until thread starts */
 
        if (commit_threads < 1)
                commit_threads = num_online_cpus();
@@ -674,24 +702,21 @@ 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, NULL,
-                                                  CLONE_KERNEL);
-               if (jfsCommitThread[i] < 0) {
-                       jfs_err("init_jfs_fs: fork failed w/rc = %d",
-                               jfsCommitThread[i]);
+               jfsCommitThread[i] = kthread_run(jfs_lazycommit, NULL, "jfsCommit");
+               if (IS_ERR(jfsCommitThread[i])) {
+                       rc = PTR_ERR(jfsCommitThread[i]);
+                       jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
                        commit_threads = i;
                        goto kill_committask;
                }
-               /* Wait until thread starts */
-               wait_for_completion(&jfsIOwait);
        }
 
-       jfsSyncThread = kernel_thread(jfs_sync, NULL, CLONE_KERNEL);
-       if (jfsSyncThread < 0) {
-               jfs_err("init_jfs_fs: fork failed w/rc = %d", jfsSyncThread);
+       jfsSyncThread = kthread_run(jfs_sync, NULL, "jfsSync");
+       if (IS_ERR(jfsSyncThread)) {
+               rc = PTR_ERR(jfsSyncThread);
+               jfs_err("init_jfs_fs: fork failed w/rc = %d", rc);
                goto kill_committask;
        }
-       wait_for_completion(&jfsIOwait);        /* Wait until thread starts */
 
 #ifdef PROC_FS_JFS
        jfs_proc_init();
@@ -700,13 +725,9 @@ static int __init init_jfs_fs(void)
        return register_filesystem(&jfs_fs_type);
 
 kill_committask:
-       jfs_stop_threads = 1;
-       wake_up_all(&jfs_commit_thread_wait);
        for (i = 0; i < commit_threads; i++)
-               wait_for_completion(&jfsIOwait);
-
-       wake_up(&jfs_IO_thread_wait);
-       wait_for_completion(&jfsIOwait);        /* Wait for thread exit */
+               kthread_stop(jfsCommitThread[i]);
+       kthread_stop(jfsIOthread);
 end_txmngr:
        txExit();
 free_metapage:
@@ -722,16 +743,13 @@ static void __exit exit_jfs_fs(void)
 
        jfs_info("exit_jfs_fs called");
 
-       jfs_stop_threads = 1;
        txExit();
        metapage_exit();
-       wake_up(&jfs_IO_thread_wait);
-       wait_for_completion(&jfsIOwait);        /* Wait until IO thread exits */
-       wake_up_all(&jfs_commit_thread_wait);
+
+       kthread_stop(jfsIOthread);
        for (i = 0; i < commit_threads; i++)
-               wait_for_completion(&jfsIOwait);
-       wake_up(&jfs_sync_thread_wait);
-       wait_for_completion(&jfsIOwait);        /* Wait until Sync thread exits */
+               kthread_stop(jfsCommitThread[i]);
+       kthread_stop(jfsSyncThread);
 #ifdef PROC_FS_JFS
        jfs_proc_clean();
 #endif
index f23048f9471f0c921c1e2514f91c9ff5afb5fd97..9bc5b7c055ce12ad015dc90df3d87fd72f42a7e7 100644 (file)
@@ -934,13 +934,13 @@ int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
        }
 
        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,
                            flags);
        if (!rc)
                rc = txCommit(tid, 1, &inode, 0);
        txEnd(tid);
-       up(&ji->commit_sem);
+       mutex_unlock(&ji->commit_mutex);
 
        return rc;
 }
@@ -1093,12 +1093,12 @@ int jfs_removexattr(struct dentry *dentry, const char *name)
                return rc;
 
        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);
        if (!rc)
                rc = txCommit(tid, 1, &inode, 0);
        txEnd(tid);
-       up(&ji->commit_sem);
+       mutex_unlock(&ji->commit_mutex);
 
        return rc;
 }