Merge branch 'for-linus' from kernel.org:/.../shaggy/jfs-2.6 manually

Clash due to new delete_inode behavior (the filesystem now needs to do
the truncate_inode_pages() call itself).

Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Linus Torvalds 2005-09-11 10:14:54 -07:00
commit 32983696a4
6 changed files with 193 additions and 62 deletions

View file

@ -23,6 +23,7 @@
#include <linux/quotaops.h> #include <linux/quotaops.h>
#include <linux/posix_acl_xattr.h> #include <linux/posix_acl_xattr.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_txnmgr.h"
#include "jfs_xattr.h" #include "jfs_xattr.h"
#include "jfs_acl.h" #include "jfs_acl.h"
@ -75,7 +76,8 @@ static struct posix_acl *jfs_get_acl(struct inode *inode, int type)
return acl; return acl;
} }
static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl) static int jfs_set_acl(tid_t tid, struct inode *inode, int type,
struct posix_acl *acl)
{ {
char *ea_name; char *ea_name;
struct jfs_inode_info *ji = JFS_IP(inode); struct jfs_inode_info *ji = JFS_IP(inode);
@ -110,7 +112,7 @@ static int jfs_set_acl(struct inode *inode, int type, struct posix_acl *acl)
if (rc < 0) if (rc < 0)
goto out; goto out;
} }
rc = __jfs_setxattr(inode, ea_name, value, size, 0); rc = __jfs_setxattr(tid, inode, ea_name, value, size, 0);
out: out:
kfree(value); kfree(value);
@ -143,7 +145,7 @@ int jfs_permission(struct inode *inode, int mask, struct nameidata *nd)
return generic_permission(inode, mask, jfs_check_acl); return generic_permission(inode, mask, jfs_check_acl);
} }
int jfs_init_acl(struct inode *inode, struct inode *dir) int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir)
{ {
struct posix_acl *acl = NULL; struct posix_acl *acl = NULL;
struct posix_acl *clone; struct posix_acl *clone;
@ -159,7 +161,7 @@ int jfs_init_acl(struct inode *inode, struct inode *dir)
if (acl) { if (acl) {
if (S_ISDIR(inode->i_mode)) { if (S_ISDIR(inode->i_mode)) {
rc = jfs_set_acl(inode, ACL_TYPE_DEFAULT, acl); rc = jfs_set_acl(tid, inode, ACL_TYPE_DEFAULT, acl);
if (rc) if (rc)
goto cleanup; goto cleanup;
} }
@ -173,7 +175,8 @@ int jfs_init_acl(struct inode *inode, struct inode *dir)
if (rc >= 0) { if (rc >= 0) {
inode->i_mode = mode; inode->i_mode = mode;
if (rc > 0) if (rc > 0)
rc = jfs_set_acl(inode, ACL_TYPE_ACCESS, clone); rc = jfs_set_acl(tid, inode, ACL_TYPE_ACCESS,
clone);
} }
posix_acl_release(clone); posix_acl_release(clone);
cleanup: cleanup:
@ -202,8 +205,15 @@ static int jfs_acl_chmod(struct inode *inode)
return -ENOMEM; return -ENOMEM;
rc = posix_acl_chmod_masq(clone, inode->i_mode); rc = posix_acl_chmod_masq(clone, inode->i_mode);
if (!rc) if (!rc) {
rc = jfs_set_acl(inode, ACL_TYPE_ACCESS, clone); tid_t tid = txBegin(inode->i_sb, 0);
down(&JFS_IP(inode)->commit_sem);
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);
}
posix_acl_release(clone); posix_acl_release(clone);
return rc; return rc;

View file

@ -128,23 +128,23 @@ void jfs_delete_inode(struct inode *inode)
{ {
jfs_info("In jfs_delete_inode, inode = 0x%p", inode); jfs_info("In jfs_delete_inode, inode = 0x%p", inode);
if (is_bad_inode(inode) || if (!is_bad_inode(inode) &&
(JFS_IP(inode)->fileset != cpu_to_le32(FILESYSTEM_I))) (JFS_IP(inode)->fileset == cpu_to_le32(FILESYSTEM_I))) {
return;
truncate_inode_pages(&inode->i_data, 0); truncate_inode_pages(&inode->i_data, 0);
if (test_cflag(COMMIT_Freewmap, inode)) if (test_cflag(COMMIT_Freewmap, inode))
jfs_free_zero_link(inode); jfs_free_zero_link(inode);
diFree(inode); diFree(inode);
/* /*
* Free the inode from the quota allocation. * Free the inode from the quota allocation.
*/ */
DQUOT_INIT(inode); DQUOT_INIT(inode);
DQUOT_FREE_INODE(inode); DQUOT_FREE_INODE(inode);
DQUOT_DROP(inode); DQUOT_DROP(inode);
}
clear_inode(inode); clear_inode(inode);
} }

View file

@ -21,8 +21,16 @@
#ifdef CONFIG_JFS_POSIX_ACL #ifdef CONFIG_JFS_POSIX_ACL
int jfs_permission(struct inode *, int, struct nameidata *); int jfs_permission(struct inode *, int, struct nameidata *);
int jfs_init_acl(struct inode *, struct inode *); int jfs_init_acl(tid_t, struct inode *, struct inode *);
int jfs_setattr(struct dentry *, struct iattr *); int jfs_setattr(struct dentry *, struct iattr *);
#endif /* CONFIG_JFS_POSIX_ACL */ #else
static inline int jfs_init_acl(tid_t tid, struct inode *inode,
struct inode *dir)
{
return 0;
}
#endif
#endif /* _H_JFS_ACL */ #endif /* _H_JFS_ACL */

View file

@ -52,8 +52,8 @@ struct jfs_ea_list {
#define END_EALIST(ealist) \ #define END_EALIST(ealist) \
((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist))) ((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist)))
extern int __jfs_setxattr(struct inode *, const char *, const void *, size_t, extern int __jfs_setxattr(tid_t, struct inode *, const char *, const void *,
int); size_t, int);
extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t, extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t,
int); int);
extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t); extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t);
@ -61,4 +61,14 @@ extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t);
extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); extern ssize_t jfs_listxattr(struct dentry *, char *, size_t);
extern int jfs_removexattr(struct dentry *, const char *); extern int jfs_removexattr(struct dentry *, const char *);
#ifdef CONFIG_JFS_SECURITY
extern int jfs_init_security(tid_t, struct inode *, struct inode *);
#else
static inline int jfs_init_security(tid_t tid, struct inode *inode,
struct inode *dir)
{
return 0;
}
#endif
#endif /* H_JFS_XATTR */ #endif /* H_JFS_XATTR */

View file

@ -38,6 +38,24 @@ struct dentry_operations jfs_ci_dentry_operations;
static s64 commitZeroLink(tid_t, struct inode *); static s64 commitZeroLink(tid_t, struct inode *);
/*
* NAME: free_ea_wmap(inode)
*
* FUNCTION: free uncommitted extended attributes from working map
*
*/
static inline void free_ea_wmap(struct inode *inode)
{
dxd_t *ea = &JFS_IP(inode)->ea;
if (ea->flag & DXD_EXTENT) {
/* free EA pages from cache */
invalidate_dxd_metapages(inode, *ea);
dbFree(inode, addressDXD(ea), lengthDXD(ea));
}
ea->flag = 0;
}
/* /*
* NAME: jfs_create(dip, dentry, mode) * NAME: jfs_create(dip, dentry, mode)
* *
@ -89,8 +107,19 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
down(&JFS_IP(dip)->commit_sem); down(&JFS_IP(dip)->commit_sem);
down(&JFS_IP(ip)->commit_sem); down(&JFS_IP(ip)->commit_sem);
rc = jfs_init_acl(tid, ip, dip);
if (rc)
goto out3;
rc = jfs_init_security(tid, ip, dip);
if (rc) {
txAbort(tid, 0);
goto out3;
}
if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
jfs_err("jfs_create: dtSearch returned %d", rc); jfs_err("jfs_create: dtSearch returned %d", rc);
txAbort(tid, 0);
goto out3; goto out3;
} }
@ -139,6 +168,7 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
up(&JFS_IP(dip)->commit_sem); up(&JFS_IP(dip)->commit_sem);
up(&JFS_IP(ip)->commit_sem); up(&JFS_IP(ip)->commit_sem);
if (rc) { if (rc) {
free_ea_wmap(ip);
ip->i_nlink = 0; ip->i_nlink = 0;
iput(ip); iput(ip);
} else } else
@ -147,11 +177,6 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
out2: out2:
free_UCSname(&dname); free_UCSname(&dname);
#ifdef CONFIG_JFS_POSIX_ACL
if (rc == 0)
jfs_init_acl(ip, dip);
#endif
out1: out1:
jfs_info("jfs_create: rc:%d", rc); jfs_info("jfs_create: rc:%d", rc);
@ -216,8 +241,19 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
down(&JFS_IP(dip)->commit_sem); down(&JFS_IP(dip)->commit_sem);
down(&JFS_IP(ip)->commit_sem); down(&JFS_IP(ip)->commit_sem);
rc = jfs_init_acl(tid, ip, dip);
if (rc)
goto out3;
rc = jfs_init_security(tid, ip, dip);
if (rc) {
txAbort(tid, 0);
goto out3;
}
if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) { if ((rc = dtSearch(dip, &dname, &ino, &btstack, JFS_CREATE))) {
jfs_err("jfs_mkdir: dtSearch returned %d", rc); jfs_err("jfs_mkdir: dtSearch returned %d", rc);
txAbort(tid, 0);
goto out3; goto out3;
} }
@ -267,6 +303,7 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
up(&JFS_IP(dip)->commit_sem); up(&JFS_IP(dip)->commit_sem);
up(&JFS_IP(ip)->commit_sem); up(&JFS_IP(ip)->commit_sem);
if (rc) { if (rc) {
free_ea_wmap(ip);
ip->i_nlink = 0; ip->i_nlink = 0;
iput(ip); iput(ip);
} else } else
@ -275,10 +312,6 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
out2: out2:
free_UCSname(&dname); free_UCSname(&dname);
#ifdef CONFIG_JFS_POSIX_ACL
if (rc == 0)
jfs_init_acl(ip, dip);
#endif
out1: out1:
@ -885,6 +918,10 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
down(&JFS_IP(dip)->commit_sem); down(&JFS_IP(dip)->commit_sem);
down(&JFS_IP(ip)->commit_sem); down(&JFS_IP(ip)->commit_sem);
rc = jfs_init_security(tid, ip, dip);
if (rc)
goto out3;
tblk = tid_to_tblock(tid); tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE; tblk->xflag |= COMMIT_CREATE;
tblk->ino = ip->i_ino; tblk->ino = ip->i_ino;
@ -1000,6 +1037,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
up(&JFS_IP(dip)->commit_sem); up(&JFS_IP(dip)->commit_sem);
up(&JFS_IP(ip)->commit_sem); up(&JFS_IP(ip)->commit_sem);
if (rc) { if (rc) {
free_ea_wmap(ip);
ip->i_nlink = 0; ip->i_nlink = 0;
iput(ip); iput(ip);
} else } else
@ -1008,11 +1046,6 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
out2: out2:
free_UCSname(&dname); free_UCSname(&dname);
#ifdef CONFIG_JFS_POSIX_ACL
if (rc == 0)
jfs_init_acl(ip, dip);
#endif
out1: out1:
jfs_info("jfs_symlink: rc:%d", rc); jfs_info("jfs_symlink: rc:%d", rc);
return rc; return rc;
@ -1328,17 +1361,31 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
down(&JFS_IP(dir)->commit_sem); down(&JFS_IP(dir)->commit_sem);
down(&JFS_IP(ip)->commit_sem); down(&JFS_IP(ip)->commit_sem);
if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) rc = jfs_init_acl(tid, ip, dir);
if (rc)
goto out3; goto out3;
rc = jfs_init_security(tid, ip, dir);
if (rc) {
txAbort(tid, 0);
goto out3;
}
if ((rc = dtSearch(dir, &dname, &ino, &btstack, JFS_CREATE))) {
txAbort(tid, 0);
goto out3;
}
tblk = tid_to_tblock(tid); tblk = tid_to_tblock(tid);
tblk->xflag |= COMMIT_CREATE; tblk->xflag |= COMMIT_CREATE;
tblk->ino = ip->i_ino; tblk->ino = ip->i_ino;
tblk->u.ixpxd = JFS_IP(ip)->ixpxd; tblk->u.ixpxd = JFS_IP(ip)->ixpxd;
ino = ip->i_ino; ino = ip->i_ino;
if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) if ((rc = dtInsert(tid, dir, &dname, &ino, &btstack))) {
txAbort(tid, 0);
goto out3; goto out3;
}
ip->i_op = &jfs_file_inode_operations; ip->i_op = &jfs_file_inode_operations;
jfs_ip->dev = new_encode_dev(rdev); jfs_ip->dev = new_encode_dev(rdev);
@ -1360,6 +1407,7 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
up(&JFS_IP(ip)->commit_sem); up(&JFS_IP(ip)->commit_sem);
up(&JFS_IP(dir)->commit_sem); up(&JFS_IP(dir)->commit_sem);
if (rc) { if (rc) {
free_ea_wmap(ip);
ip->i_nlink = 0; ip->i_nlink = 0;
iput(ip); iput(ip);
} else } else
@ -1368,11 +1416,6 @@ static int jfs_mknod(struct inode *dir, struct dentry *dentry,
out1: out1:
free_UCSname(&dname); free_UCSname(&dname);
#ifdef CONFIG_JFS_POSIX_ACL
if (rc == 0)
jfs_init_acl(ip, dir);
#endif
out: out:
jfs_info("jfs_mknod: returning %d", rc); jfs_info("jfs_mknod: returning %d", rc);
return rc; return rc;

View file

@ -21,6 +21,7 @@
#include <linux/xattr.h> #include <linux/xattr.h>
#include <linux/posix_acl_xattr.h> #include <linux/posix_acl_xattr.h>
#include <linux/quotaops.h> #include <linux/quotaops.h>
#include <linux/security.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_superblock.h" #include "jfs_superblock.h"
#include "jfs_dmap.h" #include "jfs_dmap.h"
@ -633,12 +634,12 @@ static void ea_release(struct inode *inode, struct ea_buffer *ea_buf)
} }
} }
static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) static int ea_put(tid_t tid, struct inode *inode, struct ea_buffer *ea_buf,
int new_size)
{ {
struct jfs_inode_info *ji = JFS_IP(inode); struct jfs_inode_info *ji = JFS_IP(inode);
unsigned long old_blocks, new_blocks; unsigned long old_blocks, new_blocks;
int rc = 0; int rc = 0;
tid_t tid;
if (new_size == 0) { if (new_size == 0) {
ea_release(inode, ea_buf); ea_release(inode, ea_buf);
@ -664,9 +665,6 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size)
if (rc) if (rc)
return rc; return rc;
tid = txBegin(inode->i_sb, 0);
down(&ji->commit_sem);
old_blocks = new_blocks = 0; old_blocks = new_blocks = 0;
if (ji->ea.flag & DXD_EXTENT) { if (ji->ea.flag & DXD_EXTENT) {
@ -695,11 +693,8 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size)
DQUOT_FREE_BLOCK(inode, old_blocks); DQUOT_FREE_BLOCK(inode, old_blocks);
inode->i_ctime = CURRENT_TIME; inode->i_ctime = CURRENT_TIME;
rc = txCommit(tid, 1, &inode, 0);
txEnd(tid);
up(&ji->commit_sem);
return rc; return 0;
} }
/* /*
@ -810,8 +805,8 @@ static int can_set_xattr(struct inode *inode, const char *name,
return permission(inode, MAY_WRITE, NULL); return permission(inode, MAY_WRITE, NULL);
} }
int __jfs_setxattr(struct inode *inode, const char *name, const void *value, int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name,
size_t value_len, int flags) const void *value, size_t value_len, int flags)
{ {
struct jfs_ea_list *ealist; struct jfs_ea_list *ealist;
struct jfs_ea *ea, *old_ea = NULL, *next_ea = NULL; struct jfs_ea *ea, *old_ea = NULL, *next_ea = NULL;
@ -825,9 +820,6 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
int rc; int rc;
int length; int length;
if ((rc = can_set_xattr(inode, name, value, value_len)))
return rc;
if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) { if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1, os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1,
GFP_KERNEL); GFP_KERNEL);
@ -939,7 +931,7 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
ealist->size = cpu_to_le32(new_size); ealist->size = cpu_to_le32(new_size);
rc = ea_put(inode, &ea_buf, new_size); rc = ea_put(tid, inode, &ea_buf, new_size);
goto out; goto out;
release: release:
@ -955,12 +947,29 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
size_t value_len, int flags) size_t value_len, int flags)
{ {
struct inode *inode = dentry->d_inode;
struct jfs_inode_info *ji = JFS_IP(inode);
int rc;
tid_t tid;
if ((rc = can_set_xattr(inode, name, value, value_len)))
return rc;
if (value == NULL) { /* empty EA, do not remove */ if (value == NULL) { /* empty EA, do not remove */
value = ""; value = "";
value_len = 0; value_len = 0;
} }
return __jfs_setxattr(dentry->d_inode, name, value, value_len, flags); tid = txBegin(inode->i_sb, 0);
down(&ji->commit_sem);
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);
return rc;
} }
static int can_get_xattr(struct inode *inode, const char *name) static int can_get_xattr(struct inode *inode, const char *name)
@ -1122,5 +1131,56 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
int jfs_removexattr(struct dentry *dentry, const char *name) int jfs_removexattr(struct dentry *dentry, const char *name)
{ {
return __jfs_setxattr(dentry->d_inode, name, NULL, 0, XATTR_REPLACE); struct inode *inode = dentry->d_inode;
struct jfs_inode_info *ji = JFS_IP(inode);
int rc;
tid_t tid;
if ((rc = can_set_xattr(inode, name, NULL, 0)))
return rc;
tid = txBegin(inode->i_sb, 0);
down(&ji->commit_sem);
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);
return rc;
} }
#ifdef CONFIG_JFS_SECURITY
int jfs_init_security(tid_t tid, struct inode *inode, struct inode *dir)
{
int rc;
size_t len;
void *value;
char *suffix;
char *name;
rc = security_inode_init_security(inode, dir, &suffix, &value, &len);
if (rc) {
if (rc == -EOPNOTSUPP)
return 0;
return rc;
}
name = kmalloc(XATTR_SECURITY_PREFIX_LEN + 1 + strlen(suffix),
GFP_NOFS);
if (!name) {
rc = -ENOMEM;
goto kmalloc_failed;
}
strcpy(name, XATTR_SECURITY_PREFIX);
strcpy(name + XATTR_SECURITY_PREFIX_LEN, suffix);
rc = __jfs_setxattr(tid, inode, name, value, len, 0);
kfree(name);
kmalloc_failed:
kfree(suffix);
kfree(value);
return rc;
}
#endif