summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile8
-rw-r--r--changelog11
-rw-r--r--debian/changelog6
-rw-r--r--inotail.c149
-rw-r--r--inotail.h7
5 files changed, 133 insertions, 48 deletions
diff --git a/Makefile b/Makefile
index cfeb89a..bcb8cd4 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@
#
# Licensed under the terms of the GNU General Public License; version 2 or later.
-VERSION = 0.3
+VERSION = 0.4
# Paths
prefix = /usr/local
@@ -12,7 +12,7 @@ BINDIR = $(prefix)/bin
MANDIR = $(prefix)/share/man/man1
CC := gcc
-CFLAGS := $(CFLAGS) -W -Wall -pipe -D_USE_SOURCE -DVERSION="\"$(VERSION)\"" \
+CFLAGS := $(CFLAGS) -pipe -D_USE_SOURCE -DVERSION="\"$(VERSION)\"" -W -Wall \
-Wstrict-prototypes -Wsign-compare -Wshadow -Wchar-subscripts \
-Wmissing-declarations -Wpointer-arith -Wcast-align -Wmissing-prototypes
@@ -31,6 +31,10 @@ inotail: inotail.o
install: inotail
install -m 775 -D inotail $(BINDIR)/inotail
install -m 644 -D inotail.1 $(MANDIR)/inotail.1
+ gzip -9 $(MANDIR)/inotail.1
+
+uninstall:
+ rm $(BINDIR)/inotail $(MANDIR)/inotail.1*
cscope:
cscope -b
diff --git a/changelog b/changelog
index 8af070a..851ac3e 100644
--- a/changelog
+++ b/changelog
@@ -1,3 +1,14 @@
+inotail 0.4
+
+ * Use dynamic buffers of optimal size (st_blksize in struct stat) for
+ filesystem I/O (patch by Folkert van Heusden)
+ * Added handling of EINTR/EAGAIN while watching files for changes (patch by
+ Anthony Martinez)
+ * Better error checking and handling (patch by Folkert van Heusden)
+ * Various cleanups
+
+ -- Tobias Klauser <tklauser@distanz.ch> 2007-06-20 15:00
+
inotail 0.3
* Follow files even if they were moved
diff --git a/debian/changelog b/debian/changelog
index ca3a68f..0ef3352 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+inotail (0.4-1) unstable; urgency=low
+
+ * New upstream release
+
+ -- Tobias Klauser <tklauser@access.unizh.ch> Wed, 20 Jun 2007 15:10:19 +0200
+
inotail (0.3-1) unstable; urgency=low
* New upstream release
diff --git a/inotail.c b/inotail.c
index 6f8be7c..8561054 100644
--- a/inotail.c
+++ b/inotail.c
@@ -30,7 +30,6 @@
#include <fcntl.h>
#include <errno.h>
#include <getopt.h>
-#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -40,7 +39,7 @@
#include "inotail.h"
#define PROGRAM_NAME "inotail"
-#define BUFFER_SIZE 4096
+#define DEFAULT_BUFFER_SIZE 4096
/* inotify event buffer length for one file */
#define INOTIFY_BUFLEN (4 * sizeof(struct inotify_event))
@@ -64,6 +63,18 @@ static const struct option long_opts[] = {
{ NULL, 0, NULL, 0 }
};
+static void *emalloc(size_t size)
+{
+ void *ret = malloc(size);
+
+ if (unlikely(!ret)) {
+ fprintf(stderr, "Error: Failed to allocate %d bytes of memory (%s)\n", size, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ return ret;
+}
+
static void usage(const int status)
{
fprintf(stdout, "Usage: %s [OPTION]... [FILE]...\n\n"
@@ -82,10 +93,10 @@ static void usage(const int status)
static inline void setup_file(struct file_struct *f)
{
- f->fd = -1;
+ f->fd = f->i_watch = -1;
f->st_size = 0;
+ f->st_blksize = DEFAULT_BUFFER_SIZE;
f->ignore = 0;
- f->i_watch = -1;
}
static void ignore_file(struct file_struct *f)
@@ -117,43 +128,51 @@ static void write_header(char *filename)
static off_t lines_to_offset_from_end(struct file_struct *f, unsigned long n_lines)
{
- char buf[BUFFER_SIZE];
off_t offset = f->st_size;
+ char *buf = emalloc(f->st_blksize);
n_lines++; /* We also count the last \n */
while (offset > 0 && n_lines > 0) {
int i;
- ssize_t rc, block_size = BUFFER_SIZE; /* Size of the current block we're reading */
+ ssize_t rc, block_size = f->st_blksize; /* Size of the current block we're reading */
- if (offset < BUFFER_SIZE)
+ if (offset < block_size)
block_size = offset;
/* Start of current block */
offset -= block_size;
- lseek(f->fd, offset, SEEK_SET);
+ if (lseek(f->fd, offset, SEEK_SET) == (off_t) -1) {
+ fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno));
+ free(buf);
+ return -1;
+ }
- rc = read(f->fd, &buf, block_size);
+ rc = read(f->fd, buf, block_size);
if (unlikely(rc < 0)) {
fprintf(stderr, "Error: Could not read from file '%s' (%s)\n", f->name, strerror(errno));
+ free(buf);
return -1;
}
for (i = block_size - 1; i > 0; i--) {
if (buf[i] == '\n') {
- if (--n_lines == 0)
+ if (--n_lines == 0) {
+ free(buf);
return offset += i + 1; /* We don't want the first \n */
+ }
}
}
}
+ free(buf);
return offset;
}
static off_t lines_to_offset_from_begin(struct file_struct *f, unsigned long n_lines)
{
- char buf[BUFFER_SIZE];
+ char *buf;
off_t offset = 0;
/* tail everything for 'inotail -n +0' */
@@ -161,30 +180,39 @@ static off_t lines_to_offset_from_begin(struct file_struct *f, unsigned long n_l
return 0;
n_lines--;
+ buf = emalloc(f->st_blksize);
while (offset <= f->st_size && n_lines > 0) {
int i;
- ssize_t rc, block_size = BUFFER_SIZE;
+ ssize_t rc, block_size = f->st_blksize;
- lseek(f->fd, offset, SEEK_SET);
+ if (lseek(f->fd, offset, SEEK_SET) == (off_t) -1) {
+ fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno));
+ free(buf);
+ return -1;
+ }
- rc = read(f->fd, &buf, block_size);
+ rc = read(f->fd, buf, block_size);
if (unlikely(rc < 0)) {
fprintf(stderr, "Error: Could not read from file '%s' (%s)\n", f->name, strerror(errno));
+ free(buf);
return -1;
} else if (rc < block_size)
block_size = rc;
for (i = 0; i < block_size; i++) {
if (buf[i] == '\n') {
- if (--n_lines == 0)
+ if (--n_lines == 0) {
+ free(buf);
return offset + i + 1;
+ }
}
}
offset += block_size;
}
+ free(buf);
return offset;
}
@@ -204,10 +232,8 @@ static off_t bytes_to_offset(struct file_struct *f, unsigned long n_bytes)
if (from_begin) {
if (n_bytes > 0)
offset = (off_t) n_bytes - 1;
- } else {
- if ((off_t) n_bytes < f->st_size)
- offset = f->st_size - (off_t) n_bytes;
- }
+ } else if ((off_t) n_bytes < f->st_size)
+ offset = f->st_size - (off_t) n_bytes;
return offset;
}
@@ -215,15 +241,22 @@ static off_t bytes_to_offset(struct file_struct *f, unsigned long n_bytes)
static ssize_t tail_pipe(struct file_struct *f)
{
ssize_t rc;
- char buf[BUFFER_SIZE];
+ char *buf = emalloc(f->st_blksize);
if (verbose)
write_header(f->name);
/* We will just tail everything here */
- while ((rc = read(f->fd, &buf, BUFFER_SIZE)) > 0)
- write(STDOUT_FILENO, buf, (size_t) rc);
+ while ((rc = read(f->fd, buf, f->st_blksize)) > 0) {
+ if (write(STDOUT_FILENO, buf, (size_t) rc) <= 0) {
+ /* e.g. when writing to a pipe which gets closed */
+ fprintf(stderr, "Error: Could not write to stdout (%s)\n", strerror(errno));
+ rc = -1;
+ break;
+ }
+ }
+ free(buf);
return rc;
}
@@ -231,7 +264,7 @@ static int tail_file(struct file_struct *f, unsigned long n_units, char mode, ch
{
ssize_t bytes_read = 0;
off_t offset = 0;
- char buf[BUFFER_SIZE];
+ char *buf;
struct stat finfo;
if (strcmp(f->name, "-") == 0)
@@ -262,6 +295,7 @@ static int tail_file(struct file_struct *f, unsigned long n_units, char mode, ch
return tail_pipe(f);
f->st_size = finfo.st_size;
+ f->st_blksize = finfo.st_blksize; /* TODO: Can this value be 0? */
if (mode == M_LINES)
offset = lines_to_offset(f, n_units);
@@ -277,35 +311,50 @@ static int tail_file(struct file_struct *f, unsigned long n_units, char mode, ch
if (verbose)
write_header(f->name);
- lseek(f->fd, offset, SEEK_SET);
+ if (lseek(f->fd, offset, SEEK_SET) == (off_t) -1) {
+ fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno));
+ return -1;
+ }
+
+ buf = emalloc(f->st_blksize);
- while ((bytes_read = read(f->fd, &buf, BUFFER_SIZE)) > 0)
+ while ((bytes_read = read(f->fd, buf, f->st_blksize)) > 0)
write(STDOUT_FILENO, buf, (size_t) bytes_read);
if (!forever) {
if (close(f->fd) < 0) {
fprintf(stderr, "Error: Could not close file '%s' (%s)\n", f->name, strerror(errno));
+ free(buf);
return -1;
}
} /* Let the fd open otherwise, we'll need it */
+ free(buf);
return 0;
}
static int handle_inotify_event(struct inotify_event *inev, struct file_struct *f)
{
+ char *fbuf;
int ret = 0;
if (inev->mask & IN_MODIFY) {
ssize_t rc;
- char fbuf[BUFFER_SIZE];
struct stat finfo;
+ fbuf = emalloc(f->st_blksize);
+
if (verbose)
write_header(f->name);
- lseek(f->fd, f->st_size, SEEK_SET); /* Old file size */
- while ((rc = read(f->fd, &fbuf, BUFFER_SIZE)) != 0)
+ /* Seek to old file size */
+ if (lseek(f->fd, f->st_size, SEEK_SET) == (off_t) -1) {
+ fprintf(stderr, "Error: Could not seek in file '%s' (%s)\n", f->name, strerror(errno));
+ ret = -1;
+ goto ignore;
+ }
+
+ while ((rc = read(f->fd, fbuf, f->st_blksize)) != 0)
write(STDOUT_FILENO, fbuf, (size_t) rc);
if (fstat(f->fd, &finfo) < 0) {
@@ -316,6 +365,7 @@ static int handle_inotify_event(struct inotify_event *inev, struct file_struct *
f->st_size = finfo.st_size;
+ free(fbuf);
return ret;
} else if (inev->mask & IN_DELETE_SELF) {
fprintf(stderr, "File '%s' deleted.\n", f->name);
@@ -328,7 +378,7 @@ static int handle_inotify_event(struct inotify_event *inev, struct file_struct *
ignore:
ignore_file(f);
-
+ free(fbuf);
return ret;
}
@@ -339,10 +389,10 @@ static int watch_files(struct file_struct *files, int n_files)
ifd = inotify_init();
if (errno == ENOSYS) {
- fprintf(stderr, "Error: Inotify is not supported by the kernel you're currently running.\n");
+ fprintf(stderr, "Error: inotify is not supported by the kernel you're currently running.\n");
exit(EXIT_FAILURE);
} else if (unlikely(ifd < 0)) {
- fprintf(stderr, "Error: Could not initialize Inotify (%s)\n", strerror(errno));
+ fprintf(stderr, "Error: Could not initialize inotify (%s)\n", strerror(errno));
exit(EXIT_FAILURE);
}
@@ -363,10 +413,15 @@ static int watch_files(struct file_struct *files, int n_files)
ssize_t len;
int ev_idx = 0;
- len = read(ifd, &buf, (n_files * INOTIFY_BUFLEN));
+ len = read(ifd, buf, (n_files * INOTIFY_BUFLEN));
if (unlikely(len < 0)) {
- fprintf(stderr, "Error: Could not read inotify events (%s)\n", strerror(errno));
- exit(EXIT_FAILURE);
+ /* Some signal, likely ^Z/fg's STOP and CONT interrupted the inotify read, retry */
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ else {
+ fprintf(stderr, "Error: Could not read inotify events (%s)\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
}
while (ev_idx < len) {
@@ -377,7 +432,9 @@ static int watch_files(struct file_struct *files, int n_files)
/* Which file has produced the event? */
for (i = 0; i < n_files; i++) {
- if (!files[i].ignore && files[i].fd >= 0 && files[i].i_watch == inev->wd) {
+ if (!files[i].ignore
+ && files[i].fd >= 0
+ && files[i].i_watch == inev->wd) {
f = &files[i];
break;
}
@@ -388,12 +445,12 @@ static int watch_files(struct file_struct *files, int n_files)
if (handle_inotify_event(inev, f) < 0)
break;
- ev_idx += INOTIFY_BUFLEN + inev->len;
+
+ ev_idx += sizeof(struct inotify_event) + inev->len;
}
}
close(ifd);
-
return -1;
}
@@ -418,7 +475,7 @@ int main(int argc, char **argv)
} else if (*optarg == '-')
optarg++;
- if (!isdigit(*optarg)) {
+ if (!is_digit(*optarg)) {
fprintf(stderr, "Invalid number of lines: %s\n", optarg);
exit(EXIT_FAILURE);
}
@@ -454,17 +511,19 @@ int main(int argc, char **argv)
specified and standard input is a pipe. */
if (forever) {
struct stat finfo;
- if (fstat(STDIN_FILENO, &finfo) == 0
- && IS_PIPELIKE(finfo.st_mode))
+ int rc = fstat(STDIN_FILENO, &finfo);
+
+ if (unlikely(rc == -1)) {
+ fprintf(stderr, "Error: Could not stat stdin (%s)\n", strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ if (rc == 0 && IS_PIPELIKE(finfo.st_mode))
forever = 0;
}
}
- files = malloc(n_files * sizeof(struct file_struct));
- if (unlikely(!files)) {
- fprintf(stderr, "Error: Not enough memory (%s)\n", strerror(errno));
- exit(EXIT_FAILURE);
- }
+ files = emalloc(n_files * sizeof(struct file_struct));
for (i = 0; i < n_files; i++) {
files[i].name = filenames[i];
diff --git a/inotail.h b/inotail.h
index 4c57867..f7c1406 100644
--- a/inotail.h
+++ b/inotail.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2006, Tobias Klauser <tklauser@distanz.ch>
+ * Copyright (C) 2005-2007, Tobias Klauser <tklauser@distanz.ch>
*
* Licensed under the terms of the GNU General Public License; version 2 or later.
*/
@@ -7,6 +7,8 @@
#ifndef _INOTAIL_H
#define _INOTAIL_H
+#include <sys/types.h>
+
/* Number of items to tail. */
#define DEFAULT_N_LINES 10
@@ -18,6 +20,7 @@ struct file_struct {
char *name; /* Name of file (or '-' for stdin) */
int fd; /* File descriptor (or -1 if file is not open */
off_t st_size; /* File size */
+ blksize_t st_blksize; /* Blocksize for filesystem I/O */
unsigned ignore; /* Whether to ignore the file in further processing */
int i_watch; /* Inotify watch associated with file_struct */
};
@@ -29,6 +32,8 @@ struct file_struct {
#define IS_TAILABLE(mode) \
(S_ISREG(mode) || IS_PIPELIKE(mode) || S_ISCHR(mode))
+#define is_digit(c) ((c) >= '0' && (c) <= '9')
+
#ifdef DEBUG
# define dprintf(fmt, args...) fprintf(stderr, fmt, ##args)
#else
373e35162eb7a072c5f'>userns: Convert bfs to use kuid/kgid where appropriateEric W. Biederman1-4/+4 Cc: "Tigran A. Aivazian" <tigran@aivazian.fsnet.co.uk> Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> 2012-07-14don't pass nameidata to ->create()Al Viro1-1/+1 boolean "does it have to be exclusive?" flag is passed instead; Local filesystem should just ignore it - the object is guaranteed not to be there yet. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> 2012-07-14stop passing nameidata to ->lookup()Al Viro1-1/+1 Just the flags; only NFS cares even about that, but there are legitimate uses for such argument. And getting rid of that completely would require splitting ->lookup() into a couple of methods (at least), so let's leave that alone for now... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> 2012-05-06vfs: Rename end_writeback() to clear_inode()Jan Kara1-1/+1 After we moved inode_sync_wait() from end_writeback() it doesn't make sense to call the function end_writeback() anymore. Rename it to clear_inode() which well says what the function really does - set I_CLEAR flag. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Fengguang Wu <fengguang.wu@intel.com> 2012-03-20switch open-coded instances of d_make_root() to new helperAl Viro1-2/+1 Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> 2012-01-03switch ->create() to umode_tAl Viro1-1/+1 vfs_create() ignores everything outside of 16bit subset of its mode argument; switching it to umode_t is obviously equivalent and it's the only caller of the method Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> 2012-01-03vfs: fix the stupidity with i_dentry in inode destructorsAl Viro1-1/+0 Seeing that just about every destructor got that INIT_LIST_HEAD() copied into it, there is no point whatsoever keeping this INIT_LIST_HEAD in inode_init_once(); the cost of taking it into inode_init_always() will be negligible for pipes and sockets and negative for everything else. Not to mention the removal of boilerplate code from ->destroy_inode() instances... Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> 2011-11-02filesystems: add set_nlink()Miklos Szeredi2-2/+2 Replace remaining direct i_nlink updates with a new set_nlink() updater function. Signed-off-by: Miklos Szeredi <mszeredi@suse.cz> Tested-by: Toshiyuki Okajima <toshi.okajima@jp.fujitsu.com> Signed-off-by: Christoph Hellwig <hch@lst.de> 2011-05-28bfs: remove unnecessary dentry_unhash on dir renameSage Weil1-3/+0 Bfs does not have problems with references to unlinked directories. CC: tigran@aivazian.fsnet.co.uk Signed-off-by: Sage Weil <sage@newdream.net> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> 2011-05-26vfs: push dentry_unhash on rename_dir into file systemsSage Weil1-0/+3 Only a few file systems need this. Start by pushing it down into each rename method (except gfs2 and xfs) so that it can be dealt with on a per-fs basis. Acked-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Sage Weil <sage@newdream.net> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> 2011-03-24Merge branch 'for-2.6.39/core' of git://git.kernel.dk/linux-2.6-blockLinus Torvalds1-1/+0 * 'for-2.6.39/core' of git://git.kernel.dk/linux-2.6-block: (65 commits) Documentation/iostats.txt: bit-size reference etc. cfq-iosched: removing unnecessary think time checking cfq-iosched: Don't clear queue stats when preempt. blk-throttle: Reset group slice when limits are changed blk-cgroup: Only give unaccounted_time under debug cfq-iosched: Don't set active queue in preempt block: fix non-atomic access to genhd inflight structures block: attempt to merge with existing requests on plug flush block: NULL dereference on error path in __blkdev_get() cfq-iosched: Don't update group weights when on service tree fs: assign sb->s_bdi to default_backing_dev_info if the bdi is going away block: Require subsystems to explicitly allocate bio_set integrity mempool jbd2: finish conversion from WRITE_SYNC_PLUG to WRITE_SYNC and explicit plugging jbd: finish conversion from WRITE_SYNC_PLUG to WRITE_SYNC and explicit plugging fs: make fsync_buffers_list() plug mm: make generic_writepages() use plugging blk-cgroup: Add unaccounted time to timeslice_used. block: fixup plugging stubs for !CONFIG_BLOCK block: remove obsolete comments for blkdev_issue_zeroout. blktrace: Use rq->cmd_flags directly in blk_add_trace_rq. ... Fix up conflicts in fs/{aio.c,super.c} 2011-03-21bfs: fix bitmap size argument to find_first_zero_bit()Akinobu Mita1-1/+1 The usage of find_first_zero_bit() in bfs_create() is wrong for two reasons. The bitmap size argument to find_first_zero_bit() is info->si_lasti but the correct bitmap size is info->si_lasti + 1 as info->si_lasti is the last valid index in info->si_imap bitmap. Another problem is that it is impossible to detect that info->si_imap bitmap is full because there is an off-by-one bug in the return value check for find_first_zero_bit(). If no zero bits exist in info->si_imap, find_first_zero_bit() returns info->si_lasti. But the check can't catch it due to the off-by-one. Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Acked-by: "Tigran A. Aivazian" <tigran@aivazian.fsnet.co.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> 2011-03-10block: remove per-queue pluggingJens Axboe1-1/+0 Code has been converted over to the new explicit on-stack plugging, and delay users have been converted to use the new API for that. So lets kill off the old plugging along with aops->sync_page(). Signed-off-by: Jens Axboe <jaxboe@fusionio.com> 2011-01-07fs: icache RCU free inodesNick Piggin1-1/+8 RCU free the struct inode. This will allow: - Subsequent store-free path walking patch. The inode must be consulted for permissions when walking, so an RCU inode reference is a must. - sb_inode_list_lock to be moved inside i_lock because sb list walkers who want to take i_lock no longer need to take sb_inode_list_lock to walk the list in the first place. This will simplify and optimize locking. - Could remove some nested trylock loops in dcache code - Could potentially simplify things a bit in VM land. Do not need to take the page lock to follow page->mapping. The downsides of this is the performance cost of using RCU. In a simple creat/unlink microbenchmark, performance drops by about 10% due to inability to reuse cache-hot slab objects. As iterations increase and RCU freeing starts kicking over, this increases to about 20%. In cases where inode lifetimes are longer (ie. many inodes may be allocated during the average life span of a single inode), a lot of this cache reuse is not applicable, so the regression caused by this patch is smaller. The cache-hot regression could largely be avoided by using SLAB_DESTROY_BY_RCU, however this adds some complexity to list walking and store-free path walking, so I prefer to implement this at a later date, if it is shown to be a win in real situations. I haven't found a regression in any non-micro benchmark so I doubt it will be a problem. Signed-off-by: Nick Piggin <npiggin@kernel.dk> 2010-10-29new helper: mount_bdev()Al Viro1-4/+4 ... and switch of the obvious get_sb_bdev() users to ->mount() Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> 2010-10-25new helper: ihold()Al Viro1-1/+1 Clones an existing reference to inode; caller must already hold one. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> 2010-10-04BKL: Remove BKL from BFSJan Blunck1-12/+1 The BKL is only used in put_super and fill_super that are both protected by the superblocks s_umount rw_semaphore. Therefore it is safe to remove the BKL entirely. Signed-off-by: Jan Blunck <jblunck@infradead.org> Signed-off-by: Arnd Bergmann <arnd@arndb.de> 2010-10-04BKL: Explicitly add BKL around get_sb/fill_superJan Blunck1-1/+7 This patch is a preparation necessary to remove the BKL from do_new_mount(). It explicitly adds calls to lock_kernel()/unlock_kernel() around get_sb/fill_super operations for filesystems that still uses the BKL. I've read through all the code formerly covered by the BKL inside do_kern_mount() and have satisfied myself that it doesn't need the BKL any more. do_kern_mount() is already called without the BKL when mounting the rootfs and in nfsctl. do_kern_mount() calls vfs_kern_mount(), which is called from various places without BKL: simple_pin_fs(), nfs_do_clone_mount() through nfs_follow_mountpoint(), afs_mntpt_do_automount() through afs_mntpt_follow_link(). Both later functions are actually the filesystems follow_link inode operation. vfs_kern_mount() is calling the specified get_sb function and lets the filesystem do its job by calling the given fill_super function. Therefore I think it is safe to push down the BKL from the VFS to the low-level filesystems get_sb/fill_super operation. [arnd: do not add the BKL to those file systems that already don't use it elsewhere] Signed-off-by: Jan Blunck <jblunck@infradead.org> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Cc: Matthew Wilcox <matthew@wil.cx> Cc: Christoph Hellwig <hch@infradead.org> 2010-08-09BFS: clean up the superblock usageArtem Bityutskiy3-43/+7 BFS is a very simple FS and its superblocks contains only static information and is never changed. However, the BFS code for some misterious reasons marked its buffer head as dirty from time to time, but nothing in that buffer was ever changed. This patch removes all the BFS superblock manipulation, simply because it is not needed. It removes: 1. The si_sbh filed from 'struct bfs_sb_info' because it is not needed. We only need to read the SB once on mount to get the start of data blocks and the FS size. After this, we can forget about the SB. 2. All instances of 'mark_buffer_dirty(sbh)' for BFS SB because it is never changed. 3. The '->sync_fs()' method because there is nothing to sync (inodes are synched by VFS). 4. The '->write_super()' method, again, because the SB is never changed. Tested-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> 2010-08-09switch bfs to ->evict_inode(), clean upAl Viro1-38/+32 Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> 2010-08-09get rid of block_write_begin_newtruncChristoph Hellwig1-3/+11 Move the call to vmtruncate to get rid of accessive blocks to the callers in preparation of the new truncate sequence and rename the non-truncating version to block_write_begin. While we're at it also remove several unused arguments to block_write_begin. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>