diff options
author | Dave Kleikamp <shaggy@austin.ibm.com> | 2005-09-01 09:02:43 -0500 |
---|---|---|
committer | Dave Kleikamp <shaggy@austin.ibm.com> | 2005-09-01 09:02:43 -0500 |
commit | 4f4b401bfaa97edbea41a1fcab794148e7ac0421 (patch) | |
tree | d58dcf9d90e15364398a3a4584f2892439295b64 /fs/jfs/xattr.c | |
parent | b1b5d7f9b7ac6a8e3452ac43a53eebf69fdf5a77 (diff) | |
download | lwn-4f4b401bfaa97edbea41a1fcab794148e7ac0421.tar.gz lwn-4f4b401bfaa97edbea41a1fcab794148e7ac0421.zip |
JFS: allow extended attributes to be set within a existing transaction
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
Diffstat (limited to 'fs/jfs/xattr.c')
-rw-r--r-- | fs/jfs/xattr.c | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c index 554ec739e49b..35674b2a0e6c 100644 --- a/fs/jfs/xattr.c +++ b/fs/jfs/xattr.c @@ -633,12 +633,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); unsigned long old_blocks, new_blocks; int rc = 0; - tid_t tid; if (new_size == 0) { ea_release(inode, ea_buf); @@ -664,9 +664,6 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) if (rc) return rc; - tid = txBegin(inode->i_sb, 0); - down(&ji->commit_sem); - old_blocks = new_blocks = 0; if (ji->ea.flag & DXD_EXTENT) { @@ -695,11 +692,8 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) DQUOT_FREE_BLOCK(inode, old_blocks); inode->i_ctime = CURRENT_TIME; - rc = txCommit(tid, 1, &inode, 0); - txEnd(tid); - up(&ji->commit_sem); - return rc; + return 0; } /* @@ -810,8 +804,8 @@ static int can_set_xattr(struct inode *inode, const char *name, return permission(inode, MAY_WRITE, NULL); } -int __jfs_setxattr(struct inode *inode, const char *name, const void *value, - size_t value_len, int flags) +int __jfs_setxattr(tid_t tid, struct inode *inode, const char *name, + const void *value, size_t value_len, int flags) { struct jfs_ea_list *ealist; struct jfs_ea *ea, *old_ea = NULL, *next_ea = NULL; @@ -825,9 +819,6 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value, int rc; 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) { os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1, GFP_KERNEL); @@ -939,7 +930,7 @@ int __jfs_setxattr(struct inode *inode, const char *name, const void *value, 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; release: @@ -955,12 +946,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, 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 */ value = ""; 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) @@ -1122,5 +1130,21 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size) 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; } |