Commit ad1164b7 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: (21 commits)
  ocfs2: Check search result in ocfs2_xattr_block_get()
  ocfs2: fix printk related build warnings in xattr.c
  ocfs2: truncate outstanding block after direct io failure
  ocfs2/xattr: Proper hash collision handle in bucket division
  ocfs2: return 0 in page_mkwrite to let VFS retry.
  ocfs2: Set journal descriptor to NULL after journal shutdown
  ocfs2: Fix check of return value of ocfs2_start_trans() in xattr.c.
  ocfs2: Let inode be really deleted when ocfs2_mknod_locked() fails
  ocfs2: Fix checking of return value of new_inode()
  ocfs2: Fix check of return value of ocfs2_start_trans()
  ocfs2: Fix some typos in xattr annotations.
  ocfs2: Remove unused ocfs2_restore_xattr_block().
  ocfs2: Don't repeat ocfs2_xattr_block_find()
  ocfs2: Specify appropriate journal access for new xattr buckets.
  ocfs2: Check errors from ocfs2_xattr_update_xattr_search()
  ocfs2: Don't return -EFAULT from a corrupt xattr entry.
  ocfs2: Check xattr block signatures properly.
  ocfs2: add handler_map array bounds checking
  ocfs2: remove duplicate definition in xattr
  ocfs2: fix function declaration and definition in xattr
  ...
parents 0906dd9d 6c1e183e
...@@ -247,8 +247,8 @@ int ocfs2_update_inode_atime(struct inode *inode, ...@@ -247,8 +247,8 @@ int ocfs2_update_inode_atime(struct inode *inode,
mlog_entry_void(); mlog_entry_void();
handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
if (handle == NULL) { if (IS_ERR(handle)) {
ret = -ENOMEM; ret = PTR_ERR(handle);
mlog_errno(ret); mlog_errno(ret);
goto out; goto out;
} }
...@@ -312,8 +312,8 @@ static int ocfs2_simple_size_update(struct inode *inode, ...@@ -312,8 +312,8 @@ static int ocfs2_simple_size_update(struct inode *inode,
handle_t *handle = NULL; handle_t *handle = NULL;
handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
if (handle == NULL) { if (IS_ERR(handle)) {
ret = -ENOMEM; ret = PTR_ERR(handle);
mlog_errno(ret); mlog_errno(ret);
goto out; goto out;
} }
...@@ -1055,8 +1055,8 @@ static int __ocfs2_write_remove_suid(struct inode *inode, ...@@ -1055,8 +1055,8 @@ static int __ocfs2_write_remove_suid(struct inode *inode,
(unsigned long long)OCFS2_I(inode)->ip_blkno, inode->i_mode); (unsigned long long)OCFS2_I(inode)->ip_blkno, inode->i_mode);
handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
if (handle == NULL) { if (IS_ERR(handle)) {
ret = -ENOMEM; ret = PTR_ERR(handle);
mlog_errno(ret); mlog_errno(ret);
goto out; goto out;
} }
...@@ -1259,8 +1259,8 @@ static int __ocfs2_remove_inode_range(struct inode *inode, ...@@ -1259,8 +1259,8 @@ static int __ocfs2_remove_inode_range(struct inode *inode,
} }
handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS); handle = ocfs2_start_trans(osb, OCFS2_REMOVE_EXTENT_CREDITS);
if (handle == NULL) { if (IS_ERR(handle)) {
ret = -ENOMEM; ret = PTR_ERR(handle);
mlog_errno(ret); mlog_errno(ret);
goto out; goto out;
} }
...@@ -1352,8 +1352,8 @@ static int ocfs2_zero_partial_clusters(struct inode *inode, ...@@ -1352,8 +1352,8 @@ static int ocfs2_zero_partial_clusters(struct inode *inode,
goto out; goto out;
handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
if (handle == NULL) { if (IS_ERR(handle)) {
ret = -ENOMEM; ret = PTR_ERR(handle);
mlog_errno(ret); mlog_errno(ret);
goto out; goto out;
} }
...@@ -1866,6 +1866,13 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, ...@@ -1866,6 +1866,13 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos,
ppos, count, ocount); ppos, count, ocount);
if (written < 0) { if (written < 0) {
/*
* direct write may have instantiated a few
* blocks outside i_size. Trim these off again.
* Don't need i_size_read because we hold i_mutex.
*/
if (*ppos + count > inode->i_size)
vmtruncate(inode, inode->i_size);
ret = written; ret = written;
goto out_dio; goto out_dio;
} }
......
...@@ -1106,6 +1106,12 @@ void ocfs2_clear_inode(struct inode *inode) ...@@ -1106,6 +1106,12 @@ void ocfs2_clear_inode(struct inode *inode)
oi->ip_last_trans = 0; oi->ip_last_trans = 0;
oi->ip_dir_start_lookup = 0; oi->ip_dir_start_lookup = 0;
oi->ip_blkno = 0ULL; oi->ip_blkno = 0ULL;
/*
* ip_jinode is used to track txns against this inode. We ensure that
* the journal is flushed before journal shutdown. Thus it is safe to
* have inodes get cleaned up after journal shutdown.
*/
jbd2_journal_release_jbd_inode(OCFS2_SB(inode->i_sb)->journal->j_journal, jbd2_journal_release_jbd_inode(OCFS2_SB(inode->i_sb)->journal->j_journal,
&oi->ip_jinode); &oi->ip_jinode);
......
...@@ -690,6 +690,7 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb) ...@@ -690,6 +690,7 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb)
/* Shutdown the kernel journal system */ /* Shutdown the kernel journal system */
jbd2_journal_destroy(journal->j_journal); jbd2_journal_destroy(journal->j_journal);
journal->j_journal = NULL;
OCFS2_I(inode)->ip_open_count--; OCFS2_I(inode)->ip_open_count--;
......
...@@ -113,7 +113,11 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh, ...@@ -113,7 +113,11 @@ static int __ocfs2_page_mkwrite(struct inode *inode, struct buffer_head *di_bh,
* ocfs2_write_begin_nolock(). * ocfs2_write_begin_nolock().
*/ */
if (!PageUptodate(page) || page->mapping != inode->i_mapping) { if (!PageUptodate(page) || page->mapping != inode->i_mapping) {
ret = -EINVAL; /*
* the page has been umapped in ocfs2_data_downconvert_worker.
* So return 0 here and let VFS retry.
*/
ret = 0;
goto out; goto out;
} }
......
...@@ -378,8 +378,8 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, ...@@ -378,8 +378,8 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
} }
inode = new_inode(dir->i_sb); inode = new_inode(dir->i_sb);
if (IS_ERR(inode)) { if (!inode) {
status = PTR_ERR(inode); status = -ENOMEM;
mlog(ML_ERROR, "new_inode failed!\n"); mlog(ML_ERROR, "new_inode failed!\n");
goto leave; goto leave;
} }
...@@ -491,9 +491,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb, ...@@ -491,9 +491,11 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
brelse(*new_fe_bh); brelse(*new_fe_bh);
*new_fe_bh = NULL; *new_fe_bh = NULL;
} }
if (inode) if (inode) {
clear_nlink(inode);
iput(inode); iput(inode);
} }
}
mlog_exit(status); mlog_exit(status);
return status; return status;
......
...@@ -473,6 +473,9 @@ static inline int ocfs2_uses_extended_slot_map(struct ocfs2_super *osb) ...@@ -473,6 +473,9 @@ static inline int ocfs2_uses_extended_slot_map(struct ocfs2_super *osb)
(____gd)->bg_signature); \ (____gd)->bg_signature); \
} while (0) } while (0)
#define OCFS2_IS_VALID_XATTR_BLOCK(ptr) \
(!strcmp((ptr)->xb_signature, OCFS2_XATTR_BLOCK_SIGNATURE))
static inline unsigned long ino_from_blkno(struct super_block *sb, static inline unsigned long ino_from_blkno(struct super_block *sb,
u64 blkno) u64 blkno)
{ {
......
...@@ -742,12 +742,12 @@ struct ocfs2_group_desc ...@@ -742,12 +742,12 @@ struct ocfs2_group_desc
*/ */
struct ocfs2_xattr_entry { struct ocfs2_xattr_entry {
__le32 xe_name_hash; /* hash value of xattr prefix+suffix. */ __le32 xe_name_hash; /* hash value of xattr prefix+suffix. */
__le16 xe_name_offset; /* byte offset from the 1st etnry in the local __le16 xe_name_offset; /* byte offset from the 1st entry in the
local xattr storage(inode, xattr block or local xattr storage(inode, xattr block or
xattr bucket). */ xattr bucket). */
__u8 xe_name_len; /* xattr name len, does't include prefix. */ __u8 xe_name_len; /* xattr name len, does't include prefix. */
__u8 xe_type; /* the low 7 bits indicates the name prefix's __u8 xe_type; /* the low 7 bits indicate the name prefix
* type and the highest 1 bits indicate whether * type and the highest bit indicates whether
* the EA is stored in the local storage. */ * the EA is stored in the local storage. */
__le64 xe_value_size; /* real xattr value length. */ __le64 xe_value_size; /* real xattr value length. */
}; };
...@@ -766,9 +766,10 @@ struct ocfs2_xattr_header { ...@@ -766,9 +766,10 @@ struct ocfs2_xattr_header {
xattr. */ xattr. */
__le16 xh_name_value_len; /* total length of name/value __le16 xh_name_value_len; /* total length of name/value
length in this bucket. */ length in this bucket. */
__le16 xh_num_buckets; /* bucket nums in one extent __le16 xh_num_buckets; /* Number of xattr buckets
record, only valid in the in this extent record,
first bucket. */ only valid in the first
bucket. */
__le64 xh_csum; __le64 xh_csum;
struct ocfs2_xattr_entry xh_entries[0]; /* xattr entry list. */ struct ocfs2_xattr_entry xh_entries[0]; /* xattr entry list. */
}; };
...@@ -776,8 +777,8 @@ struct ocfs2_xattr_header { ...@@ -776,8 +777,8 @@ struct ocfs2_xattr_header {
/* /*
* On disk structure for xattr value root. * On disk structure for xattr value root.
* *
* It is used when one extended attribute's size is larger, and we will save it * When an xattr's value is large enough, it is stored in an external
* in an outside cluster. It will stored in a b-tree like file content. * b-tree like file data. The xattr value root points to this structure.
*/ */
struct ocfs2_xattr_value_root { struct ocfs2_xattr_value_root {
/*00*/ __le32 xr_clusters; /* clusters covered by xattr value. */ /*00*/ __le32 xr_clusters; /* clusters covered by xattr value. */
......
This diff is collapsed.
...@@ -3,24 +3,16 @@ ...@@ -3,24 +3,16 @@
* *
* xattr.h * xattr.h
* *
* Function prototypes * Copyright (C) 2004, 2008 Oracle. All rights reserved.
*
* Copyright (C) 2008 Oracle. All rights reserved.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public * modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either * License version 2 as published by the Free Software Foundation.
* version 2 of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details. * General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 021110-1307, USA.
*/ */
#ifndef OCFS2_XATTR_H #ifndef OCFS2_XATTR_H
...@@ -40,29 +32,11 @@ enum ocfs2_xattr_type { ...@@ -40,29 +32,11 @@ enum ocfs2_xattr_type {
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 ssize_t ocfs2_listxattr(struct dentry *, char *, size_t);
extern int ocfs2_xattr_get(struct inode *, int, const char *, void *, size_t);
extern int ocfs2_xattr_set(struct inode *, int, const char *, const void *,
size_t, int);
extern int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh);
extern struct xattr_handler *ocfs2_xattr_handlers[]; extern struct xattr_handler *ocfs2_xattr_handlers[];
static inline u16 ocfs2_xattr_buckets_per_cluster(struct ocfs2_super *osb) ssize_t ocfs2_listxattr(struct dentry *, char *, size_t);
{ int ocfs2_xattr_set(struct inode *, int, const char *, const void *,
return (1 << osb->s_clustersize_bits) / OCFS2_XATTR_BUCKET_SIZE; size_t, int);
} int ocfs2_xattr_remove(struct inode *, struct buffer_head *);
static inline u16 ocfs2_blocks_per_xattr_bucket(struct super_block *sb)
{
return OCFS2_XATTR_BUCKET_SIZE / (1 << sb->s_blocksize_bits);
}
static inline u16 ocfs2_xattr_max_xe_in_bucket(struct super_block *sb)
{
u16 len = sb->s_blocksize -
offsetof(struct ocfs2_xattr_header, xh_entries);
return len / sizeof(struct ocfs2_xattr_entry);
}
#endif /* OCFS2_XATTR_H */ #endif /* OCFS2_XATTR_H */
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