diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2005-07-28 09:30:20 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-07-28 09:30:20 +0100 |
commit | 661299d9d0437a0ff72240f3d60016ac3a361a6e (patch) | |
tree | 765512576314fc3612b503f182b9ae4e60fcf849 /fs | |
parent | 05caac585f8abd6c0113856bc8858e3ef214d8a6 (diff) | |
parent | 41c018b7ecb60b1c2c4d5dee0cd37d32a94c45af (diff) |
Merge with Linus' 2.6 tree
Diffstat (limited to 'fs')
-rw-r--r-- | fs/autofs4/autofs_i.h | 1 | ||||
-rw-r--r-- | fs/autofs4/inode.c | 73 | ||||
-rw-r--r-- | fs/ext2/ialloc.c | 1 | ||||
-rw-r--r-- | fs/ext2/xattr.c | 2 | ||||
-rw-r--r-- | fs/ext2/xip.c | 2 | ||||
-rw-r--r-- | fs/ext3/ialloc.c | 2 | ||||
-rw-r--r-- | fs/ext3/xattr.c | 2 | ||||
-rw-r--r-- | fs/fcntl.c | 5 | ||||
-rw-r--r-- | fs/jffs/intrep.c | 3 | ||||
-rw-r--r-- | fs/jfs/jfs_dmap.c | 46 | ||||
-rw-r--r-- | fs/jfs/jfs_dtree.c | 13 | ||||
-rw-r--r-- | fs/jfs/jfs_logmgr.c | 3 | ||||
-rw-r--r-- | fs/jfs/jfs_metapage.c | 11 | ||||
-rw-r--r-- | fs/locks.c | 81 | ||||
-rw-r--r-- | fs/mbcache.c | 3 | ||||
-rw-r--r-- | fs/ntfs/sysctl.h | 2 | ||||
-rw-r--r-- | fs/reiserfs/inode.c | 12 | ||||
-rw-r--r-- | fs/reiserfs/journal.c | 4 | ||||
-rw-r--r-- | fs/reiserfs/xattr.c | 1 |
19 files changed, 191 insertions, 76 deletions
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index 9c09641ce90..fca83e28edc 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h @@ -92,6 +92,7 @@ struct autofs_wait_queue { struct autofs_sb_info { u32 magic; + struct dentry *root; struct file *pipe; pid_t oz_pgrp; int catatonic; diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index 4bb14cc6804..0a3c05d1016 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c @@ -16,6 +16,7 @@ #include <linux/pagemap.h> #include <linux/parser.h> #include <linux/bitops.h> +#include <linux/smp_lock.h> #include "autofs_i.h" #include <linux/module.h> @@ -76,6 +77,66 @@ void autofs4_free_ino(struct autofs_info *ino) kfree(ino); } +/* + * Deal with the infamous "Busy inodes after umount ..." message. + * + * Clean up the dentry tree. This happens with autofs if the user + * space program goes away due to a SIGKILL, SIGSEGV etc. + */ +static void autofs4_force_release(struct autofs_sb_info *sbi) +{ + struct dentry *this_parent = sbi->root; + struct list_head *next; + + spin_lock(&dcache_lock); +repeat: + next = this_parent->d_subdirs.next; +resume: + while (next != &this_parent->d_subdirs) { + struct dentry *dentry = list_entry(next, struct dentry, d_child); + + /* Negative dentry - don`t care */ + if (!simple_positive(dentry)) { + next = next->next; + continue; + } + + if (!list_empty(&dentry->d_subdirs)) { + this_parent = dentry; + goto repeat; + } + + next = next->next; + spin_unlock(&dcache_lock); + + DPRINTK("dentry %p %.*s", + dentry, (int)dentry->d_name.len, dentry->d_name.name); + + dput(dentry); + spin_lock(&dcache_lock); + } + + if (this_parent != sbi->root) { + struct dentry *dentry = this_parent; + + next = this_parent->d_child.next; + this_parent = this_parent->d_parent; + spin_unlock(&dcache_lock); + DPRINTK("parent dentry %p %.*s", + dentry, (int)dentry->d_name.len, dentry->d_name.name); + dput(dentry); + spin_lock(&dcache_lock); + goto resume; + } + spin_unlock(&dcache_lock); + + dput(sbi->root); + sbi->root = NULL; + shrink_dcache_sb(sbi->sb); + + return; +} + static void autofs4_put_super(struct super_block *sb) { struct autofs_sb_info *sbi = autofs4_sbi(sb); @@ -85,6 +146,10 @@ static void autofs4_put_super(struct super_block *sb) if ( !sbi->catatonic ) autofs4_catatonic_mode(sbi); /* Free wait queues, close pipe */ + /* Clean up and release dangling references */ + if (sbi) + autofs4_force_release(sbi); + kfree(sbi); DPRINTK("shutting down"); @@ -199,6 +264,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) s->s_fs_info = sbi; sbi->magic = AUTOFS_SBI_MAGIC; + sbi->root = NULL; sbi->catatonic = 0; sbi->exp_timeout = 0; sbi->oz_pgrp = process_group(current); @@ -267,6 +333,13 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) sbi->pipe = pipe; /* + * Take a reference to the root dentry so we get a chance to + * clean up the dentry tree on umount. + * See autofs4_force_release. + */ + sbi->root = dget(root); + + /* * Success! Install the root dentry now to indicate completion. */ s->s_root = root; diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c index 77e05914921..161f156d98c 100644 --- a/fs/ext2/ialloc.c +++ b/fs/ext2/ialloc.c @@ -612,6 +612,7 @@ got: err = ext2_init_acl(inode, dir); if (err) { DQUOT_FREE_INODE(inode); + DQUOT_DROP(inode); goto fail2; } mark_inode_dirty(inode); diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 27982b500e8..0099462d427 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -823,7 +823,7 @@ cleanup: void ext2_xattr_put_super(struct super_block *sb) { - mb_cache_shrink(ext2_xattr_cache, sb->s_bdev); + mb_cache_shrink(sb->s_bdev); } diff --git a/fs/ext2/xip.c b/fs/ext2/xip.c index 0aa5ac159c0..ca7f0031238 100644 --- a/fs/ext2/xip.c +++ b/fs/ext2/xip.c @@ -36,7 +36,7 @@ __ext2_get_sector(struct inode *inode, sector_t offset, int create, *result = tmp.b_blocknr; /* did we get a sparse block (hole in the file)? */ - if (!(*result)) { + if (!tmp.b_blocknr && !rc) { BUG_ON(create); rc = -ENODATA; } diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 1e6f3ea2871..6981bd014ed 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c @@ -604,12 +604,14 @@ got: err = ext3_init_acl(handle, inode, dir); if (err) { DQUOT_FREE_INODE(inode); + DQUOT_DROP(inode); goto fail2; } err = ext3_mark_inode_dirty(handle, inode); if (err) { ext3_std_error(sb, err); DQUOT_FREE_INODE(inode); + DQUOT_DROP(inode); goto fail2; } diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index 3f9dfa643b1..269c7b92db9 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c @@ -1106,7 +1106,7 @@ cleanup: void ext3_xattr_put_super(struct super_block *sb) { - mb_cache_shrink(ext3_xattr_cache, sb->s_bdev); + mb_cache_shrink(sb->s_bdev); } /* diff --git a/fs/fcntl.c b/fs/fcntl.c index 286a9f8f3d4..6fbc9d8fcc3 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c @@ -288,7 +288,7 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg, break; case F_SETLK: case F_SETLKW: - err = fcntl_setlk(filp, cmd, (struct flock __user *) arg); + err = fcntl_setlk(fd, filp, cmd, (struct flock __user *) arg); break; case F_GETOWN: /* @@ -376,7 +376,8 @@ asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg break; case F_SETLK64: case F_SETLKW64: - err = fcntl_setlk64(filp, cmd, (struct flock64 __user *) arg); + err = fcntl_setlk64(fd, filp, cmd, + (struct flock64 __user *) arg); break; default: err = do_fcntl(fd, cmd, arg, filp); diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c index fc589ddd076..456d7e6e29c 100644 --- a/fs/jffs/intrep.c +++ b/fs/jffs/intrep.c @@ -3397,6 +3397,9 @@ jffs_garbage_collect_thread(void *ptr) siginfo_t info; unsigned long signr = 0; + if (try_to_freeze()) + continue; + spin_lock_irq(¤t->sighand->siglock); signr = dequeue_signal(current, ¤t->blocked, &info); spin_unlock_irq(¤t->sighand->siglock); diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 0732f206ca6..c739626f5bf 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -75,7 +75,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, int nblocks); static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval); static void dbBackSplit(dmtree_t * tp, int leafno); -static void dbJoin(dmtree_t * tp, int leafno, int newval); +static int dbJoin(dmtree_t * tp, int leafno, int newval); static void dbAdjTree(dmtree_t * tp, int leafno, int newval); static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level); @@ -98,8 +98,8 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks); static int dbFindBits(u32 word, int l2nb); static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno); static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx); -static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, - int nblocks); +static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, + int nblocks); static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, int nblocks); static int dbMaxBud(u8 * cp); @@ -378,6 +378,7 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks) /* free the blocks. */ if ((rc = dbFreeDmap(bmp, dp, blkno, nb))) { + jfs_error(ip->i_sb, "dbFree: error in block map\n"); release_metapage(mp); IREAD_UNLOCK(ipbmap); return (rc); @@ -2020,7 +2021,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, int nblocks) { s8 oldroot; - int rc, word; + int rc = 0, word; /* save the current value of the root (i.e. maximum free string) * of the dmap tree. @@ -2028,11 +2029,11 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, oldroot = dp->tree.stree[ROOT]; /* free the specified (blocks) bits */ - dbFreeBits(bmp, dp, blkno, nblocks); + rc = dbFreeBits(bmp, dp, blkno, nblocks); - /* if the root has not changed, done. */ - if (dp->tree.stree[ROOT] == oldroot) - return (0); + /* if error or the root has not changed, done. */ + if (rc || (dp->tree.stree[ROOT] == oldroot)) + return (rc); /* root changed. bubble the change up to the dmap control pages. * if the adjustment of the upper level control pages fails, @@ -2221,15 +2222,16 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, * blkno - starting block number of the bits to be freed. * nblocks - number of bits to be freed. * - * RETURN VALUES: none + * RETURN VALUES: 0 for success * * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; */ -static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, +static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, int nblocks) { int dbitno, word, rembits, nb, nwords, wbitno, nw, agno; dmtree_t *tp = (dmtree_t *) & dp->tree; + int rc = 0; int size; /* determine the bit number and word within the dmap of the @@ -2278,8 +2280,10 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, /* update the leaf for this dmap word. */ - dbJoin(tp, word, - dbMaxBud((u8 *) & dp->wmap[word])); + rc = dbJoin(tp, word, + dbMaxBud((u8 *) & dp->wmap[word])); + if (rc) + return rc; word += 1; } else { @@ -2310,7 +2314,9 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, /* update the leaf. */ - dbJoin(tp, word, size); + rc = dbJoin(tp, word, size); + if (rc) + return rc; /* get the number of dmap words handled. */ @@ -2357,6 +2363,8 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, } BMAP_UNLOCK(bmp); + + return 0; } @@ -2464,7 +2472,9 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level) } dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval); } else { - dbJoin((dmtree_t *) dcp, leafno, newval); + rc = dbJoin((dmtree_t *) dcp, leafno, newval); + if (rc) + return rc; } /* check if the root of the current dmap control page changed due @@ -2689,7 +2699,7 @@ static void dbBackSplit(dmtree_t * tp, int leafno) * * RETURN VALUES: none */ -static void dbJoin(dmtree_t * tp, int leafno, int newval) +static int dbJoin(dmtree_t * tp, int leafno, int newval) { int budsz, buddy; s8 *leaf; @@ -2729,7 +2739,9 @@ static void dbJoin(dmtree_t * tp, int leafno, int newval) if (newval > leaf[buddy]) break; - assert(newval == leaf[buddy]); + /* It shouldn't be less */ + if (newval < leaf[buddy]) + return -EIO; /* check which (leafno or buddy) is the left buddy. * the left buddy gets to claim the blocks resulting @@ -2761,6 +2773,8 @@ static void dbJoin(dmtree_t * tp, int leafno, int newval) /* update the leaf value. */ dbAdjTree(tp, leafno, newval); + + return 0; } diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c index 73b5fc7eda8..404f33eae50 100644 --- a/fs/jfs/jfs_dtree.c +++ b/fs/jfs/jfs_dtree.c @@ -381,9 +381,12 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) * It's time to move the inline table to an external * page and begin to build the xtree */ - if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage) || - dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) - goto clean_up; /* No space */ + if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage)) + goto clean_up; + if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr)) { + DQUOT_FREE_BLOCK(ip, sbi->nbperpage); + goto clean_up; + } /* * Save the table, we're going to overwrite it with the @@ -397,13 +400,15 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) xtInitRoot(tid, ip); /* - * Allocate the first block & add it to the xtree + * Add the first block to the xtree */ if (xtInsert(tid, ip, 0, 0, sbi->nbperpage, &xaddr, 0)) { /* This really shouldn't fail */ jfs_warn("add_index: xtInsert failed!"); memcpy(&jfs_ip->i_dirtable, temp_table, sizeof (temp_table)); + dbFree(ip, xaddr, sbi->nbperpage); + DQUOT_FREE_BLOCK(ip, sbi->nbperpage); goto clean_up; } ip->i_size = PSIZE; diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 79d07624bfe..22815e88e7c 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -1030,7 +1030,8 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait) * starting until all current transactions are completed * by setting syncbarrier flag. */ - if (written > LOGSYNC_BARRIER(logsize) && logsize > 32 * LOGPSIZE) { + if (!test_bit(log_SYNCBARRIER, &log->flag) && + (written > LOGSYNC_BARRIER(logsize)) && log->active) { set_bit(log_SYNCBARRIER, &log->flag); jfs_info("log barrier on: lsn=0x%x syncpt=0x%x", lsn, log->syncpt); diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c index 6c5485d16c3..13d7e3f1feb 100644 --- a/fs/jfs/jfs_metapage.c +++ b/fs/jfs/jfs_metapage.c @@ -561,7 +561,6 @@ static int metapage_releasepage(struct page *page, int gfp_mask) dump_mem("page", page, sizeof(struct page)); dump_stack(); } - WARN_ON(mp->lsn); if (mp->lsn) remove_from_logsync(mp); remove_metapage(page, mp); @@ -641,7 +640,7 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, } else { page = read_cache_page(mapping, page_index, (filler_t *)mapping->a_ops->readpage, NULL); - if (IS_ERR(page)) { + if (IS_ERR(page) || !PageUptodate(page)) { jfs_err("read_cache_page failed!"); return NULL; } @@ -783,14 +782,6 @@ void release_metapage(struct metapage * mp) if (test_bit(META_discard, &mp->flag) && !mp->count) { clear_page_dirty(page); ClearPageUptodate(page); -#ifdef _NOT_YET - if (page->mapping) { - /* Remove from page cache and page cache reference */ - remove_from_page_cache(page); - page_cache_release(page); - metapage_releasepage(page, 0); - } -#endif } #else /* Try to keep metapages from using up too much memory */ diff --git a/fs/locks.c b/fs/locks.c index 29fa5da6c11..11956b6179f 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1591,7 +1591,8 @@ out: /* Apply the lock described by l to an open file descriptor. * This implements both the F_SETLK and F_SETLKW commands of fcntl(). */ -int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock __user *l) +int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd, + struct flock __user *l) { struct file_lock *file_lock = locks_alloc_lock(); struct flock flock; @@ -1620,6 +1621,7 @@ int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock __user *l) goto out; } +again: error = flock_to_posix_lock(filp, file_lock, &flock); if (error) goto out; @@ -1648,25 +1650,33 @@ int fcntl_setlk(struct file *filp, unsigned int cmd, struct flock __user *l) if (error) goto out; - if (filp->f_op && filp->f_op->lock != NULL) { + if (filp->f_op && filp->f_op->lock != NULL) error = filp->f_op->lock(filp, cmd, file_lock); - goto out; - } + else { + for (;;) { + error = __posix_lock_file(inode, file_lock); + if ((error != -EAGAIN) || (cmd == F_SETLK)) + break; + error = wait_event_interruptible(file_lock->fl_wait, + !file_lock->fl_next); + if (!error) + continue; - for (;;) { - error = __posix_lock_file(inode, file_lock); - if ((error != -EAGAIN) || (cmd == F_SETLK)) + locks_delete_block(file_lock); break; - error = wait_event_interruptible(file_lock->fl_wait, - !file_lock->fl_next); - if (!error) - continue; + } + } - locks_delete_block(file_lock); - break; + /* + * Attempt to detect a close/fcntl race and recover by + * releasing the lock that was just acquired. + */ + if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { + flock.l_type = F_UNLCK; + goto again; } - out: +out: locks_free_lock(file_lock); return error; } @@ -1724,7 +1734,8 @@ out: /* Apply the lock described by l to an open file descriptor. * This implements both the F_SETLK and F_SETLKW commands of fcntl(). */ -int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) +int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd, + struct flock64 __user *l) { struct file_lock *file_lock = locks_alloc_lock(); struct flock64 flock; @@ -1753,6 +1764,7 @@ int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) goto out; } +again: error = flock64_to_posix_lock(filp, file_lock, &flock); if (error) goto out; @@ -1781,22 +1793,30 @@ int fcntl_setlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l) if (error) goto out; - if (filp->f_op && filp->f_op->lock != NULL) { + if (filp->f_op && filp->f_op->lock != NULL) error = filp->f_op->lock(filp, cmd, file_lock); - goto out; - } + else { + for (;;) { + error = __posix_lock_file(inode, file_lock); + if ((error != -EAGAIN) || (cmd == F_SETLK64)) + break; + error = wait_event_interruptible(file_lock->fl_wait, + !file_lock->fl_next); + if (!error) + continue; - for (;;) { - error = __posix_lock_file(inode, file_lock); - if ((error != -EAGAIN) || (cmd == F_SETLK64)) + locks_delete_block(file_lock); break; - error = wait_event_interruptible(file_lock->fl_wait, - !file_lock->fl_next); - if (!error) - continue; + } + } - locks_delete_block(file_lock); - break; + /* + * Attempt to detect a close/fcntl race and recover by + * releasing the lock that was just acquired. + */ + if (!error && fcheck(fd) != filp && flock.l_type != F_UNLCK) { + flock.l_type = F_UNLCK; + goto again; } out: @@ -1888,12 +1908,7 @@ void locks_remove_flock(struct file *filp) while ((fl = *before) != NULL) { if (fl->fl_file == filp) { - /* - * We might have a POSIX lock that was created at the same time - * the filp was closed for the last time. Just remove that too, - * regardless of ownership, since nobody can own it. - */ - if (IS_FLOCK(fl) || IS_POSIX(fl)) { + if (IS_FLOCK(fl)) { locks_delete_lock(before); continue; } diff --git a/fs/mbcache.c b/fs/mbcache.c index c7170b9221a..b002a088857 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c @@ -316,11 +316,10 @@ fail: * currently in use cannot be freed, and thus remain in the cache. All others * are freed. * - * @cache: which cache to shrink * @bdev: which device's cache entries to shrink */ void -mb_cache_shrink(struct mb_cache *cache, struct block_device *bdev) +mb_cache_shrink(struct block_device *bdev) { LIST_HEAD(free_list); struct list_head *l, *ltmp; diff --git a/fs/ntfs/sysctl.h b/fs/ntfs/sysctl.h index df749cc0aac..c8064cae8f1 100644 --- a/fs/ntfs/sysctl.h +++ b/fs/ntfs/sysctl.h @@ -26,7 +26,7 @@ #include <linux/config.h> -#if (DEBUG && CONFIG_SYSCTL) +#if defined(DEBUG) && defined(CONFIG_SYSCTL) extern int ntfs_sysctl(int add); diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 1aaf2c7d44e..d9f614a5773 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c @@ -1980,7 +1980,17 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, out_inserted_sd: inode->i_nlink = 0; th->t_trans_id = 0; /* so the caller can't use this handle later */ - iput(inode); + + /* If we were inheriting an ACL, we need to release the lock so that + * iput doesn't deadlock in reiserfs_delete_xattrs. The locking + * code really needs to be reworked, but this will take care of it + * for now. -jeffm */ + if (REISERFS_I(dir)->i_acl_default) { + reiserfs_write_unlock_xattrs(dir->i_sb); + iput(inode); + reiserfs_write_lock_xattrs(dir->i_sb); + } else + iput(inode); return err; } diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index c66c27ec410..ca7989b04be 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -556,14 +556,14 @@ static inline void insert_journal_hash(struct reiserfs_journal_cnode **table, } /* lock the current transaction */ -inline static void lock_journal(struct super_block *p_s_sb) +static inline void lock_journal(struct super_block *p_s_sb) { PROC_INFO_INC(p_s_sb, journal.lock_journal); down(&SB_JOURNAL(p_s_sb)->j_lock); } /* unlock the current transaction */ -inline static void unlock_journal(struct super_block *p_s_sb) +static inline void unlock_journal(struct super_block *p_s_sb) { up(&SB_JOURNAL(p_s_sb)->j_lock); } diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index e386d3db305..87ac9dc8b38 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c @@ -39,7 +39,6 @@ #include <linux/xattr.h> #include <linux/reiserfs_xattr.h> #include <linux/reiserfs_acl.h> -#include <linux/mbcache.h> #include <asm/uaccess.h> #include <asm/checksum.h> #include <linux/smp_lock.h> |