Commit 8c5a65c6 authored by Dave Kleikamp's avatar Dave Kleikamp

Merge jfs@jfs.bkbits.net:linux-2.5

into kleikamp.austin.ibm.com:/home/shaggy/bk/jfs-2.5
parents ddc729d4 3324836f
......@@ -66,6 +66,7 @@
#include <linux/completion.h>
#include <linux/buffer_head.h> /* for sync_blockdev() */
#include <linux/bio.h>
#include <linux/suspend.h>
#include "jfs_incore.h"
#include "jfs_filsys.h"
#include "jfs_metapage.h"
......@@ -2146,12 +2147,17 @@ int jfsIOWait(void *arg)
lbmStartIO(bp);
spin_lock_irq(&log_redrive_lock);
}
if (current->flags & PF_FREEZE) {
spin_unlock_irq(&log_redrive_lock);
refrigerator(PF_IOTHREAD);
} 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);
jFYI(1,("jfsIOWait being killed!\n"));
......
......@@ -47,6 +47,7 @@
#include <linux/vmalloc.h>
#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <linux/suspend.h>
#include "jfs_incore.h"
#include "jfs_filsys.h"
#include "jfs_metapage.h"
......@@ -2789,8 +2790,6 @@ int jfs_lazycommit(void *arg)
complete(&jfsIOwait);
do {
DECLARE_WAITQUEUE(wq, current);
LAZY_LOCK(flags);
restart:
WorkDone = 0;
......@@ -2825,12 +2824,19 @@ int jfs_lazycommit(void *arg)
if (WorkDone)
goto restart;
if (current->flags & PF_FREEZE) {
LAZY_UNLOCK(flags);
refrigerator(PF_IOTHREAD);
} else {
DECLARE_WAITQUEUE(wq, current);
add_wait_queue(&jfs_commit_thread_wait, &wq);
set_current_state(TASK_INTERRUPTIBLE);
LAZY_UNLOCK(flags);
schedule();
current->state = TASK_RUNNING;
remove_wait_queue(&jfs_commit_thread_wait, &wq);
}
} while (!jfs_stop_threads);
if (TxAnchor.unlock_queue)
......@@ -2981,7 +2987,6 @@ int jfs_sync(void *arg)
complete(&jfsIOwait);
do {
DECLARE_WAITQUEUE(wq, current);
/*
* write each inode on the anonymous inode list
*/
......@@ -3030,12 +3035,20 @@ int jfs_sync(void *arg)
}
/* Add anon_list2 back to anon_list */
list_splice_init(&TxAnchor.anon_list2, &TxAnchor.anon_list);
if (current->flags & PF_FREEZE) {
TXN_UNLOCK();
refrigerator(PF_IOTHREAD);
} 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);
jFYI(1, ("jfs_sync being killed\n"));
......
......@@ -78,6 +78,68 @@ struct ea_buffer {
#define EA_NEW 0x0004
#define EA_MALLOC 0x0008
/* Namespaces */
#define XATTR_SYSTEM_PREFIX "system."
#define XATTR_SYSTEM_PREFIX_LEN (sizeof (XATTR_SYSTEM_PREFIX) - 1)
#define XATTR_USER_PREFIX "user."
#define XATTR_USER_PREFIX_LEN (sizeof (XATTR_USER_PREFIX) - 1)
#define XATTR_OS2_PREFIX "os2."
#define XATTR_OS2_PREFIX_LEN (sizeof (XATTR_OS2_PREFIX) - 1)
/*
* These three routines are used to recognize on-disk extended attributes
* that are in a recognized namespace. If the attribute is not recognized,
* "os2." is prepended to the name
*/
static inline int is_os2_xattr(struct jfs_ea *ea)
{
/*
* Check for "system."
*/
if ((ea->namelen >= XATTR_SYSTEM_PREFIX_LEN) &&
!strncmp(ea->name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN))
return FALSE;
/*
* Check for "user."
*/
if ((ea->namelen >= XATTR_USER_PREFIX_LEN) &&
!strncmp(ea->name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN))
return FALSE;
/*
* Add any other valid namespace prefixes here
*/
/*
* We assume it's OS/2's flat namespace
*/
return TRUE;
}
static inline int name_size(struct jfs_ea *ea)
{
if (is_os2_xattr(ea))
return ea->namelen + XATTR_OS2_PREFIX_LEN;
else
return ea->namelen;
}
static inline int copy_name(char *buffer, struct jfs_ea *ea)
{
int len = ea->namelen;
if (is_os2_xattr(ea)) {
memcpy(buffer, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN);
buffer += XATTR_OS2_PREFIX_LEN;
len += XATTR_OS2_PREFIX_LEN;
}
memcpy(buffer, ea->name, ea->namelen);
buffer[ea->namelen] = 0;
return len;
}
/* Forward references */
static void ea_release(struct inode *inode, struct ea_buffer *ea_buf);
......@@ -577,7 +639,8 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size)
return rc;
}
static int can_set_xattr(struct inode *inode, const char *name)
static int can_set_xattr(struct inode *inode, const char *name,
const void *value, size_t value_len)
{
if (IS_RDONLY(inode))
return -EROFS;
......@@ -585,6 +648,10 @@ static int can_set_xattr(struct inode *inode, const char *name)
if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || S_ISLNK(inode->i_mode))
return -EPERM;
if((strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN) != 0) &&
(strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) != 0))
return -ENOTSUP;
if (!S_ISREG(inode->i_mode) &&
(!S_ISDIR(inode->i_mode) || inode->i_mode &S_ISVTX))
return -EPERM;
......@@ -592,7 +659,7 @@ static int can_set_xattr(struct inode *inode, const char *name)
return permission(inode, MAY_WRITE);
}
int __jfs_setxattr(struct inode *inode, const char *name, void *value,
int __jfs_setxattr(struct inode *inode, const char *name, const void *value,
size_t value_len, int flags)
{
struct jfs_ea_list *ealist;
......@@ -602,13 +669,24 @@ int __jfs_setxattr(struct inode *inode, const char *name, void *value,
int xattr_size;
int new_size;
int namelen = strlen(name);
char *os2name = NULL;
int found = 0;
int rc;
int length;
if ((rc = can_set_xattr(inode, name)))
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);
if (!os2name)
return -ENOMEM;
strcpy(os2name, name + XATTR_OS2_PREFIX_LEN);
name = os2name;
namelen -= XATTR_OS2_PREFIX_LEN;
}
xattr_size = ea_get(inode, &ea_buf, 0);
if (xattr_size < 0) {
rc = xattr_size;
......@@ -714,10 +792,13 @@ int __jfs_setxattr(struct inode *inode, const char *name, void *value,
release:
ea_release(inode, &ea_buf);
out:
if (os2name)
kfree(os2name);
return rc;
}
int jfs_setxattr(struct dentry *dentry, const char *name, void *value,
int jfs_setxattr(struct dentry *dentry, const char *name, const void *value,
size_t value_len, int flags)
{
if (value == NULL) { /* empty EA, do not remove */
......@@ -728,7 +809,7 @@ int jfs_setxattr(struct dentry *dentry, const char *name, void *value,
return __jfs_setxattr(dentry->d_inode, name, value, value_len, flags);
}
static int can_get_xattr(struct inode *inode, const char *name)
static inline int can_get_xattr(struct inode *inode, const char *name)
{
return permission(inode, MAY_READ);
}
......@@ -742,12 +823,23 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
int xattr_size;
ssize_t size;
int namelen = strlen(name);
char *os2name = NULL;
int rc;
char *value;
if ((rc = can_get_xattr(inode, name)))
return rc;
if (strncmp(name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
os2name = kmalloc(namelen - XATTR_OS2_PREFIX_LEN + 1,
GFP_KERNEL);
if (!os2name)
return -ENOMEM;
strcpy(os2name, name + XATTR_OS2_PREFIX_LEN);
name = os2name;
namelen -= XATTR_OS2_PREFIX_LEN;
}
xattr_size = ea_get(inode, &ea_buf, 0);
if (xattr_size < 0) {
size = xattr_size;
......@@ -780,6 +872,8 @@ ssize_t __jfs_getxattr(struct inode *inode, const char *name, void *data,
release:
ea_release(inode, &ea_buf);
out:
if (os2name)
kfree(os2name);
return size;
}
......@@ -813,7 +907,7 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
/* compute required size of list */
for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea))
size += ea->namelen + 1;
size += name_size(ea) + 1;
if (!data)
goto release;
......@@ -826,9 +920,8 @@ ssize_t jfs_listxattr(struct dentry * dentry, char *data, size_t buf_size)
/* Copy attribute names to buffer */
buffer = data;
for (ea = FIRST_EA(ealist); ea < END_EALIST(ealist); ea = NEXT_EA(ea)) {
memcpy(buffer, ea->name, ea->namelen);
buffer[ea->namelen] = 0;
buffer += ea->namelen + 1;
int namelen = copy_name(buffer, ea);
buffer += namelen + 1;
}
release:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment