diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 17:11:13 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 17:11:13 -0800 |
commit | 29bd17af7d8ffc16bb5eb286947495c166ea826e (patch) | |
tree | 5c20c44b51bdb3573949d1dc23bc3d3927d759fa /fs/ocfs2/buffer_head_io.c | |
parent | 2ba14a017a4ba8d2266316f481d4ad7400073d18 (diff) | |
parent | 2fe5c1d7eb88830b09c863a4b5b3279dc120f3af (diff) | |
download | talos-obmc-linux-29bd17af7d8ffc16bb5eb286947495c166ea826e.tar.gz talos-obmc-linux-29bd17af7d8ffc16bb5eb286947495c166ea826e.zip |
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: (31 commits)
ocfs2: clean up bh null checks
ocfs2: document access rules for blocked_lock_list
configfs: file.c fix possible recursive locking
configfs: dir.c fix possible recursive locking
configfs: Remove EXPERIMENTAL
ocfs2: bump version number
ocfs2/dlm: Clear joining_node on hearbeat node down
ocfs2: convert byte order of constant instead of variable
ocfs2: Update default cluster timeouts
ocfs2: printf fixes
ocfs2: Use generic_file_llseek
ocfs2: Safer read_inline_data()
ocfs2: Silence false lockdep warnings
[PATCH 2/2] ocfs2: cluster aware flock()
[PATCH 1/2] ocfs2: add flock lock type
ocfs2: Local alloc window size changeable via mount option
ocfs2: Support commit= mount option
ocfs2: Add missing permission checks
[PATCH 2/2] ocfs2: Implement group add for online resize
[PATCH 1/2] ocfs2: Add group extend for online resize
...
Diffstat (limited to 'fs/ocfs2/buffer_head_io.c')
-rw-r--r-- | fs/ocfs2/buffer_head_io.c | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c index c9037414f4f6..f136639f5b41 100644 --- a/fs/ocfs2/buffer_head_io.c +++ b/fs/ocfs2/buffer_head_io.c @@ -79,7 +79,7 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh, * information for this bh as it's not marked locally * uptodate. */ ret = -EIO; - brelse(bh); + put_bh(bh); } mutex_unlock(&OCFS2_I(inode)->ip_io_mutex); @@ -256,7 +256,7 @@ int ocfs2_read_blocks(struct ocfs2_super *osb, u64 block, int nr, * for this bh as it's not marked locally * uptodate. */ status = -EIO; - brelse(bh); + put_bh(bh); bhs[i] = NULL; continue; } @@ -280,3 +280,64 @@ bail: mlog_exit(status); return status; } + +/* Check whether the blkno is the super block or one of the backups. */ +static void ocfs2_check_super_or_backup(struct super_block *sb, + sector_t blkno) +{ + int i; + u64 backup_blkno; + + if (blkno == OCFS2_SUPER_BLOCK_BLKNO) + return; + + for (i = 0; i < OCFS2_MAX_BACKUP_SUPERBLOCKS; i++) { + backup_blkno = ocfs2_backup_super_blkno(sb, i); + if (backup_blkno == blkno) + return; + } + + BUG(); +} + +/* + * Write super block and backups doesn't need to collaborate with journal, + * so we don't need to lock ip_io_mutex and inode doesn't need to bea passed + * into this function. + */ +int ocfs2_write_super_or_backup(struct ocfs2_super *osb, + struct buffer_head *bh) +{ + int ret = 0; + + mlog_entry_void(); + + BUG_ON(buffer_jbd(bh)); + ocfs2_check_super_or_backup(osb->sb, bh->b_blocknr); + + if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) { + ret = -EROFS; + goto out; + } + + lock_buffer(bh); + set_buffer_uptodate(bh); + + /* remove from dirty list before I/O. */ + clear_buffer_dirty(bh); + + get_bh(bh); /* for end_buffer_write_sync() */ + bh->b_end_io = end_buffer_write_sync; + submit_bh(WRITE, bh); + + wait_on_buffer(bh); + + if (!buffer_uptodate(bh)) { + ret = -EIO; + put_bh(bh); + } + +out: + mlog_exit(ret); + return ret; +} |