Commit a6e3d7db authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2

* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mfasheh/ocfs2: (23 commits)
  ocfs2: Optionally return filldir errors
  ocfs2: Write support for directories with inline data
  ocfs2: Read support for directories with inline data
  ocfs2: Write support for inline data
  ocfs2: Read support for inline data
  ocfs2: Structure updates for inline data
  ocfs2: Cleanup dirent size check
  ocfs2: Rename cleanups
  ocfs2: Provide convenience function for ino lookup
  ocfs2: Implement ocfs2_empty_dir() as a caller of ocfs2_dir_foreach()
  ocfs2: Remove open coded readdir()
  ocfs2: Pass raw u64 to filldir
  ocfs2: Abstract out core dir listing functionality
  ocfs2: Move directory manipulation code into dir.c
  ocfs2: Small refactor of truncate zeroing code
  ocfs2: move nonsparse hole-filling into ocfs2_write_begin()
  ocfs2: Sync ocfs2_fs.h with ocfs2-tools
  [PATCH] fs/ocfs2/: removed unneeded initial value and function's return value
  ocfs2: Implement show_options()
  ocfs2: Clear slot map when umounting a local volume
  ...
parents 42f04b6d e7b34019
This diff is collapsed.
...@@ -62,6 +62,11 @@ static inline int ocfs2_extend_meta_needed(struct ocfs2_dinode *fe) ...@@ -62,6 +62,11 @@ static inline int ocfs2_extend_meta_needed(struct ocfs2_dinode *fe)
return le16_to_cpu(fe->id2.i_list.l_tree_depth) + 2; return le16_to_cpu(fe->id2.i_list.l_tree_depth) + 2;
} }
void ocfs2_dinode_new_extent_list(struct inode *inode, struct ocfs2_dinode *di);
void ocfs2_set_inode_data_inline(struct inode *inode, struct ocfs2_dinode *di);
int ocfs2_convert_inline_data_to_extents(struct inode *inode,
struct buffer_head *di_bh);
int ocfs2_truncate_log_init(struct ocfs2_super *osb); int ocfs2_truncate_log_init(struct ocfs2_super *osb);
void ocfs2_truncate_log_shutdown(struct ocfs2_super *osb); void ocfs2_truncate_log_shutdown(struct ocfs2_super *osb);
void ocfs2_schedule_truncate_log_flush(struct ocfs2_super *osb, void ocfs2_schedule_truncate_log_flush(struct ocfs2_super *osb,
...@@ -115,6 +120,8 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb, ...@@ -115,6 +120,8 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb,
struct inode *inode, struct inode *inode,
struct buffer_head *fe_bh, struct buffer_head *fe_bh,
struct ocfs2_truncate_context *tc); struct ocfs2_truncate_context *tc);
int ocfs2_truncate_inline(struct inode *inode, struct buffer_head *di_bh,
unsigned int start, unsigned int end, int trunc);
int ocfs2_find_leaf(struct inode *inode, struct ocfs2_extent_list *root_el, int ocfs2_find_leaf(struct inode *inode, struct ocfs2_extent_list *root_el,
u32 cpos, struct buffer_head **leaf_bh); u32 cpos, struct buffer_head **leaf_bh);
......
This diff is collapsed.
...@@ -34,6 +34,8 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno, ...@@ -34,6 +34,8 @@ int ocfs2_map_page_blocks(struct page *page, u64 *p_blkno,
struct inode *inode, unsigned int from, struct inode *inode, unsigned int from,
unsigned int to, int new); unsigned int to, int new);
void ocfs2_unlock_and_free_pages(struct page **pages, int num_pages);
int walk_page_buffers( handle_t *handle, int walk_page_buffers( handle_t *handle,
struct buffer_head *head, struct buffer_head *head,
unsigned from, unsigned from,
...@@ -59,6 +61,10 @@ int ocfs2_write_begin_nolock(struct address_space *mapping, ...@@ -59,6 +61,10 @@ int ocfs2_write_begin_nolock(struct address_space *mapping,
struct page **pagep, void **fsdata, struct page **pagep, void **fsdata,
struct buffer_head *di_bh, struct page *mmap_page); struct buffer_head *di_bh, struct page *mmap_page);
int ocfs2_read_inline_data(struct inode *inode, struct page *page,
struct buffer_head *di_bh);
int ocfs2_size_fits_inline_data(struct buffer_head *di_bh, u64 new_size);
/* all ocfs2_dio_end_io()'s fault */ /* all ocfs2_dio_end_io()'s fault */
#define ocfs2_iocb_is_rw_locked(iocb) \ #define ocfs2_iocb_is_rw_locked(iocb) \
test_bit(0, (unsigned long *)&iocb->private) test_bit(0, (unsigned long *)&iocb->private)
......
This diff is collapsed.
...@@ -26,17 +26,49 @@ ...@@ -26,17 +26,49 @@
#ifndef OCFS2_DIR_H #ifndef OCFS2_DIR_H
#define OCFS2_DIR_H #define OCFS2_DIR_H
struct buffer_head *ocfs2_find_entry(const char *name,
int namelen,
struct inode *dir,
struct ocfs2_dir_entry **res_dir);
int ocfs2_delete_entry(handle_t *handle,
struct inode *dir,
struct ocfs2_dir_entry *de_del,
struct buffer_head *bh);
int __ocfs2_add_entry(handle_t *handle,
struct inode *dir,
const char *name, int namelen,
struct inode *inode, u64 blkno,
struct buffer_head *parent_fe_bh,
struct buffer_head *insert_bh);
static inline int ocfs2_add_entry(handle_t *handle,
struct dentry *dentry,
struct inode *inode, u64 blkno,
struct buffer_head *parent_fe_bh,
struct buffer_head *insert_bh)
{
return __ocfs2_add_entry(handle, dentry->d_parent->d_inode,
dentry->d_name.name, dentry->d_name.len,
inode, blkno, parent_fe_bh, insert_bh);
}
int ocfs2_update_entry(struct inode *dir, handle_t *handle,
struct buffer_head *de_bh, struct ocfs2_dir_entry *de,
struct inode *new_entry_inode);
int ocfs2_check_dir_for_entry(struct inode *dir, int ocfs2_check_dir_for_entry(struct inode *dir,
const char *name, const char *name,
int namelen); int namelen);
int ocfs2_empty_dir(struct inode *inode); /* FIXME: to namei.c */ int ocfs2_empty_dir(struct inode *inode);
int ocfs2_find_files_on_disk(const char *name, int ocfs2_find_files_on_disk(const char *name,
int namelen, int namelen,
u64 *blkno, u64 *blkno,
struct inode *inode, struct inode *inode,
struct buffer_head **dirent_bh, struct buffer_head **dirent_bh,
struct ocfs2_dir_entry **dirent); struct ocfs2_dir_entry **dirent);
int ocfs2_lookup_ino_from_name(struct inode *dir, const char *name,
int namelen, u64 *blkno);
int ocfs2_readdir(struct file *filp, void *dirent, filldir_t filldir); int ocfs2_readdir(struct file *filp, void *dirent, filldir_t filldir);
int ocfs2_dir_foreach(struct inode *inode, loff_t *f_pos, void *priv,
filldir_t filldir);
int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb, int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
struct inode *dir, struct inode *dir,
struct buffer_head *parent_fe_bh, struct buffer_head *parent_fe_bh,
...@@ -44,11 +76,11 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb, ...@@ -44,11 +76,11 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
int namelen, int namelen,
struct buffer_head **ret_de_bh); struct buffer_head **ret_de_bh);
struct ocfs2_alloc_context; struct ocfs2_alloc_context;
int ocfs2_do_extend_dir(struct super_block *sb, int ocfs2_fill_new_dir(struct ocfs2_super *osb,
handle_t *handle, handle_t *handle,
struct inode *dir, struct inode *parent,
struct buffer_head *parent_fe_bh, struct inode *inode,
struct ocfs2_alloc_context *data_ac, struct buffer_head *fe_bh,
struct ocfs2_alloc_context *meta_ac, struct ocfs2_alloc_context *data_ac);
struct buffer_head **new_bh);
#endif /* OCFS2_DIR_H */ #endif /* OCFS2_DIR_H */
...@@ -1482,6 +1482,7 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode) ...@@ -1482,6 +1482,7 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
lvb->lvb_imtime_packed = lvb->lvb_imtime_packed =
cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime)); cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime));
lvb->lvb_iattr = cpu_to_be32(oi->ip_attr); lvb->lvb_iattr = cpu_to_be32(oi->ip_attr);
lvb->lvb_idynfeatures = cpu_to_be16(oi->ip_dyn_features);
lvb->lvb_igeneration = cpu_to_be32(inode->i_generation); lvb->lvb_igeneration = cpu_to_be32(inode->i_generation);
out: out:
...@@ -1515,6 +1516,7 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode) ...@@ -1515,6 +1516,7 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
i_size_write(inode, be64_to_cpu(lvb->lvb_isize)); i_size_write(inode, be64_to_cpu(lvb->lvb_isize));
oi->ip_attr = be32_to_cpu(lvb->lvb_iattr); oi->ip_attr = be32_to_cpu(lvb->lvb_iattr);
oi->ip_dyn_features = be16_to_cpu(lvb->lvb_idynfeatures);
ocfs2_set_inode_flags(inode); ocfs2_set_inode_flags(inode);
/* fast-symlinks are a special case */ /* fast-symlinks are a special case */
......
...@@ -29,12 +29,12 @@ ...@@ -29,12 +29,12 @@
#include "dcache.h" #include "dcache.h"
#define OCFS2_LVB_VERSION 4 #define OCFS2_LVB_VERSION 5
struct ocfs2_meta_lvb { struct ocfs2_meta_lvb {
__u8 lvb_version; __u8 lvb_version;
__u8 lvb_reserved0; __u8 lvb_reserved0;
__be16 lvb_reserved1; __be16 lvb_idynfeatures;
__be32 lvb_iclusters; __be32 lvb_iclusters;
__be32 lvb_iuid; __be32 lvb_iuid;
__be32 lvb_igid; __be32 lvb_igid;
......
...@@ -88,8 +88,6 @@ static struct dentry *ocfs2_get_parent(struct dentry *child) ...@@ -88,8 +88,6 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
struct dentry *parent; struct dentry *parent;
struct inode *inode; struct inode *inode;
struct inode *dir = child->d_inode; struct inode *dir = child->d_inode;
struct buffer_head *dirent_bh = NULL;
struct ocfs2_dir_entry *dirent;
mlog_entry("(0x%p, '%.*s')\n", child, mlog_entry("(0x%p, '%.*s')\n", child,
child->d_name.len, child->d_name.name); child->d_name.len, child->d_name.name);
...@@ -105,8 +103,7 @@ static struct dentry *ocfs2_get_parent(struct dentry *child) ...@@ -105,8 +103,7 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
goto bail; goto bail;
} }
status = ocfs2_find_files_on_disk("..", 2, &blkno, dir, &dirent_bh, status = ocfs2_lookup_ino_from_name(dir, "..", 2, &blkno);
&dirent);
if (status < 0) { if (status < 0) {
parent = ERR_PTR(-ENOENT); parent = ERR_PTR(-ENOENT);
goto bail_unlock; goto bail_unlock;
...@@ -131,9 +128,6 @@ static struct dentry *ocfs2_get_parent(struct dentry *child) ...@@ -131,9 +128,6 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
bail_unlock: bail_unlock:
ocfs2_meta_unlock(dir, 0); ocfs2_meta_unlock(dir, 0);
if (dirent_bh)
brelse(dirent_bh);
bail: bail:
mlog_exit_ptr(parent); mlog_exit_ptr(parent);
......
...@@ -387,6 +387,12 @@ int ocfs2_get_clusters(struct inode *inode, u32 v_cluster, ...@@ -387,6 +387,12 @@ int ocfs2_get_clusters(struct inode *inode, u32 v_cluster,
struct ocfs2_extent_rec *rec; struct ocfs2_extent_rec *rec;
u32 coff; u32 coff;
if (OCFS2_I(inode)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
ret = -ERANGE;
mlog_errno(ret);
goto out;
}
ret = ocfs2_extent_map_lookup(inode, v_cluster, p_cluster, ret = ocfs2_extent_map_lookup(inode, v_cluster, p_cluster,
num_clusters, extent_flags); num_clusters, extent_flags);
if (ret == 0) if (ret == 0)
......
This diff is collapsed.
...@@ -47,6 +47,8 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb, ...@@ -47,6 +47,8 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
struct ocfs2_alloc_context *data_ac, struct ocfs2_alloc_context *data_ac,
struct ocfs2_alloc_context *meta_ac, struct ocfs2_alloc_context *meta_ac,
enum ocfs2_alloc_restarted *reason_ret); enum ocfs2_alloc_restarted *reason_ret);
int ocfs2_extend_no_holes(struct inode *inode, u64 new_i_size,
u64 zero_to);
int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_dinode *di, int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_dinode *di,
u32 clusters_to_add, u32 extents_to_split, u32 clusters_to_add, u32 extents_to_split,
struct ocfs2_alloc_context **data_ac, struct ocfs2_alloc_context **data_ac,
......
...@@ -241,6 +241,7 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe, ...@@ -241,6 +241,7 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters); OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr); OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
OCFS2_I(inode)->ip_dyn_features = le16_to_cpu(fe->i_dyn_features);
inode->i_version = 1; inode->i_version = 1;
inode->i_generation = le32_to_cpu(fe->i_generation); inode->i_generation = le32_to_cpu(fe->i_generation);
...@@ -513,6 +514,10 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb, ...@@ -513,6 +514,10 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
fe = (struct ocfs2_dinode *) fe_bh->b_data; fe = (struct ocfs2_dinode *) fe_bh->b_data;
/*
* This check will also skip truncate of inodes with inline
* data and fast symlinks.
*/
if (fe->i_clusters) { if (fe->i_clusters) {
handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
if (IS_ERR(handle)) { if (IS_ERR(handle)) {
...@@ -1220,6 +1225,7 @@ int ocfs2_mark_inode_dirty(handle_t *handle, ...@@ -1220,6 +1225,7 @@ int ocfs2_mark_inode_dirty(handle_t *handle,
fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters); fe->i_clusters = cpu_to_le32(OCFS2_I(inode)->ip_clusters);
ocfs2_get_inode_flags(OCFS2_I(inode)); ocfs2_get_inode_flags(OCFS2_I(inode));
fe->i_attr = cpu_to_le32(OCFS2_I(inode)->ip_attr); fe->i_attr = cpu_to_le32(OCFS2_I(inode)->ip_attr);
fe->i_dyn_features = cpu_to_le16(OCFS2_I(inode)->ip_dyn_features);
spin_unlock(&OCFS2_I(inode)->ip_lock); spin_unlock(&OCFS2_I(inode)->ip_lock);
fe->i_size = cpu_to_le64(i_size_read(inode)); fe->i_size = cpu_to_le64(i_size_read(inode));
...@@ -1257,6 +1263,7 @@ void ocfs2_refresh_inode(struct inode *inode, ...@@ -1257,6 +1263,7 @@ void ocfs2_refresh_inode(struct inode *inode,
OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters); OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr); OCFS2_I(inode)->ip_attr = le32_to_cpu(fe->i_attr);
OCFS2_I(inode)->ip_dyn_features = le16_to_cpu(fe->i_dyn_features);
ocfs2_set_inode_flags(inode); ocfs2_set_inode_flags(inode);
i_size_write(inode, le64_to_cpu(fe->i_size)); i_size_write(inode, le64_to_cpu(fe->i_size));
inode->i_nlink = le16_to_cpu(fe->i_links_count); inode->i_nlink = le16_to_cpu(fe->i_links_count);
......
...@@ -51,6 +51,7 @@ struct ocfs2_inode_info ...@@ -51,6 +51,7 @@ struct ocfs2_inode_info
u32 ip_flags; /* see below */ u32 ip_flags; /* see below */
u32 ip_attr; /* inode attributes */ u32 ip_attr; /* inode attributes */
u16 ip_dyn_features;
/* protected by recovery_lock. */ /* protected by recovery_lock. */
struct inode *ip_next_orphan; struct inode *ip_next_orphan;
......
...@@ -35,13 +35,13 @@ ...@@ -35,13 +35,13 @@
#include "ocfs2.h" #include "ocfs2.h"
#include "alloc.h" #include "alloc.h"
#include "dir.h"
#include "dlmglue.h" #include "dlmglue.h"
#include "extent_map.h" #include "extent_map.h"
#include "heartbeat.h" #include "heartbeat.h"
#include "inode.h" #include "inode.h"
#include "journal.h" #include "journal.h"
#include "localalloc.h" #include "localalloc.h"
#include "namei.h"
#include "slot_map.h" #include "slot_map.h"
#include "super.h" #include "super.h"
#include "vote.h" #include "vote.h"
...@@ -1213,17 +1213,49 @@ int ocfs2_mark_dead_nodes(struct ocfs2_super *osb) ...@@ -1213,17 +1213,49 @@ int ocfs2_mark_dead_nodes(struct ocfs2_super *osb)
return status; return status;
} }
struct ocfs2_orphan_filldir_priv {
struct inode *head;
struct ocfs2_super *osb;
};
static int ocfs2_orphan_filldir(void *priv, const char *name, int name_len,
loff_t pos, u64 ino, unsigned type)
{
struct ocfs2_orphan_filldir_priv *p = priv;
struct inode *iter;
if (name_len == 1 && !strncmp(".", name, 1))
return 0;
if (name_len == 2 && !strncmp("..", name, 2))
return 0;
/* Skip bad inodes so that recovery can continue */
iter = ocfs2_iget(p->osb, ino,
OCFS2_FI_FLAG_ORPHAN_RECOVERY);
if (IS_ERR(iter))
return 0;
mlog(0, "queue orphan %llu\n",
(unsigned long long)OCFS2_I(iter)->ip_blkno);
/* No locking is required for the next_orphan queue as there
* is only ever a single process doing orphan recovery. */
OCFS2_I(iter)->ip_next_orphan = p->head;
p->head = iter;
return 0;
}
static int ocfs2_queue_orphans(struct ocfs2_super *osb, static int ocfs2_queue_orphans(struct ocfs2_super *osb,
int slot, int slot,
struct inode **head) struct inode **head)
{ {
int status; int status;
struct inode *orphan_dir_inode = NULL; struct inode *orphan_dir_inode = NULL;
struct inode *iter; struct ocfs2_orphan_filldir_priv priv;
unsigned long offset, blk, local; loff_t pos = 0;
struct buffer_head *bh = NULL;
struct ocfs2_dir_entry *de; priv.osb = osb;
struct super_block *sb = osb->sb; priv.head = *head;
orphan_dir_inode = ocfs2_get_system_file_inode(osb, orphan_dir_inode = ocfs2_get_system_file_inode(osb,
ORPHAN_DIR_SYSTEM_INODE, ORPHAN_DIR_SYSTEM_INODE,
...@@ -1241,77 +1273,15 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb, ...@@ -1241,77 +1273,15 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb,
goto out; goto out;
} }
offset = 0; status = ocfs2_dir_foreach(orphan_dir_inode, &pos, &priv,
iter = NULL; ocfs2_orphan_filldir);
while(offset < i_size_read(orphan_dir_inode)) { if (status) {
blk = offset >> sb->s_blocksize_bits; mlog_errno(status);
goto out;
bh = ocfs2_bread(orphan_dir_inode, blk, &status, 0);
if (!bh)
status = -EINVAL;
if (status < 0) {
if (bh)
brelse(bh);
mlog_errno(status);
goto out_unlock;
}
local = 0;
while(offset < i_size_read(orphan_dir_inode)
&& local < sb->s_blocksize) {
de = (struct ocfs2_dir_entry *) (bh->b_data + local);
if (!ocfs2_check_dir_entry(orphan_dir_inode,
de, bh, local)) {
status = -EINVAL;
mlog_errno(status);
brelse(bh);
goto out_unlock;
}
local += le16_to_cpu(de->rec_len);
offset += le16_to_cpu(de->rec_len);
/* I guess we silently fail on no inode? */
if (!le64_to_cpu(de->inode))
continue;
if (de->file_type > OCFS2_FT_MAX) {
mlog(ML_ERROR,
"block %llu contains invalid de: "
"inode = %llu, rec_len = %u, "
"name_len = %u, file_type = %u, "
"name='%.*s'\n",
(unsigned long long)bh->b_blocknr,
(unsigned long long)le64_to_cpu(de->inode),
le16_to_cpu(de->rec_len),
de->name_len,
de->file_type,
de->name_len,
de->name);
continue;
}
if (de->name_len == 1 && !strncmp(".", de->name, 1))
continue;
if (de->name_len == 2 && !strncmp("..", de->name, 2))
continue;
iter = ocfs2_iget(osb, le64_to_cpu(de->inode),
OCFS2_FI_FLAG_ORPHAN_RECOVERY);
if (IS_ERR(iter))
continue;
mlog(0, "queue orphan %llu\n",
(unsigned long long)OCFS2_I(iter)->ip_blkno);
/* No locking is required for the next_orphan
* queue as there is only ever a single
* process doing orphan recovery. */
OCFS2_I(iter)->ip_next_orphan = *head;
*head = iter;
}
brelse(bh);
} }
out_unlock: *head = priv.head;
ocfs2_meta_unlock(orphan_dir_inode, 0); ocfs2_meta_unlock(orphan_dir_inode, 0);
out: out:
mutex_unlock(&orphan_dir_inode->i_mutex); mutex_unlock(&orphan_dir_inode->i_mutex);
......
...@@ -282,6 +282,9 @@ int ocfs2_journal_dirty_data(handle_t *handle, ...@@ -282,6 +282,9 @@ int ocfs2_journal_dirty_data(handle_t *handle,
* prev. group desc. if we relink. */ * prev. group desc. if we relink. */
#define OCFS2_SUBALLOC_ALLOC (3) #define OCFS2_SUBALLOC_ALLOC (3)
#define OCFS2_INLINE_TO_EXTENTS_CREDITS (OCFS2_SUBALLOC_ALLOC \
+ OCFS2_INODE_UPDATE_CREDITS)
/* dinode + group descriptor update. We don't relink on free yet. */ /* dinode + group descriptor update. We don't relink on free yet. */
#define OCFS2_SUBALLOC_FREE (2) #define OCFS2_SUBALLOC_FREE (2)
......
This diff is collapsed.
...@@ -30,29 +30,10 @@ extern const struct inode_operations ocfs2_dir_iops; ...@@ -30,29 +30,10 @@ extern const struct inode_operations ocfs2_dir_iops;
struct dentry *ocfs2_get_parent(struct dentry *child); struct dentry *ocfs2_get_parent(struct dentry *child);
int ocfs2_check_dir_entry (struct inode *dir,
struct ocfs2_dir_entry *de,
struct buffer_head *bh,
unsigned long offset);
struct buffer_head *ocfs2_find_entry(const char *name,
int namelen,
struct inode *dir,
struct ocfs2_dir_entry **res_dir);
int ocfs2_orphan_del(struct ocfs2_super *osb, int ocfs2_orphan_del(struct ocfs2_super *osb,
handle_t *handle, handle_t *handle,
struct inode *orphan_dir_inode, struct inode *orphan_dir_inode,
struct inode *inode, struct inode *inode,
struct buffer_head *orphan_dir_bh); struct buffer_head *orphan_dir_bh);
static inline int ocfs2_match(int len,
const char * const name,
struct ocfs2_dir_entry *de)
{
if (len != de->name_len)
return 0;
if (!de->inode)
return 0;
return !memcmp(name, de->name, len);
}
#endif /* OCFS2_NAMEI_H */ #endif /* OCFS2_NAMEI_H */
...@@ -319,6 +319,13 @@ static inline int ocfs2_writes_unwritten_extents(struct ocfs2_super *osb) ...@@ -319,6 +319,13 @@ static inline int ocfs2_writes_unwritten_extents(struct ocfs2_super *osb)
return 0; return 0;
} }
static inline int ocfs2_supports_inline_data(struct ocfs2_super *osb)
{
if (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_INLINE_DATA)
return 1;
return 0;
}
/* set / clear functions because cluster events can make these happen /* set / clear functions because cluster events can make these happen
* in parallel so we want the transitions to be atomic. this also * in parallel so we want the transitions to be atomic. this also
* means that any future flags osb_flags must be protected by spinlock * means that any future flags osb_flags must be protected by spinlock
......
...@@ -87,7 +87,8 @@ ...@@ -87,7 +87,8 @@
#define OCFS2_FEATURE_COMPAT_SUPP OCFS2_FEATURE_COMPAT_BACKUP_SB #define OCFS2_FEATURE_COMPAT_SUPP OCFS2_FEATURE_COMPAT_BACKUP_SB
#define OCFS2_FEATURE_INCOMPAT_SUPP (OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT \ #define OCFS2_FEATURE_INCOMPAT_SUPP (OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT \
| OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC) | OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC \
| OCFS2_FEATURE_INCOMPAT_INLINE_DATA)
#define OCFS2_FEATURE_RO_COMPAT_SUPP OCFS2_FEATURE_RO_COMPAT_UNWRITTEN #define OCFS2_FEATURE_RO_COMPAT_SUPP OCFS2_FEATURE_RO_COMPAT_UNWRITTEN
/* /*
...@@ -110,6 +111,20 @@ ...@@ -110,6 +111,20 @@
/* Support for sparse allocation in b-trees */ /* Support for sparse allocation in b-trees */
#define OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC 0x0010 #define OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC 0x0010
/*
* Tunefs sets this incompat flag before starting an operation which
* would require cleanup on abort. This is done to protect users from
* inadvertently mounting the fs after an aborted run without
* fsck-ing.
*
* s_tunefs_flags on the super block describes precisely which
* operations were in progress.
*/
#define OCFS2_FEATURE_INCOMPAT_TUNEFS_INPROG 0x0020
/* Support for data packed into inode blocks */
#define OCFS2_FEATURE_INCOMPAT_INLINE_DATA 0x0040
/* /*
* backup superblock flag is used to indicate that this volume * backup superblock flag is used to indicate that this volume
* has backup superblocks. * has backup superblocks.
...@@ -129,6 +144,11 @@ ...@@ -129,6 +144,11 @@
/* the max backup superblock nums */ /* the max backup superblock nums */
#define OCFS2_MAX_BACKUP_SUPERBLOCKS 6 #define OCFS2_MAX_BACKUP_SUPERBLOCKS 6
/*
* Flags on ocfs2_super_block.s_tunefs_flags
*/
#define OCFS2_TUNEFS_INPROG_REMOVE_SLOT 0x0001 /* Removing slots */
/* /*
* Flags on ocfs2_dinode.i_flags * Flags on ocfs2_dinode.i_flags
*/ */
...@@ -146,6 +166,17 @@ ...@@ -146,6 +166,17 @@
#define OCFS2_CHAIN_FL (0x00000400) /* Chain allocator */ #define OCFS2_CHAIN_FL (0x00000400) /* Chain allocator */
#define OCFS2_DEALLOC_FL (0x00000800) /* Truncate log */ #define OCFS2_DEALLOC_FL (0x00000800) /* Truncate log */
/*
* Flags on ocfs2_dinode.i_dyn_features
*
* These can change much more often than i_flags. When adding flags,
* keep in mind that i_dyn_features is only 16 bits wide.
*/
#define OCFS2_INLINE_DATA_FL (0x0001) /* Data stored in inode block */
#define OCFS2_HAS_XATTR_FL (0x0002)
#define OCFS2_INLINE_XATTR_FL (0x0004)
#define OCFS2_INDEXED_DIR_FL (0x0008)
/* Inode attributes, keep in sync with EXT2 */ /* Inode attributes, keep in sync with EXT2 */
#define OCFS2_SECRM_FL (0x00000001) /* Secure deletion */ #define OCFS2_SECRM_FL (0x00000001) /* Secure deletion */
#define OCFS2_UNRM_FL (0x00000002) /* Undelete */ #define OCFS2_UNRM_FL (0x00000002) /* Undelete */
...@@ -447,8 +478,8 @@ struct ocfs2_super_block { ...@@ -447,8 +478,8 @@ struct ocfs2_super_block {
__le32 s_clustersize_bits; /* Clustersize for this fs */ __le32 s_clustersize_bits; /* Clustersize for this fs */
/*40*/ __le16 s_max_slots; /* Max number of simultaneous mounts /*40*/ __le16 s_max_slots; /* Max number of simultaneous mounts
before tunefs required */ before tunefs required */
__le16 s_reserved1; __le16 s_tunefs_flag;
__le32 s_reserved2; __le32 s_reserved1;
__le64 s_first_cluster_group; /* Block offset of 1st cluster __le64 s_first_cluster_group; /* Block offset of 1st cluster
* group header */ * group header */
/*50*/ __u8 s_label[OCFS2_MAX_VOL_LABEL_LEN]; /* Label for mounting, etc. */ /*50*/ __u8 s_label[OCFS2_MAX_VOL_LABEL_LEN]; /* Label for mounting, etc. */
...@@ -470,6 +501,19 @@ struct ocfs2_local_alloc ...@@ -470,6 +501,19 @@ struct ocfs2_local_alloc
/*10*/ __u8 la_bitmap[0]; /*10*/ __u8 la_bitmap[0];
}; };
/*
* Data-in-inode header. This is only used if i_dyn_features has
* OCFS2_INLINE_DATA_FL set.
*/
struct ocfs2_inline_data
{
/*00*/ __le16 id_count; /* Number of bytes that can be used
* for data, starting at id_data */
__le16 id_reserved0;
__le32 id_reserved1;
__u8 id_data[0]; /* Start of user data */
};
/* /*
* On disk inode for OCFS2 * On disk inode for OCFS2
*/ */
...@@ -502,7 +546,7 @@ struct ocfs2_dinode { ...@@ -502,7 +546,7 @@ struct ocfs2_dinode {
__le32 i_attr; __le32 i_attr;
__le16 i_orphaned_slot; /* Only valid when OCFS2_ORPHANED_FL __le16 i_orphaned_slot; /* Only valid when OCFS2_ORPHANED_FL
was set in i_flags */ was set in i_flags */
__le16 i_reserved1; __le16 i_dyn_features;
/*70*/ __le64 i_reserved2[8]; /*70*/ __le64 i_reserved2[8];
/*B8*/ union { /*B8*/ union {
__le64 i_pad1; /* Generic way to refer to this __le64 i_pad1; /* Generic way to refer to this
...@@ -528,6 +572,7 @@ struct ocfs2_dinode { ...@@ -528,6 +572,7 @@ struct ocfs2_dinode {
struct ocfs2_chain_list i_chain; struct ocfs2_chain_list i_chain;
struct ocfs2_extent_list i_list; struct ocfs2_extent_list i_list;
struct ocfs2_truncate_log i_dealloc; struct ocfs2_truncate_log i_dealloc;
struct ocfs2_inline_data i_data;
__u8 i_symlink[0]; __u8 i_symlink[0];
} id2; } id2;
/* Actual on-disk size is one block */ /* Actual on-disk size is one block */
...@@ -577,6 +622,12 @@ static inline int ocfs2_fast_symlink_chars(struct super_block *sb) ...@@ -577,6 +622,12 @@ static inline int ocfs2_fast_symlink_chars(struct super_block *sb)
offsetof(struct ocfs2_dinode, id2.i_symlink); offsetof(struct ocfs2_dinode, id2.i_symlink);
} }
static inline int ocfs2_max_inline_data(struct super_block *sb)
{
return sb->s_blocksize -
offsetof(struct ocfs2_dinode, id2.i_data.id_data);
}
static inline int ocfs2_extent_recs_per_inode(struct super_block *sb) static inline int ocfs2_extent_recs_per_inode(struct super_block *sb)
{ {
int size; int size;
...@@ -656,6 +707,11 @@ static inline int ocfs2_fast_symlink_chars(int blocksize) ...@@ -656,6 +707,11 @@ static inline int ocfs2_fast_symlink_chars(int blocksize)
return blocksize - offsetof(struct ocfs2_dinode, id2.i_symlink); return blocksize - offsetof(struct ocfs2_dinode, id2.i_symlink);
} }
static inline int ocfs2_max_inline_data(int blocksize)
{
return blocksize - offsetof(struct ocfs2_dinode, id2.i_data.id_data);
}
static inline int ocfs2_extent_recs_per_inode(int blocksize) static inline int ocfs2_extent_recs_per_inode(int blocksize)
{ {
int size; int size;
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/mount.h>
#include <cluster/nodemanager.h> #include <cluster/nodemanager.h>
...@@ -91,6 +92,7 @@ struct mount_options ...@@ -91,6 +92,7 @@ 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_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);
static int ocfs2_remount(struct super_block *sb, int *flags, char *data); static int ocfs2_remount(struct super_block *sb, int *flags, char *data);
...@@ -105,7 +107,7 @@ static int ocfs2_sync_fs(struct super_block *sb, int wait); ...@@ -105,7 +107,7 @@ static int ocfs2_sync_fs(struct super_block *sb, int wait);
static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb); static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb);
static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb); static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb);
static int ocfs2_release_system_inodes(struct ocfs2_super *osb); static void ocfs2_release_system_inodes(struct ocfs2_super *osb);
static int ocfs2_fill_local_node_info(struct ocfs2_super *osb); static int ocfs2_fill_local_node_info(struct ocfs2_super *osb);
static int ocfs2_check_volume(struct ocfs2_super *osb); static int ocfs2_check_volume(struct ocfs2_super *osb);
static int ocfs2_verify_volume(struct ocfs2_dinode *di, static int ocfs2_verify_volume(struct ocfs2_dinode *di,
...@@ -133,6 +135,7 @@ static const struct super_operations ocfs2_sops = { ...@@ -133,6 +135,7 @@ static const struct super_operations ocfs2_sops = {
.write_super = ocfs2_write_super, .write_super = ocfs2_write_super,
.put_super = ocfs2_put_super, .put_super = ocfs2_put_super,
.remount_fs = ocfs2_remount, .remount_fs = ocfs2_remount,
.show_options = ocfs2_show_options,
}; };
enum { enum {
...@@ -177,7 +180,7 @@ static void ocfs2_write_super(struct super_block *sb) ...@@ -177,7 +180,7 @@ static void ocfs2_write_super(struct super_block *sb)
static int ocfs2_sync_fs(struct super_block *sb, int wait) static int ocfs2_sync_fs(struct super_block *sb, int wait)
{ {
int status = 0; int status;
tid_t target; tid_t target;
struct ocfs2_super *osb = OCFS2_SB(sb); struct ocfs2_super *osb = OCFS2_SB(sb);
...@@ -275,9 +278,9 @@ static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb) ...@@ -275,9 +278,9 @@ static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb)
return status; return status;
} }
static int ocfs2_release_system_inodes(struct ocfs2_super *osb) static void ocfs2_release_system_inodes(struct ocfs2_super *osb)
{ {
int status = 0, i; int i;
struct inode *inode; struct inode *inode;
mlog_entry_void(); mlog_entry_void();
...@@ -302,8 +305,7 @@ static int ocfs2_release_system_inodes(struct ocfs2_super *osb) ...@@ -302,8 +305,7 @@ static int ocfs2_release_system_inodes(struct ocfs2_super *osb)
osb->root_inode = NULL; osb->root_inode = NULL;
} }
mlog_exit(status); mlog_exit(0);
return status;
} }
/* We're allocating fs objects, use GFP_NOFS */ /* We're allocating fs objects, use GFP_NOFS */
...@@ -453,7 +455,7 @@ static int ocfs2_sb_probe(struct super_block *sb, ...@@ -453,7 +455,7 @@ static int ocfs2_sb_probe(struct super_block *sb,
struct buffer_head **bh, struct buffer_head **bh,
int *sector_size) int *sector_size)
{ {
int status = 0, tmpstat; int status, tmpstat;
struct ocfs1_vol_disk_hdr *hdr; struct ocfs1_vol_disk_hdr *hdr;
struct ocfs2_dinode *di; struct ocfs2_dinode *di;
int blksize; int blksize;
...@@ -830,6 +832,41 @@ static int ocfs2_parse_options(struct super_block *sb, ...@@ -830,6 +832,41 @@ static int ocfs2_parse_options(struct super_block *sb,
return status; return status;
} }
static int ocfs2_show_options(struct seq_file *s, struct vfsmount *mnt)
{
struct ocfs2_super *osb = OCFS2_SB(mnt->mnt_sb);
unsigned long opts = osb->s_mount_opt;
if (opts & OCFS2_MOUNT_HB_LOCAL)
seq_printf(s, ",_netdev,heartbeat=local");
else
seq_printf(s, ",heartbeat=none");
if (opts & OCFS2_MOUNT_NOINTR)
seq_printf(s, ",nointr");
if (opts & OCFS2_MOUNT_DATA_WRITEBACK)
seq_printf(s, ",data=writeback");
else
seq_printf(s, ",data=ordered");
if (opts & OCFS2_MOUNT_BARRIER)
seq_printf(s, ",barrier=1");
if (opts & OCFS2_MOUNT_ERRORS_PANIC)
seq_printf(s, ",errors=panic");
else
seq_printf(s, ",errors=remount-ro");
if (osb->preferred_slot != OCFS2_INVALID_SLOT)
seq_printf(s, ",preferred_slot=%d", osb->preferred_slot);
if (osb->s_atime_quantum != OCFS2_DEFAULT_ATIME_QUANTUM)
seq_printf(s, ",atime_quantum=%u", osb->s_atime_quantum);
return 0;
}
static int __init ocfs2_init(void) static int __init ocfs2_init(void)
{ {
int status; int status;
...@@ -1209,12 +1246,13 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) ...@@ -1209,12 +1246,13 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
tmp = ocfs2_request_umount_vote(osb); tmp = ocfs2_request_umount_vote(osb);
if (tmp < 0) if (tmp < 0)
mlog_errno(tmp); mlog_errno(tmp);
}
if (osb->slot_num != OCFS2_INVALID_SLOT) if (osb->slot_num != OCFS2_INVALID_SLOT)
ocfs2_put_slot(osb); ocfs2_put_slot(osb);
if (osb->dlm)
ocfs2_super_unlock(osb, 1); ocfs2_super_unlock(osb, 1);
}
ocfs2_release_system_inodes(osb); ocfs2_release_system_inodes(osb);
...@@ -1275,7 +1313,7 @@ static int ocfs2_initialize_super(struct super_block *sb, ...@@ -1275,7 +1313,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
struct buffer_head *bh, struct buffer_head *bh,
int sector_size) int sector_size)
{ {
int status = 0; int status;
int i, cbits, bbits; int i, cbits, bbits;
struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data; struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
struct inode *inode = NULL; struct inode *inode = NULL;
...@@ -1596,7 +1634,7 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di, ...@@ -1596,7 +1634,7 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di,
static int ocfs2_check_volume(struct ocfs2_super *osb) static int ocfs2_check_volume(struct ocfs2_super *osb)
{ {
int status = 0; int status;
int dirty; int dirty;
int local; int local;
struct ocfs2_dinode *local_alloc = NULL; /* only used if we struct ocfs2_dinode *local_alloc = NULL; /* only used if we
......
...@@ -100,17 +100,14 @@ static struct inode * _ocfs2_get_system_file_inode(struct ocfs2_super *osb, ...@@ -100,17 +100,14 @@ static struct inode * _ocfs2_get_system_file_inode(struct ocfs2_super *osb,
char namebuf[40]; char namebuf[40];
struct inode *inode = NULL; struct inode *inode = NULL;
u64 blkno; u64 blkno;
struct buffer_head *dirent_bh = NULL;
struct ocfs2_dir_entry *de = NULL;
int status = 0; int status = 0;
ocfs2_sprintf_system_inode_name(namebuf, ocfs2_sprintf_system_inode_name(namebuf,
sizeof(namebuf), sizeof(namebuf),
type, slot); type, slot);
status = ocfs2_find_files_on_disk(namebuf, strlen(namebuf), status = ocfs2_lookup_ino_from_name(osb->sys_root_inode, namebuf,
&blkno, osb->sys_root_inode, strlen(namebuf), &blkno);
&dirent_bh, &de);
if (status < 0) { if (status < 0) {
goto bail; goto bail;
} }
...@@ -122,8 +119,7 @@ static struct inode * _ocfs2_get_system_file_inode(struct ocfs2_super *osb, ...@@ -122,8 +119,7 @@ static struct inode * _ocfs2_get_system_file_inode(struct ocfs2_super *osb,
goto bail; goto bail;
} }
bail: bail:
if (dirent_bh)
brelse(dirent_bh);
return inode; return inode;
} }
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