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:
Linus Torvalds 2009-12-24 12:59:11 -08:00
commit 45e62974fb
19 changed files with 170 additions and 116 deletions

View file

@ -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.

View file

@ -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

View file

@ -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;

View file

@ -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 */

View file

@ -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(&reg->hr_write_timeout_work); cancel_delayed_work(&reg->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);

View file

@ -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;

View file

@ -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)];

View file

@ -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) {
emergency_restart(); 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();
break;
};
} }
/* Indicate that a timeout occured on a hearbeat region write. The /* Indicate that a timeout occured on a hearbeat region write. The

View file

@ -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);

View file

@ -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;
id_count = le16_to_cpu(di->id2.i_data.id_count); 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);
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;

View file

@ -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,
}; };

View file

@ -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

View file

@ -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 */
}; };

View 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);

View file

@ -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;
} }

View file

@ -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,
}; };

View file

@ -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);

View file

@ -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);

View file

@ -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 */