mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 03:06:10 +00:00
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2: ocfs2/trivial: Use le16_to_cpu for a disk value in xattr.c ocfs2/trivial: Use proper mask for 2 places in hearbeat.c Ocfs2: Let ocfs2 support fiemap for symlink and fast symlink. Ocfs2: Should ocfs2 support fiemap for S_IFDIR inode? ocfs2: Use FIEMAP_EXTENT_SHARED fiemap: Add new extent flag FIEMAP_EXTENT_SHARED ocfs2: replace u8 by __u8 in ocfs2_fs.h ocfs2: explicit declare uninitialized var in user_cluster_connect() ocfs2-devel: remove redundant OCFS2_MOUNT_POSIX_ACL check in ocfs2_get_acl_nolock() ocfs2: return -EAGAIN instead of EAGAIN in dlm ocfs2/cluster: Make fence method configurable - v2 ocfs2: Set MS_POSIXACL on remount ocfs2: Make acl use the default ocfs2: Always include ACL support
This commit is contained in:
commit
45e62974fb
19 changed files with 170 additions and 116 deletions
|
@ -6,6 +6,7 @@ config OCFS2_FS
|
||||||
select CRC32
|
select CRC32
|
||||||
select QUOTA
|
select QUOTA
|
||||||
select QUOTA_TREE
|
select QUOTA_TREE
|
||||||
|
select FS_POSIX_ACL
|
||||||
help
|
help
|
||||||
OCFS2 is a general purpose extent based shared disk cluster file
|
OCFS2 is a general purpose extent based shared disk cluster file
|
||||||
system with many similarities to ext3. It supports 64 bit inode
|
system with many similarities to ext3. It supports 64 bit inode
|
||||||
|
@ -74,12 +75,3 @@ config OCFS2_DEBUG_FS
|
||||||
This option will enable expensive consistency checks. Enable
|
This option will enable expensive consistency checks. Enable
|
||||||
this option for debugging only as it is likely to decrease
|
this option for debugging only as it is likely to decrease
|
||||||
performance of the filesystem.
|
performance of the filesystem.
|
||||||
|
|
||||||
config OCFS2_FS_POSIX_ACL
|
|
||||||
bool "OCFS2 POSIX Access Control Lists"
|
|
||||||
depends on OCFS2_FS
|
|
||||||
select FS_POSIX_ACL
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
Posix Access Control Lists (ACLs) support permissions for users and
|
|
||||||
groups beyond the owner/group/world scheme.
|
|
||||||
|
|
|
@ -39,11 +39,8 @@ ocfs2-objs := \
|
||||||
ver.o \
|
ver.o \
|
||||||
quota_local.o \
|
quota_local.o \
|
||||||
quota_global.o \
|
quota_global.o \
|
||||||
xattr.o
|
xattr.o \
|
||||||
|
acl.o
|
||||||
ifeq ($(CONFIG_OCFS2_FS_POSIX_ACL),y)
|
|
||||||
ocfs2-objs += acl.o
|
|
||||||
endif
|
|
||||||
|
|
||||||
ocfs2_stackglue-objs := stackglue.o
|
ocfs2_stackglue-objs := stackglue.o
|
||||||
ocfs2_stack_o2cb-objs := stack_o2cb.o
|
ocfs2_stack_o2cb-objs := stack_o2cb.o
|
||||||
|
|
|
@ -98,15 +98,11 @@ static struct posix_acl *ocfs2_get_acl_nolock(struct inode *inode,
|
||||||
int type,
|
int type,
|
||||||
struct buffer_head *di_bh)
|
struct buffer_head *di_bh)
|
||||||
{
|
{
|
||||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
|
||||||
int name_index;
|
int name_index;
|
||||||
char *value = NULL;
|
char *value = NULL;
|
||||||
struct posix_acl *acl;
|
struct posix_acl *acl;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
if (!(osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ACL_TYPE_ACCESS:
|
case ACL_TYPE_ACCESS:
|
||||||
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
|
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
|
||||||
|
|
|
@ -26,8 +26,6 @@ struct ocfs2_acl_entry {
|
||||||
__le32 e_id;
|
__le32 e_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_OCFS2_FS_POSIX_ACL
|
|
||||||
|
|
||||||
extern int ocfs2_check_acl(struct inode *, int);
|
extern int ocfs2_check_acl(struct inode *, int);
|
||||||
extern int ocfs2_acl_chmod(struct inode *);
|
extern int ocfs2_acl_chmod(struct inode *);
|
||||||
extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *,
|
extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *,
|
||||||
|
@ -35,24 +33,4 @@ extern int ocfs2_init_acl(handle_t *, struct inode *, struct inode *,
|
||||||
struct ocfs2_alloc_context *,
|
struct ocfs2_alloc_context *,
|
||||||
struct ocfs2_alloc_context *);
|
struct ocfs2_alloc_context *);
|
||||||
|
|
||||||
#else /* CONFIG_OCFS2_FS_POSIX_ACL*/
|
|
||||||
|
|
||||||
#define ocfs2_check_acl NULL
|
|
||||||
static inline int ocfs2_acl_chmod(struct inode *inode)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
static inline int ocfs2_init_acl(handle_t *handle,
|
|
||||||
struct inode *inode,
|
|
||||||
struct inode *dir,
|
|
||||||
struct buffer_head *di_bh,
|
|
||||||
struct buffer_head *dir_bh,
|
|
||||||
struct ocfs2_alloc_context *meta_ac,
|
|
||||||
struct ocfs2_alloc_context *data_ac)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* CONFIG_OCFS2_FS_POSIX_ACL*/
|
|
||||||
|
|
||||||
#endif /* OCFS2_ACL_H */
|
#endif /* OCFS2_ACL_H */
|
||||||
|
|
|
@ -176,7 +176,8 @@ static void o2hb_write_timeout(struct work_struct *work)
|
||||||
|
|
||||||
static void o2hb_arm_write_timeout(struct o2hb_region *reg)
|
static void o2hb_arm_write_timeout(struct o2hb_region *reg)
|
||||||
{
|
{
|
||||||
mlog(0, "Queue write timeout for %u ms\n", O2HB_MAX_WRITE_TIMEOUT_MS);
|
mlog(ML_HEARTBEAT, "Queue write timeout for %u ms\n",
|
||||||
|
O2HB_MAX_WRITE_TIMEOUT_MS);
|
||||||
|
|
||||||
cancel_delayed_work(®->hr_write_timeout_work);
|
cancel_delayed_work(®->hr_write_timeout_work);
|
||||||
reg->hr_last_timeout_start = jiffies;
|
reg->hr_last_timeout_start = jiffies;
|
||||||
|
@ -874,7 +875,8 @@ static int o2hb_thread(void *data)
|
||||||
do_gettimeofday(&after_hb);
|
do_gettimeofday(&after_hb);
|
||||||
elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb);
|
elapsed_msec = o2hb_elapsed_msecs(&before_hb, &after_hb);
|
||||||
|
|
||||||
mlog(0, "start = %lu.%lu, end = %lu.%lu, msec = %u\n",
|
mlog(ML_HEARTBEAT,
|
||||||
|
"start = %lu.%lu, end = %lu.%lu, msec = %u\n",
|
||||||
before_hb.tv_sec, (unsigned long) before_hb.tv_usec,
|
before_hb.tv_sec, (unsigned long) before_hb.tv_usec,
|
||||||
after_hb.tv_sec, (unsigned long) after_hb.tv_usec,
|
after_hb.tv_sec, (unsigned long) after_hb.tv_usec,
|
||||||
elapsed_msec);
|
elapsed_msec);
|
||||||
|
|
|
@ -35,6 +35,10 @@
|
||||||
* cluster references throughout where nodes are looked up */
|
* cluster references throughout where nodes are looked up */
|
||||||
struct o2nm_cluster *o2nm_single_cluster = NULL;
|
struct o2nm_cluster *o2nm_single_cluster = NULL;
|
||||||
|
|
||||||
|
char *o2nm_fence_method_desc[O2NM_FENCE_METHODS] = {
|
||||||
|
"reset", /* O2NM_FENCE_RESET */
|
||||||
|
"panic", /* O2NM_FENCE_PANIC */
|
||||||
|
};
|
||||||
|
|
||||||
struct o2nm_node *o2nm_get_node_by_num(u8 node_num)
|
struct o2nm_node *o2nm_get_node_by_num(u8 node_num)
|
||||||
{
|
{
|
||||||
|
@ -579,6 +583,43 @@ static ssize_t o2nm_cluster_attr_reconnect_delay_ms_write(
|
||||||
return o2nm_cluster_attr_write(page, count,
|
return o2nm_cluster_attr_write(page, count,
|
||||||
&cluster->cl_reconnect_delay_ms);
|
&cluster->cl_reconnect_delay_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t o2nm_cluster_attr_fence_method_read(
|
||||||
|
struct o2nm_cluster *cluster, char *page)
|
||||||
|
{
|
||||||
|
ssize_t ret = 0;
|
||||||
|
|
||||||
|
if (cluster)
|
||||||
|
ret = sprintf(page, "%s\n",
|
||||||
|
o2nm_fence_method_desc[cluster->cl_fence_method]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t o2nm_cluster_attr_fence_method_write(
|
||||||
|
struct o2nm_cluster *cluster, const char *page, size_t count)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
if (page[count - 1] != '\n')
|
||||||
|
goto bail;
|
||||||
|
|
||||||
|
for (i = 0; i < O2NM_FENCE_METHODS; ++i) {
|
||||||
|
if (count != strlen(o2nm_fence_method_desc[i]) + 1)
|
||||||
|
continue;
|
||||||
|
if (strncasecmp(page, o2nm_fence_method_desc[i], count - 1))
|
||||||
|
continue;
|
||||||
|
if (cluster->cl_fence_method != i) {
|
||||||
|
printk(KERN_INFO "ocfs2: Changing fence method to %s\n",
|
||||||
|
o2nm_fence_method_desc[i]);
|
||||||
|
cluster->cl_fence_method = i;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bail:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
static struct o2nm_cluster_attribute o2nm_cluster_attr_idle_timeout_ms = {
|
static struct o2nm_cluster_attribute o2nm_cluster_attr_idle_timeout_ms = {
|
||||||
.attr = { .ca_owner = THIS_MODULE,
|
.attr = { .ca_owner = THIS_MODULE,
|
||||||
.ca_name = "idle_timeout_ms",
|
.ca_name = "idle_timeout_ms",
|
||||||
|
@ -603,10 +644,19 @@ static struct o2nm_cluster_attribute o2nm_cluster_attr_reconnect_delay_ms = {
|
||||||
.store = o2nm_cluster_attr_reconnect_delay_ms_write,
|
.store = o2nm_cluster_attr_reconnect_delay_ms_write,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct o2nm_cluster_attribute o2nm_cluster_attr_fence_method = {
|
||||||
|
.attr = { .ca_owner = THIS_MODULE,
|
||||||
|
.ca_name = "fence_method",
|
||||||
|
.ca_mode = S_IRUGO | S_IWUSR },
|
||||||
|
.show = o2nm_cluster_attr_fence_method_read,
|
||||||
|
.store = o2nm_cluster_attr_fence_method_write,
|
||||||
|
};
|
||||||
|
|
||||||
static struct configfs_attribute *o2nm_cluster_attrs[] = {
|
static struct configfs_attribute *o2nm_cluster_attrs[] = {
|
||||||
&o2nm_cluster_attr_idle_timeout_ms.attr,
|
&o2nm_cluster_attr_idle_timeout_ms.attr,
|
||||||
&o2nm_cluster_attr_keepalive_delay_ms.attr,
|
&o2nm_cluster_attr_keepalive_delay_ms.attr,
|
||||||
&o2nm_cluster_attr_reconnect_delay_ms.attr,
|
&o2nm_cluster_attr_reconnect_delay_ms.attr,
|
||||||
|
&o2nm_cluster_attr_fence_method.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
static ssize_t o2nm_cluster_show(struct config_item *item,
|
static ssize_t o2nm_cluster_show(struct config_item *item,
|
||||||
|
@ -778,6 +828,7 @@ static struct config_group *o2nm_cluster_group_make_group(struct config_group *g
|
||||||
cluster->cl_reconnect_delay_ms = O2NET_RECONNECT_DELAY_MS_DEFAULT;
|
cluster->cl_reconnect_delay_ms = O2NET_RECONNECT_DELAY_MS_DEFAULT;
|
||||||
cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT;
|
cluster->cl_idle_timeout_ms = O2NET_IDLE_TIMEOUT_MS_DEFAULT;
|
||||||
cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT;
|
cluster->cl_keepalive_delay_ms = O2NET_KEEPALIVE_DELAY_MS_DEFAULT;
|
||||||
|
cluster->cl_fence_method = O2NM_FENCE_RESET;
|
||||||
|
|
||||||
ret = &cluster->cl_group;
|
ret = &cluster->cl_group;
|
||||||
o2nm_single_cluster = cluster;
|
o2nm_single_cluster = cluster;
|
||||||
|
|
|
@ -33,6 +33,12 @@
|
||||||
#include <linux/configfs.h>
|
#include <linux/configfs.h>
|
||||||
#include <linux/rbtree.h>
|
#include <linux/rbtree.h>
|
||||||
|
|
||||||
|
enum o2nm_fence_method {
|
||||||
|
O2NM_FENCE_RESET = 0,
|
||||||
|
O2NM_FENCE_PANIC,
|
||||||
|
O2NM_FENCE_METHODS, /* Number of fence methods */
|
||||||
|
};
|
||||||
|
|
||||||
struct o2nm_node {
|
struct o2nm_node {
|
||||||
spinlock_t nd_lock;
|
spinlock_t nd_lock;
|
||||||
struct config_item nd_item;
|
struct config_item nd_item;
|
||||||
|
@ -58,6 +64,7 @@ struct o2nm_cluster {
|
||||||
unsigned int cl_idle_timeout_ms;
|
unsigned int cl_idle_timeout_ms;
|
||||||
unsigned int cl_keepalive_delay_ms;
|
unsigned int cl_keepalive_delay_ms;
|
||||||
unsigned int cl_reconnect_delay_ms;
|
unsigned int cl_reconnect_delay_ms;
|
||||||
|
enum o2nm_fence_method cl_fence_method;
|
||||||
|
|
||||||
/* this bitmap is part of a hack for disk bitmap.. will go eventually. - zab */
|
/* this bitmap is part of a hack for disk bitmap.. will go eventually. - zab */
|
||||||
unsigned long cl_nodes_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
|
unsigned long cl_nodes_bitmap[BITS_TO_LONGS(O2NM_MAX_NODES)];
|
||||||
|
|
|
@ -74,8 +74,20 @@ static void o2quo_fence_self(void)
|
||||||
* threads can still schedule, etc, etc */
|
* threads can still schedule, etc, etc */
|
||||||
o2hb_stop_all_regions();
|
o2hb_stop_all_regions();
|
||||||
|
|
||||||
printk("ocfs2 is very sorry to be fencing this system by restarting\n");
|
switch (o2nm_single_cluster->cl_fence_method) {
|
||||||
|
case O2NM_FENCE_PANIC:
|
||||||
|
panic("*** ocfs2 is very sorry to be fencing this system by "
|
||||||
|
"panicing ***\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WARN_ON(o2nm_single_cluster->cl_fence_method >=
|
||||||
|
O2NM_FENCE_METHODS);
|
||||||
|
case O2NM_FENCE_RESET:
|
||||||
|
printk(KERN_ERR "*** ocfs2 is very sorry to be fencing this "
|
||||||
|
"system by restarting ***\n");
|
||||||
emergency_restart();
|
emergency_restart();
|
||||||
|
break;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Indicate that a timeout occured on a hearbeat region write. The
|
/* Indicate that a timeout occured on a hearbeat region write. The
|
||||||
|
|
|
@ -2589,6 +2589,14 @@ retry:
|
||||||
"begin reco msg (%d)\n", dlm->name, nodenum, ret);
|
"begin reco msg (%d)\n", dlm->name, nodenum, ret);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
if (ret == -EAGAIN) {
|
||||||
|
mlog(0, "%s: trying to start recovery of node "
|
||||||
|
"%u, but node %u is waiting for last recovery "
|
||||||
|
"to complete, backoff for a bit\n", dlm->name,
|
||||||
|
dead_node, nodenum);
|
||||||
|
msleep(100);
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
struct dlm_lock_resource *res;
|
struct dlm_lock_resource *res;
|
||||||
/* this is now a serious problem, possibly ENOMEM
|
/* this is now a serious problem, possibly ENOMEM
|
||||||
|
@ -2608,14 +2616,6 @@ retry:
|
||||||
* another ENOMEM */
|
* another ENOMEM */
|
||||||
msleep(100);
|
msleep(100);
|
||||||
goto retry;
|
goto retry;
|
||||||
} else if (ret == EAGAIN) {
|
|
||||||
mlog(0, "%s: trying to start recovery of node "
|
|
||||||
"%u, but node %u is waiting for last recovery "
|
|
||||||
"to complete, backoff for a bit\n", dlm->name,
|
|
||||||
dead_node, nodenum);
|
|
||||||
/* TODO Look into replacing msleep with cond_resched() */
|
|
||||||
msleep(100);
|
|
||||||
goto retry;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2639,7 +2639,7 @@ int dlm_begin_reco_handler(struct o2net_msg *msg, u32 len, void *data,
|
||||||
dlm->name, br->node_idx, br->dead_node,
|
dlm->name, br->node_idx, br->dead_node,
|
||||||
dlm->reco.dead_node, dlm->reco.new_master);
|
dlm->reco.dead_node, dlm->reco.new_master);
|
||||||
spin_unlock(&dlm->spinlock);
|
spin_unlock(&dlm->spinlock);
|
||||||
return EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
spin_unlock(&dlm->spinlock);
|
spin_unlock(&dlm->spinlock);
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "extent_map.h"
|
#include "extent_map.h"
|
||||||
#include "inode.h"
|
#include "inode.h"
|
||||||
#include "super.h"
|
#include "super.h"
|
||||||
|
#include "symlink.h"
|
||||||
|
|
||||||
#include "buffer_head_io.h"
|
#include "buffer_head_io.h"
|
||||||
|
|
||||||
|
@ -703,6 +704,12 @@ out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ocfs2_fiemap_inline() may be a little bit misleading, since
|
||||||
|
* it not only handles the fiemap for inlined files, but also deals
|
||||||
|
* with the fast symlink, cause they have no difference for extent
|
||||||
|
* mapping per se.
|
||||||
|
*/
|
||||||
static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh,
|
static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh,
|
||||||
struct fiemap_extent_info *fieinfo,
|
struct fiemap_extent_info *fieinfo,
|
||||||
u64 map_start)
|
u64 map_start)
|
||||||
|
@ -715,11 +722,18 @@ static int ocfs2_fiemap_inline(struct inode *inode, struct buffer_head *di_bh,
|
||||||
struct ocfs2_inode_info *oi = OCFS2_I(inode);
|
struct ocfs2_inode_info *oi = OCFS2_I(inode);
|
||||||
|
|
||||||
di = (struct ocfs2_dinode *)di_bh->b_data;
|
di = (struct ocfs2_dinode *)di_bh->b_data;
|
||||||
|
if (ocfs2_inode_is_fast_symlink(inode))
|
||||||
|
id_count = ocfs2_fast_symlink_chars(inode->i_sb);
|
||||||
|
else
|
||||||
id_count = le16_to_cpu(di->id2.i_data.id_count);
|
id_count = le16_to_cpu(di->id2.i_data.id_count);
|
||||||
|
|
||||||
if (map_start < id_count) {
|
if (map_start < id_count) {
|
||||||
phys = oi->ip_blkno << inode->i_sb->s_blocksize_bits;
|
phys = oi->ip_blkno << inode->i_sb->s_blocksize_bits;
|
||||||
phys += offsetof(struct ocfs2_dinode, id2.i_data.id_data);
|
if (ocfs2_inode_is_fast_symlink(inode))
|
||||||
|
phys += offsetof(struct ocfs2_dinode, id2.i_symlink);
|
||||||
|
else
|
||||||
|
phys += offsetof(struct ocfs2_dinode,
|
||||||
|
id2.i_data.id_data);
|
||||||
|
|
||||||
ret = fiemap_fill_next_extent(fieinfo, 0, phys, id_count,
|
ret = fiemap_fill_next_extent(fieinfo, 0, phys, id_count,
|
||||||
flags);
|
flags);
|
||||||
|
@ -756,9 +770,10 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
||||||
down_read(&OCFS2_I(inode)->ip_alloc_sem);
|
down_read(&OCFS2_I(inode)->ip_alloc_sem);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle inline-data separately.
|
* Handle inline-data and fast symlink separately.
|
||||||
*/
|
*/
|
||||||
if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
|
if ((OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) ||
|
||||||
|
ocfs2_inode_is_fast_symlink(inode)) {
|
||||||
ret = ocfs2_fiemap_inline(inode, di_bh, fieinfo, map_start);
|
ret = ocfs2_fiemap_inline(inode, di_bh, fieinfo, map_start);
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
@ -786,6 +801,8 @@ int ocfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
||||||
fe_flags = 0;
|
fe_flags = 0;
|
||||||
if (rec.e_flags & OCFS2_EXT_UNWRITTEN)
|
if (rec.e_flags & OCFS2_EXT_UNWRITTEN)
|
||||||
fe_flags |= FIEMAP_EXTENT_UNWRITTEN;
|
fe_flags |= FIEMAP_EXTENT_UNWRITTEN;
|
||||||
|
if (rec.e_flags & OCFS2_EXT_REFCOUNTED)
|
||||||
|
fe_flags |= FIEMAP_EXTENT_SHARED;
|
||||||
if (is_last)
|
if (is_last)
|
||||||
fe_flags |= FIEMAP_EXTENT_LAST;
|
fe_flags |= FIEMAP_EXTENT_LAST;
|
||||||
len_bytes = (u64)le16_to_cpu(rec.e_leaf_clusters) << osb->s_clustersize_bits;
|
len_bytes = (u64)le16_to_cpu(rec.e_leaf_clusters) << osb->s_clustersize_bits;
|
||||||
|
|
|
@ -2329,4 +2329,5 @@ const struct inode_operations ocfs2_dir_iops = {
|
||||||
.getxattr = generic_getxattr,
|
.getxattr = generic_getxattr,
|
||||||
.listxattr = ocfs2_listxattr,
|
.listxattr = ocfs2_listxattr,
|
||||||
.removexattr = generic_removexattr,
|
.removexattr = generic_removexattr,
|
||||||
|
.fiemap = ocfs2_fiemap,
|
||||||
};
|
};
|
||||||
|
|
|
@ -245,9 +245,11 @@ enum ocfs2_mount_options
|
||||||
OCFS2_MOUNT_LOCALFLOCKS = 1 << 5, /* No cluster aware user file locks */
|
OCFS2_MOUNT_LOCALFLOCKS = 1 << 5, /* No cluster aware user file locks */
|
||||||
OCFS2_MOUNT_NOUSERXATTR = 1 << 6, /* No user xattr */
|
OCFS2_MOUNT_NOUSERXATTR = 1 << 6, /* No user xattr */
|
||||||
OCFS2_MOUNT_INODE64 = 1 << 7, /* Allow inode numbers > 2^32 */
|
OCFS2_MOUNT_INODE64 = 1 << 7, /* Allow inode numbers > 2^32 */
|
||||||
OCFS2_MOUNT_POSIX_ACL = 1 << 8, /* POSIX access control lists */
|
OCFS2_MOUNT_POSIX_ACL = 1 << 8, /* Force POSIX access control lists */
|
||||||
OCFS2_MOUNT_USRQUOTA = 1 << 9, /* We support user quotas */
|
OCFS2_MOUNT_NO_POSIX_ACL = 1 << 9, /* Disable POSIX access
|
||||||
OCFS2_MOUNT_GRPQUOTA = 1 << 10, /* We support group quotas */
|
control lists */
|
||||||
|
OCFS2_MOUNT_USRQUOTA = 1 << 10, /* We support user quotas */
|
||||||
|
OCFS2_MOUNT_GRPQUOTA = 1 << 11, /* We support group quotas */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OCFS2_OSB_SOFT_RO 0x0001
|
#define OCFS2_OSB_SOFT_RO 0x0001
|
||||||
|
|
|
@ -1202,7 +1202,7 @@ struct ocfs2_local_disk_dqinfo {
|
||||||
/* Header of one chunk of a quota file */
|
/* Header of one chunk of a quota file */
|
||||||
struct ocfs2_local_disk_chunk {
|
struct ocfs2_local_disk_chunk {
|
||||||
__le32 dqc_free; /* Number of free entries in the bitmap */
|
__le32 dqc_free; /* Number of free entries in the bitmap */
|
||||||
u8 dqc_bitmap[0]; /* Bitmap of entries in the corresponding
|
__u8 dqc_bitmap[0]; /* Bitmap of entries in the corresponding
|
||||||
* chunk of quota file */
|
* chunk of quota file */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -814,7 +814,7 @@ static int fs_protocol_compare(struct ocfs2_protocol_version *existing,
|
||||||
static int user_cluster_connect(struct ocfs2_cluster_connection *conn)
|
static int user_cluster_connect(struct ocfs2_cluster_connection *conn)
|
||||||
{
|
{
|
||||||
dlm_lockspace_t *fsdlm;
|
dlm_lockspace_t *fsdlm;
|
||||||
struct ocfs2_live_connection *control;
|
struct ocfs2_live_connection *uninitialized_var(control);
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
BUG_ON(conn == NULL);
|
BUG_ON(conn == NULL);
|
||||||
|
|
|
@ -100,6 +100,8 @@ struct mount_options
|
||||||
static int ocfs2_parse_options(struct super_block *sb, char *options,
|
static int ocfs2_parse_options(struct super_block *sb, char *options,
|
||||||
struct mount_options *mopt,
|
struct mount_options *mopt,
|
||||||
int is_remount);
|
int is_remount);
|
||||||
|
static int ocfs2_check_set_options(struct super_block *sb,
|
||||||
|
struct mount_options *options);
|
||||||
static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt);
|
static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt);
|
||||||
static void ocfs2_put_super(struct super_block *sb);
|
static void ocfs2_put_super(struct super_block *sb);
|
||||||
static int ocfs2_mount_volume(struct super_block *sb);
|
static int ocfs2_mount_volume(struct super_block *sb);
|
||||||
|
@ -600,7 +602,8 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
|
||||||
|
|
||||||
lock_kernel();
|
lock_kernel();
|
||||||
|
|
||||||
if (!ocfs2_parse_options(sb, data, &parsed_options, 1)) {
|
if (!ocfs2_parse_options(sb, data, &parsed_options, 1) ||
|
||||||
|
!ocfs2_check_set_options(sb, &parsed_options)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -691,8 +694,6 @@ unlock_osb:
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
/* Only save off the new mount options in case of a successful
|
/* Only save off the new mount options in case of a successful
|
||||||
* remount. */
|
* remount. */
|
||||||
if (!(osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_XATTR))
|
|
||||||
parsed_options.mount_opt &= ~OCFS2_MOUNT_POSIX_ACL;
|
|
||||||
osb->s_mount_opt = parsed_options.mount_opt;
|
osb->s_mount_opt = parsed_options.mount_opt;
|
||||||
osb->s_atime_quantum = parsed_options.atime_quantum;
|
osb->s_atime_quantum = parsed_options.atime_quantum;
|
||||||
osb->preferred_slot = parsed_options.slot;
|
osb->preferred_slot = parsed_options.slot;
|
||||||
|
@ -701,6 +702,10 @@ unlock_osb:
|
||||||
|
|
||||||
if (!ocfs2_is_hard_readonly(osb))
|
if (!ocfs2_is_hard_readonly(osb))
|
||||||
ocfs2_set_journal_params(osb);
|
ocfs2_set_journal_params(osb);
|
||||||
|
|
||||||
|
sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
|
||||||
|
((osb->s_mount_opt & OCFS2_MOUNT_POSIX_ACL) ?
|
||||||
|
MS_POSIXACL : 0);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
unlock_kernel();
|
unlock_kernel();
|
||||||
|
@ -1011,31 +1016,16 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
|
||||||
brelse(bh);
|
brelse(bh);
|
||||||
bh = NULL;
|
bh = NULL;
|
||||||
|
|
||||||
if (!(osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_XATTR))
|
if (!ocfs2_check_set_options(sb, &parsed_options)) {
|
||||||
parsed_options.mount_opt &= ~OCFS2_MOUNT_POSIX_ACL;
|
status = -EINVAL;
|
||||||
|
goto read_super_error;
|
||||||
|
}
|
||||||
osb->s_mount_opt = parsed_options.mount_opt;
|
osb->s_mount_opt = parsed_options.mount_opt;
|
||||||
osb->s_atime_quantum = parsed_options.atime_quantum;
|
osb->s_atime_quantum = parsed_options.atime_quantum;
|
||||||
osb->preferred_slot = parsed_options.slot;
|
osb->preferred_slot = parsed_options.slot;
|
||||||
osb->osb_commit_interval = parsed_options.commit_interval;
|
osb->osb_commit_interval = parsed_options.commit_interval;
|
||||||
osb->local_alloc_default_bits = ocfs2_megabytes_to_clusters(sb, parsed_options.localalloc_opt);
|
osb->local_alloc_default_bits = ocfs2_megabytes_to_clusters(sb, parsed_options.localalloc_opt);
|
||||||
osb->local_alloc_bits = osb->local_alloc_default_bits;
|
osb->local_alloc_bits = osb->local_alloc_default_bits;
|
||||||
if (osb->s_mount_opt & OCFS2_MOUNT_USRQUOTA &&
|
|
||||||
!OCFS2_HAS_RO_COMPAT_FEATURE(sb,
|
|
||||||
OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) {
|
|
||||||
status = -EINVAL;
|
|
||||||
mlog(ML_ERROR, "User quotas were requested, but this "
|
|
||||||
"filesystem does not have the feature enabled.\n");
|
|
||||||
goto read_super_error;
|
|
||||||
}
|
|
||||||
if (osb->s_mount_opt & OCFS2_MOUNT_GRPQUOTA &&
|
|
||||||
!OCFS2_HAS_RO_COMPAT_FEATURE(sb,
|
|
||||||
OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) {
|
|
||||||
status = -EINVAL;
|
|
||||||
mlog(ML_ERROR, "Group quotas were requested, but this "
|
|
||||||
"filesystem does not have the feature enabled.\n");
|
|
||||||
goto read_super_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = ocfs2_verify_userspace_stack(osb, &parsed_options);
|
status = ocfs2_verify_userspace_stack(osb, &parsed_options);
|
||||||
if (status)
|
if (status)
|
||||||
|
@ -1245,6 +1235,40 @@ static struct file_system_type ocfs2_fs_type = {
|
||||||
.next = NULL
|
.next = NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int ocfs2_check_set_options(struct super_block *sb,
|
||||||
|
struct mount_options *options)
|
||||||
|
{
|
||||||
|
if (options->mount_opt & OCFS2_MOUNT_USRQUOTA &&
|
||||||
|
!OCFS2_HAS_RO_COMPAT_FEATURE(sb,
|
||||||
|
OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) {
|
||||||
|
mlog(ML_ERROR, "User quotas were requested, but this "
|
||||||
|
"filesystem does not have the feature enabled.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (options->mount_opt & OCFS2_MOUNT_GRPQUOTA &&
|
||||||
|
!OCFS2_HAS_RO_COMPAT_FEATURE(sb,
|
||||||
|
OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) {
|
||||||
|
mlog(ML_ERROR, "Group quotas were requested, but this "
|
||||||
|
"filesystem does not have the feature enabled.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (options->mount_opt & OCFS2_MOUNT_POSIX_ACL &&
|
||||||
|
!OCFS2_HAS_INCOMPAT_FEATURE(sb, OCFS2_FEATURE_INCOMPAT_XATTR)) {
|
||||||
|
mlog(ML_ERROR, "ACL support requested but extended attributes "
|
||||||
|
"feature is not enabled\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* No ACL setting specified? Use XATTR feature... */
|
||||||
|
if (!(options->mount_opt & (OCFS2_MOUNT_POSIX_ACL |
|
||||||
|
OCFS2_MOUNT_NO_POSIX_ACL))) {
|
||||||
|
if (OCFS2_HAS_INCOMPAT_FEATURE(sb, OCFS2_FEATURE_INCOMPAT_XATTR))
|
||||||
|
options->mount_opt |= OCFS2_MOUNT_POSIX_ACL;
|
||||||
|
else
|
||||||
|
options->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int ocfs2_parse_options(struct super_block *sb,
|
static int ocfs2_parse_options(struct super_block *sb,
|
||||||
char *options,
|
char *options,
|
||||||
struct mount_options *mopt,
|
struct mount_options *mopt,
|
||||||
|
@ -1392,40 +1416,19 @@ static int ocfs2_parse_options(struct super_block *sb,
|
||||||
mopt->mount_opt |= OCFS2_MOUNT_INODE64;
|
mopt->mount_opt |= OCFS2_MOUNT_INODE64;
|
||||||
break;
|
break;
|
||||||
case Opt_usrquota:
|
case Opt_usrquota:
|
||||||
/* We check only on remount, otherwise features
|
|
||||||
* aren't yet initialized. */
|
|
||||||
if (is_remount && !OCFS2_HAS_RO_COMPAT_FEATURE(sb,
|
|
||||||
OCFS2_FEATURE_RO_COMPAT_USRQUOTA)) {
|
|
||||||
mlog(ML_ERROR, "User quota requested but "
|
|
||||||
"filesystem feature is not set\n");
|
|
||||||
status = 0;
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
mopt->mount_opt |= OCFS2_MOUNT_USRQUOTA;
|
mopt->mount_opt |= OCFS2_MOUNT_USRQUOTA;
|
||||||
break;
|
break;
|
||||||
case Opt_grpquota:
|
case Opt_grpquota:
|
||||||
if (is_remount && !OCFS2_HAS_RO_COMPAT_FEATURE(sb,
|
|
||||||
OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)) {
|
|
||||||
mlog(ML_ERROR, "Group quota requested but "
|
|
||||||
"filesystem feature is not set\n");
|
|
||||||
status = 0;
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
mopt->mount_opt |= OCFS2_MOUNT_GRPQUOTA;
|
mopt->mount_opt |= OCFS2_MOUNT_GRPQUOTA;
|
||||||
break;
|
break;
|
||||||
#ifdef CONFIG_OCFS2_FS_POSIX_ACL
|
|
||||||
case Opt_acl:
|
case Opt_acl:
|
||||||
mopt->mount_opt |= OCFS2_MOUNT_POSIX_ACL;
|
mopt->mount_opt |= OCFS2_MOUNT_POSIX_ACL;
|
||||||
|
mopt->mount_opt &= ~OCFS2_MOUNT_NO_POSIX_ACL;
|
||||||
break;
|
break;
|
||||||
case Opt_noacl:
|
case Opt_noacl:
|
||||||
|
mopt->mount_opt |= OCFS2_MOUNT_NO_POSIX_ACL;
|
||||||
mopt->mount_opt &= ~OCFS2_MOUNT_POSIX_ACL;
|
mopt->mount_opt &= ~OCFS2_MOUNT_POSIX_ACL;
|
||||||
break;
|
break;
|
||||||
#else
|
|
||||||
case Opt_acl:
|
|
||||||
case Opt_noacl:
|
|
||||||
printk(KERN_INFO "ocfs2 (no)acl options not supported\n");
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
mlog(ML_ERROR,
|
mlog(ML_ERROR,
|
||||||
"Unrecognized mount option \"%s\" "
|
"Unrecognized mount option \"%s\" "
|
||||||
|
@ -1502,12 +1505,10 @@ static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
|
||||||
if (opts & OCFS2_MOUNT_INODE64)
|
if (opts & OCFS2_MOUNT_INODE64)
|
||||||
seq_printf(s, ",inode64");
|
seq_printf(s, ",inode64");
|
||||||
|
|
||||||
#ifdef CONFIG_OCFS2_FS_POSIX_ACL
|
|
||||||
if (opts & OCFS2_MOUNT_POSIX_ACL)
|
if (opts & OCFS2_MOUNT_POSIX_ACL)
|
||||||
seq_printf(s, ",acl");
|
seq_printf(s, ",acl");
|
||||||
else
|
else
|
||||||
seq_printf(s, ",noacl");
|
seq_printf(s, ",noacl");
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,6 +163,7 @@ const struct inode_operations ocfs2_symlink_inode_operations = {
|
||||||
.getxattr = generic_getxattr,
|
.getxattr = generic_getxattr,
|
||||||
.listxattr = ocfs2_listxattr,
|
.listxattr = ocfs2_listxattr,
|
||||||
.removexattr = generic_removexattr,
|
.removexattr = generic_removexattr,
|
||||||
|
.fiemap = ocfs2_fiemap,
|
||||||
};
|
};
|
||||||
const struct inode_operations ocfs2_fast_symlink_inode_operations = {
|
const struct inode_operations ocfs2_fast_symlink_inode_operations = {
|
||||||
.readlink = ocfs2_readlink,
|
.readlink = ocfs2_readlink,
|
||||||
|
@ -174,4 +175,5 @@ const struct inode_operations ocfs2_fast_symlink_inode_operations = {
|
||||||
.getxattr = generic_getxattr,
|
.getxattr = generic_getxattr,
|
||||||
.listxattr = ocfs2_listxattr,
|
.listxattr = ocfs2_listxattr,
|
||||||
.removexattr = generic_removexattr,
|
.removexattr = generic_removexattr,
|
||||||
|
.fiemap = ocfs2_fiemap,
|
||||||
};
|
};
|
||||||
|
|
|
@ -98,10 +98,8 @@ static struct ocfs2_xattr_def_value_root def_xv = {
|
||||||
|
|
||||||
struct xattr_handler *ocfs2_xattr_handlers[] = {
|
struct xattr_handler *ocfs2_xattr_handlers[] = {
|
||||||
&ocfs2_xattr_user_handler,
|
&ocfs2_xattr_user_handler,
|
||||||
#ifdef CONFIG_OCFS2_FS_POSIX_ACL
|
|
||||||
&ocfs2_xattr_acl_access_handler,
|
&ocfs2_xattr_acl_access_handler,
|
||||||
&ocfs2_xattr_acl_default_handler,
|
&ocfs2_xattr_acl_default_handler,
|
||||||
#endif
|
|
||||||
&ocfs2_xattr_trusted_handler,
|
&ocfs2_xattr_trusted_handler,
|
||||||
&ocfs2_xattr_security_handler,
|
&ocfs2_xattr_security_handler,
|
||||||
NULL
|
NULL
|
||||||
|
@ -109,12 +107,10 @@ struct xattr_handler *ocfs2_xattr_handlers[] = {
|
||||||
|
|
||||||
static struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = {
|
static struct xattr_handler *ocfs2_xattr_handler_map[OCFS2_XATTR_MAX] = {
|
||||||
[OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler,
|
[OCFS2_XATTR_INDEX_USER] = &ocfs2_xattr_user_handler,
|
||||||
#ifdef CONFIG_OCFS2_FS_POSIX_ACL
|
|
||||||
[OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS]
|
[OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS]
|
||||||
= &ocfs2_xattr_acl_access_handler,
|
= &ocfs2_xattr_acl_access_handler,
|
||||||
[OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT]
|
[OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT]
|
||||||
= &ocfs2_xattr_acl_default_handler,
|
= &ocfs2_xattr_acl_default_handler,
|
||||||
#endif
|
|
||||||
[OCFS2_XATTR_INDEX_TRUSTED] = &ocfs2_xattr_trusted_handler,
|
[OCFS2_XATTR_INDEX_TRUSTED] = &ocfs2_xattr_trusted_handler,
|
||||||
[OCFS2_XATTR_INDEX_SECURITY] = &ocfs2_xattr_security_handler,
|
[OCFS2_XATTR_INDEX_SECURITY] = &ocfs2_xattr_security_handler,
|
||||||
};
|
};
|
||||||
|
@ -6064,7 +6060,7 @@ static int ocfs2_value_metas_in_xattr_header(struct super_block *sb,
|
||||||
* to the extent block, so just calculate a maximum record num.
|
* to the extent block, so just calculate a maximum record num.
|
||||||
*/
|
*/
|
||||||
if (!xv->xr_list.l_tree_depth)
|
if (!xv->xr_list.l_tree_depth)
|
||||||
*num_recs += xv->xr_list.l_next_free_rec;
|
*num_recs += le16_to_cpu(xv->xr_list.l_next_free_rec);
|
||||||
else
|
else
|
||||||
*num_recs += ocfs2_clusters_for_bytes(sb,
|
*num_recs += ocfs2_clusters_for_bytes(sb,
|
||||||
XATTR_SIZE_MAX);
|
XATTR_SIZE_MAX);
|
||||||
|
|
|
@ -40,10 +40,8 @@ struct ocfs2_security_xattr_info {
|
||||||
extern struct xattr_handler ocfs2_xattr_user_handler;
|
extern struct xattr_handler ocfs2_xattr_user_handler;
|
||||||
extern struct xattr_handler ocfs2_xattr_trusted_handler;
|
extern struct xattr_handler ocfs2_xattr_trusted_handler;
|
||||||
extern struct xattr_handler ocfs2_xattr_security_handler;
|
extern struct xattr_handler ocfs2_xattr_security_handler;
|
||||||
#ifdef CONFIG_OCFS2_FS_POSIX_ACL
|
|
||||||
extern struct xattr_handler ocfs2_xattr_acl_access_handler;
|
extern struct xattr_handler ocfs2_xattr_acl_access_handler;
|
||||||
extern struct xattr_handler ocfs2_xattr_acl_default_handler;
|
extern struct xattr_handler ocfs2_xattr_acl_default_handler;
|
||||||
#endif
|
|
||||||
extern struct xattr_handler *ocfs2_xattr_handlers[];
|
extern struct xattr_handler *ocfs2_xattr_handlers[];
|
||||||
|
|
||||||
ssize_t ocfs2_listxattr(struct dentry *, char *, size_t);
|
ssize_t ocfs2_listxattr(struct dentry *, char *, size_t);
|
||||||
|
|
|
@ -62,5 +62,7 @@ struct fiemap {
|
||||||
#define FIEMAP_EXTENT_MERGED 0x00001000 /* File does not natively
|
#define FIEMAP_EXTENT_MERGED 0x00001000 /* File does not natively
|
||||||
* support extents. Result
|
* support extents. Result
|
||||||
* merged for efficiency. */
|
* merged for efficiency. */
|
||||||
|
#define FIEMAP_EXTENT_SHARED 0x00002000 /* Space shared with other
|
||||||
|
* files. */
|
||||||
|
|
||||||
#endif /* _LINUX_FIEMAP_H */
|
#endif /* _LINUX_FIEMAP_H */
|
||||||
|
|
Loading…
Reference in a new issue